Page MenuHomePhabricator

No OneTemporary

This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/Applications/CMakeLists.txt b/Applications/CMakeLists.txt
index cf092c2999..88e2c69c17 100644
--- a/Applications/CMakeLists.txt
+++ b/Applications/CMakeLists.txt
@@ -1,27 +1,27 @@
set(MITK_CPACK_PACKAGE_EXECUTABLES "" CACHE INTERNAL "Collecting windows shortcuts to executables" FORCE)
set(MITK_DIR ${PROJECT_BINARY_DIR})
set(MITK_EXPORTS_FILE_INCLUDED 1)
-if(MITK_USE_QT AND QT4_FOUND)
+if(MITK_USE_QT)
if(MITK_USE_CTK)
add_subdirectory(PluginGenerator)
endif()
-
+
if(MITK_USE_BLUEBERRY)
-
+
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)
add_subdirectory(${target_dir})
endif()
endforeach()
-
+
endif()
endif()
diff --git a/Applications/CoreApp/CMakeLists.txt b/Applications/CoreApp/CMakeLists.txt
index 7cc6731c54..b517434c0d 100644
--- a/Applications/CoreApp/CMakeLists.txt
+++ b/Applications/CoreApp/CMakeLists.txt
@@ -1,35 +1,35 @@
project(CoreApp)
set(_app_options)
if(MITK_SHOW_CONSOLE_WINDOW)
list(APPEND _app_options SHOW_CONSOLE)
endif()
# Create a cache entry for the provisioning file which is used to export
# the file name in the MITKConfig.cmake file. This will keep external projects
# which rely on this file happy.
set(MITK_COREAPP_PROVISIONING_FILE "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/MitkCoreApp.provisioning" CACHE INTERNAL "CoreApp provisioning file" FORCE)
set(_plugins
org.blueberry.compat
org.mitk.gui.qt.coreapplication
org.mitk.gui.qt.stdmultiwidgeteditor
)
# Plug-ins listed below will not be
# - added as a build-time dependency to the executable
# - listed in the provisioning file for the executable
# - installed if they are external plug-ins
set(_exclude_plugins )
FunctionCreateBlueBerryApplication(
NAME MitkCoreApp
DESCRIPTION "MITK - CoreApp Application"
PLUGINS ${_plugins}
${_app_options}
)
-mitk_use_modules(TARGET MitkCoreApp PACKAGES Qt4|QtGui)
+mitk_use_modules(TARGET MitkCoreApp PACKAGES Qt4|QtGui Qt5|Widgets)
# subproject support
add_dependencies(MITK-CoreUI MitkCoreApp)
diff --git a/Applications/Diffusion/CMakeLists.txt b/Applications/Diffusion/CMakeLists.txt
index e3ca10cb8f..6a7b78d94d 100644
--- a/Applications/Diffusion/CMakeLists.txt
+++ b/Applications/Diffusion/CMakeLists.txt
@@ -1,83 +1,84 @@
project(MitkDiffusion)
set(DIFFUSIONAPP_NAME MitkDiffusion)
set(_app_options)
if(MITK_SHOW_CONSOLE_WINDOW)
list(APPEND _app_options SHOW_CONSOLE)
endif()
# Create a cache entry for the provisioning file which is used to export
# the file name in the MITKConfig.cmake file. This will keep external projects
# which rely on this file happy.
set(DIFFUSIONIMAGINGAPP_PROVISIONING_FILE "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${DIFFUSIONAPP_NAME}.provisioning" CACHE INTERNAL "${DIFFUSIONAPP_NAME} provisioning file" FORCE)
# should be identical to the list in /CMake/mitkBuildConfigurationmitkDiffusion.cmake
# remember to set plugins which should be automatically toggled in target_libraries.cmake
set(_plugins
org.commontk.configadmin
org.commontk.eventadmin
org.blueberry.osgi
org.blueberry.compat
org.blueberry.core.runtime
org.blueberry.core.expressions
org.blueberry.solstice.common
org.blueberry.core.commands
org.blueberry.ui
org.blueberry.ui.qt
org.blueberry.ui.qt.log
org.blueberry.ui.qt.help
org.mitk.core.services
org.mitk.gui.common
org.mitk.planarfigure
org.mitk.core.ext
org.mitk.diffusionimaging
org.mitk.gui.qt.application
org.mitk.gui.qt.ext
org.mitk.gui.qt.diffusionimagingapp
org.mitk.gui.qt.common
org.mitk.gui.qt.stdmultiwidgeteditor
org.mitk.gui.qt.common.legacy
org.mitk.gui.qt.datamanager
org.mitk.gui.qt.measurementtoolbox
org.mitk.gui.qt.segmentation
org.mitk.gui.qt.volumevisualization
org.mitk.gui.qt.diffusionimaging
org.mitk.gui.qt.imagenavigator
org.mitk.gui.qt.moviemaker
org.mitk.gui.qt.basicimageprocessing
org.mitk.gui.qt.registration
org.mitk.gui.qt.properties
org.mitk.gui.qt.viewnavigator
+ org.mitk.gui.qt.cmdlinemodules
)
# Plug-ins listed below will not be
# - added as a build-time dependency to the executable
# - listed in the provisioning file for the executable
# - installed if they are external plug-ins
set(_exclude_plugins
org.blueberry.test
org.blueberry.uitest
org.mitk.gui.qt.coreapplication
org.mitk.gui.qt.extapplication
)
FunctionCreateBlueBerryApplication(
NAME ${DIFFUSIONAPP_NAME}
DESCRIPTION "MITK Diffusion"
PLUGINS ${_plugins}
EXCLUDE_PLUGINS ${_exclude_plugins}
${_app_options}
)
mitk_use_modules(TARGET ${DIFFUSIONAPP_NAME} MODULES qtsingleapplication)
# Add meta dependencies (e.g. on auto-load modules from depending modules)
if(ALL_META_DEPENDENCIES)
add_dependencies(${DIFFUSIONAPP_NAME} ${ALL_META_DEPENDENCIES})
endif()
# Add a build time dependency to legacy BlueBerry bundles.
if(MITK_MODULES_ENABLED_PLUGINS)
add_dependencies(${DIFFUSIONAPP_NAME} ${MITK_MODULES_ENABLED_PLUGINS})
endif()
diff --git a/Applications/Diffusion/MitkDiffusion.ini b/Applications/Diffusion/MitkDiffusion.ini
index 739d228940..5b1f9b5200 100644
--- a/Applications/Diffusion/MitkDiffusion.ini
+++ b/Applications/Diffusion/MitkDiffusion.ini
@@ -1,2 +1,3 @@
BlueBerry.home=@BLUEBERRY_BINARY_DIR@
-BlueBerry.provisioning=@DIFFUSIONIMAGINGAPP_PROVISIONING_FILE@
\ No newline at end of file
+BlueBerry.provisioning=@DIFFUSIONIMAGINGAPP_PROVISIONING_FILE@
+BlueBerry.qtplugin_path=@BLUEBERRY_QTPLUGIN_PATH@
diff --git a/Applications/Diffusion/target_libraries.cmake b/Applications/Diffusion/target_libraries.cmake
index 42abb7cce7..2777776563 100644
--- a/Applications/Diffusion/target_libraries.cmake
+++ b/Applications/Diffusion/target_libraries.cmake
@@ -1,24 +1,25 @@
# A list of plug-in targets which should be automatically enabled
# (or be available in external projects) for this application.
set(target_libraries
org_blueberry_compat
org_blueberry_ui_qt
org_blueberry_ui_qt_help
org_mitk_diffusionimaging
org_mitk_planarfigure
org_mitk_gui_qt_diffusionimagingapp
org_mitk_gui_qt_common_legacy
org_mitk_gui_qt_ext
org_mitk_gui_qt_datamanager
org_mitk_gui_qt_segmentation
org_mitk_gui_qt_volumevisualization
org_mitk_gui_qt_diffusionimaging
org_mitk_gui_qt_imagenavigator
org_mitk_gui_qt_moviemaker
org_mitk_gui_qt_measurementtoolbox
org_mitk_gui_qt_basicimageprocessing
org_mitk_gui_qt_registration
org_mitk_gui_qt_viewnavigator
+ org_mitk_gui_qt_cmdlinemodules
)
diff --git a/Applications/PluginGenerator/CMakeLists.txt b/Applications/PluginGenerator/CMakeLists.txt
index c47bb30588..1684f097e8 100644
--- a/Applications/PluginGenerator/CMakeLists.txt
+++ b/Applications/PluginGenerator/CMakeLists.txt
@@ -1,77 +1,92 @@
-cmake_minimum_required(VERSION 2.8.9)
+if (${CMAKE_SOURCE_DIR} EQUAL ${PROJECT_SOURCE_DIR})
+ cmake_minimum_required(VERSION 2.8.9)
+endif()
project(MitkPluginGenerator)
set(VERSION_MAJOR 1)
set(VERSION_MINOR 5)
set(VERSION_PATCH 0)
set(VERSION_STRING "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
set(standalone_build 1)
else()
set(standalone_build 0)
endif()
#-----------------------------------------------------------------------------
# Prerequisites
#-----------------------------------------------------------------------------
set(QT_DONT_USE_QTGUI 1)
set(QT_USE_QTNETWORK 1)
-find_package(Qt 4.7 REQUIRED)
-
-include(${QT_USE_FILE})
+if(MITK_USE_Qt4)
+ find_package(Qt 4.7 REQUIRED)
+ include(${QT_USE_FILE})
+else()
+ find_package(Qt5Network REQUIRED)
+endif()
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/PluginGeneratorConfig.h.in"
"${CMAKE_CURRENT_BINARY_DIR}/PluginGeneratorConfig.h" @ONLY)
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
#-----------------------------------------------------------------------------
# Executable
#-----------------------------------------------------------------------------
set(src_files
PluginGenerator.cpp
ctkCommandLineParser.cpp
)
-qt4_wrap_cpp(src_files ctkCommandLineParser.h OPTIONS -DBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
-qt4_add_resources(src_files plugin_template.qrc project_template.qrc)
+if(MITK_USE_Qt4)
+ qt4_wrap_cpp(src_files ctkCommandLineParser.h OPTIONS -DBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+ qt4_add_resources(src_files plugin_template.qrc project_template.qrc)
+else()
+ qt5_wrap_cpp(src_files ctkCommandLineParser.h OPTIONS -DBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+ qt5_add_resources(src_files plugin_template.qrc project_template.qrc)
+endif()
set(exec_target ${PROJECT_NAME})
add_executable(${exec_target} ${src_files})
-target_link_libraries(${exec_target} ${QT_LIBRARIES})
+
+if(MITK_USE_Qt4)
+ target_link_libraries(${exec_target} ${QT_LIBRARIES})
+else()
+ target_link_libraries(${exec_target} Qt5::Network)
+endif()
if(NOT standalone_build)
# subproject support
add_dependencies(MITK-CoreUI ${exec_target})
endif()
#-----------------------------------------------------------------------------
# Win32 Convenience
#-----------------------------------------------------------------------------
if(WIN32 AND NOT standalone_build)
file(TO_NATIVE_PATH "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}" native_runtime_dir)
add_custom_target(NewPlugin start "MITK PluginGenerator" /D "${native_runtime_dir}" cmd /K ${exec_target}.exe -h
DEPENDS ${exec_target})
endif()
#-----------------------------------------------------------------------------
# Testing
#-----------------------------------------------------------------------------
if(NOT standalone_build)
# Test the plugin generator
include(mitkTestPluginGenerator)
endif()
#-----------------------------------------------------------------------------
# Packaging support
#-----------------------------------------------------------------------------
if(standalone_build)
include(SetupPackaging.cmake)
endif()
diff --git a/Applications/PluginGenerator/PluginTemplate/src/internal/mitkPluginActivator.cpp b/Applications/PluginGenerator/PluginTemplate/src/internal/mitkPluginActivator.cpp
index 359d7be966..3cb1b61642 100644
--- a/Applications/PluginGenerator/PluginTemplate/src/internal/mitkPluginActivator.cpp
+++ b/Applications/PluginGenerator/PluginTemplate/src/internal/mitkPluginActivator.cpp
@@ -1,23 +1,25 @@
$(license)
#include "$(activator-file-name).h"
#include <QtPlugin>
#include "$(view-file-name).h"
namespace mitk {
void $(activator-class-name)::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS($(view-class-name), context)
}
void $(activator-class-name)::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2($(plugin-target), mitk::$(activator-class-name))
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2($(plugin-target), mitk::$(activator-class-name))
+#endif
diff --git a/Applications/PluginGenerator/PluginTemplate/src/internal/mitkPluginActivator.h b/Applications/PluginGenerator/PluginTemplate/src/internal/mitkPluginActivator.h
index 2c672945eb..589d471ae3 100644
--- a/Applications/PluginGenerator/PluginTemplate/src/internal/mitkPluginActivator.h
+++ b/Applications/PluginGenerator/PluginTemplate/src/internal/mitkPluginActivator.h
@@ -1,25 +1,28 @@
$(license)
#ifndef $(activator-file-name)_h
#define $(activator-file-name)_h
#include <ctkPluginActivator.h>
namespace mitk {
class $(activator-class-name) :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "$(plugin-target)")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
}; // $(activator-class-name)
}
#endif // $(activator-file-name)_h
diff --git a/Applications/PluginGenerator/ProjectTemplate/CMakeExternals/MITK.cmake b/Applications/PluginGenerator/ProjectTemplate/CMakeExternals/MITK.cmake
index 960505af33..c0cacdae5e 100644
--- a/Applications/PluginGenerator/ProjectTemplate/CMakeExternals/MITK.cmake
+++ b/Applications/PluginGenerator/ProjectTemplate/CMakeExternals/MITK.cmake
@@ -1,217 +1,217 @@
#-----------------------------------------------------------------------------
# MITK
#-----------------------------------------------------------------------------
set(MITK_DEPENDS)
set(proj_DEPENDENCIES)
set(proj MITK)
if(NOT MITK_DIR)
#-----------------------------------------------------------------------------
# Create CMake options to customize the MITK build
#-----------------------------------------------------------------------------
option(MITK_USE_SUPERBUILD "Use superbuild for MITK" ON)
option(MITK_USE_BLUEBERRY "Build the BlueBerry platform in MITK" ON)
option(MITK_BUILD_EXAMPLES "Build the MITK examples" OFF)
option(MITK_BUILD_ALL_PLUGINS "Build all MITK plugins" OFF)
option(MITK_BUILD_TESTING "Build the MITK unit tests" OFF)
option(MITK_USE_ACVD "Use Approximated Centroidal Voronoi Diagrams" OFF)
option(MITK_USE_CTK "Use CTK in MITK" ${MITK_USE_BLUEBERRY})
option(MITK_USE_DCMTK "Use DCMTK in MITK" ON)
option(MITK_USE_QT "Use Nokia's Qt library in MITK" ON)
option(MITK_USE_Boost "Use the Boost library in MITK" OFF)
option(MITK_USE_OpenCV "Use Intel's OpenCV library" OFF)
option(MITK_USE_SOFA "Use Simulation Open Framework Architecture" OFF)
option(MITK_USE_Python "Enable Python wrapping in MITK" OFF)
if(MITK_USE_BLUEBERRY AND 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()
if(MITK_USE_CTK AND NOT MITK_USE_QT)
message("Forcing MITK_USE_QT to ON because of MITK_USE_CTK")
set(MITK_USE_QT ON CACHE BOOL "Use Nokia's Qt library in MITK" FORCE)
endif()
set(MITK_USE_CableSwig ${MITK_USE_Python})
set(MITK_USE_GDCM 1)
set(MITK_USE_ITK 1)
set(MITK_USE_VTK 1)
mark_as_advanced(MITK_USE_SUPERBUILD
MITK_BUILD_ALL_PLUGINS
MITK_BUILD_TESTING
)
set(mitk_cmake_boolean_args
MITK_USE_SUPERBUILD
MITK_USE_BLUEBERRY
MITK_BUILD_EXAMPLES
MITK_BUILD_ALL_PLUGINS
MITK_USE_ACVD
MITK_USE_CTK
MITK_USE_DCMTK
MITK_USE_QT
MITK_USE_Boost
MITK_USE_OpenCV
MITK_USE_SOFA
MITK_USE_Python
)
if(MITK_USE_QT)
# Look for Qt at the superbuild level, to catch missing Qt libs early
find_package(Qt4 4.7 REQUIRED)
endif()
set(additional_mitk_cmakevars )
# Configure the set of default 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")
set(MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES
"double, float"
CACHE STRING "List of floating pixel types used in AccessByItk and InstantiateAccessFunction macros")
set(MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES
""
CACHE STRING "List of composite pixel types used in AccessByItk and InstantiateAccessFunction macros")
set(MITK_ACCESSBYITK_DIMENSIONS
"2,3"
CACHE STRING "List of dimensions used in AccessByItk and InstantiateAccessFunction macros")
foreach(_arg MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES
MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES MITK_ACCESSBYITK_DIMENSIONS)
mark_as_advanced(${_arg})
list(APPEND additional_mitk_cmakevars "-D${_arg}:STRING=${${_arg}}")
endforeach()
#-----------------------------------------------------------------------------
# Create options to inject pre-build dependencies
#-----------------------------------------------------------------------------
foreach(proj CTK DCMTK GDCM VTK ACVD ITK OpenCV SOFA CableSwig)
if(MITK_USE_${proj})
set(MITK_${proj}_DIR "${${proj}_DIR}" CACHE PATH "Path to ${proj} build directory")
mark_as_advanced(MITK_${proj}_DIR)
if(MITK_${proj}_DIR)
list(APPEND additional_mitk_cmakevars "-D${proj}_DIR:PATH=${MITK_${proj}_DIR}")
endif()
endif()
endforeach()
if(MITK_USE_Boost)
set(MITK_BOOST_ROOT "${BOOST_ROOT}" CACHE PATH "Path to Boost directory")
mark_as_advanced(MITK_BOOST_ROOT)
if(MITK_BOOST_ROOT)
list(APPEND additional_mitk_cmakevars "-DBOOST_ROOT:PATH=${MITK_BOOST_ROOT}")
endif()
endif()
set(MITK_SOURCE_DIR "" CACHE PATH "MITK source code location. If empty, MITK will be cloned from MITK_GIT_REPOSITORY")
set(MITK_GIT_REPOSITORY "http://git.mitk.org/MITK.git" CACHE STRING "The git repository for cloning MITK")
- set(MITK_GIT_TAG "releases/2014-03" CACHE STRING "The git tag/hash to be used when cloning from MITK_GIT_REPOSITORY")
+ set(MITK_GIT_TAG "releases/master" CACHE STRING "The git tag/hash to be used when cloning from MITK_GIT_REPOSITORY")
mark_as_advanced(MITK_SOURCE_DIR MITK_GIT_REPOSITORY MITK_GIT_TAG)
#-----------------------------------------------------------------------------
# Create the final variable containing superbuild boolean args
#-----------------------------------------------------------------------------
set(mitk_boolean_args)
foreach(mitk_cmake_arg ${mitk_cmake_boolean_args})
list(APPEND mitk_boolean_args -D${mitk_cmake_arg}:BOOL=${${mitk_cmake_arg}})
endforeach()
#-----------------------------------------------------------------------------
# Additional MITK CMake variables
#-----------------------------------------------------------------------------
if(MITK_USE_QT AND QT_QMAKE_EXECUTABLE)
list(APPEND additional_mitk_cmakevars "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}")
endif()
if(MITK_USE_CTK)
list(APPEND additional_mitk_cmakevars "-DGIT_EXECUTABLE:FILEPATH=${GIT_EXECUTABLE}")
endif()
if(MITK_INITIAL_CACHE_FILE)
list(APPEND additional_mitk_cmakevars "-DMITK_INITIAL_CACHE_FILE:INTERNAL=${MITK_INITIAL_CACHE_FILE}")
endif()
if(MITK_USE_SUPERBUILD)
set(MITK_BINARY_DIR ${proj}-superbuild)
else()
set(MITK_BINARY_DIR ${proj}-build)
endif()
set(proj_DEPENDENCIES)
set(MITK_DEPENDS ${proj})
# Configure the MITK souce code location
if(NOT MITK_SOURCE_DIR)
set(mitk_source_location
SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}
GIT_REPOSITORY ${MITK_GIT_REPOSITORY}
GIT_TAG ${MITK_GIT_TAG}
)
else()
set(mitk_source_location
SOURCE_DIR ${MITK_SOURCE_DIR}
)
endif()
ExternalProject_Add(${proj}
${mitk_source_location}
BINARY_DIR ${MITK_BINARY_DIR}
PREFIX ${proj}${ep_suffix}
INSTALL_COMMAND ""
CMAKE_GENERATOR ${gen}
CMAKE_ARGS
${ep_common_args}
${mitk_boolean_args}
${additional_mitk_cmakevars}
-DBUILD_SHARED_LIBS:BOOL=ON
-DBUILD_TESTING:BOOL=${MITK_BUILD_TESTING}
DEPENDS
${proj_DEPENDENCIES}
)
if(MITK_USE_SUPERBUILD)
set(MITK_DIR "${CMAKE_CURRENT_BINARY_DIR}/${MITK_BINARY_DIR}/MITK-build")
else()
set(MITK_DIR "${CMAKE_CURRENT_BINARY_DIR}/${MITK_BINARY_DIR}")
endif()
else()
# The project is provided using MITK_DIR, nevertheless since other
# projects may depend on MITK, let's add an 'empty' one
MacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}")
# Further, do some sanity checks in the case of a pre-built MITK
set(my_itk_dir ${ITK_DIR})
set(my_vtk_dir ${VTK_DIR})
set(my_qmake_executable ${QT_QMAKE_EXECUTABLE})
find_package(MITK REQUIRED)
if(my_itk_dir AND NOT my_itk_dir STREQUAL ${ITK_DIR})
message(FATAL_ERROR "ITK packages do not match:\n ${MY_PROJECT_NAME}: ${my_itk_dir}\n MITK: ${ITK_DIR}")
endif()
if(my_vtk_dir AND NOT my_vtk_dir STREQUAL ${VTK_DIR})
message(FATAL_ERROR "VTK packages do not match:\n ${MY_PROJECT_NAME}: ${my_vtk_dir}\n MITK: ${VTK_DIR}")
endif()
if(my_qmake_executable AND NOT my_qmake_executable STREQUAL ${MITK_QMAKE_EXECUTABLE})
message(FATAL_ERROR "Qt qmake does not match:\n ${MY_PROJECT_NAME}: ${my_qmake_executable}\n MITK: ${MITK_QMAKE_EXECUTABLE}")
endif()
endif()
diff --git a/Applications/PluginGenerator/ProjectTemplate/CMakeLists.txt b/Applications/PluginGenerator/ProjectTemplate/CMakeLists.txt
index dc3e8c7c1b..0e20c1e221 100644
--- a/Applications/PluginGenerator/ProjectTemplate/CMakeLists.txt
+++ b/Applications/PluginGenerator/ProjectTemplate/CMakeLists.txt
@@ -1,365 +1,367 @@
cmake_minimum_required(VERSION 2.8.8)
# Change project and application name to your own
set(MY_PROJECT_NAME $(project-name))
set(MY_APP_NAME $(project-app-name))
#-----------------------------------------------------------------------------
# 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(${MY_PROJECT_NAME}_USE_SUPERBUILD "Build ${MY_PROJECT_NAME} and the projects it depends on via SuperBuild.cmake." ON)
if(${MY_PROJECT_NAME}_USE_SUPERBUILD)
project(${MY_PROJECT_NAME}-superbuild)
set(${MY_PROJECT_NAME}_SOURCE_DIR ${PROJECT_SOURCE_DIR})
set(${MY_PROJECT_NAME}_BINARY_DIR ${PROJECT_BINARY_DIR})
else()
project(${MY_PROJECT_NAME})
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.
+ CMP0028 # NEW: Double colon in target name means ALIAS or IMPORTED target.
)
foreach(policy ${project_policies})
if(POLICY ${policy})
cmake_policy(SET ${policy} NEW)
endif()
endforeach()
#-----------------------------------------------------------------------------
# Update CMake module path
#------------------------------------------------------------------------------
set(CMAKE_MODULE_PATH
${${MY_PROJECT_NAME}_SOURCE_DIR}/CMake
${CMAKE_MODULE_PATH}
)
#-----------------------------------------------------------------------------
# CMake Function(s) and Macro(s)
#-----------------------------------------------------------------------------
include(MacroEmptyExternalProject)
#-----------------------------------------------------------------------------
# Output directories.
#-----------------------------------------------------------------------------
foreach(type LIBRARY RUNTIME ARCHIVE)
set(output_dir ${${MY_PROJECT_NAME}_BINARY_DIR}/bin)
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 Options (also shown during superbuild)
#-----------------------------------------------------------------------------
option(BUILD_SHARED_LIBS "Build ${MY_PROJECT_NAME} with shared libraries" ON)
option(WITH_COVERAGE "Enable/Disable coverage" OFF)
option(BUILD_TESTING "Test the project" ON)
option(${MY_PROJECT_NAME}_BUILD_ALL_PLUGINS "Build all ${MY_PROJECT_NAME} plugins" OFF)
mark_as_advanced(${MY_PROJECT_NAME}_INSTALL_RPATH_RELATIVE
${MY_PROJECT_NAME}_BUILD_ALL_PLUGINS
)
#-----------------------------------------------------------------------------
# Superbuild script
#-----------------------------------------------------------------------------
if(${MY_PROJECT_NAME}_USE_SUPERBUILD)
include("${CMAKE_CURRENT_SOURCE_DIR}/SuperBuild.cmake")
return()
endif()
#*****************************************************************************
#**************************** END OF SUPERBUILD ****************************
#*****************************************************************************
#-----------------------------------------------------------------------------
# Prerequesites
#-----------------------------------------------------------------------------
set(${PROJECT_NAME}_MODULES_PACKAGE_DEPENDS_DIR "${PROJECT_SOURCE_DIR}/CMake/PackageDepends")
set(MODULES_PACKAGE_DEPENDS_DIRS ${${PROJECT_NAME}_MODULES_PACKAGE_DEPENDS_DIR})
-find_package(MITK 2014.03.99 REQUIRED)
+find_package(MITK 2014.10.99 REQUIRED)
if(COMMAND mitkFunctionCheckMitkCompatibility)
mitkFunctionCheckMitkCompatibility(VERSIONS MITK_VERSION_PLUGIN_SYSTEM 1 REQUIRED)
else()
message(SEND_ERROR "Your MITK version is too old. Please use Git hash b86bf28 or newer")
endif()
link_directories(${MITK_LINK_DIRECTORIES})
#-----------------------------------------------------------------------------
# CMake Function(s) and Macro(s)
#-----------------------------------------------------------------------------
set(CMAKE_MODULE_PATH
${MITK_SOURCE_DIR}/CMake
${CMAKE_MODULE_PATH}
)
include(mitkFunctionCheckCompilerFlags)
include(mitkFunctionGetGccVersion)
include(mitkFunctionGetVersion)
#-----------------------------------------------------------------------------
# Set project specific options and variables (NOT available during superbuild)
#-----------------------------------------------------------------------------
set(${PROJECT_NAME}_VERSION_MAJOR "0")
set(${PROJECT_NAME}_VERSION_MINOR "1")
set(${PROJECT_NAME}_VERSION_PATCH "1")
set(${PROJECT_NAME}_VERSION_STRING "${${PROJECT_NAME}_VERSION_MAJOR}.${${PROJECT_NAME}_VERSION_MINOR}.${${PROJECT_NAME}_VERSION_PATCH}")
# Ask the user if a console window should be shown with the applications
option(${PROJECT_NAME}_SHOW_CONSOLE_WINDOW "Use this to enable or disable the console window when starting GUI Applications" ON)
mark_as_advanced(${PROJECT_NAME}_SHOW_CONSOLE_WINDOW)
if(NOT UNIX AND NOT MINGW)
set(MITK_WIN32_FORCE_STATIC "STATIC")
endif()
#-----------------------------------------------------------------------------
# Get project version info
#-----------------------------------------------------------------------------
mitkFunctionGetVersion(${PROJECT_SOURCE_DIR} ${PROJECT_NAME})
#-----------------------------------------------------------------------------
# Installation preparation
#
# These should be set before any MITK install macros are used
#-----------------------------------------------------------------------------
# on Mac OSX all CTK plugins get copied into every
# application bundle (.app directory) specified here
set(MACOSX_BUNDLE_NAMES)
if(APPLE)
list(APPEND MACOSX_BUNDLE_NAMES ${MY_APP_NAME})
endif(APPLE)
#-----------------------------------------------------------------------------
# Set symbol visibility Flags
#-----------------------------------------------------------------------------
# MinGW does not export all symbols automatically, so no need to set flags
if(CMAKE_COMPILER_IS_GNUCXX AND NOT MINGW)
# The MITK module build system does not yet support default hidden visibility
set(VISIBILITY_CXX_FLAGS ) # "-fvisibility=hidden -fvisibility-inlines-hidden")
endif()
#-----------------------------------------------------------------------------
# Set coverage Flags
#-----------------------------------------------------------------------------
if(WITH_COVERAGE)
if(CMAKE_COMPILER_IS_GNUCXX)
set(coverage_flags "-g -fprofile-arcs -ftest-coverage -O0 -DNDEBUG")
set(COVERAGE_CXX_FLAGS ${coverage_flags})
set(COVERAGE_C_FLAGS ${coverage_flags})
endif()
endif()
#-----------------------------------------------------------------------------
# Project C/CXX Flags
#-----------------------------------------------------------------------------
set(${PROJECT_NAME}_C_FLAGS "${MITK_C_FLAGS} ${COVERAGE_C_FLAGS}")
set(${PROJECT_NAME}_C_FLAGS_DEBUG ${MITK_C_FLAGS_DEBUG})
set(${PROJECT_NAME}_C_FLAGS_RELEASE ${MITK_C_FLAGS_RELEASE})
set(${PROJECT_NAME}_CXX_FLAGS "${MITK_CXX_FLAGS} ${VISIBILITY_CXX_FLAGS} ${COVERAGE_CXX_FLAGS}")
set(${PROJECT_NAME}_CXX_FLAGS_DEBUG ${MITK_CXX_FLAGS_DEBUG})
set(${PROJECT_NAME}_CXX_FLAGS_RELEASE ${MITK_CXX_FLAGS_RELEASE})
set(${PROJECT_NAME}_EXE_LINKER_FLAGS ${MITK_EXE_LINKER_FLAGS})
set(${PROJECT_NAME}_SHARED_LINKER_FLAGS ${MITK_SHARED_LINKER_FLAGS})
set(${PROJECT_NAME}_MODULE_LINKER_FLAGS ${MITK_MODULE_LINKER_FLAGS})
#-----------------------------------------------------------------------------
# Set C/CXX Flags
#-----------------------------------------------------------------------------
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${${PROJECT_NAME}_C_FLAGS}")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${${PROJECT_NAME}_C_FLAGS_DEBUG}")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${${PROJECT_NAME}_C_FLAGS_RELEASE}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${${PROJECT_NAME}_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${${PROJECT_NAME}_CXX_FLAGS_DEBUG}")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${${PROJECT_NAME}_CXX_FLAGS_RELEASE}")
set(CMAKE_EXE_LINKER_FLAGS ${${PROJECT_NAME}_EXE_LINKER_FLAGS})
set(CMAKE_SHARED_LINKER_FLAGS ${${PROJECT_NAME}_SHARED_LINKER_FLAGS})
set(CMAKE_MODULE_LINKER_FLAGS ${${PROJECT_NAME}_MODULE_LINKER_FLAGS})
#-----------------------------------------------------------------------------
# Testing
#-----------------------------------------------------------------------------
if(BUILD_TESTING)
enable_testing()
include(CTest)
mark_as_advanced(TCL_TCLSH DART_ROOT)
# Setup file for setting custom ctest vars
configure_file(
CMake/CTestCustom.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/CTestCustom.cmake
@ONLY
)
# Configuration for the CMake-generated test driver
set(CMAKE_TESTDRIVER_EXTRA_INCLUDES "#include <stdexcept>")
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;
}
")
endif()
#-----------------------------------------------------------------------------
# ${MY_PROJECT_NAME}_SUPERBUILD_BINARY_DIR
#-----------------------------------------------------------------------------
# If ${MY_PROJECT_NAME}_SUPERBUILD_BINARY_DIR isn't defined, it means this project is
# *NOT* build using Superbuild. In that specific case, ${MY_PROJECT_NAME}_SUPERBUILD_BINARY_DIR
# should default to PROJECT_BINARY_DIR
if(NOT DEFINED ${PROJECT_NAME}_SUPERBUILD_BINARY_DIR)
set(${PROJECT_NAME}_SUPERBUILD_BINARY_DIR ${PROJECT_BINARY_DIR})
endif()
#-----------------------------------------------------------------------------
# Qt support
#-----------------------------------------------------------------------------
if(MITK_USE_QT)
set(QT_QMAKE_EXECUTABLE ${MITK_QMAKE_EXECUTABLE})
endif()
#-----------------------------------------------------------------------------
# MITK modules
#-----------------------------------------------------------------------------
# This project's directory holding module config files
#set(${PROJECT_NAME}_MODULES_CONF_DIR "${PROJECT_BINARY_DIR}/${MODULES_CONF_DIRNAME}")
# Append this projects's module config directory to the global list
# (This is used to get include directories for the <module_name>Exports.h files right)
#list(APPEND MODULES_CONF_DIRS ${${PROJECT_NAME}_MODULES_CONF_DIR})
# Clean the modulesConf directory. This ensures that modules are sorted
# according to their dependencies in the Modules/CMakeLists.txt file
#file(GLOB _modules_conf_files ${${PROJECT_NAME}_MODULES_CONF_DIR}/*.cmake)
#if(_modules_conf_files)
# file(REMOVE ${_modules_conf_files})
#endif()
#add_subdirectory(Modules)
#-----------------------------------------------------------------------------
# CTK plugins
#-----------------------------------------------------------------------------
# The CMake code in this section *must* be in the top-level CMakeLists.txt file
macro(GetMyTargetLibraries all_target_libraries varname)
set(re_ctkplugin "^$(project-plugin-base)_[a-zA-Z0-9_]+$")
set(_tmp_list)
list(APPEND _tmp_list ${all_target_libraries})
ctkMacroListFilter(_tmp_list re_ctkplugin OUTPUT_VARIABLE ${varname})
endmacro()
include(${CMAKE_CURRENT_SOURCE_DIR}/Plugins/Plugins.cmake)
ctkMacroSetupPlugins(${PROJECT_PLUGINS}
BUILD_OPTION_PREFIX ${MY_PROJECT_NAME}_
BUILD_ALL ${${MY_PROJECT_NAME}_BUILD_ALL_PLUGINS})
#-----------------------------------------------------------------------------
# Add subdirectories
#-----------------------------------------------------------------------------
add_subdirectory(Apps/$(project-app-name))
#-----------------------------------------------------------------------------
# Installation
#-----------------------------------------------------------------------------
# set MITK cpack variables
include(mitkSetupCPack)
# Customize CPack variables for this project
include(CPackSetup)
list(APPEND CPACK_CREATE_DESKTOP_LINKS "${MY_APP_NAME}")
configure_file(${MITK_SOURCE_DIR}/MITKCPackOptions.cmake.in
${PROJECT_BINARY_DIR}/${PROJECT_NAME}CPackOptions.cmake @ONLY)
set(CPACK_PROJECT_CONFIG_FILE "${PROJECT_BINARY_DIR}/${PROJECT_NAME}CPackOptions.cmake")
# include CPack model once all variables are set
include(CPack)
# Additional installation rules
include(mitkInstallRules)
#-----------------------------------------------------------------------------
# Last configuration steps
#-----------------------------------------------------------------------------
# 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("${PROJECT_SOURCE_DIR}/CMake/StartVS.bat.in"
${PROJECT_BINARY_DIR}/StartVS_${VS_BUILD_TYPE}.bat
${VS_BUILD_TYPE})
endforeach()
endif(WIN32)
diff --git a/Applications/Workbench/MitkWorkbench.cpp b/Applications/Workbench/MitkWorkbench.cpp
index 9bee617438..6f22216146 100644
--- a/Applications/Workbench/MitkWorkbench.cpp
+++ b/Applications/Workbench/MitkWorkbench.cpp
@@ -1,215 +1,219 @@
/*===================================================================
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 <application/berryStarter.h>
#include <Poco/Util/MapConfiguration.h>
#include <QApplication>
#include <QMessageBox>
#include <QtSingleApplication>
#include <QtGlobal>
#include <QTime>
#include <QDir>
#include <QDesktopServices>
#include <QStringList>
#include <usModuleSettings.h>
#include <mitkCommon.h>
#include <mitkException.h>
class QtSafeApplication : public QtSingleApplication
{
public:
QtSafeApplication(int& argc, char** argv) : QtSingleApplication(argc, argv)
{}
/**
* Reimplement notify to catch unhandled exceptions and open an error message.
*
* @param receiver
* @param event
* @return
*/
bool notify(QObject* receiver, QEvent* event)
{
QString msg;
try
{
return QApplication::notify(receiver, event);
}
catch (mitk::Exception& e)
{
msg = QString("MITK Exception:\n\n")
+ QString("Description: ")
+ QString(e.GetDescription()) + QString("\n\n")
+ QString("Filename: ") + QString(e.GetFile()) + QString("\n\n")
+ QString("Line: ") + QString::number(e.GetLine());
}
catch (Poco::Exception& e)
{
msg = QString::fromStdString(e.displayText());
}
catch (std::exception& e)
{
msg = e.what();
}
catch (...)
{
msg = "Unknown exception";
}
MITK_ERROR << "An error occurred: " << msg.toStdString();
QMessageBox msgBox;
msgBox.setText("An error occurred. You should save all data and quit the program to prevent possible data loss.");
msgBox.setDetailedText(msg);
msgBox.setIcon(QMessageBox::Critical);
msgBox.addButton(trUtf8("Exit immediately"), QMessageBox::YesRole);
msgBox.addButton(trUtf8("Ignore"), QMessageBox::NoRole);
int ret = msgBox.exec();
switch(ret)
{
case 0:
MITK_ERROR << "The program was closed.";
this->closeAllWindows();
break;
case 1:
MITK_ERROR << "The error was ignored by the user. The program may be in a corrupt state and don't behave like expected!";
break;
}
return false;
}
};
int main(int argc, char** argv)
{
// Create a QApplication instance first
QtSafeApplication qSafeApp(argc, argv);
qSafeApp.setApplicationName("MITK Workbench");
qSafeApp.setOrganizationName("DKFZ");
// This function checks if an instance is already running
// and either sends a message to it (containing the command
// line arguments) or checks if a new instance was forced by
// providing the BlueBerry.newInstance command line argument.
// In the latter case, a path to a temporary directory for
// the new application's storage directory is returned.
QString storageDir = handleNewAppInstance(&qSafeApp, argc, argv, "BlueBerry.newInstance");
if (storageDir.isEmpty())
{
// This is a new instance and no other instance is already running. We specify
// the storage directory here (this is the same code as in berryInternalPlatform.cpp
// so that we can re-use the location for the persistent data location of the
// the CppMicroServices library.
// Append a hash value of the absolute path of the executable to the data location.
// This allows to start the same application from different build or install trees.
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ storageDir = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + '_';
+#else
storageDir = QDesktopServices::storageLocation(QDesktopServices::DataLocation) + '_';
+#endif
storageDir += QString::number(qHash(QCoreApplication::applicationDirPath())) + QDir::separator();
}
us::ModuleSettings::SetStoragePath((storageDir + QString("us") + QDir::separator()).toStdString());
// These paths replace the .ini file and are tailored for installation
// packages created with CPack. If a .ini file is presented, it will
// overwrite the settings in MapConfiguration
Poco::Path basePath(argv[0]);
basePath.setFileName("");
Poco::Path provFile(basePath);
provFile.setFileName("MitkWorkbench.provisioning");
Poco::Path extPath(basePath);
extPath.pushDirectory("ExtBundles");
std::string pluginDirs = extPath.toString();
Poco::Util::MapConfiguration* extConfig(new Poco::Util::MapConfiguration());
if (!storageDir.isEmpty())
{
extConfig->setString(berry::Platform::ARG_STORAGE_DIR, storageDir.toStdString());
}
extConfig->setString(berry::Platform::ARG_PLUGIN_DIRS, pluginDirs);
extConfig->setString(berry::Platform::ARG_PROVISIONING, provFile.toString());
extConfig->setString(berry::Platform::ARG_APPLICATION, "org.mitk.qt.extapplication");
QStringList preloadLibs;
// Preload the org.mitk.gui.qt.ext plug-in (and hence also QmitkExt) to speed
// up a clean-cache start. This also works around bugs in older gcc and glibc implementations,
// which have difficulties with multiple dynamic opening and closing of shared libraries with
// many global static initializers. It also helps if dependent libraries have weird static
// initialization methods and/or missing de-initialization code.
preloadLibs << "liborg_mitk_gui_qt_ext";
QMap<QString, QString> preloadLibVersion;
#ifdef Q_OS_MAC
const QString libSuffix = ".dylib";
#elif defined(Q_OS_UNIX)
const QString libSuffix = ".so";
#elif defined(Q_OS_WIN)
const QString libSuffix = ".dll";
#else
const QString libSuffix;
#endif
for (QStringList::Iterator preloadLibIter = preloadLibs.begin(),
iterEnd = preloadLibs.end(); preloadLibIter != iterEnd; ++preloadLibIter)
{
QString& preloadLib = *preloadLibIter;
// In case the application is started from an install directory
QString tempLibraryPath = QCoreApplication::applicationDirPath() + "/plugins/" + preloadLib + libSuffix;
QFile preloadLibrary (tempLibraryPath);
#ifdef Q_OS_MAC
if (!preloadLibrary.exists())
{
// In case the application is started from a build tree
QString relPath = "/../../../plugins/" + preloadLib + libSuffix;
tempLibraryPath = QCoreApplication::applicationDirPath() + relPath;
preloadLibrary.setFileName(tempLibraryPath);
}
#endif
if(preloadLibrary.exists())
{
preloadLib = tempLibraryPath;
}
// Else fall back to the QLibrary search logic
}
QString preloadConfig;
Q_FOREACH(const QString& preloadLib, preloadLibs)
{
preloadConfig += preloadLib + preloadLibVersion[preloadLib] + ",";
}
preloadConfig.chop(1);
extConfig->setString(berry::Platform::ARG_PRELOAD_LIBRARY, preloadConfig.toStdString());
// Seed the random number generator, once at startup.
QTime time = QTime::currentTime();
qsrand((uint)time.msec());
// Run the workbench.
return berry::Starter::Run(argc, argv, extConfig);
}
diff --git a/BlueBerry/Bundles/org.blueberry.compat/berryPluginActivator.cpp b/BlueBerry/Bundles/org.blueberry.compat/berryPluginActivator.cpp
index 2dbbcf72f6..c80399145b 100644
--- a/BlueBerry/Bundles/org.blueberry.compat/berryPluginActivator.cpp
+++ b/BlueBerry/Bundles/org.blueberry.compat/berryPluginActivator.cpp
@@ -1,70 +1,70 @@
/*===================================================================
BlueBerry Platform
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 "berryPluginActivator_p.h"
#include "berryCTKPluginListener_p.h"
#include <berryIExtensionPointService.h>
#include <QtPlugin>
namespace berry {
org_blueberry_compat_Activator::org_blueberry_compat_Activator()
: pluginListener(0)
{
}
org_blueberry_compat_Activator::~org_blueberry_compat_Activator()
{
delete pluginListener;
}
void org_blueberry_compat_Activator::start(ctkPluginContext* context)
{
ctkServiceReference xpRef = context->getServiceReference<IExtensionPointService>();
Q_ASSERT(xpRef);
IExtensionPointService::Pointer xpService(context->getService<IExtensionPointService>(xpRef));
Q_ASSERT(xpService);
delete pluginListener;
// register a listener to catch new plugin installations/resolutions.
pluginListener = new CTKPluginListener(xpService);
context->connectPluginListener(pluginListener, SLOT(pluginChanged(ctkPluginEvent)), Qt::DirectConnection);
// populate the registry with all the currently installed plugins.
// There is a small window here while processPlugins is being
// called where the pluginListener may receive a ctkPluginEvent
// to add/remove a plugin from the registry. This is ok since
// the registry is a synchronized object and will not add the
// same bundle twice.
pluginListener->processPlugins(context->getPlugins());
}
void org_blueberry_compat_Activator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_blueberry_compat, berry::org_blueberry_compat_Activator)
-
-
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_blueberry_compat, berry::org_blueberry_compat_Activator)
+#endif
diff --git a/BlueBerry/Bundles/org.blueberry.compat/berryPluginActivator_p.h b/BlueBerry/Bundles/org.blueberry.compat/berryPluginActivator_p.h
index 9ace285ab1..c0cbcc86bc 100644
--- a/BlueBerry/Bundles/org.blueberry.compat/berryPluginActivator_p.h
+++ b/BlueBerry/Bundles/org.blueberry.compat/berryPluginActivator_p.h
@@ -1,51 +1,54 @@
/*===================================================================
BlueBerry Platform
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 BERRYCOMPATIBILITYACTIVATOR_P_H
#define BERRYCOMPATIBILITYACTIVATOR_P_H
#include <ctkPluginActivator.h>
namespace berry {
class CTKPluginListener;
class org_blueberry_compat_Activator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_blueberry_compat")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
org_blueberry_compat_Activator();
~org_blueberry_compat_Activator();
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
private:
CTKPluginListener* pluginListener;
}; // org_blueberry_compat_Activator
typedef org_blueberry_compat_Activator PluginActivator;
}
#endif // BERRYCOMPATIBILITYACTIVATOR_P_H
diff --git a/BlueBerry/Bundles/org.blueberry.core.commands/src/internal/berryPluginActivator.cpp b/BlueBerry/Bundles/org.blueberry.core.commands/src/internal/berryPluginActivator.cpp
index 0f96034921..96d36e2dfb 100644
--- a/BlueBerry/Bundles/org.blueberry.core.commands/src/internal/berryPluginActivator.cpp
+++ b/BlueBerry/Bundles/org.blueberry.core.commands/src/internal/berryPluginActivator.cpp
@@ -1,40 +1,42 @@
/*===================================================================
BlueBerry Platform
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 "berryPluginActivator.h"
#include <QtPlugin>
namespace berry {
org_blueberry_core_commands_Activator::org_blueberry_core_commands_Activator()
{
}
void org_blueberry_core_commands_Activator::start(ctkPluginContext* context)
{
Q_UNUSED(context)
}
void org_blueberry_core_commands_Activator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_blueberry_core_commands, berry::org_blueberry_core_commands_Activator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_blueberry_core_commands, berry::org_blueberry_core_commands_Activator)
+#endif
diff --git a/BlueBerry/Bundles/org.blueberry.core.commands/src/internal/berryPluginActivator.h b/BlueBerry/Bundles/org.blueberry.core.commands/src/internal/berryPluginActivator.h
index 5eab31b1ee..4ef296411d 100644
--- a/BlueBerry/Bundles/org.blueberry.core.commands/src/internal/berryPluginActivator.h
+++ b/BlueBerry/Bundles/org.blueberry.core.commands/src/internal/berryPluginActivator.h
@@ -1,42 +1,45 @@
/*===================================================================
BlueBerry Platform
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 BERRYPLUGINACTIVATOR_H
#define BERRYPLUGINACTIVATOR_H
#include <ctkPluginActivator.h>
namespace berry {
class org_blueberry_core_commands_Activator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_blueberry_core_commands")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
org_blueberry_core_commands_Activator();
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
};
typedef org_blueberry_core_commands_Activator PluginActivator;
}
#endif // BERRYPLUGINACTIVATOR_H
diff --git a/BlueBerry/Bundles/org.blueberry.core.expressions/src/internal/berryPluginActivator.cpp b/BlueBerry/Bundles/org.blueberry.core.expressions/src/internal/berryPluginActivator.cpp
index d6926b50cc..8200b5023a 100644
--- a/BlueBerry/Bundles/org.blueberry.core.expressions/src/internal/berryPluginActivator.cpp
+++ b/BlueBerry/Bundles/org.blueberry.core.expressions/src/internal/berryPluginActivator.cpp
@@ -1,40 +1,42 @@
/*===================================================================
BlueBerry Platform
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 "berryPluginActivator.h"
#include <QtPlugin>
namespace berry {
org_blueberry_core_expressions_Activator::org_blueberry_core_expressions_Activator()
{
}
void org_blueberry_core_expressions_Activator::start(ctkPluginContext* context)
{
Q_UNUSED(context)
}
void org_blueberry_core_expressions_Activator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_blueberry_core_expressions, berry::org_blueberry_core_expressions_Activator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_blueberry_core_expressions, berry::org_blueberry_core_expressions_Activator)
+#endif
diff --git a/BlueBerry/Bundles/org.blueberry.core.expressions/src/internal/berryPluginActivator.h b/BlueBerry/Bundles/org.blueberry.core.expressions/src/internal/berryPluginActivator.h
index 6c31455fe5..666e66f040 100644
--- a/BlueBerry/Bundles/org.blueberry.core.expressions/src/internal/berryPluginActivator.h
+++ b/BlueBerry/Bundles/org.blueberry.core.expressions/src/internal/berryPluginActivator.h
@@ -1,42 +1,45 @@
/*===================================================================
BlueBerry Platform
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 BERRYPLUGINACTIVATOR_H
#define BERRYPLUGINACTIVATOR_H
#include <ctkPluginActivator.h>
namespace berry {
class org_blueberry_core_expressions_Activator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_blueberry_core_expressions")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
org_blueberry_core_expressions_Activator();
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
};
typedef org_blueberry_core_expressions_Activator PluginActivator;
}
#endif // BERRYPLUGINACTIVATOR_H
diff --git a/BlueBerry/Bundles/org.blueberry.core.jobs/src/internal/berryPluginActivator.cpp b/BlueBerry/Bundles/org.blueberry.core.jobs/src/internal/berryPluginActivator.cpp
index e56387a238..d731d79046 100644
--- a/BlueBerry/Bundles/org.blueberry.core.jobs/src/internal/berryPluginActivator.cpp
+++ b/BlueBerry/Bundles/org.blueberry.core.jobs/src/internal/berryPluginActivator.cpp
@@ -1,40 +1,42 @@
/*===================================================================
BlueBerry Platform
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 "berryPluginActivator.h"
#include <QtPlugin>
namespace berry {
org_blueberry_core_jobs_Activator::org_blueberry_core_jobs_Activator()
{
}
void org_blueberry_core_jobs_Activator::start(ctkPluginContext* context)
{
Q_UNUSED(context)
}
void org_blueberry_core_jobs_Activator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_blueberry_core_jobs, berry::org_blueberry_core_jobs_Activator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_blueberry_core_jobs, berry::org_blueberry_core_jobs_Activator)
+#endif
diff --git a/BlueBerry/Bundles/org.blueberry.core.jobs/src/internal/berryPluginActivator.h b/BlueBerry/Bundles/org.blueberry.core.jobs/src/internal/berryPluginActivator.h
index 160fea1318..7cbaf0af92 100644
--- a/BlueBerry/Bundles/org.blueberry.core.jobs/src/internal/berryPluginActivator.h
+++ b/BlueBerry/Bundles/org.blueberry.core.jobs/src/internal/berryPluginActivator.h
@@ -1,42 +1,45 @@
/*===================================================================
BlueBerry Platform
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 BERRYPLUGINACTIVATOR_H
#define BERRYPLUGINACTIVATOR_H
#include <ctkPluginActivator.h>
namespace berry {
class org_blueberry_core_jobs_Activator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_blueberry_core_jobs")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
org_blueberry_core_jobs_Activator();
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
};
typedef org_blueberry_core_jobs_Activator PluginActivator;
}
#endif // BERRYPLUGINACTIVATOR_H
diff --git a/BlueBerry/Bundles/org.blueberry.core.runtime/src/internal/berryPluginActivator.cpp b/BlueBerry/Bundles/org.blueberry.core.runtime/src/internal/berryPluginActivator.cpp
index ddb71e1657..fb819bb921 100644
--- a/BlueBerry/Bundles/org.blueberry.core.runtime/src/internal/berryPluginActivator.cpp
+++ b/BlueBerry/Bundles/org.blueberry.core.runtime/src/internal/berryPluginActivator.cpp
@@ -1,44 +1,46 @@
/*===================================================================
BlueBerry Platform
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 "berryPluginActivator.h"
#include <QtPlugin>
namespace berry {
org_blueberry_core_runtime_Activator::org_blueberry_core_runtime_Activator()
{
}
void org_blueberry_core_runtime_Activator::start(ctkPluginContext* context)
{
m_PreferencesService = new PreferencesService(context->getDataFile("").absolutePath().toStdString());
m_PrefServiceReg = context->registerService<IPreferencesService>(m_PreferencesService.GetPointer());
}
void org_blueberry_core_runtime_Activator::stop(ctkPluginContext* context)
{
m_PrefServiceReg.unregister();
m_PreferencesService->ShutDown();
m_PreferencesService = 0;
m_PrefServiceReg = 0;
}
}
-Q_EXPORT_PLUGIN2(org_blueberry_core_runtime, berry::org_blueberry_core_runtime_Activator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_blueberry_core_runtime, berry::org_blueberry_core_runtime_Activator)
+#endif
diff --git a/BlueBerry/Bundles/org.blueberry.core.runtime/src/internal/berryPluginActivator.h b/BlueBerry/Bundles/org.blueberry.core.runtime/src/internal/berryPluginActivator.h
index 44bb23387a..8b15124263 100644
--- a/BlueBerry/Bundles/org.blueberry.core.runtime/src/internal/berryPluginActivator.h
+++ b/BlueBerry/Bundles/org.blueberry.core.runtime/src/internal/berryPluginActivator.h
@@ -1,50 +1,53 @@
/*===================================================================
BlueBerry Platform
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 BERRYPLUGINACTIVATOR_H
#define BERRYPLUGINACTIVATOR_H
#include <ctkPluginActivator.h>
#include <ctkServiceRegistration.h>
#include "berryPreferencesService.h"
namespace berry {
class org_blueberry_core_runtime_Activator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_blueberry_core_runtime")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
org_blueberry_core_runtime_Activator();
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
private:
PreferencesService::Pointer m_PreferencesService;
ctkServiceRegistration m_PrefServiceReg;
};
typedef org_blueberry_core_runtime_Activator PluginActivator;
}
#endif // BERRYPLUGINACTIVATOR_H
diff --git a/BlueBerry/Bundles/org.blueberry.osgi/CMakeLists.txt b/BlueBerry/Bundles/org.blueberry.osgi/CMakeLists.txt
index cd259682dc..84895ecaed 100644
--- a/BlueBerry/Bundles/org.blueberry.osgi/CMakeLists.txt
+++ b/BlueBerry/Bundles/org.blueberry.osgi/CMakeLists.txt
@@ -1,37 +1,44 @@
project(org_blueberry_osgi)
MACRO_CREATE_CTK_PLUGIN(
EXPORT_DIRECTIVE BERRY_OSGI
EXPORTED_INCLUDE_SUFFIXES src src/application src/event src/service
)
+if(MITK_USE_Qt5)
+ qt5_use_modules(${PLUGIN_TARGET} Concurrent Gui Sql)
+endif()
add_executable(${OSGI_APP} MACOSX_BUNDLE "src/application/berryMain.cpp")
target_link_libraries(${OSGI_APP} ${PROJECT_NAME} mbilog)
if(_ctk_test_plugins)
add_dependencies(${OSGI_APP} ${_ctk_test_plugins})
add_dependencies(BlueBerry ${OSGI_APP})
set_property(TARGET ${OSGI_APP} APPEND PROPERTY LABELS BlueBerry)
endif()
configure_file(src/application/solstice.ini
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${OSGI_APP}.ini)
add_executable(${OSGI_UI_APP} MACOSX_BUNDLE "src/application/berryMainUI.cpp")
+if(MITK_USE_Qt5)
+ qt5_use_modules(${OSGI_UI_APP} Widgets)
+endif()
+
target_link_libraries(${OSGI_UI_APP} ${PROJECT_NAME} mbilog)
if(_ctk_test_plugins)
add_dependencies(${OSGI_UI_APP} ${_ctk_test_plugins})
add_dependencies(BlueBerry ${OSGI_UI_APP})
set_property(TARGET ${OSGI_UI_APP} APPEND PROPERTY LABELS BlueBerry)
endif()
configure_file(src/application/solstice.ini
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${OSGI_UI_APP}.ini)
set(BLUEBERRY_PLUGIN_CACHE_DIR "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/plugin_cache")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/berryConfig.h.in" "${CMAKE_CURRENT_BINARY_DIR}/berryConfig.h" @ONLY)
diff --git a/BlueBerry/Bundles/org.blueberry.osgi/src/berryMacros.h b/BlueBerry/Bundles/org.blueberry.osgi/src/berryMacros.h
index 9c8581cec7..1c95e2cff2 100644
--- a/BlueBerry/Bundles/org.blueberry.osgi/src/berryMacros.h
+++ b/BlueBerry/Bundles/org.blueberry.osgi/src/berryMacros.h
@@ -1,119 +1,119 @@
/*===================================================================
BlueBerry Platform
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 __BERRY_MACROS_H__
#define __BERRY_MACROS_H__
#include "berryWeakPointer.h"
#include "berryExtensionType.h"
#define berryNameMacro(className) \
virtual const char* GetClassName() const \
{ return #className; }\
static const char* GetStaticClassName() \
{ return #className; }\
#define berryManifestMacro(className, namespaze) \
static const char* GetManifestName() \
{ return #namespaze #className; } \
#define berryObjectMacro(className) \
typedef className Self; \
typedef berry::SmartPointer<Self> Pointer; \
typedef berry::SmartPointer<const Self> ConstPointer; \
typedef berry::WeakPointer<Self> WeakPtr; \
typedef berry::WeakPointer<const Self> ConstWeakPtr; \
berryNameMacro(className); \
#define berryInterfaceMacro(className, namespaze) \
public: \
berryObjectMacro(className); \
berryManifestMacro(className, namespaze); \
#define berrySimpleInterfaceMacro(className, namespaze) \
protected: className() {} \
public: \
berryNameMacro(className); \
berryManifestMacro(className, namespaze); \
#define berryNewMacro(x) \
static Pointer New(void) \
{ \
Pointer smartPtr(new x); \
return smartPtr; \
} \
#define berryNewMacro1Param(x, type1) \
static Pointer New(type1 param1) \
{ \
Pointer smartPtr(new x(param1)); \
return smartPtr; \
} \
#define berryNewMacro2Param(x, type1, type2) \
static Pointer New(type1 param1, type2 param2) \
{ \
Pointer smartPtr(new x(param1, param2)); \
return smartPtr; \
} \
#define berryNewMacro3Param(x, type1, type2, type3) \
static Pointer New(type1 param1, type2 param2, type3 param3) \
{ \
Pointer smartPtr (new x(param1, param2, param3)); \
return smartPtr; \
} \
#ifndef BERRY_NO_TYPESAFE_FLAGS
#include "berryFlags.h"
#define BERRY_DECLARE_FLAGS(_Flags, _Enum)\
typedef berry::Flags<_Enum> _Flags;
#if defined _MSC_VER && _MSC_VER < 1300
# define BERRY_DECLARE_INCOMPATIBLE_FLAGS(_Flags)
#else
# define BERRY_DECLARE_INCOMPATIBLE_FLAGS(_Flags) \
inline berry::IncompatibleFlag operator|(_Flags::enum_type f1, int f2) \
{ return berry::IncompatibleFlag(int(f1) | f2); }
#endif
#define BERRY_DECLARE_OPERATORS_FOR_FLAGS(_Flags) \
inline berry::Flags<_Flags::enum_type> operator|(_Flags::enum_type f1, _Flags::enum_type f2) \
{ return berry::Flags<_Flags::enum_type>(f1) | f2; } \
inline berry::Flags<_Flags::enum_type> operator|(_Flags::enum_type f1, berry::Flags<_Flags::enum_type> f2) \
{ return f2 | f1; } BERRY_DECLARE_INCOMPATIBLE_FLAGS(_Flags)
#else /* BERRY_NO_TYPESAFE_FLAGS */
#define BERRY_DECLARE_FLAGS(_Flags, _Enum)\
typedef uint _Flags;
#define BERRY_DECLARE_OPERATORS_FOR_FLAGS(_Flags)
#endif /* BERRY_NO_TYPESAFE_FLAGS */
#define BERRY_REGISTER_EXTENSION_CLASS(_ClassType, _PluginContext)\
{\
QString typeName = _PluginContext->getPlugin()->getSymbolicName();\
typeName = (typeName + "_") + _ClassType::staticMetaObject.className();\
- ::berry::registerExtensionType<_ClassType>(typeName.toAscii().data());\
+ ::berry::registerExtensionType<_ClassType>(typeName.toLatin1().data());\
}
#endif /*__BERRY_MACROS_H__*/
diff --git a/BlueBerry/Bundles/org.blueberry.osgi/src/internal/berryCTKPluginActivator.cpp b/BlueBerry/Bundles/org.blueberry.osgi/src/internal/berryCTKPluginActivator.cpp
index 7bae0fca60..3a1a4d8a91 100755
--- a/BlueBerry/Bundles/org.blueberry.osgi/src/internal/berryCTKPluginActivator.cpp
+++ b/BlueBerry/Bundles/org.blueberry.osgi/src/internal/berryCTKPluginActivator.cpp
@@ -1,65 +1,67 @@
/*===================================================================
BlueBerry Platform
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 "berryCTKPluginActivator.h"
#include "berrySystemBundle.h"
#include "berryInternalPlatform.h"
#include <ctkPluginFrameworkLauncher.h>
#include <QCoreApplication>
#include <QtPlugin>
#include <QDebug>
namespace berry {
ctkPluginContext* org_blueberry_osgi_Activator::context = 0;
void org_blueberry_osgi_Activator::start(ctkPluginContext* context)
{
this->context = context;
SystemBundle::Pointer systemBundle = InternalPlatform::GetInstance()->GetBundle("system.bundle").Cast<SystemBundle>();
ExtensionPointService::Pointer service(new ExtensionPointService(&systemBundle->GetBundleLoader()));
// register the service in the legacy BlueBerry service registry
Platform::GetServiceRegistry().RegisterService(IExtensionPointService::SERVICE_ID, service);
// register the service in the CTK service registry
context->registerService<IExtensionPointService>(service.GetPointer());
}
void org_blueberry_osgi_Activator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
Platform::GetServiceRegistry().UnRegisterService(IExtensionPointService::SERVICE_ID);
this->context = 0;
// TODO stop framework
}
ctkPluginContext* org_blueberry_osgi_Activator::getPluginContext()
{
return context;
}
}
-Q_EXPORT_PLUGIN2(org_blueberry_osgi, berry::org_blueberry_osgi_Activator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_blueberry_osgi, berry::org_blueberry_osgi_Activator)
+#endif
diff --git a/BlueBerry/Bundles/org.blueberry.osgi/src/internal/berryCTKPluginActivator.h b/BlueBerry/Bundles/org.blueberry.osgi/src/internal/berryCTKPluginActivator.h
index 9ff6d85df4..6022953670 100755
--- a/BlueBerry/Bundles/org.blueberry.osgi/src/internal/berryCTKPluginActivator.h
+++ b/BlueBerry/Bundles/org.blueberry.osgi/src/internal/berryCTKPluginActivator.h
@@ -1,51 +1,54 @@
/*===================================================================
BlueBerry Platform
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 BERRYCTKPLUGINACTIVATOR_H
#define BERRYCTKPLUGINACTIVATOR_H
#include <ctkPluginActivator.h>
#include <QObject>
#include <org_blueberry_osgi_Export.h>
namespace berry {
// We need to export this activator, because it is referenced
// in the templated method berry::ServiceRegistry::GetServiceById<>(...)
class BERRY_OSGI org_blueberry_osgi_Activator : public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_blueberry_osgi")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
static ctkPluginContext* getPluginContext();
private:
static ctkPluginContext* context;
};
typedef org_blueberry_osgi_Activator CTKPluginActivator;
}
#endif // BERRYCTKPLUGINACTIVATOR_H
diff --git a/BlueBerry/Bundles/org.blueberry.osgi/src/internal/berryInternalPlatform.cpp b/BlueBerry/Bundles/org.blueberry.osgi/src/internal/berryInternalPlatform.cpp
index 68485da61c..798f1ba1e1 100644
--- a/BlueBerry/Bundles/org.blueberry.osgi/src/internal/berryInternalPlatform.cpp
+++ b/BlueBerry/Bundles/org.blueberry.osgi/src/internal/berryInternalPlatform.cpp
@@ -1,626 +1,630 @@
/*===================================================================
BlueBerry Platform
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 "berryInternalPlatform.h"
#include "berryLog.h"
#include <Poco/Exception.h>
#include <Poco/File.h>
#include <Poco/FileStream.h>
#include <Poco/AutoPtr.h>
#include <Poco/Util/PropertyFileConfiguration.h>
#include <Poco/StringTokenizer.h>
#include <Poco/Util/HelpFormatter.h>
#include <Poco/Util/OptionException.h>
#include <ctkPluginFrameworkLauncher.h>
#include <ctkPluginFrameworkFactory.h>
#include <ctkPluginFramework.h>
#include <ctkPluginContext.h>
#include <ctkPlugin.h>
#include <ctkPluginException.h>
#include <iostream>
#include "berryPlatform.h"
#include "berryPlatformException.h"
#include "berryDebugUtil.h"
#include "event/berryPlatformEvents.h"
#include "berryPlatformLogChannel.h"
#include "berryIBundle.h"
#include "berryCodeCache.h"
#include "berryBundleLoader.h"
#include "berrySystemBundle.h"
#include "berryBundleDirectory.h"
#include "berryProvisioningInfo.h"
#include <QCoreApplication>
#include <QDesktopServices>
#include <QDebug>
namespace berry {
Poco::Mutex InternalPlatform::m_Mutex;
InternalPlatform::InternalPlatform() : m_Initialized(false), m_Running(false),
m_ConsoleLog(false), m_ServiceRegistry(0),
m_CodeCache(0), m_BundleLoader(0), m_SystemBundle(0), m_PlatformLogger(0),
m_ctkPluginFrameworkFactory(0),
m_EventStarted(PlatformEvent::EV_PLATFORM_STARTED)
{
}
InternalPlatform::~InternalPlatform()
{
}
InternalPlatform* InternalPlatform::GetInstance()
{
Poco::Mutex::ScopedLock lock(m_Mutex);
static InternalPlatform instance;
return &instance;
}
bool InternalPlatform::ConsoleLog() const
{
return m_ConsoleLog;
}
ctkPluginContext* InternalPlatform::GetCTKPluginFrameworkContext() const
{
if (m_ctkPluginFrameworkFactory)
{
return m_ctkPluginFrameworkFactory->getFramework()->getPluginContext();
}
return 0;
}
ServiceRegistry& InternalPlatform::GetServiceRegistry()
{
AssertInitialized();
return *m_ServiceRegistry;
}
void InternalPlatform::Initialize(int& argc, char** argv, Poco::Util::AbstractConfiguration* config)
{
// initialization
Poco::Mutex::ScopedLock lock(m_Mutex);
m_Argc = &argc;
m_Argv = argv;
try
{
this->init(argc, argv);
}
catch (const Poco::Util::UnknownOptionException& e)
{
BERRY_WARN << e.displayText();
}
this->loadConfiguration();
if (config)
{
this->config().add(config, 50, false);
}
m_ServiceRegistry = new ServiceRegistry();
m_ConsoleLog = this->GetConfiguration().hasProperty(Platform::ARG_CONSOLELOG);
m_ConfigPath.assign(this->GetConfiguration().getString("application.configDir"));
m_InstancePath.assign(this->GetConfiguration().getString("application.dir"));
try
{
m_InstallPath.assign(this->GetConfiguration().getString(Platform::ARG_HOME));
}
catch (Poco::NotFoundException& )
{
m_InstallPath.assign(m_InstancePath);
}
if (this->GetConfiguration().hasProperty(Platform::ARG_STORAGE_DIR))
{
std::string dataLocation = this->GetConfiguration().getString(Platform::ARG_STORAGE_DIR, "");
if (dataLocation.at(dataLocation.size()-1) != '/')
{
dataLocation += '/';
}
m_UserPath.assign(dataLocation);
}
else
{
// Append a hash value of the absolute path of the executable to the data location.
// This allows to start the same application from different build or install trees.
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ QString dataLocation = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + '_';
+#else
QString dataLocation = QDesktopServices::storageLocation(QDesktopServices::DataLocation) + '_';
+#endif
dataLocation += QString::number(qHash(QCoreApplication::applicationDirPath())) + "/";
m_UserPath.assign(dataLocation.toStdString());
}
BERRY_INFO(m_ConsoleLog) << "Framework storage dir: " << m_UserPath.toString();
Poco::File userFile(m_UserPath);
try
{
userFile.createDirectories();
userFile.canWrite();
}
catch(const Poco::IOException& e)
{
BERRY_WARN << e.displayText();
m_UserPath.assign(Poco::Path::temp());
m_UserPath.pushDirectory("." + this->commandName());
userFile = m_UserPath;
}
// Initialize the CTK Plugin Framework
ctkProperties fwProps;
fwProps.insert(ctkPluginConstants::FRAMEWORK_STORAGE, QString::fromStdString(userFile.path()));
if (this->GetConfiguration().hasProperty(Platform::ARG_CLEAN))
{
fwProps.insert(ctkPluginConstants::FRAMEWORK_STORAGE_CLEAN, ctkPluginConstants::FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT);
}
if (this->GetConfiguration().hasProperty(Platform::ARG_CONSOLELOG))
{
fwProps.insert("org.commontk.pluginfw.debug.framework", true);
fwProps.insert("org.commontk.pluginfw.debug.errors", true);
fwProps.insert("org.commontk.pluginfw.debug.pluginfw", true);
fwProps.insert("org.commontk.pluginfw.debug.lazy_activation", true);
fwProps.insert("org.commontk.pluginfw.debug.resolve", true);
}
if (this->GetConfiguration().hasProperty(Platform::ARG_PRELOAD_LIBRARY))
{
QString preloadLibs = QString::fromStdString(this->GetConfiguration().getString(Platform::ARG_PRELOAD_LIBRARY));
fwProps.insert(ctkPluginConstants::FRAMEWORK_PRELOAD_LIBRARIES, preloadLibs.split(',', QString::SkipEmptyParts));
}
m_ctkPluginFrameworkFactory = new ctkPluginFrameworkFactory(fwProps);
QSharedPointer<ctkPluginFramework> pfw = m_ctkPluginFrameworkFactory->getFramework();
ctkPluginContext* pfwContext = NULL;
std::string provisioningFile = this->GetConfiguration().getString(Platform::ARG_PROVISIONING);
if (!provisioningFile.empty())
{
BERRY_INFO(m_ConsoleLog) << "Using provisioning file: " << provisioningFile;
// FIXME: This is a quick-fix for Bug 16224 - Umlaut and other special characters in install/binary path
// Assumption : linux provides utf8, windows provides ascii encoded argv lists
#ifdef Q_OS_WIN
ProvisioningInfo provInfo(QString::fromStdString(provisioningFile.c_str()));
#else
ProvisioningInfo provInfo(QString::fromUtf8(provisioningFile.c_str()));
#endif
// it can still happen, that the encoding is not compatible with the fromUtf8 function ( i.e. when manipulating the LANG variable
// in such case, the QStringList in provInfo is empty which we can easily check for
if( provInfo.getPluginDirs().empty() )
{
BERRY_ERROR << "Cannot search for provisioning file, the retrieved directory list is empty.\n" <<
"This can occur if there are some special (non-ascii) characters in the install path.";
throw berry::PlatformException("No provisioning file specified. Terminating...");
}
foreach(QString pluginPath, provInfo.getPluginDirs())
{
ctkPluginFrameworkLauncher::addSearchPath(pluginPath);
}
pfw->init();
pfwContext = pfw->getPluginContext();
bool forcePluginOverwrite = this->GetConfiguration().hasOption(Platform::ARG_FORCE_PLUGIN_INSTALL);
QList<QUrl> pluginsToStart = provInfo.getPluginsToStart();
foreach(QUrl pluginUrl, provInfo.getPluginsToInstall())
{
if (forcePluginOverwrite)
{
uninstallPugin(pluginUrl, pfwContext);
}
try
{
BERRY_INFO(m_ConsoleLog) << "Installing CTK plug-in from: " << pluginUrl.toString().toStdString();
QSharedPointer<ctkPlugin> plugin = pfwContext->installPlugin(pluginUrl);
if (pluginsToStart.contains(pluginUrl))
{
m_CTKPluginsToStart << plugin->getPluginId();
}
}
catch (const ctkPluginException& e)
{
QString errorMsg;
QDebug dbg(&errorMsg);
dbg << e.printStackTrace();
BERRY_ERROR << qPrintable(errorMsg);
}
}
}
else
{
pfw->init();
pfwContext = pfw->getPluginContext();
BERRY_INFO << "No provisioning file set.";
}
m_BaseStatePath = m_UserPath;
m_BaseStatePath.pushDirectory("bb-metadata");
m_BaseStatePath.pushDirectory("bb-plugins");
Poco::Path logPath(m_UserPath);
logPath.setFileName(this->commandName() + ".log");
m_PlatformLogChannel = new PlatformLogChannel(logPath.toString());
m_PlatformLogger = &Poco::Logger::create("PlatformLogger", m_PlatformLogChannel, Poco::Message::PRIO_TRACE);
try
{
m_CodeCache = new CodeCache(this->GetConfiguration().getString(Platform::ARG_PLUGIN_CACHE));
}
catch (Poco::NotFoundException&)
{
Poco::Path cachePath(m_UserPath);
cachePath.pushDirectory("bb-plugin_cache");
m_CodeCache = new CodeCache(cachePath.toString());
}
m_BundleLoader = new BundleLoader(m_CodeCache, *m_PlatformLogger);
// tell the BundleLoader about the installed CTK plug-ins
QStringList installedCTKPlugins;
foreach(QSharedPointer<ctkPlugin> plugin, pfwContext->getPlugins())
{
installedCTKPlugins << plugin->getSymbolicName();
}
m_BundleLoader->SetCTKPlugins(installedCTKPlugins);
m_Initialized = true;
// Clear the CodeCache
if (this->GetConfiguration().hasProperty(Platform::ARG_CLEAN))
m_CodeCache->Clear();
try
{
// assemble a list of base plugin-directories (which contain
// the real plugins as directories)
std::vector<std::string> pluginBaseDirs;
Poco::StringTokenizer tokenizer(this->GetConfiguration().getString(Platform::ARG_PLUGIN_DIRS, ""), ";",
Poco::StringTokenizer::TOK_IGNORE_EMPTY | Poco::StringTokenizer::TOK_TRIM);
for (Poco::StringTokenizer::Iterator token = tokenizer.begin();
token != tokenizer.end(); ++token)
{
pluginBaseDirs.push_back(*token);
}
std::vector<Poco::Path> pluginPaths;
for (std::vector<std::string>::iterator pluginBaseDir = pluginBaseDirs.begin();
pluginBaseDir != pluginBaseDirs.end(); ++pluginBaseDir)
{
BERRY_INFO(m_ConsoleLog) << "Plugin base directory: " << *pluginBaseDir;
Poco::File pluginDir(*pluginBaseDir);
if (!pluginDir.exists() || !pluginDir.isDirectory())
{
BERRY_WARN(m_ConsoleLog) << *pluginBaseDir << " is not a direcotry or does not exist. SKIPPED.\n";
continue;
}
std::vector<std::string> pluginList;
pluginDir.list(pluginList);
std::vector<std::string>::iterator iter;
for (iter = pluginList.begin(); iter != pluginList.end(); iter++)
{
Poco::Path pluginPath = Poco::Path::forDirectory(*pluginBaseDir);
pluginPath.pushDirectory(*iter);
Poco::File file(pluginPath);
if (file.exists() && file.isDirectory())
{
pluginPaths.push_back(pluginPath);
}
}
}
std::vector<Poco::Path>::iterator pathIter;
for (pathIter = pluginPaths.begin(); pathIter != pluginPaths.end(); pathIter++)
{
try
{
Bundle::Pointer bundle = m_BundleLoader->LoadBundle(*pathIter);
if (bundle)
{
BERRY_INFO(m_ConsoleLog) << "Bundle state (" << pathIter->toString() << "): " << bundle->GetStateString() << std::endl;
}
}
catch (const BundleStateException& exc)
{
BERRY_WARN << exc.displayText() << std::endl;
}
}
// resolve plugins
m_BundleLoader->ResolveAllBundles();
}
catch (Poco::Exception& exc)
{
this->logger().log(exc);
}
#ifdef BLUEBERRY_DEBUG_SMARTPOINTER
DebugUtil::RestoreState();
#endif
}
void InternalPlatform::uninstallPugin(const QUrl& pluginUrl, ctkPluginContext* pfwContext)
{
QFileInfo libInfo(pluginUrl.toLocalFile());
QString libName = libInfo.baseName();
if (libName.startsWith("lib"))
{
libName = libName.mid(3);
}
QString symbolicName = libName.replace('_', '.');
foreach(QSharedPointer<ctkPlugin> plugin, pfwContext->getPlugins())
{
if (plugin->getSymbolicName() == symbolicName &&
plugin->getLocation() != pluginUrl.toString())
{
BERRY_WARN << "A plug-in with the symbolic name " << symbolicName.toStdString() <<
" but different location is already installed. Trying to uninstall " << plugin->getLocation().toStdString();
plugin->uninstall();
return;
}
}
}
void InternalPlatform::Launch()
{
AssertInitialized();
if (m_Running) return;
m_Running = true;
this->run();
}
void InternalPlatform::Shutdown()
{
QSharedPointer<ctkPluginFramework> ctkPluginFW;
{
Poco::Mutex::ScopedLock lock(m_Mutex);
AssertInitialized();
DebugUtil::SaveState();
ctkPluginFW = m_ctkPluginFrameworkFactory->getFramework();
m_Initialized = false;
}
ctkPluginFW->stop();
this->uninitialize();
// wait 10 seconds for the CTK plugin framework to stop
ctkPluginFW->waitForStop(10000);
{
Poco::Mutex::ScopedLock lock(m_Mutex);
delete m_ServiceRegistry;
delete m_BundleLoader;
delete m_CodeCache;
}
}
void InternalPlatform::AssertInitialized()
{
if (!m_Initialized)
throw Poco::SystemException("The Platform has not been initialized yet!");
}
IExtensionPointService::Pointer InternalPlatform::GetExtensionPointService()
{
Poco::Mutex::ScopedLock lock(m_Mutex);
this->AssertInitialized();
return m_ServiceRegistry->GetServiceById<IExtensionPointService>(IExtensionPointService::SERVICE_ID);
}
const Poco::Path& InternalPlatform::GetConfigurationPath()
{
return m_ConfigPath;
}
const Poco::Path& InternalPlatform::GetInstallPath()
{
return m_InstallPath;
}
const Poco::Path& InternalPlatform::GetInstancePath()
{
return m_InstancePath;
}
bool InternalPlatform::GetStatePath(Poco::Path& statePath, IBundle::Pointer bundle, bool create)
{
statePath = m_BaseStatePath;
statePath.pushDirectory(bundle->GetSymbolicName());
try
{
Poco::File stateFile(statePath);
if (!stateFile.exists() && create)
stateFile.createDirectories();
}
catch (Poco::FileException&)
{
return false;
}
return true;
}
PlatformEvents& InternalPlatform::GetEvents()
{
return m_Events;
}
const Poco::Path& InternalPlatform::GetUserPath()
{
return m_UserPath;
}
bool InternalPlatform::IsRunning() const
{
Poco::Mutex::ScopedLock lock(m_Mutex);
return (m_Initialized && m_Running);
}
IBundle::Pointer InternalPlatform::GetBundle(const std::string& id)
{
Poco::Mutex::ScopedLock lock(m_Mutex);
AssertInitialized();
return m_BundleLoader->FindBundle(id);
}
std::vector<IBundle::Pointer> InternalPlatform::GetBundles() const
{
return m_BundleLoader->GetBundles();
}
Poco::Logger* InternalPlatform::GetLogger()
{
return m_PlatformLogger;
}
Poco::Util::LayeredConfiguration& InternalPlatform::GetConfiguration() const
{
return this->config();
}
std::vector<std::string> InternalPlatform::GetApplicationArgs() const
{
return m_FilteredArgs;
}
int& InternalPlatform::GetRawApplicationArgs(char**& argv)
{
argv = m_Argv;
return *m_Argc;
}
void InternalPlatform::defineOptions(Poco::Util::OptionSet& options)
{
Poco::Util::Option helpOption("help", "h", "print this help text");
helpOption.callback(Poco::Util::OptionCallback<InternalPlatform>(this, &InternalPlatform::PrintHelp));
options.addOption(helpOption);
Poco::Util::Option newInstanceOption(Platform::ARG_NEWINSTANCE, "", "forces a new instance of this application");
newInstanceOption.binding(Platform::ARG_NEWINSTANCE);
options.addOption(newInstanceOption);
Poco::Util::Option cleanOption(Platform::ARG_CLEAN, "", "cleans the plugin cache");
cleanOption.binding(Platform::ARG_CLEAN);
options.addOption(cleanOption);
Poco::Util::Option appOption(Platform::ARG_APPLICATION, "", "the id of the application extension to be executed");
appOption.argument("<id>").binding(Platform::ARG_APPLICATION);
options.addOption(appOption);
Poco::Util::Option storageDirOption(Platform::ARG_STORAGE_DIR, "", "the location for storing persistent application data");
storageDirOption.argument("<dir>").binding(Platform::ARG_STORAGE_DIR);
options.addOption(storageDirOption);
Poco::Util::Option consoleLogOption(Platform::ARG_CONSOLELOG, "", "log messages to the console");
consoleLogOption.binding(Platform::ARG_CONSOLELOG);
options.addOption(consoleLogOption);
Poco::Util::Option forcePluginOption(Platform::ARG_FORCE_PLUGIN_INSTALL, "", "force installing plug-ins with same symbolic name");
forcePluginOption.binding(Platform::ARG_FORCE_PLUGIN_INSTALL);
options.addOption(forcePluginOption);
Poco::Util::Option preloadLibsOption(Platform::ARG_PRELOAD_LIBRARY, "", "preload a library");
preloadLibsOption.argument("<library>").repeatable(true).callback(Poco::Util::OptionCallback<InternalPlatform>(this, &InternalPlatform::handlePreloadLibraryOption));
options.addOption(preloadLibsOption);
Poco::Util::Option testPluginOption(Platform::ARG_TESTPLUGIN, "", "the plug-in to be tested");
testPluginOption.argument("<id>").binding(Platform::ARG_TESTPLUGIN);
options.addOption(testPluginOption);
Poco::Util::Option testAppOption(Platform::ARG_TESTAPPLICATION, "", "the application to be tested");
testAppOption.argument("<id>").binding(Platform::ARG_TESTAPPLICATION);
options.addOption(testAppOption);
Poco::Util::Option xargsOption(Platform::ARG_XARGS, "", "Extended argument list");
xargsOption.argument("<args>").binding(Platform::ARG_XARGS);
options.addOption(xargsOption);
Poco::Util::Application::defineOptions(options);
}
void InternalPlatform::handlePreloadLibraryOption(const std::string& name, const std::string& value)
{
std::string oldVal;
if (this->config().hasProperty(Platform::ARG_PRELOAD_LIBRARY))
{
oldVal = this->config().getString(Platform::ARG_PRELOAD_LIBRARY);
}
this->config().setString(Platform::ARG_PRELOAD_LIBRARY, oldVal + "," + value);
}
int InternalPlatform::main(const std::vector<std::string>& args)
{
m_FilteredArgs = args;
//m_FilteredArgs.insert(m_FilteredArgs.begin(), this->config().getString("application.argv[0]"));
ctkPluginContext* context = GetCTKPluginFrameworkContext();
QFileInfo storageDir = context->getDataFile("");
BundleDirectory::Pointer bundleStorage(new BundleDirectory(Poco::Path(storageDir.absolutePath().toStdString())));
SystemBundle::Pointer systemBundle(new SystemBundle(*m_BundleLoader, bundleStorage));
if (systemBundle == 0)
throw PlatformException("Could not find the system bundle");
m_BundleLoader->m_SystemBundle = systemBundle;
m_BundleLoader->LoadBundle(systemBundle);
m_ctkPluginFrameworkFactory->getFramework()->start();
foreach(long pluginId, m_CTKPluginsToStart)
{
BERRY_INFO(m_ConsoleLog) << "Starting CTK plug-in: " << context->getPlugin(pluginId)->getSymbolicName().toStdString()
<< " [" << pluginId << "]";
// do not change the autostart setting of this plugin
context->getPlugin(pluginId)->start(ctkPlugin::START_TRANSIENT | ctkPlugin::START_ACTIVATION_POLICY);
}
m_BundleLoader->StartSystemBundle(systemBundle);
systemBundle->Resume();
return EXIT_OK;
}
void InternalPlatform::PrintHelp(const std::string&, const std::string&)
{
Poco::Util::HelpFormatter help(this->options());
help.setAutoIndent();
help.setCommand(this->commandName());
help.format(std::cout);
exit(EXIT_OK);
}
}
diff --git a/BlueBerry/Bundles/org.blueberry.osgi/src/service/berryIConfigurationElement.h b/BlueBerry/Bundles/org.blueberry.osgi/src/service/berryIConfigurationElement.h
index c2802bb2e6..c05428584e 100644
--- a/BlueBerry/Bundles/org.blueberry.osgi/src/service/berryIConfigurationElement.h
+++ b/BlueBerry/Bundles/org.blueberry.osgi/src/service/berryIConfigurationElement.h
@@ -1,156 +1,156 @@
/*===================================================================
BlueBerry Platform
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 BERRYIEXTENSIONELEMENT_H_
#define BERRYIEXTENSIONELEMENT_H_
#include "berryLog.h"
#include <org_blueberry_osgi_Export.h>
#include "berryBundleLoader.h"
#include "berryPlatformException.h"
#include "berryExtensionType.h"
#include "berryIExecutableExtension.h"
#include "berryIExtension.h"
#include <vector>
#include <string>
namespace berry {
struct IExtension;
struct BERRY_OSGI IConfigurationElement : public Object
{
berryObjectMacro(IConfigurationElement);
public:
typedef std::vector<IConfigurationElement::Pointer> vector;
template<class C>
C* CreateExecutableExtension(const std::string& propertyName, const std::string& manifestName)
{
std::string className;
if (this->GetAttribute(propertyName, className))
{
try
{
C* cl = m_ClassLoader->LoadClass<C>(m_Contributor, className, manifestName);
// check if we have extension adapter and initialize
if (dynamic_cast<IExecutableExtension*>(cl) != 0) {
// make the call even if the initialization string is null
dynamic_cast<IExecutableExtension*>(cl)->SetInitializationData(Pointer(this), propertyName, Object::Pointer(0));
}
if (cl == 0)
{
BERRY_WARN << "Could not load executable extension " << className << " from " << GetContributor();
}
return cl;
}
catch (Poco::Exception& e)
{
BERRY_ERROR << "Error loading class: " << e.displayText() << std::endl;
throw e;
}
}
throw CoreException("Missing attribute", propertyName);
}
template<class C>
C* CreateExecutableExtension(const std::string& propertyName)
{
std::string className;
if (this->GetAttribute(propertyName, className))
{
std::string contributor = this->GetContributor();
QSharedPointer<ctkPlugin> plugin = Platform::GetCTKPlugin(QString::fromStdString(contributor));
if (!plugin.isNull())
{
// immediately start the plugin but do not change the plugins autostart setting
plugin->start(ctkPlugin::START_TRANSIENT);
QString typeName = plugin->getSymbolicName() + "_" + QString::fromStdString(className);
- int extensionTypeId = ExtensionType::type(typeName.toAscii().data());
+ int extensionTypeId = ExtensionType::type(typeName.toLatin1().data());
if (extensionTypeId == 0)
{
BERRY_WARN << "The class " << className << " was not registered as an Extension Type using BERRY_REGISTER_EXTENSION_CLASS(type, pluginContext) or you forgot to run Qt's moc on the header file. "
"Legacy BlueBerry bundles should use CreateExecutableExtension<C>(propertyName, C::GetManifestName()) instead.";
}
else
{
QObject* obj = ExtensionType::construct(extensionTypeId);
// check if we have extension adapter and initialize
if (IExecutableExtension* execExt = qobject_cast<IExecutableExtension*>(obj))
{
// make the call even if the initialization string is null
execExt->SetInitializationData(Pointer(this), propertyName, Object::Pointer(0));
}
C* interface = qobject_cast<C*>(obj);
if (interface == 0)
{
BERRY_WARN << "The QObject subclass " << className << " does not seem to implement the required interface class, or you forgot the Q_INTERFACES macro.";
}
return interface;
}
}
else
{
BERRY_WARN << "Trying to create an executable extension (from "
<< this->GetDeclaringExtension()->GetExtensionPointIdentifier()
<< " in " << contributor << ") from a non-CTK plug-in. "
"Use the CreateExecutableExtension<C>(propertyName, manifestName) method instead.";
}
}
return 0;
}
virtual bool GetAttribute(const std::string& name, std::string& value) const = 0;
virtual bool GetBoolAttribute(const std::string& name, bool& value) const = 0;
virtual const std::vector<IConfigurationElement::Pointer> GetChildren() const = 0;
virtual const std::vector<IConfigurationElement::Pointer> GetChildren(const std::string& name) const = 0;
virtual std::string GetValue() const = 0;
virtual std::string GetName() const = 0;
virtual const IConfigurationElement* GetParent() const = 0;
virtual const std::string& GetContributor() const = 0;
virtual const IExtension* GetDeclaringExtension() const = 0;
virtual ~IConfigurationElement() {};
protected:
BundleLoader* m_ClassLoader;
std::string m_Contributor;
};
} // namespace berry
#endif /*BERRYIEXTENSIONELEMENT_H_*/
diff --git a/BlueBerry/Bundles/org.blueberry.solstice.common/src/internal/berryPluginActivator.cpp b/BlueBerry/Bundles/org.blueberry.solstice.common/src/internal/berryPluginActivator.cpp
index adca73e141..111d643109 100644
--- a/BlueBerry/Bundles/org.blueberry.solstice.common/src/internal/berryPluginActivator.cpp
+++ b/BlueBerry/Bundles/org.blueberry.solstice.common/src/internal/berryPluginActivator.cpp
@@ -1,40 +1,42 @@
/*===================================================================
BlueBerry Platform
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 "berryPluginActivator.h"
#include <QtPlugin>
namespace berry {
org_blueberry_solstice_common_Activator::org_blueberry_solstice_common_Activator()
{
}
void org_blueberry_solstice_common_Activator::start(ctkPluginContext* context)
{
Q_UNUSED(context)
}
void org_blueberry_solstice_common_Activator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_blueberry_solstice_common, berry::org_blueberry_solstice_common_Activator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_blueberry_solstice_common, berry::org_blueberry_solstice_common_Activator)
+#endif
diff --git a/BlueBerry/Bundles/org.blueberry.solstice.common/src/internal/berryPluginActivator.h b/BlueBerry/Bundles/org.blueberry.solstice.common/src/internal/berryPluginActivator.h
index 196aaded06..c35fa53e29 100644
--- a/BlueBerry/Bundles/org.blueberry.solstice.common/src/internal/berryPluginActivator.h
+++ b/BlueBerry/Bundles/org.blueberry.solstice.common/src/internal/berryPluginActivator.h
@@ -1,42 +1,45 @@
/*===================================================================
BlueBerry Platform
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 BERRYPLUGINACTIVATOR_H
#define BERRYPLUGINACTIVATOR_H
#include <ctkPluginActivator.h>
namespace berry {
class org_blueberry_solstice_common_Activator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_blueberry_solstice_common")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
org_blueberry_solstice_common_Activator();
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
};
typedef org_blueberry_solstice_common_Activator PluginActivator;
}
#endif // BERRYPLUGINACTIVATOR_H
diff --git a/BlueBerry/Bundles/org.blueberry.test/src/internal/berryPluginActivator.cpp b/BlueBerry/Bundles/org.blueberry.test/src/internal/berryPluginActivator.cpp
index 085950143e..f6d0a19b0f 100644
--- a/BlueBerry/Bundles/org.blueberry.test/src/internal/berryPluginActivator.cpp
+++ b/BlueBerry/Bundles/org.blueberry.test/src/internal/berryPluginActivator.cpp
@@ -1,43 +1,45 @@
/*===================================================================
BlueBerry Platform
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 "berryPluginActivator.h"
#include "berryCoreTestApplication.h"
#include <QtPlugin>
namespace berry {
org_blueberry_test_Activator::org_blueberry_test_Activator()
{
}
void org_blueberry_test_Activator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(CoreTestApplication, context)
}
void org_blueberry_test_Activator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_blueberry_test, berry::org_blueberry_test_Activator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_blueberry_test, berry::org_blueberry_test_Activator)
+#endif
diff --git a/BlueBerry/Bundles/org.blueberry.test/src/internal/berryPluginActivator.h b/BlueBerry/Bundles/org.blueberry.test/src/internal/berryPluginActivator.h
index 1520a8d1c6..a01f96544e 100644
--- a/BlueBerry/Bundles/org.blueberry.test/src/internal/berryPluginActivator.h
+++ b/BlueBerry/Bundles/org.blueberry.test/src/internal/berryPluginActivator.h
@@ -1,42 +1,45 @@
/*===================================================================
BlueBerry Platform
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 BERRYPLUGINACTIVATOR_H
#define BERRYPLUGINACTIVATOR_H
#include <ctkPluginActivator.h>
namespace berry {
class org_blueberry_test_Activator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_blueberry_test")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
org_blueberry_test_Activator();
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
};
typedef org_blueberry_test_Activator PluginActivator;
}
#endif // BERRYPLUGINACTIVATOR_H
diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.help/CMakeLists.txt b/BlueBerry/Bundles/org.blueberry.ui.qt.help/CMakeLists.txt
index c410566d05..ab3b99d97b 100644
--- a/BlueBerry/Bundles/org.blueberry.ui.qt.help/CMakeLists.txt
+++ b/BlueBerry/Bundles/org.blueberry.ui.qt.help/CMakeLists.txt
@@ -1,13 +1,17 @@
project(org_blueberry_ui_qt_help)
set(QT_USE_QTHELP 1)
set(QT_USE_QTWEBKIT 1)
set(QT_USE_QTNETWORK 1)
MACRO_CREATE_CTK_PLUGIN(
EXPORT_DIRECTIVE org_blueberry_ui_qt_help_EXPORT
EXPORTED_INCLUDE_SUFFIXES src
)
+if(MITK_USE_Qt5)
+ qt5_use_modules(${PLUGIN_TARGET} Help OpenGL PrintSupport WebKitWidgets Xml)
+endif()
+
target_link_libraries(${PROJECT_NAME}
${QT_QTHELP_LIBRARY} ${QT_QTWEBKIT_LIBRARY} ${QT_QTNETWORK_LIBRARY})
diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpPluginActivator.cpp b/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpPluginActivator.cpp
index 31f28bf0cb..ea14811264 100644
--- a/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpPluginActivator.cpp
+++ b/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpPluginActivator.cpp
@@ -1,470 +1,472 @@
/*===================================================================
BlueBerry Platform
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 "berryHelpPluginActivator.h"
#include "berryHelpContentView.h"
#include "berryHelpIndexView.h"
#include "berryHelpSearchView.h"
#include "berryHelpEditor.h"
#include "berryHelpEditorInput.h"
#include "berryHelpPerspective.h"
#include "berryQHelpEngineConfiguration.h"
#include "berryQHelpEngineWrapper.h"
#include <berryPlatformUI.h>
#include <service/event/ctkEventConstants.h>
#include <QtPlugin>
#include <QDir>
#include <QDateTime>
namespace berry {
class HelpPerspectiveListener : public IPerspectiveListener
{
public:
Events::Types GetPerspectiveEventTypes() const;
void PerspectiveOpened(SmartPointer<IWorkbenchPage> page, IPerspectiveDescriptor::Pointer perspective);
void PerspectiveChanged(SmartPointer<IWorkbenchPage> page, IPerspectiveDescriptor::Pointer perspective, const std::string &changeId);
};
class HelpWindowListener : public IWindowListener
{
public:
HelpWindowListener();
~HelpWindowListener();
void WindowClosed(IWorkbenchWindow::Pointer window);
void WindowOpened(IWorkbenchWindow::Pointer window);
private:
// We use the same perspective listener for every window
IPerspectiveListener::Pointer perspListener;
};
HelpPluginActivator* HelpPluginActivator::instance = 0;
HelpPluginActivator::HelpPluginActivator()
: pluginListener(0)
{
this->instance = this;
}
HelpPluginActivator::~HelpPluginActivator()
{
instance = 0;
}
void
HelpPluginActivator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(berry::HelpContentView, context)
BERRY_REGISTER_EXTENSION_CLASS(berry::HelpIndexView, context)
BERRY_REGISTER_EXTENSION_CLASS(berry::HelpSearchView, context)
BERRY_REGISTER_EXTENSION_CLASS(berry::HelpEditor, context)
BERRY_REGISTER_EXTENSION_CLASS(berry::HelpPerspective, context)
QFileInfo qhcInfo = context->getDataFile("qthelpcollection.qhc");
helpEngine.reset(new QHelpEngineWrapper(qhcInfo.absoluteFilePath()));
if (!helpEngine->setupData())
{
BERRY_ERROR << "QHelpEngine set-up failed: " << helpEngine->error().toStdString();
return;
}
helpEngineConfiguration.reset(new QHelpEngineConfiguration(context, *helpEngine.data()));
delete pluginListener;
pluginListener = new QCHPluginListener(context, helpEngine.data());
context->connectPluginListener(pluginListener, SLOT(pluginChanged(ctkPluginEvent)));
// register all QCH files from all the currently installed plugins
pluginListener->processPlugins();
helpEngine->initialDocSetupDone();
// Register a wnd listener which registers a perspective listener for each
// new window. The perspective listener opens the help home page in the window
// if no other help page is opened yet.
wndListener = IWindowListener::Pointer(new HelpWindowListener());
PlatformUI::GetWorkbench()->AddWindowListener(wndListener);
// Register an event handler for CONTEXTHELP_REQUESTED events
helpContextHandler.reset(new HelpContextHandler);
ctkDictionary helpHandlerProps;
helpHandlerProps.insert(ctkEventConstants::EVENT_TOPIC, "org/blueberry/ui/help/CONTEXTHELP_REQUESTED");
context->registerService<ctkEventHandler>(helpContextHandler.data(), helpHandlerProps);
}
void
HelpPluginActivator::stop(ctkPluginContext* /*context*/)
{
delete pluginListener;
pluginListener = 0;
if (PlatformUI::IsWorkbenchRunning())
{
PlatformUI::GetWorkbench()->RemoveWindowListener(wndListener);
}
wndListener = 0;
}
HelpPluginActivator *HelpPluginActivator::getInstance()
{
return instance;
}
QHelpEngineWrapper& HelpPluginActivator::getQHelpEngine()
{
return *helpEngine;
}
void HelpPluginActivator::linkActivated(IWorkbenchPage::Pointer page, const QUrl &link)
{
IEditorInput::Pointer input(new HelpEditorInput(link));
// see if an editor with the same input is already open
IEditorPart::Pointer reuseEditor = page->FindEditor(input);
if (reuseEditor)
{
// just activate it
page->Activate(reuseEditor);
}
else
{
// reuse the currently active editor, if it is a HelpEditor
reuseEditor = page->GetActiveEditor();
if (reuseEditor.IsNotNull() && page->GetReference(reuseEditor)->GetId() == HelpEditor::EDITOR_ID)
{
page->ReuseEditor(reuseEditor.Cast<IReusableEditor>(), input);
page->Activate(reuseEditor);
}
else
{
// get the last used HelpEditor instance
std::vector<IEditorReference::Pointer> editors =
page->FindEditors(IEditorInput::Pointer(0), HelpEditor::EDITOR_ID, IWorkbenchPage::MATCH_ID);
if (editors.empty())
{
// no HelpEditor is currently open, create a new one
page->OpenEditor(input, HelpEditor::EDITOR_ID);
}
else
{
// reuse an existing editor
reuseEditor = editors.front()->GetEditor(false);
page->ReuseEditor(reuseEditor.Cast<IReusableEditor>(), input);
page->Activate(reuseEditor);
}
}
}
}
QCHPluginListener::QCHPluginListener(ctkPluginContext* context, QHelpEngine* helpEngine)
: delayRegistration(true), context(context), helpEngine(helpEngine)
{}
void QCHPluginListener::processPlugins()
{
QMutexLocker lock(&mutex);
processPlugins_unlocked();
}
void QCHPluginListener::pluginChanged(const ctkPluginEvent& event)
{
QMutexLocker lock(&mutex);
if (delayRegistration)
{
this->processPlugins_unlocked();
return;
}
/* Only should listen for RESOLVED and UNRESOLVED events.
*
* When a plugin is updated the Framework will publish an UNRESOLVED and
* then a RESOLVED event which should cause the plugin to be removed
* and then added back into the registry.
*
* When a plugin is uninstalled the Framework should publish an UNRESOLVED
* event and then an UNINSTALLED event so the plugin will have been removed
* by the UNRESOLVED event before the UNINSTALLED event is published.
*/
QSharedPointer<ctkPlugin> plugin = event.getPlugin();
switch (event.getType())
{
case ctkPluginEvent::RESOLVED :
addPlugin(plugin);
break;
case ctkPluginEvent::UNRESOLVED :
removePlugin(plugin);
break;
}
}
void QCHPluginListener::processPlugins_unlocked()
{
if (!delayRegistration) return;
foreach (QSharedPointer<ctkPlugin> plugin, context->getPlugins())
{
if (isPluginResolved(plugin))
addPlugin(plugin);
else
removePlugin(plugin);
}
delayRegistration = false;
}
bool QCHPluginListener::isPluginResolved(QSharedPointer<ctkPlugin> plugin)
{
return (plugin->getState() & (ctkPlugin::RESOLVED | ctkPlugin::ACTIVE | ctkPlugin::STARTING | ctkPlugin::STOPPING)) != 0;
}
void QCHPluginListener::removePlugin(QSharedPointer<ctkPlugin> plugin)
{
// bail out if system plugin
if (plugin->getPluginId() == 0) return;
QFileInfo qchDirInfo = context->getDataFile("qch_files/" + QString::number(plugin->getPluginId()));
if (qchDirInfo.exists())
{
QDir qchDir(qchDirInfo.absoluteFilePath());
QStringList qchEntries = qchDir.entryList(QStringList("*.qch"));
QStringList qchFiles;
foreach(QString qchEntry, qchEntries)
{
qchFiles << qchDir.absoluteFilePath(qchEntry);
}
// unregister the cached qch files
foreach(QString qchFile, qchFiles)
{
QString namespaceName = QHelpEngineCore::namespaceName(qchFile);
if (namespaceName.isEmpty())
{
BERRY_ERROR << "Could not get the namespace for qch file " << qchFile.toStdString();
continue;
}
else
{
if (!helpEngine->unregisterDocumentation(namespaceName))
{
BERRY_ERROR << "Unregistering qch namespace " << namespaceName.toStdString() << " failed: " << helpEngine->error().toStdString();
}
}
}
// clean the directory
foreach(QString qchEntry, qchEntries)
{
qchDir.remove(qchEntry);
}
}
}
void QCHPluginListener::addPlugin(QSharedPointer<ctkPlugin> plugin)
{
// bail out if system plugin
if (plugin->getPluginId() == 0) return;
QFileInfo qchDirInfo = context->getDataFile("qch_files/" + QString::number(plugin->getPluginId()));
QUrl location(plugin->getLocation());
QFileInfo pluginFileInfo(location.toLocalFile());
if (!qchDirInfo.exists() || qchDirInfo.lastModified() < pluginFileInfo.lastModified())
{
removePlugin(plugin);
if (!qchDirInfo.exists())
{
QDir().mkpath(qchDirInfo.absoluteFilePath());
}
QStringList localQCHFiles;
QStringList resourceList = plugin->findResources("/", "*.qch", true);
foreach(QString resource, resourceList)
{
QByteArray content = plugin->getResource(resource);
QFile localFile(qchDirInfo.absoluteFilePath() + "/" + resource.section('/', -1));
localFile.open(QIODevice::WriteOnly);
localFile.write(content);
localFile.close();
if (localFile.error() != QFile::NoError)
{
BERRY_WARN << "Error writing " << localFile.fileName().toStdString()
<< ": " << localFile.errorString().toStdString();
}
else
{
localQCHFiles << localFile.fileName();
}
}
foreach(QString qchFile, localQCHFiles)
{
if (!helpEngine->registerDocumentation(qchFile))
{
BERRY_ERROR << "Registering qch file " << qchFile.toStdString() << " failed: " << helpEngine->error().toStdString();
}
}
}
}
IPerspectiveListener::Events::Types HelpPerspectiveListener::GetPerspectiveEventTypes() const
{
return Events::OPENED | Events::CHANGED;
}
void HelpPerspectiveListener::PerspectiveOpened(SmartPointer<IWorkbenchPage> page, IPerspectiveDescriptor::Pointer perspective)
{
// if no help editor is opened, open one showing the home page
if (perspective->GetId() == HelpPerspective::ID &&
page->FindEditors(IEditorInput::Pointer(0), HelpEditor::EDITOR_ID, IWorkbenchPage::MATCH_ID).empty())
{
IEditorInput::Pointer input(new HelpEditorInput());
page->OpenEditor(input, HelpEditor::EDITOR_ID);
}
}
void HelpPerspectiveListener::PerspectiveChanged(SmartPointer<IWorkbenchPage> page, IPerspectiveDescriptor::Pointer perspective, const std::string &changeId)
{
if (perspective->GetId() == HelpPerspective::ID && changeId == IWorkbenchPage::CHANGE_RESET)
{
PerspectiveOpened(page, perspective);
}
}
HelpWindowListener::HelpWindowListener()
: perspListener(new HelpPerspectiveListener())
{
// Register perspective listener for already opened windows
typedef std::vector<IWorkbenchWindow::Pointer> WndVec;
WndVec windows = PlatformUI::GetWorkbench()->GetWorkbenchWindows();
for (WndVec::iterator i = windows.begin(); i != windows.end(); ++i)
{
(*i)->AddPerspectiveListener(perspListener);
}
}
HelpWindowListener::~HelpWindowListener()
{
typedef std::vector<IWorkbenchWindow::Pointer> WndVec;
WndVec windows = PlatformUI::GetWorkbench()->GetWorkbenchWindows();
for (WndVec::iterator i = windows.begin(); i != windows.end(); ++i)
{
(*i)->RemovePerspectiveListener(perspListener);
}
}
void HelpWindowListener::WindowClosed(IWorkbenchWindow::Pointer window)
{
window->RemovePerspectiveListener(perspListener);
}
void HelpWindowListener::WindowOpened(IWorkbenchWindow::Pointer window)
{
window->AddPerspectiveListener(perspListener);
}
void HelpContextHandler::handleEvent(const ctkEvent &event)
{
struct _runner : public Poco::Runnable
{
_runner(const ctkEvent& ev) : ev(ev) {}
void run()
{
QUrl helpUrl;
if (ev.containsProperty("url"))
{
helpUrl = QUrl(ev.getProperty("url").toString());
}
else
{
helpUrl = contextUrl();
}
HelpPluginActivator::linkActivated(PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage(),
helpUrl);
delete this;
}
QUrl contextUrl() const
{
berry::IWorkbench* currentWorkbench = berry::PlatformUI::GetWorkbench();
if (currentWorkbench)
{
berry::IWorkbenchWindow::Pointer currentWorkbenchWindow = currentWorkbench->GetActiveWorkbenchWindow();
if (currentWorkbenchWindow)
{
berry::IWorkbenchPage::Pointer currentPage = currentWorkbenchWindow->GetActivePage();
if (currentPage)
{
berry::IWorkbenchPart::Pointer currentPart = currentPage->GetActivePart();
if (currentPart)
{
QString pluginID = QString::fromStdString(currentPart->GetSite()->GetPluginId());
QString viewID = QString::fromStdString(currentPart->GetSite()->GetId());
QString loc = "qthelp://" + pluginID + "/bundle/%1.html";
QHelpEngineWrapper& helpEngine = HelpPluginActivator::getInstance()->getQHelpEngine();
// Get view help page if available
QUrl contextUrl(loc.arg(viewID.replace(".", "_")));
QUrl url = helpEngine.findFile(contextUrl);
if (url.isValid()) return url;
else
{
BERRY_INFO << "Context help url invalid: " << contextUrl.toString().toStdString();
}
// If no view help exists get plugin help if available
QUrl pluginContextUrl(loc.arg(pluginID.replace(".", "_")));
url = helpEngine.findFile(pluginContextUrl);
if (url.isValid()) return url;
// Try to get the index.html file of the plug-in contributing the
// currently active part.
QUrl pluginIndexUrl(loc.arg("index"));
url = helpEngine.findFile(pluginIndexUrl);
if (url != pluginIndexUrl)
{
// Use the default page instead of another index.html
// (merged via the virtual folder property).
url = QUrl();
}
return url;
}
}
}
}
return QUrl();
}
ctkEvent ev;
};
// sync with GUI thread
Display::GetDefault()->AsyncExec(new _runner(event));
}
}
-Q_EXPORT_PLUGIN2(org_blueberry_ui_qt_help, berry::HelpPluginActivator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_blueberry_ui_qt_help, berry::HelpPluginActivator)
+#endif
diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpPluginActivator.h b/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpPluginActivator.h
index c982abd6c8..157018f622 100644
--- a/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpPluginActivator.h
+++ b/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpPluginActivator.h
@@ -1,117 +1,120 @@
/*===================================================================
BlueBerry Platform
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 BERRYLOGPLUGIN_H_
#define BERRYLOGPLUGIN_H_
#include <ctkPluginActivator.h>
#include <service/event/ctkEvent.h>
#include <service/event/ctkEventHandler.h>
#include <QScopedPointer>
#include <QMutex>
#include <berryIWorkbenchPage.h>
#include <berryIWindowListener.h>
class QHelpEngine;
namespace berry {
class QHelpEngineConfiguration;
class QHelpEngineWrapper;
class QCHPluginListener;
class HelpContextHandler : public QObject, public ctkEventHandler
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_blueberry_ui_qt_help")
+#endif
Q_INTERFACES(ctkEventHandler)
public:
void handleEvent(const ctkEvent& event);
};
class HelpPluginActivator : public QObject, public ctkPluginActivator
{
Q_OBJECT
Q_INTERFACES(ctkPluginActivator)
public:
HelpPluginActivator();
~HelpPluginActivator();
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
static HelpPluginActivator* getInstance();
static void linkActivated(IWorkbenchPage::Pointer page, const QUrl &link);
QHelpEngineWrapper& getQHelpEngine();
private:
Q_DISABLE_COPY(HelpPluginActivator)
static HelpPluginActivator* instance;
QScopedPointer<QHelpEngineWrapper> helpEngine;
QScopedPointer<QHelpEngineConfiguration> helpEngineConfiguration;
QScopedPointer<HelpContextHandler> helpContextHandler;
QCHPluginListener* pluginListener;
IWindowListener::Pointer wndListener;
};
/**
* A listener for CTK plugin events. When plugins come and go we look to see
* if there are any qch files and update the QHelpEngine accordingly.
*/
class QCHPluginListener : public QObject {
Q_OBJECT
public:
QCHPluginListener(ctkPluginContext* context, QHelpEngine* helpEngine);
void processPlugins();
public Q_SLOTS:
void pluginChanged(const ctkPluginEvent& event);
private:
void processPlugins_unlocked();
bool isPluginResolved(QSharedPointer<ctkPlugin> plugin);
void removePlugin(QSharedPointer<ctkPlugin> plugin);
void addPlugin(QSharedPointer<ctkPlugin> plugin);
QMutex mutex;
bool delayRegistration;
ctkPluginContext* context;
QHelpEngine* helpEngine;
};
}
#endif /*BERRYLOGPLUGIN_H_*/
diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpSearchView.cpp b/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpSearchView.cpp
index 6463978ab9..8747f673ae 100644
--- a/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpSearchView.cpp
+++ b/BlueBerry/Bundles/org.blueberry.ui.qt.help/src/internal/berryHelpSearchView.cpp
@@ -1,242 +1,243 @@
/*===================================================================
BlueBerry Platform
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.
===================================================================*/
#ifdef __MINGW32__
// We need to inlclude winbase.h here in order to declare
// atomic intrinsics like InterlockedIncrement correctly.
// Otherwhise, they would be declared wrong within qatomic_windows.h .
#include <windows.h>
#endif
#include "berryHelpSearchView.h"
#include "berryHelpPluginActivator.h"
#include "berryQHelpEngineWrapper.h"
#include "berryHelpEditorInput.h"
#include "berryHelpEditor.h"
#include <QLayout>
#include <QMenu>
#include <QEvent>
#include <QMouseEvent>
+#include <QMimeData>
#include <QTextBrowser>
#include <QClipboard>
#include <QHelpSearchQueryWidget>
#include <QHelpSearchResultWidget>
#include <QApplication>
namespace berry {
HelpSearchView::HelpSearchView()
: m_ZoomCount(0)
, m_Parent(0)
, m_SearchEngine(HelpPluginActivator::getInstance()->getQHelpEngine().searchEngine())
, m_ResultWidget(0)
, m_QueryWidget(0)
{
}
HelpSearchView::~HelpSearchView()
{
// prevent deletion of the widget
m_ResultWidget->setParent(0);
}
void HelpSearchView::CreateQtPartControl(QWidget* parent)
{
if (m_ResultWidget == 0)
{
m_Parent = parent;
QVBoxLayout* vLayout = new QVBoxLayout(parent);
// This will be lead to strange behavior when using multiple instances of this view
// because the QHelpSearchResultWidget instance is shared. The new view will
// reparent the widget.
m_ResultWidget = m_SearchEngine->resultWidget();
m_QueryWidget = new QHelpSearchQueryWidget();
vLayout->addWidget(m_QueryWidget);
vLayout->addWidget(m_ResultWidget);
connect(m_QueryWidget, SIGNAL(search()), this, SLOT(search()));
connect(m_ResultWidget, SIGNAL(requestShowLink(QUrl)), this,
SLOT(requestShowLink(QUrl)));
connect(m_SearchEngine, SIGNAL(searchingStarted()), this,
SLOT(searchingStarted()));
connect(m_SearchEngine, SIGNAL(searchingFinished(int)), this,
SLOT(searchingFinished(int)));
- QTextBrowser* browser = qFindChild<QTextBrowser*>(m_ResultWidget);
+ QTextBrowser* browser = m_ResultWidget->findChild<QTextBrowser*>();
if (browser) // Will be null if QtHelp was configured not to use CLucene.
{
browser->viewport()->installEventFilter(this);
browser->setContextMenuPolicy(Qt::CustomContextMenu);
connect(browser, SIGNAL(customContextMenuRequested(QPoint)),
this, SLOT(showContextMenu(QPoint)));
}
}
}
void HelpSearchView::SetFocus()
{
if (!(m_ResultWidget->hasFocus()))
{
m_QueryWidget->setFocus();
}
}
void HelpSearchView::zoomIn()
{
- QTextBrowser* browser = qFindChild<QTextBrowser*>(m_ResultWidget);
+ QTextBrowser* browser = m_ResultWidget->findChild<QTextBrowser*>();
if (browser && m_ZoomCount != 10)
{
m_ZoomCount++;
browser->zoomIn();
}
}
void HelpSearchView::zoomOut()
{
- QTextBrowser* browser = qFindChild<QTextBrowser*>(m_ResultWidget);
+ QTextBrowser* browser = m_ResultWidget->findChild<QTextBrowser*>();
if (browser && m_ZoomCount != -5)
{
m_ZoomCount--;
browser->zoomOut();
}
}
void HelpSearchView::resetZoom()
{
if (m_ZoomCount == 0)
return;
- QTextBrowser* browser = qFindChild<QTextBrowser*>(m_ResultWidget);
+ QTextBrowser* browser = m_ResultWidget->findChild<QTextBrowser*>();
if (browser)
{
browser->zoomOut(m_ZoomCount);
m_ZoomCount = 0;
}
}
void HelpSearchView::search() const
{
QList<QHelpSearchQuery> query = m_QueryWidget->query();
m_SearchEngine->search(query);
}
void HelpSearchView::searchingStarted()
{
m_Parent->setCursor(QCursor(Qt::WaitCursor));
}
void HelpSearchView::searchingFinished(int hits)
{
Q_UNUSED(hits)
m_Parent->unsetCursor();
//qApp->restoreOverrideCursor();
}
void HelpSearchView::requestShowLink(const QUrl &link)
{
HelpPluginActivator::linkActivated(this->GetSite()->GetPage(), link);
}
bool HelpSearchView::eventFilter(QObject* o, QEvent *e)
{
- QTextBrowser* browser = qFindChild<QTextBrowser*>(m_ResultWidget);
+ QTextBrowser* browser = m_ResultWidget->findChild<QTextBrowser*>();
if (browser && o == browser->viewport()
&& e->type() == QEvent::MouseButtonRelease)
{
QMouseEvent* me = static_cast<QMouseEvent*>(e);
QUrl link = m_ResultWidget->linkAt(me->pos());
if (!link.isEmpty() || link.isValid())
{
bool controlPressed = me->modifiers() & Qt::ControlModifier;
if((me->button() == Qt::LeftButton && controlPressed)
|| (me->button() == Qt::MidButton))
{
IEditorInput::Pointer input(new HelpEditorInput(link));
this->GetSite()->GetPage()->OpenEditor(input, HelpEditor::EDITOR_ID);
}
}
}
return QObject::eventFilter(o,e);
}
void HelpSearchView::showContextMenu(const QPoint& point)
{
QMenu menu;
- QTextBrowser* browser = qFindChild<QTextBrowser*>(m_ResultWidget);
+ QTextBrowser* browser = m_ResultWidget->findChild<QTextBrowser*>();
if (!browser)
return;
// QPoint point = browser->mapFromGlobal(pos);
// if (!browser->rect().contains(point, true))
// return;
QUrl link = browser->anchorAt(point);
QKeySequence keySeq(QKeySequence::Copy);
QAction *copyAction = menu.addAction(tr("&Copy") + QLatin1String("\t") +
keySeq.toString(QKeySequence::NativeText));
copyAction->setEnabled(QTextCursor(browser->textCursor()).hasSelection());
QAction *copyAnchorAction = menu.addAction(tr("Copy &Link Location"));
copyAnchorAction->setEnabled(!link.isEmpty() && link.isValid());
keySeq = QKeySequence(Qt::CTRL);
QAction *newTabAction = menu.addAction(tr("Open Link in New Tab") +
QLatin1String("\t") + keySeq.toString(QKeySequence::NativeText) +
QLatin1String("LMB"));
newTabAction->setEnabled(!link.isEmpty() && link.isValid());
menu.addSeparator();
keySeq = QKeySequence::SelectAll;
QAction *selectAllAction = menu.addAction(tr("Select All") +
QLatin1String("\t") + keySeq.toString(QKeySequence::NativeText));
QAction *usedAction = menu.exec(browser->mapToGlobal(point));
if (usedAction == copyAction)
{
QTextCursor cursor = browser->textCursor();
if (!cursor.isNull() && cursor.hasSelection())
{
QString selectedText = cursor.selectedText();
QMimeData *data = new QMimeData();
data->setText(selectedText);
QApplication::clipboard()->setMimeData(data);
}
}
else if (usedAction == copyAnchorAction)
{
QApplication::clipboard()->setText(link.toString());
}
else if (usedAction == newTabAction)
{
IEditorInput::Pointer input(new HelpEditorInput(link));
this->GetSite()->GetPage()->OpenEditor(input, HelpEditor::EDITOR_ID);
}
else if (usedAction == selectAllAction)
{
browser->selectAll();
}
}
}
diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.log/CMakeLists.txt b/BlueBerry/Bundles/org.blueberry.ui.qt.log/CMakeLists.txt
index 5abf908b70..5a93b737c6 100644
--- a/BlueBerry/Bundles/org.blueberry.ui.qt.log/CMakeLists.txt
+++ b/BlueBerry/Bundles/org.blueberry.ui.qt.log/CMakeLists.txt
@@ -1,7 +1,10 @@
project(org_blueberry_ui_qt_log)
MACRO_CREATE_CTK_PLUGIN(
EXPORT_DIRECTIVE org_blueberry_ui_qt_log_EXPORT
EXPORTED_INCLUDE_SUFFIXES src
)
+if(MITK_USE_Qt5)
+ qt5_use_modules(${PLUGIN_TARGET} Widgets)
+endif()
diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryLogView.h b/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryLogView.h
index 04d276d975..4d08e09390 100644
--- a/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryLogView.h
+++ b/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryLogView.h
@@ -1,45 +1,45 @@
/*===================================================================
BlueBerry Platform
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 BERRYLOGVIEW_H_
#define BERRYLOGVIEW_H_
-#include <QtGui/QWidget>
+#include <QWidget>
#include "berryQtViewPart.h"
namespace berry {
class LogView : public QtViewPart
{
Q_OBJECT
public:
LogView();
LogView(const LogView& other);
void SetFocus();
protected:
void CreateQtPartControl(QWidget* parent);
};
} // namespace berry
#endif /*BERRYLOGVIEW_H_*/
diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtLogPlugin.cpp b/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtLogPlugin.cpp
index df916bcfd5..cfcf09dc36 100644
--- a/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtLogPlugin.cpp
+++ b/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtLogPlugin.cpp
@@ -1,60 +1,62 @@
/*===================================================================
BlueBerry Platform
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 "berryQtLogPlugin.h"
#include "berryLogView.h"
#include <QtPlugin>
namespace berry {
QtLogPlugin* QtLogPlugin::instance = 0;
QtLogPlugin::QtLogPlugin()
{
instance = this;
}
void
QtLogPlugin::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(berry::LogView, context)
m_LogModel = new QtPlatformLogModel();
}
void
QtLogPlugin::stop(ctkPluginContext* /*context*/)
{
delete m_LogModel;
}
QtLogPlugin*
QtLogPlugin::GetInstance()
{
return instance;
}
QtPlatformLogModel*
QtLogPlugin::GetLogModel()
{
return m_LogModel;
}
}
-Q_EXPORT_PLUGIN2(org_blueberry_ui_qt_log, berry::QtLogPlugin)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_blueberry_ui_qt_log, berry::QtLogPlugin)
+#endif
diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtLogPlugin.h b/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtLogPlugin.h
index 67cefc554f..3e5013dd1a 100644
--- a/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtLogPlugin.h
+++ b/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtLogPlugin.h
@@ -1,51 +1,54 @@
/*===================================================================
BlueBerry Platform
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 BERRYLOGPLUGIN_H_
#define BERRYLOGPLUGIN_H_
#include <ctkPluginActivator.h>
#include "berryQtPlatformLogModel.h"
namespace berry {
class QtLogPlugin : public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_blueberry_ui_qt_log")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
QtLogPlugin();
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
static QtLogPlugin* GetInstance();
QtPlatformLogModel* GetLogModel();
private:
static QtLogPlugin* instance;
QtPlatformLogModel* m_LogModel;
};
}
#endif /*BERRYLOGPLUGIN_H_*/
diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtLogView.h b/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtLogView.h
index 555c7e19f4..864f6eb305 100644
--- a/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtLogView.h
+++ b/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtLogView.h
@@ -1,56 +1,56 @@
/*===================================================================
BlueBerry Platform
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 BERRYQTLOGVIEW_H
#define BERRYQTLOGVIEW_H
-#include <QtGui/QWidget>
+#include <QWidget>
#include <QSortFilterProxyModel>
#include "ui_berryQtLogView.h"
#include "berryQtPlatformLogModel.h"
namespace berry {
class QtLogView : public QWidget
{
Q_OBJECT
public:
QtLogView(QWidget *parent = 0);
~QtLogView();
QtPlatformLogModel *model;
QSortFilterProxyModel *filterModel;
private:
Ui::QtLogViewClass ui;
void showEvent ( QShowEvent * event );
protected slots:
void slotFilterChange( const QString& );
void slotRowAdded( const QModelIndex & , int , int );
void slotScrollDown( );
void on_ShowAdvancedFields_clicked( bool checked = false );
void on_ShowCategory_clicked( bool checked = false );
void on_SaveToClipboard_clicked();
};
}
#endif // BERRYQTLOGVIEW_H
diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtPlatformLogModel.cpp b/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtPlatformLogModel.cpp
index 80ee8b8f98..ec373da9d7 100644
--- a/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtPlatformLogModel.cpp
+++ b/BlueBerry/Bundles/org.blueberry.ui.qt.log/src/internal/berryQtPlatformLogModel.cpp
@@ -1,329 +1,330 @@
/*===================================================================
BlueBerry Platform
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.
===================================================================*/
#ifdef __MINGW32__
// We need to inlclude winbase.h here in order to declare
// atomic intrinsics like InterlockedIncrement correctly.
// Otherwhise, they would be declared wrong within qatomic_windows.h .
#include <windows.h>
#endif
#include "berryQtPlatformLogModel.h"
#include "berryPlatform.h"
#include "event/berryPlatformEvents.h"
#include <sstream>
#include <string>
#include <iostream>
#include <iomanip>
#include <Poco/Message.h>
#include "berryLog.h"
#include <QTimer>
#include <QIcon>
#include <QModelIndex>
namespace berry {
const QString QtPlatformLogModel::Error = QString("Error");
const QString QtPlatformLogModel::Warn = QString("Warning");
const QString QtPlatformLogModel::Fatal = QString("Fatal");
const QString QtPlatformLogModel::Info = QString("Info");
const QString QtPlatformLogModel::Debug = QString("Debug");
void QtPlatformLogModel::slotFlushLogEntries()
{
m_Mutex.lock();
std::list<ExtendedLogMessage> *tmp=m_Active;
m_Active=m_Pending; m_Pending=tmp;
m_Mutex.unlock();
int num = static_cast<int>(m_Pending->size());
if (num > 0)
{
int row = static_cast<int>(m_Entries.size());
this->beginInsertRows(QModelIndex(), row, row+num-1);
do {
m_Entries.push_back(m_Pending->front());
m_Pending->pop_front();
} while(--num);
this->endInsertRows();
}
}
void QtPlatformLogModel::addLogEntry(const mbilog::LogMessage &msg)
{
m_Mutex.lock();
//mbilog::BackendCout::FormatSmart(msg); FormatSmart is not static any more. So commented out this statement. Todo: fix
m_Active->push_back(ExtendedLogMessage(msg));
m_Mutex.unlock();
emit signalFlushLogEntries();
}
void
QtPlatformLogModel::SetShowAdvancedFiels( bool showAdvancedFiels )
{
if( m_ShowAdvancedFiels != showAdvancedFiels )
{
m_ShowAdvancedFiels = showAdvancedFiels;
- this->reset();
-
+ this->beginResetModel();
+ this->endResetModel();
}
}
void QtPlatformLogModel::SetShowCategory( bool showCategory )
{
if( m_ShowCategory != showCategory )
{
m_ShowCategory = showCategory;
- this->reset();
+ this->beginResetModel();
+ this->endResetModel();
}
}
void
QtPlatformLogModel::addLogEntry(const PlatformEvent& event)
{
const Poco::Message& entry = Poco::RefAnyCast<const Poco::Message>(*event.GetData());
mbilog::LogMessage msg(mbilog::Info,"n/a",-1,"n/a");
msg.message += entry.getText();
msg.category = "BlueBerry."+entry.getSource();
msg.moduleName = "n/a";
addLogEntry(msg);
}
QtPlatformLogModel::QtPlatformLogModel(QObject* parent) : QAbstractTableModel(parent),
m_ShowAdvancedFiels(false),
m_ShowCategory(true)
{
m_Active=new std::list<ExtendedLogMessage>;
m_Pending=new std::list<ExtendedLogMessage>;
connect(this, SIGNAL(signalFlushLogEntries()), this, SLOT( slotFlushLogEntries() ), Qt::QueuedConnection );
Platform::GetEvents().logged += PlatformEventDelegate(this, &QtPlatformLogModel::addLogEntry);
myBackend = new QtLogBackend(this);
}
QtPlatformLogModel::~QtPlatformLogModel()
{
disconnect(this, SIGNAL(signalFlushLogEntries()), this, SLOT( slotFlushLogEntries() ));
// dont delete and unregister backend, only deactivate it to avoid thread syncronization issues cause mbilog::UnregisterBackend is not threadsafe
// will be fixed.
// delete myBackend;
// delete m_Active;
// delete m_Pending;
m_Mutex.lock();
myBackend->Deactivate();
m_Mutex.unlock();
}
// QT Binding
int
QtPlatformLogModel::rowCount(const QModelIndex&) const
{
return static_cast<int>(m_Entries.size());
}
int
QtPlatformLogModel::columnCount(const QModelIndex&) const
{
int returnValue = 2;
if( m_ShowAdvancedFiels ) returnValue += 7;
if( m_ShowCategory ) returnValue += 1;
return returnValue;
}
/*
struct LogEntry {
LogEntry(const std::string& msg, const std::string& src, std::time_t t)
: message(msg.c_str()), moduleName(src.c_str()),time(std::clock())
{
}
QString message;
clock_t time;
QString level;
QString filePath;
QString lineNumber;
QString moduleName;
QString category;
QString function;
LogEntry(const mbilog::LogMessage &msg)
{
message = msg.message.c_str();
filePath = msg.filePath;
std::stringstream out;
out << msg.lineNumber;
lineNumber = out.str().c_str();
moduleName = msg.moduleName;
category = msg.category.c_str();
function = msg.functionName;
time=std::clock();
}
}; */
QVariant QtPlatformLogModel::data(const QModelIndex& index, int role) const
{
const ExtendedLogMessage *msg = &m_Entries[index.row()];
if (role == Qt::DisplayRole)
{
switch (index.column())
{
case 0:
if (m_ShowAdvancedFiels) return msg->getTime();
else return msg->getLevel();
case 1:
if (m_ShowAdvancedFiels) return msg->getLevel();
else return msg->getMessage();
case 2:
if (m_ShowAdvancedFiels) return msg->getMessage();
else return msg->getCategory();
case 3:
if (m_ShowAdvancedFiels && m_ShowCategory) return msg->getCategory();
else if (m_ShowAdvancedFiels && !m_ShowCategory) return msg->getModuleName();
else break;
case 4:
if (m_ShowAdvancedFiels && m_ShowCategory) return msg->getModuleName();
else if (m_ShowAdvancedFiels && !m_ShowCategory) return msg->getFunctionName();
else break;
case 5:
if (m_ShowAdvancedFiels && m_ShowCategory) return msg->getFunctionName();
else if (m_ShowAdvancedFiels && !m_ShowCategory) return msg->getPath();
else break;
case 6:
if (m_ShowAdvancedFiels && m_ShowCategory) return msg->getPath();
else if (m_ShowAdvancedFiels && !m_ShowCategory) return msg->getLine();
else break;
case 7:
if (m_ShowAdvancedFiels && m_ShowCategory) return msg->getLine();
else break;
}
}
else if( role == Qt::DecorationRole )
{
if ( (m_ShowAdvancedFiels && index.column()==1)
|| (!m_ShowAdvancedFiels && index.column()==0) )
{
QString file ( ":/org_blueberry_ui_qt_log/information.png" );
if( msg->message.level == mbilog::Error )
file = ":/org_blueberry_ui_qt_log/error.png";
else if( msg->message.level == mbilog::Warn )
file = ":/org_blueberry_ui_qt_log/warning.png";
else if( msg->message.level == mbilog::Debug )
file = ":/org_blueberry_ui_qt_log/debug.png";
else if( msg->message.level == mbilog::Fatal )
file = ":/org_blueberry_ui_qt_log/fatal.png";
QIcon icon(file);
return QVariant(icon);
}
}
return QVariant();
}
QVariant
QtPlatformLogModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role == Qt::DisplayRole && orientation == Qt::Horizontal)
{
if( m_ShowAdvancedFiels && m_ShowCategory )
{
switch (section)
{
case 0: return QVariant(" Time ");
case 1: return QVariant(" Level ");
case 2: return QVariant(" Message ");
case 3: return QVariant(" Category ");
case 4: return QVariant(" Module ");
case 5: return QVariant(" Function ");
case 6: return QVariant(" File ");
case 7: return QVariant(" Line ");
}
}
else if (m_ShowAdvancedFiels && !m_ShowCategory)
{
switch (section)
{
case 0: return QVariant(" Time ");
case 1: return QVariant(" Level ");
case 2: return QVariant(" Message ");
case 3: return QVariant(" Module ");
case 4: return QVariant(" Function ");
case 5: return QVariant(" File ");
case 6: return QVariant(" Line ");
}
}
else //!m_ShowAdvancedFiels, m_ShowCategory is not handled seperately because it only activates case 2
{
switch (section)
{
case 0: return QVariant(" Level ");
case 1: return QVariant(" Message ");
case 2: return QVariant(" Category ");
}
}
}
return QVariant();
}
QVariant QtPlatformLogModel::ExtendedLogMessage::getTime() const
{
std::stringstream ss;
std::locale C("C");
ss.imbue(C);
ss << std::setw(7) << std::setprecision(3) << std::fixed << ((double)this->time)/CLOCKS_PER_SEC;
return QVariant(QString(ss.str().c_str()));
}
QString QtPlatformLogModel::GetDataAsString()
{
QString returnValue("");
for (int message=0; message<this->rowCount(QModelIndex()); message++)
{
for (int column=0; column<this->columnCount(QModelIndex()); column++)
{
returnValue += " " + this->data(this->index(message,column),Qt::DisplayRole).toString();
}
returnValue += "\n";
}
return returnValue;
}
}
diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.objectinspector/src/internal/berryPluginActivator.cpp b/BlueBerry/Bundles/org.blueberry.ui.qt.objectinspector/src/internal/berryPluginActivator.cpp
index 3deccddb55..79c6982d98 100644
--- a/BlueBerry/Bundles/org.blueberry.ui.qt.objectinspector/src/internal/berryPluginActivator.cpp
+++ b/BlueBerry/Bundles/org.blueberry.ui.qt.objectinspector/src/internal/berryPluginActivator.cpp
@@ -1,40 +1,40 @@
/*===================================================================
BlueBerry Platform
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 "berryPluginActivator.h"
#include "berryObjectBrowserView.h"
#include <QtPlugin>
namespace berry {
void org_blueberry_ui_qt_objectinspector_Activator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(berry::ObjectBrowserView, context)
}
void org_blueberry_ui_qt_objectinspector_Activator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_blueberry_ui_qt_objectinspector, berry::org_blueberry_ui_qt_objectinspector_Activator)
-
-
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_blueberry_ui_qt_objectinspector, berry::org_blueberry_ui_qt_objectinspector_Activator)
+#endif
diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.objectinspector/src/internal/berryPluginActivator.h b/BlueBerry/Bundles/org.blueberry.ui.qt.objectinspector/src/internal/berryPluginActivator.h
index 0840e767d1..6126f0910e 100644
--- a/BlueBerry/Bundles/org.blueberry.ui.qt.objectinspector/src/internal/berryPluginActivator.h
+++ b/BlueBerry/Bundles/org.blueberry.ui.qt.objectinspector/src/internal/berryPluginActivator.h
@@ -1,42 +1,45 @@
/*===================================================================
BlueBerry Platform
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 BERRYOBJECTINSPECTORACTIVATOR_H
#define BERRYOBJECTINSPECTORACTIVATOR_H
#include <ctkPluginActivator.h>
namespace berry {
class org_blueberry_ui_qt_objectinspector_Activator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_blueberry_ui_qt_objectinspector")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
};
typedef org_blueberry_ui_qt_objectinspector_Activator PluginActivator;
}
#endif // BERRYOBJECTINSPECTORACTIVATOR_H
diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt.objectinspector/src/internal/berryQtObjectTableModel.cpp b/BlueBerry/Bundles/org.blueberry.ui.qt.objectinspector/src/internal/berryQtObjectTableModel.cpp
index df920d5fa8..9a931e3c32 100644
--- a/BlueBerry/Bundles/org.blueberry.ui.qt.objectinspector/src/internal/berryQtObjectTableModel.cpp
+++ b/BlueBerry/Bundles/org.blueberry.ui.qt.objectinspector/src/internal/berryQtObjectTableModel.cpp
@@ -1,588 +1,589 @@
/*===================================================================
BlueBerry Platform
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 "berryQtObjectTableModel.h"
#include <berryLog.h>
#include <berryDebugUtil.h>
#include <berryDebugBreakpointManager.h>
#include <QTimer>
#include <QIcon>
#include <cstring>
namespace berry
{
class DebugObjectListener: public IDebugObjectListener
{
public:
DebugObjectListener(QtObjectTableModel* model) :
model(model)
{
}
Events::Types GetEventTypes() const
{
return Events::ALL;
}
void ObjectCreated(const Object* obj)
{
model->ObjectCreated(obj);
}
void ObjectDestroyed(const Object* obj)
{
model->ObjectDestroyed(obj);
}
void ObjectTracingChanged(unsigned int /*traceId*/, bool /*enabled = true*/,
const Object* /*obj*/ = 0)
{
}
void SmartPointerCreated(unsigned int id, const Object* obj)
{
model->SmartPointerCreated(id, obj);
}
void SmartPointerDestroyed(unsigned int id, const Object* obj)
{
model->SmartPointerDestroyed(id, obj);
}
private:
QtObjectTableModel* model;
};
QtObjectTableModel::QtObjectTableModel(QObject* parent) :
QAbstractItemModel(parent), objectListener(new DebugObjectListener(this))
{
std::vector<const Object*> objects;
DebugUtil::GetRegisteredObjects(objects);
for (std::vector<const Object*>::const_iterator i = objects.begin(); i
!= objects.end(); ++i)
{
const char* name = (*i)->GetClassName();
ObjectItem* classItem = 0;
QListIterator<ObjectItem*> iter(indexData);
bool classFound = false;
while (iter.hasNext())
{
classItem = iter.next();
if (std::strcmp(classItem->className, name) == 0)
{
classFound = true;
break;
}
}
ObjectItem* instanceItem = new ObjectItem(*i, 0);
// get smartpointer ids
std::list<unsigned int> spIds(DebugUtil::GetSmartPointerIDs(*i));
for (std::list<unsigned int>::const_iterator spIdIter = spIds.begin(); spIdIter
!= spIds.end(); ++spIdIter)
{
ObjectItem* spItem = new ObjectItem((unsigned int) (*spIdIter),
instanceItem);
instanceItem->children.push_back(spItem);
}
if (classFound)
{
instanceItem->parent = classItem;
classItem->children.push_back(instanceItem);
}
else
{
classItem = new ObjectItem(name);
indexData.push_back(classItem);
instanceItem->parent = classItem;
classItem->children.push_back(instanceItem);
}
}
QTimer* timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(UpdatePendingData()));
timer->start(500);
DebugUtil::AddObjectListener(objectListener);
}
QtObjectTableModel::~QtObjectTableModel()
{
DebugUtil::RemoveObjectListener(objectListener);
}
QModelIndex QtObjectTableModel::index(int row, int column,
const QModelIndex& parent) const
{
if (parent.isValid())
{
if (parent.parent().isValid())
{
ObjectItem* data = static_cast<ObjectItem*> (parent.internalPointer());
poco_assert(data->type == ObjectItem::INSTANCE)
; return createIndex(row, column, data->children[row]);
}
else
{
ObjectItem* data = static_cast<ObjectItem*>(parent.internalPointer());
poco_assert(data->type == ObjectItem::CLASS);
return createIndex(row, column, data->children[row]);
}
}
else
return createIndex(row, column, indexData[row]);
}
QModelIndex QtObjectTableModel::parent(const QModelIndex& index) const
{
ObjectItem* data = static_cast<ObjectItem*>(index.internalPointer());
if (data->parent)
{
return createIndex(data->parent->children.indexOf(data), 0, data->parent);
}
else
{
return QModelIndex();
}
}
int QtObjectTableModel::rowCount(const QModelIndex& parent) const
{
if (parent.isValid())
{
if (parent.parent().isValid())
{
if (parent.parent().parent().isValid()) // smart pointer parent
return 0;
// instance parent
ObjectItem* data = static_cast<ObjectItem*>(parent.internalPointer());
poco_assert(data->type == ObjectItem::INSTANCE);
return data->children.size();
}
else
{
// class parent
ObjectItem* data = static_cast<ObjectItem*>(parent.internalPointer());
poco_assert(data->type == ObjectItem::CLASS);
return data->children.size();
}
}
else
{
// root
return indexData.size();
}
}
int QtObjectTableModel::columnCount(const QModelIndex&) const
{
return 2;
}
QVariant QtObjectTableModel::data(const QModelIndex& index, int role) const
{
if (role == Qt::DisplayRole)
{
if (index.column() == 0)
{
if (index.parent().isValid())
{
QModelIndex parentIndex = index.parent();
if (parentIndex.parent().isValid())
{
ObjectItem* data = static_cast<ObjectItem*>(index.internalPointer());
poco_assert(data->type == ObjectItem::SMARTPOINTER);
return QVariant(QString("SmartPointer (id: ") + QString::number(data->spId) + QString(")"));
}
else
{
ObjectItem* data = static_cast<ObjectItem*>(index.internalPointer());
poco_assert(data->type == ObjectItem::INSTANCE);
#ifdef BLUEBERRY_DEBUG_SMARTPOINTER
QString text = QString::number(data->obj->GetTraceId());
#else
QString text;
#endif
text += QString(" (References: ") + QString::number(data->obj->GetReferenceCount()) + QString(")");
return QVariant(text);
}
}
else
{
ObjectItem* data = static_cast<ObjectItem*>(index.internalPointer());
poco_assert(data->type == ObjectItem::CLASS);
return QVariant(QString(data->className) + " (" + QString::number(data->children.size()) + ")");
}
}
}
else if (role == Qt::CheckStateRole && index.column() == 1)
{
ObjectItem* data = static_cast<ObjectItem*>(index.internalPointer());
if (data->type == ObjectItem::INSTANCE)
{
QVariant var = (DebugUtil::IsTraced(data->obj) ? Qt::Checked : Qt::Unchecked);
return var;
}
else if (data->type == ObjectItem::CLASS)
{
QVariant var = (DebugUtil::IsTraced(data->className) ? Qt::Checked : Qt::Unchecked);
return var;
}
}
else if (role == Qt::DecorationRole && index.column() == 0)
{
ObjectItem* data = static_cast<ObjectItem*>(index.internalPointer());
if (data->type == ObjectItem::INSTANCE)
{
QVariant var;
#ifdef BLUEBERRY_DEBUG_SMARTPOINTER
if (DebugUtil::GetBreakpointManager()->BreakAtObject(data->obj->GetTraceId()))
#else
if(false)
#endif
{
var = QIcon(":/objectinspector/break-enabled.png");
}
return var;
}
else if (data->type == ObjectItem::SMARTPOINTER)
{
QVariant var;
if (DebugUtil::GetBreakpointManager()->BreakAtSmartpointer(data->spId))
{
var = QIcon(":/objectinspector/break-enabled.png");
}
return var;
}
}
else if (role == Qt::UserRole)
{
return QVariant::fromValue(index.internalPointer());
}
return QVariant();
}
QVariant QtObjectTableModel::headerData(int section,
Qt::Orientation orientation, int role) const
{
if (role == Qt::DisplayRole && orientation == Qt::Horizontal)
{
switch (section)
{
case 0:
{
int count = 0;
QListIterator<ObjectItem*> iter(indexData);
while (iter.hasNext())
{
count += iter.next()->children.size();
}
return QVariant(QString("Instances (") + QString::number(count) + ")");
}
case 1:
{
return QVariant(QString("Trace"));
}
}
}
return QVariant();
}
Qt::ItemFlags QtObjectTableModel::flags(const QModelIndex& index) const
{
Qt::ItemFlags flags = QAbstractItemModel::flags(index);
ObjectItem* item = static_cast<ObjectItem*> (index.internalPointer());
if ((item->type == ObjectItem::INSTANCE || item->type == ObjectItem::CLASS)
&& index.column() == 1)
flags |= Qt::ItemIsUserCheckable;
return flags;
}
bool QtObjectTableModel::setData(const QModelIndex &index,
const QVariant &value, int role)
{
if (index.isValid() && index.column() == 1 && role == Qt::CheckStateRole)
{
ObjectItem* item = static_cast<ObjectItem*> (index.internalPointer());
if (value.toInt() == Qt::Checked)
{
if (item->type == ObjectItem::INSTANCE)
DebugUtil::TraceObject(item->obj);
else if (item->type == ObjectItem::CLASS)
DebugUtil::TraceClass(item->className);
}
else
{
if (item->type == ObjectItem::INSTANCE)
DebugUtil::StopTracing(item->obj);
else if (item->type == ObjectItem::CLASS)
DebugUtil::StopTracing(item->className);
}
emit dataChanged(index, index);
return true;
}
return false;
}
void QtObjectTableModel::ResetData()
{
indexData.clear();
DebugUtil::ResetObjectSummary();
- QAbstractItemModel::reset();
+ QAbstractItemModel::beginResetModel();
+ QAbstractItemModel::endResetModel();
}
void QtObjectTableModel::ObjectCreated(const Object* obj)
{
// This method is called inside the berry::Object
// constructor, hence we cannot reliably call the virtual
// method berry::Object::GetClassName() to put the new
// object under the right "class" parent. So add it to
// a list of pending objects.
ObjectItem* item = new ObjectItem(obj, 0);
pendingData.push_back(item);
}
void QtObjectTableModel::UpdatePendingData()
{
if (pendingData.empty())
return;
QListIterator<ObjectItem*> instanceIter(pendingData);
while (instanceIter.hasNext())
{
ObjectItem* instanceItem = instanceIter.next();
ObjectItem* classItem = 0;
ObjectItem classSearchItem(instanceItem->obj->GetClassName());
int classIndex = 0;
classItem = FindObjectItem(classSearchItem, classIndex);
if (!classItem)
{
classItem = new ObjectItem(instanceItem->obj->GetClassName());
classItem->children.push_back(instanceItem);
instanceItem->parent = classItem;
classIndex = rowCount(QModelIndex());
beginInsertRows(QModelIndex(), classIndex, classIndex);
indexData.push_back(classItem);
endInsertRows();
}
else
{
instanceItem->parent = classItem;
QModelIndex classModelIndex = createIndex(classIndex, 0, classItem);
int rowIndex = rowCount(classModelIndex);
beginInsertRows(classModelIndex, rowIndex, rowIndex);
classItem->children.push_back(instanceItem);
endInsertRows();
}
}
pendingData.clear();
}
void QtObjectTableModel::ObjectDestroyed(const Object* obj)
{
ObjectItem searchItem(obj, 0);
int index = 0;
ObjectItem* item = FindObjectItem(searchItem, index);
if (!item)
{
QMutableListIterator<ObjectItem*> pendingIter(pendingData);
while (pendingIter.hasNext())
{
ObjectItem* pendingItem = pendingIter.next();
if (pendingItem->obj == obj)
{
pendingIter.remove();
delete pendingItem;
break;
}
}
return;
}
int parentIndex = indexData.indexOf(item->parent);
beginRemoveRows(createIndex(parentIndex, 0, item->parent), index, index);
item->parent->children.removeAt(index);
endRemoveRows();
if (item->parent->children.empty())
{
beginRemoveRows(QModelIndex(), parentIndex, parentIndex);
indexData.removeAt(parentIndex);
endRemoveRows();
delete item->parent;
}
else
{
delete item;
}
}
void QtObjectTableModel::SmartPointerCreated(unsigned int id, const Object* obj)
{
ObjectItem searchInstance(obj, 0);
int instanceIndex = 0;
ObjectItem* instanceItem = FindObjectItem(searchInstance, instanceIndex);
if (!instanceItem)
{
QListIterator<ObjectItem*> pendingIter(pendingData);
while (pendingIter.hasNext())
{
ObjectItem* pendingItem = pendingIter.next();
if (pendingItem->obj == obj)
{
pendingItem->children.push_back(new ObjectItem(id, pendingItem));
break;
}
}
return;
}
int itemIndex = instanceItem->children.size();
beginInsertRows(createIndex(instanceIndex, 0, instanceItem), itemIndex,
itemIndex);
instanceItem->children.push_back(new ObjectItem(id, instanceItem));
endInsertRows();
}
void QtObjectTableModel::SmartPointerDestroyed(unsigned int id, const Object* obj)
{
ObjectItem searchSP(id, 0);
int spIndex = 0;
ObjectItem* spItem = FindObjectItem(searchSP, spIndex);
if (!spItem)
{
QListIterator<ObjectItem*> pendingIter(pendingData);
while (pendingIter.hasNext())
{
ObjectItem* pendingItem = pendingIter.next();
if (pendingItem->obj == obj)
{
QMutableListIterator<ObjectItem*> spIter(pendingItem->children);
while (spIter.hasNext())
{
spItem = spIter.next();
if (spItem->spId == id)
{
spIter.remove();
delete spItem;
return;
}
}
break;
}
}
return;
}
int parentIndex = 0;
ObjectItem searchInstance(obj, 0);
ObjectItem* instanceItem = FindObjectItem(searchInstance, parentIndex);
beginRemoveRows(createIndex(parentIndex, 0, instanceItem), spIndex, spIndex);
instanceItem->children.removeAt(spIndex);
delete spItem;
endRemoveRows();
}
ObjectItem* QtObjectTableModel::FindObjectItem(
const ObjectItem& item, int& index)
{
switch (item.type)
{
case ObjectItem::CLASS:
{
QListIterator<ObjectItem*> i(indexData);
index = 0;
while (i.hasNext())
{
ObjectItem* next = i.next();
if (std::strcmp(next->className, item.className) == 0)
return next;
++index;
}
return 0;
}
case ObjectItem::INSTANCE:
{
QListIterator<ObjectItem*> i(indexData);
while (i.hasNext())
{
ObjectItem* next = i.next();
index = 0;
QListIterator<ObjectItem*> childIter(next->children);
while (childIter.hasNext())
{
ObjectItem* child = childIter.next();
if (child->obj == item.obj)
return child;
++index;
}
}
return 0;
}
case ObjectItem::SMARTPOINTER:
{
QListIterator<ObjectItem*> classIter(indexData);
while (classIter.hasNext())
{
ObjectItem* nextClass = classIter.next();
QListIterator<ObjectItem*> instanceIter(nextClass->children);
while (instanceIter.hasNext())
{
ObjectItem* nextInstance = instanceIter.next();
index = 0;
QListIterator<ObjectItem*> spIter(nextInstance->children);
while (spIter.hasNext())
{
ObjectItem* nextSp = spIter.next();
if (nextSp->spId == item.spId)
return nextSp;
++index;
}
}
}
return 0;
}
}
return 0;
}
}
diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt/CMakeLists.txt b/BlueBerry/Bundles/org.blueberry.ui.qt/CMakeLists.txt
index dc02c6ff78..f295636662 100644
--- a/BlueBerry/Bundles/org.blueberry.ui.qt/CMakeLists.txt
+++ b/BlueBerry/Bundles/org.blueberry.ui.qt/CMakeLists.txt
@@ -1,5 +1,8 @@
project(org_blueberry_ui_qt)
MACRO_CREATE_CTK_PLUGIN(EXPORT_DIRECTIVE BERRY_UI_QT
EXPORTED_INCLUDE_SUFFIXES src src/application)
+if(MITK_USE_Qt5)
+ qt5_use_modules(${PLUGIN_TARGET} Widgets)
+endif()
diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt/src/application/berryQtWorkbenchAdvisor.cpp b/BlueBerry/Bundles/org.blueberry.ui.qt/src/application/berryQtWorkbenchAdvisor.cpp
index cbc0062635..4916ca0cb7 100755
--- a/BlueBerry/Bundles/org.blueberry.ui.qt/src/application/berryQtWorkbenchAdvisor.cpp
+++ b/BlueBerry/Bundles/org.blueberry.ui.qt/src/application/berryQtWorkbenchAdvisor.cpp
@@ -1,59 +1,61 @@
/*===================================================================
BlueBerry Platform
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 "berryQtWorkbenchAdvisor.h"
#include "internal/berryQtGlobalEventFilter.h"
#include "berryQtPreferences.h"
#include <berryPlatform.h>
#include <berryIPreferencesService.h>
#include <berryIQtStyleManager.h>
#include <QApplication>
#include <QString>
#include <QTextCodec>
#include <Poco/File.h>
#include <Poco/FileStream.h>
#include <vector>
namespace berry
{
void QtWorkbenchAdvisor::Initialize(IWorkbenchConfigurer::Pointer configurer)
{
WorkbenchAdvisor::Initialize(configurer);
IPreferencesService::Pointer prefService = Platform::GetServiceRegistry().GetServiceById<IPreferencesService>(
IPreferencesService::ID);
IPreferences::Pointer prefs = prefService->GetSystemPreferences()->Node(QtPreferences::QT_STYLES_NODE);
QString styleName = QString::fromStdString(prefs->Get(QtPreferences::QT_STYLE_NAME, ""));
IQtStyleManager::Pointer styleManager = Platform::GetServiceRegistry().GetServiceById<IQtStyleManager>(IQtStyleManager::ID);
styleManager->SetStyle(styleName);
QObject* eventFilter = new QtGlobalEventFilter(qApp);
qApp->installEventFilter(eventFilter);
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
// character strings should be interpreted as UTF-8 encoded strings
// e.g. plugin.xml files are UTF-8 encoded
QTextCodec* utf8Codec = QTextCodec::codecForName("UTF-8");
QTextCodec::setCodecForCStrings(utf8Codec);
QTextCodec::setCodecForTr(utf8Codec);
+#endif
}
}
diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt/src/internal/berryQtPluginActivator.cpp b/BlueBerry/Bundles/org.blueberry.ui.qt/src/internal/berryQtPluginActivator.cpp
index d69fdd9321..c9618241d9 100644
--- a/BlueBerry/Bundles/org.blueberry.ui.qt/src/internal/berryQtPluginActivator.cpp
+++ b/BlueBerry/Bundles/org.blueberry.ui.qt/src/internal/berryQtPluginActivator.cpp
@@ -1,72 +1,74 @@
/*===================================================================
BlueBerry Platform
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 "berryQtPluginActivator.h"
#include "berryQtStyleManager.h"
#include "berryQtDnDTweaklet.h"
#include "berryQtImageTweaklet.h"
#include "berryQtMessageDialogTweaklet.h"
#include "berryQtWorkbenchTweaklet.h"
#include "berryQtWorkbenchPageTweaklet.h"
#include "berryQtWidgetsTweaklet.h"
#include "berryQtStylePreferencePage.h"
#include "defaultpresentation/berryQtWorkbenchPresentationFactory.h"
namespace berry {
QtPluginActivator::QtPluginActivator()
{
}
QtPluginActivator::~QtPluginActivator()
{
}
void
QtPluginActivator::start(ctkPluginContext* context)
{
AbstractUICTKPlugin::start(context);
BERRY_REGISTER_EXTENSION_CLASS(QtDnDTweaklet, context)
BERRY_REGISTER_EXTENSION_CLASS(QtImageTweaklet, context);
BERRY_REGISTER_EXTENSION_CLASS(QtMessageDialogTweaklet, context);
BERRY_REGISTER_EXTENSION_CLASS(QtWidgetsTweaklet, context)
BERRY_REGISTER_EXTENSION_CLASS(QtWorkbenchTweaklet, context)
BERRY_REGISTER_EXTENSION_CLASS(QtWorkbenchPageTweaklet, context)
BERRY_REGISTER_EXTENSION_CLASS(QtWorkbenchPresentationFactory, context)
BERRY_REGISTER_EXTENSION_CLASS(QtStylePreferencePage, context)
QtStyleManager* manager = new QtStyleManager();
styleManager = IQtStyleManager::Pointer(manager);
context->registerService<berry::IQtStyleManager>(manager);
}
void QtPluginActivator::stop(ctkPluginContext* context)
{
styleManager = 0;
AbstractUICTKPlugin::stop(context);
}
}
-Q_EXPORT_PLUGIN2(org_blueberry_ui_qt, berry::QtPluginActivator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_blueberry_ui_qt, berry::QtPluginActivator)
+#endif
diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt/src/internal/berryQtPluginActivator.h b/BlueBerry/Bundles/org.blueberry.ui.qt/src/internal/berryQtPluginActivator.h
index 5c248d026a..97884f0a90 100644
--- a/BlueBerry/Bundles/org.blueberry.ui.qt/src/internal/berryQtPluginActivator.h
+++ b/BlueBerry/Bundles/org.blueberry.ui.qt/src/internal/berryQtPluginActivator.h
@@ -1,48 +1,51 @@
/*===================================================================
BlueBerry Platform
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 BERRYQTPLUGINACTIVATOR_H_
#define BERRYQTPLUGINACTIVATOR_H_
#include <berryAbstractUICTKPlugin.h>
#include <berryIQtStyleManager.h>
namespace berry {
class QtPluginActivator : public QObject, public AbstractUICTKPlugin
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_blueberry_ui_qt")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
QtPluginActivator();
~QtPluginActivator();
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
private:
IQtStyleManager::Pointer styleManager;
};
}
#endif /* BERRYQTPLUGINACTIVATOR_H_ */
diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt/src/internal/berryQtShell.cpp b/BlueBerry/Bundles/org.blueberry.ui.qt/src/internal/berryQtShell.cpp
index 25c2e2f0ee..74b421c439 100755
--- a/BlueBerry/Bundles/org.blueberry.ui.qt/src/internal/berryQtShell.cpp
+++ b/BlueBerry/Bundles/org.blueberry.ui.qt/src/internal/berryQtShell.cpp
@@ -1,223 +1,224 @@
/*===================================================================
BlueBerry Platform
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/berryTweaklets.h>
+
#include "berryQtShell.h"
#include "berryQtWidgetsTweakletImpl.h"
#include "berryQtMainWindowControl.h"
#include <internal/berryQtControlWidget.h>
#include <berryConstants.h>
-#include <internal/berryTweaklets.h>
#include <tweaklets/berryGuiWidgetsTweaklet.h>
#include <QApplication>
#include <QVariant>
namespace berry
{
QtShell::QtShell(QWidget* parent, Qt::WindowFlags flags)
: updatesDisabled(false)
{
if (parent == 0 || flags.testFlag(Qt::Window))
{
widget = new QtMainWindowControl(this, parent, flags);
widget->setUpdatesEnabled(false);
updatesDisabled = true;
widget->setAttribute(Qt::WA_DeleteOnClose);
}
else
{
widget = new QtControlWidget(parent, this, flags | Qt::Dialog);
widget->setObjectName("shell widget");
}
}
QtShell::~QtShell()
{
widget->deleteLater();
}
void QtShell::SetBounds(const Rectangle& bounds)
{
widget->move(bounds.x, bounds.y);
widget->resize(bounds.width, bounds.height);
}
Rectangle QtShell::GetBounds() const
{
const QRect& qRect = widget->frameGeometry();
const QSize& size = widget->size();
Rectangle rect(qRect.x(), qRect.y(), size.width(), size.height());
return rect;
}
void QtShell::SetLocation(int x, int y)
{
widget->move(x, y);
}
Point QtShell::ComputeSize(int /*wHint*/, int /*hHint*/, bool changed)
{
if (changed) widget->updateGeometry();
QSize size(widget->size());
Point point(size.width(), size.height());
return point;
}
std::string QtShell::GetText() const
{
return widget->windowTitle().toStdString();
}
void QtShell::SetText(const std::string& text)
{
QString title(QString::fromStdString(text));
widget->setWindowTitle(title);
widget->setObjectName(title);
}
bool QtShell::IsVisible()
{
return widget->isVisible();
}
void QtShell::SetVisible(bool visible)
{
widget->setVisible(visible);
}
void QtShell::SetActive()
{
widget->activateWindow();
widget->raise();
}
void* QtShell::GetControl()
{
return widget;
}
void QtShell::SetImages(const std::vector<void*>& /*images*/)
{
}
bool QtShell::GetMaximized()
{
return widget->isMaximized();
}
bool QtShell::GetMinimized()
{
return widget->isMinimized();
}
void QtShell::SetMaximized(bool maximized)
{
maximized ? widget->showMaximized() : widget->showNormal();
}
void QtShell::SetMinimized(bool minimized)
{
minimized ? widget->showMinimized() : widget->showNormal();
}
void QtShell::AddShellListener(IShellListener::Pointer listener)
{
QVariant variant = widget->property(QtWidgetController::PROPERTY_ID);
poco_assert(variant.isValid());
QtWidgetController::Pointer controller = variant.value<QtWidgetController::Pointer>();
poco_assert(controller != 0);
controller->AddShellListener(listener);
}
void QtShell::RemoveShellListener(IShellListener::Pointer listener)
{
QVariant variant = widget->property(QtWidgetController::PROPERTY_ID);
if (variant.isValid())
{
QtWidgetController::Pointer controller = variant.value<QtWidgetController::Pointer>();
if (controller != 0)
controller->RemoveShellListener(listener);
}
}
void QtShell::Open(bool block)
{
if (updatesDisabled)
{
widget->setUpdatesEnabled(true);
updatesDisabled = false;
}
widget->setWindowModality(block ? Qt::WindowModal : Qt::NonModal);
widget->show();
}
void QtShell::Close()
{
widget->close();
}
std::vector<Shell::Pointer> QtShell::GetShells()
{
GuiWidgetsTweaklet* widgetTweaklet = Tweaklets::Get(GuiWidgetsTweaklet::KEY);
std::vector<Shell::Pointer> allShells(widgetTweaklet->GetShells());
std::vector<Shell::Pointer> descendants;
for (std::size_t i = 0; i < allShells.size(); ++i)
{
Shell::Pointer shell = allShells[i];
if (widgetTweaklet->GetShell(shell->GetControl()) == this)
{
descendants.push_back(shell);
}
}
return descendants;
}
int QtShell::GetStyle()
{
Qt::WindowFlags qtFlags = widget->windowFlags();
int berryFlags = 0;
if (!(qtFlags & Qt::FramelessWindowHint))
berryFlags |= Constants::BORDER;
if (qtFlags & Qt::WindowTitleHint)
berryFlags |= Constants::TITLE;
if (qtFlags & Qt::WindowSystemMenuHint)
berryFlags |= Constants::CLOSE;
if (qtFlags & Qt::WindowMinimizeButtonHint)
berryFlags |= Constants::MIN;
if (qtFlags & Qt::WindowMaximizeButtonHint)
berryFlags |= Constants::MAX;
if (widget->windowModality() == Qt::WindowModal)
berryFlags |= Constants::PRIMARY_MODAL;
else if(widget->windowModality() == Qt::ApplicationModal)
berryFlags |= Constants::APPLICATION_MODAL;
return berryFlags;
}
QWidget* QtShell::GetWidget()
{
return widget;
}
}
diff --git a/BlueBerry/Bundles/org.blueberry.ui.qt/src/internal/util/berryPresentablePartFolder.cpp b/BlueBerry/Bundles/org.blueberry.ui.qt/src/internal/util/berryPresentablePartFolder.cpp
index f1488aa669..3358f8fb96 100755
--- a/BlueBerry/Bundles/org.blueberry.ui.qt/src/internal/util/berryPresentablePartFolder.cpp
+++ b/BlueBerry/Bundles/org.blueberry.ui.qt/src/internal/util/berryPresentablePartFolder.cpp
@@ -1,435 +1,436 @@
/*===================================================================
BlueBerry Platform
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/berryQtWidgetsTweaklet.h"
+
#include "berryPresentablePartFolder.h"
#include "berryAbstractTabItem.h"
-#include "internal/berryQtWidgetsTweaklet.h"
#include <internal/berryQtControlWidget.h>
#include <berryConstants.h>
#include <internal/berryDragUtil.h>
namespace berry
{
PresentablePartFolder::ContentProxyListener::ContentProxyListener(
PresentablePartFolder* folder) :
folder(folder)
{
}
GuiTk::IControlListener::Events::Types PresentablePartFolder::ContentProxyListener::GetEventTypes() const
{
return Events::MOVED & Events::RESIZED;
}
void PresentablePartFolder::ContentProxyListener::ControlMoved(
GuiTk::ControlEvent::Pointer /*e*/)
{
folder->LayoutContent();
}
void PresentablePartFolder::ContentProxyListener::ControlResized(
GuiTk::ControlEvent::Pointer /*e*/)
{
}
PresentablePartFolder::ShellListener::ShellListener(AbstractTabFolder* _folder) :
folder(_folder)
{
}
void PresentablePartFolder::ShellListener::ShellActivated(ShellEvent::Pointer /*e*/)
{
folder->ShellActive(true);
}
void PresentablePartFolder::ShellListener::ShellDeactivated(
ShellEvent::Pointer /*e*/)
{
folder->ShellActive(false);
}
PresentablePartFolder::ChildPropertyChangeListener::ChildPropertyChangeListener(
PresentablePartFolder* folder) :
presentablePartFolder(folder)
{
}
void PresentablePartFolder::ChildPropertyChangeListener::PropertyChange(
Object::Pointer source, int property)
{
if (source.Cast<IPresentablePart> () != 0)
{
IPresentablePart::Pointer part = source.Cast<IPresentablePart> ();
presentablePartFolder->ChildPropertyChanged(part, property);
}
}
PartInfo PresentablePartFolder::tempPartInfo = PartInfo();
void PresentablePartFolder::LayoutContent()
{
if (current != 0)
{
Rectangle clientArea = DragUtil::GetDisplayBounds(contentProxy);
Rectangle bounds = Tweaklets::Get(GuiWidgetsTweaklet::KEY)->ToControl(
folder->GetControl()->parentWidget(), clientArea);
current->SetBounds(bounds);
}
}
void PresentablePartFolder::InternalRemove(IPresentablePart::Pointer toRemove)
{
AbstractTabItem* item = this->GetTab(toRemove);
if (item != 0) {
item->Dispose();
}
// do not use item anymore!
if (std::find(partList.begin(), partList.end(), toRemove) != partList.end())
{
toRemove->RemovePropertyListener(childPropertyChangeListener);
partList.remove(toRemove);
}
}
void PresentablePartFolder::ChildPropertyChanged(
IPresentablePart::Pointer part, int property)
{
AbstractTabItem* tab = this->GetTab(part);
if (property == IPresentablePart::PROP_HIGHLIGHT_IF_BACK)
{
if (tab != 0 && this->GetCurrent() != part)
{//Set bold if it doesn't currently have focus
tab->SetBold(true);
this->InitTab(tab, part);
}
}
// else if (property == IPresentablePart::PROP_TOOLBAR)
// {
// if (tab != 0 && this->GetCurrent() == part)
// {
// folder->FlushToolbarSize();
// }
// if (tab != 0)
// {
// this->InitTab(tab, part);
// if (this->GetCurrent() == part)
// {
// this->Layout(true);
// }
// }
else if (property == IPresentablePart::PROP_CONTENT_DESCRIPTION || property
== IPresentablePart::PROP_PANE_MENU || property
== IPresentablePart::PROP_TITLE)
{
if (tab != 0)
{
this->InitTab(tab, part);
if (this->GetCurrent() == part)
{
this->Layout(true);
}
}
}
else if (property == IPresentablePart::PROP_PREFERRED_SIZE)
{
TabFolderEvent::Pointer event(
new TabFolderEvent(TabFolderEvent::EVENT_PREFERRED_SIZE, tab, 0, 0));
folder->FireEvent(event);
}
else
{
if (tab != 0)
this->InitTab(tab, part);
}
}
PresentablePartFolder::~PresentablePartFolder()
{
Tweaklets::Get(QtWidgetsTweaklet::KEY)->GetShell(folder->GetControl())->RemoveShellListener(
shellListener);
for (std::list<IPresentablePart::Pointer>::iterator iter = partList.begin(); iter
!= partList.end(); ++iter)
{
(*iter)->RemovePropertyListener(childPropertyChangeListener);
}
for (QWidget* currentWidget = contentProxy; currentWidget != 0 && currentWidget
!= folder->GetControl()->parentWidget(); currentWidget = currentWidget->parentWidget())
{
Tweaklets::Get(GuiWidgetsTweaklet::KEY)->RemoveControlListener(currentWidget, contentListener);
}
BERRY_DEBUG << "DELETING PresentablePartFolder and contentProxy\n";
delete folder;
}
void PresentablePartFolder::InitTab(AbstractTabItem* item,
IPresentablePart::Pointer part)
{
tempPartInfo.Set(part);
item->SetInfo(tempPartInfo);
item->SetBusy(part->IsBusy());
if (part == this->GetCurrent())
{
folder->SetSelectedInfo(tempPartInfo);
//TODO Pane menu
//folder->EnablePaneMenu(part->GetMenu() != 0);
//setToolbar(part.getToolBar());
}
}
PresentablePartFolder::PresentablePartFolder(AbstractTabFolder* _folder) :
folder(_folder), isVisible(true), shellListener(new ShellListener(folder)),
childPropertyChangeListener(new ChildPropertyChangeListener(this))
{
Shell::Pointer controlShell =
Tweaklets::Get(QtWidgetsTweaklet::KEY)->GetShell(folder->GetControl());
controlShell->AddShellListener(shellListener);
folder->ShellActive(Tweaklets::Get(QtWidgetsTweaklet::KEY)->GetActiveShell()
== controlShell);
//folder.getControl().addDisposeListener(tabDisposeListener);
//toolbarProxy = new ProxyControl(folder.getToolbarParent());
// NOTE: if the shape of contentProxy changes, the fix for bug 85899 in EmptyTabFolder.computeSize may need adjustment.
contentListener = new ContentProxyListener(this);
contentProxy = new QtControlWidget(folder->GetContentParent(), 0);
contentProxy->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
//contentProxy->setVisible(false);
for (QWidget* currentWidget = contentProxy; currentWidget != 0 && currentWidget
!= folder->GetControl()->parentWidget(); currentWidget = currentWidget->parentWidget())
{
Tweaklets::Get(GuiWidgetsTweaklet::KEY)->AddControlListener(currentWidget, contentListener);
}
folder->SetContent(contentProxy);
}
std::vector<IPresentablePart::Pointer> PresentablePartFolder::GetPartList()
{
std::vector<AbstractTabItem*> items = folder->GetItems();
std::vector<IPresentablePart::Pointer> result;
for (unsigned int i = 0; i < items.size(); i++)
{
result.push_back(this->GetPartForTab(items[i]));
}
return result;
}
void PresentablePartFolder::Insert(IPresentablePart::Pointer part, int idx)
{
poco_assert(folder->GetControl() != 0);
if (this->GetTab(part) != 0)
{
if (this->IndexOf(part) != idx)
this->Move(part, idx);
return;
}
idx = std::min<int>(idx, static_cast<int>(folder->GetItemCount()));
AbstractTabItem* item = 0;
int style = 0;
if (part->IsCloseable())
{
style |= Constants::CLOSE;
}
item = folder->Add(idx, style);
item->SetData(part);
this->InitTab(item, part);
part->AddPropertyListener(childPropertyChangeListener);
partList.push_back(part);
}
void PresentablePartFolder::Remove(IPresentablePart::Pointer toRemove)
{
if (toRemove == current)
{
this->Select(IPresentablePart::Pointer(0));
}
this->InternalRemove(toRemove);
}
void PresentablePartFolder::Move(IPresentablePart::Pointer part, int newIndex)
{
int currentIndex = this->IndexOf(part);
if (currentIndex == newIndex)
{
return;
}
folder->Move(currentIndex, newIndex);
//this->InternalRemove(part);
//this->Insert(part, newIndex);
//if (current == part)
//{
// folder->SetSelection(this->GetTab(part));
//}
}
std::size_t PresentablePartFolder::Size()
{
return folder->GetItemCount();
}
void PresentablePartFolder::SetBounds(const QRect& bounds)
{
QSize minSize = folder->ComputeSize(bounds.width(), Constants::DEFAULT);
QRect newBounds(bounds);
if (folder->GetState() == IStackPresentationSite::STATE_MINIMIZED
&& minSize.height() < bounds.height())
{
newBounds.setHeight(minSize.height());
}
// Set the tab folder's bounds
folder->GetControl()->setGeometry(newBounds);
this->Layout(false);
}
void PresentablePartFolder::Select(IPresentablePart::Pointer toSelect)
{
if (toSelect == current)
{
return;
}
if (toSelect != 0)
{
toSelect->SetVisible(true);
}
if (current != 0)
{
current->SetVisible(false);
//setToolbar(null);
}
current = toSelect;
AbstractTabItem* selectedItem = this->GetTab(toSelect);
folder->SetSelection(selectedItem);
if (selectedItem != 0)
{
// Determine if we need to un-bold this tab
selectedItem->SetBold(false);
this->InitTab(selectedItem, toSelect);
}
// else
// {
// setToolbar(null);
// }
this->Layout(true);
}
IPresentablePart::Pointer PresentablePartFolder::GetPartForTab(
AbstractTabItem* tab)
{
if (tab == 0)
{
return IPresentablePart::Pointer(0);
}
IPresentablePart::Pointer part = tab->GetData().Cast<IPresentablePart> ();
return part;
}
AbstractTabItem* PresentablePartFolder::GetTab(IPresentablePart::Pointer part)
{
return folder->FindItem(part);
}
int PresentablePartFolder::IndexOf(IPresentablePart::Pointer part)
{
AbstractTabItem* item = this->GetTab(part);
if (item == 0)
{
return -1;
}
return folder->IndexOf(item);
}
AbstractTabFolder* PresentablePartFolder::GetTabFolder()
{
return folder;
}
void PresentablePartFolder::SetVisible(bool isVisible)
{
this->isVisible = isVisible;
this->GetTabFolder()->SetVisible(isVisible);
if (isVisible)
{
this->Layout(true);
}
}
void PresentablePartFolder::Layout(bool changed)
{
if (!isVisible)
{
// Don't bother with layout if we're not visible
return;
}
// Lay out the tab folder and compute the client area
folder->Layout(changed);
//toolbarProxy.layout();
this->LayoutContent();
}
IPresentablePart::Pointer PresentablePartFolder::GetCurrent()
{
return current;
}
}
diff --git a/BlueBerry/Bundles/org.blueberry.ui/CMakeLists.txt b/BlueBerry/Bundles/org.blueberry.ui/CMakeLists.txt
index 1a06997513..35fd0f80de 100644
--- a/BlueBerry/Bundles/org.blueberry.ui/CMakeLists.txt
+++ b/BlueBerry/Bundles/org.blueberry.ui/CMakeLists.txt
@@ -1,18 +1,22 @@
project(org_blueberry_ui)
set(PLUGIN_exported_include_suffixes
src
src/application
src/dialogs
src/guitk
src/handlers
src/intro
src/presentations
src/services
src/testing
src/tweaklets
src/util
)
MACRO_CREATE_CTK_PLUGIN(EXPORT_DIRECTIVE BERRY_UI
EXPORTED_INCLUDE_SUFFIXES ${PLUGIN_exported_include_suffixes})
+
+if(MITK_USE_Qt5)
+ qt5_use_modules(${PLUGIN_TARGET} Widgets)
+endif()
diff --git a/BlueBerry/Bundles/org.blueberry.ui/src/berryGeometry.cpp b/BlueBerry/Bundles/org.blueberry.ui/src/berryGeometry.cpp
index fa10ba0829..a47b2613b6 100755
--- a/BlueBerry/Bundles/org.blueberry.ui/src/berryGeometry.cpp
+++ b/BlueBerry/Bundles/org.blueberry.ui/src/berryGeometry.cpp
@@ -1,171 +1,166 @@
/*===================================================================
BlueBerry Platform
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.
===================================================================*/
-// needed under windows to suppress the definition of the
-// min/max macros in windows.h, which would clash with
-// std::numeric_limits<>::max()
-#define NOMINMAX
-
#include "tweaklets/berryGuiWidgetsTweaklet.h"
#include "berryGeometry.h"
#include "berryConstants.h"
#include <limits>
namespace berry
{
int Geometry::GetDimension(const Rectangle& toMeasure, bool width)
{
if (width)
{
return toMeasure.width;
}
return toMeasure.height;
}
bool Geometry::IsHorizontal(int berrySideConstant)
{
return !(berrySideConstant == Constants::LEFT || berrySideConstant
== Constants::RIGHT);
}
Rectangle Geometry::GetExtrudedEdge(const Rectangle& toExtrude, int size,
int orientation)
{
Rectangle bounds(toExtrude);
if (!IsHorizontal(orientation))
{
bounds.width = size;
}
else
{
bounds.height = size;
}
if (orientation == Constants::RIGHT)
{
bounds.x = toExtrude.x + toExtrude.width - bounds.width;
}
else if (orientation == Constants::BOTTOM)
{
bounds.y = toExtrude.y + toExtrude.height - bounds.height;
}
Normalize(bounds);
return bounds;
}
void Geometry::Normalize(Rectangle& rect)
{
if (rect.width < 0)
{
rect.width = -rect.width;
rect.x -= rect.width;
}
if (rect.height < 0)
{
rect.height = -rect.height;
rect.y -= rect.height;
}
}
int Geometry::GetClosestSide(const Rectangle& boundary, const Point& toTest)
{
int sides[] =
{ Constants::LEFT, Constants::RIGHT, Constants::TOP, Constants::BOTTOM };
int closestSide = Constants::LEFT;
int closestDistance = std::numeric_limits<int>::max();
for (unsigned int idx = 0; idx < 4; idx++)
{
int side = sides[idx];
int distance = GetDistanceFromEdge(boundary, toTest, side);
if (distance < closestDistance)
{
closestDistance = distance;
closestSide = side;
}
}
return closestSide;
}
int Geometry::GetDistanceFromEdge(const Rectangle& rectangle,
const Point& testPoint, int edgeOfInterest)
{
if (edgeOfInterest == Constants::TOP)
return testPoint.y - rectangle.y;
else if (edgeOfInterest == Constants::BOTTOM)
return rectangle.y + rectangle.height - testPoint.y;
else if (edgeOfInterest == Constants::LEFT)
return testPoint.x - rectangle.x;
else if (edgeOfInterest == Constants::RIGHT)
return rectangle.x + rectangle.width - testPoint.x;
return 0;
}
int Geometry::GetOppositeSide(int directionConstant)
{
if (directionConstant == Constants::TOP)
return Constants::BOTTOM;
else if (directionConstant == Constants::BOTTOM)
return Constants::TOP;
else if (directionConstant == Constants::LEFT)
return Constants::RIGHT;
else if (directionConstant == Constants::RIGHT)
return Constants::LEFT;
return directionConstant;
}
Rectangle Geometry::ToControl(void* coordinateSystem,
const Rectangle& toConvert)
{
return Tweaklets::Get(GuiWidgetsTweaklet::KEY)->ToControl(coordinateSystem,
toConvert);
}
Point Geometry::ToControl(void* coordinateSystem, const Point& toConvert)
{
return Tweaklets::Get(GuiWidgetsTweaklet::KEY)->ToControl(coordinateSystem,
toConvert);
}
Rectangle Geometry::ToDisplay(void* coordinateSystem,
const Rectangle& toConvert)
{
return Tweaklets::Get(GuiWidgetsTweaklet::KEY)->ToDisplay(coordinateSystem,
toConvert);
}
Point Geometry::ToDisplay(void* coordinateSystem, const Point& toConvert)
{
return Tweaklets::Get(GuiWidgetsTweaklet::KEY)->ToDisplay(coordinateSystem,
toConvert);
}
}
diff --git a/BlueBerry/Bundles/org.blueberry.ui/src/internal/berryEditorReference.cpp b/BlueBerry/Bundles/org.blueberry.ui/src/internal/berryEditorReference.cpp
index 908e66f910..a6937bfb49 100644
--- a/BlueBerry/Bundles/org.blueberry.ui/src/internal/berryEditorReference.cpp
+++ b/BlueBerry/Bundles/org.blueberry.ui/src/internal/berryEditorReference.cpp
@@ -1,574 +1,574 @@
/*===================================================================
BlueBerry Platform
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 "berryEditorReference.h"
-
#include "tweaklets/berryWorkbenchPageTweaklet.h"
+#include "berryEditorReference.h"
+
#include "berryEditorManager.h"
#include "berryEditorDescriptor.h"
#include "berryEditorRegistry.h"
#include "berryEditorSite.h"
#include "berryEditorAreaHelper.h"
#include "berryWorkbenchPlugin.h"
#include "berryWorkbenchPage.h"
#include "berryNullEditorInput.h"
#include "berryPartTester.h"
#include "berryImageDescriptor.h"
#include "berryPlatformUI.h"
#include "berryIWorkbenchPartConstants.h"
namespace berry
{
EditorReference::EditorReference(EditorManager* man,
IEditorInput::Pointer input, EditorDescriptor::Pointer desc,
IMemento::Pointer editorState) :
manager(man), expectingInputChange(false),
reportedMalfunctioningEditor(false)
{
this->InitListenersAndHandlers();
restoredInput = input;
this->editorState = editorState;
this->Init(desc->GetId(), "", desc->GetImageDescriptor(),
desc->GetLabel(), "");
}
EditorReference::EditorReference(EditorManager* man, IMemento::Pointer memento) :
manager(man), expectingInputChange(false),
reportedMalfunctioningEditor(false)
{
this->InitListenersAndHandlers();
this->editorMemento = memento;
if (manager->UseIPersistableEditor())
{
//editorState = editorMemento->GetChild(WorkbenchConstants::TAG_EDITOR_STATE);
}
else
{
editorState = 0;
}
// String id = memento.getString(IWorkbenchConstants.TAG_ID);
// String title = memento.getString(IWorkbenchConstants.TAG_TITLE);
// String tooltip = Util.safeString(memento
// .getString(IWorkbenchConstants.TAG_TOOLTIP));
// String partName = memento
// .getString(IWorkbenchConstants.TAG_PART_NAME);
//
// IMemento propBag = memento.getChild(IWorkbenchConstants.TAG_PROPERTIES);
// if (propBag != null)
// {
// IMemento[] props = propBag
// .getChildren(IWorkbenchConstants.TAG_PROPERTY);
// for (int i = 0; i < props.length; i++)
// {
// propertyCache.put(props[i].getID(), props[i].getTextData());
// }
// }
// For compatibility set the part name to the title if not found
// if (partName.empty())
// {
// partName = title;
// }
// Get the editor descriptor.
// EditorDescriptor::Pointer desc;
// if (id != null)
// {
// desc = getDescriptor(id);
// }
// // desc may be null if id is null or desc is not found, but findImage below handles this
// String location = memento.getString(IWorkbenchConstants.TAG_PATH);
// IPath path = location == null ? null : new Path(location);
// ImageDescriptor iDesc = this.manager.findImage(desc, path);
//
// this.name = memento.getString(IWorkbenchConstants.TAG_NAME);
// if (this.name == null)
// {
// this.name = title;
// }
// setPinned("true".equals(memento.getString(IWorkbenchConstants.TAG_PINNED))); //$NON-NLS-1$
//
// IMemento inputMem = memento.getChild(IWorkbenchConstants.TAG_INPUT);
// if (inputMem != null)
// {
// this.factoryId = inputMem
// .getString(IWorkbenchConstants.TAG_FACTORY_ID);
// }
//
// init(id, title, tooltip, iDesc, partName, ""); //$NON-NLS-1$
}
EditorDescriptor::Pointer EditorReference::GetDescriptor()
{
return this->GetDescriptor(this->GetId());
}
EditorDescriptor::Pointer EditorReference::GetDescriptor(const std::string& id)
{
EditorDescriptor::Pointer desc;
IEditorRegistry* reg = WorkbenchPlugin::GetDefault()->GetEditorRegistry();
desc = reg->FindEditor(id).Cast<EditorDescriptor> ();
return desc;
}
void EditorReference::InitListenersAndHandlers()
{
// Create a property change listener to track the "close editors automatically"
// preference and show/remove the pin icon on editors
// Only 1 listener will be created in the EditorManager when necessary
//this->manager->CheckCreateEditorPropListener();
// Create a keyboard shortcut handler for pinning editors
// Only 1 handler will be created in the EditorManager when necessary
//this->manager->CheckCreatePinEditorShortcutKeyHandler();
}
PartPane::Pointer EditorReference::CreatePane()
{
PartPane::Pointer pane(
new PartPane(IWorkbenchPartReference::Pointer(this), this->manager->page));
return pane;
//return Tweaklets::Get(WorkbenchTweaklet::KEY)->CreateEditorPane(this,
// this->manager->page);
}
void EditorReference::PinStatusUpdated()
{
//firePropertyChange(IWorkbenchPart.PROP_TITLE);
}
std::string EditorReference::GetFactoryId()
{
// IEditorPart editor = getEditor(false);
// if (editor != null)
// {
// IPersistableElement persistable = editor.getEditorInput()
// .getPersistable();
// if (persistable != null)
// {
// return persistable.getFactoryId();
// }
// return null;
// }
// return factoryId;
return "";
}
std::string EditorReference::ComputePartName()
{
return WorkbenchPartReference::ComputePartName();
}
std::string EditorReference::GetName()
{
if (part.IsNotNull())
{
return this->GetEditor(false)->GetEditorInput()->GetName();
}
return name;
}
IEditorPart::Pointer EditorReference::GetEditor(bool restore)
{
return this->GetPart(restore).Cast<IEditorPart> ();
}
void EditorReference::SetName(const std::string& name)
{
this->name = name;
}
IMemento::Pointer EditorReference::GetMemento()
{
return editorMemento;
}
IWorkbenchPage::Pointer EditorReference::GetPage() const
{
return IWorkbenchPage::Pointer(this->manager->page);
}
IEditorInput::Pointer EditorReference::GetEditorInput()
{
IEditorPart::Pointer part = this->GetEditor(false);
if (part.IsNotNull())
{
return part->GetEditorInput();
}
return this->GetRestoredInput();
}
IEditorInput::Pointer EditorReference::GetRestoredInput()
{
if (restoredInput.IsNotNull())
{
return restoredInput;
}
// Get the input factory.
// IMemento::Pointer editorMem = this->GetMemento();
// if (editorMem == null)
// {
// throw new PartInitException(NLS.bind(WorkbenchMessages.EditorManager_no_persisted_state, getId(), getName()));
// }
// IMemento inputMem = editorMem
// .getChild(IWorkbenchConstants.TAG_INPUT);
// String factoryID = null;
// if (inputMem != null)
// {
// factoryID = inputMem
// .getString(IWorkbenchConstants.TAG_FACTORY_ID);
// }
// if (factoryID == null)
// {
// throw new PartInitException(NLS.bind(WorkbenchMessages.EditorManager_no_input_factory_ID, getId(), getName()));
// }
// IAdaptable input = null;
// String label = null; // debugging only
// if (UIStats.isDebugging(UIStats.CREATE_PART_INPUT))
// {
// label = getName() != null ? getName() : factoryID;
// }
// try
// {
// UIStats.start(UIStats.CREATE_PART_INPUT, label);
// IElementFactory factory = PlatformUI.getWorkbench()
// .getElementFactory(factoryID);
// if (factory == null)
// {
// throw new PartInitException(NLS.bind(WorkbenchMessages.EditorManager_bad_element_factory, new Object[]
// { factoryID, getId(), getName()}));
// }
//
// // Get the input element.
// input = factory.createElement(inputMem);
// if (input == null)
// {
// throw new PartInitException(NLS.bind(WorkbenchMessages.EditorManager_create_element_returned_null, new Object[]
// { factoryID, getId(), getName()}));
// }
// }finally
// {
// UIStats.end(UIStats.CREATE_PART_INPUT, input, label);
// }
// if (!(input instanceof IEditorInput))
// {
// throw new PartInitException(NLS.bind(WorkbenchMessages.EditorManager_wrong_createElement_result, new Object[]
// { factoryID, getId(), getName()}));
// }
// restoredInput = (IEditorInput) input;
return restoredInput;
}
IWorkbenchPart::Pointer EditorReference::CreatePart()
{
if (EditorRegistry::EMPTY_EDITOR_ID == this->GetId())
{
return this->GetEmptyEditor(this->GetDescriptor());
}
IWorkbenchPart::Pointer result;
// Try to restore the editor -- this does the real work of restoring the editor
//
try
{
result = this->CreatePartHelper().Cast<IWorkbenchPart> ();
} catch (PartInitException e)
{
// If unable to create the part, create an error part instead
// and pass the error to the status handling facility
// IStatus originalStatus = exception.getStatus();
// IStatus logStatus = StatusUtil.newStatus(originalStatus,
// NLS.bind("Unable to create editor ID {0}: {1}", //$NON-NLS-1$
// getId(), originalStatus.getMessage()));
// IStatus displayStatus = StatusUtil.newStatus(originalStatus,
// NLS.bind(WorkbenchMessages.EditorManager_unableToCreateEditor,
// originalStatus.getMessage()));
WorkbenchPlugin::Log("Unable to create editor ID " + this->GetId() + ": "
+ e.displayText());
// Pass the error to the status handling facility
//StatusManager.getManager().handle(logStatus);
EditorDescriptor::Pointer descr = this->GetDescriptor();
std::string label = this->GetId();
if (descr.IsNotNull())
label = descr->GetLabel();
IEditorPart::Pointer part =
Tweaklets::Get(WorkbenchPageTweaklet::KEY)->CreateErrorEditorPart(label,
e.displayText());
if (part.IsNotNull())
{
IEditorInput::Pointer input;
try
{
input = this->GetEditorInput();
} catch (PartInitException e1)
{
input = new NullEditorInput(EditorReference::Pointer(this));
}
PartPane::Pointer pane = this->GetPane();
pane->CreateControl(
manager->page->GetEditorPresentation()->GetLayoutPart()->GetControl());
EditorSite::Pointer site(
new EditorSite(IEditorReference::Pointer(this), part, manager->page, descr));
//site.setActionBars(new EditorActionBars(manager.page, site.getWorkbenchWindow(), getId()));
part->Init(site, input);
try
{
part->CreatePartControl(pane->GetControl());
} catch (...)
{
//content.dispose();
//StatusUtil.handleStatus(e, StatusManager.SHOW
// | StatusManager.LOG);
WorkbenchPlugin::Log("Error creating editor");
return IWorkbenchPart::Pointer(0);
}
result = part.Cast<IWorkbenchPart> ();
}
}
return result;
}
void EditorReference::PropertyChanged(Object::Pointer source, int propId)
{
// Detect badly behaved editors that don't fire PROP_INPUT events
// when they're supposed to. This branch is only needed to handle
// malfunctioning editors.
if (propId == IWorkbenchPartConstants::PROP_INPUT)
{
expectingInputChange = false;
}
WorkbenchPartReference::PropertyChanged(source, propId);
}
bool EditorReference::SetInput(IEditorInput::Pointer input)
{
if (part.IsNotNull())
{
if (part.Cast<IReusableEditor> ().IsNotNull())
{
IReusableEditor::Pointer editor = part.Cast<IReusableEditor> ();
expectingInputChange = true;
editor->SetInput(input);
// If the editor never fired a PROP_INPUT event, log the fact that we've discovered
// a buggy editor and fire the event for free. Firing the event for free isn't required
// and cannot be relied on (it only works if the input change was triggered by this
// method, and there are definitely other cases where events will still be lost),
// but older versions of the workbench did this so we fire it here in the spirit
// of playing nice.
if (expectingInputChange)
{
// Log the fact that this editor is broken
this->ReportMalfunction(
"Editor is not firing a PROP_INPUT event in response to IReusableEditor.setInput(...)"); //$NON-NLS-1$
// Fire the property for free (can't be relied on since there are other ways the input
// can change, but we do it here to be consistent with older versions of the workbench)
FirePropertyChange(IWorkbenchPartConstants::PROP_INPUT);
}
return editor->GetEditorInput() == input;
}
// Can't change the input if the editor already exists and isn't an IReusableEditor
return false;
}
// Changing the input is trivial and always succeeds if the editor doesn't exist yet
if (input != restoredInput)
{
restoredInput = input;
//firePropertyChange(IWorkbenchPartConstants.PROP_INPUT);
}
return true;
}
void EditorReference::ReportMalfunction(const std::string& string)
{
if (!reportedMalfunctioningEditor)
{
reportedMalfunctioningEditor = true;
std::string errorMessage = "Problem detected with part " + this->GetId(); //$NON-NLS-1$
if (part.IsNotNull())
{
errorMessage.append("(class = ").append(part->GetClassName()).append(
")"); //$NON-NLS-1$ //$NON-NLS-2$
}
errorMessage += ": " + string; //$NON-NLS-1$
//StatusManager.getManager().handle(StatusUtil.newStatus(getDescriptor().getPluginId(), errorMessage, null));
BERRY_ERROR << errorMessage << std::endl;
}
}
IEditorPart::Pointer EditorReference::CreatePartHelper()
{
EditorSite::Pointer site;
IEditorPart::Pointer part;
try
{
IEditorInput::Pointer editorInput = this->GetEditorInput();
// Get the editor descriptor.
std::string editorID = this->GetId();
EditorDescriptor::Pointer desc = this->GetDescriptor();
if (desc.IsNull())
{
throw PartInitException("No editor descriptor for id " + editorID);
}
if (desc->IsInternal())
{
// Create an editor instance.
part = manager->CreatePart(desc);
this->CreatePartProperties(part);
}
// else if (desc->GetId() == IEditorRegistry.SYSTEM_INPLACE_EDITOR_ID)
// {
//
// part = ComponentSupport.getSystemInPlaceEditor();
//
// if (part == null)
// {
// throw new PartInitException(WorkbenchMessages.EditorManager_no_in_place_support);
// }
// }
else
{
throw PartInitException("Invalid editor descriptor for id " + editorID);
}
// Create a pane for this part
PartPane::Pointer pane = this->GetPane();
pane->CreateControl(manager->page->GetEditorPresentation()->GetLayoutPart()->GetControl());
// Link everything up to the part reference (the part reference itself should not have
// been modified until this point)
site = manager->CreateSite(IEditorReference::Pointer(this), part, desc, editorInput);
// if there is saved state that's appropriate, pass it on
if (/*part instanceof IPersistableEditor &&*/editorState.IsNotNull())
{
//part->RestoreState(editorState);
}
// Remember the site and the action bars (now that we've created them, we'll need to dispose
// them if an exception occurs)
//actionBars = (EditorActionBars) site.getActionBars();
part->CreatePartControl(pane->GetControl());
// The editor should now be fully created. Exercise its public interface, and sanity-check
// it wherever possible. If it's going to throw exceptions or behave badly, it's much better
// that it does so now while we can still cancel creation of the part.
PartTester::TestEditor(part);
return part;
} catch (std::exception e)
{
throw PartInitException(e.what());
}
}
IEditorPart::Pointer EditorReference::GetEmptyEditor(
EditorDescriptor::Pointer descr)
{
IEditorPart::Pointer part =
Tweaklets::Get(WorkbenchPageTweaklet::KEY)->CreateErrorEditorPart("(Empty)", "");
IEditorInput::Pointer input;
try
{
input = this->GetEditorInput();
} catch (PartInitException e1)
{
input = new NullEditorInput(EditorReference::Pointer(this));
}
PartPane::Pointer pane = this->GetPane();
pane->CreateControl(
manager->page->GetEditorPresentation()->GetLayoutPart()->GetControl());
EditorSite::Pointer site(new EditorSite(IEditorReference::Pointer(this),
part, manager->page, descr));
//site.setActionBars(new EditorActionBars(manager.page, site.getWorkbenchWindow(), getId()));
part->Init(site, input);
try
{
part->CreatePartControl(pane->GetControl());
} catch (std::exception e)
{
//StatusManager.getManager().handle(
// StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH, e));
BERRY_ERROR << e.what() << std::endl;
return IEditorPart::Pointer(0);
}
this->part = part.Cast<IWorkbenchPart> ();
// Add a dispose listener to the part. This dispose listener does nothing but log an exception
// if the part's widgets get disposed unexpectedly. The workbench part reference is the only
// object that should dispose this control, and it will remove the listener before it does so.
this->RefreshFromPart();
//this->ReleaseReferences();
if (this->GetPage().Cast<WorkbenchPage> ()->GetActiveEditorReference()
!= this)
{
//fireInternalPropertyChange(INTERNAL_PROPERTY_OPENED);
}
return part;
}
}
diff --git a/BlueBerry/Bundles/org.blueberry.ui/src/internal/berryWorkbenchPlugin.cpp b/BlueBerry/Bundles/org.blueberry.ui/src/internal/berryWorkbenchPlugin.cpp
index d6135c9df3..abd5852d19 100644
--- a/BlueBerry/Bundles/org.blueberry.ui/src/internal/berryWorkbenchPlugin.cpp
+++ b/BlueBerry/Bundles/org.blueberry.ui/src/internal/berryWorkbenchPlugin.cpp
@@ -1,329 +1,333 @@
/*===================================================================
BlueBerry Platform
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 "berryLog.h"
#include "berryWorkbenchPlugin.h"
#include "berryWorkbenchRegistryConstants.h"
#include "berryWorkbench.h"
#include "berryPlatform.h"
#include "intro/berryEditorIntroAdapterPart.h"
#include "berryImageDescriptor.h"
#include <Poco/String.h>
#include <QDebug>
namespace berry
{
bool WorkbenchPlugin::DEBUG = false;
char WorkbenchPlugin::PREFERENCE_PAGE_CATEGORY_SEPARATOR = '/';
WorkbenchPlugin* WorkbenchPlugin::inst = 0;
WorkbenchPlugin::WorkbenchPlugin()
: AbstractUICTKPlugin()
{
inst = this;
presentationFactory = 0;
editorRegistry = 0;
viewRegistry = 0;
perspRegistry = 0;
introRegistry = 0;
}
WorkbenchPlugin::~WorkbenchPlugin()
{
delete editorRegistry;
delete viewRegistry;
delete perspRegistry;
delete introRegistry;
}
bool WorkbenchPlugin::HasExecutableExtension(
IConfigurationElement::Pointer element, const std::string& extensionName)
{
std::string attr;
if (element->GetAttribute(extensionName, attr))
return true;
std::string elementText(element->GetValue());
if (elementText != "")
return true;
IConfigurationElement::vector children(element->GetChildren(extensionName));
if (children.size() == 1)
{
if (children[0]->GetAttribute(WorkbenchRegistryConstants::ATT_CLASS, attr))
return true;
}
return false;
}
bool WorkbenchPlugin::IsBundleLoadedForExecutableExtension(
IConfigurationElement::Pointer element, const std::string& extensionName)
{
IBundle::Pointer bundle(WorkbenchPlugin::GetBundleForExecutableExtension(element, extensionName));
if (bundle.IsNull())
return true;
return bundle->GetState() == IBundle::BUNDLE_ACTIVE;
}
IBundle::Pointer WorkbenchPlugin::GetBundleForExecutableExtension(
IConfigurationElement::Pointer element, const std::string& extensionName)
{
// this code is derived heavily from
// ConfigurationElement.createExecutableExtension.
std::string prop;
std::string executable;
std::string contributorName;
std::string::size_type i;
if (extensionName != "")
element->GetAttribute(extensionName, prop);
else
{
// property not specified, try as element value
prop = element->GetValue();
if (prop != "")
{
Poco::trimInPlace(prop);
}
}
if (prop == "")
{
// property not defined, try as a child element
IConfigurationElement::vector exec(element->GetChildren(extensionName));
if (exec.size() != 0)
exec[0]->GetAttribute("plugin", contributorName); //$NON-NLS-1$
}
else
{
// simple property or element value, parse it into its components
i = prop.find_first_of(':');
if (i != std::string::npos)
executable = Poco::trim(prop.substr(0, i));
else
executable = prop;
i = executable.find_first_of('/');
if (i != std::string::npos)
contributorName = Poco::trim(executable.substr(0, i));
}
if (contributorName == "")
contributorName = element->GetContributor();
return Platform::GetBundle(contributorName);
}
WorkbenchPlugin* WorkbenchPlugin::GetDefault()
{
return inst;
}
std::size_t WorkbenchPlugin::GetBundleCount()
{
// TODO BundleContext GetBundles
//return bundleContext->GetBundles().size();
return 0;
}
// ImageRegistry createImageRegistry() {
// return WorkbenchImages.getImageRegistry();
// }
IPerspectiveRegistry* WorkbenchPlugin::GetPerspectiveRegistry() {
if (perspRegistry == 0) {
perspRegistry = new PerspectiveRegistry();
// the load methods can touch on WorkbenchImages if an image is
// missing so we need to wrap the call in
// a startup block for the case where a custom descriptor exists on
// startup that does not have an image
// associated with it. See bug 196352.
//StartupThreading.runWithoutExceptions(new StartupRunnable() {
// public void runWithException() throws Throwable {
perspRegistry->Load();
// }
//});
}
return perspRegistry;
}
// PreferenceManager getPreferenceManager() {
// if (preferenceManager == null) {
// preferenceManager = new WorkbenchPreferenceManager(
// PREFERENCE_PAGE_CATEGORY_SEPARATOR);
//
// //Get the pages from the registry
// PreferencePageRegistryReader registryReader = new PreferencePageRegistryReader(
// getWorkbench());
// registryReader
// .loadFromRegistry(Platform.getExtensionRegistry());
// preferenceManager.addPages(registryReader.getTopLevelNodes());
//
// }
// return preferenceManager;
// }
// ISharedImages getSharedImages() {
// if (sharedImages == null) {
// sharedImages = new SharedImages();
// }
// return sharedImages;
// }
IIntroRegistry* WorkbenchPlugin::GetIntroRegistry()
{
if (introRegistry == 0)
{
introRegistry = new IntroRegistry();
}
return introRegistry;
}
IViewRegistry* WorkbenchPlugin::GetViewRegistry()
{
if (!viewRegistry)
viewRegistry = new ViewRegistry();
return viewRegistry;
}
IEditorRegistry* WorkbenchPlugin::GetEditorRegistry()
{
if (!editorRegistry)
editorRegistry = new EditorRegistry();
return editorRegistry;
}
IPresentationFactory* WorkbenchPlugin::GetPresentationFactory() {
if (presentationFactory != 0) return presentationFactory;
std::string targetID = Workbench::GetInstance()->GetPresentationId();
presentationFactory = this->CreateExtension<IPresentationFactory>(
WorkbenchRegistryConstants::PL_PRESENTATION_FACTORIES,
"factory", targetID);
if (presentationFactory == 0)
WorkbenchPlugin::Log("Error creating presentation factory: " +
targetID + " -- class is not an IPresentationFactory");
return presentationFactory;
}
void WorkbenchPlugin::Log(const std::string& message)
{
BERRY_INFO << "LOG: " << message << std::endl;
//inst->GetLog().log(message);
}
void WorkbenchPlugin::Log(const Poco::RuntimeException& exc)
{
BERRY_INFO << "LOG: " << exc.message() << std::endl;
//inst->GetLog().log(exc);
}
void WorkbenchPlugin::Log(const std::string& message, const Poco::RuntimeException& t)
{
PlatformException exc(message, t);
WorkbenchPlugin::Log(exc);
}
void WorkbenchPlugin::Log(const std::string& clazz,
const std::string& methodName, const Poco::RuntimeException& t)
{
std::string msg = "Exception in " + clazz + "." + methodName + ": "
+ t.what();
WorkbenchPlugin::Log(msg, t);
}
void WorkbenchPlugin::start(ctkPluginContext* context)
{
//context.addBundleListener(getBundleListener());
AbstractUICTKPlugin::start(context);
bundleContext = context;
BERRY_REGISTER_EXTENSION_CLASS(EditorIntroAdapterPart, context)
// The UI plugin needs to be initialized so that it can install the callback in PrefUtil,
// which needs to be done as early as possible, before the workbench
// accesses any API preferences.
// Bundle uiBundle = Platform.getBundle(PlatformUI.PLUGIN_ID);
// try
// {
// // Attempt to load the activator of the ui bundle. This will force lazy start
// // of the ui bundle. Using the bundle activator class here because it is a
// // class that needs to be loaded anyway so it should not cause extra classes
// // to be loaded.
// if(uiBundle != null)
// uiBundle.loadClass(UI_BUNDLE_ACTIVATOR);
// }
// catch (ClassNotFoundException e)
// {
// WorkbenchPlugin.log("Unable to load UI activator", e); //$NON-NLS-1$
// }
/*
* DO NOT RUN ANY OTHER CODE AFTER THIS LINE. If you do, then you are
* likely to cause a deadlock in class loader code. Please see Bug 86450
* for more information.
*/
}
//const std::vector<IBundle::Pointer> WorkbenchPlugin::GetBundles()
//{
// return bundleContext.IsNull() ? std::vector<IBundle::Pointer>() : bundleContext->GetBundles();
//}
ctkPluginContext* WorkbenchPlugin::GetPluginContext()
{
return bundleContext;
}
void WorkbenchPlugin::stop(ctkPluginContext* context)
{
AbstractUICTKPlugin::stop(context);
delete perspRegistry;
+ // avoid possible crash, see bug #18399
+ perspRegistry = 0;
}
bool WorkbenchPlugin::GetDataPath(Poco::Path& path)
{
QFileInfo fileInfo = bundleContext->getDataFile("");
path.assign(fileInfo.absolutePath().toStdString() + '/');
return fileInfo.isWritable();
}
}
-Q_EXPORT_PLUGIN2(org_blueberry_ui, berry::WorkbenchPlugin)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_blueberry_ui, berry::WorkbenchPlugin)
+#endif
diff --git a/BlueBerry/Bundles/org.blueberry.ui/src/internal/berryWorkbenchPlugin.h b/BlueBerry/Bundles/org.blueberry.ui/src/internal/berryWorkbenchPlugin.h
index f4577ff2aa..7c7753a1b5 100644
--- a/BlueBerry/Bundles/org.blueberry.ui/src/internal/berryWorkbenchPlugin.h
+++ b/BlueBerry/Bundles/org.blueberry.ui/src/internal/berryWorkbenchPlugin.h
@@ -1,474 +1,477 @@
/*===================================================================
BlueBerry Platform
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 BERRYWORKBENCHPLUGIN_H_
#define BERRYWORKBENCHPLUGIN_H_
#include <Poco/Path.h>
#include <berryIExtensionPoint.h>
#include <berryIExtensionPointService.h>
#include <berryPlatform.h>
#include "berryAbstractUICTKPlugin.h"
#include "berryPlatformUI.h"
#include "presentations/berryIPresentationFactory.h"
#include "berryViewRegistry.h"
#include "berryEditorRegistry.h"
#include "berryPerspectiveRegistry.h"
#include "intro/berryIntroRegistry.h"
namespace berry {
/**
* \ingroup org_blueberry_ui_internal
*
* This class represents the TOP of the workbench UI world
* A plugin class is effectively an application wrapper
* for a plugin & its classes. This class should be thought
* of as the workbench UI's application class.
*
* This class is responsible for tracking various registries
* font, preference, graphics, dialog store.
*
* This class is explicitly referenced by the
* workbench plugin's "plugin.xml" and places it
* into the UI start extension point of the main
* overall application harness
*
* When is this class started?
* When the Application
* calls createExecutableExtension to create an executable
* instance of our workbench class.
*/
class WorkbenchPlugin : public QObject, public AbstractUICTKPlugin {
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_blueberry_ui")
+#endif
Q_INTERFACES(ctkPluginActivator)
private:
//static const std::string UI_BUNDLE_ACTIVATOR = "org.blueberry.ui.internal.UIPlugin"; //$NON-NLS-1$
// Default instance of the receiver
static WorkbenchPlugin* inst;
// The presentation factory
IPresentationFactory* presentationFactory;
// Manager that maps resources to descriptors of editors to use
EditorRegistry* editorRegistry;
// The context within which this plugin was started.
ctkPluginContext* bundleContext;
// Other data.
//WorkbenchPreferenceManager preferenceManager;
ViewRegistry* viewRegistry;
PerspectiveRegistry* perspRegistry;
IntroRegistry* introRegistry;
//SharedImages sharedImages;
public:
/**
* Global workbench ui plugin flag. Only workbench implementation is allowed to use this flag
* All other plugins, examples, or test cases must *not* use this flag.
*/
static bool DEBUG;
/**
* The character used to separate preference page category ids
*/
static char PREFERENCE_PAGE_CATEGORY_SEPARATOR;
/**
* Create an instance of the WorkbenchPlugin. The workbench plugin is
* effectively the "application" for the workbench UI. The entire UI
* operates as a good plugin citizen.
*/
WorkbenchPlugin();
~WorkbenchPlugin();
/**
* Creates an extension. If the extension plugin has not
* been loaded a busy cursor will be activated during the duration of
* the load.
*
* @param element the config element defining the extension
* @param classAttribute the name of the attribute carrying the class
* @return the extension object
* @throws CoreException if the extension cannot be created
*/
// template<class E>
// static E* CreateExtension(IConfigurationElement::ConstPointer element,
// const std::string& classAttribute) {
// try {
// // If plugin has been loaded create extension.
// // Otherwise, show busy cursor then create extension.
// if (BundleUtility.isActivated(element.getDeclaringExtension()
// .getNamespace())) {
// return element.createExecutableExtension(classAttribute);
// }
// final Object[] ret = new Object[1];
// final CoreException[] exc = new CoreException[1];
// BusyIndicator.showWhile(null, new Runnable() {
// public void run() {
// try {
// ret[0] = element
// .createExecutableExtension(classAttribute);
// } catch (CoreException e) {
// exc[0] = e;
// }
// }
// });
// if (exc[0] != null) {
// throw exc[0];
// }
// return ret[0];
//
// } catch (CoreException core) {
// throw core;
// } catch (Exception e) {
// throw new CoreException(new Status(IStatus.ERR, PI_WORKBENCH,
// IStatus.ERR, WorkbenchMessages.WorkbenchPlugin_extension,e));
// }
// }
/**
* Answers whether the provided element either has an attribute with the
* given name or a child element with the given name with an attribute
* called class.
*
* @param element
* the element to test
* @param extensionName
* the name of the extension to test for
* @return whether or not the extension is declared
* @since 3.3
*/
static bool HasExecutableExtension(IConfigurationElement::Pointer element,
const std::string& extensionName);
/**
* Checks to see if the provided element has the syntax for an executable
* extension with a given name that resides in a bundle that is already
* active. Determining the bundle happens in one of two ways:<br/>
* <ul>
* <li>The element has an attribute with the specified name or element text
* in the form <code>bundle.id/class.name[:optional attributes]</code></li>
* <li>The element has a child element with the specified name that has a
* <code>plugin</code> attribute</li>
* </ul>
*
* @param element
* the element to test
* @param extensionName
* the name of the extension to test for
* @return whether or not the bundle expressed by the above criteria is
* active. If the bundle cannot be determined then the state of the
* bundle that declared the element is returned.
* @since 3.3
*/
static bool IsBundleLoadedForExecutableExtension(
IConfigurationElement::Pointer element, const std::string& extensionName);
/**
* Returns the bundle that contains the class referenced by an executable
* extension. Determining the bundle happens in one of two ways:<br/>
* <ul>
* <li>The element has an attribute with the specified name or element text
* in the form <code>bundle.id/class.name[:optional attributes]</code></li>
* <li>The element has a child element with the specified name that has a
* <code>plugin</code> attribute</li>
* </ul>
*
* @param element
* the element to test
* @param extensionName
* the name of the extension to test for
* @return the bundle referenced by the extension. If that bundle cannot be
* determined the bundle that declared the element is returned. Note
* that this may be <code>null</code>.
* @since 3.3
*/
static IBundle::Pointer GetBundleForExecutableExtension(IConfigurationElement::Pointer element, const std::string& extensionName);
/**
* Return the default instance of the receiver. This represents the runtime plugin.
* @return WorkbenchPlugin
* @see AbstractUICTKPlugin for the typical implementation pattern for plugin classes.
*/
static WorkbenchPlugin* GetDefault();
std::size_t GetBundleCount();
/**
* Answer the manager that maps resource types to a the
* description of the editor to use
* @return IEditorRegistry the editor registry used
* by this plug-in.
*/
IEditorRegistry* GetEditorRegistry();
/**
* Returns the presentation factory with the given id, or <code>null</code> if not found.
* @param targetID The id of the presentation factory to use.
* @return IPresentationFactory or <code>null</code>
* if not factory matches that id.
*/
IPresentationFactory* GetPresentationFactory();
protected:
/**
* Returns the image registry for this plugin.
*
* Where are the images? The images (typically gifs) are found in the same
* plugins directory.
*
* @see ImageRegistry
*
* Note: The workbench uses the standard JFace ImageRegistry to track its
* images. In addition the class WorkbenchGraphicResources provides
* convenience access to the graphics resources and fast field access for
* some of the commonly used graphical images.
*/
// ImageRegistry createImageRegistry();
private:
/**
* Looks up the configuration element with the given id on the given extension point
* and instantiates the class specified by the class attributes.
*
* @param extensionPointId the extension point id (simple id)
* @param elementName the name of the configuration element, or <code>null</code>
* to match any element
* @param targetID the target id
* @return the instantiated extension object, or <code>null</code> if not found
*/
template<class C>
C* CreateExtension(const std::string extensionPointId, const std::string& elementName,
const std::string& targetID) {
const IExtensionPoint* extensionPoint = Platform::GetExtensionPointService()
->GetExtensionPoint("" + PlatformUI::PLUGIN_ID + "." + extensionPointId);
if (extensionPoint == 0) {
WorkbenchPlugin
::Log("Unable to find extension. Extension point: " + extensionPointId + " not found"); //$NON-NLS-1$ //$NON-NLS-2$
return 0;
}
// Loop through the config elements.
IConfigurationElement::Pointer targetElement(0);
IConfigurationElement::vector elements(Platform::GetExtensionPointService()
->GetConfigurationElementsFor("" + PlatformUI::PLUGIN_ID + "." + extensionPointId));
for (unsigned int j = 0; j < elements.size(); j++) {
if (elementName == "" || elementName == elements[j]->GetName()) {
std::string strID;
elements[j]->GetAttribute("id", strID);
if (targetID == strID) {
targetElement = elements[j];
break;
}
}
}
if (targetElement.IsNull()) {
// log it since we cannot safely display a dialog.
WorkbenchPlugin::Log("Unable to find extension: " + targetID //$NON-NLS-1$
+ " in extension point: " + extensionPointId); //$NON-NLS-1$
return 0;
}
// Create the extension.
try {
C* impl = targetElement->CreateExecutableExtension<C>("class"); //$NON-NLS-1$
if (impl == 0)
{
// support legacy BlueBerry extensions
impl = targetElement->CreateExecutableExtension<C>("class", C::GetManifestName());
}
return impl;
} catch (CoreException e) {
// log it since we cannot safely display a dialog.
WorkbenchPlugin::Log("Unable to create extension: " + targetID //$NON-NLS-1$
+ " in extension point: " + extensionPointId); //$NON-NLS-1$
}
return 0;
}
public:
/**
* Return the perspective registry.
* @return IPerspectiveRegistry. The registry for the receiver.
*/
IPerspectiveRegistry* GetPerspectiveRegistry();
/**
* Returns the introduction registry.
*
* @return the introduction registry.
* @since 3.0
*/
IIntroRegistry* GetIntroRegistry();
/**
* Get the preference manager.
* @return PreferenceManager the preference manager for
* the receiver.
*/
// PreferenceManager getPreferenceManager();
/**
* Returns the shared images for the workbench.
*
* @return the shared image manager
*/
// ISharedImages getSharedImages();
/**
* Answer the view registry.
* @return IViewRegistry the view registry for the
* receiver.
*/
IViewRegistry* GetViewRegistry();
/**
* Logs the given message to the platform log.
*
* If you have an exception in hand, call log(String, Throwable) instead.
*
* If you have a status object in hand call log(String, IStatus) instead.
*
* This convenience method is for internal use by the Workbench only and
* must not be called outside the Workbench.
*
* @param message
* A high level UI message describing when the problem happened.
*/
static void Log(const std::string& message);
/**
* Log the throwable.
* @param t
*/
static void Log(const Poco::RuntimeException& exc);
/**
* Logs the given message and throwable to the platform log.
*
* If you have a status object in hand call log(String, IStatus) instead.
*
* This convenience method is for internal use by the Workbench only and
* must not be called outside the Workbench.
*
* @param message
* A high level UI message describing when the problem happened.
* @param t
* The throwable from where the problem actually occurred.
*/
static void Log(const std::string& message, const Poco::RuntimeException& t);
/**
* Logs the given throwable to the platform log, indicating the class and
* method from where it is being logged (this is not necessarily where it
* occurred).
*
* This convenience method is for internal use by the Workbench only and
* must not be called outside the Workbench.
*
* @param clazz
* The calling class.
* @param methodName
* The calling method name.
* @param t
* The throwable from where the problem actually occurred.
*/
static void Log(const std::string& clazz, const std::string& methodName, const Poco::RuntimeException& t);
/*
* (non-Javadoc)
* @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
*/
void start(ctkPluginContext* context);
/**
* Return an array of all bundles contained in this workbench.
*
* @return an array of bundles in the workbench or an empty array if none
* @since 3.0
*/
//const std::vector<IBundle::Pointer> GetBundles();
/**
* Returns the bundle context associated with the workbench plug-in.
*
* @return the bundle context
* @since 3.1
*/
ctkPluginContext* GetPluginContext();
/* (non-Javadoc)
* @see org.blueberry.ui.plugin.AbstractUICTKPlugin#stop(org.osgi.framework.BundleContext)
*/
void stop(ctkPluginContext* context);
/**
* FOR INTERNAL WORKBENCH USE ONLY.
*
* Returns the path to a location in the file system that can be used
* to persist/restore state between workbench invocations.
* If the location did not exist prior to this call it will be created.
* Returns <code>null</code> if no such location is available.
*
* @return path to a location in the file system where this plug-in can
* persist data between sessions, or <code>null</code> if no such
* location is available.
* @since 3.1
*/
bool GetDataPath(Poco::Path& path);
};
}
#endif /*BERRYWORKBENCHPLUGIN_H_*/
diff --git a/BlueBerry/Bundles/org.blueberry.uitest/src/internal/berryPluginActivator.cpp b/BlueBerry/Bundles/org.blueberry.uitest/src/internal/berryPluginActivator.cpp
index 1135ff4e0e..00ad1a8952 100644
--- a/BlueBerry/Bundles/org.blueberry.uitest/src/internal/berryPluginActivator.cpp
+++ b/BlueBerry/Bundles/org.blueberry.uitest/src/internal/berryPluginActivator.cpp
@@ -1,45 +1,47 @@
/*===================================================================
BlueBerry Platform
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 "berryPluginActivator.h"
#include "berryUITestApplication.h"
#include "util/berryEmptyPerspective.h"
#include <QtPlugin>
namespace berry {
org_blueberry_uitest_Activator::org_blueberry_uitest_Activator()
{
}
void org_blueberry_uitest_Activator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(UITestApplication, context)
BERRY_REGISTER_EXTENSION_CLASS(EmptyPerspective, context)
}
void org_blueberry_uitest_Activator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_blueberry_uitest, berry::org_blueberry_uitest_Activator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_blueberry_uitest, berry::org_blueberry_uitest_Activator)
+#endif
diff --git a/BlueBerry/Bundles/org.blueberry.uitest/src/internal/berryPluginActivator.h b/BlueBerry/Bundles/org.blueberry.uitest/src/internal/berryPluginActivator.h
index d470ebee6f..064af0d13c 100644
--- a/BlueBerry/Bundles/org.blueberry.uitest/src/internal/berryPluginActivator.h
+++ b/BlueBerry/Bundles/org.blueberry.uitest/src/internal/berryPluginActivator.h
@@ -1,42 +1,45 @@
/*===================================================================
BlueBerry Platform
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 BERRYPLUGINACTIVATOR_H
#define BERRYPLUGINACTIVATOR_H
#include <ctkPluginActivator.h>
namespace berry {
class org_blueberry_uitest_Activator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_blueberry_uitest")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
org_blueberry_uitest_Activator();
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
};
typedef org_blueberry_uitest_Activator PluginActivator;
}
#endif // BERRYPLUGINACTIVATOR_H
diff --git a/BlueBerry/CMake/FunctionCreateBlueBerryApplication.cmake b/BlueBerry/CMake/FunctionCreateBlueBerryApplication.cmake
index 5f08c8121c..a36a1a0ede 100644
--- a/BlueBerry/CMake/FunctionCreateBlueBerryApplication.cmake
+++ b/BlueBerry/CMake/FunctionCreateBlueBerryApplication.cmake
@@ -1,229 +1,229 @@
#!
#! Create a BlueBerry application.
#!
#! \brief This function will create a BlueBerry application together with all
#! necessary provisioning and configuration data and install support.
#!
#! \param NAME (required) The name of the executable.
#! \param DESCRIPTION (optional) A human-readable description of your application.
#! The usage depends on the CPack generator (on Windows, this is a descriptive
#! text for the created shortcuts).
#! \param SOURCES (optional) A list of source files to compile into your executable. Defaults
#! to <name>.cpp.
#! \param PLUGINS (optional) A list of required plug-ins. Defaults to all known plug-ins.
#! \param EXCLUDE_PLUGINS (optional) A list of plug-ins which should not be used. Mainly
#! useful if PLUGINS was not used.
#! \param LINK_LIBRARIES A list of libraries to be linked with the executable.
#! \param LIBRARY_DIRS A list of directories to pass through to MITK_INSTALL_TARGETS
#! \param SHOW_CONSOLE (option) Show the console output window (on Windows).
#! \param NO_PROVISIONING (option) Do not create provisioning files.
#! \param NO_INSTALL (option) Do not install this executable
#!
#! Assuming that there exists a file called <code>MyApp.cpp</code>, an example call looks like:
#! \code
#! FunctionCreateBlueBerryApplication(
#! NAME MyApp
#! DESCRIPTION "MyApp - New ways to explore medical data"
#! EXCLUDE_PLUGINS org.mitk.gui.qt.extapplication
#! SHOW_CONSOLE
#! )
#! \endcode
#!
function(FunctionCreateBlueBerryApplication)
macro_parse_arguments(_APP "NAME;DESCRIPTION;SOURCES;PLUGINS;EXCLUDE_PLUGINS;LINK_LIBRARIES;LIBRARY_DIRS" "SHOW_CONSOLE;NO_PROVISIONING;NO_INSTALL" ${ARGN})
if(NOT _APP_NAME)
message(FATAL_ERROR "NAME argument cannot be empty.")
endif()
if(NOT _APP_SOURCES)
set(_APP_SOURCES ${_APP_NAME}.cpp)
endif()
if(NOT _APP_PLUGINS)
ctkFunctionGetAllPluginTargets(_APP_PLUGINS)
else()
set(_plugins ${_APP_PLUGINS})
set(_APP_PLUGINS)
foreach(_plugin ${_plugins})
string(REPLACE "." "_" _plugin_target ${_plugin})
list(APPEND _APP_PLUGINS ${_plugin_target})
endforeach()
# get all plug-in dependencies
ctkFunctionGetPluginDependencies(_plugin_deps PLUGINS ${_APP_PLUGINS} ALL)
# add the dependencies to the list of application plug-ins
list(APPEND _APP_PLUGINS ${_plugin_deps})
endif()
#------------------------------------------------------------------------
# Prerequesites
#------------------------------------------------------------------------
find_package(MITK REQUIRED)
find_package(Poco REQUIRED)
# -----------------------------------------------------------------------
# Set up include and link dirs for the executable
# -----------------------------------------------------------------------
include_directories(
${org_blueberry_osgi_INCLUDE_DIRS}
)
# -----------------------------------------------------------------------
# Add executable icon (Windows)
# -----------------------------------------------------------------------
set(WINDOWS_ICON_RESOURCE_FILE "")
if(WIN32)
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/icons/${_APP_NAME}.rc")
set(WINDOWS_ICON_RESOURCE_FILE "${CMAKE_CURRENT_SOURCE_DIR}/icons/${_APP_NAME}.rc")
endif()
endif()
# -----------------------------------------------------------------------
# Create the executable and link libraries
# -----------------------------------------------------------------------
set(_app_compile_flags )
if(WIN32)
set(_app_compile_flags "${_app_compile_flags} -DPOCO_NO_UNWINDOWS -DWIN32_LEAN_AND_MEAN")
endif()
# Work-around for linking GDCM libraries, until GDCM provides proper
# target exports.
foreach(dir ${MODULES_PACKAGE_DEPENDS_DIRS})
if(EXISTS "${dir}/MITK_GDCM_Config.cmake")
include("${dir}/MITK_GDCM_Config.cmake")
break()
endif()
endforeach()
if(ALL_LIBRARY_DIRS)
list(REMOVE_DUPLICATES ALL_LIBRARY_DIRS)
link_directories(${ALL_LIBRARY_DIRS})
endif()
if(_APP_SHOW_CONSOLE)
add_executable(${_APP_NAME} MACOSX_BUNDLE ${_APP_SOURCES} ${WINDOWS_ICON_RESOURCE_FILE})
else()
add_executable(${_APP_NAME} MACOSX_BUNDLE WIN32 ${_APP_SOURCES} ${WINDOWS_ICON_RESOURCE_FILE})
endif()
-mitk_use_modules(TARGET ${_APP_NAME} MODULES mbilog PACKAGES Poco Qt4|QtCore)
+mitk_use_modules(TARGET ${_APP_NAME} MODULES mbilog PACKAGES Poco Qt4|QtCore Qt5|Core)
set_target_properties(${_APP_NAME} PROPERTIES
COMPILE_FLAGS "${_app_compile_flags}")
target_link_libraries(${_APP_NAME} org_blueberry_osgi ${_APP_LINK_LIBRARIES})
if(WIN32)
target_link_libraries(${_APP_NAME} ${QT_QTMAIN_LIBRARY})
endif()
# -----------------------------------------------------------------------
# Add executable icon and bundle name (Mac)
# -----------------------------------------------------------------------
if(APPLE)
if( _APP_DESCRIPTION)
set_target_properties(${_APP_NAME} PROPERTIES MACOSX_BUNDLE_NAME "${_APP_DESCRIPTION}")
else()
set_target_properties(${_APP_NAME} PROPERTIES MACOSX_BUNDLE_NAME "${_APP_NAME}")
endif()
set(icon_name "icon.icns")
set(icon_full_path "${CMAKE_CURRENT_SOURCE_DIR}/icons/${icon_name}")
if(EXISTS "${icon_full_path}")
set_target_properties(${_APP_NAME} PROPERTIES MACOSX_BUNDLE_ICON_FILE "${icon_name}")
file(COPY ${icon_full_path} DESTINATION "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${_APP_NAME}.app/Contents/Resources/")
INSTALL (FILES ${icon_full_path} DESTINATION "${_APP_NAME}.app/Contents/Resources/")
endif()
endif()
# -----------------------------------------------------------------------
# Set build time dependencies
# -----------------------------------------------------------------------
# This ensures that all enabled plug-ins are up-to-date when the
# executable is build.
if(_APP_PLUGINS)
ctkMacroGetAllProjectTargetLibraries("${_APP_PLUGINS}" _project_plugins)
if(_APP_EXCLUDE_PLUGINS)
set(_exclude_targets)
foreach(_exclude_plugin ${_APP_EXCLUDE_PLUGINS})
string(REPLACE "." "_" _exclude_target ${_exclude_plugin})
list(APPEND _exclude_targets ${_exclude_target})
endforeach()
list(REMOVE_ITEM _project_plugins ${_exclude_targets})
endif()
if(_project_plugins)
add_dependencies(${_APP_NAME} ${_project_plugins})
endif()
endif()
# -----------------------------------------------------------------------
# Additional files needed for the executable
# -----------------------------------------------------------------------
if(NOT _APP_NO_PROVISIONING)
# Create a provisioning file, listing all plug-ins
set(_prov_file "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${_APP_NAME}.provisioning")
FunctionCreateProvisioningFile(FILE ${_prov_file}
PLUGINS ${_APP_PLUGINS}
EXCLUDE_PLUGINS ${_APP_EXCLUDE_PLUGINS}
)
endif()
# Create a .ini file for initial parameters
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${_APP_NAME}.ini")
configure_file(${_APP_NAME}.ini
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${_APP_NAME}.ini)
endif()
# Create batch files for Windows platforms
if(WIN32)
set(template_name "start${_APP_NAME}.bat.in")
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${template_name}")
foreach(BUILD_TYPE debug release)
mitkFunctionCreateWindowsBatchScript(${template_name}
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/start${_APP_NAME}_${BUILD_TYPE}.bat
${BUILD_TYPE})
endforeach()
endif()
endif(WIN32)
# -----------------------------------------------------------------------
# Install support
# -----------------------------------------------------------------------
if(NOT _APP_NO_INSTALL)
# This installs all third-party CTK plug-ins
FunctionInstallThirdPartyCTKPlugins(${_APP_PLUGINS} EXCLUDE ${_APP_EXCLUDE_PLUGINS})
if(COMMAND BlueBerryApplicationInstallHook)
set(_real_app_plugins ${_APP_PLUGINS})
if(_APP_EXCLUDE_PLUGINS)
list(REMOVE_ITEM _real_app_plugins ${_APP_EXCLUDE_PLUGINS})
endif()
BlueBerryApplicationInstallHook(APP_NAME ${_APP_NAME} PLUGINS ${_real_app_plugins})
endif()
# Install the executable
MITK_INSTALL_TARGETS(EXECUTABLES ${_APP_NAME} LIBRARY_DIRS ${_APP_LIBRARY_DIRS} GLOB_PLUGINS )
if(NOT _APP_NO_PROVISIONING)
# Install the provisioning file
mitkFunctionInstallProvisioningFiles(${_prov_file})
endif()
# On Linux, create a shell script to start a relocatable application
if(UNIX AND NOT APPLE)
install(PROGRAMS "${MITK_SOURCE_DIR}/CMake/RunInstalledApp.sh" DESTINATION "." RENAME ${_APP_NAME}.sh)
endif()
# Tell cpack the executables that you want in the start menu as links
set(MITK_CPACK_PACKAGE_EXECUTABLES ${MITK_CPACK_PACKAGE_EXECUTABLES} "${_APP_NAME};${_APP_DESCRIPTION}" CACHE INTERNAL "Collecting windows shortcuts to executables")
endif()
endfunction()
diff --git a/BlueBerry/CMakeLists.txt b/BlueBerry/CMakeLists.txt
index 1e9821b1d0..3b77eba726 100644
--- a/BlueBerry/CMakeLists.txt
+++ b/BlueBerry/CMakeLists.txt
@@ -1,273 +1,285 @@
project(BlueBerry)
-cmake_minimum_required(VERSION 2.8.5)
+if (${CMAKE_SOURCE_DIR} EQUAL ${PROJECT_SOURCE_DIR})
+ cmake_minimum_required(VERSION 2.8.9)
+endif()
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/CMake/")
include(MacroParseArguments)
include(MacroConvertSchema)
include(MacroOrganizeSources)
include(MacroCreateCTKPlugin)
include(MacroCreateQtHelp)
include(MacroInstallCTKPlugin)
include(FunctionCreateProvisioningFile)
if(MSVC)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4250 /wd4275 /wd4251 /wd4503")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNOMINMAX /wd4250 /wd4275 /wd4251 /wd4503")
endif()
if(NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
endif()
find_package(mbilog REQUIRED)
include_directories(${mbilog_INCLUDE_DIRS})
-
-find_package(Qt4 4.7 REQUIRED)
+if(MITK_USE_Qt4)
+ find_package(Qt4 4.7 REQUIRED)
+else()
+ find_package(Qt5Concurrent ${MITK_QT5_MINIMUM_VERSION} REQUIRED)
+ find_package(Qt5Help ${MITK_QT5_MINIMUM_VERSION} REQUIRED)
+ find_package(Qt5Sql ${MITK_QT5_MINIMUM_VERSION} REQUIRED)
+ find_package(Qt5WebKitWidgets ${MITK_QT5_MINIMUM_VERSION} REQUIRED)
+ find_package(Qt5Widgets ${MITK_QT5_MINIMUM_VERSION} REQUIRED)
+ find_package(Qt5Xml ${MITK_QT5_MINIMUM_VERSION} REQUIRED)
+endif()
if(QT_QMAKE_CHANGED)
set(QT_HELPGENERATOR_EXECUTABLE NOTFOUND)
set(QT_COLLECTIONGENERATOR_EXECUTABLE NOTFOUND)
set(QT_ASSISTANT_EXECUTABLE NOTFOUND)
set(QT_XMLPATTERNS_EXECUTABLE NOTFOUND)
endif()
find_program(QT_HELPGENERATOR_EXECUTABLE
NAMES qhelpgenerator qhelpgenerator-qt4 qhelpgenerator4
PATHS ${QT_BINARY_DIR}
NO_DEFAULT_PATH
)
find_program(QT_COLLECTIONGENERATOR_EXECUTABLE
NAMES qcollectiongenerator qcollectiongenerator-qt4 qcollectiongenerator4
PATHS ${QT_BINARY_DIR}
NO_DEFAULT_PATH
)
find_program(QT_ASSISTANT_EXECUTABLE
NAMES assistant-qt4 assistant4 assistant
PATHS ${QT_BINARY_DIR}
NO_DEFAULT_PATH
)
find_program(QT_XMLPATTERNS_EXECUTABLE
NAMES xmlpatterns
PATHS ${QT_BINARY_DIR}
NO_DEFAULT_PATH
)
find_package(Doxygen)
option(BLUEBERRY_USE_QT_HELP "Enable support for integrating bundle documentation into Qt Help" ${DOXYGEN_FOUND})
mark_as_advanced(BLUEBERRY_USE_QT_HELP
QT_HELPGENERATOR_EXECUTABLE
QT_COLLECTIONGENERATOR_EXECUTABLE
QT_ASSISTANT_EXECUTABLE
QT_XMLPATTERNS_EXECUTABLE)
if(BLUEBERRY_USE_QT_HELP)
set(_force_blueberry_use_qt_help_to_off 0)
if(NOT DOXYGEN_FOUND)
message("> Forcing BLUEBERRY_USE_QT_HELP to OFF because Doxygen was not found.")
set(_force_blueberry_use_qt_help_to_off 1)
endif()
if(DOXYGEN_FOUND AND DOXYGEN_VERSION VERSION_LESS 1.8.7)
message("> Forcing BLUEBERRY_USE_QT_HELP to OFF because Doxygen version 1.8.7 or newer not found.")
set(_force_blueberry_use_qt_help_to_off 1)
endif()
if(NOT QT_HELPGENERATOR_EXECUTABLE)
message("> Forcing BLUEBERRY_USE_QT_HELP to OFF because QT_HELPGENERATOR_EXECUTABLE is empty.")
set(_force_blueberry_use_qt_help_to_off 1)
endif()
if(NOT QT_XMLPATTERNS_EXECUTABLE)
message("You have enabled Qt Help support, but QT_XMLPATTERNS_EXECUTABLE is empty")
set(_force_blueberry_use_qt_help_to_off 1)
endif()
if(_force_blueberry_use_qt_help_to_off)
set(BLUEBERRY_USE_QT_HELP OFF CACHE BOOL "Enable support for integrating bundle documentation into Qt Help" FORCE)
endif()
endif(BLUEBERRY_USE_QT_HELP)
-include(${QT_USE_FILE})
+if(MITK_USE_Qt4)
+ include(${QT_USE_FILE})
+endif()
# ========= CTK specific CMake stuff ============
cmake_policy(SET CMP0012 NEW)
find_package(CTK REQUIRED)
# Extract all library names starting with org_blueberry_
macro(GetMyTargetLibraries all_target_libraries varname)
set(re_ctkplugin "^org_blueberry_[a-zA-Z0-9_]+$")
set(_tmp_list)
list(APPEND _tmp_list ${all_target_libraries})
ctkMacroListFilter(_tmp_list re_ctkplugin OUTPUT_VARIABLE ${varname})
endmacro()
# ================================================
option(BLUEBERRY_BUILD_ALL_PLUGINS "Build all BlueBerry plugins (overriding selection)" OFF)
mark_as_advanced(BLUEBERRY_BUILD_ALL_PLUGINS)
if(BLUEBERRY_BUILD_ALL_PLUGINS)
set(BLUEBERRY_BUILD_ALL_PLUGINS_OPTION "FORCE_BUILD_ALL")
endif()
option(BLUEBERRY_STATIC "Build all plugins as static libraries" OFF)
mark_as_advanced(BLUEBERRY_STATIC)
option(BLUEBERRY_DEBUG_SMARTPOINTER "Enable code for debugging smart pointers" OFF)
mark_as_advanced(BLUEBERRY_DEBUG_SMARTPOINTER)
find_package(Poco REQUIRED)
find_package(Ant)
find_package(Eclipse)
set(BLUEBERRY_SOURCE_DIR ${BlueBerry_SOURCE_DIR})
set(BLUEBERRY_BINARY_DIR ${BlueBerry_BINARY_DIR})
set(BLUEBERRY_PLUGINS_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Bundles)
set(BLUEBERRY_PLUGINS_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/Bundles)
set(OSGI_APP solstice)
set(OSGI_UI_APP solstice_ui)
if(Eclipse_DIR)
set(BLUEBERRY_DOC_TOOLS_DIR "${Eclipse_DIR}" CACHE PATH "Directory containing additional tools needed for generating the documentation")
else()
set(BLUEBERRY_DOC_TOOLS_DIR "" CACHE PATH "Directory containing additional tools needed for generating the documentation")
endif()
set(BLUEBERRY_DEBUG_POSTFIX d)
# Testing options
if(DEFINED BLUEBERRY_BUILD_TESTING)
option(BLUEBERRY_BUILD_TESTING "Build the BlueBerry tests." ${BLUEBERRY_BUILD_TESTING})
else()
option(BLUEBERRY_BUILD_TESTING "Build the BlueBerry tests." ${BUILD_TESTING})
endif()
if(WIN32)
set(_gui_testing_default "ON")
else()
set(_gui_testing_default "OFF")
endif()
option(BLUEBERRY_ENABLE_GUI_TESTING "Enable the BlueBerry GUI tests" ${_gui_testing_default})
mark_as_advanced(BLUEBERRY_ENABLE_GUI_TESTING)
if(BLUEBERRY_BUILD_TESTING)
enable_testing()
endif()
# Add CTK plugins
set(_ctk_plugins
Bundles/org.blueberry.osgi:ON
Bundles/org.blueberry.compat:OFF
Bundles/org.blueberry.core.runtime:OFF
Bundles/org.blueberry.core.expressions:OFF
Bundles/org.blueberry.solstice.common:OFF
Bundles/org.blueberry.core.commands:OFF
Bundles/org.blueberry.core.jobs:OFF
Bundles/org.blueberry.ui:OFF
Bundles/org.blueberry.ui.qt:OFF
Bundles/org.blueberry.ui.qt.help:OFF
Bundles/org.blueberry.ui.qt.log:ON
Bundles/org.blueberry.ui.qt.objectinspector:OFF
)
set(_ctk_test_plugins )
set(_ctk_plugins_include_dirs
${Poco_INCLUDE_DIRS}
)
include_directories(${_ctk_plugins_include_dirs})
if(BLUEBERRY_BUILD_TESTING)
find_package(CppUnit REQUIRED)
include(berryTestingHelpers)
set(BLUEBERRY_TEST_APP "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${OSGI_APP}")
get_target_property(_is_macosx_bundle ${OSGI_APP} MACOSX_BUNDLE)
if(APPLE AND _is_macosx_bundle)
set(BLUEBERRY_TEST_APP "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${OSGI_APP}.app/Contents/MacOS/${OSGI_APP}")
endif()
set(_ctk_testinfrastructure_plugins
Bundles/org.blueberry.test:ON
Bundles/org.blueberry.uitest:ON
)
set(_ctk_test_plugins
# Testing/org.blueberry.core.runtime.tests:ON
# Testing/org.blueberry.osgi.tests:ON
)
if(BLUEBERRY_ENABLE_GUI_TESTING)
# list(APPEND _ctk_test_plugins Testing/org.blueberry.ui.tests:ON)
set(BLUEBERRY_UI_TEST_APP "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${OSGI_UI_APP}")
get_target_property(_is_macosx_bundle ${OSGI_UI_APP} MACOSX_BUNDLE)
if(APPLE AND _is_macosx_bundle)
set(BLUEBERRY_UI_TEST_APP "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${OSGI_UI_APP}.app/Contents/MacOS/${OSGI_UI_APP}")
endif()
endif()
endif()
set(BLUEBERRY_TESTING_PROVISIONING_FILE "${BlueBerry_BINARY_DIR}/BlueBerryTesting.provisioning")
add_custom_target(BlueBerry)
ctkMacroSetupPlugins(${_ctk_plugins} ${_ctk_testinfrastructure_plugins} ${_ctk_test_plugins}
BUILD_OPTION_PREFIX BLUEBERRY_BUILD_
BUILD_ALL ${BLUEBERRY_BUILD_ALL_PLUGINS}
COMPACT_OPTIONS)
set(BLUEBERRY_PROVISIONING_FILE "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/BlueBerry.provisioning")
FunctionCreateProvisioningFile(
FILE ${BLUEBERRY_PROVISIONING_FILE}
PLUGINS ${_ctk_plugins}
)
FunctionCreateProvisioningFile(
FILE ${BLUEBERRY_TESTING_PROVISIONING_FILE}
INCLUDE ${BLUEBERRY_PROVISIONING_FILE}
PLUGINS ${_ctk_testinfrastructure_plugins} ${_ctk_test_plugins}
)
if(${CMAKE_PROJECT_NAME}_PLUGIN_LIBRARIES)
add_dependencies(BlueBerry ${${CMAKE_PROJECT_NAME}_PLUGIN_LIBRARIES})
endif()
set_property(TARGET ${${CMAKE_PROJECT_NAME}_PLUGIN_LIBRARIES} PROPERTY LABELS BlueBerry)
set(BB_PLUGIN_USE_FILE "${BlueBerry_BINARY_DIR}/BlueBerryPluginUseFile.cmake")
if(${PROJECT_NAME}_PLUGIN_LIBRARIES)
ctkFunctionGeneratePluginUseFile(${BB_PLUGIN_USE_FILE})
else()
file(REMOVE ${BB_PLUGIN_USE_FILE})
set(BB_PLUGIN_USE_FILE )
endif()
# CTK Plugin Exports
set(BB_PLUGIN_EXPORTS_FILE "${CMAKE_CURRENT_BINARY_DIR}/BlueBerryPluginExports.cmake")
GetMyTargetLibraries("${${PROJECT_NAME}_PLUGIN_LIBRARIES}" my_plugin_targets)
set(additional_export_targets mbilog)
export(TARGETS ${my_plugin_targets} ${additional_export_targets}
FILE ${BB_PLUGIN_EXPORTS_FILE})
add_subdirectory(Documentation)
set(BLUEBERRY_QTPLUGIN_PATH )
if(CTK_QTDESIGNERPLUGINS_DIR AND EXISTS ${CTK_QTDESIGNERPLUGINS_DIR})
set(BLUEBERRY_QTPLUGIN_PATH "${CTK_QTDESIGNERPLUGINS_DIR}")
endif()
configure_file(BlueBerryConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/BlueBerryConfig.cmake @ONLY)
diff --git a/CMake/MITKDashboardDriverScript.cmake b/CMake/MITKDashboardDriverScript.cmake
index 4c36060d43..4385481bba 100644
--- a/CMake/MITKDashboardDriverScript.cmake
+++ b/CMake/MITKDashboardDriverScript.cmake
@@ -1,485 +1,486 @@
#
# Included from a dashboard script, this cmake file will drive the configure and build
# steps of MITK
#
#-----------------------------------------------------------------------------
# The following variable are expected to be define in the top-level script:
set(expected_variables
CTEST_NOTES_FILES
CTEST_SITE
CTEST_DASHBOARD_ROOT
CTEST_CMAKE_COMMAND
CTEST_CMAKE_GENERATOR
WITH_MEMCHECK
WITH_COVERAGE
WITH_DOCUMENTATION
CTEST_BUILD_CONFIGURATION
CTEST_TEST_TIMEOUT
CTEST_BUILD_FLAGS
TEST_TO_EXCLUDE_REGEX
CTEST_SOURCE_DIRECTORY
CTEST_BINARY_DIRECTORY
CTEST_BUILD_NAME
SCRIPT_MODE
CTEST_COVERAGE_COMMAND
CTEST_MEMORYCHECK_COMMAND
CTEST_GIT_COMMAND
PROJECT_BUILD_DIR
SUPERBUILD_TARGETS
)
foreach(var ${expected_variables})
if(NOT DEFINED ${var})
message(FATAL_ERROR "Variable ${var} should be defined in top-level script !")
endif()
endforeach()
+string(REPLACE " " "%20" _build_name_escaped "${CTEST_BUILD_NAME}")
+
# Check if "mbits" is reachable
file(DOWNLOAD "http://mbits" "${CTEST_SCRIPT_DIRECTORY}/mbits.html" TIMEOUT 2 STATUS _status)
list(GET _status 0 _status_code)
if(_status_code EQUAL 6) # couldn't resovle host name
set(MBITS_AVAILABLE 0)
else()
set(MBITS_AVAILABLE 1)
endif()
#
# Site specific options
#
if(NOT CDASH_ADMIN_URL_PREFIX AND MBITS_AVAILABLE)
set(CDASH_ADMIN_URL_PREFIX "http://mbits")
endif()
if(NOT MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL AND MBITS_AVAILABLE)
set(MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL "http://mbits/dl-cache")
endif()
if(NOT DEFINED GIT_BRANCH OR GIT_BRANCH STREQUAL "")
set(GIT_BRANCH "")
else()
set(GIT_BRANCH "-b ${GIT_BRANCH}")
endif()
# Should binary directory be cleaned?
set(empty_binary_directory FALSE)
# Attempt to build and test also if 'ctest_update' returned an error
set(initial_force_build FALSE)
# Set model options
set(model "")
if(SCRIPT_MODE STREQUAL "experimental")
set(empty_binary_directory FALSE)
set(initial_force_build TRUE)
set(model Experimental)
elseif(SCRIPT_MODE STREQUAL "continuous")
set(empty_binary_directory FALSE)
set(initial_force_build FALSE)
set(model Continuous)
elseif(SCRIPT_MODE STREQUAL "nightly")
set(empty_binary_directory TRUE)
set(initial_force_build TRUE)
set(model Nightly)
else()
message(FATAL_ERROR "Unknown script mode: '${SCRIPT_MODE}'. Script mode should be either 'experimental', 'continuous' or 'nightly'")
endif()
#message("script_mode:${SCRIPT_MODE}")
#message("model:${model}")
#message("empty_binary_directory:${empty_binary_directory}")
#message("force_build:${initial_force_build}")
set(CTEST_CONFIGURATION_TYPE ${CTEST_BUILD_CONFIGURATION})
if(empty_binary_directory)
message("Directory ${CTEST_BINARY_DIRECTORY} cleaned !")
ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY})
endif()
if(NOT DEFINED CTEST_CHECKOUT_DIR)
set(CTEST_CHECKOUT_DIR ${CTEST_SOURCE_DIRECTORY})
endif()
if(NOT EXISTS "${CTEST_CHECKOUT_DIR}")
set(CTEST_CHECKOUT_COMMAND "\"${CTEST_GIT_COMMAND}\" clone ${GIT_BRANCH} ${GIT_REPOSITORY} \"${CTEST_CHECKOUT_DIR}\"")
endif()
set(CTEST_UPDATE_TYPE "git")
set(CTEST_UPDATE_COMMAND "${CTEST_GIT_COMMAND}")
#----------------------------------------------------------------------
# Utility macros
#----------------------------------------------------------------------
function(func_build_target target build_dir)
set(CTEST_BUILD_TARGET ${target})
ctest_build(BUILD "${build_dir}" APPEND
RETURN_VALUE res
NUMBER_ERRORS num_errors
NUMBER_WARNINGS num_warnings)
ctest_submit(PARTS Build RETRY_DELAY 3 RETRY_COUNT 3)
if(num_errors)
math(EXPR build_errors "${build_errors} + ${num_errors}")
set(build_errors ${build_errors} PARENT_SCOPE)
endif()
if(num_warnings)
math(EXPR build_warnings "${build_warnings} + ${num_warnings}")
set(build_warnings ${build_warnings} PARENT_SCOPE)
endif()
endfunction()
function(func_test label build_dir)
if(NOT TESTING_PARALLEL_LEVEL)
set(TESTING_PARALLEL_LEVEL 8)
endif()
if(label MATCHES "Unlabeled")
set(_include_label EXCLUDE_LABEL .*)
else()
set(_include_label INCLUDE_LABEL ${label})
endif()
ctest_test(BUILD "${build_dir}"
${_include_label}
PARALLEL_LEVEL ${TESTING_PARALLEL_LEVEL}
EXCLUDE ${TEST_TO_EXCLUDE_REGEX}
RETURN_VALUE res
)
ctest_submit(PARTS Test RETRY_DELAY 3 RETRY_COUNT 3)
if(res)
math(EXPR test_errors "${test_errors} + 1")
set(test_errors ${test_errors} PARENT_SCOPE)
endif()
if(ARG3)
set(WITH_COVERAGE ${ARG3})
endif()
if(ARG4)
set(WITH_MEMCHECK ${ARG4})
endif()
if(WITH_COVERAGE AND CTEST_COVERAGE_COMMAND)
message("----------- [ Coverage ${label} ] -----------")
ctest_coverage(BUILD "${build_dir}" LABELS ${label})
ctest_submit(PARTS Coverage RETRY_DELAY 3 RETRY_COUNT 3)
endif()
if(WITH_MEMCHECK AND CTEST_MEMORYCHECK_COMMAND)
if(NOT CTEST_MEMORYCHECK_SUPPRESSIONS_FILE)
if(EXISTS "${CTEST_SOURCE_DIRECTORY}/CMake/valgrind.supp")
set(CTEST_MEMORYCHECK_SUPPRESSIONS_FILE "${CTEST_SOURCE_DIRECTORY}/CMake/valgrind.supp")
endif()
endif()
if(NOT CTEST_MEMORYCHECK_COMMAND_OPTIONS)
set(CTEST_MEMORYCHECK_COMMAND_OPTIONS "-q --tool=memcheck --leak-check=yes --show-reachable=no --show-possibly-lost=no --workaround-gcc296-bugs=yes --num-callers=50")
endif()
ctest_memcheck(BUILD "${build_dir}" INCLUDE_LABEL ${label})
ctest_submit(PARTS MemCheck RETRY_DELAY 3 RETRY_COUNT 3)
endif()
endfunction()
#---------------------------------------------------------------------
# run_ctest macro
#---------------------------------------------------------------------
macro(run_ctest)
set(build_warnings 0)
set(build_errors 0)
set(test_errors 0)
ctest_start(${model})
ctest_update(SOURCE "${CTEST_CHECKOUT_DIR}" RETURN_VALUE res)
if(res LESS 0)
# update error
math(EXPR build_errors "${build_errors} + 1")
endif()
set(force_build ${initial_force_build})
# Check if a forced run was requested
set(cdash_remove_rerun_url )
if(CDASH_ADMIN_URL_PREFIX)
- set(cdash_rerun_url "${CDASH_ADMIN_URL_PREFIX}/rerun/${CTEST_BUILD_NAME}")
- set(cdash_remove_rerun_url "${CDASH_ADMIN_URL_PREFIX}/rerun/rerun.php?name=${CTEST_BUILD_NAME}&remove=1")
+ set(cdash_rerun_url "${CDASH_ADMIN_URL_PREFIX}/rerun/${_build_name_escaped}")
+ set(cdash_remove_rerun_url "${CDASH_ADMIN_URL_PREFIX}/rerun/rerun.php?name=${_build_name_escaped}&remove=1")
file(DOWNLOAD
"${cdash_rerun_url}"
"${CTEST_BINARY_DIRECTORY}/tmp.txt"
STATUS status
)
list(GET status 0 error_code)
file(READ "${CTEST_BINARY_DIRECTORY}/tmp.txt" rerun_content LIMIT 1)
if(NOT error_code AND NOT rerun_content)
set(force_build 1)
endif()
endif()
if(COMMAND MITK_OVERRIDE_FORCE_BUILD)
MITK_OVERRIDE_FORCE_BUILD(force_build)
endif()
# force a build if this is the first run and the build dir is empty
if(NOT EXISTS "${CTEST_BINARY_DIRECTORY}/CMakeCache.txt")
message("First time build - Initialize CMakeCache.txt")
set(res 1)
# Write initial cache.
if(NOT DEFINED BUILD_TESTING)
set(BUILD_TESTING ON)
endif()
# Write initial cache.
file(WRITE "${CTEST_BINARY_DIRECTORY}/CMakeCache.txt" "
CTEST_USE_LAUNCHERS:BOOL=${CTEST_USE_LAUNCHERS}
CTEST_PROJECT_ADDITIONAL_TARGETS:INTERNAL=${CTEST_PROJECT_ADDITIONAL_TARGETS}
BUILD_TESTING:BOOL=${BUILD_TESTING}
MITK_CTEST_SCRIPT_MODE:STRING=${SCRIPT_MODE}
CMAKE_BUILD_TYPE:STRING=${CTEST_BUILD_CONFIGURATION}
WITH_COVERAGE:BOOL=${WITH_COVERAGE}
MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL:STRING=${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}
${INITIAL_CMAKECACHE_OPTIONS}
")
endif()
if(res GREATER 0 OR force_build)
# Clear the forced rerun request
if(CDASH_ADMIN_URL_PREFIX AND cdash_remove_rerun_url)
file(DOWNLOAD "${cdash_remove_rerun_url}" "${CTEST_BINARY_DIRECTORY}/tmp.txt")
file(REMOVE "${CTEST_BINARY_DIRECTORY}/tmp.txt")
endif()
if(CTEST_PROJECT_NAME_SUPERBUILD)
set(ctest_project_name_orig ${CTEST_PROJECT_NAME})
set(CTEST_PROJECT_NAME ${CTEST_PROJECT_NAME_SUPERBUILD})
endif()
message("----------- [ Configure SuperBuild ] -----------")
set_property(GLOBAL PROPERTY SubProject SuperBuild)
set_property(GLOBAL PROPERTY Label SuperBuild)
ctest_configure(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res OPTIONS "${SUPERBUILD_CONFIG_OPTIONS}")
if(res)
math(EXPR build_errors "${build_errors} + 1")
endif()
# Project.xml is generated during the superbuild configure step
ctest_submit(FILES "${CTEST_BINARY_DIRECTORY}/Project.xml" RETRY_DELAY 3 RETRY_COUNT 3)
ctest_read_custom_files("${CTEST_BINARY_DIRECTORY}")
ctest_submit(PARTS Configure RETRY_DELAY 3 RETRY_COUNT 3)
# submit the update results *after* the submitting the Configure info,
# otherwise CDash is somehow confused and cannot add the update info
# to the superbuild project
ctest_submit(PARTS Update RETRY_DELAY 3 RETRY_COUNT 3)
# To get CTEST_PROJECT_SUBPROJECTS and CTEST_PROJECT_EXTERNALS definition
include("${CTEST_BINARY_DIRECTORY}/CTestConfigSubProject.cmake")
# Build top level (either all or the supplied targets at
# superbuild level
if(SUPERBUILD_TARGETS AND NOT build_errors)
foreach(superbuild_target ${SUPERBUILD_TARGETS})
message("----------- [ Build ${superbuild_target} - SuperBuild ] -----------")
func_build_target(${superbuild_target} "${CTEST_BINARY_DIRECTORY}")
# runs only tests that have a LABELS property matching "SuperBuild"
func_test("SuperBuild" "${CTEST_BINARY_DIRECTORY}")
endforeach()
# HACK Unfortunately ctest_coverage ignores the build argument, back-up the original dirs
file(READ "${CTEST_BINARY_DIRECTORY}/CMakeFiles/TargetDirectories.txt" old_coverage_dirs)
# explicitly build requested external projects as subprojects
foreach(external_project_with_build_dir ${CTEST_PROJECT_EXTERNALS})
string(REPLACE "^^" ";" external_project_with_build_dir_list "${external_project_with_build_dir}")
list(GET external_project_with_build_dir_list 0 external_project_name)
list(GET external_project_with_build_dir_list 1 external_project_builddir)
set_property(GLOBAL PROPERTY SubProject ${external_project_name})
set_property(GLOBAL PROPERTY Label ${external_project_name})
message("----------- [ Build ${external_project_name} ] -----------")
func_build_target("${external_project_name}" "${CTEST_BINARY_DIRECTORY}")
if(NOT build_errors)
# HACK Unfortunately ctest_coverage ignores the build argument, try to force it...
file(READ "${CTEST_BINARY_DIRECTORY}/${external_project_builddir}/CMakeFiles/TargetDirectories.txt" mitk_build_coverage_dirs)
file(APPEND "${CTEST_BINARY_DIRECTORY}/CMakeFiles/TargetDirectories.txt" "${mitk_build_coverage_dirs}")
message("----------- [ Test ${external_project_name} ] -----------")
# runs only tests that have a LABELS property matching "${external_project_name}"
func_test(${external_project_name} "${CTEST_BINARY_DIRECTORY}/${external_project_builddir}")
# restore old coverage dirs
file(WRITE "${CTEST_BINARY_DIRECTORY}/CMakeFiles/TargetDirectories.txt" "${old_coverage_dirs}")
endif()
endforeach()
# switch back to SuperBuild label
set_property(GLOBAL PROPERTY SubProject SuperBuild)
set_property(GLOBAL PROPERTY Label SuperBuild)
message("----------- [ Finish SuperBuild ] -----------")
else()
message("----------- [ Build SuperBuild ] -----------")
endif()
if(NOT build_errors)
# build everything at superbuild level which has not yet been built
func_build_target("" "${CTEST_BINARY_DIRECTORY}")
endif()
# runs only tests that have a LABELS property matching "SuperBuild"
#func_test("SuperBuild" "${CTEST_BINARY_DIRECTORY}")
set(build_dir "${CTEST_BINARY_DIRECTORY}/${PROJECT_BUILD_DIR}")
if(CTEST_PROJECT_NAME_SUPERBUILD)
set(CTEST_PROJECT_NAME ${ctest_project_name_orig})
endif()
message("----------- [ Configure ${build_dir} ] -----------")
# Configure target
ctest_configure(BUILD "${build_dir}"
OPTIONS "-DCTEST_USE_LAUNCHERS=${CTEST_USE_LAUNCHERS}"
RETURN_VALUE res
)
ctest_read_custom_files("${CTEST_BINARY_DIRECTORY}")
ctest_submit(PARTS Configure RETRY_DELAY 3 RETRY_COUNT 3)
if(res)
math(EXPR build_errors "${build_errors} + 1")
endif()
foreach(subproject ${CTEST_PROJECT_SUBPROJECTS})
if(NOT build_errors)
set_property(GLOBAL PROPERTY SubProject ${subproject})
set_property(GLOBAL PROPERTY Label ${subproject})
if(subproject MATCHES "Unlabeled")
message("----------- [ Build All (Unlabeled) ] -----------")
# Build target
func_build_target("" "${build_dir}")
else()
message("----------- [ Build ${subproject} ] -----------")
# Build target
func_build_target(${subproject} "${build_dir}")
endif()
endif()
endforeach()
if(NOT build_errors)
# HACK Unfortunately ctest_coverage ignores the build argument, try to force it...
file(READ ${build_dir}/CMakeFiles/TargetDirectories.txt mitk_build_coverage_dirs)
file(APPEND "${CTEST_BINARY_DIRECTORY}/CMakeFiles/TargetDirectories.txt" "${mitk_build_coverage_dirs}")
foreach(subproject ${CTEST_PROJECT_SUBPROJECTS})
set_property(GLOBAL PROPERTY SubProject ${subproject})
set_property(GLOBAL PROPERTY Label ${subproject})
message("----------- [ Test ${subproject} ] -----------")
# runs only tests that have a LABELS property matching "${subproject}"
func_test(${subproject} "${build_dir}")
endforeach()
endif()
# Build any additional target which is not build by "all"
# i.e. the "package" target
if(CTEST_PROJECT_ADDITIONAL_TARGETS AND NOT build_errors)
foreach(additional_target ${CTEST_PROJECT_ADDITIONAL_TARGETS})
set_property(GLOBAL PROPERTY SubProject ${additional_target})
set_property(GLOBAL PROPERTY Label ${additional_target})
message("----------- [ Build ${additional_target} ] -----------")
func_build_target(${additional_target} "${build_dir}")
message("----------- [ Test ${additional_target} ] -----------")
# runs only tests that have a LABELS property matching "${subproject}"
func_test(${additional_target} "${build_dir}")
endforeach()
endif()
if(WITH_DOCUMENTATION)
message("----------- [ Build Documentation ] -----------")
set(ctest_use_launchers_orig ${CTEST_USE_LAUNCHERS})
set(CTEST_USE_LAUNCHERS 0)
# Build Documentation target
set_property(GLOBAL PROPERTY SubProject Documentation)
set_property(GLOBAL PROPERTY Label Documentation)
func_build_target("doc" "${build_dir}")
set(CTEST_USE_LAUNCHERS ${ctest_use_launchers_orig})
endif()
set_property(GLOBAL PROPERTY SubProject SuperBuild)
set_property(GLOBAL PROPERTY Label SuperBuild)
# Global coverage ...
if(WITH_COVERAGE AND CTEST_COVERAGE_COMMAND)
message("----------- [ Global coverage ] -----------")
ctest_coverage(BUILD "${build_dir}" APPEND)
ctest_submit(PARTS Coverage RETRY_DELAY 3 RETRY_COUNT 3)
endif()
# Global dynamic analysis ...
if(WITH_MEMCHECK AND CTEST_MEMORYCHECK_COMMAND)
message("----------- [ Global memcheck ] -----------")
ctest_memcheck(BUILD "${build_dir}")
ctest_submit(PARTS MemCheck RETRY_DELAY 3 RETRY_COUNT 3)
endif()
# Note should be at the end
ctest_submit(PARTS Notes RETRY_DELAY 3 RETRY_COUNT 3)
# Send status to the "CDash Web Admin"
if(CDASH_ADMIN_URL_PREFIX)
set(cdash_admin_url "${CDASH_ADMIN_URL_PREFIX}/cdashadmin-web/index.php?pw=4da12ca9c06d46d3171d7f73974c900f")
string(REGEX REPLACE ".*\\?project=(.*)&?" "\\1" _ctest_project "${CTEST_DROP_LOCATION}")
- string(REPLACE " " "%20" _build_name_escaped "${CTEST_BUILD_NAME}")
file(DOWNLOAD
"${cdash_admin_url}&action=submit&name=${_build_name_escaped}&hasTestErrors=${test_errors}&hasBuildErrors=${build_errors}&hasBuildWarnings=${build_warnings}&ctestDropSite=${CTEST_DROP_SITE}&ctestProject=${_ctest_project}"
"${CTEST_BINARY_DIRECTORY}/cdashadmin.txt"
STATUS status
)
list(GET status 0 error_code)
list(GET status 1 error_msg)
if(error_code)
message(FATAL_ERROR "error: Failed to communicate with cdashadmin-web - ${error_msg}")
endif()
endif()
endif()
# Clear the CTEST_CHECKOUT_COMMAND variable to prevent continuous clients
# to try to checkout again
set(CTEST_CHECKOUT_COMMAND "")
endmacro()
if(SCRIPT_MODE STREQUAL "continuous")
while(1)
run_ctest()
# Loop no faster than once every 5 minutes
message("Wait for 5 minutes ...")
ctest_sleep(300)
endwhile()
else()
run_ctest()
endif()
diff --git a/CMake/MITKDashboardSetup.cmake b/CMake/MITKDashboardSetup.cmake
index c32e91b87a..33d4415c84 100644
--- a/CMake/MITKDashboardSetup.cmake
+++ b/CMake/MITKDashboardSetup.cmake
@@ -1,208 +1,154 @@
# This file is intended to be included at the end of a custom MITKDashboardScript.TEMPLATE.cmake file
list(APPEND CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
#
# Automatically determined properties
#
set(MY_OPERATING_SYSTEM )
if(UNIX)
# Download a utility script
set(url "http://mitk.org/git/?p=MITK.git;a=blob_plain;f=CMake/mitkDetectOS.sh;hb=${hb}")
set(dest "${CTEST_SCRIPT_DIRECTORY}/mitkDetectOS.sh")
downloadFile("${url}" "${dest}")
execute_process(COMMAND sh "${dest}"
RESULT_VARIABLE _result OUTPUT_VARIABLE _out
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT _result)
set(MY_OPERATING_SYSTEM "${_out}")
endif()
endif()
if(NOT MY_OPERATING_SYSTEM)
set(MY_OPERATING_SYSTEM "${CMAKE_HOST_SYSTEM}") # Windows 7, Linux-2.6.32, Darwin...
endif()
site_name(CTEST_SITE)
if(NOT DEFINED MITK_USE_QT)
set(MITK_USE_QT 1)
endif()
if(MITK_USE_QT)
if(NOT QT_QMAKE_EXECUTABLE)
find_program(QT_QMAKE_EXECUTABLE NAMES qmake qmake-qt4
HINTS ${QT_BINARY_DIR})
endif()
execute_process(COMMAND ${QT_QMAKE_EXECUTABLE} --version
OUTPUT_VARIABLE MY_QT_VERSION
RESULT_VARIABLE qmake_error)
if(qmake_error)
message(FATAL_ERROR "Error when executing ${QT_QMAKE_EXECUTABLE} --version\n${qmake_error}")
endif()
string(REGEX REPLACE ".*Qt version ([0-9.]+) .*" "\\1" MY_QT_VERSION ${MY_QT_VERSION})
endif()
#
# Project specific properties
#
if(NOT CTEST_BUILD_NAME)
if(MITK_USE_QT)
set(CTEST_BUILD_NAME "${MY_OPERATING_SYSTEM} ${MY_COMPILER} Qt${MY_QT_VERSION} ${CTEST_BUILD_CONFIGURATION}")
else()
set(CTEST_BUILD_NAME "${MY_OPERATING_SYSTEM} ${MY_COMPILER} ${CTEST_BUILD_CONFIGURATION}")
endif()
set(CTEST_BUILD_NAME "${CTEST_BUILD_NAME}${CTEST_BUILD_NAME_SUFFIX}")
endif()
set(PROJECT_BUILD_DIR "MITK-build")
set(CTEST_PATH "$ENV{PATH}")
if(WIN32)
set(ANN_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/ANN-build/${CTEST_BUILD_CONFIGURATION}")
set(CPPUNIT_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/CppUnit-build/${CTEST_BUILD_CONFIGURATION}")
set(GLUT_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/GLUT-build/${CTEST_BUILD_CONFIGURATION}")
set(GLEW_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/GLEW-build/${CTEST_BUILD_CONFIGURATION}")
set(TINYXML_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/tinyxml-build/${CTEST_BUILD_CONFIGURATION}")
set(QWT_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/Qwt-build/${CTEST_BUILD_CONFIGURATION}")
- set(QXT_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/Qxt-build/${CTEST_BUILD_CONFIGURATION}")
set(VTK_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/VTK-build/bin/${CTEST_BUILD_CONFIGURATION}")
set(ACVD_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/ACVD-build/bin/${CTEST_BUILD_CONFIGURATION}")
set(ITK_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/ITK-build/bin/${CTEST_BUILD_CONFIGURATION}")
set(BOOST_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/Boost-install/lib")
set(GDCM_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/GDCM-build/bin/${CTEST_BUILD_CONFIGURATION}")
set(DCMTK_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/DCMTK-install/bin/${CTEST_BUILD_CONFIGURATION}")
set(OPENCV_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/OpenCV-build/bin/${CTEST_BUILD_CONFIGURATION}")
set(POCO_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/Poco-install/lib")
set(SOFA_BINARY_DIR "${CTEST_BINARY_DIRECTORY}/SOFA-build/bin/${CTEST_BUILD_CONFIGURATION}")
set(BLUEBERRY_OSGI_DIR "${CTEST_BINARY_DIRECTORY}/MITK-build/bin/BlueBerry/org.blueberry.osgi/bin/${CTEST_BUILD_CONFIGURATION}")
- set(CTEST_PATH "${CTEST_PATH};${CPPUNIT_BINARY_DIR};${QT_BINARY_DIR};${VTK_BINARY_DIR};${ANN_BINARY_DIR};${GLUT_BINARY_DIR};${GLEW_BINARY_DIR};${TINYXML_BINARY_DIR};${QWT_BINARY_DIR};${QXT_BINARY_DIR};${ACVD_BINARY_DIR};${ITK_BINARY_DIR};${BOOST_BINARY_DIR};${GDCM_BINARY_DIR};${DCMTK_BINARY_DIR};${OPENCV_BINARY_DIR};${POCO_BINARY_DIR};${SOFA_BINARY_DIR};${BLUEBERRY_OSGI_DIR}")
+ set(CTEST_PATH "${CTEST_PATH};${CPPUNIT_BINARY_DIR};${QT_BINARY_DIR};${VTK_BINARY_DIR};${ANN_BINARY_DIR};${GLUT_BINARY_DIR};${GLEW_BINARY_DIR};${TINYXML_BINARY_DIR};${QWT_BINARY_DIR};${ACVD_BINARY_DIR};${ITK_BINARY_DIR};${BOOST_BINARY_DIR};${GDCM_BINARY_DIR};${DCMTK_BINARY_DIR};${OPENCV_BINARY_DIR};${POCO_BINARY_DIR};${SOFA_BINARY_DIR};${BLUEBERRY_OSGI_DIR}")
endif()
set(ENV{PATH} "${CTEST_PATH}")
set(SUPERBUILD_TARGETS "")
# If the dashscript doesn't define a GIT_REPOSITORY variable, let's define it here.
if(NOT DEFINED GIT_REPOSITORY OR GIT_REPOSITORY STREQUAL "")
set(GIT_REPOSITORY "http://git.mitk.org/MITK.git")
endif()
#
# Display build info
#
message("Site name: ${CTEST_SITE}")
message("Build name: ${CTEST_BUILD_NAME}")
message("Script Mode: ${SCRIPT_MODE}")
message("Coverage: ${WITH_COVERAGE}, MemCheck: ${WITH_MEMCHECK}")
#
# Set initial cache options
#
if(${CMAKE_VERSION} VERSION_GREATER "2.8.9")
set(CTEST_USE_LAUNCHERS 1)
set(ENV{CTEST_USE_LAUNCHERS_DEFAULT} 1)
endif()
# Remove this if block after all dartclients work
if(DEFINED ADDITIONNAL_CMAKECACHE_OPTION)
message(WARNING "Rename ADDITIONNAL to ADDITIONAL in your dartlclient script: ${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
set(ADDITIONAL_CMAKECACHE_OPTION ${ADDITIONNAL_CMAKECACHE_OPTION})
endif()
-if(NOT DEFINED MITK_USE_ACVD)
- set(MITK_USE_ACVD 1)
-endif()
-
-if(NOT DEFINED MITK_USE_Boost)
- set(MITK_USE_Boost 1)
-endif()
-
-if(NOT DEFINED MITK_USE_OpenCV)
- set(MITK_USE_OpenCV 1)
-endif()
-
-if(NOT DEFINED MITK_USE_Poco)
- set(MITK_USE_Poco 1)
-endif()
-
-if(NOT DEFINED MITK_USE_Python)
- if(WIN32)
- set(MITK_USE_Python FALSE)
- else()
- set(MITK_USE_Python TRUE)
- endif()
-endif()
-
-if(NOT DEFINED MITK_USE_SOFA)
- set(MITK_USE_SOFA 1)
+if(NOT DEFINED MITK_BUILD_CONFIGURATION)
+ set(MITK_BUILD_CONFIGURATION "All")
endif()
if(NOT DEFINED MITK_VTK_DEBUG_LEAKS)
set(MITK_VTK_DEBUG_LEAKS 1)
endif()
-if(NOT DEFINED MITK_BUILD_ALL_APPS)
- set(MITK_BUILD_ALL_APPS TRUE)
-endif()
-
-if(NOT DEFINED BLUEBERRY_BUILD_ALL_PLUGINS)
- set(BLUEBERRY_BUILD_ALL_PLUGINS TRUE)
-endif()
-
-if(NOT DEFINED MITK_BUILD_ALL_PLUGINS)
- set(MITK_BUILD_ALL_PLUGINS TRUE)
-endif()
-
-if(NOT DEFINED MITK_BUILD_EXAMPLES)
- set(MITK_BUILD_EXAMPLES TRUE)
-endif()
-
-if(NOT BUILD_DiffusionMiniApps)
- set(BUILD_DiffusionMiniApps TRUE)
-endif()
set(INITIAL_CMAKECACHE_OPTIONS "
-BLUEBERRY_BUILD_ALL_PLUGINS:BOOL=${MITK_BUILD_ALL_PLUGINS}
-MITK_BUILD_ALL_PLUGINS:BOOL=${MITK_BUILD_ALL_PLUGINS}
-MITK_BUILD_ALL_APPS:BOOL=${MITK_BUILD_ALL_APPS}
-MITK_BUILD_EXAMPLES:BOOL=${MITK_BUILD_EXAMPLES}
SUPERBUILD_EXCLUDE_MITKBUILD_TARGET:BOOL=TRUE
-MITK_USE_ACVD:BOOL=${MITK_USE_ACVD}
-MITK_USE_Boost:BOOL=${MITK_USE_Boost}
-MITK_USE_OpenCV:BOOL=${MITK_USE_OpenCV}
-MITK_USE_Poco:BOOL=${MITK_USE_Poco}
-MITK_USE_Python:BOOL=${MITK_USE_Python}
-MITK_USE_SOFA:BOOL=${MITK_USE_SOFA}
-MITK_USE_QT:BOOL=${MITK_USE_QT}
+MITK_BUILD_CONFIGURATION:STRING=${MITK_BUILD_CONFIGURATION}
MITK_VTK_DEBUG_LEAKS:BOOL=${MITK_VTK_DEBUG_LEAKS}
${ADDITIONAL_CMAKECACHE_OPTION}
")
if(MITK_USE_QT)
set(INITIAL_CMAKECACHE_OPTIONS "${INITIAL_CMAKECACHE_OPTIONS}
QT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}")
endif()
# Write a cache file for populating the MITK initial cache (not the superbuild cache).
# This can be used to provide variables which are not passed through the
# superbuild process to the MITK configure step)
if(MITK_INITIAL_CACHE)
set(mitk_cache_file "${CTEST_SCRIPT_DIRECTORY}/mitk_initial_cache.txt")
file(WRITE "${mitk_cache_file}" "${MITK_INITIAL_CACHE}")
set(INITIAL_CMAKECACHE_OPTIONS "${INITIAL_CMAKECACHE_OPTIONS}
MITK_INITIAL_CACHE_FILE:INTERNAL=${mitk_cache_file}
")
endif()
#
# Download and include dashboard driver script
#
set(url "http://mitk.org/git/?p=MITK.git;a=blob_plain;f=CMake/MITKDashboardDriverScript.cmake;hb=${hb}")
set(dest ${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}.driver)
downloadFile("${url}" "${dest}")
include(${dest})
diff --git a/CMake/PackageDepends/MITK_Qxt_Config.cmake b/CMake/PackageDepends/MITK_Qxt_Config.cmake
deleted file mode 100644
index f0ee7c0e44..0000000000
--- a/CMake/PackageDepends/MITK_Qxt_Config.cmake
+++ /dev/null
@@ -1,9 +0,0 @@
-# first look for the superbuild Qxt version, pointed to by Qxt_DIR
-find_package(Qxt QUIET NO_MODULE)
-if(NOT Qxt_FOUND)
- # now try invoking a FindQxt.cmake script
- find_package(Qxt REQUIRED)
-endif()
-
-list(APPEND ALL_LIBRARIES ${Qxt_LIBRARIES})
-list(APPEND ALL_INCLUDE_DIRECTORIES ${Qxt_INCLUDE_DIRS})
diff --git a/CMake/mitkBuildConfigurationAll.cmake b/CMake/mitkBuildConfigurationAll.cmake
index 6e58614be3..ae3261bb6d 100644
--- a/CMake/mitkBuildConfigurationAll.cmake
+++ b/CMake/mitkBuildConfigurationAll.cmake
@@ -1,35 +1,53 @@
set(MITK_CONFIG_PACKAGES )
+set(_apple_package_excludes)
+
+if(APPLE)
+ set(_apple_package_excludes
+ SOFA
+ )
+endif()
+
set(_package_excludes
+ ${_apple_package_excludes}
Python
OpenCL
SYSTEM_Boost
Boost_LIBRARIES
SOFA_PLUGINS
SOFA_PLUGINS_DIR
SUPERBUILD
KWSTYLE
+ MICROBIRD_TRACKER
+ MICROBIRD_TRACKER_INCLUDE_DIR
+ MICROBIRD_TRACKER_LIB
MICRON_TRACKER
OPTITRACK_TRACKER
+ SPACENAVIGATOR
TOF_KINECT
TOF_KINECTV2
TOF_MESASR4000
TOF_PMDCAMBOARD
TOF_PMDCAMCUBE
+ US_TELEMED_SDK
+ videoInput
+ WIIMOTE
)
get_cmake_property(_cache_vars CACHE_VARIABLES)
foreach(_cache_var ${_cache_vars})
string(REGEX REPLACE "MITK_USE_(.+)" "\\1" _package "${_cache_var}")
if(_package AND NOT _package STREQUAL _cache_var)
list(FIND _package_excludes ${_package} _index)
if(_index EQUAL -1)
list(APPEND MITK_CONFIG_PACKAGES ${_package})
endif()
endif()
endforeach()
set(MITK_BUILD_ALL_APPS ON CACHE BOOL "Build all MITK applications" FORCE)
set(MITK_BUILD_ALL_PLUGINS ON CACHE BOOL "Build all MITK plugins" FORCE)
set(MITK_BUILD_EXAMPLES ON CACHE BOOL "Build the MITK examples" FORCE)
+set(BLUEBERRY_BUILD_ALL_PLUGINS ON CACHE BOOL "Build all BlueBerry plugins" FORCE)
+set(BUILD_DiffusionMiniApps ON CACHE BOOL "Build MITK Diffusion MiniApps" FORCE)
diff --git a/CMake/mitkBuildConfigurationDefault.cmake b/CMake/mitkBuildConfigurationDefault.cmake
index 1b59e1adbf..c0deb791b6 100644
--- a/CMake/mitkBuildConfigurationDefault.cmake
+++ b/CMake/mitkBuildConfigurationDefault.cmake
@@ -1,22 +1,23 @@
set(MITK_CONFIG_PACKAGES
+ ACVD
QT
BLUEBERRY
)
set(MITK_CONFIG_PLUGINS
org.mitk.gui.qt.datamanager
org.mitk.gui.qt.stdmultiwidgeteditor
org.mitk.gui.qt.dicom
org.mitk.gui.qt.imagenavigator
org.mitk.gui.qt.measurementtoolbox
org.mitk.gui.qt.properties
org.mitk.gui.qt.segmentation
org.mitk.gui.qt.volumevisualization
org.mitk.planarfigure
org.mitk.gui.qt.moviemaker
org.mitk.gui.qt.pointsetinteraction
org.mitk.gui.qt.registration
org.mitk.gui.qt.remeshing
org.mitk.gui.qt.viewnavigator
org.mitk.gui.qt.imagecropper
)
diff --git a/CMake/mitkBuildConfigurationWorkbenchRelease.cmake b/CMake/mitkBuildConfigurationWorkbenchRelease.cmake
new file mode 100644
index 0000000000..d354b0bb40
--- /dev/null
+++ b/CMake/mitkBuildConfigurationWorkbenchRelease.cmake
@@ -0,0 +1,3 @@
+include(${CMAKE_CURRENT_LIST_DIR}/mitkBuildConfigurationDefault.cmake)
+
+set(MITK_VTK_DEBUG_LEAKS OFF CACHE BOOL "Enable VTK Debug Leaks" FORCE)
diff --git a/CMake/mitkFunctionCreateModule.cmake b/CMake/mitkFunctionCreateModule.cmake
index d9880b4ed2..ee59f166a9 100644
--- a/CMake/mitkFunctionCreateModule.cmake
+++ b/CMake/mitkFunctionCreateModule.cmake
@@ -1,633 +1,638 @@
function(_link_directories_for_packages)
set(ALL_LIBRARY_DIRS )
foreach(package ${ARGN})
if(NOT ${package} MATCHES "^(Qt[45].*|ITK|VTK)$")
foreach(dir ${MODULES_PACKAGE_DEPENDS_DIRS})
if(EXISTS "${dir}/MITK_${package}_Config.cmake")
include("${dir}/MITK_${package}_Config.cmake")
break()
endif()
endforeach()
endif()
endforeach()
if(ALL_LIBRARY_DIRS)
list(REMOVE_DUPLICATES ALL_LIBRARY_DIRS)
link_directories(${ALL_LIBRARY_DIRS})
endif()
endfunction()
##################################################################
#
# mitk_create_module
#
#! Creates a module for the automatic module dependency system within MITK.
#! Configurations are generated in the moduleConf directory.
#!
#! USAGE:
#!
#! \code
#! mitk_create_module([<moduleName>]
#! [INCLUDE_DIRS <include directories>]
#! [INTERNAL_INCLUDE_DIRS <internally used include directories>]
#! [DEPENDS <modules we need>]
#! [PACKAGE_DEPENDS <packages we need, like ITK, VTK, QT>]
#! [TARGET_DEPENDS <list of additional dependencies>
#! [EXPORT_DEFINE <declspec macro name for dll exports>]
#! [HEADERS_ONLY]
#! [WARNINGS_AS_ERRORS]
#! \endcode
#!
#! The <moduleName> parameter specifies the name of the module which is used
#! to create a logical target name. The parameter is optional in case the
#! MITK_MODULE_NAME_DEFAULTS_TO_DIRECTORY_NAME variable evaluates to TRUE. The
#! module name will then be derived from the directory name in which this
#! function is called.
#!
#! If set, the following variables will be used to validate the module name:
#!
#! MITK_MODULE_NAME_REGEX_MATCH The module name must match this regular expression.
#! MITK_MODULE_NAME_REGEX_NOT_MATCH The module name must not match this regular expression.
#!
#! If the MITK_MODULE_NAME_PREFIX variable is set, the module name will be prefixed
#! with its contents.
#!
#! A modules source files are specified in a separate CMake file usually
#! called files.cmake, located in the module root directory. The
#! mitk_create_module() macro evaluates the following CMake variables
#! from the files.cmake file:
#!
#! - CPP_FILES A list of .cpp files
#! - H_FILES A list of .h files without a corresponding .cpp file
#! - TXX_FILES A list of .txx files
#! - RESOURCE_FILES A list of files (resources) which are embedded into the module
#! - MOC_H_FILES A list of Qt header files which should be processed by the MOC
#! - UI_FILES A list of .ui Qt UI files
#! - QRC_FILES A list of .qrc Qt resource files
#! - DOX_FILES A list of .dox Doxygen files
#!
#! List of variables available after the function is called:
#! - MODULE_NAME
#! - MODULE_TARGET
#! - MODULE_IS_ENABLED
#! - MODULE_SUBPROJECTS
#! - ALL_META_DEPENDENCIES
#!
#! \sa mitk_create_executable
#!
#! Parameters (all optional):
#!
#! \param <moduleName> The module name (also used as target name)
#! \param SUBPROJECTS List of CDash labels
#! \param VERSION Module version number, e.g. "1.2.0"
#! \param INCLUDE_DIRS Public include dirs (used in mitkMacroCreateModuleConf.cmake)
#! \param INTERNAL_INCLUDE_DIRS Private include dirs internal to this module
#! \param DEPENDS List of public module dependencies
#! \param DEPENDS_INTERNAL List of private module dependencies
#! \param PACKAGE_DEPENDS List of public packages dependencies (e.g. Qt, VTK, etc.).
#! Package dependencies have the following syntax:
#! \verbatim
#! PACKAGE[|COMPONENT1[+COMPONENT2]...]
#! \endverbatim
#! \param TARGET_DEPENDS List of CMake targets this module depends on
#! \param EXPORT_DEFINE Export macro name for public symbols of this module
#! \param AUTOLOAD_WITH A module target name identifying the module which will
#! trigger the automatic loading of this module
#! \param ADDITIONAL_LIBS List of addidtional libraries linked to this module
#! \param FILES_CMAKE File name of a CMake file setting source list variables
#! (defaults to files.cmake)
#! \param DEPRECATED_SINCE Marks this modules as deprecated since <arg>
#! \param DESCRIPTION A description for this module
#!
#! Options (optional)
#!
#! \param FORCE_STATIC Force building this module as a static library
#! \param HEADERS_ONLY This module is a headers-only library
#! \param GCC_DEFAULT_VISIBILITY Do not use gcc visibility flags - all
#! symbols will be exported
#! \param NO_INIT Do not create CppMicroServices initialization code
#! \param NO_FEATURE_INFO Do not create a feature info by calling add_feature_info()
#! \param WARNINGS_AS_ERRORS Treat compiler warnings as errors
#
##################################################################
function(mitk_create_module)
set(_macro_params
SUBPROJECTS # list of CDash labels
VERSION # module version number, e.g. "1.2.0"
INCLUDE_DIRS # exported include dirs (used in mitkMacroCreateModuleConf.cmake)
INTERNAL_INCLUDE_DIRS # include dirs internal to this module
DEPENDS # list of modules this module depends on
DEPENDS_INTERNAL # list of modules this module internally depends on
PACKAGE_DEPENDS # list of "packages this module depends on (e.g. Qt, VTK, etc.)
TARGET_DEPENDS # list of CMake targets this module should depend on
EXPORT_DEFINE # export macro name for public symbols of this module
AUTOLOAD_WITH # a module target name identifying the module which will trigger the
# automatic loading of this module
ADDITIONAL_LIBS # list of addidtional libraries linked to this module
FILES_CMAKE # file name of a CMake file setting source list variables
# (defaults to files.cmake)
+ CPP_FILES # list of cpp files
DEPRECATED_SINCE # marks this modules as deprecated
DESCRIPTION # a description for this module
)
set(_macro_options
FORCE_STATIC # force building this module as a static library
HEADERS_ONLY # this module is a headers-only library
GCC_DEFAULT_VISIBILITY # do not use gcc visibility flags - all symbols will be exported
NO_INIT # do not create CppMicroServices initialization code
NO_FEATURE_INFO # do not create a feature info by calling add_feature_info()
WARNINGS_AS_ERRORS # treat all compiler warnings as errors
EXECUTABLE # create an executable; do not use directly, use mitk_create_executable() instead
)
MACRO_PARSE_ARGUMENTS(MODULE "${_macro_params}" "${_macro_options}" ${ARGN})
set(MODULE_NAME ${MODULE_DEFAULT_ARGS})
if(NOT MODULE_NAME)
if(MITK_MODULE_NAME_DEFAULTS_TO_DIRECTORY_NAME)
get_filename_component(MODULE_NAME ${CMAKE_CURRENT_SOURCE_DIR} NAME)
else()
message(SEND_ERROR "The module name must not be empty")
endif()
endif()
set(_module_type module)
set(_Module_type Module)
if(MODULE_EXECUTABLE)
set(_module_type executable)
set(_Module_type Executable)
endif()
if(MITK_MODULE_NAME_REGEX_MATCH)
if(NOT ${MODULE_NAME} MATCHES ${MITK_MODULE_NAME_REGEX_MATCH})
message(SEND_ERROR "The ${_module_type} name \"${MODULE_NAME}\" does not match the regular expression \"${MITK_MODULE_NAME_REGEX_MATCH}\".")
endif()
endif()
if(MITK_MODULE_NAME_REGEX_NOT_MATCH)
if(${MODULE_NAME} MATCHES ${MITK_MODULE_NAME_REGEX_NOT_MATCH})
message(SEND_ERROR "The ${_module_type} name \"${MODULE_NAME}\" must not match the regular expression \"${MITK_MODULE_NAME_REGEX_NOT_MATCH}\".")
endif()
endif()
if(MITK_MODULE_NAME_PREFIX AND NOT MODULE_NAME MATCHES "^${MITK_MODULE_NAME_PREFIX}.*$")
set(MODULE_NAME "${MITK_MODULE_NAME_PREFIX}${MODULE_NAME}")
endif()
if(NOT MODULE_FILES_CMAKE)
set(MODULE_FILES_CMAKE files.cmake)
endif()
if(NOT IS_ABSOLUTE ${MODULE_FILES_CMAKE})
set(MODULE_FILES_CMAKE ${CMAKE_CURRENT_SOURCE_DIR}/${MODULE_FILES_CMAKE})
endif()
if(MODULE_HEADERS_ONLY)
set(MODULE_TARGET )
if(MODULE_AUTOLOAD_WITH)
message(SEND_ERROR "A headers only module cannot be auto-loaded")
endif()
else()
set(MODULE_TARGET ${MODULE_NAME})
endif()
if(MODULE_DEPRECATED_SINCE)
set(MODULE_IS_DEPRECATED 1)
else()
set(MODULE_IS_DEPRECATED 0)
endif()
if(NOT MODULE_SUBPROJECTS)
if(MITK_DEFAULT_SUBPROJECTS)
set(MODULE_SUBPROJECTS ${MITK_DEFAULT_SUBPROJECTS})
endif()
endif()
# check if the subprojects exist as targets
if(MODULE_SUBPROJECTS)
foreach(subproject ${MODULE_SUBPROJECTS})
if(NOT TARGET ${subproject})
message(SEND_ERROR "The subproject ${subproject} does not have a corresponding target")
endif()
endforeach()
endif()
# assume worst case
set(MODULE_IS_ENABLED 0)
# first we check if we have an explicit module build list
if(MITK_MODULES_TO_BUILD)
list(FIND MITK_MODULES_TO_BUILD ${MODULE_NAME} _MOD_INDEX)
if(_MOD_INDEX EQUAL -1)
set(MODULE_IS_EXCLUDED 1)
endif()
endif()
if(NOT MODULE_IS_EXCLUDED)
# first of all we check for the dependencies
_mitk_parse_package_args(${MODULE_PACKAGE_DEPENDS})
mitk_check_module_dependencies(MODULES ${MODULE_DEPENDS}
PACKAGES ${PACKAGE_NAMES}
MISSING_DEPENDENCIES_VAR _MISSING_DEP
PACKAGE_DEPENDENCIES_VAR PACKAGE_NAMES)
if(_MISSING_DEP)
if(MODULE_NO_FEATURE_INFO)
message("${_Module_type} ${MODULE_NAME} won't be built, missing dependency: ${_MISSING_DEP}")
endif()
set(MODULE_IS_ENABLED 0)
else()
set(MODULE_IS_ENABLED 1)
# now check for every package if it is enabled. This overlaps a bit with
# MITK_CHECK_MODULE ...
foreach(_package ${PACKAGE_NAMES})
if((DEFINED MITK_USE_${_package}) AND NOT (MITK_USE_${_package}))
message("${_Module_type} ${MODULE_NAME} won't be built. Turn on MITK_USE_${_package} if you want to use it.")
set(MODULE_IS_ENABLED 0)
break()
endif()
endforeach()
if(MODULE_IS_ENABLED)
# clear variables defined in files.cmake
set(RESOURCE_FILES )
set(CPP_FILES )
set(H_FILES )
set(TXX_FILES )
set(DOX_FILES )
set(UI_FILES )
set(MOC_H_FILES )
set(QRC_FILES )
# clear other variables
set(Q${KITNAME}_GENERATED_CPP )
set(Q${KITNAME}_GENERATED_MOC_CPP )
set(Q${KITNAME}_GENERATED_QRC_CPP )
set(Q${KITNAME}_GENERATED_UI_CPP )
# check and set-up auto-loading
if(MODULE_AUTOLOAD_WITH)
if(NOT TARGET "${MODULE_AUTOLOAD_WITH}")
message(SEND_ERROR "The module target \"${MODULE_AUTOLOAD_WITH}\" specified as the auto-loading module for \"${MODULE_NAME}\" does not exist")
endif()
set(_module_autoload_meta_target "${MODULE_AUTOLOAD_WITH}-autoload")
# create a meta-target if it does not already exist
if(NOT TARGET ${_module_autoload_meta_target})
add_custom_target(${_module_autoload_meta_target})
endif()
endif()
# Convert relative include dirs to absolute dirs
set(_include_dirs . ${MODULE_INCLUDE_DIRS})
set(MODULE_INCLUDE_DIRS)
foreach(dir ${_include_dirs})
get_filename_component(_abs_dir ${dir} ABSOLUTE)
list(APPEND MODULE_INCLUDE_DIRS ${_abs_dir})
endforeach()
list(APPEND MODULE_INCLUDE_DIRS ${MITK_BINARY_DIR} ${MODULES_CONF_DIRS})
# Convert relative internal include dirs to absolute dirs
set(_include_dirs ${MODULE_INTERNAL_INCLUDE_DIRS})
set(MODULE_INTERNAL_INCLUDE_DIRS)
foreach(dir ${_include_dirs})
get_filename_component(_abs_dir ${dir} ABSOLUTE)
list(APPEND MODULE_INTERNAL_INCLUDE_DIRS ${_abs_dir})
endforeach()
# Qt generates headers in the binary tree
list(APPEND MODULE_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR})
# Add the module specific include dirs
include_directories(${MODULE_INCLUDE_DIRS} ${MODULE_INTERNAL_INCLUDE_DIRS})
if(NOT MODULE_EXECUTABLE)
_MITK_CREATE_MODULE_CONF()
endif()
if(NOT MODULE_EXPORT_DEFINE)
set(MODULE_EXPORT_DEFINE ${MODULE_NAME}_EXPORT)
endif(NOT MODULE_EXPORT_DEFINE)
if(MITK_GENERATE_MODULE_DOT)
message("MODULEDOTNAME ${MODULE_NAME}")
foreach(dep ${MODULE_DEPENDS})
message("MODULEDOT \"${MODULE_NAME}\" -> \"${dep}\" ; ")
endforeach(dep)
endif(MITK_GENERATE_MODULE_DOT)
# ok, now create the module itself
- include(${MODULE_FILES_CMAKE})
+ if (EXISTS ${MODULE_FILES_CMAKE})
+ include(${MODULE_FILES_CMAKE})
+ elseif(NOT MODULE_CPP_FILES AND NOT MODULE_HEADERS_ONLY)
+ message("WARNING No cmake file found AND no cpp files specified... ")
+ endif()
set(module_c_flags )
set(module_c_flags_debug )
set(module_c_flags_release )
set(module_cxx_flags )
set(module_cxx_flags_debug )
set(module_cxx_flags_release )
if(MODULE_GCC_DEFAULT_VISIBILITY)
set(use_visibility_flags 0)
else()
# We only support hidden visibility for gcc for now. Clang 3.0 still has troubles with
# correctly marking template declarations and explicit template instantiations as exported.
# See http://comments.gmane.org/gmane.comp.compilers.clang.scm/50028
# and http://llvm.org/bugs/show_bug.cgi?id=10113
if(CMAKE_COMPILER_IS_GNUCXX)
set(use_visibility_flags 1)
else()
# set(use_visibility_flags 0)
endif()
endif()
if(CMAKE_COMPILER_IS_GNUCXX)
# MinGW does not export all symbols automatically, so no need to set flags.
#
# With gcc < 4.5, RTTI symbols from classes declared in third-party libraries
# which are not "gcc visibility aware" are marked with hidden visibility in
# DSOs which include the class declaration and which are compiled with
# hidden visibility. This leads to dynamic_cast and exception handling problems.
# While this problem could be worked around by sandwiching the include
# directives for the third-party headers between "#pragma visibility push/pop"
# statements, it is generally safer to just use default visibility with
# gcc < 4.5.
if(${GCC_VERSION} VERSION_LESS "4.5" OR MINGW)
set(use_visibility_flags 0)
endif()
endif()
if(use_visibility_flags)
mitkFunctionCheckCAndCXXCompilerFlags("-fvisibility=hidden" module_c_flags module_cxx_flags)
mitkFunctionCheckCAndCXXCompilerFlags("-fvisibility-inlines-hidden" module_c_flags module_cxx_flags)
endif()
configure_file(${MITK_SOURCE_DIR}/CMake/moduleExports.h.in ${CMAKE_BINARY_DIR}/${MODULES_CONF_DIRNAME}/${MODULE_NAME}Exports.h @ONLY)
if(MODULE_WARNINGS_AS_ERRORS)
if(MSVC_VERSION)
mitkFunctionCheckCAndCXXCompilerFlags("/WX" module_c_flags module_cxx_flags)
else()
mitkFunctionCheckCAndCXXCompilerFlags("-Werror" module_c_flags module_cxx_flags)
# The flag "c++0x-static-nonintegral-init" has been renamed in newer Clang
# versions to "static-member-init", see
# http://clang-developers.42468.n3.nabble.com/Wc-0x-static-nonintegral-init-gone-td3999651.html
#
# Also, older Clang and seemingly all gcc versions do not warn if unknown
# "-no-*" flags are used, so CMake will happily append any -Wno-* flag to the
# command line. This may get confusing if unrelated compiler errors happen and
# the error output then additionally contains errors about unknown flags (which
# is not the case if there were no compile errors).
#
# So instead of using -Wno-* we use -Wno-error=*, which will be properly rejected by
# the compiler and if applicable, prints the specific warning as a real warning and
# not as an error (although -Werror was given).
mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=c++0x-static-nonintegral-init" module_c_flags module_cxx_flags)
mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=static-member-init" module_c_flags module_cxx_flags)
mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=unknown-warning" module_c_flags module_cxx_flags)
mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=gnu" module_c_flags module_cxx_flags)
# VNL headers throw a lot of these, not fixable for us at least in ITK 3
mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=unused-parameter" module_c_flags module_cxx_flags)
# Some DICOM header file in ITK
mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=cast-align" module_c_flags module_cxx_flags)
endif()
endif(MODULE_WARNINGS_AS_ERRORS)
if(MODULE_FORCE_STATIC)
set(_STATIC STATIC)
else()
set(_STATIC )
endif(MODULE_FORCE_STATIC)
# create a meta-target for auto-loaded modules
add_custom_target(${MODULE_NAME}-autoload)
if(NOT MODULE_HEADERS_ONLY)
if(NOT MODULE_NO_INIT OR RESOURCE_FILES)
find_package(CppMicroServices QUIET NO_MODULE REQUIRED)
endif()
if(NOT MODULE_NO_INIT)
usFunctionGenerateModuleInit(CPP_FILES)
endif()
set(binary_res_files )
set(source_res_files )
if(RESOURCE_FILES)
set(res_dir Resources)
foreach(res_file ${RESOURCE_FILES})
if(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/${res_dir}/${res_file})
list(APPEND binary_res_files "${res_file}")
else()
list(APPEND source_res_files "${res_file}")
endif()
endforeach()
# Add a source level dependencies on resource files
usFunctionGetResourceSource(TARGET ${MODULE_TARGET} OUT CPP_FILES)
endif()
endif()
# Qt 4 case
if(MITK_USE_Qt4)
if(UI_FILES)
qt4_wrap_ui(Q${KITNAME}_GENERATED_UI_CPP ${UI_FILES})
endif()
if(MOC_H_FILES)
qt4_wrap_cpp(Q${KITNAME}_GENERATED_MOC_CPP ${MOC_H_FILES} OPTIONS -DBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
endif()
if(QRC_FILES)
qt4_add_resources(Q${KITNAME}_GENERATED_QRC_CPP ${QRC_FILES})
endif()
endif()
# all the same for Qt 5
if(MITK_USE_Qt5)
if(UI_FILES)
qt5_wrap_ui(Q${KITNAME}_GENERATED_UI_CPP ${UI_FILES})
endif()
if(MOC_H_FILES)
qt5_wrap_cpp(Q${KITNAME}_GENERATED_MOC_CPP ${MOC_H_FILES} OPTIONS -DBOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
endif()
if(QRC_FILES)
qt5_add_resources(Q${KITNAME}_GENERATED_QRC_CPP ${QRC_FILES})
endif()
endif()
set(Q${KITNAME}_GENERATED_CPP ${Q${KITNAME}_GENERATED_CPP} ${Q${KITNAME}_GENERATED_UI_CPP} ${Q${KITNAME}_GENERATED_MOC_CPP} ${Q${KITNAME}_GENERATED_QRC_CPP})
ORGANIZE_SOURCES(SOURCE ${CPP_FILES}
HEADER ${H_FILES}
TXX ${TXX_FILES}
DOC ${DOX_FILES}
UI ${UI_FILES}
QRC ${QRC_FILES}
MOC ${Q${KITNAME}_GENERATED_MOC_CPP}
GEN_QRC ${Q${KITNAME}_GENERATED_QRC_CPP}
GEN_UI ${Q${KITNAME}_GENERATED_UI_CPP})
set(coverage_sources
${CPP_FILES} ${H_FILES} ${GLOBBED__H_FILES} ${CORRESPONDING__H_FILES} ${TXX_FILES}
${TOOL_CPPS} ${TOOL_GUI_CPPS})
if(MODULE_SUBPROJECTS)
set_property(SOURCE ${coverage_sources} APPEND PROPERTY LABELS ${MODULE_SUBPROJECTS} MITK)
endif()
if(NOT MODULE_HEADERS_ONLY)
# We have to include the MITK_<package>_Config.cmake files here because
# some external packages do not provide exported targets with an
# absolute path to link to. So we need to add link directories *before*
# add_library() or add_executable() is called. So far, this is needed only
# for GDCM and ACVD.
_link_directories_for_packages(${PACKAGE_NAMES})
# Apply properties to the module target.
# We cannot use set_target_properties like below since there is no way to
# differentiate C/C++ and Releas/Debug flags using target properties.
# See http://www.cmake.org/Bug/view.php?id=6493
#set_target_properties(${MODULE_TARGET} PROPERTIES
# COMPILE_FLAGS "${module_compile_flags}")
#
# Strangely, we need to set the variables below in the parent scope
# (outside of the function) to be picked up by the target.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${module_c_flags}" PARENT_SCOPE)
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${module_c_flags_debug}" PARENT_SCOPE)
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${module_c_flags_release}" PARENT_SCOPE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${module_cxx_flags}" PARENT_SCOPE)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${module_cxx_flags_debug}" PARENT_SCOPE)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${module_cxx_flags_release}" PARENT_SCOPE)
if(MODULE_EXECUTABLE)
add_executable(${MODULE_TARGET}
- ${coverage_sources} ${CPP_FILES_GENERATED} ${Q${KITNAME}_GENERATED_CPP}
+ ${MODULE_CPP_FILES} ${coverage_sources} ${CPP_FILES_GENERATED} ${Q${KITNAME}_GENERATED_CPP}
${DOX_FILES} ${UI_FILES} ${QRC_FILES})
set(_us_module_name main)
else()
add_library(${MODULE_TARGET} ${_STATIC}
${coverage_sources} ${CPP_FILES_GENERATED} ${Q${KITNAME}_GENERATED_CPP}
${DOX_FILES} ${UI_FILES} ${QRC_FILES})
set(_us_module_name ${MODULE_TARGET})
endif()
set_property(TARGET ${MODULE_TARGET} APPEND PROPERTY COMPILE_DEFINITIONS US_MODULE_NAME=${_us_module_name})
set_property(TARGET ${MODULE_TARGET} PROPERTY US_MODULE_NAME ${_us_module_name})
if(MODULE_TARGET_DEPENDS)
add_dependencies(${MODULE_TARGET} ${MODULE_TARGET_DEPENDS})
endif()
if(MODULE_SUBPROJECTS)
set_property(TARGET ${MODULE_TARGET} PROPERTY LABELS ${MODULE_SUBPROJECTS} MITK)
foreach(subproject ${MODULE_SUBPROJECTS})
add_dependencies(${subproject} ${MODULE_TARGET})
endforeach()
endif()
set(DEPENDS "${MODULE_DEPENDS}")
if(NOT MODULE_NO_INIT)
# Add a CppMicroServices dependency implicitly, since it is
# needed for the generated "module initialization" code.
set(DEPENDS "CppMicroServices;${DEPENDS}")
endif()
if(DEPENDS OR MODULE_PACKAGE_DEPENDS)
mitk_use_modules(TARGET ${MODULE_TARGET}
MODULES ${DEPENDS}
PACKAGES ${MODULE_PACKAGE_DEPENDS}
)
endif()
if(MINGW)
target_link_libraries(${MODULE_TARGET} ssp) # add stack smash protection lib
endif()
# Add additional library search directories to a global property which
# can be evaluated by other CMake macros, e.g. our install scripts.
if(MODULE_ADDITIONAL_LIBS)
target_link_libraries(${MODULE_TARGET} ${MODULE_ADDITIONAL_LIBS})
get_property(_mitk_additional_library_search_paths GLOBAL PROPERTY MITK_ADDITIONAL_LIBRARY_SEARCH_PATHS)
foreach(_lib_filepath ${MODULE_ADDITIONAL_LIBS})
get_filename_component(_search_path "${_lib_filepath}" PATH)
if(_search_path)
list(APPEND _mitk_additional_library_search_paths "${_search_path}")
endif()
endforeach()
if(_mitk_additional_library_search_paths)
list(REMOVE_DUPLICATES _mitk_additional_library_search_paths)
set_property(GLOBAL PROPERTY MITK_ADDITIONAL_LIBRARY_SEARCH_PATHS ${_mitk_additional_library_search_paths})
endif()
endif()
# add the target name to a global property which is used in the top-level
# CMakeLists.txt file to export the target
set_property(GLOBAL APPEND PROPERTY MITK_MODULE_TARGETS ${MODULE_TARGET})
if(MODULE_AUTOLOAD_WITH)
# for auto-loaded modules, adapt the output directory
add_dependencies(${_module_autoload_meta_target} ${MODULE_TARGET})
if(WIN32)
set(_module_output_prop RUNTIME_OUTPUT_DIRECTORY)
else()
set(_module_output_prop LIBRARY_OUTPUT_DIRECTORY)
endif()
set(_module_output_dir ${CMAKE_${_module_output_prop}}/${MODULE_AUTOLOAD_WITH})
get_target_property(_module_is_imported ${MODULE_AUTOLOAD_WITH} IMPORTED)
if(NOT _module_is_imported)
# if the auto-loading module is not imported, get its location
# and put the auto-load module relative to it.
get_target_property(_module_output_dir ${MODULE_AUTOLOAD_WITH} ${_module_output_prop})
set_target_properties(${MODULE_TARGET} PROPERTIES
${_module_output_prop} ${_module_output_dir}/${MODULE_AUTOLOAD_WITH})
else()
set_target_properties(${MODULE_TARGET} PROPERTIES
${_module_output_prop} ${CMAKE_${_module_output_prop}}/${MODULE_AUTOLOAD_WITH})
endif()
set_target_properties(${MODULE_TARGET} PROPERTIES
MITK_AUTOLOAD_DIRECTORY ${MODULE_AUTOLOAD_WITH})
# add the auto-load module name as a property
set_property(TARGET ${MODULE_AUTOLOAD_WITH} APPEND PROPERTY MITK_AUTOLOAD_TARGETS ${MODULE_TARGET})
endif()
if(binary_res_files)
usFunctionAddResources(TARGET ${MODULE_TARGET}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${res_dir}
FILES ${binary_res_files})
endif()
if(source_res_files)
usFunctionAddResources(TARGET ${MODULE_TARGET}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${res_dir}
FILES ${source_res_files})
endif()
if(binary_res_files OR source_res_files)
usFunctionEmbedResources(TARGET ${MODULE_TARGET})
endif()
endif()
endif()
endif()
endif()
if(NOT MODULE_IS_ENABLED AND NOT MODULE_EXECUTABLE)
_MITK_CREATE_MODULE_CONF()
endif()
if(_MISSING_DEP)
if(MODULE_DESCRIPTION)
set(MODULE_DESCRIPTION "${MODULE_DESCRIPTION} (missing dependencies: ${_MISSING_DEP})")
else()
set(MODULE_DESCRIPTION "(missing dependencies: ${_MISSING_DEP})")
endif()
endif()
if(NOT MODULE_NO_FEATURE_INFO)
add_feature_info(${MODULE_NAME} MODULE_IS_ENABLED "${MODULE_DESCRIPTION}")
endif()
set(MODULE_NAME ${MODULE_NAME} PARENT_SCOPE)
set(MODULE_TARGET ${MODULE_TARGET} PARENT_SCOPE)
set(MODULE_IS_ENABLED ${MODULE_IS_ENABLED} PARENT_SCOPE)
set(MODULE_SUBPROJECTS ${MODULE_SUBPROJECTS} PARENT_SCOPE)
set(ALL_META_DEPENDENCIES ${ALL_META_DEPENDENCIES} PARENT_SCOPE)
endfunction()
diff --git a/CMake/mitkFunctionGetLibrarySearchPaths.cmake b/CMake/mitkFunctionGetLibrarySearchPaths.cmake
index 60585b675e..8ca66499b5 100644
--- a/CMake/mitkFunctionGetLibrarySearchPaths.cmake
+++ b/CMake/mitkFunctionGetLibrarySearchPaths.cmake
@@ -1,177 +1,174 @@
function(mitkFunctionGetLibrarySearchPaths search_path intermediate_dir)
set(_dir_candidates ${MITK_VTK_LIBRARY_DIRS} ${MITK_ITK_LIBRARY_DIRS}
"${MITK_BINARY_DIR}/bin" "${MITK_BINARY_DIR}/bin/plugins")
# Determine the Qt4/5 library installation prefix
set(_qmake_location )
if(MITK_USE_Qt4)
set(_qmake_location ${QT_QMAKE_EXECUTABLE})
elseif(MITK_USE_Qt5 AND TARGET ${Qt5Core_QMAKE_EXECUTABLE})
get_property(_qmake_location TARGET ${Qt5Core_QMAKE_EXECUTABLE}
PROPERTY IMPORT_LOCATION)
endif()
if(_qmake_location)
if(NOT _qt_install_libs)
if(WIN32)
execute_process(COMMAND ${_qmake_location} -query QT_INSTALL_BINS
OUTPUT_VARIABLE _qt_install_libs
OUTPUT_STRIP_TRAILING_WHITESPACE)
else()
execute_process(COMMAND ${_qmake_location} -query QT_INSTALL_LIBS
OUTPUT_VARIABLE _qt_install_libs
OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()
file(TO_CMAKE_PATH "${_qt_install_libs}" _qt_install_libs)
set(_qt_install_libs ${_qt_install_libs} CACHE INTERNAL "Qt library installation prefix" FORCE)
endif()
if(_qt_install_libs)
list(APPEND _dir_candidates ${_qt_install_libs})
endif()
elseif(MITK_USE_QT)
message(WARNING "The qmake executable could not be found.")
endif()
get_property(_additional_paths GLOBAL PROPERTY MITK_ADDITIONAL_LIBRARY_SEARCH_PATHS)
if(_additional_paths)
list(APPEND _dir_candidates ${_additional_paths})
endif()
if(VTK_DIR)
find_package(VTK QUIET)
if(VTK_RUNTIME_LIBRARY_DIRS)
list(APPEND _dir_candidates ${VTK_RUNTIME_LIBRARY_DIRS})
endif()
endif()
# The code below is sub-optimal. It makes assumptions about
# the structure of the build directories, pointed to by
# the *_DIR variables. Instead, we should rely on package
# specific "LIBRARY_DIRS" variables, if they exist.
if(WIN32)
if(DCMTK_DIR)
list(APPEND _dir_candidates "${DCMTK_DIR}/bin")
endif()
if(OpenCV_DIR)
list(APPEND _dir_candidates "${OpenCV_DIR}/bin")
endif()
if(SOFA_DIR)
list(APPEND _dir_candidates "${SOFA_DIR}/bin")
endif()
if(Python_DIR)
list(APPEND _dir_candidates "${Python_DIR}/bin")
endif()
if(SimpleITK_DIR)
list(APPEND _dir_candidates "${SimpleITK_DIR}/bin")
endif()
list(APPEND _dir_candidates "${ITK_DIR}/bin")
else()
if(DCMTK_DIR)
list(APPEND _dir_candidates "${DCMTK_DIR}/lib")
endif()
if(OpenCV_DIR)
list(APPEND _dir_candidates "${OpenCV_DIR}/lib")
endif()
if(SOFA_DIR)
list(APPEND _dir_candidates "${SOFA_DIR}/lib")
endif()
if(Python_DIR)
list(APPEND _dir_candidates "${Python_DIR}/lib")
endif()
if(SimpleITK_DIR)
list(APPEND _dir_candidates "${SimpleITK_DIR}/lib")
endif()
list(APPEND _dir_candidates "${ITK_DIR}/lib")
endif()
if(MITK_USE_Python AND CTK_PYTHONQT_INSTALL_DIR)
list(APPEND _dir_candidates "${CTK_PYTHONQT_INSTALL_DIR}/bin")
endif()
if(MITK_USE_Boost AND MITK_USE_Boost_LIBRARIES AND NOT MITK_USE_SYSTEM_Boost)
list(APPEND _dir_candidates "${Boost_LIBRARY_DIR}")
endif()
if(ACVD_DIR)
list(APPEND _dir_candidates "${ACVD_DIR}/bin")
endif()
if(ANN_DIR)
list(APPEND _dir_candidates "${ANN_DIR}")
endif()
if(CppUnit_DIR)
list(APPEND _dir_candidates "${CppUnit_DIR}")
endif()
if(GLUT_DIR)
list(APPEND _dir_candidates "${GLUT_DIR}")
endif()
if(GDCM_DIR)
list(APPEND _dir_candidates "${GDCM_DIR}/bin")
endif()
if(GLEW_DIR)
list(APPEND _dir_candidates "${GLEW_DIR}")
endif()
if(tinyxml_DIR)
list(APPEND _dir_candidates "${tinyxml_DIR}")
endif()
if(Poco_DIR)
list(APPEND _dir_candidates "${Poco_DIR}/lib")
endif()
if(Qwt_DIR)
list(APPEND _dir_candidates "${Qwt_DIR}")
endif()
- if(Qxt_DIR)
- list(APPEND _dir_candidates "${Qxt_DIR}")
- endif()
if(MITK_USE_TOF_PMDO3 OR MITK_USE_TOF_PMDCAMCUBE OR MITK_USE_TOF_PMDCAMBOARD)
list(APPEND _dir_candidates "${MITK_PMD_SDK_DIR}/plugins" "${MITK_PMD_SDK_DIR}/bin")
endif()
if(MITK_USE_CTK)
list(APPEND _dir_candidates "${CTK_LIBRARY_DIRS}")
foreach(_ctk_library ${CTK_LIBRARIES})
if(${_ctk_library}_LIBRARY_DIRS)
list(APPEND _dir_candidates "${${_ctk_library}_LIBRARY_DIRS}")
endif()
endforeach()
endif()
if(MITK_USE_BLUEBERRY)
if(DEFINED CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY)
if(IS_ABSOLUTE "${CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY}")
list(APPEND _dir_candidates "${CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY}")
else()
list(APPEND _dir_candidates "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY}")
endif()
endif()
endif()
if(MITK_LIBRARY_DIRS)
list(APPEND _dir_candidates ${MITK_LIBRARY_DIRS})
endif()
list(REMOVE_DUPLICATES _dir_candidates)
set(_search_dirs )
foreach(_dir ${_dir_candidates})
if(EXISTS "${_dir}/${intermediate_dir}")
list(APPEND _search_dirs "${_dir}/${intermediate_dir}")
else()
list(APPEND _search_dirs "${_dir}")
endif()
endforeach()
# Special handling for "internal" search dirs. The intermediate directory
# might not have been created yet, so we can't check for its existence.
# Hence we just add it for Windows without checking.
set(_internal_search_dirs "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/plugins")
if(WIN32)
foreach(_dir ${_internal_search_dirs})
set(_search_dirs "${_dir}/${intermediate_dir}" ${_search_dirs})
endforeach()
else()
set(_search_dirs ${_internal_search_dirs} ${_search_dirs})
endif()
list(REMOVE_DUPLICATES _search_dirs)
set(${search_path} ${_search_dirs} PARENT_SCOPE)
endfunction()
diff --git a/CMake/mitkMacroCreateExecutable.cmake b/CMake/mitkMacroCreateExecutable.cmake
index 23fbf25464..373a3dfd6a 100644
--- a/CMake/mitkMacroCreateExecutable.cmake
+++ b/CMake/mitkMacroCreateExecutable.cmake
@@ -1,99 +1,101 @@
##################################################################
#
# MITK_CREATE_EXECUTABLE
#
#! Creates an executable with MITK dependencies and batch files
#! for proper application start-up.
#!
#! USAGE:
#!
#! \code
#! MITK_CREATE_EXECUTABLE( [<exectuableName>]
#! [DEPENDS <modules we need>]
#! [PACKAGE_DEPENDS <packages we need, like ITK, VTK, QT>]
#! [INCLUDE_DIRS <list of additional include directories>]
#! [TARGET_DEPENDS <list of additional dependencies>
#! [WARNINGS_AS_ERRORS]
#! \endcode
#!
#! \param EXECUTABLE_NAME The name for the new executable target
##################################################################
macro(mitk_create_executable)
set(_macro_params
SUBPROJECTS # list of CDash labels
VERSION # version number, e.g. "1.2.0"
INCLUDE_DIRS # additional include dirs
DEPENDS # list of modules this module depends on
PACKAGE_DEPENDS # list of "packages" this module depends on (e.g. Qt, VTK, etc.)
TARGET_DEPENDS # list of CMake targets this executable should depend on
ADDITIONAL_LIBS # list of additional libraries linked to this executable
FILES_CMAKE # file name of a CMake file setting source list variables
# (defaults to files.cmake)
+ CPP_FILES # (optional) list of cpp files
DESCRIPTION # a description for the executable
)
set(_macro_options
NO_INIT # do not create CppMicroServices initialization code
NO_FEATURE_INFO # do not create a feature info by calling add_feature_info()
NO_BATCH_FILE # do not create batch files on Windows
WARNINGS_AS_ERRORS # treat all compiler warnings as errors
)
MACRO_PARSE_ARGUMENTS(EXEC "${_macro_params}" "${_macro_options}" ${ARGN})
set(_EXEC_OPTIONS EXECUTABLE)
if(EXEC_NO_INIT)
list(APPEND _EXEC_OPTIONS NO_INIT)
endif()
if(EXEC_WARNINGS_AS_ERRORS)
list(APPEND _EXEC_OPTIONS WARNINGS_AS_ERRORS)
endif()
if(EXEC_NO_FEATURE_INFO)
list(APPEND _EXEC_OPTIONS NO_FEATURE_INFO)
endif()
mitk_create_module(${EXEC_DEFAULT_ARGS}
SUBPROJECTS ${EXEC_SUBPROJECTS}
VERSION ${EXEC_VERSION}
INCLUDE_DIRS ${EXEC_INCLUDE_DIRS}
DEPENDS ${EXEC_DEPENDS}
PACKAGE_DEPENDS ${EXEC_PACKAGE_DEPENDS}
TARGET_DEPENDS ${EXEC_TARGET_DEPENDS}
ADDITIONAL_LIBS ${EXEC_ADDITIONAL_LIBS}
FILES_CMAKE ${EXEC_FILES_CMAKE}
+ CPP_FILES ${EXEC_CPP_FILES}
DESCRIPTION "${DESCRIPTION}"
${_EXEC_OPTIONS}
)
set(EXECUTABLE_IS_ENABLED ${MODULE_IS_ENABLED})
set(EXECUTABLE_TARGET ${MODULE_TARGET})
if(MODULE_IS_ENABLED)
# Add meta dependencies (e.g. on auto-load modules from depending modules)
if(ALL_META_DEPENDENCIES)
add_dependencies(${MODULE_TARGET} ${ALL_META_DEPENDENCIES})
endif()
# Create batch files for Windows platforms
if(WIN32)
set(_batch_file_in "${CMAKE_CURRENT_SOURCE_DIR}/${MODULE_TARGET}.bat.in")
if(NOT EXISTS "${_batch_file_in}")
set(_batch_file_in "${MITK_CMAKE_DIR}/StartApp.bat.in")
endif()
if(CMAKE_RUNTIME_OUTPUT_DIRECTORY)
set(_batch_file_out_dir "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
else()
set(_batch_file_out_dir "${CMAKE_CURRENT_BINARY_DIR}")
endif()
if(NOT EXEC_NO_BATCH_FILE)
foreach(BUILD_TYPE debug release)
mitkFunctionCreateWindowsBatchScript(
${_batch_file_in} ${_batch_file_out_dir}/${MODULE_TARGET}_${BUILD_TYPE}.bat
${BUILD_TYPE}
)
endforeach()
endif()
endif()
endif()
endmacro()
diff --git a/CMake/mitkSetupVariables.cmake b/CMake/mitkSetupVariables.cmake
index e4024464d4..e17a239081 100644
--- a/CMake/mitkSetupVariables.cmake
+++ b/CMake/mitkSetupVariables.cmake
@@ -1,106 +1,106 @@
#-----------------------------------
# Basic MITK CMake variables
#-----------------------------------
# MITK_VERSION
set(MITK_VERSION_MAJOR "2014")
-set(MITK_VERSION_MINOR "03")
+set(MITK_VERSION_MINOR "10")
set(MITK_VERSION_PATCH "99")
set(MITK_VERSION_STRING "${MITK_VERSION_MAJOR}.${MITK_VERSION_MINOR}.${MITK_VERSION_PATCH}")
if(MITK_VERSION_PATCH STREQUAL "99")
set(MITK_VERSION_STRING "${MITK_VERSION_STRING}-${MITK_REVISION_SHORTID}")
endif()
# Needed early on for redirecting the BlueBerry documentation output dir
set(MITK_DOXYGEN_OUTPUT_DIR ${PROJECT_BINARY_DIR}/Documentation/Doxygen CACHE PATH
"Output directory for doxygen generated documentation." )
if(NOT UNIX AND NOT MINGW)
set(MITK_WIN32_FORCE_STATIC "STATIC" CACHE INTERNAL "Use this variable to always build static libraries on non-unix platforms")
endif()
if(MITK_BUILD_ALL_PLUGINS)
set(MITK_BUILD_ALL_PLUGINS_OPTION "FORCE_BUILD_ALL")
endif()
#-----------------------------------
# Find external dependencies
#-----------------------------------
# Qt support
if(MITK_USE_QT)
if(DESIRED_QT_VERSION MATCHES 4)
find_package(Qt4 ${MITK_QT4_MINIMUM_VERSION} REQUIRED)
elseif(DESIRED_QT_VERSION MATCHES 5)
find_package(Qt5Core ${MITK_QT5_MINIMUM_VERSION} REQUIRED) # at least Core required
endif()
endif()
#-----------------------------------
# Configuration of module system
#-----------------------------------
set(MODULES_CONF_DIRNAME modulesConf)
set(MODULES_CONF_DIRS ${MITK_BINARY_DIR}/${MODULES_CONF_DIRNAME})
# Configure module naming conventions
set(MITK_MODULE_NAME_REGEX_MATCH "^[A-Z].*$")
set(MITK_MODULE_NAME_REGEX_NOT_MATCH "^[Mm][Ii][Tt][Kk].*$")
set(MITK_MODULE_NAME_PREFIX "Mitk")
set(MITK_MODULE_NAME_DEFAULTS_TO_DIRECTORY_NAME 1)
#-----------------------------------
# Configuration of the buid-in MITK pixel types
#-----------------------------------
# create a list of types for template instantiations of itk image access functions
function(_create_type_seq TYPES seq_var seqdim_var)
set(_seq )
set(_seq_dim )
string(REPLACE "," ";" _pixeltypes "${TYPES}")
foreach(_pixeltype ${_pixeltypes})
set(_seq "${_seq}(${_pixeltype})")
set(_seq_dim "${_seq_dim}((${_pixeltype},dim))")
endforeach()
set(${seq_var} "${_seq}" PARENT_SCOPE)
set(${seqdim_var} "${_seq_dim}" PARENT_SCOPE)
endfunction()
set(MITK_ACCESSBYITK_PIXEL_TYPES )
set(MITK_ACCESSBYITK_PIXEL_TYPES_SEQ )
set(MITK_ACCESSBYITK_TYPES_DIMN_SEQ )
# concatenate only the simple pixel types to the MITK_ACCESSBYITK_PIXEL_TYPE_SEQ list
# see Bug 12682 for detailed information
foreach(_type INTEGRAL FLOATING)
set(_typelist "${MITK_ACCESSBYITK_${_type}_PIXEL_TYPES}")
if(_typelist)
if(MITK_ACCESSBYITK_PIXEL_TYPES)
set(MITK_ACCESSBYITK_PIXEL_TYPES "${MITK_ACCESSBYITK_PIXEL_TYPES},${_typelist}")
else()
set(MITK_ACCESSBYITK_PIXEL_TYPES "${_typelist}")
endif()
endif()
_create_type_seq("${_typelist}"
MITK_ACCESSBYITK_${_type}_PIXEL_TYPES_SEQ
MITK_ACCESSBYITK_${_type}_TYPES_DIMN_SEQ)
set(MITK_ACCESSBYITK_PIXEL_TYPES_SEQ "${MITK_ACCESSBYITK_PIXEL_TYPES_SEQ}${MITK_ACCESSBYITK_${_type}_PIXEL_TYPES_SEQ}")
set(MITK_ACCESSBYITK_TYPES_DIMN_SEQ "${MITK_ACCESSBYITK_TYPES_DIMN_SEQ}${MITK_ACCESSBYITK_${_type}_TYPES_DIMN_SEQ}")
endforeach()
# separate processing of the COMPOSITE list to avoid its concatenation to the global list
_create_type_seq(${MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES}
MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES_SEQ
MITK_ACCESSBYITK_COMPOSITE_TYPES_DIMN_SEQ)
# separate processing of the VECTOR list to avoid its concatenation to the global list
_create_type_seq(${MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES}
MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES_SEQ
MITK_ACCESSBYITK_VECTOR_TYPES_DIMN_SEQ)
set(MITK_ACCESSBYITK_DIMENSIONS_SEQ )
string(REPLACE "," ";" _dimensions "${MITK_ACCESSBYITK_DIMENSIONS}")
foreach(_dimension ${_dimensions})
set(MITK_ACCESSBYITK_DIMENSIONS_SEQ "${MITK_ACCESSBYITK_DIMENSIONS_SEQ}(${_dimension})")
endforeach()
diff --git a/CMake/mitkTestPluginGenerator.cmake b/CMake/mitkTestPluginGenerator.cmake
index 001229ec94..971860cbcf 100644
--- a/CMake/mitkTestPluginGenerator.cmake
+++ b/CMake/mitkTestPluginGenerator.cmake
@@ -1,110 +1,113 @@
if(BUILD_TESTING)
set(proj GP) # Means GenerateProject (use a short name due to Windows limitations)
set(test_project_out_dir "${MITK_BINARY_DIR}")
set(test_project_source_dir "${MITK_BINARY_DIR}/${proj}")
set(test_project_binary_dir "${MITK_BINARY_DIR}/${proj}-bin")
add_test(NAME mitkPluginGeneratorCleanTest
COMMAND ${CMAKE_COMMAND} -E remove_directory "${test_project_source_dir}"
)
set_tests_properties(mitkPluginGeneratorCleanTest PROPERTIES
LABELS "MITK;BlueBerry")
add_test(NAME mitkPluginGeneratorCleanTest2
COMMAND ${CMAKE_COMMAND} -E remove_directory "${test_project_binary_dir}"
)
set_tests_properties(mitkPluginGeneratorCleanTest2 PROPERTIES
LABELS "MITK;BlueBerry")
add_test(NAME mitkPluginGeneratorCleanTest3
COMMAND ${CMAKE_COMMAND} -E make_directory "${test_project_binary_dir}"
)
set_tests_properties(mitkPluginGeneratorCleanTest3 PROPERTIES
DEPENDS mitkPluginGeneratorCleanTest2
LABELS "MITK;BlueBerry")
add_test(NAME mitkPluginGeneratorCreateTest
COMMAND ${exec_target} --project-name "${proj}" --project-app-name "TestApp"
-ps org.test.plugin -pn "Test Plugin" -vn "Test View"
-o ${test_project_out_dir} -y -n
)
set_tests_properties(mitkPluginGeneratorCreateTest PROPERTIES
DEPENDS "${exec_target};mitkPluginGeneratorCleanTest;mitkPluginGeneratorCleanTest3"
LABELS "MITK;BlueBerry")
set(configure_options
-DMITK_DIR:PATH=${MITK_BINARY_DIR}
-DCMAKE_C_COMPILER:STRING=${CMAKE_C_COMPILER}
-DCMAKE_CXX_COMPILER:STRING=${CMAKE_CXX_COMPILER}
+ -DCMAKE_OSX_SYSROOT:PATH=${CMAKE_OSX_SYSROOT}
+ -DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=${CMAKE_OSX_DEPLOYMENT_TARGET}
+ -DCMAKE_OSX_ARCHITECTURES:STRING=${CMAKE_OSX_ARCHITECTURES}
-G${CMAKE_GENERATOR}
)
if(MITK_USE_Qt4)
list(APPEND configure_options -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE})
endif()
if(CMAKE_PREFIX_PATH)
list(APPEND configure_options -DCMAKE_PREFIX_PATH:PATH=${CMAKE_PREFIX_PATH})
endif()
if(CMAKE_CONFIGURATION_TYPES)
foreach(config ${CMAKE_CONFIGURATION_TYPES})
add_test(NAME mitkPluginGeneratorConfigureTest-${config} CONFIGURATIONS ${config}
WORKING_DIRECTORY "${test_project_binary_dir}"
COMMAND ${CMAKE_COMMAND} ${configure_options}
"${test_project_source_dir}")
set_tests_properties(mitkPluginGeneratorConfigureTest-${config} PROPERTIES
DEPENDS mitkPluginGeneratorCreateTest
LABELS "MITK;BlueBerry")
add_test(NAME mitkPluginGeneratorBuildTest-${config} CONFIGURATIONS ${config}
COMMAND ${CMAKE_COMMAND} --build ${test_project_binary_dir} --config ${config})
set_tests_properties(mitkPluginGeneratorBuildTest-${config} PROPERTIES
DEPENDS mitkPluginGeneratorConfigureTest-${config}
LABELS "MITK;BlueBerry")
endforeach()
else()
add_test(NAME mitkPluginGeneratorConfigureTest-${CMAKE_BUILD_TYPE}
WORKING_DIRECTORY "${test_project_binary_dir}"
COMMAND ${CMAKE_COMMAND} ${configure_options}
-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
"${test_project_source_dir}")
set_tests_properties(mitkPluginGeneratorConfigureTest-${CMAKE_BUILD_TYPE} PROPERTIES
DEPENDS mitkPluginGeneratorCreateTest
LABELS "MITK;BlueBerry")
add_test(NAME mitkPluginGeneratorBuildTest-${CMAKE_BUILD_TYPE}
COMMAND ${CMAKE_COMMAND} --build ${test_project_binary_dir} --config ${CMAKE_BUILD_TYPE})
set_tests_properties(mitkPluginGeneratorBuildTest-${CMAKE_BUILD_TYPE} PROPERTIES
DEPENDS mitkPluginGeneratorConfigureTest-${CMAKE_BUILD_TYPE}
LABELS "MITK;BlueBerry")
endif()
set(package_test_configurations)
if(WIN32)
# Only test packaging if build type is "Release" on Windows
set(package_test_configurations CONFIGURATIONS Release)
endif()
if(NOT MITK_FAST_TESTING)
if(WIN32)
# Only test packaging if build type is "Release" on Windows
add_test(NAME mitkPluginGeneratorPackageTest CONFIGURATIONS Release
COMMAND ${CMAKE_COMMAND} --build ${test_project_binary_dir}/${proj}-build --config Release --target package)
set_tests_properties(mitkPluginGeneratorPackageTest PROPERTIES
DEPENDS mitkPluginGeneratorBuildTest-Release
TIMEOUT 6000
LABELS "MITK;BlueBerry;PACKAGE_TESTS")
elseif(CMAKE_BUILD_TYPE)
add_test(mitkPluginGeneratorPackageTest
${CMAKE_COMMAND} --build ${test_project_binary_dir}/${proj}-build --config ${CMAKE_BUILD_TYPE} --target package)
set_tests_properties(mitkPluginGeneratorPackageTest PROPERTIES
DEPENDS mitkPluginGeneratorBuildTest-${CMAKE_BUILD_TYPE}
TIMEOUT 6000
LABELS "MITK;BlueBerry;PACKAGE_TESTS")
endif()
endif()
endif()
diff --git a/CMake/mitkTestProjectTemplate.cmake b/CMake/mitkTestProjectTemplate.cmake
index 5fda20517f..64019cc556 100644
--- a/CMake/mitkTestProjectTemplate.cmake
+++ b/CMake/mitkTestProjectTemplate.cmake
@@ -1,110 +1,113 @@
if(BUILD_TESTING)
include(ExternalProject)
set(proj PT) # Means ProjectTemplate (use a short name due to Windows limitations)
set(MITK-ProjectTemplate_SOURCE_DIR "${MITK_BINARY_DIR}/${proj}")
set(MITK-ProjectTemplate_BINARY_DIR "${MITK_BINARY_DIR}/${proj}-bin")
add_test(NAME mitkProjectTemplateRmSrcTest
COMMAND ${CMAKE_COMMAND} -E remove_directory "${MITK-ProjectTemplate_SOURCE_DIR}"
)
set_tests_properties(mitkProjectTemplateRmSrcTest PROPERTIES
LABELS "MITK;BlueBerry")
add_test(NAME mitkProjectTemplateRmBinTest
COMMAND ${CMAKE_COMMAND} -E remove_directory "${MITK-ProjectTemplate_BINARY_DIR}"
)
set_tests_properties(mitkProjectTemplateRmBinTest PROPERTIES
LABELS "MITK;BlueBerry")
add_test(NAME mitkProjectTemplateMakeBinTest
COMMAND ${CMAKE_COMMAND} -E make_directory "${MITK-ProjectTemplate_BINARY_DIR}"
)
set_tests_properties(mitkProjectTemplateMakeBinTest PROPERTIES
DEPENDS mitkProjectTemplateRmBinTest
LABELS "MITK;BlueBerry")
add_test(NAME mitkProjectTemplateCloneTest
COMMAND ${GIT_EXECUTABLE} clone http://git.mitk.org/MITK-ProjectTemplate.git ${MITK-ProjectTemplate_SOURCE_DIR}
)
set_tests_properties(mitkProjectTemplateCloneTest PROPERTIES
DEPENDS mitkProjectTemplateRmSrcTest
LABELS "MITK;BlueBerry")
set(configure_options
-DMITK_DIR:PATH=${MITK_BINARY_DIR}
-DCMAKE_C_COMPILER:STRING=${CMAKE_C_COMPILER}
-DCMAKE_CXX_COMPILER:STRING=${CMAKE_CXX_COMPILER}
+ -DCMAKE_OSX_SYSROOT:PATH=${CMAKE_OSX_SYSROOT}
+ -DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=${CMAKE_OSX_DEPLOYMENT_TARGET}
+ -DCMAKE_OSX_ARCHITECTURES:STRING=${CMAKE_OSX_ARCHITECTURES}
-DAwesomeProject_BUILD_ALL_PLUGINS:BOOL=ON
-DAwesomeProject_BUILD_ALL_APPS:BOOL=ON
-G${CMAKE_GENERATOR}
)
if(MITK_USE_Qt4)
list(APPEND configure_options -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE})
endif()
if(CMAKE_PREFIX_PATH)
list(APPEND configure_options -DCMAKE_PREFIX_PATH:PATH=${CMAKE_PREFIX_PATH})
endif()
if(CMAKE_CONFIGURATION_TYPES)
foreach(config ${CMAKE_CONFIGURATION_TYPES})
add_test(NAME mitkProjectTemplateConfigureTest-${config} CONFIGURATIONS ${config}
WORKING_DIRECTORY "${MITK-ProjectTemplate_BINARY_DIR}"
COMMAND ${CMAKE_COMMAND} ${configure_options}
"${MITK-ProjectTemplate_SOURCE_DIR}")
set_tests_properties(mitkProjectTemplateConfigureTest-${config} PROPERTIES
DEPENDS "mitkProjectTemplateCloneTest;mitkProjectTemplateMakeBinTest"
LABELS "MITK;BlueBerry")
add_test(NAME mitkProjectTemplateBuildTest-${config} CONFIGURATIONS ${config}
COMMAND ${CMAKE_COMMAND} --build ${MITK-ProjectTemplate_BINARY_DIR} --config ${config})
set_tests_properties(mitkProjectTemplateBuildTest-${config} PROPERTIES
DEPENDS mitkProjectTemplateConfigureTest-${config}
LABELS "MITK;BlueBerry")
endforeach()
else()
add_test(NAME mitkProjectTemplateConfigureTest-${CMAKE_BUILD_TYPE}
WORKING_DIRECTORY "${MITK-ProjectTemplate_BINARY_DIR}"
COMMAND ${CMAKE_COMMAND} ${configure_options}
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
"${MITK-ProjectTemplate_SOURCE_DIR}")
set_tests_properties(mitkProjectTemplateConfigureTest-${CMAKE_BUILD_TYPE} PROPERTIES
DEPENDS "mitkProjectTemplateCloneTest;mitkProjectTemplateMakeBinTest"
LABELS "MITK;BlueBerry")
add_test(NAME mitkProjectTemplateBuildTest-${CMAKE_BUILD_TYPE}
COMMAND ${CMAKE_COMMAND} --build ${MITK-ProjectTemplate_BINARY_DIR} --config ${CMAKE_BUILD_TYPE})
set_tests_properties(mitkProjectTemplateBuildTest-${CMAKE_BUILD_TYPE} PROPERTIES
DEPENDS mitkProjectTemplateConfigureTest-${CMAKE_BUILD_TYPE}
LABELS "MITK;BlueBerry")
endif()
set(package_test_configurations)
if(WIN32)
# Only test packaging if build type is "Release" on Windows
set(package_test_configurations CONFIGURATIONS Release)
endif()
if(NOT MITK_FAST_TESTING)
if(WIN32)
# Only test packaging if build type is "Release" on Windows
add_test(NAME mitkProjectTemplatePackageTest CONFIGURATIONS Release
COMMAND ${CMAKE_COMMAND} --build ${MITK-ProjectTemplate_BINARY_DIR}/AwesomeProject-build --config Release --target package)
set_tests_properties(mitkProjectTemplatePackageTest PROPERTIES
DEPENDS mitkProjectTemplateBuildTest-Release
TIMEOUT 6000
LABELS "MITK;BlueBerry;PACKAGE_TESTS")
elseif(CMAKE_BUILD_TYPE)
add_test(NAME mitkProjectTemplatePackageTest
COMMAND ${CMAKE_COMMAND} --build ${MITK-ProjectTemplate_BINARY_DIR}/AwesomeProject-build --config ${CMAKE_BUILD_TYPE} --target package)
set_tests_properties(mitkProjectTemplatePackageTest PROPERTIES
DEPENDS mitkProjectTemplateBuildTest-${CMAKE_BUILD_TYPE}
TIMEOUT 6000
LABELS "MITK;BlueBerry;PACKAGE_TESTS")
endif()
endif()
endif()
diff --git a/CMakeExternals/ACVD.cmake b/CMakeExternals/ACVD.cmake
index 54fc13cf3d..409417331f 100644
--- a/CMakeExternals/ACVD.cmake
+++ b/CMakeExternals/ACVD.cmake
@@ -1,42 +1,42 @@
#-----------------------------------------------------------------------------
# ACVD
#-----------------------------------------------------------------------------
if(MITK_USE_ACVD)
# Sanity checks
if(DEFINED ACVD_DIR AND NOT EXISTS ${ACVD_DIR})
message(FATAL_ERROR "ACVD_DIR variable is defined but corresponds to non-existing directory")
endif()
set(proj ACVD)
set(proj_DEPENDENCIES VTK)
set(ACVD_DEPENDS ${proj})
set(additional_cmake_args
-DUSE_MULTITHREADING:BOOL=ON
-DVTK_DIR:PATH=${VTK_DIR}
)
- set(ACVD_PATCH_COMMAND ${CMAKE_COMMAND} -DTEMPLATE_FILE:FILEPATH=${MITK_SOURCE_DIR}/CMakeExternals/EmptyFileForPatching.dummy -P ${MITK_SOURCE_DIR}/CMakeExternals/PatchACVD.cmake)
+ set(ACVD_PATCH_COMMAND ${CMAKE_COMMAND} -DDESIRED_QT_VERSION:STRING=${DESIRED_QT_VERSION} -DTEMPLATE_FILE:FILEPATH=${MITK_SOURCE_DIR}/CMakeExternals/EmptyFileForPatching.dummy -P ${MITK_SOURCE_DIR}/CMakeExternals/PatchACVD.cmake)
if(NOT DEFINED ACVD_DIR)
ExternalProject_Add(${proj}
SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}-src
BINARY_DIR ${proj}-build
PREFIX ${proj}-cmake
URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/ACVD-vtk6_2d8f5ea5.tar.gz
URL_MD5 ecc97728a86798b35c20eef964b094c9
PATCH_COMMAND ${ACVD_PATCH_COMMAND}
INSTALL_COMMAND ""
CMAKE_GENERATOR ${gen}
CMAKE_ARGS
${ep_common_args}
${additional_cmake_args}
DEPENDS ${proj_DEPENDENCIES}
)
set(ACVD_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-build)
else()
mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}")
endif()
endif()
diff --git a/CMakeExternals/CTK.cmake b/CMakeExternals/CTK.cmake
index e4fe546732..a0805cc2e8 100644
--- a/CMakeExternals/CTK.cmake
+++ b/CMakeExternals/CTK.cmake
@@ -1,98 +1,105 @@
#-----------------------------------------------------------------------------
# CTK
#-----------------------------------------------------------------------------
if(MITK_USE_CTK)
# Sanity checks
if(DEFINED CTK_DIR AND NOT EXISTS ${CTK_DIR})
message(FATAL_ERROR "CTK_DIR variable is defined but corresponds to non-existing directory")
endif()
set(proj CTK)
set(proj_DEPENDENCIES )
set(CTK_DEPENDS ${proj})
if(NOT DEFINED CTK_DIR)
- set(revision_tag 9331130f)
+ set(revision_tag 9331130f+65420ed0+e57224a2)
#IF(${proj}_REVISION_TAG)
# SET(revision_tag ${${proj}_REVISION_TAG})
#ENDIF()
set(ctk_optional_cache_args )
if(MITK_USE_Python)
if(NOT MITK_USE_SYSTEM_PYTHON)
list(APPEND proj_DEPENDENCIES Python)
endif()
list(APPEND ctk_optional_cache_args
-DCTK_LIB_Scripting/Python/Widgets:BOOL=ON
-DCTK_ENABLE_Python_Wrapping:BOOL=ON
-DCTK_APP_ctkSimplePythonShell:BOOL=ON
-DPYTHON_EXECUTABLE:FILEPATH=${PYTHON_EXECUTABLE}
-DPYTHON_INCLUDE_DIR:PATH=${PYTHON_INCLUDE_DIR}
-DPYTHON_INCLUDE_DIR2:PATH=${PYTHON_INCLUDE_DIR2}
-DPYTHON_LIBRARY:FILEPATH=${PYTHON_LIBRARY}
)
else()
list(APPEND ctk_optional_cache_args
-DCTK_LIB_Scripting/Python/Widgets:BOOL=OFF
-DCTK_ENABLE_Python_Wrapping:BOOL=OFF
-DCTK_APP_ctkSimplePythonShell:BOOL=OFF
)
endif()
if(MITK_USE_DCMTK)
list(APPEND ctk_optional_cache_args
-DDCMTK_DIR:PATH=${DCMTK_DIR}
)
list(APPEND proj_DEPENDENCIES DCMTK)
else()
list(APPEND ctk_optional_cache_args
-DDCMTK_URL:STRING=${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/CTK_DCMTK_085525e6.tar.gz
)
endif()
+ set (ctk_qt_args -DCTK_QT_VERSION:STRING=${DESIRED_QT_VERSION})
+
+ if (DESIRED_QT_VERSION MATCHES "5")
+ list(APPEND ctk_qt_args -DQT5_INSTALL_PREFIX:FILEPATH=${QT5_INSTALL_PREFIX})
+ else()
+ list(APPEND ctk_qt_args -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE})
+ endif()
+
FOREACH(type RUNTIME ARCHIVE LIBRARY)
IF(DEFINED CTK_PLUGIN_${type}_OUTPUT_DIRECTORY)
LIST(APPEND mitk_optional_cache_args -DCTK_PLUGIN_${type}_OUTPUT_DIRECTORY:PATH=${CTK_PLUGIN_${type}_OUTPUT_DIRECTORY})
ENDIF()
ENDFOREACH()
ExternalProject_Add(${proj}
SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}-src
BINARY_DIR ${proj}-build
PREFIX ${proj}-cmake
URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/CTK_${revision_tag}.tar.gz
- URL_MD5 c6f66556103c8d0dcae4e7db5eb0f77e
+ URL_MD5 0ee6baf7333b3bb53480453311f4a3ee
UPDATE_COMMAND ""
INSTALL_COMMAND ""
CMAKE_GENERATOR ${gen}
CMAKE_ARGS
${ep_common_args}
${ctk_optional_cache_args}
- -DDESIRED_QT_VERSION:STRING=${DESIRED_QT_VERSION}
- -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}
+ ${ctk_qt_args}
-DGit_EXECUTABLE:FILEPATH=${GIT_EXECUTABLE}
-DGIT_EXECUTABLE:FILEPATH=${GIT_EXECUTABLE}
-DCTK_LIB_CommandLineModules/Backend/LocalProcess:BOOL=ON
-DCTK_LIB_CommandLineModules/Frontend/QtGui:BOOL=ON
-DCTK_LIB_PluginFramework:BOOL=ON
-DCTK_LIB_DICOM/Widgets:BOOL=ON
-DCTK_LIB_XNAT/Core:BOOL=ON
-DCTK_PLUGIN_org.commontk.eventadmin:BOOL=ON
-DCTK_PLUGIN_org.commontk.configadmin:BOOL=ON
-DCTK_USE_GIT_PROTOCOL:BOOL=OFF
-DDCMTK_URL:STRING=${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/CTK_DCMTK_085525e6.tar.gz
-DqRestAPI_URL:STRING=${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/qRestAPI_5f3a03b1.tar.gz
DEPENDS ${proj_DEPENDENCIES}
)
set(CTK_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-build)
else()
mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}")
endif()
endif()
diff --git a/CMakeExternals/Eigen.cmake b/CMakeExternals/Eigen.cmake
index 6f3ee885b2..da5fd0af63 100644
--- a/CMakeExternals/Eigen.cmake
+++ b/CMakeExternals/Eigen.cmake
@@ -1,30 +1,30 @@
#-----------------------------------------------------------------------------
# Eigen
#-----------------------------------------------------------------------------
# Sanity checks
if(DEFINED Eigen_DIR AND NOT EXISTS ${Eigen_DIR})
message(FATAL_ERROR "Eigen_DIR variable is defined but corresponds to non-existing directory")
endif()
set(proj Eigen)
set(proj_DEPENDENCIES )
set(Eigen_DEPENDS ${proj})
if(NOT DEFINED Eigen_DIR)
ExternalProject_Add(${proj}
- PREFIX ${CMAKE_BINARY_DIR}/${proj}-cmake
- URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/Eigen-3.2.2-headers-only.tar.gz
- URL_MD5 d0a7fe82ab7bd39bf577afebe287aa20
- CMAKE_ARGS
- -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/${proj}-src
-)
+ PREFIX ${CMAKE_BINARY_DIR}/${proj}-cmake
+ URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/Eigen-3.2.2-headers-only.tar.gz
+ URL_MD5 d0a7fe82ab7bd39bf577afebe287aa20
+ CMAKE_ARGS
+ -DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_CURRENT_BINARY_DIR}/${proj}-src
+ )
set(Eigen_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-src)
else()
mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}")
endif()
diff --git a/CMakeExternals/PatchACVD.cmake b/CMakeExternals/PatchACVD.cmake
index d7caa9ace7..73d4e09987 100644
--- a/CMakeExternals/PatchACVD.cmake
+++ b/CMakeExternals/PatchACVD.cmake
@@ -1,54 +1,61 @@
+set(path "CMakeLists.txt")
+file(STRINGS ${path} contents NEWLINE_CONSUME)
+if(DESIRED_QT_VERSION MATCHES "5")
+ string(REPLACE "find_package(VTK" "find_package(Qt5Widgets REQUIRED)\nfind_package(VTK" contents ${contents})
+endif()
+string(REPLACE "ENDIF(BUILD_VOLUMEPROCESSING)" "ENDIF(BUILD_VOLUMEPROCESSING)\n\nCONFIGURE_FILE(ACVDConfig.cmake.in ACVDConfig.cmake @ONLY)" contents ${contents})
+set(CONTENTS ${contents})
+configure_file(${TEMPLATE_FILE} ${path} @ONLY)
+
# Create <name>Config.cmake file to make ACVD findable through config mode of find_package()
file(WRITE "ACVDConfig.cmake.in"
"set(ACVD_INCLUDE_DIRS \"@VTKSURFACE_INCLUDE_DIR@;@VTKDISCRETEREMESHING_INCLUDE_DIR@;@VTKVOLUMEPROCESSING_INCLUDE_DIR@\")
set(ACVD_LIBRARY_DIRS \"@PROJECT_BINARY_DIR@/bin\")
set(ACVD_LIBRARIES vtkSurface vtkDiscreteRemeshing vtkVolumeProcessing)
add_definitions(-DDOmultithread)")
-file(APPEND "CMakeLists.txt" "CONFIGURE_FILE(ACVDConfig.cmake.in ACVDConfig.cmake @ONLY)")
-
# Add vtkVersionMacros.h header file
set(path "Common/vtkCurvatureMeasure.cxx")
file(STRINGS ${path} contents NEWLINE_CONSUME)
string(REPLACE "vtkNeighbourhoodComputation.h\"" "vtkNeighbourhoodComputation.h\"\n#include <vtkVersionMacros.h>" contents ${contents})
set(CONTENTS ${contents})
configure_file(${TEMPLATE_FILE} ${path} @ONLY)
# Add missing VTK_EXPORT to class declaration
set(path "VolumeProcessing/vtkImageDataCleanLabels.h")
file(STRINGS ${path} contents NEWLINE_CONSUME)
string(REPLACE "ss" "ss VTK_EXPORT" contents ${contents})
set(CONTENTS ${contents})
configure_file(${TEMPLATE_FILE} ${path} @ONLY)
# Replace int by vtkIdType, which are types of different size (x64)
set(path "DiscreteRemeshing/vtkVerticesProcessing.h")
file(STRINGS ${path} contents NEWLINE_CONSUME)
string(REPLACE "int N" "vtkIdType N" contents ${contents})
set(CONTENTS ${contents})
configure_file(${TEMPLATE_FILE} ${path} @ONLY)
# Replace VTK 5 module names by VTK 6 module names
# Link to POSIX thread library
set(path "DiscreteRemeshing/CMakeLists.txt")
file(STRINGS ${path} contents NEWLINE_CONSUME)
string(REPLACE "vtkCommon" "vtkCommonCore" contents ${contents})
string(REPLACE "vtkFiltering" "vtkFiltersCore" contents ${contents})
string(REPLACE "vtkImaging" "vtkImagingCore" contents ${contents})
string(REPLACE "vtkIO" "vtkIOCore" contents ${contents})
string(REPLACE "vtkRendering" "vtkRenderingCore" contents ${contents})
string(REPLACE "vtkHybrid" "vtkFiltersHybrid vtkImagingHybrid" contents ${contents})
string(REPLACE "ENDFOREACH(loop_var)" "ENDFOREACH()\nendif()" contents ${contents})
string(REPLACE "FOREACH(loop_var" "option(ACVD_BUILD_EXAMPLES \"build examples\" OFF)
if(ACVD_BUILD_EXAMPLES)
FOREACH(loop_var" contents ${contents})
set(CONTENTS ${contents})
configure_file(${TEMPLATE_FILE} ${path} @ONLY)
diff --git a/CMakeExternals/Patchtinyxml-2.6.2.cpp b/CMakeExternals/Patchtinyxml-2.6.2.cpp
index df8c540b47..7afb5def1c 100644
--- a/CMakeExternals/Patchtinyxml-2.6.2.cpp
+++ b/CMakeExternals/Patchtinyxml-2.6.2.cpp
@@ -1,1950 +1,1974 @@
/*
www.sourceforge.net/projects/tinyxml
Original code by Lee Thomason (www.grinninglizard.com)
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
#include <ctype.h>
#ifdef TIXML_USE_STL
#include <sstream>
#include <iostream>
#endif
#include "tinyxml.h"
FILE* TiXmlFOpen( const char* filename, const char* mode );
bool TiXmlBase::condenseWhiteSpace = true;
static unsigned int required_decimal_places = 14+1; // Need 14 for mitk default accuracy plus 1 to make sure we're within tolerance.
// Microsoft compiler security
FILE* TiXmlFOpen( const char* filename, const char* mode )
{
#if defined(_MSC_VER) && (_MSC_VER >= 1400 )
FILE* fp = 0;
errno_t err = fopen_s( &fp, filename, mode );
if ( !err && fp )
return fp;
return 0;
#else
return fopen( filename, mode );
#endif
}
void TiXmlBase::EncodeString( const TIXML_STRING& str, TIXML_STRING* outString )
{
int i=0;
while( i<(int)str.length() )
{
unsigned char c = (unsigned char) str[i];
if ( c == '&'
&& i < ( (int)str.length() - 2 )
&& str[i+1] == '#'
&& str[i+2] == 'x' )
{
// Hexadecimal character reference.
// Pass through unchanged.
// &#xA9; -- copyright symbol, for example.
//
// The -1 is a bug fix from Rob Laveaux. It keeps
// an overflow from happening if there is no ';'.
// There are actually 2 ways to exit this loop -
// while fails (error case) and break (semicolon found).
// However, there is no mechanism (currently) for
// this function to return an error.
while ( i<(int)str.length()-1 )
{
outString->append( str.c_str() + i, 1 );
++i;
if ( str[i] == ';' )
break;
}
}
else if ( c == '&' )
{
outString->append( entity[0].str, entity[0].strLength );
++i;
}
else if ( c == '<' )
{
outString->append( entity[1].str, entity[1].strLength );
++i;
}
else if ( c == '>' )
{
outString->append( entity[2].str, entity[2].strLength );
++i;
}
else if ( c == '\"' )
{
outString->append( entity[3].str, entity[3].strLength );
++i;
}
else if ( c == '\'' )
{
outString->append( entity[4].str, entity[4].strLength );
++i;
}
else if ( c < 32 )
{
// Easy pass at non-alpha/numeric/symbol
// Below 32 is symbolic.
char buf[ 32 ];
#if defined(TIXML_SNPRINTF)
TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) );
#else
sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) );
#endif
//*ME: warning C4267: convert 'size_t' to 'int'
//*ME: Int-Cast to make compiler happy ...
outString->append( buf, (int)strlen( buf ) );
++i;
}
else
{
//char realc = (char) c;
//outString->append( &realc, 1 );
*outString += (char) c; // somewhat more efficient function call.
++i;
}
}
}
TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase()
{
parent = 0;
type = _type;
firstChild = 0;
lastChild = 0;
prev = 0;
next = 0;
}
TiXmlNode::~TiXmlNode()
{
TiXmlNode* node = firstChild;
TiXmlNode* temp = 0;
while ( node )
{
temp = node;
node = node->next;
delete temp;
}
}
void TiXmlNode::CopyTo( TiXmlNode* target ) const
{
target->SetValue (value.c_str() );
target->userData = userData;
target->location = location;
}
void TiXmlNode::Clear()
{
TiXmlNode* node = firstChild;
TiXmlNode* temp = 0;
while ( node )
{
temp = node;
node = node->next;
delete temp;
}
firstChild = 0;
lastChild = 0;
}
TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node )
{
assert( node->parent == 0 || node->parent == this );
assert( node->GetDocument() == 0 || node->GetDocument() == this->GetDocument() );
if ( node->Type() == TiXmlNode::TINYXML_DOCUMENT )
{
delete node;
if ( GetDocument() )
GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
return 0;
}
node->parent = this;
node->prev = lastChild;
node->next = 0;
if ( lastChild )
lastChild->next = node;
else
firstChild = node; // it was an empty list.
lastChild = node;
return node;
}
TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis )
{
if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
{
if ( GetDocument() )
GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
return 0;
}
TiXmlNode* node = addThis.Clone();
if ( !node )
return 0;
return LinkEndChild( node );
}
TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis )
{
if ( !beforeThis || beforeThis->parent != this ) {
return 0;
}
if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
{
if ( GetDocument() )
GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
return 0;
}
TiXmlNode* node = addThis.Clone();
if ( !node )
return 0;
node->parent = this;
node->next = beforeThis;
node->prev = beforeThis->prev;
if ( beforeThis->prev )
{
beforeThis->prev->next = node;
}
else
{
assert( firstChild == beforeThis );
firstChild = node;
}
beforeThis->prev = node;
return node;
}
TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis )
{
if ( !afterThis || afterThis->parent != this ) {
return 0;
}
if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
{
if ( GetDocument() )
GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
return 0;
}
TiXmlNode* node = addThis.Clone();
if ( !node )
return 0;
node->parent = this;
node->prev = afterThis;
node->next = afterThis->next;
if ( afterThis->next )
{
afterThis->next->prev = node;
}
else
{
assert( lastChild == afterThis );
lastChild = node;
}
afterThis->next = node;
return node;
}
TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis )
{
if ( !replaceThis )
return 0;
if ( replaceThis->parent != this )
return 0;
if ( withThis.ToDocument() ) {
// A document can never be a child. Thanks to Noam.
TiXmlDocument* document = GetDocument();
if ( document )
document->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
return 0;
}
TiXmlNode* node = withThis.Clone();
if ( !node )
return 0;
node->next = replaceThis->next;
node->prev = replaceThis->prev;
if ( replaceThis->next )
replaceThis->next->prev = node;
else
lastChild = node;
if ( replaceThis->prev )
replaceThis->prev->next = node;
else
firstChild = node;
delete replaceThis;
node->parent = this;
return node;
}
bool TiXmlNode::RemoveChild( TiXmlNode* removeThis )
{
if ( !removeThis ) {
return false;
}
if ( removeThis->parent != this )
{
assert( 0 );
return false;
}
if ( removeThis->next )
removeThis->next->prev = removeThis->prev;
else
lastChild = removeThis->prev;
if ( removeThis->prev )
removeThis->prev->next = removeThis->next;
else
firstChild = removeThis->next;
delete removeThis;
return true;
}
const TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const
{
const TiXmlNode* node;
for ( node = firstChild; node; node = node->next )
{
if ( strcmp( node->Value(), _value ) == 0 )
return node;
}
return 0;
}
const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const
{
const TiXmlNode* node;
for ( node = lastChild; node; node = node->prev )
{
if ( strcmp( node->Value(), _value ) == 0 )
return node;
}
return 0;
}
const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const
{
if ( !previous )
{
return FirstChild();
}
else
{
assert( previous->parent == this );
return previous->NextSibling();
}
}
const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const
{
if ( !previous )
{
return FirstChild( val );
}
else
{
assert( previous->parent == this );
return previous->NextSibling( val );
}
}
const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const
{
const TiXmlNode* node;
for ( node = next; node; node = node->next )
{
if ( strcmp( node->Value(), _value ) == 0 )
return node;
}
return 0;
}
const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const
{
const TiXmlNode* node;
for ( node = prev; node; node = node->prev )
{
if ( strcmp( node->Value(), _value ) == 0 )
return node;
}
return 0;
}
void TiXmlElement::RemoveAttribute( const char * name )
{
#ifdef TIXML_USE_STL
TIXML_STRING str( name );
TiXmlAttribute* node = attributeSet.Find( str );
#else
TiXmlAttribute* node = attributeSet.Find( name );
#endif
if ( node )
{
attributeSet.Remove( node );
delete node;
}
}
const TiXmlElement* TiXmlNode::FirstChildElement() const
{
const TiXmlNode* node;
for ( node = FirstChild();
node;
node = node->NextSibling() )
{
if ( node->ToElement() )
return node->ToElement();
}
return 0;
}
const TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const
{
const TiXmlNode* node;
for ( node = FirstChild( _value );
node;
node = node->NextSibling( _value ) )
{
if ( node->ToElement() )
return node->ToElement();
}
return 0;
}
const TiXmlElement* TiXmlNode::NextSiblingElement() const
{
const TiXmlNode* node;
for ( node = NextSibling();
node;
node = node->NextSibling() )
{
if ( node->ToElement() )
return node->ToElement();
}
return 0;
}
const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const
{
const TiXmlNode* node;
for ( node = NextSibling( _value );
node;
node = node->NextSibling( _value ) )
{
if ( node->ToElement() )
return node->ToElement();
}
return 0;
}
const TiXmlDocument* TiXmlNode::GetDocument() const
{
const TiXmlNode* node;
for( node = this; node; node = node->parent )
{
if ( node->ToDocument() )
return node->ToDocument();
}
return 0;
}
TiXmlElement::TiXmlElement (const char * _value)
: TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
{
firstChild = lastChild = 0;
value = _value;
}
#ifdef TIXML_USE_STL
TiXmlElement::TiXmlElement( const std::string& _value )
: TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
{
firstChild = lastChild = 0;
value = _value;
}
#endif
TiXmlElement::TiXmlElement( const TiXmlElement& copy)
: TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
{
firstChild = lastChild = 0;
copy.CopyTo( this );
}
TiXmlElement& TiXmlElement::operator=( const TiXmlElement& base )
{
ClearThis();
base.CopyTo( this );
return *this;
}
TiXmlElement::~TiXmlElement()
{
ClearThis();
}
void TiXmlElement::ClearThis()
{
Clear();
while( attributeSet.First() )
{
TiXmlAttribute* node = attributeSet.First();
attributeSet.Remove( node );
delete node;
}
}
const char* TiXmlElement::Attribute( const char* name ) const
{
const TiXmlAttribute* node = attributeSet.Find( name );
if ( node )
return node->Value();
return 0;
}
#ifdef TIXML_USE_STL
const std::string* TiXmlElement::Attribute( const std::string& name ) const
{
const TiXmlAttribute* attrib = attributeSet.Find( name );
if ( attrib )
return &attrib->ValueStr();
return 0;
}
#endif
const char* TiXmlElement::Attribute( const char* name, int* i ) const
{
const TiXmlAttribute* attrib = attributeSet.Find( name );
const char* result = 0;
if ( attrib ) {
result = attrib->Value();
if ( i ) {
attrib->QueryIntValue( i );
}
}
return result;
}
#ifdef TIXML_USE_STL
const std::string* TiXmlElement::Attribute( const std::string& name, int* i ) const
{
const TiXmlAttribute* attrib = attributeSet.Find( name );
const std::string* result = 0;
if ( attrib ) {
result = &attrib->ValueStr();
if ( i ) {
attrib->QueryIntValue( i );
}
}
return result;
}
#endif
const char* TiXmlElement::Attribute( const char* name, double* d ) const
{
const TiXmlAttribute* attrib = attributeSet.Find( name );
const char* result = 0;
if ( attrib ) {
result = attrib->Value();
if ( d ) {
attrib->QueryDoubleValue( d );
}
}
return result;
}
#ifdef TIXML_USE_STL
const std::string* TiXmlElement::Attribute( const std::string& name, double* d ) const
{
const TiXmlAttribute* attrib = attributeSet.Find( name );
const std::string* result = 0;
if ( attrib ) {
result = &attrib->ValueStr();
if ( d ) {
attrib->QueryDoubleValue( d );
}
}
return result;
}
#endif
int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const
{
const TiXmlAttribute* attrib = attributeSet.Find( name );
if ( !attrib )
return TIXML_NO_ATTRIBUTE;
return attrib->QueryIntValue( ival );
}
int TiXmlElement::QueryUnsignedAttribute( const char* name, unsigned* value ) const
{
const TiXmlAttribute* node = attributeSet.Find( name );
if ( !node )
return TIXML_NO_ATTRIBUTE;
int ival = 0;
int result = node->QueryIntValue( &ival );
*value = (unsigned)ival;
return result;
}
int TiXmlElement::QueryBoolAttribute( const char* name, bool* bval ) const
{
const TiXmlAttribute* node = attributeSet.Find( name );
if ( !node )
return TIXML_NO_ATTRIBUTE;
int result = TIXML_WRONG_TYPE;
if ( StringEqual( node->Value(), "true", true, TIXML_ENCODING_UNKNOWN )
|| StringEqual( node->Value(), "yes", true, TIXML_ENCODING_UNKNOWN )
|| StringEqual( node->Value(), "1", true, TIXML_ENCODING_UNKNOWN ) )
{
*bval = true;
result = TIXML_SUCCESS;
}
else if ( StringEqual( node->Value(), "false", true, TIXML_ENCODING_UNKNOWN )
|| StringEqual( node->Value(), "no", true, TIXML_ENCODING_UNKNOWN )
|| StringEqual( node->Value(), "0", true, TIXML_ENCODING_UNKNOWN ) )
{
*bval = false;
result = TIXML_SUCCESS;
}
return result;
}
#ifdef TIXML_USE_STL
int TiXmlElement::QueryIntAttribute( const std::string& name, int* ival ) const
{
const TiXmlAttribute* attrib = attributeSet.Find( name );
if ( !attrib )
return TIXML_NO_ATTRIBUTE;
return attrib->QueryIntValue( ival );
}
#endif
int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const
{
const TiXmlAttribute* attrib = attributeSet.Find( name );
if ( !attrib )
return TIXML_NO_ATTRIBUTE;
return attrib->QueryDoubleValue( dval );
}
#ifdef TIXML_USE_STL
int TiXmlElement::QueryDoubleAttribute( const std::string& name, double* dval ) const
{
const TiXmlAttribute* attrib = attributeSet.Find( name );
if ( !attrib )
return TIXML_NO_ATTRIBUTE;
return attrib->QueryDoubleValue( dval );
}
#endif
void TiXmlElement::SetAttribute( const char * name, int val )
{
TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
if ( attrib ) {
attrib->SetIntValue( val );
}
}
#ifdef TIXML_USE_STL
void TiXmlElement::SetAttribute( const std::string& name, int val )
{
TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
if ( attrib ) {
attrib->SetIntValue( val );
}
}
#endif
void TiXmlElement::SetDoubleAttribute( const char * name, double val, const unsigned int requiredDecimalPlaces )
{
TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
if ( attrib ) {
attrib->SetDoubleValue( val, requiredDecimalPlaces );
}
}
#ifdef TIXML_USE_STL
void TiXmlElement::SetDoubleAttribute( const std::string& name, double val, const unsigned int requiredDecimalPlaces )
{
TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
if ( attrib ) {
attrib->SetDoubleValue( val, requiredDecimalPlaces );
}
}
#endif
void TiXmlElement::SetAttribute( const char * cname, const char * cvalue )
{
TiXmlAttribute* attrib = attributeSet.FindOrCreate( cname );
if ( attrib ) {
attrib->SetValue( cvalue );
}
}
#ifdef TIXML_USE_STL
void TiXmlElement::SetAttribute( const std::string& _name, const std::string& _value )
{
TiXmlAttribute* attrib = attributeSet.FindOrCreate( _name );
if ( attrib ) {
attrib->SetValue( _value );
}
}
#endif
void TiXmlElement::Print( FILE* cfile, int depth ) const
{
int i;
assert( cfile );
for ( i=0; i<depth; i++ ) {
fprintf( cfile, " " );
}
fprintf( cfile, "<%s", value.c_str() );
const TiXmlAttribute* attrib;
for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
{
fprintf( cfile, " " );
attrib->Print( cfile, depth );
}
// There are 3 different formatting approaches:
// 1) An element without children is printed as a <foo /> node
// 2) An element with only a text child is printed as <foo> text </foo>
// 3) An element with children is printed on multiple lines.
TiXmlNode* node;
if ( !firstChild )
{
fprintf( cfile, " />" );
}
else if ( firstChild == lastChild && firstChild->ToText() )
{
fprintf( cfile, ">" );
firstChild->Print( cfile, depth + 1 );
fprintf( cfile, "</%s>", value.c_str() );
}
else
{
fprintf( cfile, ">" );
for ( node = firstChild; node; node=node->NextSibling() )
{
if ( !node->ToText() )
{
fprintf( cfile, "\n" );
}
node->Print( cfile, depth+1 );
}
fprintf( cfile, "\n" );
for( i=0; i<depth; ++i ) {
fprintf( cfile, " " );
}
fprintf( cfile, "</%s>", value.c_str() );
}
}
void TiXmlElement::CopyTo( TiXmlElement* target ) const
{
// superclass:
TiXmlNode::CopyTo( target );
// Element class:
// Clone the attributes, then clone the children.
const TiXmlAttribute* attribute = 0;
for( attribute = attributeSet.First();
attribute;
attribute = attribute->Next() )
{
target->SetAttribute( attribute->Name(), attribute->Value() );
}
TiXmlNode* node = 0;
for ( node = firstChild; node; node = node->NextSibling() )
{
target->LinkEndChild( node->Clone() );
}
}
bool TiXmlElement::Accept( TiXmlVisitor* visitor ) const
{
if ( visitor->VisitEnter( *this, attributeSet.First() ) )
{
for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
{
if ( !node->Accept( visitor ) )
break;
}
}
return visitor->VisitExit( *this );
}
TiXmlNode* TiXmlElement::Clone() const
{
TiXmlElement* clone = new TiXmlElement( Value() );
if ( !clone )
return 0;
CopyTo( clone );
return clone;
}
const char* TiXmlElement::GetText() const
{
const TiXmlNode* child = this->FirstChild();
if ( child ) {
const TiXmlText* childText = child->ToText();
if ( childText ) {
return childText->Value();
}
}
return 0;
}
TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
{
tabsize = 4;
useMicrosoftBOM = false;
ClearError();
}
TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
{
tabsize = 4;
useMicrosoftBOM = false;
value = documentName;
ClearError();
}
#ifdef TIXML_USE_STL
TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
{
tabsize = 4;
useMicrosoftBOM = false;
value = documentName;
ClearError();
}
#endif
TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::TINYXML_DOCUMENT )
{
copy.CopyTo( this );
}
TiXmlDocument& TiXmlDocument::operator=( const TiXmlDocument& copy )
{
Clear();
copy.CopyTo( this );
return *this;
}
bool TiXmlDocument::LoadFile( TiXmlEncoding encoding )
{
return LoadFile( Value(), encoding );
}
bool TiXmlDocument::SaveFile() const
{
return SaveFile( Value() );
}
bool TiXmlDocument::LoadFile( const char* _filename, TiXmlEncoding encoding )
{
TIXML_STRING filename( _filename );
value = filename;
// reading in binary mode so that tinyxml can normalize the EOL
FILE* file = TiXmlFOpen( value.c_str (), "rb" );
if ( file )
{
bool result = LoadFile( file, encoding );
fclose( file );
return result;
}
else
{
SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
return false;
}
}
bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding )
{
if ( !file )
{
SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
return false;
}
// Delete the existing data:
Clear();
location.Clear();
// Get the file size, so we can pre-allocate the string. HUGE speed impact.
long length = 0;
fseek( file, 0, SEEK_END );
length = ftell( file );
fseek( file, 0, SEEK_SET );
// Strange case, but good to handle up front.
if ( length <= 0 )
{
SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
return false;
}
// Subtle bug here. TinyXml did use fgets. But from the XML spec:
// 2.11 End-of-Line Handling
// <snip>
// <quote>
// ...the XML processor MUST behave as if it normalized all line breaks in external
// parsed entities (including the document entity) on input, before parsing, by translating
// both the two-character sequence #xD #xA and any #xD that is not followed by #xA to
// a single #xA character.
// </quote>
//
// It is not clear fgets does that, and certainly isn't clear it works cross platform.
// Generally, you expect fgets to translate from the convention of the OS to the c/unix
// convention, and not work generally.
/*
while( fgets( buf, sizeof(buf), file ) )
{
data += buf;
}
*/
char* buf = new char[ length+1 ];
buf[0] = 0;
if ( fread( buf, length, 1, file ) != 1 ) {
delete [] buf;
SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
return false;
}
// Process the buffer in place to normalize new lines. (See comment above.)
// Copies from the 'p' to 'q' pointer, where p can advance faster if
// a newline-carriage return is hit.
//
// Wikipedia:
// Systems based on ASCII or a compatible character set use either LF (Line feed, '\n', 0x0A, 10 in decimal) or
// CR (Carriage return, '\r', 0x0D, 13 in decimal) individually, or CR followed by LF (CR+LF, 0x0D 0x0A)...
// * LF: Multics, Unix and Unix-like systems (GNU/Linux, AIX, Xenix, Mac OS X, FreeBSD, etc.), BeOS, Amiga, RISC OS, and others
// * CR+LF: DEC RT-11 and most other early non-Unix, non-IBM OSes, CP/M, MP/M, DOS, OS/2, Microsoft Windows, Symbian OS
// * CR: Commodore 8-bit machines, Apple II family, Mac OS up to version 9 and OS-9
const char* p = buf; // the read head
char* q = buf; // the write head
const char CR = 0x0d;
const char LF = 0x0a;
buf[length] = 0;
while( *p ) {
assert( p < (buf+length) );
assert( q <= (buf+length) );
assert( q <= p );
if ( *p == CR ) {
*q++ = LF;
p++;
if ( *p == LF ) { // check for CR+LF (and skip LF)
p++;
}
}
else {
*q++ = *p++;
}
}
assert( q <= (buf+length) );
*q = 0;
Parse( buf, 0, encoding );
delete [] buf;
return !Error();
}
bool TiXmlDocument::SaveFile( const char * filename ) const
{
// The old c stuff lives on...
FILE* fp = TiXmlFOpen( filename, "w" );
if ( fp )
{
bool result = SaveFile( fp );
fclose( fp );
return result;
}
return false;
}
bool TiXmlDocument::SaveFile( FILE* fp ) const
{
if ( useMicrosoftBOM )
{
const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
fputc( TIXML_UTF_LEAD_0, fp );
fputc( TIXML_UTF_LEAD_1, fp );
fputc( TIXML_UTF_LEAD_2, fp );
}
Print( fp, 0 );
return (ferror(fp) == 0);
}
void TiXmlDocument::CopyTo( TiXmlDocument* target ) const
{
TiXmlNode::CopyTo( target );
target->error = error;
target->errorId = errorId;
target->errorDesc = errorDesc;
target->tabsize = tabsize;
target->errorLocation = errorLocation;
target->useMicrosoftBOM = useMicrosoftBOM;
TiXmlNode* node = 0;
for ( node = firstChild; node; node = node->NextSibling() )
{
target->LinkEndChild( node->Clone() );
}
}
TiXmlNode* TiXmlDocument::Clone() const
{
TiXmlDocument* clone = new TiXmlDocument();
if ( !clone )
return 0;
CopyTo( clone );
return clone;
}
void TiXmlDocument::Print( FILE* cfile, int depth ) const
{
assert( cfile );
for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
{
node->Print( cfile, depth );
fprintf( cfile, "\n" );
}
}
bool TiXmlDocument::Accept( TiXmlVisitor* visitor ) const
{
if ( visitor->VisitEnter( *this ) )
{
for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
{
if ( !node->Accept( visitor ) )
break;
}
}
return visitor->VisitExit( *this );
}
const TiXmlAttribute* TiXmlAttribute::Next() const
{
// We are using knowledge of the sentinel. The sentinel
// have a value or name.
if ( next->value.empty() && next->name.empty() )
return 0;
return next;
}
/*
TiXmlAttribute* TiXmlAttribute::Next()
{
// We are using knowledge of the sentinel. The sentinel
// have a value or name.
if ( next->value.empty() && next->name.empty() )
return 0;
return next;
}
*/
const TiXmlAttribute* TiXmlAttribute::Previous() const
{
// We are using knowledge of the sentinel. The sentinel
// have a value or name.
if ( prev->value.empty() && prev->name.empty() )
return 0;
return prev;
}
/*
TiXmlAttribute* TiXmlAttribute::Previous()
{
// We are using knowledge of the sentinel. The sentinel
// have a value or name.
if ( prev->value.empty() && prev->name.empty() )
return 0;
return prev;
}
*/
void TiXmlAttribute::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const
{
TIXML_STRING n, v;
EncodeString( name, &n );
EncodeString( value, &v );
if (value.find ('\"') == TIXML_STRING::npos) {
if ( cfile ) {
fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() );
}
if ( str ) {
(*str) += n; (*str) += "=\""; (*str) += v; (*str) += "\"";
}
}
else {
if ( cfile ) {
fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() );
}
if ( str ) {
(*str) += n; (*str) += "='"; (*str) += v; (*str) += "'";
}
}
}
int TiXmlAttribute::QueryIntValue( int* ival ) const
{
if ( TIXML_SSCANF( value.c_str(), "%d", ival ) == 1 )
return TIXML_SUCCESS;
return TIXML_WRONG_TYPE;
}
int TiXmlAttribute::QueryDoubleValue( double* dval ) const
{
+ //save old locale
+ char * oldLocale;
+ oldLocale = setlocale( LC_ALL, 0 );
+
+ //set new locale
+ setlocale( LC_ALL, "C" );
if ( TIXML_SSCANF( value.c_str(), "%lf", dval ) == 1 )
+ {
+ //restore locale
+ setlocale( LC_ALL, oldLocale );
return TIXML_SUCCESS;
+ }
+ //restore locale
+ setlocale( LC_ALL, oldLocale );
return TIXML_WRONG_TYPE;
}
void TiXmlAttribute::SetIntValue( int _value )
{
char buf [64];
#if defined(TIXML_SNPRINTF)
TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value);
#else
sprintf (buf, "%d", _value);
#endif
SetValue (buf);
}
void TiXmlAttribute::SetDoubleValue( double _value, const unsigned int requiredDecimalPlaces )
{
#if defined(TIXML_USE_STL)
std::ostringstream ss;
- ss.imbue(std::locale("C"));
+ //save old locale
+ char * oldLocale;
+ oldLocale = setlocale( LC_ALL, 0 );
+
+ //set new locale
+ setlocale( LC_ALL, "C" );
ss.precision(TiXmlBase::Precision(_value, requiredDecimalPlaces));
ss << _value;
SetValue( ss.str() );
+ //restore locale
+ setlocale( LC_ALL, oldLocale );
#else
char buf [256];
+
+ //save old locale
+ char * oldLocale;
+ oldLocale = setlocale( LC_ALL, 0 );
+
+ //set new locale
+ setlocale( LC_ALL, "C" );
#if defined(TIXML_SNPRINTF)
TIXML_SNPRINTF( buf, sizeof(buf), TiXmlBase::Format(_value, requiredDecimalPlaces).c_str(), _value);
#else
sprintf (buf, TiXmlBase::Format(_value, requiredDecimalPlaces).c_str(), _value);
#endif
SetValue (buf);
+ //restore locale
+ setlocale( LC_ALL, oldLocale );
#endif
-
}
int TiXmlAttribute::IntValue() const
{
return atoi (value.c_str ());
}
double TiXmlAttribute::DoubleValue() const
{
#if defined(TIXML_USE_STL)
std::istringstream ss(value);
ss.imbue(std::locale("C"));
double dval;
ss >> dval;
return dval;
#else
return atof (value.c_str ());
#endif
}
TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::TINYXML_COMMENT )
{
copy.CopyTo( this );
}
TiXmlComment& TiXmlComment::operator=( const TiXmlComment& base )
{
Clear();
base.CopyTo( this );
return *this;
}
void TiXmlComment::Print( FILE* cfile, int depth ) const
{
assert( cfile );
for ( int i=0; i<depth; i++ )
{
fprintf( cfile, " " );
}
fprintf( cfile, "<!--%s-->", value.c_str() );
}
void TiXmlComment::CopyTo( TiXmlComment* target ) const
{
TiXmlNode::CopyTo( target );
}
bool TiXmlComment::Accept( TiXmlVisitor* visitor ) const
{
return visitor->Visit( *this );
}
TiXmlNode* TiXmlComment::Clone() const
{
TiXmlComment* clone = new TiXmlComment();
if ( !clone )
return 0;
CopyTo( clone );
return clone;
}
void TiXmlText::Print( FILE* cfile, int depth ) const
{
assert( cfile );
if ( cdata )
{
int i;
fprintf( cfile, "\n" );
for ( i=0; i<depth; i++ ) {
fprintf( cfile, " " );
}
fprintf( cfile, "<![CDATA[%s]]>\n", value.c_str() ); // unformatted output
}
else
{
TIXML_STRING buffer;
EncodeString( value, &buffer );
fprintf( cfile, "%s", buffer.c_str() );
}
}
void TiXmlText::CopyTo( TiXmlText* target ) const
{
TiXmlNode::CopyTo( target );
target->cdata = cdata;
}
bool TiXmlText::Accept( TiXmlVisitor* visitor ) const
{
return visitor->Visit( *this );
}
TiXmlNode* TiXmlText::Clone() const
{
TiXmlText* clone = 0;
clone = new TiXmlText( "" );
if ( !clone )
return 0;
CopyTo( clone );
return clone;
}
TiXmlDeclaration::TiXmlDeclaration( const char * _version,
const char * _encoding,
const char * _standalone )
: TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
{
version = _version;
encoding = _encoding;
standalone = _standalone;
}
#ifdef TIXML_USE_STL
TiXmlDeclaration::TiXmlDeclaration( const std::string& _version,
const std::string& _encoding,
const std::string& _standalone )
: TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
{
version = _version;
encoding = _encoding;
standalone = _standalone;
}
#endif
TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy )
: TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
{
copy.CopyTo( this );
}
TiXmlDeclaration& TiXmlDeclaration::operator=( const TiXmlDeclaration& copy )
{
Clear();
copy.CopyTo( this );
return *this;
}
void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const
{
if ( cfile ) fprintf( cfile, "<?xml " );
if ( str ) (*str) += "<?xml ";
if ( !version.empty() ) {
if ( cfile ) fprintf (cfile, "version=\"%s\" ", version.c_str ());
if ( str ) { (*str) += "version=\""; (*str) += version; (*str) += "\" "; }
}
if ( !encoding.empty() ) {
if ( cfile ) fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ());
if ( str ) { (*str) += "encoding=\""; (*str) += encoding; (*str) += "\" "; }
}
if ( !standalone.empty() ) {
if ( cfile ) fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ());
if ( str ) { (*str) += "standalone=\""; (*str) += standalone; (*str) += "\" "; }
}
if ( cfile ) fprintf( cfile, "?>" );
if ( str ) (*str) += "?>";
}
void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const
{
TiXmlNode::CopyTo( target );
target->version = version;
target->encoding = encoding;
target->standalone = standalone;
}
bool TiXmlDeclaration::Accept( TiXmlVisitor* visitor ) const
{
return visitor->Visit( *this );
}
TiXmlNode* TiXmlDeclaration::Clone() const
{
TiXmlDeclaration* clone = new TiXmlDeclaration();
if ( !clone )
return 0;
CopyTo( clone );
return clone;
}
void TiXmlUnknown::Print( FILE* cfile, int depth ) const
{
for ( int i=0; i<depth; i++ )
fprintf( cfile, " " );
fprintf( cfile, "<%s>", value.c_str() );
}
void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const
{
TiXmlNode::CopyTo( target );
}
bool TiXmlUnknown::Accept( TiXmlVisitor* visitor ) const
{
return visitor->Visit( *this );
}
TiXmlNode* TiXmlUnknown::Clone() const
{
TiXmlUnknown* clone = new TiXmlUnknown();
if ( !clone )
return 0;
CopyTo( clone );
return clone;
}
TiXmlAttributeSet::TiXmlAttributeSet()
{
sentinel.next = &sentinel;
sentinel.prev = &sentinel;
}
TiXmlAttributeSet::~TiXmlAttributeSet()
{
assert( sentinel.next == &sentinel );
assert( sentinel.prev == &sentinel );
}
void TiXmlAttributeSet::Add( TiXmlAttribute* addMe )
{
#ifdef TIXML_USE_STL
assert( !Find( TIXML_STRING( addMe->Name() ) ) ); // Shouldn't be multiply adding to the set.
#else
assert( !Find( addMe->Name() ) ); // Shouldn't be multiply adding to the set.
#endif
addMe->next = &sentinel;
addMe->prev = sentinel.prev;
sentinel.prev->next = addMe;
sentinel.prev = addMe;
}
void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe )
{
TiXmlAttribute* node;
for( node = sentinel.next; node != &sentinel; node = node->next )
{
if ( node == removeMe )
{
node->prev->next = node->next;
node->next->prev = node->prev;
node->next = 0;
node->prev = 0;
return;
}
}
assert( 0 ); // we tried to remove a non-linked attribute.
}
#ifdef TIXML_USE_STL
TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) const
{
for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
{
if ( node->name == name )
return node;
}
return 0;
}
TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const std::string& _name )
{
TiXmlAttribute* attrib = Find( _name );
if ( !attrib ) {
attrib = new TiXmlAttribute();
Add( attrib );
attrib->SetName( _name );
}
return attrib;
}
#endif
TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) const
{
for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
{
if ( strcmp( node->name.c_str(), name ) == 0 )
return node;
}
return 0;
}
TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const char* _name )
{
TiXmlAttribute* attrib = Find( _name );
if ( !attrib ) {
attrib = new TiXmlAttribute();
Add( attrib );
attrib->SetName( _name );
}
return attrib;
}
#ifdef TIXML_USE_STL
std::istream& operator>> (std::istream & in, TiXmlNode & base)
{
TIXML_STRING tag;
tag.reserve( 8 * 1000 );
base.StreamIn( &in, &tag );
base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING );
return in;
}
#endif
#ifdef TIXML_USE_STL
std::ostream& operator<< (std::ostream & out, const TiXmlNode & base)
{
TiXmlPrinter printer;
printer.SetStreamPrinting();
base.Accept( &printer );
out << printer.Str();
return out;
}
std::string& operator<< (std::string& out, const TiXmlNode& base )
{
TiXmlPrinter printer;
printer.SetStreamPrinting();
base.Accept( &printer );
out.append( printer.Str() );
return out;
}
#endif
TiXmlHandle TiXmlHandle::FirstChild() const
{
if ( node )
{
TiXmlNode* child = node->FirstChild();
if ( child )
return TiXmlHandle( child );
}
return TiXmlHandle( 0 );
}
TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const
{
if ( node )
{
TiXmlNode* child = node->FirstChild( value );
if ( child )
return TiXmlHandle( child );
}
return TiXmlHandle( 0 );
}
TiXmlHandle TiXmlHandle::FirstChildElement() const
{
if ( node )
{
TiXmlElement* child = node->FirstChildElement();
if ( child )
return TiXmlHandle( child );
}
return TiXmlHandle( 0 );
}
TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const
{
if ( node )
{
TiXmlElement* child = node->FirstChildElement( value );
if ( child )
return TiXmlHandle( child );
}
return TiXmlHandle( 0 );
}
TiXmlHandle TiXmlHandle::Child( int count ) const
{
if ( node )
{
int i;
TiXmlNode* child = node->FirstChild();
for ( i=0;
child && i<count;
child = child->NextSibling(), ++i )
{
// nothing
}
if ( child )
return TiXmlHandle( child );
}
return TiXmlHandle( 0 );
}
TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const
{
if ( node )
{
int i;
TiXmlNode* child = node->FirstChild( value );
for ( i=0;
child && i<count;
child = child->NextSibling( value ), ++i )
{
// nothing
}
if ( child )
return TiXmlHandle( child );
}
return TiXmlHandle( 0 );
}
TiXmlHandle TiXmlHandle::ChildElement( int count ) const
{
if ( node )
{
int i;
TiXmlElement* child = node->FirstChildElement();
for ( i=0;
child && i<count;
child = child->NextSiblingElement(), ++i )
{
// nothing
}
if ( child )
return TiXmlHandle( child );
}
return TiXmlHandle( 0 );
}
TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const
{
if ( node )
{
int i;
TiXmlElement* child = node->FirstChildElement( value );
for ( i=0;
child && i<count;
child = child->NextSiblingElement( value ), ++i )
{
// nothing
}
if ( child )
return TiXmlHandle( child );
}
return TiXmlHandle( 0 );
}
bool TiXmlPrinter::VisitEnter( const TiXmlDocument& )
{
return true;
}
bool TiXmlPrinter::VisitExit( const TiXmlDocument& )
{
return true;
}
bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute )
{
DoIndent();
buffer += "<";
buffer += element.Value();
for( const TiXmlAttribute* attrib = firstAttribute; attrib; attrib = attrib->Next() )
{
buffer += " ";
attrib->Print( 0, 0, &buffer );
}
if ( !element.FirstChild() )
{
buffer += " />";
DoLineBreak();
}
else
{
buffer += ">";
if ( element.FirstChild()->ToText()
&& element.LastChild() == element.FirstChild()
&& element.FirstChild()->ToText()->CDATA() == false )
{
simpleTextPrint = true;
// no DoLineBreak()!
}
else
{
DoLineBreak();
}
}
++depth;
return true;
}
bool TiXmlPrinter::VisitExit( const TiXmlElement& element )
{
--depth;
if ( !element.FirstChild() )
{
// nothing.
}
else
{
if ( simpleTextPrint )
{
simpleTextPrint = false;
}
else
{
DoIndent();
}
buffer += "</";
buffer += element.Value();
buffer += ">";
DoLineBreak();
}
return true;
}
bool TiXmlPrinter::Visit( const TiXmlText& text )
{
if ( text.CDATA() )
{
DoIndent();
buffer += "<![CDATA[";
buffer += text.Value();
buffer += "]]>";
DoLineBreak();
}
else if ( simpleTextPrint )
{
TIXML_STRING str;
TiXmlBase::EncodeString( text.ValueTStr(), &str );
buffer += str;
}
else
{
DoIndent();
TIXML_STRING str;
TiXmlBase::EncodeString( text.ValueTStr(), &str );
buffer += str;
DoLineBreak();
}
return true;
}
bool TiXmlPrinter::Visit( const TiXmlDeclaration& declaration )
{
DoIndent();
declaration.Print( 0, 0, &buffer );
DoLineBreak();
return true;
}
bool TiXmlPrinter::Visit( const TiXmlComment& comment )
{
DoIndent();
buffer += "<!--";
buffer += comment.Value();
buffer += "-->";
DoLineBreak();
return true;
}
bool TiXmlPrinter::Visit( const TiXmlUnknown& unknown )
{
DoIndent();
buffer += "<";
buffer += unknown.Value();
buffer += ">";
DoLineBreak();
return true;
}
unsigned int TiXmlBase::Precision( const double value, const unsigned int requiredDecimalPlaces ) const
{
unsigned int lhs = 0;
unsigned int one_for_plus_minus_sign = 1;
lhs = 0;
double temp(value);
while (temp >= 1.0)
{
lhs++;
temp /= 10.0;
}
return( lhs + requiredDecimalPlaces + one_for_plus_minus_sign );
}
/**
Return the printf format string that will ensure that the double value
passed in will be stored with 'required_decimal_places' worth of decimal
points as well as enough digits for the left hand side of the decimal point.
*/
TIXML_STRING TiXmlBase::Format( const double value, const unsigned int requiredDecimalPlaces ) const
{
char buf[ 32 ];
#if defined(TIXML_SNPRINTF)
TIXML_SNPRINTF( buf, sizeof(buf), "%%%d.%dlf", Precision(value, requiredDecimalPlaces), requiredDecimalPlaces);
#else
sprintf( buf, "%%%d.%dlf", Precision(value, requiredDecimalPlaces), requiredDecimalPlaces);
#endif
return(TIXML_STRING(buf));
}
-
-
-
diff --git a/CMakeExternals/Qxt.cmake b/CMakeExternals/Qxt.cmake
deleted file mode 100644
index 3e56c585ef..0000000000
--- a/CMakeExternals/Qxt.cmake
+++ /dev/null
@@ -1,43 +0,0 @@
-#-----------------------------------------------------------------------------
-# Qxt
-#-----------------------------------------------------------------------------
-
-if(MITK_USE_Qxt)
-
-# Sanity checks
-if(DEFINED Qxt_DIR AND NOT EXISTS ${Qxt_DIR})
- message(FATAL_ERROR "Qxt_DIR variable is defined but corresponds to non-existing directory")
-endif()
-
-set(proj Qxt)
-set(proj_DEPENDENCIES )
-set(${proj}_DEPENDS ${proj})
-
-if(NOT DEFINED ${proj}_DIR)
-
- set(patch_cmd ${CMAKE_COMMAND} -Dproj:STRING=${proj} -Dproj_target:STRING=QxtCore -P ${CMAKE_CURRENT_LIST_DIR}/GenerateDefaultCMakeBuildSystem.cmake)
-
- ExternalProject_Add(${proj}
- SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}-src
- BINARY_DIR ${proj}-build
- PREFIX ${proj}-cmake
- URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/libqxt-3e7424f842d4.tar.gz
- URL_MD5 a41a1e6d114cdabfc655f278176ca062
- PATCH_COMMAND ${patch_cmd}
- INSTALL_COMMAND ""
- CMAKE_GENERATOR ${gen}
- CMAKE_ARGS
- ${ep_common_args}
- ${qt_project_args}
- DEPENDS ${proj_DEPENDENCIES}
- )
-
- set(${proj}_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-build)
-
-else()
-
- mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}")
-
-endif()
-
-endif()
diff --git a/CMakeExternals/QxtCMakeLists.txt b/CMakeExternals/QxtCMakeLists.txt
deleted file mode 100644
index cfc018037b..0000000000
--- a/CMakeExternals/QxtCMakeLists.txt
+++ /dev/null
@@ -1,559 +0,0 @@
-if(DESIRED_QT_VERSION MATCHES 5)
- cmake_minimum_required(VERSION 2.8.12)
-else()
- cmake_minimum_required(VERSION 2.8.4)
-endif()
-
-project(Qxt)
-
-set(${PROJECT_NAME}_MAJOR_VERSION 0)
-set(${PROJECT_NAME}_MINOR_VERSION 6)
-set(${PROJECT_NAME}_PATCH_VERSION 99)
-set(${PROJECT_NAME}_VERSION ${${PROJECT_NAME}_MAJOR_VERSION}.${${PROJECT_NAME}_MINOR_VERSION}.${${PROJECT_NAME}_PATCH_VERSION})
-
-macro(_qt_generate_mocs)
- foreach(file ${ARGN})
- get_filename_component(source_path ${file} PATH)
- get_filename_component(source_name ${file} NAME_WE)
- get_filename_component(source_ext ${file} EXT)
-
- set(moc_file ${CMAKE_CURRENT_BINARY_DIR}/${source_path}/moc_${source_name}.cpp)
- if(DESIRED_QT_VERSION MATCHES "4")
- QT4_GENERATE_MOC(${file} ${moc_file})
- else()
- qt5_generate_moc(${file} ${moc_file})
- endif()
- set_property(SOURCE ${source_path}/${source_name}.cpp APPEND PROPERTY
- OBJECT_DEPENDS ${moc_file})
- endforeach()
-endmacro()
-
-macro(_qt_wrap_cpp)
- if(DESIRED_QT_VERSION MATCHES "4")
- qt4_wrap_cpp(${ARGN})
- else()
- qt5_wrap_cpp(${ARGN})
- endif()
-endmacro()
-
-macro(_qt_add_resources)
- if(DESIRED_QT_VERSION MATCHES "4")
- qt4_add_resources(${ARGN})
- else()
- qt5_add_resources(${ARGN})
- endif()
-endmacro()
-
-set(${PROJECT_NAME}_LIBRARIES
- QxtCore
- QxtWidgets
- QxtNetwork
- QxtWeb
-)
-
-set(QXT_CORE_MOC_HEADERS
- qxtabstractconnectionmanager.h
- qxtboundfunction.h
- qxtcsvmodel.h
- qxtdaemon.h
- qxtdeplex.h
- qxtdeplex_p.h
- qxtfifo.h
- qxtfilelock.h
- qxtjob.h
- qxtjob_p.h
- qxtlinesocket.h
- qxtlinesocket_p.h
- qxtlocale.h
- qxtlogger.h
- qxtlogger_p.h
- qxtmultisignalwaiter.h
- qxtnamespace.h
- qxtpipe.h
- qxtpipe_p.h
- qxtpointerlist.h
- qxtsignalgroup.h
- qxtsignalwaiter.h
- qxtslotjob.h
- qxtslotjob_p.h
- qxtstdio.h
- qxtstdio_p.h
- qxtstdstreambufdevice.h
- qxtrpcservice.h
- qxtrpcservice_p.h
-)
-
-set(QXT_GUI_MOC_HEADERS
- qxtbasespinbox.h
- qxtcheckcombobox.h
- qxtcheckcombobox_p.h
- qxtconfigdialog.h
- qxtconfigdialog_p.h
- qxtconfigwidget.h
- qxtconfigwidget_p.h
- qxtconfirmationmessage.h
- qxtcountrycombobox.h
- qxtcountrycombobox_p.h
- qxtcountrymodel.h
- qxtcountrymodel_p.h
- qxtcrumbview.h
- qxtcrumbview_p.h
- qxtflowview.h
- qxtflowview_p.h
- qxtgroupbox.h
- qxtheaderview.h
- qxtitemdelegate.h
- qxtitemdelegate_p.h
- qxtlabel.h
- qxtletterboxwidget.h
- qxtletterboxwidget_p.h
- qxtlineedit.h
- qxtlistwidget.h
- qxtlistwidget_p.h
- qxtlanguagecombobox.h
- qxtlanguagecombobox_p.h
- qxtprogresslabel.h
- qxtproxystyle.h
- qxtpushbutton.h
- qxtspanslider.h
- qxtspanslider_p.h
- qxtstars.h
- qxtstringspinbox.h
- qxtstringvalidator.h
- qxttablewidget.h
- qxttablewidget_p.h
- qxttabwidget.h
- qxttabwidget_p.h
- qxttooltip_p.h
- qxttreewidget.h
- qxttreewidget_p.h
-
- qxtscheduleheaderwidget.h
- qxtscheduleitemdelegate.h
- qxtscheduleview.h
- qxtscheduleviewheadermodel_p.h
- qxtscheduleview_p.h
-
- qxtsortfilterproxymodel.h
- qxtfilterdialog.h
- qxtfilterdialog_p.h
- qxtlookuplineedit.h
-
- # !qws:!symbian
- #qxtapplication.h
- #qxtglobalshortcut.h
-)
-
-set(QXT_NETWORK_MOC_HEADERS
- qxtjsonrpcclient.h
- qxtsmtp.h
- qxtrpcpeer.h
- qxtsmtp_p.h
- qxtsslserver.h
- qxtsslconnectionmanager.h
- qxttcpconnectionmanager.h
- qxttcpconnectionmanager_p.h
- qxtxmlrpcclient.h
-)
-
-set(QXT_WEB_MOC_HEADERS
- qxtabstracthttpconnector.h
- qxtabstractwebservice.h
- qxtabstractwebsessionmanager.h
- qxtabstractwebsessionmanager_p.h
- qxthttpsessionmanager.h
- qxtwebcontent.h
- qxtwebservicedirectory.h
- qxtwebservicedirectory_p.h
- qxtwebslotservice.h
- qxtwebcgiservice.h
- qxtwebcgiservice_p.h
-)
-
-set(QXT_NETWORK_MANUAL_MOC_HEADERS
- qxtjsonrpccall.h
- qxtxmlrpccall.h
-)
-
-set(QXT_CORE_SOURCES
- qxtabstractconnectionmanager.cpp
- qxtabstractfileloggerengine.cpp
- qxtabstractiologgerengine.cpp
- qxtbasicfileloggerengine.cpp
- qxtbasicstdloggerengine.cpp
- qxtcommandoptions.cpp
- qxtcsvmodel.cpp
- qxtdaemon.cpp
- qxtdatastreamsignalserializer.cpp
- qxtdeplex.cpp
- qxterror.cpp
- qxtfifo.cpp
- qxtfilelock.cpp
- qxtglobal.cpp
- qxthmac.cpp
- qxtlocale.cpp
- qxtjson.cpp
- qxtjob.cpp
- qxtlinesocket.cpp
- qxtlinkedtree.cpp
- qxtlogger.cpp
- qxtloggerengine.cpp
- qxtlogstream.cpp
- qxtmetaobject.cpp
- qxtmodelserializer.cpp
- qxtmultisignalwaiter.cpp
- qxtnull.cpp
- qxtpipe.cpp
- qxtpointerlist.cpp
- qxtsignalgroup.cpp
- qxtsignalwaiter.cpp
- qxtslotjob.cpp
- qxtslotmapper.cpp
- qxtstdio.cpp
- qxtstdstreambufdevice.cpp
- qxttimer.cpp
- qxtrpcservice.cpp
- qxtxmlfileloggerengine.cpp
-)
-
-set(QXT_GUI_SOURCES
- qxtbasespinbox.cpp
- qxtcheckcombobox.cpp
- qxtconfigdialog.cpp
- qxtconfigwidget.cpp
- qxtconfirmationmessage.cpp
- qxtcountrymodel.cpp
- qxtcountrycombobox.cpp
- qxtcrumbview.cpp
- qxtflowview.cpp
- qxtflowview_p.cpp
- qxtgroupbox.cpp
- qxtheaderview.cpp
- qxtitemdelegate.cpp
- qxtlabel.cpp
- qxtletterboxwidget.cpp
- qxtlineedit.cpp
- qxtlistwidget.cpp
- qxtlistwidgetitem.cpp
- qxtlanguagecombobox.cpp
- qxtprogresslabel.cpp
- qxtproxystyle.cpp
- qxtpushbutton.cpp
- qxtspanslider.cpp
- qxtstars.cpp
- qxtstringspinbox.cpp
- qxtstringvalidator.cpp
- qxttablewidget.cpp
- qxttablewidgetitem.cpp
- qxttabwidget.cpp
- qxttooltip.cpp
- qxttreewidget.cpp
- qxttreewidgetitem.cpp
-
- qxtscheduleitemdelegate.cpp
- qxtscheduleview.cpp
- qxtscheduleview_p.cpp
- qxtscheduleviewheadermodel_p.cpp
- qxtstyleoptionscheduleviewitem.cpp
- qxtscheduleheaderwidget.cpp
-
- qxtsortfilterproxymodel.cpp
- qxtfilterdialog.cpp
- qxtlookuplineedit.cpp
-
- # !qws:!symbian
- #qxtapplication.cpp
- #qxtglobalshortcut.cpp
-)
-
-set(QXT_NETWORK_SOURCES
- qxtjsonrpccall.cpp
- qxtjsonrpcclient.cpp
- qxtmailattachment.cpp
- qxtmailmessage.cpp
- qxtrpcpeer.cpp
- qxtsmtp.cpp
- qxtsslserver.cpp
- qxtsslconnectionmanager.cpp
- qxttcpconnectionmanager.cpp
- qxtxmlrpccall.cpp
- qxtxmlrpcclient.cpp
- qxtxmlrpc_p.cpp
-)
-
-set(QXT_WEB_SOURCES
- qxtabstracthttpconnector.cpp
- qxtabstractwebservice.cpp
- qxtabstractwebsessionmanager.cpp
- qxthtmltemplate.cpp
- qxthttpserverconnector.cpp
- qxthttpsessionmanager.cpp
- qxtscgiserverconnector.cpp
- qxtwebcontent.cpp
- qxtwebevent.cpp
- qxtwebservicedirectory.cpp
- qxtwebslotservice.cpp
- qxtwebcgiservice.cpp
-)
-
-if(UNIX)
- list(APPEND QXT_CORE_MOC_HEADERS unix/qxtserialdevice.h unix/qxtserialdevice_p.h)
- list(APPEND QXT_CORE_SOURCES
- unix/qxtfilelock_unix.cpp unix/qxtserialdevice.cpp unix/qxtserialdevice_unix.cpp)
- if(APPLE)
- list(APPEND QXT_GUI_SOURCES
- #mac/qxtapplication_mac.cpp
- #mac/qxtglobalshortcut_mac.cpp
- )
- else()
- if(DESIRED_QT_VERSION MATCHES "5")
- find_package(Qt5X11Extras REQUIRED)
- endif()
- list(APPEND QXT_GUI_SOURCES
- #x11/qxtapplication_x11.cpp
- #x11/qxtglobalshortcut_x11.cpp
- x11/qxtscreen_x11.cpp
- #x11/qxtwindowsystem_x11.cpp
- )
- endif()
-endif()
-
-if(NOT APPLE)
- list(APPEND QXT_GUI_SOURCES
- qxtscreen.cpp
- #qxtwindowsystem.cpp
- )
-endif()
-
-if(WIN32)
- list(APPEND QXT_CORE_SOURCES win/qxtfilelock_win.cpp)
- list(APPEND QXT_GUI_SOURCES
- #win/qxtapplication_win.cpp
- #win/qxtglobalshortcut_win.cpp
- win/qxtscreen_win.cpp
- #win/qxtwindowsystem_win.cpp
- )
-endif()
-
-set(_qxt_core_moc_headers )
-foreach(_header ${QXT_CORE_MOC_HEADERS})
- list(APPEND _qxt_core_moc_headers src/core/${_header})
-endforeach()
-
-set(_qxt_gui_moc_headers )
-foreach(_header ${QXT_GUI_MOC_HEADERS})
- list(APPEND _qxt_gui_moc_headers src/widgets/${_header})
-endforeach()
-
-set(_qxt_network_moc_headers )
-foreach(_header ${QXT_NETWORK_MOC_HEADERS})
- list(APPEND _qxt_network_moc_headers src/network/${_header})
-endforeach()
-
-set(_qxt_network_manual_moc_headers )
-foreach(_header ${QXT_NETWORK_MANUAL_MOC_HEADERS})
- list(APPEND _qxt_network_manual_moc_headers src/network/${_header})
-endforeach()
-
-set(_qxt_web_moc_headers )
-foreach(_header ${QXT_WEB_MOC_HEADERS})
- list(APPEND _qxt_web_moc_headers src/web/${_header})
-endforeach()
-
-set(_qxt_core_sources )
-foreach(_source ${QXT_CORE_SOURCES})
- list(APPEND _qxt_core_sources src/core/${_source})
-endforeach()
-
-set(_qxt_gui_sources )
-foreach(_source ${QXT_GUI_SOURCES})
- list(APPEND _qxt_gui_sources src/widgets/${_source})
-endforeach()
-
-set(_qxt_network_sources )
-foreach(_source ${QXT_NETWORK_SOURCES})
- list(APPEND _qxt_network_sources src/network/${_source})
-endforeach()
-
-set(_qxt_web_sources )
-foreach(_source ${QXT_WEB_SOURCES})
- list(APPEND _qxt_web_sources src/web/${_source})
-endforeach()
-
-set(_qxt_gui_resources src/widgets/resources.qrc)
-
-set(${PROJECT_NAME}_INCLUDE_DIRS
- ${CMAKE_CURRENT_SOURCE_DIR}/src/core
- ${CMAKE_CURRENT_SOURCE_DIR}/include/QxtCore
- ${CMAKE_CURRENT_SOURCE_DIR}/src/widgets
- ${CMAKE_CURRENT_SOURCE_DIR}/include/QxtWidgets
- ${CMAKE_CURRENT_SOURCE_DIR}/src/network
- ${CMAKE_CURRENT_SOURCE_DIR}/include/QxtNetwork
- ${CMAKE_CURRENT_SOURCE_DIR}/src/web
- ${CMAKE_CURRENT_SOURCE_DIR}/include/QxtWeb
- )
-
-include_directories(${${PROJECT_NAME}_INCLUDE_DIRS})
-
-if(DESIRED_QT_VERSION MATCHES "4")
- find_package(Qt4 REQUIRED)
- set(QT_USE_QTNETWORK 1)
- set(QT_USE_QTDESIGNER 1)
- include(${QT_USE_FILE})
- if("${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}" VERSION_LESS "4.8")
- # We add the QT_NO_OPENSSL definition in case of Qt < 4.8 because
- # the Qxt SSL code uses QSsl::TlsV1SslV3 which added in Qt 4.8.
- # So even if Qt 4.7 was compiled with OpenSSL support, we manually
- # disable it in Qxt to simplify the build system stuff and to avoid
- # bumping the minimum required Qt version for MITK
- add_definitions(-DQT_NO_OPENSSL)
- endif()
-else()
- if (WIN32)
- cmake_policy(SET CMP0020 NEW) # Automatically link Qt executables to qtmain target on Windows
- endif()
- find_package(Qt5 COMPONENTS Network Designer Widgets REQUIRED)
-endif()
-
-# Build the QxtCore library
-_qt_wrap_cpp(_qxt_core_sources ${_qxt_core_moc_headers})
-
-add_library(QxtCore SHARED ${_qxt_core_sources})
-if(DESIRED_QT_VERSION MATCHES "4")
- target_link_libraries(QxtCore ${QT_LIBRARIES})
-else()
- target_link_libraries(QxtCore Qt5::Core)
-endif()
-
-set_target_properties(QxtCore PROPERTIES
- SOVERSION ${${PROJECT_NAME}_VERSION}
- COMPILE_DEFINITIONS "BUILD_QXT_CORE")
-
-# Build the QxtWidgets (formerly QxtGui) library
-_qt_wrap_cpp(_qxt_gui_sources ${_qxt_gui_moc_headers})
-_qt_add_resources(_qxt_gui_sources ${_qxt_gui_resources})
-
-if(DESIRED_QT_VERSION MATCHES "4")
- set(QxtGui_link_libraries ${QT_LIBRARIES})
-else()
- set(QxtGui_link_libraries Qt5::Widgets)
- if(UNIX AND NOT APPLE)
- list(APPEND QxtGui_link_libraries Qt5::X11Extras)
- endif()
-endif()
-if(APPLE)
- find_library(CARBON_FW NAMES Carbon)
- list(APPEND QxtGui_link_libraries ${CARBON_FW})
-endif()
-add_library(QxtWidgets SHARED ${_qxt_gui_sources})
-target_link_libraries(QxtWidgets QxtCore ${QxtGui_link_libraries})
-
-set_target_properties(QxtWidgets PROPERTIES
- SOVERSION ${${PROJECT_NAME}_VERSION}
- COMPILE_DEFINITIONS "BUILD_QXT_GUI")
-
-# Build the QxtNetwork library
-_qt_wrap_cpp(_qxt_network_sources ${_qxt_network_moc_headers})
-_qt_add_resources(_qxt_network_sources ${_qxt_network_resources})
-
-# The generate moc_* sources are included directly in .cpp files
-_qt_generate_mocs(${_qxt_network_manual_moc_headers})
-include_directories(${CMAKE_CURRENT_BINARY_DIR}/src/network)
-
-add_library(QxtNetwork SHARED ${_qxt_network_sources})
-if(DESIRED_QT_VERSION MATCHES "4")
- target_link_libraries(QxtNetwork QxtCore ${QT_LIBRARIES})
-else()
- target_link_libraries(QxtNetwork Qt5::Network)
-endif()
-
-set_target_properties(QxtNetwork PROPERTIES
- SOVERSION ${${PROJECT_NAME}_VERSION}
- COMPILE_DEFINITIONS "BUILD_QXT_NETWORK")
-
-# Build the QxtWeb library
-_qt_wrap_cpp(_qxt_web_sources ${_qxt_web_moc_headers})
-
-add_library(QxtWeb SHARED ${_qxt_web_sources})
-target_link_libraries(QxtWeb QxtCore QxtNetwork ${QT_LIBRARIES})
-
-set_target_properties(QxtWeb PROPERTIES
- SOVERSION ${${PROJECT_NAME}_VERSION}
- COMPILE_DEFINITIONS "BUILD_QXT_WEB")
-
-
-# Build the designer plug-in
-
-set(_qxt_designer_sources
- src/designer/qxtbasespinboxplugin.cpp
- src/designer/qxtcheckcomboboxplugin.cpp
- src/designer/qxtcountrycomboboxplugin.cpp
- src/designer/qxtdesignerplugin.cpp
- src/designer/qxtdesignerplugins.cpp
- src/designer/qxtflowviewplugin.cpp
- src/designer/qxtgroupboxplugin.cpp
- src/designer/qxtlabelplugin.cpp
- src/designer/qxtlanguagecomboboxplugin.cpp
- src/designer/qxtletterboxwidgetplugin.cpp
- src/designer/qxtlineeditplugin.cpp
- src/designer/qxtlistwidgetplugin.cpp
- src/designer/qxtprogresslabelplugin.cpp
- src/designer/qxtpushbuttonplugin.cpp
- src/designer/qxtspansliderplugin.cpp
- src/designer/qxtstarsplugin.cpp
- src/designer/qxtstringspinboxplugin.cpp
- src/designer/qxttablewidgetplugin.cpp
- src/designer/qxttreewidgetplugin.cpp
-)
-
-set(wrap_cpp_options )
-if(DESIRED_QT_VERSION MATCHES "5")
- list(APPEND wrap_cpp_options TARGET QxtDesignerPlugins)
-endif()
-
-_qt_wrap_cpp(_qxt_designer_sources
- src/designer/qxtbasespinboxplugin.h
- src/designer/qxtcheckcomboboxplugin.h
- src/designer/qxtcountrycomboboxplugin.h
- src/designer/qxtdesignerplugins.h
- src/designer/qxtflowviewplugin.h
- src/designer/qxtgroupboxplugin.h
- src/designer/qxtlabelplugin.h
- src/designer/qxtlanguagecomboboxplugin.h
- src/designer/qxtletterboxwidgetplugin.h
- src/designer/qxtlineeditplugin.h
- src/designer/qxtlistwidgetplugin.h
- src/designer/qxtprogresslabelplugin.h
- src/designer/qxtpushbuttonplugin.h
- src/designer/qxtspansliderplugin.h
- src/designer/qxtstarsplugin.h
- src/designer/qxtstringspinboxplugin.h
- src/designer/qxttablewidgetplugin.h
- src/designer/qxttreewidgetplugin.h
- ${wrap_cpp_options}
-)
-
-_qt_add_resources(_qxt_designer_sources src/designer/resources.qrc)
-add_library(QxtDesignerPlugins SHARED ${_qxt_designer_sources})
-if(DESIRED_QT_VERSION MATCHES "4")
- target_link_libraries(QxtDesignerPlugins QxtWidgets QxtCore ${QT_LIBRARIES})
-else()
- target_link_libraries(QxtDesignerPlugins QxtWidgets QxtCore Qt5::Designer)
-endif()
-
-set_target_properties(QxtDesignerPlugins PROPERTIES
- SOVERSION ${${PROJECT_NAME}_VERSION}
- COMPILE_DEFINITIONS BUILD_QXT_DESIGNER)
-
-
-# Config files
-configure_file(${PROJECT_NAME}Config.cmake.in
- ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake @ONLY)
-export(TARGETS ${Qxt_LIBRARIES} FILE ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Exports.cmake)
-
-# Version information
-configure_file(
- ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}ConfigVersion.cmake.in
- ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
- @ONLY
- )
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b88ed89574..b8825baaeb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,1084 +1,1085 @@
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
+ CMP0014 # NEW: Input directories must have CMakeLists.txt.
+ CMP0020 # NEW: Automatically link Qt executables to qtmain target on Windows.
+ CMP0028 # NEW: Double colon in target name means ALIAS or IMPORTED target.
)
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)
+ find_package(Qt5Concurrent ${MITK_QT5_MINIMUM_VERSION} REQUIRED)
+ find_package(Qt5OpenGL ${MITK_QT5_MINIMUM_VERSION} REQUIRED)
+ find_package(Qt5PrintSupport ${MITK_QT5_MINIMUM_VERSION} REQUIRED)
+ find_package(Qt5Sql ${MITK_QT5_MINIMUM_VERSION} REQUIRED)
+ find_package(Qt5Svg ${MITK_QT5_MINIMUM_VERSION} REQUIRED)
+ find_package(Qt5WebKit ${MITK_QT5_MINIMUM_VERSION} REQUIRED)
+ find_package(Qt5WebKitWidgets ${MITK_QT5_MINIMUM_VERSION} REQUIRED)
+ find_package(Qt5Widgets ${MITK_QT5_MINIMUM_VERSION} REQUIRED)
+ find_package(Qt5Xml ${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_BLUEBERRY "Build the BlueBerry platform" ON)
+env_option(MITK_USE_CTK "Use CTK in MITK" ON)
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 mitkDiffusion All)
+set_property(CACHE MITK_BUILD_CONFIGURATION PROPERTY STRINGS Custom Default WorkbenchRelease mitkDiffusion 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<unsigned char>, itk::RGBAPixel<unsigned char>"
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<unsigned char>, itk::RGBAPixel<unsigned char>"
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
+ set(MITK_CXX_FLAGS "${MITK_CXX_FLAGS} -D_WIN32_WINNT=0x0501 -DPOCO_NO_UNWINDOWS -DWIN32_LEAN_AND_MEAN -DNOMINMAX")
+ mitkFunctionCheckCompilerFlags("/wd4005" MITK_CXX_FLAGS) # warning C4005: macro redefinition
+ mitkFunctionCheckCompilerFlags("/wd4231" MITK_CXX_FLAGS) # warning C4231: nonstandard extension used : 'extern' before template explicit instantiation
# the following line should be removed after fixing bug 17637
mitkFunctionCheckCompilerFlags("/wd4316" MITK_CXX_FLAGS) # warning C4316: object alignment on heap
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 <stdexcept>")
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")
if(TARGET CoreApp)
get_target_property(_is_macosx_bundle CoreApp MACOSX_BUNDLE)
if(APPLE AND _is_macosx_bundle)
set(BLUEBERRY_UI_TEST_APP "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/CoreApp.app/Contents/MacOS/CoreApp")
endif()
endif()
set(BLUEBERRY_TEST_APP_ID "org.mitk.qt.coreapplication")
endif()
include("${CMAKE_CURRENT_SOURCE_DIR}/Plugins/PluginList.cmake")
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/Core/Code/DataManagement/mitkImageStatisticsHolder.cpp b/Core/Code/DataManagement/mitkImageStatisticsHolder.cpp
index d472f98c24..0ccdb2d71c 100644
--- a/Core/Code/DataManagement/mitkImageStatisticsHolder.cpp
+++ b/Core/Code/DataManagement/mitkImageStatisticsHolder.cpp
@@ -1,363 +1,366 @@
/*===================================================================
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 "mitkImageStatisticsHolder.h"
#include "mitkHistogramGenerator.h"
//#include "mitkImageTimeSelector.h"
+#include <mitkProperties.h>
mitk::ImageStatisticsHolder::ImageStatisticsHolder( mitk::Image* image)
: m_Image(image)/*, m_TimeSelectorForExtremaObject(NULL)*/
{
m_CountOfMinValuedVoxels.resize(1, 0);
m_CountOfMaxValuedVoxels.resize(1, 0);
m_ScalarMin.resize(1, itk::NumericTraits<ScalarType>::max());
m_ScalarMax.resize(1, itk::NumericTraits<ScalarType>::NonpositiveMin());
m_Scalar2ndMin.resize(1, itk::NumericTraits<ScalarType>::max());
m_Scalar2ndMax.resize(1, itk::NumericTraits<ScalarType>::NonpositiveMin());
mitk::HistogramGenerator::Pointer generator = mitk::HistogramGenerator::New();
m_HistogramGeneratorObject = generator;
//m_Image = image;
// create time selector
//this->GetTimeSelector();
}
mitk::ImageStatisticsHolder::~ImageStatisticsHolder()
{
m_HistogramGeneratorObject = NULL;
//m_TimeSelectorForExtremaObject = NULL;
//m_Image = NULL;
}
const mitk::ImageStatisticsHolder::HistogramType* mitk::ImageStatisticsHolder::GetScalarHistogram(int t, unsigned int component)
{
mitk::ImageTimeSelector* timeSelector = this->GetTimeSelector();
if(timeSelector!=NULL)
{
timeSelector->SetTimeNr(t);
timeSelector->UpdateLargestPossibleRegion();
mitk::HistogramGenerator* generator = static_cast<mitk::HistogramGenerator*>(m_HistogramGeneratorObject.GetPointer());
generator->SetImage(timeSelector->GetOutput());
generator->ComputeHistogram();
return static_cast<const mitk::ImageStatisticsHolder::HistogramType*>(generator->GetHistogram());
}
return NULL;
}
bool mitk::ImageStatisticsHolder::IsValidTimeStep( int t) const
{
return m_Image->IsValidTimeStep(t);
}
mitk::ImageTimeSelector::Pointer mitk::ImageStatisticsHolder::GetTimeSelector()
{
//if(m_TimeSelectorForExtremaObject.IsNull())
//{
// m_TimeSelectorForExtremaObject = ImageTimeSelector::New();
ImageTimeSelector::Pointer timeSelector = ImageTimeSelector::New();//static_cast<mitk::ImageTimeSelector*>( m_TimeSelectorForExtremaObject.GetPointer() );
timeSelector->SetInput(m_Image);
//}
return timeSelector; //static_cast<ImageTimeSelector*>( m_TimeSelectorForExtremaObject.GetPointer() );
}
void mitk::ImageStatisticsHolder::Expand( unsigned int timeSteps )
{
if(! m_Image->IsValidTimeStep(timeSteps - 1) ) return;
// The BaseData needs to be expanded, call the mitk::Image::Expand() method
m_Image->Expand(timeSteps);
if(timeSteps > m_ScalarMin.size() )
{
m_ScalarMin.resize(timeSteps, itk::NumericTraits<ScalarType>::max());
m_ScalarMax.resize(timeSteps, itk::NumericTraits<ScalarType>::NonpositiveMin());
m_Scalar2ndMin.resize(timeSteps, itk::NumericTraits<ScalarType>::max());
m_Scalar2ndMax.resize(timeSteps, itk::NumericTraits<ScalarType>::NonpositiveMin());
m_CountOfMinValuedVoxels.resize(timeSteps, 0);
m_CountOfMaxValuedVoxels.resize(timeSteps, 0);
}
}
void mitk::ImageStatisticsHolder::ResetImageStatistics()
{
m_ScalarMin.assign(1, itk::NumericTraits<ScalarType>::max());
m_ScalarMax.assign(1, itk::NumericTraits<ScalarType>::NonpositiveMin());
m_Scalar2ndMin.assign(1, itk::NumericTraits<ScalarType>::max());
m_Scalar2ndMax.assign(1, itk::NumericTraits<ScalarType>::NonpositiveMin());
m_CountOfMinValuedVoxels.assign(1, 0);
m_CountOfMaxValuedVoxels.assign(1, 0);
}
#include "mitkImageAccessByItk.h"
//#define BOUNDINGOBJECT_IGNORE
template < typename ItkImageType >
void mitk::_ComputeExtremaInItkImage( const ItkImageType* itkImage, mitk::ImageStatisticsHolder* statisticsHolder, int t)
{
typename ItkImageType::RegionType region;
region = itkImage->GetBufferedRegion();
if(region.Crop(itkImage->GetRequestedRegion()) == false) return;
if(region != itkImage->GetRequestedRegion()) return;
itk::ImageRegionConstIterator<ItkImageType> it(itkImage, region);
typedef typename ItkImageType::PixelType TPixel;
TPixel value = 0;
if ( statisticsHolder == NULL || !statisticsHolder->IsValidTimeStep( t ) ) return;
statisticsHolder->Expand(t+1); // make sure we have initialized all arrays
statisticsHolder->m_CountOfMinValuedVoxels[t] = 0;
statisticsHolder->m_CountOfMaxValuedVoxels[t] = 0;
statisticsHolder->m_Scalar2ndMin[t]=
statisticsHolder->m_ScalarMin[t] = itk::NumericTraits<ScalarType>::max();
statisticsHolder->m_Scalar2ndMax[t]=
statisticsHolder->m_ScalarMax[t] = itk::NumericTraits<ScalarType>::NonpositiveMin();
while( !it.IsAtEnd() )
{
value = it.Get();
// if ( (value > mitkImage->m_ScalarMin) && (value < mitkImage->m_Scalar2ndMin) ) mitkImage->m_Scalar2ndMin = value;
// else if ( (value < mitkImage->m_ScalarMax) && (value > mitkImage->m_Scalar2ndMax) ) mitkImage->m_Scalar2ndMax = value;
// else if (value > mitkImage->m_ScalarMax) mitkImage->m_ScalarMax = value;
// else if (value < mitkImage->m_ScalarMin) mitkImage->m_ScalarMin = value;
// if numbers start with 2ndMin or 2ndMax and never have that value again, the previous above logic failed
#ifdef BOUNDINGOBJECT_IGNORE
if( value > -32765)
{
#endif
// update min
if ( value < statisticsHolder->m_ScalarMin[t] )
{
statisticsHolder->m_Scalar2ndMin[t] =
statisticsHolder->m_ScalarMin[t]; statisticsHolder->m_ScalarMin[t] = value;
statisticsHolder->m_CountOfMinValuedVoxels[t] = 1;
}
else if ( value == statisticsHolder->m_ScalarMin[t] )
{
++statisticsHolder->m_CountOfMinValuedVoxels[t];
}
else if ( value < statisticsHolder->m_Scalar2ndMin[t] )
{
statisticsHolder->m_Scalar2ndMin[t] = value;
}
// update max
if ( value > statisticsHolder->m_ScalarMax[t] )
{
statisticsHolder->m_Scalar2ndMax[t] =
statisticsHolder->m_ScalarMax[t]; statisticsHolder->m_ScalarMax[t] = value;
statisticsHolder->m_CountOfMaxValuedVoxels[t] = 1;
}
else if ( value == statisticsHolder->m_ScalarMax[t] )
{
++statisticsHolder->m_CountOfMaxValuedVoxels[t];
}
else if ( value > statisticsHolder->m_Scalar2ndMax[t] )
{
statisticsHolder->m_Scalar2ndMax[t] = value;
}
#ifdef BOUNDINGOBJECT_IGNORE
}
#endif
++it;
}
//// guard for wrong 2dMin/Max on single constant value images
if (statisticsHolder->m_ScalarMax[t] == statisticsHolder->m_ScalarMin[t])
{
statisticsHolder->m_Scalar2ndMax[t] = statisticsHolder->m_Scalar2ndMin[t] = statisticsHolder->m_ScalarMax[t];
}
statisticsHolder->m_LastRecomputeTimeStamp.Modified();
//MITK_DEBUG <<"extrema "<<itk::NumericTraits<TPixel>::NonpositiveMin()<<" "<<mitkImage->m_ScalarMin<<" "<<mitkImage->m_Scalar2ndMin<<" "<<mitkImage->m_Scalar2ndMax<<" "<<mitkImage->m_ScalarMax<<" "<<itk::NumericTraits<TPixel>::max();
}
template < typename ItkImageType >
void mitk::_ComputeExtremaInItkVectorImage( const ItkImageType* itkImage, mitk::ImageStatisticsHolder* statisticsHolder, int t, unsigned int component)
{
typename ItkImageType::RegionType region;
region = itkImage->GetBufferedRegion();
if(region.Crop(itkImage->GetRequestedRegion()) == false) return;
if(region != itkImage->GetRequestedRegion()) return;
itk::ImageRegionConstIterator<ItkImageType> it(itkImage, region);
typedef typename ItkImageType::PixelType TPixel;
double value = 0;
if ( statisticsHolder == NULL || !statisticsHolder->IsValidTimeStep( t ) ) return;
statisticsHolder->Expand(t+1); // make sure we have initialized all arrays
statisticsHolder->m_CountOfMinValuedVoxels[t] = 0;
statisticsHolder->m_CountOfMaxValuedVoxels[t] = 0;
statisticsHolder->m_Scalar2ndMin[t]=
statisticsHolder->m_ScalarMin[t] = itk::NumericTraits<ScalarType>::max();
statisticsHolder->m_Scalar2ndMax[t]=
statisticsHolder->m_ScalarMax[t] = itk::NumericTraits<ScalarType>::NonpositiveMin();
while( !it.IsAtEnd() )
{
value = it.Get()[component];
// if ( (value > mitkImage->m_ScalarMin) && (value < mitkImage->m_Scalar2ndMin) ) mitkImage->m_Scalar2ndMin = value;
// else if ( (value < mitkImage->m_ScalarMax) && (value > mitkImage->m_Scalar2ndMax) ) mitkImage->m_Scalar2ndMax = value;
// else if (value > mitkImage->m_ScalarMax) mitkImage->m_ScalarMax = value;
// else if (value < mitkImage->m_ScalarMin) mitkImage->m_ScalarMin = value;
// if numbers start with 2ndMin or 2ndMax and never have that value again, the previous above logic failed
#ifdef BOUNDINGOBJECT_IGNORE
if( value > -32765)
{
#endif
// update min
if ( value < statisticsHolder->m_ScalarMin[t] )
{
statisticsHolder->m_Scalar2ndMin[t] =
statisticsHolder->m_ScalarMin[t]; statisticsHolder->m_ScalarMin[t] = value;
statisticsHolder->m_CountOfMinValuedVoxels[t] = 1;
}
else if ( value == statisticsHolder->m_ScalarMin[t] )
{
++statisticsHolder->m_CountOfMinValuedVoxels[t];
}
else if ( value < statisticsHolder->m_Scalar2ndMin[t] )
{
statisticsHolder->m_Scalar2ndMin[t] = value;
}
// update max
if ( value > statisticsHolder->m_ScalarMax[t] )
{
statisticsHolder->m_Scalar2ndMax[t] =
statisticsHolder->m_ScalarMax[t]; statisticsHolder->m_ScalarMax[t] = value;
statisticsHolder->m_CountOfMaxValuedVoxels[t] = 1;
}
else if ( value == statisticsHolder->m_ScalarMax[t] )
{
++statisticsHolder->m_CountOfMaxValuedVoxels[t];
}
else if ( value > statisticsHolder->m_Scalar2ndMax[t] )
{
statisticsHolder->m_Scalar2ndMax[t] = value;
}
#ifdef BOUNDINGOBJECT_IGNORE
}
#endif
++it;
}
//// guard for wrong 2dMin/Max on single constant value images
if (statisticsHolder->m_ScalarMax[t] == statisticsHolder->m_ScalarMin[t])
{
statisticsHolder->m_Scalar2ndMax[t] = statisticsHolder->m_Scalar2ndMin[t] = statisticsHolder->m_ScalarMax[t];
}
statisticsHolder->m_LastRecomputeTimeStamp.Modified();
//MITK_DEBUG <<"extrema "<<itk::NumericTraits<TPixel>::NonpositiveMin()<<" "<<mitkImage->m_ScalarMin<<" "<<mitkImage->m_Scalar2ndMin<<" "<<mitkImage->m_Scalar2ndMax<<" "<<mitkImage->m_ScalarMax<<" "<<itk::NumericTraits<TPixel>::max();
}
void mitk::ImageStatisticsHolder::ComputeImageStatistics(int t, unsigned int component)
{
// timestep valid?
if (!m_Image->IsValidTimeStep(t)) return;
// image modified?
if (this->m_Image->GetMTime() > m_LastRecomputeTimeStamp.GetMTime())
this->ResetImageStatistics();
Expand(t+1);
// do we have valid information already?
if( m_ScalarMin[t] != itk::NumericTraits<ScalarType>::max() ||
m_Scalar2ndMin[t] != itk::NumericTraits<ScalarType>::max() ) return; // Values already calculated before...
+ // used to avoid statistics calculation on qball images. property will be replaced as soons as bug 17928 is merged and the diffusion image refactoring is complete.
+ mitk::BoolProperty* isqball = dynamic_cast< mitk::BoolProperty* >( m_Image->GetProperty( "IsQballImage" ).GetPointer() );
const mitk::PixelType pType = m_Image->GetPixelType(0);
if(pType.GetNumberOfComponents() == 1 && (pType.GetPixelType() != itk::ImageIOBase::UNKNOWNPIXELTYPE) && (pType.GetPixelType() != itk::ImageIOBase::VECTOR) )
{
// recompute
mitk::ImageTimeSelector::Pointer timeSelector = this->GetTimeSelector();
if(timeSelector.IsNotNull())
{
timeSelector->SetTimeNr(t);
timeSelector->UpdateLargestPossibleRegion();
const mitk::Image* image = timeSelector->GetOutput();
AccessByItk_2( image, _ComputeExtremaInItkImage, this, t );
}
}
- else if (pType.GetPixelType() == itk::ImageIOBase::VECTOR) // we have a vector image
+ else if (pType.GetPixelType() == itk::ImageIOBase::VECTOR && (!isqball || !isqball->GetValue())) // we have a vector image
{
// recompute
mitk::ImageTimeSelector::Pointer timeSelector = this->GetTimeSelector();
if(timeSelector.IsNotNull())
{
timeSelector->SetTimeNr(t);
timeSelector->UpdateLargestPossibleRegion();
const mitk::Image* image = timeSelector->GetOutput();
AccessVectorPixelTypeByItk_n( image, _ComputeExtremaInItkVectorImage, (this, t, component) );
}
}
else
{
m_ScalarMin[t] = 0;
m_ScalarMax[t] = 255;
m_Scalar2ndMin[t] = 0;
m_Scalar2ndMax[t] = 255;
}
}
mitk::ScalarType mitk::ImageStatisticsHolder::GetScalarValueMin(int t, unsigned int component)
{
ComputeImageStatistics(t, component);
return m_ScalarMin[t];
}
mitk::ScalarType mitk::ImageStatisticsHolder::GetScalarValueMax(int t, unsigned int component)
{
ComputeImageStatistics(t, component);
return m_ScalarMax[t];
}
mitk::ScalarType mitk::ImageStatisticsHolder::GetScalarValue2ndMin(int t, unsigned int component)
{
ComputeImageStatistics(t, component);
return m_Scalar2ndMin[t];
}
mitk::ScalarType mitk::ImageStatisticsHolder::GetScalarValue2ndMax(int t, unsigned int component)
{
ComputeImageStatistics(t, component);
return m_Scalar2ndMax[t];
}
mitk::ScalarType mitk::ImageStatisticsHolder::GetCountOfMinValuedVoxels(int t, unsigned int component)
{
ComputeImageStatistics(t, component);
return m_CountOfMinValuedVoxels[t];
}
mitk::ScalarType mitk::ImageStatisticsHolder::GetCountOfMaxValuedVoxels(int t, unsigned int component)
{
ComputeImageStatistics(t, component);
return m_CountOfMaxValuedVoxels[t];
}
diff --git a/Core/Code/DataManagement/mitkImageVtkReadAccessor.cpp b/Core/Code/DataManagement/mitkImageVtkReadAccessor.cpp
index c3f8c3af71..61c439bb3c 100644
--- a/Core/Code/DataManagement/mitkImageVtkReadAccessor.cpp
+++ b/Core/Code/DataManagement/mitkImageVtkReadAccessor.cpp
@@ -1,61 +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.
===================================================================*/
#include "mitkImageVtkReadAccessor.h"
#include "mitkImage.h"
#include <vtkImageData.h>
const mitk::Image* mitk::ImageVtkReadAccessor::GetImage() const
{
return m_Image;
}
mitk::ImageVtkReadAccessor::ImageVtkReadAccessor(
ImageConstPointer iP, const mitk::ImageDataItem* iDI,
const vtkImageData* imageDataVtk)
- : ImageAccessorBase(NULL, iDI)
+ : ImageAccessorBase(iP, iDI)
, m_Image(iP.GetPointer())
, m_ImageDataVtk(imageDataVtk)
{
m_Image->m_VtkReadersLock.Lock();
m_Image->m_VtkReaders.push_back(this);
//printf("m_VtkReaders.size(): %d\n", (int) m_Image->m_VtkReaders.size());
m_Image->m_VtkReadersLock.Unlock();
}
mitk::ImageVtkReadAccessor::~ImageVtkReadAccessor()
{
m_Image->m_VtkReadersLock.Lock();
std::vector<ImageAccessorBase*>::iterator it =
std::find(m_Image->m_VtkReaders.begin(), m_Image->m_VtkReaders.end(), this);
if (it != m_Image->m_VtkReaders.end())
{
m_Image->m_VtkReaders.erase(it);
}
//printf("m_VtkReaders.size(): %d\n", (int) m_Image->m_VtkReaders.size());
m_Image->m_VtkReadersLock.Unlock();
}
const vtkImageData*mitk::ImageVtkReadAccessor::GetVtkImageData() const
{
return m_ImageDataVtk;
}
diff --git a/Core/Code/Internal/mitkImageVtkLegacyIO.cpp b/Core/Code/Internal/mitkImageVtkLegacyIO.cpp
index 4ceb996638..a24fd7ed91 100644
--- a/Core/Code/Internal/mitkImageVtkLegacyIO.cpp
+++ b/Core/Code/Internal/mitkImageVtkLegacyIO.cpp
@@ -1,107 +1,107 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkImageVtkLegacyIO.h"
#include "mitkImage.h"
#include "mitkIOMimeTypes.h"
#include "mitkImageVtkReadAccessor.h"
#include <vtkStructuredPointsReader.h>
#include <vtkStructuredPointsWriter.h>
#include <vtkStructuredPoints.h>
#include <vtkErrorCode.h>
#include <vtkSmartPointer.h>
namespace mitk {
ImageVtkLegacyIO::ImageVtkLegacyIO()
- : AbstractFileIO(Image::GetStaticNameOfClass(), IOMimeTypes::VTK_IMAGE_MIMETYPE(), "VTK XML Image")
+ : AbstractFileIO(Image::GetStaticNameOfClass(), IOMimeTypes::VTK_IMAGE_LEGACY_MIMETYPE(), "VTK Legacy Image")
{
this->RegisterService();
}
std::vector<BaseData::Pointer> ImageVtkLegacyIO::Read()
{
// The legay vtk reader cannot work with input streams
const std::string fileName = this->GetLocalFileName();
vtkSmartPointer<vtkStructuredPointsReader> reader = vtkSmartPointer<vtkStructuredPointsReader>::New();
reader->SetFileName(fileName.c_str());
reader->Update();
if ( reader->GetOutput() != NULL )
{
mitk::Image::Pointer output = mitk::Image::New();
output->Initialize(reader->GetOutput());
output->SetVolume(reader->GetOutput()->GetScalarPointer());
std::vector<BaseData::Pointer> result;
result.push_back(output.GetPointer());
return result;
}
else
{
mitkThrow() << "vtkStructuredPointsReader error: " << vtkErrorCode::GetStringFromErrorCode(reader->GetErrorCode());
}
}
IFileIO::ConfidenceLevel ImageVtkLegacyIO::GetReaderConfidenceLevel() const
{
if (AbstractFileIO::GetReaderConfidenceLevel() == Unsupported) return Unsupported;
vtkSmartPointer<vtkStructuredPointsReader> reader = vtkSmartPointer<vtkStructuredPointsReader>::New();
reader->SetFileName(this->GetLocalFileName().c_str());
if (reader->IsFileStructuredPoints())
{
return Supported;
}
return Unsupported;
}
void ImageVtkLegacyIO::Write()
{
ValidateOutputLocation();
const Image* input = dynamic_cast<const Image*>(this->GetInput());
vtkSmartPointer<vtkStructuredPointsWriter> writer = vtkSmartPointer<vtkStructuredPointsWriter>::New();
// The legacy vtk image writer cannot write to streams
LocalFile localFile(this);
writer->SetFileName(localFile.GetFileName().c_str());
- ImageVtkReadAccessor vtkReadAccessor(Image::ConstPointer(input), NULL, NULL);
+ ImageVtkReadAccessor vtkReadAccessor(Image::ConstPointer(input), NULL, input->GetVtkImageData());
writer->SetInputData(const_cast<vtkImageData*>(vtkReadAccessor.GetVtkImageData()));
if (writer->Write() == 0 || writer->GetErrorCode() != 0 )
{
mitkThrow() << "vtkStructuredPointesWriter error: " << vtkErrorCode::GetStringFromErrorCode(writer->GetErrorCode());
}
}
IFileIO::ConfidenceLevel ImageVtkLegacyIO::GetWriterConfidenceLevel() const
{
if (AbstractFileIO::GetWriterConfidenceLevel() == Unsupported) return Unsupported;
const Image* input = static_cast<const Image*>(this->GetInput());
if (input->GetDimension() == 3) return Supported;
else if (input->GetDimension() < 3) return PartiallySupported;
return Unsupported;
}
ImageVtkLegacyIO* ImageVtkLegacyIO::IOClone() const
{
return new ImageVtkLegacyIO(*this);
}
}
diff --git a/Core/Code/Internal/mitkImageVtkXmlIO.cpp b/Core/Code/Internal/mitkImageVtkXmlIO.cpp
index cb8c35da10..881f70b890 100644
--- a/Core/Code/Internal/mitkImageVtkXmlIO.cpp
+++ b/Core/Code/Internal/mitkImageVtkXmlIO.cpp
@@ -1,142 +1,142 @@
/*===================================================================
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 "mitkImageVtkXmlIO.h"
#include "mitkImage.h"
#include "mitkIOMimeTypes.h"
#include "mitkImageVtkReadAccessor.h"
#include <vtkXMLImageDataReader.h>
#include <vtkXMLImageDataWriter.h>
#include <vtkImageData.h>
#include <vtkErrorCode.h>
#include <vtkSmartPointer.h>
namespace mitk {
class VtkXMLImageDataReader : public ::vtkXMLImageDataReader
{
public:
static VtkXMLImageDataReader *New() { return new VtkXMLImageDataReader(); }
vtkTypeMacro(VtkXMLImageDataReader,vtkXMLImageDataReader)
void SetStream(std::istream* is) { this->Stream = is; }
std::istream* GetStream() const { return this->Stream; }
};
class VtkXMLImageDataWriter : public ::vtkXMLImageDataWriter
{
public:
static VtkXMLImageDataWriter *New() { return new VtkXMLImageDataWriter(); }
vtkTypeMacro(VtkXMLImageDataWriter,vtkXMLImageDataWriter)
void SetStream(std::ostream* os) { this->Stream = os; }
std::ostream* GetStream() const { return this->Stream; }
};
ImageVtkXmlIO::ImageVtkXmlIO()
: AbstractFileIO(Image::GetStaticNameOfClass(), IOMimeTypes::VTK_IMAGE_MIMETYPE(), "VTK XML Image")
{
this->RegisterService();
}
std::vector<BaseData::Pointer> ImageVtkXmlIO::Read()
{
vtkSmartPointer<VtkXMLImageDataReader> reader = vtkSmartPointer<VtkXMLImageDataReader>::New();
if (this->GetInputStream())
{
reader->SetStream(this->GetInputStream());
}
else
{
reader->SetFileName(this->GetInputLocation().c_str());
}
reader->Update();
if (reader->GetOutput() != NULL)
{
mitk::Image::Pointer output = mitk::Image::New();
output->Initialize(reader->GetOutput());
output->SetVolume(reader->GetOutput()->GetScalarPointer());
std::vector<BaseData::Pointer> result;
result.push_back(output.GetPointer());
return result;
}
else
{
mitkThrow() << "vtkXMLImageDataReader error: " << vtkErrorCode::GetStringFromErrorCode(reader->GetErrorCode());
}
}
IFileIO::ConfidenceLevel ImageVtkXmlIO::GetReaderConfidenceLevel() const
{
if (AbstractFileIO::GetReaderConfidenceLevel() == Unsupported) return Unsupported;
if (this->GetInputStream() == NULL)
{
// check if the xml vtk reader can handle the file
vtkSmartPointer<VtkXMLImageDataReader> xmlReader = vtkSmartPointer<VtkXMLImageDataReader>::New();
if (xmlReader->CanReadFile(this->GetInputLocation().c_str()) != 0)
{
return Supported;
}
return Unsupported;
}
// in case of an input stream, VTK does not seem to have methods for
// validating it
return Supported;
}
void ImageVtkXmlIO::Write()
{
ValidateOutputLocation();
const Image* input = dynamic_cast<const Image*>(this->GetInput());
vtkSmartPointer<VtkXMLImageDataWriter> writer = vtkSmartPointer<VtkXMLImageDataWriter>::New();
if (this->GetOutputStream())
{
writer->SetStream(this->GetOutputStream());
}
else
{
writer->SetFileName(this->GetOutputLocation().c_str());
}
- ImageVtkReadAccessor vtkReadAccessor(Image::ConstPointer(input), NULL, NULL);
+ ImageVtkReadAccessor vtkReadAccessor(Image::ConstPointer(input), NULL, input->GetVtkImageData());
writer->SetInputData(const_cast<vtkImageData*>(vtkReadAccessor.GetVtkImageData()));
if (writer->Write() == 0 || writer->GetErrorCode() != 0 )
{
mitkThrow() << "vtkXMLImageDataWriter error: " << vtkErrorCode::GetStringFromErrorCode(writer->GetErrorCode());
}
}
IFileIO::ConfidenceLevel ImageVtkXmlIO::GetWriterConfidenceLevel() const
{
if (AbstractFileIO::GetWriterConfidenceLevel() == Unsupported) return Unsupported;
const Image* input = static_cast<const Image*>(this->GetInput());
if (input->GetDimension() == 3) return Supported;
else if (input->GetDimension() < 3) return PartiallySupported;
return Unsupported;
}
ImageVtkXmlIO* ImageVtkXmlIO::IOClone() const
{
return new ImageVtkXmlIO(*this);
}
}
diff --git a/Core/CppMicroServices/third_party/miniz.c b/Core/CppMicroServices/third_party/miniz.c
index 32c9d5090e..cdaba92086 100644
--- a/Core/CppMicroServices/third_party/miniz.c
+++ b/Core/CppMicroServices/third_party/miniz.c
@@ -1,4925 +1,4929 @@
/* miniz.c v1.15 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing
See "unlicense" statement at the end of this file.
Rich Geldreich <richgel99@gmail.com>, last updated Oct. 13, 2013
Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt
Most API's defined in miniz.c are optional. For example, to disable the archive related functions just define
MINIZ_NO_ARCHIVE_APIS, or to get rid of all stdio usage define MINIZ_NO_STDIO (see the list below for more macros).
* Change History
10/13/13 v1.15 r4 - Interim bugfix release while I work on the next major release with Zip64 support (almost there!):
- Critical fix for the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY bug (thanks kahmyong.moon@hp.com) which could cause locate files to not find files. This bug
would only have occured in earlier versions if you explicitly used this flag, OR if you used mz_zip_extract_archive_file_to_heap() or mz_zip_add_mem_to_archive_file_in_place()
(which used this flag). If you can't switch to v1.15 but want to fix this bug, just remove the uses of this flag from both helper funcs (and of course don't use the flag).
- Bugfix in mz_zip_reader_extract_to_mem_no_alloc() from kymoon when pUser_read_buf is not NULL and compressed size is > uncompressed size
- Fixing mz_zip_reader_extract_*() funcs so they don't try to extract compressed data from directory entries, to account for weird zipfiles which contain zero-size compressed data on dir entries.
Hopefully this fix won't cause any issues on weird zip archives, because it assumes the low 16-bits of zip external attributes are DOS attributes (which I believe they always are in practice).
- Fixing mz_zip_reader_is_file_a_directory() so it doesn't check the internal attributes, just the filename and external attributes
- mz_zip_reader_init_file() - missing MZ_FCLOSE() call if the seek failed
- Added cmake support for Linux builds which builds all the examples, tested with clang v3.3 and gcc v4.6.
- Clang fix for tdefl_write_image_to_png_file_in_memory() from toffaletti
- Merged MZ_FORCEINLINE fix from hdeanclark
- Fix <time.h> include before config #ifdef, thanks emil.brink
- Added tdefl_write_image_to_png_file_in_memory_ex(): supports Y flipping (super useful for OpenGL apps), and explicit control over the compression level (so you can
set it to 1 for real-time compression).
- Merged in some compiler fixes from paulharris's github repro.
- Retested this build under Windows (VS 2010, including static analysis), tcc 0.9.26, gcc v4.6 and clang v3.3.
- Added example6.c, which dumps an image of the mandelbrot set to a PNG file.
- Modified example2 to help test the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY flag more.
- In r3: Bugfix to mz_zip_writer_add_file() found during merge: Fix possible src file fclose() leak if alignment bytes+local header file write faiiled
- In r4: Minor bugfix to mz_zip_writer_add_from_zip_reader(): Was pushing the wrong central dir header offset, appears harmless in this release, but it became a problem in the zip64 branch
5/20/12 v1.14 - MinGW32/64 GCC 4.6.1 compiler fixes: added MZ_FORCEINLINE, #include <time.h> (thanks fermtect).
5/19/12 v1.13 - From jason@cornsyrup.org and kelwert@mtu.edu - Fix mz_crc32() so it doesn't compute the wrong CRC-32's when mz_ulong is 64-bit.
- Temporarily/locally slammed in "typedef unsigned long mz_ulong" and re-ran a randomized regression test on ~500k files.
- Eliminated a bunch of warnings when compiling with GCC 32-bit/64.
- Ran all examples, miniz.c, and tinfl.c through MSVC 2008's /analyze (static analysis) option and fixed all warnings (except for the silly
"Use of the comma-operator in a tested expression.." analysis warning, which I purposely use to work around a MSVC compiler warning).
- Created 32-bit and 64-bit Codeblocks projects/workspace. Built and tested Linux executables. The codeblocks workspace is compatible with Linux+Win32/x64.
- Added miniz_tester solution/project, which is a useful little app derived from LZHAM's tester app that I use as part of the regression test.
- Ran miniz.c and tinfl.c through another series of regression testing on ~500,000 files and archives.
- Modified example5.c so it purposely disables a bunch of high-level functionality (MINIZ_NO_STDIO, etc.). (Thanks to corysama for the MINIZ_NO_STDIO bug report.)
- Fix ftell() usage in examples so they exit with an error on files which are too large (a limitation of the examples, not miniz itself).
4/12/12 v1.12 - More comments, added low-level example5.c, fixed a couple minor level_and_flags issues in the archive API's.
level_and_flags can now be set to MZ_DEFAULT_COMPRESSION. Thanks to Bruce Dawson <bruced@valvesoftware.com> for the feedback/bug report.
5/28/11 v1.11 - Added statement from unlicense.org
5/27/11 v1.10 - Substantial compressor optimizations:
- Level 1 is now ~4x faster than before. The L1 compressor's throughput now varies between 70-110MB/sec. on a
- Core i7 (actual throughput varies depending on the type of data, and x64 vs. x86).
- Improved baseline L2-L9 compression perf. Also, greatly improved compression perf. issues on some file types.
- Refactored the compression code for better readability and maintainability.
- Added level 10 compression level (L10 has slightly better ratio than level 9, but could have a potentially large
drop in throughput on some files).
5/15/11 v1.09 - Initial stable release.
* Low-level Deflate/Inflate implementation notes:
Compression: Use the "tdefl" API's. The compressor supports raw, static, and dynamic blocks, lazy or
greedy parsing, match length filtering, RLE-only, and Huffman-only streams. It performs and compresses
approximately as well as zlib.
Decompression: Use the "tinfl" API's. The entire decompressor is implemented as a single function
coroutine: see tinfl_decompress(). It supports decompression into a 32KB (or larger power of 2) wrapping buffer, or into a memory
block large enough to hold the entire file.
The low-level tdefl/tinfl API's do not make any use of dynamic memory allocation.
* zlib-style API notes:
miniz.c implements a fairly large subset of zlib. There's enough functionality present for it to be a drop-in
zlib replacement in many apps:
The z_stream struct, optional memory allocation callbacks
deflateInit/deflateInit2/deflate/deflateReset/deflateEnd/deflateBound
inflateInit/inflateInit2/inflate/inflateEnd
compress, compress2, compressBound, uncompress
CRC-32, Adler-32 - Using modern, minimal code size, CPU cache friendly routines.
Supports raw deflate streams or standard zlib streams with adler-32 checking.
Limitations:
The callback API's are not implemented yet. No support for gzip headers or zlib static dictionaries.
I've tried to closely emulate zlib's various flavors of stream flushing and return status codes, but
there are no guarantees that miniz.c pulls this off perfectly.
* PNG writing: See the tdefl_write_image_to_png_file_in_memory() function, originally written by
Alex Evans. Supports 1-4 bytes/pixel images.
* ZIP archive API notes:
The ZIP archive API's where designed with simplicity and efficiency in mind, with just enough abstraction to
get the job done with minimal fuss. There are simple API's to retrieve file information, read files from
existing archives, create new archives, append new files to existing archives, or clone archive data from
one archive to another. It supports archives located in memory or the heap, on disk (using stdio.h),
or you can specify custom file read/write callbacks.
- Archive reading: Just call this function to read a single file from a disk archive:
void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name,
size_t *pSize, mz_uint zip_flags);
For more complex cases, use the "mz_zip_reader" functions. Upon opening an archive, the entire central
directory is located and read as-is into memory, and subsequent file access only occurs when reading individual files.
- Archives file scanning: The simple way is to use this function to scan a loaded archive for a specific file:
int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags);
The locate operation can optionally check file comments too, which (as one example) can be used to identify
multiple versions of the same file in an archive. This function uses a simple linear search through the central
directory, so it's not very fast.
Alternately, you can iterate through all the files in an archive (using mz_zip_reader_get_num_files()) and
retrieve detailed info on each file by calling mz_zip_reader_file_stat().
- Archive creation: Use the "mz_zip_writer" functions. The ZIP writer immediately writes compressed file data
to disk and builds an exact image of the central directory in memory. The central directory image is written
all at once at the end of the archive file when the archive is finalized.
The archive writer can optionally align each file's local header and file data to any power of 2 alignment,
which can be useful when the archive will be read from optical media. Also, the writer supports placing
arbitrary data blobs at the very beginning of ZIP archives. Archives written using either feature are still
readable by any ZIP tool.
- Archive appending: The simple way to add a single file to an archive is to call this function:
mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name,
const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
The archive will be created if it doesn't already exist, otherwise it'll be appended to.
Note the appending is done in-place and is not an atomic operation, so if something goes wrong
during the operation it's possible the archive could be left without a central directory (although the local
file headers and file data will be fine, so the archive will be recoverable).
For more complex archive modification scenarios:
1. The safest way is to use a mz_zip_reader to read the existing archive, cloning only those bits you want to
preserve into a new archive using using the mz_zip_writer_add_from_zip_reader() function (which compiles the
compressed file data as-is). When you're done, delete the old archive and rename the newly written archive, and
you're done. This is safe but requires a bunch of temporary disk space or heap memory.
2. Or, you can convert an mz_zip_reader in-place to an mz_zip_writer using mz_zip_writer_init_from_reader(),
append new files as needed, then finalize the archive which will write an updated central directory to the
original archive. (This is basically what mz_zip_add_mem_to_archive_file_in_place() does.) There's a
possibility that the archive's central directory could be lost with this method if anything goes wrong, though.
- ZIP archive support limitations:
No zip64 or spanning support. Extraction functions can only handle unencrypted, stored or deflated files.
Requires streams capable of seeking.
* This is a header file library, like stb_image.c. To get only a header file, either cut and paste the
below header, or create miniz.h, #define MINIZ_HEADER_FILE_ONLY, and then include miniz.c from it.
* Important: For best perf. be sure to customize the below macros for your target platform:
#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1
#define MINIZ_LITTLE_ENDIAN 1
#define MINIZ_HAS_64BIT_REGISTERS 1
* On platforms using glibc, Be sure to "#define _LARGEFILE64_SOURCE 1" before including miniz.c to ensure miniz
uses the 64-bit variants: fopen64(), stat64(), etc. Otherwise you won't be able to process large files
(i.e. 32-bit stat() fails for me on files > 0x7FFFFFFF bytes).
*/
#ifndef MINIZ_HEADER_INCLUDED
#define MINIZ_HEADER_INCLUDED
#include <stdlib.h>
// Defines to completely disable specific portions of miniz.c:
// If all macros here are defined the only functionality remaining will be CRC-32, adler-32, tinfl, and tdefl.
// Define MINIZ_NO_STDIO to disable all usage and any functions which rely on stdio for file I/O.
//#define MINIZ_NO_STDIO
// If MINIZ_NO_TIME is specified then the ZIP archive functions will not be able to get the current time, or
// get/set file times, and the C run-time funcs that get/set times won't be called.
// The current downside is the times written to your archives will be from 1979.
//#define MINIZ_NO_TIME
// Define MINIZ_NO_ARCHIVE_APIS to disable all ZIP archive API's.
//#define MINIZ_NO_ARCHIVE_APIS
// Define MINIZ_NO_ARCHIVE_APIS to disable all writing related ZIP archive API's.
//#define MINIZ_NO_ARCHIVE_WRITING_APIS
// Define MINIZ_NO_ZLIB_APIS to remove all ZLIB-style compression/decompression API's.
//#define MINIZ_NO_ZLIB_APIS
// Define MINIZ_NO_ZLIB_COMPATIBLE_NAME to disable zlib names, to prevent conflicts against stock zlib.
//#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES
// Define MINIZ_NO_MALLOC to disable all calls to malloc, free, and realloc.
// Note if MINIZ_NO_MALLOC is defined then the user must always provide custom user alloc/free/realloc
// callbacks to the zlib and archive API's, and a few stand-alone helper API's which don't provide custom user
// functions (such as tdefl_compress_mem_to_heap() and tinfl_decompress_mem_to_heap()) won't work.
//#define MINIZ_NO_MALLOC
#if defined(__TINYC__) && (defined(__linux) || defined(__linux__))
// TODO: Work around "error: include file 'sys\utime.h' when compiling with tcc on Linux
#define MINIZ_NO_TIME
#endif
#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_ARCHIVE_APIS)
#include <time.h>
#endif
#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i486) || defined(i386) || defined(__ia64__) || defined(__x86_64__)
// MINIZ_X86_OR_X64_CPU is only used to help set the below macros.
#define MINIZ_X86_OR_X64_CPU 1
#endif
#if (__BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__) || MINIZ_X86_OR_X64_CPU
// Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian.
#define MINIZ_LITTLE_ENDIAN 1
#endif
#if MINIZ_X86_OR_X64_CPU
// Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 on CPU's that permit efficient integer loads and stores from unaligned addresses.
#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1
#endif
#if defined(_M_X64) || defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__) || defined(__ia64__) || defined(__x86_64__)
// Set MINIZ_HAS_64BIT_REGISTERS to 1 if operations on 64-bit integers are reasonably fast (and don't involve compiler generated calls to helper functions).
#define MINIZ_HAS_64BIT_REGISTERS 1
#endif
#ifdef __cplusplus
extern "C" {
#endif
// ------------------- zlib-style API Definitions.
// For more compatibility with zlib, miniz.c uses unsigned long for some parameters/struct members. Beware: mz_ulong can be either 32 or 64-bits!
typedef unsigned long mz_ulong;
// mz_free() internally uses the MZ_FREE() macro (which by default calls free() unless you've modified the MZ_MALLOC macro) to release a block allocated from the heap.
void mz_free(void *p);
#define MZ_ADLER32_INIT (1)
// mz_adler32() returns the initial adler-32 value to use when called with ptr==NULL.
mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len);
#define MZ_CRC32_INIT (0)
// mz_crc32() returns the initial CRC-32 value to use when called with ptr==NULL.
mz_ulong mz_crc32(mz_ulong crc, const unsigned char *ptr, size_t buf_len);
// Compression strategies.
enum { MZ_DEFAULT_STRATEGY = 0, MZ_FILTERED = 1, MZ_HUFFMAN_ONLY = 2, MZ_RLE = 3, MZ_FIXED = 4 };
// Method
#define MZ_DEFLATED 8
#ifndef MINIZ_NO_ZLIB_APIS
// Heap allocation callbacks.
// Note that mz_alloc_func parameter types purpsosely differ from zlib's: items/size is size_t, not unsigned long.
typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size);
typedef void (*mz_free_func)(void *opaque, void *address);
typedef void *(*mz_realloc_func)(void *opaque, void *address, size_t items, size_t size);
#define MZ_VERSION "9.1.15"
#define MZ_VERNUM 0x91F0
#define MZ_VER_MAJOR 9
#define MZ_VER_MINOR 1
#define MZ_VER_REVISION 15
#define MZ_VER_SUBREVISION 0
// Flush values. For typical usage you only need MZ_NO_FLUSH and MZ_FINISH. The other values are for advanced use (refer to the zlib docs).
enum { MZ_NO_FLUSH = 0, MZ_PARTIAL_FLUSH = 1, MZ_SYNC_FLUSH = 2, MZ_FULL_FLUSH = 3, MZ_FINISH = 4, MZ_BLOCK = 5 };
// Return status codes. MZ_PARAM_ERROR is non-standard.
enum { MZ_OK = 0, MZ_STREAM_END = 1, MZ_NEED_DICT = 2, MZ_ERRNO = -1, MZ_STREAM_ERROR = -2, MZ_DATA_ERROR = -3, MZ_MEM_ERROR = -4, MZ_BUF_ERROR = -5, MZ_VERSION_ERROR = -6, MZ_PARAM_ERROR = -10000 };
// Compression levels: 0-9 are the standard zlib-style levels, 10 is best possible compression (not zlib compatible, and may be very slow), MZ_DEFAULT_COMPRESSION=MZ_DEFAULT_LEVEL.
enum { MZ_NO_COMPRESSION = 0, MZ_BEST_SPEED = 1, MZ_BEST_COMPRESSION = 9, MZ_UBER_COMPRESSION = 10, MZ_DEFAULT_LEVEL = 6, MZ_DEFAULT_COMPRESSION = -1 };
// Window bits
#define MZ_DEFAULT_WINDOW_BITS 15
struct mz_internal_state;
// Compression/decompression stream struct.
typedef struct mz_stream_s
{
const unsigned char *next_in; // pointer to next byte to read
unsigned int avail_in; // number of bytes available at next_in
mz_ulong total_in; // total number of bytes consumed so far
unsigned char *next_out; // pointer to next byte to write
unsigned int avail_out; // number of bytes that can be written to next_out
mz_ulong total_out; // total number of bytes produced so far
char *msg; // error msg (unused)
struct mz_internal_state *state; // internal state, allocated by zalloc/zfree
mz_alloc_func zalloc; // optional heap allocation function (defaults to malloc)
mz_free_func zfree; // optional heap free function (defaults to free)
void *opaque; // heap alloc function user pointer
int data_type; // data_type (unused)
mz_ulong adler; // adler32 of the source or uncompressed data
mz_ulong reserved; // not used
} mz_stream;
typedef mz_stream *mz_streamp;
// Returns the version string of miniz.c.
const char *mz_version(void);
// mz_deflateInit() initializes a compressor with default options:
// Parameters:
// pStream must point to an initialized mz_stream struct.
// level must be between [MZ_NO_COMPRESSION, MZ_BEST_COMPRESSION].
// level 1 enables a specially optimized compression function that's been optimized purely for performance, not ratio.
// (This special func. is currently only enabled when MINIZ_USE_UNALIGNED_LOADS_AND_STORES and MINIZ_LITTLE_ENDIAN are defined.)
// Return values:
// MZ_OK on success.
// MZ_STREAM_ERROR if the stream is bogus.
// MZ_PARAM_ERROR if the input parameters are bogus.
// MZ_MEM_ERROR on out of memory.
int mz_deflateInit(mz_streamp pStream, int level);
// mz_deflateInit2() is like mz_deflate(), except with more control:
// Additional parameters:
// method must be MZ_DEFLATED
// window_bits must be MZ_DEFAULT_WINDOW_BITS (to wrap the deflate stream with zlib header/adler-32 footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate/no header or footer)
// mem_level must be between [1, 9] (it's checked but ignored by miniz.c)
int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy);
// Quickly resets a compressor without having to reallocate anything. Same as calling mz_deflateEnd() followed by mz_deflateInit()/mz_deflateInit2().
int mz_deflateReset(mz_streamp pStream);
// mz_deflate() compresses the input to output, consuming as much of the input and producing as much output as possible.
// Parameters:
// pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members.
// flush may be MZ_NO_FLUSH, MZ_PARTIAL_FLUSH/MZ_SYNC_FLUSH, MZ_FULL_FLUSH, or MZ_FINISH.
// Return values:
// MZ_OK on success (when flushing, or if more input is needed but not available, and/or there's more output to be written but the output buffer is full).
// MZ_STREAM_END if all input has been consumed and all output bytes have been written. Don't call mz_deflate() on the stream anymore.
// MZ_STREAM_ERROR if the stream is bogus.
// MZ_PARAM_ERROR if one of the parameters is invalid.
// MZ_BUF_ERROR if no forward progress is possible because the input and/or output buffers are empty. (Fill up the input buffer or free up some output space and try again.)
int mz_deflate(mz_streamp pStream, int flush);
// mz_deflateEnd() deinitializes a compressor:
// Return values:
// MZ_OK on success.
// MZ_STREAM_ERROR if the stream is bogus.
int mz_deflateEnd(mz_streamp pStream);
// mz_deflateBound() returns a (very) conservative upper bound on the amount of data that could be generated by deflate(), assuming flush is set to only MZ_NO_FLUSH or MZ_FINISH.
mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len);
// Single-call compression functions mz_compress() and mz_compress2():
// Returns MZ_OK on success, or one of the error codes from mz_deflate() on failure.
int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len);
int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level);
// mz_compressBound() returns a (very) conservative upper bound on the amount of data that could be generated by calling mz_compress().
mz_ulong mz_compressBound(mz_ulong source_len);
// Initializes a decompressor.
int mz_inflateInit(mz_streamp pStream);
// mz_inflateInit2() is like mz_inflateInit() with an additional option that controls the window size and whether or not the stream has been wrapped with a zlib header/footer:
// window_bits must be MZ_DEFAULT_WINDOW_BITS (to parse zlib header/footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate).
int mz_inflateInit2(mz_streamp pStream, int window_bits);
// Decompresses the input stream to the output, consuming only as much of the input as needed, and writing as much to the output as possible.
// Parameters:
// pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members.
// flush may be MZ_NO_FLUSH, MZ_SYNC_FLUSH, or MZ_FINISH.
// On the first call, if flush is MZ_FINISH it's assumed the input and output buffers are both sized large enough to decompress the entire stream in a single call (this is slightly faster).
// MZ_FINISH implies that there are no more source bytes available beside what's already in the input buffer, and that the output buffer is large enough to hold the rest of the decompressed data.
// Return values:
// MZ_OK on success. Either more input is needed but not available, and/or there's more output to be written but the output buffer is full.
// MZ_STREAM_END if all needed input has been consumed and all output bytes have been written. For zlib streams, the adler-32 of the decompressed data has also been verified.
// MZ_STREAM_ERROR if the stream is bogus.
// MZ_DATA_ERROR if the deflate stream is invalid.
// MZ_PARAM_ERROR if one of the parameters is invalid.
// MZ_BUF_ERROR if no forward progress is possible because the input buffer is empty but the inflater needs more input to continue, or if the output buffer is not large enough. Call mz_inflate() again
// with more input data, or with more room in the output buffer (except when using single call decompression, described above).
int mz_inflate(mz_streamp pStream, int flush);
// Deinitializes a decompressor.
int mz_inflateEnd(mz_streamp pStream);
// Single-call decompression.
// Returns MZ_OK on success, or one of the error codes from mz_inflate() on failure.
int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len);
// Returns a string description of the specified error code, or NULL if the error code is invalid.
const char *mz_error(int err);
// Redefine zlib-compatible names to miniz equivalents, so miniz.c can be used as a drop-in replacement for the subset of zlib that miniz.c supports.
// Define MINIZ_NO_ZLIB_COMPATIBLE_NAMES to disable zlib-compatibility if you use zlib in the same project.
#ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES
typedef unsigned char Byte;
typedef unsigned int uInt;
typedef mz_ulong uLong;
typedef Byte Bytef;
typedef uInt uIntf;
typedef char charf;
typedef int intf;
typedef void *voidpf;
typedef uLong uLongf;
typedef void *voidp;
typedef void *const voidpc;
#define Z_NULL 0
#define Z_NO_FLUSH MZ_NO_FLUSH
#define Z_PARTIAL_FLUSH MZ_PARTIAL_FLUSH
#define Z_SYNC_FLUSH MZ_SYNC_FLUSH
#define Z_FULL_FLUSH MZ_FULL_FLUSH
#define Z_FINISH MZ_FINISH
#define Z_BLOCK MZ_BLOCK
#define Z_OK MZ_OK
#define Z_STREAM_END MZ_STREAM_END
#define Z_NEED_DICT MZ_NEED_DICT
#define Z_ERRNO MZ_ERRNO
#define Z_STREAM_ERROR MZ_STREAM_ERROR
#define Z_DATA_ERROR MZ_DATA_ERROR
#define Z_MEM_ERROR MZ_MEM_ERROR
#define Z_BUF_ERROR MZ_BUF_ERROR
#define Z_VERSION_ERROR MZ_VERSION_ERROR
#define Z_PARAM_ERROR MZ_PARAM_ERROR
#define Z_NO_COMPRESSION MZ_NO_COMPRESSION
#define Z_BEST_SPEED MZ_BEST_SPEED
#define Z_BEST_COMPRESSION MZ_BEST_COMPRESSION
#define Z_DEFAULT_COMPRESSION MZ_DEFAULT_COMPRESSION
#define Z_DEFAULT_STRATEGY MZ_DEFAULT_STRATEGY
#define Z_FILTERED MZ_FILTERED
#define Z_HUFFMAN_ONLY MZ_HUFFMAN_ONLY
#define Z_RLE MZ_RLE
#define Z_FIXED MZ_FIXED
#define Z_DEFLATED MZ_DEFLATED
#define Z_DEFAULT_WINDOW_BITS MZ_DEFAULT_WINDOW_BITS
#define alloc_func mz_alloc_func
#define free_func mz_free_func
#define internal_state mz_internal_state
#define z_stream mz_stream
#define deflateInit mz_deflateInit
#define deflateInit2 mz_deflateInit2
#define deflateReset mz_deflateReset
#define deflate mz_deflate
#define deflateEnd mz_deflateEnd
#define deflateBound mz_deflateBound
#define compress mz_compress
#define compress2 mz_compress2
#define compressBound mz_compressBound
#define inflateInit mz_inflateInit
#define inflateInit2 mz_inflateInit2
#define inflate mz_inflate
#define inflateEnd mz_inflateEnd
#define uncompress mz_uncompress
#define crc32 mz_crc32
#define adler32 mz_adler32
#define MAX_WBITS 15
#define MAX_MEM_LEVEL 9
#define zError mz_error
#define ZLIB_VERSION MZ_VERSION
#define ZLIB_VERNUM MZ_VERNUM
#define ZLIB_VER_MAJOR MZ_VER_MAJOR
#define ZLIB_VER_MINOR MZ_VER_MINOR
#define ZLIB_VER_REVISION MZ_VER_REVISION
#define ZLIB_VER_SUBREVISION MZ_VER_SUBREVISION
#define zlibVersion mz_version
#define zlib_version mz_version()
#endif // #ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES
#endif // MINIZ_NO_ZLIB_APIS
// ------------------- Types and macros
typedef unsigned char mz_uint8;
typedef signed short mz_int16;
typedef unsigned short mz_uint16;
typedef unsigned int mz_uint32;
typedef unsigned int mz_uint;
typedef long long mz_int64;
typedef unsigned long long mz_uint64;
typedef int mz_bool;
#define MZ_FALSE (0)
#define MZ_TRUE (1)
// An attempt to work around MSVC's spammy "warning C4127: conditional expression is constant" message.
#ifdef _MSC_VER
#define MZ_MACRO_END while (0, 0)
#else
#define MZ_MACRO_END while (0)
#endif
// ------------------- ZIP archive reading/writing
#ifndef MINIZ_NO_ARCHIVE_APIS
enum
{
MZ_ZIP_MAX_IO_BUF_SIZE = 64*1024,
MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE = 260,
MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE = 256
};
typedef struct
{
mz_uint32 m_file_index;
mz_uint32 m_central_dir_ofs;
mz_uint16 m_version_made_by;
mz_uint16 m_version_needed;
mz_uint16 m_bit_flag;
mz_uint16 m_method;
#ifndef MINIZ_NO_TIME
time_t m_time;
#endif
mz_uint32 m_crc32;
mz_uint64 m_comp_size;
mz_uint64 m_uncomp_size;
mz_uint16 m_internal_attr;
mz_uint32 m_external_attr;
mz_uint64 m_local_header_ofs;
mz_uint32 m_comment_size;
char m_filename[MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE];
char m_comment[MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE];
} mz_zip_archive_file_stat;
typedef size_t (*mz_file_read_func)(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n);
typedef size_t (*mz_file_write_func)(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n);
struct mz_zip_internal_state_tag;
typedef struct mz_zip_internal_state_tag mz_zip_internal_state;
typedef enum
{
MZ_ZIP_MODE_INVALID = 0,
MZ_ZIP_MODE_READING = 1,
MZ_ZIP_MODE_WRITING = 2,
MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED = 3
} mz_zip_mode;
typedef struct mz_zip_archive_tag
{
mz_uint64 m_archive_size;
mz_uint64 m_archive_file_ofs;
mz_uint64 m_central_directory_file_ofs;
mz_uint m_total_files;
mz_zip_mode m_zip_mode;
mz_uint m_file_offset_alignment;
mz_alloc_func m_pAlloc;
mz_free_func m_pFree;
mz_realloc_func m_pRealloc;
void *m_pAlloc_opaque;
mz_file_read_func m_pRead;
mz_file_write_func m_pWrite;
void *m_pIO_opaque;
mz_zip_internal_state *m_pState;
} mz_zip_archive;
typedef enum
{
MZ_ZIP_FLAG_CASE_SENSITIVE = 0x0100,
MZ_ZIP_FLAG_IGNORE_PATH = 0x0200,
MZ_ZIP_FLAG_COMPRESSED_DATA = 0x0400,
MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY = 0x0800
} mz_zip_flags;
// ZIP archive reading
// Inits a ZIP archive reader.
// These functions read and validate the archive's central directory.
mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, mz_uint32 flags);
mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint32 flags);
#ifndef MINIZ_NO_STDIO
mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags);
#endif
// Returns the total number of files in the archive.
mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip);
// Returns detailed information about an archive file entry.
mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat);
// Determines if an archive file entry is a directory entry.
mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index);
mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index);
// Retrieves the filename of an archive file entry.
// Returns the number of bytes written to pFilename, or if filename_buf_size is 0 this function returns the number of bytes needed to fully store the filename.
mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size);
// Attempts to locates a file in the archive's central directory.
// Valid flags: MZ_ZIP_FLAG_CASE_SENSITIVE, MZ_ZIP_FLAG_IGNORE_PATH
// Returns -1 if the file cannot be found.
int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags);
// Extracts a archive file to a memory buffer using no memory allocation.
mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size);
mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size);
// Extracts a archive file to a memory buffer.
mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags);
mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags);
// Extracts a archive file to a dynamically allocated heap buffer.
void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags);
void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags);
// Extracts a archive file using a callback function to output the file's data.
mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, mz_uint file_index, mz_file_write_func pCallback, void *pOpaque, mz_uint flags);
mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip, const char *pFilename, mz_file_write_func pCallback, void *pOpaque, mz_uint flags);
#ifndef MINIZ_NO_STDIO
// Extracts a archive file to a disk file and sets its last accessed and modified times.
// This function only extracts files, not archive directory records.
mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const char *pDst_filename, mz_uint flags);
mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const char *pDst_filename, mz_uint flags);
#endif
// Ends archive reading, freeing all allocations, and closing the input archive file if mz_zip_reader_init_file() was used.
mz_bool mz_zip_reader_end(mz_zip_archive *pZip);
// ZIP archive writing
#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
// Inits a ZIP archive writer.
mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size);
mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size);
#ifndef MINIZ_NO_STDIO
mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning);
#endif
// Converts a ZIP archive reader object into a writer object, to allow efficient in-place file appends to occur on an existing archive.
// For archives opened using mz_zip_reader_init_file, pFilename must be the archive's filename so it can be reopened for writing. If the file can't be reopened, mz_zip_reader_end() will be called.
// For archives opened using mz_zip_reader_init_mem, the memory block must be growable using the realloc callback (which defaults to realloc unless you've overridden it).
// Finally, for archives opened using mz_zip_reader_init, the mz_zip_archive's user provided m_pWrite function cannot be NULL.
// Note: In-place archive modification is not recommended unless you know what you're doing, because if execution stops or something goes wrong before
// the archive is finalized the file's central directory will be hosed.
mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const char *pFilename);
// Adds the contents of a memory buffer to an archive. These functions record the current local time into the archive.
// To add a directory entry, call this method with an archive name ending in a forwardslash with empty buffer.
// level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION.
mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags);
mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32);
#ifndef MINIZ_NO_STDIO
// Adds the contents of a disk file to an archive. This function also records the disk file's modified time into the archive.
// level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION.
mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
#endif
// Adds a file to an archive by fully cloning the data from another archive.
// This function fully clones the source file's compressed data (no recompression), along with its full filename, extra data, and comment fields.
mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint file_index);
// Finalizes the archive by writing the central directory records followed by the end of central directory record.
// After an archive is finalized, the only valid call on the mz_zip_archive struct is mz_zip_writer_end().
// An archive must be manually finalized by calling this function for it to be valid.
mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip);
mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **pBuf, size_t *pSize);
// Ends archive writing, freeing all allocations, and closing the output file if mz_zip_writer_init_file() was used.
// Note for the archive to be valid, it must have been finalized before ending.
mz_bool mz_zip_writer_end(mz_zip_archive *pZip);
// Misc. high-level helper functions:
// mz_zip_add_mem_to_archive_file_in_place() efficiently (but not atomically) appends a memory blob to a ZIP archive.
// level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION.
mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
// Reads a single file from an archive into a heap block.
// Returns NULL on failure.
void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint zip_flags);
#endif // #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
#endif // #ifndef MINIZ_NO_ARCHIVE_APIS
// ------------------- Low-level Decompression API Definitions
// Decompression flags used by tinfl_decompress().
// TINFL_FLAG_PARSE_ZLIB_HEADER: If set, the input has a valid zlib header and ends with an adler32 checksum (it's a valid zlib stream). Otherwise, the input is a raw deflate stream.
// TINFL_FLAG_HAS_MORE_INPUT: If set, there are more input bytes available beyond the end of the supplied input buffer. If clear, the input buffer contains all remaining input.
// TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF: If set, the output buffer is large enough to hold the entire decompressed stream. If clear, the output buffer is at least the size of the dictionary (typically 32KB).
// TINFL_FLAG_COMPUTE_ADLER32: Force adler-32 checksum computation of the decompressed bytes.
enum
{
TINFL_FLAG_PARSE_ZLIB_HEADER = 1,
TINFL_FLAG_HAS_MORE_INPUT = 2,
TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF = 4,
TINFL_FLAG_COMPUTE_ADLER32 = 8
};
// High level decompression functions:
// tinfl_decompress_mem_to_heap() decompresses a block in memory to a heap block allocated via malloc().
// On entry:
// pSrc_buf, src_buf_len: Pointer and size of the Deflate or zlib source data to decompress.
// On return:
// Function returns a pointer to the decompressed data, or NULL on failure.
// *pOut_len will be set to the decompressed data's size, which could be larger than src_buf_len on uncompressible data.
// The caller must call mz_free() on the returned block when it's no longer needed.
void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags);
// tinfl_decompress_mem_to_mem() decompresses a block in memory to another block in memory.
// Returns TINFL_DECOMPRESS_MEM_TO_MEM_FAILED on failure, or the number of bytes written on success.
#define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1))
size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags);
// tinfl_decompress_mem_to_callback() decompresses a block in memory to an internal 32KB buffer, and a user provided callback function will be called to flush the buffer.
// Returns 1 on success or 0 on failure.
typedef int (*tinfl_put_buf_func_ptr)(const void* pBuf, int len, void *pUser);
int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
struct tinfl_decompressor_tag; typedef struct tinfl_decompressor_tag tinfl_decompressor;
// Max size of LZ dictionary.
#define TINFL_LZ_DICT_SIZE 32768
// Return status.
typedef enum
{
TINFL_STATUS_BAD_PARAM = -3,
TINFL_STATUS_ADLER32_MISMATCH = -2,
TINFL_STATUS_FAILED = -1,
TINFL_STATUS_DONE = 0,
TINFL_STATUS_NEEDS_MORE_INPUT = 1,
TINFL_STATUS_HAS_MORE_OUTPUT = 2
} tinfl_status;
// Initializes the decompressor to its initial state.
#define tinfl_init(r) do { (r)->m_state = 0; } MZ_MACRO_END
#define tinfl_get_adler32(r) (r)->m_check_adler32
// Main low-level decompressor coroutine function. This is the only function actually needed for decompression. All the other functions are just high-level helpers for improved usability.
// This is a universal API, i.e. it can be used as a building block to build any desired higher level decompression API. In the limit case, it can be called once per every byte input or output.
tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags);
// Internal/private bits follow.
enum
{
TINFL_MAX_HUFF_TABLES = 3, TINFL_MAX_HUFF_SYMBOLS_0 = 288, TINFL_MAX_HUFF_SYMBOLS_1 = 32, TINFL_MAX_HUFF_SYMBOLS_2 = 19,
TINFL_FAST_LOOKUP_BITS = 10, TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS
};
typedef struct
{
mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0];
mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE], m_tree[TINFL_MAX_HUFF_SYMBOLS_0 * 2];
} tinfl_huff_table;
#if MINIZ_HAS_64BIT_REGISTERS
#define TINFL_USE_64BIT_BITBUF 1
#endif
#if TINFL_USE_64BIT_BITBUF
typedef mz_uint64 tinfl_bit_buf_t;
#define TINFL_BITBUF_SIZE (64)
#else
typedef mz_uint32 tinfl_bit_buf_t;
#define TINFL_BITBUF_SIZE (32)
#endif
struct tinfl_decompressor_tag
{
mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type, m_check_adler32, m_dist, m_counter, m_num_extra, m_table_sizes[TINFL_MAX_HUFF_TABLES];
tinfl_bit_buf_t m_bit_buf;
size_t m_dist_from_out_buf_start;
tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES];
mz_uint8 m_raw_header[4], m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137];
};
// ------------------- Low-level Compression API Definitions
// Set TDEFL_LESS_MEMORY to 1 to use less memory (compression will be slightly slower, and raw/dynamic blocks will be output more frequently).
#define TDEFL_LESS_MEMORY 0
// tdefl_init() compression flags logically OR'd together (low 12 bits contain the max. number of probes per dictionary search):
// TDEFL_DEFAULT_MAX_PROBES: The compressor defaults to 128 dictionary probes per dictionary search. 0=Huffman only, 1=Huffman+LZ (fastest/crap compression), 4095=Huffman+LZ (slowest/best compression).
enum
{
TDEFL_HUFFMAN_ONLY = 0, TDEFL_DEFAULT_MAX_PROBES = 128, TDEFL_MAX_PROBES_MASK = 0xFFF
};
// TDEFL_WRITE_ZLIB_HEADER: If set, the compressor outputs a zlib header before the deflate data, and the Adler-32 of the source data at the end. Otherwise, you'll get raw deflate data.
// TDEFL_COMPUTE_ADLER32: Always compute the adler-32 of the input data (even when not writing zlib headers).
// TDEFL_GREEDY_PARSING_FLAG: Set to use faster greedy parsing, instead of more efficient lazy parsing.
// TDEFL_NONDETERMINISTIC_PARSING_FLAG: Enable to decrease the compressor's initialization time to the minimum, but the output may vary from run to run given the same input (depending on the contents of memory).
// TDEFL_RLE_MATCHES: Only look for RLE matches (matches with a distance of 1)
// TDEFL_FILTER_MATCHES: Discards matches <= 5 chars if enabled.
// TDEFL_FORCE_ALL_STATIC_BLOCKS: Disable usage of optimized Huffman tables.
// TDEFL_FORCE_ALL_RAW_BLOCKS: Only use raw (uncompressed) deflate blocks.
// The low 12 bits are reserved to control the max # of hash probes per dictionary lookup (see TDEFL_MAX_PROBES_MASK).
enum
{
TDEFL_WRITE_ZLIB_HEADER = 0x01000,
TDEFL_COMPUTE_ADLER32 = 0x02000,
TDEFL_GREEDY_PARSING_FLAG = 0x04000,
TDEFL_NONDETERMINISTIC_PARSING_FLAG = 0x08000,
TDEFL_RLE_MATCHES = 0x10000,
TDEFL_FILTER_MATCHES = 0x20000,
TDEFL_FORCE_ALL_STATIC_BLOCKS = 0x40000,
TDEFL_FORCE_ALL_RAW_BLOCKS = 0x80000
};
// High level compression functions:
// tdefl_compress_mem_to_heap() compresses a block in memory to a heap block allocated via malloc().
// On entry:
// pSrc_buf, src_buf_len: Pointer and size of source block to compress.
// flags: The max match finder probes (default is 128) logically OR'd against the above flags. Higher probes are slower but improve compression.
// On return:
// Function returns a pointer to the compressed data, or NULL on failure.
// *pOut_len will be set to the compressed data's size, which could be larger than src_buf_len on uncompressible data.
// The caller must free() the returned block when it's no longer needed.
void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags);
// tdefl_compress_mem_to_mem() compresses a block in memory to another block in memory.
// Returns 0 on failure.
size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags);
// Compresses an image to a compressed PNG file in memory.
// On entry:
// pImage, w, h, and num_chans describe the image to compress. num_chans may be 1, 2, 3, or 4.
// The image pitch in bytes per scanline will be w*num_chans. The leftmost pixel on the top scanline is stored first in memory.
// level may range from [0,10], use MZ_NO_COMPRESSION, MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc. or a decent default is MZ_DEFAULT_LEVEL
// If flip is true, the image will be flipped on the Y axis (useful for OpenGL apps).
// On return:
// Function returns a pointer to the compressed data, or NULL on failure.
// *pLen_out will be set to the size of the PNG image file.
// The caller must mz_free() the returned heap block (which will typically be larger than *pLen_out) when it's no longer needed.
void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, int num_chans, size_t *pLen_out, mz_uint level, mz_bool flip);
void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out);
// Output stream interface. The compressor uses this interface to write compressed data. It'll typically be called TDEFL_OUT_BUF_SIZE at a time.
typedef mz_bool (*tdefl_put_buf_func_ptr)(const void* pBuf, int len, void *pUser);
// tdefl_compress_mem_to_output() compresses a block to an output stream. The above helpers use this function internally.
mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
enum { TDEFL_MAX_HUFF_TABLES = 3, TDEFL_MAX_HUFF_SYMBOLS_0 = 288, TDEFL_MAX_HUFF_SYMBOLS_1 = 32, TDEFL_MAX_HUFF_SYMBOLS_2 = 19, TDEFL_LZ_DICT_SIZE = 32768, TDEFL_LZ_DICT_SIZE_MASK = TDEFL_LZ_DICT_SIZE - 1, TDEFL_MIN_MATCH_LEN = 3, TDEFL_MAX_MATCH_LEN = 258 };
// TDEFL_OUT_BUF_SIZE MUST be large enough to hold a single entire compressed output block (using static/fixed Huffman codes).
#if TDEFL_LESS_MEMORY
enum { TDEFL_LZ_CODE_BUF_SIZE = 24 * 1024, TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13 ) / 10, TDEFL_MAX_HUFF_SYMBOLS = 288, TDEFL_LZ_HASH_BITS = 12, TDEFL_LEVEL1_HASH_SIZE_MASK = 4095, TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3, TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS };
#else
enum { TDEFL_LZ_CODE_BUF_SIZE = 64 * 1024, TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13 ) / 10, TDEFL_MAX_HUFF_SYMBOLS = 288, TDEFL_LZ_HASH_BITS = 15, TDEFL_LEVEL1_HASH_SIZE_MASK = 4095, TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3, TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS };
#endif
// The low-level tdefl functions below may be used directly if the above helper functions aren't flexible enough. The low-level functions don't make any heap allocations, unlike the above helper functions.
typedef enum
{
TDEFL_STATUS_BAD_PARAM = -2,
TDEFL_STATUS_PUT_BUF_FAILED = -1,
TDEFL_STATUS_OKAY = 0,
TDEFL_STATUS_DONE = 1,
} tdefl_status;
// Must map to MZ_NO_FLUSH, MZ_SYNC_FLUSH, etc. enums
typedef enum
{
TDEFL_NO_FLUSH = 0,
TDEFL_SYNC_FLUSH = 2,
TDEFL_FULL_FLUSH = 3,
TDEFL_FINISH = 4
} tdefl_flush;
// tdefl's compression state structure.
typedef struct
{
tdefl_put_buf_func_ptr m_pPut_buf_func;
void *m_pPut_buf_user;
mz_uint m_flags, m_max_probes[2];
int m_greedy_parsing;
mz_uint m_adler32, m_lookahead_pos, m_lookahead_size, m_dict_size;
mz_uint8 *m_pLZ_code_buf, *m_pLZ_flags, *m_pOutput_buf, *m_pOutput_buf_end;
mz_uint m_num_flags_left, m_total_lz_bytes, m_lz_code_buf_dict_pos, m_bits_in, m_bit_buffer;
mz_uint m_saved_match_dist, m_saved_match_len, m_saved_lit, m_output_flush_ofs, m_output_flush_remaining, m_finished, m_block_index, m_wants_to_finish;
tdefl_status m_prev_return_status;
const void *m_pIn_buf;
void *m_pOut_buf;
size_t *m_pIn_buf_size, *m_pOut_buf_size;
tdefl_flush m_flush;
const mz_uint8 *m_pSrc;
size_t m_src_buf_left, m_out_buf_ofs;
mz_uint8 m_dict[TDEFL_LZ_DICT_SIZE + TDEFL_MAX_MATCH_LEN - 1];
mz_uint16 m_huff_count[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
mz_uint16 m_huff_codes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
mz_uint8 m_huff_code_sizes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
mz_uint8 m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE];
mz_uint16 m_next[TDEFL_LZ_DICT_SIZE];
mz_uint16 m_hash[TDEFL_LZ_HASH_SIZE];
mz_uint8 m_output_buf[TDEFL_OUT_BUF_SIZE];
} tdefl_compressor;
// Initializes the compressor.
// There is no corresponding deinit() function because the tdefl API's do not dynamically allocate memory.
// pBut_buf_func: If NULL, output data will be supplied to the specified callback. In this case, the user should call the tdefl_compress_buffer() API for compression.
// If pBut_buf_func is NULL the user should always call the tdefl_compress() API.
// flags: See the above enums (TDEFL_HUFFMAN_ONLY, TDEFL_WRITE_ZLIB_HEADER, etc.)
tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
// Compresses a block of data, consuming as much of the specified input buffer as possible, and writing as much compressed data to the specified output buffer as possible.
tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush);
// tdefl_compress_buffer() is only usable when the tdefl_init() is called with a non-NULL tdefl_put_buf_func_ptr.
// tdefl_compress_buffer() always consumes the entire input buffer.
tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush);
tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d);
mz_uint32 tdefl_get_adler32(tdefl_compressor *d);
// Can't use tdefl_create_comp_flags_from_zip_params if MINIZ_NO_ZLIB_APIS isn't defined, because it uses some of its macros.
#ifndef MINIZ_NO_ZLIB_APIS
// Create tdefl_compress() flags given zlib-style compression parameters.
// level may range from [0,10] (where 10 is absolute max compression, but may be much slower on some files)
// window_bits may be -15 (raw deflate) or 15 (zlib)
// strategy may be either MZ_DEFAULT_STRATEGY, MZ_FILTERED, MZ_HUFFMAN_ONLY, MZ_RLE, or MZ_FIXED
mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy);
#endif // #ifndef MINIZ_NO_ZLIB_APIS
#ifdef __cplusplus
}
#endif
#endif // MINIZ_HEADER_INCLUDED
// ------------------- End of Header: Implementation follows. (If you only want the header, define MINIZ_HEADER_FILE_ONLY.)
#ifndef MINIZ_HEADER_FILE_ONLY
typedef unsigned char mz_validate_uint16[sizeof(mz_uint16)==2 ? 1 : -1];
typedef unsigned char mz_validate_uint32[sizeof(mz_uint32)==4 ? 1 : -1];
typedef unsigned char mz_validate_uint64[sizeof(mz_uint64)==8 ? 1 : -1];
#include <string.h>
#include <assert.h>
#define MZ_ASSERT(x) assert(x)
#ifdef MINIZ_NO_MALLOC
#define MZ_MALLOC(x) NULL
#define MZ_FREE(x) (void)x, ((void)0)
#define MZ_REALLOC(p, x) NULL
#else
#define MZ_MALLOC(x) malloc(x)
#define MZ_FREE(x) free(x)
#define MZ_REALLOC(p, x) realloc(p, x)
#endif
#define MZ_MAX(a,b) (((a)>(b))?(a):(b))
#define MZ_MIN(a,b) (((a)<(b))?(a):(b))
#define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj))
#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
#define MZ_READ_LE16(p) *((const mz_uint16 *)(p))
#define MZ_READ_LE32(p) *((const mz_uint32 *)(p))
#else
#define MZ_READ_LE16(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U))
#define MZ_READ_LE32(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U) | ((mz_uint32)(((const mz_uint8 *)(p))[2]) << 16U) | ((mz_uint32)(((const mz_uint8 *)(p))[3]) << 24U))
#endif
#ifdef _MSC_VER
#define MZ_FORCEINLINE __forceinline
#elif defined(__GNUC__)
#define MZ_FORCEINLINE inline __attribute__((__always_inline__))
#else
#define MZ_FORCEINLINE inline
#endif
#ifdef __cplusplus
extern "C" {
#endif
// ------------------- zlib-style API's
mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len)
{
mz_uint32 i, s1 = (mz_uint32)(adler & 0xffff), s2 = (mz_uint32)(adler >> 16); size_t block_len = buf_len % 5552;
if (!ptr) return MZ_ADLER32_INIT;
while (buf_len) {
for (i = 0; i + 7 < block_len; i += 8, ptr += 8) {
s1 += ptr[0], s2 += s1; s1 += ptr[1], s2 += s1; s1 += ptr[2], s2 += s1; s1 += ptr[3], s2 += s1;
s1 += ptr[4], s2 += s1; s1 += ptr[5], s2 += s1; s1 += ptr[6], s2 += s1; s1 += ptr[7], s2 += s1;
}
for ( ; i < block_len; ++i) s1 += *ptr++, s2 += s1;
s1 %= 65521U, s2 %= 65521U; buf_len -= block_len; block_len = 5552;
}
return (s2 << 16) + s1;
}
// Karl Malbrain's compact CRC-32. See "A compact CCITT crc16 and crc32 C implementation that balances processor cache usage against speed": http://www.geocities.com/malbrain/
mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len)
{
static const mz_uint32 s_crc32[16] = { 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c };
mz_uint32 crcu32 = (mz_uint32)crc;
if (!ptr) return MZ_CRC32_INIT;
crcu32 = ~crcu32; while (buf_len--) { mz_uint8 b = *ptr++; crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)]; crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)]; }
return ~crcu32;
}
void mz_free(void *p)
{
MZ_FREE(p);
}
#ifndef MINIZ_NO_ZLIB_APIS
static void *def_alloc_func(void *opaque, size_t items, size_t size) { (void)opaque, (void)items, (void)size; return MZ_MALLOC(items * size); }
static void def_free_func(void *opaque, void *address) { (void)opaque, (void)address; MZ_FREE(address); }
static void *def_realloc_func(void *opaque, void *address, size_t items, size_t size) { (void)opaque, (void)address, (void)items, (void)size; return MZ_REALLOC(address, items * size); }
const char *mz_version(void)
{
return MZ_VERSION;
}
int mz_deflateInit(mz_streamp pStream, int level)
{
return mz_deflateInit2(pStream, level, MZ_DEFLATED, MZ_DEFAULT_WINDOW_BITS, 9, MZ_DEFAULT_STRATEGY);
}
int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy)
{
tdefl_compressor *pComp;
mz_uint comp_flags = TDEFL_COMPUTE_ADLER32 | tdefl_create_comp_flags_from_zip_params(level, window_bits, strategy);
if (!pStream) return MZ_STREAM_ERROR;
if ((method != MZ_DEFLATED) || ((mem_level < 1) || (mem_level > 9)) || ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS))) return MZ_PARAM_ERROR;
pStream->data_type = 0;
pStream->adler = MZ_ADLER32_INIT;
pStream->msg = NULL;
pStream->reserved = 0;
pStream->total_in = 0;
pStream->total_out = 0;
if (!pStream->zalloc) pStream->zalloc = def_alloc_func;
if (!pStream->zfree) pStream->zfree = def_free_func;
pComp = (tdefl_compressor *)pStream->zalloc(pStream->opaque, 1, sizeof(tdefl_compressor));
if (!pComp)
return MZ_MEM_ERROR;
pStream->state = (struct mz_internal_state *)pComp;
if (tdefl_init(pComp, NULL, NULL, comp_flags) != TDEFL_STATUS_OKAY)
{
mz_deflateEnd(pStream);
return MZ_PARAM_ERROR;
}
return MZ_OK;
}
int mz_deflateReset(mz_streamp pStream)
{
if ((!pStream) || (!pStream->state) || (!pStream->zalloc) || (!pStream->zfree)) return MZ_STREAM_ERROR;
pStream->total_in = pStream->total_out = 0;
tdefl_init((tdefl_compressor*)pStream->state, NULL, NULL, ((tdefl_compressor*)pStream->state)->m_flags);
return MZ_OK;
}
int mz_deflate(mz_streamp pStream, int flush)
{
size_t in_bytes, out_bytes;
mz_ulong orig_total_in, orig_total_out;
int mz_status = MZ_OK;
if ((!pStream) || (!pStream->state) || (flush < 0) || (flush > MZ_FINISH) || (!pStream->next_out)) return MZ_STREAM_ERROR;
if (!pStream->avail_out) return MZ_BUF_ERROR;
if (flush == MZ_PARTIAL_FLUSH) flush = MZ_SYNC_FLUSH;
if (((tdefl_compressor*)pStream->state)->m_prev_return_status == TDEFL_STATUS_DONE)
return (flush == MZ_FINISH) ? MZ_STREAM_END : MZ_BUF_ERROR;
orig_total_in = pStream->total_in; orig_total_out = pStream->total_out;
for ( ; ; )
{
tdefl_status defl_status;
in_bytes = pStream->avail_in; out_bytes = pStream->avail_out;
defl_status = tdefl_compress((tdefl_compressor*)pStream->state, pStream->next_in, &in_bytes, pStream->next_out, &out_bytes, (tdefl_flush)flush);
pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes;
pStream->total_in += (mz_uint)in_bytes; pStream->adler = tdefl_get_adler32((tdefl_compressor*)pStream->state);
pStream->next_out += (mz_uint)out_bytes; pStream->avail_out -= (mz_uint)out_bytes;
pStream->total_out += (mz_uint)out_bytes;
if (defl_status < 0)
{
mz_status = MZ_STREAM_ERROR;
break;
}
else if (defl_status == TDEFL_STATUS_DONE)
{
mz_status = MZ_STREAM_END;
break;
}
else if (!pStream->avail_out)
break;
else if ((!pStream->avail_in) && (flush != MZ_FINISH))
{
if ((flush) || (pStream->total_in != orig_total_in) || (pStream->total_out != orig_total_out))
break;
return MZ_BUF_ERROR; // Can't make forward progress without some input.
}
}
return mz_status;
}
int mz_deflateEnd(mz_streamp pStream)
{
if (!pStream) return MZ_STREAM_ERROR;
if (pStream->state)
{
pStream->zfree(pStream->opaque, pStream->state);
pStream->state = NULL;
}
return MZ_OK;
}
mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len)
{
(void)pStream;
// This is really over conservative. (And lame, but it's actually pretty tricky to compute a true upper bound given the way tdefl's blocking works.)
return MZ_MAX(128 + (source_len * 110) / 100, 128 + source_len + ((source_len / (31 * 1024)) + 1) * 5);
}
int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level)
{
int status;
mz_stream stream;
memset(&stream, 0, sizeof(stream));
// In case mz_ulong is 64-bits (argh I hate longs).
if ((source_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR;
stream.next_in = pSource;
stream.avail_in = (mz_uint32)source_len;
stream.next_out = pDest;
stream.avail_out = (mz_uint32)*pDest_len;
status = mz_deflateInit(&stream, level);
if (status != MZ_OK) return status;
status = mz_deflate(&stream, MZ_FINISH);
if (status != MZ_STREAM_END)
{
mz_deflateEnd(&stream);
return (status == MZ_OK) ? MZ_BUF_ERROR : status;
}
*pDest_len = stream.total_out;
return mz_deflateEnd(&stream);
}
int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
{
return mz_compress2(pDest, pDest_len, pSource, source_len, MZ_DEFAULT_COMPRESSION);
}
mz_ulong mz_compressBound(mz_ulong source_len)
{
return mz_deflateBound(NULL, source_len);
}
typedef struct
{
tinfl_decompressor m_decomp;
mz_uint m_dict_ofs, m_dict_avail, m_first_call, m_has_flushed; int m_window_bits;
mz_uint8 m_dict[TINFL_LZ_DICT_SIZE];
tinfl_status m_last_status;
} inflate_state;
int mz_inflateInit2(mz_streamp pStream, int window_bits)
{
inflate_state *pDecomp;
if (!pStream) return MZ_STREAM_ERROR;
if ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS)) return MZ_PARAM_ERROR;
pStream->data_type = 0;
pStream->adler = 0;
pStream->msg = NULL;
pStream->total_in = 0;
pStream->total_out = 0;
pStream->reserved = 0;
if (!pStream->zalloc) pStream->zalloc = def_alloc_func;
if (!pStream->zfree) pStream->zfree = def_free_func;
pDecomp = (inflate_state*)pStream->zalloc(pStream->opaque, 1, sizeof(inflate_state));
if (!pDecomp) return MZ_MEM_ERROR;
pStream->state = (struct mz_internal_state *)pDecomp;
tinfl_init(&pDecomp->m_decomp);
pDecomp->m_dict_ofs = 0;
pDecomp->m_dict_avail = 0;
pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT;
pDecomp->m_first_call = 1;
pDecomp->m_has_flushed = 0;
pDecomp->m_window_bits = window_bits;
return MZ_OK;
}
int mz_inflateInit(mz_streamp pStream)
{
return mz_inflateInit2(pStream, MZ_DEFAULT_WINDOW_BITS);
}
int mz_inflate(mz_streamp pStream, int flush)
{
inflate_state* pState;
mz_uint n, first_call, decomp_flags = TINFL_FLAG_COMPUTE_ADLER32;
size_t in_bytes, out_bytes, orig_avail_in;
tinfl_status status;
if ((!pStream) || (!pStream->state)) return MZ_STREAM_ERROR;
if (flush == MZ_PARTIAL_FLUSH) flush = MZ_SYNC_FLUSH;
if ((flush) && (flush != MZ_SYNC_FLUSH) && (flush != MZ_FINISH)) return MZ_STREAM_ERROR;
pState = (inflate_state*)pStream->state;
if (pState->m_window_bits > 0) decomp_flags |= TINFL_FLAG_PARSE_ZLIB_HEADER;
orig_avail_in = pStream->avail_in;
first_call = pState->m_first_call; pState->m_first_call = 0;
if (pState->m_last_status < 0) return MZ_DATA_ERROR;
if (pState->m_has_flushed && (flush != MZ_FINISH)) return MZ_STREAM_ERROR;
pState->m_has_flushed |= (flush == MZ_FINISH);
if ((flush == MZ_FINISH) && (first_call))
{
// MZ_FINISH on the first call implies that the input and output buffers are large enough to hold the entire compressed/decompressed file.
decomp_flags |= TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF;
in_bytes = pStream->avail_in; out_bytes = pStream->avail_out;
status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pStream->next_out, pStream->next_out, &out_bytes, decomp_flags);
pState->m_last_status = status;
pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes; pStream->total_in += (mz_uint)in_bytes;
pStream->adler = tinfl_get_adler32(&pState->m_decomp);
pStream->next_out += (mz_uint)out_bytes; pStream->avail_out -= (mz_uint)out_bytes; pStream->total_out += (mz_uint)out_bytes;
if (status < 0)
return MZ_DATA_ERROR;
else if (status != TINFL_STATUS_DONE)
{
pState->m_last_status = TINFL_STATUS_FAILED;
return MZ_BUF_ERROR;
}
return MZ_STREAM_END;
}
// flush != MZ_FINISH then we must assume there's more input.
if (flush != MZ_FINISH) decomp_flags |= TINFL_FLAG_HAS_MORE_INPUT;
if (pState->m_dict_avail)
{
n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
pStream->next_out += n; pStream->avail_out -= n; pStream->total_out += n;
pState->m_dict_avail -= n; pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
return ((pState->m_last_status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
}
for ( ; ; )
{
in_bytes = pStream->avail_in;
out_bytes = TINFL_LZ_DICT_SIZE - pState->m_dict_ofs;
status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pState->m_dict, pState->m_dict + pState->m_dict_ofs, &out_bytes, decomp_flags);
pState->m_last_status = status;
pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes;
pStream->total_in += (mz_uint)in_bytes; pStream->adler = tinfl_get_adler32(&pState->m_decomp);
pState->m_dict_avail = (mz_uint)out_bytes;
n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
pStream->next_out += n; pStream->avail_out -= n; pStream->total_out += n;
pState->m_dict_avail -= n; pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
if (status < 0)
return MZ_DATA_ERROR; // Stream is corrupted (there could be some uncompressed data left in the output dictionary - oh well).
else if ((status == TINFL_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in))
return MZ_BUF_ERROR; // Signal caller that we can't make forward progress without supplying more input or by setting flush to MZ_FINISH.
else if (flush == MZ_FINISH)
{
// The output buffer MUST be large to hold the remaining uncompressed data when flush==MZ_FINISH.
if (status == TINFL_STATUS_DONE)
return pState->m_dict_avail ? MZ_BUF_ERROR : MZ_STREAM_END;
// status here must be TINFL_STATUS_HAS_MORE_OUTPUT, which means there's at least 1 more byte on the way. If there's no more room left in the output buffer then something is wrong.
else if (!pStream->avail_out)
return MZ_BUF_ERROR;
}
else if ((status == TINFL_STATUS_DONE) || (!pStream->avail_in) || (!pStream->avail_out) || (pState->m_dict_avail))
break;
}
return ((status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
}
int mz_inflateEnd(mz_streamp pStream)
{
if (!pStream)
return MZ_STREAM_ERROR;
if (pStream->state)
{
pStream->zfree(pStream->opaque, pStream->state);
pStream->state = NULL;
}
return MZ_OK;
}
int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
{
mz_stream stream;
int status;
memset(&stream, 0, sizeof(stream));
// In case mz_ulong is 64-bits (argh I hate longs).
if ((source_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR;
stream.next_in = pSource;
stream.avail_in = (mz_uint32)source_len;
stream.next_out = pDest;
stream.avail_out = (mz_uint32)*pDest_len;
status = mz_inflateInit(&stream);
if (status != MZ_OK)
return status;
status = mz_inflate(&stream, MZ_FINISH);
if (status != MZ_STREAM_END)
{
mz_inflateEnd(&stream);
return ((status == MZ_BUF_ERROR) && (!stream.avail_in)) ? MZ_DATA_ERROR : status;
}
*pDest_len = stream.total_out;
return mz_inflateEnd(&stream);
}
const char *mz_error(int err)
{
static struct { int m_err; const char *m_pDesc; } s_error_descs[] =
{
{ MZ_OK, "" }, { MZ_STREAM_END, "stream end" }, { MZ_NEED_DICT, "need dictionary" }, { MZ_ERRNO, "file error" }, { MZ_STREAM_ERROR, "stream error" },
{ MZ_DATA_ERROR, "data error" }, { MZ_MEM_ERROR, "out of memory" }, { MZ_BUF_ERROR, "buf error" }, { MZ_VERSION_ERROR, "version error" }, { MZ_PARAM_ERROR, "parameter error" }
};
mz_uint i; for (i = 0; i < sizeof(s_error_descs) / sizeof(s_error_descs[0]); ++i) if (s_error_descs[i].m_err == err) return s_error_descs[i].m_pDesc;
return NULL;
}
#endif //MINIZ_NO_ZLIB_APIS
// ------------------- Low-level Decompression (completely independent from all compression API's)
#define TINFL_MEMCPY(d, s, l) memcpy(d, s, l)
#define TINFL_MEMSET(p, c, l) memset(p, c, l)
#define TINFL_CR_BEGIN switch(r->m_state) { case 0:
#define TINFL_CR_RETURN(state_index, result) do { status = result; r->m_state = state_index; goto common_exit; case state_index:; } MZ_MACRO_END
#define TINFL_CR_RETURN_FOREVER(state_index, result) do { for ( ; ; ) { TINFL_CR_RETURN(state_index, result); } } MZ_MACRO_END
#define TINFL_CR_FINISH }
// TODO: If the caller has indicated that there's no more input, and we attempt to read beyond the input buf, then something is wrong with the input because the inflator never
// reads ahead more than it needs to. Currently TINFL_GET_BYTE() pads the end of the stream with 0's in this scenario.
#define TINFL_GET_BYTE(state_index, c) do { \
if (pIn_buf_cur >= pIn_buf_end) { \
for ( ; ; ) { \
if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) { \
TINFL_CR_RETURN(state_index, TINFL_STATUS_NEEDS_MORE_INPUT); \
if (pIn_buf_cur < pIn_buf_end) { \
c = *pIn_buf_cur++; \
break; \
} \
} else { \
c = 0; \
break; \
} \
} \
} else c = *pIn_buf_cur++; } MZ_MACRO_END
#define TINFL_NEED_BITS(state_index, n) do { mz_uint c; TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; } while (num_bits < (mz_uint)(n))
#define TINFL_SKIP_BITS(state_index, n) do { if (num_bits < (mz_uint)(n)) { TINFL_NEED_BITS(state_index, n); } bit_buf >>= (n); num_bits -= (n); } MZ_MACRO_END
#define TINFL_GET_BITS(state_index, b, n) do { if (num_bits < (mz_uint)(n)) { TINFL_NEED_BITS(state_index, n); } b = bit_buf & ((1 << (n)) - 1); bit_buf >>= (n); num_bits -= (n); } MZ_MACRO_END
// TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes remaining in the input buffer falls below 2.
// It reads just enough bytes from the input stream that are needed to decode the next Huffman code (and absolutely no more). It works by trying to fully decode a
// Huffman code by using whatever bits are currently present in the bit buffer. If this fails, it reads another byte, and tries again until it succeeds or until the
// bit buffer contains >=15 bits (deflate's max. Huffman code size).
#define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \
do { \
temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \
if (temp >= 0) { \
code_len = temp >> 9; \
if ((code_len) && (num_bits >= code_len)) \
break; \
} else if (num_bits > TINFL_FAST_LOOKUP_BITS) { \
code_len = TINFL_FAST_LOOKUP_BITS; \
do { \
temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \
} while ((temp < 0) && (num_bits >= (code_len + 1))); if (temp >= 0) break; \
} TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; \
} while (num_bits < 15);
// TINFL_HUFF_DECODE() decodes the next Huffman coded symbol. It's more complex than you would initially expect because the zlib API expects the decompressor to never read
// beyond the final byte of the deflate stream. (In other words, when this macro wants to read another byte from the input, it REALLY needs another byte in order to fully
// decode the next Huffman code.) Handling this properly is particularly important on raw deflate (non-zlib) streams, which aren't followed by a byte aligned adler-32.
// The slow path is only executed at the very end of the input buffer.
#define TINFL_HUFF_DECODE(state_index, sym, pHuff) do { \
int temp; mz_uint code_len, c; \
if (num_bits < 15) { \
if ((pIn_buf_end - pIn_buf_cur) < 2) { \
TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \
} else { \
bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); pIn_buf_cur += 2; num_bits += 16; \
} \
} \
if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \
code_len = temp >> 9, temp &= 511; \
else { \
code_len = TINFL_FAST_LOOKUP_BITS; do { temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; } while (temp < 0); \
} sym = temp; bit_buf >>= code_len; num_bits -= code_len; } MZ_MACRO_END
tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags)
{
static const int s_length_base[31] = { 3,4,5,6,7,8,9,10,11,13, 15,17,19,23,27,31,35,43,51,59, 67,83,99,115,131,163,195,227,258,0,0 };
static const int s_length_extra[31]= { 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 };
static const int s_dist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0};
static const int s_dist_extra[32] = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
static const mz_uint8 s_length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 };
static const int s_min_table_sizes[3] = { 257, 1, 4 };
tinfl_status status = TINFL_STATUS_FAILED; mz_uint32 num_bits, dist, counter, num_extra; tinfl_bit_buf_t bit_buf;
const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = pIn_buf_next + *pIn_buf_size;
mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = pOut_buf_next + *pOut_buf_size;
size_t out_buf_size_mask = (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF) ? (size_t)-1 : ((pOut_buf_next - pOut_buf_start) + *pOut_buf_size) - 1, dist_from_out_buf_start;
// Ensure the output buffer's size is a power of 2, unless the output buffer is large enough to hold the entire output file (in which case it doesn't matter).
if (((out_buf_size_mask + 1) & out_buf_size_mask) || (pOut_buf_next < pOut_buf_start)) { *pIn_buf_size = *pOut_buf_size = 0; return TINFL_STATUS_BAD_PARAM; }
num_bits = r->m_num_bits; bit_buf = r->m_bit_buf; dist = r->m_dist; counter = r->m_counter; num_extra = r->m_num_extra; dist_from_out_buf_start = r->m_dist_from_out_buf_start;
TINFL_CR_BEGIN
bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0; r->m_z_adler32 = r->m_check_adler32 = 1;
if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
{
TINFL_GET_BYTE(1, r->m_zhdr0); TINFL_GET_BYTE(2, r->m_zhdr1);
counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8));
if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || ((out_buf_size_mask + 1) < (size_t)(1U << (8U + (r->m_zhdr0 >> 4)))));
if (counter) { TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED); }
}
do
{
TINFL_GET_BITS(3, r->m_final, 3); r->m_type = r->m_final >> 1;
if (r->m_type == 0)
{
TINFL_SKIP_BITS(5, num_bits & 7);
for (counter = 0; counter < 4; ++counter) { if (num_bits) TINFL_GET_BITS(6, r->m_raw_header[counter], 8); else TINFL_GET_BYTE(7, r->m_raw_header[counter]); }
if ((counter = (r->m_raw_header[0] | (r->m_raw_header[1] << 8))) != (mz_uint)(0xFFFF ^ (r->m_raw_header[2] | (r->m_raw_header[3] << 8)))) { TINFL_CR_RETURN_FOREVER(39, TINFL_STATUS_FAILED); }
while ((counter) && (num_bits))
{
TINFL_GET_BITS(51, dist, 8);
while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT); }
*pOut_buf_cur++ = (mz_uint8)dist;
counter--;
}
while (counter)
{
size_t n; while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT); }
while (pIn_buf_cur >= pIn_buf_end)
{
if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT)
{
TINFL_CR_RETURN(38, TINFL_STATUS_NEEDS_MORE_INPUT);
}
else
{
TINFL_CR_RETURN_FOREVER(40, TINFL_STATUS_FAILED);
}
}
n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), (size_t)(pIn_buf_end - pIn_buf_cur)), counter);
TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n); pIn_buf_cur += n; pOut_buf_cur += n; counter -= (mz_uint)n;
}
}
else if (r->m_type == 3)
{
TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED);
}
else
{
if (r->m_type == 1)
{
mz_uint8 *p = r->m_tables[0].m_code_size; mz_uint i;
r->m_table_sizes[0] = 288; r->m_table_sizes[1] = 32; TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32);
for ( i = 0; i <= 143; ++i) *p++ = 8; for ( ; i <= 255; ++i) *p++ = 9; for ( ; i <= 279; ++i) *p++ = 7; for ( ; i <= 287; ++i) *p++ = 8;
}
else
{
for (counter = 0; counter < 3; counter++) { TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]); r->m_table_sizes[counter] += s_min_table_sizes[counter]; }
MZ_CLEAR_OBJ(r->m_tables[2].m_code_size); for (counter = 0; counter < r->m_table_sizes[2]; counter++) { mz_uint s; TINFL_GET_BITS(14, s, 3); r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s; }
r->m_table_sizes[2] = 19;
}
for ( ; (int)r->m_type >= 0; r->m_type--)
{
int tree_next, tree_cur; tinfl_huff_table *pTable;
mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16]; pTable = &r->m_tables[r->m_type]; MZ_CLEAR_OBJ(total_syms); MZ_CLEAR_OBJ(pTable->m_look_up); MZ_CLEAR_OBJ(pTable->m_tree);
for (i = 0; i < r->m_table_sizes[r->m_type]; ++i) total_syms[pTable->m_code_size[i]]++;
used_syms = 0, total = 0; next_code[0] = next_code[1] = 0;
for (i = 1; i <= 15; ++i) { used_syms += total_syms[i]; next_code[i + 1] = (total = ((total + total_syms[i]) << 1)); }
if ((65536 != total) && (used_syms > 1))
{
TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED);
}
for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index)
{
mz_uint rev_code = 0, l, cur_code, code_size = pTable->m_code_size[sym_index]; if (!code_size) continue;
cur_code = next_code[code_size]++; for (l = code_size; l > 0; l--, cur_code >>= 1) rev_code = (rev_code << 1) | (cur_code & 1);
if (code_size <= TINFL_FAST_LOOKUP_BITS) { mz_int16 k = (mz_int16)((code_size << 9) | sym_index); while (rev_code < TINFL_FAST_LOOKUP_SIZE) { pTable->m_look_up[rev_code] = k; rev_code += (1 << code_size); } continue; }
if (0 == (tree_cur = pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)])) { pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; }
rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1);
for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--)
{
tree_cur -= ((rev_code >>= 1) & 1);
if (!pTable->m_tree[-tree_cur - 1]) { pTable->m_tree[-tree_cur - 1] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; } else tree_cur = pTable->m_tree[-tree_cur - 1];
}
tree_cur -= ((rev_code >>= 1) & 1); pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index;
}
if (r->m_type == 2)
{
for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]); )
{
mz_uint s; TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]); if (dist < 16) { r->m_len_codes[counter++] = (mz_uint8)dist; continue; }
if ((dist == 16) && (!counter))
{
TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED);
}
num_extra = "\02\03\07"[dist - 16]; TINFL_GET_BITS(18, s, num_extra); s += "\03\03\013"[dist - 16];
TINFL_MEMSET(r->m_len_codes + counter, (dist == 16) ? r->m_len_codes[counter - 1] : 0, s); counter += s;
}
if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter)
{
TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED);
}
TINFL_MEMCPY(r->m_tables[0].m_code_size, r->m_len_codes, r->m_table_sizes[0]); TINFL_MEMCPY(r->m_tables[1].m_code_size, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]);
}
}
for ( ; ; )
{
mz_uint8 *pSrc;
for ( ; ; )
{
if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2))
{
TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]);
if (counter >= 256)
break;
while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT); }
*pOut_buf_cur++ = (mz_uint8)counter;
}
else
{
int sym2; mz_uint code_len;
#if TINFL_USE_64BIT_BITBUF
if (num_bits < 30) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE32(pIn_buf_cur)) << num_bits); pIn_buf_cur += 4; num_bits += 32; }
#else
if (num_bits < 15) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); pIn_buf_cur += 2; num_bits += 16; }
#endif
if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
code_len = sym2 >> 9;
else
{
code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0);
}
counter = sym2; bit_buf >>= code_len; num_bits -= code_len;
if (counter & 256)
break;
#if !TINFL_USE_64BIT_BITBUF
if (num_bits < 15) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); pIn_buf_cur += 2; num_bits += 16; }
#endif
if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
code_len = sym2 >> 9;
else
{
code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0);
}
bit_buf >>= code_len; num_bits -= code_len;
pOut_buf_cur[0] = (mz_uint8)counter;
if (sym2 & 256)
{
pOut_buf_cur++;
counter = sym2;
break;
}
pOut_buf_cur[1] = (mz_uint8)sym2;
pOut_buf_cur += 2;
}
}
if ((counter &= 511) == 256) break;
num_extra = s_length_extra[counter - 257]; counter = s_length_base[counter - 257];
if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(25, extra_bits, num_extra); counter += extra_bits; }
TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]);
num_extra = s_dist_extra[dist]; dist = s_dist_base[dist];
if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(27, extra_bits, num_extra); dist += extra_bits; }
dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start;
if ((dist > dist_from_out_buf_start) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
{
TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED);
}
pSrc = pOut_buf_start + ((dist_from_out_buf_start - dist) & out_buf_size_mask);
if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end)
{
while (counter--)
{
while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT); }
*pOut_buf_cur++ = pOut_buf_start[(dist_from_out_buf_start++ - dist) & out_buf_size_mask];
}
continue;
}
#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
else if ((counter >= 9) && (counter <= dist))
{
const mz_uint8 *pSrc_end = pSrc + (counter & ~7);
do
{
((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0];
((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1];
pOut_buf_cur += 8;
} while ((pSrc += 8) < pSrc_end);
if ((counter &= 7) < 3)
{
if (counter)
{
pOut_buf_cur[0] = pSrc[0];
if (counter > 1)
pOut_buf_cur[1] = pSrc[1];
pOut_buf_cur += counter;
}
continue;
}
}
#endif
do
{
pOut_buf_cur[0] = pSrc[0];
pOut_buf_cur[1] = pSrc[1];
pOut_buf_cur[2] = pSrc[2];
pOut_buf_cur += 3; pSrc += 3;
} while ((int)(counter -= 3) > 2);
if ((int)counter > 0)
{
pOut_buf_cur[0] = pSrc[0];
if ((int)counter > 1)
pOut_buf_cur[1] = pSrc[1];
pOut_buf_cur += counter;
}
}
}
} while (!(r->m_final & 1));
if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
{
TINFL_SKIP_BITS(32, num_bits & 7); for (counter = 0; counter < 4; ++counter) { mz_uint s; if (num_bits) TINFL_GET_BITS(41, s, 8); else TINFL_GET_BYTE(42, s); r->m_z_adler32 = (r->m_z_adler32 << 8) | s; }
}
TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE);
TINFL_CR_FINISH
common_exit:
r->m_num_bits = num_bits; r->m_bit_buf = bit_buf; r->m_dist = dist; r->m_counter = counter; r->m_num_extra = num_extra; r->m_dist_from_out_buf_start = dist_from_out_buf_start;
*pIn_buf_size = pIn_buf_cur - pIn_buf_next; *pOut_buf_size = pOut_buf_cur - pOut_buf_next;
if ((decomp_flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && (status >= 0))
{
const mz_uint8 *ptr = pOut_buf_next; size_t buf_len = *pOut_buf_size;
mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, s2 = r->m_check_adler32 >> 16; size_t block_len = buf_len % 5552;
while (buf_len)
{
for (i = 0; i + 7 < block_len; i += 8, ptr += 8)
{
s1 += ptr[0], s2 += s1; s1 += ptr[1], s2 += s1; s1 += ptr[2], s2 += s1; s1 += ptr[3], s2 += s1;
s1 += ptr[4], s2 += s1; s1 += ptr[5], s2 += s1; s1 += ptr[6], s2 += s1; s1 += ptr[7], s2 += s1;
}
for ( ; i < block_len; ++i) s1 += *ptr++, s2 += s1;
s1 %= 65521U, s2 %= 65521U; buf_len -= block_len; block_len = 5552;
}
r->m_check_adler32 = (s2 << 16) + s1; if ((status == TINFL_STATUS_DONE) && (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) && (r->m_check_adler32 != r->m_z_adler32)) status = TINFL_STATUS_ADLER32_MISMATCH;
}
return status;
}
// Higher level helper functions.
void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags)
{
tinfl_decompressor decomp; void *pBuf = NULL, *pNew_buf; size_t src_buf_ofs = 0, out_buf_capacity = 0;
*pOut_len = 0;
tinfl_init(&decomp);
for ( ; ; )
{
size_t src_buf_size = src_buf_len - src_buf_ofs, dst_buf_size = out_buf_capacity - *pOut_len, new_out_buf_capacity;
tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8*)pSrc_buf + src_buf_ofs, &src_buf_size, (mz_uint8*)pBuf, pBuf ? (mz_uint8*)pBuf + *pOut_len : NULL, &dst_buf_size,
(flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF);
if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT))
{
MZ_FREE(pBuf); *pOut_len = 0; return NULL;
}
src_buf_ofs += src_buf_size;
*pOut_len += dst_buf_size;
if (status == TINFL_STATUS_DONE) break;
new_out_buf_capacity = out_buf_capacity * 2; if (new_out_buf_capacity < 128) new_out_buf_capacity = 128;
pNew_buf = MZ_REALLOC(pBuf, new_out_buf_capacity);
if (!pNew_buf)
{
MZ_FREE(pBuf); *pOut_len = 0; return NULL;
}
pBuf = pNew_buf; out_buf_capacity = new_out_buf_capacity;
}
return pBuf;
}
size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags)
{
tinfl_decompressor decomp; tinfl_status status; tinfl_init(&decomp);
status = tinfl_decompress(&decomp, (const mz_uint8*)pSrc_buf, &src_buf_len, (mz_uint8*)pOut_buf, (mz_uint8*)pOut_buf, &out_buf_len, (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF);
return (status != TINFL_STATUS_DONE) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED : out_buf_len;
}
int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags)
{
int result = 0;
tinfl_decompressor decomp;
mz_uint8 *pDict = (mz_uint8*)MZ_MALLOC(TINFL_LZ_DICT_SIZE); size_t in_buf_ofs = 0, dict_ofs = 0;
if (!pDict)
return TINFL_STATUS_FAILED;
tinfl_init(&decomp);
for ( ; ; )
{
size_t in_buf_size = *pIn_buf_size - in_buf_ofs, dst_buf_size = TINFL_LZ_DICT_SIZE - dict_ofs;
tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8*)pIn_buf + in_buf_ofs, &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size,
(flags & ~(TINFL_FLAG_HAS_MORE_INPUT | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)));
in_buf_ofs += in_buf_size;
if ((dst_buf_size) && (!(*pPut_buf_func)(pDict + dict_ofs, (int)dst_buf_size, pPut_buf_user)))
break;
if (status != TINFL_STATUS_HAS_MORE_OUTPUT)
{
result = (status == TINFL_STATUS_DONE);
break;
}
dict_ofs = (dict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1);
}
MZ_FREE(pDict);
*pIn_buf_size = in_buf_ofs;
return result;
}
// ------------------- Low-level Compression (independent from all decompression API's)
// Purposely making these tables static for faster init and thread safety.
static const mz_uint16 s_tdefl_len_sym[256] = {
257,258,259,260,261,262,263,264,265,265,266,266,267,267,268,268,269,269,269,269,270,270,270,270,271,271,271,271,272,272,272,272,
273,273,273,273,273,273,273,273,274,274,274,274,274,274,274,274,275,275,275,275,275,275,275,275,276,276,276,276,276,276,276,276,
277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,
279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,
281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,
282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,
283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,
284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,285 };
static const mz_uint8 s_tdefl_len_extra[256] = {
0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0 };
static const mz_uint8 s_tdefl_small_dist_sym[512] = {
0,1,2,3,4,4,5,5,6,6,6,6,7,7,7,7,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,
11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,
13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14,
14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17 };
static const mz_uint8 s_tdefl_small_dist_extra[512] = {
0,0,0,0,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7 };
static const mz_uint8 s_tdefl_large_dist_sym[128] = {
0,0,18,19,20,20,21,21,22,22,22,22,23,23,23,23,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,
26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,
28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29 };
static const mz_uint8 s_tdefl_large_dist_extra[128] = {
0,0,8,8,9,9,9,9,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13 };
// Radix sorts tdefl_sym_freq[] array by 16-bit key m_key. Returns ptr to sorted values.
typedef struct { mz_uint16 m_key, m_sym_index; } tdefl_sym_freq;
static tdefl_sym_freq* tdefl_radix_sort_syms(mz_uint num_syms, tdefl_sym_freq* pSyms0, tdefl_sym_freq* pSyms1)
{
mz_uint32 total_passes = 2, pass_shift, pass, i, hist[256 * 2]; tdefl_sym_freq* pCur_syms = pSyms0, *pNew_syms = pSyms1; MZ_CLEAR_OBJ(hist);
for (i = 0; i < num_syms; i++) { mz_uint freq = pSyms0[i].m_key; hist[freq & 0xFF]++; hist[256 + ((freq >> 8) & 0xFF)]++; }
while ((total_passes > 1) && (num_syms == hist[(total_passes - 1) * 256])) total_passes--;
for (pass_shift = 0, pass = 0; pass < total_passes; pass++, pass_shift += 8)
{
const mz_uint32* pHist = &hist[pass << 8];
mz_uint offsets[256], cur_ofs = 0;
for (i = 0; i < 256; i++) { offsets[i] = cur_ofs; cur_ofs += pHist[i]; }
for (i = 0; i < num_syms; i++) pNew_syms[offsets[(pCur_syms[i].m_key >> pass_shift) & 0xFF]++] = pCur_syms[i];
{ tdefl_sym_freq* t = pCur_syms; pCur_syms = pNew_syms; pNew_syms = t; }
}
return pCur_syms;
}
// tdefl_calculate_minimum_redundancy() originally written by: Alistair Moffat, alistair@cs.mu.oz.au, Jyrki Katajainen, jyrki@diku.dk, November 1996.
static void tdefl_calculate_minimum_redundancy(tdefl_sym_freq *A, int n)
{
int root, leaf, next, avbl, used, dpth;
if (n==0) return; else if (n==1) { A[0].m_key = 1; return; }
A[0].m_key += A[1].m_key; root = 0; leaf = 2;
for (next=1; next < n-1; next++)
{
if (leaf>=n || A[root].m_key<A[leaf].m_key) { A[next].m_key = A[root].m_key; A[root++].m_key = (mz_uint16)next; } else A[next].m_key = A[leaf++].m_key;
if (leaf>=n || (root<next && A[root].m_key<A[leaf].m_key)) { A[next].m_key = (mz_uint16)(A[next].m_key + A[root].m_key); A[root++].m_key = (mz_uint16)next; } else A[next].m_key = (mz_uint16)(A[next].m_key + A[leaf++].m_key);
}
A[n-2].m_key = 0; for (next=n-3; next>=0; next--) A[next].m_key = A[A[next].m_key].m_key+1;
avbl = 1; used = dpth = 0; root = n-2; next = n-1;
while (avbl>0)
{
while (root>=0 && (int)A[root].m_key==dpth) { used++; root--; }
while (avbl>used) { A[next--].m_key = (mz_uint16)(dpth); avbl--; }
avbl = 2*used; dpth++; used = 0;
}
}
// Limits canonical Huffman code table's max code size.
enum { TDEFL_MAX_SUPPORTED_HUFF_CODESIZE = 32 };
static void tdefl_huffman_enforce_max_code_size(int *pNum_codes, int code_list_len, int max_code_size)
{
int i; mz_uint32 total = 0; if (code_list_len <= 1) return;
for (i = max_code_size + 1; i <= TDEFL_MAX_SUPPORTED_HUFF_CODESIZE; i++) pNum_codes[max_code_size] += pNum_codes[i];
for (i = max_code_size; i > 0; i--) total += (((mz_uint32)pNum_codes[i]) << (max_code_size - i));
while (total != (1UL << max_code_size))
{
pNum_codes[max_code_size]--;
for (i = max_code_size - 1; i > 0; i--) if (pNum_codes[i]) { pNum_codes[i]--; pNum_codes[i + 1] += 2; break; }
total--;
}
}
static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num, int table_len, int code_size_limit, int static_table)
{
int i, j, l, num_codes[1 + TDEFL_MAX_SUPPORTED_HUFF_CODESIZE]; mz_uint next_code[TDEFL_MAX_SUPPORTED_HUFF_CODESIZE + 1]; MZ_CLEAR_OBJ(num_codes);
if (static_table)
{
for (i = 0; i < table_len; i++) num_codes[d->m_huff_code_sizes[table_num][i]]++;
}
else
{
tdefl_sym_freq syms0[TDEFL_MAX_HUFF_SYMBOLS], syms1[TDEFL_MAX_HUFF_SYMBOLS], *pSyms;
int num_used_syms = 0;
const mz_uint16 *pSym_count = &d->m_huff_count[table_num][0];
for (i = 0; i < table_len; i++) if (pSym_count[i]) { syms0[num_used_syms].m_key = (mz_uint16)pSym_count[i]; syms0[num_used_syms++].m_sym_index = (mz_uint16)i; }
pSyms = tdefl_radix_sort_syms(num_used_syms, syms0, syms1); tdefl_calculate_minimum_redundancy(pSyms, num_used_syms);
for (i = 0; i < num_used_syms; i++) num_codes[pSyms[i].m_key]++;
tdefl_huffman_enforce_max_code_size(num_codes, num_used_syms, code_size_limit);
MZ_CLEAR_OBJ(d->m_huff_code_sizes[table_num]); MZ_CLEAR_OBJ(d->m_huff_codes[table_num]);
for (i = 1, j = num_used_syms; i <= code_size_limit; i++)
for (l = num_codes[i]; l > 0; l--) d->m_huff_code_sizes[table_num][pSyms[--j].m_sym_index] = (mz_uint8)(i);
}
next_code[1] = 0; for (j = 0, i = 2; i <= code_size_limit; i++) next_code[i] = j = ((j + num_codes[i - 1]) << 1);
for (i = 0; i < table_len; i++)
{
mz_uint rev_code = 0, code, code_size; if ((code_size = d->m_huff_code_sizes[table_num][i]) == 0) continue;
code = next_code[code_size]++; for (l = code_size; l > 0; l--, code >>= 1) rev_code = (rev_code << 1) | (code & 1);
d->m_huff_codes[table_num][i] = (mz_uint16)rev_code;
}
}
#define TDEFL_PUT_BITS(b, l) do { \
mz_uint bits = b; mz_uint len = l; MZ_ASSERT(bits <= ((1U << len) - 1U)); \
d->m_bit_buffer |= (bits << d->m_bits_in); d->m_bits_in += len; \
while (d->m_bits_in >= 8) { \
if (d->m_pOutput_buf < d->m_pOutput_buf_end) \
*d->m_pOutput_buf++ = (mz_uint8)(d->m_bit_buffer); \
d->m_bit_buffer >>= 8; \
d->m_bits_in -= 8; \
} \
} MZ_MACRO_END
#define TDEFL_RLE_PREV_CODE_SIZE() { if (rle_repeat_count) { \
if (rle_repeat_count < 3) { \
d->m_huff_count[2][prev_code_size] = (mz_uint16)(d->m_huff_count[2][prev_code_size] + rle_repeat_count); \
while (rle_repeat_count--) packed_code_sizes[num_packed_code_sizes++] = prev_code_size; \
} else { \
d->m_huff_count[2][16] = (mz_uint16)(d->m_huff_count[2][16] + 1); packed_code_sizes[num_packed_code_sizes++] = 16; packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_repeat_count - 3); \
} rle_repeat_count = 0; } }
#define TDEFL_RLE_ZERO_CODE_SIZE() { if (rle_z_count) { \
if (rle_z_count < 3) { \
d->m_huff_count[2][0] = (mz_uint16)(d->m_huff_count[2][0] + rle_z_count); while (rle_z_count--) packed_code_sizes[num_packed_code_sizes++] = 0; \
} else if (rle_z_count <= 10) { \
d->m_huff_count[2][17] = (mz_uint16)(d->m_huff_count[2][17] + 1); packed_code_sizes[num_packed_code_sizes++] = 17; packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 3); \
} else { \
d->m_huff_count[2][18] = (mz_uint16)(d->m_huff_count[2][18] + 1); packed_code_sizes[num_packed_code_sizes++] = 18; packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 11); \
} rle_z_count = 0; } }
static mz_uint8 s_tdefl_packed_code_size_syms_swizzle[] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
static void tdefl_start_dynamic_block(tdefl_compressor *d)
{
int num_lit_codes, num_dist_codes, num_bit_lengths; mz_uint i, total_code_sizes_to_pack, num_packed_code_sizes, rle_z_count, rle_repeat_count, packed_code_sizes_index;
mz_uint8 code_sizes_to_pack[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], packed_code_sizes[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], prev_code_size = 0xFF;
d->m_huff_count[0][256] = 1;
tdefl_optimize_huffman_table(d, 0, TDEFL_MAX_HUFF_SYMBOLS_0, 15, MZ_FALSE);
tdefl_optimize_huffman_table(d, 1, TDEFL_MAX_HUFF_SYMBOLS_1, 15, MZ_FALSE);
for (num_lit_codes = 286; num_lit_codes > 257; num_lit_codes--) if (d->m_huff_code_sizes[0][num_lit_codes - 1]) break;
for (num_dist_codes = 30; num_dist_codes > 1; num_dist_codes--) if (d->m_huff_code_sizes[1][num_dist_codes - 1]) break;
memcpy(code_sizes_to_pack, &d->m_huff_code_sizes[0][0], num_lit_codes);
memcpy(code_sizes_to_pack + num_lit_codes, &d->m_huff_code_sizes[1][0], num_dist_codes);
total_code_sizes_to_pack = num_lit_codes + num_dist_codes; num_packed_code_sizes = 0; rle_z_count = 0; rle_repeat_count = 0;
memset(&d->m_huff_count[2][0], 0, sizeof(d->m_huff_count[2][0]) * TDEFL_MAX_HUFF_SYMBOLS_2);
for (i = 0; i < total_code_sizes_to_pack; i++)
{
mz_uint8 code_size = code_sizes_to_pack[i];
if (!code_size)
{
TDEFL_RLE_PREV_CODE_SIZE();
if (++rle_z_count == 138) { TDEFL_RLE_ZERO_CODE_SIZE(); }
}
else
{
TDEFL_RLE_ZERO_CODE_SIZE();
if (code_size != prev_code_size)
{
TDEFL_RLE_PREV_CODE_SIZE();
d->m_huff_count[2][code_size] = (mz_uint16)(d->m_huff_count[2][code_size] + 1); packed_code_sizes[num_packed_code_sizes++] = code_size;
}
else if (++rle_repeat_count == 6)
{
TDEFL_RLE_PREV_CODE_SIZE();
}
}
prev_code_size = code_size;
}
if (rle_repeat_count) { TDEFL_RLE_PREV_CODE_SIZE(); } else { TDEFL_RLE_ZERO_CODE_SIZE(); }
tdefl_optimize_huffman_table(d, 2, TDEFL_MAX_HUFF_SYMBOLS_2, 7, MZ_FALSE);
TDEFL_PUT_BITS(2, 2);
TDEFL_PUT_BITS(num_lit_codes - 257, 5);
TDEFL_PUT_BITS(num_dist_codes - 1, 5);
for (num_bit_lengths = 18; num_bit_lengths >= 0; num_bit_lengths--) if (d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[num_bit_lengths]]) break;
num_bit_lengths = MZ_MAX(4, (num_bit_lengths + 1)); TDEFL_PUT_BITS(num_bit_lengths - 4, 4);
for (i = 0; (int)i < num_bit_lengths; i++) TDEFL_PUT_BITS(d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[i]], 3);
for (packed_code_sizes_index = 0; packed_code_sizes_index < num_packed_code_sizes; )
{
mz_uint code = packed_code_sizes[packed_code_sizes_index++]; MZ_ASSERT(code < TDEFL_MAX_HUFF_SYMBOLS_2);
TDEFL_PUT_BITS(d->m_huff_codes[2][code], d->m_huff_code_sizes[2][code]);
if (code >= 16) TDEFL_PUT_BITS(packed_code_sizes[packed_code_sizes_index++], "\02\03\07"[code - 16]);
}
}
static void tdefl_start_static_block(tdefl_compressor *d)
{
mz_uint i;
mz_uint8 *p = &d->m_huff_code_sizes[0][0];
for (i = 0; i <= 143; ++i) *p++ = 8;
for ( ; i <= 255; ++i) *p++ = 9;
for ( ; i <= 279; ++i) *p++ = 7;
for ( ; i <= 287; ++i) *p++ = 8;
memset(d->m_huff_code_sizes[1], 5, 32);
tdefl_optimize_huffman_table(d, 0, 288, 15, MZ_TRUE);
tdefl_optimize_huffman_table(d, 1, 32, 15, MZ_TRUE);
TDEFL_PUT_BITS(1, 2);
}
static const mz_uint mz_bitmasks[17] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF };
#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS
static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d)
{
mz_uint flags;
mz_uint8 *pLZ_codes;
mz_uint8 *pOutput_buf = d->m_pOutput_buf;
mz_uint8 *pLZ_code_buf_end = d->m_pLZ_code_buf;
mz_uint64 bit_buffer = d->m_bit_buffer;
mz_uint bits_in = d->m_bits_in;
#define TDEFL_PUT_BITS_FAST(b, l) { bit_buffer |= (((mz_uint64)(b)) << bits_in); bits_in += (l); }
flags = 1;
for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < pLZ_code_buf_end; flags >>= 1)
{
if (flags == 1)
flags = *pLZ_codes++ | 0x100;
if (flags & 1)
{
mz_uint s0, s1, n0, n1, sym, num_extra_bits;
mz_uint match_len = pLZ_codes[0], match_dist = *(const mz_uint16 *)(pLZ_codes + 1); pLZ_codes += 3;
MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
TDEFL_PUT_BITS_FAST(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]);
// This sequence coaxes MSVC into using cmov's vs. jmp's.
s0 = s_tdefl_small_dist_sym[match_dist & 511];
n0 = s_tdefl_small_dist_extra[match_dist & 511];
s1 = s_tdefl_large_dist_sym[match_dist >> 8];
n1 = s_tdefl_large_dist_extra[match_dist >> 8];
sym = (match_dist < 512) ? s0 : s1;
num_extra_bits = (match_dist < 512) ? n0 : n1;
MZ_ASSERT(d->m_huff_code_sizes[1][sym]);
TDEFL_PUT_BITS_FAST(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]);
TDEFL_PUT_BITS_FAST(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits);
}
else
{
mz_uint lit = *pLZ_codes++;
MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end))
{
flags >>= 1;
lit = *pLZ_codes++;
MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end))
{
flags >>= 1;
lit = *pLZ_codes++;
MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
}
}
}
if (pOutput_buf >= d->m_pOutput_buf_end)
return MZ_FALSE;
*(mz_uint64*)pOutput_buf = bit_buffer;
pOutput_buf += (bits_in >> 3);
bit_buffer >>= (bits_in & ~7);
bits_in &= 7;
}
#undef TDEFL_PUT_BITS_FAST
d->m_pOutput_buf = pOutput_buf;
d->m_bits_in = 0;
d->m_bit_buffer = 0;
while (bits_in)
{
mz_uint32 n = MZ_MIN(bits_in, 16);
TDEFL_PUT_BITS((mz_uint)bit_buffer & mz_bitmasks[n], n);
bit_buffer >>= n;
bits_in -= n;
}
TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]);
return (d->m_pOutput_buf < d->m_pOutput_buf_end);
}
#else
static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d)
{
mz_uint flags;
mz_uint8 *pLZ_codes;
flags = 1;
for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < d->m_pLZ_code_buf; flags >>= 1)
{
if (flags == 1)
flags = *pLZ_codes++ | 0x100;
if (flags & 1)
{
mz_uint sym, num_extra_bits;
mz_uint match_len = pLZ_codes[0], match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8)); pLZ_codes += 3;
MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
TDEFL_PUT_BITS(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
TDEFL_PUT_BITS(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]);
if (match_dist < 512)
{
sym = s_tdefl_small_dist_sym[match_dist]; num_extra_bits = s_tdefl_small_dist_extra[match_dist];
}
else
{
sym = s_tdefl_large_dist_sym[match_dist >> 8]; num_extra_bits = s_tdefl_large_dist_extra[match_dist >> 8];
}
MZ_ASSERT(d->m_huff_code_sizes[1][sym]);
TDEFL_PUT_BITS(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]);
TDEFL_PUT_BITS(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits);
}
else
{
mz_uint lit = *pLZ_codes++;
MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
TDEFL_PUT_BITS(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
}
}
TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]);
return (d->m_pOutput_buf < d->m_pOutput_buf_end);
}
#endif // MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS
static mz_bool tdefl_compress_block(tdefl_compressor *d, mz_bool static_block)
{
if (static_block)
tdefl_start_static_block(d);
else
tdefl_start_dynamic_block(d);
return tdefl_compress_lz_codes(d);
}
static int tdefl_flush_block(tdefl_compressor *d, int flush)
{
mz_uint saved_bit_buf, saved_bits_in;
mz_uint8 *pSaved_output_buf;
mz_bool comp_block_succeeded = MZ_FALSE;
int n, use_raw_block = ((d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS) != 0) && (d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size;
mz_uint8 *pOutput_buf_start = ((d->m_pPut_buf_func == NULL) && ((*d->m_pOut_buf_size - d->m_out_buf_ofs) >= TDEFL_OUT_BUF_SIZE)) ? ((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs) : d->m_output_buf;
d->m_pOutput_buf = pOutput_buf_start;
d->m_pOutput_buf_end = d->m_pOutput_buf + TDEFL_OUT_BUF_SIZE - 16;
MZ_ASSERT(!d->m_output_flush_remaining);
d->m_output_flush_ofs = 0;
d->m_output_flush_remaining = 0;
*d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> d->m_num_flags_left);
d->m_pLZ_code_buf -= (d->m_num_flags_left == 8);
if ((d->m_flags & TDEFL_WRITE_ZLIB_HEADER) && (!d->m_block_index))
{
TDEFL_PUT_BITS(0x78, 8); TDEFL_PUT_BITS(0x01, 8);
}
TDEFL_PUT_BITS(flush == TDEFL_FINISH, 1);
pSaved_output_buf = d->m_pOutput_buf; saved_bit_buf = d->m_bit_buffer; saved_bits_in = d->m_bits_in;
if (!use_raw_block)
comp_block_succeeded = tdefl_compress_block(d, (d->m_flags & TDEFL_FORCE_ALL_STATIC_BLOCKS) || (d->m_total_lz_bytes < 48));
// If the block gets expanded, forget the current contents of the output buffer and send a raw block instead.
if ( ((use_raw_block) || ((d->m_total_lz_bytes) && ((d->m_pOutput_buf - pSaved_output_buf + 1U) >= d->m_total_lz_bytes))) &&
((d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size) )
{
mz_uint i; d->m_pOutput_buf = pSaved_output_buf; d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in;
TDEFL_PUT_BITS(0, 2);
if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); }
for (i = 2; i; --i, d->m_total_lz_bytes ^= 0xFFFF)
{
TDEFL_PUT_BITS(d->m_total_lz_bytes & 0xFFFF, 16);
}
for (i = 0; i < d->m_total_lz_bytes; ++i)
{
TDEFL_PUT_BITS(d->m_dict[(d->m_lz_code_buf_dict_pos + i) & TDEFL_LZ_DICT_SIZE_MASK], 8);
}
}
// Check for the extremely unlikely (if not impossible) case of the compressed block not fitting into the output buffer when using dynamic codes.
else if (!comp_block_succeeded)
{
d->m_pOutput_buf = pSaved_output_buf; d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in;
tdefl_compress_block(d, MZ_TRUE);
}
if (flush)
{
if (flush == TDEFL_FINISH)
{
if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); }
if (d->m_flags & TDEFL_WRITE_ZLIB_HEADER) { mz_uint i, a = d->m_adler32; for (i = 0; i < 4; i++) { TDEFL_PUT_BITS((a >> 24) & 0xFF, 8); a <<= 8; } }
}
else
{
mz_uint i, z = 0; TDEFL_PUT_BITS(0, 3); if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); } for (i = 2; i; --i, z ^= 0xFFFF) { TDEFL_PUT_BITS(z & 0xFFFF, 16); }
}
}
MZ_ASSERT(d->m_pOutput_buf < d->m_pOutput_buf_end);
memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0);
memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1);
d->m_pLZ_code_buf = d->m_lz_code_buf + 1; d->m_pLZ_flags = d->m_lz_code_buf; d->m_num_flags_left = 8; d->m_lz_code_buf_dict_pos += d->m_total_lz_bytes; d->m_total_lz_bytes = 0; d->m_block_index++;
if ((n = (int)(d->m_pOutput_buf - pOutput_buf_start)) != 0)
{
if (d->m_pPut_buf_func)
{
*d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf;
if (!(*d->m_pPut_buf_func)(d->m_output_buf, n, d->m_pPut_buf_user))
return (d->m_prev_return_status = TDEFL_STATUS_PUT_BUF_FAILED);
}
else if (pOutput_buf_start == d->m_output_buf)
{
int bytes_to_copy = (int)MZ_MIN((size_t)n, (size_t)(*d->m_pOut_buf_size - d->m_out_buf_ofs));
memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf, bytes_to_copy);
d->m_out_buf_ofs += bytes_to_copy;
if ((n -= bytes_to_copy) != 0)
{
d->m_output_flush_ofs = bytes_to_copy;
d->m_output_flush_remaining = n;
}
}
else
{
d->m_out_buf_ofs += n;
}
}
return d->m_output_flush_remaining;
}
#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
#define TDEFL_READ_UNALIGNED_WORD(p) *(const mz_uint16*)(p)
static MZ_FORCEINLINE void tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len)
{
mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len;
mz_uint num_probes_left = d->m_max_probes[match_len >= 32];
const mz_uint16 *s = (const mz_uint16*)(d->m_dict + pos), *p, *q;
mz_uint16 c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]), s01 = TDEFL_READ_UNALIGNED_WORD(s);
MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN); if (max_match_len <= match_len) return;
for ( ; ; )
{
for ( ; ; )
{
if (--num_probes_left == 0) return;
#define TDEFL_PROBE \
next_probe_pos = d->m_next[probe_pos]; \
if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) return; \
probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \
if (TDEFL_READ_UNALIGNED_WORD(&d->m_dict[probe_pos + match_len - 1]) == c01) break;
TDEFL_PROBE; TDEFL_PROBE; TDEFL_PROBE;
}
if (!dist) break; q = (const mz_uint16*)(d->m_dict + probe_pos); if (TDEFL_READ_UNALIGNED_WORD(q) != s01) continue; p = s; probe_len = 32;
do { } while ( (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) &&
(TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (--probe_len > 0) );
if (!probe_len)
{
*pMatch_dist = dist; *pMatch_len = MZ_MIN(max_match_len, TDEFL_MAX_MATCH_LEN); break;
}
else if ((probe_len = ((mz_uint)(p - s) * 2) + (mz_uint)(*(const mz_uint8*)p == *(const mz_uint8*)q)) > match_len)
{
*pMatch_dist = dist; if ((*pMatch_len = match_len = MZ_MIN(max_match_len, probe_len)) == max_match_len) break;
c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]);
}
}
}
#else
static MZ_FORCEINLINE void tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len)
{
mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len;
mz_uint num_probes_left = d->m_max_probes[match_len >= 32];
const mz_uint8 *s = d->m_dict + pos, *p, *q;
mz_uint8 c0 = d->m_dict[pos + match_len], c1 = d->m_dict[pos + match_len - 1];
MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN); if (max_match_len <= match_len) return;
for ( ; ; )
{
for ( ; ; )
{
if (--num_probes_left == 0) return;
#define TDEFL_PROBE \
next_probe_pos = d->m_next[probe_pos]; \
if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) return; \
probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \
if ((d->m_dict[probe_pos + match_len] == c0) && (d->m_dict[probe_pos + match_len - 1] == c1)) break;
TDEFL_PROBE; TDEFL_PROBE; TDEFL_PROBE;
}
if (!dist) break; p = s; q = d->m_dict + probe_pos; for (probe_len = 0; probe_len < max_match_len; probe_len++) if (*p++ != *q++) break;
if (probe_len > match_len)
{
*pMatch_dist = dist; if ((*pMatch_len = match_len = probe_len) == max_match_len) return;
c0 = d->m_dict[pos + match_len]; c1 = d->m_dict[pos + match_len - 1];
}
}
}
#endif // #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
static mz_bool tdefl_compress_fast(tdefl_compressor *d)
{
// Faster, minimally featured LZRW1-style match+parse loop with better register utilization. Intended for applications where raw throughput is valued more highly than ratio.
mz_uint lookahead_pos = d->m_lookahead_pos, lookahead_size = d->m_lookahead_size, dict_size = d->m_dict_size, total_lz_bytes = d->m_total_lz_bytes, num_flags_left = d->m_num_flags_left;
mz_uint8 *pLZ_code_buf = d->m_pLZ_code_buf, *pLZ_flags = d->m_pLZ_flags;
mz_uint cur_pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK;
while ((d->m_src_buf_left) || ((d->m_flush) && (lookahead_size)))
{
const mz_uint TDEFL_COMP_FAST_LOOKAHEAD_SIZE = 4096;
mz_uint dst_pos = (lookahead_pos + lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK;
mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(d->m_src_buf_left, TDEFL_COMP_FAST_LOOKAHEAD_SIZE - lookahead_size);
d->m_src_buf_left -= num_bytes_to_process;
lookahead_size += num_bytes_to_process;
while (num_bytes_to_process)
{
mz_uint32 n = MZ_MIN(TDEFL_LZ_DICT_SIZE - dst_pos, num_bytes_to_process);
memcpy(d->m_dict + dst_pos, d->m_pSrc, n);
if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
memcpy(d->m_dict + TDEFL_LZ_DICT_SIZE + dst_pos, d->m_pSrc, MZ_MIN(n, (TDEFL_MAX_MATCH_LEN - 1) - dst_pos));
d->m_pSrc += n;
dst_pos = (dst_pos + n) & TDEFL_LZ_DICT_SIZE_MASK;
num_bytes_to_process -= n;
}
dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - lookahead_size, dict_size);
if ((!d->m_flush) && (lookahead_size < TDEFL_COMP_FAST_LOOKAHEAD_SIZE)) break;
while (lookahead_size >= 4)
{
mz_uint cur_match_dist, cur_match_len = 1;
mz_uint8 *pCur_dict = d->m_dict + cur_pos;
mz_uint first_trigram = (*(const mz_uint32 *)pCur_dict) & 0xFFFFFF;
mz_uint hash = (first_trigram ^ (first_trigram >> (24 - (TDEFL_LZ_HASH_BITS - 8)))) & TDEFL_LEVEL1_HASH_SIZE_MASK;
mz_uint probe_pos = d->m_hash[hash];
d->m_hash[hash] = (mz_uint16)lookahead_pos;
if (((cur_match_dist = (mz_uint16)(lookahead_pos - probe_pos)) <= dict_size) && ((*(const mz_uint32 *)(d->m_dict + (probe_pos &= TDEFL_LZ_DICT_SIZE_MASK)) & 0xFFFFFF) == first_trigram))
{
const mz_uint16 *p = (const mz_uint16 *)pCur_dict;
const mz_uint16 *q = (const mz_uint16 *)(d->m_dict + probe_pos);
mz_uint32 probe_len = 32;
do { } while ( (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) &&
(TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (--probe_len > 0) );
cur_match_len = ((mz_uint)(p - (const mz_uint16 *)pCur_dict) * 2) + (mz_uint)(*(const mz_uint8 *)p == *(const mz_uint8 *)q);
if (!probe_len)
cur_match_len = cur_match_dist ? TDEFL_MAX_MATCH_LEN : 0;
if ((cur_match_len < TDEFL_MIN_MATCH_LEN) || ((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U*1024U)))
{
cur_match_len = 1;
*pLZ_code_buf++ = (mz_uint8)first_trigram;
*pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
d->m_huff_count[0][(mz_uint8)first_trigram]++;
}
else
{
mz_uint32 s0, s1;
cur_match_len = MZ_MIN(cur_match_len, lookahead_size);
MZ_ASSERT((cur_match_len >= TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 1) && (cur_match_dist <= TDEFL_LZ_DICT_SIZE));
cur_match_dist--;
pLZ_code_buf[0] = (mz_uint8)(cur_match_len - TDEFL_MIN_MATCH_LEN);
*(mz_uint16 *)(&pLZ_code_buf[1]) = (mz_uint16)cur_match_dist;
pLZ_code_buf += 3;
*pLZ_flags = (mz_uint8)((*pLZ_flags >> 1) | 0x80);
s0 = s_tdefl_small_dist_sym[cur_match_dist & 511];
s1 = s_tdefl_large_dist_sym[cur_match_dist >> 8];
d->m_huff_count[1][(cur_match_dist < 512) ? s0 : s1]++;
d->m_huff_count[0][s_tdefl_len_sym[cur_match_len - TDEFL_MIN_MATCH_LEN]]++;
}
}
else
{
*pLZ_code_buf++ = (mz_uint8)first_trigram;
*pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
d->m_huff_count[0][(mz_uint8)first_trigram]++;
}
if (--num_flags_left == 0) { num_flags_left = 8; pLZ_flags = pLZ_code_buf++; }
total_lz_bytes += cur_match_len;
lookahead_pos += cur_match_len;
dict_size = MZ_MIN(dict_size + cur_match_len, TDEFL_LZ_DICT_SIZE);
cur_pos = (cur_pos + cur_match_len) & TDEFL_LZ_DICT_SIZE_MASK;
MZ_ASSERT(lookahead_size >= cur_match_len);
lookahead_size -= cur_match_len;
if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8])
{
int n;
d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size;
d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left;
if ((n = tdefl_flush_block(d, 0)) != 0)
return (n < 0) ? MZ_FALSE : MZ_TRUE;
total_lz_bytes = d->m_total_lz_bytes; pLZ_code_buf = d->m_pLZ_code_buf; pLZ_flags = d->m_pLZ_flags; num_flags_left = d->m_num_flags_left;
}
}
while (lookahead_size)
{
mz_uint8 lit = d->m_dict[cur_pos];
total_lz_bytes++;
*pLZ_code_buf++ = lit;
*pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
if (--num_flags_left == 0) { num_flags_left = 8; pLZ_flags = pLZ_code_buf++; }
d->m_huff_count[0][lit]++;
lookahead_pos++;
dict_size = MZ_MIN(dict_size + 1, TDEFL_LZ_DICT_SIZE);
cur_pos = (cur_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK;
lookahead_size--;
if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8])
{
int n;
d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size;
d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left;
if ((n = tdefl_flush_block(d, 0)) != 0)
return (n < 0) ? MZ_FALSE : MZ_TRUE;
total_lz_bytes = d->m_total_lz_bytes; pLZ_code_buf = d->m_pLZ_code_buf; pLZ_flags = d->m_pLZ_flags; num_flags_left = d->m_num_flags_left;
}
}
}
d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size;
d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left;
return MZ_TRUE;
}
#endif // MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
static MZ_FORCEINLINE void tdefl_record_literal(tdefl_compressor *d, mz_uint8 lit)
{
d->m_total_lz_bytes++;
*d->m_pLZ_code_buf++ = lit;
*d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> 1); if (--d->m_num_flags_left == 0) { d->m_num_flags_left = 8; d->m_pLZ_flags = d->m_pLZ_code_buf++; }
d->m_huff_count[0][lit]++;
}
static MZ_FORCEINLINE void tdefl_record_match(tdefl_compressor *d, mz_uint match_len, mz_uint match_dist)
{
mz_uint32 s0, s1;
MZ_ASSERT((match_len >= TDEFL_MIN_MATCH_LEN) && (match_dist >= 1) && (match_dist <= TDEFL_LZ_DICT_SIZE));
d->m_total_lz_bytes += match_len;
d->m_pLZ_code_buf[0] = (mz_uint8)(match_len - TDEFL_MIN_MATCH_LEN);
match_dist -= 1;
d->m_pLZ_code_buf[1] = (mz_uint8)(match_dist & 0xFF);
d->m_pLZ_code_buf[2] = (mz_uint8)(match_dist >> 8); d->m_pLZ_code_buf += 3;
*d->m_pLZ_flags = (mz_uint8)((*d->m_pLZ_flags >> 1) | 0x80); if (--d->m_num_flags_left == 0) { d->m_num_flags_left = 8; d->m_pLZ_flags = d->m_pLZ_code_buf++; }
s0 = s_tdefl_small_dist_sym[match_dist & 511]; s1 = s_tdefl_large_dist_sym[(match_dist >> 8) & 127];
d->m_huff_count[1][(match_dist < 512) ? s0 : s1]++;
if (match_len >= TDEFL_MIN_MATCH_LEN) d->m_huff_count[0][s_tdefl_len_sym[match_len - TDEFL_MIN_MATCH_LEN]]++;
}
static mz_bool tdefl_compress_normal(tdefl_compressor *d)
{
const mz_uint8 *pSrc = d->m_pSrc; size_t src_buf_left = d->m_src_buf_left;
tdefl_flush flush = d->m_flush;
while ((src_buf_left) || ((flush) && (d->m_lookahead_size)))
{
mz_uint len_to_move, cur_match_dist, cur_match_len, cur_pos;
// Update dictionary and hash chains. Keeps the lookahead size equal to TDEFL_MAX_MATCH_LEN.
if ((d->m_lookahead_size + d->m_dict_size) >= (TDEFL_MIN_MATCH_LEN - 1))
{
mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK, ins_pos = d->m_lookahead_pos + d->m_lookahead_size - 2;
mz_uint hash = (d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK];
mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(src_buf_left, TDEFL_MAX_MATCH_LEN - d->m_lookahead_size);
const mz_uint8 *pSrc_end = pSrc + num_bytes_to_process;
src_buf_left -= num_bytes_to_process;
d->m_lookahead_size += num_bytes_to_process;
while (pSrc != pSrc_end)
{
mz_uint8 c = *pSrc++; d->m_dict[dst_pos] = c; if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c;
hash = ((hash << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1);
d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash]; d->m_hash[hash] = (mz_uint16)(ins_pos);
dst_pos = (dst_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK; ins_pos++;
}
}
else
{
while ((src_buf_left) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN))
{
mz_uint8 c = *pSrc++;
mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK;
src_buf_left--;
d->m_dict[dst_pos] = c;
if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c;
if ((++d->m_lookahead_size + d->m_dict_size) >= TDEFL_MIN_MATCH_LEN)
{
mz_uint ins_pos = d->m_lookahead_pos + (d->m_lookahead_size - 1) - 2;
mz_uint hash = ((d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << (TDEFL_LZ_HASH_SHIFT * 2)) ^ (d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1);
d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash]; d->m_hash[hash] = (mz_uint16)(ins_pos);
}
}
}
d->m_dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - d->m_lookahead_size, d->m_dict_size);
if ((!flush) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN))
break;
// Simple lazy/greedy parsing state machine.
len_to_move = 1; cur_match_dist = 0; cur_match_len = d->m_saved_match_len ? d->m_saved_match_len : (TDEFL_MIN_MATCH_LEN - 1); cur_pos = d->m_lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK;
if (d->m_flags & (TDEFL_RLE_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS))
{
if ((d->m_dict_size) && (!(d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS)))
{
mz_uint8 c = d->m_dict[(cur_pos - 1) & TDEFL_LZ_DICT_SIZE_MASK];
cur_match_len = 0; while (cur_match_len < d->m_lookahead_size) { if (d->m_dict[cur_pos + cur_match_len] != c) break; cur_match_len++; }
if (cur_match_len < TDEFL_MIN_MATCH_LEN) cur_match_len = 0; else cur_match_dist = 1;
}
}
else
{
tdefl_find_match(d, d->m_lookahead_pos, d->m_dict_size, d->m_lookahead_size, &cur_match_dist, &cur_match_len);
}
if (((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U*1024U)) || (cur_pos == cur_match_dist) || ((d->m_flags & TDEFL_FILTER_MATCHES) && (cur_match_len <= 5)))
{
cur_match_dist = cur_match_len = 0;
}
if (d->m_saved_match_len)
{
if (cur_match_len > d->m_saved_match_len)
{
tdefl_record_literal(d, (mz_uint8)d->m_saved_lit);
if (cur_match_len >= 128)
{
tdefl_record_match(d, cur_match_len, cur_match_dist);
d->m_saved_match_len = 0; len_to_move = cur_match_len;
}
else
{
d->m_saved_lit = d->m_dict[cur_pos]; d->m_saved_match_dist = cur_match_dist; d->m_saved_match_len = cur_match_len;
}
}
else
{
tdefl_record_match(d, d->m_saved_match_len, d->m_saved_match_dist);
len_to_move = d->m_saved_match_len - 1; d->m_saved_match_len = 0;
}
}
else if (!cur_match_dist)
tdefl_record_literal(d, d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)]);
else if ((d->m_greedy_parsing) || (d->m_flags & TDEFL_RLE_MATCHES) || (cur_match_len >= 128))
{
tdefl_record_match(d, cur_match_len, cur_match_dist);
len_to_move = cur_match_len;
}
else
{
d->m_saved_lit = d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)]; d->m_saved_match_dist = cur_match_dist; d->m_saved_match_len = cur_match_len;
}
// Move the lookahead forward by len_to_move bytes.
d->m_lookahead_pos += len_to_move;
MZ_ASSERT(d->m_lookahead_size >= len_to_move);
d->m_lookahead_size -= len_to_move;
d->m_dict_size = MZ_MIN(d->m_dict_size + len_to_move, TDEFL_LZ_DICT_SIZE);
// Check if it's time to flush the current LZ codes to the internal output buffer.
if ( (d->m_pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) ||
( (d->m_total_lz_bytes > 31*1024) && (((((mz_uint)(d->m_pLZ_code_buf - d->m_lz_code_buf) * 115) >> 7) >= d->m_total_lz_bytes) || (d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS))) )
{
int n;
d->m_pSrc = pSrc; d->m_src_buf_left = src_buf_left;
if ((n = tdefl_flush_block(d, 0)) != 0)
return (n < 0) ? MZ_FALSE : MZ_TRUE;
}
}
d->m_pSrc = pSrc; d->m_src_buf_left = src_buf_left;
return MZ_TRUE;
}
static tdefl_status tdefl_flush_output_buffer(tdefl_compressor *d)
{
if (d->m_pIn_buf_size)
{
*d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf;
}
if (d->m_pOut_buf_size)
{
size_t n = MZ_MIN(*d->m_pOut_buf_size - d->m_out_buf_ofs, d->m_output_flush_remaining);
memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf + d->m_output_flush_ofs, n);
d->m_output_flush_ofs += (mz_uint)n;
d->m_output_flush_remaining -= (mz_uint)n;
d->m_out_buf_ofs += n;
*d->m_pOut_buf_size = d->m_out_buf_ofs;
}
return (d->m_finished && !d->m_output_flush_remaining) ? TDEFL_STATUS_DONE : TDEFL_STATUS_OKAY;
}
tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush)
{
if (!d)
{
if (pIn_buf_size) *pIn_buf_size = 0;
if (pOut_buf_size) *pOut_buf_size = 0;
return TDEFL_STATUS_BAD_PARAM;
}
d->m_pIn_buf = pIn_buf; d->m_pIn_buf_size = pIn_buf_size;
d->m_pOut_buf = pOut_buf; d->m_pOut_buf_size = pOut_buf_size;
d->m_pSrc = (const mz_uint8 *)(pIn_buf); d->m_src_buf_left = pIn_buf_size ? *pIn_buf_size : 0;
d->m_out_buf_ofs = 0;
d->m_flush = flush;
if ( ((d->m_pPut_buf_func != NULL) == ((pOut_buf != NULL) || (pOut_buf_size != NULL))) || (d->m_prev_return_status != TDEFL_STATUS_OKAY) ||
(d->m_wants_to_finish && (flush != TDEFL_FINISH)) || (pIn_buf_size && *pIn_buf_size && !pIn_buf) || (pOut_buf_size && *pOut_buf_size && !pOut_buf) )
{
if (pIn_buf_size) *pIn_buf_size = 0;
if (pOut_buf_size) *pOut_buf_size = 0;
return (d->m_prev_return_status = TDEFL_STATUS_BAD_PARAM);
}
d->m_wants_to_finish |= (flush == TDEFL_FINISH);
if ((d->m_output_flush_remaining) || (d->m_finished))
return (d->m_prev_return_status = tdefl_flush_output_buffer(d));
#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
if (((d->m_flags & TDEFL_MAX_PROBES_MASK) == 1) &&
((d->m_flags & TDEFL_GREEDY_PARSING_FLAG) != 0) &&
((d->m_flags & (TDEFL_FILTER_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS | TDEFL_RLE_MATCHES)) == 0))
{
if (!tdefl_compress_fast(d))
return d->m_prev_return_status;
}
else
#endif // #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
{
if (!tdefl_compress_normal(d))
return d->m_prev_return_status;
}
if ((d->m_flags & (TDEFL_WRITE_ZLIB_HEADER | TDEFL_COMPUTE_ADLER32)) && (pIn_buf))
d->m_adler32 = (mz_uint32)mz_adler32(d->m_adler32, (const mz_uint8 *)pIn_buf, d->m_pSrc - (const mz_uint8 *)pIn_buf);
if ((flush) && (!d->m_lookahead_size) && (!d->m_src_buf_left) && (!d->m_output_flush_remaining))
{
if (tdefl_flush_block(d, flush) < 0)
return d->m_prev_return_status;
d->m_finished = (flush == TDEFL_FINISH);
if (flush == TDEFL_FULL_FLUSH) { MZ_CLEAR_OBJ(d->m_hash); MZ_CLEAR_OBJ(d->m_next); d->m_dict_size = 0; }
}
return (d->m_prev_return_status = tdefl_flush_output_buffer(d));
}
tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush)
{
MZ_ASSERT(d->m_pPut_buf_func); return tdefl_compress(d, pIn_buf, &in_buf_size, NULL, NULL, flush);
}
tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags)
{
d->m_pPut_buf_func = pPut_buf_func; d->m_pPut_buf_user = pPut_buf_user;
d->m_flags = (mz_uint)(flags); d->m_max_probes[0] = 1 + ((flags & 0xFFF) + 2) / 3; d->m_greedy_parsing = (flags & TDEFL_GREEDY_PARSING_FLAG) != 0;
d->m_max_probes[1] = 1 + (((flags & 0xFFF) >> 2) + 2) / 3;
if (!(flags & TDEFL_NONDETERMINISTIC_PARSING_FLAG)) MZ_CLEAR_OBJ(d->m_hash);
d->m_lookahead_pos = d->m_lookahead_size = d->m_dict_size = d->m_total_lz_bytes = d->m_lz_code_buf_dict_pos = d->m_bits_in = 0;
d->m_output_flush_ofs = d->m_output_flush_remaining = d->m_finished = d->m_block_index = d->m_bit_buffer = d->m_wants_to_finish = 0;
d->m_pLZ_code_buf = d->m_lz_code_buf + 1; d->m_pLZ_flags = d->m_lz_code_buf; d->m_num_flags_left = 8;
d->m_pOutput_buf = d->m_output_buf; d->m_pOutput_buf_end = d->m_output_buf; d->m_prev_return_status = TDEFL_STATUS_OKAY;
d->m_saved_match_dist = d->m_saved_match_len = d->m_saved_lit = 0; d->m_adler32 = 1;
d->m_pIn_buf = NULL; d->m_pOut_buf = NULL;
d->m_pIn_buf_size = NULL; d->m_pOut_buf_size = NULL;
d->m_flush = TDEFL_NO_FLUSH; d->m_pSrc = NULL; d->m_src_buf_left = 0; d->m_out_buf_ofs = 0;
memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0);
memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1);
return TDEFL_STATUS_OKAY;
}
tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d)
{
return d->m_prev_return_status;
}
mz_uint32 tdefl_get_adler32(tdefl_compressor *d)
{
return d->m_adler32;
}
mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags)
{
tdefl_compressor *pComp; mz_bool succeeded; if (((buf_len) && (!pBuf)) || (!pPut_buf_func)) return MZ_FALSE;
pComp = (tdefl_compressor*)MZ_MALLOC(sizeof(tdefl_compressor)); if (!pComp) return MZ_FALSE;
succeeded = (tdefl_init(pComp, pPut_buf_func, pPut_buf_user, flags) == TDEFL_STATUS_OKAY);
succeeded = succeeded && (tdefl_compress_buffer(pComp, pBuf, buf_len, TDEFL_FINISH) == TDEFL_STATUS_DONE);
MZ_FREE(pComp); return succeeded;
}
typedef struct
{
size_t m_size, m_capacity;
mz_uint8 *m_pBuf;
mz_bool m_expandable;
} tdefl_output_buffer;
static mz_bool tdefl_output_buffer_putter(const void *pBuf, int len, void *pUser)
{
tdefl_output_buffer *p = (tdefl_output_buffer *)pUser;
size_t new_size = p->m_size + len;
if (new_size > p->m_capacity)
{
size_t new_capacity = p->m_capacity; mz_uint8 *pNew_buf; if (!p->m_expandable) return MZ_FALSE;
do { new_capacity = MZ_MAX(128U, new_capacity << 1U); } while (new_size > new_capacity);
pNew_buf = (mz_uint8*)MZ_REALLOC(p->m_pBuf, new_capacity); if (!pNew_buf) return MZ_FALSE;
p->m_pBuf = pNew_buf; p->m_capacity = new_capacity;
}
memcpy((mz_uint8*)p->m_pBuf + p->m_size, pBuf, len); p->m_size = new_size;
return MZ_TRUE;
}
void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags)
{
tdefl_output_buffer out_buf; MZ_CLEAR_OBJ(out_buf);
if (!pOut_len) return MZ_FALSE; else *pOut_len = 0;
out_buf.m_expandable = MZ_TRUE;
if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags)) return NULL;
*pOut_len = out_buf.m_size; return out_buf.m_pBuf;
}
size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags)
{
tdefl_output_buffer out_buf; MZ_CLEAR_OBJ(out_buf);
if (!pOut_buf) return 0;
out_buf.m_pBuf = (mz_uint8*)pOut_buf; out_buf.m_capacity = out_buf_len;
if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags)) return 0;
return out_buf.m_size;
}
#ifndef MINIZ_NO_ZLIB_APIS
static const mz_uint s_tdefl_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 };
// level may actually range from [0,10] (10 is a "hidden" max level, where we want a bit more compression and it's fine if throughput to fall off a cliff on some files).
mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy)
{
mz_uint comp_flags = s_tdefl_num_probes[(level >= 0) ? MZ_MIN(10, level) : MZ_DEFAULT_LEVEL] | ((level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0);
if (window_bits > 0) comp_flags |= TDEFL_WRITE_ZLIB_HEADER;
if (!level) comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS;
else if (strategy == MZ_FILTERED) comp_flags |= TDEFL_FILTER_MATCHES;
else if (strategy == MZ_HUFFMAN_ONLY) comp_flags &= ~TDEFL_MAX_PROBES_MASK;
else if (strategy == MZ_FIXED) comp_flags |= TDEFL_FORCE_ALL_STATIC_BLOCKS;
else if (strategy == MZ_RLE) comp_flags |= TDEFL_RLE_MATCHES;
return comp_flags;
}
#endif //MINIZ_NO_ZLIB_APIS
#ifdef _MSC_VER
#pragma warning (push)
#pragma warning (disable:4204) // nonstandard extension used : non-constant aggregate initializer (also supported by GNU C and C99, so no big deal)
#endif
// Simple PNG writer function by Alex Evans, 2011. Released into the public domain: https://gist.github.com/908299, more context at
// http://altdevblogaday.org/2011/04/06/a-smaller-jpg-encoder/.
// This is actually a modification of Alex's original code so PNG files generated by this function pass pngcheck.
void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, int num_chans, size_t *pLen_out, mz_uint level, mz_bool flip)
{
// Using a local copy of this array here in case MINIZ_NO_ZLIB_APIS was defined.
static const mz_uint s_tdefl_png_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 };
tdefl_compressor *pComp = (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor)); tdefl_output_buffer out_buf; int i, bpl = w * num_chans, y, z; mz_uint32 c; *pLen_out = 0;
if (!pComp) return NULL;
MZ_CLEAR_OBJ(out_buf); out_buf.m_expandable = MZ_TRUE; out_buf.m_capacity = 57+MZ_MAX(64, (1+bpl)*h); if (NULL == (out_buf.m_pBuf = (mz_uint8*)MZ_MALLOC(out_buf.m_capacity))) { MZ_FREE(pComp); return NULL; }
// write dummy header
for (z = 41; z; --z) tdefl_output_buffer_putter(&z, 1, &out_buf);
// compress image data
tdefl_init(pComp, tdefl_output_buffer_putter, &out_buf, s_tdefl_png_num_probes[MZ_MIN(10, level)] | TDEFL_WRITE_ZLIB_HEADER);
for (y = 0; y < h; ++y) { tdefl_compress_buffer(pComp, &z, 1, TDEFL_NO_FLUSH); tdefl_compress_buffer(pComp, (mz_uint8*)pImage + (flip ? (h - 1 - y) : y) * bpl, bpl, TDEFL_NO_FLUSH); }
if (tdefl_compress_buffer(pComp, NULL, 0, TDEFL_FINISH) != TDEFL_STATUS_DONE) { MZ_FREE(pComp); MZ_FREE(out_buf.m_pBuf); return NULL; }
// write real header
*pLen_out = out_buf.m_size-41;
{
static const mz_uint8 chans[] = {0x00, 0x00, 0x04, 0x02, 0x06};
mz_uint8 pnghdr[41]={0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
0,0,(mz_uint8)(w>>8),(mz_uint8)w,0,0,(mz_uint8)(h>>8),(mz_uint8)h,8,chans[num_chans],0,0,0,0,0,0,0,
(mz_uint8)(*pLen_out>>24),(mz_uint8)(*pLen_out>>16),(mz_uint8)(*pLen_out>>8),(mz_uint8)*pLen_out,0x49,0x44,0x41,0x54};
c=(mz_uint32)mz_crc32(MZ_CRC32_INIT,pnghdr+12,17); for (i=0; i<4; ++i, c<<=8) ((mz_uint8*)(pnghdr+29))[i]=(mz_uint8)(c>>24);
memcpy(out_buf.m_pBuf, pnghdr, 41);
}
// write footer (IDAT CRC-32, followed by IEND chunk)
if (!tdefl_output_buffer_putter("\0\0\0\0\0\0\0\0\x49\x45\x4e\x44\xae\x42\x60\x82", 16, &out_buf)) { *pLen_out = 0; MZ_FREE(pComp); MZ_FREE(out_buf.m_pBuf); return NULL; }
c = (mz_uint32)mz_crc32(MZ_CRC32_INIT,out_buf.m_pBuf+41-4, *pLen_out+4); for (i=0; i<4; ++i, c<<=8) (out_buf.m_pBuf+out_buf.m_size-16)[i] = (mz_uint8)(c >> 24);
// compute final size of file, grab compressed data buffer and return
*pLen_out += 57; MZ_FREE(pComp); return out_buf.m_pBuf;
}
void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out)
{
// Level 6 corresponds to TDEFL_DEFAULT_MAX_PROBES or MZ_DEFAULT_LEVEL (but we can't depend on MZ_DEFAULT_LEVEL being available in case the zlib API's where #defined out)
return tdefl_write_image_to_png_file_in_memory_ex(pImage, w, h, num_chans, pLen_out, 6, MZ_FALSE);
}
#ifdef _MSC_VER
#pragma warning (pop)
#endif
// ------------------- .ZIP archive reading
#ifndef MINIZ_NO_ARCHIVE_APIS
#ifdef MINIZ_NO_STDIO
#define MZ_FILE void *
#else
#include <stdio.h>
#include <sys/stat.h>
#if defined(_MSC_VER) || defined(__MINGW64__)
static FILE *mz_fopen(const char *pFilename, const char *pMode)
{
FILE* pFile = NULL;
fopen_s(&pFile, pFilename, pMode);
return pFile;
}
static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream)
{
FILE* pFile = NULL;
if (freopen_s(&pFile, pPath, pMode, pStream))
return NULL;
return pFile;
}
#ifndef MINIZ_NO_TIME
#include <sys/utime.h>
#endif
#define MZ_FILE FILE
#define MZ_FOPEN mz_fopen
#define MZ_FCLOSE fclose
#define MZ_FREAD fread
#define MZ_FWRITE fwrite
#define MZ_FTELL64 _ftelli64
#define MZ_FSEEK64 _fseeki64
#define MZ_FILE_STAT_STRUCT _stat
#define MZ_FILE_STAT _stat
#define MZ_FFLUSH fflush
#define MZ_FREOPEN mz_freopen
#define MZ_DELETE_FILE remove
#elif defined(__MINGW32__)
#ifndef MINIZ_NO_TIME
#include <sys/utime.h>
#endif
#define MZ_FILE FILE
#define MZ_FOPEN(f, m) fopen(f, m)
#define MZ_FCLOSE fclose
#define MZ_FREAD fread
#define MZ_FWRITE fwrite
#define MZ_FTELL64 ftello64
#define MZ_FSEEK64 fseeko64
#define MZ_FILE_STAT_STRUCT _stat
#define MZ_FILE_STAT _stat
#define MZ_FFLUSH fflush
#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
#define MZ_DELETE_FILE remove
#elif defined(__TINYC__)
#ifndef MINIZ_NO_TIME
#include <sys/utime.h>
#endif
#define MZ_FILE FILE
#define MZ_FOPEN(f, m) fopen(f, m)
#define MZ_FCLOSE fclose
#define MZ_FREAD fread
#define MZ_FWRITE fwrite
#define MZ_FTELL64 ftell
#define MZ_FSEEK64 fseek
#define MZ_FILE_STAT_STRUCT stat
#define MZ_FILE_STAT stat
#define MZ_FFLUSH fflush
#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
#define MZ_DELETE_FILE remove
#elif defined(__GNUC__) && _LARGEFILE64_SOURCE
#ifndef MINIZ_NO_TIME
#include <utime.h>
#endif
#define MZ_FILE FILE
#define MZ_FOPEN(f, m) fopen64(f, m)
#define MZ_FCLOSE fclose
#define MZ_FREAD fread
#define MZ_FWRITE fwrite
#define MZ_FTELL64 ftello64
#define MZ_FSEEK64 fseeko64
#define MZ_FILE_STAT_STRUCT stat64
#define MZ_FILE_STAT stat64
#define MZ_FFLUSH fflush
#define MZ_FREOPEN(p, m, s) freopen64(p, m, s)
#define MZ_DELETE_FILE remove
#else
#ifndef MINIZ_NO_TIME
#include <utime.h>
#endif
#define MZ_FILE FILE
#define MZ_FOPEN(f, m) fopen(f, m)
#define MZ_FCLOSE fclose
#define MZ_FREAD fread
#define MZ_FWRITE fwrite
#define MZ_FTELL64 ftello
#define MZ_FSEEK64 fseeko
#define MZ_FILE_STAT_STRUCT stat
#define MZ_FILE_STAT stat
#define MZ_FFLUSH fflush
#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
#define MZ_DELETE_FILE remove
#endif // #ifdef _MSC_VER
#endif // #ifdef MINIZ_NO_STDIO
#define MZ_TOLOWER(c) ((((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c))
// Various ZIP archive enums. To completely avoid cross platform compiler alignment and platform endian issues, miniz.c doesn't use structs for any of this stuff.
enum
{
// ZIP archive identifiers and record sizes
MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG = 0x06054b50, MZ_ZIP_CENTRAL_DIR_HEADER_SIG = 0x02014b50, MZ_ZIP_LOCAL_DIR_HEADER_SIG = 0x04034b50,
MZ_ZIP_LOCAL_DIR_HEADER_SIZE = 30, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE = 46, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE = 22,
// Central directory header record offsets
MZ_ZIP_CDH_SIG_OFS = 0, MZ_ZIP_CDH_VERSION_MADE_BY_OFS = 4, MZ_ZIP_CDH_VERSION_NEEDED_OFS = 6, MZ_ZIP_CDH_BIT_FLAG_OFS = 8,
MZ_ZIP_CDH_METHOD_OFS = 10, MZ_ZIP_CDH_FILE_TIME_OFS = 12, MZ_ZIP_CDH_FILE_DATE_OFS = 14, MZ_ZIP_CDH_CRC32_OFS = 16,
MZ_ZIP_CDH_COMPRESSED_SIZE_OFS = 20, MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS = 24, MZ_ZIP_CDH_FILENAME_LEN_OFS = 28, MZ_ZIP_CDH_EXTRA_LEN_OFS = 30,
MZ_ZIP_CDH_COMMENT_LEN_OFS = 32, MZ_ZIP_CDH_DISK_START_OFS = 34, MZ_ZIP_CDH_INTERNAL_ATTR_OFS = 36, MZ_ZIP_CDH_EXTERNAL_ATTR_OFS = 38, MZ_ZIP_CDH_LOCAL_HEADER_OFS = 42,
// Local directory header offsets
MZ_ZIP_LDH_SIG_OFS = 0, MZ_ZIP_LDH_VERSION_NEEDED_OFS = 4, MZ_ZIP_LDH_BIT_FLAG_OFS = 6, MZ_ZIP_LDH_METHOD_OFS = 8, MZ_ZIP_LDH_FILE_TIME_OFS = 10,
MZ_ZIP_LDH_FILE_DATE_OFS = 12, MZ_ZIP_LDH_CRC32_OFS = 14, MZ_ZIP_LDH_COMPRESSED_SIZE_OFS = 18, MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS = 22,
MZ_ZIP_LDH_FILENAME_LEN_OFS = 26, MZ_ZIP_LDH_EXTRA_LEN_OFS = 28,
// End of central directory offsets
MZ_ZIP_ECDH_SIG_OFS = 0, MZ_ZIP_ECDH_NUM_THIS_DISK_OFS = 4, MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS = 6, MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS = 8,
MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS = 10, MZ_ZIP_ECDH_CDIR_SIZE_OFS = 12, MZ_ZIP_ECDH_CDIR_OFS_OFS = 16, MZ_ZIP_ECDH_COMMENT_SIZE_OFS = 20,
};
typedef struct
{
void *m_p;
size_t m_size, m_capacity;
mz_uint m_element_size;
} mz_zip_array;
struct mz_zip_internal_state_tag
{
mz_zip_array m_central_dir;
mz_zip_array m_central_dir_offsets;
mz_zip_array m_sorted_central_dir_offsets;
MZ_FILE *m_pFile;
void *m_pMem;
size_t m_mem_size;
size_t m_mem_capacity;
};
#define MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(array_ptr, element_size) (array_ptr)->m_element_size = element_size
#define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index) ((element_type *)((array_ptr)->m_p))[index]
static MZ_FORCEINLINE void mz_zip_array_clear(mz_zip_archive *pZip, mz_zip_array *pArray)
{
pZip->m_pFree(pZip->m_pAlloc_opaque, pArray->m_p);
memset(pArray, 0, sizeof(mz_zip_array));
}
static mz_bool mz_zip_array_ensure_capacity(mz_zip_archive *pZip, mz_zip_array *pArray, size_t min_new_capacity, mz_uint growing)
{
void *pNew_p; size_t new_capacity = min_new_capacity; MZ_ASSERT(pArray->m_element_size); if (pArray->m_capacity >= min_new_capacity) return MZ_TRUE;
if (growing) { new_capacity = MZ_MAX(1, pArray->m_capacity); while (new_capacity < min_new_capacity) new_capacity *= 2; }
if (NULL == (pNew_p = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pArray->m_p, pArray->m_element_size, new_capacity))) return MZ_FALSE;
pArray->m_p = pNew_p; pArray->m_capacity = new_capacity;
return MZ_TRUE;
}
static MZ_FORCEINLINE mz_bool mz_zip_array_reserve(mz_zip_archive *pZip, mz_zip_array *pArray, size_t new_capacity, mz_uint growing)
{
if (new_capacity > pArray->m_capacity) { if (!mz_zip_array_ensure_capacity(pZip, pArray, new_capacity, growing)) return MZ_FALSE; }
return MZ_TRUE;
}
static MZ_FORCEINLINE mz_bool mz_zip_array_resize(mz_zip_archive *pZip, mz_zip_array *pArray, size_t new_size, mz_uint growing)
{
if (new_size > pArray->m_capacity) { if (!mz_zip_array_ensure_capacity(pZip, pArray, new_size, growing)) return MZ_FALSE; }
pArray->m_size = new_size;
return MZ_TRUE;
}
static MZ_FORCEINLINE mz_bool mz_zip_array_ensure_room(mz_zip_archive *pZip, mz_zip_array *pArray, size_t n)
{
return mz_zip_array_reserve(pZip, pArray, pArray->m_size + n, MZ_TRUE);
}
static MZ_FORCEINLINE mz_bool mz_zip_array_push_back(mz_zip_archive *pZip, mz_zip_array *pArray, const void *pElements, size_t n)
{
size_t orig_size = pArray->m_size; if (!mz_zip_array_resize(pZip, pArray, orig_size + n, MZ_TRUE)) return MZ_FALSE;
memcpy((mz_uint8*)pArray->m_p + orig_size * pArray->m_element_size, pElements, n * pArray->m_element_size);
return MZ_TRUE;
}
#ifndef MINIZ_NO_TIME
static time_t mz_zip_dos_to_time_t(int dos_time, int dos_date)
{
struct tm tm;
memset(&tm, 0, sizeof(tm)); tm.tm_isdst = -1;
tm.tm_year = ((dos_date >> 9) & 127) + 1980 - 1900; tm.tm_mon = ((dos_date >> 5) & 15) - 1; tm.tm_mday = dos_date & 31;
tm.tm_hour = (dos_time >> 11) & 31; tm.tm_min = (dos_time >> 5) & 63; tm.tm_sec = (dos_time << 1) & 62;
return mktime(&tm);
}
static void mz_zip_time_to_dos_time(time_t time, mz_uint16 *pDOS_time, mz_uint16 *pDOS_date)
{
#ifdef _MSC_VER
struct tm tm_struct;
struct tm *tm = &tm_struct;
errno_t err = localtime_s(tm, &time);
if (err)
{
*pDOS_date = 0; *pDOS_time = 0;
return;
}
#else
struct tm *tm = localtime(&time);
#endif
*pDOS_time = (mz_uint16)(((tm->tm_hour) << 11) + ((tm->tm_min) << 5) + ((tm->tm_sec) >> 1));
*pDOS_date = (mz_uint16)(((tm->tm_year + 1900 - 1980) << 9) + ((tm->tm_mon + 1) << 5) + tm->tm_mday);
}
#endif
#ifndef MINIZ_NO_STDIO
static mz_bool mz_zip_get_file_modified_time(const char *pFilename, mz_uint16 *pDOS_time, mz_uint16 *pDOS_date)
{
#ifdef MINIZ_NO_TIME
(void)pFilename; *pDOS_date = *pDOS_time = 0;
#else
struct MZ_FILE_STAT_STRUCT file_stat;
// On Linux with x86 glibc, this call will fail on large files (>= 0x80000000 bytes) unless you compiled with _LARGEFILE64_SOURCE. Argh.
if (MZ_FILE_STAT(pFilename, &file_stat) != 0)
return MZ_FALSE;
mz_zip_time_to_dos_time(file_stat.st_mtime, pDOS_time, pDOS_date);
#endif // #ifdef MINIZ_NO_TIME
return MZ_TRUE;
}
#ifndef MINIZ_NO_TIME
static mz_bool mz_zip_set_file_times(const char *pFilename, time_t access_time, time_t modified_time)
{
struct utimbuf t; t.actime = access_time; t.modtime = modified_time;
return !utime(pFilename, &t);
}
#endif // #ifndef MINIZ_NO_TIME
#endif // #ifndef MINIZ_NO_STDIO
static mz_bool mz_zip_reader_init_internal(mz_zip_archive *pZip, mz_uint32 flags)
{
(void)flags;
if ((!pZip) || (pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID))
return MZ_FALSE;
if (!pZip->m_pAlloc) pZip->m_pAlloc = def_alloc_func;
if (!pZip->m_pFree) pZip->m_pFree = def_free_func;
if (!pZip->m_pRealloc) pZip->m_pRealloc = def_realloc_func;
pZip->m_zip_mode = MZ_ZIP_MODE_READING;
pZip->m_archive_size = 0;
pZip->m_central_directory_file_ofs = 0;
pZip->m_total_files = 0;
if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state))))
return MZ_FALSE;
memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state));
MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir, sizeof(mz_uint8));
MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets, sizeof(mz_uint32));
MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_sorted_central_dir_offsets, sizeof(mz_uint32));
return MZ_TRUE;
}
static MZ_FORCEINLINE mz_bool mz_zip_reader_filename_less(const mz_zip_array *pCentral_dir_array, const mz_zip_array *pCentral_dir_offsets, mz_uint l_index, mz_uint r_index)
{
const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, l_index)), *pE;
const mz_uint8 *pR = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, r_index));
mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS), r_len = MZ_READ_LE16(pR + MZ_ZIP_CDH_FILENAME_LEN_OFS);
mz_uint8 l = 0, r = 0;
pL += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; pR += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
pE = pL + MZ_MIN(l_len, r_len);
while (pL < pE)
{
if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR)))
break;
pL++; pR++;
}
return (pL == pE) ? (l_len < r_len) : (l < r);
}
#define MZ_SWAP_UINT32(a, b) do { mz_uint32 t = a; a = b; b = t; } MZ_MACRO_END
// Heap sort of lowercased filenames, used to help accelerate plain central directory searches by mz_zip_reader_locate_file(). (Could also use qsort(), but it could allocate memory.)
static void mz_zip_reader_sort_central_dir_offsets_by_filename(mz_zip_archive *pZip)
{
mz_zip_internal_state *pState = pZip->m_pState;
const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets;
const mz_zip_array *pCentral_dir = &pState->m_central_dir;
mz_uint32 *pIndices = &MZ_ZIP_ARRAY_ELEMENT(&pState->m_sorted_central_dir_offsets, mz_uint32, 0);
const int size = pZip->m_total_files;
int start = (size - 2) >> 1, end;
while (start >= 0)
{
int child, root = start;
for ( ; ; )
{
if ((child = (root << 1) + 1) >= size)
break;
child += (((child + 1) < size) && (mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[child], pIndices[child + 1])));
if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[root], pIndices[child]))
break;
MZ_SWAP_UINT32(pIndices[root], pIndices[child]); root = child;
}
start--;
}
end = size - 1;
while (end > 0)
{
int child, root = 0;
MZ_SWAP_UINT32(pIndices[end], pIndices[0]);
for ( ; ; )
{
if ((child = (root << 1) + 1) >= end)
break;
child += (((child + 1) < end) && mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[child], pIndices[child + 1]));
if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[root], pIndices[child]))
break;
MZ_SWAP_UINT32(pIndices[root], pIndices[child]); root = child;
}
end--;
}
}
static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint32 flags)
{
mz_uint cdir_size, num_this_disk, cdir_disk_index;
mz_uint64 cdir_ofs;
mz_int64 cur_file_ofs;
const mz_uint8 *p;
mz_uint32 buf_u32[4096 / sizeof(mz_uint32)]; mz_uint8 *pBuf = (mz_uint8 *)buf_u32;
mz_bool sort_central_dir = ((flags & MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0);
+ mz_bool zip_signature_found = 0;
// Basic sanity checks - reject files which are too small, and check the first 4 bytes of the file to make sure a local header is there.
if (pZip->m_archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
return MZ_FALSE;
// Find the end of central directory record by scanning the file from the end towards the beginning.
cur_file_ofs = MZ_MAX((mz_int64)pZip->m_archive_size - (mz_int64)sizeof(buf_u32), 0);
for ( ; ; )
{
- for ( ; ; )
+ int i, n = (int)MZ_MIN(sizeof(buf_u32), pZip->m_archive_size - cur_file_ofs);
+ if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, n) != (mz_uint)n)
+ return MZ_FALSE;
+ for (i = n - 4; i >= 0; --i)
{
- int i, n = (int)MZ_MIN(sizeof(buf_u32), pZip->m_archive_size - cur_file_ofs);
- if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, n) != (mz_uint)n)
- return MZ_FALSE;
- for (i = n - 4; i >= 0; --i)
- if (MZ_READ_LE32(pBuf + i) == MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG)
- break;
- if (i >= 0)
+ if (MZ_READ_LE32(pBuf + i) == MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG)
{
- cur_file_ofs += i;
+ // Read and verify the end of central directory record.
+ if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs + i, pBuf, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
+ continue;
+ if ((MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_SIG_OFS) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG) ||
+ ((pZip->m_total_files = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS)) != MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS)))
+ continue;
+ zip_signature_found = 1;
break;
}
- if ((!cur_file_ofs) || (cur_file_ofs < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE))
- return MZ_FALSE;
- cur_file_ofs = MZ_MAX(cur_file_ofs - (sizeof(buf_u32) - 3), 0);
}
- // Read and verify the end of central directory record.
- if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
- continue;
- if ((MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_SIG_OFS) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG) ||
- ((pZip->m_total_files = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS)) != MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS)))
- continue;
- break;
+
+ if (zip_signature_found)
+ {
+ cur_file_ofs += i;
+ break;
+ }
+ if ((!cur_file_ofs) || (cur_file_ofs < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE))
+ return MZ_FALSE;
+
+ cur_file_ofs = MZ_MAX(cur_file_ofs - (mz_int64)(sizeof(buf_u32) - 3), 0);
}
num_this_disk = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_THIS_DISK_OFS);
cdir_disk_index = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS);
if (((num_this_disk | cdir_disk_index) != 0) && ((num_this_disk != 1) || (cdir_disk_index != 1)))
return MZ_FALSE;
if ((cdir_size = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_SIZE_OFS)) < pZip->m_total_files * MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)
return MZ_FALSE;
cdir_ofs = cur_file_ofs - cdir_size;
if ((cdir_ofs + (mz_uint64)cdir_size) > pZip->m_archive_size)
return MZ_FALSE;
pZip->m_central_directory_file_ofs = cdir_ofs;
pZip->m_archive_file_ofs = cdir_ofs - MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_OFS_OFS);
if (pZip->m_archive_file_ofs > pZip->m_archive_size)
return MZ_FALSE;
if (pZip->m_total_files)
{
mz_uint i, n;
// Read the entire central directory into a heap block, and allocate another heap block to hold the unsorted central dir file record offsets, and another to hold the sorted indices.
if ((!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir, cdir_size, MZ_FALSE)) ||
(!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir_offsets, pZip->m_total_files, MZ_FALSE)))
return MZ_FALSE;
if (sort_central_dir)
{
if (!mz_zip_array_resize(pZip, &pZip->m_pState->m_sorted_central_dir_offsets, pZip->m_total_files, MZ_FALSE))
return MZ_FALSE;
}
if (pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs, pZip->m_pState->m_central_dir.m_p, cdir_size) != cdir_size)
return MZ_FALSE;
// Now create an index into the central directory file records, do some basic sanity checking on each record, and check for zip64 entries (which are not yet supported).
p = (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p;
for (n = cdir_size, i = 0; i < pZip->m_total_files; ++i)
{
mz_uint total_header_size, comp_size, decomp_size, disk_index;
if ((n < MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) || (MZ_READ_LE32(p) != MZ_ZIP_CENTRAL_DIR_HEADER_SIG))
return MZ_FALSE;
MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, i) = (mz_uint32)(p - (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p);
if (sort_central_dir)
MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_sorted_central_dir_offsets, mz_uint32, i) = i;
comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS);
decomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS);
if (((!MZ_READ_LE32(p + MZ_ZIP_CDH_METHOD_OFS)) && (decomp_size != comp_size)) || (decomp_size && !comp_size) || (decomp_size == 0xFFFFFFFF) || (comp_size == 0xFFFFFFFF))
return MZ_FALSE;
disk_index = MZ_READ_LE16(p + MZ_ZIP_CDH_DISK_START_OFS);
if ((disk_index != num_this_disk) && (disk_index != 1))
return MZ_FALSE;
if (((mz_uint64)MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS) + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + comp_size) > pZip->m_archive_size)
return MZ_FALSE;
if ((total_header_size = MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS)) > n)
return MZ_FALSE;
n -= total_header_size; p += total_header_size;
}
}
if (sort_central_dir)
mz_zip_reader_sort_central_dir_offsets_by_filename(pZip);
return MZ_TRUE;
}
mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, mz_uint32 flags)
{
if ((!pZip) || (!pZip->m_pRead))
return MZ_FALSE;
if (!mz_zip_reader_init_internal(pZip, flags))
return MZ_FALSE;
pZip->m_archive_size = size;
if (!mz_zip_reader_read_central_dir(pZip, flags))
{
mz_zip_reader_end(pZip);
return MZ_FALSE;
}
return MZ_TRUE;
}
static size_t mz_zip_mem_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n)
{
mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
size_t s = (file_ofs >= pZip->m_archive_size) ? 0 : (size_t)MZ_MIN(pZip->m_archive_size - file_ofs, n);
memcpy(pBuf, (const mz_uint8 *)pZip->m_pState->m_pMem + file_ofs, s);
return s;
}
mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint32 flags)
{
if (!mz_zip_reader_init_internal(pZip, flags))
return MZ_FALSE;
pZip->m_archive_size = size;
pZip->m_pRead = mz_zip_mem_read_func;
pZip->m_pIO_opaque = pZip;
#ifdef __cplusplus
pZip->m_pState->m_pMem = const_cast<void *>(pMem);
#else
pZip->m_pState->m_pMem = (void *)pMem;
#endif
pZip->m_pState->m_mem_size = size;
if (!mz_zip_reader_read_central_dir(pZip, flags))
{
mz_zip_reader_end(pZip);
return MZ_FALSE;
}
return MZ_TRUE;
}
#ifndef MINIZ_NO_STDIO
static size_t mz_zip_file_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n)
{
mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile);
if (((mz_int64)file_ofs < 0) || (((cur_ofs != (mz_int64)file_ofs)) && (MZ_FSEEK64(pZip->m_pState->m_pFile, (mz_int64)file_ofs, SEEK_SET))))
return 0;
return MZ_FREAD(pBuf, 1, n, pZip->m_pState->m_pFile);
}
mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags)
{
mz_uint64 file_size;
MZ_FILE *pFile = MZ_FOPEN(pFilename, "rb");
if (!pFile)
return MZ_FALSE;
if (MZ_FSEEK64(pFile, 0, SEEK_END))
{
MZ_FCLOSE(pFile);
return MZ_FALSE;
}
file_size = MZ_FTELL64(pFile);
if (!mz_zip_reader_init_internal(pZip, flags))
{
MZ_FCLOSE(pFile);
return MZ_FALSE;
}
pZip->m_pRead = mz_zip_file_read_func;
pZip->m_pIO_opaque = pZip;
pZip->m_pState->m_pFile = pFile;
pZip->m_archive_size = file_size;
if (!mz_zip_reader_read_central_dir(pZip, flags))
{
mz_zip_reader_end(pZip);
return MZ_FALSE;
}
return MZ_TRUE;
}
#endif // #ifndef MINIZ_NO_STDIO
mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip)
{
return pZip ? pZip->m_total_files : 0;
}
static MZ_FORCEINLINE const mz_uint8 *mz_zip_reader_get_cdh(mz_zip_archive *pZip, mz_uint file_index)
{
if ((!pZip) || (!pZip->m_pState) || (file_index >= pZip->m_total_files) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
return NULL;
return &MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index));
}
mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index)
{
mz_uint m_bit_flag;
const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index);
if (!p)
return MZ_FALSE;
m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
return (m_bit_flag & 1);
}
mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index)
{
mz_uint filename_len, external_attr;
const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index);
if (!p)
return MZ_FALSE;
// First see if the filename ends with a '/' character.
filename_len = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
if (filename_len)
{
if (*(p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_len - 1) == '/')
return MZ_TRUE;
}
// Bugfix: This code was also checking if the internal attribute was non-zero, which wasn't correct.
// Most/all zip writers (hopefully) set DOS file/directory attributes in the low 16-bits, so check for the DOS directory flag and ignore the source OS ID in the created by field.
// FIXME: Remove this check? Is it necessary - we already check the filename.
external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS);
if ((external_attr & 0x10) != 0)
return MZ_TRUE;
return MZ_FALSE;
}
mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat)
{
mz_uint n;
const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index);
if ((!p) || (!pStat))
return MZ_FALSE;
// Unpack the central directory record.
pStat->m_file_index = file_index;
pStat->m_central_dir_ofs = MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index);
pStat->m_version_made_by = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_MADE_BY_OFS);
pStat->m_version_needed = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_NEEDED_OFS);
pStat->m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
pStat->m_method = MZ_READ_LE16(p + MZ_ZIP_CDH_METHOD_OFS);
#ifndef MINIZ_NO_TIME
pStat->m_time = mz_zip_dos_to_time_t(MZ_READ_LE16(p + MZ_ZIP_CDH_FILE_TIME_OFS), MZ_READ_LE16(p + MZ_ZIP_CDH_FILE_DATE_OFS));
#endif
pStat->m_crc32 = MZ_READ_LE32(p + MZ_ZIP_CDH_CRC32_OFS);
pStat->m_comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS);
pStat->m_uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS);
pStat->m_internal_attr = MZ_READ_LE16(p + MZ_ZIP_CDH_INTERNAL_ATTR_OFS);
pStat->m_external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS);
pStat->m_local_header_ofs = MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS);
// Copy as much of the filename and comment as possible.
n = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS); n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE - 1);
memcpy(pStat->m_filename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n); pStat->m_filename[n] = '\0';
n = MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS); n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE - 1);
pStat->m_comment_size = n;
memcpy(pStat->m_comment, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS), n); pStat->m_comment[n] = '\0';
return MZ_TRUE;
}
mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size)
{
mz_uint n;
const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index);
if (!p) { if (filename_buf_size) pFilename[0] = '\0'; return 0; }
n = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
if (filename_buf_size)
{
n = MZ_MIN(n, filename_buf_size - 1);
memcpy(pFilename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n);
pFilename[n] = '\0';
}
return n + 1;
}
static MZ_FORCEINLINE mz_bool mz_zip_reader_string_equal(const char *pA, const char *pB, mz_uint len, mz_uint flags)
{
mz_uint i;
if (flags & MZ_ZIP_FLAG_CASE_SENSITIVE)
return 0 == memcmp(pA, pB, len);
for (i = 0; i < len; ++i)
if (MZ_TOLOWER(pA[i]) != MZ_TOLOWER(pB[i]))
return MZ_FALSE;
return MZ_TRUE;
}
static MZ_FORCEINLINE int mz_zip_reader_filename_compare(const mz_zip_array *pCentral_dir_array, const mz_zip_array *pCentral_dir_offsets, mz_uint l_index, const char *pR, mz_uint r_len)
{
const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, l_index)), *pE;
mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS);
mz_uint8 l = 0, r = 0;
pL += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
pE = pL + MZ_MIN(l_len, r_len);
while (pL < pE)
{
if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR)))
break;
pL++; pR++;
}
return (pL == pE) ? (int)(l_len - r_len) : (l - r);
}
static int mz_zip_reader_locate_file_binary_search(mz_zip_archive *pZip, const char *pFilename)
{
mz_zip_internal_state *pState = pZip->m_pState;
const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets;
const mz_zip_array *pCentral_dir = &pState->m_central_dir;
mz_uint32 *pIndices = &MZ_ZIP_ARRAY_ELEMENT(&pState->m_sorted_central_dir_offsets, mz_uint32, 0);
const int size = pZip->m_total_files;
const mz_uint filename_len = (mz_uint)strlen(pFilename);
int l = 0, h = size - 1;
while (l <= h)
{
int m = (l + h) >> 1, file_index = pIndices[m], comp = mz_zip_reader_filename_compare(pCentral_dir, pCentral_dir_offsets, file_index, pFilename, filename_len);
if (!comp)
return file_index;
else if (comp < 0)
l = m + 1;
else
h = m - 1;
}
return -1;
}
int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags)
{
mz_uint file_index; size_t name_len, comment_len;
if ((!pZip) || (!pZip->m_pState) || (!pName) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
return -1;
if (((flags & (MZ_ZIP_FLAG_IGNORE_PATH | MZ_ZIP_FLAG_CASE_SENSITIVE)) == 0) && (!pComment) && (pZip->m_pState->m_sorted_central_dir_offsets.m_size))
return mz_zip_reader_locate_file_binary_search(pZip, pName);
name_len = strlen(pName); if (name_len > 0xFFFF) return -1;
comment_len = pComment ? strlen(pComment) : 0; if (comment_len > 0xFFFF) return -1;
for (file_index = 0; file_index < pZip->m_total_files; file_index++)
{
const mz_uint8 *pHeader = &MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index));
mz_uint filename_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_FILENAME_LEN_OFS);
const char *pFilename = (const char *)pHeader + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
if (filename_len < name_len)
continue;
if (comment_len)
{
mz_uint file_extra_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_EXTRA_LEN_OFS), file_comment_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_COMMENT_LEN_OFS);
const char *pFile_comment = pFilename + filename_len + file_extra_len;
if ((file_comment_len != comment_len) || (!mz_zip_reader_string_equal(pComment, pFile_comment, file_comment_len, flags)))
continue;
}
if ((flags & MZ_ZIP_FLAG_IGNORE_PATH) && (filename_len))
{
int ofs = filename_len - 1;
do
{
if ((pFilename[ofs] == '/') || (pFilename[ofs] == '\\') || (pFilename[ofs] == ':'))
break;
} while (--ofs >= 0);
ofs++;
pFilename += ofs; filename_len -= ofs;
}
if ((filename_len == name_len) && (mz_zip_reader_string_equal(pName, pFilename, filename_len, flags)))
return file_index;
}
return -1;
}
mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size)
{
int status = TINFL_STATUS_DONE;
mz_uint64 needed_size, cur_file_ofs, comp_remaining, out_buf_ofs = 0, read_buf_size, read_buf_ofs = 0, read_buf_avail;
mz_zip_archive_file_stat file_stat;
void *pRead_buf;
mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
tinfl_decompressor inflator;
if ((buf_size) && (!pBuf))
return MZ_FALSE;
if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
return MZ_FALSE;
// Empty file, or a directory (but not always a directory - I've seen odd zips with directories that have compressed data which inflates to 0 bytes)
if (!file_stat.m_comp_size)
return MZ_TRUE;
// Entry is a subdirectory (I've seen old zips with dir entries which have compressed deflate data which inflates to 0 bytes, but these entries claim to uncompress to 512 bytes in the headers).
// I'm torn how to handle this case - should it fail instead?
if (mz_zip_reader_is_file_a_directory(pZip, file_index))
return MZ_TRUE;
// Encryption and patch files are not supported.
if (file_stat.m_bit_flag & (1 | 32))
return MZ_FALSE;
// This function only supports stored and deflate.
if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED))
return MZ_FALSE;
// Ensure supplied output buffer is large enough.
needed_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? file_stat.m_comp_size : file_stat.m_uncomp_size;
if (buf_size < needed_size)
return MZ_FALSE;
// Read and parse the local directory entry.
cur_file_ofs = pZip->m_archive_file_ofs + file_stat.m_local_header_ofs;
if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
return MZ_FALSE;
if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
return MZ_FALSE;
cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size)
return MZ_FALSE;
if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method))
{
// The file is stored or the caller has requested the compressed data.
if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, (size_t)needed_size) != needed_size)
return MZ_FALSE;
return ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) != 0) || (mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, (size_t)file_stat.m_uncomp_size) == file_stat.m_crc32);
}
// Decompress the file either directly from memory or from a file input buffer.
tinfl_init(&inflator);
if (pZip->m_pState->m_pMem)
{
// Read directly from the archive in memory.
pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs;
read_buf_size = read_buf_avail = file_stat.m_comp_size;
comp_remaining = 0;
}
else if (pUser_read_buf)
{
// Use a user provided read buffer.
if (!user_read_buf_size)
return MZ_FALSE;
pRead_buf = (mz_uint8 *)pUser_read_buf;
read_buf_size = user_read_buf_size;
read_buf_avail = 0;
comp_remaining = file_stat.m_comp_size;
}
else
{
// Temporarily allocate a read buffer.
read_buf_size = MZ_MIN(file_stat.m_comp_size, MZ_ZIP_MAX_IO_BUF_SIZE);
#ifdef _MSC_VER
if (((0, sizeof(size_t) == sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF))
#else
if (((sizeof(size_t) == sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF))
#endif
return MZ_FALSE;
if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)read_buf_size)))
return MZ_FALSE;
read_buf_avail = 0;
comp_remaining = file_stat.m_comp_size;
}
do
{
size_t in_buf_size, out_buf_size = (size_t)(file_stat.m_uncomp_size - out_buf_ofs);
if ((!read_buf_avail) && (!pZip->m_pState->m_pMem))
{
read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
{
status = TINFL_STATUS_FAILED;
break;
}
cur_file_ofs += read_buf_avail;
comp_remaining -= read_buf_avail;
read_buf_ofs = 0;
}
in_buf_size = (size_t)read_buf_avail;
status = tinfl_decompress(&inflator, (mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size, (mz_uint8 *)pBuf, (mz_uint8 *)pBuf + out_buf_ofs, &out_buf_size, TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF | (comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0));
read_buf_avail -= in_buf_size;
read_buf_ofs += in_buf_size;
out_buf_ofs += out_buf_size;
} while (status == TINFL_STATUS_NEEDS_MORE_INPUT);
if (status == TINFL_STATUS_DONE)
{
// Make sure the entire file was decompressed, and check its CRC.
if ((out_buf_ofs != file_stat.m_uncomp_size) || (mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, (size_t)file_stat.m_uncomp_size) != file_stat.m_crc32))
status = TINFL_STATUS_FAILED;
}
if ((!pZip->m_pState->m_pMem) && (!pUser_read_buf))
pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
return status == TINFL_STATUS_DONE;
}
mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size)
{
int file_index = mz_zip_reader_locate_file(pZip, pFilename, NULL, flags);
if (file_index < 0)
return MZ_FALSE;
return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size, flags, pUser_read_buf, user_read_buf_size);
}
mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags)
{
return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size, flags, NULL, 0);
}
mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags)
{
return mz_zip_reader_extract_file_to_mem_no_alloc(pZip, pFilename, pBuf, buf_size, flags, NULL, 0);
}
void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags)
{
mz_uint64 comp_size, uncomp_size, alloc_size;
const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index);
void *pBuf;
if (pSize)
*pSize = 0;
if (!p)
return NULL;
comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS);
uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS);
alloc_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? comp_size : uncomp_size;
#ifdef _MSC_VER
if (((0, sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF))
#else
if (((sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF))
#endif
return NULL;
if (NULL == (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)alloc_size)))
return NULL;
if (!mz_zip_reader_extract_to_mem(pZip, file_index, pBuf, (size_t)alloc_size, flags))
{
pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
return NULL;
}
if (pSize) *pSize = (size_t)alloc_size;
return pBuf;
}
void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags)
{
int file_index = mz_zip_reader_locate_file(pZip, pFilename, NULL, flags);
if (file_index < 0)
{
if (pSize) *pSize = 0;
return MZ_FALSE;
}
return mz_zip_reader_extract_to_heap(pZip, file_index, pSize, flags);
}
mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, mz_uint file_index, mz_file_write_func pCallback, void *pOpaque, mz_uint flags)
{
int status = TINFL_STATUS_DONE; mz_uint file_crc32 = MZ_CRC32_INIT;
mz_uint64 read_buf_size, read_buf_ofs = 0, read_buf_avail, comp_remaining, out_buf_ofs = 0, cur_file_ofs;
mz_zip_archive_file_stat file_stat;
void *pRead_buf = NULL; void *pWrite_buf = NULL;
mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
return MZ_FALSE;
// Empty file, or a directory (but not always a directory - I've seen odd zips with directories that have compressed data which inflates to 0 bytes)
if (!file_stat.m_comp_size)
return MZ_TRUE;
// Entry is a subdirectory (I've seen old zips with dir entries which have compressed deflate data which inflates to 0 bytes, but these entries claim to uncompress to 512 bytes in the headers).
// I'm torn how to handle this case - should it fail instead?
if (mz_zip_reader_is_file_a_directory(pZip, file_index))
return MZ_TRUE;
// Encryption and patch files are not supported.
if (file_stat.m_bit_flag & (1 | 32))
return MZ_FALSE;
// This function only supports stored and deflate.
if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED))
return MZ_FALSE;
// Read and parse the local directory entry.
cur_file_ofs = file_stat.m_local_header_ofs;
if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
return MZ_FALSE;
if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
return MZ_FALSE;
cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size)
return MZ_FALSE;
// Decompress the file either directly from memory or from a file input buffer.
if (pZip->m_pState->m_pMem)
{
pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs;
read_buf_size = read_buf_avail = file_stat.m_comp_size;
comp_remaining = 0;
}
else
{
read_buf_size = MZ_MIN(file_stat.m_comp_size, MZ_ZIP_MAX_IO_BUF_SIZE);
if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)read_buf_size)))
return MZ_FALSE;
read_buf_avail = 0;
comp_remaining = file_stat.m_comp_size;
}
if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method))
{
// The file is stored or the caller has requested the compressed data.
if (pZip->m_pState->m_pMem)
{
#ifdef _MSC_VER
if (((0, sizeof(size_t) == sizeof(mz_uint32))) && (file_stat.m_comp_size > 0xFFFFFFFF))
#else
if (((sizeof(size_t) == sizeof(mz_uint32))) && (file_stat.m_comp_size > 0xFFFFFFFF))
#endif
return MZ_FALSE;
if (pCallback(pOpaque, out_buf_ofs, pRead_buf, (size_t)file_stat.m_comp_size) != file_stat.m_comp_size)
status = TINFL_STATUS_FAILED;
else if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
file_crc32 = (mz_uint32)mz_crc32(file_crc32, (const mz_uint8 *)pRead_buf, (size_t)file_stat.m_comp_size);
cur_file_ofs += file_stat.m_comp_size;
out_buf_ofs += file_stat.m_comp_size;
comp_remaining = 0;
}
else
{
while (comp_remaining)
{
read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
{
status = TINFL_STATUS_FAILED;
break;
}
if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
file_crc32 = (mz_uint32)mz_crc32(file_crc32, (const mz_uint8 *)pRead_buf, (size_t)read_buf_avail);
if (pCallback(pOpaque, out_buf_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
{
status = TINFL_STATUS_FAILED;
break;
}
cur_file_ofs += read_buf_avail;
out_buf_ofs += read_buf_avail;
comp_remaining -= read_buf_avail;
}
}
}
else
{
tinfl_decompressor inflator;
tinfl_init(&inflator);
if (NULL == (pWrite_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, TINFL_LZ_DICT_SIZE)))
status = TINFL_STATUS_FAILED;
else
{
do
{
mz_uint8 *pWrite_buf_cur = (mz_uint8 *)pWrite_buf + (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
size_t in_buf_size, out_buf_size = TINFL_LZ_DICT_SIZE - (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
if ((!read_buf_avail) && (!pZip->m_pState->m_pMem))
{
read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
{
status = TINFL_STATUS_FAILED;
break;
}
cur_file_ofs += read_buf_avail;
comp_remaining -= read_buf_avail;
read_buf_ofs = 0;
}
in_buf_size = (size_t)read_buf_avail;
status = tinfl_decompress(&inflator, (const mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size, (mz_uint8 *)pWrite_buf, pWrite_buf_cur, &out_buf_size, comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0);
read_buf_avail -= in_buf_size;
read_buf_ofs += in_buf_size;
if (out_buf_size)
{
if (pCallback(pOpaque, out_buf_ofs, pWrite_buf_cur, out_buf_size) != out_buf_size)
{
status = TINFL_STATUS_FAILED;
break;
}
file_crc32 = (mz_uint32)mz_crc32(file_crc32, pWrite_buf_cur, out_buf_size);
if ((out_buf_ofs += out_buf_size) > file_stat.m_uncomp_size)
{
status = TINFL_STATUS_FAILED;
break;
}
}
} while ((status == TINFL_STATUS_NEEDS_MORE_INPUT) || (status == TINFL_STATUS_HAS_MORE_OUTPUT));
}
}
if ((status == TINFL_STATUS_DONE) && (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)))
{
// Make sure the entire file was decompressed, and check its CRC.
if ((out_buf_ofs != file_stat.m_uncomp_size) || (file_crc32 != file_stat.m_crc32))
status = TINFL_STATUS_FAILED;
}
if (!pZip->m_pState->m_pMem)
pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
if (pWrite_buf)
pZip->m_pFree(pZip->m_pAlloc_opaque, pWrite_buf);
return status == TINFL_STATUS_DONE;
}
mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip, const char *pFilename, mz_file_write_func pCallback, void *pOpaque, mz_uint flags)
{
int file_index = mz_zip_reader_locate_file(pZip, pFilename, NULL, flags);
if (file_index < 0)
return MZ_FALSE;
return mz_zip_reader_extract_to_callback(pZip, file_index, pCallback, pOpaque, flags);
}
#ifndef MINIZ_NO_STDIO
static size_t mz_zip_file_write_callback(void *pOpaque, mz_uint64 ofs, const void *pBuf, size_t n)
{
(void)ofs; return MZ_FWRITE(pBuf, 1, n, (MZ_FILE*)pOpaque);
}
mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const char *pDst_filename, mz_uint flags)
{
mz_bool status;
mz_zip_archive_file_stat file_stat;
MZ_FILE *pFile;
if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
return MZ_FALSE;
pFile = MZ_FOPEN(pDst_filename, "wb");
if (!pFile)
return MZ_FALSE;
status = mz_zip_reader_extract_to_callback(pZip, file_index, mz_zip_file_write_callback, pFile, flags);
if (MZ_FCLOSE(pFile) == EOF)
return MZ_FALSE;
#ifndef MINIZ_NO_TIME
if (status)
mz_zip_set_file_times(pDst_filename, file_stat.m_time, file_stat.m_time);
#endif
return status;
}
#endif // #ifndef MINIZ_NO_STDIO
mz_bool mz_zip_reader_end(mz_zip_archive *pZip)
{
if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
return MZ_FALSE;
if (pZip->m_pState)
{
mz_zip_internal_state *pState = pZip->m_pState; pZip->m_pState = NULL;
mz_zip_array_clear(pZip, &pState->m_central_dir);
mz_zip_array_clear(pZip, &pState->m_central_dir_offsets);
mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets);
#ifndef MINIZ_NO_STDIO
if (pState->m_pFile)
{
MZ_FCLOSE(pState->m_pFile);
pState->m_pFile = NULL;
}
#endif // #ifndef MINIZ_NO_STDIO
pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
}
pZip->m_zip_mode = MZ_ZIP_MODE_INVALID;
return MZ_TRUE;
}
#ifndef MINIZ_NO_STDIO
mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const char *pDst_filename, mz_uint flags)
{
int file_index = mz_zip_reader_locate_file(pZip, pArchive_filename, NULL, flags);
if (file_index < 0)
return MZ_FALSE;
return mz_zip_reader_extract_to_file(pZip, file_index, pDst_filename, flags);
}
#endif
// ------------------- .ZIP archive writing
#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
static void mz_write_le16(mz_uint8 *p, mz_uint16 v) { p[0] = (mz_uint8)v; p[1] = (mz_uint8)(v >> 8); }
static void mz_write_le32(mz_uint8 *p, mz_uint32 v) { p[0] = (mz_uint8)v; p[1] = (mz_uint8)(v >> 8); p[2] = (mz_uint8)(v >> 16); p[3] = (mz_uint8)(v >> 24); }
#define MZ_WRITE_LE16(p, v) mz_write_le16((mz_uint8 *)(p), (mz_uint16)(v))
#define MZ_WRITE_LE32(p, v) mz_write_le32((mz_uint8 *)(p), (mz_uint32)(v))
mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size)
{
if ((!pZip) || (pZip->m_pState) || (!pZip->m_pWrite) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID))
return MZ_FALSE;
if (pZip->m_file_offset_alignment)
{
// Ensure user specified file offset alignment is a power of 2.
if (pZip->m_file_offset_alignment & (pZip->m_file_offset_alignment - 1))
return MZ_FALSE;
}
if (!pZip->m_pAlloc) pZip->m_pAlloc = def_alloc_func;
if (!pZip->m_pFree) pZip->m_pFree = def_free_func;
if (!pZip->m_pRealloc) pZip->m_pRealloc = def_realloc_func;
pZip->m_zip_mode = MZ_ZIP_MODE_WRITING;
pZip->m_archive_size = existing_size;
pZip->m_central_directory_file_ofs = 0;
pZip->m_total_files = 0;
if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state))))
return MZ_FALSE;
memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state));
MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir, sizeof(mz_uint8));
MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets, sizeof(mz_uint32));
MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_sorted_central_dir_offsets, sizeof(mz_uint32));
return MZ_TRUE;
}
static size_t mz_zip_heap_write_func(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n)
{
mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
mz_zip_internal_state *pState = pZip->m_pState;
mz_uint64 new_size = MZ_MAX(file_ofs + n, pState->m_mem_size);
#ifdef _MSC_VER
if ((!n) || ((0, sizeof(size_t) == sizeof(mz_uint32)) && (new_size > 0x7FFFFFFF)))
#else
if ((!n) || ((sizeof(size_t) == sizeof(mz_uint32)) && (new_size > 0x7FFFFFFF)))
#endif
return 0;
if (new_size > pState->m_mem_capacity)
{
void *pNew_block;
size_t new_capacity = MZ_MAX(64, pState->m_mem_capacity); while (new_capacity < new_size) new_capacity *= 2;
if (NULL == (pNew_block = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pState->m_pMem, 1, new_capacity)))
return 0;
pState->m_pMem = pNew_block; pState->m_mem_capacity = new_capacity;
}
memcpy((mz_uint8 *)pState->m_pMem + file_ofs, pBuf, n);
pState->m_mem_size = (size_t)new_size;
return n;
}
mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size)
{
pZip->m_pWrite = mz_zip_heap_write_func;
pZip->m_pIO_opaque = pZip;
if (!mz_zip_writer_init(pZip, size_to_reserve_at_beginning))
return MZ_FALSE;
if (0 != (initial_allocation_size = MZ_MAX(initial_allocation_size, size_to_reserve_at_beginning)))
{
if (NULL == (pZip->m_pState->m_pMem = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, initial_allocation_size)))
{
mz_zip_writer_end(pZip);
return MZ_FALSE;
}
pZip->m_pState->m_mem_capacity = initial_allocation_size;
}
return MZ_TRUE;
}
#ifndef MINIZ_NO_STDIO
static size_t mz_zip_file_write_func(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n)
{
mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile);
if (((mz_int64)file_ofs < 0) || (((cur_ofs != (mz_int64)file_ofs)) && (MZ_FSEEK64(pZip->m_pState->m_pFile, (mz_int64)file_ofs, SEEK_SET))))
return 0;
return MZ_FWRITE(pBuf, 1, n, pZip->m_pState->m_pFile);
}
mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning)
{
MZ_FILE *pFile;
pZip->m_pWrite = mz_zip_file_write_func;
pZip->m_pIO_opaque = pZip;
if (!mz_zip_writer_init(pZip, size_to_reserve_at_beginning))
return MZ_FALSE;
if (NULL == (pFile = MZ_FOPEN(pFilename, "wb")))
{
mz_zip_writer_end(pZip);
return MZ_FALSE;
}
pZip->m_pState->m_pFile = pFile;
if (size_to_reserve_at_beginning)
{
mz_uint64 cur_ofs = 0; char buf[4096]; MZ_CLEAR_OBJ(buf);
do
{
size_t n = (size_t)MZ_MIN(sizeof(buf), size_to_reserve_at_beginning);
if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_ofs, buf, n) != n)
{
mz_zip_writer_end(pZip);
return MZ_FALSE;
}
cur_ofs += n; size_to_reserve_at_beginning -= n;
} while (size_to_reserve_at_beginning);
}
return MZ_TRUE;
}
#endif // #ifndef MINIZ_NO_STDIO
mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const char *pFilename)
{
mz_zip_internal_state *pState;
if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
return MZ_FALSE;
// No sense in trying to write to an archive that's already at the support max size
if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_ZIP_LOCAL_DIR_HEADER_SIZE) > 0xFFFFFFFF))
return MZ_FALSE;
pState = pZip->m_pState;
if (pState->m_pFile)
{
#ifdef MINIZ_NO_STDIO
pFilename; return MZ_FALSE;
#else
// Archive is being read from stdio - try to reopen as writable.
if (pZip->m_pIO_opaque != pZip)
return MZ_FALSE;
if (!pFilename)
return MZ_FALSE;
pZip->m_pWrite = mz_zip_file_write_func;
if (NULL == (pState->m_pFile = MZ_FREOPEN(pFilename, "r+b", pState->m_pFile)))
{
// The mz_zip_archive is now in a bogus state because pState->m_pFile is NULL, so just close it.
mz_zip_reader_end(pZip);
return MZ_FALSE;
}
#endif // #ifdef MINIZ_NO_STDIO
}
else if (pState->m_pMem)
{
// Archive lives in a memory block. Assume it's from the heap that we can resize using the realloc callback.
if (pZip->m_pIO_opaque != pZip)
return MZ_FALSE;
pState->m_mem_capacity = pState->m_mem_size;
pZip->m_pWrite = mz_zip_heap_write_func;
}
// Archive is being read via a user provided read function - make sure the user has specified a write function too.
else if (!pZip->m_pWrite)
return MZ_FALSE;
// Start writing new files at the archive's current central directory location.
pZip->m_archive_size = pZip->m_central_directory_file_ofs;
pZip->m_zip_mode = MZ_ZIP_MODE_WRITING;
pZip->m_central_directory_file_ofs = 0;
return MZ_TRUE;
}
mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags)
{
return mz_zip_writer_add_mem_ex(pZip, pArchive_name, pBuf, buf_size, NULL, 0, level_and_flags, 0, 0);
}
typedef struct
{
mz_zip_archive *m_pZip;
mz_uint64 m_cur_archive_file_ofs;
mz_uint64 m_comp_size;
} mz_zip_writer_add_state;
static mz_bool mz_zip_writer_add_put_buf_callback(const void* pBuf, int len, void *pUser)
{
mz_zip_writer_add_state *pState = (mz_zip_writer_add_state *)pUser;
if ((int)pState->m_pZip->m_pWrite(pState->m_pZip->m_pIO_opaque, pState->m_cur_archive_file_ofs, pBuf, len) != len)
return MZ_FALSE;
pState->m_cur_archive_file_ofs += len;
pState->m_comp_size += len;
return MZ_TRUE;
}
static mz_bool mz_zip_writer_create_local_dir_header(mz_zip_archive *pZip, mz_uint8 *pDst, mz_uint16 filename_size, mz_uint16 extra_size, mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date)
{
(void)pZip;
memset(pDst, 0, MZ_ZIP_LOCAL_DIR_HEADER_SIZE);
MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_SIG_OFS, MZ_ZIP_LOCAL_DIR_HEADER_SIG);
MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_VERSION_NEEDED_OFS, method ? 20 : 0);
MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_BIT_FLAG_OFS, bit_flags);
MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_METHOD_OFS, method);
MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_TIME_OFS, dos_time);
MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_DATE_OFS, dos_date);
MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_CRC32_OFS, uncomp_crc32);
MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS, comp_size);
MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS, uncomp_size);
MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILENAME_LEN_OFS, filename_size);
MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_EXTRA_LEN_OFS, extra_size);
return MZ_TRUE;
}
static mz_bool mz_zip_writer_create_central_dir_header(mz_zip_archive *pZip, mz_uint8 *pDst, mz_uint16 filename_size, mz_uint16 extra_size, mz_uint16 comment_size, mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date, mz_uint64 local_header_ofs, mz_uint32 ext_attributes)
{
(void)pZip;
memset(pDst, 0, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE);
MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_SIG_OFS, MZ_ZIP_CENTRAL_DIR_HEADER_SIG);
MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_VERSION_NEEDED_OFS, method ? 20 : 0);
MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_BIT_FLAG_OFS, bit_flags);
MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_METHOD_OFS, method);
MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_TIME_OFS, dos_time);
MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_DATE_OFS, dos_date);
MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_CRC32_OFS, uncomp_crc32);
MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS, comp_size);
MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS, uncomp_size);
MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILENAME_LEN_OFS, filename_size);
MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_EXTRA_LEN_OFS, extra_size);
MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_COMMENT_LEN_OFS, comment_size);
MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS, ext_attributes);
MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_LOCAL_HEADER_OFS, local_header_ofs);
return MZ_TRUE;
}
static mz_bool mz_zip_writer_add_to_central_dir(mz_zip_archive *pZip, const char *pFilename, mz_uint16 filename_size, const void *pExtra, mz_uint16 extra_size, const void *pComment, mz_uint16 comment_size, mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date, mz_uint64 local_header_ofs, mz_uint32 ext_attributes)
{
mz_zip_internal_state *pState = pZip->m_pState;
mz_uint32 central_dir_ofs = (mz_uint32)pState->m_central_dir.m_size;
size_t orig_central_dir_size = pState->m_central_dir.m_size;
mz_uint8 central_dir_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE];
// No zip64 support yet
if ((local_header_ofs > 0xFFFFFFFF) || (((mz_uint64)pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + extra_size + comment_size) > 0xFFFFFFFF))
return MZ_FALSE;
if (!mz_zip_writer_create_central_dir_header(pZip, central_dir_header, filename_size, extra_size, comment_size, uncomp_size, comp_size, uncomp_crc32, method, bit_flags, dos_time, dos_date, local_header_ofs, ext_attributes))
return MZ_FALSE;
if ((!mz_zip_array_push_back(pZip, &pState->m_central_dir, central_dir_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)) ||
(!mz_zip_array_push_back(pZip, &pState->m_central_dir, pFilename, filename_size)) ||
(!mz_zip_array_push_back(pZip, &pState->m_central_dir, pExtra, extra_size)) ||
(!mz_zip_array_push_back(pZip, &pState->m_central_dir, pComment, comment_size)) ||
(!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, &central_dir_ofs, 1)))
{
// Try to push the central directory array back into its original state.
mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
return MZ_FALSE;
}
return MZ_TRUE;
}
static mz_bool mz_zip_writer_validate_archive_name(const char *pArchive_name)
{
// Basic ZIP archive filename validity checks: Valid filenames cannot start with a forward slash, cannot contain a drive letter, and cannot use DOS-style backward slashes.
if (*pArchive_name == '/')
return MZ_FALSE;
while (*pArchive_name)
{
if ((*pArchive_name == '\\') || (*pArchive_name == ':'))
return MZ_FALSE;
pArchive_name++;
}
return MZ_TRUE;
}
static mz_uint mz_zip_writer_compute_padding_needed_for_file_alignment(mz_zip_archive *pZip)
{
mz_uint32 n;
if (!pZip->m_file_offset_alignment)
return 0;
n = (mz_uint32)(pZip->m_archive_size & (pZip->m_file_offset_alignment - 1));
return (pZip->m_file_offset_alignment - n) & (pZip->m_file_offset_alignment - 1);
}
static mz_bool mz_zip_writer_write_zeros(mz_zip_archive *pZip, mz_uint64 cur_file_ofs, mz_uint32 n)
{
char buf[4096];
memset(buf, 0, MZ_MIN(sizeof(buf), n));
while (n)
{
mz_uint32 s = MZ_MIN(sizeof(buf), n);
if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_file_ofs, buf, s) != s)
return MZ_FALSE;
cur_file_ofs += s; n -= s;
}
return MZ_TRUE;
}
mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32)
{
mz_uint16 method = 0, dos_time = 0, dos_date = 0;
mz_uint level, ext_attributes = 0, num_alignment_padding_bytes;
mz_uint64 local_dir_header_ofs = pZip->m_archive_size, cur_archive_file_ofs = pZip->m_archive_size, comp_size = 0;
size_t archive_name_size;
mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE];
tdefl_compressor *pComp = NULL;
mz_bool store_data_uncompressed;
mz_zip_internal_state *pState;
if ((int)level_and_flags < 0)
level_and_flags = MZ_DEFAULT_LEVEL;
level = level_and_flags & 0xF;
store_data_uncompressed = ((!level) || (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA));
if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || ((buf_size) && (!pBuf)) || (!pArchive_name) || ((comment_size) && (!pComment)) || (pZip->m_total_files == 0xFFFF) || (level > MZ_UBER_COMPRESSION))
return MZ_FALSE;
pState = pZip->m_pState;
if ((!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (uncomp_size))
return MZ_FALSE;
// No zip64 support yet
if ((buf_size > 0xFFFFFFFF) || (uncomp_size > 0xFFFFFFFF))
return MZ_FALSE;
if (!mz_zip_writer_validate_archive_name(pArchive_name))
return MZ_FALSE;
#ifndef MINIZ_NO_TIME
{
time_t cur_time; time(&cur_time);
mz_zip_time_to_dos_time(cur_time, &dos_time, &dos_date);
}
#endif // #ifndef MINIZ_NO_TIME
archive_name_size = strlen(pArchive_name);
if (archive_name_size > 0xFFFF)
return MZ_FALSE;
num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
// no zip64 support yet
if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + comment_size + archive_name_size) > 0xFFFFFFFF))
return MZ_FALSE;
if ((archive_name_size) && (pArchive_name[archive_name_size - 1] == '/'))
{
// Set DOS Subdirectory attribute bit.
ext_attributes |= 0x10;
// Subdirectories cannot contain data.
if ((buf_size) || (uncomp_size))
return MZ_FALSE;
}
// Try to do any allocations before writing to the archive, so if an allocation fails the file remains unmodified. (A good idea if we're doing an in-place modification.)
if ((!mz_zip_array_ensure_room(pZip, &pState->m_central_dir, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size)) || (!mz_zip_array_ensure_room(pZip, &pState->m_central_dir_offsets, 1)))
return MZ_FALSE;
if ((!store_data_uncompressed) && (buf_size))
{
if (NULL == (pComp = (tdefl_compressor *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(tdefl_compressor))))
return MZ_FALSE;
}
if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes + sizeof(local_dir_header)))
{
pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
return MZ_FALSE;
}
local_dir_header_ofs += num_alignment_padding_bytes;
if (pZip->m_file_offset_alignment) { MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0); }
cur_archive_file_ofs += num_alignment_padding_bytes + sizeof(local_dir_header);
MZ_CLEAR_OBJ(local_dir_header);
if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size)
{
pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
return MZ_FALSE;
}
cur_archive_file_ofs += archive_name_size;
if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
{
uncomp_crc32 = (mz_uint32)mz_crc32(MZ_CRC32_INIT, (const mz_uint8*)pBuf, buf_size);
uncomp_size = buf_size;
if (uncomp_size <= 3)
{
level = 0;
store_data_uncompressed = MZ_TRUE;
}
}
if (store_data_uncompressed)
{
if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pBuf, buf_size) != buf_size)
{
pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
return MZ_FALSE;
}
cur_archive_file_ofs += buf_size;
comp_size = buf_size;
if (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)
method = MZ_DEFLATED;
}
else if (buf_size)
{
mz_zip_writer_add_state state;
state.m_pZip = pZip;
state.m_cur_archive_file_ofs = cur_archive_file_ofs;
state.m_comp_size = 0;
if ((tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state, tdefl_create_comp_flags_from_zip_params(level, -15, MZ_DEFAULT_STRATEGY)) != TDEFL_STATUS_OKAY) ||
(tdefl_compress_buffer(pComp, pBuf, buf_size, TDEFL_FINISH) != TDEFL_STATUS_DONE))
{
pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
return MZ_FALSE;
}
comp_size = state.m_comp_size;
cur_archive_file_ofs = state.m_cur_archive_file_ofs;
method = MZ_DEFLATED;
}
pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
pComp = NULL;
// no zip64 support yet
if ((comp_size > 0xFFFFFFFF) || (cur_archive_file_ofs > 0xFFFFFFFF))
return MZ_FALSE;
if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, 0, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date))
return MZ_FALSE;
if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header))
return MZ_FALSE;
if (!mz_zip_writer_add_to_central_dir(pZip, pArchive_name, (mz_uint16)archive_name_size, NULL, 0, pComment, comment_size, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date, local_dir_header_ofs, ext_attributes))
return MZ_FALSE;
pZip->m_total_files++;
pZip->m_archive_size = cur_archive_file_ofs;
return MZ_TRUE;
}
#ifndef MINIZ_NO_STDIO
mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags)
{
mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes;
mz_uint16 method = 0, dos_time = 0, dos_date = 0, ext_attributes = 0;
mz_uint64 local_dir_header_ofs = pZip->m_archive_size, cur_archive_file_ofs = pZip->m_archive_size, uncomp_size = 0, comp_size = 0;
size_t archive_name_size;
mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE];
MZ_FILE *pSrc_file = NULL;
if ((int)level_and_flags < 0)
level_and_flags = MZ_DEFAULT_LEVEL;
level = level_and_flags & 0xF;
if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pArchive_name) || ((comment_size) && (!pComment)) || (level > MZ_UBER_COMPRESSION))
return MZ_FALSE;
if (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)
return MZ_FALSE;
if (!mz_zip_writer_validate_archive_name(pArchive_name))
return MZ_FALSE;
archive_name_size = strlen(pArchive_name);
if (archive_name_size > 0xFFFF)
return MZ_FALSE;
num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
// no zip64 support yet
if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + comment_size + archive_name_size) > 0xFFFFFFFF))
return MZ_FALSE;
if (!mz_zip_get_file_modified_time(pSrc_filename, &dos_time, &dos_date))
return MZ_FALSE;
pSrc_file = MZ_FOPEN(pSrc_filename, "rb");
if (!pSrc_file)
return MZ_FALSE;
MZ_FSEEK64(pSrc_file, 0, SEEK_END);
uncomp_size = MZ_FTELL64(pSrc_file);
MZ_FSEEK64(pSrc_file, 0, SEEK_SET);
if (uncomp_size > 0xFFFFFFFF)
{
// No zip64 support yet
MZ_FCLOSE(pSrc_file);
return MZ_FALSE;
}
if (uncomp_size <= 3)
level = 0;
if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes + sizeof(local_dir_header)))
{
MZ_FCLOSE(pSrc_file);
return MZ_FALSE;
}
local_dir_header_ofs += num_alignment_padding_bytes;
if (pZip->m_file_offset_alignment) { MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0); }
cur_archive_file_ofs += num_alignment_padding_bytes + sizeof(local_dir_header);
MZ_CLEAR_OBJ(local_dir_header);
if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size)
{
MZ_FCLOSE(pSrc_file);
return MZ_FALSE;
}
cur_archive_file_ofs += archive_name_size;
if (uncomp_size)
{
mz_uint64 uncomp_remaining = uncomp_size;
void *pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, MZ_ZIP_MAX_IO_BUF_SIZE);
if (!pRead_buf)
{
MZ_FCLOSE(pSrc_file);
return MZ_FALSE;
}
if (!level)
{
while (uncomp_remaining)
{
mz_uint n = (mz_uint)MZ_MIN(MZ_ZIP_MAX_IO_BUF_SIZE, uncomp_remaining);
if ((MZ_FREAD(pRead_buf, 1, n, pSrc_file) != n) || (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pRead_buf, n) != n))
{
pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
MZ_FCLOSE(pSrc_file);
return MZ_FALSE;
}
uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, n);
uncomp_remaining -= n;
cur_archive_file_ofs += n;
}
comp_size = uncomp_size;
}
else
{
mz_bool result = MZ_FALSE;
mz_zip_writer_add_state state;
tdefl_compressor *pComp = (tdefl_compressor *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(tdefl_compressor));
if (!pComp)
{
pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
MZ_FCLOSE(pSrc_file);
return MZ_FALSE;
}
state.m_pZip = pZip;
state.m_cur_archive_file_ofs = cur_archive_file_ofs;
state.m_comp_size = 0;
if (tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state, tdefl_create_comp_flags_from_zip_params(level, -15, MZ_DEFAULT_STRATEGY)) != TDEFL_STATUS_OKAY)
{
pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
MZ_FCLOSE(pSrc_file);
return MZ_FALSE;
}
for ( ; ; )
{
size_t in_buf_size = (mz_uint32)MZ_MIN(uncomp_remaining, MZ_ZIP_MAX_IO_BUF_SIZE);
tdefl_status status;
if (MZ_FREAD(pRead_buf, 1, in_buf_size, pSrc_file) != in_buf_size)
break;
uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, in_buf_size);
uncomp_remaining -= in_buf_size;
status = tdefl_compress_buffer(pComp, pRead_buf, in_buf_size, uncomp_remaining ? TDEFL_NO_FLUSH : TDEFL_FINISH);
if (status == TDEFL_STATUS_DONE)
{
result = MZ_TRUE;
break;
}
else if (status != TDEFL_STATUS_OKAY)
break;
}
pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
if (!result)
{
pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
MZ_FCLOSE(pSrc_file);
return MZ_FALSE;
}
comp_size = state.m_comp_size;
cur_archive_file_ofs = state.m_cur_archive_file_ofs;
method = MZ_DEFLATED;
}
pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
}
MZ_FCLOSE(pSrc_file); pSrc_file = NULL;
// no zip64 support yet
if ((comp_size > 0xFFFFFFFF) || (cur_archive_file_ofs > 0xFFFFFFFF))
return MZ_FALSE;
if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, 0, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date))
return MZ_FALSE;
if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header))
return MZ_FALSE;
if (!mz_zip_writer_add_to_central_dir(pZip, pArchive_name, (mz_uint16)archive_name_size, NULL, 0, pComment, comment_size, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date, local_dir_header_ofs, ext_attributes))
return MZ_FALSE;
pZip->m_total_files++;
pZip->m_archive_size = cur_archive_file_ofs;
return MZ_TRUE;
}
#endif // #ifndef MINIZ_NO_STDIO
mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint file_index)
{
mz_uint n, bit_flags, num_alignment_padding_bytes;
mz_uint64 comp_bytes_remaining, local_dir_header_ofs;
mz_uint64 cur_src_file_ofs, cur_dst_file_ofs;
mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
mz_uint8 central_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE];
size_t orig_central_dir_size;
mz_zip_internal_state *pState;
void *pBuf; const mz_uint8 *pSrc_central_header;
if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING))
return MZ_FALSE;
if (NULL == (pSrc_central_header = mz_zip_reader_get_cdh(pSource_zip, file_index)))
return MZ_FALSE;
pState = pZip->m_pState;
num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
// no zip64 support yet
if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) > 0xFFFFFFFF))
return MZ_FALSE;
cur_src_file_ofs = pSource_zip->m_archive_file_ofs + MZ_READ_LE32(pSrc_central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS);
cur_dst_file_ofs = pZip->m_archive_size;
if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
return MZ_FALSE;
if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
return MZ_FALSE;
cur_src_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE;
if (!mz_zip_writer_write_zeros(pZip, cur_dst_file_ofs, num_alignment_padding_bytes))
return MZ_FALSE;
cur_dst_file_ofs += num_alignment_padding_bytes;
local_dir_header_ofs = cur_dst_file_ofs;
if (pZip->m_file_offset_alignment) { MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0); }
if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
return MZ_FALSE;
cur_dst_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE;
n = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
comp_bytes_remaining = n + MZ_READ_LE32(pSrc_central_header + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS);
if (NULL == (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)MZ_MAX(sizeof(mz_uint32) * 4, MZ_MIN(MZ_ZIP_MAX_IO_BUF_SIZE, comp_bytes_remaining)))))
return MZ_FALSE;
while (comp_bytes_remaining)
{
n = (mz_uint)MZ_MIN(MZ_ZIP_MAX_IO_BUF_SIZE, comp_bytes_remaining);
if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, n) != n)
{
pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
return MZ_FALSE;
}
cur_src_file_ofs += n;
if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n)
{
pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
return MZ_FALSE;
}
cur_dst_file_ofs += n;
comp_bytes_remaining -= n;
}
bit_flags = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_BIT_FLAG_OFS);
if (bit_flags & 8)
{
// Copy data descriptor
if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, sizeof(mz_uint32) * 4) != sizeof(mz_uint32) * 4)
{
pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
return MZ_FALSE;
}
n = sizeof(mz_uint32) * ((MZ_READ_LE32(pBuf) == 0x08074b50) ? 4 : 3);
if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n)
{
pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
return MZ_FALSE;
}
cur_src_file_ofs += n;
cur_dst_file_ofs += n;
}
pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
// no zip64 support yet
if (cur_dst_file_ofs > 0xFFFFFFFF)
return MZ_FALSE;
orig_central_dir_size = pState->m_central_dir.m_size;
memcpy(central_header, pSrc_central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE);
MZ_WRITE_LE32(central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS, local_dir_header_ofs);
if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE))
return MZ_FALSE;
n = MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_EXTRA_LEN_OFS) + MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_COMMENT_LEN_OFS);
if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n))
{
mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
return MZ_FALSE;
}
if (pState->m_central_dir.m_size > 0xFFFFFFFF)
return MZ_FALSE;
n = (mz_uint32)orig_central_dir_size;
if (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, &n, 1))
{
mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
return MZ_FALSE;
}
pZip->m_total_files++;
pZip->m_archive_size = cur_dst_file_ofs;
return MZ_TRUE;
}
mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip)
{
mz_zip_internal_state *pState;
mz_uint64 central_dir_ofs, central_dir_size;
mz_uint8 hdr[MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE];
if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING))
return MZ_FALSE;
pState = pZip->m_pState;
// no zip64 support yet
if ((pZip->m_total_files > 0xFFFF) || ((pZip->m_archive_size + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) > 0xFFFFFFFF))
return MZ_FALSE;
central_dir_ofs = 0;
central_dir_size = 0;
if (pZip->m_total_files)
{
// Write central directory
central_dir_ofs = pZip->m_archive_size;
central_dir_size = pState->m_central_dir.m_size;
pZip->m_central_directory_file_ofs = central_dir_ofs;
if (pZip->m_pWrite(pZip->m_pIO_opaque, central_dir_ofs, pState->m_central_dir.m_p, (size_t)central_dir_size) != central_dir_size)
return MZ_FALSE;
pZip->m_archive_size += central_dir_size;
}
// Write end of central directory record
MZ_CLEAR_OBJ(hdr);
MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_SIG_OFS, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG);
MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS, pZip->m_total_files);
MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS, pZip->m_total_files);
MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_SIZE_OFS, central_dir_size);
MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_OFS_OFS, central_dir_ofs);
if (pZip->m_pWrite(pZip->m_pIO_opaque, pZip->m_archive_size, hdr, sizeof(hdr)) != sizeof(hdr))
return MZ_FALSE;
#ifndef MINIZ_NO_STDIO
if ((pState->m_pFile) && (MZ_FFLUSH(pState->m_pFile) == EOF))
return MZ_FALSE;
#endif // #ifndef MINIZ_NO_STDIO
pZip->m_archive_size += sizeof(hdr);
pZip->m_zip_mode = MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED;
return MZ_TRUE;
}
mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **pBuf, size_t *pSize)
{
if ((!pZip) || (!pZip->m_pState) || (!pBuf) || (!pSize))
return MZ_FALSE;
if (pZip->m_pWrite != mz_zip_heap_write_func)
return MZ_FALSE;
if (!mz_zip_writer_finalize_archive(pZip))
return MZ_FALSE;
*pBuf = pZip->m_pState->m_pMem;
*pSize = pZip->m_pState->m_mem_size;
pZip->m_pState->m_pMem = NULL;
pZip->m_pState->m_mem_size = pZip->m_pState->m_mem_capacity = 0;
return MZ_TRUE;
}
mz_bool mz_zip_writer_end(mz_zip_archive *pZip)
{
mz_zip_internal_state *pState;
mz_bool status = MZ_TRUE;
if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || ((pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) && (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED)))
return MZ_FALSE;
pState = pZip->m_pState;
pZip->m_pState = NULL;
mz_zip_array_clear(pZip, &pState->m_central_dir);
mz_zip_array_clear(pZip, &pState->m_central_dir_offsets);
mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets);
#ifndef MINIZ_NO_STDIO
if (pState->m_pFile)
{
MZ_FCLOSE(pState->m_pFile);
pState->m_pFile = NULL;
}
#endif // #ifndef MINIZ_NO_STDIO
if ((pZip->m_pWrite == mz_zip_heap_write_func) && (pState->m_pMem))
{
pZip->m_pFree(pZip->m_pAlloc_opaque, pState->m_pMem);
pState->m_pMem = NULL;
}
pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
pZip->m_zip_mode = MZ_ZIP_MODE_INVALID;
return status;
}
#ifndef MINIZ_NO_STDIO
mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags)
{
mz_bool status, created_new_archive = MZ_FALSE;
mz_zip_archive zip_archive;
struct MZ_FILE_STAT_STRUCT file_stat;
MZ_CLEAR_OBJ(zip_archive);
if ((int)level_and_flags < 0)
level_and_flags = MZ_DEFAULT_LEVEL;
if ((!pZip_filename) || (!pArchive_name) || ((buf_size) && (!pBuf)) || ((comment_size) && (!pComment)) || ((level_and_flags & 0xF) > MZ_UBER_COMPRESSION))
return MZ_FALSE;
if (!mz_zip_writer_validate_archive_name(pArchive_name))
return MZ_FALSE;
if (MZ_FILE_STAT(pZip_filename, &file_stat) != 0)
{
// Create a new archive.
if (!mz_zip_writer_init_file(&zip_archive, pZip_filename, 0))
return MZ_FALSE;
created_new_archive = MZ_TRUE;
}
else
{
// Append to an existing archive.
if (!mz_zip_reader_init_file(&zip_archive, pZip_filename, level_and_flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY))
return MZ_FALSE;
if (!mz_zip_writer_init_from_reader(&zip_archive, pZip_filename))
{
mz_zip_reader_end(&zip_archive);
return MZ_FALSE;
}
}
status = mz_zip_writer_add_mem_ex(&zip_archive, pArchive_name, pBuf, buf_size, pComment, comment_size, level_and_flags, 0, 0);
// Always finalize, even if adding failed for some reason, so we have a valid central directory. (This may not always succeed, but we can try.)
if (!mz_zip_writer_finalize_archive(&zip_archive))
status = MZ_FALSE;
if (!mz_zip_writer_end(&zip_archive))
status = MZ_FALSE;
if ((!status) && (created_new_archive))
{
// It's a new archive and something went wrong, so just delete it.
int ignoredStatus = MZ_DELETE_FILE(pZip_filename);
(void)ignoredStatus;
}
return status;
}
void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint flags)
{
int file_index;
mz_zip_archive zip_archive;
void *p = NULL;
if (pSize)
*pSize = 0;
if ((!pZip_filename) || (!pArchive_name))
return NULL;
MZ_CLEAR_OBJ(zip_archive);
if (!mz_zip_reader_init_file(&zip_archive, pZip_filename, flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY))
return NULL;
if ((file_index = mz_zip_reader_locate_file(&zip_archive, pArchive_name, NULL, flags)) >= 0)
p = mz_zip_reader_extract_to_heap(&zip_archive, file_index, pSize, flags);
mz_zip_reader_end(&zip_archive);
return p;
}
#endif // #ifndef MINIZ_NO_STDIO
#endif // #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
#endif // #ifndef MINIZ_NO_ARCHIVE_APIS
#ifdef __cplusplus
}
#endif
#endif // MINIZ_HEADER_FILE_ONLY
/*
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>
*/
diff --git a/Core/CppMicroServices/third_party/miniz_v115_r4.patch b/Core/CppMicroServices/third_party/miniz_v115_r4.patch
index 0ec308cd79..7fba1f9627 100644
--- a/Core/CppMicroServices/third_party/miniz_v115_r4.patch
+++ b/Core/CppMicroServices/third_party/miniz_v115_r4.patch
@@ -1,77 +1,94 @@
---- a/miniz.c 2013-10-14 04:02:24.000000000 +0200
-+++ b/miniz.c 2014-10-28 14:08:19.668529223 +0100
+--- /home/sascha/miniz.c 2013-10-14 04:02:24.000000000 +0200
++++ miniz.c 2014-11-19 23:10:15.744583538 +0100
@@ -535,6 +535,7 @@
typedef struct mz_zip_archive_tag
{
mz_uint64 m_archive_size;
+ mz_uint64 m_archive_file_ofs;
mz_uint64 m_central_directory_file_ofs;
mz_uint m_total_files;
mz_zip_mode m_zip_mode;
-@@ -3180,6 +3181,8 @@
- cur_file_ofs = MZ_MAX((mz_int64)pZip->m_archive_size - (mz_int64)sizeof(buf_u32), 0);
- for ( ; ; )
- {
-+ for ( ; ; )
-+ {
- int i, n = (int)MZ_MIN(sizeof(buf_u32), pZip->m_archive_size - cur_file_ofs);
+@@ -3173,6 +3174,7 @@
+ const mz_uint8 *p;
+ mz_uint32 buf_u32[4096 / sizeof(mz_uint32)]; mz_uint8 *pBuf = (mz_uint8 *)buf_u32;
+ mz_bool sort_central_dir = ((flags & MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0);
++ mz_bool zip_signature_found = 0;
+ // Basic sanity checks - reject files which are too small, and check the first 4 bytes of the file to make sure a local header is there.
+ if (pZip->m_archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
+ return MZ_FALSE;
+@@ -3184,23 +3186,30 @@
if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, n) != (mz_uint)n)
return MZ_FALSE;
-@@ -3191,16 +3194,18 @@
+ for (i = n - 4; i >= 0; --i)
++ {
+ if (MZ_READ_LE32(pBuf + i) == MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG)
++ {
++ // Read and verify the end of central directory record.
++ if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs + i, pBuf, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
++ continue;
++ if ((MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_SIG_OFS) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG) ||
++ ((pZip->m_total_files = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS)) != MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS)))
++ continue;
++ zip_signature_found = 1;
+ break;
+- if (i >= 0)
++ }
++ }
++
++ if (zip_signature_found)
+ {
cur_file_ofs += i;
break;
}
- if ((!cur_file_ofs) || ((pZip->m_archive_size - cur_file_ofs) >= (0xFFFF + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)))
-+ if ((!cur_file_ofs) || (cur_file_ofs < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE))
++ if ((!cur_file_ofs) || (cur_file_ofs < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE))
return MZ_FALSE;
- cur_file_ofs = MZ_MAX(cur_file_ofs - (sizeof(buf_u32) - 3), 0);
+- cur_file_ofs = MZ_MAX(cur_file_ofs - (sizeof(buf_u32) - 3), 0);
++
++ cur_file_ofs = MZ_MAX(cur_file_ofs - (mz_int64)(sizeof(buf_u32) - 3), 0);
}
- // Read and verify the end of central directory record.
- if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
+- // Read and verify the end of central directory record.
+- if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
- return MZ_FALSE;
-+ continue;
- if ((MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_SIG_OFS) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG) ||
- ((pZip->m_total_files = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS)) != MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS)))
+- if ((MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_SIG_OFS) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG) ||
+- ((pZip->m_total_files = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS)) != MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS)))
- return MZ_FALSE;
-+ continue;
-+ break;
-+ }
num_this_disk = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_THIS_DISK_OFS);
cdir_disk_index = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS);
-@@ -3210,12 +3215,16 @@
+@@ -3210,12 +3219,16 @@
if ((cdir_size = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_SIZE_OFS)) < pZip->m_total_files * MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)
return MZ_FALSE;
- cdir_ofs = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_OFS_OFS);
+ cdir_ofs = cur_file_ofs - cdir_size;
if ((cdir_ofs + (mz_uint64)cdir_size) > pZip->m_archive_size)
return MZ_FALSE;
pZip->m_central_directory_file_ofs = cdir_ofs;
+ pZip->m_archive_file_ofs = cdir_ofs - MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_OFS_OFS);
+ if (pZip->m_archive_file_ofs > pZip->m_archive_size)
+ return MZ_FALSE;
+
if (pZip->m_total_files)
{
mz_uint i, n;
-@@ -3573,7 +3582,7 @@
+@@ -3573,7 +3586,7 @@
return MZ_FALSE;
// Read and parse the local directory entry.
- cur_file_ofs = file_stat.m_local_header_ofs;
+ cur_file_ofs = pZip->m_archive_file_ofs + file_stat.m_local_header_ofs;
if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
return MZ_FALSE;
if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
-@@ -4610,7 +4619,7 @@
+@@ -4610,7 +4623,7 @@
if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) > 0xFFFFFFFF))
return MZ_FALSE;
- cur_src_file_ofs = MZ_READ_LE32(pSrc_central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS);
+ cur_src_file_ofs = pSource_zip->m_archive_file_ofs + MZ_READ_LE32(pSrc_central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS);
cur_dst_file_ofs = pZip->m_archive_size;
if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
diff --git a/Documentation/Doxygen/DeveloperManual/Starting/SettingUpMITK/SupportedPlatforms.md b/Documentation/Doxygen/DeveloperManual/Starting/SettingUpMITK/SupportedPlatforms.md
index 6b3da15e32..f23e467c9d 100644
--- a/Documentation/Doxygen/DeveloperManual/Starting/SettingUpMITK/SupportedPlatforms.md
+++ b/Documentation/Doxygen/DeveloperManual/Starting/SettingUpMITK/SupportedPlatforms.md
@@ -1,53 +1,52 @@
Supported Platforms {#SupportedPlatformsPage}
===================
MITK is a cross-platform framework and is available for the following platforms:
- Windows
- Linux/X11
- Mac OS X
Supported Platforms Details
---------------------------
The MITK team provides support for the most frequently used platforms and continuously runs testing procedures
to ensure compatibility. Due to the large amount of possible combinations of operating systems and compiler versions,
we divide platform support into two test categories (Tier 1 and Tier 2).
Although MITK may be built on a range of platform-compiler combinations, only a subset of these are actively
support by the MITK development team.
Tier 1 Platforms
----------------
All Tier 1 platforms are continuously tested by our unit test suite and other internal testing procedures.
Errors or bugs discovered in these platforms are prioritized and corrected as soon as possible.
| Platform | Compilers
| ----------------------------------- | -----------------------------
| Ubuntu Linux 12.04 (64-bit) | gcc as provided by Ubuntu
| Microsoft Windows 7 (64-bit) | MSVC 2010 Professional SP1 (x64)
-| Apple Mac OS X 10.7 "Lion" | LLVM-GCC as provided by Apple
-| Apple OS X 10.8 "Mountain Lion" | LLVM-GCC as provided by Apple
+| Apple OS X 10.9 "Mavericks" | LLVM-Clang 6.0 as provided by Apple (XCode)
Tier 2 Platforms
----------------
Tier 2 platforms may or may not be tested on a regular basis. Some Tier 2 platforms are used by individual
members of the MITK development team on a daily basis and some only receive occasional testing. While we
strive to support these platforms, MITK users should note that errors may be present in released versions
as well as in the current master branch.
| Platform | Compilers
| ---------------------------------- | -----------------------------
| Fedora 20 (64-bit) | gcc as provided by Fedora
| Fedora 20 (64-bit) | Clang as provided by Fedora
| Microsoft Windows 7 (32-bit) | MSVC 2012 Express (x64)
-| Apple OS X 10.9 "Mavericks" | Clang as provided by Apple (XCode)
+| Apple OS X 10.7 "Lion" | LLVM-Clang as provided by Apple (XCode)
All platforms not listed above are not officially supported by the MITK team. However, we will happily accept
contributions to improve support for other platforms.
diff --git a/Documentation/Doxygen/UserManual/MITKPluginManualsList.dox b/Documentation/Doxygen/UserManual/MITKPluginManualsList.dox
index be03f2ba30..9e6cfc40e6 100644
--- a/Documentation/Doxygen/UserManual/MITKPluginManualsList.dox
+++ b/Documentation/Doxygen/UserManual/MITKPluginManualsList.dox
@@ -1,46 +1,46 @@
/**
\page PluginListPage MITK Plugin Manuals
\section PluginListPageOverview Overview
The plugins and bundles provide much of the extended functionality of MITK. Each encapsulates a solution to a problem and associated features. This way one can easily assemble the necessary capabilites for a workflow without adding a lot of bloat, by combining plugins as needed.
The distinction between developer and end user use is for convenience only and mainly distinguishes which group a plugin is primarily aimed at.
\section PluginListPageEndUserPluginList List of Plugins for End User Use
\li \subpage org_blueberry_ui_qt_log
\li \subpage org_mitk_views_basicimageprocessing
\li \subpage org_mitk_views_cmdlinemodules
\li \subpage org_mitk_views_datamanager
\li \subpage org_mitk_gui_qt_dicom
\li \subpage org_mitk_gui_qt_diffusionimaging
\li \subpage org_mitk_views_imagecropper
\li \subpage org_mitk_views_imagenavigator
\li \subpage org_mitk_gui_qt_measurementtoolbox
- \li \subpage org_mitk_views_meshdecimation
- \li \subpage org_mitk_views_moviemaker
+ \li \subpage org_mitk_gui_qt_moviemaker
\li \subpage org_mitk_views_screenshotmaker
\li \subpage org_mitk_views_pointsetinteraction
\li \subpage org_mitk_gui_qt_python
\li \subpage org_mitk_gui_qt_registration
\li \subpage org_mitk_gui_qt_remeshing
\li \subpage org_mitk_views_segmentation
\li \subpage org_mitk_gui_qt_ultrasound
\li \subpage org_mitk_gui_qt_viewnavigator
\li \subpage org_mitk_views_volumevisualization
\li \subpage org_mitk_gui_qt_xnat
-
+ \li \subpage org_mitk_gui_qt_aicpregistration
+
\section PluginListPageDevPluginList List of Plugins for Developer Use and Examples
\li \subpage org_surfacematerialeditor
\li \subpage org_toftutorial
\li \subpage org_mitk_gui_qt_examples
\li \subpage org_mitkexamplesopencv
\li \subpage org_mitk_gui_qt_igtexample
\li \subpage org_mitk_gui_qt_igttracking
\li \subpage org_blueberry_ui_qt_objectinspector
\li \subpage org_mitk_gui_qt_eventrecorder
*/
diff --git a/Documentation/Doxygen/UserManual/MiniApps.dox b/Documentation/Doxygen/UserManual/MiniApps.dox
index 7b7af0fa00..cc1cd1d413 100644
--- a/Documentation/Doxygen/UserManual/MiniApps.dox
+++ b/Documentation/Doxygen/UserManual/MiniApps.dox
@@ -1,70 +1,47 @@
/**
\page MiniAppExplainPage MITK MiniApps
\section MiniAppExplainPageDescription What are MiniApps
MiniApps are small compilations of command line tools. Each of these tools is designed to fulfill one simple task,
-e.g. resample an image or extract image statistics of a given region of interest (ROI). Several tools that relate to
-a similar topic or research area are grouped into one MiniApp.
+e.g. resample an image or extract image statistics of a given region of interest (ROI).
They are intended to provide command line access to a variety of features of MITK, thus facilitating batched processing of data.
\section MiniAppExplainPageUsage Usage
-The MiniApps are built in a self-describing way. When calling a MiniApp without any arguments it will list
-all available sub-tools. When calling e.g. the DiffusionMiniApp it will look similarly to this:
+The MiniApps are built in a self-describing way, that is they follow the usual print out about parameters when called without any argumments, e.g.
\code
-$./MitkDiffusionMiniApps
+$./MitkGibbsTracking
-Please choose the mini app to execute:
-(0) BatchedFolderRegistration
-(1) CopyGeometry
-(2) DicomFolderDump
-(3) DiffusionIndices
-(4) DwiDenoising
-(5) ExportShImage
-(6) ExtractImageStatistics
-(7) FiberDirectionExtraction
-(8) FiberProcessing
-(9) FileFormatConverter
-(10) GibbsTracking
-(11) LocalDirectionalFiberPlausibility
-(12) MultishellMethods
-(13) NetworkCreation
-(14) NetworkStatistics
-(15) PeakExtraction
-(16) PeaksAngularError
-(17) QballReconstruction
-(18) StreamlineTracking
-(19) TensorDerivedMapsExtraction
-(20) TensorReconstruction
-Please select:
-\endcode
-
-In order to select one of those tools simply append the displayed name to call, e.g. GibbsTracking
-this will provide a listing of the parameters of that tool:
-\code
-$./MitkDiffusionMiniApps GibbsTracking
-
-[1.081] Start GibbsTracking ..
-i, --input, input image (tensor, Q-ball or FSL/MRTrix SH-coefficient image)
-p, --parameters, parameter file (.gtp)
-m, --mask, binary mask image (optional)
-s, --shConvention, sh coefficient convention (FSL, MRtrix) (optional), (default: FSL)
-o, --outFile, output fiber bundle (.fib)
-f, --noFlip, do not flip input image to match MITK coordinate convention (optional)
\endcode
-To execute the tool with parameters an exemplary call would look like this:
+They also follow the <a href="http://www.slicer.org/slicerWiki/index.php/Slicer3:Execution_Model_Documentation">Slicer Execution Model</a> in describing themselves via xml:
\code
-$./MitkDiffusionMiniApps GibbsTracking -i test.dti -p param.gtp -o /tmp/fiber.fib
+$./GibbsTracking --xml
+<executable>
+<category>Fiber Tracking and Processing Methods</category>
+<title>Gibbs Tracking</title>
+<description></description>
+<contributor>MBI</contributor>
+<parameters>
+...
+</parameters>
+</executable>
\endcode
+\note Full conformity is still a work in progress.
\section MiniAppExplainPageAvailableList Available MiniApps
\li \subpage DiffusionMiniApps
*/
diff --git a/Examples/BlueBerryExampleLauncher/CMakeLists.txt b/Examples/BlueBerryExampleLauncher/CMakeLists.txt
index 2cd2b7188d..3ce31cf4e1 100644
--- a/Examples/BlueBerryExampleLauncher/CMakeLists.txt
+++ b/Examples/BlueBerryExampleLauncher/CMakeLists.txt
@@ -1,85 +1,93 @@
project(BlueBerryExampleLauncher)
set(_source_files
BlueBerryExampleLauncher.cpp
BlueBerryExampleLauncherDialog.cpp
)
set(_source_moc_h_files
BlueBerryExampleLauncherDialog.h
)
set(_source_ui_files
BlueBerryExampleLauncherDialog.ui
)
# this is a workaround for Visual Studio. The relative include paths in the generated
# moc files can get very long and can't be resolved by the MSVC compiler.
foreach(_moc_src ${_source_moc_h_files})
- qt4_wrap_cpp(_source_files ${_moc_src} OPTIONS -f${_moc_src})
+ if (DESIRED_QT_VERSION MATCHES "5")
+ qt5_wrap_cpp(_source_files ${_moc_src} OPTIONS -f${_moc_src})
+ else()
+ qt4_wrap_cpp(_source_files ${_moc_src} OPTIONS -f${_moc_src})
+ endif()
endforeach()
-qt4_wrap_ui(_source_files ${_source_ui_files})
+if (DESIRED_QT_VERSION MATCHES "5")
+ qt5_wrap_ui(_source_files ${_source_ui_files})
+else()
+ qt4_wrap_ui(_source_files ${_source_ui_files})
+endif()
include_directories(${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
)
#-----------------------------------------------------------------------------
# Create provisioning files
#-----------------------------------------------------------------------------
set(_plugins_for_all_demos
org.blueberry.compat
)
file(GLOB _demo_configurations Configurations/*.cmake)
set(ALL_REQUIRED_PLUGINS ${_plugins_for_all_demos})
foreach(_demo_config_file ${_demo_configurations})
set(REQUIRED_PLUGINS )
set(DESCRIPTION )
include(${_demo_config_file})
get_filename_component(_name ${_demo_config_file} NAME_WE)
FunctionCreateProvisioningFile(FILE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${PROJECT_NAME}_${_name}.provisioning
PLUGINS ${REQUIRED_PLUGINS} ${_plugins_for_all_demos}
NO_INSTALL
)
if(DESCRIPTION)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/BlueBerryExampleDescription.txt
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${PROJECT_NAME}_${_name}.txt @ONLY)
endif()
list(APPEND ALL_REQUIRED_PLUGINS ${REQUIRED_PLUGINS})
endforeach()
list(REMOVE_DUPLICATES ALL_REQUIRED_PLUGINS)
set(ALL_REQUIRED_PLUGIN_TARGETS )
foreach(req_plugin ${ALL_REQUIRED_PLUGINS})
string(REPLACE "." "_" _plugin_target ${req_plugin})
if(TARGET ${_plugin_target})
list(APPEND ALL_REQUIRED_PLUGIN_TARGETS ${_plugin_target})
endif()
endforeach()
#-----------------------------------------------------------------------------
# Create the example launcher
#-----------------------------------------------------------------------------
FunctionCreateBlueBerryApplication(
NAME ${PROJECT_NAME}
DESCRIPTION "MITK Application Framework Demo"
SOURCES ${_source_files}
# PLUGINS ${ALL_REQUIRED_PLUGIN_TARGETS}
NO_PROVISIONING
NO_INSTALL
SHOW_CONSOLE
)
-mitk_use_modules(TARGET ${PROJECT_NAME} PACKAGES Qt4|QtGui)
+mitk_use_modules(TARGET ${PROJECT_NAME} PACKAGES Qt4|QtGui Qt5|Widgets)
add_dependencies(${PROJECT_NAME} ${ALL_REQUIRED_PLUGIN_TARGETS})
# subproject support
set_property(TARGET ${PROJECT_NAME} PROPERTY LABELS ${MITK_DEFAULT_SUBPROJECTS})
foreach(subproject ${MITK_DEFAULT_SUBPROJECTS})
add_dependencies(${subproject} ${PROJECT_NAME})
endforeach()
diff --git a/Examples/Plugins/org.mitk.example.gui.customviewer.views/src/internal/org_mitk_example_gui_customviewer_views_Activator.cpp b/Examples/Plugins/org.mitk.example.gui.customviewer.views/src/internal/org_mitk_example_gui_customviewer_views_Activator.cpp
index dc35d5ddc5..4eda975a56 100644
--- a/Examples/Plugins/org.mitk.example.gui.customviewer.views/src/internal/org_mitk_example_gui_customviewer_views_Activator.cpp
+++ b/Examples/Plugins/org.mitk.example.gui.customviewer.views/src/internal/org_mitk_example_gui_customviewer_views_Activator.cpp
@@ -1,48 +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.
===================================================================*/
#include "org_mitk_example_gui_customviewer_views_Activator.h"
#include "DicomView.h"
#include "SimpleRenderWindowView.h"
#include <QtPlugin>
ctkPluginContext* org_mitk_example_gui_customviewer_views_Activator::PluginContext = 0;
void org_mitk_example_gui_customviewer_views_Activator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(DicomView, context)
BERRY_REGISTER_EXTENSION_CLASS(SimpleRenderWindowView, context)
PluginContext = context;
}
void org_mitk_example_gui_customviewer_views_Activator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
PluginContext = 0;
}
ctkPluginContext* org_mitk_example_gui_customviewer_views_Activator::GetPluginContext()
{
return PluginContext;
}
-Q_EXPORT_PLUGIN2(org_mitk_example_gui_customviewer_views, org_mitk_example_gui_customviewer_views_Activator)
-
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_example_gui_customviewer_views, org_mitk_example_gui_customviewer_views_Activator)
+#endif
diff --git a/Examples/Plugins/org.mitk.example.gui.customviewer.views/src/internal/org_mitk_example_gui_customviewer_views_Activator.h b/Examples/Plugins/org.mitk.example.gui.customviewer.views/src/internal/org_mitk_example_gui_customviewer_views_Activator.h
index 5f84e99346..576c37adcf 100644
--- a/Examples/Plugins/org.mitk.example.gui.customviewer.views/src/internal/org_mitk_example_gui_customviewer_views_Activator.h
+++ b/Examples/Plugins/org.mitk.example.gui.customviewer.views/src/internal/org_mitk_example_gui_customviewer_views_Activator.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 org_mitk_example_gui_customviewer_views_Activator_H
#define org_mitk_example_gui_customviewer_views_Activator_H
#include <ctkPluginActivator.h>
class ctkPluginContext;
class org_mitk_example_gui_customviewer_views_Activator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_example_gui_customviewer_views")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
static ctkPluginContext* GetPluginContext();
private:
static ctkPluginContext* PluginContext;
};
#endif // org_mitk_example_gui_customviewer_views_Activator_H
diff --git a/Examples/Plugins/org.mitk.example.gui.customviewer/src/internal/org_mitk_example_gui_customviewer_Activator.cpp b/Examples/Plugins/org.mitk.example.gui.customviewer/src/internal/org_mitk_example_gui_customviewer_Activator.cpp
index 518103ebb2..2a48532fa0 100644
--- a/Examples/Plugins/org.mitk.example.gui.customviewer/src/internal/org_mitk_example_gui_customviewer_Activator.cpp
+++ b/Examples/Plugins/org.mitk.example.gui.customviewer/src/internal/org_mitk_example_gui_customviewer_Activator.cpp
@@ -1,50 +1,51 @@
/*===================================================================
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_example_gui_customviewer_Activator.h"
#include "CustomViewer.h"
#include "ViewerPerspective.h"
#include "DicomPerspective.h"
#include <QtPlugin>
ctkPluginContext* org_mitk_example_gui_customviewer_Activator::PluginContext = 0;
void org_mitk_example_gui_customviewer_Activator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(CustomViewer, context)
BERRY_REGISTER_EXTENSION_CLASS(ViewerPerspective, context)
BERRY_REGISTER_EXTENSION_CLASS(DicomPerspective, context)
PluginContext = context;
}
void org_mitk_example_gui_customviewer_Activator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
PluginContext = 0;
}
ctkPluginContext* org_mitk_example_gui_customviewer_Activator::GetPluginContext()
{
return PluginContext;
}
-Q_EXPORT_PLUGIN2(org_mitk_example_gui_customviewer, org_mitk_example_gui_customviewer_Activator)
-
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_example_gui_customviewer, org_mitk_example_gui_customviewer_Activator)
+#endif
diff --git a/Examples/Plugins/org.mitk.example.gui.customviewer/src/internal/org_mitk_example_gui_customviewer_Activator.h b/Examples/Plugins/org.mitk.example.gui.customviewer/src/internal/org_mitk_example_gui_customviewer_Activator.h
index 22dd6970c1..27a2b0e9c8 100644
--- a/Examples/Plugins/org.mitk.example.gui.customviewer/src/internal/org_mitk_example_gui_customviewer_Activator.h
+++ b/Examples/Plugins/org.mitk.example.gui.customviewer/src/internal/org_mitk_example_gui_customviewer_Activator.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 org_mitk_example_gui_customviewer_Activator_H
#define org_mitk_example_gui_customviewer_Activator_H
#include <ctkPluginActivator.h>
class ctkPluginContext;
// //! [PluginActivatorHeader]
class org_mitk_example_gui_customviewer_Activator : public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_example_gui_customviewer")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
static ctkPluginContext* GetPluginContext();
private:
static ctkPluginContext* PluginContext;
};
// //! [PluginActivatorHeader]
#endif // org_mitk_example_gui_customviewer_Activator_H
diff --git a/Examples/Plugins/org.mitk.example.gui.extensionpointcontribution/src/internal/org_mitk_example_gui_extensionpointcontribution_Activator.cpp b/Examples/Plugins/org.mitk.example.gui.extensionpointcontribution/src/internal/org_mitk_example_gui_extensionpointcontribution_Activator.cpp
index e44ad74007..1c8b726083 100644
--- a/Examples/Plugins/org.mitk.example.gui.extensionpointcontribution/src/internal/org_mitk_example_gui_extensionpointcontribution_Activator.cpp
+++ b/Examples/Plugins/org.mitk.example.gui.extensionpointcontribution/src/internal/org_mitk_example_gui_extensionpointcontribution_Activator.cpp
@@ -1,35 +1,38 @@
/*===================================================================
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_example_gui_extensionpointcontribution_Activator.h"
#include "ChangeTextToLowerCase.h"
#include "ChangeTextToUpperCase.h"
#include <QtPlugin>
void org_mitk_example_gui_extensionpointcontribution_Activator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(ChangeTextToLowerCase, context)
BERRY_REGISTER_EXTENSION_CLASS(ChangeTextToUpperCase, context)
}
void org_mitk_example_gui_extensionpointcontribution_Activator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
-Q_EXPORT_PLUGIN2(org_mitk_example_gui_extensionpointcontribution, org_mitk_example_gui_extensionpointcontribution_Activator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_example_gui_extensionpointcontribution, org_mitk_example_gui_extensionpointcontribution_Activator)
+#endif
+
diff --git a/Examples/Plugins/org.mitk.example.gui.extensionpointcontribution/src/internal/org_mitk_example_gui_extensionpointcontribution_Activator.h b/Examples/Plugins/org.mitk.example.gui.extensionpointcontribution/src/internal/org_mitk_example_gui_extensionpointcontribution_Activator.h
index 6cd46f0ada..263fb1264b 100644
--- a/Examples/Plugins/org.mitk.example.gui.extensionpointcontribution/src/internal/org_mitk_example_gui_extensionpointcontribution_Activator.h
+++ b/Examples/Plugins/org.mitk.example.gui.extensionpointcontribution/src/internal/org_mitk_example_gui_extensionpointcontribution_Activator.h
@@ -1,36 +1,39 @@
/*===================================================================
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 org_mitk_example_gui_extensionpointcontribution_Activator_H
#define org_mitk_example_gui_extensionpointcontribution_Activator_H
#include <ctkPluginActivator.h>
class org_mitk_example_gui_extensionpointcontribution_Activator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_example_gui_extensionpointcontribution")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
};
#endif // org_mitk_example_gui_extensionpointcontribution_Activator_H
diff --git a/Examples/Plugins/org.mitk.example.gui.extensionpointdefinition/src/internal/org_mitk_example_gui_extensionpointdefinition_Activator.cpp b/Examples/Plugins/org.mitk.example.gui.extensionpointdefinition/src/internal/org_mitk_example_gui_extensionpointdefinition_Activator.cpp
index f9edf73097..b28cd9175a 100644
--- a/Examples/Plugins/org.mitk.example.gui.extensionpointdefinition/src/internal/org_mitk_example_gui_extensionpointdefinition_Activator.cpp
+++ b/Examples/Plugins/org.mitk.example.gui.extensionpointdefinition/src/internal/org_mitk_example_gui_extensionpointdefinition_Activator.cpp
@@ -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.
===================================================================*/
#include "org_mitk_example_gui_extensionpointdefinition_Activator.h"
#include "ExtensionPointDefinition.h"
#include "MinimalPerspective.h"
#include "MinimalView.h"
#include <QtPlugin>
void org_mitk_example_gui_extensionpointdefinition_Activator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(ExtensionPointDefinition, context)
BERRY_REGISTER_EXTENSION_CLASS(MinimalPerspective, context)
BERRY_REGISTER_EXTENSION_CLASS(MinimalView, context)
}
void org_mitk_example_gui_extensionpointdefinition_Activator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
ChangeTextRegistry* org_mitk_example_gui_extensionpointdefinition_Activator::getChangeTextRegistry()
{
static ChangeTextRegistry registry;
return &registry;
}
-Q_EXPORT_PLUGIN2(org_mitk_example_gui_extensionpointdefinition, org_mitk_example_gui_extensionpointdefinition_Activator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_example_gui_extensionpointdefinition, org_mitk_example_gui_extensionpointdefinition_Activator)
+#endif
diff --git a/Examples/Plugins/org.mitk.example.gui.extensionpointdefinition/src/internal/org_mitk_example_gui_extensionpointdefinition_Activator.h b/Examples/Plugins/org.mitk.example.gui.extensionpointdefinition/src/internal/org_mitk_example_gui_extensionpointdefinition_Activator.h
index 52a9660365..0cf1942db2 100644
--- a/Examples/Plugins/org.mitk.example.gui.extensionpointdefinition/src/internal/org_mitk_example_gui_extensionpointdefinition_Activator.h
+++ b/Examples/Plugins/org.mitk.example.gui.extensionpointdefinition/src/internal/org_mitk_example_gui_extensionpointdefinition_Activator.h
@@ -1,43 +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 org_mitk_example_gui_extensionpointdefinition_Activator_H
#define org_mitk_example_gui_extensionpointdefinition_Activator_H
#include <ctkPluginActivator.h>
#include "ChangeTextRegistry.h"
class org_mitk_example_gui_extensionpointdefinition_Activator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_example_gui_extensionpointdefinition")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
/**
* Get the Registry (for extensions).
*/
static ChangeTextRegistry* getChangeTextRegistry();
};
#endif // org_mitk_example_gui_extensionpointdefinition_Activator_H
diff --git a/Examples/Plugins/org.mitk.example.gui.imaging/src/internal/mitkPluginActivator.cpp b/Examples/Plugins/org.mitk.example.gui.imaging/src/internal/mitkPluginActivator.cpp
index 7c4b40697a..42c32ff086 100644
--- a/Examples/Plugins/org.mitk.example.gui.imaging/src/internal/mitkPluginActivator.cpp
+++ b/Examples/Plugins/org.mitk.example.gui.imaging/src/internal/mitkPluginActivator.cpp
@@ -1,50 +1,52 @@
/*===================================================================
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 "mitkPluginActivator.h"
#include <QtPlugin>
#include "src/internal/colourimageprocessing/QmitkColourImageProcessingView.h"
#include "src/internal/isosurface/QmitkIsoSurface.h"
#include "src/internal/simpleexample/QmitkSimpleExampleView.h"
#include "src/internal/simplemeasurement/QmitkSimpleMeasurement.h"
#include "src/internal/viewinitialization/QmitkViewInitializationView.h"
#include "src/internal/volumetry/QmitkVolumetryView.h"
#include "src/internal/surfaceutilities/QmitkSurfaceUtilities.h"
namespace mitk {
void PluginActivator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(QmitkColourImageProcessingView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkIsoSurface, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkSimpleExampleView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkSimpleMeasurement, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkViewInitializationView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkVolumetryView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkSurfaceUtilities, context)
}
void PluginActivator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_examples, mitk::PluginActivator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_examples, mitk::PluginActivator)
+#endif
diff --git a/Examples/Plugins/org.mitk.example.gui.imaging/src/internal/mitkPluginActivator.h b/Examples/Plugins/org.mitk.example.gui.imaging/src/internal/mitkPluginActivator.h
index 489bd853ca..5dd5940465 100644
--- a/Examples/Plugins/org.mitk.example.gui.imaging/src/internal/mitkPluginActivator.h
+++ b/Examples/Plugins/org.mitk.example.gui.imaging/src/internal/mitkPluginActivator.h
@@ -1,40 +1,43 @@
/*===================================================================
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 MITKPLUGINACTIVATOR_H
#define MITKPLUGINACTIVATOR_H
#include <ctkPluginActivator.h>
#include <mitkExportMacros.h>
namespace mitk {
class MITK_LOCAL PluginActivator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_examples")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
}; // PluginActivator
}
#endif // MITKPLUGINACTIVATOR_H
diff --git a/Examples/Plugins/org.mitk.example.gui.minimalapplication/src/internal/org_mitk_example_gui_minimalapplication_Activator.cpp b/Examples/Plugins/org.mitk.example.gui.minimalapplication/src/internal/org_mitk_example_gui_minimalapplication_Activator.cpp
index 1ffd94fc04..016215472c 100644
--- a/Examples/Plugins/org.mitk.example.gui.minimalapplication/src/internal/org_mitk_example_gui_minimalapplication_Activator.cpp
+++ b/Examples/Plugins/org.mitk.example.gui.minimalapplication/src/internal/org_mitk_example_gui_minimalapplication_Activator.cpp
@@ -1,36 +1,38 @@
/*===================================================================
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_example_gui_minimalapplication_Activator.h"
#include "MinimalApplication.h"
#include "MinimalPerspective.h"
#include <QtPlugin>
void org_mitk_example_gui_minimalapplication_Activator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(MinimalApplication, context)
BERRY_REGISTER_EXTENSION_CLASS(MinimalPerspective, context)
}
void org_mitk_example_gui_minimalapplication_Activator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
-Q_EXPORT_PLUGIN2(org_mitk_example_gui_minimalapplication, org_mitk_example_gui_minimalapplication_Activator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_example_gui_minimalapplication, org_mitk_example_gui_minimalapplication_Activator)
+#endif
diff --git a/Examples/Plugins/org.mitk.example.gui.minimalapplication/src/internal/org_mitk_example_gui_minimalapplication_Activator.h b/Examples/Plugins/org.mitk.example.gui.minimalapplication/src/internal/org_mitk_example_gui_minimalapplication_Activator.h
index d1e5c6ce75..4ce677fcd2 100644
--- a/Examples/Plugins/org.mitk.example.gui.minimalapplication/src/internal/org_mitk_example_gui_minimalapplication_Activator.h
+++ b/Examples/Plugins/org.mitk.example.gui.minimalapplication/src/internal/org_mitk_example_gui_minimalapplication_Activator.h
@@ -1,36 +1,39 @@
/*===================================================================
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 org_mitk_example_gui_minimalapplication_Activator_H
#define org_mitk_example_gui_minimalapplication_Activator_H
#include <ctkPluginActivator.h>
class org_mitk_example_gui_minimalapplication_Activator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_example_gui_minimalapplication")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
};
#endif // org_mitk_example_gui_minimalapplication_Activator_H
diff --git a/Examples/Plugins/org.mitk.example.gui.multipleperspectives/src/internal/org_mitk_example_gui_multipleperspectives_Activator.cpp b/Examples/Plugins/org.mitk.example.gui.multipleperspectives/src/internal/org_mitk_example_gui_multipleperspectives_Activator.cpp
index a071e49572..a1b6e034ff 100644
--- a/Examples/Plugins/org.mitk.example.gui.multipleperspectives/src/internal/org_mitk_example_gui_multipleperspectives_Activator.cpp
+++ b/Examples/Plugins/org.mitk.example.gui.multipleperspectives/src/internal/org_mitk_example_gui_multipleperspectives_Activator.cpp
@@ -1,42 +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 "org_mitk_example_gui_multipleperspectives_Activator.h"
#include "MultiplePerspectives.h"
#include "MinimalPerspective.h"
#include "ExtendedPerspective.h"
#include "EmptyView1.h"
#include "EmptyView2.h"
#include <QtPlugin>
void org_mitk_example_gui_multipleperspectives_Activator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(MultiplePerspectives, context)
BERRY_REGISTER_EXTENSION_CLASS(MinimalPerspective, context)
BERRY_REGISTER_EXTENSION_CLASS(ExtendedPerspective, context)
BERRY_REGISTER_EXTENSION_CLASS(EmptyView1, context)
BERRY_REGISTER_EXTENSION_CLASS(EmptyView2, context)
}
void org_mitk_example_gui_multipleperspectives_Activator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
-Q_EXPORT_PLUGIN2(org_mitk_example_gui_multipleperspectives, org_mitk_example_gui_multipleperspectives_Activator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_example_gui_multipleperspectives, org_mitk_example_gui_multipleperspectives_Activator)
+#endif
diff --git a/Examples/Plugins/org.mitk.example.gui.multipleperspectives/src/internal/org_mitk_example_gui_multipleperspectives_Activator.h b/Examples/Plugins/org.mitk.example.gui.multipleperspectives/src/internal/org_mitk_example_gui_multipleperspectives_Activator.h
index ed1f4df078..7ee1d5272b 100644
--- a/Examples/Plugins/org.mitk.example.gui.multipleperspectives/src/internal/org_mitk_example_gui_multipleperspectives_Activator.h
+++ b/Examples/Plugins/org.mitk.example.gui.multipleperspectives/src/internal/org_mitk_example_gui_multipleperspectives_Activator.h
@@ -1,36 +1,39 @@
/*===================================================================
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 org_mitk_example_gui_multipleperspectives_Activator_H
#define org_mitk_example_gui_multipleperspectives_Activator_H
#include <ctkPluginActivator.h>
class org_mitk_example_gui_multipleperspectives_Activator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_example_gui_multipleperspectives")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
};
#endif // org_mitk_example_gui_multipleperspectives_Activator_H
diff --git a/Examples/Plugins/org.mitk.example.gui.opencv/src/internal/mitkPluginActivator.cpp b/Examples/Plugins/org.mitk.example.gui.opencv/src/internal/mitkPluginActivator.cpp
index 86724180cb..bb64d5ec02 100644
--- a/Examples/Plugins/org.mitk.example.gui.opencv/src/internal/mitkPluginActivator.cpp
+++ b/Examples/Plugins/org.mitk.example.gui.opencv/src/internal/mitkPluginActivator.cpp
@@ -1,36 +1,38 @@
/*===================================================================
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 "mitkPluginActivator.h"
#include "src/internal/videoplayer/QmitkVideoPlayer.h"
#include <QtPlugin>
namespace mitk {
void PluginActivator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(QmitkVideoPlayer, context)
}
void PluginActivator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_examplesopencv, mitk::PluginActivator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_examplesopencv, mitk::PluginActivator)
+#endif
diff --git a/Examples/Plugins/org.mitk.example.gui.opencv/src/internal/mitkPluginActivator.h b/Examples/Plugins/org.mitk.example.gui.opencv/src/internal/mitkPluginActivator.h
index b96fd0fb6e..bb961625ce 100644
--- a/Examples/Plugins/org.mitk.example.gui.opencv/src/internal/mitkPluginActivator.h
+++ b/Examples/Plugins/org.mitk.example.gui.opencv/src/internal/mitkPluginActivator.h
@@ -1,40 +1,43 @@
/*===================================================================
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 MITKPLUGINACTIVATOR_H
#define MITKPLUGINACTIVATOR_H
#include <ctkPluginActivator.h>
#include <mitkExportMacros.h>
namespace mitk {
class MITK_LOCAL PluginActivator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
- Q_INTERFACES(ctkPluginActivator)
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_examplesopencv")
+#endif
+ Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
}; // PluginActivator
}
#endif // MITKPLUGINACTIVATOR_H
diff --git a/Examples/Plugins/org.mitk.example.gui.regiongrowing/src/internal/org_mitk_example_gui_regiongrowing_Activator.cpp b/Examples/Plugins/org.mitk.example.gui.regiongrowing/src/internal/org_mitk_example_gui_regiongrowing_Activator.cpp
index a0d3863e2e..d7bd9aae63 100644
--- a/Examples/Plugins/org.mitk.example.gui.regiongrowing/src/internal/org_mitk_example_gui_regiongrowing_Activator.cpp
+++ b/Examples/Plugins/org.mitk.example.gui.regiongrowing/src/internal/org_mitk_example_gui_regiongrowing_Activator.cpp
@@ -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.
===================================================================*/
#include "org_mitk_example_gui_regiongrowing_Activator.h"
#include <QtPlugin>
#include "QmitkRegionGrowingView.h"
namespace mitk {
void org_mitk_example_gui_regiongrowing_Activator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(QmitkRegionGrowingView, context)
}
void org_mitk_example_gui_regiongrowing_Activator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_mitk_example_gui_regiongrowing, mitk::org_mitk_example_gui_regiongrowing_Activator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_example_gui_regiongrowing, mitk::org_mitk_example_gui_regiongrowing_Activator)
+#endif
diff --git a/Examples/Plugins/org.mitk.example.gui.regiongrowing/src/internal/org_mitk_example_gui_regiongrowing_Activator.h b/Examples/Plugins/org.mitk.example.gui.regiongrowing/src/internal/org_mitk_example_gui_regiongrowing_Activator.h
index 29d561d6f5..37f5aeef32 100644
--- a/Examples/Plugins/org.mitk.example.gui.regiongrowing/src/internal/org_mitk_example_gui_regiongrowing_Activator.h
+++ b/Examples/Plugins/org.mitk.example.gui.regiongrowing/src/internal/org_mitk_example_gui_regiongrowing_Activator.h
@@ -1,40 +1,43 @@
/*===================================================================
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 org_mitk_example_gui_regiongrowing_Activator_h
#define org_mitk_example_gui_regiongrowing_Activator_h
#include <ctkPluginActivator.h>
namespace mitk {
class org_mitk_example_gui_regiongrowing_Activator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_example_gui_regiongrowing")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
}; // org_mitk_example_gui_regiongrowing_Activator
}
#endif // org_mitk_example_gui_regiongrowing_Activator_h
diff --git a/Examples/Plugins/org.mitk.example.gui.selectionservicemitk.views/src/internal/org_mitk_example_gui_selectionservicemitk_views_Activator.cpp b/Examples/Plugins/org.mitk.example.gui.selectionservicemitk.views/src/internal/org_mitk_example_gui_selectionservicemitk_views_Activator.cpp
index 6dbb8b0ae1..65547f0103 100644
--- a/Examples/Plugins/org.mitk.example.gui.selectionservicemitk.views/src/internal/org_mitk_example_gui_selectionservicemitk_views_Activator.cpp
+++ b/Examples/Plugins/org.mitk.example.gui.selectionservicemitk.views/src/internal/org_mitk_example_gui_selectionservicemitk_views_Activator.cpp
@@ -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.
===================================================================*/
#include "org_mitk_example_gui_selectionservicemitk_views_Activator.h"
#include "ListenerViewMitk.h"
#include "SelectionViewMitk.h"
#include <QtPlugin>
void org_mitk_example_gui_selectionservicemitk_views_Activator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(ListenerViewMitk, context)
BERRY_REGISTER_EXTENSION_CLASS(SelectionViewMitk, context)
}
void org_mitk_example_gui_selectionservicemitk_views_Activator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
-Q_EXPORT_PLUGIN2(org_mitk_example_gui_selectionservicemitk_views, org_mitk_example_gui_selectionservicemitk_views_Activator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_example_gui_selectionservicemitk_views, org_mitk_example_gui_selectionservicemitk_views_Activator)
+#endif
diff --git a/Examples/Plugins/org.mitk.example.gui.selectionservicemitk.views/src/internal/org_mitk_example_gui_selectionservicemitk_views_Activator.h b/Examples/Plugins/org.mitk.example.gui.selectionservicemitk.views/src/internal/org_mitk_example_gui_selectionservicemitk_views_Activator.h
index fc8d45039c..ad4f34297b 100644
--- a/Examples/Plugins/org.mitk.example.gui.selectionservicemitk.views/src/internal/org_mitk_example_gui_selectionservicemitk_views_Activator.h
+++ b/Examples/Plugins/org.mitk.example.gui.selectionservicemitk.views/src/internal/org_mitk_example_gui_selectionservicemitk_views_Activator.h
@@ -1,36 +1,39 @@
/*===================================================================
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 org_mitk_example_gui_selectionservicemitk_views_Activator_H
#define org_mitk_example_gui_selectionservicemitk_views_Activator_H
#include <ctkPluginActivator.h>
class org_mitk_example_gui_selectionservicemitk_views_Activator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_example_gui_selectionservicemitk_views")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
};
#endif // org_mitk_example_gui_selectionservicemitk_views_Activator_H
diff --git a/Examples/Plugins/org.mitk.example.gui.selectionservicemitk/src/internal/org_mitk_example_gui_selectionservicemitk_Activator.cpp b/Examples/Plugins/org.mitk.example.gui.selectionservicemitk/src/internal/org_mitk_example_gui_selectionservicemitk_Activator.cpp
index dd9ce20696..1c25e30bce 100644
--- a/Examples/Plugins/org.mitk.example.gui.selectionservicemitk/src/internal/org_mitk_example_gui_selectionservicemitk_Activator.cpp
+++ b/Examples/Plugins/org.mitk.example.gui.selectionservicemitk/src/internal/org_mitk_example_gui_selectionservicemitk_Activator.cpp
@@ -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.
===================================================================*/
#include "org_mitk_example_gui_selectionservicemitk_Activator.h"
#include "SelectionServiceMitk.h"
#include "ExtendedPerspective.h"
#include <QtPlugin>
void org_mitk_example_gui_selectionservicemitk_Activator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(SelectionServiceMitk, context)
BERRY_REGISTER_EXTENSION_CLASS(ExtendedPerspective, context)
}
void org_mitk_example_gui_selectionservicemitk_Activator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
-Q_EXPORT_PLUGIN2(org_mitk_example_gui_selectionservicemitk, org_mitk_example_gui_selectionservicemitk_Activator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_example_gui_selectionservicemitk, org_mitk_example_gui_selectionservicemitk_Activator)
+#endif
diff --git a/Examples/Plugins/org.mitk.example.gui.selectionservicemitk/src/internal/org_mitk_example_gui_selectionservicemitk_Activator.h b/Examples/Plugins/org.mitk.example.gui.selectionservicemitk/src/internal/org_mitk_example_gui_selectionservicemitk_Activator.h
index e1f807d2ee..eeea2518ca 100644
--- a/Examples/Plugins/org.mitk.example.gui.selectionservicemitk/src/internal/org_mitk_example_gui_selectionservicemitk_Activator.h
+++ b/Examples/Plugins/org.mitk.example.gui.selectionservicemitk/src/internal/org_mitk_example_gui_selectionservicemitk_Activator.h
@@ -1,36 +1,39 @@
/*===================================================================
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 org_mitk_example_gui_selectionservicemitk_Activator_H
#define org_mitk_example_gui_selectionservicemitk_Activator_H
#include <ctkPluginActivator.h>
class org_mitk_example_gui_selectionservicemitk_Activator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_example_gui_selectionservicemitk")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
};
#endif // org_mitk_example_gui_selectionservicemitk_Activator_H
diff --git a/Examples/Plugins/org.mitk.example.gui.selectionserviceqt/src/internal/org_mitk_example_gui_selectionserviceqt_Activator.cpp b/Examples/Plugins/org.mitk.example.gui.selectionserviceqt/src/internal/org_mitk_example_gui_selectionserviceqt_Activator.cpp
index 440edb3ab4..33ac2db633 100644
--- a/Examples/Plugins/org.mitk.example.gui.selectionserviceqt/src/internal/org_mitk_example_gui_selectionserviceqt_Activator.cpp
+++ b/Examples/Plugins/org.mitk.example.gui.selectionserviceqt/src/internal/org_mitk_example_gui_selectionserviceqt_Activator.cpp
@@ -1,41 +1,43 @@
/*===================================================================
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_example_gui_selectionserviceqt_Activator.h"
#include "SelectionServiceQt.h"
#include "ExtendedPerspective.h"
#include "ListenerView.h"
#include "SelectionView.h"
#include <QtPlugin>
void org_mitk_example_gui_selectionserviceqt_Activator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(SelectionServiceQt, context)
BERRY_REGISTER_EXTENSION_CLASS(ExtendedPerspective, context)
BERRY_REGISTER_EXTENSION_CLASS(ListenerView, context)
BERRY_REGISTER_EXTENSION_CLASS(SelectionView, context)
}
void org_mitk_example_gui_selectionserviceqt_Activator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
-Q_EXPORT_PLUGIN2(org_mitk_example_gui_selectionserviceqt, org_mitk_example_gui_selectionserviceqt_Activator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_example_gui_selectionserviceqt, org_mitk_example_gui_selectionserviceqt_Activator)
+#endif
diff --git a/Examples/Plugins/org.mitk.example.gui.selectionserviceqt/src/internal/org_mitk_example_gui_selectionserviceqt_Activator.h b/Examples/Plugins/org.mitk.example.gui.selectionserviceqt/src/internal/org_mitk_example_gui_selectionserviceqt_Activator.h
index 63661b8979..a4a00cf7cb 100644
--- a/Examples/Plugins/org.mitk.example.gui.selectionserviceqt/src/internal/org_mitk_example_gui_selectionserviceqt_Activator.h
+++ b/Examples/Plugins/org.mitk.example.gui.selectionserviceqt/src/internal/org_mitk_example_gui_selectionserviceqt_Activator.h
@@ -1,36 +1,39 @@
/*===================================================================
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 org_mitk_example_gui_selectionserviceqt_Activator_H
#define org_mitk_example_gui_selectionserviceqt_Activator_H
#include <ctkPluginActivator.h>
class org_mitk_example_gui_selectionserviceqt_Activator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_example_gui_selectionserviceqt")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
};
#endif // org_mitk_example_gui_selectionserviceqt_Activator_H
diff --git a/Examples/QuickRender/CMakeLists.txt b/Examples/QuickRender/CMakeLists.txt
index 0bc5f675a0..ab2111efc6 100644
--- a/Examples/QuickRender/CMakeLists.txt
+++ b/Examples/QuickRender/CMakeLists.txt
@@ -1,4 +1,4 @@
project(QuickRender)
find_package(MITK REQUIRED)
-mitk_create_executable(DEPENDS MitkQmlItems)
+mitk_create_executable(DEPENDS MitkQmlItems MitkLegacyIO)
diff --git a/Modules/AlgorithmsExt/Testing/files.cmake b/Modules/AlgorithmsExt/Testing/files.cmake
index 9a9b325349..952b04cef2 100644
--- a/Modules/AlgorithmsExt/Testing/files.cmake
+++ b/Modules/AlgorithmsExt/Testing/files.cmake
@@ -1,9 +1,11 @@
set(MODULE_TESTS
mitkAutoCropImageFilterTest.cpp
mitkBoundingObjectCutterTest.cpp
mitkSimpleHistogramTest.cpp
+ mitkCovarianceMatrixCalculatorTest.cpp
+ mitkAnisotropicIterativeClosestPointRegistrationTest.cpp
)
set(MODULE_CUSTOM_TESTS
mitkLabeledImageToSurfaceFilterTest.cpp
)
diff --git a/Modules/AlgorithmsExt/Testing/mitkAnisotropicIterativeClosestPointRegistrationTest.cpp b/Modules/AlgorithmsExt/Testing/mitkAnisotropicIterativeClosestPointRegistrationTest.cpp
new file mode 100644
index 0000000000..00864f1dce
--- /dev/null
+++ b/Modules/AlgorithmsExt/Testing/mitkAnisotropicIterativeClosestPointRegistrationTest.cpp
@@ -0,0 +1,176 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#include <mitkTestingMacros.h>
+#include <mitkSurface.h>
+#include <mitkIOUtil.h>
+#include <vtkCleanPolyData.h>
+#include <mitkTestFixture.h>
+
+
+#include "mitkAnisotropicIterativeClosestPointRegistration.h"
+#include "mitkCovarianceMatrixCalculator.h"
+#include "mitkAnisotropicRegistrationCommon.h"
+
+/**
+ * Test to verify the results of the A-ICP registration.
+ * The test runs the standard A-ICP and the trimmed variant.
+ */
+class mitkAnisotropicIterativeClosestPointRegistrationTestSuite : public mitk::TestFixture
+{
+ CPPUNIT_TEST_SUITE(mitkAnisotropicIterativeClosestPointRegistrationTestSuite);
+ MITK_TEST(testAicpRegistration);
+ MITK_TEST(testTrimmedAicpregistration);
+ CPPUNIT_TEST_SUITE_END();
+
+private:
+
+ typedef itk::Matrix < double, 3, 3 > Matrix3x3;
+ typedef itk::Vector < double, 3 > Vector3;
+ typedef std::vector < Matrix3x3 > CovarianceMatrixList;
+
+ mitk::Surface::Pointer m_MovingSurface;
+ mitk::Surface::Pointer m_FixedSurface;
+
+ mitk::PointSet::Pointer m_TargetsMovingSurface;
+ mitk::PointSet::Pointer m_TargetsFixedSurface;
+
+ CovarianceMatrixList m_SigmasMovingSurface;
+ CovarianceMatrixList m_SigmasFixedSurface;
+
+ double m_FRENormalizationFactor;
+
+public:
+
+ /**
+ * @brief Setup Always call this method before each Test-case to ensure
+ * correct and new intialization of the used members for a new test case.
+ * (If the members are not used in a test, the method does not need to be called).
+ */
+ void setUp()
+ {
+ mitk::CovarianceMatrixCalculator::Pointer matrixCalculator
+ = mitk::CovarianceMatrixCalculator::New();
+
+ m_MovingSurface = mitk::IOUtil::LoadSurface(GetTestDataFilePath("AICPRegistration/head_green.stl"));
+ m_FixedSurface = mitk::IOUtil::LoadSurface(GetTestDataFilePath("AICPRegistration/head_red.stl"));
+
+ m_TargetsMovingSurface = mitk::IOUtil::LoadPointSet(GetTestDataFilePath("AICPRegistration/targets_head_green.mps"));
+ m_TargetsFixedSurface = mitk::IOUtil::LoadPointSet(GetTestDataFilePath("AICPRegistration/targets_head_red.mps"));
+
+ // compute covariance matrices
+ matrixCalculator->SetInputSurface(m_MovingSurface);
+ matrixCalculator->ComputeCovarianceMatrices();
+ m_SigmasMovingSurface = matrixCalculator->GetCovarianceMatrices();
+ const double meanVarX = matrixCalculator->GetMeanVariance();
+
+ matrixCalculator->SetInputSurface(m_FixedSurface);
+ matrixCalculator->ComputeCovarianceMatrices();
+ m_SigmasFixedSurface = matrixCalculator->GetCovarianceMatrices();
+ const double meanVarY = matrixCalculator->GetMeanVariance();
+
+ m_FRENormalizationFactor = sqrt( meanVarX + meanVarY );
+ }
+
+ void tearDown()
+ {
+ m_MovingSurface = NULL;
+ m_FixedSurface = NULL;
+
+ m_TargetsMovingSurface = NULL;
+ m_TargetsFixedSurface = NULL;
+
+ m_SigmasMovingSurface.clear();
+ m_SigmasFixedSurface.clear();
+ }
+
+ void testAicpRegistration()
+ {
+ const double expFRE = 27.5799;
+ const double expTRE = 1.68835;
+ mitk::AnisotropicIterativeClosestPointRegistration::Pointer aICP =
+ mitk::AnisotropicIterativeClosestPointRegistration::New();
+
+ // set up parameters
+ aICP->SetMovingSurface(m_MovingSurface);
+ aICP->SetFixedSurface(m_FixedSurface);
+ aICP->SetCovarianceMatricesMovingSurface(m_SigmasMovingSurface);
+ aICP->SetCovarianceMatricesFixedSurface(m_SigmasFixedSurface);
+ aICP->SetFRENormalizationFactor(m_FRENormalizationFactor);
+ aICP->SetThreshold(0.000001);
+
+ // run the algorithm
+ aICP->Update();
+
+ MITK_INFO << "FRE: Expected: " << expFRE << ", computed: " << aICP->GetFRE();
+ CPPUNIT_ASSERT_MESSAGE("mitkAnisotropicIterativeClosestPointRegistrationTest:AicpRegistration Test FRE",
+ mitk::Equal(aICP->GetFRE(),expFRE,0.0001));
+
+ // compute the target registration Error
+ const double tre = mitk::AnisotropicRegistrationCommon::ComputeTargetRegistrationError(
+ m_TargetsMovingSurface.GetPointer(),
+ m_TargetsFixedSurface.GetPointer(),
+ aICP->GetRotation(),
+ aICP->GetTranslation()
+ );
+
+ // MITK_INFO << "R:\n" << aICP->GetRotation() << "T: "<< aICP->GetTranslation();
+
+ MITK_INFO << "TRE: Expected: " << expTRE << ", computed: " << tre;
+ CPPUNIT_ASSERT_MESSAGE("mitkAnisotropicIterativeClosestPointRegistrationTest:AicpRegistration Test TRE",
+ mitk::Equal(tre,expTRE,0.00001));
+ }
+
+ void testTrimmedAicpregistration()
+ {
+ const double expFRE = 4.8912;
+ const double expTRE = 0.0484215;
+
+ mitk::AnisotropicIterativeClosestPointRegistration::Pointer aICP =
+ mitk::AnisotropicIterativeClosestPointRegistration::New();
+
+ // Swap X and Y for partial overlapping registration
+ aICP->SetMovingSurface(m_MovingSurface);
+ aICP->SetFixedSurface(m_FixedSurface);
+ aICP->SetCovarianceMatricesMovingSurface(m_SigmasMovingSurface);
+ aICP->SetCovarianceMatricesFixedSurface(m_SigmasFixedSurface);
+ aICP->SetFRENormalizationFactor(m_FRENormalizationFactor);
+ aICP->SetThreshold(0.000001);
+ aICP->SetTrimmFactor(0.50);
+
+ // run the algorithm
+ aICP->Update();
+
+ MITK_INFO << "FRE: Expected: " << expFRE << ", computed: " << aICP->GetFRE();
+
+ CPPUNIT_ASSERT_MESSAGE("mitkAnisotropicIterativeClosestPointRegistrationTest:AicpRegistration Test FRE",
+ mitk::Equal(aICP->GetFRE(),expFRE,0.01));
+
+ // compute the target registration Error
+ const double tre = mitk::AnisotropicRegistrationCommon::ComputeTargetRegistrationError(
+ m_TargetsMovingSurface.GetPointer(),
+ m_TargetsFixedSurface.GetPointer(),
+ aICP->GetRotation(),
+ aICP->GetTranslation()
+ );
+
+ MITK_INFO << "TRE: Expected: " << expTRE << ", computed: " << tre;
+ CPPUNIT_ASSERT_MESSAGE("mitkAnisotropicIterativeClosestPointRegistrationTest:AicpRegistration Test TRE",
+ mitk::Equal(tre,expTRE,0.01));
+ }
+};
+
+MITK_TEST_SUITE_REGISTRATION(mitkAnisotropicIterativeClosestPointRegistration)
diff --git a/Modules/AlgorithmsExt/Testing/mitkCovarianceMatrixCalculatorTest.cpp b/Modules/AlgorithmsExt/Testing/mitkCovarianceMatrixCalculatorTest.cpp
new file mode 100644
index 0000000000..35304ee9cd
--- /dev/null
+++ b/Modules/AlgorithmsExt/Testing/mitkCovarianceMatrixCalculatorTest.cpp
@@ -0,0 +1,96 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#include <mitkTestingMacros.h>
+#include <mitkSurface.h>
+#include <mitkIOUtil.h>
+#include <vtkCleanPolyData.h>
+#include <mitkVector.h>
+#include <mitkCovarianceMatrixCalculator.h>
+
+#include <mitkTestFixture.h>
+
+/** Test class to test the computation of covariance matrices
+ * for the A-ICP algorithm. The test runs the CM_PCA method.
+ */
+class mitkCovarianceMatrixCalculatorTestSuite : public mitk::TestFixture
+{
+ CPPUNIT_TEST_SUITE(mitkCovarianceMatrixCalculatorTestSuite);
+ MITK_TEST(testCovarianceMatrixCalculation_CM_PCA);
+ CPPUNIT_TEST_SUITE_END();
+
+private:
+ typedef itk::Matrix<double,3,3> CovarianceMatrix;
+ typedef std::vector<CovarianceMatrix> CovarianceMatrixList;
+
+ mitk::Surface::Pointer m_Surface;
+ CovarianceMatrixList m_Reference;
+
+public:
+
+ void setUp()
+ {
+ m_Surface = mitk::IOUtil::LoadSurface(GetTestDataFilePath(
+ "RenderingTestData/Stanford_bunny.stl"
+ ));
+
+ // saved results
+ CovarianceMatrix m1,m2,m3;
+
+ // set 3 reference results into the vector. The first in the array, one from
+ // the middle and the last one
+ m1[0][0] = 366.169; m1[1][0] = 39.5242; m1[2][0] = 102.368;
+ m1[0][1] = 39.5242; m1[1][1] = 6.97979; m1[2][1] = 6.91726;
+ m1[0][2] = 102.368; m1[1][2] = 6.91726; m1[2][2] = 389.481;
+ m_Reference.push_back(m1);
+
+ m2[0][0] = 107.999; m2[1][0] = 71.6708; m2[2][0] = -0.908269;
+ m2[0][1] = 71.6708 ; m2[1][1] = 133.407; m2[2][1] = 40.8706;
+ m2[0][2] = -0.908269; m2[1][2] = 40.8706; m2[2][2] = 25.1825;
+ m_Reference.push_back(m2);
+
+ m3[0][0] = 177.916; m3[1][0] = 4.92498; m3[2][0] = 5.86319;
+ m3[0][1] = 4.92498; m3[1][1] = 0.214147; m3[2][1] = -1.98345;
+ m3[0][2] = 5.86319; m3[1][2] = -1.98345; m3[2][2] = 232.092;
+ m_Reference.push_back(m3);
+ }
+
+ void tearDown()
+ {
+ m_Surface = NULL;
+ m_Reference.clear();
+ }
+
+ void testCovarianceMatrixCalculation_CM_PCA()
+ {
+ mitk::CovarianceMatrixCalculator::Pointer matrixCalculator =
+ mitk::CovarianceMatrixCalculator::New();
+ matrixCalculator->SetInputSurface(m_Surface);
+ matrixCalculator->ComputeCovarianceMatrices();
+ CovarianceMatrixList result = matrixCalculator->GetCovarianceMatrices();
+
+ CPPUNIT_ASSERT_MESSAGE("mitkCovarianceMatrixCalculatorTestSuite test first matrix",
+ mitk::MatrixEqualElementWise(result.at(0),m_Reference.at(0),0.001));
+
+ CPPUNIT_ASSERT_MESSAGE("mitkCovarianceMatrixCalculatorTestSuite test middle matrix",
+ mitk::MatrixEqualElementWise(result.at(result.size()/2),m_Reference.at(1),0.001));
+
+ CPPUNIT_ASSERT_MESSAGE("mitkCovarianceMatrixCalculatorTestSuite test last matrix",
+ mitk::MatrixEqualElementWise(result.at((result.size() - 1)),m_Reference.at(2),0.001));
+ }
+};
+
+MITK_TEST_SUITE_REGISTRATION(mitkCovarianceMatrixCalculator)
diff --git a/Modules/AlgorithmsExt/files.cmake b/Modules/AlgorithmsExt/files.cmake
index 62667e34bc..5359942579 100644
--- a/Modules/AlgorithmsExt/files.cmake
+++ b/Modules/AlgorithmsExt/files.cmake
@@ -1,23 +1,27 @@
set(CPP_FILES
mitkAutoCropImageFilter.cpp
mitkBoundingObjectCutter.cpp
mitkBoundingObjectToSegmentationFilter.cpp
mitkGeometryClipImageFilter.cpp
mitkHeightFieldSurfaceClipImageFilter.cpp
mitkLabeledImageToSurfaceFilter.cpp
mitkMaskAndCutRoiImageFilter.cpp
mitkMaskImageFilter.cpp
mitkMovieGenerator.cpp
mitkNonBlockingAlgorithm.cpp
mitkPadImageFilter.cpp
mitkPlaneLandmarkProjector.cpp
mitkPointLocator.cpp
mitkSimpleHistogram.cpp
mitkSimpleUnstructuredGridHistogram.cpp
+ mitkCovarianceMatrixCalculator.cpp
+ mitkAnisotropicIterativeClosestPointRegistration.cpp
+ mitkWeightedPointTransform.cpp
+ mitkAnisotropicRegistrationCommon.cpp
)
if(WIN32 AND NOT MINGW)
list(APPEND CPP_FILES
mitkMovieGeneratorWin32.cpp
)
endif()
diff --git a/Modules/AlgorithmsExt/mitkAnisotropicIterativeClosestPointRegistration.cpp b/Modules/AlgorithmsExt/mitkAnisotropicIterativeClosestPointRegistration.cpp
new file mode 100644
index 0000000000..ed76c297af
--- /dev/null
+++ b/Modules/AlgorithmsExt/mitkAnisotropicIterativeClosestPointRegistration.cpp
@@ -0,0 +1,321 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+// MITK
+#include "mitkAnisotropicIterativeClosestPointRegistration.h"
+#include "mitkWeightedPointTransform.h"
+#include "mitkAnisotropicRegistrationCommon.h"
+#include <mitkSurface.h>
+#include <mitkProgressBar.h>
+// VTK
+#include <vtkKdTree.h>
+#include <vtkPoints.h>
+#include <vtkPolyData.h>
+#include <vtkIdList.h>
+#include <vtkKdTreePointLocator.h>
+// STL pair
+#include <utility>
+
+/** \brief Comperator implementation used to sort the CorrespondenceList in the
+ * trimmed version of the AnisotropicIterativeClosestPointRegistration.
+ */
+struct AICPComperator
+{
+ typedef std::pair < unsigned int, double > Correspondence;
+
+ bool operator() (const Correspondence& a, const Correspondence& b)
+ {
+ return (a.second < b.second);
+ }
+} AICPComp;
+
+mitk::AnisotropicIterativeClosestPointRegistration::AnisotropicIterativeClosestPointRegistration()
+ : m_MaxIterations(1000),
+ m_Threshold(0.000001),
+ m_FRENormalizationFactor(1.0),
+ m_SearchRadius(30.0),
+ m_MaxIterationsInWeightedPointTransform(1000),
+ m_FRE(0.0),
+ m_TrimmFactor(0.0),
+ m_NumberOfIterations(0),
+ m_MovingSurface(NULL),
+ m_FixedSurface(NULL),
+ m_WeightedPointTransform(mitk::WeightedPointTransform::New())
+{
+}
+
+mitk::AnisotropicIterativeClosestPointRegistration::~AnisotropicIterativeClosestPointRegistration()
+{
+}
+
+void mitk::AnisotropicIterativeClosestPointRegistration::ComputeCorrespondences ( vtkPoints* X,
+ vtkPoints* Z,
+ vtkKdTreePointLocator* Y,
+ const CovarianceMatrixList& sigma_X,
+ const CovarianceMatrixList& sigma_Y,
+ CovarianceMatrixList& sigma_Z,
+ CorrespondenceList& correspondences,
+ const double radius
+ )
+{
+ typedef itk::Matrix < double, 3, 3 > WeightMatrix;
+
+# pragma omp parallel for
+ for ( vtkIdType i = 0; i < X->GetNumberOfPoints(); ++i )
+ {
+ vtkIdType bestIdx = 0;
+ mitk::Vector3D x;
+ mitk::Vector3D y;
+ double bestDist = std::numeric_limits<double>::max();
+ vtkIdList* ids = vtkIdList::New();
+ double r = radius;
+ double p[3];
+ // get point
+ X->GetPoint(i,p);
+ // fill vector
+ x[0] = p[0];
+ x[1] = p[1];
+ x[2] = p[2];
+
+ // double the radius till we find at least one point
+ while( ids->GetNumberOfIds() <= 0 )
+ {
+ Y->FindPointsWithinRadius(r,p,ids);
+ r *= 2.0;
+ }
+
+ // loop over the points in the sphere and find the point with the
+ // minimal weighted squared distance
+ for ( vtkIdType j = 0; j < ids->GetNumberOfIds(); ++j )
+ {
+ // get id
+ const vtkIdType id = ids->GetId(j);
+ // compute weightmatrix
+ WeightMatrix m =
+ mitk::AnisotropicRegistrationCommon::CalculateWeightMatrix( sigma_X[i],
+ sigma_Y[id]
+ );
+ // point of the fixed data set
+ Y->GetDataSet()->GetPoint(id,p);
+
+ // fill mitk vector
+ y[0] = p[0];
+ y[1] = p[1];
+ y[2] = p[2];
+
+ const mitk::Vector3D res = m * ( x - y );
+
+ const double dist = res[0] * res[0] +
+ res[1] * res[1] +
+ res[2] * res[2];
+
+ if ( dist < bestDist )
+ {
+ bestDist = dist;
+ bestIdx = id;
+ }
+ }
+
+ // save correspondences of the fixed point set
+ Y->GetDataSet()->GetPoint(bestIdx,p);
+ Z->SetPoint(i,p);
+ sigma_Z[i] = sigma_Y[bestIdx];
+
+ Correspondence _pair(i,bestDist);
+ correspondences[i] = _pair;
+
+ ids->Delete();
+ }
+}
+
+void mitk::AnisotropicIterativeClosestPointRegistration::Update()
+{
+ unsigned int k = 0;
+ unsigned int numberOfTrimmedPoints = 0;
+ double diff = 0.0;
+ double FRE_new = std::numeric_limits<double>::max();
+ // Moving pointset
+ vtkPoints* X = vtkPoints::New();
+ // Correspondences
+ vtkPoints* Z = vtkPoints::New();
+ // Covariance matrices of the pointset X
+ CovarianceMatrixList& Sigma_X = m_CovarianceMatricesMovingSurface;
+ // Covariance matrices of the pointset Y
+ CovarianceMatrixList& Sigma_Y = m_CovarianceMatricesFixedSurface;
+ // Covariance matrices of the correspondences
+ CovarianceMatrixList Sigma_Z;
+ // transform of the current iteration
+ Rotation RotationNew;
+ Translation TranslationNew;
+ // corresponding indizes with distance
+ CorrespondenceList distanceList;
+ // sorted datasets used if trimming is enabled
+ vtkPoints* X_sorted = vtkPoints::New();
+ vtkPoints* Z_sorted = vtkPoints::New();
+ CovarianceMatrixList Sigma_X_sorted;
+ CovarianceMatrixList Sigma_Z_sorted;
+
+ // create kdtree for correspondence search
+ vtkKdTreePointLocator* Y = vtkKdTreePointLocator::New();
+ Y->SetDataSet(m_FixedSurface->GetVtkPolyData());
+ Y->BuildLocator();
+
+ // initialize local variables
+ // copy the moving pointset to prevent to modify it
+ X->DeepCopy(m_MovingSurface->GetVtkPolyData()->GetPoints());
+ // initialize size of the correspondences
+ Z->SetNumberOfPoints(X->GetNumberOfPoints());
+ // size of the corresponding matrices
+ Sigma_Z.resize(X->GetNumberOfPoints());
+ distanceList.resize(X->GetNumberOfPoints());
+ RotationNew.SetIdentity();
+ TranslationNew.Fill(0.0);
+
+ // reset members
+ m_FRE = std::numeric_limits<double>::max();
+ m_Rotation.SetIdentity();
+ m_Translation.Fill(0.0);
+
+ // compute number of correspondences based
+ // on the trimmfactor
+ if ( m_TrimmFactor > 0.0)
+ {
+ numberOfTrimmedPoints = X->GetNumberOfPoints() * m_TrimmFactor;
+ }
+
+ // initialize the sizes of the sorted datasets
+ // used in the trimmed version of the algorithm
+ Sigma_Z_sorted.resize(numberOfTrimmedPoints);
+ Sigma_X_sorted.resize(numberOfTrimmedPoints);
+ X_sorted->SetNumberOfPoints(numberOfTrimmedPoints);
+ Z_sorted->SetNumberOfPoints(numberOfTrimmedPoints);
+
+ // initialize the progress bar
+ unsigned int steps = m_MaxIterations;
+ unsigned int stepSize = m_MaxIterations / 10;
+ mitk::ProgressBar::GetInstance()->AddStepsToDo(steps);
+
+ do {
+
+ // reset innerloop
+ double currSearchRadius = m_SearchRadius;
+ unsigned int radiusDoubled = 0;
+
+ k = k + 1;
+
+ MITK_DEBUG << "iteration: " << k;
+
+ do {
+ // search correspondences
+ ComputeCorrespondences( X, Z, Y, Sigma_X,
+ Sigma_Y, Sigma_Z,
+ distanceList,
+ currSearchRadius );
+
+ // tmp pointers
+ vtkPoints* X_k = X;
+ vtkPoints* Z_k = Z;
+ CovarianceMatrixList* Sigma_Z_k = &Sigma_Z;
+ CovarianceMatrixList* Sigma_X_k = &Sigma_X;
+
+ // sort the correspondences depending on their
+ // distance, if trimming is enabled
+ if ( m_TrimmFactor > 0.0 )
+ {
+ std::sort ( distanceList.begin(), distanceList.end(), AICPComp );
+ // map correspondences to the data arrays
+ for ( unsigned int i = 0; i < numberOfTrimmedPoints; ++i )
+ {
+ const int idx = distanceList[i].first;
+ Sigma_Z_sorted[i] = Sigma_Z[idx];
+ Sigma_X_sorted[i] = Sigma_X[idx];
+ Z_sorted->SetPoint(i,Z->GetPoint(idx));
+ X_sorted->SetPoint(i,X->GetPoint(idx));
+ }
+ // assign pointers
+ X_k = X_sorted;
+ Z_k = Z_sorted;
+ Sigma_X_k = &Sigma_X_sorted;
+ Sigma_Z_k = &Sigma_Z_sorted;
+ }
+
+ // compute weighted transformation
+ // set parameters
+ m_WeightedPointTransform->SetMovingPointSet(X_k);
+ m_WeightedPointTransform->SetFixedPointSet(Z_k);
+ m_WeightedPointTransform->SetCovarianceMatricesMoving(*Sigma_X_k);
+ m_WeightedPointTransform->SetCovarianceMatricesFixed(*Sigma_Z_k);
+ m_WeightedPointTransform->SetMaxIterations(m_MaxIterationsInWeightedPointTransform);
+ m_WeightedPointTransform->SetFRENormalizationFactor(m_FRENormalizationFactor);
+
+ // run computation
+ m_WeightedPointTransform->ComputeTransformation();
+ // retrieve result
+ RotationNew = m_WeightedPointTransform->GetTransformR();
+ TranslationNew = m_WeightedPointTransform->GetTransformT();
+ FRE_new = m_WeightedPointTransform->GetFRE();
+
+ // double the radius
+ radiusDoubled += 1;
+ currSearchRadius *= 2.0;
+
+ // sanity check to prevent endless loop
+ if ( radiusDoubled >= 20 )
+ {
+ mitkThrow() << "Radius doubled 20 times, preventing endless loop, check input and search radius";
+ }
+
+ // termination constraint
+ diff = m_FRE - FRE_new;
+
+ } while ( diff < -1.0e-3 ); // increase radius as long as the FRE grows
+
+ MITK_DEBUG << "FRE:" << m_FRE << ", FRE_new: "<< FRE_new;
+ // transform points and propagate matrices
+ mitk::AnisotropicRegistrationCommon::TransformPoints(X,X,RotationNew,TranslationNew);
+ mitk::AnisotropicRegistrationCommon::PropagateMatrices(Sigma_X,Sigma_X,RotationNew);
+
+ // update global transformation
+ m_Rotation = RotationNew * m_Rotation;
+ m_Translation = RotationNew * m_Translation + TranslationNew;
+
+ MITK_DEBUG << "diff:" << diff;
+ // update FRE
+ m_FRE = FRE_new;
+
+ // update the progressbar. Just use the half every 2nd iteration
+ // to use a simulated endless progress bar since we don't have
+ // a fixed amount of iterations
+ stepSize = (k % 2 == 0) ? stepSize / 2 : stepSize;
+ stepSize = ( stepSize == 0 ) ? 1 : stepSize;
+ mitk::ProgressBar::GetInstance()->Progress(stepSize);
+
+ } while ( diff > m_Threshold && k < m_MaxIterations );
+
+ m_NumberOfIterations = k;
+
+ // finish the progress bar if there are more steps
+ // left than iterations used
+ if ( k < steps )
+ mitk::ProgressBar::GetInstance()->Progress(steps);
+
+ // free memory
+ Y->Delete();
+ Z->Delete();
+ X->Delete();
+ X_sorted->Delete();
+ Z_sorted->Delete();
+}
diff --git a/Modules/AlgorithmsExt/mitkAnisotropicIterativeClosestPointRegistration.h b/Modules/AlgorithmsExt/mitkAnisotropicIterativeClosestPointRegistration.h
new file mode 100644
index 0000000000..0e84981480
--- /dev/null
+++ b/Modules/AlgorithmsExt/mitkAnisotropicIterativeClosestPointRegistration.h
@@ -0,0 +1,325 @@
+/*===================================================================
+
+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 __ANISOTROPICITERATIVECLOSESTPOINTREGISTRATION_H__
+#define __ANISOTROPICITERATIVECLOSESTPOINTREGISTRATION_H__
+
+//MITK
+#include <mitkCommon.h>
+#include <mitkVector.h>
+
+//EXPORTS
+#include "MitkAlgorithmsExtExports.h"
+
+// STL
+#include <vector>
+
+// ITK
+#include <itkMatrix.h>
+
+// forward declarations
+class vtkPoints;
+class vtkKdTreePointLocator;
+
+namespace mitk
+{
+
+class Surface;
+class WeightedPointTransform;
+
+/**
+ * \ingroup AnisotropicRegistration
+ *
+ * @brief Implementation of the anisotropic iterative closest point (A-ICP)
+ * algoritm.
+ *
+ * This class implements the anisotropic interative closest point (A-ICP)
+ * algorithm presented in L. Maier-Hein et al. in "Convergent Iterative
+ * Closest-Point Algorithm to Accomodate Anisotropic and Inhomogenous
+ * Localization Error.", IEEE T Pattern Anal 34 (8), 1520-1532, 2012.
+ * The algorithm computes the optimal transformation to align two surfaces.
+ * In addition to the surfaces a list of covariance matrices is used as
+ * input for every surface. Each covariance matrix represents the error of
+ * a specific vertex in the Surface. The covariance matrices
+ * for each surface can be defined by the user, or calculated
+ * by the CovarianceMatrixCalculator. In addition a trimmed algorithm version
+ * is provided to compute the registration of partial overlapping surfaces.
+ * The algorithm needs a clean surface non manifold edges and without duplicated
+ * vertices. In addition vtkCleanPolyData can be used to ensure a correct
+ * Surface representation.
+ *
+ * \note The correspondence search is accelerated when OpenMP is enabled.
+ *
+ * \b Example:
+ *
+ *
+ * \code
+ * typedef itk::Matrix < double, 3, 3 > Matrix3x3;
+ * typedef itk::Vector < double, 3 > Vector3;
+ * typedef std::vector < Matrix3x3 > CovarianceMatrixList;
+ *
+ * // compute the covariance matrices
+ * mitk::CovarianceMatrixCalculator::Pointer matrixCalculator =
+ * mitk::CovarianceMatrixCalculator::New();
+ *
+ * // compute the covariance matrices for the moving surface (X)
+ * matrixCalculator->SetInputSurface(movingSurface);
+ * matrixCalculator->ComputeCovarianceMatrices();
+ * CovarianceMatrixList sigmas_X = matrixCalculator->GetCovarianceMatrices();
+ * double meanVarX = matrixCalculator->GetMeanVariance();
+ *
+ * // compute the covariance matrices for the fixed surface (Y)
+ * matrixCalculator->SetInputSurface(fixedSurface);
+ * matrixCalculator->ComputeCovarianceMatrices();
+ * CovarianceMatrixList sigmas_Y = matrixCalculator->GetCovarianceMatrices();
+ * double meanVarY = matrixCalculator->GetMeanVariance();
+ *
+ * // the FRE normalization factor
+ * double normalizationFactor = sqrt( meanVarX + meanVarY);
+ *
+ * // A-ICP algorithm
+ * mitk::AnisotropicIterativeClosestPointRegistration::Pointer aICP =
+ * mitk::AnisotropicIterativeClosestPointRegistration::New();
+ *
+ * // set up parameters
+ * aICP->SetMovingSurface(movingSurface);
+ * aICP->SetFixedSurface(fixedSurface);
+ * aICP->SetCovarianceMatricesMovingSurface(sigmas_X);
+ * aICP->SetCovarianceMatricesFixedSurface(sigmas_Y);
+ * aICP->SetFRENormalizationFactor(normalizationFactor);
+ *
+ * // Trimming is enabled if a fator > 0.0 is set.
+ * // 40 percent of the moving point set
+ * // will be used for registration in this example.
+ * // To disable trimming set the trim factor back to 0.0
+ * aICP->SetTrimmFactor(0.4);
+ *
+ * // run the algorithm
+ * aICP->Update();
+ *
+ * // retrieve the computed transformation
+ * Matrix3x3 rotation = aICP->GetRotation();
+ * Vector3 translation = aICP->GetTranslation();
+ * \endcode
+ *
+ */
+class MitkAlgorithmsExt_EXPORT AnisotropicIterativeClosestPointRegistration : public itk::Object
+{
+
+protected:
+
+ /** Definition of a 3x3 covariance matrix.*/
+ typedef itk::Matrix < double, 3, 3 > CovarianceMatrix;
+ /** Definition of a list of covariance matrices.*/
+ typedef std::vector< CovarianceMatrix > CovarianceMatrixList;
+ /** Definition of a translation vector.*/
+ typedef mitk::Vector3D Translation;
+ /** Definition of a 3x3 rotation matrix.*/
+ typedef CovarianceMatrix Rotation;
+ /** Definition of a correspondeces, index and distance.*/
+ typedef std::pair < unsigned int, double > Correspondence;
+ /** Definition of a list of correspondences.*/
+ typedef std::vector < Correspondence > CorrespondenceList;
+
+ AnisotropicIterativeClosestPointRegistration();
+ ~AnisotropicIterativeClosestPointRegistration();
+
+ /** Max amount of iterations. Default is 1000.*/
+ unsigned int m_MaxIterations;
+
+ /** Threshold used for termination. Default is 1.0e-6.*/
+ double m_Threshold;
+
+ /** Normalization factor for the feducial registration error. default is 0.0.*/
+ double m_FRENormalizationFactor;
+
+ /** Search radius for the correspondence search. Default is 30.*/
+ double m_SearchRadius;
+
+ /** The maximum number of iterations in the weighted point based
+ * registration. Default is 1000.
+ */
+ double m_MaxIterationsInWeightedPointTransform;
+
+ /** The fiducial registration error (FRE).*/
+ double m_FRE;
+
+ /** Trimmfactor for partial overlapping registration. Default is 0.*/
+ double m_TrimmFactor;
+
+ /** Amount of iterations used by the algorithm.*/
+ unsigned int m_NumberOfIterations;
+
+ /** Moving surface that is transformed on the fixed surface.*/
+ itk::SmartPointer < Surface > m_MovingSurface;
+ /** The fixed / target surface.*/
+ itk::SmartPointer < Surface > m_FixedSurface;
+
+ /** The weighted point based registration algorithm.*/
+ itk::SmartPointer < WeightedPointTransform > m_WeightedPointTransform;
+
+ /** The covariance matrices belonging to the moving surface (X).*/
+ CovarianceMatrixList m_CovarianceMatricesMovingSurface;
+
+ /** The covariance matrices belonging to the moving surface (Y).*/
+ CovarianceMatrixList m_CovarianceMatricesFixedSurface;
+
+ /** The computed 3x1 translation vector.*/
+ Translation m_Translation;
+ /** The computed 3x3 rotation matrix.*/
+ Rotation m_Rotation;
+
+ /**
+ * Method that computes the correspondences between the moving point set X
+ * and the fixed point set Y. The distances between the points
+ * are weighted with weight matrices that are computed from the covariances
+ * along the surfaces axes. This method implements the runtime optimization
+ * presented by L. Maier-Hein et al.. The correspondences are computed with
+ * the help of a kd tree. The correspondences are searched in a given radius
+ * in the euklidian space. Every correspondence found in this radius is
+ * weighted based on the covariance matrices and the best weighting will be
+ * used as a correspondence.
+ *
+ * @param X The moving point set.
+ * @param Z The returned correspondences from the fixed point set.
+ * @param Y The fixed point set saved in a kd tree.
+ * @param sigma_X Covariance matrices belonging to the moving point set.
+ * @param sigma_Y Covariance matrices belonging to the fixed point set.
+ * @param sigma_Z Covariance matrices belonging to the correspondences found.
+ * @param correspondences Saved correspondences, in a pair containing the
+ * their index in Y and distance.
+ * @param radius The search radius used in in kd tree.
+ *
+ */
+ void ComputeCorrespondences ( vtkPoints* X,
+ vtkPoints* Z,
+ vtkKdTreePointLocator *Y,
+ const CovarianceMatrixList& sigma_X,
+ const CovarianceMatrixList& sigma_Y,
+ CovarianceMatrixList& sigma_Z,
+ CorrespondenceList &correspondences,
+ const double radius
+ );
+
+
+public:
+ mitkClassMacro(AnisotropicIterativeClosestPointRegistration, itk::Object)
+ itkFactorylessNewMacro(Self)
+ itkCloneMacro(Self)
+
+
+ /** Set the maximum amount of iterations used by the algorithm. */
+ itkSetMacro(MaxIterations, unsigned int)
+
+ /** Set the threshold used to terminate the algorithm.*/
+ itkSetMacro(Threshold, double)
+
+ /** Set the normalization factor for the fiducial registration error (FRE).
+ * The normalization factor is computed with the help of the mean variance
+ * of both CovarianceMatrixList that can be obtained when the covariance
+ * matrices are calculated with the CovarianceMatrixCalculator:
+ *
+ * \code{.cpp}
+ * double FRENormalizationFactor = sqrt ( MeanVarianceX + MeanVarianceY );
+ * \endcode
+ *
+ * if no FRE normalization is used the normalization factor is set to 1.0
+ * as default value.
+ */
+ itkSetMacro(FRENormalizationFactor, double)
+
+ /** Set search radius for the correspondence search.*/
+ itkSetMacro(SearchRadius, double)
+
+ /** Set the maximim number of iterations used by the point based registration
+ * algorithm.
+ */
+ itkSetMacro(MaxIterationsInWeightedPointTransform, double)
+
+ /** Get the fiducial registration error (FRE).*/
+ itkGetMacro(FRE,double)
+
+ /** Get the number of iterations used by the algorithm.*/
+ itkGetMacro(NumberOfIterations, unsigned int)
+
+ /**
+ * Factor that trimms the point set in percent for
+ * partial overlapping surfaces. E.g. 0.4 will use 40 precent
+ * of the point set. To enable the trimmed version a
+ * factor > 0 and < 1 must be set. The default value is 0.0.
+ */
+ itkSetMacro(TrimmFactor,double)
+
+ /**
+ * Set moving surface that includes the point set (X).
+ */
+ itkSetMacro(MovingSurface,itk::SmartPointer<Surface>)
+
+ /**
+ * Set fixed surface that includes the point set (Y).
+ */
+ itkSetMacro(FixedSurface,itk::SmartPointer<Surface>)
+
+ /**
+ * Returns the 3x1 translation vector computed by the algorithm.
+ */
+ itkGetConstReferenceMacro(Translation,Translation)
+
+ /**
+ * Returns the 3x3 rotation matrix computed by the algorithm.
+ */
+ itkGetConstReferenceMacro(Rotation,Rotation)
+
+ /**
+ * Set the covariance matrices of the moving surface. The algorithm
+ * need the same amount of covariance and points available in the surface.
+ * The covariance matrix for every vertex in a Surface can be calculated by
+ * the CovarianceMatrixCalculator. It is also possible to define
+ * arbitrary matrices by hand.
+ */
+ void SetCovarianceMatricesMovingSurface( CovarianceMatrixList& list )
+ {
+ m_CovarianceMatricesMovingSurface = list;
+ }
+
+ /**
+ * Set the covariance matrices of the fixed surface. The algorithm
+ * need the same amount of covariance and points available in the surface.
+ * The covariance matrix for every vertex in a Surface can be calculated by
+ * the CovarianceMatrixCalculator. It is also possible to define
+ * arbitrary matrices by hand.
+ */
+ void SetCovarianceMatricesFixedSurface( CovarianceMatrixList& list )
+ {
+ m_CovarianceMatricesFixedSurface = list;
+ }
+
+ /**
+ * This method executes the algorithm.
+ *
+ * @warning The algorithm is only a simple calculation filter and can not be
+ * used in a mitk filter pipline.
+ *
+ * @throws Exception if the search radius was doubled more than 20 times to
+ * prevent endless loops. Re-run the with a different search radius that
+ * will find the correspondences.
+ */
+ void Update();
+};
+
+}
+#endif
+
diff --git a/Modules/AlgorithmsExt/mitkAnisotropicRegistrationCommon.cpp b/Modules/AlgorithmsExt/mitkAnisotropicRegistrationCommon.cpp
new file mode 100644
index 0000000000..b3c297c15f
--- /dev/null
+++ b/Modules/AlgorithmsExt/mitkAnisotropicRegistrationCommon.cpp
@@ -0,0 +1,109 @@
+/*===================================================================
+
+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 <mitkAnisotropicRegistrationCommon.h>
+#include <vtkPoints.h>
+#include <mitkPointSet.h>
+
+mitk::AnisotropicRegistrationCommon::WeightMatrix
+mitk::AnisotropicRegistrationCommon::CalculateWeightMatrix(const CovarianceMatrix &sigma_X,
+ const CovarianceMatrix &sigma_Y )
+{
+ WeightMatrix returnValue;
+
+ WeightMatrix sum = sigma_X + sigma_Y;
+ vnl_svd<double> svd(sum.GetVnlMatrix());
+
+ WeightMatrix diag; diag.Fill(0.0);
+ diag[0][0] = 1.0 / sqrt(svd.W(0));
+ diag[1][1] = 1.0 / sqrt(svd.W(1));
+ diag[2][2] = 1.0 / sqrt(svd.W(2));
+
+ WeightMatrix V; //convert vnl matrix to itk matrix...
+ for (unsigned int i = 0; i < 3; ++i)
+ for (unsigned int j = 0; j < 3; ++j)
+ V[i][j] = svd.V()[i][j];
+
+ //add weighting matrix for point j1 (corresponding to identity transform)
+ returnValue = V * diag * V.GetTranspose();
+
+ return returnValue;
+}
+
+void mitk::AnisotropicRegistrationCommon::TransformPoints( vtkPoints *src,
+ vtkPoints *dst,
+ const Rotation &rotation,
+ const Translation &translation )
+{
+#pragma omp parallel for
+ for ( vtkIdType i = 0; i < src->GetNumberOfPoints(); ++i )
+ {
+ double p_in[3];
+ double p_out[3];
+ src->GetPoint(i,p_in);
+
+ for ( unsigned int j = 0; j < 3; ++j )
+ {
+ p_out[j] = p_in[0] * rotation[j][0] +
+ p_in[1] * rotation[j][1] +
+ p_in[2] * rotation[j][2] +
+ translation[j];
+ }
+
+ dst->SetPoint(i,p_out);
+ }
+}
+
+void mitk::AnisotropicRegistrationCommon::PropagateMatrices( const MatrixList &src,
+ MatrixList &dst,
+ const Rotation &rotation )
+{
+
+ const vnl_matrix_fixed < double, 3, 3 > rotationT = rotation.GetTranspose();
+
+#pragma omp parallel for
+ for ( size_t i = 0; i < src.size(); ++i )
+ {
+ dst[i] = rotation * src[i] * rotationT;
+ }
+}
+
+double mitk::AnisotropicRegistrationCommon::ComputeTargetRegistrationError(const mitk::PointSet *movingTargets,
+ const mitk::PointSet *fixedTargets,
+ const Rotation &rotation,
+ const Translation &translation)
+{
+ double tre = 0.0;
+
+ for ( int i = 0; i < movingTargets->GetSize(); ++i )
+ {
+ mitk::Point3D pm = movingTargets->GetPoint(i);
+ mitk::Point3D ps = fixedTargets->GetPoint(i);
+
+ // transform point
+ pm = rotation * pm + translation;
+
+ const double dist = (ps[0] - pm[0]) * (ps[0] - pm[0]) +
+ (ps[1] - pm[1]) * (ps[1] - pm[1]) +
+ (ps[2] - pm[2]) * (ps[2] - pm[2]);
+
+ tre += dist;
+ }
+
+ tre /= movingTargets->GetSize();
+
+ return sqrt(tre);
+}
diff --git a/Modules/AlgorithmsExt/mitkAnisotropicRegistrationCommon.h b/Modules/AlgorithmsExt/mitkAnisotropicRegistrationCommon.h
new file mode 100644
index 0000000000..2ea8df065d
--- /dev/null
+++ b/Modules/AlgorithmsExt/mitkAnisotropicRegistrationCommon.h
@@ -0,0 +1,142 @@
+/*===================================================================
+
+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 __ANISOTROPICREGISTRATIONCOMMON_H__
+#define __ANISOTROPICREGISTRATIONCOMMON_H__
+
+#include <mitkCommon.h>
+#include <itkMatrix.h>
+#include <mitkVector.h>
+
+#include "MitkAlgorithmsExtExports.h"
+
+// forward declarations
+class vtkPoints;
+
+namespace mitk
+{
+
+class PointSet;
+
+
+/**
+ * \ingroup AnisotropicRegistration
+ * \brief A Class that provides common static functions used by all classes
+ * and tests in the anisotropic iterative closest point algorithm
+ * (AnisotropicIterativeClosestPointRegistration).
+ *
+ * The class provides common functionality used by the A-ICP algorithm like:
+ * compute weightmatrices (@ref CalculateWeightMatrix()),
+ * transform points (@ref TransformPoints()), propagate 3 x 3 matrices
+ * (@ref PropagateMatrices()) and compute the target registration error (TRE)
+ * (@ref ComputeTargetRegistrationError()).
+ */
+class MitkAlgorithmsExt_EXPORT AnisotropicRegistrationCommon
+{
+
+protected:
+
+ // local typedefs
+
+ /** Definition of the 3 x 3 weight matrix.*/
+ typedef itk::Matrix <double, 3, 3> WeightMatrix;
+ /** Definition of a rotation matrix.*/
+ typedef WeightMatrix Rotation;
+ /** Definition of the covariance matrix.*/
+ typedef WeightMatrix CovarianceMatrix;
+ /** Definition of the translation vector.*/
+ typedef mitk::Vector3D Translation;
+ /** Definition of the weight matrix list.*/
+ typedef std::vector< WeightMatrix > MatrixList;
+
+ AnisotropicRegistrationCommon(){}
+ ~AnisotropicRegistrationCommon(){}
+
+public:
+
+/** @brief Method that computes a WeightMatrix with two CovarianceMatrices.
+ * @param sigma_X CovarianceMatrix from the moving point set.
+ * @param sigma_Y CovarianceMatrix from the fixed point set.
+ * @return The computed WeighMatrix.
+ */
+static WeightMatrix CalculateWeightMatrix( const CovarianceMatrix &sigma_X,
+ const CovarianceMatrix &sigma_Y );
+
+/**
+ * @brief Transforms a point cloud with a Rotation and Translation.
+ *
+ * The method uses two point sets as input. It transforms every point from the
+ * source point set and saves the result in the destination. The soure is not
+ * modified. If the same point set is used as source and destination. The method
+ * will modify the source and the transformation is done in place.
+ *
+ * @warning No bound check is done. Ensure that source and destination are
+ * allocated and have the same size.
+ *
+ * @param src The source point set.
+ * @param dst The destination point set.
+ * @param rotation The rotation matrix.
+ * @param translation The translation vector.
+ *
+ */
+static void TransformPoints( vtkPoints* src,
+ vtkPoints* dst,
+ const Rotation& rotation,
+ const Translation& translation );
+
+/**
+ * @brief Propagate a list of matrices with a rotation matrix.
+ *
+ * Method that propagate the source list and saves the result in the destination.
+ * If the source and destination lists are the same the matrices will be computed
+ * in place.
+ *
+ * @warning No bound check is done. Make sure that both lists are allocated and
+ * have the same size.
+ *
+ * @param src Reference to the source matrices list.
+ * @param dst Reference to the destination list
+ * @param rotation Reference to a rotation matrix.
+ */
+static void PropagateMatrices( const MatrixList &src,
+ MatrixList& dst,
+ const Rotation &rotation );
+
+/**
+ * @brief Compute the target registration error between two point sets.
+ *
+ * Method that is used for testing and evaluation. It computes the target
+ * registration error (TRE) between two point sets with a rotation matrix and
+ * a translation vector.
+ *
+ * @param movingTargets The target points of the moving point set.
+ * @param fixedTargets The target points of the fixed point set.
+ * @param rotation A 3x3 rotation matrix.
+ * @param translation A 3x1 translation vector.
+ *
+ * @return The Target Registration Error (TRE).
+ */
+static double ComputeTargetRegistrationError( const mitk::PointSet* movingTargets,
+ const mitk::PointSet* fixedTargets,
+ const Rotation& rotation,
+ const Translation& translation
+ );
+
+};
+
+}
+
+#endif
diff --git a/Modules/AlgorithmsExt/mitkCovarianceMatrixCalculator.cpp b/Modules/AlgorithmsExt/mitkCovarianceMatrixCalculator.cpp
new file mode 100644
index 0000000000..dc62d527e9
--- /dev/null
+++ b/Modules/AlgorithmsExt/mitkCovarianceMatrixCalculator.cpp
@@ -0,0 +1,421 @@
+/*===================================================================
+
+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 "mitkCovarianceMatrixCalculator.h"
+#include <mitkSurface.h>
+#include <vtkPolyDataNormals.h>
+#include <vtkSmartPointer.h>
+#include <vtkPointData.h>
+#include <vtkCell.h>
+#include <vtkCellLinks.h>
+#include <vtkPlane.h>
+#include <mitkExceptionMacro.h>
+
+// forward declarations of private functions
+static vtkIdList* GetNeighboursOfPoint( unsigned int index, vtkPolyData* polydata);
+
+static vtkIdList* CalculatePCAonPointNeighboursForNormalVector ( int index,
+ double normal[3],
+ itk::Matrix<double,3,3> & mat,
+ double curVertex[3],
+ std::vector<mitk::Point3D>& pointList,
+ vtkPolyData* polyData
+ );
+
+static itk::Matrix<double,3,3> ComputeCovarianceMatrix( itk::Matrix < double,3,3 > & axes,
+ double sigma[3],
+ double normalizationValue
+ );
+namespace mitk
+{
+
+/** \brief Pimpl to hold the private data in the CovarianceMatrixCalculator.*/
+struct CovarianceMatrixCalculatorData
+{
+ vtkPolyDataNormals* m_PolyDataNormals;
+ vtkPolyData* m_PolyData;
+ Surface* m_Input;
+ double m_VoronoiScalingFactor;
+ bool m_EnableNormalization;
+ double m_MeanVariance;
+
+ CovarianceMatrixCalculatorData()
+ : m_PolyDataNormals(vtkPolyDataNormals::New()),
+ m_PolyData(NULL),
+ m_Input(NULL),
+ m_VoronoiScalingFactor(1.0),
+ m_EnableNormalization(false),
+ m_MeanVariance(0.0)
+ {
+ m_PolyDataNormals->SplittingOff();
+ }
+
+ ~CovarianceMatrixCalculatorData()
+ {
+ if ( m_PolyDataNormals )
+ m_PolyDataNormals->Delete();
+ }
+};
+
+}
+
+mitk::CovarianceMatrixCalculator::CovarianceMatrixCalculator()
+ : d (new CovarianceMatrixCalculatorData())
+{
+}
+
+mitk::CovarianceMatrixCalculator::~CovarianceMatrixCalculator()
+{
+ delete d;
+}
+
+void mitk::CovarianceMatrixCalculator::SetVoronoiScalingFator(const double factor)
+{
+ d->m_VoronoiScalingFactor = factor;
+}
+
+void mitk::CovarianceMatrixCalculator::EnableNormalization(bool state)
+{
+ d->m_EnableNormalization = state;
+}
+
+double mitk::CovarianceMatrixCalculator::GetMeanVariance() const
+{
+ return d->m_MeanVariance;
+}
+
+const mitk::CovarianceMatrixCalculator::CovarianceMatrixList&
+mitk::CovarianceMatrixCalculator::GetCovarianceMatrices() const
+{
+ return m_CovarianceMatrixList;
+}
+
+void mitk::CovarianceMatrixCalculator::SetInputSurface(Surface *input)
+{
+ d->m_Input = input;
+}
+
+void mitk::CovarianceMatrixCalculator::ComputeCovarianceMatrices()
+{
+ double normalizationValue = -1.0;
+ vtkDataArray* normals = NULL;
+ d->m_MeanVariance = 0.0;
+
+ if ( !d->m_Input )
+ mitkThrow() << "No input surface was set in mitk::CovarianceMatrixCalculator";
+
+ d->m_PolyData = d->m_Input->GetVtkPolyData();
+
+ // Optional normal calculation can be disabled to use the normals
+ // of the surface:
+ //normals = d->m_PolyData->GetPointData()->GetNormals();
+ //// compute surface normals if the surface has no normals
+ //if ( normals == NULL )
+ //{
+ d->m_PolyDataNormals->SetInputData(d->m_PolyData);
+ d->m_PolyDataNormals->Update();
+ normals = d->m_PolyDataNormals->GetOutput()->GetPointData()->GetNormals();
+ //}
+
+ if( d->m_EnableNormalization )
+ normalizationValue = 1.5;
+
+ // clear the matrixlist
+ m_CovarianceMatrixList.clear();
+ // allocate memory if required
+ if ( d->m_PolyData->GetNumberOfPoints() > (vtkIdType)m_CovarianceMatrixList.capacity() )
+ m_CovarianceMatrixList.reserve(d->m_PolyData->GetNumberOfPoints());
+
+ for ( vtkIdType i = 0; i < d->m_PolyData->GetNumberOfPoints(); ++i )
+ {
+ Vertex normal;
+ Vertex currentVertex;
+ Vertex variances = { 0.0, 0.0, 0.0 };
+ CovarianceMatrix mat; mat.Fill(0.0);
+
+ normals->GetTuple(i,normal);
+ d->m_PolyData->GetPoint(i, currentVertex);
+
+ ComputeOrthonormalCoordinateSystem(i,normal,mat,variances, currentVertex);
+
+ //use prefactor for sigma along surface
+ variances[0] = (d->m_VoronoiScalingFactor * variances[0]);
+ variances[1] = (d->m_VoronoiScalingFactor * variances[1]);
+ variances[2] = (d->m_VoronoiScalingFactor * variances[2]);
+
+ d->m_MeanVariance += ( variances[0] + variances[1] + variances[2] );
+ // compute the covariance matrix and save it
+ const CovarianceMatrix covarianceMatrix = ComputeCovarianceMatrix(mat, variances, normalizationValue);
+ m_CovarianceMatrixList.push_back(covarianceMatrix);
+ }
+
+ if ( d->m_EnableNormalization )
+ d->m_MeanVariance = normalizationValue / 3.0;
+ else
+ d->m_MeanVariance /= (3.0 * (double) d->m_PolyData->GetNumberOfPoints());
+
+ // reset input
+ d->m_PolyData = NULL;
+ d->m_Input = NULL;
+}
+
+// Get a list with the id's of all surrounding conected vertices
+// to the current vertex at the given index in the polydata
+vtkIdList* GetNeighboursOfPoint( unsigned int index, vtkPolyData* polydata)
+{
+ vtkIdList* cellIds = vtkIdList::New();
+ vtkIdList* result = vtkIdList::New();
+ polydata->GetPointCells(index,cellIds);
+
+ for (vtkIdType j=0; j < cellIds->GetNumberOfIds(); j++)
+ {
+ vtkIdList* newPoints = polydata->GetCell(cellIds->GetId(j))->GetPointIds();
+ for (vtkIdType k=0; k < newPoints->GetNumberOfIds(); k++)
+ {
+ //if point has not yet been inserted add id
+ if (result->IsId(newPoints->GetId(k))==-1)
+ {
+ result->InsertNextId(newPoints->GetId(k));
+ }
+ }
+ }
+ cellIds->Delete();
+ return result;
+}
+
+// Computes a primary component analysis of the surounding vertices
+// of the verex at the current index.
+vtkIdList* CalculatePCAonPointNeighboursForNormalVector( int index,
+ double normal[3],
+ itk::Matrix<double,3,3> & mat,
+ double curVertex[3],
+ std::vector<mitk::Point3D>& pointList,
+ vtkPolyData* polyData
+ )
+{
+ typedef std::vector<mitk::Point3D> VectorType;
+ typedef VectorType::const_iterator ConstPointIterator;
+ typedef double Vertex[3];
+
+ Vertex mean = { 0.0, 0.0, 0.0 };
+ Vertex tmp = { 0.0, 0.0, 0.0 };
+ vtkIdList* neighbourPoints = GetNeighboursOfPoint(index, polyData);
+ const vtkIdType size = neighbourPoints->GetNumberOfIds();
+
+ // reserve memory for all neighbours
+ pointList.reserve(size);
+
+ // project neighbours on plane given by normal
+ // and compute mean
+ for(vtkIdType i = 0; i < size; ++i)
+ {
+ mitk::Point3D p;
+ Vertex resultPoint;
+
+ polyData->GetPoint((neighbourPoints->GetId(i)),tmp);
+
+ vtkPlane::GeneralizedProjectPoint(tmp,curVertex,normal,resultPoint);
+
+ p[0] = resultPoint[0];
+ p[1] = resultPoint[1];
+ p[2] = resultPoint[2];
+
+ mean[0] += p[0];
+ mean[1] += p[1];
+ mean[2] += p[2];
+
+ pointList.push_back(p);
+ }
+
+ mean[0] /= (double) size;
+ mean[1] /= (double) size;
+ mean[2] /= (double) size;
+
+ // compute the covariances with matrix multiplication
+ for( ConstPointIterator it = pointList.begin(); it != pointList.end(); ++it )
+ {
+ tmp[0] = ((*it)[0] - mean[0]);
+ tmp[1] = ((*it)[1] - mean[1]);
+ tmp[2] = ((*it)[2] - mean[2]);
+
+ // on diagonal elements
+ mat[0][0] += tmp[0] * tmp[0];
+ mat[1][1] += tmp[1] * tmp[1];
+ mat[2][2] += tmp[2] * tmp[2];
+
+ // of diagonal elements
+ mat[1][0] += tmp[0] * tmp[1];
+ mat[2][0] += tmp[0] * tmp[2];
+ mat[2][1] += tmp[1] * tmp[2];
+ }
+
+ // copy upper triangle to lower triangle,
+ // we got a symetric matrix
+ mat[0][1] = mat[1][0];
+ mat[0][2] = mat[2][0];
+ mat[1][2] = mat[2][1];
+
+ // variance
+ mat /= (size - 1);
+
+ vnl_svd<double> svd(mat.GetVnlMatrix());
+
+ for ( int i = 0; i < 3; ++i )
+ for ( int j = 0; j < 3; ++j )
+ mat[i][j] = svd.U()[j][i];
+
+ return neighbourPoints;
+}
+
+// Computes an orthonormal system for a vertex with it's surrounding neighbours.
+void mitk::CovarianceMatrixCalculator::ComputeOrthonormalCoordinateSystem( const int index,
+ Vertex normal,
+ CovarianceMatrix& axes,
+ Vertex variances,
+ Vertex curVertex
+ )
+{
+ typedef std::vector<mitk::Point3D> VectorType;
+ typedef VectorType::const_iterator ConstPointIterator;
+ VectorType projectedPoints;
+
+ Vertex meanValues = { 0.0, 0.0, 0.0 };
+ //project neighbours to new coordinate system and get principal axes
+ vtkIdList* neighbourPoints = CalculatePCAonPointNeighboursForNormalVector( index,
+ normal,
+ axes,
+ curVertex,
+ projectedPoints,
+ d->m_PolyData );
+
+ // Set the normal as the third principal axis
+ axes[2][0] = normal[0];
+ axes[2][1] = normal[1];
+ axes[2][2] = normal[2];
+
+ for( vtkIdType i = 0; i < neighbourPoints->GetNumberOfIds(); ++i )
+ {
+ mitk::Point3D projectedPoint;
+ Vertex curNeighbour;
+ d->m_PolyData->GetPoint(neighbourPoints->GetId(i), curNeighbour);
+
+ curNeighbour[0] = curNeighbour[0] - curVertex[0];
+ curNeighbour[1] = curNeighbour[1] - curVertex[1];
+ curNeighbour[2] = curNeighbour[2] - curVertex[2];
+
+ for(int k = 0; k < 3; ++k)
+ {
+ projectedPoint[k] = axes[k][0] * curNeighbour[0] +
+ axes[k][1] * curNeighbour[1] +
+ axes[k][2] * curNeighbour[2];
+
+ meanValues[k] += projectedPoint[k];
+ }
+ // reuse the allocated vector from the PCA on the point neighbours
+ projectedPoints[i] = projectedPoint;
+ }
+
+ meanValues[0] /= (double) projectedPoints.size();
+ meanValues[1] /= (double) projectedPoints.size();
+ meanValues[2] /= (double) projectedPoints.size();
+
+ // compute variances along new axes
+ for( ConstPointIterator it = projectedPoints.begin(); it != projectedPoints.end(); ++it )
+ {
+ const mitk::Point3D& p = *it;
+
+ variances[0] += (p[0] - meanValues[0]) * (p[0] - meanValues[0]);
+ variances[1] += (p[1] - meanValues[1]) * (p[1] - meanValues[1]);
+ variances[2] += (p[2] - meanValues[2]) * (p[2] - meanValues[2]);
+ }
+
+ variances[0] /= (double) (projectedPoints.size() - 1);
+ variances[1] /= (double) (projectedPoints.size() - 1);
+ variances[2] /= (double) (projectedPoints.size() - 1);
+
+ //clean up
+ neighbourPoints->Delete();
+}
+
+// Sorts the axes of the computed orthonormal system based on
+// the eigenvalues in a descending order
+itk::Matrix<double,3,3> ComputeCovarianceMatrix( itk::Matrix < double,3,3 > & axes,
+ double sigma[3],
+ double normalizationValue
+ )
+{
+ unsigned int idxMax,idxMin,idxBetween;
+ itk::Matrix<double,3,3> returnValue;
+ itk::Matrix<double,3,3> V;
+ itk::Matrix<double,3,3> diagMatrix;
+ diagMatrix.Fill(0.0);
+
+ if(sigma[0] >= sigma[1] && sigma[0] >= sigma[2])
+ {
+ idxMax = 0;
+ if(sigma[1] >= sigma[2])
+ {
+ idxBetween = 1;
+ idxMin = 2;
+ } else
+ {
+ idxBetween = 2;
+ idxMin = 1;
+ }
+ } else if (sigma[1] >= sigma[0] && sigma[1] >= sigma[2])
+ {
+ idxMax = 1;
+ if(sigma[0] >= sigma[2])
+ {
+ idxBetween = 0;
+ idxMin = 2;
+ } else
+ {
+ idxBetween = 2;
+ idxMin = 0;
+ }
+ } else // index 2 corresponds to largest sigma
+ {
+ idxMax = 2;
+ if(sigma[0] >= sigma[1])
+ {
+ idxBetween = 0;
+ idxMin = 1;
+ } else
+ {
+ idxBetween = 1;
+ idxMin = 0;
+ }
+ }
+
+ V[0][0] = axes[idxMax][0]; V[1][0] = axes[idxMax][1]; V[2][0] = axes[idxMax][2];
+ V[0][1] = axes[idxBetween][0]; V[1][1] = axes[idxBetween][1]; V[2][1] = axes[idxBetween][2];
+ V[0][2] = axes[idxMin][0]; V[1][2] = axes[idxMin][1]; V[2][2] = axes[idxMin][2];
+
+ diagMatrix[0][0] = sigma[idxMax];
+ diagMatrix[1][1] = sigma[idxBetween];
+ diagMatrix[2][2] = sigma[idxMin];
+
+ returnValue = V * diagMatrix * V.GetTranspose();
+
+ if(normalizationValue > 0.0)
+ {
+ double trace = returnValue[0][0] + returnValue[1][1] + returnValue[2][2];
+ returnValue *= (normalizationValue / trace);
+ }
+
+ return returnValue;
+}
diff --git a/Modules/AlgorithmsExt/mitkCovarianceMatrixCalculator.h b/Modules/AlgorithmsExt/mitkCovarianceMatrixCalculator.h
new file mode 100644
index 0000000000..82e2182df8
--- /dev/null
+++ b/Modules/AlgorithmsExt/mitkCovarianceMatrixCalculator.h
@@ -0,0 +1,130 @@
+/*===================================================================
+
+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 __MITK_COVARIANCEMATRIXCALCULATOR_H__
+#define __MITK_COVARIANCEMATRIXCALCULATOR_H__
+
+// exports
+#include "MitkAlgorithmsExtExports.h"
+
+#include <mitkCommon.h>
+
+#include <itkObjectFactory.h>
+#include <vector>
+#include <itkMatrix.h>
+
+namespace mitk
+{
+// forward declarations
+class Surface;
+struct CovarianceMatrixCalculatorData;
+
+/**
+ * \ingroup AnisotropicRegistration
+ *
+ * @brief Class that computes the covariance matrices for every point in a
+ * {@link Surface} used in the A-ICP algorithm.
+ *
+ * Computes a covariance matrix for every vertex in a given {@link Surface}
+ * based on it's direct neighbours and saves them into a CovarianceMatrixList.
+ * The Class implements the CM_PCA method presented by
+ * L. Maier-Hein et al. in "Convergent Iterative Closest-Point Algorithm
+ * to Accomodate Anisotropic and Inhomogenous Localization Error.",
+ * IEEE T Pattern Anal 34 (8), 1520-1532, 2012. The algorithm needs
+ * a clean Surface with non manifold edges and no duplicated vertices. To
+ * ensure a clean Surface representation use vtkCleanPolyData.
+ */
+class MitkAlgorithmsExt_EXPORT CovarianceMatrixCalculator : public itk::Object
+{
+
+private:
+ /** Pimpl to hold private data.*/
+ CovarianceMatrixCalculatorData* d;
+
+protected:
+
+ // local typedefs
+
+ /** Definition of the covariance matrix.*/
+ typedef itk::Matrix<double,3,3> CovarianceMatrix;
+ /** Definition of a list of covariance matrices */
+ typedef std::vector<CovarianceMatrix> CovarianceMatrixList;
+ typedef double Vertex[3];
+
+ /** List that stores the computed covariance matrices. */
+ CovarianceMatrixList m_CovarianceMatrixList;
+
+ /** This method projects all surrounding vertices of given vertex in a Surface
+ * in the normal direction onto a plane and computes a primary component
+ * analysis on the projected vertices. In the next step a orthonormal
+ * system is created.
+ *
+ * @param The index of the input Vertex in the Surface.
+ * @param The normal of the input Vertex.
+ * @param Output CovarianceMatrix of the principal component analysis.
+ * @param Output. Variances along the axes of the createt Orthonormal system.
+ * @param Output. The current Vertex in the surface
+ *
+ */
+ void ComputeOrthonormalCoordinateSystem( const int index,
+ Vertex normal,
+ CovarianceMatrix &principalComponents,
+ Vertex variances,
+ Vertex curVertex);
+ CovarianceMatrixCalculator();
+ ~CovarianceMatrixCalculator();
+
+public:
+ mitkClassMacro(CovarianceMatrixCalculator, itk::Object)
+ itkFactorylessNewMacro (Self)
+ itkCloneMacro(Self)
+
+ /** Sets the scaling factor for the voronoi area.
+ * @param factor The scaling factor.
+ */
+ void SetVoronoiScalingFator( const double factor );
+
+ /** Enables/disables the covariance matrix normalization.
+ * @param state Enables the covariance matrix normalization.
+ */
+ void EnableNormalization( bool state );
+
+ /** Returns the mean of variance of all computed covariance matrices.
+ * @return The mean variance.
+ */
+ double GetMeanVariance() const;
+
+ /** Returns a reference to the CovarianceMatrixList with the computed covariance matrices.
+ * @return A CovarianceMatrixList.
+ */
+ const CovarianceMatrixList& GetCovarianceMatrices() const;
+
+ /** Sets the input {@link Surface} for which the covariance matrices will be calculated.
+ * @param input A {@link Surface}.
+ */
+ void SetInputSurface (Surface *input);
+
+
+ /** Method that computes the covariance matrices for the input surface.
+ * @throws std::exception If the input surface is not set.
+ */
+ void ComputeCovarianceMatrices();
+
+};
+
+}
+
+#endif
diff --git a/Modules/AlgorithmsExt/mitkWeightedPointTransform.cpp b/Modules/AlgorithmsExt/mitkWeightedPointTransform.cpp
new file mode 100644
index 0000000000..6ac325c29a
--- /dev/null
+++ b/Modules/AlgorithmsExt/mitkWeightedPointTransform.cpp
@@ -0,0 +1,477 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+//MITK
+#include "mitkWeightedPointTransform.h"
+#include "mitkAnisotropicRegistrationCommon.h"
+#include <vtkLandmarkTransform.h>
+#include <vtkPoints.h>
+#include <vtkMatrix4x4.h>
+
+typedef itk::Matrix < double,3,3 > Matrix3x3;
+typedef std::vector < Matrix3x3 > Matrix3x3List;
+
+///////////////////////////////////////////////
+// forward declarations of private functions
+///////////////////////////////////////////////
+
+static double ComputeWeightedFRE ( vtkPoints* X,
+ vtkPoints* Y,
+ const Matrix3x3List &CovarianceMatricesMoving,
+ const Matrix3x3List &CovarianceMatricesFixed,
+ double FRENormalizationFactor,
+ Matrix3x3List& WeightMatrices,
+ const Matrix3x3& rotation,
+ const itk::Vector<double,3>& translation
+ );
+
+static void calculateWeightMatrices( const Matrix3x3List& X,
+ const Matrix3x3List& Y,
+ Matrix3x3List& result,
+ const Matrix3x3& rotation
+ );
+
+static void IsotropicRegistration( vtkPoints* X,
+ vtkPoints* Y,
+ vtkLandmarkTransform* landmarkTransform,
+ Matrix3x3& rotation,
+ itk::Vector<double,3>& translation
+ );
+
+mitk::WeightedPointTransform::WeightedPointTransform()
+ : m_Threshold(1.0e-4),
+ m_MaxIterations(1000),
+ m_Iterations(-1),
+ m_FRE(-1.0),
+ m_FRENormalizationFactor(1.0),
+ m_LandmarkTransform(vtkSmartPointer<vtkLandmarkTransform>::New())
+{
+}
+
+mitk::WeightedPointTransform::~WeightedPointTransform()
+{
+ m_FixedPointSet = NULL;
+ m_MovingPointSet = NULL;
+ m_LandmarkTransform = NULL;
+}
+
+void mitk::WeightedPointTransform::ComputeTransformation()
+{
+ WeightedPointRegister( m_MovingPointSet,
+ m_FixedPointSet,
+ m_CovarianceMatricesMoving,
+ m_CovarianceMatricesFixed,
+ m_Threshold,
+ m_MaxIterations,
+ m_Rotation,
+ m_Translation,
+ m_FRE,
+ m_Iterations );
+}
+
+// computes the weightmatrix with 2 covariance matrices
+// and a given transformation
+void calculateWeightMatrices( const Matrix3x3List& X,
+ const Matrix3x3List& Y,
+ Matrix3x3List& result,
+ const Matrix3x3& rotation )
+{
+ const vnl_matrix_fixed<double,3,3> rotation_T = rotation.GetTranspose();
+
+#pragma omp parallel for
+ for ( size_t i = 0; i < X.size(); ++i )
+ {
+ const Matrix3x3 w = rotation * X[i] * rotation_T;
+ result[i] = mitk::AnisotropicRegistrationCommon::CalculateWeightMatrix(w,Y[i]);
+ }
+}
+
+// computes the weighted fiducial registration error
+double ComputeWeightedFRE ( vtkPoints* X,
+ vtkPoints* Y,
+ const Matrix3x3List &CovarianceMatricesMoving,
+ const Matrix3x3List &CovarianceMatricesFixed,
+ double FRENormalizationFactor,
+ Matrix3x3List& WeightMatrices,
+ const Matrix3x3& rotation,
+ const itk::Vector<double,3>& translation
+ )
+{
+ double FRE = 0;
+ //compute weighting matrices
+ calculateWeightMatrices( CovarianceMatricesMoving,
+ CovarianceMatricesFixed,
+ WeightMatrices,
+ rotation );
+
+#pragma omp parallel for reduction(+:FRE)
+ for (unsigned int i = 0; i < WeightMatrices.size(); ++i)
+ {
+ //convert to itk data types (nessecary since itk 4 migration)
+ itk::Vector<double,3> converted_MovingPoint;
+ double point[3];
+ X->GetPoint(i,point);
+ converted_MovingPoint[0] = point[0];
+ converted_MovingPoint[1] = point[1];
+ converted_MovingPoint[2] = point[2];
+
+ // transform point
+ itk::Vector<double,3> p = rotation * converted_MovingPoint + translation;
+
+ Y->GetPoint(i,point);
+ p[0] -= point[0];
+ p[1] -= point[1];
+ p[2] -= point[2];
+
+ //do calculation
+ const itk::Vector<double,3> D = WeightMatrices.at(i) * p;
+ FRE += (D[0] * D[0] + D[1] * D[1] + D[2] * D[2]);
+ }
+
+ FRE /= WeightMatrices.size();
+ FRE = FRENormalizationFactor * sqrt(FRE);
+
+ return FRE;
+}
+
+// registers two pointsets with an isotropic landmark transform
+void IsotropicRegistration( vtkPoints* X,
+ vtkPoints* Y,
+ vtkLandmarkTransform* landmarkTransform,
+ Matrix3x3& rotation,
+ itk::Vector<double,3>& translation )
+{
+ landmarkTransform->SetSourceLandmarks(X);
+ landmarkTransform->SetTargetLandmarks(Y);
+ landmarkTransform->SetModeToRigidBody();
+ landmarkTransform->Modified();
+ landmarkTransform->Update();
+
+ vtkMatrix4x4* m = landmarkTransform->GetMatrix();
+
+ for ( int i = 0; i < 3; ++i )
+ for ( int j = 0; j < 3;++j )
+ rotation[i][j] = m->GetElement(i,j);
+
+ translation[0] = m->GetElement(0,3);
+ translation[1] = m->GetElement(1,3);
+ translation[2] = m->GetElement(2,3);
+}
+
+void mitk::WeightedPointTransform::C_maker( vtkPoints* X,
+ const WeightMatrixList &W,
+ itk::VariableSizeMatrix< double >& returnValue )
+{
+#pragma omp parallel for
+ for(vtkIdType i = 0; i < X->GetNumberOfPoints(); ++i )
+ {
+ unsigned int index = 3u * i;
+ double point[3];
+ X->GetPoint(i,point);
+
+ for ( int j = 0; j < 3; ++j )
+ {
+ returnValue[index][0] = -W.at(i)[j][1] * point[2] + W.at(i)[j][2] * point[1];
+ returnValue[index][1] = W.at(i)[j][0] * point[2] - W.at(i)[j][2] * point[0];
+ returnValue[index][2] = -W.at(i)[j][0] * point[1] + W.at(i)[j][1] * point[0];
+ returnValue[index][3] = W.at(i)[j][0];
+ returnValue[index][4] = W.at(i)[j][1];
+ returnValue[index][5] = W.at(i)[j][2];
+ index += 1;
+ }
+ }
+}
+
+void mitk::WeightedPointTransform::E_maker( vtkPoints* X,
+ vtkPoints* Y,
+ const WeightMatrixList &W,
+ vnl_vector< double >& returnValue
+ )
+{
+#pragma omp parallel for
+ for( vtkIdType i = 0; i < X->GetNumberOfPoints(); ++i )
+ {
+ unsigned int index = 3u * i;
+ double pX[3];
+ double pY[3];
+ Matrix3x3 M;
+
+ X->GetPoint(i,pX);
+ Y->GetPoint(i,pY);
+
+ M[0][0] = pY[0] - pX[0];
+ M[0][1] = pY[1] - pX[1];
+ M[0][2] = pY[2] - pX[2];
+ M[1][0] = M[0][0];
+ M[1][1] = M[0][1];
+ M[1][2] = M[0][2];
+ M[2][0] = M[0][0];
+ M[2][1] = M[0][1];
+ M[2][2] = M[0][2];
+
+
+ for ( unsigned int j = 0; j < 3; ++j )
+ {
+ returnValue[index + j] = W.at(i)[j][0] * M[j][0] +
+ W.at(i)[j][1] * M[j][1] +
+ W.at(i)[j][2] * M[j][2];
+ }
+ }
+}
+
+void mitk::WeightedPointTransform::WeightedPointRegister(
+ vtkPoints *X,
+ vtkPoints *Y,
+ const CovarianceMatrixList &Sigma_X,
+ const CovarianceMatrixList &Sigma_Y,
+ double Threshold,
+ int MaxIterations,
+ Rotation &TransformationR,
+ Translation &TransformationT,
+ double& FRE,
+ int& n
+ )
+{
+ double FRE_identity = 0.0;
+ double FRE_isotropic_weighted = 0.0;
+ double initialFRE = 0.0;
+ //set config_change to infinite (max double) at start
+ double config_change = std::numeric_limits<double>::max();
+ Rotation initial_TransformationR; initial_TransformationR.SetIdentity();
+ Translation initial_TransformationT; initial_TransformationT.Fill(0.0);
+ // Weightmatrices
+ Matrix3x3List W;
+ vtkPoints* X_transformed = vtkPoints::New();
+ vtkPoints* X_transformedNew = vtkPoints::New();
+ vnl_vector< double > oldq;
+ itk::VariableSizeMatrix< double > iA;
+ vnl_vector< double > iB;
+
+ // initialize memory
+ W.resize(X->GetNumberOfPoints());
+ X_transformed->SetNumberOfPoints(X->GetNumberOfPoints());
+ X_transformedNew->SetNumberOfPoints(X->GetNumberOfPoints());
+ iA.SetSize(3u * X->GetNumberOfPoints(), 6u);
+ iB.set_size(3u * X->GetNumberOfPoints());
+
+ //calculate FRE_0 with identity transform
+ FRE_identity = ComputeWeightedFRE(X,Y,Sigma_X,Sigma_Y,m_FRENormalizationFactor,
+ W,initial_TransformationR,
+ initial_TransformationT);
+
+ MITK_DEBUG << "FRE for identity transform: "<<FRE_identity;
+
+ // compute isotropic transformation as initial estimate
+ IsotropicRegistration( X,Y,m_LandmarkTransform,initial_TransformationR,
+ initial_TransformationT );
+
+ //result of unweighted registration algorithm
+ TransformationR = initial_TransformationR;
+ TransformationT = initial_TransformationT;
+
+ //calculate FRE_0 with isotropic transform
+ FRE_isotropic_weighted = ComputeWeightedFRE(X,Y,Sigma_X,Sigma_Y,
+ m_FRENormalizationFactor,
+ W,TransformationR,TransformationT);
+ MITK_DEBUG << "FRE for transform obtained with unweighted registration: "
+ << FRE_isotropic_weighted;
+
+ //if R,t is worse than the identity, use the identity as initial transform
+ if (FRE_isotropic_weighted < FRE_identity)
+ {
+ initialFRE = FRE_isotropic_weighted;
+ } else {
+ initialFRE = FRE_identity;
+ TransformationR.SetIdentity(); //set rotation to identity element
+ TransformationT.Fill(0.0); //set translation to identity element
+ initial_TransformationR.SetIdentity();
+ initial_TransformationT.Fill(0.0);
+ }
+
+ //apply transform to moving set:
+ mitk::AnisotropicRegistrationCommon::TransformPoints( X, X_transformed,
+ TransformationR,
+ TransformationT );
+
+ //start with iteration 0
+ n = 0;
+
+ do {
+
+ n++;
+
+ calculateWeightMatrices(Sigma_X,Sigma_Y,W,TransformationR);
+
+ //'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+ //PROBLEM: no square matrix but the backslash operator in matlab does solve the system anyway. How to convert this to C++?
+ // good descriptons to the "backslash"-operator (in german): http://www.tm-mathe.de/Themen/html/matlab__zauberstab__backslash-.html
+ // http://www.tm-mathe.de/Themen/html/matlab__matrix-division__vorsi.html#HoheMatrixA
+ //
+ // current method: treat the problem as a minimization problem, because this is what the "backslash"-operator also does with "high" matrices.
+ // (and we will have those matrices in most cases)
+
+ C_maker(X_transformed,W,iA);
+ E_maker(X_transformed,Y,W,iB);
+
+ vnl_matrix_inverse<double> myInverse(iA.GetVnlMatrix());
+ vnl_vector< double > q = myInverse.pinverse(iB.size()) * iB;
+ //'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+ if (n>1)
+ q = (q+oldq)/2;
+ oldq = q;
+
+ itk::Vector<double,3> delta_t;
+ delta_t[0] = q[3];
+ delta_t[1] = q[4];
+ delta_t[2] = q[5];
+
+ Matrix3x3 delta_theta;
+ delta_theta[0][0] = 1;
+ delta_theta[0][1] = -q[2];
+ delta_theta[0][2] = q[1];
+ delta_theta[1][0] = q[2];
+ delta_theta[1][1] = 1;
+ delta_theta[1][2] = -q[0];
+ delta_theta[2][0] = -q[1];
+ delta_theta[2][1] = q[0];
+ delta_theta[2][2] = 1;
+
+ vnl_svd<double> svd_delta_theta(delta_theta.GetVnlMatrix());
+
+ //convert vnl matrices to itk matrices...
+ Matrix3x3 U;
+ Matrix3x3 V;
+
+ for (int i = 0; i < 3; ++i) {
+ for (int j = 0; j < 3; ++j) {
+ U[i][j] = svd_delta_theta.U()[i][j];
+ V[i][j] = svd_delta_theta.V()[i][j];
+ }
+ }
+
+ Matrix3x3 delta_R = U * V.GetTranspose();
+
+ //update rotation
+ TransformationR = delta_R * TransformationR;
+
+ //update translation
+ TransformationT = delta_R * TransformationT + delta_t;
+
+ //update moving points
+ mitk::AnisotropicRegistrationCommon::TransformPoints( X, X_transformedNew,
+ TransformationR,
+ TransformationT );
+ //calculate config change
+ config_change = CalculateConfigChange(X_transformed,X_transformedNew);
+
+ // swap the pointers the old set for the next iteration is
+ // the new set of the last iteration
+ vtkPoints* tmp = X_transformed;
+ X_transformed = X_transformedNew;
+ X_transformedNew = tmp;
+
+ } while ( config_change > Threshold && n < MaxIterations );
+
+ //calculate FRE with current transform
+ FRE = ComputeWeightedFRE( X,Y,Sigma_X,Sigma_Y,m_FRENormalizationFactor,
+ W,TransformationR,TransformationT );
+
+ MITK_DEBUG <<"FRE after algorithm (prior to check with initial): "<<FRE;
+
+ //compare with FRE_initial
+ if (initialFRE < FRE)
+ {
+ MITK_WARN <<"FRE did not improve in anisotropic point registration function";
+ TransformationR = initial_TransformationR;
+ TransformationT = initial_TransformationT;
+ FRE = initialFRE;
+ }
+
+ MITK_DEBUG <<"FRE final: "<<FRE;
+
+ X_transformed->Delete();
+ X_transformedNew->Delete();
+}
+
+void mitk::WeightedPointTransform::SetMovingPointSet(vtkSmartPointer<vtkPoints> p)
+{
+ m_MovingPointSet = p;
+}
+
+void mitk::WeightedPointTransform::SetCovarianceMatricesMoving(const CovarianceMatrixList &matrices)
+{
+ m_CovarianceMatricesMoving = matrices;
+}
+
+void mitk::WeightedPointTransform::SetFixedPointSet(vtkSmartPointer<vtkPoints> p)
+{
+ m_FixedPointSet = p;
+}
+
+void mitk::WeightedPointTransform::SetCovarianceMatricesFixed(const CovarianceMatrixList &matrices)
+{
+ m_CovarianceMatricesFixed = matrices;
+}
+
+double mitk::WeightedPointTransform::CalculateConfigChange( vtkPoints* X,
+ vtkPoints* X_new
+ )
+{
+ double sum[3] = { 0.0,0.0,0.0 };
+ double mean[3] = { 0.0,0.0,0.0 };
+ double pX[3] = { 0.0,0.0,0.0 };
+ double pX_new[3] = { 0.0,0.0,0.0 };
+
+ // compute mean of the old point set and the first sum
+ for ( vtkIdType i = 0; i < X->GetNumberOfPoints(); ++i )
+ {
+ X->GetPoint(i,pX);
+ X_new->GetPoint(i,pX_new);
+
+ // first sum
+ sum[0] += ( pX_new[0] - pX[0] ) * ( pX_new[0] - pX[0] );
+ sum[1] += ( pX_new[1] - pX[1] ) * ( pX_new[1] - pX[1] );
+ sum[2] += ( pX_new[2] - pX[2] ) * ( pX_new[2] - pX[2] );
+
+ // mean
+ mean[0] += pX[0];
+ mean[1] += pX[1];
+ mean[2] += pX[2];
+ }
+
+ mean[0] /= X->GetNumberOfPoints();
+ mean[1] /= X->GetNumberOfPoints();
+ mean[2] /= X->GetNumberOfPoints();
+
+ const double us = sum[0] + sum[1] + sum[2];
+
+ // reset sum
+ sum[0] = sum[1] = sum[2] = 0.0;
+
+ for ( vtkIdType i = 0; i < X->GetNumberOfPoints(); ++i )
+ {
+ X->GetPoint(i,pX);
+
+ sum[0] += (pX[0] - mean[0]) * (pX[0] - mean[0]);
+ sum[1] += (pX[1] - mean[1]) * (pX[1] - mean[1]);
+ sum[2] += (pX[2] - mean[2]) * (pX[2] - mean[2]);
+ }
+
+ const double ls = sum[0] + sum[1] + sum[2];
+
+ return sqrt(us/ls);
+}
diff --git a/Modules/AlgorithmsExt/mitkWeightedPointTransform.h b/Modules/AlgorithmsExt/mitkWeightedPointTransform.h
new file mode 100644
index 0000000000..eb5fa679c3
--- /dev/null
+++ b/Modules/AlgorithmsExt/mitkWeightedPointTransform.h
@@ -0,0 +1,259 @@
+/*===================================================================
+
+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 __WEIGHTEDPOINTTRANSFORM_H__
+#define __WEIGHTEDPOINTTRANSFORM_H__
+
+//EXPORTS
+#include "MitkAlgorithmsExtExports.h"
+
+//ITK
+#include <itkVariableSizeMatrix.h>
+#include <mitkCommon.h>
+#include <itkMatrix.h>
+#include <vector>
+#include <mitkPointSet.h>
+#include <vtkSmartPointer.h>
+
+// forward declarations
+class vtkPoints;
+class vtkLandmarkTransform;
+
+namespace mitk
+{
+
+/**
+ * \ingroup AnisotropicRegistration
+ *
+ * @brief This class implements an extension of the
+ * weighted point based registration algorithm
+ * from A. Danilchenko, R. Balachandran and J. M. Fitzpatrick.
+ *
+ * The class implements an extension of the weighted point based registration
+ * from A. Danilchenko et al.
+ * presented by L. Maier-Hein et al. in "Convergent Iterative Closest-Point Algorithm
+ * to Accomodate Anisotropic and Inhomogenous Localization Error.",
+ * IEEE T Pattern Anal 34 (8), 1520-1532, 2012. The extension computes, in order
+ * to ensure the convergence of the algorithm, an isotropic estimation
+ * by an unweighted point based registration algorithm as an initial estimate.
+ * The implemantion was originally ported to C/C++ by A. Franz.
+ *
+ * \note Some methods are accelerated when OpenMP is enabled.
+ *
+ */
+class MitkAlgorithmsExt_EXPORT WeightedPointTransform : public itk::Object
+{
+ /** Definition of a 3x3 matrix.*/
+ typedef itk::Matrix<double,3,3> Matrix3x3;
+ /** Definition of a 3x3 Weighting matrix.*/
+ typedef Matrix3x3 WeightMatrix;
+ /** Definition of a Rotation matrix.*/
+ typedef Matrix3x3 Rotation;
+ /** Definition of a translation vector.*/
+ typedef itk::Vector<double,3> Translation;
+ /** Definition of a weight matrix list.*/
+ typedef std::vector<WeightMatrix> WeightMatrixList;
+ /** Definition of a covariance matrix list.*/
+ typedef std::vector<Matrix3x3> CovarianceMatrixList;
+
+public:
+
+ mitkClassMacro(WeightedPointTransform, itk::Object);
+ itkFactorylessNewMacro(Self);
+ itkCloneMacro(Self)
+
+ /** @brief Method which registers both point sets. */
+ void ComputeTransformation();
+
+ /** @brief Sets the threshold of the registration. Default value is 0.0001.*/
+ itkSetMacro(Threshold,double)
+
+ /** @brief Sets the maximum number of iterations of the registration.
+ * Default value is 1000.
+ */
+ itkSetMacro(MaxIterations,double)
+
+ /** @return Returns the number of iterations of the last run
+ * of the registration algorithm. Returns -1 if there was no
+ * run of the registration yet.
+ */
+ itkGetMacro(Iterations,int);
+
+ /** @return Returns the FRE of the last run of the registration algorithm.
+ * Returns -1 if there was no run of the registration yet.
+ */
+ itkGetMacro(FRE,double);
+
+ /** @brief Sets the FRE normalization factor. Default value is 1.0. */
+ itkSetMacro(FRENormalizationFactor,double);
+
+ /** @return Returns the current FRE normalization factor.*/
+ itkGetMacro(FRENormalizationFactor,double);
+
+ /** Sets the moving point set used for the registration.
+ * @param p The input point set.
+ */
+ void SetMovingPointSet(vtkSmartPointer<vtkPoints> p);
+
+ /**
+ * Set the list of 3x3 covariance matrices belonging to the moving point set.
+ * @param matrices List of covariance matrices.
+ */
+ void SetCovarianceMatricesMoving( const CovarianceMatrixList& matrices);
+
+ /** Sets the fixed point set used for the registration.
+ * @param p The input point set.
+ */
+ void SetFixedPointSet(vtkSmartPointer<vtkPoints> p);
+
+ /**
+ * Set the list of 3x3 covariance matrices belonging to the fixed point set.
+ * @param matrices List of covariance matrices.
+ */
+ void SetCovarianceMatricesFixed( const CovarianceMatrixList& matrices);
+
+ /**
+ * The translation vector computed by the algorithm.
+ * @return 3x1 translation vector.
+ */
+ const Translation& GetTransformT() const { return m_Translation; }
+
+ /**
+ * The rotation matrix computed by the algorithm.
+ */
+ const Rotation& GetTransformR() const { return m_Rotation; }
+
+protected:
+ WeightedPointTransform();
+ ~WeightedPointTransform();
+
+ /** Threshold used to terminate the algorithm.*/
+ double m_Threshold;
+
+ /** Max allowed iterations used by the algorithm.*/
+ int m_MaxIterations;
+
+ /** The amount of iterations needed by the algorithm.*/
+ int m_Iterations;
+
+ /** The fiducial registration error (FRE) used in the algorithm.*/
+ double m_FRE;
+
+ /** Normalization factor for the FRE.*/
+ double m_FRENormalizationFactor;
+
+ /** Isotropic point based registration used for initial estimate.*/
+ vtkSmartPointer<vtkLandmarkTransform> m_LandmarkTransform;
+
+ /** The fixed point set (Y).*/
+ vtkSmartPointer<vtkPoints> m_FixedPointSet;
+
+ /** Moving point set (X).*/
+ vtkSmartPointer<vtkPoints> m_MovingPointSet;
+
+ /** Covariance matrices of the moving point set (Sigma_X).*/
+ CovarianceMatrixList m_CovarianceMatricesMoving;
+
+ /** Covariance matrices of the moving point set (Sigma_Y).*/
+ CovarianceMatrixList m_CovarianceMatricesFixed;
+
+ /** 3x1 translation vector.*/
+ Translation m_Translation;
+
+ /** 3x3 rotation matrix.*/
+ Rotation m_Rotation;
+
+
+ /**
+ * original matlab-function:
+ *
+ * Constructs the C matrix of the linear version of the registration
+ * problem, Cq = e, where q = [delta_angle(1:3),delta_translation(1:3)] and
+ * e is produced by e_maker(X,Y,W)
+ *
+ * Authors: JM Fitzpatrick and R Balachandran
+ * Creation: February 2009
+ *
+ * --------------------------------------------
+ *
+ * converted to C++ by Alfred Franz in March/April 2010
+ */
+ void C_maker( vtkPoints* X, const WeightMatrixList &W,
+ itk::VariableSizeMatrix< double >& returnValue );
+
+ /**
+ * original matlab-function:
+ *
+ * Constructs the e vector of the linear version of the registration
+ * problem, Cq = e, where q = [delta_angle(1:3),delta_translation(1:3)] and
+ * C is produced by C_maker(X,W)
+ *
+ * Authors: JM Fitzpatrick and R Balachandran
+ * Creation: February 2009
+ *
+ * --------------------------------------------
+ *
+ * converted to C++ by Alfred Franz in March/April 2010
+ */
+ void E_maker( vtkPoints* X, vtkPoints* Y,
+ const WeightMatrixList &W,
+ vnl_vector< double >& returnValue );
+
+ /**
+ * This method computes the change in a root mean squared
+ * sense between the previous and the actual iteration.
+ * The computed value is used as a termination constraint of the algorithm and
+ * compared against the threshold.
+ *
+ * @param X The moving point set in the previous iteration step.
+ * @param X_new The moving point set in the actual step.
+ *
+ * @return The computed change between the two point sets.
+ */
+ double CalculateConfigChange( vtkPoints* X, vtkPoints* X_new );
+
+ /**
+ * @brief This method performs a variant of the weighted point register algorithm presented by
+ * A. Danilchenko, R. Balachandran and J. M. Fitzpatrick in January 2010. (Modified in January 2011)
+ * converted to C++ by Alfred Franz in March/April 2010
+ *
+ * @param X (input) the moving point set
+ * @param Y (input) the fixed (static) point set
+ * @param Sigma_X (input) a 3-by-3-by-N array, each page containing the weighting matrix for the Nth pair of points in X
+ * @param Sigma_Y (input) a 3-by-3-by-N array, each page containing the weighting matrix for the Nth pair of points in Y
+ * @param Threshold (input) the relative size of the change to the moving set above which the iteration continues
+ * @param MaxIterations (input) the maximum number of iterations allowed
+ * @param Threshold (input) the threshold used to terminate the algorithm
+ * @param TransformationR (output) this variable will hold the computed rotation matrix
+ * @param TransformationT (output) this variable will hold the computed translation vector
+ * @param FRE (output) this variable will hold the computed rotation FRE of the transformation
+ * @param n (output) this variable will hold the number of iterations used by the algorithm
+ */
+ void WeightedPointRegister( vtkPoints* X,
+ vtkPoints* Y,
+ const CovarianceMatrixList &Sigma_X,
+ const CovarianceMatrixList &Sigma_Y,
+ double Threshold,
+ int MaxIterations,
+ Rotation& TransformationR,
+ Translation& TransformationT,
+ double& FRE,
+ int& n );
+
+};
+
+}
+#endif
diff --git a/Modules/DeformableRegistrationUI/QmitkBSplineRegistrationView.cpp b/Modules/DeformableRegistrationUI/QmitkBSplineRegistrationView.cpp
index 4b9674049c..f0b4e45efb 100644
--- a/Modules/DeformableRegistrationUI/QmitkBSplineRegistrationView.cpp
+++ b/Modules/DeformableRegistrationUI/QmitkBSplineRegistrationView.cpp
@@ -1,216 +1,216 @@
/*===================================================================
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 <qvalidator.h>
#include <mitkImageCast.h>
#include <stdio.h>
#include <stdlib.h>
#include <mitkLevelWindowProperty.h>
#include <mitkRenderingManager.h>
#include "itkRegularStepGradientDescentOptimizer.h"
#include <qfiledialog.h>
#include <qmessagebox.h>
#include "QmitkBSplineRegistrationView.h"
#include "ui_QmitkBSplineRegistrationViewControls.h"
#include "mitkBSplineRegistration.h"
#include "itkImageFileReader.h"
typedef itk::Vector< float, 3 > VectorType;
typedef itk::Image< VectorType, 3 > DeformationFieldType;
typedef itk::ImageFileReader< DeformationFieldType > ImageReaderType;
QmitkBSplineRegistrationView::QmitkBSplineRegistrationView(QWidget* parent, Qt::WindowFlags f ) : QWidget( parent, f ),
m_FixedNode(NULL), m_MovingNode(NULL)
{
m_Controls.setupUi(parent);
QObject::connect( (QObject*)(m_Controls.m_PrintDeformField),
SIGNAL(clicked()),
(QObject*) this,
SLOT(PrintDeformationField()) );
QObject::connect( (QObject*)(m_Controls.m_BrowseDeformationField),
SIGNAL(clicked()),
(QObject*) this,
SLOT(SelectDeformationField()) );
connect( m_Controls.m_OptimizerSelector, SIGNAL(activated(int)), m_Controls.m_OptimizerWidgetStack, SLOT(setCurrentIndex(int)));
connect( m_Controls.m_OptimizerSelector, SIGNAL(activated(int)), this, SLOT(OptimizerSelected(int)));
}
QmitkBSplineRegistrationView::~QmitkBSplineRegistrationView()
{
}
void QmitkBSplineRegistrationView::OptimizerSelected(int optimizer)
{
HideAllOptimizerFrames();
if(optimizer == 0)
{
m_Controls.m_LBFGSFrame->show();
}
else if(optimizer == 1)
{
m_Controls.m_GradientDescentFrame->show();
}
}
void QmitkBSplineRegistrationView::HideAllOptimizerFrames()
{
m_Controls.m_LBFGSFrame->hide();
m_Controls.m_GradientDescentFrame->hide();
}
void QmitkBSplineRegistrationView::SelectDeformationField()
{
// SELECT FOLDER DIALOG
QFileDialog* w = new QFileDialog( this, "Select Deformation Field" );
w->setFileMode( QFileDialog::ExistingFiles );
- w->setFilter( "Images (*.mhd)" );
+ w->setNameFilter( "Images (*.mhd)" );
w->setDirectory("G:\\home\\vanbrugg\\testimages\\deformable");
// RETRIEVE SELECTION
if ( w->exec() != QDialog::Accepted )
{
return;
cout << "Failed to load" << endl;
}
QStringList filenames = w->selectedFiles();
QStringList::Iterator it = filenames.begin();
if( it != filenames.end() ) {
std::string filename = ( *it ).toStdString();
++it;
QString qStr = QString( filename.c_str() );
m_Controls.m_DeformationField->setText(qStr);
}
}
void QmitkBSplineRegistrationView::PrintDeformationField()
{
ImageReaderType::Pointer reader = ImageReaderType::New();
reader->SetFileName( m_Controls.m_DeformationField->text().toStdString() );
reader->Update();
DeformationFieldType::Pointer deformationField = reader->GetOutput();
typedef itk::ImageRegionIterator<DeformationFieldType> IteratorType;
IteratorType deformIter(deformationField, deformationField->GetRequestedRegion());
for(deformIter.GoToBegin(); !deformIter.IsAtEnd(); ++deformIter)
{
std::cout << deformIter.Get() << std::endl;
}
}
void QmitkBSplineRegistrationView::CalculateTransformation()
{
if (m_FixedNode != NULL && m_MovingNode != NULL)
{
mitk::Image::Pointer fimage = dynamic_cast<mitk::Image*>(m_FixedNode->GetData());
mitk::Image::Pointer mimage = dynamic_cast<mitk::Image*>(m_MovingNode->GetData());
mitk::BSplineRegistration::Pointer registration = mitk::BSplineRegistration::New();
registration->SetSaveResult(false);
registration->SetReferenceImage(fimage);
registration->SetInput(mimage);
// Read out optimizer parameters from the interface
setOptimizerParameters();
registration->SetNumberOfGridPoints( m_Controls.m_NumberOfGridNodes->text().toInt() );
registration->SetOptimizerParameters(m_OptimizerParameters);
registration->SetUpdateInputImage(true);
if(m_Controls.m_SaveDeformFieldCheck->isChecked())
{
// Set some parameters to save the deformation field
registration->SetSaveDeformationField(true);
registration->SetDeformationFileName( m_Controls.m_DeformationField->text().toStdString() );
}
try
{
registration->Update();
}
catch (itk::ExceptionObject& excpt)
{
QMessageBox::information( this, "Registration exception", excpt.GetDescription(), QMessageBox::Ok );
}
mitk::Image::Pointer image = registration->GetOutput();
if (image.IsNotNull())
{
m_MovingNode->SetData(image);
mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New();
mitk::LevelWindow levelWindow;
levelWindow.SetAuto( image );
levWinProp->SetLevelWindow(levelWindow);
m_MovingNode->GetPropertyList()->SetProperty("levelwindow",levWinProp);
}
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void QmitkBSplineRegistrationView::setOptimizerParameters()
{
m_OptimizerParameters = mitk::OptimizerParameters::New();
if(m_Controls.m_OptimizerSelector->currentText() == "LBFGSOptimizer")
{
m_OptimizerParameters->SetOptimizer(mitk::OptimizerParameters::LBFGSOPTIMIZER);
m_OptimizerParameters->SetGradientConvergenceToleranceLBFGS( m_Controls.m_GradConvTolerance->text().toFloat() );
m_OptimizerParameters->SetLineSearchAccuracyLBFGS( m_Controls.m_LineSearchAccuracy->text().toFloat() );
m_OptimizerParameters->SetDefaultStepLengthLBFGS( m_Controls.m_DefaultStepLength->text().toFloat() );
m_OptimizerParameters->SetNumberOfIterationsLBFGS( m_Controls.m_FunctionEvaluations->text().toInt() );
}
else if(m_Controls.m_OptimizerSelector->currentText() == "Gradient Descent")
{
m_OptimizerParameters->SetOptimizer(mitk::OptimizerParameters::GRADIENTDESCENTOPTIMIZER);
m_OptimizerParameters->SetLearningRateGradientDescent( m_Controls.m_LearningRateGradientDescent->text().toFloat() );
m_OptimizerParameters->SetNumberOfIterationsGradientDescent (m_Controls.m_NumberOfIterationsGradientDescent->text().toInt() );
}
}
void QmitkBSplineRegistrationView::SetFixedNode( mitk::DataNode * fixedNode )
{
m_FixedNode = fixedNode;
}
void QmitkBSplineRegistrationView::SetMovingNode( mitk::DataNode * movingNode )
{
m_MovingNode = movingNode;
}
diff --git a/Modules/DicomUI/CMakeLists.txt b/Modules/DicomUI/CMakeLists.txt
index fac3a66d09..e0fcbef18f 100644
--- a/Modules/DicomUI/CMakeLists.txt
+++ b/Modules/DicomUI/CMakeLists.txt
@@ -1,7 +1,7 @@
include_directories(${CTK_INCLUDE_DIRS})
MITK_CREATE_MODULE(
DEPENDS MitkCore
- PACKAGE_DEPENDS CTK|CTKDICOMWidgets Qt4|QtGui+QtSql
+ PACKAGE_DEPENDS CTK|CTKDICOMWidgets Qt4|QtGui+QtSql Qt5|OpenGL+Sql+Widgets+Xml
EXPORT_DEFINE MITK_DICOMUI_EXPORT
)
diff --git a/Modules/DiffusionImaging/DiffusionCore/CMakeLists.txt b/Modules/DiffusionImaging/DiffusionCore/CMakeLists.txt
index c6bbc6b951..b0ee596bbe 100644
--- a/Modules/DiffusionImaging/DiffusionCore/CMakeLists.txt
+++ b/Modules/DiffusionImaging/DiffusionCore/CMakeLists.txt
@@ -1,15 +1,19 @@
# With apple gcc 4.2.1 the following waring leads to an build error if boost is enabled
if(APPLE)
mitkFunctionCheckCAndCXXCompilerFlags("-Wno-error=empty-body" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
endif()
MITK_CREATE_MODULE(
SUBPROJECTS MITK-DTI
INCLUDE_DIRS Algorithms Algorithms/Reconstruction Algorithms/Registration Algorithms/Reconstruction/MultishellProcessing DicomImport IODataStructures/DiffusionWeightedImages IODataStructures/QBallImages IODataStructures/TensorImages IODataStructures Rendering ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS MitkMapperExt MitkPlanarFigure MitkImageExtraction MitkSceneSerializationBase MitkDICOMReader
PACKAGE_DEPENDS VTK|vtkFiltersProgrammable ITK|ITKDistanceMap+ITKRegistrationCommon+ITKLabelVoting+ITKVTK Boost
ITK|ITKMetricsv4+ITKRegistrationMethodsv4
WARNINGS_AS_ERRORS
)
+if(MSVC)
+ mitkFunctionCheckCAndCXXCompilerFlags("/wd4005" CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+endif()
+
add_subdirectory(Testing)
diff --git a/Modules/DiffusionImaging/DiffusionCore/IODataStructures/QBallImages/mitkQBallImage.cpp b/Modules/DiffusionImaging/DiffusionCore/IODataStructures/QBallImages/mitkQBallImage.cpp
index 11a6705aa8..3535a6747a 100644
--- a/Modules/DiffusionImaging/DiffusionCore/IODataStructures/QBallImages/mitkQBallImage.cpp
+++ b/Modules/DiffusionImaging/DiffusionCore/IODataStructures/QBallImages/mitkQBallImage.cpp
@@ -1,85 +1,88 @@
/*===================================================================
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 "mitkQBallImage.h"
#include "mitkImageCast.h"
#include "itkImage.h"
#include "mitkImageVtkAccessor.h"
#include "itkQBallToRgbImageFilter.h"
+#include <mitkProperties.h>
mitk::QBallImage::QBallImage() : Image()
{
m_RgbImage = 0;
+ // not needed anymore as soon as all diffusion images are identified via properties anyway
+ this->SetProperty("IsQballImage", mitk::BoolProperty::New(true));
}
mitk::QBallImage::~QBallImage()
{
}
const vtkImageData* mitk::QBallImage::GetVtkImageData(int t, int n) const
{
if(m_RgbImage.IsNull())
ConstructRgbImage();
return m_RgbImage->GetVtkImageData(t,n);
}
vtkImageData*mitk::QBallImage::GetVtkImageData(int t, int n)
{
if(m_RgbImage.IsNull())
ConstructRgbImage();
return m_RgbImage->GetVtkImageData(t,n);
}
void mitk::QBallImage::ConstructRgbImage() const
{
typedef itk::Image<itk::Vector<float,QBALL_ODFSIZE>,3> ImageType;
typedef itk::QBallToRgbImageFilter<ImageType> FilterType;
FilterType::Pointer filter = FilterType::New();
ImageType::Pointer itkvol = ImageType::New();
mitk::CastToItkImage(this, itkvol);
filter->SetInput(itkvol);
filter->Update();
m_RgbImage = mitk::Image::New();
m_RgbImage->InitializeByItk( filter->GetOutput() );
m_RgbImage->SetVolume( filter->GetOutput()->GetBufferPointer() );
}
const vtkImageData* mitk::QBallImage::GetNonRgbVtkImageData(int t, int n) const
{
return Superclass::GetVtkImageData(t,n);
}
vtkImageData* mitk::QBallImage::GetNonRgbVtkImageData(int t, int n)
{
return Superclass::GetVtkImageData(t,n);
}
//
//void mitk::QBallImage::CopyConstruct(mitk::Image::Pointer img)
//{
// m_LargestPossibleRegion = img->GetLargestPossibleRegion();
// m_RequestedRegion = img->GetRequestedRegion();
// m_Channels.push_back(img->GetChannelData(0).GetPointer());
// m_Volumes.push_back(img->GetVolumeData(0).GetPointer());
// m_Slices.push_back(img->GetSliceData(0).GetPointer());
// m_Dimension = img->GetDimension();
// m_Dimensions = img->GetDimensions();
// m_PixelType = img->GetPixelType();
//}
diff --git a/Modules/DiffusionImaging/MiniApps/CMakeLists.txt b/Modules/DiffusionImaging/MiniApps/CMakeLists.txt
index 66e1fbdc43..b9abc090de 100755
--- a/Modules/DiffusionImaging/MiniApps/CMakeLists.txt
+++ b/Modules/DiffusionImaging/MiniApps/CMakeLists.txt
@@ -1,65 +1,153 @@
option(BUILD_DiffusionMiniApps "Build commandline tools for diffusion" OFF)
if(BUILD_DiffusionMiniApps OR MITK_BUILD_ALL_APPS)
# needed include directories
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
)
- project( MitkDiffusionMiniApps )
-
- # fill in the standalone executables here
- set(DIFFUSIONMINIAPPS
- mitkDiffusionMiniApps
- )
-
- # set additional files here
- set(DIFFUSIONCORE_ADDITIONAL_FILES
- MiniAppManager.cpp
- FileFormatConverter.cpp
- TensorReconstruction.cpp
- QballReconstruction.cpp
- DiffusionIndices.cpp
- CopyGeometry.cpp
- GibbsTracking.cpp
- StreamlineTracking.cpp
- FiberProcessing.cpp
- LocalDirectionalFiberPlausibility.cpp
- #TractogramAngularError.cpp
- FiberDirectionExtraction.cpp
- PeakExtraction.cpp
- PeaksAngularError.cpp
- MultishellMethods.cpp
- Fiberfox.cpp
- ExportShImage.cpp
- NetworkCreation.cpp
- NetworkStatistics.cpp
- DwiDenoising.cpp
- TractometerMetrics.cpp
- )
-
- # deprecated
-# FOREACH(tool ${DIFFUSIONMINIAPPS})
-# ADD_EXECUTABLE(
-# ${tool}
-# ${tool}.cpp
-# ${DIFFUSIONCORE_ADDITIONAL_FILES}
-# )
-
-# TARGET_LINK_LIBRARIES(
-# ${tool}
-# ${ALL_LIBRARIES} )
-# ENDFOREACH(tool)
-
- mitk_create_executable(DiffusionMiniApps
- DEPENDS MitkDiffusionCore MitkFiberTracking MitkConnectomics
- PACKAGE_DEPENDS ITK|ITKDiffusionTensorImage
+
+ mitk_create_executable(DwiDenoising
+ DEPENDS MitkCore MitkDiffusionCore
+ PACKAGE_DEPENDS ITK
+ CPP_FILES DwiDenoising.cpp mitkCommandLineParser.cpp
+ )
+
+ mitk_create_executable(ImageResampler
+ DEPENDS MitkCore MitkDiffusionCore
+ PACKAGE_DEPENDS ITK
+ CPP_FILES ImageResampler.cpp mitkCommandLineParser.cpp
+ )
+
+ mitk_create_executable(NetworkCreation
+ DEPENDS MitkCore MitkDiffusionCore MitkFiberTracking MitkConnectomics
+ PACKAGE_DEPENDS ITK
+ CPP_FILES NetworkCreation.cpp mitkCommandLineParser.cpp
+ )
+
+ mitk_create_executable(NetworkStatistics
+ DEPENDS MitkCore MitkDiffusionCore MitkConnectomics
+ PACKAGE_DEPENDS ITK
+ CPP_FILES NetworkStatistics.cpp mitkCommandLineParser.cpp
+ )
+
+ mitk_create_executable(ExportShImage
+ DEPENDS MitkCore MitkDiffusionCore
+ PACKAGE_DEPENDS ITK
+ CPP_FILES ExportShImage.cpp mitkCommandLineParser.cpp
+ )
+
+ mitk_create_executable(Fiberfox
+ DEPENDS MitkCore MitkDiffusionCore MitkFiberTracking
+ PACKAGE_DEPENDS ITK
+ CPP_FILES Fiberfox.cpp mitkCommandLineParser.cpp
+ )
+
+ mitk_create_executable(MultishellMethods
+ DEPENDS MitkCore MitkDiffusionCore MitkFiberTracking
+ PACKAGE_DEPENDS ITK
+ CPP_FILES MultishellMethods.cpp mitkCommandLineParser.cpp
+ )
+
+ mitk_create_executable(PeaksAngularError
+ DEPENDS MitkCore MitkDiffusionCore MitkFiberTracking
+ PACKAGE_DEPENDS ITK
+ CPP_FILES PeaksAngularError.cpp mitkCommandLineParser.cpp
+ )
+
+ mitk_create_executable(PeakExtraction
+ DEPENDS MitkCore MitkDiffusionCore MitkFiberTracking
+ PACKAGE_DEPENDS ITK
+ CPP_FILES PeakExtraction.cpp mitkCommandLineParser.cpp
+ )
+
+ mitk_create_executable(FiberDirectionExtraction
+ DEPENDS MitkCore MitkDiffusionCore MitkFiberTracking
+ PACKAGE_DEPENDS ITK
+ CPP_FILES FiberDirectionExtraction.cpp mitkCommandLineParser.cpp
+ )
+
+ mitk_create_executable(LocalDirectionalFiberPlausibility
+ DEPENDS MitkCore MitkDiffusionCore MitkFiberTracking
+ PACKAGE_DEPENDS ITK
+ CPP_FILES LocalDirectionalFiberPlausibility.cpp mitkCommandLineParser.cpp
+ )
+
+ mitk_create_executable(StreamlineTracking
+ DEPENDS MitkCore MitkDiffusionCore MitkFiberTracking
+ PACKAGE_DEPENDS ITK
+ CPP_FILES StreamlineTracking.cpp mitkCommandLineParser.cpp
+ )
+
+ mitk_create_executable(GibbsTracking
+ DEPENDS MitkCore MitkDiffusionCore MitkFiberTracking
+ PACKAGE_DEPENDS ITK
+ CPP_FILES GibbsTracking.cpp mitkCommandLineParser.cpp
+ )
+
+ mitk_create_executable(CopyGeometry
+ DEPENDS MitkCore MitkDiffusionCore
+ PACKAGE_DEPENDS ITK
+ CPP_FILES CopyGeometry.cpp mitkCommandLineParser.cpp
+ )
+
+ mitk_create_executable(DiffusionIndices
+ DEPENDS MitkCore MitkDiffusionCore
+ PACKAGE_DEPENDS ITK
+ CPP_FILES DiffusionIndices.cpp mitkCommandLineParser.cpp
+ )
+
+ mitk_create_executable(TractometerMetrics
+ DEPENDS MitkCore MitkDiffusionCore MitkFiberTracking
+ PACKAGE_DEPENDS ITK
+ CPP_FILES TractometerMetrics.cpp mitkCommandLineParser.cpp
+ )
+
+ mitk_create_executable(QballReconstruction
+ DEPENDS MitkCore MitkDiffusionCore
+ PACKAGE_DEPENDS ITK
+ CPP_FILES QballReconstruction.cpp mitkCommandLineParser.cpp
+ )
+
+ mitk_create_executable(FolderRegistration
+ DEPENDS MitkCore MitkDiffusionCore
+ PACKAGE_DEPENDS ITK
+ CPP_FILES mitkRegistration.cpp mitkCommandLineParser.cpp
+ )
+
+ mitk_create_executable(FileFormatConverter
+ DEPENDS MitkCore MitkDiffusionCore MitkFiberTracking MitkDiffusionIO
+ PACKAGE_DEPENDS ITK
+ CPP_FILES mitkFileFormatConverter.cpp mitkCommandLineParser.cpp
+ )
+
+ mitk_create_executable(TensorReconstruction
+ DEPENDS MitkCore MitkDiffusionCore MitkDiffusionIO
+ PACKAGE_DEPENDS ITK
+ CPP_FILES TensorReconstruction.cpp mitkCommandLineParser.cpp
+ )
+
+ mitk_create_executable(TensorDerivedMapExtraction
+ DEPENDS MitkCore MitkDiffusionCore MitkDiffusionIO
+ PACKAGE_DEPENDS ITK
+ CPP_FILES TensorDerivedMapsExtraction.cpp mitkCommandLineParser.cpp
+ )
+
+ mitk_create_executable(DICOMLoader
+ DEPENDS MitkCore MitkDiffusionCore
+ PACKAGE_DEPENDS ITK
+ CPP_FILES DICOMLoader.cpp mitkCommandLineParser.cpp
+ )
+
+ mitk_create_executable(Dicom2Nrrd
+ DEPENDS MitkCore
+ CPP_FILES Dicom2Nrrd.cpp mitkCommandLineParser.cpp
)
if(EXECUTABLE_IS_ENABLED)
MITK_INSTALL_TARGETS(EXECUTABLES ${EXECUTABLE_TARGET})
endif()
endif()
diff --git a/Modules/DiffusionImaging/MiniApps/CopyGeometry.cpp b/Modules/DiffusionImaging/MiniApps/CopyGeometry.cpp
index 192c554961..de9023fb32 100755
--- a/Modules/DiffusionImaging/MiniApps/CopyGeometry.cpp
+++ b/Modules/DiffusionImaging/MiniApps/CopyGeometry.cpp
@@ -1,88 +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 "MiniAppManager.h"
#include <mitkImageCast.h>
#include <mitkDiffusionImage.h>
#include <mitkBaseDataIOFactory.h>
#include <mitkIOUtil.h>
-#include "ctkCommandLineParser.h"
+#include "mitkCommandLineParser.h"
using namespace mitk;
-#include "ctkCommandLineParser.h"
-int CopyGeometry(int argc, char* argv[])
+
+int main(int argc, char* argv[])
{
- ctkCommandLineParser parser;
+ mitkCommandLineParser parser;
parser.setTitle("Copy Geometry");
parser.setCategory("Preprocessing Tools");
parser.setDescription("");
parser.setContributor("MBI");
parser.setArgumentPrefix("--", "-");
- parser.addArgument("in", "i", ctkCommandLineParser::InputFile, "Input:", "input image", us::Any(), false);
- parser.addArgument("ref", "r", ctkCommandLineParser::InputFile, "Reference:", "reference image", us::Any(), false);
- parser.addArgument("out", "o", ctkCommandLineParser::OutputFile, "Output:", "output image", us::Any(), false);
+ parser.addArgument("in", "i", mitkCommandLineParser::InputFile, "Input:", "input image", us::Any(), false);
+ parser.addArgument("ref", "r", mitkCommandLineParser::InputFile, "Reference:", "reference image", us::Any(), false);
+ parser.addArgument("out", "o", mitkCommandLineParser::OutputFile, "Output:", "output image", us::Any(), false);
map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
if (parsedArgs.size()==0)
return EXIT_FAILURE;
// mandatory arguments
string imageName = us::any_cast<string>(parsedArgs["in"]);
string refImage = us::any_cast<string>(parsedArgs["ref"]);
string outImage = us::any_cast<string>(parsedArgs["out"]);
try
{
const std::string s1="", s2="";
std::vector<BaseData::Pointer> infile = BaseDataIO::LoadBaseDataFromFile( refImage, s1, s2, false );
Image::Pointer source = dynamic_cast<Image*>(infile.at(0).GetPointer());
infile = BaseDataIO::LoadBaseDataFromFile( imageName, s1, s2, false );
Image::Pointer target = dynamic_cast<Image*>(infile.at(0).GetPointer());
mitk::BaseGeometry* s_geom = source->GetGeometry();
mitk::BaseGeometry* t_geom = target->GetGeometry();
t_geom->SetIndexToWorldTransform(s_geom->GetIndexToWorldTransform());
target->SetGeometry(t_geom);
if ( dynamic_cast<DiffusionImage<short>*>(target.GetPointer()) )
{
mitk::IOUtil::Save(dynamic_cast<DiffusionImage<short>*>(target.GetPointer()), outImage.c_str());
}
else
mitk::IOUtil::SaveImage(target, outImage);
}
catch (itk::ExceptionObject e)
{
- MITK_INFO << e;
+ std::cout << e;
return EXIT_FAILURE;
}
catch (std::exception e)
{
- MITK_INFO << e.what();
+ std::cout << e.what();
return EXIT_FAILURE;
}
catch (...)
{
- MITK_INFO << "ERROR!?!";
+ std::cout << "ERROR!?!";
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
-RegisterDiffusionMiniApp(CopyGeometry);
diff --git a/Modules/DiffusionImaging/MiniApps/DICOMLoader.cmake b/Modules/DiffusionImaging/MiniApps/DICOMLoader.cmake
new file mode 100644
index 0000000000..47ba810620
--- /dev/null
+++ b/Modules/DiffusionImaging/MiniApps/DICOMLoader.cmake
@@ -0,0 +1,4 @@
+set(CPP_FILES
+ mitkCommandLineParser.cpp
+ DICOMLoader.cpp
+)
diff --git a/Modules/DiffusionImaging/MiniApps/DICOMLoader.cpp b/Modules/DiffusionImaging/MiniApps/DICOMLoader.cpp
index 6a428e14b4..f62f43f2c2 100644
--- a/Modules/DiffusionImaging/MiniApps/DICOMLoader.cpp
+++ b/Modules/DiffusionImaging/MiniApps/DICOMLoader.cpp
@@ -1,275 +1,272 @@
/*===================================================================
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 "MiniAppManager.h"
#include "mitkBaseDataIOFactory.h"
#include "mitkDiffusionImage.h"
#include "mitkBaseData.h"
#include <itkImageFileWriter.h>
#include <itkNrrdImageIO.h>
-#include "ctkCommandLineParser.h"
+#include "mitkCommandLineParser.h"
#include <itksys/SystemTools.hxx>
#include <itksys/Directory.hxx>
#include "mitkDiffusionDICOMFileReader.h"
#include "mitkDICOMTagBasedSorter.h"
#include "mitkDICOMSortByTag.h"
#include "itkMergeDiffusionImagesFilter.h"
#include <mitkIOUtil.h>
static mitk::StringList& GetInputFilenames()
{
static mitk::StringList inputs;
return inputs;
}
void SetInputFileNames( std::string input_directory )
{
// I. Get all files in directory
itksys::Directory input;
input.Load( input_directory.c_str() );
// II. Push back files
mitk::StringList inputlist;//, mergedlist;
for( unsigned long idx=0; idx<input.GetNumberOfFiles(); idx++)
{
if( ! itksys::SystemTools::FileIsDirectory( input.GetFile(idx)) )
{
std::string fullpath = input_directory + "/" + std::string( input.GetFile(idx) );
inputlist.push_back( itksys::SystemTools::ConvertToOutputPath( fullpath.c_str() ) );
MITK_INFO("dicom.loader.inputdir.addfile") << input.GetFile(idx);
}
}
/*mergedlist.reserve( GetInputFilenames().size() + inputlist.size() );
mergedlist.insert( mergedlist.end(), GetInputFilenames().begin(), GetInputFilenames().end() );
mergedlist.insert( mergedlist.end(), inputlist.begin(), inputlist.end() );*/
GetInputFilenames() = inputlist;//mergedlist;
MITK_INFO("dicom.loader.setinputfiles.end") << "[]";
}
mitk::DiffusionImage<short>::Pointer ReadInDICOMFiles( mitk::StringList& input_files, std::string output_file )
{
// repeat test with some more realistic sorting
mitk::DiffusionDICOMFileReader::Pointer gdcmReader = mitk::DiffusionDICOMFileReader::New(); // this also tests destruction
mitk::DICOMTagBasedSorter::Pointer tagSorter = mitk::DICOMTagBasedSorter::New();
// Use tags as in Qmitk
// all the things that split by tag in DicomSeriesReader
tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0028, 0x0010) ); // Number of Rows
tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0028, 0x0011) ); // Number of Columns
tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0028, 0x0030) ); // Pixel Spacing
tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0018, 0x1164) ); // Imager Pixel Spacing
tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0020, 0x0037) ); // Image Orientation (Patient) // TODO add tolerance parameter (l. 1572 of original code)
tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0018, 0x0050) ); // Slice Thickness
tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0028, 0x0008) ); // Number of Frames
tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0020, 0x0052) ); // Frame of Reference UID
mitk::DICOMSortCriterion::ConstPointer sorting =
mitk::DICOMSortByTag::New( mitk::DICOMTag(0x0020, 0x0013), // instance number
mitk::DICOMSortByTag::New( mitk::DICOMTag(0x0020, 0x0012) //acquisition number
).GetPointer()
).GetPointer();
tagSorter->SetSortCriterion( sorting );
MITK_INFO("dicom.loader.read.init") << "[]" ;
MITK_INFO("dicom.loader.read.inputs") << " " << input_files.size();
gdcmReader->SetInputFiles( input_files );
gdcmReader->AddSortingElement( tagSorter );
gdcmReader->AnalyzeInputFiles();
gdcmReader->LoadImages();
mitk::Image::Pointer loaded_image = gdcmReader->GetOutput(0).GetMitkImage();
mitk::DiffusionImage<short>::Pointer d_img = static_cast<mitk::DiffusionImage<short>*>( loaded_image.GetPointer() );
return d_img;
}
typedef short DiffusionPixelType;
typedef itk::VectorImage<DiffusionPixelType,3> DwiImageType;
typedef DwiImageType::PixelType DwiPixelType;
typedef DwiImageType::RegionType DwiRegionType;
typedef std::vector< DwiImageType::Pointer > DwiImageContainerType;
typedef mitk::DiffusionImage<DiffusionPixelType> DiffusionImageType;
typedef DiffusionImageType::GradientDirectionContainerType GradientContainerType;
typedef std::vector< GradientContainerType::Pointer > GradientListContainerType;
void SearchForInputInSubdirs( std::string root_directory, std::string subdir_prefix , std::vector<DiffusionImageType::Pointer>& output_container)
{
// I. Get all dirs in directory
itksys::Directory rootdir;
rootdir.Load( root_directory.c_str() );
MITK_INFO("dicom.loader.setinputdirs.start") << "Prefix = " << subdir_prefix;
for( unsigned int idx=0; idx<rootdir.GetNumberOfFiles(); idx++)
{
std::string current_path = rootdir.GetFile(idx);
std::string directory_path = std::string(rootdir.GetPath()) + std::string("/") + current_path;
MITK_INFO("dicom.loader.inputrootdir.test") << "ProbePath: " << current_path;
MITK_INFO("dicom.loader.inputrootdir.test") << "IsDirectory: " << itksys::SystemTools::FileIsDirectory( itksys::SystemTools::ConvertToOutputPath( directory_path.c_str() ).c_str() )
<< " StartsWith: " << itksys::SystemTools::StringStartsWith( current_path.c_str(), subdir_prefix.c_str() );
// test for prefix
if( itksys::SystemTools::FileIsDirectory( itksys::SystemTools::ConvertToOutputPath( directory_path.c_str() ).c_str() )
&& itksys::SystemTools::StringStartsWith( current_path.c_str(), subdir_prefix.c_str() )
)
{
MITK_INFO("dicom.loader.inputrootdir.searchin") << directory_path;
SetInputFileNames( itksys::SystemTools::ConvertToOutputPath( directory_path.c_str() ) );
MITK_INFO("dicom.loader.inputrootdir.preload") << "[]" ;
DiffusionImageType::Pointer dwi = ReadInDICOMFiles( GetInputFilenames(), "" );
output_container.push_back( dwi );
}
}
MITK_INFO("dicom.loader.setinputdirs.end") << "[]";
}
using namespace mitk;
/**
* Read DICOM Files through the new (refactored) Diffusion DICOM Loader. It serves also as a first test of the new functionality, it will replace the
* current loading mechanism after the necessary parts are merged into the master branch.
*/
-int DICOMLoader(int argc, char* argv[])
+int main(int argc, char* argv[])
{
- ctkCommandLineParser parser;
+ mitkCommandLineParser parser;
parser.setArgumentPrefix("--", "-");
- parser.addArgument("inputdir", "i", ctkCommandLineParser::String, "Input Directory" ,"input directory containing dicom files", us::Any(), false);
- parser.addArgument("output", "o", ctkCommandLineParser::String, "Output File Name", "output file", us::Any(), false);
- parser.addArgument("dwprefix", "p", ctkCommandLineParser::String, "Recursive Scan Prefix", "prefix for subfolders search rootdir is specified by the 'inputdir' argument value", us::Any(), true);
- parser.addArgument("dryrun", "-s", ctkCommandLineParser::Bool, "Dry run","do not read, only look for input files ", us::Any(), true );
+ parser.addArgument("inputdir", "i", mitkCommandLineParser::String, "Input Directory" ,"input directory containing dicom files", us::Any(), false);
+ parser.addArgument("output", "o", mitkCommandLineParser::String, "Output File Name", "output file", us::Any(), false);
+ parser.addArgument("dwprefix", "p", mitkCommandLineParser::String, "Recursive Scan Prefix", "prefix for subfolders search rootdir is specified by the 'inputdir' argument value", us::Any(), true);
+ parser.addArgument("dryrun", "-s", mitkCommandLineParser::Bool, "Dry run","do not read, only look for input files ", us::Any(), true );
map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
if (parsedArgs.size()==0)
{
- MITK_ERROR << "No input arguments were specified. Please provide all non-optional arguments. ";
- return 0;
+ return EXIT_FAILURE;
}
std::string inputDirectory = us::any_cast<std::string>( parsedArgs["inputdir"] );
MITK_INFO << "Loading data from directory: " << inputDirectory;
// retrieve the prefix flag (if set)
bool search_for_subdirs = false;
std::string subdir_prefix;
if( parsedArgs.count("dwprefix"))
{
MITK_INFO << "Prefix specified, will search for subdirs in the input directory!";
subdir_prefix = us::any_cast<std::string>( parsedArgs["dwprefix"] );
search_for_subdirs = true;
}
// retrieve the output
std::string outputFile = us::any_cast< std::string >( parsedArgs["output"] );
// if the executable is called with a single directory, just parse the given folder for files and read them into a diffusion image
if( !search_for_subdirs )
{
SetInputFileNames( inputDirectory );
MITK_INFO << "Got " << GetInputFilenames().size() << " input files.";
mitk::DiffusionImage<short>::Pointer d_img = ReadInDICOMFiles( GetInputFilenames(), outputFile );
try
{
mitk::IOUtil::Save(d_img, outputFile.c_str());
}
catch( const itk::ExceptionObject& e)
{
MITK_ERROR << "Failed to write out the output file. \n\t Reason : ITK Exception " << e.what();
}
}
// if the --dwprefix flag is set, then we have to look for the directories, load each of them separately and afterwards merge the images
else
{
std::vector<mitk::DiffusionImage<DiffusionPixelType>::Pointer> output_container;
SearchForInputInSubdirs( inputDirectory, subdir_prefix, output_container );
// final output image
mitk::DiffusionImage<DiffusionPixelType>::Pointer image = mitk::DiffusionImage<DiffusionPixelType>::New();
if( output_container.size() > 1 )
{
DwiImageContainerType imageContainer;
GradientListContainerType gradientListContainer;
std::vector< double > bValueContainer;
for ( std::vector< mitk::DiffusionImage<DiffusionPixelType>::Pointer >::iterator dwi = output_container.begin();
dwi != output_container.end(); ++dwi )
{
imageContainer.push_back((*dwi)->GetVectorImage());
gradientListContainer.push_back((*dwi)->GetDirections());
bValueContainer.push_back((*dwi)->GetReferenceBValue());
}
typedef itk::MergeDiffusionImagesFilter<short> FilterType;
FilterType::Pointer filter = FilterType::New();
filter->SetImageVolumes(imageContainer);
filter->SetGradientLists(gradientListContainer);
filter->SetBValues(bValueContainer);
filter->Update();
vnl_matrix_fixed< double, 3, 3 > mf; mf.set_identity();
image->SetVectorImage( filter->GetOutput() );
image->SetReferenceBValue(filter->GetB_Value());
image->SetDirections(filter->GetOutputGradients());
image->SetMeasurementFrame(mf);
image->InitializeFromVectorImage();
}
// just output the image if there was only one folder found
else
{
image = output_container.at(0);
}
MITK_INFO("dicom.import.writeout") << " [OutputFile] " << outputFile.c_str();
try
{
mitk::IOUtil::Save(image, outputFile.c_str());
}
catch( const itk::ExceptionObject& e)
{
MITK_ERROR << "Failed to write out the output file. \n\t Reason : ITK Exception " << e.what();
}
}
return 1;
}
-RegisterDiffusionMiniApp(DICOMLoader);
diff --git a/Modules/DiffusionImaging/MiniApps/DicomFolderDump.cpp b/Modules/DiffusionImaging/MiniApps/Dicom2Nrrd.cpp
similarity index 76%
rename from Modules/DiffusionImaging/MiniApps/DicomFolderDump.cpp
rename to Modules/DiffusionImaging/MiniApps/Dicom2Nrrd.cpp
index e9500f7fcf..4e6472aa90 100644
--- a/Modules/DiffusionImaging/MiniApps/DicomFolderDump.cpp
+++ b/Modules/DiffusionImaging/MiniApps/Dicom2Nrrd.cpp
@@ -1,91 +1,88 @@
/*===================================================================
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 "MiniAppManager.h"
-
#include "mitkDicomSeriesReader.h"
#include "mitkProperties.h"
-// CTK
-#include "ctkCommandLineParser.h"
+
+#include "mitkCommandLineParser.h"
#include "mitkIOUtil.h"
-int DicomFolderDump(int argc, char* argv[])
+int main(int argc, char* argv[])
{
- ctkCommandLineParser parser;
+ mitkCommandLineParser parser;
parser.setTitle("Dicom Loader");
parser.setCategory("Preprocessing Tools");
parser.setDescription("");
parser.setContributor("MBI");
parser.setArgumentPrefix("--","-");
// Add command line argument names
- parser.addArgument("help", "h",ctkCommandLineParser::Bool, "Help:", "Show this help text");
-// parser.addArgument("xml", "x",ctkCommandLineParser::Bool, "Print a XML description of this modules command line interface");
- parser.addArgument("input", "i", ctkCommandLineParser::InputDirectory, "Input folder:", "Input folder",us::Any(),false);
- parser.addArgument("output", "o", ctkCommandLineParser::OutputDirectory, "Output folder:", "Output folder (ending with /)",us::Any(),false);
- parser.addArgument("filename", "f", ctkCommandLineParser::String, "Output name:", "Output filename (incl. .nrrd)",us::Any(),false);
+ parser.addArgument("help", "h",mitkCommandLineParser::Bool, "Help:", "Show this help text");
+ parser.addArgument("input", "i", mitkCommandLineParser::InputDirectory, "Input folder:", "Input folder",us::Any(),false);
+ parser.addArgument("output", "o", mitkCommandLineParser::OutputDirectory, "Output folder:", "Output folder (ending with /)",us::Any(),false);
+ parser.addArgument("filename", "f", mitkCommandLineParser::String, "Output name:", "Output filename (incl. .nrrd)",us::Any(),false);
map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
+ if (parsedArgs.size()==0)
+ return EXIT_FAILURE;
// Show a help message
if ( parsedArgs.count("help") || parsedArgs.count("h"))
{
std::cout << parser.helpText();
return EXIT_SUCCESS;
}
std::string inputFolder = us::any_cast<string>(parsedArgs["input"]);
std::string outputFolder = us::any_cast<string>(parsedArgs["output"]);
std::string outFileName = us::any_cast<string>(parsedArgs["filename"]);
//check if DICOMTags have been set as property for mitk::Image
mitk::DicomSeriesReader::FileNamesGrouping seriesInFiles = mitk::DicomSeriesReader::GetSeries( inputFolder, true );
std::list<mitk::Image::Pointer> images;
std::map<mitk::Image::Pointer, mitk::DicomSeriesReader::StringContainer> fileMap;
// TODO sort series UIDs, implementation of map iterator might differ on different platforms (or verify this is a standard topic??)
for (mitk::DicomSeriesReader::FileNamesGrouping::const_iterator seriesIter = seriesInFiles.begin();
seriesIter != seriesInFiles.end();
++seriesIter)
{
mitk::DicomSeriesReader::StringContainer files = seriesIter->second.GetFilenames();
mitk::DataNode::Pointer node = mitk::DicomSeriesReader::LoadDicomSeries( files );
if (node.IsNotNull())
{
mitk::Image::Pointer image = dynamic_cast<mitk::Image*>( node->GetData() );
images.push_back( image );
fileMap.insert( std::pair<mitk::Image::Pointer, mitk::DicomSeriesReader::StringContainer>(image,files));
}
}
// WARN: EXPECT ONLY ONE ITEM PER FOLDER
for ( std::list<mitk::Image::Pointer>::const_iterator imageIter = images.begin();
imageIter != images.end();
++imageIter )
{
const mitk::Image::Pointer image = *imageIter;
mitk::IOUtil::SaveImage(image,outputFolder + outFileName);
}
return EXIT_SUCCESS;
}
-RegisterDiffusionMiniApp(DicomFolderDump);
diff --git a/Modules/DiffusionImaging/MiniApps/DiffusionIndices.cpp b/Modules/DiffusionImaging/MiniApps/DiffusionIndices.cpp
index 8e768840f7..4454344ef2 100644
--- a/Modules/DiffusionImaging/MiniApps/DiffusionIndices.cpp
+++ b/Modules/DiffusionImaging/MiniApps/DiffusionIndices.cpp
@@ -1,149 +1,144 @@
/*===================================================================
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 "MiniAppManager.h"
-
#include <mitkImageCast.h>
#include <itkExceptionObject.h>
#include <itkImageFileWriter.h>
#include <mitkBaseDataIOFactory.h>
#include <mitkQBallImage.h>
#include <itkTensorDerivedMeasurementsFilter.h>
#include <itkDiffusionQballGeneralizedFaImageFilter.h>
#include <mitkTensorImage.h>
-#include "ctkCommandLineParser.h"
+#include "mitkCommandLineParser.h"
#include <boost/algorithm/string.hpp>
#include <itksys/SystemTools.hxx>
#include <itkMultiThreader.h>
/**
* Calculate indices derived from Qball or tensor images
*/
-int DiffusionIndices(int argc, char* argv[])
+int main(int argc, char* argv[])
{
- MITK_INFO << "DiffusionIndices";
- ctkCommandLineParser parser;
+ mitkCommandLineParser parser;
parser.setTitle("Diffusion Indices");
parser.setCategory("Diffusion Related Measures");
parser.setDescription("");
parser.setContributor("MBI");
parser.setArgumentPrefix("--", "-");
- parser.addArgument("input", "i", ctkCommandLineParser::InputFile, "Input:", "input image (tensor, Q-ball or FSL/MRTrix SH-coefficient image)", us::Any(), false);
- parser.addArgument("index", "idx", ctkCommandLineParser::String, "Index:", "index (fa, gfa, ra, ad, rd, ca, l2, l3, md)", us::Any(), false);
- parser.addArgument("outFile", "o", ctkCommandLineParser::OutputFile, "Output:", "output file", us::Any(), false);
+ parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input:", "input image (tensor, Q-ball or FSL/MRTrix SH-coefficient image)", us::Any(), false);
+ parser.addArgument("index", "idx", mitkCommandLineParser::String, "Index:", "index (fa, gfa, ra, ad, rd, ca, l2, l3, md)", us::Any(), false);
+ parser.addArgument("outFile", "o", mitkCommandLineParser::OutputFile, "Output:", "output file", us::Any(), false);
map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
if (parsedArgs.size()==0)
return EXIT_FAILURE;
string inFileName = us::any_cast<string>(parsedArgs["input"]);
string index = us::any_cast<string>(parsedArgs["index"]);
string outFileName = us::any_cast<string>(parsedArgs["outFile"]);
string ext = itksys::SystemTools::GetFilenameLastExtension(outFileName);
if (ext.empty())
outFileName += ".nrrd";
try
{
// load input image
const std::string s1="", s2="";
std::vector<mitk::BaseData::Pointer> infile = mitk::BaseDataIO::LoadBaseDataFromFile( inFileName, s1, s2, false );
if( boost::algorithm::ends_with(inFileName, ".qbi") && index=="gfa" )
{
typedef itk::Vector<float, QBALL_ODFSIZE> OdfVectorType;
typedef itk::Image<OdfVectorType,3> ItkQballImageType;
mitk::QBallImage::Pointer mitkQballImage = dynamic_cast<mitk::QBallImage*>(infile.at(0).GetPointer());
ItkQballImageType::Pointer itk_qbi = ItkQballImageType::New();
mitk::CastToItkImage(mitkQballImage, itk_qbi);
typedef itk::DiffusionQballGeneralizedFaImageFilter<float,float,QBALL_ODFSIZE> GfaFilterType;
GfaFilterType::Pointer gfaFilter = GfaFilterType::New();
gfaFilter->SetInput(itk_qbi);
gfaFilter->SetComputationMethod(GfaFilterType::GFA_STANDARD);
gfaFilter->Update();
itk::ImageFileWriter< itk::Image<float,3> >::Pointer fileWriter = itk::ImageFileWriter< itk::Image<float,3> >::New();
fileWriter->SetInput(gfaFilter->GetOutput());
fileWriter->SetFileName(outFileName);
fileWriter->Update();
}
else if( boost::algorithm::ends_with(inFileName, ".dti") )
{
typedef itk::Image< itk::DiffusionTensor3D<float>, 3 > ItkTensorImage;
mitk::TensorImage::Pointer mitkTensorImage = dynamic_cast<mitk::TensorImage*>(infile.at(0).GetPointer());
ItkTensorImage::Pointer itk_dti = ItkTensorImage::New();
mitk::CastToItkImage(mitkTensorImage, itk_dti);
typedef itk::TensorDerivedMeasurementsFilter<float> MeasurementsType;
MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New();
measurementsCalculator->SetInput(itk_dti.GetPointer() );
if(index=="fa")
measurementsCalculator->SetMeasure(MeasurementsType::FA);
else if(index=="ra")
measurementsCalculator->SetMeasure(MeasurementsType::RA);
else if(index=="ad")
measurementsCalculator->SetMeasure(MeasurementsType::AD);
else if(index=="rd")
measurementsCalculator->SetMeasure(MeasurementsType::RD);
else if(index=="ca")
measurementsCalculator->SetMeasure(MeasurementsType::CA);
else if(index=="l2")
measurementsCalculator->SetMeasure(MeasurementsType::L2);
else if(index=="l3")
measurementsCalculator->SetMeasure(MeasurementsType::L3);
else if(index=="md")
measurementsCalculator->SetMeasure(MeasurementsType::MD);
else
{
MITK_WARN << "No valid diffusion index for input image (tensor image) defined";
return EXIT_FAILURE;
}
measurementsCalculator->Update();
itk::ImageFileWriter< itk::Image<float,3> >::Pointer fileWriter = itk::ImageFileWriter< itk::Image<float,3> >::New();
fileWriter->SetInput(measurementsCalculator->GetOutput());
fileWriter->SetFileName(outFileName);
fileWriter->Update();
}
else
- MITK_INFO << "Diffusion index " << index << " not supported for supplied file type.";
+ std::cout << "Diffusion index " << index << " not supported for supplied file type.";
}
catch (itk::ExceptionObject e)
{
- MITK_INFO << e;
+ std::cout << e;
return EXIT_FAILURE;
}
catch (std::exception e)
{
- MITK_INFO << e.what();
+ std::cout << e.what();
return EXIT_FAILURE;
}
catch (...)
{
- MITK_INFO << "ERROR!?!";
+ std::cout << "ERROR!?!";
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
-
-RegisterDiffusionMiniApp(DiffusionIndices);
diff --git a/Modules/DiffusionImaging/MiniApps/Documentation/DiffusionMiniApps.dox b/Modules/DiffusionImaging/MiniApps/Documentation/DiffusionMiniApps.dox
index b47a2d0313..47cbd4fd62 100644
--- a/Modules/DiffusionImaging/MiniApps/Documentation/DiffusionMiniApps.dox
+++ b/Modules/DiffusionImaging/MiniApps/Documentation/DiffusionMiniApps.dox
@@ -1,199 +1,196 @@
/**
\page DiffusionMiniApps MITK Diffusion MiniApps
\tableofcontents
-The respective MiniApp is called MitkDiffusionMiniApp and is shipped with the current MITK Diffusion installer.
-This page intends to provide an overview of all tools that are included in the DiffusionMiniApp. Also it relates them
-to the respective Plugin in the MITK Diffusion application (if one exists).
+This page intends to provide an overview of all tools that are included with the current MITK Diffusion Installer and refer to the respective Plugin in the MITK Diffusion application (if one exists).
For a detailed list of parameters call the according tool without any arguments (see \ref MiniAppExplainPage for details on this) or refer its Plugin equivalent.
\section Preprocessing Preprocessing Tools
-
-\subsection BatchedFolderRegistratuion Batched Folder Registration
+\subsection SecFolderRegistration Folder Registration
Allows to register a series of images (of different modalities, including diffusion weighted) to one reference image. It allows to register derived resources (e.g. a segmentation on
a T2 image) using the transformation of the original (T2) image.
For the following examples assume a folder containing a longitudinal study with T1,T2, DWI images and segmentations (ROI) :
\code
Patien01_2010-1.dwi
Patien01_2010-1_T1.nrrd
Patien01_2010-1_T2.nrrd
Patien01_2010-1_ROI.nrrd
Patien01_2010-2.dwi
Patien01_2010-2_T1.nrrd
Patien01_2010-2_T2.nrrd
Patien01_2010-2_ROI.nrrd
Patien01_2010-3.dwi
Patien01_2010-3_T1.nrrd
Patien01_2010-3_T2.nrrd
Patien01_2010-3_ROI.nrrd
Patien01_2010-4.dwi
Patien01_2010-4_T1.nrrd
Patien01_2010-4_T2.nrrd
Patien01_2010-4_ROI.nrrd
\endcode
All T2 and DWI images are to be co-registered to the first T2 image, this can be achieved by the following two calls:
\code
- $./MitkDiffusionMiniApps BatchedFolderRegistration -i /home/inputFolder/ -o /home/outputFolder/ -f Patien01_2010-1_T2.nrrd -m T2.nrrd
- $./MitkDiffusionMiniApps BatchedFolderRegistration -i /home/inputFolder/ -o /home/outputFolder/ -f Patien01_2010-1_T2.nrrd -m .dwi
+ $./MitkFolderRegistration -i /home/inputFolder/ -o /home/outputFolder/ -f Patien01_2010-1_T2.nrrd -m T2.nrrd
+ $./MitkFolderRegistration -i /home/inputFolder/ -o /home/outputFolder/ -f Patien01_2010-1_T2.nrrd -m .dwi
\endcode
The segmentations where performed on the T1 image and are therefore related to the image space of the respective T1 image,
so they can be bound to these images by marking them as derived resources. To register them both you would call
\code
-$./bin/MitkDiffusionMiniApps BatchedFolderRegistration -i /home/inputFolder/ -o /home/outputFolder/ -f Patien01_2010-1_T2.nrrd -m _T1.nrrd -d _ROI.nrrd -b
+ $./MitkFolderRegistration -i /home/inputFolder/ -o /home/outputFolder/ -f Patien01_2010-1_T2.nrrd -m _T1.nrrd -d _ROI.nrrd -b
\endcode
\note the suffixes of '_T1.nrrd' and '_ROI.nrrd' must have the same length!
The parameter -b designates the derived resource as binary such that a nearest neighbor interpolation is used.
All images (execpt for DWI files) are resample to the reference image, to resample to a specific spacing append the desired
spacing like this (e.g. 1 x 1 x 2 mm)
\code
-$./MitkDiffusionMiniApps BatchedFolderRegistration -i /home/inputFolder/ -o /home/outputFolder/ -f Patien01_2010-1_T2.nrrd -m .dwi -r 1,1,2
+ $./MitkFolderRegistration -i /home/inputFolder/ -o /home/outputFolder/ -f Patien01_2010-1_T2.nrrd -m .dwi -r 1,1,2
\endcode
\note Registration methods assume that both images occupy roughly the same space. It may happend that this is not the case,
and therefore registration fails. In this case you can try the -c option which uses the same origin for both images.
\subsection CopyGeometry Copy Geometry
Copies the geometry (origin) of the source image to the target image.
\subsection ImageResampler Resampling of Images
This tool can be used to resample images in different ways. One way is by specifying the spacing.
Transforming an image test.nrrd to have a spacing of 1x1x3 mm can be done using this command:
\code
-$./MitkDiffusionMiniApps ImageResampler -i test.nrrd -s 1,1,3 -o resampledImage.nrrd
+ $./MitkImageResampler -i test.nrrd -s 1,1,3 -o resampledImage.nrrd
\endcode
Alternatively this program can be used to resample by reference. This will resample the input image to the grid provided by the reference image
and also ensure they occupy the same physical space (that is the input image will have the same origin and voxel dimensions)
\code
-$./MitkDiffusionMiniApps ImageResampler -i test.nrrd -r referenceImage.nrrd -o resampledImage.nrrd
+ $./MitkImageResampler -i test.nrrd -r referenceImage.nrrd -o resampledImage.nrrd
\endcode
\note Resampling by reference image can also be applied to MR Diffusion data (.dwi files).
\subsection TensorRecon Tensor Reconstruction
See \ref QmitkDiffusionImagingUserManualTensorReconstruction for the GUI equivalent of this tool.
Takes a .dwi, .fsl/.fslgz file as input and saves the computed reconstructed tensor to the specified file.
It also allows for a threshold to be set, to exclude low b values from the reconstruction process.
\code
-./MitkDiffusionMiniApps TensorReconstruction -i /home/user/sample.dwi -o /home/user/tensors.dti -t 50
+$./MitkTensorReconstruction -i /home/user/sample.dwi -o /home/user/tensors.dti -t 50
\endcode
\subsection QballRecon Qball Reconstruction
See \ref QmitkDiffusionImagingUserManualQBallReconstruction for the GUI equivalent of this tool.
\code
-./MitkDiffusionMiniApps QballReconstruction -i /home/user/sample.dwi -o /home/user/tensors.qbi -t 50 -r .006 -shc /home/user/coeffs.csv
+./MitkQballReconstruction -i /home/user/sample.dwi -o /home/user/tensors.qbi -t 50 -r .006 -shc /home/user/coeffs.csv
\endcode
\subsection PeakExtraction Peak Extraction
Extracts ODF peaks from the given spherical harmonics coefficient image. Input image type is an image that contains a vector with the spherical harmonics coefficients as pixel type: Image< Vector< float, (ShOrder*ShOrder + ShOrder + 2)/2 + ShOrder >, 3 >
\subsection PeakAngularErr Peak Angular Error
Calculates the angular error between two sets of input directions. The directions are stored as images. Each image voxel contains one direction vector. Such images are for example the output of the fiber direction extraction miniapp.
\section DiffusionMeasures Diffusion Related Measures
\subsection DiffusionIndices Diffusion Indices
See \ref QmitkDiffusionImagingUserManualQuantification for the GUI equivalent of this tool.
Computes a selected tensor derived indices (fa, gfa, ra, ad, rd, ca, l2, l3, md) given a
Tensor, Q-ball or FSL/MRTrix SH-coefficient image. E.g. to compute the fraction anisotropy call
\code
-./MitkDiffusionMiniApps DiffusionIndices -i /home/user/input.dti -idx fa -o /home/user/fa_image.nrrd
+./MitkDiffusionIndices -i /home/user/input.dti -idx fa -o /home/user/fa_image.nrrd
\endcode
\subsection AllDiffusionIndices Tensor Derived Maps Extraction
Similar to \ref DiffusionIndices . But computes all of the following indices FA, RA, MD, CA, RD, AD at once.
Also the input is a regular .dwi file, the tensor reconstruction is done implicitly (using a b0 threshold of 50).
\section FibTracking Fiber Tracking and Processing Methods
\subsection FibDirection Fiber Direction Extraction
Extracts the voxel-wise main fiber directions from a tractogram.
\subsection Streamline Streamline Tracking
See \ref org_mitk_views_streamlinetracking for the GUI equivalent of this tool.
Performs streamline tractography on a tensor image.
\subsection GibbsTracking Gibbs Fiber Tracking
See \ref org_mitk_views_gibbstracking for the GUI equivalent of this tool.
Performs global Gibbs tractography on a tensor/Q-ball/SH-coefficient image.
\subsection FibProcessing Fiber Processing
Post-process a fiber bundle. Provides the possibility to
\li remove short/long fiber tracks
\li apply curvature threshold
\li resample a fiber bundle (linear and spline based)
\li compress a fiber bundle (lossy)
\li transform fiber bundle (scale, translate, rotate)
\li mirror fiber bundle
\subsection FibFoxProcessing Fiberfox
See \ref QmitkFiberfoxViewUserManualSignalGeneration for the GUI equivalent of this tool.
Generates a signal from a fiber bundle provided a reference DWI and a parameter file. The parameter file can be generated
using the Fiberfox plugin (sub-tab) Signal Generation.
\subsection FormatConv File Format Converter
Determines the data type and converts the input file (if possible) to .NRRD (regular image),
.DWI (diffusion image) or .FIB (fiber bundle).
\subsection MultiShell Multishell Methods
Computes several fits on an images (Kurtosis,Bi-Exponential, ADC).
These fits are part of the Preprocessing Plugin \ref QmitkDiffusionImagingUserManualPreprocessing .
\section NetworkTools Connectomics
\subsection NetworkCreation Network Creation
See \ref org_mitk_views_connectomicsdata for the GUI equivalent of this tool.
Creates a network based on a brain parcellation and a fiber image.
\subsection NetworkStatistics Network Statistics
See \ref org_mitk_views_connectomicsstatistics for the GUI equivalent of this tool.
Calculates several network statistics for a given connectome.
*/
diff --git a/Modules/DiffusionImaging/MiniApps/DwiDenoising.cpp b/Modules/DiffusionImaging/MiniApps/DwiDenoising.cpp
index 5b46b97ba0..83f8f18544 100644
--- a/Modules/DiffusionImaging/MiniApps/DwiDenoising.cpp
+++ b/Modules/DiffusionImaging/MiniApps/DwiDenoising.cpp
@@ -1,162 +1,156 @@
/*===================================================================
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 "MiniAppManager.h"
-
#include <mitkImageCast.h>
#include <mitkBaseDataIOFactory.h>
-#include "ctkCommandLineParser.h"
+#include "mitkCommandLineParser.h"
#include <boost/algorithm/string.hpp>
#include <DiffusionWeightedImages/mitkDiffusionImage.h>
#include <itkNonLocalMeansDenoisingFilter.h>
#include <itkImage.h>
#include <mitkIOUtil.h>
typedef mitk::DiffusionImage<short> DiffusionImageType;
typedef itk::Image<short, 3> ImageType;
mitk::BaseData::Pointer LoadFile(std::string filename)
{
if( filename.empty() )
return NULL;
const std::string s1="", s2="";
std::vector<mitk::BaseData::Pointer> infile = mitk::BaseDataIO::LoadBaseDataFromFile( filename, s1, s2, false );
if( infile.empty() )
{
- MITK_INFO << "File " << filename << " could not be read!";
+ std::cout << "File " << filename << " could not be read!";
return NULL;
}
mitk::BaseData::Pointer baseData = infile.at(0);
return baseData;
}
/**
* Denoises DWI using the Nonlocal - Means algorithm
*/
-int DwiDenoising(int argc, char* argv[])
+int main(int argc, char* argv[])
{
- MITK_INFO << "DwiDenoising";
- ctkCommandLineParser parser;
+ std::cout << "DwiDenoising";
+ mitkCommandLineParser parser;
parser.setTitle("DWI Denoising");
parser.setCategory("Preprocessing Tools");
parser.setContributor("MBI");
parser.setDescription("Denoising for diffusion weighted images using a non-local means algorithm.");
parser.setArgumentPrefix("--", "-");
- parser.addArgument("input", "i", ctkCommandLineParser::InputFile, "Input:", "input image (DWI)", us::Any(), false);
- parser.addArgument("variance", "v", ctkCommandLineParser::Float, "Variance:", "noise variance", us::Any(), false);
+ parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input:", "input image (DWI)", us::Any(), false);
+ parser.addArgument("variance", "v", mitkCommandLineParser::Float, "Variance:", "noise variance", us::Any(), false);
- parser.addArgument("mask", "m", ctkCommandLineParser::InputFile, "Mask:", "brainmask for input image", us::Any(), true);
- parser.addArgument("search", "s", ctkCommandLineParser::Int, "Search radius:", "search radius", us::Any(), true);
- parser.addArgument("compare", "c", ctkCommandLineParser::Int, "Comparison radius:", "comparison radius", us::Any(), true);
- parser.addArgument("joint", "j", ctkCommandLineParser::Bool, "Joint information:", "use joint information");
- parser.addArgument("rician", "r", ctkCommandLineParser::Bool, "Rician adaption:", "use rician adaption");
+ parser.addArgument("mask", "m", mitkCommandLineParser::InputFile, "Mask:", "brainmask for input image", us::Any(), true);
+ parser.addArgument("search", "s", mitkCommandLineParser::Int, "Search radius:", "search radius", us::Any(), true);
+ parser.addArgument("compare", "c", mitkCommandLineParser::Int, "Comparison radius:", "comparison radius", us::Any(), true);
+ parser.addArgument("joint", "j", mitkCommandLineParser::Bool, "Joint information:", "use joint information");
+ parser.addArgument("rician", "r", mitkCommandLineParser::Bool, "Rician adaption:", "use rician adaption");
parser.changeParameterGroup("Output", "Output of this miniapp");
- parser.addArgument("output", "o", ctkCommandLineParser::OutputFile, "Output:", "output image (DWI)", us::Any(), false);
+ parser.addArgument("output", "o", mitkCommandLineParser::OutputFile, "Output:", "output image (DWI)", us::Any(), false);
map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
if (parsedArgs.size()==0)
return EXIT_FAILURE;
string inFileName = us::any_cast<string>(parsedArgs["input"]);
double variance = static_cast<double>(us::any_cast<float>(parsedArgs["variance"]));
string maskName;
if (parsedArgs.count("mask"))
maskName = us::any_cast<string>(parsedArgs["mask"]);
string outFileName = us::any_cast<string>(parsedArgs["output"]);
// boost::algorithm::erase_all(outFileName, ".dwi");
int search = 4;
if (parsedArgs.count("search"))
search = us::any_cast<int>(parsedArgs["search"]);
int compare = 1;
if (parsedArgs.count("compare"))
compare = us::any_cast<int>(parsedArgs["compare"]);
bool joint = false;
if (parsedArgs.count("joint"))
joint = true;
bool rician = false;
if (parsedArgs.count("rician"))
rician = true;
try
{
if( boost::algorithm::ends_with(inFileName, ".dwi"))
{
DiffusionImageType::Pointer dwi = dynamic_cast<DiffusionImageType*>(LoadFile(inFileName).GetPointer());
itk::NonLocalMeansDenoisingFilter<short>::Pointer filter = itk::NonLocalMeansDenoisingFilter<short>::New();
filter->SetNumberOfThreads(12);
filter->SetInputImage(dwi->GetVectorImage());
if (!maskName.empty())
{
mitk::Image::Pointer mask = dynamic_cast<mitk::Image*>(LoadFile(maskName).GetPointer());
ImageType::Pointer itkMask = ImageType::New();
mitk::CastToItkImage(mask, itkMask);
filter->SetInputMask(itkMask);
}
filter->SetUseJointInformation(joint);
filter->SetUseRicianAdaption(rician);
filter->SetSearchRadius(search);
filter->SetComparisonRadius(compare);
filter->SetVariance(variance);
filter->Update();
DiffusionImageType::Pointer output = DiffusionImageType::New();
output->SetVectorImage(filter->GetOutput());
output->SetReferenceBValue(dwi->GetReferenceBValue());
output->SetDirections(dwi->GetDirections());
output->InitializeFromVectorImage();
// std::stringstream name;
// name << outFileName << "_NLM_" << search << "-" << compare << "-" << variance << ".dwi";
mitk::IOUtil::Save(output, outFileName.c_str());
}
else
{
- MITK_INFO << "Only supported for .dwi!";
+ std::cout << "Only supported for .dwi!";
}
}
catch (itk::ExceptionObject e)
{
- MITK_INFO << e;
+ std::cout << e;
return EXIT_FAILURE;
}
catch (std::exception e)
{
- MITK_INFO << e.what();
+ std::cout << e.what();
return EXIT_FAILURE;
}
catch (...)
{
- MITK_INFO << "ERROR!?!";
+ std::cout << "ERROR!?!";
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
-
-
-
-RegisterDiffusionMiniApp(DwiDenoising);
diff --git a/Modules/DiffusionImaging/MiniApps/ExportShImage.cpp b/Modules/DiffusionImaging/MiniApps/ExportShImage.cpp
index 8bbd36c37b..b42ebf97b4 100755
--- a/Modules/DiffusionImaging/MiniApps/ExportShImage.cpp
+++ b/Modules/DiffusionImaging/MiniApps/ExportShImage.cpp
@@ -1,138 +1,136 @@
/*===================================================================
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 "MiniAppManager.h"
#include <mitkBaseDataIOFactory.h>
#include <mitkBaseData.h>
#include <mitkImageCast.h>
#include <mitkImageToItk.h>
#include <metaCommand.h>
-#include "ctkCommandLineParser.h"
+#include "mitkCommandLineParser.h"
#include <usAny.h>
#include <itkImageFileWriter.h>
#include <itkImageFileReader.h>
#include <mitkIOUtil.h>
#include <boost/lexical_cast.hpp>
#include <itkShCoefficientImageExporter.h>
#include <itkFlipImageFilter.h>
#define _USE_MATH_DEFINES
#include <math.h>
template<int shOrder>
int StartShConversion(int argc, char* argv[])
{
- ctkCommandLineParser parser;
+ mitkCommandLineParser parser;
parser.setTitle("Export SH Image");
parser.setCategory("Preprocessing Tools");
parser.setDescription("");
parser.setContributor("MBI");
parser.setArgumentPrefix("--", "-");
- parser.addArgument("input", "i", ctkCommandLineParser::InputFile, "Input:", "MITK SH image", us::Any(), false);
- parser.addArgument("output", "o", ctkCommandLineParser::InputFile, "Output", "MRtrix SH image", us::Any(), false);
- parser.addArgument("shOrder", "sh", ctkCommandLineParser::Int, "SH order:", "spherical harmonics order");
+ parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input:", "MITK SH image", us::Any(), false);
+ parser.addArgument("output", "o", mitkCommandLineParser::InputFile, "Output", "MRtrix SH image", us::Any(), false);
+ parser.addArgument("shOrder", "sh", mitkCommandLineParser::Int, "SH order:", "spherical harmonics order");
map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
if (parsedArgs.size()==0)
return EXIT_FAILURE;
string inFile = us::any_cast<string>(parsedArgs["input"]);
string outFile = us::any_cast<string>(parsedArgs["output"]);
try
{
typedef itk::Image< float, 4 > OutImageType;
typedef itk::Image< itk::Vector< float, (shOrder*shOrder + shOrder + 2)/2 + shOrder >, 3 > InputImageType;
typename InputImageType::Pointer itkInImage = InputImageType::New();
typedef itk::ImageFileReader< InputImageType > ReaderType;
typename ReaderType::Pointer reader = ReaderType::New();
- MITK_INFO << "reading " << inFile;
+ std::cout << "reading " << inFile;
reader->SetFileName(inFile.c_str());
reader->Update();
itkInImage = reader->GetOutput();
// extract directions from fiber bundle
typename itk::ShCoefficientImageExporter<float, shOrder>::Pointer filter = itk::ShCoefficientImageExporter<float,shOrder>::New();
filter->SetInputImage(itkInImage);
filter->GenerateData();
OutImageType::Pointer outImage = filter->GetOutputImage();
typedef itk::ImageFileWriter< OutImageType > WriterType;
WriterType::Pointer writer = WriterType::New();
writer->SetFileName(outFile.c_str());
writer->SetInput(outImage);
writer->Update();
}
catch (itk::ExceptionObject e)
{
- MITK_INFO << e;
+ std::cout << e;
return EXIT_FAILURE;
}
catch (std::exception e)
{
- MITK_INFO << e.what();
+ std::cout << e.what();
return EXIT_FAILURE;
}
catch (...)
{
- MITK_INFO << "ERROR!?!";
+ std::cout << "ERROR!?!";
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
-int ExportShImage(int argc, char* argv[])
+int main(int argc, char* argv[])
{
- MITK_INFO << "ExportShImage";
- ctkCommandLineParser parser;
+
+ mitkCommandLineParser parser;
parser.setArgumentPrefix("--", "-");
- parser.addArgument("input", "i", ctkCommandLineParser::InputFile, "Input image", "MITK SH image", us::Any(), false);
- parser.addArgument("output", "o", ctkCommandLineParser::OutputFile, "Output image", "MRtrix SH image", us::Any(), false);
- parser.addArgument("shOrder", "sh", ctkCommandLineParser::Int, "Spherical harmonics order", "spherical harmonics order");
+ parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input image", "MITK SH image", us::Any(), false);
+ parser.addArgument("output", "o", mitkCommandLineParser::OutputFile, "Output image", "MRtrix SH image", us::Any(), false);
+ parser.addArgument("shOrder", "sh", mitkCommandLineParser::Int, "Spherical harmonics order", "spherical harmonics order");
parser.setCategory("Preprocessing Tools");
parser.setTitle("Export SH Image");
parser.setDescription("");
parser.setContributor("MBI");
map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
if (parsedArgs.size()==0)
return EXIT_FAILURE;
int shOrder = -1;
if (parsedArgs.count("shOrder"))
shOrder = us::any_cast<int>(parsedArgs["shOrder"]);
switch (shOrder)
{
case 4:
return StartShConversion<4>(argc, argv);
case 6:
return StartShConversion<6>(argc, argv);
case 8:
return StartShConversion<8>(argc, argv);
case 10:
return StartShConversion<10>(argc, argv);
case 12:
return StartShConversion<12>(argc, argv);
}
return EXIT_FAILURE;
}
-RegisterDiffusionMiniApp(ExportShImage);
diff --git a/Modules/DiffusionImaging/MiniApps/ExtractImageStatistics.cpp b/Modules/DiffusionImaging/MiniApps/ExtractImageStatistics.cpp
index 8717752432..e30bbfa158 100644
--- a/Modules/DiffusionImaging/MiniApps/ExtractImageStatistics.cpp
+++ b/Modules/DiffusionImaging/MiniApps/ExtractImageStatistics.cpp
@@ -1,127 +1,127 @@
/*===================================================================
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 "MiniAppManager.h"
#include "ctkCommandLineParser.h"
#include "mitkImage.h"
#include "mitkImageStatisticsCalculator.h"
#include "mitkIOUtil.h"
#include <iostream>
#include <usAny.h>
#include <fstream>
int ExtractImageStatistics(int argc, char* argv[])
{
- ctkCommandLineParser parser;
+ mitkCommandLineParser parser;
parser.setTitle("Extract Image Statistics");
parser.setCategory("Preprocessing Tools");
parser.setDescription("");
parser.setContributor("MBI");
parser.setArgumentPrefix("--", "-");
- parser.addArgument("help", "h", ctkCommandLineParser::String, "Help:", "Show this help text");
- parser.addArgument("input", "i", ctkCommandLineParser::InputFile, "Input:", "input image", us::Any(),false);
- parser.addArgument("mask", "m", ctkCommandLineParser::InputFile, "Mask:", "mask image / roi image denotin area on which statistics are calculated", us::Any(),false);
- parser.addArgument("out", "o", ctkCommandLineParser::OutputFile, "Output", "output file (default: filenameOfRoi.nrrd_statistics.txt)", us::Any());
+ parser.addArgument("help", "h", mitkCommandLineParser::String, "Help:", "Show this help text");
+ parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input:", "input image", us::Any(),false);
+ parser.addArgument("mask", "m", mitkCommandLineParser::InputFile, "Mask:", "mask image / roi image denotin area on which statistics are calculated", us::Any(),false);
+ parser.addArgument("out", "o", mitkCommandLineParser::OutputFile, "Output", "output file (default: filenameOfRoi.nrrd_statistics.txt)", us::Any());
map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
if (parsedArgs.size()==0 || parsedArgs.count("help") || parsedArgs.count("h"))
{
std::cout << "\n\n MiniApp Description: \nCalculates statistics on the supplied image using given mask." << endl;
std::cout << "Output is written to the designated output file in this order:" << endl;
std::cout << "Mean, Standard Deviation, RMS, Max, Min, Number of Voxels, Volume [mm3]" << endl;
std::cout << "\n\n Parameters:"<< endl;
std::cout << parser.helpText();
return EXIT_SUCCESS;
}
// Parameters:
bool ignoreZeroValues = false;
unsigned int timeStep = 0;
std::string inputImageFile = us::any_cast<string>(parsedArgs["input"]);
std::string maskImageFile = us::any_cast<string>(parsedArgs["mask"]);
std::string outFile;
if (parsedArgs.count("out") || parsedArgs.count("o") )
outFile = us::any_cast<string>(parsedArgs["out"]);
else
outFile = inputImageFile + "_statistics.txt";
// Load image and mask
mitk::Image::Pointer maskImage = mitk::IOUtil::LoadImage(maskImageFile);
mitk::Image::Pointer inputImage = mitk::IOUtil::LoadImage(inputImageFile);
// Calculate statistics
mitk::ImageStatisticsCalculator::Statistics statisticsStruct;
mitk::ImageStatisticsCalculator::Pointer calculator = mitk::ImageStatisticsCalculator::New();
try
{
calculator->SetImage(inputImage);
calculator->SetImageMask(maskImage);
calculator->SetMaskingModeToImage();
}
catch( const itk::ExceptionObject& e)
{
MITK_ERROR << "Statistic Calculation Failed - ITK Exception:" << e.what();
return -1;
}
calculator->SetDoIgnorePixelValue(ignoreZeroValues);
calculator->SetIgnorePixelValue(0);
try
{
calculator->ComputeStatistics(timeStep);
}
catch ( mitk::Exception& e)
{
MITK_ERROR<< "MITK Exception: " << e.what();
return -1;
}
statisticsStruct = calculator->GetStatistics(timeStep);
// Calculate Volume
double volume = 0;
const mitk::BaseGeometry *geometry = inputImage->GetGeometry();
if ( geometry != NULL )
{
const mitk::Vector3D &spacing = inputImage->GetGeometry()->GetSpacing();
volume = spacing[0] * spacing[1] * spacing[2] * (double) statisticsStruct.GetN();
}
// Write Results to file
std::ofstream output;
output.open(outFile.c_str());
output << statisticsStruct.GetMean() << " , ";
output << statisticsStruct.GetSigma() << " , ";
output << statisticsStruct.GetRMS() << " , ";
output << statisticsStruct.GetMax() << " , ";
output << statisticsStruct.GetMin() << " , ";
output << statisticsStruct.GetN() << " , ";
output << volume << "\n";
output.flush();
output.close();
return 0;
}
RegisterDiffusionMiniApp(ExtractImageStatistics);
diff --git a/Modules/DiffusionImaging/MiniApps/FiberDirectionExtraction.cpp b/Modules/DiffusionImaging/MiniApps/FiberDirectionExtraction.cpp
index b80b1e1b1c..3bf5e834b8 100755
--- a/Modules/DiffusionImaging/MiniApps/FiberDirectionExtraction.cpp
+++ b/Modules/DiffusionImaging/MiniApps/FiberDirectionExtraction.cpp
@@ -1,177 +1,174 @@
/*===================================================================
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 "MiniAppManager.h"
#include <mitkBaseDataIOFactory.h>
#include <mitkBaseData.h>
#include <mitkImageCast.h>
#include <mitkImageToItk.h>
#include <metaCommand.h>
-#include "ctkCommandLineParser.h"
+#include "mitkCommandLineParser.h"
#include <usAny.h>
#include <itkImageFileWriter.h>
#include <mitkIOUtil.h>
#include <boost/lexical_cast.hpp>
#include <itkEvaluateDirectionImagesFilter.h>
#include <itkTractsToVectorImageFilter.h>
#include <mitkCoreObjectFactory.h>
#define _USE_MATH_DEFINES
#include <math.h>
-int FiberDirectionExtraction(int argc, char* argv[])
+int main(int argc, char* argv[])
{
- MITK_INFO << "FiberDirectionExtraction";
- ctkCommandLineParser parser;
+ mitkCommandLineParser parser;
parser.setTitle("Fiber Direction Extraction");
parser.setCategory("Fiber Tracking and Processing Methods");
parser.setDescription("");
parser.setContributor("MBI");
parser.setArgumentPrefix("--", "-");
- parser.addArgument("input", "i", ctkCommandLineParser::InputFile, "Input:", "input tractogram (.fib/.trk)", us::Any(), false);
- parser.addArgument("out", "o", ctkCommandLineParser::OutputDirectory, "Output:", "output root", us::Any(), false);
- parser.addArgument("mask", "m", ctkCommandLineParser::InputFile, "Mask:", "mask image");
- parser.addArgument("athresh", "a", ctkCommandLineParser::Float, "Angular threshold:", "angular threshold in degrees. closer fiber directions are regarded as one direction and clustered together.", 25, true);
- parser.addArgument("peakthresh", "t", ctkCommandLineParser::Float, "Peak size threshold:", "peak size threshold relative to largest peak in voxel", 0.2, true);
- parser.addArgument("verbose", "v", ctkCommandLineParser::Bool, "Verbose:", "output optional and intermediate calculation results");
- parser.addArgument("numdirs", "d", ctkCommandLineParser::Int, "Max. num. directions:", "maximum number of fibers per voxel", 3, true);
- parser.addArgument("normalize", "n", ctkCommandLineParser::Bool, "Normalize:", "normalize vectors");
+ parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input:", "input tractogram (.fib/.trk)", us::Any(), false);
+ parser.addArgument("out", "o", mitkCommandLineParser::OutputDirectory, "Output:", "output root", us::Any(), false);
+ parser.addArgument("mask", "m", mitkCommandLineParser::InputFile, "Mask:", "mask image");
+ parser.addArgument("athresh", "a", mitkCommandLineParser::Float, "Angular threshold:", "angular threshold in degrees. closer fiber directions are regarded as one direction and clustered together.", 25, true);
+ parser.addArgument("peakthresh", "t", mitkCommandLineParser::Float, "Peak size threshold:", "peak size threshold relative to largest peak in voxel", 0.2, true);
+ parser.addArgument("verbose", "v", mitkCommandLineParser::Bool, "Verbose:", "output optional and intermediate calculation results");
+ parser.addArgument("numdirs", "d", mitkCommandLineParser::Int, "Max. num. directions:", "maximum number of fibers per voxel", 3, true);
+ parser.addArgument("normalize", "n", mitkCommandLineParser::Bool, "Normalize:", "normalize vectors");
map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
if (parsedArgs.size()==0)
return EXIT_FAILURE;
string fibFile = us::any_cast<string>(parsedArgs["input"]);
string maskImage("");
if (parsedArgs.count("mask"))
maskImage = us::any_cast<string>(parsedArgs["mask"]);
float peakThreshold = 0.2;
if (parsedArgs.count("peakthresh"))
peakThreshold = us::any_cast<float>(parsedArgs["peakthresh"]);
float angularThreshold = 25;
if (parsedArgs.count("athresh"))
angularThreshold = us::any_cast<float>(parsedArgs["athresh"]);
string outRoot = us::any_cast<string>(parsedArgs["out"]);
bool verbose = false;
if (parsedArgs.count("verbose"))
verbose = us::any_cast<bool>(parsedArgs["verbose"]);
int maxNumDirs = 3;
if (parsedArgs.count("numdirs"))
maxNumDirs = us::any_cast<int>(parsedArgs["numdirs"]);
bool normalize = false;
if (parsedArgs.count("normalize"))
normalize = us::any_cast<bool>(parsedArgs["normalize"]);
try
{
typedef itk::Image<unsigned char, 3> ItkUcharImgType;
typedef itk::Image< itk::Vector< float, 3>, 3 > ItkDirectionImage3DType;
typedef itk::VectorContainer< unsigned int, ItkDirectionImage3DType::Pointer > ItkDirectionImageContainerType;
// load fiber bundle
mitk::FiberBundleX::Pointer inputTractogram = dynamic_cast<mitk::FiberBundleX*>(mitk::IOUtil::LoadDataNode(fibFile)->GetData());
// load/create mask image
ItkUcharImgType::Pointer itkMaskImage = NULL;
if (maskImage.compare("")!=0)
{
- MITK_INFO << "Using mask image";
+ std::cout << "Using mask image";
itkMaskImage = ItkUcharImgType::New();
mitk::Image::Pointer mitkMaskImage = dynamic_cast<mitk::Image*>(mitk::IOUtil::LoadDataNode(maskImage)->GetData());
mitk::CastToItkImage<ItkUcharImgType>(mitkMaskImage, itkMaskImage);
}
// extract directions from fiber bundle
itk::TractsToVectorImageFilter<float>::Pointer fOdfFilter = itk::TractsToVectorImageFilter<float>::New();
fOdfFilter->SetFiberBundle(inputTractogram);
fOdfFilter->SetMaskImage(itkMaskImage);
fOdfFilter->SetAngularThreshold(cos(angularThreshold*M_PI/180));
fOdfFilter->SetNormalizeVectors(normalize);
fOdfFilter->SetUseWorkingCopy(false);
fOdfFilter->SetSizeThreshold(peakThreshold);
fOdfFilter->SetMaxNumDirections(maxNumDirs);
fOdfFilter->Update();
ItkDirectionImageContainerType::Pointer directionImageContainer = fOdfFilter->GetDirectionImageContainer();
// write direction images
for (unsigned int i=0; i<directionImageContainer->Size(); i++)
{
itk::TractsToVectorImageFilter<float>::ItkDirectionImageType::Pointer itkImg = directionImageContainer->GetElement(i);
typedef itk::ImageFileWriter< itk::TractsToVectorImageFilter<float>::ItkDirectionImageType > WriterType;
WriterType::Pointer writer = WriterType::New();
string outfilename = outRoot;
outfilename.append("_DIRECTION_");
outfilename.append(boost::lexical_cast<string>(i));
outfilename.append(".nrrd");
writer->SetFileName(outfilename.c_str());
writer->SetInput(itkImg);
writer->Update();
}
if (verbose)
{
// write vector field
mitk::FiberBundleX::Pointer directions = fOdfFilter->GetOutputFiberBundle();
string outfilename = outRoot;
outfilename.append("_VECTOR_FIELD.fib");
mitk::IOUtil::SaveBaseData(directions.GetPointer(), outfilename );
// write num direction image
{
ItkUcharImgType::Pointer numDirImage = fOdfFilter->GetNumDirectionsImage();
typedef itk::ImageFileWriter< ItkUcharImgType > WriterType;
WriterType::Pointer writer = WriterType::New();
string outfilename = outRoot;
outfilename.append("_NUM_DIRECTIONS.nrrd");
writer->SetFileName(outfilename.c_str());
writer->SetInput(numDirImage);
writer->Update();
}
}
}
catch (itk::ExceptionObject e)
{
- MITK_INFO << e;
+ std::cout << e;
return EXIT_FAILURE;
}
catch (std::exception e)
{
- MITK_INFO << e.what();
+ std::cout << e.what();
return EXIT_FAILURE;
}
catch (...)
{
- MITK_INFO << "ERROR!?!";
+ std::cout << "ERROR!?!";
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
-RegisterDiffusionMiniApp(FiberDirectionExtraction);
diff --git a/Modules/DiffusionImaging/MiniApps/FiberExtraction.cpp b/Modules/DiffusionImaging/MiniApps/FiberExtraction.cpp
index eeacda652a..3ac292d293 100755
--- a/Modules/DiffusionImaging/MiniApps/FiberExtraction.cpp
+++ b/Modules/DiffusionImaging/MiniApps/FiberExtraction.cpp
@@ -1,158 +1,158 @@
/*===================================================================
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 "MiniAppManager.h"
#include <mitkBaseDataIOFactory.h>
#include <metaCommand.h>
#include "ctkCommandLineParser.h"
#include <usAny.h>
#include <mitkIOUtil.h>
#include <boost/lexical_cast.hpp>
#include <mitkCoreObjectFactory.h>
#include <mitkPlanarFigure.h>
#include <mitkPlanarFigureComposite.h>
#include <mitkFiberBundleX.h>
#include <mitkImageCast.h>
#include <mitkImageToItk.h>
#define _USE_MATH_DEFINES
#include <math.h>
int FiberExtraction(int argc, char* argv[])
{
- MITK_INFO << "FiberExtraction";
- ctkCommandLineParser parser;
+ std::cout << "FiberExtraction";
+ mitkCommandLineParser parser;
parser.setTitle("Fiber Extraction");
parser.setCategory("Fiber Tracking and Processing Methods");
parser.setContributor("MBI");
parser.setDescription("");
parser.setArgumentPrefix("--", "-");
- parser.addArgument("input", "i", ctkCommandLineParser::String, "Input:", "input tractogram (.fib/.trk)", us::Any(), false);
- parser.addArgument("out", "o", ctkCommandLineParser::String, "Output:", "output tractogram", us::Any(), false);
- parser.addArgument("planfirgure1", "pf1", ctkCommandLineParser::String, "Figure 1:", "first ROI", us::Any(), false);
- parser.addArgument("planfirgure2", "pf2", ctkCommandLineParser::String, "Figure 2:", "second ROI", us::Any());
- parser.addArgument("operation", "op", ctkCommandLineParser::String, "Operation:", "logical operation (AND, OR, NOT)", us::Any());
+ parser.addArgument("input", "i", mitkCommandLineParser::String, "Input:", "input tractogram (.fib/.trk)", us::Any(), false);
+ parser.addArgument("out", "o", mitkCommandLineParser::String, "Output:", "output tractogram", us::Any(), false);
+ parser.addArgument("planfirgure1", "pf1", mitkCommandLineParser::String, "Figure 1:", "first ROI", us::Any(), false);
+ parser.addArgument("planfirgure2", "pf2", mitkCommandLineParser::String, "Figure 2:", "second ROI", us::Any());
+ parser.addArgument("operation", "op", mitkCommandLineParser::String, "Operation:", "logical operation (AND, OR, NOT)", us::Any());
map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
if (parsedArgs.size()==0)
return EXIT_FAILURE;
string inFib = us::any_cast<string>(parsedArgs["input"]);
string outFib = us::any_cast<string>(parsedArgs["out"]);
string pf1_path = us::any_cast<string>(parsedArgs["planfirgure1"]);
string operation("");
string pf2_path("");
if (parsedArgs.count("operation"))
{
operation = us::any_cast<string>(parsedArgs["operation"]);
if (parsedArgs.count("planfirgure2") && (operation=="AND" || operation=="OR"))
pf2_path = us::any_cast<string>(parsedArgs["planfirgure2"]);
}
try
{
typedef itk::Image<unsigned char, 3> ItkUcharImgType;
// load fiber bundle
mitk::FiberBundleX::Pointer inputTractogram = dynamic_cast<mitk::FiberBundleX*>(mitk::IOUtil::LoadDataNode(inFib)->GetData());
mitk::FiberBundleX::Pointer result;
mitk::BaseData::Pointer input1 = mitk::IOUtil::LoadDataNode(pf1_path)->GetData();
mitk::PlanarFigure::Pointer pf1 = dynamic_cast<mitk::PlanarFigure*>(input1.GetPointer());
if (pf1.IsNotNull())
{
mitk::BaseData::Pointer input2;
mitk::PlanarFigure::Pointer pf2;
if (!pf2_path.empty())
{
input2 = mitk::IOUtil::LoadDataNode(pf2_path)->GetData();
pf2 = dynamic_cast<mitk::PlanarFigure*>(input2.GetPointer());
}
mitk::PlanarFigureComposite::Pointer pfc = mitk::PlanarFigureComposite::New();
if (operation.empty())
{
result = inputTractogram->ExtractFiberSubset(input1);
}
else if (operation=="NOT")
{
pfc->setOperationType(mitk::PFCOMPOSITION_NOT_OPERATION);
pfc->addPlanarFigure(input1);
result = inputTractogram->ExtractFiberSubset(pfc);
}
else if (operation=="AND" && pf2.IsNotNull())
{
pfc->setOperationType(mitk::PFCOMPOSITION_AND_OPERATION);
pfc->addPlanarFigure(input1);
pfc->addPlanarFigure(input2);
result = inputTractogram->ExtractFiberSubset(pfc);
}
else if (operation=="OR" && pf2.IsNotNull())
{
pfc->setOperationType(mitk::PFCOMPOSITION_OR_OPERATION);
pfc->addPlanarFigure(input1);
pfc->addPlanarFigure(input2);
result = inputTractogram->ExtractFiberSubset(pfc);
}
else
{
- MITK_INFO << "Could not process input:";
- MITK_INFO << pf1_path;
- MITK_INFO << pf2_path;
- MITK_INFO << operation;
+ std::cout << "Could not process input:";
+ std::cout << pf1_path;
+ std::cout << pf2_path;
+ std::cout << operation;
}
}
else
{
ItkUcharImgType::Pointer itkMaskImage = ItkUcharImgType::New();
mitk::Image::Pointer mitkMaskImage = dynamic_cast<mitk::Image*>(mitk::IOUtil::LoadDataNode(pf1_path)->GetData());
mitk::CastToItkImage<ItkUcharImgType>(mitkMaskImage, itkMaskImage);
if (operation=="NOT")
result = inputTractogram->ExtractFiberSubset(itkMaskImage, true, true);
else
result = inputTractogram->ExtractFiberSubset(itkMaskImage, true, false);
}
if (result.IsNotNull())
mitk::IOUtil::SaveBaseData(result, outFib);
else
- MITK_INFO << "No valid fiber bundle extracted.";
+ std::cout << "No valid fiber bundle extracted.";
}
catch (itk::ExceptionObject e)
{
- MITK_INFO << e;
+ std::cout << e;
return EXIT_FAILURE;
}
catch (std::exception e)
{
- MITK_INFO << e.what();
+ std::cout << e.what();
return EXIT_FAILURE;
}
catch (...)
{
- MITK_INFO << "ERROR!?!";
+ std::cout << "ERROR!?!";
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
RegisterDiffusionMiniApp(FiberExtraction);
diff --git a/Modules/DiffusionImaging/MiniApps/FiberJoin.cpp b/Modules/DiffusionImaging/MiniApps/FiberJoin.cpp
index 2728b666e5..5e8dd0c7c3 100755
--- a/Modules/DiffusionImaging/MiniApps/FiberJoin.cpp
+++ b/Modules/DiffusionImaging/MiniApps/FiberJoin.cpp
@@ -1,89 +1,89 @@
/*===================================================================
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 "MiniAppManager.h"
#include <mitkBaseDataIOFactory.h>
#include <metaCommand.h>
#include "ctkCommandLineParser.h"
#include <usAny.h>
#include <mitkIOUtil.h>
#include <boost/lexical_cast.hpp>
#include <mitkCoreObjectFactory.h>
#include <mitkPlanarFigure.h>
#include <mitkPlanarFigureComposite.h>
#include <mitkFiberBundleX.h>
#define _USE_MATH_DEFINES
#include <math.h>
int FiberJoin(int argc, char* argv[])
{
- ctkCommandLineParser parser;
+ mitkCommandLineParser parser;
parser.setTitle("Fiber Join");
parser.setCategory("Fiber Tracking and Processing Methods");
parser.setContributor("MBI");
parser.setDescription("");
parser.setArgumentPrefix("--", "-");
- parser.addArgument("input", "i", ctkCommandLineParser::StringList, "Input:", "input tractograms (.fib, vtk file format)", us::Any(), false);
- parser.addArgument("out", "o", ctkCommandLineParser::String, "Output:", "output tractogram", us::Any(), false);
+ parser.addArgument("input", "i", mitkCommandLineParser::StringList, "Input:", "input tractograms (.fib, vtk file format)", us::Any(), false);
+ parser.addArgument("out", "o", mitkCommandLineParser::String, "Output:", "output tractogram", us::Any(), false);
map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
if (parsedArgs.size()==0)
return EXIT_FAILURE;
- ctkCommandLineParser::StringContainerType inFibs = us::any_cast<ctkCommandLineParser::StringContainerType>(parsedArgs["input"]);
+ mitkCommandLineParser::StringContainerType inFibs = us::any_cast<mitkCommandLineParser::StringContainerType>(parsedArgs["input"]);
string outFib = us::any_cast<string>(parsedArgs["out"]);
if (inFibs.size()<=1)
{
- MITK_INFO << "More than one input tractogram required!";
+ std::cout << "More than one input tractogram required!";
return EXIT_FAILURE;
}
try
{
mitk::FiberBundleX::Pointer result = dynamic_cast<mitk::FiberBundleX*>(mitk::IOUtil::LoadDataNode(inFibs.at(0))->GetData());
for (int i=1; i<inFibs.size(); i++)
{
try
{
mitk::FiberBundleX::Pointer inputTractogram = dynamic_cast<mitk::FiberBundleX*>(mitk::IOUtil::LoadDataNode(inFibs.at(i))->GetData());
result = result->AddBundle(inputTractogram);
}
- catch(...){ MITK_INFO << "could not load: " << inFibs.at(i); }
+ catch(...){ std::cout << "could not load: " << inFibs.at(i); }
}
mitk::IOUtil::SaveBaseData(result, outFib);
}
catch (itk::ExceptionObject e)
{
- MITK_INFO << e;
+ std::cout << e;
return EXIT_FAILURE;
}
catch (std::exception e)
{
- MITK_INFO << e.what();
+ std::cout << e.what();
return EXIT_FAILURE;
}
catch (...)
{
- MITK_INFO << "ERROR!?!";
+ std::cout << "ERROR!?!";
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
RegisterDiffusionMiniApp(FiberJoin);
diff --git a/Modules/DiffusionImaging/MiniApps/FiberProcessing.cpp b/Modules/DiffusionImaging/MiniApps/FiberProcessing.cpp
index 0b2ea4d085..4398eb26bf 100644
--- a/Modules/DiffusionImaging/MiniApps/FiberProcessing.cpp
+++ b/Modules/DiffusionImaging/MiniApps/FiberProcessing.cpp
@@ -1,210 +1,210 @@
/*===================================================================
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 "MiniAppManager.h"
#include <vector>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <string>
#include <itkImageFileWriter.h>
#include <itkMetaDataObject.h>
#include <itkVectorImage.h>
#include <mitkBaseDataIOFactory.h>
#include <mitkBaseData.h>
#include <mitkFiberBundleX.h>
#include "ctkCommandLineParser.h"
#include <boost/lexical_cast.hpp>
#include <mitkCoreObjectFactory.h>
#include <mitkIOUtil.h>
mitk::FiberBundleX::Pointer LoadFib(std::string filename)
{
const std::string s1="", s2="";
std::vector<mitk::BaseData::Pointer> fibInfile = mitk::BaseDataIO::LoadBaseDataFromFile( filename, s1, s2, false );
if( fibInfile.empty() )
- MITK_INFO << "File " << filename << " could not be read!";
+ std::cout << "File " << filename << " could not be read!";
mitk::BaseData::Pointer baseData = fibInfile.at(0);
return dynamic_cast<mitk::FiberBundleX*>(baseData.GetPointer());
}
int FiberProcessing(int argc, char* argv[])
{
- MITK_INFO << "FiberProcessing";
- ctkCommandLineParser parser;
+ std::cout << "FiberProcessing";
+ mitkCommandLineParser parser;
parser.setTitle("Fiber Processing");
parser.setCategory("Fiber Tracking and Processing Methods");
parser.setDescription("");
parser.setContributor("MBI");
parser.setArgumentPrefix("--", "-");
- parser.addArgument("input", "i", ctkCommandLineParser::InputFile, "Input:", "input fiber bundle (.fib)", us::Any(), false);
- parser.addArgument("outFile", "o", ctkCommandLineParser::OutputFile, "Output:", "output fiber bundle (.fib)", us::Any(), false);
+ parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input:", "input fiber bundle (.fib)", us::Any(), false);
+ parser.addArgument("outFile", "o", mitkCommandLineParser::OutputFile, "Output:", "output fiber bundle (.fib)", us::Any(), false);
- parser.addArgument("smooth", "s", ctkCommandLineParser::Float, "Spline resampling:", "Resample fiber using splines with the given point distance (in mm)");
- parser.addArgument("compress", "c", ctkCommandLineParser::Float, "Compress:", "Compress fiber using the given error threshold (in mm)");
- parser.addArgument("minLength", "l", ctkCommandLineParser::Float, "Minimum length:", "Minimum fiber length (in mm)");
- parser.addArgument("maxLength", "m", ctkCommandLineParser::Float, "Maximum length:", "Maximum fiber length (in mm)");
- parser.addArgument("minCurv", "a", ctkCommandLineParser::Float, "Minimum curvature radius:", "Minimum curvature radius (in mm)");
- parser.addArgument("mirror", "p", ctkCommandLineParser::Int, "Invert coordinates:", "Invert fiber coordinates XYZ (e.g. 010 to invert y-coordinate of each fiber point)");
+ parser.addArgument("smooth", "s", mitkCommandLineParser::Float, "Spline resampling:", "Resample fiber using splines with the given point distance (in mm)");
+ parser.addArgument("compress", "c", mitkCommandLineParser::Float, "Compress:", "Compress fiber using the given error threshold (in mm)");
+ parser.addArgument("minLength", "l", mitkCommandLineParser::Float, "Minimum length:", "Minimum fiber length (in mm)");
+ parser.addArgument("maxLength", "m", mitkCommandLineParser::Float, "Maximum length:", "Maximum fiber length (in mm)");
+ parser.addArgument("minCurv", "a", mitkCommandLineParser::Float, "Minimum curvature radius:", "Minimum curvature radius (in mm)");
+ parser.addArgument("mirror", "p", mitkCommandLineParser::Int, "Invert coordinates:", "Invert fiber coordinates XYZ (e.g. 010 to invert y-coordinate of each fiber point)");
- parser.addArgument("rotate-x", "rx", ctkCommandLineParser::Float, "Rotate x-axis:", "Rotate around x-axis (if copy is given the copy is rotated, in deg)");
- parser.addArgument("rotate-y", "ry", ctkCommandLineParser::Float, "Rotate y-axis:", "Rotate around y-axis (if copy is given the copy is rotated, in deg)");
- parser.addArgument("rotate-z", "rz", ctkCommandLineParser::Float, "Rotate z-axis:", "Rotate around z-axis (if copy is given the copy is rotated, in deg)");
+ parser.addArgument("rotate-x", "rx", mitkCommandLineParser::Float, "Rotate x-axis:", "Rotate around x-axis (if copy is given the copy is rotated, in deg)");
+ parser.addArgument("rotate-y", "ry", mitkCommandLineParser::Float, "Rotate y-axis:", "Rotate around y-axis (if copy is given the copy is rotated, in deg)");
+ parser.addArgument("rotate-z", "rz", mitkCommandLineParser::Float, "Rotate z-axis:", "Rotate around z-axis (if copy is given the copy is rotated, in deg)");
- parser.addArgument("scale-x", "sx", ctkCommandLineParser::Float, "Scale x-axis:", "Scale in direction of x-axis (if copy is given the copy is scaled)");
- parser.addArgument("scale-y", "sy", ctkCommandLineParser::Float, "Scale y-axis:", "Scale in direction of y-axis (if copy is given the copy is scaled)");
- parser.addArgument("scale-z", "sz", ctkCommandLineParser::Float, "Scale z-axis", "Scale in direction of z-axis (if copy is given the copy is scaled)");
+ parser.addArgument("scale-x", "sx", mitkCommandLineParser::Float, "Scale x-axis:", "Scale in direction of x-axis (if copy is given the copy is scaled)");
+ parser.addArgument("scale-y", "sy", mitkCommandLineParser::Float, "Scale y-axis:", "Scale in direction of y-axis (if copy is given the copy is scaled)");
+ parser.addArgument("scale-z", "sz", mitkCommandLineParser::Float, "Scale z-axis", "Scale in direction of z-axis (if copy is given the copy is scaled)");
- parser.addArgument("translate-x", "tx", ctkCommandLineParser::Float, "Translate x-axis:", "Translate in direction of x-axis (if copy is given the copy is translated, in mm)");
- parser.addArgument("translate-y", "ty", ctkCommandLineParser::Float, "Translate y-axis:", "Translate in direction of y-axis (if copy is given the copy is translated, in mm)");
- parser.addArgument("translate-z", "tz", ctkCommandLineParser::Float, "Translate z-axis:", "Translate in direction of z-axis (if copy is given the copy is translated, in mm)");
+ parser.addArgument("translate-x", "tx", mitkCommandLineParser::Float, "Translate x-axis:", "Translate in direction of x-axis (if copy is given the copy is translated, in mm)");
+ parser.addArgument("translate-y", "ty", mitkCommandLineParser::Float, "Translate y-axis:", "Translate in direction of y-axis (if copy is given the copy is translated, in mm)");
+ parser.addArgument("translate-z", "tz", mitkCommandLineParser::Float, "Translate z-axis:", "Translate in direction of z-axis (if copy is given the copy is translated, in mm)");
map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
if (parsedArgs.size()==0)
return EXIT_FAILURE;
float smoothDist = -1;
if (parsedArgs.count("smooth"))
smoothDist = us::any_cast<float>(parsedArgs["smooth"]);
float compress = -1;
if (parsedArgs.count("compress"))
compress = us::any_cast<float>(parsedArgs["compress"]);
float minFiberLength = -1;
if (parsedArgs.count("minLength"))
minFiberLength = us::any_cast<float>(parsedArgs["minLength"]);
float maxFiberLength = -1;
if (parsedArgs.count("maxLength"))
maxFiberLength = us::any_cast<float>(parsedArgs["maxLength"]);
float curvThres = -1;
if (parsedArgs.count("minCurv"))
curvThres = us::any_cast<float>(parsedArgs["minCurv"]);
int axis = 0;
if (parsedArgs.count("mirror"))
axis = us::any_cast<int>(parsedArgs["mirror"]);
float rotateX = 0;
if (parsedArgs.count("rotate-x"))
rotateX = us::any_cast<float>(parsedArgs["rotate-x"]);
float rotateY = 0;
if (parsedArgs.count("rotate-y"))
rotateY = us::any_cast<float>(parsedArgs["rotate-y"]);
float rotateZ = 0;
if (parsedArgs.count("rotate-z"))
rotateZ = us::any_cast<float>(parsedArgs["rotate-z"]);
float scaleX = 0;
if (parsedArgs.count("scale-x"))
scaleX = us::any_cast<float>(parsedArgs["scale-x"]);
float scaleY = 0;
if (parsedArgs.count("scale-y"))
scaleY = us::any_cast<float>(parsedArgs["scale-y"]);
float scaleZ = 0;
if (parsedArgs.count("scale-z"))
scaleZ = us::any_cast<float>(parsedArgs["scale-z"]);
float translateX = 0;
if (parsedArgs.count("translate-x"))
translateX = us::any_cast<float>(parsedArgs["translate-x"]);
float translateY = 0;
if (parsedArgs.count("translate-y"))
translateY = us::any_cast<float>(parsedArgs["translate-y"]);
float translateZ = 0;
if (parsedArgs.count("translate-z"))
translateZ = us::any_cast<float>(parsedArgs["translate-z"]);
string inFileName = us::any_cast<string>(parsedArgs["input"]);
string outFileName = us::any_cast<string>(parsedArgs["outFile"]);
try
{
mitk::FiberBundleX::Pointer fib = LoadFib(inFileName);
if (minFiberLength>0)
fib->RemoveShortFibers(minFiberLength);
if (maxFiberLength>0)
fib->RemoveLongFibers(maxFiberLength);
if (curvThres>0)
fib->ApplyCurvatureThreshold(curvThres, false);
if (smoothDist>0)
fib->ResampleSpline(smoothDist);
if (compress>0)
fib->Compress(compress);
if (axis/100==1)
fib->MirrorFibers(0);
if ((axis%100)/10==1)
fib->MirrorFibers(1);
if (axis%10==1)
fib->MirrorFibers(2);
if (rotateX > 0 || rotateY > 0 || rotateZ > 0){
- MITK_INFO << "Rotate " << rotateX << " " << rotateY << " " << rotateZ;
+ std::cout << "Rotate " << rotateX << " " << rotateY << " " << rotateZ;
fib->RotateAroundAxis(rotateX, rotateY, rotateZ);
}
if (translateX > 0 || translateY > 0 || translateZ > 0){
fib->TranslateFibers(translateX, translateY, translateZ);
}
if (scaleX > 0 || scaleY > 0 || scaleZ > 0)
fib->ScaleFibers(scaleX, scaleY, scaleZ);
mitk::IOUtil::SaveBaseData(fib.GetPointer(), outFileName );
}
catch (itk::ExceptionObject e)
{
- MITK_INFO << e;
+ std::cout << e;
return EXIT_FAILURE;
}
catch (std::exception e)
{
- MITK_INFO << e.what();
+ std::cout << e.what();
return EXIT_FAILURE;
}
catch (...)
{
- MITK_INFO << "ERROR!?!";
+ std::cout << "ERROR!?!";
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
RegisterDiffusionMiniApp(FiberProcessing);
diff --git a/Modules/DiffusionImaging/MiniApps/Fiberfox.cpp b/Modules/DiffusionImaging/MiniApps/Fiberfox.cpp
index 53d3d478ee..e767f81004 100755
--- a/Modules/DiffusionImaging/MiniApps/Fiberfox.cpp
+++ b/Modules/DiffusionImaging/MiniApps/Fiberfox.cpp
@@ -1,81 +1,78 @@
/*===================================================================
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 "MiniAppManager.h"
#include <mitkImageCast.h>
#include <mitkDiffusionImage.h>
#include <mitkBaseDataIOFactory.h>
#include <mitkIOUtil.h>
#include <mitkFiberBundleX.h>
#include <mitkFiberfoxParameters.h>
-#include "ctkCommandLineParser.h"
+#include "mitkCommandLineParser.h"
#include <itkAddArtifactsToDwiImageFilter.h>
#include <itkTractsToDWIImageFilter.h>
#include "boost/property_tree/ptree.hpp"
#include "boost/property_tree/xml_parser.hpp"
#include "boost/foreach.hpp"
/** TODO: Proritype signal komplett speichern oder bild mit speichern. */
/** TODO: Tarball aus images und parametern? */
/** TODO: Artefakte auf bild in miniapp */
-namespace mitk
-{
-int Fiberfox(int argc, char* argv[])
+using namespace mitk;
+
+int main(int argc, char* argv[])
{
- MITK_INFO << "Fiberfox";
- ctkCommandLineParser parser;
+ mitkCommandLineParser parser;
parser.setArgumentPrefix("--", "-");
- parser.addArgument("out", "o", ctkCommandLineParser::OutputFile, "Output root:", "output root", us::Any(), false);
- parser.addArgument("parameters", "p", ctkCommandLineParser::InputFile, "Parameter file:", "fiberfox parameter file", us::Any(), false);
- parser.addArgument("fiberbundle", "f", ctkCommandLineParser::String, "Fiberbundle:", "", us::Any(), false);
+ parser.addArgument("out", "o", mitkCommandLineParser::OutputFile, "Output root:", "output root", us::Any(), false);
+ parser.addArgument("parameters", "p", mitkCommandLineParser::InputFile, "Parameter file:", "fiberfox parameter file", us::Any(), false);
+ parser.addArgument("fiberbundle", "f", mitkCommandLineParser::String, "Fiberbundle:", "", us::Any(), false);
map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
if (parsedArgs.size()==0)
return EXIT_FAILURE;
string outName = us::any_cast<string>(parsedArgs["out"]);
string paramName = us::any_cast<string>(parsedArgs["parameters"]);
string fibFile = "";
if (parsedArgs.count("fiberbundle"))
fibFile = us::any_cast<string>(parsedArgs["fiberbundle"]);
{
FiberfoxParameters<double> parameters;
parameters.LoadParameters(paramName);
mitk::FiberBundleX::Pointer inputTractogram = dynamic_cast<mitk::FiberBundleX*>(mitk::IOUtil::LoadDataNode(fibFile)->GetData());
itk::TractsToDWIImageFilter< short >::Pointer tractsToDwiFilter = itk::TractsToDWIImageFilter< short >::New();
tractsToDwiFilter->SetParameters(parameters);
tractsToDwiFilter->SetFiberBundle(inputTractogram);
tractsToDwiFilter->Update();
DiffusionImage<short>::Pointer image = DiffusionImage<short>::New();
image->SetVectorImage( tractsToDwiFilter->GetOutput() );
image->SetReferenceBValue( parameters.m_SignalGen.m_Bvalue );
image->SetDirections( parameters.m_SignalGen.GetGradientDirections() );
image->InitializeFromVectorImage();
mitk::IOUtil::Save(image, outName.c_str());
}
return EXIT_SUCCESS;
}
-}
-RegisterDiffusionMiniApp(Fiberfox);
+
diff --git a/Modules/DiffusionImaging/MiniApps/GibbsTracking.cpp b/Modules/DiffusionImaging/MiniApps/GibbsTracking.cpp
index e5a222818c..21f316dd0d 100755
--- a/Modules/DiffusionImaging/MiniApps/GibbsTracking.cpp
+++ b/Modules/DiffusionImaging/MiniApps/GibbsTracking.cpp
@@ -1,245 +1,242 @@
/*===================================================================
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 "MiniAppManager.h"
-
#include <mitkImageCast.h>
#include <mitkQBallImage.h>
#include <mitkTensorImage.h>
#include <mitkBaseDataIOFactory.h>
#include <mitkFiberBundleX.h>
#include <itkGibbsTrackingFilter.h>
#include <itkDiffusionTensor3D.h>
#include <itkShCoefficientImageImporter.h>
#include <mitkImageToItk.h>
#include <mitkIOUtil.h>
-#include "ctkCommandLineParser.h"
+#include "mitkCommandLineParser.h"
#include <boost/algorithm/string.hpp>
#include <itkFlipImageFilter.h>
#include <mitkCoreObjectFactory.h>
template<int shOrder>
typename itk::ShCoefficientImageImporter< float, shOrder >::QballImageType::Pointer TemplatedConvertShCoeffs(mitk::Image* mitkImg, int toolkit, bool noFlip = false)
{
typedef itk::ShCoefficientImageImporter< float, shOrder > FilterType;
typedef mitk::ImageToItk< itk::Image< float, 4 > > CasterType;
CasterType::Pointer caster = CasterType::New();
caster->SetInput(mitkImg);
caster->Update();
itk::Image< float, 4 >::Pointer itkImage = caster->GetOutput();
typename FilterType::Pointer filter = FilterType::New();
if (noFlip)
{
filter->SetInputImage(itkImage);
}
else
{
- MITK_INFO << "Flipping image";
+ std::cout << "Flipping image";
itk::FixedArray<bool, 4> flipAxes;
flipAxes[0] = true;
flipAxes[1] = true;
flipAxes[2] = false;
flipAxes[3] = false;
itk::FlipImageFilter< itk::Image< float, 4 > >::Pointer flipper = itk::FlipImageFilter< itk::Image< float, 4 > >::New();
flipper->SetInput(itkImage);
flipper->SetFlipAxes(flipAxes);
flipper->Update();
itk::Image< float, 4 >::Pointer flipped = flipper->GetOutput();
itk::Matrix< double,4,4 > m = itkImage->GetDirection(); m[0][0] *= -1; m[1][1] *= -1;
flipped->SetDirection(m);
itk::Point< float, 4 > o = itkImage->GetOrigin();
o[0] -= (flipped->GetLargestPossibleRegion().GetSize(0)-1);
o[1] -= (flipped->GetLargestPossibleRegion().GetSize(1)-1);
flipped->SetOrigin(o);
filter->SetInputImage(flipped);
}
switch (toolkit)
{
case 0:
filter->SetToolkit(FilterType::FSL);
break;
case 1:
filter->SetToolkit(FilterType::MRTRIX);
break;
default:
filter->SetToolkit(FilterType::FSL);
}
filter->GenerateData();
return filter->GetQballImage();
}
-int GibbsTracking(int argc, char* argv[])
+int main(int argc, char* argv[])
{
- MITK_INFO << "GibbsTracking";
- ctkCommandLineParser parser;
+ std::cout << "GibbsTracking";
+ mitkCommandLineParser parser;
parser.setTitle("Gibbs Tracking");
parser.setCategory("Fiber Tracking and Processing Methods");
parser.setDescription("");
parser.setContributor("MBI");
parser.setArgumentPrefix("--", "-");
- parser.addArgument("input", "i", ctkCommandLineParser::InputFile, "Input:", "input image (tensor, Q-ball or FSL/MRTrix SH-coefficient image)", us::Any(), false);
- parser.addArgument("parameters", "p", ctkCommandLineParser::InputFile, "Parameters:", "parameter file (.gtp)", us::Any(), false);
- parser.addArgument("mask", "m", ctkCommandLineParser::InputFile, "Mask:", "binary mask image");
- parser.addArgument("shConvention", "s", ctkCommandLineParser::String, "SH coefficient:", "sh coefficient convention (FSL, MRtrix)", string("FSL"), true);
- parser.addArgument("outFile", "o", ctkCommandLineParser::OutputFile, "Output:", "output fiber bundle (.fib)", us::Any(), false);
- parser.addArgument("noFlip", "f", ctkCommandLineParser::Bool, "No flip:", "do not flip input image to match MITK coordinate convention");
+ parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input:", "input image (tensor, Q-ball or FSL/MRTrix SH-coefficient image)", us::Any(), false);
+ parser.addArgument("parameters", "p", mitkCommandLineParser::InputFile, "Parameters:", "parameter file (.gtp)", us::Any(), false);
+ parser.addArgument("mask", "m", mitkCommandLineParser::InputFile, "Mask:", "binary mask image");
+ parser.addArgument("shConvention", "s", mitkCommandLineParser::String, "SH coefficient:", "sh coefficient convention (FSL, MRtrix)", string("FSL"), true);
+ parser.addArgument("outFile", "o", mitkCommandLineParser::OutputFile, "Output:", "output fiber bundle (.fib)", us::Any(), false);
+ parser.addArgument("noFlip", "f", mitkCommandLineParser::Bool, "No flip:", "do not flip input image to match MITK coordinate convention");
map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
if (parsedArgs.size()==0)
return EXIT_FAILURE;
string inFileName = us::any_cast<string>(parsedArgs["input"]);
string paramFileName = us::any_cast<string>(parsedArgs["parameters"]);
string outFileName = us::any_cast<string>(parsedArgs["outFile"]);
bool noFlip = false;
if (parsedArgs.count("noFlip"))
noFlip = us::any_cast<bool>(parsedArgs["noFlip"]);
try
{
// instantiate gibbs tracker
typedef itk::Vector<float, QBALL_ODFSIZE> OdfVectorType;
typedef itk::Image<OdfVectorType,3> ItkQballImageType;
typedef itk::GibbsTrackingFilter<ItkQballImageType> GibbsTrackingFilterType;
GibbsTrackingFilterType::Pointer gibbsTracker = GibbsTrackingFilterType::New();
// load input image
const std::string s1="", s2="";
std::vector<mitk::BaseData::Pointer> infile = mitk::BaseDataIO::LoadBaseDataFromFile( inFileName, s1, s2, false );
mitk::Image::Pointer mitkImage = dynamic_cast<mitk::Image*>(infile.at(0).GetPointer());
// try to cast to qball image
if( boost::algorithm::ends_with(inFileName, ".qbi") )
{
- MITK_INFO << "Loading qball image ...";
+ std::cout << "Loading qball image ...";
mitk::QBallImage::Pointer mitkQballImage = dynamic_cast<mitk::QBallImage*>(infile.at(0).GetPointer());
ItkQballImageType::Pointer itk_qbi = ItkQballImageType::New();
mitk::CastToItkImage(mitkQballImage, itk_qbi);
gibbsTracker->SetQBallImage(itk_qbi.GetPointer());
}
else if( boost::algorithm::ends_with(inFileName, ".dti") )
{
- MITK_INFO << "Loading tensor image ...";
+ std::cout << "Loading tensor image ...";
typedef itk::Image< itk::DiffusionTensor3D<float>, 3 > ItkTensorImage;
mitk::TensorImage::Pointer mitkTensorImage = dynamic_cast<mitk::TensorImage*>(infile.at(0).GetPointer());
ItkTensorImage::Pointer itk_dti = ItkTensorImage::New();
mitk::CastToItkImage(mitkTensorImage, itk_dti);
gibbsTracker->SetTensorImage(itk_dti);
}
else if ( boost::algorithm::ends_with(inFileName, ".nii") )
{
- MITK_INFO << "Loading sh-coefficient image ...";
+ std::cout << "Loading sh-coefficient image ...";
int nrCoeffs = mitkImage->GetLargestPossibleRegion().GetSize()[3];
int c=3, d=2-2*nrCoeffs;
double D = c*c-4*d;
int shOrder;
if (D>0)
{
shOrder = (-c+sqrt(D))/2.0;
if (shOrder<0)
shOrder = (-c-sqrt(D))/2.0;
}
else if (D==0)
shOrder = -c/2.0;
- MITK_INFO << "using SH-order " << shOrder;
+ std::cout << "using SH-order " << shOrder;
int toolkitConvention = 0;
if (parsedArgs.count("shConvention"))
{
string convention = us::any_cast<string>(parsedArgs["shConvention"]).c_str();
if ( boost::algorithm::equals(convention, "MRtrix") )
{
toolkitConvention = 1;
- MITK_INFO << "Using MRtrix style sh-coefficient convention";
+ std::cout << "Using MRtrix style sh-coefficient convention";
}
else
- MITK_INFO << "Using FSL style sh-coefficient convention";
+ std::cout << "Using FSL style sh-coefficient convention";
}
else
- MITK_INFO << "Using FSL style sh-coefficient convention";
+ std::cout << "Using FSL style sh-coefficient convention";
switch (shOrder)
{
case 4:
gibbsTracker->SetQBallImage(TemplatedConvertShCoeffs<4>(mitkImage, toolkitConvention, noFlip));
break;
case 6:
gibbsTracker->SetQBallImage(TemplatedConvertShCoeffs<6>(mitkImage, toolkitConvention, noFlip));
break;
case 8:
gibbsTracker->SetQBallImage(TemplatedConvertShCoeffs<8>(mitkImage, toolkitConvention, noFlip));
break;
case 10:
gibbsTracker->SetQBallImage(TemplatedConvertShCoeffs<10>(mitkImage, toolkitConvention, noFlip));
break;
case 12:
gibbsTracker->SetQBallImage(TemplatedConvertShCoeffs<12>(mitkImage, toolkitConvention, noFlip));
break;
default:
- MITK_INFO << "SH-order " << shOrder << " not supported";
+ std::cout << "SH-order " << shOrder << " not supported";
}
}
else
return EXIT_FAILURE;
// global tracking
if (parsedArgs.count("mask"))
{
typedef itk::Image<float,3> MaskImgType;
mitk::Image::Pointer mitkMaskImage = mitk::IOUtil::LoadImage(us::any_cast<string>(parsedArgs["mask"]));
MaskImgType::Pointer itk_mask = MaskImgType::New();
mitk::CastToItkImage(mitkMaskImage, itk_mask);
gibbsTracker->SetMaskImage(itk_mask);
}
gibbsTracker->SetDuplicateImage(false);
gibbsTracker->SetLoadParameterFile( paramFileName );
// gibbsTracker->SetLutPath( "" );
gibbsTracker->Update();
mitk::FiberBundleX::Pointer mitkFiberBundle = mitk::FiberBundleX::New(gibbsTracker->GetFiberBundle());
mitkFiberBundle->SetReferenceGeometry(mitkImage->GetGeometry());
mitk::IOUtil::SaveBaseData(mitkFiberBundle.GetPointer(), outFileName );
}
catch (itk::ExceptionObject e)
{
- MITK_INFO << e;
+ std::cout << e;
return EXIT_FAILURE;
}
catch (std::exception e)
{
- MITK_INFO << e.what();
+ std::cout << e.what();
return EXIT_FAILURE;
}
catch (...)
{
- MITK_INFO << "ERROR!?!";
+ std::cout << "ERROR!?!";
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
-RegisterDiffusionMiniApp(GibbsTracking);
diff --git a/Modules/DiffusionImaging/MiniApps/ImageResampler.cpp b/Modules/DiffusionImaging/MiniApps/ImageResampler.cpp
index cf30617938..faff7c6965 100644
--- a/Modules/DiffusionImaging/MiniApps/ImageResampler.cpp
+++ b/Modules/DiffusionImaging/MiniApps/ImageResampler.cpp
@@ -1,337 +1,326 @@
/*===================================================================
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 "MiniAppManager.h"
-// CTK
-#include "ctkCommandLineParser.h"
+#include "mitkCommandLineParser.h"
#include <mitkIOUtil.h>
#include <mitkRegistrationWrapper.h>
#include <mitkImage.h>
#include <mitkImageCast.h>
#include <mitkITKImageImport.h>
#include <mitkDiffusionImage.h>
#include <mitkImageTimeSelector.h>
// ITK
#include <itksys/SystemTools.hxx>
#include <itkDirectory.h>
#include "itkLinearInterpolateImageFunction.h"
#include "itkWindowedSincInterpolateImageFunction.h"
#include "itkIdentityTransform.h"
#include "itkResampleImageFilter.h"
#include "itkResampleDwiImageFilter.h"
typedef itk::Image<double, 3> InputImageType;
typedef mitk::DiffusionImage<short> DiffusionImageType;
static mitk::Image::Pointer TransformToReference(mitk::Image *reference, mitk::Image *moving, bool sincInterpol = false)
{
// Convert to itk Images
InputImageType::Pointer itkReference = InputImageType::New();
InputImageType::Pointer itkMoving = InputImageType::New();
mitk::CastToItkImage(reference,itkReference);
mitk::CastToItkImage(moving,itkMoving);
// Identify Transform
typedef itk::IdentityTransform<double, 3> T_Transform;
T_Transform::Pointer _pTransform = T_Transform::New();
_pTransform->SetIdentity();
typedef itk::WindowedSincInterpolateImageFunction< InputImageType, 3> WindowedSincInterpolatorType;
WindowedSincInterpolatorType::Pointer sinc_interpolator = WindowedSincInterpolatorType::New();
typedef itk::ResampleImageFilter<InputImageType, InputImageType> ResampleFilterType;
ResampleFilterType::Pointer resampler = ResampleFilterType::New();
resampler->SetInput(itkMoving);
resampler->SetReferenceImage( itkReference );
resampler->UseReferenceImageOn();
resampler->SetTransform(_pTransform);
resampler->SetInterpolator(sinc_interpolator);
resampler->Update();
// Convert back to mitk
mitk::Image::Pointer result = mitk::Image::New();
result->InitializeByItk(resampler->GetOutput());
GrabItkImageMemory( resampler->GetOutput() , result );
return result;
}
static std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems)
{
std::stringstream ss(s);
std::string item;
while (std::getline(ss, item, delim))
{
elems.push_back(item);
}
return elems;
}
static std::vector<std::string> split(const std::string &s, char delim)
{
std::vector < std::string > elems;
return split(s, delim, elems);
}
static mitk::Image::Pointer ResampleBySpacing(mitk::Image *input, float *spacing, bool useLinInt = true)
{
InputImageType::Pointer itkImage = InputImageType::New();
CastToItkImage(input,itkImage);
/**
* 1) Resampling
*
*/
// Identity transform.
// We don't want any transform on our image except rescaling which is not
// specified by a transform but by the input/output spacing as we will see
// later.
// So no transform will be specified.
typedef itk::IdentityTransform<double, 3> T_Transform;
// The resampler type itself.
typedef itk::ResampleImageFilter<InputImageType, InputImageType> T_ResampleFilter;
// Prepare the resampler.
// Instantiate the transform and specify it should be the id transform.
T_Transform::Pointer _pTransform = T_Transform::New();
_pTransform->SetIdentity();
// Instantiate the resampler. Wire in the transform and the interpolator.
T_ResampleFilter::Pointer _pResizeFilter = T_ResampleFilter::New();
// Specify the input.
_pResizeFilter->SetInput(itkImage);
_pResizeFilter->SetTransform(_pTransform);
// Set the output origin.
_pResizeFilter->SetOutputOrigin(itkImage->GetOrigin());
// Compute the size of the output.
// The size (# of pixels) in the output is recomputed using
// the ratio of the input and output sizes.
InputImageType::SpacingType inputSpacing = itkImage->GetSpacing();
InputImageType::SpacingType outputSpacing;
const InputImageType::RegionType& inputSize = itkImage->GetLargestPossibleRegion();
InputImageType::SizeType outputSize;
typedef InputImageType::SizeType::SizeValueType SizeValueType;
// Set the output spacing.
outputSpacing[0] = spacing[0];
outputSpacing[1] = spacing[1];
outputSpacing[2] = spacing[2];
outputSize[0] = static_cast<SizeValueType>(inputSize.GetSize()[0] * inputSpacing[0] / outputSpacing[0] + .5);
outputSize[1] = static_cast<SizeValueType>(inputSize.GetSize()[1] * inputSpacing[1] / outputSpacing[1] + .5);
outputSize[2] = static_cast<SizeValueType>(inputSize.GetSize()[2] * inputSpacing[2] / outputSpacing[2] + .5);
_pResizeFilter->SetOutputSpacing(outputSpacing);
_pResizeFilter->SetSize(outputSize);
typedef itk::LinearInterpolateImageFunction< InputImageType > LinearInterpolatorType;
LinearInterpolatorType::Pointer lin_interpolator = LinearInterpolatorType::New();
typedef itk::WindowedSincInterpolateImageFunction< InputImageType, 4> WindowedSincInterpolatorType;
WindowedSincInterpolatorType::Pointer sinc_interpolator = WindowedSincInterpolatorType::New();
if (useLinInt)
_pResizeFilter->SetInterpolator(lin_interpolator);
else
_pResizeFilter->SetInterpolator(sinc_interpolator);
_pResizeFilter->Update();
mitk::Image::Pointer image = mitk::Image::New();
image->InitializeByItk(_pResizeFilter->GetOutput());
mitk::GrabItkImageMemory( _pResizeFilter->GetOutput(), image);
return image;
}
/// Save images according to file type
static void SaveImage(std::string fileName, mitk::Image* image, std::string fileType )
{
- MITK_INFO << "----Save to " << fileName;
+ std::cout << "----Save to " << fileName;
if (fileType == "dwi") // IOUtil does not handle dwi files properly Bug 15772
{
try
{
mitk::IOUtil::Save(dynamic_cast<mitk::DiffusionImage<short>*>(image), fileName.c_str());
}
catch( const itk::ExceptionObject& e)
{
MITK_ERROR << "Caught exception: " << e.what();
mitkThrow() << "Failed with exception from subprocess!";
}
}
else
{
mitk::IOUtil::SaveImage(image, fileName);
}
}
DiffusionImageType::Pointer ResampleDWIbySpacing(DiffusionImageType::Pointer input, float* spacing, bool useLinInt = true)
{
itk::Vector<double, 3> spacingVector;
spacingVector[0] = spacing[0];
spacingVector[1] = spacing[1];
spacingVector[2] = spacing[2];
typedef itk::ResampleDwiImageFilter<short> ResampleFilterType;
ResampleFilterType::Pointer resampler = ResampleFilterType::New();
resampler->SetInput(input->GetVectorImage());
resampler->SetInterpolation(ResampleFilterType::Interpolate_Linear);
resampler->SetNewSpacing(spacingVector);
resampler->Update();
DiffusionImageType::Pointer output = DiffusionImageType::New();
output->SetVectorImage(resampler->GetOutput());
output->SetDirections(input->GetDirections());
output->SetReferenceBValue(input->GetReferenceBValue());
output->InitializeFromVectorImage();
return output;
}
-int ImageResampler( int argc, char* argv[] )
+int main( int argc, char* argv[] )
{
- ctkCommandLineParser parser;
+ mitkCommandLineParser parser;
parser.setArgumentPrefix("--","-");
parser.setTitle("Image Resampler");
parser.setCategory("Preprocessing Tools");
parser.setContributor("MBI");
- parser.setDescription("");
+ parser.setDescription("Resample an image to eigther a specific spacing or to a reference image.");
// Add command line argument names
- parser.addArgument("help", "h",ctkCommandLineParser::Bool, "Show this help text");
- parser.addArgument("input", "i", ctkCommandLineParser::String, "Input:", "Input file",us::Any(),false);
- parser.addArgument("output", "o", ctkCommandLineParser::String, "Output:", "Output folder (ending with /)",us::Any(),false);
- parser.addArgument("spacing", "s", ctkCommandLineParser::String, "Spacing:", "Resample provide x,y,z spacing in mm (e.g. -r 1,1,3), is not applied to tensor data",us::Any());
- parser.addArgument("reference", "r", ctkCommandLineParser::String, "Reference:", "Resample using supplied reference image. Also cuts image to same dimensions");
- parser.addArgument("sinc-int", "s", ctkCommandLineParser::Bool, "Windowed-sinc interpolation:", "Use windowed-sinc interpolation (3) instead of linear interpolation ",us::Any());
+ parser.addArgument("help", "h",mitkCommandLineParser::Bool, "Show this help text");
+ parser.addArgument("input", "i", mitkCommandLineParser::InputImage, "Input:", "Input file",us::Any(),false);
+ parser.addArgument("output", "o", mitkCommandLineParser::OutputDirectory, "Output:", "Output folder (ending with /)",us::Any(),false);
+ parser.addArgument("spacing", "s", mitkCommandLineParser::String, "Spacing:", "Resample provide x,y,z spacing in mm (e.g. -r 1,1,3), is not applied to tensor data",us::Any());
+ parser.addArgument("reference", "r", mitkCommandLineParser::String, "Reference:", "Resample using supplied reference image. Also cuts image to same dimensions",us::Any());
+ parser.addArgument("win-sinc", "w", mitkCommandLineParser::Bool, "Windowed-sinc interpolation:", "Use windowed-sinc interpolation (3) instead of linear interpolation ",us::Any());
map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
// Handle special arguments
bool useSpacing = false;
bool useLinearInterpol = true;
{
if (parsedArgs.size() == 0)
{
- MITK_ERROR << "Missig arguements" ;
return EXIT_FAILURE;
}
- if (parsedArgs.count("xml"))
- {
- MITK_ERROR << "This is to be handled by shell script";
- return EXIT_SUCCESS;
- }
-
if (parsedArgs.count("sinc-int"))
useLinearInterpol = false;
// Show a help message
if ( parsedArgs.count("help") || parsedArgs.count("h"))
{
std::cout << parser.helpText();
return EXIT_SUCCESS;
}
}
std::string outputPath = us::any_cast<string>(parsedArgs["output"]);
std::string inputFile = us::any_cast<string>(parsedArgs["input"]);
std::vector<std::string> spacings;
float spacing[3];
if (parsedArgs.count("spacing"))
{
std::string arg = us::any_cast<string>(parsedArgs["spacing"]);
spacings = split(arg ,',');
spacing[0] = atoi(spacings.at(0).c_str());
spacing[1] = atoi(spacings.at(1).c_str());
spacing[2] = atoi(spacings.at(2).c_str());
useSpacing = true;
}
std::string refImageFile = "";
if (parsedArgs.count("reference"))
{
refImageFile = us::any_cast<string>(parsedArgs["reference"]);
}
if (refImageFile =="" && useSpacing == false)
{
MITK_ERROR << "No information how to resample is supplied. Use eigther --spacing or --reference !";
return EXIT_FAILURE;
}
mitk::Image::Pointer refImage;
if (!useSpacing)
refImage = mitk::IOUtil::LoadImage(refImageFile);
DiffusionImageType::Pointer inputDWI = dynamic_cast<DiffusionImageType*>(mitk::IOUtil::LoadBaseData(inputFile).GetPointer());
if (inputDWI.IsNotNull())
{
DiffusionImageType::Pointer outputImage;
if (useSpacing)
outputImage = ResampleDWIbySpacing(inputDWI, spacing);
else
{
MITK_WARN << "Not supported yet, to resample a DWI please set a new spacing.";
return EXIT_FAILURE;
}
std::string fileStem = itksys::SystemTools::GetFilenameWithoutExtension(inputFile);
std::string outName(outputPath + fileStem + "_res.dwi");
mitk::IOUtil::Save(outputImage, outName.c_str());
return EXIT_SUCCESS;
}
mitk::Image::Pointer inputImage = mitk::IOUtil::LoadImage(inputFile);
mitk::Image::Pointer resultImage;
if (useSpacing)
resultImage = ResampleBySpacing(inputImage,spacing);
else
resultImage = TransformToReference(refImage,inputImage);
std::string fileStem = itksys::SystemTools::GetFilenameWithoutExtension(inputFile);
mitk::IOUtil::SaveImage(resultImage, outputPath + fileStem + "_res.nrrd");
return EXIT_SUCCESS;
}
-
-RegisterDiffusionMiniApp(ImageResampler);
diff --git a/Modules/DiffusionImaging/MiniApps/LocalDirectionalFiberPlausibility.cpp b/Modules/DiffusionImaging/MiniApps/LocalDirectionalFiberPlausibility.cpp
index ff292b4feb..c73052c411 100755
--- a/Modules/DiffusionImaging/MiniApps/LocalDirectionalFiberPlausibility.cpp
+++ b/Modules/DiffusionImaging/MiniApps/LocalDirectionalFiberPlausibility.cpp
@@ -1,304 +1,302 @@
/*===================================================================
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 "MiniAppManager.h"
#include <mitkBaseDataIOFactory.h>
#include <mitkBaseData.h>
#include <mitkImageCast.h>
#include <mitkImageToItk.h>
#include <itkEvaluateDirectionImagesFilter.h>
#include <metaCommand.h>
-#include "ctkCommandLineParser.h"
+#include "mitkCommandLineParser.h"
#include <itkTractsToVectorImageFilter.h>
#include <usAny.h>
#include <itkImageFileWriter.h>
#include <mitkIOUtil.h>
#include <boost/lexical_cast.hpp>
#include <iostream>
#include <fstream>
#include <itksys/SystemTools.hxx>
#include <mitkCoreObjectFactory.h>
#define _USE_MATH_DEFINES
#include <math.h>
-int LocalDirectionalFiberPlausibility(int argc, char* argv[])
+int main(int argc, char* argv[])
{
- MITK_INFO << "LocalDirectionalFiberPlausibility";
- ctkCommandLineParser parser;
+ std::cout << "LocalDirectionalFiberPlausibility";
+ mitkCommandLineParser parser;
parser.setTitle("Local Directional Fiber Plausibility");
parser.setCategory("Fiber Tracking and Processing Methods");
parser.setDescription("");
parser.setContributor("MBI");
parser.setArgumentPrefix("--", "-");
- parser.addArgument("input", "i", ctkCommandLineParser::InputFile, "Input:", "input tractogram (.fib, vtk ascii file format)", us::Any(), false);
- parser.addArgument("reference", "r", ctkCommandLineParser::StringList, "Reference images:", "reference direction images", us::Any(), false);
- parser.addArgument("out", "o", ctkCommandLineParser::OutputDirectory, "Output:", "output root", us::Any(), false);
- parser.addArgument("mask", "m", ctkCommandLineParser::StringList, "Masks:", "mask images");
- parser.addArgument("athresh", "a", ctkCommandLineParser::Float, "Angular threshold:", "angular threshold in degrees. closer fiber directions are regarded as one direction and clustered together.", 25, true);
- parser.addArgument("verbose", "v", ctkCommandLineParser::Bool, "Verbose:", "output optional and intermediate calculation results");
- parser.addArgument("ignore", "n", ctkCommandLineParser::Bool, "Ignore:", "don't increase error for missing or too many directions");
- parser.addArgument("fileID", "id", ctkCommandLineParser::String, "ID:", "optional ID field");
+ parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input:", "input tractogram (.fib, vtk ascii file format)", us::Any(), false);
+ parser.addArgument("reference", "r", mitkCommandLineParser::StringList, "Reference images:", "reference direction images", us::Any(), false);
+ parser.addArgument("out", "o", mitkCommandLineParser::OutputDirectory, "Output:", "output root", us::Any(), false);
+ parser.addArgument("mask", "m", mitkCommandLineParser::StringList, "Masks:", "mask images");
+ parser.addArgument("athresh", "a", mitkCommandLineParser::Float, "Angular threshold:", "angular threshold in degrees. closer fiber directions are regarded as one direction and clustered together.", 25, true);
+ parser.addArgument("verbose", "v", mitkCommandLineParser::Bool, "Verbose:", "output optional and intermediate calculation results");
+ parser.addArgument("ignore", "n", mitkCommandLineParser::Bool, "Ignore:", "don't increase error for missing or too many directions");
+ parser.addArgument("fileID", "id", mitkCommandLineParser::String, "ID:", "optional ID field");
map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
if (parsedArgs.size()==0)
return EXIT_FAILURE;
- ctkCommandLineParser::StringContainerType referenceImages = us::any_cast<ctkCommandLineParser::StringContainerType>(parsedArgs["reference"]);
- ctkCommandLineParser::StringContainerType maskImages;
+ mitkCommandLineParser::StringContainerType referenceImages = us::any_cast<mitkCommandLineParser::StringContainerType>(parsedArgs["reference"]);
+ mitkCommandLineParser::StringContainerType maskImages;
if (parsedArgs.count("mask"))
- maskImages = us::any_cast<ctkCommandLineParser::StringContainerType>(parsedArgs["mask"]);
+ maskImages = us::any_cast<mitkCommandLineParser::StringContainerType>(parsedArgs["mask"]);
string fibFile = us::any_cast<string>(parsedArgs["input"]);
float angularThreshold = 25;
if (parsedArgs.count("athresh"))
angularThreshold = us::any_cast<float>(parsedArgs["athresh"]);
string outRoot = us::any_cast<string>(parsedArgs["out"]);
bool verbose = false;
if (parsedArgs.count("verbose"))
verbose = us::any_cast<bool>(parsedArgs["verbose"]);
bool ignore = false;
if (parsedArgs.count("ignore"))
ignore = us::any_cast<bool>(parsedArgs["ignore"]);
string fileID = "";
if (parsedArgs.count("fileID"))
fileID = us::any_cast<string>(parsedArgs["fileID"]);
try
{
typedef itk::Image<unsigned char, 3> ItkUcharImgType;
typedef itk::Image< itk::Vector< float, 3>, 3 > ItkDirectionImage3DType;
typedef itk::VectorContainer< unsigned int, ItkDirectionImage3DType::Pointer > ItkDirectionImageContainerType;
typedef itk::EvaluateDirectionImagesFilter< float > EvaluationFilterType;
// load fiber bundle
mitk::FiberBundleX::Pointer inputTractogram = dynamic_cast<mitk::FiberBundleX*>(mitk::IOUtil::LoadDataNode(fibFile)->GetData());
// load reference directions
ItkDirectionImageContainerType::Pointer referenceImageContainer = ItkDirectionImageContainerType::New();
for (unsigned int i=0; i<referenceImages.size(); i++)
{
try
{
mitk::Image::Pointer img = dynamic_cast<mitk::Image*>(mitk::IOUtil::LoadDataNode(referenceImages.at(i))->GetData());
typedef mitk::ImageToItk< ItkDirectionImage3DType > CasterType;
CasterType::Pointer caster = CasterType::New();
caster->SetInput(img);
caster->Update();
ItkDirectionImage3DType::Pointer itkImg = caster->GetOutput();
referenceImageContainer->InsertElement(referenceImageContainer->Size(),itkImg);
}
- catch(...){ MITK_INFO << "could not load: " << referenceImages.at(i); }
+ catch(...){ std::cout << "could not load: " << referenceImages.at(i); }
}
ItkUcharImgType::Pointer itkMaskImage = ItkUcharImgType::New();
ItkDirectionImage3DType::Pointer dirImg = referenceImageContainer->GetElement(0);
itkMaskImage->SetSpacing( dirImg->GetSpacing() );
itkMaskImage->SetOrigin( dirImg->GetOrigin() );
itkMaskImage->SetDirection( dirImg->GetDirection() );
itkMaskImage->SetLargestPossibleRegion( dirImg->GetLargestPossibleRegion() );
itkMaskImage->SetBufferedRegion( dirImg->GetLargestPossibleRegion() );
itkMaskImage->SetRequestedRegion( dirImg->GetLargestPossibleRegion() );
itkMaskImage->Allocate();
itkMaskImage->FillBuffer(1);
// extract directions from fiber bundle
itk::TractsToVectorImageFilter<float>::Pointer fOdfFilter = itk::TractsToVectorImageFilter<float>::New();
fOdfFilter->SetFiberBundle(inputTractogram);
fOdfFilter->SetMaskImage(itkMaskImage);
fOdfFilter->SetAngularThreshold(cos(angularThreshold*M_PI/180));
fOdfFilter->SetNormalizeVectors(true);
fOdfFilter->SetUseWorkingCopy(false);
fOdfFilter->Update();
ItkDirectionImageContainerType::Pointer directionImageContainer = fOdfFilter->GetDirectionImageContainer();
if (verbose)
{
// write vector field
mitk::FiberBundleX::Pointer directions = fOdfFilter->GetOutputFiberBundle();
string outfilename = outRoot;
outfilename.append("_VECTOR_FIELD.fib");
mitk::IOUtil::SaveBaseData(directions.GetPointer(), outfilename );
// write direction images
for (unsigned int i=0; i<directionImageContainer->Size(); i++)
{
itk::TractsToVectorImageFilter<float>::ItkDirectionImageType::Pointer itkImg = directionImageContainer->GetElement(i);
typedef itk::ImageFileWriter< itk::TractsToVectorImageFilter<float>::ItkDirectionImageType > WriterType;
WriterType::Pointer writer = WriterType::New();
string outfilename = outRoot;
outfilename.append("_DIRECTION_");
outfilename.append(boost::lexical_cast<string>(i));
outfilename.append(".nrrd");
writer->SetFileName(outfilename.c_str());
writer->SetInput(itkImg);
writer->Update();
}
// write num direction image
{
ItkUcharImgType::Pointer numDirImage = fOdfFilter->GetNumDirectionsImage();
typedef itk::ImageFileWriter< ItkUcharImgType > WriterType;
WriterType::Pointer writer = WriterType::New();
string outfilename = outRoot;
outfilename.append("_NUM_DIRECTIONS.nrrd");
writer->SetFileName(outfilename.c_str());
writer->SetInput(numDirImage);
writer->Update();
}
}
string logFile = outRoot;
logFile.append("_ANGULAR_ERROR.csv");
ofstream file;
file.open (logFile.c_str());
if (maskImages.size()>0)
{
for (unsigned int i=0; i<maskImages.size(); i++)
{
mitk::Image::Pointer mitkMaskImage = dynamic_cast<mitk::Image*>(mitk::IOUtil::LoadDataNode(maskImages.at(i))->GetData());
mitk::CastToItkImage(mitkMaskImage, itkMaskImage);
// evaluate directions
EvaluationFilterType::Pointer evaluationFilter = EvaluationFilterType::New();
evaluationFilter->SetImageSet(directionImageContainer);
evaluationFilter->SetReferenceImageSet(referenceImageContainer);
evaluationFilter->SetMaskImage(itkMaskImage);
evaluationFilter->SetIgnoreMissingDirections(ignore);
evaluationFilter->Update();
if (verbose)
{
EvaluationFilterType::OutputImageType::Pointer angularErrorImage = evaluationFilter->GetOutput(0);
typedef itk::ImageFileWriter< EvaluationFilterType::OutputImageType > WriterType;
WriterType::Pointer writer = WriterType::New();
string outfilename = outRoot;
outfilename.append("_ERROR_IMAGE.nrrd");
writer->SetFileName(outfilename.c_str());
writer->SetInput(angularErrorImage);
writer->Update();
}
string maskFileName = itksys::SystemTools::GetFilenameWithoutExtension(maskImages.at(i));
unsigned found = maskFileName.find_last_of("_");
string sens = itksys::SystemTools::GetFilenameWithoutLastExtension(fibFile);
if (!fileID.empty())
sens = fileID;
sens.append(",");
sens.append(maskFileName.substr(found+1));
sens.append(",");
sens.append(boost::lexical_cast<string>(evaluationFilter->GetMeanAngularError()));
sens.append(",");
sens.append(boost::lexical_cast<string>(evaluationFilter->GetMedianAngularError()));
sens.append(",");
sens.append(boost::lexical_cast<string>(evaluationFilter->GetMaxAngularError()));
sens.append(",");
sens.append(boost::lexical_cast<string>(evaluationFilter->GetMinAngularError()));
sens.append(",");
sens.append(boost::lexical_cast<string>(std::sqrt(evaluationFilter->GetVarAngularError())));
sens.append(";\n");
file << sens;
}
}
else
{
// evaluate directions
EvaluationFilterType::Pointer evaluationFilter = EvaluationFilterType::New();
evaluationFilter->SetImageSet(directionImageContainer);
evaluationFilter->SetReferenceImageSet(referenceImageContainer);
evaluationFilter->SetMaskImage(itkMaskImage);
evaluationFilter->SetIgnoreMissingDirections(ignore);
evaluationFilter->Update();
if (verbose)
{
EvaluationFilterType::OutputImageType::Pointer angularErrorImage = evaluationFilter->GetOutput(0);
typedef itk::ImageFileWriter< EvaluationFilterType::OutputImageType > WriterType;
WriterType::Pointer writer = WriterType::New();
string outfilename = outRoot;
outfilename.append("_ERROR_IMAGE.nrrd");
writer->SetFileName(outfilename.c_str());
writer->SetInput(angularErrorImage);
writer->Update();
}
string sens = itksys::SystemTools::GetFilenameWithoutLastExtension(fibFile);
if (!fileID.empty())
sens = fileID;
sens.append(",");
sens.append(boost::lexical_cast<string>(evaluationFilter->GetMeanAngularError()));
sens.append(",");
sens.append(boost::lexical_cast<string>(evaluationFilter->GetMedianAngularError()));
sens.append(",");
sens.append(boost::lexical_cast<string>(evaluationFilter->GetMaxAngularError()));
sens.append(",");
sens.append(boost::lexical_cast<string>(evaluationFilter->GetMinAngularError()));
sens.append(",");
sens.append(boost::lexical_cast<string>(std::sqrt(evaluationFilter->GetVarAngularError())));
sens.append(";\n");
file << sens;
}
file.close();
}
catch (itk::ExceptionObject e)
{
- MITK_INFO << e;
+ std::cout << e;
return EXIT_FAILURE;
}
catch (std::exception e)
{
- MITK_INFO << e.what();
+ std::cout << e.what();
return EXIT_FAILURE;
}
catch (...)
{
- MITK_INFO << "ERROR!?!";
+ std::cout << "ERROR!?!";
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
-RegisterDiffusionMiniApp(LocalDirectionalFiberPlausibility);
diff --git a/Modules/DiffusionImaging/MiniApps/MiniAppManager.cpp b/Modules/DiffusionImaging/MiniApps/MiniAppManager.cpp
deleted file mode 100644
index 57616b9d2d..0000000000
--- a/Modules/DiffusionImaging/MiniApps/MiniAppManager.cpp
+++ /dev/null
@@ -1,123 +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 "MiniAppManager.h"
-#include <itkMultiThreader.h>
-
-MiniAppManager* MiniAppManager::GetInstance()
-{
- static MiniAppManager instance;
- return &instance;
-}
-
-// Attention: Name of the miniApp must be the last argument!!!
-// it will be cut off from the rest of the arguments and then
-// the app will be run
-int MiniAppManager::RunMiniApp(int argc, char* argv[])
-{
- int threadNum = itk::MultiThreader::GetGlobalMaximumNumberOfThreads();
- if (threadNum>12)
- threadNum = 12;
- itk::MultiThreader::SetGlobalDefaultNumberOfThreads(threadNum);
- try
- {
- std::string nameOfMiniApp;
- std::map< std::string, MiniAppFunction >::iterator it = m_Functions.begin();
-
- if( argc < 2)
- {
- std::cout << "Please choose the mini app to execute: " << std::endl;
-
- for(int i=0; it != m_Functions.end(); ++i,++it)
- {
- std::cout << "(" << i << ")" << " " << it->first << std::endl;
- }
- std::cout << "Please select: ";
- int choose;
- std::cin >> choose;
-
- it = m_Functions.begin();
- std::advance(it, choose);
- if( it != m_Functions.end() )
- nameOfMiniApp = it->first;
- }
- else
- {
- std::string arg = argv[1];
-
- if (arg == "--xml")
- {
- std::cout << this->CreateXML() << std::endl;
- }
- else
- {
- nameOfMiniApp = argv[1];
- }
- }
-
- it = m_Functions.find(nameOfMiniApp);
- if(it == m_Functions.end())
- {
- std::ostringstream s; s << "MiniApp (" << nameOfMiniApp << ") not found!";
- throw std::invalid_argument(s.str().c_str());
- }
-
-// MITK_INFO << "Start " << nameOfMiniApp << " ..";
- MiniAppFunction func = it->second;
- return func( argc, argv );
- }
-
- catch(std::exception& e)
- {
- MITK_ERROR << e.what();
- }
-
- catch(...)
- {
- MITK_ERROR << "Unknown error occurred";
- }
-
- return EXIT_FAILURE;
-}
-
-/////////////////////
-// MiniAppFunction //
-/////////////////////
-MiniAppManager::MiniAppFunction
-MiniAppManager::AddFunction(const std::string& name, MiniAppFunction func)
-{
- m_Functions.insert( std::pair<std::string, MiniAppFunction>(name, func) );
- return func;
-}
-
-std::string MiniAppManager::CreateXML() const
-{
- std::ostringstream output;
-
- output << "<?xml version=\"1.0\" encoding=\"utf-8\"?>" << std::endl;
- output << "<executables>" << std::endl;
-
- std::map<std::string, MiniAppFunction>::const_iterator it = m_Functions.begin();
-
- for (; it != m_Functions.end(); ++it)
- {
- output << " <executable name=\"" << it->first << "\"/>" << std::endl;
- }
-
- output << "</executables>";
-
- return output.str();
-}
diff --git a/Modules/DiffusionImaging/MiniApps/MiniAppManager.h b/Modules/DiffusionImaging/MiniApps/MiniAppManager.h
deleted file mode 100644
index 39210b0b0a..0000000000
--- a/Modules/DiffusionImaging/MiniApps/MiniAppManager.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef MiniAppManager_h
-#define MiniAppManager_h
-
-#include <mitkCommon.h>
-
-struct MiniAppManager
-{
-
-public:
-
- typedef int (*MiniAppFunction)(int argc, char* argv[]);
-
-public:
-
- static MiniAppManager* GetInstance();
-
- // Attention: Name of the miniApp must be the last argument!!!
- // it will be cut off from the rest of the arguments and then
- // the app will be run
- int RunMiniApp(int argc, char* argv[]);
-
- //
- // Add miniApp
- //
- MiniAppFunction AddFunction(const std::string& name, MiniAppFunction func);
-
- std::string CreateXML() const;
-
-protected:
-
- std::map< std::string, MiniAppFunction > m_Functions;
-};
-
-//
-// Register miniApps
-//
-#define RegisterDiffusionMiniApp(functionName) \
- static MiniAppManager::MiniAppFunction MiniApp##functionName = \
- MiniAppManager::GetInstance()->AddFunction(#functionName, &functionName)
-#endif
diff --git a/Modules/DiffusionImaging/MiniApps/MultishellMethods.cpp b/Modules/DiffusionImaging/MiniApps/MultishellMethods.cpp
index 23fcc974e3..687ed57bf1 100644
--- a/Modules/DiffusionImaging/MiniApps/MultishellMethods.cpp
+++ b/Modules/DiffusionImaging/MiniApps/MultishellMethods.cpp
@@ -1,220 +1,215 @@
/*===================================================================
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 "MiniAppManager.h"
-
#include <vector>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <string>
#include <itkImage.h>
#include <itkImageFileReader.h>
#include <itkExceptionObject.h>
#include <itkImageFileWriter.h>
#include <itkMetaDataObject.h>
#include <itkVectorImage.h>
#include <itkResampleImageFilter.h>
#include <mitkBaseDataIOFactory.h>
#include <mitkDiffusionImage.h>
#include <mitkQBallImage.h>
#include <mitkBaseData.h>
#include <mitkFiberBundleX.h>
-#include "ctkCommandLineParser.h"
+#include "mitkCommandLineParser.h"
#include <boost/lexical_cast.hpp>
#include <itkRadialMultishellToSingleshellImageFilter.h>
#include <itkADCAverageFunctor.h>
#include <itkBiExpFitFunctor.h>
#include <itkKurtosisFitFunctor.h>
#include <itkDwiGradientLengthCorrectionFilter.h>
#include <mitkIOUtil.h>
-int MultishellMethods(int argc, char* argv[])
+int main(int argc, char* argv[])
{
- MITK_INFO << "MultishellMethods";
- ctkCommandLineParser parser;
+ mitkCommandLineParser parser;
parser.setTitle("Multishell Methods");
parser.setCategory("Fiber Tracking and Processing Methods");
parser.setDescription("");
parser.setContributor("MBI");
parser.setArgumentPrefix("--", "-");
- parser.addArgument("in", "i", ctkCommandLineParser::InputFile, "Input:", "input file", us::Any(), false);
- parser.addArgument("out", "o", ctkCommandLineParser::OutputFile, "Output:", "output file", us::Any(), false);
- parser.addArgument("adc", "D", ctkCommandLineParser::Bool, "ADC:", "ADC Average", us::Any(), false);
- parser.addArgument("akc", "K", ctkCommandLineParser::Bool, "Kurtosis fit:", "Kurtosis Fit", us::Any(), false);
- parser.addArgument("biexp", "B", ctkCommandLineParser::Bool, "BiExp fit:", "BiExp fit", us::Any(), false);
- parser.addArgument("targetbvalue", "b", ctkCommandLineParser::String, "b Value:", "target bValue (mean, min, max)", us::Any(), false);
+ parser.addArgument("in", "i", mitkCommandLineParser::InputFile, "Input:", "input file", us::Any(), false);
+ parser.addArgument("out", "o", mitkCommandLineParser::OutputFile, "Output:", "output file", us::Any(), false);
+ parser.addArgument("adc", "D", mitkCommandLineParser::Bool, "ADC:", "ADC Average", us::Any(), false);
+ parser.addArgument("akc", "K", mitkCommandLineParser::Bool, "Kurtosis fit:", "Kurtosis Fit", us::Any(), false);
+ parser.addArgument("biexp", "B", mitkCommandLineParser::Bool, "BiExp fit:", "BiExp fit", us::Any(), false);
+ parser.addArgument("targetbvalue", "b", mitkCommandLineParser::String, "b Value:", "target bValue (mean, min, max)", us::Any(), false);
map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
if (parsedArgs.size()==0)
return EXIT_FAILURE;
// mandatory arguments
string inName = us::any_cast<string>(parsedArgs["in"]);
string outName = us::any_cast<string>(parsedArgs["out"]);
bool applyADC = us::any_cast<bool>(parsedArgs["adc"]);
bool applyAKC = us::any_cast<bool>(parsedArgs["akc"]);
bool applyBiExp = us::any_cast<bool>(parsedArgs["biexp"]);
string targetType = us::any_cast<string>(parsedArgs["targetbvalue"]);
try
{
- MITK_INFO << "Loading " << inName;
+ std::cout << "Loading " << inName;
const std::string s1="", s2="";
std::vector<mitk::BaseData::Pointer> infile = mitk::BaseDataIO::LoadBaseDataFromFile( inName, s1, s2, false );
mitk::BaseData::Pointer baseData = infile.at(0);
if ( dynamic_cast<mitk::DiffusionImage<short>*>(baseData.GetPointer()) )
{
mitk::DiffusionImage<short>::Pointer dwi = dynamic_cast<mitk::DiffusionImage<short>*>(baseData.GetPointer());
typedef itk::RadialMultishellToSingleshellImageFilter<short, short> FilterType;
typedef itk::DwiGradientLengthCorrectionFilter CorrectionFilterType;
CorrectionFilterType::Pointer roundfilter = CorrectionFilterType::New();
roundfilter->SetRoundingValue( 1000 );
roundfilter->SetReferenceBValue(dwi->GetReferenceBValue());
roundfilter->SetReferenceGradientDirectionContainer(dwi->GetDirections());
roundfilter->Update();
dwi->SetReferenceBValue( roundfilter->GetNewBValue() );
dwi->SetDirections( roundfilter->GetOutputGradientDirectionContainer());
// filter input parameter
const mitk::DiffusionImage<short>::BValueMap
&originalShellMap = dwi->GetBValueMap();
const mitk::DiffusionImage<short>::ImageType
*vectorImage = dwi->GetVectorImage();
const mitk::DiffusionImage<short>::GradientDirectionContainerType::Pointer
gradientContainer = dwi->GetDirections();
const unsigned int
&bValue = dwi->GetReferenceBValue();
// filter call
vnl_vector<double> bValueList(originalShellMap.size()-1);
double targetBValue = bValueList.mean();
mitk::DiffusionImage<short>::BValueMap::const_iterator it = originalShellMap.begin();
++it; int i = 0 ;
for(; it != originalShellMap.end(); ++it)
bValueList.put(i++,it->first);
if( targetType == "mean" )
targetBValue = bValueList.mean();
else if( targetType == "min" )
targetBValue = bValueList.min_value();
else if( targetType == "max" )
targetBValue = bValueList.max_value();
if(applyADC)
{
FilterType::Pointer filter = FilterType::New();
filter->SetInput(vectorImage);
filter->SetOriginalGradientDirections(gradientContainer);
filter->SetOriginalBValueMap(originalShellMap);
filter->SetOriginalBValue(bValue);
itk::ADCAverageFunctor::Pointer functor = itk::ADCAverageFunctor::New();
functor->setListOfBValues(bValueList);
functor->setTargetBValue(targetBValue);
filter->SetFunctor(functor);
filter->Update();
// create new DWI image
mitk::DiffusionImage<short>::Pointer outImage = mitk::DiffusionImage<short>::New();
outImage->SetVectorImage( filter->GetOutput() );
outImage->SetReferenceBValue( targetBValue );
outImage->SetDirections( filter->GetTargetGradientDirections() );
outImage->InitializeFromVectorImage();
mitk::IOUtil::Save(outImage, (outName + "_ADC.dwi").c_str());
}
if(applyAKC)
{
FilterType::Pointer filter = FilterType::New();
filter->SetInput(vectorImage);
filter->SetOriginalGradientDirections(gradientContainer);
filter->SetOriginalBValueMap(originalShellMap);
filter->SetOriginalBValue(bValue);
itk::KurtosisFitFunctor::Pointer functor = itk::KurtosisFitFunctor::New();
functor->setListOfBValues(bValueList);
functor->setTargetBValue(targetBValue);
filter->SetFunctor(functor);
filter->Update();
// create new DWI image
mitk::DiffusionImage<short>::Pointer outImage = mitk::DiffusionImage<short>::New();
outImage->SetVectorImage( filter->GetOutput() );
outImage->SetReferenceBValue( targetBValue );
outImage->SetDirections( filter->GetTargetGradientDirections() );
outImage->InitializeFromVectorImage();
mitk::IOUtil::Save(outImage, (string(outName) + "_AKC.dwi").c_str());
}
if(applyBiExp)
{
FilterType::Pointer filter = FilterType::New();
filter->SetInput(vectorImage);
filter->SetOriginalGradientDirections(gradientContainer);
filter->SetOriginalBValueMap(originalShellMap);
filter->SetOriginalBValue(bValue);
itk::BiExpFitFunctor::Pointer functor = itk::BiExpFitFunctor::New();
functor->setListOfBValues(bValueList);
functor->setTargetBValue(targetBValue);
filter->SetFunctor(functor);
filter->Update();
// create new DWI image
mitk::DiffusionImage<short>::Pointer outImage = mitk::DiffusionImage<short>::New();
outImage->SetVectorImage( filter->GetOutput() );
outImage->SetReferenceBValue( targetBValue );
outImage->SetDirections( filter->GetTargetGradientDirections() );
outImage->InitializeFromVectorImage();
mitk::IOUtil::Save(outImage, (string(outName) + "_BiExp.dwi").c_str());
}
}
}
catch (itk::ExceptionObject e)
{
- MITK_INFO << e;
+ std::cout << e;
return EXIT_FAILURE;
}
catch (std::exception e)
{
- MITK_INFO << e.what();
+ std::cout << e.what();
return EXIT_FAILURE;
}
catch (...)
{
- MITK_INFO << "ERROR!?!";
+ std::cout << "ERROR!?!";
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
-RegisterDiffusionMiniApp(MultishellMethods);
diff --git a/Modules/DiffusionImaging/MiniApps/NetworkCreation.cpp b/Modules/DiffusionImaging/MiniApps/NetworkCreation.cpp
index c3349de199..08c92ab5c0 100644
--- a/Modules/DiffusionImaging/MiniApps/NetworkCreation.cpp
+++ b/Modules/DiffusionImaging/MiniApps/NetworkCreation.cpp
@@ -1,136 +1,133 @@
/*===================================================================
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 "MiniAppManager.h"
-
// std includes
#include <string>
// CTK includes
-#include "ctkCommandLineParser.h"
+#include "mitkCommandLineParser.h"
// MITK includes
#include <mitkBaseDataIOFactory.h>
#include "mitkConnectomicsNetworkCreator.h"
#include <mitkCoreObjectFactory.h>
#include <mitkIOUtil.h>
-int NetworkCreation(int argc, char* argv[])
+int main(int argc, char* argv[])
{
- ctkCommandLineParser parser;
+ mitkCommandLineParser parser;
parser.setArgumentPrefix("--", "-");
- parser.addArgument("fiberImage", "f", ctkCommandLineParser::InputFile, "Input image", "input fiber image (.fib)", us::Any(), false);
- parser.addArgument("parcellation", "p", ctkCommandLineParser::InputFile, "Parcellation image", "parcellation image", us::Any(), false);
- parser.addArgument("outputNetwork", "o", ctkCommandLineParser::String, "Output network", "where to save the output (.cnf)", us::Any(), false);
+ parser.addArgument("fiberImage", "f", mitkCommandLineParser::InputFile, "Input image", "input fiber image (.fib)", us::Any(), false);
+ parser.addArgument("parcellation", "p", mitkCommandLineParser::InputFile, "Parcellation image", "parcellation image", us::Any(), false);
+ parser.addArgument("outputNetwork", "o", mitkCommandLineParser::String, "Output network", "where to save the output (.cnf)", us::Any(), false);
- parser.addArgument("radius", "r", ctkCommandLineParser::Int, "Radius", "Search radius in mm", 15, true);
- parser.addArgument("noCenterOfMass", "com", ctkCommandLineParser::Bool, "No center of mass", "Do not use center of mass for node positions");
+ parser.addArgument("radius", "r", mitkCommandLineParser::Int, "Radius", "Search radius in mm", 15, true);
+ parser.addArgument("noCenterOfMass", "com", mitkCommandLineParser::Bool, "No center of mass", "Do not use center of mass for node positions");
parser.setCategory("Connectomics");
parser.setTitle("Network Creation");
parser.setDescription("");
parser.setContributor("MBI");
map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
if (parsedArgs.size()==0)
return EXIT_FAILURE;
//default values
int searchRadius( 15 );
bool noCenterOfMass( false );
// parse command line arguments
std::string fiberFilename = us::any_cast<std::string>(parsedArgs["fiberImage"]);
std::string parcellationFilename = us::any_cast<std::string>(parsedArgs["parcellation"]);
std::string outputFilename = us::any_cast<std::string>(parsedArgs["outputNetwork"]);
if (parsedArgs.count("radius"))
searchRadius = us::any_cast<int>(parsedArgs["radius"]);
if (parsedArgs.count("noCenterOfMass"))
noCenterOfMass = us::any_cast<bool>(parsedArgs["noCenterOfMass"]);
try
{
const std::string s1="", s2="";
// load fiber image
std::vector<mitk::BaseData::Pointer> fiberInfile =
mitk::BaseDataIO::LoadBaseDataFromFile( fiberFilename, s1, s2, false );
if( fiberInfile.empty() )
{
std::string errorMessage = "Fiber Image at " + fiberFilename + " could not be read. Aborting.";
MITK_ERROR << errorMessage;
return EXIT_FAILURE;
}
mitk::BaseData* fiberBaseData = fiberInfile.at(0);
mitk::FiberBundleX* fiberBundle = dynamic_cast<mitk::FiberBundleX*>( fiberBaseData );
// load parcellation
std::vector<mitk::BaseData::Pointer> parcellationInFile =
mitk::BaseDataIO::LoadBaseDataFromFile( parcellationFilename, s1, s2, false );
if( parcellationInFile.empty() )
{
std::string errorMessage = "Parcellation at " + parcellationFilename + " could not be read. Aborting.";
MITK_ERROR << errorMessage;
return EXIT_FAILURE;
}
mitk::BaseData* parcellationBaseData = parcellationInFile.at(0);
mitk::Image* parcellationImage = dynamic_cast<mitk::Image*>( parcellationBaseData );
// do creation
mitk::ConnectomicsNetworkCreator::Pointer connectomicsNetworkCreator = mitk::ConnectomicsNetworkCreator::New();
connectomicsNetworkCreator->SetSegmentation( parcellationImage );
connectomicsNetworkCreator->SetFiberBundle( fiberBundle );
if( !noCenterOfMass )
{
connectomicsNetworkCreator->CalculateCenterOfMass();
}
connectomicsNetworkCreator->SetEndPointSearchRadius( searchRadius );
connectomicsNetworkCreator->CreateNetworkFromFibersAndSegmentation();
mitk::ConnectomicsNetwork::Pointer network = connectomicsNetworkCreator->GetNetwork();
- MITK_INFO << "searching writer";
+ std::cout << "searching writer";
mitk::IOUtil::SaveBaseData(network.GetPointer(), outputFilename );
return EXIT_SUCCESS;
}
catch (itk::ExceptionObject e)
{
- MITK_INFO << e;
+ std::cout << e;
return EXIT_FAILURE;
}
catch (std::exception e)
{
- MITK_INFO << e.what();
+ std::cout << e.what();
return EXIT_FAILURE;
}
catch (...)
{
- MITK_INFO << "ERROR!?!";
+ std::cout << "ERROR!?!";
return EXIT_FAILURE;
}
- MITK_INFO << "DONE";
+ std::cout << "DONE";
return EXIT_SUCCESS;
}
-RegisterDiffusionMiniApp(NetworkCreation);
diff --git a/Modules/DiffusionImaging/MiniApps/NetworkStatistics.cpp b/Modules/DiffusionImaging/MiniApps/NetworkStatistics.cpp
index 8d7bf91637..1fe492899c 100644
--- a/Modules/DiffusionImaging/MiniApps/NetworkStatistics.cpp
+++ b/Modules/DiffusionImaging/MiniApps/NetworkStatistics.cpp
@@ -1,518 +1,515 @@
/*===================================================================
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 <MiniAppManager.h>
-
// std includes
#include <string>
#include <sstream>
#include <fstream>
#include <vector>
#include <map>
#include <utility>
// boost includes
#include <boost/algorithm/string.hpp>
// ITK includes
#include <itkImageFileWriter.h>
// CTK includes
-#include "ctkCommandLineParser.h"
+#include "mitkCommandLineParser.h"
// MITK includes
#include <mitkBaseDataIOFactory.h>
#include <mitkConnectomicsStatisticsCalculator.h>
#include <mitkConnectomicsNetworkThresholder.h>
#include <itkConnectomicsNetworkToConnectivityMatrixImageFilter.h>
-int NetworkStatistics(int argc, char* argv[])
+int main(int argc, char* argv[])
{
- ctkCommandLineParser parser;
+ mitkCommandLineParser parser;
parser.setArgumentPrefix("--", "-");
- parser.addArgument("inputNetwork", "i", ctkCommandLineParser::InputFile, "Input network", "input connectomics network (.cnf)", us::Any(), false);
- parser.addArgument("outputFile", "o", ctkCommandLineParser::OutputFile, "Output file", "name of output file", us::Any(), false);
-
- parser.addArgument("noGlobalStatistics", "g", ctkCommandLineParser::Bool, "No global statistics", "Do not calculate global statistics");
- parser.addArgument("createConnectivityMatriximage", "I", ctkCommandLineParser::Bool, "Write connectivity matrix image", "Write connectivity matrix image");
- parser.addArgument("binaryConnectivity", "b", ctkCommandLineParser::Bool, "Binary connectivity", "Whether to create a binary connectivity matrix");
- parser.addArgument("rescaleConnectivity", "r", ctkCommandLineParser::Bool, "Rescale connectivity", "Whether to rescale the connectivity matrix");
- parser.addArgument("localStatistics", "L", ctkCommandLineParser::StringList, "Local statistics", "Provide a list of node labels for local statistics", us::Any());
- parser.addArgument("regionList", "R", ctkCommandLineParser::StringList, "Region list", "A space separated list of regions. Each region has the format\n regionname;label1;label2;...;labelN", us::Any());
- parser.addArgument("granularity", "gr", ctkCommandLineParser::Int, "Granularity", "How finely to test the density range and how many thresholds to consider");
- parser.addArgument("startDensity", "d", ctkCommandLineParser::Float, "Start Density", "Largest density for the range");
- parser.addArgument("thresholdStepSize", "t", ctkCommandLineParser::Int, "Step size threshold", "Distance of two adjacent thresholds");
+ parser.addArgument("inputNetwork", "i", mitkCommandLineParser::InputFile, "Input network", "input connectomics network (.cnf)", us::Any(), false);
+ parser.addArgument("outputFile", "o", mitkCommandLineParser::OutputFile, "Output file", "name of output file", us::Any(), false);
+
+ parser.addArgument("noGlobalStatistics", "g", mitkCommandLineParser::Bool, "No global statistics", "Do not calculate global statistics");
+ parser.addArgument("createConnectivityMatriximage", "I", mitkCommandLineParser::Bool, "Write connectivity matrix image", "Write connectivity matrix image");
+ parser.addArgument("binaryConnectivity", "b", mitkCommandLineParser::Bool, "Binary connectivity", "Whether to create a binary connectivity matrix");
+ parser.addArgument("rescaleConnectivity", "r", mitkCommandLineParser::Bool, "Rescale connectivity", "Whether to rescale the connectivity matrix");
+ parser.addArgument("localStatistics", "L", mitkCommandLineParser::StringList, "Local statistics", "Provide a list of node labels for local statistics", us::Any());
+ parser.addArgument("regionList", "R", mitkCommandLineParser::StringList, "Region list", "A space separated list of regions. Each region has the format\n regionname;label1;label2;...;labelN", us::Any());
+ parser.addArgument("granularity", "gr", mitkCommandLineParser::Int, "Granularity", "How finely to test the density range and how many thresholds to consider");
+ parser.addArgument("startDensity", "d", mitkCommandLineParser::Float, "Start Density", "Largest density for the range");
+ parser.addArgument("thresholdStepSize", "t", mitkCommandLineParser::Int, "Step size threshold", "Distance of two adjacent thresholds");
parser.setCategory("Connectomics");
parser.setTitle("Network Statistics");
parser.setDescription("");
parser.setContributor("MBI");
map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
if (parsedArgs.size()==0)
return EXIT_FAILURE;
//default values
bool noGlobalStatistics( false );
bool binaryConnectivity( false );
bool rescaleConnectivity( false );
bool createConnectivityMatriximage( false );
int granularity( 1 );
double startDensity( 1.0 );
int thresholdStepSize( 3 );
// parse command line arguments
std::string networkName = us::any_cast<std::string>(parsedArgs["inputNetwork"]);
std::string outName = us::any_cast<std::string>(parsedArgs["outputFile"]);
- ctkCommandLineParser::StringContainerType localLabels;
+ mitkCommandLineParser::StringContainerType localLabels;
if(parsedArgs.count("localStatistics"))
{
- localLabels = us::any_cast<ctkCommandLineParser::StringContainerType>(parsedArgs["localStatistics"]);
+ localLabels = us::any_cast<mitkCommandLineParser::StringContainerType>(parsedArgs["localStatistics"]);
}
- ctkCommandLineParser::StringContainerType unparsedRegions;
+ mitkCommandLineParser::StringContainerType unparsedRegions;
std::map< std::string, std::vector<std::string> > parsedRegions;
std::map< std::string, std::vector<std::string> >::iterator parsedRegionsIterator;
if(parsedArgs.count("regionList"))
{
- unparsedRegions = us::any_cast<ctkCommandLineParser::StringContainerType>(parsedArgs["regionList"]);
+ unparsedRegions = us::any_cast<mitkCommandLineParser::StringContainerType>(parsedArgs["regionList"]);
for(unsigned int index(0); index < unparsedRegions.size(); index++ )
{
std::vector< std::string > tempRegionVector;
boost::split(tempRegionVector, unparsedRegions.at(index), boost::is_any_of(";"));
std::vector< std::string >::const_iterator begin = tempRegionVector.begin();
std::vector< std::string >::const_iterator last = tempRegionVector.begin() + tempRegionVector.size();
std::vector< std::string > insertRegionVector(begin + 1, last);
if( parsedRegions.count( tempRegionVector.at(0) ) == 0 )
{
parsedRegions.insert( std::pair< std::string, std::vector<std::string> >( tempRegionVector.at(0), insertRegionVector) );
}
else
{
MITK_ERROR << "Region already exists. Skipping second occurrence.";
}
}
}
if (parsedArgs.count("noGlobalStatistics"))
noGlobalStatistics = us::any_cast<bool>(parsedArgs["noGlobalStatistics"]);
if (parsedArgs.count("binaryConnectivity"))
binaryConnectivity = us::any_cast<bool>(parsedArgs["binaryConnectivity"]);
if (parsedArgs.count("rescaleConnectivity"))
rescaleConnectivity = us::any_cast<bool>(parsedArgs["rescaleConnectivity"]);
if (parsedArgs.count("createConnectivityMatriximage"))
createConnectivityMatriximage = us::any_cast<bool>(parsedArgs["createConnectivityMatriximage"]);
if (parsedArgs.count("granularity"))
granularity = us::any_cast<int>(parsedArgs["granularity"]);
if (parsedArgs.count("startDensity"))
startDensity = us::any_cast<float>(parsedArgs["startDensity"]);
if (parsedArgs.count("thresholdStepSize"))
thresholdStepSize = us::any_cast<int>(parsedArgs["thresholdStepSize"]);
try
{
const std::string s1="", s2="";
// load network
std::vector<mitk::BaseData::Pointer> networkFile =
mitk::BaseDataIO::LoadBaseDataFromFile( networkName, s1, s2, false );
if( networkFile.empty() )
{
std::string errorMessage = "File at " + networkName + " could not be read. Aborting.";
MITK_ERROR << errorMessage;
return EXIT_FAILURE;
}
mitk::BaseData* networkBaseData = networkFile.at(0);
mitk::ConnectomicsNetwork* network = dynamic_cast<mitk::ConnectomicsNetwork*>( networkBaseData );
if( !network )
{
std::string errorMessage = "Read file at " + networkName + " could not be recognized as network. Aborting.";
MITK_ERROR << errorMessage;
return EXIT_FAILURE;
}
// streams
std::stringstream globalHeaderStream;
globalHeaderStream << "NumberOfVertices "
<< "NumberOfEdges "
<< "AverageDegree "
<< "ConnectionDensity "
<< "NumberOfConnectedComponents "
<< "AverageComponentSize "
<< "LargestComponentSize "
<< "RatioOfNodesInLargestComponent "
<< "HopPlotExponent "
<< "EffectiveHopDiameter "
<< "AverageClusteringCoefficientsC "
<< "AverageClusteringCoefficientsD "
<< "AverageClusteringCoefficientsE "
<< "AverageVertexBetweennessCentrality "
<< "AverageEdgeBetweennessCentrality "
<< "NumberOfIsolatedPoints "
<< "RatioOfIsolatedPoints "
<< "NumberOfEndPoints "
<< "RatioOfEndPoints "
<< "Diameter "
<< "Diameter90 "
<< "Radius "
<< "Radius90 "
<< "AverageEccentricity "
<< "AverageEccentricity90 "
<< "AveragePathLength "
<< "NumberOfCentralPoints "
<< "RatioOfCentralPoints "
<< "SpectralRadius "
<< "SecondLargestEigenValue "
<< "AdjacencyTrace "
<< "AdjacencyEnergy "
<< "LaplacianTrace "
<< "LaplacianEnergy "
<< "LaplacianSpectralGap "
<< "NormalizedLaplacianTrace "
<< "NormalizedLaplacianEnergy "
<< "NormalizedLaplacianNumberOf2s "
<< "NormalizedLaplacianNumberOf1s "
<< "NormalizedLaplacianNumberOf0s "
<< "NormalizedLaplacianLowerSlope "
<< "NormalizedLaplacianUpperSlope "
<< "SmallWorldness"
<< std::endl;
std::stringstream localHeaderStream;
std::stringstream regionalHeaderStream;
std::stringstream globalDataStream;
std::stringstream localDataStream;
std::stringstream regionalDataStream;
std::string globalOutName = outName + "_global.txt";
std::string localOutName = outName + "_local.txt";
std::string regionalOutName = outName + "_regional.txt";
bool firstRun( true );
// iterate over all three possible methods
for(unsigned int method( 0 ); method < 3; method++)
{
// 0 - Random removal threshold
// 1 - Largest density below threshold
// 2 - Threshold based
// iterate over possible targets
for( unsigned int step( 0 ); step < granularity; step++ )
{
double targetValue( 0.0 );
bool newStep( true );
switch ( method )
{
case mitk::ConnectomicsNetworkThresholder::RandomRemovalOfWeakest :
case mitk::ConnectomicsNetworkThresholder::LargestLowerThanDensity :
targetValue = startDensity * (1 - static_cast<double>( step ) / ( granularity + 0.5 ) );
break;
case mitk::ConnectomicsNetworkThresholder::ThresholdBased :
targetValue = static_cast<double>( thresholdStepSize * step );
break;
default:
MITK_ERROR << "Invalid thresholding method called, aborting.";
return EXIT_FAILURE;
break;
}
mitk::ConnectomicsNetworkThresholder::Pointer thresholder = mitk::ConnectomicsNetworkThresholder::New();
thresholder->SetNetwork( network );
thresholder->SetTargetThreshold( targetValue );
thresholder->SetTargetDensity( targetValue );
thresholder->SetThresholdingScheme( static_cast<mitk::ConnectomicsNetworkThresholder::ThresholdingSchemes>(method) );
mitk::ConnectomicsNetwork::Pointer thresholdedNetwork = thresholder->GetThresholdedNetwork();
mitk::ConnectomicsStatisticsCalculator::Pointer statisticsCalculator = mitk::ConnectomicsStatisticsCalculator::New();
statisticsCalculator->SetNetwork( thresholdedNetwork );
statisticsCalculator->Update();
// global statistics
if( !noGlobalStatistics )
{
globalDataStream << statisticsCalculator->GetNumberOfVertices() << " "
<< statisticsCalculator->GetNumberOfEdges() << " "
<< statisticsCalculator->GetAverageDegree() << " "
<< statisticsCalculator->GetConnectionDensity() << " "
<< statisticsCalculator->GetNumberOfConnectedComponents() << " "
<< statisticsCalculator->GetAverageComponentSize() << " "
<< statisticsCalculator->GetLargestComponentSize() << " "
<< statisticsCalculator->GetRatioOfNodesInLargestComponent() << " "
<< statisticsCalculator->GetHopPlotExponent() << " "
<< statisticsCalculator->GetEffectiveHopDiameter() << " "
<< statisticsCalculator->GetAverageClusteringCoefficientsC() << " "
<< statisticsCalculator->GetAverageClusteringCoefficientsD() << " "
<< statisticsCalculator->GetAverageClusteringCoefficientsE() << " "
<< statisticsCalculator->GetAverageVertexBetweennessCentrality() << " "
<< statisticsCalculator->GetAverageEdgeBetweennessCentrality() << " "
<< statisticsCalculator->GetNumberOfIsolatedPoints() << " "
<< statisticsCalculator->GetRatioOfIsolatedPoints() << " "
<< statisticsCalculator->GetNumberOfEndPoints() << " "
<< statisticsCalculator->GetRatioOfEndPoints() << " "
<< statisticsCalculator->GetDiameter() << " "
<< statisticsCalculator->GetDiameter90() << " "
<< statisticsCalculator->GetRadius() << " "
<< statisticsCalculator->GetRadius90() << " "
<< statisticsCalculator->GetAverageEccentricity() << " "
<< statisticsCalculator->GetAverageEccentricity90() << " "
<< statisticsCalculator->GetAveragePathLength() << " "
<< statisticsCalculator->GetNumberOfCentralPoints() << " "
<< statisticsCalculator->GetRatioOfCentralPoints() << " "
<< statisticsCalculator->GetSpectralRadius() << " "
<< statisticsCalculator->GetSecondLargestEigenValue() << " "
<< statisticsCalculator->GetAdjacencyTrace() << " "
<< statisticsCalculator->GetAdjacencyEnergy() << " "
<< statisticsCalculator->GetLaplacianTrace() << " "
<< statisticsCalculator->GetLaplacianEnergy() << " "
<< statisticsCalculator->GetLaplacianSpectralGap() << " "
<< statisticsCalculator->GetNormalizedLaplacianTrace() << " "
<< statisticsCalculator->GetNormalizedLaplacianEnergy() << " "
<< statisticsCalculator->GetNormalizedLaplacianNumberOf2s() << " "
<< statisticsCalculator->GetNormalizedLaplacianNumberOf1s() << " "
<< statisticsCalculator->GetNormalizedLaplacianNumberOf0s() << " "
<< statisticsCalculator->GetNormalizedLaplacianLowerSlope() << " "
<< statisticsCalculator->GetNormalizedLaplacianUpperSlope() << " "
<< statisticsCalculator->GetSmallWorldness()
<< std::endl;
} // end global statistics
//create connectivity matrix png
if( createConnectivityMatriximage )
{
std::string connectivity_png_postfix = "_connectivity";
if( binaryConnectivity )
{
connectivity_png_postfix += "_binary";
}
else if( rescaleConnectivity )
{
connectivity_png_postfix += "_rescaled";
}
connectivity_png_postfix += ".png";
/* File format
* A png file depicting the binary connectivity matrix
*/
itk::ConnectomicsNetworkToConnectivityMatrixImageFilter::Pointer filter = itk::ConnectomicsNetworkToConnectivityMatrixImageFilter::New();
filter->SetInputNetwork( network );
filter->SetBinaryConnectivity( binaryConnectivity );
filter->SetRescaleConnectivity( rescaleConnectivity );
filter->Update();
typedef itk::ConnectomicsNetworkToConnectivityMatrixImageFilter::OutputImageType connectivityMatrixImageType;
itk::ImageFileWriter< connectivityMatrixImageType >::Pointer connectivityWriter = itk::ImageFileWriter< connectivityMatrixImageType >::New();
connectivityWriter->SetInput( filter->GetOutput() );
connectivityWriter->SetFileName( outName + connectivity_png_postfix);
connectivityWriter->Update();
- MITK_INFO << "Connectivity matrix image written.";
+ std::cout << "Connectivity matrix image written.";
} // end create connectivity matrix png
/*
* We can either calculate local indices for specific nodes, or specific regions
*/
// Create LabelToIndex translation
std::map< std::string, int > labelToIdMap;
std::vector< mitk::ConnectomicsNetwork::NetworkNode > nodeVector = thresholdedNetwork->GetVectorOfAllNodes();
for(int loop(0); loop < nodeVector.size(); loop++)
{
labelToIdMap.insert( std::pair< std::string, int>(nodeVector.at(loop).label, nodeVector.at(loop).id) );
}
std::vector< int > degreeVector = thresholdedNetwork->GetDegreeOfNodes();
std::vector< double > ccVector = thresholdedNetwork->GetLocalClusteringCoefficients( );
std::vector< double > bcVector = thresholdedNetwork->GetNodeBetweennessVector( );
// calculate local indices
{
// only add to header for the first step of the first method
if( firstRun )
{
localHeaderStream << "Th_method " << "Th_target " << "density";
}
double density = statisticsCalculator->GetConnectionDensity();
localDataStream << "\n"
<< method << " "
<< targetValue << " "
<< density;
for(unsigned int loop(0); loop < localLabels.size(); loop++ )
{
if( network->CheckForLabel(localLabels.at( loop )) )
{
if( firstRun )
{
localHeaderStream << " "
<< localLabels.at( loop ) << "_Degree "
<< localLabels.at( loop ) << "_CC "
<< localLabels.at( loop ) << "_BC";
}
localDataStream << " " << degreeVector.at( labelToIdMap.find( localLabels.at( loop ) )->second )
<< " " << ccVector.at( labelToIdMap.find( localLabels.at( loop ) )->second )
<< " " << bcVector.at( labelToIdMap.find( localLabels.at( loop ) )->second );
}
else
{
MITK_ERROR << "Illegal label. Label: \"" << localLabels.at( loop ) << "\" not found.";
}
}
}
// calculate regional indices
{
// only add to header for the first step of the first method
if( firstRun )
{
regionalHeaderStream << "Th_method " << "Th_target " << "density";
}
double density = statisticsCalculator->GetConnectionDensity();
regionalDataStream << "\n"
<< method << " "
<< targetValue << " "
<< density;
for( parsedRegionsIterator = parsedRegions.begin(); parsedRegionsIterator != parsedRegions.end(); parsedRegionsIterator++ )
{
std::vector<std::string> regionLabelsVector = parsedRegionsIterator->second;
std::string regionName = parsedRegionsIterator->first;
double sumDegree( 0 );
double sumCC( 0 );
double sumBC( 0 );
double count( 0 );
for( int loop(0); loop < regionLabelsVector.size(); loop++ )
{
if( thresholdedNetwork->CheckForLabel(regionLabelsVector.at( loop )) )
{
sumDegree = sumDegree + degreeVector.at( labelToIdMap.find( regionLabelsVector.at( loop ) )->second );
sumCC = sumCC + ccVector.at( labelToIdMap.find( regionLabelsVector.at( loop ) )->second );
sumBC = sumBC + bcVector.at( labelToIdMap.find( regionLabelsVector.at( loop ) )->second );
count = count + 1;
}
else
{
MITK_ERROR << "Illegal label. Label: \"" << regionLabelsVector.at( loop ) << "\" not found.";
}
}
// only add to header for the first step of the first method
if( firstRun )
{
regionalHeaderStream << " " << regionName << "_LocalAverageDegree "
<< regionName << "_LocalAverageCC "
<< regionName << "_LocalAverageBC "
<< regionName << "_NumberOfNodes";
}
regionalDataStream << " " << sumDegree / count
<< " " << sumCC / count
<< " " << sumBC / count
<< " " << count;
}
}
firstRun = false;
}
}// end calculate local averages
if( !noGlobalStatistics )
{
- MITK_INFO << "Writing to " << globalOutName;
+ std::cout << "Writing to " << globalOutName;
std::ofstream glocalOutFile( globalOutName.c_str(), ios::out );
if( ! glocalOutFile.is_open() )
{
std::string errorMessage = "Could not open " + globalOutName + " for writing.";
MITK_ERROR << errorMessage;
return EXIT_FAILURE;
}
glocalOutFile << globalHeaderStream.str() << globalDataStream.str();
glocalOutFile.close();
}
if( localLabels.size() > 0 )
{
- MITK_INFO << "Writing to " << localOutName;
+ std::cout << "Writing to " << localOutName;
std::ofstream localOutFile( localOutName.c_str(), ios::out );
if( ! localOutFile.is_open() )
{
std::string errorMessage = "Could not open " + localOutName + " for writing.";
MITK_ERROR << errorMessage;
return EXIT_FAILURE;
}
localOutFile << localHeaderStream.str() << localDataStream.str();
localOutFile.close();
}
if( parsedRegions.size() > 0 )
{
- MITK_INFO << "Writing to " << regionalOutName;
+ std::cout << "Writing to " << regionalOutName;
std::ofstream regionalOutFile( regionalOutName.c_str(), ios::out );
if( ! regionalOutFile.is_open() )
{
std::string errorMessage = "Could not open " + regionalOutName + " for writing.";
MITK_ERROR << errorMessage;
return EXIT_FAILURE;
}
regionalOutFile << regionalHeaderStream.str() << regionalDataStream.str();
regionalOutFile.close();
}
return EXIT_SUCCESS;
}
catch (itk::ExceptionObject e)
{
- MITK_INFO << e;
+ std::cout << e;
return EXIT_FAILURE;
}
catch (std::exception e)
{
- MITK_INFO << e.what();
+ std::cout << e.what();
return EXIT_FAILURE;
}
catch (...)
{
- MITK_INFO << "ERROR!?!";
+ std::cout << "ERROR!?!";
return EXIT_FAILURE;
}
- MITK_INFO << "DONE";
+ std::cout << "DONE";
return EXIT_SUCCESS;
}
-RegisterDiffusionMiniApp(NetworkStatistics);
diff --git a/Modules/DiffusionImaging/MiniApps/PeakExtraction.cpp b/Modules/DiffusionImaging/MiniApps/PeakExtraction.cpp
index c1a0bbad7f..bebbbee478 100755
--- a/Modules/DiffusionImaging/MiniApps/PeakExtraction.cpp
+++ b/Modules/DiffusionImaging/MiniApps/PeakExtraction.cpp
@@ -1,378 +1,374 @@
/*===================================================================
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 "MiniAppManager.h"
-
#include <itkImageFileWriter.h>
#include <itkResampleImageFilter.h>
#include <itkFiniteDiffOdfMaximaExtractionFilter.h>
#include <mitkBaseDataIOFactory.h>
#include <mitkDiffusionImage.h>
#include <mitkQBallImage.h>
#include <mitkImageCast.h>
#include <mitkImageToItk.h>
#include <mitkTensorImage.h>
#include <mitkCoreObjectFactory.h>
-#include "ctkCommandLineParser.h"
+#include "mitkCommandLineParser.h"
#include <itkShCoefficientImageImporter.h>
#include <itkFlipImageFilter.h>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>
#include <mitkIOUtil.h>
mitk::Image::Pointer LoadData(std::string filename)
{
if( filename.empty() )
return NULL;
const std::string s1="", s2="";
std::vector<mitk::BaseData::Pointer> infile = mitk::BaseDataIO::LoadBaseDataFromFile( filename, s1, s2, false );
if( infile.empty() )
{
- MITK_INFO << "File " << filename << " could not be read!";
+ std::cout << "File " << filename << " could not be read!";
return NULL;
}
mitk::BaseData::Pointer baseData = infile.at(0);
return dynamic_cast<mitk::Image*>(baseData.GetPointer());
}
template<int shOrder>
int StartPeakExtraction(int argc, char* argv[])
{
- MITK_INFO << "StartPeakExtraction";
- ctkCommandLineParser parser;
+ mitkCommandLineParser parser;
parser.setArgumentPrefix("--", "-");
- parser.addArgument("image", "i", ctkCommandLineParser::InputFile, "Input image", "sh coefficient image", us::Any(), false);
- parser.addArgument("outroot", "o", ctkCommandLineParser::OutputDirectory, "Output directory", "output root", us::Any(), false);
- parser.addArgument("mask", "m", ctkCommandLineParser::InputFile, "Mask", "mask image");
- parser.addArgument("normalization", "n", ctkCommandLineParser::Int, "Normalization", "0=no norm, 1=max norm, 2=single vec norm", 1, true);
- parser.addArgument("numpeaks", "p", ctkCommandLineParser::Int, "Max. number of peaks", "maximum number of extracted peaks", 2, true);
- parser.addArgument("peakthres", "r", ctkCommandLineParser::Float, "Peak threshold", "peak threshold relative to largest peak", 0.4, true);
- parser.addArgument("abspeakthres", "a", ctkCommandLineParser::Float, "Absolute peak threshold", "absolute peak threshold weighted with local GFA value", 0.06, true);
- parser.addArgument("shConvention", "s", ctkCommandLineParser::String, "Use specified SH-basis", "use specified SH-basis (MITK, FSL, MRtrix)", string("MITK"), true);
- parser.addArgument("noFlip", "f", ctkCommandLineParser::Bool, "No flip", "do not flip input image to match MITK coordinate convention");
+ parser.addArgument("image", "i", mitkCommandLineParser::InputFile, "Input image", "sh coefficient image", us::Any(), false);
+ parser.addArgument("outroot", "o", mitkCommandLineParser::OutputDirectory, "Output directory", "output root", us::Any(), false);
+ parser.addArgument("mask", "m", mitkCommandLineParser::InputFile, "Mask", "mask image");
+ parser.addArgument("normalization", "n", mitkCommandLineParser::Int, "Normalization", "0=no norm, 1=max norm, 2=single vec norm", 1, true);
+ parser.addArgument("numpeaks", "p", mitkCommandLineParser::Int, "Max. number of peaks", "maximum number of extracted peaks", 2, true);
+ parser.addArgument("peakthres", "r", mitkCommandLineParser::Float, "Peak threshold", "peak threshold relative to largest peak", 0.4, true);
+ parser.addArgument("abspeakthres", "a", mitkCommandLineParser::Float, "Absolute peak threshold", "absolute peak threshold weighted with local GFA value", 0.06, true);
+ parser.addArgument("shConvention", "s", mitkCommandLineParser::String, "Use specified SH-basis", "use specified SH-basis (MITK, FSL, MRtrix)", string("MITK"), true);
+ parser.addArgument("noFlip", "f", mitkCommandLineParser::Bool, "No flip", "do not flip input image to match MITK coordinate convention");
parser.setCategory("Preprocessing Tools");
parser.setTitle("Peak Extraction");
parser.setDescription("");
parser.setContributor("MBI");
map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
if (parsedArgs.size()==0)
return EXIT_FAILURE;
// mandatory arguments
string imageName = us::any_cast<string>(parsedArgs["image"]);
string outRoot = us::any_cast<string>(parsedArgs["outroot"]);
// optional arguments
string maskImageName("");
if (parsedArgs.count("mask"))
maskImageName = us::any_cast<string>(parsedArgs["mask"]);
int normalization = 1;
if (parsedArgs.count("normalization"))
normalization = us::any_cast<int>(parsedArgs["normalization"]);
int numPeaks = 2;
if (parsedArgs.count("numpeaks"))
numPeaks = us::any_cast<int>(parsedArgs["numpeaks"]);
float peakThres = 0.4;
if (parsedArgs.count("peakthres"))
peakThres = us::any_cast<float>(parsedArgs["peakthres"]);
float absPeakThres = 0.06;
if (parsedArgs.count("abspeakthres"))
absPeakThres = us::any_cast<float>(parsedArgs["abspeakthres"]);
bool noFlip = false;
if (parsedArgs.count("noFlip"))
noFlip = us::any_cast<bool>(parsedArgs["noFlip"]);
- MITK_INFO << "image: " << imageName;
- MITK_INFO << "outroot: " << outRoot;
+ std::cout << "image: " << imageName;
+ std::cout << "outroot: " << outRoot;
if (!maskImageName.empty())
- MITK_INFO << "mask: " << maskImageName;
+ std::cout << "mask: " << maskImageName;
else
- MITK_INFO << "no mask image selected";
- MITK_INFO << "numpeaks: " << numPeaks;
- MITK_INFO << "peakthres: " << peakThres;
- MITK_INFO << "abspeakthres: " << absPeakThres;
- MITK_INFO << "shOrder: " << shOrder;
+ std::cout << "no mask image selected";
+ std::cout << "numpeaks: " << numPeaks;
+ std::cout << "peakthres: " << peakThres;
+ std::cout << "abspeakthres: " << absPeakThres;
+ std::cout << "shOrder: " << shOrder;
try
{
mitk::Image::Pointer image = LoadData(imageName);
mitk::Image::Pointer mask = LoadData(maskImageName);
typedef itk::Image<unsigned char, 3> ItkUcharImgType;
typedef itk::FiniteDiffOdfMaximaExtractionFilter< float, shOrder, 20242 > MaximaExtractionFilterType;
typename MaximaExtractionFilterType::Pointer filter = MaximaExtractionFilterType::New();
int toolkitConvention = 0;
if (parsedArgs.count("shConvention"))
{
string convention = us::any_cast<string>(parsedArgs["shConvention"]).c_str();
if ( boost::algorithm::equals(convention, "FSL") )
{
toolkitConvention = 1;
- MITK_INFO << "Using FSL SH-basis";
+ std::cout << "Using FSL SH-basis";
}
else if ( boost::algorithm::equals(convention, "MRtrix") )
{
toolkitConvention = 2;
- MITK_INFO << "Using MRtrix SH-basis";
+ std::cout << "Using MRtrix SH-basis";
}
else
- MITK_INFO << "Using MITK SH-basis";
+ std::cout << "Using MITK SH-basis";
}
else
- MITK_INFO << "Using MITK SH-basis";
+ std::cout << "Using MITK SH-basis";
ItkUcharImgType::Pointer itkMaskImage = NULL;
if (mask.IsNotNull())
{
try{
itkMaskImage = ItkUcharImgType::New();
mitk::CastToItkImage(mask, itkMaskImage);
filter->SetMaskImage(itkMaskImage);
}
catch(...)
{
}
}
if (toolkitConvention>0)
{
- MITK_INFO << "Converting coefficient image to MITK format";
+ std::cout << "Converting coefficient image to MITK format";
typedef itk::ShCoefficientImageImporter< float, shOrder > ConverterType;
typedef mitk::ImageToItk< itk::Image< float, 4 > > CasterType;
CasterType::Pointer caster = CasterType::New();
caster->SetInput(image);
caster->Update();
itk::Image< float, 4 >::Pointer itkImage = caster->GetOutput();
typename ConverterType::Pointer converter = ConverterType::New();
if (noFlip)
{
converter->SetInputImage(itkImage);
}
else
{
- MITK_INFO << "Flipping image";
+ std::cout << "Flipping image";
itk::FixedArray<bool, 4> flipAxes;
flipAxes[0] = true;
flipAxes[1] = true;
flipAxes[2] = false;
flipAxes[3] = false;
itk::FlipImageFilter< itk::Image< float, 4 > >::Pointer flipper = itk::FlipImageFilter< itk::Image< float, 4 > >::New();
flipper->SetInput(itkImage);
flipper->SetFlipAxes(flipAxes);
flipper->Update();
itk::Image< float, 4 >::Pointer flipped = flipper->GetOutput();
itk::Matrix< double,4,4 > m = itkImage->GetDirection(); m[0][0] *= -1; m[1][1] *= -1;
flipped->SetDirection(m);
itk::Point< float, 4 > o = itkImage->GetOrigin();
o[0] -= (flipped->GetLargestPossibleRegion().GetSize(0)-1);
o[1] -= (flipped->GetLargestPossibleRegion().GetSize(1)-1);
flipped->SetOrigin(o);
converter->SetInputImage(flipped);
}
- MITK_INFO << "Starting conversion";
+ std::cout << "Starting conversion";
switch (toolkitConvention)
{
case 1:
converter->SetToolkit(ConverterType::FSL);
filter->SetToolkit(MaximaExtractionFilterType::FSL);
break;
case 2:
converter->SetToolkit(ConverterType::MRTRIX);
filter->SetToolkit(MaximaExtractionFilterType::MRTRIX);
break;
default:
converter->SetToolkit(ConverterType::FSL);
filter->SetToolkit(MaximaExtractionFilterType::FSL);
break;
}
converter->GenerateData();
filter->SetInput(converter->GetCoefficientImage());
}
else
{
try{
typedef mitk::ImageToItk< typename MaximaExtractionFilterType::CoefficientImageType > CasterType;
typename CasterType::Pointer caster = CasterType::New();
caster->SetInput(image);
caster->Update();
filter->SetInput(caster->GetOutput());
}
catch(...)
{
- MITK_INFO << "wrong image type";
+ std::cout << "wrong image type";
return EXIT_FAILURE;
}
}
filter->SetMaxNumPeaks(numPeaks);
filter->SetPeakThreshold(peakThres);
filter->SetAbsolutePeakThreshold(absPeakThres);
filter->SetAngularThreshold(1);
switch (normalization)
{
case 0:
filter->SetNormalizationMethod(MaximaExtractionFilterType::NO_NORM);
break;
case 1:
filter->SetNormalizationMethod(MaximaExtractionFilterType::MAX_VEC_NORM);
break;
case 2:
filter->SetNormalizationMethod(MaximaExtractionFilterType::SINGLE_VEC_NORM);
break;
}
- MITK_INFO << "Starting extraction";
+ std::cout << "Starting extraction";
filter->Update();
// write direction images
{
typedef typename MaximaExtractionFilterType::ItkDirectionImageContainer ItkDirectionImageContainer;
typename ItkDirectionImageContainer::Pointer container = filter->GetDirectionImageContainer();
for (unsigned int i=0; i<container->Size(); i++)
{
typename MaximaExtractionFilterType::ItkDirectionImage::Pointer itkImg = container->GetElement(i);
if (itkMaskImage.IsNotNull())
{
itkImg->SetDirection(itkMaskImage->GetDirection());
itkImg->SetOrigin(itkMaskImage->GetOrigin());
}
string outfilename = outRoot;
outfilename.append("_DIRECTION_");
outfilename.append(boost::lexical_cast<string>(i));
outfilename.append(".nrrd");
typedef itk::ImageFileWriter< typename MaximaExtractionFilterType::ItkDirectionImage > WriterType;
typename WriterType::Pointer writer = WriterType::New();
writer->SetFileName(outfilename);
writer->SetInput(itkImg);
writer->Update();
}
}
// write num directions image
{
ItkUcharImgType::Pointer numDirImage = filter->GetNumDirectionsImage();
if (itkMaskImage.IsNotNull())
{
numDirImage->SetDirection(itkMaskImage->GetDirection());
numDirImage->SetOrigin(itkMaskImage->GetOrigin());
}
string outfilename = outRoot.c_str();
outfilename.append("_NUM_DIRECTIONS.nrrd");
typedef itk::ImageFileWriter< ItkUcharImgType > WriterType;
WriterType::Pointer writer = WriterType::New();
writer->SetFileName(outfilename);
writer->SetInput(numDirImage);
writer->Update();
}
// write vector field
{
mitk::FiberBundleX::Pointer directions = filter->GetOutputFiberBundle();
string outfilename = outRoot.c_str();
outfilename.append("_VECTOR_FIELD.fib");
mitk::IOUtil::Save(directions.GetPointer(),outfilename.c_str());
}
}
catch (itk::ExceptionObject e)
{
- MITK_INFO << e;
+ std::cout << e;
return EXIT_FAILURE;
}
catch (std::exception e)
{
- MITK_INFO << e.what();
+ std::cout << e.what();
return EXIT_FAILURE;
}
catch (...)
{
- MITK_INFO << "ERROR!?!";
+ std::cout << "ERROR!?!";
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
-int PeakExtraction(int argc, char* argv[])
+int main(int argc, char* argv[])
{
- ctkCommandLineParser parser;
+ mitkCommandLineParser parser;
parser.setArgumentPrefix("--", "-");
- parser.addArgument("image", "i", ctkCommandLineParser::InputFile, "Input image", "sh coefficient image", us::Any(), false);
- parser.addArgument("shOrder", "sh", ctkCommandLineParser::Int, "Spherical harmonics order", "spherical harmonics order");
- parser.addArgument("outroot", "o", ctkCommandLineParser::OutputDirectory, "Output directory", "output root", us::Any(), false);
- parser.addArgument("mask", "m", ctkCommandLineParser::InputFile, "Mask", "mask image");
- parser.addArgument("normalization", "n", ctkCommandLineParser::Int, "Normalization", "0=no norm, 1=max norm, 2=single vec norm", 1, true);
- parser.addArgument("numpeaks", "p", ctkCommandLineParser::Int, "Max. number of peaks", "maximum number of extracted peaks", 2, true);
- parser.addArgument("peakthres", "r", ctkCommandLineParser::Float, "Peak threshold", "peak threshold relative to largest peak", 0.4, true);
- parser.addArgument("abspeakthres", "a", ctkCommandLineParser::Float, "Absolute peak threshold", "absolute peak threshold weighted with local GFA value", 0.06, true);
- parser.addArgument("shConvention", "s", ctkCommandLineParser::String, "Use specified SH-basis", "use specified SH-basis (MITK, FSL, MRtrix)", string("MITK"), true);
- parser.addArgument("noFlip", "f", ctkCommandLineParser::Bool, "No flip", "do not flip input image to match MITK coordinate convention");
+ parser.addArgument("image", "i", mitkCommandLineParser::InputFile, "Input image", "sh coefficient image", us::Any(), false);
+ parser.addArgument("shOrder", "sh", mitkCommandLineParser::Int, "Spherical harmonics order", "spherical harmonics order");
+ parser.addArgument("outroot", "o", mitkCommandLineParser::OutputDirectory, "Output directory", "output root", us::Any(), false);
+ parser.addArgument("mask", "m", mitkCommandLineParser::InputFile, "Mask", "mask image");
+ parser.addArgument("normalization", "n", mitkCommandLineParser::Int, "Normalization", "0=no norm, 1=max norm, 2=single vec norm", 1, true);
+ parser.addArgument("numpeaks", "p", mitkCommandLineParser::Int, "Max. number of peaks", "maximum number of extracted peaks", 2, true);
+ parser.addArgument("peakthres", "r", mitkCommandLineParser::Float, "Peak threshold", "peak threshold relative to largest peak", 0.4, true);
+ parser.addArgument("abspeakthres", "a", mitkCommandLineParser::Float, "Absolute peak threshold", "absolute peak threshold weighted with local GFA value", 0.06, true);
+ parser.addArgument("shConvention", "s", mitkCommandLineParser::String, "Use specified SH-basis", "use specified SH-basis (MITK, FSL, MRtrix)", string("MITK"), true);
+ parser.addArgument("noFlip", "f", mitkCommandLineParser::Bool, "No flip", "do not flip input image to match MITK coordinate convention");
parser.setCategory("Preprocessing Tools");
parser.setTitle("Peak Extraction");
parser.setDescription("");
parser.setContributor("MBI");
map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
if (parsedArgs.size()==0)
return EXIT_FAILURE;
int shOrder = -1;
if (parsedArgs.count("shOrder"))
shOrder = us::any_cast<int>(parsedArgs["shOrder"]);
switch (shOrder)
{
case 4:
return StartPeakExtraction<4>(argc, argv);
case 6:
return StartPeakExtraction<6>(argc, argv);
case 8:
return StartPeakExtraction<8>(argc, argv);
case 10:
return StartPeakExtraction<10>(argc, argv);
case 12:
return StartPeakExtraction<12>(argc, argv);
}
return EXIT_FAILURE;
}
-RegisterDiffusionMiniApp(PeakExtraction);
diff --git a/Modules/DiffusionImaging/MiniApps/PeaksAngularError.cpp b/Modules/DiffusionImaging/MiniApps/PeaksAngularError.cpp
index 9b5d4bbe10..51a28efe4c 100755
--- a/Modules/DiffusionImaging/MiniApps/PeaksAngularError.cpp
+++ b/Modules/DiffusionImaging/MiniApps/PeaksAngularError.cpp
@@ -1,208 +1,205 @@
/*===================================================================
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 "MiniAppManager.h"
#include <mitkBaseDataIOFactory.h>
#include <mitkBaseData.h>
#include <mitkImageCast.h>
#include <mitkImageToItk.h>
#include <itkEvaluateDirectionImagesFilter.h>
#include <metaCommand.h>
-#include "ctkCommandLineParser.h"
+#include "mitkCommandLineParser.h"
#include <itkTractsToVectorImageFilter.h>
#include <usAny.h>
#include <itkImageFileWriter.h>
#include <mitkIOUtil.h>
#include <boost/lexical_cast.hpp>
#include <iostream>
#include <fstream>
#define _USE_MATH_DEFINES
#include <math.h>
-int PeaksAngularError(int argc, char* argv[])
+int main(int argc, char* argv[])
{
- MITK_INFO << "PeaksAngularError";
- ctkCommandLineParser parser;
+ mitkCommandLineParser parser;
parser.setArgumentPrefix("--", "-");
- parser.addArgument("test", "t", ctkCommandLineParser::StringList, "Test images", "test direction images", us::Any(), false);
- parser.addArgument("reference", "r", ctkCommandLineParser::StringList, "Reference images", "reference direction images", us::Any(), false);
- parser.addArgument("out", "o", ctkCommandLineParser::OutputDirectory, "Output directory", "output root", us::Any(), false);
- parser.addArgument("mask", "m", ctkCommandLineParser::InputFile, "Mask", "mask image");
- parser.addArgument("verbose", "v", ctkCommandLineParser::Bool, "Verbose", "output optional and intermediate calculation results");
- parser.addArgument("ignore", "i", ctkCommandLineParser::Bool, "Ignore", "don't increase error for missing or too many directions");
+ parser.addArgument("test", "t", mitkCommandLineParser::StringList, "Test images", "test direction images", us::Any(), false);
+ parser.addArgument("reference", "r", mitkCommandLineParser::StringList, "Reference images", "reference direction images", us::Any(), false);
+ parser.addArgument("out", "o", mitkCommandLineParser::OutputDirectory, "Output directory", "output root", us::Any(), false);
+ parser.addArgument("mask", "m", mitkCommandLineParser::InputFile, "Mask", "mask image");
+ parser.addArgument("verbose", "v", mitkCommandLineParser::Bool, "Verbose", "output optional and intermediate calculation results");
+ parser.addArgument("ignore", "i", mitkCommandLineParser::Bool, "Ignore", "don't increase error for missing or too many directions");
parser.setCategory("Preprocessing Tools");
parser.setTitle("Peaks Angular Error");
parser.setDescription("");
parser.setContributor("MBI");
map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
if (parsedArgs.size()==0)
return EXIT_FAILURE;
- ctkCommandLineParser::StringContainerType testImages = us::any_cast<ctkCommandLineParser::StringContainerType>(parsedArgs["test"]);
- ctkCommandLineParser::StringContainerType referenceImages = us::any_cast<ctkCommandLineParser::StringContainerType>(parsedArgs["reference"]);
+ mitkCommandLineParser::StringContainerType testImages = us::any_cast<mitkCommandLineParser::StringContainerType>(parsedArgs["test"]);
+ mitkCommandLineParser::StringContainerType referenceImages = us::any_cast<mitkCommandLineParser::StringContainerType>(parsedArgs["reference"]);
string maskImage("");
if (parsedArgs.count("mask"))
maskImage = us::any_cast<string>(parsedArgs["mask"]);
string outRoot = us::any_cast<string>(parsedArgs["out"]);
bool verbose = false;
if (parsedArgs.count("verbose"))
verbose = us::any_cast<bool>(parsedArgs["verbose"]);
bool ignore = false;
if (parsedArgs.count("ignore"))
ignore = us::any_cast<bool>(parsedArgs["ignore"]);
try
{
typedef itk::Image<unsigned char, 3> ItkUcharImgType;
typedef itk::Image< itk::Vector< float, 3>, 3 > ItkDirectionImage3DType;
typedef itk::VectorContainer< unsigned int, ItkDirectionImage3DType::Pointer > ItkDirectionImageContainerType;
typedef itk::EvaluateDirectionImagesFilter< float > EvaluationFilterType;
ItkDirectionImageContainerType::Pointer directionImageContainer = ItkDirectionImageContainerType::New();
for (unsigned int i=0; i<testImages.size(); i++)
{
try
{
mitk::Image::Pointer img = dynamic_cast<mitk::Image*>(mitk::IOUtil::LoadDataNode(testImages.at(i))->GetData());
typedef mitk::ImageToItk< ItkDirectionImage3DType > CasterType;
CasterType::Pointer caster = CasterType::New();
caster->SetInput(img);
caster->Update();
ItkDirectionImage3DType::Pointer itkImg = caster->GetOutput();
directionImageContainer->InsertElement(directionImageContainer->Size(),itkImg);
}
- catch(...){ MITK_INFO << "could not load: " << referenceImages.at(i); }
+ catch(...){ std::cout << "could not load: " << referenceImages.at(i); }
}
// load reference directions
ItkDirectionImageContainerType::Pointer referenceImageContainer = ItkDirectionImageContainerType::New();
for (unsigned int i=0; i<referenceImages.size(); i++)
{
try
{
mitk::Image::Pointer img = dynamic_cast<mitk::Image*>(mitk::IOUtil::LoadDataNode(referenceImages.at(i))->GetData());
typedef mitk::ImageToItk< ItkDirectionImage3DType > CasterType;
CasterType::Pointer caster = CasterType::New();
caster->SetInput(img);
caster->Update();
ItkDirectionImage3DType::Pointer itkImg = caster->GetOutput();
referenceImageContainer->InsertElement(referenceImageContainer->Size(),itkImg);
}
- catch(...){ MITK_INFO << "could not load: " << referenceImages.at(i); }
+ catch(...){ std::cout << "could not load: " << referenceImages.at(i); }
}
// load/create mask image
ItkUcharImgType::Pointer itkMaskImage = ItkUcharImgType::New();
if (maskImage.compare("")==0)
{
ItkDirectionImage3DType::Pointer dirImg = referenceImageContainer->GetElement(0);
itkMaskImage->SetSpacing( dirImg->GetSpacing() );
itkMaskImage->SetOrigin( dirImg->GetOrigin() );
itkMaskImage->SetDirection( dirImg->GetDirection() );
itkMaskImage->SetLargestPossibleRegion( dirImg->GetLargestPossibleRegion() );
itkMaskImage->SetBufferedRegion( dirImg->GetLargestPossibleRegion() );
itkMaskImage->SetRequestedRegion( dirImg->GetLargestPossibleRegion() );
itkMaskImage->Allocate();
itkMaskImage->FillBuffer(1);
}
else
{
mitk::Image::Pointer mitkMaskImage = dynamic_cast<mitk::Image*>(mitk::IOUtil::LoadDataNode(maskImage)->GetData());
mitk::CastToItkImage(mitkMaskImage, itkMaskImage);
}
// evaluate directions
EvaluationFilterType::Pointer evaluationFilter = EvaluationFilterType::New();
evaluationFilter->SetImageSet(directionImageContainer);
evaluationFilter->SetReferenceImageSet(referenceImageContainer);
evaluationFilter->SetMaskImage(itkMaskImage);
evaluationFilter->SetIgnoreMissingDirections(ignore);
evaluationFilter->Update();
if (verbose)
{
EvaluationFilterType::OutputImageType::Pointer angularErrorImage = evaluationFilter->GetOutput(0);
typedef itk::ImageFileWriter< EvaluationFilterType::OutputImageType > WriterType;
WriterType::Pointer writer = WriterType::New();
string outfilename = outRoot;
outfilename.append("_ERROR_IMAGE.nrrd");
writer->SetFileName(outfilename.c_str());
writer->SetInput(angularErrorImage);
writer->Update();
}
string logFile = outRoot;
logFile.append("_ANGULAR_ERROR.csv");
ofstream file;
file.open (logFile.c_str());
string sens = "Mean:";
sens.append(",");
sens.append(boost::lexical_cast<string>(evaluationFilter->GetMeanAngularError()));
sens.append(";\n");
sens.append("Median:");
sens.append(",");
sens.append(boost::lexical_cast<string>(evaluationFilter->GetMedianAngularError()));
sens.append(";\n");
sens.append("Maximum:");
sens.append(",");
sens.append(boost::lexical_cast<string>(evaluationFilter->GetMaxAngularError()));
sens.append(";\n");
sens.append("Minimum:");
sens.append(",");
sens.append(boost::lexical_cast<string>(evaluationFilter->GetMinAngularError()));
sens.append(";\n");
sens.append("STDEV:");
sens.append(",");
sens.append(boost::lexical_cast<string>(std::sqrt(evaluationFilter->GetVarAngularError())));
sens.append(";\n");
file << sens;
file.close();
}
catch (itk::ExceptionObject e)
{
- MITK_INFO << e;
+ std::cout << e;
return EXIT_FAILURE;
}
catch (std::exception e)
{
- MITK_INFO << e.what();
+ std::cout << e.what();
return EXIT_FAILURE;
}
catch (...)
{
- MITK_INFO << "ERROR!?!";
+ std::cout << "ERROR!?!";
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
-RegisterDiffusionMiniApp(PeaksAngularError);
diff --git a/Modules/DiffusionImaging/MiniApps/QballReconstruction.cpp b/Modules/DiffusionImaging/MiniApps/QballReconstruction.cpp
index 68392158d1..65cb7e0e33 100644
--- a/Modules/DiffusionImaging/MiniApps/QballReconstruction.cpp
+++ b/Modules/DiffusionImaging/MiniApps/QballReconstruction.cpp
@@ -1,243 +1,239 @@
/*===================================================================
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 "MiniAppManager.h"
-
#include "mitkBaseDataIOFactory.h"
#include <mitkCoreObjectFactory.h>
#include "mitkDiffusionImage.h"
#include "itkAnalyticalDiffusionQballReconstructionImageFilter.h"
#include <boost/lexical_cast.hpp>
-#include "ctkCommandLineParser.h"
+#include "mitkCommandLineParser.h"
#include <mitkIOUtil.h>
#include <itksys/SystemTools.hxx>
using namespace mitk;
/**
* Perform Q-ball reconstruction using a spherical harmonics basis
*/
-int QballReconstruction(int argc, char* argv[])
+int main(int argc, char* argv[])
{
- MITK_INFO << "QballReconstruction";
- ctkCommandLineParser parser;
+ mitkCommandLineParser parser;
parser.setArgumentPrefix("--", "-");
- parser.addArgument("input", "i", ctkCommandLineParser::InputFile, "Input file", "input raw dwi (.dwi or .fsl/.fslgz)", us::Any(), false);
- parser.addArgument("outFile", "o", ctkCommandLineParser::OutputFile, "Output file", "output file", us::Any(), false);
- parser.addArgument("shOrder", "sh", ctkCommandLineParser::Int, "Spherical harmonics order", "spherical harmonics order", 4, true);
- parser.addArgument("b0Threshold", "t", ctkCommandLineParser::Int, "b0 threshold", "baseline image intensity threshold", 0, true);
- parser.addArgument("lambda", "r", ctkCommandLineParser::Float, "Lambda", "ragularization factor lambda", 0.006, true);
- parser.addArgument("csa", "csa", ctkCommandLineParser::Bool, "Constant solid angle consideration", "use constant solid angle consideration");
- parser.addArgument("outputCoeffs", "shc", ctkCommandLineParser::Bool, "Output coefficients", "output file containing the SH coefficients");
- parser.addArgument("mrtrix", "mb", ctkCommandLineParser::Bool, "MRtrix", "use MRtrix compatible spherical harmonics definition");
+ parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input file", "input raw dwi (.dwi or .fsl/.fslgz)", us::Any(), false);
+ parser.addArgument("outFile", "o", mitkCommandLineParser::OutputFile, "Output file", "output file", us::Any(), false);
+ parser.addArgument("shOrder", "sh", mitkCommandLineParser::Int, "Spherical harmonics order", "spherical harmonics order", 4, true);
+ parser.addArgument("b0Threshold", "t", mitkCommandLineParser::Int, "b0 threshold", "baseline image intensity threshold", 0, true);
+ parser.addArgument("lambda", "r", mitkCommandLineParser::Float, "Lambda", "ragularization factor lambda", 0.006, true);
+ parser.addArgument("csa", "csa", mitkCommandLineParser::Bool, "Constant solid angle consideration", "use constant solid angle consideration");
+ parser.addArgument("outputCoeffs", "shc", mitkCommandLineParser::Bool, "Output coefficients", "output file containing the SH coefficients");
+ parser.addArgument("mrtrix", "mb", mitkCommandLineParser::Bool, "MRtrix", "use MRtrix compatible spherical harmonics definition");
parser.setCategory("Preprocessing Tools");
parser.setTitle("Qball Reconstruction");
parser.setDescription("");
parser.setContributor("MBI");
map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
if (parsedArgs.size()==0)
return EXIT_FAILURE;
std::string inFileName = us::any_cast<string>(parsedArgs["input"]);
std::string outfilename = us::any_cast<string>(parsedArgs["outFile"]);
outfilename = itksys::SystemTools::GetFilenamePath(outfilename)+"/"+itksys::SystemTools::GetFilenameWithoutExtension(outfilename);
int threshold = 0;
if (parsedArgs.count("b0Threshold"))
threshold = us::any_cast<int>(parsedArgs["b0Threshold"]);
int shOrder = 4;
if (parsedArgs.count("shOrder"))
shOrder = us::any_cast<int>(parsedArgs["shOrder"]);
float lambda = 0.006;
if (parsedArgs.count("lambda"))
lambda = us::any_cast<float>(parsedArgs["lambda"]);
int normalization = 0;
if (parsedArgs.count("csa") && us::any_cast<bool>(parsedArgs["csa"]))
normalization = 6;
bool outCoeffs = false;
if (parsedArgs.count("outputCoeffs"))
outCoeffs = us::any_cast<bool>(parsedArgs["outputCoeffs"]);
bool mrTrix = false;
if (parsedArgs.count("mrtrix"))
mrTrix = us::any_cast<bool>(parsedArgs["mrtrix"]);
try
{
const std::string s1="", s2="";
std::vector<BaseData::Pointer> infile = BaseDataIO::LoadBaseDataFromFile( inFileName, s1, s2, false );
DiffusionImage<short>::Pointer dwi = dynamic_cast<DiffusionImage<short>*>(infile.at(0).GetPointer());
dwi->AverageRedundantGradients(0.001);
mitk::QBallImage::Pointer image = mitk::QBallImage::New();
mitk::Image::Pointer coeffsImage = mitk::Image::New();
- MITK_INFO << "SH order: " << shOrder;
- MITK_INFO << "lambda: " << lambda;
- MITK_INFO << "B0 threshold: " << threshold;
+ std::cout << "SH order: " << shOrder;
+ std::cout << "lambda: " << lambda;
+ std::cout << "B0 threshold: " << threshold;
switch ( shOrder )
{
case 4:
{
typedef itk::AnalyticalDiffusionQballReconstructionImageFilter<short,short,float,4,QBALL_ODFSIZE> FilterType;
FilterType::Pointer filter = FilterType::New();
filter->SetGradientImage( dwi->GetDirections(), dwi->GetVectorImage() );
filter->SetBValue(dwi->GetReferenceBValue());
filter->SetThreshold( threshold );
filter->SetLambda(lambda);
filter->SetUseMrtrixBasis(mrTrix);
if (normalization==0)
filter->SetNormalizationMethod(FilterType::QBAR_STANDARD);
else
filter->SetNormalizationMethod(FilterType::QBAR_SOLID_ANGLE);
filter->Update();
image->InitializeByItk( filter->GetOutput() );
image->SetVolume( filter->GetOutput()->GetBufferPointer() );
coeffsImage->InitializeByItk( filter->GetCoefficientImage().GetPointer() );
coeffsImage->SetVolume( filter->GetCoefficientImage()->GetBufferPointer() );
break;
}
case 6:
{
typedef itk::AnalyticalDiffusionQballReconstructionImageFilter<short,short,float,6,QBALL_ODFSIZE> FilterType;
FilterType::Pointer filter = FilterType::New();
filter->SetGradientImage( dwi->GetDirections(), dwi->GetVectorImage() );
filter->SetBValue(dwi->GetReferenceBValue());
filter->SetThreshold( threshold );
filter->SetLambda(lambda);
filter->SetUseMrtrixBasis(mrTrix);
if (normalization==0)
filter->SetNormalizationMethod(FilterType::QBAR_STANDARD);
else
filter->SetNormalizationMethod(FilterType::QBAR_SOLID_ANGLE);
filter->Update();
image->InitializeByItk( filter->GetOutput() );
image->SetVolume( filter->GetOutput()->GetBufferPointer() );
coeffsImage->InitializeByItk( filter->GetCoefficientImage().GetPointer() );
coeffsImage->SetVolume( filter->GetCoefficientImage()->GetBufferPointer() );
break;
}
case 8:
{
typedef itk::AnalyticalDiffusionQballReconstructionImageFilter<short,short,float,8,QBALL_ODFSIZE> FilterType;
FilterType::Pointer filter = FilterType::New();
filter->SetGradientImage( dwi->GetDirections(), dwi->GetVectorImage() );
filter->SetBValue(dwi->GetReferenceBValue());
filter->SetThreshold( threshold );
filter->SetLambda(lambda);
filter->SetUseMrtrixBasis(mrTrix);
if (normalization==0)
filter->SetNormalizationMethod(FilterType::QBAR_STANDARD);
else
filter->SetNormalizationMethod(FilterType::QBAR_SOLID_ANGLE);
filter->Update();
image->InitializeByItk( filter->GetOutput() );
image->SetVolume( filter->GetOutput()->GetBufferPointer() );
coeffsImage->InitializeByItk( filter->GetCoefficientImage().GetPointer() );
coeffsImage->SetVolume( filter->GetCoefficientImage()->GetBufferPointer() );
break;
}
case 10:
{
typedef itk::AnalyticalDiffusionQballReconstructionImageFilter<short,short,float,10,QBALL_ODFSIZE> FilterType;
FilterType::Pointer filter = FilterType::New();
filter->SetGradientImage( dwi->GetDirections(), dwi->GetVectorImage() );
filter->SetBValue(dwi->GetReferenceBValue());
filter->SetThreshold( threshold );
filter->SetLambda(lambda);
filter->SetUseMrtrixBasis(mrTrix);
if (normalization==0)
filter->SetNormalizationMethod(FilterType::QBAR_STANDARD);
else
filter->SetNormalizationMethod(FilterType::QBAR_SOLID_ANGLE);
filter->Update();
image->InitializeByItk( filter->GetOutput() );
image->SetVolume( filter->GetOutput()->GetBufferPointer() );
coeffsImage->InitializeByItk( filter->GetCoefficientImage().GetPointer() );
coeffsImage->SetVolume( filter->GetCoefficientImage()->GetBufferPointer() );
break;
}
case 12:
{
typedef itk::AnalyticalDiffusionQballReconstructionImageFilter<short,short,float,12,QBALL_ODFSIZE> FilterType;
FilterType::Pointer filter = FilterType::New();
filter->SetGradientImage( dwi->GetDirections(), dwi->GetVectorImage() );
filter->SetBValue(dwi->GetReferenceBValue());
filter->SetThreshold( threshold );
filter->SetLambda(lambda);
if (normalization==0)
filter->SetNormalizationMethod(FilterType::QBAR_STANDARD);
else
filter->SetNormalizationMethod(FilterType::QBAR_SOLID_ANGLE);
filter->Update();
image->InitializeByItk( filter->GetOutput() );
image->SetVolume( filter->GetOutput()->GetBufferPointer() );
coeffsImage->InitializeByItk( filter->GetCoefficientImage().GetPointer() );
coeffsImage->SetVolume( filter->GetCoefficientImage()->GetBufferPointer() );
break;
}
default:
{
- MITK_INFO << "Supplied SH order not supported. Using default order of 4.";
+ std::cout << "Supplied SH order not supported. Using default order of 4.";
typedef itk::AnalyticalDiffusionQballReconstructionImageFilter<short,short,float,4,QBALL_ODFSIZE> FilterType;
FilterType::Pointer filter = FilterType::New();
filter->SetGradientImage( dwi->GetDirections(), dwi->GetVectorImage() );
filter->SetBValue(dwi->GetReferenceBValue());
filter->SetThreshold( threshold );
filter->SetLambda(lambda);
filter->SetUseMrtrixBasis(mrTrix);
if (normalization==0)
filter->SetNormalizationMethod(FilterType::QBAR_STANDARD);
else
filter->SetNormalizationMethod(FilterType::QBAR_SOLID_ANGLE);
filter->Update();
image->InitializeByItk( filter->GetOutput() );
image->SetVolume( filter->GetOutput()->GetBufferPointer() );
coeffsImage->InitializeByItk( filter->GetCoefficientImage().GetPointer() );
coeffsImage->SetVolume( filter->GetCoefficientImage()->GetBufferPointer() );
}
}
std::string coeffout = outfilename;
coeffout += "_shcoeffs.nrrd";
outfilename += ".qbi";
mitk::IOUtil::SaveBaseData(image, outfilename);
if (outCoeffs)
mitk::IOUtil::SaveImage(coeffsImage, coeffout);
}
catch ( itk::ExceptionObject &err)
{
- MITK_INFO << "Exception: " << err;
+ std::cout << "Exception: " << err;
}
catch ( std::exception err)
{
- MITK_INFO << "Exception: " << err.what();
+ std::cout << "Exception: " << err.what();
}
catch ( ... )
{
- MITK_INFO << "Exception!";
+ std::cout << "Exception!";
}
return EXIT_SUCCESS;
}
-RegisterDiffusionMiniApp(QballReconstruction);
diff --git a/Modules/DiffusionImaging/MiniApps/StreamlineTracking.cpp b/Modules/DiffusionImaging/MiniApps/StreamlineTracking.cpp
index bdd10f38b0..8bf091d69e 100755
--- a/Modules/DiffusionImaging/MiniApps/StreamlineTracking.cpp
+++ b/Modules/DiffusionImaging/MiniApps/StreamlineTracking.cpp
@@ -1,180 +1,177 @@
/*===================================================================
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 "MiniAppManager.h"
#include <mitkImageCast.h>
#include <mitkTensorImage.h>
#include <mitkIOUtil.h>
#include <mitkBaseDataIOFactory.h>
#include <mitkFiberBundleX.h>
#include <itkStreamlineTrackingFilter.h>
#include <itkDiffusionTensor3D.h>
-#include "ctkCommandLineParser.h"
+#include "mitkCommandLineParser.h"
#include <mitkCoreObjectFactory.h>
-int StreamlineTracking(int argc, char* argv[])
+int main(int argc, char* argv[])
{
- MITK_INFO << "StreamlineTracking";
- ctkCommandLineParser parser;
+ mitkCommandLineParser parser;
parser.setArgumentPrefix("--", "-");
- parser.addArgument("input", "i", ctkCommandLineParser::StringList, "Input image", "input tensor image (.dti)", us::Any(), false);
- parser.addArgument("seed", "si", ctkCommandLineParser::InputFile, "Seed image", "binary seed image", us::Any(), true);
- parser.addArgument("mask", "mi", ctkCommandLineParser::InputFile, "Mask", "binary mask image", us::Any(), true);
- parser.addArgument("faImage", "fai", ctkCommandLineParser::InputFile, "FA image", "FA image", us::Any(), true);
- parser.addArgument("minFA", "fa", ctkCommandLineParser::Float, "Min. FA threshold", "minimum fractional anisotropy threshold", 0.15, true);
- parser.addArgument("minCurv", "c", ctkCommandLineParser::Float, "Min. curvature radius", "minimum curvature radius in mm (default = 0.5*minimum-spacing)");
- parser.addArgument("stepSize", "s", ctkCommandLineParser::Float, "Step size", "step size in mm (default = 0.1*minimum-spacing)");
- parser.addArgument("tendf", "f", ctkCommandLineParser::Float, "Weight f", "Weighting factor between first eigenvector (f=1 equals FACT tracking) and input vector dependent direction (f=0).", 1.0, true);
- parser.addArgument("tendg", "g", ctkCommandLineParser::Float, "Weight g", "Weighting factor between input vector (g=0) and tensor deflection (g=1 equals TEND tracking)", 0.0, true);
- parser.addArgument("numSeeds", "n", ctkCommandLineParser::Int, "Seeds per voxel", "Number of seeds per voxel.", 1, true);
- parser.addArgument("minLength", "l", ctkCommandLineParser::Float, "Min. fiber length", "minimum fiber length in mm", 20, true);
-
- parser.addArgument("interpolate", "ip", ctkCommandLineParser::Bool, "Interpolate", "Use linear interpolation", false, true);
- parser.addArgument("outFile", "o", ctkCommandLineParser::String, "Output file", "output fiber bundle (.fib)", us::Any(), false);
+ parser.addArgument("input", "i", mitkCommandLineParser::StringList, "Input image", "input tensor image (.dti)", us::Any(), false);
+ parser.addArgument("seed", "si", mitkCommandLineParser::InputFile, "Seed image", "binary seed image", us::Any(), true);
+ parser.addArgument("mask", "mi", mitkCommandLineParser::InputFile, "Mask", "binary mask image", us::Any(), true);
+ parser.addArgument("faImage", "fai", mitkCommandLineParser::InputFile, "FA image", "FA image", us::Any(), true);
+ parser.addArgument("minFA", "fa", mitkCommandLineParser::Float, "Min. FA threshold", "minimum fractional anisotropy threshold", 0.15, true);
+ parser.addArgument("minCurv", "c", mitkCommandLineParser::Float, "Min. curvature radius", "minimum curvature radius in mm (default = 0.5*minimum-spacing)");
+ parser.addArgument("stepSize", "s", mitkCommandLineParser::Float, "Step size", "step size in mm (default = 0.1*minimum-spacing)");
+ parser.addArgument("tendf", "f", mitkCommandLineParser::Float, "Weight f", "Weighting factor between first eigenvector (f=1 equals FACT tracking) and input vector dependent direction (f=0).", 1.0, true);
+ parser.addArgument("tendg", "g", mitkCommandLineParser::Float, "Weight g", "Weighting factor between input vector (g=0) and tensor deflection (g=1 equals TEND tracking)", 0.0, true);
+ parser.addArgument("numSeeds", "n", mitkCommandLineParser::Int, "Seeds per voxel", "Number of seeds per voxel.", 1, true);
+ parser.addArgument("minLength", "l", mitkCommandLineParser::Float, "Min. fiber length", "minimum fiber length in mm", 20, true);
+
+ parser.addArgument("interpolate", "ip", mitkCommandLineParser::Bool, "Interpolate", "Use linear interpolation", false, true);
+ parser.addArgument("outFile", "o", mitkCommandLineParser::String, "Output file", "output fiber bundle (.fib)", us::Any(), false);
parser.setCategory("Fiber Tracking and Processing Methods");
parser.setTitle("Streamline Tracking");
parser.setDescription("");
parser.setContributor("MBI");
map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
if (parsedArgs.size()==0)
return EXIT_FAILURE;
- ctkCommandLineParser::StringContainerType inputImages = us::any_cast<ctkCommandLineParser::StringContainerType>(parsedArgs["input"]);
+ mitkCommandLineParser::StringContainerType inputImages = us::any_cast<mitkCommandLineParser::StringContainerType>(parsedArgs["input"]);
string dtiFileName;
string outFileName = us::any_cast<string>(parsedArgs["outFile"]);
float minFA = 0.15;
float minCurv = -1;
float stepSize = -1;
float tendf = 1;
float tendg = 0;
float minLength = 20;
int numSeeds = 1;
bool interpolate = false;
if (parsedArgs.count("minCurv"))
minCurv = us::any_cast<float>(parsedArgs["minCurv"]);
if (parsedArgs.count("minFA"))
minFA = us::any_cast<float>(parsedArgs["minFA"]);
if (parsedArgs.count("stepSize"))
stepSize = us::any_cast<float>(parsedArgs["stepSize"]);
if (parsedArgs.count("tendf"))
tendf = us::any_cast<float>(parsedArgs["tendf"]);
if (parsedArgs.count("tendg"))
tendg = us::any_cast<float>(parsedArgs["tendg"]);
if (parsedArgs.count("minLength"))
minLength = us::any_cast<float>(parsedArgs["minLength"]);
if (parsedArgs.count("numSeeds"))
numSeeds = us::any_cast<int>(parsedArgs["numSeeds"]);
if (parsedArgs.count("interpolate"))
interpolate = us::any_cast<bool>(parsedArgs["interpolate"]);
try
{
typedef itk::StreamlineTrackingFilter< float > FilterType;
FilterType::Pointer filter = FilterType::New();
mitk::Image::Pointer mitkImage = NULL;
- MITK_INFO << "Loading tensor images ...";
+ std::cout << "Loading tensor images ...";
typedef itk::Image< itk::DiffusionTensor3D<float>, 3 > ItkTensorImage;
dtiFileName = inputImages.at(0);
for (unsigned int i=0; i<inputImages.size(); i++)
{
try
{
mitkImage = dynamic_cast<mitk::Image*>(mitk::IOUtil::LoadDataNode(inputImages.at(i))->GetData());
mitk::TensorImage::Pointer img = dynamic_cast<mitk::TensorImage*>(mitk::IOUtil::LoadDataNode(inputImages.at(i))->GetData());
ItkTensorImage::Pointer itk_dti = ItkTensorImage::New();
mitk::CastToItkImage(img, itk_dti);
filter->SetInput(i, itk_dti);
}
- catch(...){ MITK_INFO << "could not load: " << inputImages.at(i); }
+ catch(...){ std::cout << "could not load: " << inputImages.at(i); }
}
- MITK_INFO << "Loading seed image ...";
+ std::cout << "Loading seed image ...";
typedef itk::Image< unsigned char, 3 > ItkUCharImageType;
mitk::Image::Pointer mitkSeedImage = NULL;
if (parsedArgs.count("seed"))
mitkSeedImage = mitk::IOUtil::LoadImage(us::any_cast<string>(parsedArgs["seed"]));
- MITK_INFO << "Loading mask image ...";
+ std::cout << "Loading mask image ...";
mitk::Image::Pointer mitkMaskImage = NULL;
if (parsedArgs.count("mask"))
mitkMaskImage = mitk::IOUtil::LoadImage(us::any_cast<string>(parsedArgs["mask"]));
// instantiate tracker
filter->SetSeedsPerVoxel(numSeeds);
filter->SetFaThreshold(minFA);
filter->SetMinCurvatureRadius(minCurv);
filter->SetStepSize(stepSize);
filter->SetF(tendf);
filter->SetG(tendg);
filter->SetInterpolate(interpolate);
filter->SetMinTractLength(minLength);
if (mitkSeedImage.IsNotNull())
{
ItkUCharImageType::Pointer mask = ItkUCharImageType::New();
mitk::CastToItkImage(mitkSeedImage, mask);
filter->SetSeedImage(mask);
}
if (mitkMaskImage.IsNotNull())
{
ItkUCharImageType::Pointer mask = ItkUCharImageType::New();
mitk::CastToItkImage(mitkMaskImage, mask);
filter->SetMaskImage(mask);
}
filter->Update();
vtkSmartPointer<vtkPolyData> fiberBundle = filter->GetFiberPolyData();
if ( fiberBundle->GetNumberOfLines()==0 )
{
- MITK_INFO << "No fibers reconstructed. Check parametrization.";
+ std::cout << "No fibers reconstructed. Check parametrization.";
return EXIT_FAILURE;
}
mitk::FiberBundleX::Pointer fib = mitk::FiberBundleX::New(fiberBundle);
fib->SetReferenceGeometry(mitkImage->GetGeometry());
mitk::IOUtil::SaveBaseData(fib.GetPointer(), outFileName );
}
catch (itk::ExceptionObject e)
{
- MITK_INFO << e;
+ std::cout << e;
return EXIT_FAILURE;
}
catch (std::exception e)
{
- MITK_INFO << e.what();
+ std::cout << e.what();
return EXIT_FAILURE;
}
catch (...)
{
- MITK_INFO << "ERROR!?!";
+ std::cout << "ERROR!?!";
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
-RegisterDiffusionMiniApp(StreamlineTracking);
diff --git a/Modules/DiffusionImaging/MiniApps/TensorDerivedMapsExtraction.cpp b/Modules/DiffusionImaging/MiniApps/TensorDerivedMapsExtraction.cpp
index 6f4b744a57..5f1b3a55db 100644
--- a/Modules/DiffusionImaging/MiniApps/TensorDerivedMapsExtraction.cpp
+++ b/Modules/DiffusionImaging/MiniApps/TensorDerivedMapsExtraction.cpp
@@ -1,196 +1,191 @@
/*===================================================================
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 "MiniAppManager.h"
#include <mitkIOUtil.h>
#include "mitkImage.h"
#include <mitkImageCast.h>
#include "mitkITKImageImport.h"
#include <iostream>
#include <fstream>
#include <mitkTensorImage.h>
#include <mitkDiffusionImage.h>
#include "itkTensorDerivedMeasurementsFilter.h"
#include "itkDiffusionTensor3DReconstructionImageFilter.h"
-#include "ctkCommandLineParser.h"
+#include "mitkCommandLineParser.h"
#include <itkImageFileWriter.h>
#include <itkNrrdImageIO.h>
#include <itkDiffusionTensor3D.h>
typedef short DiffusionPixelType;
typedef double TTensorPixelType;
static void ExtractMapsAndSave(mitk::TensorImage::Pointer tensorImage, std::string filename, std::string postfix = "")
{
mitk::Image* image = dynamic_cast<mitk::Image*> (tensorImage.GetPointer());
typedef itk::DiffusionTensor3D< TTensorPixelType > TensorPixelType;
typedef itk::Image< TensorPixelType, 3 > TensorImageType;
TensorImageType::Pointer itkvol = TensorImageType::New();
mitk::CastToItkImage(image, itkvol);
typedef itk::TensorDerivedMeasurementsFilter<TTensorPixelType> MeasurementsType;
MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New();
measurementsCalculator->SetInput(itkvol.GetPointer() );
mitk::Image::Pointer map = mitk::Image::New();
// FA
measurementsCalculator->SetMeasure(MeasurementsType::FA);
measurementsCalculator->Update();
map->InitializeByItk( measurementsCalculator->GetOutput() );
map->SetVolume( measurementsCalculator->GetOutput()->GetBufferPointer() );
mitk::IOUtil::SaveImage(map, filename + "_dti_FA" + postfix + ".nrrd");
// MD
measurementsCalculator->SetMeasure(MeasurementsType::MD);
measurementsCalculator->Update();
map->InitializeByItk( measurementsCalculator->GetOutput() );
map->SetVolume( measurementsCalculator->GetOutput()->GetBufferPointer() );
mitk::IOUtil::SaveImage(map, filename + "_dti_MD" + postfix + ".nrrd");
// AD
measurementsCalculator->SetMeasure(MeasurementsType::AD);
measurementsCalculator->Update();
map->InitializeByItk( measurementsCalculator->GetOutput() );
map->SetVolume( measurementsCalculator->GetOutput()->GetBufferPointer() );
mitk::IOUtil::SaveImage(map, filename + "_dti_AD" + postfix + ".nrrd");
// CA
measurementsCalculator->SetMeasure(MeasurementsType::CA);
measurementsCalculator->Update();
map->InitializeByItk( measurementsCalculator->GetOutput() );
map->SetVolume( measurementsCalculator->GetOutput()->GetBufferPointer() );
mitk::IOUtil::SaveImage(map, filename + "_dti_CA" + postfix + ".nrrd");
// RA
measurementsCalculator->SetMeasure(MeasurementsType::RA);
measurementsCalculator->Update();
map->InitializeByItk( measurementsCalculator->GetOutput() );
map->SetVolume( measurementsCalculator->GetOutput()->GetBufferPointer() );
mitk::IOUtil::SaveImage(map, filename + "_dti_RA" + postfix + ".nrrd");
// RD
measurementsCalculator->SetMeasure(MeasurementsType::RD);
measurementsCalculator->Update();
map->InitializeByItk( measurementsCalculator->GetOutput() );
map->SetVolume( measurementsCalculator->GetOutput()->GetBufferPointer() );
mitk::IOUtil::SaveImage(map, filename + "_dti_RD" + postfix + ".nrrd");
}
-int TensorDerivedMapsExtraction(int argc, char* argv[])
+int main(int argc, char* argv[])
{
- MITK_INFO << "TensorDerivedMapsExtraction";
- ctkCommandLineParser parser;
+ std::cout << "TensorDerivedMapsExtraction";
+ mitkCommandLineParser parser;
parser.setArgumentPrefix("--", "-");
- parser.addArgument("help", "h", ctkCommandLineParser::String, "Help", "Show this help text");
- parser.addArgument("input", "i", ctkCommandLineParser::InputFile, "Input file", "input dwi file", us::Any(),false);
- parser.addArgument("out", "o", ctkCommandLineParser::String, "Output folder", "output folder and base name, e.g. /tmp/outPatient1 ", us::Any(),false);
+ parser.addArgument("help", "h", mitkCommandLineParser::String, "Help", "Show this help text");
+ parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input file", "input dwi file", us::Any(),false);
+ parser.addArgument("out", "o", mitkCommandLineParser::String, "Output folder", "output folder and base name, e.g. /tmp/outPatient1 ", us::Any(),false);
parser.setCategory("Diffusion Related Measures");
parser.setTitle("Tensor Derived Maps Extraction");
parser.setDescription("");
parser.setContributor("MBI");
map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
if (parsedArgs.size()==0 || parsedArgs.count("help") || parsedArgs.count("h"))
{
std::cout << "\n\nMiniApp Description: \nPerforms tensor reconstruction on DWI file," << endl;
std::cout << "and computes tensor derived measures." << endl;
std::cout << "\n\n For out parameter /tmp/outPatient1 it will produce :"<< endl;
std::cout << " /tmp/outPatient1_dti.dti , /tmp/outPatient1_dti_FA.nrrd, ..."<< endl;
std::cout << "\n\n Parameters:"<< endl;
std::cout << parser.helpText();
return EXIT_SUCCESS;
}
std::string inputFile = us::any_cast<string>(parsedArgs["input"]);
std::string baseFileName = us::any_cast<string>(parsedArgs["out"]);
std::string dtiFileName = "_dti.dti";
- MITK_INFO << "BaseFileName: " << baseFileName;
+ std::cout << "BaseFileName: " << baseFileName;
mitk::Image::Pointer inputImage = mitk::IOUtil::LoadImage(inputFile);
mitk::DiffusionImage<short>* diffusionImage = static_cast<mitk::DiffusionImage<short>*>(inputImage.GetPointer());
if (diffusionImage == NULL) // does NULL pointer check make sense after static cast ?
{
MITK_ERROR << "Invalid Input Image. Must be DWI. Aborting.";
return -1;
}
mitk::DiffusionImage<DiffusionPixelType>* vols = dynamic_cast <mitk::DiffusionImage<DiffusionPixelType>*> (inputImage.GetPointer());
typedef itk::DiffusionTensor3DReconstructionImageFilter< DiffusionPixelType, DiffusionPixelType, TTensorPixelType > TensorReconstructionImageFilterType;
TensorReconstructionImageFilterType::Pointer tensorReconstructionFilter = TensorReconstructionImageFilterType::New();
typedef mitk::DiffusionImage<DiffusionPixelType> DiffusionImageType;
typedef DiffusionImageType::GradientDirectionContainerType GradientDirectionContainerType;
GradientDirectionContainerType::Pointer gradientContainerCopy = GradientDirectionContainerType::New();
for(GradientDirectionContainerType::ConstIterator it = vols->GetDirections()->Begin(); it != vols->GetDirections()->End(); it++)
{
gradientContainerCopy->push_back(it.Value());
}
tensorReconstructionFilter->SetGradientImage( gradientContainerCopy, vols->GetVectorImage() );
tensorReconstructionFilter->SetBValue(vols->GetReferenceBValue());
tensorReconstructionFilter->SetThreshold(50);
tensorReconstructionFilter->Update();
typedef itk::Image<itk::DiffusionTensor3D<TTensorPixelType>, 3> TensorImageType;
TensorImageType::Pointer tensorImage = tensorReconstructionFilter->GetOutput();
tensorImage->SetDirection( vols->GetVectorImage()->GetDirection() );
mitk::TensorImage::Pointer tensorImageMitk = mitk::TensorImage::New();
tensorImageMitk->InitializeByItk(tensorImage.GetPointer());
tensorImageMitk->SetVolume( tensorImage->GetBufferPointer() );
itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New();
io->SetFileType( itk::ImageIOBase::Binary );
io->UseCompressionOn();
itk::ImageFileWriter< itk::Image< itk::DiffusionTensor3D< double >, 3 > >::Pointer writer = itk::ImageFileWriter< itk::Image< itk::DiffusionTensor3D< double >, 3 > >::New();
writer->SetInput(tensorReconstructionFilter->GetOutput());
writer->SetFileName(baseFileName + dtiFileName);
writer->SetImageIO(io);
writer->UseCompressionOn();
writer->Update();
ExtractMapsAndSave(tensorImageMitk,baseFileName);
return EXIT_SUCCESS;
}
-
-
-
-RegisterDiffusionMiniApp(TensorDerivedMapsExtraction);
diff --git a/Modules/DiffusionImaging/MiniApps/TensorReconstruction.cpp b/Modules/DiffusionImaging/MiniApps/TensorReconstruction.cpp
index e73a4a4d01..2b7968a1fd 100644
--- a/Modules/DiffusionImaging/MiniApps/TensorReconstruction.cpp
+++ b/Modules/DiffusionImaging/MiniApps/TensorReconstruction.cpp
@@ -1,100 +1,98 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
-#include "MiniAppManager.h"
#include "mitkBaseDataIOFactory.h"
#include "mitkDiffusionImage.h"
#include "mitkBaseData.h"
#include <itkDiffusionTensor3DReconstructionImageFilter.h>
#include <itkDiffusionTensor3D.h>
#include <itkImageFileWriter.h>
#include <itkNrrdImageIO.h>
-#include "ctkCommandLineParser.h"
+#include "mitkCommandLineParser.h"
#include <itksys/SystemTools.hxx>
using namespace mitk;
/**
* Convert files from one ending to the other
*/
-int TensorReconstruction(int argc, char* argv[])
+int main(int argc, char* argv[])
{
- MITK_INFO << "TensorReconstruction";
- ctkCommandLineParser parser;
+ std::cout << "TensorReconstruction";
+ mitkCommandLineParser parser;
parser.setArgumentPrefix("--", "-");
- parser.addArgument("input", "i", ctkCommandLineParser::InputFile, "Input file", "input raw dwi (.dwi or .fsl/.fslgz)", us::Any(), false);
- parser.addArgument("outFile", "o", ctkCommandLineParser::OutputFile, "Output file", "output file", us::Any(), false);
- parser.addArgument("b0Threshold", "t", ctkCommandLineParser::Int, "b0 threshold", "baseline image intensity threshold", 0, true);
+ parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input file", "input raw dwi (.dwi or .fsl/.fslgz)", us::Any(), false);
+ parser.addArgument("outFile", "o", mitkCommandLineParser::OutputFile, "Output file", "output file", us::Any(), false);
+ parser.addArgument("b0Threshold", "t", mitkCommandLineParser::Int, "b0 threshold", "baseline image intensity threshold", 0, true);
parser.setCategory("Preprocessing Tools");
parser.setTitle("Tensor Reconstruction");
parser.setDescription("");
parser.setContributor("MBI");
map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
if (parsedArgs.size()==0)
return EXIT_FAILURE;
std::string inFileName = us::any_cast<string>(parsedArgs["input"]);
std::string outfilename = us::any_cast<string>(parsedArgs["outFile"]);
outfilename = itksys::SystemTools::GetFilenamePath(outfilename)+"/"+itksys::SystemTools::GetFilenameWithoutExtension(outfilename);
outfilename += ".dti";
int threshold = 0;
if (parsedArgs.count("b0Threshold"))
threshold = us::any_cast<int>(parsedArgs["b0Threshold"]);
try
{
const std::string s1="", s2="";
std::vector<BaseData::Pointer> infile = BaseDataIO::LoadBaseDataFromFile( inFileName, s1, s2, false );
DiffusionImage<short>::Pointer dwi = dynamic_cast<DiffusionImage<short>*>(infile.at(0).GetPointer());
typedef itk::DiffusionTensor3DReconstructionImageFilter< short, short, float > TensorReconstructionImageFilterType;
TensorReconstructionImageFilterType::Pointer filter = TensorReconstructionImageFilterType::New();
filter->SetGradientImage( dwi->GetDirections(), dwi->GetVectorImage() );
filter->SetBValue(dwi->GetReferenceBValue());
filter->SetThreshold(threshold);
filter->Update();
// Save tensor image
itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New();
io->SetFileType( itk::ImageIOBase::Binary );
io->UseCompressionOn();
itk::ImageFileWriter< itk::Image< itk::DiffusionTensor3D< float >, 3 > >::Pointer writer = itk::ImageFileWriter< itk::Image< itk::DiffusionTensor3D< float >, 3 > >::New();
writer->SetInput(filter->GetOutput());
writer->SetFileName(outfilename);
writer->SetImageIO(io);
writer->UseCompressionOn();
writer->Update();
}
catch ( itk::ExceptionObject &err)
{
- MITK_INFO << "Exception: " << err;
+ std::cout << "Exception: " << err;
}
catch ( std::exception err)
{
- MITK_INFO << "Exception: " << err.what();
+ std::cout << "Exception: " << err.what();
}
catch ( ... )
{
- MITK_INFO << "Exception!";
+ std::cout << "Exception!";
}
return EXIT_SUCCESS;
}
-RegisterDiffusionMiniApp(TensorReconstruction);
diff --git a/Modules/DiffusionImaging/MiniApps/TractometerMetrics.cpp b/Modules/DiffusionImaging/MiniApps/TractometerMetrics.cpp
index 3bc7636c97..0acfa5b28a 100755
--- a/Modules/DiffusionImaging/MiniApps/TractometerMetrics.cpp
+++ b/Modules/DiffusionImaging/MiniApps/TractometerMetrics.cpp
@@ -1,418 +1,415 @@
/*===================================================================
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 "MiniAppManager.h"
#include <mitkBaseDataIOFactory.h>
#include <mitkBaseData.h>
#include <mitkImageCast.h>
#include <mitkImageToItk.h>
#include <itkEvaluateDirectionImagesFilter.h>
#include <metaCommand.h>
-#include "ctkCommandLineParser.h"
+#include "mitkCommandLineParser.h"
#include <itkTractsToVectorImageFilter.h>
#include <usAny.h>
#include <itkImageFileWriter.h>
#include <mitkIOUtil.h>
#include <boost/lexical_cast.hpp>
#include <iostream>
#include <fstream>
#include <itksys/SystemTools.hxx>
#include <mitkCoreObjectFactory.h>
#define _USE_MATH_DEFINES
#include <math.h>
-int TractometerMetrics(int argc, char* argv[])
+int main(int argc, char* argv[])
{
- MITK_INFO << "TractometerMetrics";
- ctkCommandLineParser parser;
+ mitkCommandLineParser parser;
parser.setTitle("Tractometer Metrics");
parser.setCategory("Fiber Tracking and Processing Methods");
parser.setDescription("");
parser.setContributor("MBI");
parser.setArgumentPrefix("--", "-");
- parser.addArgument("input", "i", ctkCommandLineParser::InputFile, "Input:", "input tractogram (.fib, vtk ascii file format)", us::Any(), false);
- parser.addArgument("out", "o", ctkCommandLineParser::OutputDirectory, "Output:", "output root", us::Any(), false);
- parser.addArgument("labels", "l", ctkCommandLineParser::StringList, "Label pairs:", "label pairs", false);
- parser.addArgument("labelimage", "li", ctkCommandLineParser::String, "Label image:", "label image", false);
- parser.addArgument("verbose", "v", ctkCommandLineParser::Bool, "Verbose:", "output valid, invalid and no connections as fiber bundles");
+ parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input:", "input tractogram (.fib, vtk ascii file format)", us::Any(), false);
+ parser.addArgument("out", "o", mitkCommandLineParser::OutputDirectory, "Output:", "output root", us::Any(), false);
+ parser.addArgument("labels", "l", mitkCommandLineParser::StringList, "Label pairs:", "label pairs", false);
+ parser.addArgument("labelimage", "li", mitkCommandLineParser::String, "Label image:", "label image", false);
+ parser.addArgument("verbose", "v", mitkCommandLineParser::Bool, "Verbose:", "output valid, invalid and no connections as fiber bundles");
- parser.addArgument("fileID", "id", ctkCommandLineParser::String, "ID:", "optional ID field");
+ parser.addArgument("fileID", "id", mitkCommandLineParser::String, "ID:", "optional ID field");
map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
if (parsedArgs.size()==0)
return EXIT_FAILURE;
- ctkCommandLineParser::StringContainerType labelpairs = us::any_cast<ctkCommandLineParser::StringContainerType>(parsedArgs["labels"]);
+ mitkCommandLineParser::StringContainerType labelpairs = us::any_cast<mitkCommandLineParser::StringContainerType>(parsedArgs["labels"]);
string fibFile = us::any_cast<string>(parsedArgs["input"]);
string labelImageFile = us::any_cast<string>(parsedArgs["labelimage"]);
string outRoot = us::any_cast<string>(parsedArgs["out"]);
string fileID = "";
if (parsedArgs.count("fileID"))
fileID = us::any_cast<string>(parsedArgs["fileID"]);
bool verbose = false;
if (parsedArgs.count("verbose"))
verbose = us::any_cast<bool>(parsedArgs["verbose"]);
try
{
typedef itk::Image<short, 3> ItkShortImgType;
typedef itk::Image<unsigned char, 3> ItkUcharImgType;
// load fiber bundle
mitk::FiberBundleX::Pointer inputTractogram = dynamic_cast<mitk::FiberBundleX*>(mitk::IOUtil::LoadDataNode(fibFile)->GetData());
mitk::Image::Pointer img = dynamic_cast<mitk::Image*>(mitk::IOUtil::LoadDataNode(labelImageFile)->GetData());
typedef mitk::ImageToItk< ItkShortImgType > CasterType;
CasterType::Pointer caster = CasterType::New();
caster->SetInput(img);
caster->Update();
ItkShortImgType::Pointer labelImage = caster->GetOutput();
string path = itksys::SystemTools::GetFilenamePath(labelImageFile);
std::vector< bool > detected;
std::vector< std::pair< int, int > > labelsvector;
std::vector< ItkUcharImgType::Pointer > bundleMasks;
std::vector< ItkUcharImgType::Pointer > bundleMasksCoverage;
short max = 0;
for (unsigned int i=0; i<labelpairs.size()-1; i+=2)
{
std::pair< short, short > l;
l.first = boost::lexical_cast<short>(labelpairs.at(i));
l.second = boost::lexical_cast<short>(labelpairs.at(i+1));
- MITK_INFO << labelpairs.at(i);
- MITK_INFO << labelpairs.at(i+1);
+ std::cout << labelpairs.at(i);
+ std::cout << labelpairs.at(i+1);
if (l.first>max)
max=l.first;
if (l.second>max)
max=l.second;
labelsvector.push_back(l);
detected.push_back(false);
{
mitk::Image::Pointer img = dynamic_cast<mitk::Image*>(mitk::IOUtil::LoadDataNode(path+"/Bundle"+boost::lexical_cast<string>(labelsvector.size())+"_MASK.nrrd")->GetData());
typedef mitk::ImageToItk< ItkUcharImgType > CasterType;
CasterType::Pointer caster = CasterType::New();
caster->SetInput(img);
caster->Update();
ItkUcharImgType::Pointer bundle = caster->GetOutput();
bundleMasks.push_back(bundle);
}
{
mitk::Image::Pointer img = dynamic_cast<mitk::Image*>(mitk::IOUtil::LoadDataNode(path+"/Bundle"+boost::lexical_cast<string>(labelsvector.size())+"_MASK_COVERAGE.nrrd")->GetData());
typedef mitk::ImageToItk< ItkUcharImgType > CasterType;
CasterType::Pointer caster = CasterType::New();
caster->SetInput(img);
caster->Update();
ItkUcharImgType::Pointer bundle = caster->GetOutput();
bundleMasksCoverage.push_back(bundle);
}
}
vnl_matrix< unsigned char > matrix; matrix.set_size(max, max); matrix.fill(0);
vtkSmartPointer<vtkPolyData> polyData = inputTractogram->GetFiberPolyData();
int validConnections = 0;
int noConnection = 0;
int validBundles = 0;
int invalidBundles = 0;
int invalidConnections = 0;
ItkUcharImgType::Pointer coverage = ItkUcharImgType::New();
coverage->SetSpacing(labelImage->GetSpacing());
coverage->SetOrigin(labelImage->GetOrigin());
coverage->SetDirection(labelImage->GetDirection());
coverage->SetLargestPossibleRegion(labelImage->GetLargestPossibleRegion());
coverage->SetBufferedRegion( labelImage->GetLargestPossibleRegion() );
coverage->SetRequestedRegion( labelImage->GetLargestPossibleRegion() );
coverage->Allocate();
coverage->FillBuffer(0);
vtkSmartPointer<vtkPoints> noConnPoints = vtkSmartPointer<vtkPoints>::New();
vtkSmartPointer<vtkCellArray> noConnCells = vtkSmartPointer<vtkCellArray>::New();
vtkSmartPointer<vtkPoints> invalidPoints = vtkSmartPointer<vtkPoints>::New();
vtkSmartPointer<vtkCellArray> invalidCells = vtkSmartPointer<vtkCellArray>::New();
vtkSmartPointer<vtkPoints> validPoints = vtkSmartPointer<vtkPoints>::New();
vtkSmartPointer<vtkCellArray> validCells = vtkSmartPointer<vtkCellArray>::New();
boost::progress_display disp(inputTractogram->GetNumFibers());
for (int i=0; i<inputTractogram->GetNumFibers(); i++)
{
++disp;
vtkCell* cell = polyData->GetCell(i);
int numPoints = cell->GetNumberOfPoints();
vtkPoints* points = cell->GetPoints();
if (numPoints>1)
{
double* start = points->GetPoint(0);
itk::Point<float, 3> itkStart;
itkStart[0] = start[0]; itkStart[1] = start[1]; itkStart[2] = start[2];
itk::Index<3> idxStart;
labelImage->TransformPhysicalPointToIndex(itkStart, idxStart);
double* end = points->GetPoint(numPoints-1);
itk::Point<float, 3> itkEnd;
itkEnd[0] = end[0]; itkEnd[1] = end[1]; itkEnd[2] = end[2];
itk::Index<3> idxEnd;
labelImage->TransformPhysicalPointToIndex(itkEnd, idxEnd);
if ( labelImage->GetPixel(idxStart)==0 || labelImage->GetPixel(idxEnd)==0 )
{
noConnection++;
if (verbose)
{
vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
for (int j=0; j<numPoints; j++)
{
double* p = points->GetPoint(j);
vtkIdType id = noConnPoints->InsertNextPoint(p);
container->GetPointIds()->InsertNextId(id);
}
noConnCells->InsertNextCell(container);
}
}
else
{
bool invalid = true;
for (unsigned int i=0; i<labelsvector.size(); i++)
{
bool outside = false;
ItkUcharImgType::Pointer bundle = bundleMasks.at(i);
std::pair< short, short > l = labelsvector.at(i);
if ( (labelImage->GetPixel(idxStart)==l.first && labelImage->GetPixel(idxEnd)==l.second) ||
(labelImage->GetPixel(idxStart)==l.second && labelImage->GetPixel(idxEnd)==l.first) )
{
for (int j=0; j<numPoints; j++)
{
double* p = points->GetPoint(j);
itk::Point<float, 3> itkP;
itkP[0] = p[0]; itkP[1] = p[1]; itkP[2] = p[2];
itk::Index<3> idx;
bundle->TransformPhysicalPointToIndex(itkP, idx);
if ( !bundle->GetPixel(idx)>0 && bundle->GetLargestPossibleRegion().IsInside(idx) )
{
outside=true;
}
}
if (!outside)
{
validConnections++;
if (detected.at(i)==false)
validBundles++;
detected.at(i) = true;
invalid = false;
vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
for (int j=0; j<numPoints; j++)
{
double* p = points->GetPoint(j);
vtkIdType id = validPoints->InsertNextPoint(p);
container->GetPointIds()->InsertNextId(id);
itk::Point<float, 3> itkP;
itkP[0] = p[0]; itkP[1] = p[1]; itkP[2] = p[2];
itk::Index<3> idx;
coverage->TransformPhysicalPointToIndex(itkP, idx);
if ( coverage->GetLargestPossibleRegion().IsInside(idx) )
coverage->SetPixel(idx, 1);
}
validCells->InsertNextCell(container);
}
break;
}
}
if (invalid==true)
{
invalidConnections++;
int x = labelImage->GetPixel(idxStart)-1;
int y = labelImage->GetPixel(idxEnd)-1;
if (x>=0 && y>0 && x<matrix.cols() && y<matrix.rows() && (matrix[x][y]==0 || matrix[y][x]==0) )
{
invalidBundles++;
matrix[x][y]=1;
matrix[y][x]=1;
}
if (verbose)
{
vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
for (int j=0; j<numPoints; j++)
{
double* p = points->GetPoint(j);
vtkIdType id = invalidPoints->InsertNextPoint(p);
container->GetPointIds()->InsertNextId(id);
}
invalidCells->InsertNextCell(container);
}
}
}
}
}
if (verbose)
{
mitk::CoreObjectFactory::FileWriterList fileWriters = mitk::CoreObjectFactory::GetInstance()->GetFileWriters();
vtkSmartPointer<vtkPolyData> noConnPolyData = vtkSmartPointer<vtkPolyData>::New();
noConnPolyData->SetPoints(noConnPoints);
noConnPolyData->SetLines(noConnCells);
mitk::FiberBundleX::Pointer noConnFib = mitk::FiberBundleX::New(noConnPolyData);
string ncfilename = outRoot;
ncfilename.append("_NC.fib");
mitk::IOUtil::SaveBaseData(noConnFib.GetPointer(), ncfilename );
vtkSmartPointer<vtkPolyData> invalidPolyData = vtkSmartPointer<vtkPolyData>::New();
invalidPolyData->SetPoints(invalidPoints);
invalidPolyData->SetLines(invalidCells);
mitk::FiberBundleX::Pointer invalidFib = mitk::FiberBundleX::New(invalidPolyData);
string icfilename = outRoot;
icfilename.append("_IC.fib");
mitk::IOUtil::SaveBaseData(invalidFib.GetPointer(), icfilename );
vtkSmartPointer<vtkPolyData> validPolyData = vtkSmartPointer<vtkPolyData>::New();
validPolyData->SetPoints(validPoints);
validPolyData->SetLines(validCells);
mitk::FiberBundleX::Pointer validFib = mitk::FiberBundleX::New(validPolyData);
string vcfilename = outRoot;
vcfilename.append("_VC.fib");
mitk::IOUtil::SaveBaseData(validFib.GetPointer(), vcfilename );
{
typedef itk::ImageFileWriter< ItkUcharImgType > WriterType;
WriterType::Pointer writer = WriterType::New();
writer->SetFileName(outRoot+"_ABC.nrrd");
writer->SetInput(coverage);
writer->Update();
}
}
// calculate coverage
int wmVoxels = 0;
int coveredVoxels = 0;
itk::ImageRegionIterator<ItkUcharImgType> it (coverage, coverage->GetLargestPossibleRegion());
while(!it.IsAtEnd())
{
bool wm = false;
for (unsigned int i=0; i<bundleMasksCoverage.size(); i++)
{
ItkUcharImgType::Pointer bundle = bundleMasksCoverage.at(i);
if (bundle->GetPixel(it.GetIndex())>0)
{
wm = true;
wmVoxels++;
break;
}
}
if (wm && it.Get()>0)
coveredVoxels++;
++it;
}
int numFibers = inputTractogram->GetNumFibers();
double nc = (double)noConnection/numFibers;
double vc = (double)validConnections/numFibers;
double ic = (double)invalidConnections/numFibers;
if (numFibers==0)
{
nc = 0.0;
vc = 0.0;
ic = 0.0;
}
int vb = validBundles;
int ib = invalidBundles;
double abc = (double)coveredVoxels/wmVoxels;
- MITK_INFO << "NC: " << nc;
- MITK_INFO << "VC: " << vc;
- MITK_INFO << "IC: " << ic;
- MITK_INFO << "VB: " << vb;
- MITK_INFO << "IB: " << ib;
- MITK_INFO << "ABC: " << abc;
+ std::cout << "NC: " << nc;
+ std::cout << "VC: " << vc;
+ std::cout << "IC: " << ic;
+ std::cout << "VB: " << vb;
+ std::cout << "IB: " << ib;
+ std::cout << "ABC: " << abc;
string logFile = outRoot;
logFile.append("_TRACTOMETER.csv");
ofstream file;
file.open (logFile.c_str());
{
string sens = itksys::SystemTools::GetFilenameWithoutLastExtension(fibFile);
if (!fileID.empty())
sens = fileID;
sens.append(",");
sens.append(boost::lexical_cast<string>(nc));
sens.append(",");
sens.append(boost::lexical_cast<string>(vc));
sens.append(",");
sens.append(boost::lexical_cast<string>(ic));
sens.append(",");
sens.append(boost::lexical_cast<string>(validBundles));
sens.append(",");
sens.append(boost::lexical_cast<string>(invalidBundles));
sens.append(",");
sens.append(boost::lexical_cast<string>(abc));
sens.append(";\n");
file << sens;
}
file.close();
}
catch (itk::ExceptionObject e)
{
- MITK_INFO << e;
+ std::cout << e;
return EXIT_FAILURE;
}
catch (std::exception e)
{
- MITK_INFO << e.what();
+ std::cout << e.what();
return EXIT_FAILURE;
}
catch (...)
{
- MITK_INFO << "ERROR!?!";
+ std::cout << "ERROR!?!";
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
-RegisterDiffusionMiniApp(TractometerMetrics);
diff --git a/Modules/DiffusionImaging/MiniApps/files.cmake b/Modules/DiffusionImaging/MiniApps/files.cmake
deleted file mode 100644
index d662c60a19..0000000000
--- a/Modules/DiffusionImaging/MiniApps/files.cmake
+++ /dev/null
@@ -1,33 +0,0 @@
-set(CPP_FILES
- mitkDiffusionMiniApps.cpp
- MiniAppManager.cpp
-
- BatchedFolderRegistration.cpp
- DicomFolderDump.cpp
- FileFormatConverter.cpp
- TensorReconstruction.cpp
- TensorDerivedMapsExtraction.cpp
- QballReconstruction.cpp
- DiffusionIndices.cpp
- ExtractImageStatistics.cpp
- CopyGeometry.cpp
- GibbsTracking.cpp
- StreamlineTracking.cpp
- FiberProcessing.cpp
- LocalDirectionalFiberPlausibility.cpp
- #TractogramAngularError.cpp
- FiberDirectionExtraction.cpp
- ImageResampler.cpp
- PeakExtraction.cpp
- PeaksAngularError.cpp
- MultishellMethods.cpp
- Fiberfox.cpp
- ExportShImage.cpp
- NetworkCreation.cpp
- NetworkStatistics.cpp
- DwiDenoising.cpp
- FiberExtraction.cpp
- FiberJoin.cpp
- DICOMLoader.cpp
- TractometerMetrics.cpp
-)
diff --git a/Modules/DiffusionImaging/MiniApps/ctkCommandLineParser.cpp b/Modules/DiffusionImaging/MiniApps/mitkCommandLineParser.cpp
similarity index 83%
rename from Modules/DiffusionImaging/MiniApps/ctkCommandLineParser.cpp
rename to Modules/DiffusionImaging/MiniApps/mitkCommandLineParser.cpp
index 355c22d404..71db4fc8bd 100755
--- a/Modules/DiffusionImaging/MiniApps/ctkCommandLineParser.cpp
+++ b/Modules/DiffusionImaging/MiniApps/mitkCommandLineParser.cpp
@@ -1,881 +1,893 @@
/*===================================================================
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.
===================================================================*/
/*=========================================================================
Library: CTK
Copyright (c) Kitware Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
// STL includes
#include <stdexcept>
+#include <iostream>
-// CTK includes
-#include "ctkCommandLineParser.h"
+// MITK includes
+#include "mitkCommandLineParser.h"
+
using namespace std;
namespace
{
// --------------------------------------------------------------------------
class CommandLineParserArgumentDescription
{
public:
CommandLineParserArgumentDescription(
const string& longArg, const string& longArgPrefix,
const string& shortArg, const string& shortArgPrefix,
- ctkCommandLineParser::Type type, const string& argHelp, const string& argLabel,
+ mitkCommandLineParser::Type type, const string& argHelp, const string& argLabel,
const us::Any& defaultValue, bool ignoreRest,
bool deprecated, bool optional, string& argGroup, string& groupDescription)
: LongArg(longArg), LongArgPrefix(longArgPrefix),
ShortArg(shortArg), ShortArgPrefix(shortArgPrefix),
ArgHelp(argHelp), ArgLabel(argLabel), IgnoreRest(ignoreRest), NumberOfParametersToProcess(0),
Deprecated(deprecated), DefaultValue(defaultValue), Value(type), ValueType(type), Optional(optional), ArgGroup(argGroup), ArgGroupDescription(groupDescription)
{
Value = defaultValue;
switch (type)
{
- case ctkCommandLineParser::String:
+ case mitkCommandLineParser::String:
{
NumberOfParametersToProcess = 1;
}
break;
- case ctkCommandLineParser::Bool:
+ case mitkCommandLineParser::Bool:
{
NumberOfParametersToProcess = 0;
}
break;
- case ctkCommandLineParser::StringList:
+ case mitkCommandLineParser::StringList:
{
NumberOfParametersToProcess = -1;
}
break;
- case ctkCommandLineParser::Int:
+ case mitkCommandLineParser::Int:
{
NumberOfParametersToProcess = 1;
}
break;
- case ctkCommandLineParser::Float:
+ case mitkCommandLineParser::Float:
{
NumberOfParametersToProcess = 1;
}
break;
- case ctkCommandLineParser::OutputDirectory:
- case ctkCommandLineParser::InputDirectory:
+ case mitkCommandLineParser::OutputDirectory:
+ case mitkCommandLineParser::InputDirectory:
{
NumberOfParametersToProcess = 1;
}
break;
- case ctkCommandLineParser::OutputFile:
- case ctkCommandLineParser::InputFile:
+ case mitkCommandLineParser::OutputFile:
+ case mitkCommandLineParser::InputFile:
{
NumberOfParametersToProcess = 1;
}
break;
+ case mitkCommandLineParser::InputImage:
+ {
+ NumberOfParametersToProcess = 1;
+ }
+ break;
default:
- MITK_INFO << "Type not supported: " << static_cast<int>(type);
+ std::cout << "Type not supported: " << static_cast<int>(type);
}
}
~CommandLineParserArgumentDescription(){}
bool addParameter(const string& value);
string helpText();
string LongArg;
string LongArgPrefix;
string ShortArg;
string ShortArgPrefix;
string ArgHelp;
string ArgLabel;
string ArgGroup;
string ArgGroupDescription;
bool IgnoreRest;
int NumberOfParametersToProcess;
bool Deprecated;
bool Optional;
us::Any DefaultValue;
us::Any Value;
- ctkCommandLineParser::Type ValueType;
+ mitkCommandLineParser::Type ValueType;
};
// --------------------------------------------------------------------------
bool CommandLineParserArgumentDescription::addParameter(const string &value)
{
switch (ValueType)
{
- case ctkCommandLineParser::String:
+ case mitkCommandLineParser::String:
{
Value = value;
}
break;
- case ctkCommandLineParser::Bool:
+ case mitkCommandLineParser::Bool:
{
if (value.compare("true")==0)
Value = true;
else
Value = false;
}
break;
- case ctkCommandLineParser::StringList:
+ case mitkCommandLineParser::StringList:
{
try
{
- ctkCommandLineParser::StringContainerType list = us::any_cast<ctkCommandLineParser::StringContainerType>(Value);
+ mitkCommandLineParser::StringContainerType list = us::any_cast<mitkCommandLineParser::StringContainerType>(Value);
list.push_back(value);
Value = list;
}
catch(...)
{
- ctkCommandLineParser::StringContainerType list;
+ mitkCommandLineParser::StringContainerType list;
list.push_back(value);
Value = list;
}
}
break;
- case ctkCommandLineParser::Int:
+ case mitkCommandLineParser::Int:
{
stringstream ss(value);
int i;
ss >> i;
Value = i;
}
break;
- case ctkCommandLineParser::Float:
+ case mitkCommandLineParser::Float:
{
stringstream ss(value);
float f;
ss >> f;
Value = f;
}
break;
- case ctkCommandLineParser::InputDirectory:
- case ctkCommandLineParser::OutputDirectory:
+ case mitkCommandLineParser::InputDirectory:
+ case mitkCommandLineParser::OutputDirectory:
{
Value = value;
}
break;
- case ctkCommandLineParser::InputFile:
- case ctkCommandLineParser::OutputFile:
+ case mitkCommandLineParser::InputFile:
+ case mitkCommandLineParser::InputImage:
+ case mitkCommandLineParser::OutputFile:
{
Value = value;
}
break;
default:
return false;
}
return true;
}
// --------------------------------------------------------------------------
string CommandLineParserArgumentDescription::helpText()
{
string text;
string shortAndLongArg;
if (!this->ShortArg.empty())
{
shortAndLongArg = " ";
shortAndLongArg += this->ShortArgPrefix;
shortAndLongArg += this->ShortArg;
}
if (!this->LongArg.empty())
{
if (this->ShortArg.empty())
shortAndLongArg.append(" ");
else
shortAndLongArg.append(", ");
shortAndLongArg += this->LongArgPrefix;
shortAndLongArg += this->LongArg;
}
text = text + shortAndLongArg + ", " + this->ArgHelp;
if (this->Optional)
text += " (optional)";
if (!this->DefaultValue.Empty())
{
text = text + ", (default: " + this->DefaultValue.ToString() + ")";
}
text += "\n";
return text;
}
}
// --------------------------------------------------------------------------
// ctkCommandLineParser::ctkInternal class
// --------------------------------------------------------------------------
-class ctkCommandLineParser::ctkInternal
+class mitkCommandLineParser::ctkInternal
{
public:
ctkInternal()
: Debug(false), FieldWidth(0), StrictMode(false)
{}
~ctkInternal() { }
CommandLineParserArgumentDescription* argumentDescription(const string& argument);
vector<CommandLineParserArgumentDescription*> ArgumentDescriptionList;
map<string, CommandLineParserArgumentDescription*> ArgNameToArgumentDescriptionMap;
map<string, vector<CommandLineParserArgumentDescription*> > GroupToArgumentDescriptionListMap;
StringContainerType UnparsedArguments;
StringContainerType ProcessedArguments;
string ErrorString;
bool Debug;
int FieldWidth;
string LongPrefix;
string ShortPrefix;
string CurrentGroup;
string DisableQSettingsLongArg;
string DisableQSettingsShortArg;
bool StrictMode;
};
// --------------------------------------------------------------------------
// ctkCommandLineParser::ctkInternal methods
// --------------------------------------------------------------------------
CommandLineParserArgumentDescription*
-ctkCommandLineParser::ctkInternal::argumentDescription(const string& argument)
+mitkCommandLineParser::ctkInternal::argumentDescription(const string& argument)
{
string unprefixedArg = argument;
if (!LongPrefix.empty() && argument.compare(0, LongPrefix.size(), LongPrefix)==0)
{
// Case when (ShortPrefix + UnPrefixedArgument) matches LongPrefix
if (argument == LongPrefix && !ShortPrefix.empty() && argument.compare(0, ShortPrefix.size(), ShortPrefix)==0)
{
unprefixedArg = argument.substr(ShortPrefix.size(),argument.size());
}
else
{
unprefixedArg = argument.substr(LongPrefix.size(),argument.size());
}
}
else if (!ShortPrefix.empty() && argument.compare(0, ShortPrefix.size(), ShortPrefix)==0)
{
unprefixedArg = argument.substr(ShortPrefix.size(),argument.size());
}
else if (!LongPrefix.empty() && !ShortPrefix.empty())
{
return 0;
}
if (ArgNameToArgumentDescriptionMap.count(unprefixedArg))
{
return this->ArgNameToArgumentDescriptionMap[unprefixedArg];
}
return 0;
}
// --------------------------------------------------------------------------
// ctkCommandLineParser methods
// --------------------------------------------------------------------------
-ctkCommandLineParser::ctkCommandLineParser()
+mitkCommandLineParser::mitkCommandLineParser()
{
this->Internal = new ctkInternal();
this->Category = string();
this->Title = string();
this->Contributor = string();
this->Description = string();
this->ParameterGroupName = "Parameters";
this->ParameterGroupDescription = "Groupbox containing parameters.";
}
// --------------------------------------------------------------------------
-ctkCommandLineParser::~ctkCommandLineParser()
+mitkCommandLineParser::~mitkCommandLineParser()
{
delete this->Internal;
}
// --------------------------------------------------------------------------
-map<string, us::Any> ctkCommandLineParser::parseArguments(const StringContainerType& arguments,
+map<string, us::Any> mitkCommandLineParser::parseArguments(const StringContainerType& arguments,
bool* ok)
{
// Reset
this->Internal->UnparsedArguments.clear();
this->Internal->ProcessedArguments.clear();
this->Internal->ErrorString.clear();
// foreach (CommandLineParserArgumentDescription* desc, this->Internal->ArgumentDescriptionList)
for (unsigned int i=0; i<Internal->ArgumentDescriptionList.size(); i++)
{
CommandLineParserArgumentDescription* desc = Internal->ArgumentDescriptionList.at(i);
desc->Value = us::Any(desc->ValueType);
if (!desc->DefaultValue.Empty())
{
desc->Value = desc->DefaultValue;
}
}
bool error = false;
bool ignoreRest = false;
CommandLineParserArgumentDescription * currentArgDesc = 0;
vector<CommandLineParserArgumentDescription*> parsedArgDescriptions;
for(unsigned int i = 1; i < arguments.size(); ++i)
{
string argument = arguments.at(i);
- if (this->Internal->Debug) { MITK_DEBUG << "Processing" << argument; }
+ if (this->Internal->Debug) { std::cout << "Processing" << argument; }
if (!argument.compare("--xml") || !argument.compare("-xml") || !argument.compare("--XML") || !argument.compare("-XML"))
{
this->generateXmlOutput();
return map<string, us::Any>();
}
// should argument be ignored ?
if (ignoreRest)
{
if (this->Internal->Debug)
{
- MITK_DEBUG << " Skipping: IgnoreRest flag was been set";
+ std::cout << " Skipping: IgnoreRest flag was been set";
}
this->Internal->UnparsedArguments.push_back(argument);
continue;
}
// Skip if the argument does not start with the defined prefix
if (!(argument.compare(0, Internal->LongPrefix.size(), Internal->LongPrefix)==0
|| argument.compare(0, Internal->ShortPrefix.size(), Internal->ShortPrefix)==0))
{
if (this->Internal->StrictMode)
{
this->Internal->ErrorString = "Unknown argument ";
this->Internal->ErrorString += argument;
error = true;
break;
}
if (this->Internal->Debug)
{
- MITK_DEBUG << " Skipping: It does not start with the defined prefix";
+ std::cout << " Skipping: It does not start with the defined prefix";
}
this->Internal->UnparsedArguments.push_back(argument);
continue;
}
// Skip if argument has already been parsed ...
bool alreadyProcessed = false;
for (unsigned int i=0; i<Internal->ProcessedArguments.size(); i++)
if (argument.compare(Internal->ProcessedArguments.at(i))==0)
{
alreadyProcessed = true;
break;
}
if (alreadyProcessed)
{
if (this->Internal->StrictMode)
{
this->Internal->ErrorString = "Argument ";
this->Internal->ErrorString += argument;
this->Internal->ErrorString += " already processed !";
error = true;
break;
}
if (this->Internal->Debug)
{
- MITK_DEBUG << " Skipping: Already processed !";
+ std::cout << " Skipping: Already processed !";
}
continue;
}
// Retrieve corresponding argument description
currentArgDesc = this->Internal->argumentDescription(argument);
// Is there a corresponding argument description ?
if (currentArgDesc)
{
// If the argument is deprecated, print the help text but continue processing
if (currentArgDesc->Deprecated)
{
- MITK_WARN << "Deprecated argument " << argument << ": " << currentArgDesc->ArgHelp;
+ std::cout << "Deprecated argument " << argument << ": " << currentArgDesc->ArgHelp;
}
else
{
parsedArgDescriptions.push_back(currentArgDesc);
}
this->Internal->ProcessedArguments.push_back(currentArgDesc->ShortArg);
this->Internal->ProcessedArguments.push_back(currentArgDesc->LongArg);
int numberOfParametersToProcess = currentArgDesc->NumberOfParametersToProcess;
ignoreRest = currentArgDesc->IgnoreRest;
if (this->Internal->Debug && ignoreRest)
{
- MITK_DEBUG << " IgnoreRest flag is True";
+ std::cout << " IgnoreRest flag is True";
}
// Is the number of parameters associated with the argument being processed known ?
if (numberOfParametersToProcess == 0)
{
currentArgDesc->addParameter("true");
}
else if (numberOfParametersToProcess > 0)
{
string missingParameterError =
"Argument %1 has %2 value(s) associated whereas exacly %3 are expected.";
for(int j=1; j <= numberOfParametersToProcess; ++j)
{
if (i + j >= arguments.size())
{
// this->Internal->ErrorString =
// missingParameterError.arg(argument).arg(j-1).arg(numberOfParametersToProcess);
-// if (this->Internal->Debug) { MITK_DEBUG << this->Internal->ErrorString; }
+// if (this->Internal->Debug) { std::cout << this->Internal->ErrorString; }
if (ok) { *ok = false; }
return map<string, us::Any>();
}
string parameter = arguments.at(i + j);
if (this->Internal->Debug)
{
- MITK_DEBUG << " Processing parameter" << j << ", value:" << parameter;
+ std::cout << " Processing parameter" << j << ", value:" << parameter;
}
if (this->argumentAdded(parameter))
{
// this->Internal->ErrorString =
// missingParameterError.arg(argument).arg(j-1).arg(numberOfParametersToProcess);
-// if (this->Internal->Debug) { MITK_DEBUG << this->Internal->ErrorString; }
+// if (this->Internal->Debug) { std::cout << this->Internal->ErrorString; }
if (ok) { *ok = false; }
return map<string, us::Any>();
}
if (!currentArgDesc->addParameter(parameter))
{
// this->Internal->ErrorString = string(
// "Value(s) associated with argument %1 are incorrect. %2").
// arg(argument).arg(currentArgDesc->ExactMatchFailedMessage);
-// if (this->Internal->Debug) { MITK_DEBUG << this->Internal->ErrorString; }
+// if (this->Internal->Debug) { std::cout << this->Internal->ErrorString; }
if (ok) { *ok = false; }
return map<string, us::Any>();
}
}
// Update main loop increment
i = i + numberOfParametersToProcess;
}
else if (numberOfParametersToProcess == -1)
{
if (this->Internal->Debug)
{
- MITK_DEBUG << " Proccessing StringList ...";
+ std::cout << " Proccessing StringList ...";
}
int j = 1;
while(j + i < arguments.size())
{
if (this->argumentAdded(arguments.at(j + i)))
{
if (this->Internal->Debug)
{
- MITK_DEBUG << " No more parameter for" << argument;
+ std::cout << " No more parameter for" << argument;
}
break;
}
string parameter = arguments.at(j + i);
if (parameter.compare(0, Internal->LongPrefix.size(), Internal->LongPrefix)==0
|| parameter.compare(0, Internal->ShortPrefix.size(), Internal->ShortPrefix)==0)
{
j--;
break;
}
if (this->Internal->Debug)
{
- MITK_DEBUG << " Processing parameter" << j << ", value:" << parameter;
+ std::cout << " Processing parameter" << j << ", value:" << parameter;
}
if (!currentArgDesc->addParameter(parameter))
{
// this->Internal->ErrorString = string(
// "Value(s) associated with argument %1 are incorrect. %2").
// arg(argument).arg(currentArgDesc->ExactMatchFailedMessage);
-// if (this->Internal->Debug) { MITK_DEBUG << this->Internal->ErrorString; }
+// if (this->Internal->Debug) { std::cout << this->Internal->ErrorString; }
if (ok) { *ok = false; }
return map<string, us::Any>();
}
j++;
}
// Update main loop increment
i = i + j;
}
}
else
{
if (this->Internal->StrictMode)
{
this->Internal->ErrorString = "Unknown argument ";
this->Internal->ErrorString += argument;
error = true;
break;
}
if (this->Internal->Debug)
{
- MITK_DEBUG << " Skipping: Unknown argument";
+ std::cout << " Skipping: Unknown argument";
}
this->Internal->UnparsedArguments.push_back(argument);
}
}
if (ok)
{
*ok = !error;
}
map<string, us::Any> parsedArguments;
int obligatoryArgs = 0;
vector<CommandLineParserArgumentDescription*>::iterator it;
for(it = Internal->ArgumentDescriptionList.begin(); it != Internal->ArgumentDescriptionList.end();++it)
{
CommandLineParserArgumentDescription* desc = *it;
if(!desc->Optional)
obligatoryArgs++;
}
int parsedObligatoryArgs = 0;
for(it = parsedArgDescriptions.begin(); it != parsedArgDescriptions.end();++it)
{
CommandLineParserArgumentDescription* desc = *it;
string key;
if (!desc->LongArg.empty())
{
key = desc->LongArg;
}
else
{
key = desc->ShortArg;
}
if(!desc->Optional)
parsedObligatoryArgs++;
std::pair<string, us::Any> elem; elem.first = key; elem.second = desc->Value;
parsedArguments.insert(elem);
}
if (obligatoryArgs>parsedObligatoryArgs)
{
parsedArguments.clear();
cout << helpText();
}
return parsedArguments;
}
// -------------------------------------------------------------------------
-map<string, us::Any> ctkCommandLineParser::parseArguments(int argc, char** argv, bool* ok)
+map<string, us::Any> mitkCommandLineParser::parseArguments(int argc, char** argv, bool* ok)
{
StringContainerType arguments;
// Create a StringContainerType of arguments
for(int i = 0; i < argc; ++i)
arguments.push_back(argv[i]);
return this->parseArguments(arguments, ok);
}
// -------------------------------------------------------------------------
-string ctkCommandLineParser::errorString() const
+string mitkCommandLineParser::errorString() const
{
return this->Internal->ErrorString;
}
// -------------------------------------------------------------------------
-const ctkCommandLineParser::StringContainerType& ctkCommandLineParser::unparsedArguments() const
+const mitkCommandLineParser::StringContainerType& mitkCommandLineParser::unparsedArguments() const
{
return this->Internal->UnparsedArguments;
}
// --------------------------------------------------------------------------
-void ctkCommandLineParser::addArgument(const string& longarg, const string& shortarg,
+void mitkCommandLineParser::addArgument(const string& longarg, const string& shortarg,
Type type, const string& argLabel, const string& argHelp,
const us::Any& defaultValue, bool optional, bool ignoreRest,
bool deprecated)
{
if (longarg.empty() && shortarg.empty()) { return; }
/* Make sure it's not already added */
bool added = this->Internal->ArgNameToArgumentDescriptionMap.count(longarg);
if (added) { return; }
added = this->Internal->ArgNameToArgumentDescriptionMap.count(shortarg);
if (added) { return; }
CommandLineParserArgumentDescription* argDesc =
new CommandLineParserArgumentDescription(longarg, this->Internal->LongPrefix,
shortarg, this->Internal->ShortPrefix, type,
argHelp, argLabel, defaultValue, ignoreRest, deprecated, optional, ParameterGroupName, ParameterGroupDescription);
int argWidth = 0;
if (!longarg.empty())
{
this->Internal->ArgNameToArgumentDescriptionMap[longarg] = argDesc;
argWidth += longarg.size() + this->Internal->LongPrefix.size();
}
if (!shortarg.empty())
{
this->Internal->ArgNameToArgumentDescriptionMap[shortarg] = argDesc;
argWidth += shortarg.size() + this->Internal->ShortPrefix.size() + 2;
}
argWidth += 5;
// Set the field width for the arguments
if (argWidth > this->Internal->FieldWidth)
{
this->Internal->FieldWidth = argWidth;
}
this->Internal->ArgumentDescriptionList.push_back(argDesc);
this->Internal->GroupToArgumentDescriptionListMap[this->Internal->CurrentGroup].push_back(argDesc);
}
// --------------------------------------------------------------------------
-void ctkCommandLineParser::addDeprecatedArgument(
+void mitkCommandLineParser::addDeprecatedArgument(
const string& longarg, const string& shortarg, const string& argLabel, const string& argHelp)
{
addArgument(longarg, shortarg, StringList, argLabel, argHelp, us::Any(), false, true, false);
}
// --------------------------------------------------------------------------
-int ctkCommandLineParser::fieldWidth() const
+int mitkCommandLineParser::fieldWidth() const
{
return this->Internal->FieldWidth;
}
// --------------------------------------------------------------------------
-void ctkCommandLineParser::beginGroup(const string& description)
+void mitkCommandLineParser::beginGroup(const string& description)
{
this->Internal->CurrentGroup = description;
}
// --------------------------------------------------------------------------
-void ctkCommandLineParser::endGroup()
+void mitkCommandLineParser::endGroup()
{
this->Internal->CurrentGroup.clear();
}
// --------------------------------------------------------------------------
-string ctkCommandLineParser::helpText() const
+string mitkCommandLineParser::helpText() const
{
string text;
vector<CommandLineParserArgumentDescription*> deprecatedArgs;
// Loop over grouped argument descriptions
map<string, vector<CommandLineParserArgumentDescription*> >::iterator it;
for(it = Internal->GroupToArgumentDescriptionListMap.begin(); it != Internal->GroupToArgumentDescriptionListMap.end();++it)
{
if (!(*it).first.empty())
{
text = text + "\n" + (*it).first + "\n";
}
vector<CommandLineParserArgumentDescription*>::iterator it2;
for(it2 = (*it).second.begin(); it2 != (*it).second.end(); ++it2)
{
CommandLineParserArgumentDescription* argDesc = *it2;
if (argDesc->Deprecated)
{
deprecatedArgs.push_back(argDesc);
}
else
{
text += argDesc->helpText();
}
}
}
if (!deprecatedArgs.empty())
{
text += "\nDeprecated arguments:\n";
vector<CommandLineParserArgumentDescription*>::iterator it2;
for(it2 = deprecatedArgs.begin(); it2 != deprecatedArgs.end(); ++it2)
{
CommandLineParserArgumentDescription* argDesc = *it2;
text += argDesc->helpText();
}
}
return text;
}
// --------------------------------------------------------------------------
-bool ctkCommandLineParser::argumentAdded(const string& argument) const
+bool mitkCommandLineParser::argumentAdded(const string& argument) const
{
return this->Internal->ArgNameToArgumentDescriptionMap.count(argument);
}
// --------------------------------------------------------------------------
-bool ctkCommandLineParser::argumentParsed(const string& argument) const
+bool mitkCommandLineParser::argumentParsed(const string& argument) const
{
for (unsigned int i=0; i<Internal->ProcessedArguments.size(); i++)
if (argument.compare(Internal->ProcessedArguments.at(i))==0)
return true;
return false;
}
// --------------------------------------------------------------------------
-void ctkCommandLineParser::setArgumentPrefix(const string& longPrefix, const string& shortPrefix)
+void mitkCommandLineParser::setArgumentPrefix(const string& longPrefix, const string& shortPrefix)
{
this->Internal->LongPrefix = longPrefix;
this->Internal->ShortPrefix = shortPrefix;
}
// --------------------------------------------------------------------------
-void ctkCommandLineParser::setStrictModeEnabled(bool strictMode)
+void mitkCommandLineParser::setStrictModeEnabled(bool strictMode)
{
this->Internal->StrictMode = strictMode;
}
-void ctkCommandLineParser::generateXmlOutput()
+void mitkCommandLineParser::generateXmlOutput()
{
std::stringstream xml;
xml << "<executable>" << endl;
xml << "<category>" << Category << "</category>" << endl;
xml << "<title>" << Title <<"</title>" << endl;
xml << "<description>" << Description << "</description>" << endl;
xml << "<contributor>" << Contributor << "</contributor>" << endl;
xml << "<parameters>" << endl;
std::vector<CommandLineParserArgumentDescription*>::iterator it;
std::string lastParameterGroup = "";
for (it = this->Internal->ArgumentDescriptionList.begin(); it != this->Internal->ArgumentDescriptionList.end(); it++)
{
std::string type;
switch ((*it)->ValueType)
{
- case ctkCommandLineParser::String:
+ case mitkCommandLineParser::String:
type = "string";
break;
- case ctkCommandLineParser::Bool:
+ case mitkCommandLineParser::Bool:
type = "boolean";
break;
- case ctkCommandLineParser::StringList:
+ case mitkCommandLineParser::StringList:
type = "string-vector";
break;
- case ctkCommandLineParser::Int:
+ case mitkCommandLineParser::Int:
type = "integer";
break;
- case ctkCommandLineParser::Float:
+ case mitkCommandLineParser::Float:
type = "float";
break;
- case ctkCommandLineParser::OutputDirectory:
- case ctkCommandLineParser::InputDirectory:
+ case mitkCommandLineParser::OutputDirectory:
+ case mitkCommandLineParser::InputDirectory:
type = "directory";
break;
- case ctkCommandLineParser::OutputFile:
- case ctkCommandLineParser::InputFile:
+ case mitkCommandLineParser::InputImage:
+ type = "image";
+ break;
+
+ case mitkCommandLineParser::OutputFile:
+ case mitkCommandLineParser::InputFile:
type = "file";
break;
}
if (lastParameterGroup.compare((*it)->ArgGroup))
{
if (it != this->Internal->ArgumentDescriptionList.begin())
{
xml << "</parameters>" << endl;
xml << "<parameters>" << endl;
}
xml << "<label>" << (*it)->ArgGroup << "</label>" << endl;
xml << "<description>" << (*it)->ArgGroupDescription << "</description>" << endl;
lastParameterGroup = (*it)->ArgGroup;
}
xml << "<" << type << ">" << endl;
xml << "<name>" << (*it)->LongArg << "</name>" << endl;
xml << "<label>" << (*it)->ArgLabel << "</label>" << endl;
xml << "<description>" << (*it)->ArgHelp << "</description>" << endl;
xml << "<longflag>" << (*it)->LongArg << "</longflag>" << endl;
xml << "<flag>" << (*it)->ShortArg << "</flag>" << endl;
- if ((*it)->ValueType == ctkCommandLineParser::InputDirectory || (*it)->ValueType == ctkCommandLineParser::InputFile)
+ if ((*it)->ValueType == mitkCommandLineParser::InputDirectory || (*it)->ValueType == mitkCommandLineParser::InputFile || (*it)->ValueType == mitkCommandLineParser::InputImage)
{
xml << "<channel>input</channel>" << endl;
}
- else if ((*it)->ValueType == ctkCommandLineParser::OutputDirectory || (*it)->ValueType == ctkCommandLineParser::OutputFile)
+ else if ((*it)->ValueType == mitkCommandLineParser::OutputDirectory || (*it)->ValueType == mitkCommandLineParser::OutputFile)
{
xml << "<channel>output</channel>" << endl;
}
xml << "</" << type << ">" << endl;
}
xml << "</parameters>" << endl;
xml << "</executable>" << endl;
cout << xml.str();
}
-void ctkCommandLineParser::setTitle(string title)
+void mitkCommandLineParser::setTitle(string title)
{
Title = title;
}
-void ctkCommandLineParser::setContributor(string contributor)
+void mitkCommandLineParser::setContributor(string contributor)
{
Contributor = contributor;
}
-void ctkCommandLineParser::setCategory(string category)
+void mitkCommandLineParser::setCategory(string category)
{
Category = category;
}
-void ctkCommandLineParser::setDescription(string description)
+void mitkCommandLineParser::setDescription(string description)
{
Description = description;
}
-void ctkCommandLineParser::changeParameterGroup(string name, string tooltip)
+void mitkCommandLineParser::changeParameterGroup(string name, string tooltip)
{
ParameterGroupName = name;
ParameterGroupDescription = tooltip;
}
diff --git a/Modules/DiffusionImaging/MiniApps/ctkCommandLineParser.h b/Modules/DiffusionImaging/MiniApps/mitkCommandLineParser.h
similarity index 98%
rename from Modules/DiffusionImaging/MiniApps/ctkCommandLineParser.h
rename to Modules/DiffusionImaging/MiniApps/mitkCommandLineParser.h
index e6e0a356d0..763b43be04 100755
--- a/Modules/DiffusionImaging/MiniApps/ctkCommandLineParser.h
+++ b/Modules/DiffusionImaging/MiniApps/mitkCommandLineParser.h
@@ -1,474 +1,475 @@
/*===================================================================
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.
===================================================================*/
/*=========================================================================
Library: CTK
Copyright (c) Kitware Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================================================*/
-#ifndef __ctkCommandLineParser_h
-#define __ctkCommandLineParser_h
+#ifndef __mitkCommandLineParser_h
+#define __mitkCommandLineParser_h
#include <usAny.h>
#include <map>
/**
* \ingroup Core
*
* The CTK command line parser.
*
* Use this class to add information about the command line arguments
* your program understands and to easily parse them from a given list
* of strings.
*
* This parser provides the following features:
*
* <ul>
* <li>Add arguments by supplying a long name and/or a short name.
* Arguments are validated using a regular expression. They can have
* a default value and a help string.</li>
* <li>Deprecated arguments.</li>
* <li>Custom regular expressions for argument validation.</li>
* <li>Set different argument name prefixes for native platform look and feel.</li>
* <li>QSettings support. Default values for arguments can be read from
* a QSettings object.</li>
* <li>Create a help text for the command line arguments with support for
* grouping arguments.</li>
* </ul>
*
* Here is an example how to use this class inside a main function:
*
* \code
* #include <ctkCommandLineParser.h>
* #include <QCoreApplication>
* #include <QTextStream>
*
* int main(int argc, char** argv)
* {
* QCoreApplication app(argc, argv);
* // This is used by QSettings
* QCoreApplication::setOrganizationName("MyOrg");
* QCoreApplication::setApplicationName("MyApp");
*
* ctkCommandLineParser parser;
* // Use Unix-style argument names
* parser.setArgumentPrefix("--", "-");
* // Enable QSettings support
* parser.enableSettings("disable-settings");
*
* // Add command line argument names
* parser.addArgument("disable-settings", "", us::Any::Bool, "Do not use QSettings");
* parser.addArgument("help", "h", us::Any::Bool, "Show this help text");
* parser.addArgument("search-paths", "s", us::Any::StringList, "A list of paths to search");
*
* // Parse the command line arguments
* bool ok = false;
* map<string, us::Any> parsedArgs = parser.parseArguments(QCoreApplication::arguments(), &ok);
* if (!ok)
* {
* QTextStream(stderr, QIODevice::WriteOnly) << "Error parsing arguments: "
* << parser.errorString() << "\n";
* return EXIT_FAILURE;
* }
*
* // Show a help message
* if (parsedArgs.contains("help") || parsedArgs.contains("h"))
* {
* QTextStream(stdout, QIODevice::WriteOnly) << parser.helpText();
* return EXIT_SUCCESS;
* }
*
* // Do something
*
* return EXIT_SUCCESS;
* }
* \endcode
*/
using namespace std;
-class ctkCommandLineParser
+class mitkCommandLineParser
{
public:
enum Type {
String = 0,
Bool = 1,
StringList = 2,
Int = 3,
Float = 4,
InputDirectory = 5,
InputFile = 6,
OutputDirectory = 7,
- OutputFile = 8
+ OutputFile = 8,
+ InputImage = 9
};
typedef std::vector< std::string > StringContainerType;
/**
* Constructs a parser instance.
*
* If QSettings support is enabled by a call to <code>enableSettings()</code>
* a default constructed QSettings instance will be used when parsing
* the command line arguments. Make sure to call <code>QCoreApplication::setOrganizationName()</code>
* and <code>QCoreApplication::setApplicationName()</code> before using default
* constructed QSettings objects.
*
* @param newParent The QObject parent.
*/
- ctkCommandLineParser();
+ mitkCommandLineParser();
- ~ctkCommandLineParser();
+ ~mitkCommandLineParser();
/**
* Parse a given list of command line arguments.
*
* This method parses a list of string elements considering the known arguments
* added by calls to <code>addArgument()</code>. If any one of the argument
* values does not match the corresponding regular expression,
* <code>ok</code> is set to false and an empty map object is returned.
*
* The keys in the returned map object correspond to the long argument string,
* if it is not empty. Otherwise, the short argument string is used as key. The
* us::Any values can safely be converted to the type specified in the
* <code>addArgument()</code> method call.
*
* @param arguments A StringContainerType containing command line arguments. Usually
* given by <code>QCoreApplication::arguments()</code>.
* @param ok A pointer to a boolean variable. Will be set to <code>true</code>
* if all regular expressions matched, <code>false</code> otherwise.
* @return A map object mapping the long argument (if empty, the short one)
* to a us::Any containing the value.
*/
map<string, us::Any> parseArguments(const StringContainerType &arguments, bool* ok = 0);
/**
* Convenient method allowing to parse a given list of command line arguments.
* @see parseArguments(const StringContainerType &, bool*)
*/
map<string, us::Any> parseArguments(int argc, char** argv, bool* ok = 0);
/**
* Returns a detailed error description if a call to <code>parseArguments()</code>
* failed.
*
* @return The error description, empty if no error occured.
* @see parseArguments(const StringContainerType&, bool*)
*/
string errorString() const;
/**
* This method returns all unparsed arguments, i.e. all arguments
* for which no long or short name has been registered via a call
* to <code>addArgument()</code>.
*
* @see addArgument()
*
* @return A list containing unparsed arguments.
*/
const StringContainerType& unparsedArguments() const;
/**
* Checks if the given argument has been added via a call
* to <code>addArgument()</code>.
*
* @see addArgument()
*
* @param argument The argument to be checked.
* @return <code>true</code> if the argument was added, <code>false</code>
* otherwise.
*/
bool argumentAdded(const string& argument) const;
/**
* Checks if the given argument has been parsed successfully by a previous
* call to <code>parseArguments()</code>.
*
* @param argument The argument to be checked.
* @return <code>true</code> if the argument was parsed, <code>false</code>
* otherwise.
*/
bool argumentParsed(const string& argument) const;
/**
* Adds a command line argument. An argument can have a long name
* (like --long-argument-name), a short name (like -l), or both. The type
* of the argument can be specified by using the <code>type</code> parameter.
* The following types are supported:
*
* <table>
* <tr><td><b>Type</b></td><td><b># of parameters</b></td><td><b>Default regular expr</b></td>
* <td><b>Example</b></td></tr>
* <tr><td>us::Any::String</td><td>1</td><td>.*</td><td>--test-string StringParameter</td></tr>
* <tr><td>us::Any::Bool</td><td>0</td><td>does not apply</td><td>--enable-something</td></tr>
* <tr><td>us::Any::StringList</td><td>-1</td><td>.*</td><td>--test-list string1 string2</td></tr>
* <tr><td>us::Any::Int</td><td>1</td><td>-?[0-9]+</td><td>--test-int -5</td></tr>
* </table>
*
* The regular expressions are used to validate the parameters of command line
* arguments. You can restrict the valid set of parameters by calling
* <code>setExactMatchRegularExpression()</code> for your argument.
*
* Optionally, a help string and a default value can be provided for the argument. If
* the us::Any type of the default value does not match <code>type</code>, an
* exception is thrown. Arguments with default values are always returned by
* <code>parseArguments()</code>.
*
* You can also declare an argument deprecated, by setting <code>deprecated</code>
* to <code>true</code>. Alternatively you can add a deprecated argument by calling
* <code>addDeprecatedArgument()</code>.
*
* If the long or short argument has already been added, or if both are empty strings,
* the method call has no effect.
*
* @param longarg The long argument name.
* @param shortarg The short argument name.
* @param type The argument type (see the list above for supported types).
* @param argLabel The label of this argument, when auto generated interface is used.
* @param argHelp A help string describing the argument.
* @param defaultValue A default value for the argument.
* @param ignoreRest All arguments after the current one will be ignored.
* @param deprecated Declares the argument deprecated.
*
* @see setExactMatchRegularExpression()
* @see addDeprecatedArgument()
* @throws std::logic_error If the us::Any type of <code>defaultValue</code>
* does not match <code>type</code>, a <code>std::logic_error</code> is thrown.
*/
void addArgument(const string& longarg, const string& shortarg,
Type type, const string& argLabel, const string& argHelp = string(),
const us::Any& defaultValue = us::Any(), bool optional=true,
bool ignoreRest = false, bool deprecated = false);
/**
* Adds a deprecated command line argument. If a deprecated argument is provided
* on the command line, <code>argHelp</code> is displayed in the console and
* processing continues with the next argument.
*
* Deprecated arguments are grouped separately at the end of the help text
* returned by <code>helpText()</code>.
*
* @param longarg The long argument name.
* @param shortarg The short argument name.
* @param argHelp A help string describing alternatives to the deprecated argument.
*/
void addDeprecatedArgument(const string& longarg, const string& shortarg, const string& argLabel,
const string& argHelp);
/**
* Sets a custom regular expression for validating argument parameters. The method
* <code>errorString()</code> can be used the get the last error description.
*
* @param argument The previously added long or short argument name.
* @param expression A regular expression which the arugment parameters must match.
* @param exactMatchFailedMessage An error message explaining why the parameter did
* not match.
*
* @return <code>true</code> if the argument was found and the regular expression was set,
* <code>false</code> otherwise.
*
* @see errorString()
*/
bool setExactMatchRegularExpression(const string& argument, const string& expression,
const string& exactMatchFailedMessage);
/**
* The field width for the argument names without the help text.
*
* @return The argument names field width in the help text.
*/
int fieldWidth() const;
/**
* Creates a help text containing properly formatted argument names and help strings
* provided by calls to <code>addArgument()</code>. The arguments can be grouped by
* using <code>beginGroup()</code> and <code>endGroup()</code>.
*
* @param charPad The padding character.
* @return The formatted help text.
*/
string helpText() const;
/**
* Sets the argument prefix for long and short argument names. This can be used
* to create native command line arguments without changing the calls to
* <code>addArgument()</code>. For example on Unix-based systems, long argument
* names start with "--" and short names with "-", while on Windows argument names
* always start with "/".
*
* Note that all methods in ctkCommandLineParser which take an argument name
* expect the name as it was supplied to <code>addArgument</code>.
*
* Example usage:
*
* \code
* ctkCommandLineParser parser;
* parser.setArgumentPrefix("--", "-");
* parser.addArgument("long-argument", "l", us::Any::String);
* StringContainerType args;
* args << "program name" << "--long-argument Hi";
* parser.parseArguments(args);
* \endcode
*
* @param longPrefix The prefix for long argument names.
* @param shortPrefix The prefix for short argument names.
*/
void setArgumentPrefix(const string& longPrefix, const string& shortPrefix);
/**
* Begins a new group for documenting arguments. All newly added arguments via
* <code>addArgument()</code> will be put in the new group. You can close the
* current group by calling <code>endGroup()</code> or be opening a new group.
*
* Note that groups cannot be nested and all arguments which do not belong to
* a group will be listed at the top of the text created by <code>helpText()</code>.
*
* @param description The description of the group
*/
void beginGroup(const string& description);
/**
* Ends the current group.
*
* @see beginGroup(const string&)
*/
void endGroup();
/**
* Enables QSettings support in ctkCommandLineParser. If an argument name is found
* in the QSettings instance with a valid us::Any, the value is considered as
* a default value and overwrites default values registered with
* <code>addArgument()</code>. User supplied values on the command line overwrite
* values in the QSettings instance, except for arguments with multiple parameters
* which are merged with QSettings values. Call <code>mergeSettings(false)</code>
* to disable merging.
*
* See <code>ctkCommandLineParser(QSettings*)</code> for information about how to
* supply a QSettings instance.
*
* Additionally, a long and short argument name can be specified which will disable
* QSettings support if supplied on the command line. The argument name must be
* registered as a regular argument via <code>addArgument()</code>.
*
* @param disableLongArg Long argument name.
* @param disableShortArg Short argument name.
*
* @see ctkCommandLineParser(QSettings*)
*/
void enableSettings(const string& disableLongArg = "",
const string& disableShortArg = "");
/**
* Controlls the merging behavior of user values and QSettings values.
*
* If merging is on (the default), user supplied values for an argument
* which can take more than one parameter are merged with values stored
* in the QSettings instance. If merging is off, the user values overwrite
* the QSettings values.
*
* @param merge <code>true</code> enables QSettings merging, <code>false</code>
* disables it.
*/
void mergeSettings(bool merge);
/**
* Can be used to check if QSettings support has been enabled by a call to
* <code>enableSettings()</code>.
*
* @return <code>true</code> if QSettings support is enabled, <code>false</code>
* otherwise.
*/
bool settingsEnabled() const;
/**
* Can be used to teach the parser to stop parsing the arguments and return False when
* an unknown argument is encountered. By default <code>StrictMode</code> is disabled.
*
* @see parseArguments(const StringContainerType &, bool*)
*/
void setStrictModeEnabled(bool strictMode);
/**
* Is used to generate an XML output for any commandline program.
*/
void generateXmlOutput();
/**
* Is used to set the title of the auto generated interface.
*
* @param title The title of the app.
*/
void setTitle(std::string title);
/**
* Is used to set the contributor for the help view in the auto generated interface.
*
* @param contributor Contributor of the app.
*/
void setContributor(std::string contributor);
/**
* Is used to categorize the apps in the commandline module.
*
* @param category The category of the app.
*/
void setCategory(std::string category);
/**
* Is used as the help text in the auto generated interface.
*
* @param description A short description for the app.
*/
void setDescription(std::string description);
/**
* Is used to group several Parameters in one groupbox in the auto generated interface.
* Default name is "Parameters", with the tooltip: "Groupbox containing parameters."
*
* To change the group of several arguments, call this method before the arguments are added.
*
* @param name The name of the groupbox.
* @param tooltip The tooltip of the groupbox.
*/
void changeParameterGroup(std::string name, std::string tooltip);
private:
class ctkInternal;
ctkInternal * Internal;
string Title;
string Contributor;
string Category;
string Description;
string ParameterGroupName;
string ParameterGroupDescription;
};
#endif
diff --git a/Modules/DiffusionImaging/MiniApps/FileFormatConverter.cpp b/Modules/DiffusionImaging/MiniApps/mitkFileFormatConverter.cpp
similarity index 78%
rename from Modules/DiffusionImaging/MiniApps/FileFormatConverter.cpp
rename to Modules/DiffusionImaging/MiniApps/mitkFileFormatConverter.cpp
index e0466b6c8d..1cac8e8832 100755
--- a/Modules/DiffusionImaging/MiniApps/FileFormatConverter.cpp
+++ b/Modules/DiffusionImaging/MiniApps/mitkFileFormatConverter.cpp
@@ -1,87 +1,84 @@
/*===================================================================
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 "MiniAppManager.h"
#include <mitkImageCast.h>
#include <mitkDiffusionImage.h>
#include <mitkBaseDataIOFactory.h>
#include <mitkIOUtil.h>
#include <mitkFiberBundleX.h>
-#include "ctkCommandLineParser.h"
-#include "ctkCommandLineParser.cpp"
+#include "mitkCommandLineParser.h"
using namespace mitk;
-int FileFormatConverter(int argc, char* argv[])
+int main(int argc, char* argv[])
{
- ctkCommandLineParser parser;
+ mitkCommandLineParser parser;
parser.setTitle("Format Converter");
parser.setCategory("Fiber Tracking and Processing Methods");
parser.setDescription("");
parser.setContributor("MBI");
parser.setArgumentPrefix("--", "-");
- parser.addArgument("in", "i", ctkCommandLineParser::InputFile, "Input:", "input file", us::Any(), false);
- parser.addArgument("out", "o", ctkCommandLineParser::OutputFile, "Output:", "output file", us::Any(), false);
+ parser.addArgument("in", "i", mitkCommandLineParser::InputFile, "Input:", "input file", us::Any(), false);
+ parser.addArgument("out", "o", mitkCommandLineParser::OutputFile, "Output:", "output file", us::Any(), false);
map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
if (parsedArgs.size()==0)
return EXIT_FAILURE;
// mandatory arguments
string inName = us::any_cast<string>(parsedArgs["in"]);
string outName = us::any_cast<string>(parsedArgs["out"]);
try
{
const std::string s1="", s2="";
std::vector<BaseData::Pointer> infile = BaseDataIO::LoadBaseDataFromFile( inName, s1, s2, false );
mitk::BaseData::Pointer baseData = infile.at(0);
if ( dynamic_cast<DiffusionImage<short>*>(baseData.GetPointer()) )
{
mitk::IOUtil::Save(dynamic_cast<DiffusionImage<short>*>(baseData.GetPointer()), outName.c_str());
}
else if ( dynamic_cast<Image*>(baseData.GetPointer()) )
{
mitk::IOUtil::Save(dynamic_cast<Image*>(baseData.GetPointer()), outName.c_str());
}
else if ( dynamic_cast<FiberBundleX*>(baseData.GetPointer()) )
{
mitk::IOUtil::Save(dynamic_cast<FiberBundleX*>(baseData.GetPointer()) ,outName.c_str());
}
else
- MITK_INFO << "File type currently not supported!";
+ std::cout << "File type currently not supported!";
}
catch (itk::ExceptionObject e)
{
- MITK_INFO << e;
+ std::cout << e;
return EXIT_FAILURE;
}
catch (std::exception e)
{
- MITK_INFO << e.what();
+ std::cout << e.what();
return EXIT_FAILURE;
}
catch (...)
{
- MITK_INFO << "ERROR!?!";
+ std::cout << "ERROR!?!";
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
-RegisterDiffusionMiniApp(FileFormatConverter);
diff --git a/Modules/DiffusionImaging/MiniApps/BatchedFolderRegistration.cpp b/Modules/DiffusionImaging/MiniApps/mitkRegistration.cpp
similarity index 88%
rename from Modules/DiffusionImaging/MiniApps/BatchedFolderRegistration.cpp
rename to Modules/DiffusionImaging/MiniApps/mitkRegistration.cpp
index 848637f7df..d262915ba7 100644
--- a/Modules/DiffusionImaging/MiniApps/BatchedFolderRegistration.cpp
+++ b/Modules/DiffusionImaging/MiniApps/mitkRegistration.cpp
@@ -1,483 +1,473 @@
/*===================================================================
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 "MiniAppManager.h"
// CTK
-#include "ctkCommandLineParser.h"
+#include "mitkCommandLineParser.h"
#include <mitkIOUtil.h>
#include <mitkRegistrationWrapper.h>
#include <mitkImage.h>
#include <mitkImageCast.h>
#include <mitkITKImageImport.h>
#include <mitkDiffusionImage.h>
#include <mitkImageTimeSelector.h>
// ITK
#include <itksys/SystemTools.hxx>
#include <itkDirectory.h>
#include "itkLinearInterpolateImageFunction.h"
#include "itkWindowedSincInterpolateImageFunction.h"
#include "itkIdentityTransform.h"
#include "itkResampleImageFilter.h"
typedef std::vector<std::string> FileListType;
typedef itk::Image<double, 3> InputImageType;
static mitk::Image::Pointer ExtractFirstTS(mitk::Image* image, std::string fileType)
{
if (fileType == ".dwi")
return image;
mitk::ImageTimeSelector::Pointer selector = mitk::ImageTimeSelector::New();
selector->SetInput(image);
selector->SetTimeNr(0);
selector->UpdateLargestPossibleRegion();
mitk::Image::Pointer img =selector->GetOutput()->Clone();
return img;
}
static std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems)
{
std::stringstream ss(s);
std::string item;
while (std::getline(ss, item, delim))
{
elems.push_back(item);
}
return elems;
}
static std::vector<std::string> split(const std::string &s, char delim)
{
std::vector < std::string > elems;
return split(s, delim, elems);
}
/// Create list of all files in provided folder ending with same postfix
static FileListType CreateFileList(std::string folder , std::string postfix)
{
itk::Directory::Pointer dir = itk::Directory::New();
FileListType fileList;
if( dir->Load(folder.c_str() ) )
{
int n = dir->GetNumberOfFiles();
for(int r=0;r<n;r++)
{
std::string filename = dir->GetFile( r );
if (filename == "." || filename == "..")
continue;
filename = folder + filename;
if (!itksys::SystemTools::FileExists( filename.c_str()))
continue;
if (filename.substr(filename.length() -postfix.length() ) == postfix)
fileList.push_back(filename);
}
}
return fileList;
}
static std::string GetSavePath(std::string outputFolder, std::string fileName)
{
std::string fileType = itksys::SystemTools::GetFilenameExtension(fileName);
std::string fileStem = itksys::SystemTools::GetFilenameWithoutExtension(fileName);
std::string savePathAndFileName = outputFolder +fileStem + fileType;
return savePathAndFileName;
}
static mitk::Image::Pointer ResampleBySpacing(mitk::Image *input, float *spacing, bool useLinInt = false)
{
InputImageType::Pointer itkImage = InputImageType::New();
CastToItkImage(input,itkImage);
/**
* 1) Resampling
*
*/
// Identity transform.
// We don't want any transform on our image except rescaling which is not
// specified by a transform but by the input/output spacing as we will see
// later.
// So no transform will be specified.
typedef itk::IdentityTransform<double, 3> T_Transform;
// The resampler type itself.
typedef itk::ResampleImageFilter<InputImageType, InputImageType> T_ResampleFilter;
// Prepare the resampler.
// Instantiate the transform and specify it should be the id transform.
T_Transform::Pointer _pTransform = T_Transform::New();
_pTransform->SetIdentity();
// Instantiate the resampler. Wire in the transform and the interpolator.
T_ResampleFilter::Pointer _pResizeFilter = T_ResampleFilter::New();
_pResizeFilter->SetTransform(_pTransform);
// Set the output origin.
_pResizeFilter->SetOutputOrigin(itkImage->GetOrigin());
// Compute the size of the output.
// The size (# of pixels) in the output is recomputed using
// the ratio of the input and output sizes.
InputImageType::SpacingType inputSpacing = itkImage->GetSpacing();
InputImageType::SpacingType outputSpacing;
const InputImageType::RegionType& inputSize = itkImage->GetLargestPossibleRegion();
InputImageType::SizeType outputSize;
typedef InputImageType::SizeType::SizeValueType SizeValueType;
// Set the output spacing.
outputSpacing[0] = spacing[0];
outputSpacing[1] = spacing[1];
outputSpacing[2] = spacing[2];
outputSize[0] = static_cast<SizeValueType>(inputSize.GetSize()[0] * inputSpacing[0] / outputSpacing[0] + .5);
outputSize[1] = static_cast<SizeValueType>(inputSize.GetSize()[1] * inputSpacing[1] / outputSpacing[1] + .5);
outputSize[2] = static_cast<SizeValueType>(inputSize.GetSize()[2] * inputSpacing[2] / outputSpacing[2] + .5);
_pResizeFilter->SetOutputSpacing(outputSpacing);
_pResizeFilter->SetSize(outputSize);
typedef itk::LinearInterpolateImageFunction< InputImageType > LinearInterpolatorType;
LinearInterpolatorType::Pointer lin_interpolator = LinearInterpolatorType::New();
typedef itk::Function::WelchWindowFunction<4> WelchWindowFunction;
typedef itk::WindowedSincInterpolateImageFunction< InputImageType, 4,WelchWindowFunction> WindowedSincInterpolatorType;
WindowedSincInterpolatorType::Pointer sinc_interpolator = WindowedSincInterpolatorType::New();
if (useLinInt)
_pResizeFilter->SetInterpolator(lin_interpolator);
else
_pResizeFilter->SetInterpolator(sinc_interpolator);
// Specify the input.
_pResizeFilter->SetInput(itkImage);
_pResizeFilter->Update();
mitk::Image::Pointer image = mitk::Image::New();
image->InitializeByItk(_pResizeFilter->GetOutput());
mitk::GrabItkImageMemory( _pResizeFilter->GetOutput(), image);
return image;
}
/// Build a derived file name from moving images e.g. xxx_T2.nrrd becomes xxx_GTV.nrrd
static FileListType CreateDerivedFileList(std::string baseFN, std::string baseSuffix, std::vector<std::string> derivedPatterns)
{
FileListType files;
for (unsigned int i=0; i < derivedPatterns.size(); i++)
{
std::string derResourceSuffix = derivedPatterns.at(i);
std::string derivedResourceFilename = baseFN.substr(0,baseFN.length() -baseSuffix.length()) + derResourceSuffix;
MITK_INFO <<" Looking for file: " << derivedResourceFilename;
if (!itksys::SystemTools::FileExists(derivedResourceFilename.c_str()))
{
MITK_INFO << "CreateDerivedFileList: File does not exit. Skipping entry.";
continue;
}
files.push_back(derivedResourceFilename);
}
return files;
}
/// Save images according to file type
static void SaveImage(std::string fileName, mitk::Image* image, std::string fileType )
{
MITK_INFO << "----Save to " << fileName;
if (fileType == "dwi") // IOUtil does not handle dwi files properly Bug 15772
{
try
{
mitk::IOUtil::Save(dynamic_cast<mitk::DiffusionImage<short>*>(image), fileName.c_str());
}
catch( const itk::ExceptionObject& e)
{
MITK_ERROR << "Caught exception: " << e.what();
mitkThrow() << "Failed with exception from subprocess!";
}
}
else
{
mitk::IOUtil::SaveImage(image, fileName);
}
}
/// Copy derived resources from first time step. Append _reg tag, but leave data untouched.
static void CopyResources(FileListType fileList, std::string outputPath)
{
for (unsigned int j=0; j < fileList.size(); j++)
{
std::string derivedResourceFilename = fileList.at(j);
std::string fileType = itksys::SystemTools::GetFilenameExtension(derivedResourceFilename);
std::string fileStem = itksys::SystemTools::GetFilenameWithoutExtension(derivedResourceFilename);
std::string savePathAndFileName = outputPath +fileStem + "." + fileType;
MITK_INFO << "Copy resource " << savePathAndFileName;
mitk::Image::Pointer resImage = ExtractFirstTS(mitk::IOUtil::LoadImage(derivedResourceFilename), fileType);
mitk::IOUtil::SaveImage(resImage, savePathAndFileName);
}
}
-int BatchedFolderRegistration( int argc, char* argv[] )
+int main( int argc, char* argv[] )
{
- ctkCommandLineParser parser;
+ mitkCommandLineParser parser;
parser.setArgumentPrefix("--","-");
- parser.setTitle("Batched Folder Registraton");
+ parser.setTitle("Folder Registraton");
parser.setCategory("Preprocessing Tools");
- parser.setDescription("");
+ parser.setDescription("http://docs.mitk.org/nightly-qt4/DiffusionMiniApps.html");
parser.setContributor("MBI");
// Add command line argument names
- parser.addArgument("help", "h",ctkCommandLineParser::Bool, "Help", "Show this help text");
+ parser.addArgument("help", "h",mitkCommandLineParser::Bool, "Help", "Show this help text");
//parser.addArgument("usemask", "u", QVariant::Bool, "Use segmentations (derived resources) to exclude areas from registration metrics");
- parser.addArgument("input", "i", ctkCommandLineParser::InputDirectory, "Input:", "Input folder",us::Any(),false);
- parser.addArgument("output", "o", ctkCommandLineParser::OutputDirectory, "Output:", "Output folder (ending with /)",us::Any(),false);
- parser.addArgument("fixed", "f", ctkCommandLineParser::String, "Fixed images:", "Suffix for fixed image (if none is supplied first file matching moving pattern is chosen)",us::Any(),true);
- parser.addArgument("moving", "m", ctkCommandLineParser::String, "Moving images:", "Suffix for moving images",us::Any(),false);
- parser.addArgument("derived", "d", ctkCommandLineParser::String, "Derived resources:", "Derived resources suffixes (replaces suffix for moving images); comma separated",us::Any(),true);
- parser.addArgument("silent", "s", ctkCommandLineParser::Bool, "Silent:" "No xml progress output.");
- parser.addArgument("resample", "r", ctkCommandLineParser::String, "Resample (x,y,z)mm:", "Resample provide x,y,z spacing in mm (e.g. -r 1,1,3), is not applied to tensor data",us::Any());
- parser.addArgument("binary", "b", ctkCommandLineParser::Bool, "Binary:", "Speficies that derived resource are binary (interpolation using nearest neighbor)",us::Any());
- parser.addArgument("correct-origin", "c", ctkCommandLineParser::Bool, "Origin correction:", "Correct for large origin displacement. Switch when you reveive: Joint PDF summed to zero ",us::Any());
- parser.addArgument("sinc-int", "s", ctkCommandLineParser::Bool, "Windowed-sinc interpolation:", "Use windowed-sinc interpolation (3) instead of linear interpolation ",us::Any());
+ parser.addArgument("input", "i", mitkCommandLineParser::InputDirectory, "Input:", "Input folder",us::Any(),false);
+ parser.addArgument("output", "o", mitkCommandLineParser::OutputDirectory, "Output:", "Output folder (ending with /)",us::Any(),false);
+ parser.addArgument("fixed", "f", mitkCommandLineParser::String, "Fixed images:", "Suffix for fixed image (if none is supplied first file matching moving pattern is chosen)",us::Any(),true);
+ parser.addArgument("moving", "m", mitkCommandLineParser::String, "Moving images:", "Suffix for moving images",us::Any(),false);
+ parser.addArgument("derived", "d", mitkCommandLineParser::String, "Derived resources:", "Derived resources suffixes (replaces suffix for moving images); comma separated",us::Any(),true);
+ parser.addArgument("silent", "s", mitkCommandLineParser::Bool, "Silent:" "No xml progress output.");
+ parser.addArgument("resample", "r", mitkCommandLineParser::String, "Resample (x,y,z)mm:", "Resample provide x,y,z spacing in mm (e.g. -r 1,1,3), is not applied to tensor data",us::Any());
+ parser.addArgument("binary", "b", mitkCommandLineParser::Bool, "Binary:", "Speficies that derived resource are binary (interpolation using nearest neighbor)",us::Any());
+ parser.addArgument("correct-origin", "c", mitkCommandLineParser::Bool, "Origin correction:", "Correct for large origin displacement. Switch when you reveive: Joint PDF summed to zero ",us::Any());
+ parser.addArgument("sinc-int", "s", mitkCommandLineParser::Bool, "Windowed-sinc interpolation:", "Use windowed-sinc interpolation (3) instead of linear interpolation ",us::Any());
map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
// Handle special arguments
bool silent = false;
bool isBinary = false;
bool alignOrigin = false;
bool useLinearInterpol = true;
{
if (parsedArgs.size() == 0)
{
- MITK_ERROR << "Missig arguements" ;
return EXIT_FAILURE;
}
- if (parsedArgs.count("xml"))
- {
- MITK_ERROR << "This is to be handled by shell script";
- return EXIT_SUCCESS;
- }
-
if (parsedArgs.count("sinc-int"))
useLinearInterpol = false;
if (parsedArgs.count("silent"))
silent = true;
if (parsedArgs.count("binary"))
isBinary = true;
if (parsedArgs.count("correct-origin"))
alignOrigin = true;
// Show a help message
if ( parsedArgs.count("help") || parsedArgs.count("h"))
{
std::cout << parser.helpText();
return EXIT_SUCCESS;
}
}
std::string refPattern = "";
bool useFirstMoving = false;
std::string movingImgPattern = us::any_cast<string>(parsedArgs["moving"]);
if (parsedArgs.count("fixed"))
{
refPattern = us::any_cast<string>(parsedArgs["fixed"]);
}
else
{
useFirstMoving = true;
refPattern = movingImgPattern;
}
std::string outputPath = us::any_cast<string>(parsedArgs["output"]);
std::string inputPath = us::any_cast<string>(parsedArgs["input"]);
//QString resampleReference = parsedArgs["resample"].toString();
//bool maskTumor = parsedArgs["usemask"].toBool();
// if derived sources pattern is provided, populate QStringList with possible filename postfixes
std::vector<std::string> derPatterns;
if (parsedArgs.count("derived") || parsedArgs.count("d") )
{
std::string arg = us::any_cast<string>(parsedArgs["derived"]);
derPatterns = split(arg ,',');
}
std::vector<std::string> spacings;
float spacing[3];
bool doResampling = false;
if (parsedArgs.count("resample") || parsedArgs.count("d") )
{
std::string arg = us::any_cast<string>(parsedArgs["resample"]);
spacings = split(arg ,',');
spacing[0] = atoi(spacings.at(0).c_str());
spacing[1] = atoi(spacings.at(1).c_str());
spacing[2] = atoi(spacings.at(2).c_str());
doResampling = true;
}
MITK_INFO << "Input Folder : " << inputPath;
MITK_INFO << "Looking for reference image ...";
FileListType referenceFileList = CreateFileList(inputPath,refPattern);
if ((!useFirstMoving && referenceFileList.size() != 1) || (useFirstMoving && referenceFileList.size() == 0))
{
MITK_ERROR << "None or more than one possible reference images (" << refPattern <<") found. Exiting." << referenceFileList.size();
MITK_INFO << "Choose a fixed arguement that is unique in the given folder!";
return EXIT_FAILURE;
}
std::string referenceFileName = referenceFileList.at(0);
MITK_INFO << "Loading Reference (fixed) image: " << referenceFileName;
std::string fileType = itksys::SystemTools::GetFilenameExtension(referenceFileName);
mitk::Image::Pointer refImage = ExtractFirstTS(mitk::IOUtil::LoadImage(referenceFileName), fileType);
mitk::Image::Pointer resampleReference = NULL;
if (doResampling)
{
refImage = ResampleBySpacing(refImage,spacing);
resampleReference = refImage;
}
if (refImage.IsNull())
MITK_ERROR << "Loaded fixed image is NULL";
// Copy reference image to destination
std::string savePathAndFileName = GetSavePath(outputPath, referenceFileName);
mitk::IOUtil::SaveImage(refImage, savePathAndFileName);
// Copy all derived resources also to output folder, adding _reg suffix
referenceFileList = CreateDerivedFileList(referenceFileName, movingImgPattern,derPatterns);
CopyResources(referenceFileList, outputPath);
std::string derivedResourceFilename;
mitk::Image::Pointer referenceMask = NULL; // union of all segmentations
if (!silent)
{
// XML Output to report progress
std::cout << "<filter-start>";
std::cout << "<filter-name>Batched Registration</filter-name>";
std::cout << "<filter-comment>Starting registration ... </filter-comment>";
std::cout << "</filter-start>";
}
// Now iterate over all files and register them to the reference image,
// also register derived resources based on file patterns
// ------------------------------------------------------------------------------
// Create File list
FileListType movingImagesList = CreateFileList(inputPath, movingImgPattern);
// TODO Reactivate Resampling Feature
// mitk::Image::Pointer resampleImage = NULL;
// if (QFileInfo(resampleReference).isFile())
// {
// resampleImage = mitk::IOUtil::LoadImage(resampleReference.toStdString());
// }
for (unsigned int i =0; i < movingImagesList.size(); i++)
{
std::string fileMorphName = movingImagesList.at(i);
if (fileMorphName == referenceFileName)
{
// do not process reference image again
continue;
}
MITK_INFO << "Processing image " << fileMorphName;
// 1 Register morphological file to reference image
if (!itksys::SystemTools::FileExists(fileMorphName.c_str()))
{
MITK_WARN << "File does not exit. Skipping entry.";
continue;
}
// Origin of images is cancelled
// TODO make this optional!!
double transf[6];
double offset[3];
{
std::string fileType = itksys::SystemTools::GetFilenameExtension(fileMorphName);
mitk::Image::Pointer movingImage = ExtractFirstTS(mitk::IOUtil::LoadImage(fileMorphName), fileType);
if (movingImage.IsNull())
MITK_ERROR << "Loaded moving image is NULL";
// Store transformation, apply it to morph file
MITK_INFO << "----------Registering moving image to reference----------";
mitk::RegistrationWrapper::GetTransformation(refImage, movingImage, transf, offset, alignOrigin, referenceMask);
mitk::RegistrationWrapper::ApplyTransformationToImage(movingImage, transf,offset, resampleReference); // , resampleImage
savePathAndFileName = GetSavePath(outputPath, fileMorphName);
if (fileType == ".dwi")
fileType = "dwi";
SaveImage(savePathAndFileName,movingImage,fileType );
}
if (!silent)
{
std::cout << "<filter-progress-text progress=\"" <<
(float)i / (float)movingImagesList.size()
<< "\" >.</filter-progress-text>";
}
// Now parse all derived resource and apply the above calculated transformation to them
// ------------------------------------------------------------------------------------
FileListType fList = CreateDerivedFileList(fileMorphName, movingImgPattern,derPatterns);
if (fList.size() > 0)
MITK_INFO << "----------DERIVED RESOURCES ---------";
for (unsigned int j=0; j < fList.size(); j++)
{
derivedResourceFilename = fList.at(j);
MITK_INFO << "----Processing derived resorce " << derivedResourceFilename << " ...";
std::string fileType = itksys::SystemTools::GetFilenameExtension(derivedResourceFilename);
mitk::Image::Pointer derivedMovingResource = ExtractFirstTS(mitk::IOUtil::LoadImage(derivedResourceFilename), fileType);
// Apply transformation to derived resource, treat derived resource as binary
mitk::RegistrationWrapper::ApplyTransformationToImage(derivedMovingResource, transf,offset, resampleReference,isBinary);
savePathAndFileName = GetSavePath(outputPath, derivedResourceFilename);
SaveImage(savePathAndFileName,derivedMovingResource,fileType );
}
}
if (!silent)
std::cout << "<filter-end/>";
return EXIT_SUCCESS;
}
-
-RegisterDiffusionMiniApp(BatchedFolderRegistration);
diff --git a/Modules/GPGPU/CMakeLists.txt b/Modules/GPGPU/CMakeLists.txt
index 77e7253458..794102e1e4 100644
--- a/Modules/GPGPU/CMakeLists.txt
+++ b/Modules/GPGPU/CMakeLists.txt
@@ -1,19 +1,19 @@
if(APPLE)
message(STATUS "Module GPGPU is not ported to MacOS yet")
else(APPLE)
set(package_deps)
if(UNIX)
list(APPEND package_deps X11)
endif()
MITK_CREATE_MODULE(
# INCLUDE_DIRS .
DEPENDS MitkCore
- PACKAGE_DEPENDS ${package_deps} GLEW Qt4|QtGui
+ PACKAGE_DEPENDS ${package_deps} GLEW Qt4|QtGui Qt5|Widgets
EXPORT_DEFINE GPGPU_DLL_API
WARNINGS_AS_ERRORS
)
endif(APPLE)
diff --git a/Modules/GPGPU/mitkGPGPU.cpp b/Modules/GPGPU/mitkGPGPU.cpp
index 56de055027..abb8c2320c 100644
--- a/Modules/GPGPU/mitkGPGPU.cpp
+++ b/Modules/GPGPU/mitkGPGPU.cpp
@@ -1,627 +1,627 @@
/*===================================================================
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 <QApplication>
#include <QWidget>
#include "mitkGPGPU.h"
#include <iostream>
#define GPGPU_INFO MITK_INFO("mitk.gpgpu")
#define GPGPU_ERROR MITK_ERROR("mitk.gpgpu")
#define GPGPU_CHECKGLERR MITK_ERROR(glGetError()!=GL_NO_ERROR)("mitk.gpgpu") << "GL ERROR @ "
#define OPERATING_TEXTURE GL_TEXTURE15
static GLint convertTextureFormatToInternalFormatGL(mitk::GPGPU::TextureFormat format)
{
switch(format)
{
case mitk::GPGPU::FLOAT32_LUMINANCE: return GL_LUMINANCE_FLOAT32_ATI;
case mitk::GPGPU::FLOAT32_LUMINANCE_ALPHA: return GL_LUMINANCE_ALPHA_FLOAT32_ATI;
case mitk::GPGPU::FLOAT32_RGBA: return GL_RGBA32F_ARB;
case mitk::GPGPU::UINT8_RGBA: return GL_RGBA8;
}
return 0;
}
static GLint convertTextureFormatToFormatGL(mitk::GPGPU::TextureFormat format)
{
switch(format)
{
case mitk::GPGPU::FLOAT32_LUMINANCE: return GL_LUMINANCE;
case mitk::GPGPU::FLOAT32_LUMINANCE_ALPHA: return GL_LUMINANCE_ALPHA;
case mitk::GPGPU::FLOAT32_RGBA: return GL_RGBA;
case mitk::GPGPU::UINT8_RGBA: return GL_RGBA;
}
return 0;
}
static GLint convertTextureFormatToTypeGL(mitk::GPGPU::TextureFormat format)
{
switch(format)
{
case mitk::GPGPU::FLOAT32_LUMINANCE: return GL_FLOAT;
case mitk::GPGPU::FLOAT32_LUMINANCE_ALPHA: return GL_FLOAT;
case mitk::GPGPU::FLOAT32_RGBA: return GL_FLOAT;
case mitk::GPGPU::UINT8_RGBA: return GL_UNSIGNED_BYTE;
}
return 0;
}
int mitk::GPGPU::Texture::GetWidth(){return myWidth;}
int mitk::GPGPU::Texture::GetHeigth(){return myHeight;}
int mitk::GPGPU::Texture::GetDepth(){return myDepth;}
mitk::GPGPU::Texture::Texture(mitk::GPGPU::TextureFormat format,int width,int height,int depth)
{
if(depth==0)
glTarget=GL_TEXTURE_2D;
else
glTarget=GL_TEXTURE_3D;
myFormat=format;
myWidth=width;
myHeight=height;
myDepth=depth;
GLuint handle;
glGenTextures(1,&handle);
glTextureHandle = handle;
glActiveTexture(OPERATING_TEXTURE);
glBindTexture(glTarget,glTextureHandle);
GPGPU_CHECKGLERR << "allocating texture handle";
if(glTarget==GL_TEXTURE_2D)
{
glTexImage2D(GL_TEXTURE_2D,0,convertTextureFormatToInternalFormatGL(myFormat),width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,0);
// glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_R,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
}
else
{
glTexImage3D(GL_TEXTURE_3D,0,convertTextureFormatToInternalFormatGL(myFormat),width,height,depth,0,GL_RGBA,GL_UNSIGNED_BYTE,0);
// glGenerateMipmap(GL_TEXTURE_3D);
glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_WRAP_R,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
}
GPGPU_CHECKGLERR << "declaring texture format&dimensions";
glGenFramebuffers(1,&handle);
glFBOHandle = handle;
GPGPU_CHECKGLERR << "allocating framebuffer object";
}
mitk::GPGPU::Texture::~Texture()
{
GLuint handle;
handle=glFBOHandle;
glDeleteFramebuffers(1,&handle);
GPGPU_CHECKGLERR << "deleting framebufferobject";
handle=glTextureHandle;
glDeleteTextures(1,&handle);
GPGPU_CHECKGLERR << "deleting texture handle";
}
void mitk::GPGPU::Texture::ActivateAsSource(int unit)
{
glActiveTexture(GL_TEXTURE0 + unit);
glBindTexture(glTarget,glTextureHandle);
GPGPU_CHECKGLERR << "binding texture to unit";
}
void mitk::GPGPU::Texture::ActivateAsDestination()
{
static GLenum buffers[5][4] =
{
{ GL_NONE, GL_NONE, GL_NONE, GL_NONE },
{ GL_COLOR_ATTACHMENT0, GL_NONE, GL_NONE, GL_NONE },
{ GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_NONE, GL_NONE },
{ GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_NONE },
{ GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 },
};
glBindFramebuffer( GL_FRAMEBUFFER, glFBOHandle );
glDrawBuffers(4, buffers[1]);
glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, glTarget,glTextureHandle,0);
GPGPU_CHECKGLERR << "associating texture to framebufferobject";
int error = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
switch(error)
{
case GL_FRAMEBUFFER_COMPLETE_EXT:
break;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
GPGPU_ERROR << "Incomplete attachment\n";break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
GPGPU_ERROR << "Missing attachment\n";break;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
GPGPU_ERROR << "Incomplete dimensions\n";break;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
GPGPU_ERROR << "Incomplete formats\n";break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
GPGPU_ERROR << "Incomplete draw buffer\n";break;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
GPGPU_ERROR << "Incomplete read buffer\n";break;
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
GPGPU_ERROR << "Framebufferobjects unsupported\n";break;
default:
GPGPU_ERROR << "unknown framebuffer status\n";break;
}
glViewport(0,0,myWidth,myHeight);
GPGPU_CHECKGLERR << "setting viewport";
}
void mitk::GPGPU::Texture::Upload(TextureFormat inputformat,const void *src)
{
glActiveTexture(OPERATING_TEXTURE);
glBindTexture(glTarget,glTextureHandle);
if(glTarget==GL_TEXTURE_2D)
{
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,myWidth,myHeight,convertTextureFormatToFormatGL(inputformat),convertTextureFormatToTypeGL(inputformat),src);
}
else
{
glTexSubImage3D(GL_TEXTURE_3D,0,0,0,0,myWidth,myHeight,myDepth,convertTextureFormatToFormatGL(inputformat),convertTextureFormatToTypeGL(inputformat),src);
}
GPGPU_CHECKGLERR << "texture upload to gpu";
}
void mitk::GPGPU::Texture::Download(TextureFormat inputformat,void *dst)
{
glActiveTexture(OPERATING_TEXTURE);
glBindTexture(glTarget,glTextureHandle);
if(glTarget==GL_TEXTURE_2D)
{
glGetTexImage( GL_TEXTURE_2D,0,convertTextureFormatToFormatGL(inputformat),convertTextureFormatToTypeGL(inputformat),dst);
GPGPU_CHECKGLERR << "texture download to cpu";
}
else
{
}
}
static char stubVertexShader[] =
"void main() { gl_Position = vec4( 2*gl_Vertex.xy-1,0,1 ); }\n";
mitk::GPGPU::Shader::Shader(char *source)
{
//std::cout << "compiling shader:\n" << source << std::endl;
glHandleVertex = glCreateShader(GL_VERTEX_SHADER);
glHandleFragment = glCreateShader(GL_FRAGMENT_SHADER);
glHandleProgram = glCreateProgram();
GLchar *src[2];
src[0] = stubVertexShader;
src[1] = 0;
glShaderSource(glHandleVertex,1,(const GLchar **)src,0);
src[0] = source;
src[1] = 0;
glShaderSource(glHandleFragment,1,(const GLchar **)src,0);
bool failed=false;
GLint _sv,_sf,_sl;
glCompileShader( glHandleVertex );
GPGPU_CHECKGLERR << "compiling vertex shader";
glGetShaderiv( glHandleVertex, GL_COMPILE_STATUS, &_sv);
if( !_sv)
{
GPGPU_ERROR << "vertex shader compilation failed\n";
failed=true;
}
glCompileShader( glHandleFragment );
GPGPU_CHECKGLERR << "compiling fragment shader";
glGetShaderiv( glHandleFragment, GL_COMPILE_STATUS, &_sf);
if( !_sf)
{
GPGPU_ERROR << "fragment shader compilation failed\n";
failed=true;
}
glAttachShader( glHandleProgram,glHandleVertex );
glAttachShader( glHandleProgram,glHandleFragment );
glLinkProgram( glHandleProgram );
GPGPU_CHECKGLERR << "linking shader program";
glGetProgramiv( glHandleProgram, GL_LINK_STATUS, &_sl);
if( !_sl)
{
GPGPU_ERROR << "shader linkage failed\n";
failed=true;
}
if(failed)
{
int infologLength = 0;
int charsWritten = 0;
char *infoLog;
glGetProgramiv(glHandleProgram, GL_INFO_LOG_LENGTH,&infologLength);
if (infologLength > 0)
{
infoLog = (char *)malloc(infologLength);
glGetProgramInfoLog(glHandleProgram, infologLength, &charsWritten, infoLog);
GPGPU_ERROR << "SHADER CREATION FAILED INFOLOG:\n" << infoLog;
free(infoLog);
}
}
}
mitk::GPGPU::Shader::~Shader()
{
glDeleteProgram( glHandleProgram);
glDeleteShader( glHandleVertex );
glDeleteShader( glHandleFragment );
}
void mitk::GPGPU::Shader::Activate()
{
glUseProgram( glHandleProgram );
GPGPU_CHECKGLERR << "activating shader";
}
int mitk::GPGPU::Shader::GetUniformLocation(char *name)
{
return glGetUniformLocation(glHandleProgram,name);
}
void mitk::GPGPU::Shader::SetUniform(char *name,int i0)
{
glUniform1i( GetUniformLocation(name) , i0);
GPGPU_CHECKGLERR << "setting uniform";
}
void mitk::GPGPU::Shader::SetUniform(char *name,int i0,int i1)
{
GLint i[2];
i[0]=i0;
i[1]=i1;
glUniform2iv( GetUniformLocation(name) , 1 , i );
GPGPU_CHECKGLERR << "setting uniform";
}
void mitk::GPGPU::Shader::SetUniform(char *name,int i0,int i1,int i2)
{
GLint i[3];
i[0]=i0;
i[1]=i1;
i[2]=i2;
glUniform3iv( GetUniformLocation(name) , 1 , i );
GPGPU_CHECKGLERR << "setting uniform";
}
void mitk::GPGPU::Shader::SetUniform(char *name,int i0,int i1,int i2,int i3)
{
GLint i[4];
i[0]=i0;
i[1]=i1;
i[2]=i2;
i[3]=i3;
glUniform4iv( GetUniformLocation(name) , 1 , i );
GPGPU_CHECKGLERR << "setting uniform";
}
void mitk::GPGPU::Shader::SetUniform(char *name,float i0)
{
GLint location = GetUniformLocation(name);
glUniform1f(location,i0);
GPGPU_CHECKGLERR << "setting uniform";
}
void mitk::GPGPU::Shader::SetUniform(char *name,float i0,float i1)
{
GLfloat i[2];
i[0]=i0;
i[1]=i1;
glUniform2fv(GetUniformLocation(name),1,i);
GPGPU_CHECKGLERR << "setting uniform";
}
void mitk::GPGPU::Shader::SetUniform(char *name,float i0,float i1,float i2)
{
GLfloat i[3];
i[0]=i0;
i[1]=i1;
i[2]=i2;
glUniform3fv(GetUniformLocation(name),1,i);
GPGPU_CHECKGLERR << "setting uniform";
}
void mitk::GPGPU::Shader::SetUniform(char *name,float i0,float i1,float i2,float i3)
{
GLfloat i[4];
i[0]=i0;
i[1]=i1;
i[2]=i2;
i[3]=i3;
glUniform4fv(GetUniformLocation(name),1,i);
GPGPU_CHECKGLERR << "setting uniform";
}
#ifdef _WIN32
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
#endif
mitk::GPGPU::GPGPU()
{
#ifdef _WIN32
/*
WNDCLASSEX wcx;
// Fill in the window class structure with parameters
// that describe the main window.
wcx.cbSize = sizeof(wcx); // size of structure
wcx.style = CS_HREDRAW |
CS_VREDRAW; // redraw if size changes
wcx.lpfnWndProc = MainWndProc; // points to window procedure
wcx.cbClsExtra = 0; // no extra class memory
wcx.cbWndExtra = 0; // no extra window memory
wcx.hInstance = GetModuleHandle(NULL); // handle to inst ance
wcx.hIcon = LoadIcon(NULL,
IDI_APPLICATION); // predefined app. icon
wcx.hCursor = LoadCursor(NULL,
IDC_ARROW); // predefined arrow
wcx.hbrBackground = NULL; // white background brush
wcx.lpszMenuName = (LPCSTR) "MainMenu"; // name of menu resource
wcx.lpszClassName = (LPCSTR) "MainWClass"; // name of window class
wcx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
// Register the window class.
if(!RegisterClassEx(&wcx))
std::cout << "failed registering window class\n";
HWND desktopWindow=CreateWindowEx(
WS_EX_CLIENTEDGE,
(LPCSTR)"MainWClass",
(LPCSTR)"Anatomy of a Window",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 240, 120,
NULL,
NULL,
GetModuleHandle(NULL),
NULL);
windowHandle = desktopWindow;
ShowWindow(desktopWindow, SW_RESTORE);
if(desktopWindow==0)
std::cout << "failed creating window\n";
*/
- HWND desktopWindow=QApplication::topLevelWidgets().at(0)->winId();
+ HWND desktopWindow= (HWND)QApplication::topLevelWidgets().at(0)->winId();
windowsContext = GetDC(desktopWindow);
if(windowsContext==0)
std::cout << "failed getting window device context\n";
static PIXELFORMATDESCRIPTOR pfd =// pfd Tells Windows How We Want Things To Be
{
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
1, // Version Number
PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
PFD_DOUBLEBUFFER |
PFD_SWAP_EXCHANGE , // Must Support Double Buffering
PFD_TYPE_RGBA, // Request An RGBA Format
24, // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored if(openGLContext==0)
0, // No Alpha Buffer
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
0, // 16Bit Z-Buffer (Depth Buffer)
0, // No Stencil Buffer
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
0, 0, 0 // Layer Masks Ignored
};
// Sonstiges einstellen
int iFormat = ChoosePixelFormat(windowsContext,&pfd);
SetPixelFormat(windowsContext,iFormat,&pfd);
openGLContext = wglCreateContext(windowsContext);
int errw=GetLastError();
if(openGLContext==0)
std::cout << "failed creating openGL context "<<errw<<"\n";
#else
X_display = XOpenDisplay(NULL);
GPGPU_ERROR( !X_display ) << "cant open X display";
GLX_drawable = QApplication::topLevelWidgets().at(0)->winId();
GPGPU_ERROR( !GLX_drawable ) << "cant get toplevel widget from QT";
static int visAttributes[] = {
GLX_RGBA,
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
GLX_DOUBLEBUFFER,
None
};
XVisualInfo *visinfo = glXChooseVisual(X_display, 0, visAttributes);
GPGPU_ERROR(!visinfo) << "Unable to choose specified visual!";
openGLContext = glXCreateContext(X_display, visinfo, 0, true);
if(visinfo)
XFree(visinfo);
GPGPU_ERROR(!openGLContext) << "cant create GLX context";
#endif
Activate();
GPGPU_INFO << "initializing glew";
int err=glewInit();
GPGPU_CHECKGLERR << "initializing glew";
GPGPU_ERROR(GLEW_OK != err) << "glewInit() fails with " << err << " as text: " << glewGetErrorString(err);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,1,0,1,-1,1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
GPGPU_CHECKGLERR << "intializing projection&modelview matrix";
glDisable(GL_CULL_FACE);
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glDisable(GL_DEPTH_TEST); // Enables Depth Testing
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
glHint(GL_TEXTURE_COMPRESSION_HINT, GL_NICEST);
glDepthMask(false);
GPGPU_CHECKGLERR << "setting up openGL context";
}
mitk::GPGPU::~GPGPU()
{
#ifdef _WIN32
wglDeleteContext( openGLContext );
#else
if(openGLContext)
glXDestroyContext(X_display,openGLContext);
if(X_display)
XCloseDisplay(X_display);
#endif
}
void mitk::GPGPU::Activate()
{
#ifdef _WIN32
wglMakeCurrent(windowsContext,openGLContext);
#else
glXMakeCurrent(X_display, GLX_drawable, openGLContext);
#endif
GPGPU_CHECKGLERR << "activating openGL context";
}
void mitk::GPGPU::Deactivate()
{
}
void mitk::GPGPU::Run()
{
glBegin( GL_TRIANGLE_STRIP );
glVertex2f( 0,0 );
glVertex2f( 0,1 );
glVertex2f( 1,0 );
glVertex2f( 1,1 );
glEnd();
GPGPU_CHECKGLERR << "running a shader";
}
void mitk::GPGPU::Run(float start,float end)
{
glBegin( GL_TRIANGLE_STRIP );
glVertex2f( 0,start );
glVertex2f( 0,end );
glVertex2f( 1,start );
glVertex2f( 1,end );
glEnd();
GPGPU_CHECKGLERR << "running a shader";
}
diff --git a/Modules/IGTUI/Qmitk/QmitkNDIToolDelegate.cpp b/Modules/IGTUI/Qmitk/QmitkNDIToolDelegate.cpp
index 6c04598e97..f6ca846c21 100644
--- a/Modules/IGTUI/Qmitk/QmitkNDIToolDelegate.cpp
+++ b/Modules/IGTUI/Qmitk/QmitkNDIToolDelegate.cpp
@@ -1,214 +1,214 @@
/*===================================================================
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 "QmitkNDIToolDelegate.h"
#include <QStringList>
#include <QComboBox>
#include <QLabel>
#include <QFileDialog>
#include "QmitkEnums.h"
#include "QmitkDataStorageComboBox.h"
#include "QmitkCustomVariants.h"
#include "mitkDataStorage.h"
#include "mitkNodePredicateBase.h"
#include "QmitkDataStorageComboBox.h"
#include "mitkNDIPassiveTool.h"
Q_DECLARE_METATYPE(mitk::NDIPassiveTool*)
QmitkNDIToolDelegate::QmitkNDIToolDelegate(QObject * parent) : QStyledItemDelegate(parent),
m_Types(), m_DataStorage(NULL), m_Predicate(NULL), m_TagProperty(NULL), m_TagPropertyName()
{
}
QWidget* QmitkNDIToolDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if (index.isValid() == false)
return QStyledItemDelegate::createEditor(parent, option, index);
switch (index.column())
{
case SROMCol:
{
return new QLabel("", parent);
}
case TypeCol:
{
QComboBox* c = new QComboBox(parent);
c->addItems(m_Types);
return c;
}
case NodeCol:
{
return new QmitkDataStorageComboBox(m_DataStorage, m_Predicate, parent);
}
case IndexCol:
case NameCol:
case StatusCol:
default:
return QStyledItemDelegate::createEditor(parent, option, index);
}
}
void QmitkNDIToolDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
if (index.isValid() == false)
return;
switch (index.column())
{
case SROMCol:
{
QLabel* l = qobject_cast<QLabel*>(editor);
if (l->text().isEmpty())
{
- QString fileName = qVariantValue<QString>(index.data(/*mitk::FileNameRole*/));
+ QString fileName = index.data(/*mitk::FileNameRole*/).value<QString>();
fileName = QFileDialog::getOpenFileName(editor, "Open SROM file", fileName, "SROM files (*.rom)");
QLabel* l = qobject_cast<QLabel*>(editor);
l->setText(fileName);
}
return;
}
case TypeCol:
{
- QString type = qVariantValue<QString>(index.data(/*mitk::TypeRole*/));
+ QString type = index.data(/*mitk::TypeRole*/).value<QString>();
QComboBox* c = qobject_cast<QComboBox*>(editor);
c->setCurrentIndex(c->findText(type));
connect(c, SIGNAL(currentIndexChanged(int)), this, SLOT(ComboBoxCurrentIndexChanged(int)));
return;
}
case NodeCol:
{
- mitk::DataNode::Pointer n = qVariantValue<mitk::DataNode::Pointer>(index.data(/*mitk::OrganNodeRole*/));
+ mitk::DataNode::Pointer n = index.data(/*mitk::OrganNodeRole*/).value<mitk::DataNode::Pointer>();
if (n.IsNotNull())
{
QmitkDataStorageComboBox* dsc = qobject_cast<QmitkDataStorageComboBox*>(editor);
dsc->setCurrentIndex(dsc->findText(QString::fromStdString(n->GetName())));
connect(dsc, SIGNAL(currentIndexChanged(int)), this, SLOT(ComboBoxCurrentIndexChanged(int)));
}
return;
}
case IndexCol:
case NameCol:
case StatusCol:
default:
QStyledItemDelegate::setEditorData(editor, index);
}
}
void QmitkNDIToolDelegate::setModelData(QWidget *editor, QAbstractItemModel* model, const QModelIndex &index) const
{
if (index.isValid() == false)
return;
switch (index.column())
{
case SROMCol:
{
QLabel* l = qobject_cast<QLabel*>(editor);
//model->setData(index, l->text(), mitk::FileNameRole);
//model->setData(index, l->text(), Qt::DisplayRole); // use for display too
model->setData(index, l->text()); // use for display too
return;
}
case TypeCol:
{
QComboBox* c = qobject_cast<QComboBox*>(editor);
//model->setData(index, c->currentText(), mitk::TypeRole);
model->setData(index, c->currentText(), Qt::DisplayRole);
return;
}
case NodeCol:
{
QmitkDataStorageComboBox* dsc = qobject_cast<QmitkDataStorageComboBox*>(editor);
if (dsc->GetSelectedNode().IsNotNull())
{
model->setData(index, qVariantFromValue(dsc->GetSelectedNode()), OrganNodeRole);
//model->setData(index, QString::fromStdString(dsc->GetSelectedNode()->GetName()), Qt::DisplayRole);
model->setData(index, QString::fromStdString(dsc->GetSelectedNode()->GetName()));
if ((m_TagProperty.IsNotNull()) && (m_TagPropertyName.empty() == false)) // tag this node as selected
dsc->GetSelectedNode()->SetProperty(m_TagPropertyName.c_str(), m_TagProperty);
}
}
return;
case IndexCol:
case NameCol:
case StatusCol:
default:
QStyledItemDelegate::setModelData(editor, model, index);
}
}
void QmitkNDIToolDelegate::commitAndCloseEditor()
{
//QWidget* editor = 0;
//if(QPushButton *pushBtn = qobject_cast<QPushButton *>(sender()))
//{
//}
//if(editor)
//{
//emit commitData(editor);
//emit closeEditor(editor);
//}
}
void QmitkNDIToolDelegate::ComboBoxCurrentIndexChanged( int /*index*/ )
{
if(QComboBox *comboBox = qobject_cast<QComboBox *>(sender()))
{
emit commitData(comboBox);
emit closeEditor(comboBox);
}
}
void QmitkNDIToolDelegate::SetTypes( const QStringList& types )
{
m_Types = types;
}
void QmitkNDIToolDelegate::SetDataStorage(mitk::DataStorage* ds)
{
m_DataStorage = ds;
}
void QmitkNDIToolDelegate::SetPredicate(mitk::NodePredicateBase::Pointer p)
{
m_Predicate = p;
}
void QmitkNDIToolDelegate::SetTagProperty(mitk::BaseProperty::Pointer prop)
{
m_TagProperty = prop;
}
void QmitkNDIToolDelegate::SetTagPropertyName( const std::string& name )
{
m_TagPropertyName = name;
}
diff --git a/Modules/IGTUI/Qmitk/QmitkNavigationToolCreationWidget.cpp b/Modules/IGTUI/Qmitk/QmitkNavigationToolCreationWidget.cpp
index 7f1a272816..09aff65686 100644
--- a/Modules/IGTUI/Qmitk/QmitkNavigationToolCreationWidget.cpp
+++ b/Modules/IGTUI/Qmitk/QmitkNavigationToolCreationWidget.cpp
@@ -1,341 +1,341 @@
/*===================================================================
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 "QmitkNavigationToolCreationWidget.h"
//mitk headers
#include "mitkTrackingTypes.h"
#include <mitkIOUtil.h>
#include <mitkSurface.h>
#include "mitkNavigationData.h"
#include "mitkRenderingManager.h"
//qt headers
#include <qfiledialog.h>
#include <qmessagebox.h>
#include <QDialog>
//poco headers
#include <Poco/Path.h>
// vtk
#include <vtkSphereSource.h>
#include "vtkConeSource.h"
const std::string QmitkNavigationToolCreationWidget::VIEW_ID = "org.mitk.views.navigationtoolcreationwizardwidget";
QmitkNavigationToolCreationWidget::QmitkNavigationToolCreationWidget(QWidget* parent, Qt::WindowFlags f)
: QWidget(parent, f)
{
m_Controls = NULL;
m_AdvancedWidget = new QmitkNavigationToolCreationAdvancedWidget(this);
m_AdvancedWidget->setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint);
m_AdvancedWidget->setWindowTitle("Tool Creation Advanced Options");
m_AdvancedWidget->setModal(false);
CreateQtPartControl(this);
CreateConnections();
}
QmitkNavigationToolCreationWidget::~QmitkNavigationToolCreationWidget()
{
m_Controls->m_CalibrationLandmarksList->SetPointSetNode(NULL);
m_Controls->m_RegistrationLandmarksList->SetPointSetNode(NULL);
delete m_AdvancedWidget;
}
void QmitkNavigationToolCreationWidget::CreateQtPartControl(QWidget *parent)
{
if (!m_Controls)
{
// create GUI widgets
m_Controls = new Ui::QmitkNavigationToolCreationWidgetControls;
m_Controls->setupUi(parent);
}
}
void QmitkNavigationToolCreationWidget::CreateConnections()
{
if ( m_Controls )
{
connect( (QObject*)(m_Controls->m_cancel), SIGNAL(clicked()), this, SLOT(OnCancel()) );
connect( (QObject*)(m_Controls->m_finished), SIGNAL(clicked()), this, SLOT(OnFinished()) );
connect( (QObject*)(m_Controls->m_LoadSurface), SIGNAL(clicked()), this, SLOT(OnLoadSurface()) );
connect( (QObject*)(m_Controls->m_LoadCalibrationFile), SIGNAL(clicked()), this, SLOT(OnLoadCalibrationFile()) );
connect( (QObject*)(m_Controls->m_ShowAdvancedOptionsPB), SIGNAL(toggled(bool)), this, SLOT(OnShowAdvancedOptions(bool)) );
connect( (QObject*)(m_AdvancedWidget), SIGNAL(DialogCloseRequested()), this, SLOT(OnProcessDialogCloseRequest()) );
connect( (QObject*)(m_AdvancedWidget), SIGNAL(RetrieveDataForManualToolTipManipulation()), this, SLOT(OnRetrieveDataForManualTooltipManipulation()) );
connect( m_Controls->m_Surface_Use_Other, SIGNAL(toggled(bool)), this, SLOT(OnSurfaceUseOtherToggled(bool)));
}
}
void QmitkNavigationToolCreationWidget::Initialize(mitk::DataStorage* dataStorage, std::string supposedIdentifier, std::string supposedName)
{
m_DataStorage = dataStorage;
//initialize UI components
m_Controls->m_SurfaceChooser->SetDataStorage(m_DataStorage);
m_Controls->m_SurfaceChooser->SetAutoSelectNewItems(true);
m_Controls->m_SurfaceChooser->SetPredicate(mitk::NodePredicateDataType::New("Surface"));
//set default data
m_Controls->m_ToolNameEdit->setText(supposedName.c_str());
m_Controls->m_CalibrationFileName->setText("none");
m_Controls->m_Surface_Use_Sphere->setChecked(true);
m_AdvancedWidget->SetDataStorage(m_DataStorage);
m_Controls->m_IdentifierEdit->setText(supposedIdentifier.c_str());
this->InitializeUIToolLandmarkLists();
m_Controls->m_CalibrationLandmarksList->EnableEditButton(false);
m_Controls->m_RegistrationLandmarksList->EnableEditButton(false);
}
void QmitkNavigationToolCreationWidget::SetTrackingDeviceType(mitk::TrackingDeviceType type, bool changeable)
{
switch(type)
{
case mitk::NDIAurora:
m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(0);break;
case mitk::NDIPolaris:
m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(1);break;
case mitk::ClaronMicron:
m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(2);break;
case mitk::NPOptitrack:
m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(3);break;
default:
m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(0);
}
m_Controls->m_TrackingDeviceTypeChooser->setEnabled(changeable);
}
mitk::NavigationTool::Pointer QmitkNavigationToolCreationWidget::GetCreatedTool()
{
return m_CreatedTool;
}
//##################################################################################
//############################## slots ############################
//##################################################################################
void QmitkNavigationToolCreationWidget::OnFinished()
{
//here we create a new tool
m_CreatedTool = mitk::NavigationTool::New();
//create DataNode...
mitk::DataNode::Pointer newNode = mitk::DataNode::New();
if(m_Controls->m_Surface_Use_Sphere->isChecked())
{
//create small sphere and use it as surface
mitk::Surface::Pointer mySphere = mitk::Surface::New();
vtkConeSource *vtkData = vtkConeSource::New();
vtkData->SetAngle(5.0);
vtkData->SetResolution(50);
vtkData->SetHeight(6.0f);
vtkData->SetRadius(2.0f);
vtkData->SetCenter(0.0, 0.0, 0.0);
vtkData->Update();
mySphere->SetVtkPolyData(vtkData->GetOutput());
vtkData->Delete();
newNode->SetData(mySphere);
}
else
{
newNode->SetData(m_Controls->m_SurfaceChooser->GetSelectedNode()->GetData());
}
newNode->SetName(m_Controls->m_ToolNameEdit->text().toLatin1());
m_CreatedTool->SetDataNode(newNode);
//fill NavigationTool object
-m_CreatedTool->SetCalibrationFile(m_Controls->m_CalibrationFileName->text().toAscii().data());
-m_CreatedTool->SetIdentifier(m_Controls->m_IdentifierEdit->text().toAscii().data());
-m_CreatedTool->SetSerialNumber(m_Controls->m_SerialNumberEdit->text().toAscii().data());
+m_CreatedTool->SetCalibrationFile(m_Controls->m_CalibrationFileName->text().toLatin1().data());
+m_CreatedTool->SetIdentifier(m_Controls->m_IdentifierEdit->text().toLatin1().data());
+m_CreatedTool->SetSerialNumber(m_Controls->m_SerialNumberEdit->text().toLatin1().data());
//Tracking Device
if (m_Controls->m_TrackingDeviceTypeChooser->currentText()=="NDI Aurora") m_CreatedTool->SetTrackingDeviceType(mitk::NDIAurora);
else if (m_Controls->m_TrackingDeviceTypeChooser->currentText()=="NDI Polaris") m_CreatedTool->SetTrackingDeviceType(mitk::NDIPolaris);
else if (m_Controls->m_TrackingDeviceTypeChooser->currentText()=="Claron Technology Micron Tracker") m_CreatedTool->SetTrackingDeviceType(mitk::ClaronMicron);
else if (m_Controls->m_TrackingDeviceTypeChooser->currentText()=="NP Optitrack") m_CreatedTool->SetTrackingDeviceType(mitk::NPOptitrack);
else m_CreatedTool->SetTrackingDeviceType(mitk::TrackingSystemNotSpecified);
//ToolType
if (m_Controls->m_ToolTypeChooser->currentText()=="Instrument") m_CreatedTool->SetType(mitk::NavigationTool::Instrument);
else if (m_Controls->m_ToolTypeChooser->currentText()=="Fiducial") m_CreatedTool->SetType(mitk::NavigationTool::Fiducial);
else if (m_Controls->m_ToolTypeChooser->currentText()=="Skinmarker") m_CreatedTool->SetType(mitk::NavigationTool::Skinmarker);
else m_CreatedTool->SetType(mitk::NavigationTool::Unknown);
//Tool Tip
mitk::NavigationData::Pointer tempND = mitk::NavigationData::New(m_AdvancedWidget->GetManipulatedToolTip());
m_CreatedTool->SetToolTipOrientation(tempND->GetOrientation());
m_CreatedTool->SetToolTipPosition(tempND->GetPosition());
//Tool Landmarks
mitk::PointSet::Pointer toolCalLandmarks, toolRegLandmarks;
GetUIToolLandmarksLists(toolCalLandmarks,toolRegLandmarks);
m_CreatedTool->SetToolCalibrationLandmarks(toolCalLandmarks);
m_CreatedTool->SetToolRegistrationLandmarks(toolRegLandmarks);
emit NavigationToolFinished();
}
void QmitkNavigationToolCreationWidget::OnCancel()
{
m_CreatedTool = NULL;
emit Canceled();
}
void QmitkNavigationToolCreationWidget::OnLoadSurface()
{
std::string filename = QFileDialog::getOpenFileName(NULL,tr("Open Surface"), "/", tr("STL (*.stl)")).toLatin1().data();
mitk::Surface::Pointer surface;
try
{
surface = mitk::IOUtil::LoadSurface(filename);
}
catch (...)
{
}
if (surface.IsNotNull())
{
mitk::DataNode::Pointer newNode = mitk::DataNode::New();
newNode->SetName(filename);
newNode->SetData(surface);
m_DataStorage->Add(newNode);
}
}
void QmitkNavigationToolCreationWidget::OnLoadCalibrationFile()
{
m_Controls->m_CalibrationFileName->setText(QFileDialog::getOpenFileName(NULL,tr("Open Calibration File"), "/", "*.*"));
}
void QmitkNavigationToolCreationWidget::SetDefaultData(mitk::NavigationTool::Pointer DefaultTool)
{
m_Controls->m_ToolNameEdit->setText(QString(DefaultTool->GetDataNode()->GetName().c_str()));
m_Controls->m_IdentifierEdit->setText(QString(DefaultTool->GetIdentifier().c_str()));
m_Controls->m_SerialNumberEdit->setText(QString(DefaultTool->GetSerialNumber().c_str()));
m_AdvancedWidget->SetDefaultTooltip( DefaultTool->GetToolTipTransform() );
switch(DefaultTool->GetTrackingDeviceType())
{
case mitk::NDIAurora:
m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(0);break;
case mitk::NDIPolaris:
m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(1);break;
case mitk::ClaronMicron:
m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(2);break;
case mitk::NPOptitrack:
m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(3);break;
default:
m_Controls->m_TrackingDeviceTypeChooser->setCurrentIndex(0);
}
m_Controls->m_CalibrationFileName->setText(QString(DefaultTool->GetCalibrationFile().c_str()));
m_Controls->m_Surface_Use_Other->setChecked(true);
switch(DefaultTool->GetType())
{
case mitk::NavigationTool::Instrument:
m_Controls->m_ToolTypeChooser->setCurrentIndex(0); break;
case mitk::NavigationTool::Fiducial:
m_Controls->m_ToolTypeChooser->setCurrentIndex(1); break;
case mitk::NavigationTool::Skinmarker:
m_Controls->m_ToolTypeChooser->setCurrentIndex(2); break;
case mitk::NavigationTool::Unknown:
m_Controls->m_ToolTypeChooser->setCurrentIndex(3); break;
}
m_Controls->m_SurfaceChooser->SetSelectedNode(DefaultTool->GetDataNode());
FillUIToolLandmarkLists(DefaultTool->GetToolCalibrationLandmarks(),DefaultTool->GetToolRegistrationLandmarks());
}
//##################################################################################
//############################## internal help methods #############################
//##################################################################################
void QmitkNavigationToolCreationWidget::MessageBox(std::string s)
{
QMessageBox msgBox;
msgBox.setText(s.c_str());
msgBox.exec();
}
void QmitkNavigationToolCreationWidget::OnShowAdvancedOptions(bool state)
{
if(state)
{
m_AdvancedWidget->show();
m_AdvancedWidget->SetDefaultTooltip(m_AdvancedWidget->GetManipulatedToolTip()); //use the last one, if there is one
m_AdvancedWidget->ReInitialize();
// reinit the views with the new nodes
mitk::DataStorage::SetOfObjects::ConstPointer rs = m_DataStorage->GetAll();
mitk::TimeGeometry::Pointer bounds = m_DataStorage->ComputeBoundingGeometry3D(rs, "visible"); // initialize the views to the bounding geometry
mitk::RenderingManager::GetInstance()->InitializeViews(bounds);
}
else
{
m_AdvancedWidget->hide();
}
}
void QmitkNavigationToolCreationWidget::OnProcessDialogCloseRequest()
{
m_AdvancedWidget->hide();
m_Controls->m_ShowAdvancedOptionsPB->setChecked(false);
}
void QmitkNavigationToolCreationWidget::OnRetrieveDataForManualTooltipManipulation()
{
if(m_Controls->m_Surface_Use_Sphere->isChecked())
{
m_AdvancedWidget->SetToolTipSurface(true);
}
else
{
m_AdvancedWidget->SetToolTipSurface(false,
dynamic_cast<mitk::DataNode*>(m_Controls->m_SurfaceChooser->GetSelectedNode().GetPointer()));
}
}
void QmitkNavigationToolCreationWidget::OnSurfaceUseOtherToggled(bool checked)
{
m_Controls->m_LoadSurface->setEnabled(checked);
}
void QmitkNavigationToolCreationWidget::FillUIToolLandmarkLists(mitk::PointSet::Pointer calLandmarks, mitk::PointSet::Pointer regLandmarks)
{
m_calLandmarkNode->SetData(calLandmarks);
m_regLandmarkNode->SetData(regLandmarks);
m_Controls->m_CalibrationLandmarksList->SetPointSetNode(m_calLandmarkNode);
m_Controls->m_RegistrationLandmarksList->SetPointSetNode(m_regLandmarkNode);
}
void QmitkNavigationToolCreationWidget::GetUIToolLandmarksLists(mitk::PointSet::Pointer& calLandmarks, mitk::PointSet::Pointer& regLandmarks)
{
calLandmarks = dynamic_cast<mitk::PointSet*>(m_calLandmarkNode->GetData());
regLandmarks = dynamic_cast<mitk::PointSet*>(m_regLandmarkNode->GetData());
}
void QmitkNavigationToolCreationWidget::InitializeUIToolLandmarkLists()
{
m_calLandmarkNode = mitk::DataNode::New();
m_regLandmarkNode = mitk::DataNode::New();
FillUIToolLandmarkLists(mitk::PointSet::New(),mitk::PointSet::New());
}
diff --git a/Modules/IGTUI/Qmitk/QmitkNavigationToolManagementWidget.cpp b/Modules/IGTUI/Qmitk/QmitkNavigationToolManagementWidget.cpp
index 54fbfaf68b..a74b7e515e 100644
--- a/Modules/IGTUI/Qmitk/QmitkNavigationToolManagementWidget.cpp
+++ b/Modules/IGTUI/Qmitk/QmitkNavigationToolManagementWidget.cpp
@@ -1,356 +1,356 @@
/*===================================================================
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 "QmitkNavigationToolManagementWidget.h"
//mitk headers
#include "mitkTrackingTypes.h"
#include <mitkSurface.h>
#include <mitkNavigationToolReader.h>
#include <mitkNavigationToolWriter.h>
#include <mitkNavigationToolStorage.h>
#include <mitkNavigationToolStorageDeserializer.h>
#include <mitkNavigationToolStorageSerializer.h>
//qt headers
#include <qfiledialog.h>
#include <qinputdialog.h>
#include <qmessagebox.h>
//poco headers
#include <Poco/Path.h>
const std::string QmitkNavigationToolManagementWidget::VIEW_ID = "org.mitk.views.navigationtoolmanagementwidget";
QmitkNavigationToolManagementWidget::QmitkNavigationToolManagementWidget(QWidget* parent, Qt::WindowFlags f)
: QWidget(parent, f)
{
m_Controls = NULL;
CreateQtPartControl(this);
CreateConnections();
}
QmitkNavigationToolManagementWidget::~QmitkNavigationToolManagementWidget()
{
}
void QmitkNavigationToolManagementWidget::CreateQtPartControl(QWidget *parent)
{
if (!m_Controls)
{
// create GUI widgets
m_Controls = new Ui::QmitkNavigationToolManagementWidgetControls;
m_Controls->setupUi(parent);
}
//Disable StorageControls in the beginning, because there is no storage to edit
DisableStorageControls();
}
void QmitkNavigationToolManagementWidget::OnLoadTool()
{
if(m_NavigationToolStorage->isLocked())
{
MessageBox("Storage is locked, cannot modify it. Maybe the tracking device which uses this storage is connected. If you want to modify the storage please disconnect the device first.");
return;
}
mitk::NavigationToolReader::Pointer myReader = mitk::NavigationToolReader::New();
- std::string filename = QFileDialog::getOpenFileName(NULL,tr("Add Navigation Tool"), "/", "*.IGTTool").toAscii().data();
+ std::string filename = QFileDialog::getOpenFileName(NULL,tr("Add Navigation Tool"), "/", "*.IGTTool").toLatin1().data();
if (filename == "") return;
mitk::NavigationTool::Pointer readTool = myReader->DoRead(filename);
if (readTool.IsNull()) MessageBox("Error: " + myReader->GetErrorMessage());
else
{
if (!m_NavigationToolStorage->AddTool(readTool))
{
MessageBox("Error: Can't add tool!");
m_DataStorage->Remove(readTool->GetDataNode());
}
UpdateToolTable();
}
}
void QmitkNavigationToolManagementWidget::OnSaveTool()
{
//if no item is selected, show error message:
if (m_Controls->m_ToolList->currentItem() == NULL) {MessageBox("Error: Please select tool first!");return;}
mitk::NavigationToolWriter::Pointer myWriter = mitk::NavigationToolWriter::New();
- std::string filename = QFileDialog::getSaveFileName(NULL,tr("Save Navigation Tool"), "/", "*.IGTTool").toAscii().data();
+ std::string filename = QFileDialog::getSaveFileName(NULL,tr("Save Navigation Tool"), "/", "*.IGTTool").toLatin1().data();
if (filename == "") return;
if (!myWriter->DoWrite(filename,m_NavigationToolStorage->GetTool(m_Controls->m_ToolList->currentIndex().row())))
MessageBox("Error: "+ myWriter->GetErrorMessage());
}
void QmitkNavigationToolManagementWidget::CreateConnections()
{
if ( m_Controls )
{
//main widget page:
connect( (QObject*)(m_Controls->m_AddTool), SIGNAL(clicked()), this, SLOT(OnAddTool()) );
connect( (QObject*)(m_Controls->m_DeleteTool), SIGNAL(clicked()), this, SLOT(OnDeleteTool()) );
connect( (QObject*)(m_Controls->m_EditTool), SIGNAL(clicked()), this, SLOT(OnEditTool()) );
connect( (QObject*)(m_Controls->m_LoadStorage), SIGNAL(clicked()), this, SLOT(OnLoadStorage()) );
connect( (QObject*)(m_Controls->m_SaveStorage), SIGNAL(clicked()), this, SLOT(OnSaveStorage()) );
connect( (QObject*)(m_Controls->m_LoadTool), SIGNAL(clicked()), this, SLOT(OnLoadTool()) );
connect( (QObject*)(m_Controls->m_SaveTool), SIGNAL(clicked()), this, SLOT(OnSaveTool()) );
connect( (QObject*)(m_Controls->m_CreateNewStorage), SIGNAL(clicked()), this, SLOT(OnCreateStorage()) );
//widget page "add tool":
connect( (QObject*)(m_Controls->m_ToolCreationWidget), SIGNAL(Canceled()), this, SLOT(OnAddToolCancel()) );
connect( (QObject*)(m_Controls->m_ToolCreationWidget), SIGNAL(NavigationToolFinished()), this, SLOT(OnAddToolSave()) );
}
}
void QmitkNavigationToolManagementWidget::Initialize(mitk::DataStorage* dataStorage)
{
m_DataStorage = dataStorage;
m_Controls->m_ToolCreationWidget->Initialize(m_DataStorage,"Tool0");
}
void QmitkNavigationToolManagementWidget::LoadStorage(mitk::NavigationToolStorage::Pointer storageToLoad)
{
if(storageToLoad.IsNotNull())
{
m_NavigationToolStorage = storageToLoad;
m_Controls->m_StorageName->setText(m_NavigationToolStorage->GetName().c_str());
EnableStorageControls();
}
else
{
m_NavigationToolStorage = NULL;
DisableStorageControls();
}
UpdateToolTable();
}
//##################################################################################
//############################## slots: main widget ################################
//##################################################################################
void QmitkNavigationToolManagementWidget::OnAddTool()
{
if(m_NavigationToolStorage->isLocked())
{
MessageBox("Storage is locked, cannot modify it. Maybe the tracking device which uses this storage is connected. If you want to modify the storage please disconnect the device first.");
return;
}
QString defaultIdentifier = "NavigationTool#"+QString::number(m_NavigationToolStorage->GetToolCount());
m_Controls->m_ToolCreationWidget->Initialize(m_DataStorage,defaultIdentifier.toStdString());
m_edit = false;
m_Controls->m_MainWidgets->setCurrentIndex(1);
}
void QmitkNavigationToolManagementWidget::OnDeleteTool()
{
//first: some checks
if(m_NavigationToolStorage->isLocked())
{
MessageBox("Storage is locked, cannot modify it. Maybe the tracking device which uses this storage is connected. If you want to modify the storage please disconnect the device first.");
return;
}
else if (m_Controls->m_ToolList->currentItem() == NULL) //if no item is selected, show error message:
{
MessageBox("Error: Please select tool first!");
return;
}
m_DataStorage->Remove(m_NavigationToolStorage->GetTool(m_Controls->m_ToolList->currentIndex().row())->GetDataNode());
m_NavigationToolStorage->DeleteTool(m_Controls->m_ToolList->currentIndex().row());
UpdateToolTable();
}
void QmitkNavigationToolManagementWidget::OnEditTool()
{
if(m_NavigationToolStorage->isLocked())
{
MessageBox("Storage is locked, cannot modify it. Maybe the tracking device which uses this storage is connected. If you want to modify the storage please disconnect the device first.");
return;
}
else if (m_Controls->m_ToolList->currentItem() == NULL) //if no item is selected, show error message:
{
MessageBox("Error: Please select tool first!");
return;
}
mitk::NavigationTool::Pointer selectedTool = m_NavigationToolStorage->GetTool(m_Controls->m_ToolList->currentIndex().row());
m_Controls->m_ToolCreationWidget->SetDefaultData(selectedTool);
m_edit = true;
m_Controls->m_MainWidgets->setCurrentIndex(1);
}
void QmitkNavigationToolManagementWidget::OnCreateStorage()
{
QString storageName = QInputDialog::getText(NULL,"Storage Name","Name of the new tool storage:");
if (storageName.isNull()) return;
m_NavigationToolStorage = mitk::NavigationToolStorage::New(this->m_DataStorage);
m_NavigationToolStorage->SetName(storageName.toStdString());
m_Controls->m_StorageName->setText(m_NavigationToolStorage->GetName().c_str());
EnableStorageControls();
emit NewStorageAdded(m_NavigationToolStorage, storageName.toStdString());
}
void QmitkNavigationToolManagementWidget::OnLoadStorage()
{
mitk::NavigationToolStorageDeserializer::Pointer myDeserializer = mitk::NavigationToolStorageDeserializer::New(m_DataStorage);
std::string filename = QFileDialog::getOpenFileName(NULL, tr("Open Navigation Tool Storage"), "/", tr("IGT Tool Storage (*.IGTToolStorage)")).toStdString();
if (filename == "") return;
try
{
mitk::NavigationToolStorage::Pointer tempStorage = myDeserializer->Deserialize(filename);
if (tempStorage.IsNull()) MessageBox("Error" + myDeserializer->GetErrorMessage());
else
{
Poco::Path myPath = Poco::Path(filename.c_str());
tempStorage->SetName(myPath.getFileName()); //set the filename as name for the storage, so the user can identify it
this->LoadStorage(tempStorage);
emit NewStorageAdded(m_NavigationToolStorage,myPath.getFileName());
}
}
catch (const mitk::Exception& exception)
{
MessageBox(exception.GetDescription());
}
}
void QmitkNavigationToolManagementWidget::OnSaveStorage()
{
//read in filename
QString filename = QFileDialog::getSaveFileName(NULL, tr("Save Navigation Tool Storage"), "/", tr("IGT Tool Storage (*.IGTToolStorage)"));
if (filename.isEmpty()) return; //canceled by the user
// add file extension if it wasn't added by the file dialog
if ( filename.right(15) != ".IGTToolStorage" ) { filename += ".IGTToolStorage"; }
//serialize tool storage
mitk::NavigationToolStorageSerializer::Pointer mySerializer = mitk::NavigationToolStorageSerializer::New();
if (!mySerializer->Serialize(filename.toStdString(),m_NavigationToolStorage))
{
MessageBox("Error: " + mySerializer->GetErrorMessage());
return;
}
Poco::Path myPath = Poco::Path(filename.toStdString());
m_Controls->m_StorageName->setText(QString::fromStdString(myPath.getFileName()));
}
//##################################################################################
//############################## slots: add tool widget ############################
//##################################################################################
void QmitkNavigationToolManagementWidget::OnAddToolSave()
{
mitk::NavigationTool::Pointer newTool = m_Controls->m_ToolCreationWidget->GetCreatedTool();
if (m_edit) //here we edit a existing tool
{
mitk::NavigationTool::Pointer editedTool = m_NavigationToolStorage->GetTool(m_Controls->m_ToolList->currentIndex().row());
editedTool->Graft(newTool);
}
else //here we create a new tool
{
m_NavigationToolStorage->AddTool(newTool);
}
UpdateToolTable();
m_Controls->m_MainWidgets->setCurrentIndex(0);
}
void QmitkNavigationToolManagementWidget::OnAddToolCancel()
{
m_Controls->m_MainWidgets->setCurrentIndex(0);
}
//##################################################################################
//############################## private help methods ##############################
//##################################################################################
void QmitkNavigationToolManagementWidget::UpdateToolTable()
{
m_Controls->m_ToolList->clear();
if(m_NavigationToolStorage.IsNull()) return;
for(int i=0; i<m_NavigationToolStorage->GetToolCount(); i++)
{
QString currentTool = "Tool" + QString::number(i) + ": " + QString(m_NavigationToolStorage->GetTool(i)->GetDataNode()->GetName().c_str())+ " ";
switch (m_NavigationToolStorage->GetTool(i)->GetTrackingDeviceType())
{
case mitk::ClaronMicron:
currentTool += "(MicronTracker/"; break;
case mitk::NDIAurora:
currentTool += "(NDI Aurora/"; break;
case mitk::NDIPolaris:
currentTool += "(NDI Polaris/"; break;
case mitk::NPOptitrack:
currentTool += "(NP Optitrack/"; break;
default:
currentTool += "(unknown tracking system/"; break;
}
switch (m_NavigationToolStorage->GetTool(i)->GetType())
{
case mitk::NavigationTool::Instrument:
currentTool += "Instrument)"; break;
case mitk::NavigationTool::Fiducial:
currentTool += "Fiducial)"; break;
case mitk::NavigationTool::Skinmarker:
currentTool += "Skinmarker)"; break;
default:
currentTool += "Unknown)";
}
m_Controls->m_ToolList->addItem(currentTool);
}
}
void QmitkNavigationToolManagementWidget::MessageBox(std::string s)
{
QMessageBox msgBox;
msgBox.setText(s.c_str());
msgBox.exec();
}
void QmitkNavigationToolManagementWidget::DisableStorageControls()
{
m_Controls->m_StorageName->setText("<none>");
m_Controls->m_AddTool->setEnabled(false);
m_Controls->m_LoadTool->setEnabled(false);
m_Controls->m_selectedLabel->setEnabled(false);
m_Controls->m_DeleteTool->setEnabled(false);
m_Controls->m_EditTool->setEnabled(false);
m_Controls->m_SaveTool->setEnabled(false);
m_Controls->m_ToolList->setEnabled(false);
m_Controls->m_SaveStorage->setEnabled(false);
m_Controls->m_ToolLabel->setEnabled(false);
}
void QmitkNavigationToolManagementWidget::EnableStorageControls()
{
m_Controls->m_AddTool->setEnabled(true);
m_Controls->m_LoadTool->setEnabled(true);
m_Controls->m_selectedLabel->setEnabled(true);
m_Controls->m_DeleteTool->setEnabled(true);
m_Controls->m_EditTool->setEnabled(true);
m_Controls->m_SaveTool->setEnabled(true);
m_Controls->m_ToolList->setEnabled(true);
m_Controls->m_SaveStorage->setEnabled(true);
m_Controls->m_ToolLabel->setEnabled(true);
}
diff --git a/Modules/IGTUI/Qmitk/QmitkTrackingDeviceConfigurationWidget.cpp b/Modules/IGTUI/Qmitk/QmitkTrackingDeviceConfigurationWidget.cpp
index 028bb29069..f5cb6899d9 100644
--- a/Modules/IGTUI/Qmitk/QmitkTrackingDeviceConfigurationWidget.cpp
+++ b/Modules/IGTUI/Qmitk/QmitkTrackingDeviceConfigurationWidget.cpp
@@ -1,728 +1,728 @@
/*===================================================================
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 "QmitkTrackingDeviceConfigurationWidget.h"
#include <mitkClaronTrackingDevice.h>
#include <mitkNDITrackingDevice.h>
#include <mitkOptitrackTrackingDevice.h>
#include <mitkIGTException.h>
#include <mitkSerialCommunication.h>
#include <mitkProgressBar.h>
#include <qscrollbar.h>
#include <qmessagebox.h>
#include <qfiledialog.h>
#include <mitkIGTException.h>
#include <QSettings>
#include <itksys/SystemTools.hxx>
#include <Poco/Path.h>
const std::string QmitkTrackingDeviceConfigurationWidget::VIEW_ID = "org.mitk.views.trackingdeviceconfigurationwidget";
QmitkTrackingDeviceConfigurationWidget::QmitkTrackingDeviceConfigurationWidget(QWidget* parent, Qt::WindowFlags f)
: QWidget(parent, f)
{
//initialize worker thread
m_TestConnectionWorker = new QmitkTrackingDeviceConfigurationWidgetConnectionWorker();
m_ScanPortsWorker = new QmitkTrackingDeviceConfigurationWidgetScanPortsWorker();
m_ScanPortsWorkerThread = new QThread();
m_TestConnectionWorkerThread = new QThread();
//initializations
m_Controls = NULL;
CreateQtPartControl(this);
CreateConnections();
m_MTCalibrationFile = "";
m_AdvancedUserControl = true;
//initialize a few UI elements
this->m_TrackingDeviceConfigurated = false;
AddOutput("<br>NDI Polaris selected"); //Polaris is selected by default
m_Controls->m_trackingDeviceChooser->setCurrentIndex(0);
m_Controls->m_TrackingSystemWidget->setCurrentIndex(0);
//reset a few things
ResetOutput();
//restore old UI settings
LoadUISettings();
}
void QmitkTrackingDeviceConfigurationWidget::SetGUIStyle(QmitkTrackingDeviceConfigurationWidget::Style style)
{
switch(style)
{
case QmitkTrackingDeviceConfigurationWidget::SIMPLE:
//move all UI elements to an empty dummy layout
//m_Controls->dummyLayout->addItem(m_Controls->mainLayout);
m_Controls->dummyLayout->addWidget(m_Controls->widget_title_label);
m_Controls->dummyLayout->addWidget(m_Controls->choose_tracking_device_label);
m_Controls->dummyLayout->addWidget(m_Controls->polaris_label);
m_Controls->dummyLayout->addWidget(m_Controls->aurora_label);
//m_Controls->dummyLayout->addWidget(m_Controls->aurora_label);
m_Controls->dummyLayout->addWidget(m_Controls->microntracker_label);
m_Controls->dummyLayout->addWidget(m_Controls->m_testConnectionMicronTracker);
m_Controls->dummyLayout->addWidget(m_Controls->m_outputTextMicronTracker);
m_Controls->dummyLayout->addWidget(m_Controls->m_outputTextAurora);
m_Controls->dummyLayout->addWidget(m_Controls->m_testConnectionAurora);
m_Controls->dummyLayout->addWidget(m_Controls->m_outputTextPolaris);
m_Controls->dummyLayout->addWidget(m_Controls->m_testConnectionPolaris);
m_Controls->dummyLayout->addWidget(m_Controls->m_polarisTrackingModeBox);
m_Controls->dummyLayout->addWidget(m_Controls->m_testConnectionOptitrack);
m_Controls->dummyLayout->addWidget(m_Controls->m_outputTextOptitrack);
m_Controls->dummyLayout->addWidget(m_Controls->m_OptitrackExp);
m_Controls->dummyLayout->addWidget(m_Controls->m_OptitrackThr);
m_Controls->dummyLayout->addWidget(m_Controls->m_OptitrackLed);
m_Controls->dummyLayout->addWidget(m_Controls->Optitrack_label);
m_Controls->dummyLayout->addWidget(m_Controls->m_finishedLine);
m_Controls->dummyLayout->addWidget(m_Controls->line);
m_Controls->dummyLayout->addWidget(m_Controls->configuration_finished_label);
m_Controls->dummyLayout->addItem(m_Controls->horizontalLayout_4);
m_Controls->mainLayout->removeItem(m_Controls->horizontalLayout_4);
m_Controls->dummyLayout->addWidget(m_Controls->configuration_finished_label);
m_Controls->dummyLayout->addItem(m_Controls->verticalSpacer_2);
m_Controls->verticalLayout_3->removeItem(m_Controls->verticalSpacer_2);
m_Controls->dummyLayout->addItem(m_Controls->horizontalSpacer_9);
m_Controls->horizontalLayout_9->removeItem(m_Controls->horizontalSpacer_9);
m_Controls->dummyLayout->addItem(m_Controls->horizontalSpacer_3);
m_Controls->horizontalLayout_11->removeItem(m_Controls->horizontalSpacer_3);
m_Controls->dummyLayout->addItem(m_Controls->verticalSpacer_3);
m_Controls->verticalLayout_7->removeItem(m_Controls->verticalSpacer_3);
m_Controls->dummyLayout->addItem(m_Controls->verticalSpacer_4);
m_Controls->verticalLayout_10->removeItem(m_Controls->verticalSpacer_4);
m_Controls->dummyLayout->addItem(m_Controls->horizontalSpacer_10);
m_Controls->verticalLayout_10->removeItem(m_Controls->horizontalSpacer_10);
//set height to min
m_Controls->m_outputTextPolaris->setMinimumHeight(0);
m_Controls->m_outputTextPolaris->setMaximumHeight(0);
m_Controls->m_outputTextMicronTracker->setMinimumHeight(0);
m_Controls->m_outputTextMicronTracker->setMaximumHeight(0);
m_Controls->m_outputTextAurora->setMinimumHeight(0);
m_Controls->m_outputTextAurora->setMaximumHeight(0);
m_Controls->m_finishedButton->setMinimumHeight(0);
m_Controls->m_finishedButton->setMaximumHeight(0);
m_Controls->m_resetButton->setMinimumHeight(0);
m_Controls->m_resetButton->setMaximumHeight(0);
//set the height of the tracking device combo box
m_Controls->m_trackingDeviceChooser->setMinimumHeight(50);
//move back the used elemets to the main layout
m_Controls->simpleLayout->addWidget(m_Controls->m_trackingDeviceChooser);
m_Controls->simpleLayout->addWidget(m_Controls->m_TrackingSystemWidget);
m_Controls->mainWidget->setCurrentIndex(1);
this->setMaximumHeight(150);
this->EnableAdvancedUserControl(false);
break;
case QmitkTrackingDeviceConfigurationWidget::ADVANCED:
//default at the moment => start settings are advanced
break;
}
}
QmitkTrackingDeviceConfigurationWidget::~QmitkTrackingDeviceConfigurationWidget()
{
StoreUISettings();
if (m_ScanPortsWorker) delete m_ScanPortsWorker;
if (m_TestConnectionWorker) delete m_TestConnectionWorker;
if (m_ScanPortsWorkerThread) delete m_ScanPortsWorkerThread;
if (m_TestConnectionWorkerThread) delete m_TestConnectionWorkerThread;
}
void QmitkTrackingDeviceConfigurationWidget::CreateQtPartControl(QWidget *parent)
{
if (!m_Controls)
{
// create GUI widgets
m_Controls = new Ui::QmitkTrackingDeviceConfigurationWidgetControls;
m_Controls->setupUi(parent);
}
}
void QmitkTrackingDeviceConfigurationWidget::CreateConnections()
{
if ( m_Controls )
{
connect( (QObject*)(m_Controls->m_trackingDeviceChooser), SIGNAL(currentIndexChanged(int)), this, SLOT(TrackingDeviceChanged()) );
connect( (QObject*)(m_Controls->m_testConnectionPolaris), SIGNAL(clicked()), this, SLOT(TestConnection()) );
connect( (QObject*)(m_Controls->m_testConnectionAurora), SIGNAL(clicked()), this, SLOT(TestConnection()) );
connect( (QObject*)(m_Controls->m_testConnectionMicronTracker), SIGNAL(clicked()), this, SLOT(TestConnection()) );
connect( (QObject*)(m_Controls->m_testConnectionOptitrack), SIGNAL(clicked()), this, SLOT(TestConnection()) );
connect( (QObject*)(m_Controls->m_resetButton), SIGNAL(clicked()), this, SLOT(ResetByUser()) );
connect( (QObject*)(m_Controls->m_finishedButton), SIGNAL(clicked()), this, SLOT(Finished()) );
connect( (QObject*)(m_Controls->m_AutoScanPolaris), SIGNAL(clicked()), this, SLOT(AutoScanPorts()) );
connect( (QObject*)(m_Controls->m_AutoScanAurora), SIGNAL(clicked()), this, SLOT(AutoScanPorts()) );
connect( (QObject*)(m_Controls->m_SetMTCalibrationFile), SIGNAL(clicked()), this, SLOT(SetMTCalibrationFileClicked()) );
connect( (QObject*)(m_Controls->m_SetOptitrackCalibrationFile), SIGNAL(clicked()), this, SLOT(SetOptitrackCalibrationFileClicked()) );
//slots for the worker thread
connect(m_ScanPortsWorker, SIGNAL(PortsScanned(int,int,QString,int,int)), this, SLOT(AutoScanPortsFinished(int,int,QString,int,int)) );
connect(m_TestConnectionWorker, SIGNAL(ConnectionTested(bool,QString)), this, SLOT(TestConnectionFinished(bool,QString)) );
connect(m_ScanPortsWorkerThread,SIGNAL(started()), m_ScanPortsWorker, SLOT(ScanPortsThreadFunc()) );
connect(m_TestConnectionWorkerThread,SIGNAL(started()), m_TestConnectionWorker, SLOT(TestConnectionThreadFunc()) );
//move the worker to the thread
m_ScanPortsWorker->moveToThread(m_ScanPortsWorkerThread);
m_TestConnectionWorker->moveToThread(m_TestConnectionWorkerThread);
//set a few UI components depending on Windows / Linux
#ifdef WIN32
m_Controls->portTypeLabelPolaris->setVisible(false);
m_Controls->portTypePolaris->setVisible(false);
m_Controls->portTypeLabelAurora->setVisible(false);
m_Controls->portTypeAurora->setVisible(false);
#else
m_Controls->comPortLabelAurora->setText("Port Nr:");
m_Controls->m_comPortLabelPolaris->setText("Port Nr:");
m_Controls->m_portSpinBoxAurora->setPrefix("");
m_Controls->m_portSpinBoxPolaris->setPrefix("");
#endif
//disable unused UI component
m_Controls->m_polarisTrackingModeBox->setVisible(false); //don't delete this component, because it is used in the MBI part of MITK
}
}
void QmitkTrackingDeviceConfigurationWidget::TrackingDeviceChanged()
{
//show the correspondig widget
m_Controls->m_TrackingSystemWidget->setCurrentIndex(m_Controls->m_trackingDeviceChooser->currentIndex());
//the new trackingdevice is not configurated yet
m_TrackingDeviceConfigurated = false;
//reset output
ResetOutput();
//print output and do further initializations
if (m_Controls->m_trackingDeviceChooser->currentIndex()==0)//NDI Polaris
{
AddOutput("<br>NDI Polaris selected");
}
else if (m_Controls->m_trackingDeviceChooser->currentIndex()==1) //NDI Aurora
{
AddOutput("<br>NDI Aurora selected");
}
else if (m_Controls->m_trackingDeviceChooser->currentIndex()==2) //ClaronTechnology MicronTracker 2
{
AddOutput("<br>Microntracker selected");
if (!mitk::ClaronTrackingDevice::New()->IsDeviceInstalled())
{
AddOutput("<br>ERROR: not installed!");
}
else if (this->m_MTCalibrationFile == "") //if configuration file for MicronTracker is empty: load default
{
mitk::ClaronTrackingDevice::Pointer tempDevice = mitk::ClaronTrackingDevice::New();
m_MTCalibrationFile = tempDevice->GetCalibrationDir();
Poco::Path myPath = Poco::Path(m_MTCalibrationFile.c_str());
m_Controls->m_MTCalibrationFile->setText("Calibration File: " + QString(myPath.getFileName().c_str()));
}
}
else if (m_Controls->m_trackingDeviceChooser->currentIndex()==3)
{
AddOutput("<br>Optitrack selected");
if (!mitk::OptitrackTrackingDevice::New()->IsDeviceInstalled())
{
AddOutput("<br>ERROR: not installed!");
}
}
emit TrackingDeviceSelectionChanged();
}
void QmitkTrackingDeviceConfigurationWidget::EnableUserReset(bool enable)
{
if (enable) m_Controls->m_resetButton->setVisible(true);
else m_Controls->m_resetButton->setVisible(false);
}
void QmitkTrackingDeviceConfigurationWidget::TestConnection()
{
this->setEnabled(false);
//construct a tracking device:
mitk::TrackingDevice::Pointer testTrackingDevice = ConstructTrackingDevice();
m_TestConnectionWorker->SetTrackingDevice(testTrackingDevice);
m_TestConnectionWorkerThread->start();
emit ProgressStarted();
}
void QmitkTrackingDeviceConfigurationWidget::TestConnectionFinished(bool connected, QString output)
{
m_TestConnectionWorkerThread->quit();
AddOutput(output.toStdString());
MITK_INFO << "Test connection: " << connected;
this->setEnabled(true);
emit ProgressFinished();
}
void QmitkTrackingDeviceConfigurationWidget::Finished()
{
m_TrackingDevice = ConstructTrackingDevice();
m_Controls->m_TrackingSystemWidget->setEnabled(false);
m_Controls->m_trackingDeviceChooser->setEnabled(false);
m_Controls->choose_tracking_device_label->setEnabled(false);
m_Controls->configuration_finished_label->setText("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\np, li { white-space: pre-wrap; }\n</style></head><body style=\" font-family:\'MS Shell Dlg 2\'; font-size:8.25pt; font-weight:400; font-style:normal;\">\n<p align=\"right\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;\"><span style=\" font-weight:600;\">Configuration finished</span></p></body></html>");
this->m_TrackingDeviceConfigurated = true;
emit TrackingDeviceConfigurationFinished();
}
void QmitkTrackingDeviceConfigurationWidget::Reset()
{
m_TrackingDevice = NULL;
m_Controls->m_TrackingSystemWidget->setEnabled(true);
m_Controls->m_trackingDeviceChooser->setEnabled(true);
m_Controls->choose_tracking_device_label->setEnabled(true);
m_Controls->configuration_finished_label->setText("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\np, li { white-space: pre-wrap; }\n</style></head><body style=\" font-family:\'MS Shell Dlg 2\'; font-size:8.25pt; font-weight:400; font-style:normal;\">\n<p align=\"right\" style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;\"><span style=\" font-weight:600;\">Press \"Finished\" to confirm configuration</span></p></body></html>");
this->m_TrackingDeviceConfigurated = false;
emit TrackingDeviceConfigurationReseted();
}
void QmitkTrackingDeviceConfigurationWidget::ResetByUser()
{
Reset();
}
void QmitkTrackingDeviceConfigurationWidget::AutoScanPorts()
{
this->setEnabled(false);
AddOutput("<br>Scanning...");
m_ScanPortsWorkerThread->start();
emit ProgressStarted();
}
void QmitkTrackingDeviceConfigurationWidget::AutoScanPortsFinished(int PolarisPort, int AuroraPort, QString result, int PortTypePolaris, int PortTypeAurora)
{
m_ScanPortsWorkerThread->quit();
#ifdef WIN32
if((PortTypePolaris!=-1)||(PortTypeAurora!=-1)) {MITK_WARN << "Port type is specified although this should not be the case for Windows. Ignoring port type.";}
#else //linux systems
if (PortTypePolaris!=-1) {m_Controls->portTypePolaris->setCurrentIndex(PortTypePolaris);}
if (PortTypeAurora!=-1) {m_Controls->portTypeAurora->setCurrentIndex(PortTypeAurora);}
#endif
m_Controls->m_portSpinBoxPolaris->setValue(PolarisPort);
m_Controls->m_portSpinBoxAurora->setValue(AuroraPort);
AddOutput(result.toStdString());
this->setEnabled(true);
emit ProgressFinished();
}
void QmitkTrackingDeviceConfigurationWidget::SetMTCalibrationFileClicked()
{
- std::string filename = QFileDialog::getOpenFileName(NULL,tr("Open Calibration File"), "/", "*.*").toAscii().data();
+ std::string filename = QFileDialog::getOpenFileName(NULL,tr("Open Calibration File"), "/", "*.*").toLatin1().data();
if (filename=="") {return;}
else
{
m_MTCalibrationFile = filename;
Poco::Path myPath = Poco::Path(m_MTCalibrationFile.c_str());
m_Controls->m_MTCalibrationFile->setText("Calibration File: " + QString(myPath.getFileName().c_str()));
}
}
void QmitkTrackingDeviceConfigurationWidget::SetOptitrackCalibrationFileClicked()
{
- std::string filename = QFileDialog::getOpenFileName(NULL,tr("Open Calibration File"), "/", "*.*").toAscii().data();
+ std::string filename = QFileDialog::getOpenFileName(NULL,tr("Open Calibration File"), "/", "*.*").toLatin1().data();
if (filename=="") {return;}
else
{
m_OptitrackCalibrationFile = filename;
Poco::Path myPath = Poco::Path(m_OptitrackCalibrationFile.c_str());
m_Controls->m_OptitrackCalibrationFile->setText("Calibration File: " + QString(myPath.getFileName().c_str()));
}
}
//######################### internal help methods #######################################
void QmitkTrackingDeviceConfigurationWidget::ResetOutput()
{
m_output.str("");
m_output <<"<body style=\" font-family:\'MS Shell Dlg 2\'; font-size:7pt; font-weight:400; font-style:normal;\" bgcolor=black><span style=\"color:#ffffff;\"><u>output:</u>";
m_Controls->m_outputTextAurora->setHtml(QString(m_output.str().c_str()));
m_Controls->m_outputTextPolaris->setHtml(QString(m_output.str().c_str()));
m_Controls->m_outputTextMicronTracker->setHtml(QString(m_output.str().c_str()));
}
void QmitkTrackingDeviceConfigurationWidget::AddOutput(std::string s)
{
//print output
m_output << s;
m_Controls->m_outputTextAurora->setHtml(QString(m_output.str().c_str()));
m_Controls->m_outputTextPolaris->setHtml(QString(m_output.str().c_str()));
m_Controls->m_outputTextMicronTracker->setHtml(QString(m_output.str().c_str()));
m_Controls->m_outputTextOptitrack->setHtml(QString(m_output.str().c_str()));
m_Controls->m_outputTextPolaris->verticalScrollBar()->setValue(m_Controls->m_outputTextPolaris->verticalScrollBar()->maximum());
m_Controls->m_outputTextAurora->verticalScrollBar()->setValue(m_Controls->m_outputTextAurora->verticalScrollBar()->maximum());
m_Controls->m_outputTextMicronTracker->verticalScrollBar()->setValue(m_Controls->m_outputTextMicronTracker->verticalScrollBar()->maximum());
m_Controls->m_outputTextOptitrack->verticalScrollBar()->setValue(m_Controls->m_outputTextOptitrack->verticalScrollBar()->maximum());
repaint();
}
mitk::TrackingDevice::Pointer QmitkTrackingDeviceConfigurationWidget::ConstructTrackingDevice()
{
mitk::TrackingDevice::Pointer returnValue;
//#### Step 1: configure tracking device:
MITK_INFO << "Current Index: " << m_Controls->m_trackingDeviceChooser->currentIndex();
if (m_Controls->m_trackingDeviceChooser->currentIndex()==0)//NDI Polaris
{
if(m_Controls->m_radioPolaris5D->isChecked()) //5D Tracking
{
//not yet in the open source part so we'll only get NULL here.
returnValue = ConfigureNDI5DTrackingDevice();
}
else //6D Tracking
{
returnValue = ConfigureNDI6DTrackingDevice();
returnValue->SetType(mitk::NDIPolaris);
}
}
else if (m_Controls->m_trackingDeviceChooser->currentIndex()==1)//NDI Aurora
{
returnValue = ConfigureNDI6DTrackingDevice();
returnValue->SetType(mitk::NDIAurora);
}
else if (m_Controls->m_trackingDeviceChooser->currentIndex()==2)//ClaronTechnology MicronTracker 2
{
mitk::ClaronTrackingDevice::Pointer newDevice = mitk::ClaronTrackingDevice::New();
if(this->m_MTCalibrationFile=="") AddOutput("<br>Warning: Calibration file is not set!");
else
{
//extract path from calibration file and set the calibration dir of the device
std::string path = itksys::SystemTools::GetFilenamePath(m_MTCalibrationFile);
newDevice->SetCalibrationDir(path);
}
returnValue = newDevice;
}
else if (m_Controls->m_trackingDeviceChooser->currentIndex()==3)
{
// Create the Tracking Device this->m_OptitrackDevice = mitk::OptitrackTrackingDevice::New();
returnValue = ConfigureOptitrackTrackingDevice();
returnValue->SetType(mitk::NPOptitrack);
}
return returnValue;
}
mitk::TrackingDevice::Pointer QmitkTrackingDeviceConfigurationWidget::ConfigureNDI5DTrackingDevice()
{
return NULL;
}
mitk::TrackingDevice::Pointer QmitkTrackingDeviceConfigurationWidget::ConfigureOptitrackTrackingDevice()
{
mitk::OptitrackTrackingDevice::Pointer tempTrackingDevice = mitk::OptitrackTrackingDevice::New();
// Set the calibration File
tempTrackingDevice->SetCalibrationPath(m_OptitrackCalibrationFile);
//Set the camera parameters
tempTrackingDevice->SetExp(m_Controls->m_OptitrackExp->value());
tempTrackingDevice->SetLed(m_Controls->m_OptitrackLed->value());
tempTrackingDevice->SetThr(m_Controls->m_OptitrackThr->value());
mitk::TrackingDevice::Pointer returnValue = static_cast<mitk::TrackingDevice*>(tempTrackingDevice);
return returnValue;
}
mitk::TrackingDevice::Pointer QmitkTrackingDeviceConfigurationWidget::ConfigureNDI6DTrackingDevice()
{
mitk::NDITrackingDevice::Pointer tempTrackingDevice = mitk::NDITrackingDevice::New();
//get port
int port = 0;
if (m_Controls->m_trackingDeviceChooser->currentIndex()==1) port = m_Controls->m_portSpinBoxAurora->value();
else port = m_Controls->m_portSpinBoxPolaris->value();
//build prefix (depends on linux/win)
QString prefix = "";
#ifdef WIN32
prefix ="COM";
tempTrackingDevice->SetPortNumber(static_cast<mitk::SerialCommunication::PortNumber>(port)); //also set the com port for compatibility
#else
if (m_Controls->m_trackingDeviceChooser->currentIndex()==1) //Aurora
prefix = m_Controls->portTypeAurora->currentText();
else //Polaris
prefix = m_Controls->portTypePolaris->currentText();
#endif
//build port name string
QString portName = prefix + QString::number(port);
tempTrackingDevice->SetDeviceName(portName.toStdString()); //set the port name
tempTrackingDevice->SetBaudRate(mitk::SerialCommunication::BaudRate115200);//set baud rate
mitk::TrackingDevice::Pointer returnValue = static_cast<mitk::TrackingDevice*>(tempTrackingDevice);
return returnValue;
}
mitk::TrackingDevice::Pointer QmitkTrackingDeviceConfigurationWidget::GetTrackingDevice()
{
if (!m_AdvancedUserControl) m_TrackingDevice = ConstructTrackingDevice();
if (m_TrackingDevice.IsNull() || !m_TrackingDevice->IsDeviceInstalled()) return NULL;
else return this->m_TrackingDevice;
}
bool QmitkTrackingDeviceConfigurationWidget::GetTrackingDeviceConfigured()
{
return this->m_TrackingDeviceConfigurated;
}
void QmitkTrackingDeviceConfigurationWidget::ConfigurationFinished()
{
Finished();
}
void QmitkTrackingDeviceConfigurationWidget::EnableAdvancedUserControl(bool enable)
{
m_AdvancedUserControl = enable;
m_Controls->configuration_finished_label->setVisible(enable);
m_Controls->m_finishedLine->setVisible(enable);
m_Controls->m_resetButton->setVisible(enable);
m_Controls->m_finishedButton->setVisible(enable);
}
void QmitkTrackingDeviceConfigurationWidget::StoreUISettings()
{
std::string id = "org.mitk.modules.igt.ui.trackingdeviceconfigurationwidget";
int selectedDevice = m_Controls->m_trackingDeviceChooser->currentIndex();
if ( this->GetPeristenceService() ) // now save the settings using the persistence service
{
mitk::PropertyList::Pointer propList = this->GetPeristenceService()->GetPropertyList(id);
propList->Set("PolarisPortWin",m_Controls->m_portSpinBoxPolaris->value());
propList->Set("AuroraPortWin",m_Controls->m_portSpinBoxAurora->value());
propList->Set("PortTypePolaris", m_Controls->portTypePolaris->currentIndex());
propList->Set("PortTypeAurora", m_Controls->portTypeAurora->currentIndex());
propList->Set("MTCalibrationFile",m_MTCalibrationFile);
propList->Set("SelectedDevice",selectedDevice);
}
else // QSettings as a fallback if the persistence service is not available
{
QSettings settings;
settings.beginGroup(QString::fromStdString(id));
settings.setValue("trackingDeviceChooser", QVariant(selectedDevice));
settings.setValue("portSpinBoxAurora", QVariant(m_Controls->m_portSpinBoxAurora->value()));
settings.setValue("portSpinBoxPolaris", QVariant(m_Controls->m_portSpinBoxPolaris->value()));
settings.setValue("portTypePolaris", QVariant(m_Controls->portTypePolaris->currentIndex()));
settings.setValue("portTypeAurora", QVariant(m_Controls->portTypeAurora->currentIndex()));
settings.setValue("mTCalibrationFile", QVariant(QString::fromStdString(m_MTCalibrationFile)));
settings.endGroup();
}
}
void QmitkTrackingDeviceConfigurationWidget::LoadUISettings()
{
std::string id = "org.mitk.modules.igt.ui.trackingdeviceconfigurationwidget";
int SelectedDevice = 0;
if ( this->GetPeristenceService() )
{
mitk::PropertyList::Pointer propList = this->GetPeristenceService()->GetPropertyList(id);
if (propList.IsNull())
{MITK_ERROR << "Property list for this UI (" << id <<") is not available, could not load UI settings!"; return;}
int portPolarisWin,portAuroraWin,portTypePolaris,portTypeAurora;
propList->Get("PolarisPortWin",portPolarisWin);
propList->Get("AuroraPortWin",portAuroraWin);
propList->Get("PortTypePolaris", portTypePolaris);
propList->Get("PortTypeAurora", portTypeAurora);
propList->Get("MTCalibrationFile",m_MTCalibrationFile);
propList->Get("SelectedDevice",SelectedDevice);
if (SelectedDevice<0)
{
MITK_ERROR << "Loaded data from persistence service is invalid (SelectedDevice:" <<SelectedDevice<<"): aborted to restore data!";
return;
}
m_Controls->m_portSpinBoxPolaris->setValue(portPolarisWin);
m_Controls->m_portSpinBoxAurora->setValue(portAuroraWin);
m_Controls->portTypePolaris->setCurrentIndex(portTypePolaris);
m_Controls->portTypeAurora->setCurrentIndex(portTypeAurora);
MITK_INFO << "Sucessfully restored UI settings";
}
else
{
// QSettings as a fallback if the persistence service is not available
QSettings settings;
settings.beginGroup(QString::fromStdString(id));
SelectedDevice = settings.value("trackingDeviceChooser", 0).toInt();
m_Controls->m_portSpinBoxAurora->setValue(settings.value("portSpinBoxAurora", 0).toInt());
m_Controls->m_portSpinBoxPolaris->setValue(settings.value("portSpinBoxPolaris", 0).toInt());
m_Controls->portTypePolaris->setCurrentIndex(settings.value("portTypePolaris", 0).toInt());
m_Controls->portTypeAurora->setCurrentIndex(settings.value("portTypeAurora", 0).toInt());
m_MTCalibrationFile = settings.value("mTCalibrationFile", "").toString().toStdString();
settings.endGroup();
}
//the selected device requires some checks because a device that is not installed should not be restored to avoids bugs
int selectedDeviceChecked = SelectedDevice;
if (SelectedDevice==2 && !mitk::ClaronTrackingDevice::New()->IsDeviceInstalled())
{selectedDeviceChecked = 0;} //0 = Polaris (default)
else if (SelectedDevice==3 && !mitk::OptitrackTrackingDevice::New()->IsDeviceInstalled())
{selectedDeviceChecked = 0;}
MITK_INFO << "SelectedDeviceChecked: " << selectedDeviceChecked;
m_Controls->m_TrackingSystemWidget->setCurrentIndex(selectedDeviceChecked);
m_Controls->m_trackingDeviceChooser->setCurrentIndex(selectedDeviceChecked);
m_Controls->m_MTCalibrationFile->setText("Calibration File: " + QString::fromStdString(m_MTCalibrationFile));
}
void QmitkTrackingDeviceConfigurationWidgetConnectionWorker::TestConnectionThreadFunc()
{
MITK_INFO << "Testing Connection!";
QString output;
bool connected = false;
mitk::ProgressBar::GetInstance()->AddStepsToDo(4);
try
{
if (!m_TrackingDevice->IsDeviceInstalled())
{
output = "ERROR: Device is not installed!";
}
else
{
//test connection and start tracking, generate output
output = "<br>testing connection <br> ...";
m_TrackingDevice->OpenConnection();
output += "OK";
mitk::ProgressBar::GetInstance()->Progress();
//try start/stop tracking
output += "<br>testing tracking <br> ...";
m_TrackingDevice->StartTracking();
mitk::ProgressBar::GetInstance()->Progress();
m_TrackingDevice->StopTracking();
mitk::ProgressBar::GetInstance()->Progress();
//try close connection
m_TrackingDevice->CloseConnection();
mitk::ProgressBar::GetInstance()->Progress();
output += "OK";
connected = true;
}
}
catch(mitk::IGTException &e)
{
output += "ERROR!";
MITK_WARN << "Error while testing connection / start tracking of the device: " << e.GetDescription();
}
mitk::ProgressBar::GetInstance()->Progress(4);
emit ConnectionTested(connected,output);
}
void QmitkTrackingDeviceConfigurationWidgetScanPortsWorker::ScanPortsThreadFunc()
{
int PolarisPort = -1;
int AuroraPort = -1;
int PortTypePolaris = -1;
int PortTypeAurora = -1;
QString result = "<br>Found Devices:";
int resultSize = result.size(); //remember size of result: if it stays the same no device were found
#ifdef WIN32
mitk::ProgressBar::GetInstance()->AddStepsToDo(19);
QString devName;
for (unsigned int i = 1; i < 20; ++i)
{
QString statusOutput = "Scanning Port #" + QString::number(i);
MITK_INFO << statusOutput.toStdString().c_str();
if (i<10) devName = QString("COM%1").arg(i);
else devName = QString("\\\\.\\COM%1").arg(i); // prepend "\\.\ to COM ports >9, to be able to allow connection"
mitk::TrackingDeviceType scannedPort = ScanPort(devName);
switch (scannedPort)
{
case mitk::NDIPolaris:
result += "<br>" + devName + ": " + "NDI Polaris";
PolarisPort = i;
break;
case mitk::NDIAurora:
result += "<br>" + devName + ": " + "NDI Aurora";
AuroraPort = i;
break;
}
mitk::ProgressBar::GetInstance()->Progress();
}
#else //linux systems
for(unsigned int i = 1; i < 6; ++i)
{
QString devName = QString("/dev/ttyS%1").arg(i);
mitk::TrackingDeviceType scannedPort = ScanPort(devName);
switch (scannedPort)
{
case mitk::NDIPolaris:
result += "<br>" + devName + ": " + "NDI Polaris";
PolarisPort = i;
PortTypePolaris = 1;
break;
case mitk::NDIAurora:
result += "<br>" + devName + ": " + "NDI Aurora";
AuroraPort = i;
PortTypeAurora = 1;
break;
}
}
for(unsigned int i = 0; i <7; ++i)
{
QString devName = QString("/dev/ttyUSB%1").arg(i);
mitk::TrackingDeviceType scannedPort = ScanPort(devName);
switch (scannedPort)
{
case mitk::NDIPolaris:
result += "<br>" + devName + ": " + "NDI Polaris";
PolarisPort = i;
PortTypePolaris = 0;
break;
case mitk::NDIAurora:
result += "<br>" + devName + ": " + "NDI Aurora";
AuroraPort = i;
PortTypeAurora = 0;
break;
}
}
#endif
if ( result.size() == resultSize) result += "<br>none";
emit PortsScanned(PolarisPort,AuroraPort,result,PortTypePolaris,PortTypeAurora);
}
mitk::TrackingDeviceType QmitkTrackingDeviceConfigurationWidgetScanPortsWorker::ScanPort(QString port)
{
mitk::NDITrackingDevice::Pointer tracker = mitk::NDITrackingDevice::New();
tracker->SetDeviceName(port.toStdString());
mitk::TrackingDeviceType returnValue = mitk::TrackingSystemInvalid;
try
{returnValue = tracker->TestConnection();}
catch (mitk::IGTException)
{}//do nothing: there is simply no device on this port
return returnValue;
}
void QmitkTrackingDeviceConfigurationWidgetConnectionWorker::SetTrackingDevice(mitk::TrackingDevice::Pointer t)
{
m_TrackingDevice = t;
}
diff --git a/Modules/ImageStatistics/CMakeLists.txt b/Modules/ImageStatistics/CMakeLists.txt
index fe177d3216..f4c68ee64b 100644
--- a/Modules/ImageStatistics/CMakeLists.txt
+++ b/Modules/ImageStatistics/CMakeLists.txt
@@ -1,11 +1,11 @@
MITK_CREATE_MODULE(
DEPENDS MitkImageExtraction MitkPlanarFigure
PACKAGE_DEPENDS ITK|ITKVTK+ITKConvolution+ITKIOXML
- WARNINGS_AS_ERRORS
+ # WARNINGS_AS_ERRORS
)
if(BUILD_TESTING)
add_subdirectory(Testing)
endif(BUILD_TESTING)
diff --git a/Modules/OpenCL/Testing/files.cmake b/Modules/OpenCL/Testing/files.cmake
index b53960e7c9..10dff632d7 100644
--- a/Modules/OpenCL/Testing/files.cmake
+++ b/Modules/OpenCL/Testing/files.cmake
@@ -1,7 +1,6 @@
set(MODULE_TESTS
mitkOclResourceServiceTest.cpp
- #Tests disabled temporarily. See bug #18303
- #mitkOclImageTest.cpp
- #mitkOclBinaryThresholdImageFilterTest.cpp
- #mitkOclReferenceCountTest.cpp
+ mitkOclImageTest.cpp
+ mitkOclBinaryThresholdImageFilterTest.cpp
+ mitkOclReferenceCountTest.cpp
)
diff --git a/Modules/OpenCL/Testing/mitkOclBinaryThresholdImageFilterTest.cpp b/Modules/OpenCL/Testing/mitkOclBinaryThresholdImageFilterTest.cpp
index 52cfe7cc4e..c822ec4425 100644
--- a/Modules/OpenCL/Testing/mitkOclBinaryThresholdImageFilterTest.cpp
+++ b/Modules/OpenCL/Testing/mitkOclBinaryThresholdImageFilterTest.cpp
@@ -1,111 +1,139 @@
/*===================================================================
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 <mitkImage.h>
#include <mitkTestingMacros.h>
+#include <mitkTestFixture.h>
#include <mitkImageGenerator.h>
#include <mitkImageCast.h>
#include <mitkOclBinaryThresholdImageFilter.h>
+#include <mitkException.h>
-// itk filter for reference computation
+//ITK Filter as reference computation
#include <itkBinaryThresholdImageFilter.h>
-#include <itkSubtractImageFilter.h>
-#include <itkStatisticsImageFilter.h>
-using namespace mitk;
-
-/**
- This function is testing the class mitk::OclContextManager.
- */
-int mitkOclBinaryThresholdImageFilterTest( int argc, char* argv[] )
+class mitkOclBinaryThresholdImageFilterTestSuite : public mitk::TestFixture
{
- MITK_TEST_BEGIN("mitkOclBinaryThresholdImageFilterTest");
-
- us::ServiceReference<OclResourceService> ref = GetModuleContext()->GetServiceReference<OclResourceService>();
- MITK_TEST_CONDITION_REQUIRED( ref != 0, "Got valid ServiceReference" );
-
- OclResourceService* resources = GetModuleContext()->GetService<OclResourceService>(ref);
- MITK_TEST_CONDITION_REQUIRED( resources != NULL, "OpenCL Resource service available." );
-
- cl_context gpuContext = resources->GetContext();
- MITK_TEST_CONDITION_REQUIRED( gpuContext != NULL, "Got not-null OpenCL context.");
-
- cl_device_id gpuDevice = resources->GetCurrentDevice();
- MITK_TEST_CONDITION_REQUIRED( gpuDevice != NULL, "Got not-null OpenCL device.");
-
- //Create a random reference image
- mitk::Image::Pointer inputImage = mitk::ImageGenerator::GenerateRandomImage<unsigned char>(119, 204, 52, 1, // dimension
- 1.0f, 1.0f, 1.0f, // spacing
- 255, 0); // max, min
- MITK_TEST_CONDITION_REQUIRED( inputImage.IsNotNull(), "Input (random) mitk::Image object instantiated.");
-
- // FIXME: could also be random values
- int upperThr = 255;
- int lowerThr = 60;
-
- int outsideVal = 0;
- int insideVal = 100;
-
- mitk::OclBinaryThresholdImageFilter::Pointer oclFilter = mitk::OclBinaryThresholdImageFilter::New();
- MITK_TEST_CONDITION_REQUIRED( oclFilter.GetPointer() != NULL, "Filter was created. ");
-
- oclFilter->SetInput( inputImage );
- oclFilter->SetUpperThreshold( upperThr );
- oclFilter->SetLowerThreshold( lowerThr );
- oclFilter->SetOutsideValue( outsideVal );
- oclFilter->SetInsideValue( insideVal );
-
- oclFilter->Update();
-
- mitk::Image::Pointer outputImage = mitk::Image::New();
- outputImage = oclFilter->GetOutput();
-
- MITK_TEST_CONDITION_REQUIRED( outputImage.IsNotNull(), "Filter returned an not-NULL image. ");
-
- // reference computation
- typedef itk::Image< unsigned char, 3> ImageType;
- typedef itk::BinaryThresholdImageFilter< ImageType, ImageType > ThresholdFilterType;
-
- ImageType::Pointer itkInputImage = ImageType::New();
- CastToItkImage( inputImage, itkInputImage );
-
- ThresholdFilterType::Pointer refThrFilter = ThresholdFilterType::New();
- refThrFilter->SetInput( itkInputImage );
- refThrFilter->SetLowerThreshold( lowerThr );
- refThrFilter->SetUpperThreshold( upperThr );
- refThrFilter->SetOutsideValue( outsideVal );
- refThrFilter->SetInsideValue( insideVal );
-
- typedef itk::SubtractImageFilter< ImageType, ImageType > SubtractFilterType;
- SubtractFilterType::Pointer subFilt = SubtractFilterType::New();
-
- ImageType::Pointer gpuReferenceImage = ImageType::New();
- CastToItkImage( oclFilter->GetOutput() ,gpuReferenceImage );
-
- subFilt->SetInput1( refThrFilter->GetOutput() );
- subFilt->SetInput2( gpuReferenceImage );
-
- typedef itk::StatisticsImageFilter< ImageType > StatFilterType;
- StatFilterType::Pointer stats = StatFilterType::New();
- stats->SetInput( subFilt->GetOutput() );
- stats->Update();
-
- MITK_TEST_CONDITION( stats->GetMaximum() == 0, "Maximal value in the difference image is 0.");
- MITK_TEST_CONDITION( stats->GetMinimum() == 0, "Minimal value in the difference image is 0.")
- MITK_TEST_END();
-}
+ CPPUNIT_TEST_SUITE(mitkOclBinaryThresholdImageFilterTestSuite);
+ MITK_TEST(SetInput_2DImage_ThrowsException);
+ MITK_TEST(GenerateData_3DImage_CompareToReference);
+ CPPUNIT_TEST_SUITE_END();
+
+private:
+
+ /** Members used inside the different (sub-)tests. All members are initialized via setUp().
+ */
+ mitk::OclBinaryThresholdImageFilter::Pointer m_oclBinaryFilter;
+
+ mitk::Image::Pointer m_Random2DImage;
+ mitk::Image::Pointer m_Random3DImage;
+ mitk::Image::Pointer m_ReferenceImage;
+
+public:
+
+ /**
+ * @brief Setup a recorder including a device. Here, we use a player, because in an automatic test
+ * hardware is not useful.
+ */
+ void setUp()
+ {
+ //Random input images
+ m_Random3DImage = mitk::ImageGenerator::GenerateRandomImage<unsigned char>(119, 204, 52, 1, // dimension
+ 1.0f, 1.0f, 1.0f, // spacing
+ 255, 0); // max, min
+
+ m_Random2DImage = mitk::ImageGenerator::GenerateRandomImage<unsigned char>(119, 204, 0, 0, // dimension
+ 1.0f, 1.0f, 1.0f, // spacing
+ 255, 0); // max, min
+ m_oclBinaryFilter = mitk::OclBinaryThresholdImageFilter::New();
+ }
+
+ void tearDown()
+ {
+ m_oclBinaryFilter = NULL;
+ }
+
+ void SetInput_2DImage_ThrowsException()
+ {
+ CPPUNIT_ASSERT_THROW( m_oclBinaryFilter->SetInput( m_Random2DImage ), mitk::Exception );
+ }
+
+ void GenerateData_3DImage_CompareToReference()
+ {
+ int upperThr = 255;
+ int lowerThr = 60;
+
+ int outsideVal = 0;
+ int insideVal = 100;
+
+ us::ServiceReference<OclResourceService> ref = GetModuleContext()->GetServiceReference<OclResourceService>();
+ OclResourceService* resources = GetModuleContext()->GetService<OclResourceService>(ref);
+ resources->GetContext(); //todo why do i need to call this before GetMaximumImageSize()?
+ if(resources->GetMaximumImageSize(2, CL_MEM_OBJECT_IMAGE3D) == 0)
+ {
+ //GPU device does not support 3D images. Skip this test.
+ MITK_INFO << "Skipping test.";
+ return;
+ }
+
+ try{
+
+ m_oclBinaryFilter->SetInput( m_Random3DImage );
+ m_oclBinaryFilter->SetUpperThreshold( upperThr );
+ m_oclBinaryFilter->SetLowerThreshold( lowerThr );
+ m_oclBinaryFilter->SetOutsideValue( outsideVal );
+ m_oclBinaryFilter->SetInsideValue( insideVal );
+ m_oclBinaryFilter->Update();
+
+ mitk::Image::Pointer outputImage = mitk::Image::New();
+ outputImage = m_oclBinaryFilter->GetOutput();
+
+ // reference computation
+ //This is not optimal here, but since we use a random image
+ //we cannot know the reference image at this point.
+ typedef itk::Image< unsigned char, 3> ImageType;
+ typedef itk::BinaryThresholdImageFilter< ImageType, ImageType > ThresholdFilterType;
+
+ ImageType::Pointer itkInputImage = ImageType::New();
+ CastToItkImage( m_Random3DImage, itkInputImage );
+
+ ThresholdFilterType::Pointer refThrFilter = ThresholdFilterType::New();
+ refThrFilter->SetInput( itkInputImage );
+ refThrFilter->SetLowerThreshold( lowerThr );
+ refThrFilter->SetUpperThreshold( upperThr );
+ refThrFilter->SetOutsideValue( outsideVal );
+ refThrFilter->SetInsideValue( insideVal );
+ refThrFilter->Update();
+ mitk::Image::Pointer referenceImage = mitk::Image::New();
+ mitk::CastToMitkImage(refThrFilter->GetOutput(), referenceImage);
+
+ MITK_ASSERT_EQUAL( referenceImage, outputImage,
+ "OclBinaryThresholdFilter should be equal to regular itkBinaryThresholdImageFilter.");
+ }
+ catch(mitk::Exception &e)
+ {
+ std::string errorMessage = "Caught unexpected exception ";
+ errorMessage.append(e.what());
+ CPPUNIT_FAIL(errorMessage.c_str());
+ }
+
+ }
+};
+
+MITK_TEST_SUITE_REGISTRATION(mitkOclBinaryThresholdImageFilter)
diff --git a/Modules/OpenCL/Testing/mitkOclImageTest.cpp b/Modules/OpenCL/Testing/mitkOclImageTest.cpp
index 1474300709..d91d0bdeb4 100644
--- a/Modules/OpenCL/Testing/mitkOclImageTest.cpp
+++ b/Modules/OpenCL/Testing/mitkOclImageTest.cpp
@@ -1,94 +1,113 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <mitkTestingMacros.h>
-
#include <mitkImageGenerator.h>
-
#include <mitkOclImage.h>
using namespace mitk;
/**
This function is testing the mitk::OclImage class.
*/
int mitkOclImageTest( int /*argc*/, char* /*argv*/[] )
{
MITK_TEST_BEGIN("mitkOclImageTest");
us::ServiceReference<OclResourceService> ref = GetModuleContext()->GetServiceReference<OclResourceService>();
MITK_TEST_CONDITION_REQUIRED( ref != 0, "Got valid ServiceReference" );
OclResourceService* resources = GetModuleContext()->GetService<OclResourceService>(ref);
MITK_TEST_CONDITION_REQUIRED( resources != NULL, "OpenCL Resource service available." );
cl_context gpuContext = resources->GetContext();
MITK_TEST_CONDITION_REQUIRED( gpuContext != NULL, "Got not-null OpenCL context.");
cl_device_id gpuDevice = resources->GetCurrentDevice();
MITK_TEST_CONDITION_REQUIRED( gpuDevice != NULL, "Got not-null OpenCL device.");
- //Create a random reference image
- mitk::Image::Pointer reference = mitk::ImageGenerator::GenerateRandomImage<float>(119, 204, 52, 1, // dimension
- 1.0f, 1.0f, 1.0f, // spacing
- 1024, 0); // max, min
+ //create a random image
+ mitk::Image::Pointer reference;
+ //check if 3D images are supported by the device and initialize image accordingly
+ if( resources->GetMaximumImageSize(2, CL_MEM_OBJECT_IMAGE3D) == 0 ) //2D required
+ {
+ //Create a random reference image
+ reference = mitk::ImageGenerator::GenerateRandomImage<unsigned char>(119, 204, 0, 0, // dimension
+ 1.0f, 1.0f, 1.0f, // spacing
+ 255, 0); // max, min
+ }
+ else //3D ok
+ {
+ //Create a random reference image
+ reference = mitk::ImageGenerator::GenerateRandomImage<unsigned char>(119, 204, 52, 1, // dimension
+ 1.0f, 1.0f, 1.0f, // spacing
+ 255, 0); // max, min
+ }
MITK_TEST_CONDITION_REQUIRED( reference.IsNotNull(), "Reference mitk::Image object instantiated.");
- mitk::OclImage::Pointer first = mitk::OclImage::New();
- first->InitializeByMitkImage(reference);
- MITK_TEST_CONDITION_REQUIRED(first.IsNotNull(), "oclImage object instantiated.");
+ mitk::OclImage::Pointer oclTestImage = mitk::OclImage::New();
+ oclTestImage->InitializeByMitkImage(reference);
+ MITK_TEST_CONDITION_REQUIRED(oclTestImage.IsNotNull(), "oclImage object instantiated.");
// test if oclImage correct initialized
- MITK_TEST_CONDITION( first->GetMITKImage() == reference, "oclImage has the correct reference mitk::Image");
- MITK_TEST_CONDITION( first->GetDimension() == reference->GetDimension(), "Same dimensionality.");
+ MITK_TEST_CONDITION( oclTestImage->GetMITKImage() == reference, "oclImage has the correct reference mitk::Image");
+ MITK_TEST_CONDITION( oclTestImage->GetDimension() == reference->GetDimension(), "Same dimensionality.");
cl_int clErr = 0;
cl_command_queue cmdQueue = clCreateCommandQueue( gpuContext, gpuDevice,
0 ,&clErr);
MITK_TEST_CONDITION_REQUIRED( clErr == CL_SUCCESS, "A command queue was created.");
// Allocate and copy image data to GPU
- first->TransferDataToGPU(cmdQueue);
- MITK_TEST_CONDITION( first->IsModified(0), "Modified flag for GPU correctly set.");
-
- // check if the created GPU object is valid
- cl_mem gpuImage = first->GetGPUImage(cmdQueue);
- MITK_TEST_CONDITION_REQUIRED( gpuImage != NULL, "oclImage returned a valid GPU memory pointer");
- size_t returned = 0;
- cl_image_format imgFmt;
- clErr = clGetImageInfo( gpuImage, CL_IMAGE_FORMAT, sizeof(cl_image_format),
- (void*) &imgFmt, &returned );
- MITK_TEST_CONDITION( clErr == CL_SUCCESS, "oclImage has created a valid GPU image");
-
- // test for dimensions
- size_t imagesize = 0;
- clErr = clGetImageInfo( gpuImage, CL_IMAGE_WIDTH, sizeof(size_t),
- (void*) &imagesize, &returned );
- MITK_TEST_CONDITION( imagesize == static_cast<size_t>(first->GetDimension(0)), "Image width corresponds" );
-
- clErr = clGetImageInfo( gpuImage, CL_IMAGE_HEIGHT, sizeof(size_t),
- (void*) &imagesize, &returned );
- MITK_TEST_CONDITION( imagesize == static_cast<size_t>(first->GetDimension(1)), "Image height corresponds" );
-
- clErr = clGetImageInfo( gpuImage, CL_IMAGE_DEPTH, sizeof(size_t),
- (void*) &imagesize, &returned );
- MITK_TEST_CONDITION( imagesize == static_cast<size_t>(first->GetDimension(2)), "Image depth corresponds" );
-
- // clean up
- clReleaseCommandQueue( cmdQueue );
+ try
+ {
+ oclTestImage->TransferDataToGPU(cmdQueue);
+ MITK_TEST_CONDITION( oclTestImage->IsModified(0), "Modified flag for GPU correctly set.");
+
+ // check if the created GPU object is valid
+ cl_mem gpuImage = oclTestImage->GetGPUImage(cmdQueue);
+ MITK_TEST_CONDITION_REQUIRED( gpuImage != NULL, "oclImage returned a valid GPU memory pointer");
+ size_t returned = 0;
+ cl_image_format imgFmt;
+ clErr = clGetImageInfo( gpuImage, CL_IMAGE_FORMAT, sizeof(cl_image_format),
+ (void*) &imgFmt, &returned );
+ MITK_TEST_CONDITION( clErr == CL_SUCCESS, "oclImage has created a valid GPU image");
+
+ // test for dimensions
+ size_t imagesize = 0;
+ clErr = clGetImageInfo( gpuImage, CL_IMAGE_WIDTH, sizeof(size_t),
+ (void*) &imagesize, &returned );
+ MITK_TEST_CONDITION( imagesize == static_cast<size_t>(oclTestImage->GetDimension(0)), "Image width corresponds" );
+
+ clErr = clGetImageInfo( gpuImage, CL_IMAGE_HEIGHT, sizeof(size_t),
+ (void*) &imagesize, &returned );
+ MITK_TEST_CONDITION( imagesize == static_cast<size_t>(oclTestImage->GetDimension(1)), "Image height corresponds" );
+
+ clErr = clGetImageInfo( gpuImage, CL_IMAGE_DEPTH, sizeof(size_t),
+ (void*) &imagesize, &returned );
+ MITK_TEST_CONDITION( imagesize == static_cast<size_t>(oclTestImage->GetDimension(2)), "Image depth corresponds" );
+
+ // clean up
+ clReleaseCommandQueue( cmdQueue );
+ }
+ catch(mitk::ImageTypeIsNotSupportedByGPU& e)
+ {
+ MITK_ERROR << "Caught exception: " << e.what();
+ //Image type is not supported -> skip test.
+ }
MITK_TEST_END();
-}
\ No newline at end of file
+}
diff --git a/Modules/OpenCL/Testing/mitkOclReferenceCountTest.cpp b/Modules/OpenCL/Testing/mitkOclReferenceCountTest.cpp
index 79ade4571e..8ca17803ac 100644
--- a/Modules/OpenCL/Testing/mitkOclReferenceCountTest.cpp
+++ b/Modules/OpenCL/Testing/mitkOclReferenceCountTest.cpp
@@ -1,92 +1,87 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include <mitkTestingMacros.h>
-
#include <mitkImageGenerator.h>
-#include <mitkImageCast.h>
-
#include <mitkOclBinaryThresholdImageFilter.h>
-// itk filter for reference computation
-#include <itkBinaryThresholdImageFilter.h>
-#include <itkSubtractImageFilter.h>
-#include <itkStatisticsImageFilter.h>
-
using namespace mitk;
/**
This function is testing the OclFilter class and the
OpenCL resource service. To prevent segmentation faults
a mutexed reference counter is implemented in the resource service.
It tracks the number of opencl program references for the corresponding filter
and delete only the opencl programm if the reference count reaches 0.
Every new instance of a filter increases the reference count by 1.
This test runs successfull if the 2 filters are initialized, run
and deleted without any crash.
*/
-int mitkOclReferenceCountTest( int argc, char* argv[] )
+int mitkOclReferenceCountTest( int /*argc*/, char* /*argv*/[] )
{
MITK_TEST_BEGIN("mitkOclReferenceCountTest");
- // instancate uService
us::ServiceReference<OclResourceService> ref = GetModuleContext()->GetServiceReference<OclResourceService>();
OclResourceService* resources = GetModuleContext()->GetService<OclResourceService>(ref);
- cl_context gpuContext = resources->GetContext();
- cl_device_id gpuDevice = resources->GetCurrentDevice();
-
- //Create a random reference image
- mitk::Image::Pointer inputImage = mitk::ImageGenerator::GenerateRandomImage<unsigned char>(119, 204, 0, 1, // dimension
- 1.0f, 1.0f, 1.0f, // spacing
- 255, 0); // max, min
+ resources->GetContext(); //todo why do i need to call this before GetMaximumImageSize()?
+ if(resources->GetMaximumImageSize(2, CL_MEM_OBJECT_IMAGE3D) == 0)
+ {
+ //GPU device does not support 3D images. Skip this test.
+ MITK_INFO << "Skipping test.";
+ return 0;
+ }
+
+ mitk::Image::Pointer inputImage = mitk::ImageGenerator::GenerateRandomImage<unsigned char>(119, 204, 52, 1, // dimension
+ 1.0f, 1.0f, 1.0f, // spacing
+ 255, 0); // max, min
int upperThr = 255;
int lowerThr = 60;
int outsideVal = 0;
int insideVal = 100;
mitk::OclBinaryThresholdImageFilter::Pointer oclFilter1 = mitk::OclBinaryThresholdImageFilter::New();
oclFilter1->SetInput( inputImage );
oclFilter1->SetUpperThreshold( upperThr );
oclFilter1->SetLowerThreshold( lowerThr );
oclFilter1->SetOutsideValue( outsideVal );
oclFilter1->SetInsideValue( insideVal );
oclFilter1->Update();
mitk::Image::Pointer outputImage1 = mitk::Image::New();
outputImage1 = oclFilter1->GetOutput();
mitk::OclBinaryThresholdImageFilter::Pointer oclFilter2 = mitk::OclBinaryThresholdImageFilter::New();
oclFilter2->SetInput( inputImage );
oclFilter2->SetUpperThreshold( upperThr );
oclFilter2->SetLowerThreshold( lowerThr );
oclFilter2->SetOutsideValue( outsideVal );
oclFilter2->SetInsideValue( insideVal );
oclFilter2->Update();
mitk::Image::Pointer outputImage2 = mitk::Image::New();
outputImage2 = oclFilter2->GetOutput();
// delete filters
oclFilter1 = NULL;
oclFilter2 = NULL;
// this is only visible if the delete did not cause a segmentation fault
// it is always true and successfull if the program reaches this state
MITK_TEST_CONDITION_REQUIRED( true, "2 Filters deleted without a crash -> success ");
MITK_TEST_END();
}
diff --git a/Modules/OpenCL/Testing/mitkOclResourceServiceTest.cpp b/Modules/OpenCL/Testing/mitkOclResourceServiceTest.cpp
index e3c59cdcc7..29098372a6 100644
--- a/Modules/OpenCL/Testing/mitkOclResourceServiceTest.cpp
+++ b/Modules/OpenCL/Testing/mitkOclResourceServiceTest.cpp
@@ -1,114 +1,109 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
-#include "mitkTestingMacros.h"
-#include "mitkOclUtils.h"
+#include <mitkTestingMacros.h>
+#include <mitkOclUtils.h>
+#include <mitkOclResourceService.h>
+#include <mitkException.h>
#include <usModuleContext.h>
#include <usGetModuleContext.h>
#include <usModuleInitialization.h>
-#include "mitkOclResourceService.h"
-#include "mitkException.h"
-
-#include <itkLightObject.h>
-
-#include <string>
-
using namespace mitk;
/**
- This function is testing the class mitk::OclContextManager.
+ This function is testing the class mitk::OclResourceService.
*/
-int mitkOclResourceServiceTest( int argc, char* argv[] )
+int mitkOclResourceServiceTest( int /*argc*/, char* /*argv*/[] )
{
MITK_TEST_BEGIN("mitkOclResourceServiceTest");
us::ServiceReference<OclResourceService> ref = us::GetModuleContext()->GetServiceReference<OclResourceService>();
MITK_TEST_CONDITION_REQUIRED( ref != NULL, "Resource service available." );
OclResourceService* resources = us::GetModuleContext()->GetService<OclResourceService>(ref);
MITK_TEST_CONDITION_REQUIRED( resources != NULL, "Resource service available." );
cl_context first = resources->GetContext();
MITK_TEST_CONDITION_REQUIRED(first != NULL, "Got not-null OpenCL context.");
OclResourceService* resources_2 = us::GetModuleContext()->GetService<OclResourceService>(ref);
MITK_TEST_CONDITION_REQUIRED( resources == resources_2, "Same resource reference the second time." );
cl_context second = resources_2->GetContext();
MITK_TEST_CONDITION_REQUIRED( first == second, "Both return same context");
// further tests requires for valid context
if( first )
{
cl_image_format testFmt;
testFmt.image_channel_data_type = CL_FLOAT;
testFmt.image_channel_order = CL_RGBA;
MITK_TEST_CONDITION( resources->GetIsFormatSupported( &testFmt ), "Checking if format CL_FLOAT / CL_RGBA supported." );
}
// create test program
const std::string testProgramSource =
"__kernel void testKernel( __global uchar* buffer ){ \
const unsigned int globalPosX = get_global_id(0); \
buffer[globalPosX] = buffer[globalPosX] + 1;}";
cl_int err = 0;
size_t progSize = testProgramSource.length();
const char* progSource = testProgramSource.c_str();
cl_program testProgram = clCreateProgramWithSource( first, 1, &progSource, &progSize, &err );
MITK_TEST_CONDITION_REQUIRED( err == CL_SUCCESS, "Test program loaded succesfully.");
err = clBuildProgram(testProgram, 0, NULL, NULL, NULL, NULL);
MITK_TEST_CONDITION_REQUIRED( err == CL_SUCCESS, "Test program built succesfully.");
resources->InsertProgram( testProgram, "test_program", true);
MITK_TEST_CONDITION( resources->GetProgram("test_program") == testProgram, "Program correctly stored by ResourceService");
// the manger throws exception when accessing non-existant programs
MITK_TEST_FOR_EXCEPTION( mitk::Exception, resources->GetProgram("blah"); );
// another test source, this one does not compile
const std::string testProgramSource_notCompiling =
"__kernel void testKernel( __global uchar* buffer ){ \
const unsigned intt globalPosX = get_global_id(0); }";
progSize = testProgramSource_notCompiling.length();
const char* progSource2 = testProgramSource_notCompiling.c_str();
cl_program notComp_testProgram = clCreateProgramWithSource( first, 1, &progSource2, &progSize, &err );
// the error in the source code has no influence on loading the program
MITK_TEST_CONDITION_REQUIRED( err == CL_SUCCESS, "Test program 2 loaded succesfully.");
err = clBuildProgram(notComp_testProgram, 0, NULL, NULL, NULL, NULL);
MITK_TEST_CONDITION_REQUIRED( err == CL_BUILD_PROGRAM_FAILURE, "Test program 2 failed to build.");
std::cout << " --> The (expected) OpenCL Build Error occured : ";// << GetOclErrorString(err);
resources->InsertProgram( notComp_testProgram, "test_program_failed", true);
MITK_TEST_CONDITION( resources->GetProgram("test_program_failed") == notComp_testProgram, "Program correctly stored by ResourceService");
// calling the InvalidateStorage() will result in removing the _failed test program inserted above
resources->InvalidateStorage();
// the second test program should no more exist in the storage, hence we await an exception
MITK_TEST_FOR_EXCEPTION( mitk::Exception, resources->GetProgram("test_program_failed"); );
MITK_TEST_END();
}
US_INITIALIZE_MODULE
diff --git a/Modules/OpenCL/mitkOclBinaryThresholdImageFilter.cpp b/Modules/OpenCL/mitkOclBinaryThresholdImageFilter.cpp
index 88f7a7c06e..8d4f412b34 100644
--- a/Modules/OpenCL/mitkOclBinaryThresholdImageFilter.cpp
+++ b/Modules/OpenCL/mitkOclBinaryThresholdImageFilter.cpp
@@ -1,104 +1,114 @@
/*===================================================================
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 "mitkOclBinaryThresholdImageFilter.h"
#include "usServiceReference.h"
mitk::OclBinaryThresholdImageFilter::OclBinaryThresholdImageFilter()
: m_ckBinaryThreshold( NULL )
{
this->AddSourceFile("BinaryThresholdFilter.cl");
this->m_FilterID = "BinaryThreshold";
this->m_LowerThreshold = 10;
this->m_UpperThreshold = 200;
this->m_InsideValue = 100;
this->m_OutsideValue = 0;
}
mitk::OclBinaryThresholdImageFilter::~OclBinaryThresholdImageFilter()
{
if ( this->m_ckBinaryThreshold )
{
clReleaseKernel( m_ckBinaryThreshold );
}
}
void mitk::OclBinaryThresholdImageFilter::Update()
{
//Check if context & program available
if (!this->Initialize())
{
us::ServiceReference<OclResourceService> ref = GetModuleContext()->GetServiceReference<OclResourceService>();
OclResourceService* resources = GetModuleContext()->GetService<OclResourceService>(ref);
// clean-up also the resources
resources->InvalidateStorage();
mitkThrow() <<"Filter is not initialized. Cannot update.";
}
else{
// Execute
this->Execute();
}
}
void mitk::OclBinaryThresholdImageFilter::Execute()
{
cl_int clErr = 0;
try
{
this->InitExec( this->m_ckBinaryThreshold );
}
catch( const mitk::Exception& e)
{
MITK_ERROR << "Catched exception while initializing filter: " << e.what();
return;
}
// set kernel arguments
clErr = clSetKernelArg( this->m_ckBinaryThreshold, 2, sizeof(cl_int), &(this->m_LowerThreshold) );
clErr |= clSetKernelArg( this->m_ckBinaryThreshold, 3, sizeof(cl_int), &(this->m_UpperThreshold) );
clErr |= clSetKernelArg( this->m_ckBinaryThreshold, 4, sizeof(cl_int), &(this->m_OutsideValue) );
clErr |= clSetKernelArg( this->m_ckBinaryThreshold, 5, sizeof(cl_int), &(this->m_InsideValue) );
CHECK_OCL_ERR( clErr );
// execute the filter on a 3D NDRange
this->ExecuteKernel( m_ckBinaryThreshold, 3);
// signalize the GPU-side data changed
m_Output->Modified( GPU_DATA );
}
us::Module *mitk::OclBinaryThresholdImageFilter::GetModule()
{
return us::GetModuleContext()->GetModule();
}
bool mitk::OclBinaryThresholdImageFilter::Initialize()
{
bool buildErr = true;
cl_int clErr = 0;
if ( OclFilter::Initialize() )
{
this->m_ckBinaryThreshold = clCreateKernel( this->m_ClProgram, "ckBinaryThreshold", &clErr);
buildErr |= CHECK_OCL_ERR( clErr );
}
return (OclFilter::IsInitialized() && buildErr );
}
+
+void mitk::OclBinaryThresholdImageFilter::SetInput(mitk::Image::Pointer image)
+{
+ if(image->GetDimension() != 3)
+ {
+ mitkThrowException(mitk::Exception) << "Input for " << this->GetNameOfClass() <<
+ " is not 3D. The filter only supports 3D. Please change your input.";
+ }
+ OclImageToImageFilter::SetInput(image);
+}
diff --git a/Modules/OpenCL/mitkOclBinaryThresholdImageFilter.h b/Modules/OpenCL/mitkOclBinaryThresholdImageFilter.h
index 51b217e49f..ef66f61ee8 100644
--- a/Modules/OpenCL/mitkOclBinaryThresholdImageFilter.h
+++ b/Modules/OpenCL/mitkOclBinaryThresholdImageFilter.h
@@ -1,119 +1,125 @@
/*===================================================================
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 _MITKOCLBINARYTHRESHOLDIMAGEFILTER_H_
#define _MITKOCLBINARYTHRESHOLDIMAGEFILTER_H_
#include "mitkOclImageToImageFilter.h"
#include <itkObject.h>
namespace mitk
{
class OclImageToImageFilter;
/** Documentation
*
* \brief The OclBinaryThresholdImageFilter computes a binary segmentation based on given
threshold values.
*
* The filter requires two threshold values ( the upper and the lower threshold ) and two image values ( inside and outside ). The resulting voxel of the segmentation image is assigned the inside value 1 if the image value is between the given thresholds and the outside value otherwise.
*/
class MitkOpenCL_EXPORT OclBinaryThresholdImageFilter : public OclImageToImageFilter, public itk::Object
{
public:
mitkClassMacro(OclBinaryThresholdImageFilter, OclImageToImageFilter);
itkNewMacro(Self);
+ /**
+ * @brief SetInput Set the input image. Only 3D images are supported for now.
+ * @param image a 3D image.
+ * @throw mitk::Exception if the dimesion is not 3.
+ */
+ void SetInput(Image::Pointer image);
/** Update the filter */
void Update();
/** Set the lower threshold
@param thr Threshold value
*/
void SetLowerThreshold( int lowerThreshold )
{
this->m_LowerThreshold = lowerThreshold;
}
/** Set the upper threshold
@param thr Threshold value
*/
void SetUpperThreshold( int upperThreshold )
{
this->m_UpperThreshold = upperThreshold;
}
/** Set the outside value
@param val The outside value
*/
void SetOutsideValue( int outsideValue )
{
this->m_OutsideValue = outsideValue;
}
/** Set the inside value
@param val The inside value
*/
void SetInsideValue( int insideValue )
{
this->m_InsideValue = insideValue;
}
protected:
/** Constructor */
OclBinaryThresholdImageFilter();
/** Destructor */
virtual ~OclBinaryThresholdImageFilter();
/** Initialize the filter */
bool Initialize();
void Execute();
mitk::PixelType GetOutputType()
{
return mitk::MakeScalarPixelType<unsigned char>();
}
int GetBytesPerElem()
{
return sizeof(unsigned char);
}
virtual us::Module* GetModule();
private:
/** The OpenCL kernel for the filter */
cl_kernel m_ckBinaryThreshold;
int m_LowerThreshold;
int m_UpperThreshold;
int m_InsideValue;
int m_OutsideValue;
};
}
#endif
diff --git a/Modules/OpenCL/mitkOclImage.cpp b/Modules/OpenCL/mitkOclImage.cpp
index 8095672d89..adfeea9ba1 100644
--- a/Modules/OpenCL/mitkOclImage.cpp
+++ b/Modules/OpenCL/mitkOclImage.cpp
@@ -1,350 +1,349 @@
/*===================================================================
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 "mitkOclImage.h"
#include "mitkImageDataItem.h"
#include "mitkCommon.h"
#include "mitkLogMacros.h"
#include "mitkOclUtils.h"
#include <mitkImageReadAccessor.h>
#include <fstream>
mitk::OclImage::OclImage() : m_gpuImage(NULL), m_context(NULL), m_bufferSize(0), m_gpuModified(false), m_cpuModified(false),
m_Image(NULL), m_dim(0), m_Dims(NULL), m_BpE(1), m_formatSupported(false)
{
}
mitk::OclImage::~OclImage()
{
MITK_INFO << "OclImage Destructor";
//release GMEM Image buffer
if (m_gpuImage) clReleaseMemObject(m_gpuImage);
}
cl_mem mitk::OclImage::CreateGPUImage(unsigned int _wi, unsigned int _he, unsigned int _de,
unsigned int _bpp)
{
MITK_INFO << "CreateGPUImage call with: BPP=" << _bpp;
this->m_Dims = new unsigned int[MAX_DIMS];
m_Dims[0] = _wi;
m_Dims[1] = _he;
m_Dims[2] = _de;
for (unsigned int i=3; i<MAX_DIMS; i++)
m_Dims[i] = 1;
m_bufferSize = _wi * _he * _de;
m_BpE = _bpp;
us::ServiceReference<OclResourceService> ref = GetModuleContext()->GetServiceReference<OclResourceService>();
OclResourceService* resources = GetModuleContext()->GetService<OclResourceService>(ref);
cl_context gpuContext = resources->GetContext();
int clErr;
m_gpuImage = clCreateBuffer( gpuContext, CL_MEM_READ_WRITE, m_bufferSize * m_BpE, NULL, &clErr);
CHECK_OCL_ERR(clErr);
return m_gpuImage;
}
void mitk::OclImage::InitializeByMitkImage(mitk::Image::Pointer _image)
{
this->m_Image = _image;
this->m_cpuModified = true;
this->m_gpuModified = false;
this->m_gpuImage = NULL;
// compute the size of the GMEM buffer
this->m_dim = this->m_Image->GetDimension();
this->m_Dims = this->m_Image->GetDimensions();
MITK_INFO << "Image: " << this->m_Dims[0] <<"x"<< this->m_Dims[1] <<"x"<< this->m_Dims[2];
// get the dimensions
this->m_bufferSize = 1;
for (unsigned int i=0; i<this->m_dim; i++)
{
this->m_bufferSize *= this->m_Dims[i];
}
// multiply by sizeof(PixelType)
this->m_BpE = ( this->m_Image->GetPixelType().GetBpe() / 8);
}
bool mitk::OclImage::IsModified(int _type)
{
if (_type) return m_cpuModified;
else return m_gpuModified;
}
void mitk::OclImage::Modified(int _type)
{
// defines... GPU: 0, CPU: 1
m_cpuModified = _type;
m_gpuModified = !_type;
}
int mitk::OclImage::TransferDataToGPU(cl_command_queue gpuComQueue)
{
cl_int clErr = 0;
// check whether an image present
if (!m_Image->IsInitialized()){
MITK_ERROR("ocl.Image") << "(mitk) Image not initialized!\n";
return -1;
}
// there is a need for copy only if RAM-Data newer then GMEM data
if (m_cpuModified)
{
//check the buffer
if(m_gpuImage == NULL)
{
clErr = this->AllocateGPUImage();
}
if (m_Image->IsInitialized() &&
(clErr == CL_SUCCESS))
{
const size_t origin[3] = {0, 0, 0};
const size_t region[3] = {m_Dims[0], m_Dims[1], m_Dims[2]};
if( this->m_formatSupported )
{
mitk::ImageReadAccessor accessor(m_Image);
clErr = clEnqueueWriteImage( gpuComQueue, m_gpuImage, CL_TRUE, origin, region, 0, 0, accessor.GetData(), 0, NULL, NULL);
}
else
{
MITK_ERROR << "Selected image format currently not supported...";
}
CHECK_OCL_ERR(clErr);
}
m_gpuModified = true;
}
return clErr;
}
cl_int mitk::OclImage::AllocateGPUImage()
{
cl_int clErr = 0;
us::ServiceReference<OclResourceService> ref = GetModuleContext()->GetServiceReference<OclResourceService>();
OclResourceService* resources = GetModuleContext()->GetService<OclResourceService>(ref);
cl_context gpuContext = resources->GetContext();
// initialize both proposed and supported format variables to same value
this->m_proposedFormat = this->ConvertPixelTypeToOCLFormat();
this->m_supportedFormat = this->m_proposedFormat;
// test the current format for HW support
this->m_formatSupported = resources->GetIsFormatSupported( &(this->m_supportedFormat) );
// create an transfer kernel object in case the proposed format is not supported
if( !(this->m_formatSupported) )
{
- MITK_ERROR << "Original format not supported on the installed graphics card.";
- return -1;
+ mitkThrowException(mitk::ImageTypeIsNotSupportedByGPU) << "Original format not supported on the installed graphics card.";
}
// create new buffer
if( this->m_dim > 2)
{
//Create a 3D Image
m_gpuImage = clCreateImage3D(gpuContext, CL_MEM_READ_ONLY, &m_supportedFormat, *(m_Dims), *(m_Dims+1), *(m_Dims+2), 0, 0, NULL, &clErr);
}
else
{
//Create a 2D Image
m_gpuImage = clCreateImage2D(gpuContext, CL_MEM_READ_ONLY, &m_supportedFormat, *(m_Dims), *(m_Dims+1), 0, NULL, &clErr);
}
CHECK_OCL_ERR(clErr);
return clErr;
}
cl_mem mitk::OclImage::GetGPUImage(cl_command_queue gpuComQueue)
{
// clGetMemObjectInfo()
cl_mem_object_type memInfo;
cl_int clErr = 0;
// query image object info only if already initialized
if( this->m_gpuImage )
{
clErr = clGetMemObjectInfo(this->m_gpuImage, CL_MEM_TYPE, sizeof(cl_mem_object_type), &memInfo, NULL );
CHECK_OCL_ERR(clErr);
}
MITK_INFO << "Querying info for object, recieving: " << memInfo;
// test if m_gpuImage CL_MEM_IMAGE_2/3D
// if not, copy buffer to image
if (memInfo == CL_MEM_OBJECT_BUFFER)
{
MITK_WARN << " Passed oclImage is a buffer-object, creating image";
//hold a copy of the buffer gmem pointer
cl_mem tempBuffer = this->m_gpuImage;
const size_t origin[3] = {0, 0, 0};
size_t region[3] = {this->m_Dims[0], this->m_Dims[1], 1};
clErr = this->AllocateGPUImage();
this->m_dim = 3;
//copy last data to the image data
clErr = clEnqueueCopyBufferToImage( gpuComQueue, tempBuffer, m_gpuImage, 0, origin, region, 0, NULL, NULL);
CHECK_OCL_ERR(clErr);
//release pointer
clReleaseMemObject(tempBuffer);
}
return m_gpuImage;
}
void mitk::OclImage::SetPixelType(const cl_image_format *_image)
{
this->m_proposedFormat.image_channel_data_type = _image->image_channel_data_type;
this->m_proposedFormat.image_channel_order = _image->image_channel_order;
}
void* mitk::OclImage::TransferDataToCPU(cl_command_queue gpuComQueue)
{
cl_int clErr = 0;
// if image created on GPU, needs to create mitk::Image
if( m_Image.IsNull() ){
MITK_INFO << "Image not initialized, creating new one.";
m_Image = mitk::Image::New();
}
// check buffersize/image size
char* data = new char[m_bufferSize * m_BpE];
// debug info
oclPrintMemObjectInfo( m_gpuImage );
clErr = clEnqueueReadBuffer( gpuComQueue, m_gpuImage, CL_FALSE, 0, m_bufferSize * m_BpE, data ,0, NULL, NULL);
CHECK_OCL_ERR(clErr);
clFlush( gpuComQueue );
// the cpu data is same as gpu
this->m_gpuModified = false;
return (void*) data;
}
cl_image_format mitk::OclImage::ConvertPixelTypeToOCLFormat()
{
cl_image_format texFormat;
//single channel Gray-Valued Images
texFormat.image_channel_order = CL_R;
MITK_INFO << "Class own value: " << this->m_BpE;
switch ( this->m_BpE )
{
case 1:
texFormat.image_channel_data_type = CL_UNSIGNED_INT8;
MITK_INFO<< "PixelType: UCHAR => CLFormat: [CL_UNORM_INT8, CL_R]";
break;
case 2:
texFormat.image_channel_data_type = CL_SIGNED_INT16;
// texFormat.image_channel_order = CL_R;
MITK_INFO<< "PixelType: SHORT => CLFormat: [CL_SIGNED_INT16, CL_R]";
break;
case 4:
texFormat.image_channel_data_type = CL_FLOAT;
MITK_INFO<< "Choosing CL_FLOAT";
break;
default:
texFormat.image_channel_data_type = CL_UNORM_INT8;
texFormat.image_channel_order = CL_RG;
MITK_INFO<< "Choosing (default) short: 2-Channel UCHAR";
break;
}
return texFormat;
}
int mitk::OclImage::GetDimension(int idx) const
{
if (this->m_dim > idx)
{
return m_Dims[idx];
}
else
{
MITK_WARN << "Trying to access non-existing dimension.";
return 1;
}
}
void mitk::OclImage::SetDimensions(unsigned int* Dims)
{
m_Dims = Dims;
}
void mitk::OclImage::SetDimension(unsigned short dim)
{
m_dim = dim;
}
float mitk::OclImage::GetSpacing(int idx)
{
if (this->m_dim > idx)
{
const mitk::Vector3D imSpacing = m_Image->GetSlicedGeometry()->GetSpacing();
return imSpacing[idx];
}
else
{
MITK_WARN << "Trying to access non-existing dimension.";
return 1;
}
}
void mitk::OclImage::InitializeMITKImage()
{
this->m_Image = mitk::Image::New();
}
void mitk::OclImage::GetOffset(float* _imOffset) const
{
itk::Vector<float, 3> result2;
result2.Fill(0.0f);
result2 = this->m_Image->GetGeometry()->GetIndexToWorldTransform()->GetOffset();
_imOffset[0] = result2[0];
_imOffset[1] = result2[1];
_imOffset[2] = result2[2];
-}
\ No newline at end of file
+}
diff --git a/Modules/OpenCL/mitkOclImage.h b/Modules/OpenCL/mitkOclImage.h
index 17efd9f4be..096e1f0290 100644
--- a/Modules/OpenCL/mitkOclImage.h
+++ b/Modules/OpenCL/mitkOclImage.h
@@ -1,191 +1,204 @@
/*===================================================================
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 __mitkOclImage_h
#define __mitkOclImage_h
#define GPU_DATA 0
#define CPU_DATA 1
#define MAX_DIMS 20
-#include "mitkImage.h"
-#include <MitkOpenCLExports.h>
+#include <mitkImage.h>
+#include "MitkOpenCLExports.h"
#include "mitkOclBaseData.h"
#include "mitkOclImageFormats.h"
-
#include "mitkOpenCLActivator.h"
+#include <mitkException.h>
+
#define SHORT_IM mitk::MakeScalarPixelType<short>()
#define FLOAT_IM mitk::MakeScalarPixelType<float>()
namespace mitk {
/*!
* \brief Class implementing the image format for GPU Image Processing
*
* The class holds a pointer to the mitk::Image stored in RAM and performs an
* on-demand-copy to the graphics memory. It is the basic data structure for all
* mitk::oclImageToImageFilter classes
+ * @throw This class may throw an ImageTypeIsNotSupportedByGPU, if the image
+ * format is supported by the GPU.
*/
class MitkOpenCL_EXPORT OclImage : public OclBaseData
{
public:
mitkClassMacro(OclImage, OclBaseData);
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
/*! \brief Copies the RAM-stored data to GMEM */
virtual int TransferDataToGPU(cl_command_queue);
/*! \brief Copies the in GMEM stored data to RAM */
virtual void* TransferDataToCPU(cl_command_queue);
/*! \brief Returns the pointer to the referenced mitk::Image */
Image::Pointer GetMITKImage()
{
return m_Image;
}
/*! \brief Checks whether gpuImage is a valid clImage object
when an oclImage gets created by an image to image filter, the output image is created
by clCreateBuffer() because it is not in general possible to write to clImage directly
*/
cl_mem GetGPUImage(cl_command_queue);
/** Returns the pointer to the GPU buffer */
cl_mem GetGPUBuffer()
{
return this->m_gpuImage;
}
/** Create the GPU buffer for image
*
*/
cl_mem CreateGPUImage(unsigned int, unsigned int, unsigned int, unsigned int);
/** \brief Returns the status of the image buffer
*
* @param _type The flag to specify the buffer type ( GPU / CPU )
*/
bool IsModified(int _type);
/** \brief Set the modified flag for one of the buffers
*
* @param _type The flag to specify the buffer type ( GPU / CPU )
*/
void Modified(int _type);
/** @brief Initialize the internal variable of type mitk::Image.
*/
void InitializeMITKImage();
/** \brief Initialze the OclImage with an mitkImage. */
void InitializeByMitkImage(mitk::Image::Pointer _image);
/*! \brief returns the specified image dimension size */
int GetDimension(int) const;
/*! \brief returns the dimensionality of the image */
int GetDimension() const
{
return this->m_dim;
}
/*! \brief returns the pointer to the array of image sizes */
unsigned int* GetDimensions(){ return this->m_Dims; }
/*! \brief returns the spacing of the image for specified dimension */
float GetSpacing(int);
/*! \brief Returns the image offset (needed for WorldToIndex Transform */
void GetOffset(float*) const;
/** @brief Set the pixel type for the image to be used
*/
void SetPixelType(const cl_image_format*);
short GetBytesPerPixel() const
{
return this->m_BpE;
}
/** @brief Get the currently used pixel type
@returns OpenCL Image Format struct
*/
const cl_image_format* GetPixelType() const
{
return &(this->m_proposedFormat);
}
/** @brief Set the image dimensions through an unsigned int array */
void SetDimensions(unsigned int* Dims);
/** @brief Set the dimensionality of the image */
void SetDimension(unsigned short dim);
protected:
/*! \brief Constructor */
OclImage();
/** @brief Destructor */
virtual ~OclImage();
/*! GMEM Image buffer */
cl_mem m_gpuImage;
/*! GPU Context the Image Buffer was created in, needed for access */
cl_context m_context;
/*! GMEM Buffer Size */
unsigned int m_bufferSize;
private:
cl_image_format ConvertPixelTypeToOCLFormat();
bool m_gpuModified;
bool m_cpuModified;
/*! Reference to mitk::Image */
Image::Pointer m_Image;
unsigned short m_dim;
unsigned int* m_Dims;
unsigned short m_BpE;
cl_int AllocateGPUImage();
/** Bool flag to signalize if the proposed format is supported on currend HW.
For value 'false', the transfer kernel has to be called to fit the data to
the supported format */
bool m_formatSupported;
/** Supported format, defined using oclImageFormats */
cl_image_format m_supportedFormat;
/** Proposed format for image */
cl_image_format m_proposedFormat;
};
+/**
+ * @brief The ImageTypeIsNotSupportedByGPU class specialized exception class for unsupported
+ * image formats. If this exception is thrown, try other graphics device.
+ */
+class ImageTypeIsNotSupportedByGPU : public Exception
+{
+public:
+ mitkExceptionClassMacro(ImageTypeIsNotSupportedByGPU,Exception)
+};
+
}
#endif //__mitkOclImage_h
diff --git a/Modules/OpenCL/mitkOclResourceServiceImpl_Private.cpp b/Modules/OpenCL/mitkOclResourceServiceImpl_Private.cpp
index ff82ab83e5..2fd633f794 100644
--- a/Modules/OpenCL/mitkOclResourceServiceImpl_Private.cpp
+++ b/Modules/OpenCL/mitkOclResourceServiceImpl_Private.cpp
@@ -1,260 +1,260 @@
/*===================================================================
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 "mitkOclResourceServiceImpl_p.h"
OclResourceService::~OclResourceService()
{
}
OclResourceServiceImpl::OclResourceServiceImpl()
: m_ContextCollection(NULL), m_ProgramStorage()
{
m_ProgramStorageMutex = itk::FastMutexLock::New();
}
OclResourceServiceImpl::~OclResourceServiceImpl()
{
// if map non-empty, release all remaining
if( m_ProgramStorage.size() )
{
ProgramMapType::iterator it = m_ProgramStorage.begin();
while(it != m_ProgramStorage.end() )
{
clReleaseProgram( it->second.program );
m_ProgramStorage.erase( it++ );
}
}
if( m_ContextCollection )
delete m_ContextCollection;
}
cl_context OclResourceServiceImpl::GetContext() const
{
if( m_ContextCollection == NULL )
{
m_ContextCollection = new OclContextCollection();
}
else if( !m_ContextCollection->CanProvideContext() )
{
return NULL;
}
return m_ContextCollection->m_Context;
}
cl_command_queue OclResourceServiceImpl::GetCommandQueue() const
{
// check if queue valid
cl_context clQueueContext;
// check if there is a context available
// if not create one
if( ! m_ContextCollection )
{
m_ContextCollection = new OclContextCollection();
}
cl_int clErr = clGetCommandQueueInfo( m_ContextCollection->m_CommandQueue, CL_QUEUE_CONTEXT, sizeof(clQueueContext), &clQueueContext, NULL );
if( clErr != CL_SUCCESS || clQueueContext != m_ContextCollection->m_Context )
{
MITK_WARN << "Have no valid command queue. Query returned : " << GetOclErrorAsString( clErr );
return NULL;
}
return m_ContextCollection->m_CommandQueue;
}
cl_device_id OclResourceServiceImpl::GetCurrentDevice() const
{
return m_ContextCollection->m_Devices[0];
}
bool OclResourceServiceImpl::GetIsFormatSupported(cl_image_format *fmt)
{
cl_image_format temp;
temp.image_channel_data_type = fmt->image_channel_data_type;
temp.image_channel_order = fmt->image_channel_order;
return (this->m_ContextCollection->m_ImageFormats->GetNearestSupported(&temp, fmt));
}
void OclResourceServiceImpl::PrintContextInfo() const
{
// context and devices available
if( m_ContextCollection->CanProvideContext() )
{
oclPrintDeviceInfo( m_ContextCollection->m_Devices[0] );
}
}
void OclResourceServiceImpl::InsertProgram(cl_program _program_in, std::string name, bool forceOverride)
{
typedef std::pair < std::string, ProgramData > MapElemPair;
std::pair< ProgramMapType::iterator, bool> retValue;
ProgramData data;
data.counter = 1;
data.program = _program_in;
data.mutex = itk::FastMutexLock::New();
// program is not stored, insert first instance (count = 1)
m_ProgramStorageMutex->Lock();
retValue = m_ProgramStorage.insert( MapElemPair(name, data) );
m_ProgramStorageMutex->Unlock();
// insertion failed, i.e. a program with same name exists
if( !retValue.second )
{
std::string overrideMsg("");
if( forceOverride )
{
// overwrite old instance
m_ProgramStorage[name].program = _program_in;
overrideMsg +=" The old program was overwritten!";
}
MITK_WARN("OpenCL.ResourceService") << "The program " << name << " already exists." << overrideMsg;
}
}
cl_program OclResourceServiceImpl::GetProgram(const std::string &name)
{
ProgramMapType::iterator it = m_ProgramStorage.find(name);
if( it != m_ProgramStorage.end() )
{
it->second.mutex->Lock();
// first check if the program was deleted
// while waiting on the mutex
if ( it->second.counter == 0 )
mitkThrow() << "Requested OpenCL Program (" << name <<") not found."
<< "(deleted while waiting on the mutex)";
// increase the reference counter
// by one if the program is requestet
it->second.counter += 1;
it->second.mutex->Unlock();
// return the cl_program
return it->second.program;
}
mitkThrow() << "Requested OpenCL Program (" << name <<") not found.";
}
void OclResourceServiceImpl::InvalidateStorage()
{
// do nothing if no context present, there is also no storage
if( !m_ContextCollection->CanProvideContext() )
return;
// query the map
ProgramMapType::iterator it = m_ProgramStorage.begin();
while(it != m_ProgramStorage.end() )
{
// query the program build status
cl_build_status status;
unsigned int query = clGetProgramBuildInfo( it->second.program, m_ContextCollection->m_Devices[0], CL_PROGRAM_BUILD_STATUS, sizeof(cl_int), &status, NULL );
CHECK_OCL_ERR( query )
MITK_DEBUG << "Quering status for " << it->first << std::endl;
// remove program if no succesfull build
// we need to pay attention to the increment of the iterator when erasing current element
if( status != CL_BUILD_SUCCESS )
{
MITK_DEBUG << " +-- Build failed " << std::endl;
m_ProgramStorage.erase( it++ );
}
else
{
++it;
}
}
}
void OclResourceServiceImpl::RemoveProgram(const std::string& name)
{
ProgramMapType::iterator it = m_ProgramStorage.find(name);
cl_int status = 0;
cl_program program = NULL;
if( it != m_ProgramStorage.end() )
{
it->second.mutex->Lock();
// decrease reference by one
it->second.counter -= 1;
it->second.mutex->Unlock();
// remove from the storage
if( it->second.counter == 0 )
{
program = it->second.program;
m_ProgramStorageMutex->Lock();
m_ProgramStorage.erase(it);
m_ProgramStorageMutex->Unlock();
}
// delete the program
if( program )
{
status = clReleaseProgram(program);
CHECK_OCL_ERR( status );
}
}
else
{
MITK_WARN("OpenCL.ResourceService") << "Program name [" <<name <<"] passed for deletion not found.";
}
}
unsigned int OclResourceServiceImpl::GetMaximumImageSize(unsigned int dimension, cl_mem_object_type _imagetype)
{
if( ! m_ContextCollection->CanProvideContext() )
return 0;
- unsigned int retValue = 0;
+ size_t retValue = 0;
switch(dimension)
{
case 0:
if ( _imagetype == CL_MEM_OBJECT_IMAGE2D)
- clGetDeviceInfo( m_ContextCollection->m_Devices[0], CL_DEVICE_IMAGE2D_MAX_WIDTH, sizeof( cl_uint ), &retValue, NULL );
+ clGetDeviceInfo( m_ContextCollection->m_Devices[0], CL_DEVICE_IMAGE2D_MAX_WIDTH, sizeof( size_t ), &retValue, NULL );
else
- clGetDeviceInfo( m_ContextCollection->m_Devices[0], CL_DEVICE_IMAGE3D_MAX_WIDTH, sizeof( cl_uint ), &retValue, NULL );
+ clGetDeviceInfo( m_ContextCollection->m_Devices[0], CL_DEVICE_IMAGE3D_MAX_WIDTH, sizeof( size_t ), &retValue, NULL );
break;
case 1:
if ( _imagetype == CL_MEM_OBJECT_IMAGE2D)
- clGetDeviceInfo( m_ContextCollection->m_Devices[0], CL_DEVICE_IMAGE2D_MAX_HEIGHT, sizeof( cl_uint ), &retValue, NULL );
+ clGetDeviceInfo( m_ContextCollection->m_Devices[0], CL_DEVICE_IMAGE2D_MAX_HEIGHT, sizeof( size_t ), &retValue, NULL );
else
- clGetDeviceInfo( m_ContextCollection->m_Devices[0], CL_DEVICE_IMAGE3D_MAX_HEIGHT, sizeof( cl_uint ), &retValue, NULL );
+ clGetDeviceInfo( m_ContextCollection->m_Devices[0], CL_DEVICE_IMAGE3D_MAX_HEIGHT, sizeof( size_t ), &retValue, NULL );
break;
case 2:
if ( _imagetype == CL_MEM_OBJECT_IMAGE3D)
- clGetDeviceInfo( m_ContextCollection->m_Devices[0], CL_DEVICE_IMAGE3D_MAX_DEPTH, sizeof( cl_uint ), &retValue, NULL);
+ clGetDeviceInfo( m_ContextCollection->m_Devices[0], CL_DEVICE_IMAGE3D_MAX_DEPTH, sizeof( size_t ), &retValue, NULL);
break;
default:
MITK_WARN << "Could not recieve info. Desired dimension or object type does not exist. ";
break;
}
return retValue;
}
diff --git a/Modules/PlanarFigure/CMakeLists.txt b/Modules/PlanarFigure/CMakeLists.txt
index 3f37aaf0f2..cf6f567b1b 100644
--- a/Modules/PlanarFigure/CMakeLists.txt
+++ b/Modules/PlanarFigure/CMakeLists.txt
@@ -1,9 +1,9 @@
MITK_CREATE_MODULE(
INCLUDE_DIRS Algorithms DataManagement Interactions IO Rendering
DEPENDS MitkSceneSerializationBase
- # WARNINGS_AS_ERRORS
+ WARNINGS_AS_ERRORS
)
IF( BUILD_TESTING )
add_subdirectory(Testing)
ENDIF()
diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarArrow.cpp b/Modules/PlanarFigure/DataManagement/mitkPlanarArrow.cpp
index 6185f0e685..7c6f27186c 100644
--- a/Modules/PlanarFigure/DataManagement/mitkPlanarArrow.cpp
+++ b/Modules/PlanarFigure/DataManagement/mitkPlanarArrow.cpp
@@ -1,132 +1,132 @@
/*===================================================================
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 "mitkPlanarArrow.h"
#include "mitkPlaneGeometry.h"
mitk::PlanarArrow::PlanarArrow()
: FEATURE_ID_LENGTH( this->AddFeature( "Length", "mm" ) )
{
// Directed arrow has two control points
this->ResetNumberOfControlPoints( 2 );
m_ArrowTipScaleFactor = -1.0;
this->SetNumberOfPolyLines( 1 );
this->SetNumberOfHelperPolyLines( 2 );
// Create helper polyline object (for drawing the orthogonal orientation line)
m_HelperPolyLinesToBePainted->InsertElement( 0, false );
m_HelperPolyLinesToBePainted->InsertElement( 1, false );
}
mitk::PlanarArrow::~PlanarArrow()
{
}
void mitk::PlanarArrow::GeneratePolyLine()
{
this->ClearPolyLines();
this->AppendPointToPolyLine(0, this->GetControlPoint(0));
this->AppendPointToPolyLine(0, this->GetControlPoint(1));
}
void mitk::PlanarArrow::GenerateHelperPolyLine(double mmPerDisplayUnit, unsigned int displayHeight)
{
// Generate helper polyline (orientation line orthogonal to first line)
// if the third control point is currently being set
if ( this->GetNumberOfControlPoints() != 2 )
{
m_HelperPolyLinesToBePainted->SetElement( 0, false );
m_HelperPolyLinesToBePainted->SetElement( 1, false );
return;
}
this->ClearHelperPolyLines();
m_HelperPolyLinesToBePainted->SetElement( 0, true );
m_HelperPolyLinesToBePainted->SetElement( 1, true );
//Fixed size depending on screen size for the angle
float scaleFactor = 0.015;
if ( m_ArrowTipScaleFactor > 0.0 )
{
scaleFactor = m_ArrowTipScaleFactor;
}
double nonScalingLength = displayHeight * mmPerDisplayUnit * scaleFactor;
// Calculate arrow peak
const Point2D p1 = this->GetControlPoint( 0 );
const Point2D p2 = this->GetControlPoint( 1 );
Vector2D n1 = p1 - p2;
n1.Normalize();
double degrees = 100.0;
Vector2D temp;
temp[0] = n1[0] * cos(degrees) - n1[1] * sin(degrees);
temp[1] = n1[0] * sin(degrees) + n1[1] * cos(degrees);
Vector2D temp2;
temp2[0] = n1[0] * cos(-degrees) - n1[1] * sin(-degrees);
temp2[1] = n1[0] * sin(-degrees) + n1[1] * cos(-degrees);
this->AppendPointToHelperPolyLine(0, p1);
this->AppendPointToHelperPolyLine(0, Point2D(p1 - temp * nonScalingLength));
this->AppendPointToHelperPolyLine(1, p1);
this->AppendPointToHelperPolyLine(1, Point2D(p1 - temp2 * nonScalingLength));
}
void mitk::PlanarArrow::EvaluateFeaturesInternal()
{
// Calculate line length
const Point3D &p0 = this->GetWorldControlPoint( 0 );
const Point3D &p1 = this->GetWorldControlPoint( 1 );
double length = p0.EuclideanDistanceTo( p1 );
this->SetQuantity( FEATURE_ID_LENGTH, length );
}
void mitk::PlanarArrow::PrintSelf( std::ostream& os, itk::Indent indent) const
{
Superclass::PrintSelf( os, indent );
}
void mitk::PlanarArrow::SetArrowTipScaleFactor( float scale )
{
m_ArrowTipScaleFactor = scale;
}
-bool mitk::PlanarArrow::Equals(mitk::PlanarFigure& other)
+bool mitk::PlanarArrow::Equals(const mitk::PlanarFigure& other) const
{
- mitk::PlanarArrow* otherArrow = dynamic_cast<mitk::PlanarArrow*>(&other);
+ const mitk::PlanarArrow* otherArrow = dynamic_cast<const mitk::PlanarArrow*>(&other);
if ( otherArrow )
{
if ( std::abs(this->m_ArrowTipScaleFactor - otherArrow->m_ArrowTipScaleFactor) > mitk::eps)
return false;
return Superclass::Equals(other);
}
else
{
return false;
}
}
diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarArrow.h b/Modules/PlanarFigure/DataManagement/mitkPlanarArrow.h
index 9375c529f7..1822578ebc 100644
--- a/Modules/PlanarFigure/DataManagement/mitkPlanarArrow.h
+++ b/Modules/PlanarFigure/DataManagement/mitkPlanarArrow.h
@@ -1,99 +1,99 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef _MITK_PLANAR_ARROW_H_
#define _MITK_PLANAR_ARROW_H_
#include "mitkPlanarFigure.h"
#include <MitkPlanarFigureExports.h>
namespace mitk
{
class PlaneGeometry;
/**
* \brief Implementation of PlanarFigure representing an arrow
* through two control points
*/
class MitkPlanarFigure_EXPORT PlanarArrow : public PlanarFigure
{
public:
mitkClassMacro( PlanarArrow, PlanarFigure );
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
/** \brief Place figure in its minimal configuration (a point at least)
* onto the given 2D geometry.
*
* Must be implemented in sub-classes.
*/
//virtual void Initialize();
/** \brief Line has 2 control points per definition. */
unsigned int GetMinimumNumberOfControlPoints() const
{
return 2;
}
/** \brief Line has 2 control points per definition. */
unsigned int GetMaximumNumberOfControlPoints() const
{
return 2;
}
void SetArrowTipScaleFactor( float scale );
- virtual bool Equals(mitk::PlanarFigure& other);
+ virtual bool Equals(const mitk::PlanarFigure& other) const;
protected:
PlanarArrow();
virtual ~PlanarArrow();
mitkCloneMacro(Self);
/** \brief Generates the poly-line representation of the planar figure. */
virtual void GeneratePolyLine();
/** \brief Generates the poly-lines that should be drawn the same size regardless of zoom.*/
virtual void GenerateHelperPolyLine(double mmPerDisplayUnit, unsigned int displayHeight);
/** \brief Calculates feature quantities of the planar figure. */
virtual void EvaluateFeaturesInternal();
virtual void PrintSelf( std::ostream &os, itk::Indent indent ) const;
// Feature identifiers
const unsigned int FEATURE_ID_LENGTH;
// ScaleFactor defining size of helper-lines in relation to display size
float m_ArrowTipScaleFactor;
private:
};
} // namespace mitk
#endif //_MITK_PLANAR_ARROW_H_
diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarFigure.cpp b/Modules/PlanarFigure/DataManagement/mitkPlanarFigure.cpp
index 5d69c365d6..de54c2413c 100644
--- a/Modules/PlanarFigure/DataManagement/mitkPlanarFigure.cpp
+++ b/Modules/PlanarFigure/DataManagement/mitkPlanarFigure.cpp
@@ -1,895 +1,796 @@
/*===================================================================
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 "mitkPlanarFigure.h"
#include "mitkPlaneGeometry.h"
#include <mitkProperties.h>
#include <mitkProportionalTimeGeometry.h>
#include <algorithm>
-#ifdef __GNUC__
-# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-#elif __clang__
-# pragma clang diagnostic ignored "-Wdeprecated-declarations"
-#elif _MSC_VER
-# pragma warning (push)
-# pragma warning (disable: 4996)
-#endif
-
-mitk::PlanarFigure::PolyLineElement::PolyLineElement(Point2D point, int index)
- : Point(point),
- Index(index)
-{
-}
-
-mitk::PlanarFigure::PolyLineElement::PolyLineElement(const Point2D& point)
- : Point(point),
- Index(-1)
-{
-}
-
-mitk::PlanarFigure::PolyLineElement::PolyLineElement(const PolyLineElement &other)
- : Point(other.Point),
- Index(other.Index)
-{
-}
-
-mitk::PlanarFigure::PolyLineElement& mitk::PlanarFigure::PolyLineElement::operator=(const PolyLineElement &other)
-{
- if (this != &other)
- {
- Point = other.Point;
- Index = other.Index;
- }
-
- return *this;
-}
-
-mitk::PlanarFigure::PolyLineElement::operator mitk::Point2D&()
-{
- return Point;
-}
-
-mitk::PlanarFigure::PolyLineElement::operator const mitk::Point2D&() const
-{
- return Point;
-}
-
mitk::PlanarFigure::PlanarFigure()
: m_SelectedControlPoint( -1 ),
m_PreviewControlPointVisible( false ),
m_FigurePlaced( false ),
m_PlaneGeometry( NULL ),
m_PolyLineUpToDate(false),
m_HelperLinesUpToDate(false),
m_FeaturesUpToDate(false),
m_FeaturesMTime( 0 )
{
m_HelperPolyLinesToBePainted = BoolContainerType::New();
m_DisplaySize.first = 0.0;
m_DisplaySize.second = 0;
this->SetProperty( "closed", mitk::BoolProperty::New( false ) );
// Currently only single-time-step geometries are supported
this->InitializeTimeGeometry( 1 );
}
mitk::PlanarFigure::~PlanarFigure()
{
}
mitk::PlanarFigure::PlanarFigure(const Self& other)
: BaseData(other),
m_ControlPoints(other.m_ControlPoints),
m_NumberOfControlPoints(other.m_NumberOfControlPoints),
m_SelectedControlPoint(other.m_SelectedControlPoint),
m_PolyLines(other.m_PolyLines),
m_HelperPolyLines(other.m_HelperPolyLines),
m_HelperPolyLinesToBePainted(other.m_HelperPolyLinesToBePainted->Clone()),
m_PreviewControlPoint(other.m_PreviewControlPoint),
m_PreviewControlPointVisible(other.m_PreviewControlPointVisible),
m_FigurePlaced(other.m_FigurePlaced),
m_PlaneGeometry(other.m_PlaneGeometry), // do not clone since SetPlaneGeometry() doesn't clone either
m_PolyLineUpToDate(other.m_PolyLineUpToDate),
m_HelperLinesUpToDate(other.m_HelperLinesUpToDate),
m_FeaturesUpToDate(other.m_FeaturesUpToDate),
m_Features(other.m_Features),
m_FeaturesMTime(other.m_FeaturesMTime),
m_DisplaySize(other.m_DisplaySize)
{
}
void mitk::PlanarFigure::SetPlaneGeometry( mitk::PlaneGeometry *geometry )
{
this->SetGeometry( geometry );
m_PlaneGeometry = dynamic_cast<PlaneGeometry *>(GetGeometry(0));//geometry;
}
const mitk::PlaneGeometry *mitk::PlanarFigure::GetPlaneGeometry() const
{
return m_PlaneGeometry;
}
bool mitk::PlanarFigure::IsClosed() const
{
mitk::BoolProperty* closed = dynamic_cast< mitk::BoolProperty* >( this->GetProperty( "closed" ).GetPointer() );
if ( closed != NULL )
{
return closed->GetValue();
}
return false;
}
void mitk::PlanarFigure::PlaceFigure( const mitk::Point2D& point )
{
for ( unsigned int i = 0; i < this->GetNumberOfControlPoints(); ++i )
{
m_ControlPoints.push_back( this->ApplyControlPointConstraints( i, point ) );
}
m_FigurePlaced = true;
m_SelectedControlPoint = 1;
}
bool mitk::PlanarFigure::AddControlPoint( const mitk::Point2D& point, int position )
{
// if we already have the maximum number of control points, do nothing
if ( m_NumberOfControlPoints < this->GetMaximumNumberOfControlPoints() )
{
// if position has not been defined or position would be the last control point, just append the new one
// we also append a new point if we click onto the line between the first two control-points if the second control-point is selected
// -> special case for PlanarCross
if ( position == -1 || position > (int)m_NumberOfControlPoints-1 || (position == 1 && m_SelectedControlPoint == 2) )
{
if ( m_ControlPoints.size() > this->GetMaximumNumberOfControlPoints()-1 )
{
// get rid of deprecated control points in the list. This is necessary
// as ::ResetNumberOfControlPoints() only sets the member, does not resize the list!
m_ControlPoints.resize( this->GetNumberOfControlPoints() );
}
m_ControlPoints.push_back( this->ApplyControlPointConstraints( m_NumberOfControlPoints, point ) );
m_SelectedControlPoint = m_NumberOfControlPoints;
}
else
{
// insert the point at the given position and set it as selected point
ControlPointListType::iterator iter = m_ControlPoints.begin() + position;
m_ControlPoints.insert( iter, this->ApplyControlPointConstraints( position, point ) );
for( unsigned int i = 0; i < m_ControlPoints.size(); ++i )
{
if( point == m_ControlPoints.at(i) )
{
m_SelectedControlPoint = i;
}
}
}
// polylines & helperpolylines need to be repainted
m_PolyLineUpToDate = false;
m_HelperLinesUpToDate = false;
m_FeaturesUpToDate = false;
// one control point more
++m_NumberOfControlPoints;
return true;
}
else
{
return false;
}
}
bool mitk::PlanarFigure::SetControlPoint( unsigned int index, const Point2D& point, bool createIfDoesNotExist )
{
bool controlPointSetCorrectly = false;
if (createIfDoesNotExist)
{
if ( m_NumberOfControlPoints <= index )
{
m_ControlPoints.push_back( this->ApplyControlPointConstraints( index, point ) );
m_NumberOfControlPoints++;
}
else
{
m_ControlPoints.at( index ) = this->ApplyControlPointConstraints( index, point );
}
controlPointSetCorrectly = true;
}
else if ( index < m_NumberOfControlPoints )
{
m_ControlPoints.at( index ) = this->ApplyControlPointConstraints( index, point );
controlPointSetCorrectly = true;
}
else
{
return false;
}
if ( controlPointSetCorrectly )
{
m_PolyLineUpToDate = false;
m_HelperLinesUpToDate = false;
m_FeaturesUpToDate = false;
}
return controlPointSetCorrectly;
}
bool mitk::PlanarFigure::SetCurrentControlPoint( const Point2D& point )
{
if ( (m_SelectedControlPoint < 0) || (m_SelectedControlPoint >= (int)m_NumberOfControlPoints) )
{
return false;
}
return this->SetControlPoint(m_SelectedControlPoint, point, false);
}
unsigned int mitk::PlanarFigure::GetNumberOfControlPoints() const
{
return m_NumberOfControlPoints;
}
bool mitk::PlanarFigure::SelectControlPoint( unsigned int index )
{
if ( index < this->GetNumberOfControlPoints() )
{
m_SelectedControlPoint = index;
return true;
}
else
{
return false;
}
}
bool mitk::PlanarFigure::DeselectControlPoint()
{
bool wasSelected = ( m_SelectedControlPoint != -1);
m_SelectedControlPoint = -1;
return wasSelected;
}
void mitk::PlanarFigure::SetPreviewControlPoint( const Point2D& point )
{
m_PreviewControlPoint = point;
m_PreviewControlPointVisible = true;
}
void mitk::PlanarFigure::ResetPreviewContolPoint()
{
m_PreviewControlPointVisible = false;
}
mitk::Point2D mitk::PlanarFigure::GetPreviewControlPoint()
{
return m_PreviewControlPoint;
}
bool mitk::PlanarFigure::IsPreviewControlPointVisible()
{
return m_PreviewControlPointVisible;
}
mitk::Point2D mitk::PlanarFigure::GetControlPoint( unsigned int index ) const
{
if ( index < m_NumberOfControlPoints )
{
return m_ControlPoints.at( index );
}
itkExceptionMacro( << "GetControlPoint(): Invalid index!" );
}
mitk::Point3D mitk::PlanarFigure::GetWorldControlPoint( unsigned int index ) const
{
Point3D point3D;
if ( (m_PlaneGeometry != NULL) && (index < m_NumberOfControlPoints) )
{
m_PlaneGeometry->Map( m_ControlPoints.at( index ), point3D );
return point3D;
}
itkExceptionMacro( << "GetWorldControlPoint(): Invalid index!" );
}
const mitk::PlanarFigure::PolyLineType
mitk::PlanarFigure::GetPolyLine(unsigned int index)
{
mitk::PlanarFigure::PolyLineType polyLine;
if ( index > m_PolyLines.size() || !m_PolyLineUpToDate )
{
this->GeneratePolyLine();
m_PolyLineUpToDate = true;
}
return m_PolyLines.at( index );;
}
const mitk::PlanarFigure::PolyLineType
mitk::PlanarFigure::GetPolyLine(unsigned int index) const
{
return m_PolyLines.at( index );
}
void mitk::PlanarFigure::ClearPolyLines()
{
for ( std::vector<PolyLineType>::size_type i=0; i<m_PolyLines.size(); i++ )
{
m_PolyLines.at( i ).clear();
}
m_PolyLineUpToDate = false;
}
const mitk::PlanarFigure::PolyLineType mitk::PlanarFigure::GetHelperPolyLine( unsigned int index,
double mmPerDisplayUnit,
unsigned int displayHeight )
{
mitk::PlanarFigure::PolyLineType helperPolyLine;
if ( index < m_HelperPolyLines.size() )
{
// m_HelperLinesUpToDate does not cover changes in zoom-level, so we have to check previous values of the
// two parameters as well
if ( !m_HelperLinesUpToDate || m_DisplaySize.first != mmPerDisplayUnit || m_DisplaySize.second != displayHeight )
{
this->GenerateHelperPolyLine(mmPerDisplayUnit, displayHeight);
m_HelperLinesUpToDate = true;
// store these parameters to be able to check next time if somebody zoomed in or out
m_DisplaySize.first = mmPerDisplayUnit;
m_DisplaySize.second = displayHeight;
}
helperPolyLine = m_HelperPolyLines.at(index);
}
return helperPolyLine;
}
void mitk::PlanarFigure::ClearHelperPolyLines()
{
for ( std::vector<PolyLineType>::size_type i=0; i<m_HelperPolyLines.size(); i++ )
{
m_HelperPolyLines.at(i).clear();
}
m_HelperLinesUpToDate = false;
}
/** \brief Returns the number of features available for this PlanarFigure
* (such as, radius, area, ...). */
unsigned int mitk::PlanarFigure::GetNumberOfFeatures() const
{
return m_Features.size();
}
const char *mitk::PlanarFigure::GetFeatureName( unsigned int index ) const
{
if ( index < m_Features.size() )
{
return m_Features[index].Name.c_str();
}
else
{
return NULL;
}
}
const char *mitk::PlanarFigure::GetFeatureUnit( unsigned int index ) const
{
if ( index < m_Features.size() )
{
return m_Features[index].Unit.c_str();
}
else
{
return NULL;
}
}
double mitk::PlanarFigure::GetQuantity( unsigned int index ) const
{
if ( index < m_Features.size() )
{
return m_Features[index].Quantity;
}
else
{
return 0.0;
}
}
bool mitk::PlanarFigure::IsFeatureActive( unsigned int index ) const
{
if ( index < m_Features.size() )
{
return m_Features[index].Active;
}
else
{
return false;
}
}
bool mitk::PlanarFigure::IsFeatureVisible( unsigned int index ) const
{
if ( index < m_Features.size() )
{
return m_Features[index].Visible;
}
else
{
return false;
}
}
void mitk::PlanarFigure::SetFeatureVisible( unsigned int index, bool visible )
{
if ( index < m_Features.size() )
{
m_Features[index].Visible = visible;
}
}
void mitk::PlanarFigure::EvaluateFeatures()
{
if ( !m_FeaturesUpToDate || !m_PolyLineUpToDate )
{
if ( !m_PolyLineUpToDate )
{
this->GeneratePolyLine();
}
this->EvaluateFeaturesInternal();
m_FeaturesUpToDate = true;
}
}
void mitk::PlanarFigure::UpdateOutputInformation()
{
// Bounds are NOT calculated here, since the PlaneGeometry defines a fixed
// frame (= bounds) for the planar figure.
Superclass::UpdateOutputInformation();
this->GetTimeGeometry()->Update();
}
void mitk::PlanarFigure::SetRequestedRegionToLargestPossibleRegion()
{
}
bool mitk::PlanarFigure::RequestedRegionIsOutsideOfTheBufferedRegion()
{
return false;
}
bool mitk::PlanarFigure::VerifyRequestedRegion()
{
return true;
}
void mitk::PlanarFigure::SetRequestedRegion(const itk::DataObject * /*data*/ )
{
}
void mitk::PlanarFigure::ResetNumberOfControlPoints( int numberOfControlPoints )
{
// DO NOT resize the list here, will cause crash!!
m_NumberOfControlPoints = numberOfControlPoints;
}
mitk::Point2D mitk::PlanarFigure::ApplyControlPointConstraints( unsigned int /*index*/, const Point2D& point )
{
if ( m_PlaneGeometry == NULL )
{
return point;
}
Point2D indexPoint;
m_PlaneGeometry->WorldToIndex( point, indexPoint );
BoundingBox::BoundsArrayType bounds = m_PlaneGeometry->GetBounds();
if ( indexPoint[0] < bounds[0] ) { indexPoint[0] = bounds[0]; }
if ( indexPoint[0] > bounds[1] ) { indexPoint[0] = bounds[1]; }
if ( indexPoint[1] < bounds[2] ) { indexPoint[1] = bounds[2]; }
if ( indexPoint[1] > bounds[3] ) { indexPoint[1] = bounds[3]; }
Point2D constrainedPoint;
m_PlaneGeometry->IndexToWorld( indexPoint, constrainedPoint );
return constrainedPoint;
}
unsigned int mitk::PlanarFigure::AddFeature( const char *featureName, const char *unitName )
{
unsigned int index = m_Features.size();
Feature newFeature( featureName, unitName );
m_Features.push_back( newFeature );
return index;
}
void mitk::PlanarFigure::SetFeatureName( unsigned int index, const char *featureName )
{
if ( index < m_Features.size() )
{
m_Features[index].Name = featureName;
}
}
void mitk::PlanarFigure::SetFeatureUnit( unsigned int index, const char *unitName )
{
if ( index < m_Features.size() )
{
m_Features[index].Unit = unitName;
}
}
void mitk::PlanarFigure::SetQuantity( unsigned int index, double quantity )
{
if ( index < m_Features.size() )
{
m_Features[index].Quantity = quantity;
}
}
void mitk::PlanarFigure::ActivateFeature( unsigned int index )
{
if ( index < m_Features.size() )
{
m_Features[index].Active = true;
}
}
void mitk::PlanarFigure::DeactivateFeature( unsigned int index )
{
if ( index < m_Features.size() )
{
m_Features[index].Active = false;
}
}
void mitk::PlanarFigure::InitializeTimeGeometry( unsigned int timeSteps )
{
mitk::PlaneGeometry::Pointer geometry2D = mitk::PlaneGeometry::New();
geometry2D->Initialize();
// The geometry is propagated automatically to all time steps,
// if EvenlyTimed is true...
ProportionalTimeGeometry::Pointer timeGeometry = ProportionalTimeGeometry::New();
timeGeometry->Initialize(geometry2D, timeSteps);
SetTimeGeometry(timeGeometry);
}
void mitk::PlanarFigure::PrintSelf( std::ostream& os, itk::Indent indent) const
{
Superclass::PrintSelf( os, indent );
os << indent << this->GetNameOfClass() << ":\n";
if (this->IsClosed())
os << indent << "This figure is closed\n";
else
os << indent << "This figure is not closed\n";
os << indent << "Minimum number of control points: " << this->GetMinimumNumberOfControlPoints() << std::endl;
os << indent << "Maximum number of control points: " << this->GetMaximumNumberOfControlPoints() << std::endl;
os << indent << "Current number of control points: " << this->GetNumberOfControlPoints() << std::endl;
os << indent << "Control points:" << std::endl;
for ( unsigned int i = 0; i < this->GetNumberOfControlPoints(); ++i )
{
//os << indent.GetNextIndent() << i << ": " << m_ControlPoints->ElementAt( i ) << std::endl;
os << indent.GetNextIndent() << i << ": " << m_ControlPoints.at( i ) << std::endl;
}
os << indent << "Geometry:\n";
this->GetPlaneGeometry()->Print(os, indent.GetNextIndent());
}
unsigned short mitk::PlanarFigure::GetPolyLinesSize()
{
if ( !m_PolyLineUpToDate )
{
this->GeneratePolyLine();
m_PolyLineUpToDate = true;
}
return m_PolyLines.size();
}
unsigned short mitk::PlanarFigure::GetHelperPolyLinesSize()
{
return m_HelperPolyLines.size();
}
bool mitk::PlanarFigure::IsHelperToBePainted(unsigned int index)
{
return m_HelperPolyLinesToBePainted->GetElement( index );
}
bool mitk::PlanarFigure::ResetOnPointSelect()
{
return false;
}
void mitk::PlanarFigure::RemoveControlPoint( unsigned int index )
{
if ( index > m_ControlPoints.size() )
return;
if ( (m_ControlPoints.size() -1) < this->GetMinimumNumberOfControlPoints() )
return;
ControlPointListType::iterator iter;
iter = m_ControlPoints.begin() + index;
m_ControlPoints.erase( iter );
m_PolyLineUpToDate = false;
m_HelperLinesUpToDate = false;
m_FeaturesUpToDate = false;
--m_NumberOfControlPoints;
}
void mitk::PlanarFigure::RemoveLastControlPoint()
{
RemoveControlPoint( m_ControlPoints.size()-1 );
}
-void mitk::PlanarFigure::DeepCopy(Self::Pointer oldFigure)
-{
- //DeepCopy only same types of planar figures
- //Notice to get typeid polymorph you have to use the *operator
- if(typeid(*oldFigure) != typeid(*this))
- {
- itkExceptionMacro( << "DeepCopy(): Inconsistent type of source (" << typeid(*oldFigure).name() << ") and destination figure (" << typeid(*this).name() << ")!" );
- return;
- }
-
- m_ControlPoints.clear();
- this->ClearPolyLines();
- this->ClearHelperPolyLines();
-
- // clone base data members
- SetPropertyList(oldFigure->GetPropertyList()->Clone());
-
- /// deep copy members
- m_FigurePlaced = oldFigure->m_FigurePlaced;
- m_SelectedControlPoint = oldFigure->m_SelectedControlPoint;
- m_FeaturesMTime = oldFigure->m_FeaturesMTime;
- m_Features = oldFigure->m_Features;
- m_NumberOfControlPoints = oldFigure->m_NumberOfControlPoints;
-
- //copy geometry 2D of planar figure
- PlaneGeometry::Pointer affineGeometry = oldFigure->m_PlaneGeometry->Clone();
- SetPlaneGeometry(affineGeometry.GetPointer());
-
- for(unsigned long index=0; index < oldFigure->GetNumberOfControlPoints(); index++)
- {
- m_ControlPoints.push_back( oldFigure->GetControlPoint( index ));
- }
-
- //After setting the control points we can generate the polylines
- this->GeneratePolyLine();
-}
-
void mitk::PlanarFigure::SetNumberOfPolyLines( unsigned int numberOfPolyLines )
{
m_PolyLines.resize(numberOfPolyLines);
}
void mitk::PlanarFigure::SetNumberOfHelperPolyLines( unsigned int numberOfHerlperPolyLines )
{
m_HelperPolyLines.resize(numberOfHerlperPolyLines);
}
void mitk::PlanarFigure::AppendPointToPolyLine( unsigned int index, PolyLineElement element )
{
if ( index < m_PolyLines.size() )
{
- if(element.Index == -1)
- element.Index = m_PolyLines[index].size();
-
m_PolyLines[index].push_back(element);
m_PolyLineUpToDate = false;
}
else
{
MITK_ERROR << "Tried to add point to PolyLine " << index+1 << ", although only " << m_PolyLines.size() << " exists";
}
}
void mitk::PlanarFigure::AppendPointToHelperPolyLine( unsigned int index, PolyLineElement element )
{
if ( index < m_HelperPolyLines.size() )
{
- if(element.Index == -1)
- element.Index = m_HelperPolyLines[index].size();
-
m_HelperPolyLines[index].push_back(element);
m_HelperLinesUpToDate = false;
}
else
{
MITK_ERROR << "Tried to add point to HelperPolyLine " << index+1 << ", although only " << m_HelperPolyLines.size() << " exists";
}
}
-#ifdef __GNUC__
-# pragma GCC diagnostic error "-Wdeprecated-declarations"
-#elif __clang__
-# pragma clang diagnostic error "-Wdeprecated-declarations"
-#elif _MSC_VER
-# pragma warning (pop)
-#endif
-
bool mitk::PlanarFigure::Equals(const mitk::PlanarFigure& other) const
{
//check geometries
if ( this->GetPlaneGeometry() && other.GetPlaneGeometry() )
{
if( !Equal(*(this->GetPlaneGeometry()), *(other.GetPlaneGeometry()), mitk::eps, true))
{
return false;
}
}
else
{
MITK_ERROR << "Geometry is not equal";
return false;
}
//check isPlaced member
if ( this->m_FigurePlaced != other.m_FigurePlaced)
{
MITK_ERROR << "Is_Placed is not equal";
return false;
}
//check closed property
if (this->IsClosed() != other.IsClosed())
{
MITK_ERROR << "Is_closed is not equal";
return false;
}
//check poly lines
if (this->m_PolyLines.size() != other.m_PolyLines.size())
{
return false;
}
else
{
std::vector<PolyLineType>::const_iterator itThis = this->m_PolyLines.begin();
std::vector<PolyLineType>::const_iterator itEnd = this->m_PolyLines.end();
std::vector<PolyLineType>::const_iterator itOther = other.m_PolyLines.begin();
while( itThis != itEnd )
{
if(itThis->size() != itOther->size())
return false;
else
{
PolyLineType::const_iterator itLineThis = itThis->begin();
PolyLineType::const_iterator itLineEnd = itThis->end();
PolyLineType::const_iterator itLineOther = itOther->begin();
while(itLineThis != itLineEnd)
{
Point2D p1 = *itLineThis;
Point2D p2 = *itLineOther;
ScalarType delta = fabs(p1[0]-p2[0])+fabs(p1[1]-p2[1]);
if(delta > .001)
{
MITK_ERROR << "Poly line is not equal";
MITK_ERROR << p1 << "/" << p2;
return false;
}
++itLineThis;
++itLineOther;
}
}
++itThis;
++itOther;
}
}
//check features
if (this->GetNumberOfFeatures() != other.GetNumberOfFeatures())
{
MITK_ERROR << "Number of Features is Different";
return false;
}
else
{
std::vector<Feature>::const_iterator itThis = m_Features.begin();
std::vector<Feature>::const_iterator itEnd = m_Features.end();
std::vector<Feature>::const_iterator itOther = other.m_Features.begin();
while(itThis != itEnd)
{
if(( itThis->Quantity - itOther->Quantity) > .001 )
{
MITK_ERROR << "Quantity is Different" << itThis->Quantity << "/" << itOther->Quantity;
return false;
}
if( itThis->Unit.compare(itOther->Unit) != 0 )
{
MITK_ERROR << "Unit is Different" << itThis->Unit << "/" << itOther->Unit;
return false;
}
if( itThis->Name.compare(itOther->Name) != 0 )
{
MITK_ERROR << "Name of Measure is Different " << itThis->Name << "/ " << itOther->Name;;
return false;
}
++itThis;
++itOther;
}
}
return true;
}
bool mitk::Equal( const mitk::PlanarFigure& leftHandSide, const mitk::PlanarFigure& rightHandSide, ScalarType eps, bool verbose )
{
return leftHandSide.Equals(rightHandSide);
}
diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarFigure.h b/Modules/PlanarFigure/DataManagement/mitkPlanarFigure.h
index 08dcd0fa69..f274b8cb96 100644
--- a/Modules/PlanarFigure/DataManagement/mitkPlanarFigure.h
+++ b/Modules/PlanarFigure/DataManagement/mitkPlanarFigure.h
@@ -1,441 +1,406 @@
/*===================================================================
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 _MITK_PLANAR_FIGURE_H_
#define _MITK_PLANAR_FIGURE_H_
#include <MitkPlanarFigureExports.h>
#include "mitkBaseData.h"
#include "mitkCommon.h"
#include <deque>
namespace mitk
{
class PlaneGeometry;
/**
* \brief Base-class for geometric planar (2D) figures, such as
* lines, circles, rectangles, polygons, etc.
*
* \warning Currently does not support time-resolved data handling
*
* Behavior and appearance of PlanarFigures are controlled by various properties; for a detailed
* list of appearance properties see mitk::PlanarFigureMapper2D
*
* The following properties control general PlanarFigure behavior:
*
* <ul>
* <li>"selected": true if the planar figure is selected
* <li>"planarfigure.ishovering": true if the mouse "hovers" over the planar figure
* <li>"planarfigure.iseditable": true if the planar figure can be edited (otherwise,
* it can only be picked/selected, but its control points cannot be edited); default is true
* <li>"planarfigure.isextendable": true if new control points can be inserted into the list of control points;
* default is false
* </ul>
*
*
* TODO: Implement local 2D transform (including center of rotation...)
*
*/
class MitkPlanarFigure_EXPORT PlanarFigure : public BaseData
{
public:
mitkClassMacro( PlanarFigure, BaseData )
itkCloneMacro( Self )
- /** \brief Treat as Point2D by implicitly using conversion operators.
- *
- * \deprecatedSince{2014_10} "struct PolyLineElement {...};" will be changed to "typedef Point2D PolyLineElement;".
- */
- struct MitkPlanarFigure_EXPORT PolyLineElement
- {
- DEPRECATED(PolyLineElement(Point2D point, int index));
- PolyLineElement(const Point2D& point);
-
- PolyLineElement(const PolyLineElement &other);
- PolyLineElement& operator=(const PolyLineElement &other);
-
- operator Point2D&();
- operator const Point2D&() const;
-
- DEPRECATED(Point2D Point);
- DEPRECATED(int Index);
- };
+ typedef Point2D PolyLineElement;
typedef itk::VectorContainer< unsigned long, bool> BoolContainerType;
typedef std::deque< Point2D > ControlPointListType;
typedef std::vector< PolyLineElement > PolyLineType;
/** \brief Sets the 2D geometry on which this figure will be placed.
*
* In most cases, this is a Geometry already owned by another object, e.g.
* describing the slice of the image on which measurements will be
* performed.
*/
virtual void SetPlaneGeometry( mitk::PlaneGeometry *geometry );
- /**
- * \deprecatedSince{2014_10} Please use SetPlaneGeometry
- */
- DEPRECATED(void SetGeometry2D(PlaneGeometry* geo)){SetPlaneGeometry(geo);};
-
/** \brief Returns (previously set) 2D geometry of this figure. */
virtual const PlaneGeometry *GetPlaneGeometry() const;
- /**
- * \deprecatedSince{2014_10} Please use GetPlaneGeometry
- */
- DEPRECATED(const PlaneGeometry* GetGeometry2D()){return GetPlaneGeometry();};
-
/** \brief True if the planar figure is closed.
*
* Default is false. The "closed" boolean property must be set in sub-classes. */
virtual bool IsClosed() const;
/** \brief True if the planar figure has been placed (and can be
* displayed/interacted with). */
virtual bool IsPlaced() const { return m_FigurePlaced; };
/** \brief Place figure at the given point (in 2D index coordinates) onto
* the given 2D geometry.
*
* By default, the first two control points of the figure are set to the
* passed point. Further points can be set via AddControlPoint(), if the
* current number of control points is below the maximum number of control
* points.
*
* Can be re-implemented in sub-classes as needed.
*/
virtual void PlaceFigure( const Point2D& point );
/**
* \brief Adds / inserts new control-points
*
* This method adds a new control-point with the coordinates defined by point at the given index.
* If 'index' == -1 or index is greater than the number of control-points the new point is appended
* to the back of the list of control points.
* If a control-point already exists for 'index', an additional point is inserted at that position.
* It is not possible to add more points if the maximum number of control-points (GetMaximumNumberOfControlPoints())
* has been reached.
*/
virtual bool AddControlPoint( const Point2D& point, int index = -1 );
virtual bool SetControlPoint( unsigned int index, const Point2D& point, bool createIfDoesNotExist = false);
virtual bool SetCurrentControlPoint( const Point2D& point );
/** \brief Returns the current number of 2D control points defining this figure. */
unsigned int GetNumberOfControlPoints() const;
/** \brief Returns the minimum number of control points needed to represent
* this figure.
*
* Must be implemented in sub-classes.
*/
virtual unsigned int GetMinimumNumberOfControlPoints() const = 0;
/** \brief Returns the maximum number of control points allowed for
* this figure (e.g. 3 for triangles).
*
* Must be implemented in sub-classes.
*/
virtual unsigned int GetMaximumNumberOfControlPoints() const = 0;
/** \brief Selects currently active control points. */
virtual bool SelectControlPoint( unsigned int index );
/** \brief Deselect control point; no control point active. */
virtual bool DeselectControlPoint();
/** \brief Return currently selected control point. */
virtual int GetSelectedControlPoint() const { return m_SelectedControlPoint; }
/** \brief Returns specified control point in 2D world coordinates. */
Point2D GetControlPoint( unsigned int index ) const;
/** \brief Returns specified control point in world coordinates. */
Point3D GetWorldControlPoint( unsigned int index ) const;
/** \brief Returns the polyline representing the planar figure
* (for rendering, measurements, etc.). */
const PolyLineType GetPolyLine(unsigned int index);
/** \brief Returns the polyline representing the planar figure
* (for rendering, measurments, etc.). */
const PolyLineType GetPolyLine(unsigned int index) const;
/** \brief Returns the polyline that should be drawn the same size at every scale
* (for text, angles, etc.). */
const PolyLineType GetHelperPolyLine( unsigned int index, double mmPerDisplayUnit, unsigned int displayHeight );
/** \brief Sets the position of the PreviewControlPoint. Automatically sets it visible.*/
void SetPreviewControlPoint( const Point2D& point );
/** \brief Marks the PreviewControlPoint as invisible.*/
void ResetPreviewContolPoint();
/** \brief Returns whether or not the PreviewControlPoint is visible.*/
bool IsPreviewControlPointVisible();
/** \brief Returns the coordinates of the PreviewControlPoint. */
Point2D GetPreviewControlPoint();
/** \brief Returns the number of features available for this PlanarFigure
* (such as, radius, area, ...). */
virtual unsigned int GetNumberOfFeatures() const;
/** \brief Returns the name (identifier) of the specified features. */
const char *GetFeatureName( unsigned int index ) const;
/** \brief Returns the physical unit of the specified features. */
const char *GetFeatureUnit( unsigned int index ) const;
/** Returns quantity of the specified feature (e.g., length, radius,
* area, ... ) */
double GetQuantity( unsigned int index ) const;
/** \brief Returns true if the feature with the specified index exists and
* is active (an inactive feature may e.g. be the area of a non-closed
* polygon. */
bool IsFeatureActive( unsigned int index ) const;
/** \brief Returns true if the feature with the specified index exists and is set visible */
bool IsFeatureVisible( unsigned int index ) const;
/** \brief Defines if the feature with the specified index will be shown as an
* overlay in the RenderWindow */
void SetFeatureVisible( unsigned int index, bool visible );
/** \brief Calculates quantities of all features of this planar figure. */
virtual void EvaluateFeatures();
/** \brief Intherited from parent */
virtual void UpdateOutputInformation();
/** \brief Intherited from parent */
virtual void SetRequestedRegionToLargestPossibleRegion();
/** \brief Intherited from parent */
virtual bool RequestedRegionIsOutsideOfTheBufferedRegion();
/** \brief Intherited from parent */
virtual bool VerifyRequestedRegion();
/** \brief Intherited from parent */
virtual void SetRequestedRegion( const itk::DataObject *data);
/** \brief Returns the current number of polylines */
virtual unsigned short GetPolyLinesSize();
/** \brief Returns the current number of helperpolylines */
virtual unsigned short GetHelperPolyLinesSize();
/** \brief Returns whether a helper polyline should be painted or not */
virtual bool IsHelperToBePainted(unsigned int index);
/** \brief Returns true if the planar figure is reset to "add points" mode
* when a point is selected.
*
* Default return value is false. Subclasses can overwrite this method and
* execute any reset / initialization statements required. */
virtual bool ResetOnPointSelect();
/** \brief removes the point with the given index from the list of controlpoints. */
virtual void RemoveControlPoint( unsigned int index );
/** \brief Removes last control point */
virtual void RemoveLastControlPoint();
- /** \brief Copies contents and state of a figre provided as parameter to the current object.
- *
- * Requires a matching type of both figures.
- *
- * \note Deprecated, use Clone() instead.
- */
- DEPRECATED(void DeepCopy(Self::Pointer oldFigure));
-
/** \brief Allow sub-classes to apply constraints on control points.
*
* Sub-classes can define spatial constraints to certain control points by
* overwriting this method and returning a constrained point. By default,
* the points are constrained by the image bounds. */
virtual Point2D ApplyControlPointConstraints( unsigned int /*index*/, const Point2D& point );
/**
* \brief Compare two PlanarFigure objects
* Note: all subclasses have to implement the method on their own.
*/
virtual bool Equals(const mitk::PlanarFigure& other) const;
protected:
PlanarFigure();
virtual ~PlanarFigure();
PlanarFigure(const Self& other);
/** \brief Set the initial number of control points of the planar figure */
void ResetNumberOfControlPoints( int numberOfControlPoints );
/** Adds feature (e.g., circumference, radius, angle, ...) to feature vector
* of a planar figure object and returns integer ID for the feature element.
* Should be called in sub-class constructors. */
virtual unsigned int AddFeature( const char *featureName, const char *unitName );
/** Sets the name of the specified feature. INTERNAL METHOD. */
void SetFeatureName( unsigned int index, const char *featureName );
/** Sets the physical unit of the specified feature. INTERNAL METHOD. */
void SetFeatureUnit( unsigned int index, const char *unitName );
/** Sets quantity of the specified feature. INTERNAL METHOD. */
void SetQuantity( unsigned int index, double quantity );
/** Sets the specified feature as active. INTERAL METHOD. */
void ActivateFeature( unsigned int index );
/** Sets the specified feature as active. INTERAL METHOD. */
void DeactivateFeature( unsigned int index );
/** \brief Generates the poly-line representation of the planar figure.
* Must be implemented in sub-classes. */
virtual void GeneratePolyLine() = 0;
/** \brief Generates the poly-lines that should be drawn the same size regardless of zoom.
* Must be implemented in sub-classes. */
virtual void GenerateHelperPolyLine(double mmPerDisplayUnit, unsigned int displayHeight) = 0;
/** \brief Calculates quantities of all features of this planar figure.
* Must be implemented in sub-classes. */
virtual void EvaluateFeaturesInternal() = 0;
/** \brief Initializes the TimeGeometry describing the (time-resolved)
* geometry of this figure. Note that each time step holds one PlaneGeometry.
*/
virtual void InitializeTimeGeometry( unsigned int timeSteps = 1 );
/** \brief defines the number of PolyLines that will be available */
void SetNumberOfPolyLines( unsigned int numberOfPolyLines );
/** \brief Append a point to the PolyLine # index */
void AppendPointToPolyLine( unsigned int index, PolyLineElement element );
/** \brief clears the list of PolyLines. Call before re-calculating a new Polyline. */
void ClearPolyLines();
/** \brief defines the number of HelperPolyLines that will be available */
void SetNumberOfHelperPolyLines( unsigned int numberOfHelperPolyLines );
/** \brief Append a point to the HelperPolyLine # index */
void AppendPointToHelperPolyLine( unsigned int index, PolyLineElement element );
/** \brief clears the list of HelperPolyLines. Call before re-calculating a new HelperPolyline. */
void ClearHelperPolyLines();
virtual void PrintSelf( std::ostream& os, itk::Indent indent ) const;
ControlPointListType m_ControlPoints;
unsigned int m_NumberOfControlPoints;
// Currently selected control point; -1 means no point selected
int m_SelectedControlPoint;
std::vector<PolyLineType> m_PolyLines;
std::vector<PolyLineType> m_HelperPolyLines;
BoolContainerType::Pointer m_HelperPolyLinesToBePainted;
// this point is used to store the coordiantes an additional 'ControlPoint' that is rendered
// when the mouse cursor is above the figure (and not a control-point) and when the
// property 'planarfigure.isextendable' is set to true
Point2D m_PreviewControlPoint;
bool m_PreviewControlPointVisible;
bool m_FigurePlaced;
private:
// not implemented to prevent PlanarFigure::New() calls which would create an itk::Object.
static Pointer New();
struct Feature
{
Feature( const char *name, const char *unit )
: Name( name ), Unit( unit ), Quantity( 0.0 ), Active( true ), Visible( true )
{
}
std::string Name;
std::string Unit;
double Quantity;
bool Active;
bool Visible;
};
virtual itk::LightObject::Pointer InternalClone() const = 0;
PlaneGeometry *m_PlaneGeometry;
bool m_PolyLineUpToDate;
bool m_HelperLinesUpToDate;
bool m_FeaturesUpToDate;
// Vector of features available for this geometric figure
typedef std::vector< Feature > FeatureVectorType;
FeatureVectorType m_Features;
unsigned long m_FeaturesMTime;
// this pair is used to store the mmInDisplayUnits (m_DisplaySize.first) and the displayHeight (m_DisplaySize.second)
// that the helperPolyLines have been calculated for.
// It's used to determine whether or not GetHelperPolyLine() needs to recalculate the HelperPolyLines.
std::pair<double, unsigned int> m_DisplaySize;
};
MITK_CORE_EXPORT bool Equal( const mitk::PlanarFigure& leftHandSide, const mitk::PlanarFigure& rightHandSide, ScalarType eps, bool verbose );
} // namespace mitk
#endif //_MITK_PLANAR_FIGURE_H_
diff --git a/Modules/PlanarFigure/DataManagement/mitkPlanarSubdivisionPolygon.cpp b/Modules/PlanarFigure/DataManagement/mitkPlanarSubdivisionPolygon.cpp
index 2b63f2dffd..0ca442e346 100644
--- a/Modules/PlanarFigure/DataManagement/mitkPlanarSubdivisionPolygon.cpp
+++ b/Modules/PlanarFigure/DataManagement/mitkPlanarSubdivisionPolygon.cpp
@@ -1,149 +1,147 @@
/*===================================================================
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 "mitkPlanarSubdivisionPolygon.h"
#include "mitkPlaneGeometry.h"
#include "mitkProperties.h"
// stl related includes
#include <algorithm>
mitk::PlanarSubdivisionPolygon::PlanarSubdivisionPolygon():
m_TensionParameter(0.0625),
m_SubdivisionRounds(5)
{
// Polygon is subdivision (in contrast to parent class PlanarPolygon
this->SetProperty( "closed", mitk::BoolProperty::New( true ) );
this->SetProperty( "subdivision", mitk::BoolProperty::New( true ) );
// Other properties are inherited / already initialized by parent class PlanarPolygon
}
mitk::PlanarSubdivisionPolygon::~PlanarSubdivisionPolygon()
{
}
void mitk::PlanarSubdivisionPolygon::GeneratePolyLine()
{
this->ClearPolyLines();
ControlPointListType subdivisionPoints;
ControlPointListType newSubdivisionPoints;
subdivisionPoints.clear();
subdivisionPoints = m_ControlPoints;
if( m_ControlPoints.size() >= GetMinimumNumberOfControlPoints() )
{
for( unsigned int i=0; i < GetSubdivisionRounds(); i++ )
{
// Indices
unsigned int index, indexPrev, indexNext, indexNextNext;
unsigned int numberOfPoints = subdivisionPoints.size();
Point2D newPoint;
// Keep cycling our array indices forward until they wrap around at the end
for ( index = 0; index < numberOfPoints; ++index )
{
// Create new subdivision point according to formula
// p_new = (0.5 + tension) * (p_here + p_next) - tension * (p_prev + p_nextnext)
indexPrev = (numberOfPoints + index - 1) % numberOfPoints;
indexNext = (index + 1) % numberOfPoints;
indexNextNext = (index + 2) % numberOfPoints;
newPoint[0] = (0.5 + GetTensionParameter()) * (double)( subdivisionPoints[index][0] + subdivisionPoints[indexNext][0] )
- GetTensionParameter() * (double)( subdivisionPoints[indexPrev][0] + subdivisionPoints[indexNextNext][0]);
newPoint[1] = (0.5 + GetTensionParameter()) * (double)( subdivisionPoints[index][1] + subdivisionPoints[indexNext][1] )
- GetTensionParameter() * (double)( subdivisionPoints[indexPrev][1] + subdivisionPoints[indexNextNext][1]);
newSubdivisionPoints.push_back( newPoint );
}
ControlPointListType mergedSubdivisionPoints;
ControlPointListType::iterator it, itNew;
for ( it = subdivisionPoints.begin() , itNew = newSubdivisionPoints.begin();
it != subdivisionPoints.end();
++it, ++itNew )
{
mergedSubdivisionPoints.push_back( *it );
mergedSubdivisionPoints.push_back( *itNew );
}
subdivisionPoints = mergedSubdivisionPoints;
newSubdivisionPoints.clear();
}
}
bool isInitiallyPlaced = this->GetProperty("initiallyplaced");
unsigned int i;
ControlPointListType::iterator it;
for ( it = subdivisionPoints.begin(), i = 0;
it != subdivisionPoints.end();
++it, ++i )
{
// Determine the index of the control point FOLLOWING this poly-line element
// (this is needed by PlanarFigureInteractor to insert new points at the correct position,
// namely BEFORE the next control point)
unsigned int nextIndex;
if ( i == 0 )
{
// For the FIRST polyline point, use the index of the LAST control point
// (it will used to check if the mouse is near the very last polyline element)
nextIndex = m_ControlPoints.size() - 1;
}
else
{
// For all other polyline points, use the index of the control point succeeding it
// (for polyline points lying on control points, the index of the previous control point
// is used)
nextIndex = (((i - 1) >> this->GetSubdivisionRounds()) + 1) % m_ControlPoints.size();
if(!isInitiallyPlaced && nextIndex > m_ControlPoints.size()-2)
{
-
- PolyLineElement elem( m_ControlPoints[m_ControlPoints.size()-1], nextIndex );
- this->AppendPointToPolyLine( 0, elem );
+ this->AppendPointToPolyLine( 0, m_ControlPoints[m_ControlPoints.size()-1] );
break;
}
}
- PolyLineElement elem( *it, nextIndex );
- this->AppendPointToPolyLine( 0, elem );
+
+ this->AppendPointToPolyLine( 0, *it );
}
subdivisionPoints.clear();
}
bool mitk::PlanarSubdivisionPolygon::Equals(const mitk::PlanarFigure& other) const
{
const mitk::PlanarSubdivisionPolygon* otherSubDivPoly = dynamic_cast<const mitk::PlanarSubdivisionPolygon*>(&other);
if ( otherSubDivPoly )
{
if ( this->m_SubdivisionRounds != otherSubDivPoly->m_SubdivisionRounds)
return false;
if ( std::abs(this->m_TensionParameter - otherSubDivPoly->m_TensionParameter) > mitk::eps)
return false;
return Superclass::Equals(other);
}
else
{
return false;
}
}
diff --git a/Modules/PlanarFigure/Rendering/mitkPlanarFigureMapper2D.cpp b/Modules/PlanarFigure/Rendering/mitkPlanarFigureMapper2D.cpp
index 37a3838482..78a9213403 100644
--- a/Modules/PlanarFigure/Rendering/mitkPlanarFigureMapper2D.cpp
+++ b/Modules/PlanarFigure/Rendering/mitkPlanarFigureMapper2D.cpp
@@ -1,925 +1,925 @@
/*===================================================================
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 "mitkPlanarFigureMapper2D.h"
#include "mitkBaseRenderer.h"
#include "mitkPlaneGeometry.h"
#include "mitkColorProperty.h"
#include "mitkProperties.h"
#include "mitkGL.h"
#include "mitkVtkPropRenderer.h"
#define _USE_MATH_DEFINES
#include <math.h>
// offset which moves the planarfigures on top of the other content
// the crosshair is rendered into the z = 1 layer.
static const float PLANAR_OFFSET = 0.5f;
mitk::PlanarFigureMapper2D::PlanarFigureMapper2D()
: m_NodeModified(true)
, m_NodeModifiedObserverTag(0)
, m_NodeModifiedObserverAdded(false)
{
this->InitializeDefaultPlanarFigureProperties();
}
mitk::PlanarFigureMapper2D::~PlanarFigureMapper2D()
{
if ( m_NodeModifiedObserverAdded && GetDataNode() != NULL )
{
GetDataNode()->RemoveObserver( m_NodeModifiedObserverTag );
}
}
void mitk::PlanarFigureMapper2D::Paint( mitk::BaseRenderer *renderer )
{
bool visible = true;
GetDataNode()->GetVisibility(visible, renderer, "visible");
if ( !visible ) return;
// Get PlanarFigure from input
mitk::PlanarFigure *planarFigure = const_cast< mitk::PlanarFigure * >(
static_cast< const mitk::PlanarFigure * >( GetDataNode()->GetData() ) );
// Check if PlanarFigure has already been placed; otherwise, do nothing
if ( !planarFigure->IsPlaced() )
{
return;
}
// Get 2D geometry frame of PlanarFigure
mitk::PlaneGeometry *planarFigurePlaneGeometry =
dynamic_cast< PlaneGeometry * >( planarFigure->GetGeometry( 0 ) );
if ( planarFigurePlaneGeometry == NULL )
{
MITK_ERROR << "PlanarFigure does not have valid PlaneGeometry!";
return;
}
// Get current world 2D geometry from renderer
const mitk::PlaneGeometry *rendererPlaneGeometry = renderer->GetCurrentWorldPlaneGeometry();
// If the PlanarFigure geometry is a plane geometry, check if current
// world plane is parallel to and within the planar figure geometry bounds
// (otherwise, display nothing)
if ( (planarFigurePlaneGeometry != NULL) && (rendererPlaneGeometry != NULL) )
{
double planeThickness = planarFigurePlaneGeometry->GetExtentInMM( 2 );
if ( !planarFigurePlaneGeometry->IsParallel( rendererPlaneGeometry )
|| !(planarFigurePlaneGeometry->DistanceFromPlane(
rendererPlaneGeometry ) < planeThickness / 3.0) )
{
// Planes are not parallel or renderer plane is not within PlanarFigure
// geometry bounds --> exit
return;
}
}
else
{
// Plane is not valid (curved reformations are not possible yet)
return;
}
// Get display geometry
mitk::DisplayGeometry *displayGeometry = renderer->GetDisplayGeometry();
assert( displayGeometry != NULL );
// Apply visual appearance properties from the PropertyList
ApplyColorAndOpacityProperties( renderer );
// Enable line antialiasing
glEnable( GL_LINE_SMOOTH );
glHint( GL_LINE_SMOOTH_HINT, GL_NICEST );
glEnable(GL_DEPTH_TEST);
// Get properties from node (if present)
const mitk::DataNode* node=this->GetDataNode();
this->InitializePlanarFigurePropertiesFromDataNode( node );
PlanarFigureDisplayMode lineDisplayMode = PF_DEFAULT;
if ( m_IsSelected )
{
lineDisplayMode = PF_SELECTED;
}
else if ( m_IsHovering )
{
lineDisplayMode = PF_HOVER;
}
mitk::Point2D anchorPoint; anchorPoint[0] = 0; anchorPoint[1] = 1;
// render the actual lines of the PlanarFigure
RenderLines(lineDisplayMode, planarFigure, anchorPoint, planarFigurePlaneGeometry, rendererPlaneGeometry, displayGeometry);
// position-offset of the annotations, is set in RenderAnnotations() and
// used in RenderQuantities()
double annotationOffset = 0.0;
//Get Global Opacity
float globalOpacity = 1.0;
node->GetFloatProperty("opacity", globalOpacity);
// draw name near the anchor point (point located on the right)
std::string name = node->GetName();
if ( m_DrawName && !name.empty() )
{
RenderAnnotations(renderer, name, anchorPoint, globalOpacity, lineDisplayMode, annotationOffset);
}
// draw feature quantities (if requested) next to the anchor point,
// but under the name (that is where 'annotationOffset' is used)
if ( m_DrawQuantities )
{
RenderQuantities(planarFigure, renderer, anchorPoint, annotationOffset, globalOpacity, lineDisplayMode);
}
if ( m_DrawControlPoints )
{
// draw the control-points
RenderControlPoints(planarFigure, lineDisplayMode, planarFigurePlaneGeometry, rendererPlaneGeometry, displayGeometry);
}
glLineWidth( 1.0f );
}
void mitk::PlanarFigureMapper2D::PaintPolyLine(
mitk::PlanarFigure::PolyLineType vertices,
bool closed,
Point2D& anchorPoint,
const PlaneGeometry* planarFigurePlaneGeometry,
const PlaneGeometry* rendererPlaneGeometry,
const DisplayGeometry* displayGeometry)
{
mitk::Point2D rightMostPoint;
rightMostPoint.Fill( itk::NumericTraits<float>::min() );
// transform all vertices into Point2Ds in display-Coordinates and store them in vector
std::vector<mitk::Point2D> pointlist;
for ( PlanarFigure::PolyLineType::iterator iter = vertices.begin(); iter!=vertices.end(); iter++ )
{
// Draw this 2D point as OpenGL vertex
mitk::Point2D displayPoint;
this->TransformObjectToDisplay( *iter, displayPoint,
planarFigurePlaneGeometry, rendererPlaneGeometry, displayGeometry );
pointlist.push_back(displayPoint);
if ( displayPoint[0] > rightMostPoint[0] )
rightMostPoint = displayPoint;
}
// If the planarfigure is closed, we add the first control point again.
// Thus we can always use 'GL_LINE_STRIP' and get rid of strange flickering
// effect when using the MESA OpenGL library.
if ( closed )
{
mitk::Point2D displayPoint;
- this->TransformObjectToDisplay( vertices.begin()->Point, displayPoint,
+ this->TransformObjectToDisplay( vertices.begin()[0], displayPoint,
planarFigurePlaneGeometry, rendererPlaneGeometry, displayGeometry );
pointlist.push_back( displayPoint );
}
// now paint all the points in one run
std::vector<mitk::Point2D>::iterator pointIter;
glBegin( GL_LINE_STRIP );
for ( pointIter = pointlist.begin(); pointIter!=pointlist.end(); pointIter++ )
{
glVertex3f( (*pointIter)[0], (*pointIter)[1], PLANAR_OFFSET );
}
glEnd();
anchorPoint = rightMostPoint;
}
void mitk::PlanarFigureMapper2D::DrawMainLines(
mitk::PlanarFigure* figure,
Point2D& anchorPoint,
const PlaneGeometry* planarFigurePlaneGeometry,
const PlaneGeometry* rendererPlaneGeometry,
const DisplayGeometry* displayGeometry)
{
unsigned short numberOfPolyLines = figure->GetPolyLinesSize();
for ( unsigned short loop=0; loop<numberOfPolyLines ; ++loop )
{
PlanarFigure::PolyLineType polyline = figure->GetPolyLine(loop);
this->PaintPolyLine( polyline,
figure->IsClosed(),
anchorPoint, planarFigurePlaneGeometry,
rendererPlaneGeometry, displayGeometry );
}
}
void mitk::PlanarFigureMapper2D::DrawHelperLines(
mitk::PlanarFigure* figure,
Point2D& anchorPoint,
const PlaneGeometry* planarFigurePlaneGeometry,
const PlaneGeometry* rendererPlaneGeometry,
const DisplayGeometry* displayGeometry)
{
unsigned short numberOfHelperPolyLines = figure->GetHelperPolyLinesSize();
// Draw helper objects
for ( unsigned int loop=0; loop<numberOfHelperPolyLines; ++loop )
{
const mitk::PlanarFigure::PolyLineType helperPolyLine = figure->GetHelperPolyLine(loop,
displayGeometry->GetScaleFactorMMPerDisplayUnit(),
displayGeometry->GetDisplayHeight() );
// Check if the current helper objects is to be painted
if ( !figure->IsHelperToBePainted( loop ) )
{
continue;
}
// ... and once normally above the shadow.
this->PaintPolyLine( helperPolyLine, false,
anchorPoint, planarFigurePlaneGeometry,
rendererPlaneGeometry, displayGeometry );
}
}
void mitk::PlanarFigureMapper2D::TransformObjectToDisplay(
const mitk::Point2D &point2D,
mitk::Point2D &displayPoint,
const mitk::PlaneGeometry *objectGeometry,
const mitk::PlaneGeometry *rendererGeometry,
const mitk::DisplayGeometry *displayGeometry )
{
mitk::Point3D point3D;
// Map circle point from local 2D geometry into 3D world space
objectGeometry->Map( point2D, point3D );
// Project 3D world point onto display geometry
rendererGeometry->Map( point3D, displayPoint );
displayGeometry->WorldToDisplay( displayPoint, displayPoint );
}
void mitk::PlanarFigureMapper2D::DrawMarker(
const mitk::Point2D &point,
float* lineColor,
float lineOpacity,
float* markerColor,
float markerOpacity,
float lineWidth,
PlanarFigureControlPointStyleProperty::Shape shape,
const mitk::PlaneGeometry *objectGeometry,
const mitk::PlaneGeometry *rendererGeometry,
const mitk::DisplayGeometry *displayGeometry )
{
mitk::Point2D displayPoint;
if ( markerOpacity == 0 && lineOpacity == 0 )
return;
this->TransformObjectToDisplay(
point, displayPoint,
objectGeometry, rendererGeometry, displayGeometry );
glColor4f( markerColor[0], markerColor[1], markerColor[2], markerOpacity );
glLineWidth( lineWidth );
switch ( shape )
{
case PlanarFigureControlPointStyleProperty::Square:
default:
{
// Paint filled square
// Disable line antialiasing (does not look nice for squares)
glDisable( GL_LINE_SMOOTH );
if ( markerOpacity > 0 )
{
glRectf(
displayPoint[0] - 4, displayPoint[1] - 4,
displayPoint[0] + 4, displayPoint[1] + 4 );
}
// Paint outline
glColor4f( lineColor[0], lineColor[1], lineColor[2], lineOpacity );
glBegin( GL_LINE_LOOP );
glVertex3f( displayPoint[0] - 4, displayPoint[1] - 4, PLANAR_OFFSET );
glVertex3f( displayPoint[0] - 4, displayPoint[1] + 4, PLANAR_OFFSET );
glVertex3f( displayPoint[0] + 4, displayPoint[1] + 4, PLANAR_OFFSET );
glVertex3f( displayPoint[0] + 4, displayPoint[1] - 4, PLANAR_OFFSET );
glEnd();
break;
}
case PlanarFigureControlPointStyleProperty::Circle:
{
float radius = 4.0;
if ( markerOpacity > 0 )
{
// Paint filled circle
glBegin( GL_POLYGON );
for ( int angle = 0; angle < 8; ++angle )
{
float angleRad = angle * (float) 3.14159 / 4.0;
float x = displayPoint[0] + radius * (float)cos( angleRad );
float y = displayPoint[1] + radius * (float)sin( angleRad );
glVertex3f(x, y, PLANAR_OFFSET);
}
glEnd();
}
// Paint outline
glColor4f( lineColor[0], lineColor[1], lineColor[2], lineOpacity );
glBegin( GL_LINE_LOOP );
for ( int angle = 0; angle < 8; ++angle )
{
float angleRad = angle * (float) 3.14159 / 4.0;
float x = displayPoint[0] + radius * (float)cos( angleRad );
float y = displayPoint[1] + radius * (float)sin( angleRad );
glVertex3f(x, y, PLANAR_OFFSET);
}
glEnd();
break;
}
} // end switch
}
void mitk::PlanarFigureMapper2D::InitializeDefaultPlanarFigureProperties()
{
m_IsSelected = false;
m_IsHovering = false;
m_DrawOutline = false;
m_DrawQuantities = false;
m_DrawShadow = false;
m_DrawControlPoints = false;
m_DrawName = true;
m_DrawDashed = false;
m_DrawHelperDashed = false;
m_ShadowWidthFactor = 1.2;
m_LineWidth = 1.0;
m_OutlineWidth = 4.0;
m_HelperlineWidth = 2.0;
m_ControlPointShape = PlanarFigureControlPointStyleProperty::Square;
this->SetColorProperty( m_LineColor, PF_DEFAULT, 1.0, 1.0, 1.0 );
this->SetFloatProperty( m_LineOpacity, PF_DEFAULT, 1.0 );
this->SetColorProperty( m_OutlineColor, PF_DEFAULT, 0.0, 0.0, 1.0 );
this->SetFloatProperty( m_OutlineOpacity, PF_DEFAULT, 1.0 );
this->SetColorProperty( m_HelperlineColor, PF_DEFAULT, 0.4, 0.8, 0.2 );
this->SetFloatProperty( m_HelperlineOpacity, PF_DEFAULT, 0.4 );
this->SetColorProperty( m_MarkerlineColor, PF_DEFAULT, 1.0, 1.0, 1.0 );
this->SetFloatProperty( m_MarkerlineOpacity, PF_DEFAULT, 1.0 );
this->SetColorProperty( m_MarkerColor, PF_DEFAULT, 1.0, 1.0, 1.0 );
this->SetFloatProperty( m_MarkerOpacity, PF_DEFAULT, 0.0 );
this->SetColorProperty( m_LineColor, PF_HOVER, 1.0, 0.7, 0.0 );
this->SetFloatProperty( m_LineOpacity, PF_HOVER, 1.0 );
this->SetColorProperty( m_OutlineColor, PF_HOVER, 0.0, 0.0, 1.0 );
this->SetFloatProperty( m_OutlineOpacity, PF_HOVER, 1.0 );
this->SetColorProperty( m_HelperlineColor, PF_HOVER, 0.4, 0.8, 0.2 );
this->SetFloatProperty( m_HelperlineOpacity, PF_HOVER, 0.4 );
this->SetColorProperty( m_MarkerlineColor, PF_HOVER, 1.0, 1.0, 1.0 );
this->SetFloatProperty( m_MarkerlineOpacity, PF_HOVER, 1.0 );
this->SetColorProperty( m_MarkerColor, PF_HOVER, 1.0, 0.6, 0.0 );
this->SetFloatProperty( m_MarkerOpacity, PF_HOVER, 0.2 );
this->SetColorProperty( m_LineColor, PF_SELECTED, 1.0, 0.0, 0.0 );
this->SetFloatProperty( m_LineOpacity, PF_SELECTED, 1.0 );
this->SetColorProperty( m_OutlineColor, PF_SELECTED, 0.0, 0.0, 1.0 );
this->SetFloatProperty( m_OutlineOpacity, PF_SELECTED, 1.0 );
this->SetColorProperty( m_HelperlineColor, PF_SELECTED, 0.4, 0.8, 0.2 );
this->SetFloatProperty( m_HelperlineOpacity, PF_SELECTED, 0.4 );
this->SetColorProperty( m_MarkerlineColor, PF_SELECTED, 1.0, 1.0, 1.0 );
this->SetFloatProperty( m_MarkerlineOpacity, PF_SELECTED, 1.0 );
this->SetColorProperty( m_MarkerColor, PF_SELECTED, 1.0, 0.6, 0.0 );
this->SetFloatProperty( m_MarkerOpacity, PF_SELECTED, 1.0 );
}
void mitk::PlanarFigureMapper2D::InitializePlanarFigurePropertiesFromDataNode( const mitk::DataNode* node )
{
if ( node == NULL )
{
return;
}
// if we have not added an observer for ModifiedEvents on the DataNode,
// we add one now.
if ( !m_NodeModifiedObserverAdded )
{
itk::SimpleMemberCommand<mitk::PlanarFigureMapper2D>::Pointer nodeModifiedCommand = itk::SimpleMemberCommand<mitk::PlanarFigureMapper2D>::New();
nodeModifiedCommand->SetCallbackFunction(this, &mitk::PlanarFigureMapper2D::OnNodeModified);
m_NodeModifiedObserverTag = node->AddObserver(itk::ModifiedEvent(), nodeModifiedCommand);
m_NodeModifiedObserverAdded = true;
}
// If the DataNode has not been modified since the last execution of
// this method, we do not run it now.
if ( !m_NodeModified )
return;
// Mark the current properties as unmodified
m_NodeModified = false;
//Get Global Opacity
float globalOpacity = 1.0;
node->GetFloatProperty("opacity", globalOpacity);
node->GetBoolProperty( "selected", m_IsSelected );
node->GetBoolProperty( "planarfigure.ishovering", m_IsHovering );
node->GetBoolProperty( "planarfigure.drawoutline", m_DrawOutline );
node->GetBoolProperty( "planarfigure.drawshadow", m_DrawShadow );
node->GetBoolProperty( "planarfigure.drawquantities", m_DrawQuantities );
node->GetBoolProperty( "planarfigure.drawcontrolpoints", m_DrawControlPoints );
node->GetBoolProperty( "planarfigure.drawname", m_DrawName );
node->GetBoolProperty( "planarfigure.drawdashed", m_DrawDashed );
node->GetBoolProperty( "planarfigure.helperline.drawdashed", m_DrawHelperDashed );
node->GetFloatProperty( "planarfigure.line.width", m_LineWidth );
node->GetFloatProperty( "planarfigure.shadow.widthmodifier", m_ShadowWidthFactor );
node->GetFloatProperty( "planarfigure.outline.width", m_OutlineWidth );
node->GetFloatProperty( "planarfigure.helperline.width", m_HelperlineWidth );
PlanarFigureControlPointStyleProperty::Pointer styleProperty =
dynamic_cast< PlanarFigureControlPointStyleProperty* >( node->GetProperty( "planarfigure.controlpointshape" ) );
if ( styleProperty.IsNotNull() )
{
m_ControlPointShape = styleProperty->GetShape();
}
//Set default color and opacity
//If property "planarfigure.default.*.color" exists, then use that color. Otherwise global "color" property is used.
if( !node->GetColor( m_LineColor[PF_DEFAULT], NULL, "planarfigure.default.line.color"))
{
node->GetColor( m_LineColor[PF_DEFAULT], NULL, "color" );
}
node->GetFloatProperty( "planarfigure.default.line.opacity", m_LineOpacity[PF_DEFAULT] );
if( !node->GetColor( m_OutlineColor[PF_DEFAULT], NULL, "planarfigure.default.outline.color"))
{
node->GetColor( m_OutlineColor[PF_DEFAULT], NULL, "color" );
}
node->GetFloatProperty( "planarfigure.default.outline.opacity", m_OutlineOpacity[PF_DEFAULT] );
if( !node->GetColor( m_HelperlineColor[PF_DEFAULT], NULL, "planarfigure.default.helperline.color"))
{
node->GetColor( m_HelperlineColor[PF_DEFAULT], NULL, "color" );
}
node->GetFloatProperty( "planarfigure.default.helperline.opacity", m_HelperlineOpacity[PF_DEFAULT] );
node->GetColor( m_MarkerlineColor[PF_DEFAULT], NULL, "planarfigure.default.markerline.color" );
node->GetFloatProperty( "planarfigure.default.markerline.opacity", m_MarkerlineOpacity[PF_DEFAULT] );
node->GetColor( m_MarkerColor[PF_DEFAULT], NULL, "planarfigure.default.marker.color" );
node->GetFloatProperty( "planarfigure.default.marker.opacity", m_MarkerOpacity[PF_DEFAULT] );
//Set hover color and opacity
node->GetColor( m_LineColor[PF_HOVER], NULL, "planarfigure.hover.line.color" );
node->GetFloatProperty( "planarfigure.hover.line.opacity", m_LineOpacity[PF_HOVER] );
node->GetColor( m_OutlineColor[PF_HOVER], NULL, "planarfigure.hover.outline.color" );
node->GetFloatProperty( "planarfigure.hover.outline.opacity", m_OutlineOpacity[PF_HOVER] );
node->GetColor( m_HelperlineColor[PF_HOVER], NULL, "planarfigure.hover.helperline.color" );
node->GetFloatProperty( "planarfigure.hover.helperline.opacity", m_HelperlineOpacity[PF_HOVER] );
node->GetColor( m_MarkerlineColor[PF_HOVER], NULL, "planarfigure.hover.markerline.color" );
node->GetFloatProperty( "planarfigure.hover.markerline.opacity", m_MarkerlineOpacity[PF_HOVER] );
node->GetColor( m_MarkerColor[PF_HOVER], NULL, "planarfigure.hover.marker.color" );
node->GetFloatProperty( "planarfigure.hover.marker.opacity", m_MarkerOpacity[PF_HOVER] );
//Set selected color and opacity
node->GetColor( m_LineColor[PF_SELECTED], NULL, "planarfigure.selected.line.color" );
node->GetFloatProperty( "planarfigure.selected.line.opacity", m_LineOpacity[PF_SELECTED] );
node->GetColor( m_OutlineColor[PF_SELECTED], NULL, "planarfigure.selected.outline.color" );
node->GetFloatProperty( "planarfigure.selected.outline.opacity", m_OutlineOpacity[PF_SELECTED] );
node->GetColor( m_HelperlineColor[PF_SELECTED], NULL, "planarfigure.selected.helperline.color" );
node->GetFloatProperty( "planarfigure.selected.helperline.opacity", m_HelperlineOpacity[PF_SELECTED] );
node->GetColor( m_MarkerlineColor[PF_SELECTED], NULL, "planarfigure.selected.markerline.color" );
node->GetFloatProperty( "planarfigure.selected.markerline.opacity", m_MarkerlineOpacity[PF_SELECTED] );
node->GetColor( m_MarkerColor[PF_SELECTED], NULL, "planarfigure.selected.marker.color" );
node->GetFloatProperty( "planarfigure.selected.marker.opacity", m_MarkerOpacity[PF_SELECTED] );
//adapt opacity values to global "opacity" property
for( unsigned int i = 0; i < PF_COUNT; ++i )
{
m_LineOpacity[i] *= globalOpacity;
m_OutlineOpacity[i] *= globalOpacity;
m_HelperlineOpacity[i] *= globalOpacity;
m_MarkerlineOpacity[i] *= globalOpacity;
m_MarkerOpacity[i] *= globalOpacity;
}
}
void mitk::PlanarFigureMapper2D::OnNodeModified()
{
m_NodeModified = true;
}
void mitk::PlanarFigureMapper2D::SetDefaultProperties( mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite )
{
node->AddProperty( "visible", mitk::BoolProperty::New(true), renderer, overwrite );
//node->SetProperty("planarfigure.iseditable",mitk::BoolProperty::New(true));
node->AddProperty("planarfigure.isextendable",mitk::BoolProperty::New(false));
//node->AddProperty( "planarfigure.ishovering", mitk::BoolProperty::New(true) );
node->AddProperty( "planarfigure.drawoutline", mitk::BoolProperty::New(false) );
//node->AddProperty( "planarfigure.drawquantities", mitk::BoolProperty::New(true) );
node->AddProperty( "planarfigure.drawshadow", mitk::BoolProperty::New(true) );
node->AddProperty( "planarfigure.drawcontrolpoints", mitk::BoolProperty::New(true) );
node->AddProperty( "planarfigure.drawname", mitk::BoolProperty::New(true) );
node->AddProperty( "planarfigure.drawdashed", mitk::BoolProperty::New(false) );
node->AddProperty( "planarfigure.helperline.drawdashed", mitk::BoolProperty::New(false) );
node->AddProperty("planarfigure.line.width", mitk::FloatProperty::New(2.0) );
node->AddProperty("planarfigure.shadow.widthmodifier", mitk::FloatProperty::New(2.0) );
node->AddProperty("planarfigure.outline.width", mitk::FloatProperty::New(2.0) );
node->AddProperty("planarfigure.helperline.width", mitk::FloatProperty::New(1.0) );
node->AddProperty( "planarfigure.default.line.opacity", mitk::FloatProperty::New(1.0) );
node->AddProperty( "planarfigure.default.outline.opacity", mitk::FloatProperty::New(1.0) );
node->AddProperty( "planarfigure.default.helperline.opacity", mitk::FloatProperty::New(1.0) );
node->AddProperty( "planarfigure.default.markerline.color", mitk::ColorProperty::New(1.0,1.0,1.0) );
node->AddProperty( "planarfigure.default.markerline.opacity", mitk::FloatProperty::New(1.0) );
node->AddProperty( "planarfigure.default.marker.color", mitk::ColorProperty::New(1.0,1.0,1.0) );
node->AddProperty( "planarfigure.default.marker.opacity",mitk::FloatProperty::New(1.0) );
node->AddProperty( "planarfigure.hover.line.color", mitk::ColorProperty::New(0.0,1.0,0.0) );
node->AddProperty( "planarfigure.hover.line.opacity", mitk::FloatProperty::New(1.0) );
node->AddProperty( "planarfigure.hover.outline.color", mitk::ColorProperty::New(0.0,1.0,0.0) );
node->AddProperty( "planarfigure.hover.outline.opacity", mitk::FloatProperty::New(1.0) );
node->AddProperty( "planarfigure.hover.helperline.color", mitk::ColorProperty::New(0.0,1.0,0.0) );
node->AddProperty( "planarfigure.hover.helperline.opacity", mitk::FloatProperty::New(1.0) );
node->AddProperty( "planarfigure.hover.markerline.color", mitk::ColorProperty::New(0.0,1.0,0.0) );
node->AddProperty( "planarfigure.hover.markerline.opacity", mitk::FloatProperty::New(1.0) );
node->AddProperty( "planarfigure.hover.marker.color", mitk::ColorProperty::New(0.0,1.0,0.0) );
node->AddProperty( "planarfigure.hover.marker.opacity", mitk::FloatProperty::New(1.0) );
node->AddProperty( "planarfigure.selected.line.color", mitk::ColorProperty::New(1.0,0.0,0.0) );
node->AddProperty( "planarfigure.selected.line.opacity",mitk::FloatProperty::New(1.0) );
node->AddProperty( "planarfigure.selected.outline.color", mitk::ColorProperty::New(1.0,0.0,0.0) );
node->AddProperty( "planarfigure.selected.outline.opacity", mitk::FloatProperty::New(1.0));
node->AddProperty( "planarfigure.selected.helperline.color", mitk::ColorProperty::New(1.0,0.0,0.0) );
node->AddProperty( "planarfigure.selected.helperline.opacity",mitk::FloatProperty::New(1.0) );
node->AddProperty( "planarfigure.selected.markerline.color", mitk::ColorProperty::New(1.0,0.0,0.0) );
node->AddProperty( "planarfigure.selected.markerline.opacity", mitk::FloatProperty::New(1.0) );
node->AddProperty( "planarfigure.selected.marker.color", mitk::ColorProperty::New(1.0,0.0,0.0) );
node->AddProperty( "planarfigure.selected.marker.opacity",mitk::FloatProperty::New(1.0));
}
void mitk::PlanarFigureMapper2D::RenderControlPoints( mitk::PlanarFigure * planarFigure,
PlanarFigureDisplayMode lineDisplayMode,
mitk::PlaneGeometry * planarFigurePlaneGeometry,
const mitk::PlaneGeometry * rendererPlaneGeometry,
mitk::DisplayGeometry * displayGeometry )
{
bool isEditable = true;
m_DataNode->GetBoolProperty( "planarfigure.iseditable", isEditable );
PlanarFigureDisplayMode pointDisplayMode = PF_DEFAULT;
unsigned int selectedControlPointsIdx = (unsigned int) planarFigure->GetSelectedControlPoint();
unsigned int numberOfControlPoints = planarFigure->GetNumberOfControlPoints();
// Draw markers at control points (selected control point will be colored)
for ( unsigned int i = 0; i < numberOfControlPoints ; ++i )
{
// Only if planar figure is marked as editable: display markers (control points) in a
// different style if mouse is over them or they are selected
if ( isEditable )
{
if ( i == selectedControlPointsIdx )
{
pointDisplayMode = PF_SELECTED;
}
else if ( m_IsHovering && isEditable )
{
pointDisplayMode = PF_HOVER;
}
}
if ( m_MarkerOpacity[pointDisplayMode] == 0
&& m_MarkerlineOpacity[pointDisplayMode] == 0 )
{
continue;
}
if ( m_DrawOutline )
{
// draw outlines for markers as well
// linewidth for the contour is only half, as full width looks
// much too thick!
this->DrawMarker( planarFigure->GetControlPoint( i ),
m_OutlineColor[lineDisplayMode],
m_MarkerlineOpacity[pointDisplayMode],
m_OutlineColor[lineDisplayMode],
m_MarkerOpacity[pointDisplayMode],
m_OutlineWidth/2,
m_ControlPointShape,
planarFigurePlaneGeometry,
rendererPlaneGeometry,
displayGeometry );
}
this->DrawMarker( planarFigure->GetControlPoint( i ),
m_MarkerlineColor[pointDisplayMode],
m_MarkerlineOpacity[pointDisplayMode],
m_MarkerColor[pointDisplayMode],
m_MarkerOpacity[pointDisplayMode],
m_LineWidth,
m_ControlPointShape,
planarFigurePlaneGeometry,
rendererPlaneGeometry,
displayGeometry );
}
if ( planarFigure->IsPreviewControlPointVisible() )
{
this->DrawMarker( planarFigure->GetPreviewControlPoint(),
m_MarkerlineColor[PF_HOVER],
m_MarkerlineOpacity[PF_HOVER],
m_MarkerColor[PF_HOVER],
m_MarkerOpacity[PF_HOVER],
m_LineWidth,
m_ControlPointShape,
planarFigurePlaneGeometry,
rendererPlaneGeometry,
displayGeometry
);
}
}
void mitk::PlanarFigureMapper2D::RenderAnnotations( mitk::BaseRenderer * renderer,
std::string name,
mitk::Point2D anchorPoint,
float globalOpacity,
PlanarFigureDisplayMode lineDisplayMode,
double &annotationOffset )
{
mitk::VtkPropRenderer* openGLrenderer = dynamic_cast<mitk::VtkPropRenderer*>( renderer );
if ( openGLrenderer )
{
openGLrenderer->WriteSimpleText( name,
anchorPoint[0] + 6.0, anchorPoint[1] + 4.0,
0,
0,
0,
globalOpacity ); //this is a shadow
openGLrenderer->WriteSimpleText( name,
anchorPoint[0] + 5.0, anchorPoint[1] + 5.0,
m_LineColor[lineDisplayMode][0],
m_LineColor[lineDisplayMode][1],
m_LineColor[lineDisplayMode][2],
globalOpacity );
// If drawing is successful, add approximate height to annotation offset
annotationOffset -= 15.0;
}
}
void mitk::PlanarFigureMapper2D::RenderQuantities( mitk::PlanarFigure * planarFigure,
mitk::BaseRenderer * renderer,
mitk::Point2D anchorPoint,
double &annotationOffset,
float globalOpacity,
PlanarFigureDisplayMode lineDisplayMode )
{
std::stringstream quantityString;
quantityString.setf( ios::fixed, ios::floatfield );
quantityString.precision( 1 );
bool firstActiveFeature = true;
for ( unsigned int i = 0; i < planarFigure->GetNumberOfFeatures(); ++i )
{
if( planarFigure->IsFeatureActive(i) && planarFigure->IsFeatureVisible( i ) )
{
if ( ! firstActiveFeature )
{
quantityString << " x ";
}
quantityString << planarFigure->GetQuantity( i ) << " ";
quantityString << planarFigure->GetFeatureUnit( i );
firstActiveFeature = false;
}
}
mitk::VtkPropRenderer* openGLrenderer = dynamic_cast<mitk::VtkPropRenderer*>( renderer );
if ( openGLrenderer )
{
openGLrenderer->WriteSimpleText( quantityString.str().c_str(),
anchorPoint[0] + 6.0, anchorPoint[1] + 4.0 + annotationOffset,
0,
0,
0,
globalOpacity ); //this is a shadow
openGLrenderer->WriteSimpleText( quantityString.str().c_str(),
anchorPoint[0] + 5.0, anchorPoint[1] + 5.0 + annotationOffset,
m_LineColor[lineDisplayMode][0],
m_LineColor[lineDisplayMode][1],
m_LineColor[lineDisplayMode][2],
globalOpacity );
// If drawing is successful, add approximate height to annotation offset
annotationOffset -= 15.0;
}
}
void mitk::PlanarFigureMapper2D::RenderLines( PlanarFigureDisplayMode lineDisplayMode,
mitk::PlanarFigure * planarFigure,
mitk::Point2D &anchorPoint,
mitk::PlaneGeometry * planarFigurePlaneGeometry,
const mitk::PlaneGeometry * rendererPlaneGeometry,
mitk::DisplayGeometry * displayGeometry )
{
glLineStipple(1, 0x00FF);
// If we want to draw an outline, we do it here
if ( m_DrawOutline )
{
float* color = m_OutlineColor[lineDisplayMode];
float opacity = m_OutlineOpacity[lineDisplayMode];
// convert to a float array that also contains opacity, faster GL
float* colorVector = new float[4];
colorVector[0] = color[0];
colorVector[1] = color[1];
colorVector[2] = color[2];
colorVector[3] = opacity;
// set the color and opacity here as it is common for all outlines
glColor4fv( colorVector );
glLineWidth(m_OutlineWidth);
if (m_DrawDashed)
glEnable(GL_LINE_STIPPLE);
else
glDisable(GL_LINE_STIPPLE);
// Draw the outline for all polylines if requested
this->DrawMainLines( planarFigure,
anchorPoint,
planarFigurePlaneGeometry,
rendererPlaneGeometry,
displayGeometry );
glLineWidth( m_HelperlineWidth );
if (m_DrawHelperDashed)
glEnable(GL_LINE_STIPPLE);
else
glDisable(GL_LINE_STIPPLE);
// Draw the outline for all helper objects if requested
this->DrawHelperLines( planarFigure,
anchorPoint,
planarFigurePlaneGeometry,
rendererPlaneGeometry,
displayGeometry );
// cleanup
delete[] colorVector;
}
// If we want to draw a shadow, we do it here
if ( m_DrawShadow )
{
// determine the shadow opacity
float opacity = m_OutlineOpacity[lineDisplayMode];
float shadowOpacity = 0.0f;
if( opacity > 0.2f )
shadowOpacity = opacity - 0.2f;
// convert to a float array that also contains opacity, faster GL
float* shadow = new float[4];
shadow[0] = 0;
shadow[1] = 0;
shadow[2] = 0;
shadow[3] = shadowOpacity;
// set the color and opacity here as it is common for all shadows
glColor4fv( shadow );
glLineWidth( m_OutlineWidth * m_ShadowWidthFactor );
if (m_DrawDashed)
glEnable(GL_LINE_STIPPLE);
else
glDisable(GL_LINE_STIPPLE);
// Draw the outline for all polylines if requested
this->DrawMainLines( planarFigure,
anchorPoint,
planarFigurePlaneGeometry,
rendererPlaneGeometry,
displayGeometry );
glLineWidth( m_HelperlineWidth );
if (m_DrawHelperDashed)
glEnable(GL_LINE_STIPPLE);
else
glDisable(GL_LINE_STIPPLE);
// Draw the outline for all helper objects if requested
this->DrawHelperLines( planarFigure,
anchorPoint,
planarFigurePlaneGeometry,
rendererPlaneGeometry,
displayGeometry );
// cleanup
delete[] shadow;
}
// set this in brackets to avoid duplicate variables in the same scope
{
float* color = m_LineColor[lineDisplayMode];
float opacity = m_LineOpacity[lineDisplayMode];
// convert to a float array that also contains opacity, faster GL
float* colorVector = new float[4];
colorVector[0] = color[0];
colorVector[1] = color[1];
colorVector[2] = color[2];
colorVector[3] = opacity;
// set the color and opacity here as it is common for all mainlines
glColor4fv( colorVector );
glLineWidth( m_LineWidth );
if (m_DrawDashed)
glEnable(GL_LINE_STIPPLE);
else
glDisable(GL_LINE_STIPPLE);
// Draw the main line for all polylines
this->DrawMainLines( planarFigure,
anchorPoint,
planarFigurePlaneGeometry,
rendererPlaneGeometry,
displayGeometry );
float* helperColor = m_HelperlineColor[lineDisplayMode];
float helperOpacity = m_HelperlineOpacity[lineDisplayMode];
// convert to a float array that also contains opacity, faster GL
float* helperColorVector = new float[4];
helperColorVector[0] = helperColor[0];
helperColorVector[1] = helperColor[1];
helperColorVector[2] = helperColor[2];
helperColorVector[3] = helperOpacity;
// we only set the color for the helperlines as the linewidth is unchanged
glColor4fv( helperColorVector );
glLineWidth( m_HelperlineWidth );
if (m_DrawHelperDashed)
glEnable(GL_LINE_STIPPLE);
else
glDisable(GL_LINE_STIPPLE);
// Draw helper objects
this->DrawHelperLines( planarFigure,
anchorPoint,
planarFigurePlaneGeometry,
rendererPlaneGeometry,
displayGeometry );
// cleanup
delete[] colorVector;
delete[] helperColorVector;
}
if ( m_DrawDashed || m_DrawHelperDashed )
glDisable(GL_LINE_STIPPLE);
}
diff --git a/Modules/Python/CMakeLists.txt b/Modules/Python/CMakeLists.txt
index ec064837e1..3c96e67f95 100644
--- a/Modules/Python/CMakeLists.txt
+++ b/Modules/Python/CMakeLists.txt
@@ -1,26 +1,26 @@
if( MITK_USE_Python )
if(NOT MITK_USE_SYSTEM_PYTHON)
add_definitions( -DUSE_MITK_BUILTIN_PYTHON )
endif()
set(OpenCV_DEP )
if(MITK_USE_OpenCV)
set(OpenCV_DEP OpenCV)
endif()
# workaround until testing has a package depends
set(SimpleITK_DEP )
if(BUILD_TESTING AND NOT APPLE)
set(SimpleITK_DEP SimpleITK)
endif()
MITK_CREATE_MODULE(
DEPENDS MitkCore MitkQtWidgets
EXPORT_DEFINE MITK_PYTHON_EXPORT
- PACKAGE_DEPENDS Qt4|QtGui CTK|CTKScriptingPythonCore+CTKScriptingPythonWidgets PythonLibs VTK|vtkPython+vtkWrappingPythonCore Numpy ${SimpleITK_DEP} ${OpenCV_DEP}
+ PACKAGE_DEPENDS Qt4|QtGui Qt5|Widgets CTK|CTKScriptingPythonCore+CTKScriptingPythonWidgets PythonLibs VTK|vtkPython+vtkWrappingPythonCore Numpy ${SimpleITK_DEP} ${OpenCV_DEP}
)
configure_file(PythonPath.h.in "${CMAKE_CURRENT_BINARY_DIR}/PythonPath.h" @ONLY)
add_subdirectory(Testing)
endif()
diff --git a/Modules/Python/QmitkPythonVariableStackTableModel.cpp b/Modules/Python/QmitkPythonVariableStackTableModel.cpp
index 38ecedaf89..f213bf8641 100755
--- a/Modules/Python/QmitkPythonVariableStackTableModel.cpp
+++ b/Modules/Python/QmitkPythonVariableStackTableModel.cpp
@@ -1,225 +1,226 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "QmitkPythonVariableStackTableModel.h"
#include <QMimeData>
#include <usModuleContext.h>
#include <mitkDataNode.h>
#include <usGetModuleContext.h>
#include <QStringList>
#include <QMessageBox>
#include "QmitkMimeTypes.h"
const QString QmitkPythonVariableStackTableModel::MITK_IMAGE_VAR_NAME = "mitkImage";
const QString QmitkPythonVariableStackTableModel::MITK_SURFACE_VAR_NAME = "mitkSurface";
QmitkPythonVariableStackTableModel::QmitkPythonVariableStackTableModel(QObject *parent)
:QAbstractTableModel(parent)
{
us::ModuleContext* context = us::GetModuleContext();
m_PythonServiceRef = context->GetServiceReference<mitk::IPythonService>();
m_PythonService = context->GetService<mitk::IPythonService>(m_PythonServiceRef);
m_PythonService->AddPythonCommandObserver( this );
}
QmitkPythonVariableStackTableModel::~QmitkPythonVariableStackTableModel()
{
us::ModuleContext* context = us::GetModuleContext();
context->UngetService( m_PythonServiceRef );
m_PythonService->RemovePythonCommandObserver( this );
}
bool QmitkPythonVariableStackTableModel::dropMimeData ( const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent )
{
// Early exit, returning true, but not actually doing anything (ignoring data).
if (action == Qt::IgnoreAction)
return true;
// Note, we are returning true if we handled it, and false otherwise
bool returnValue = false;
if(data->hasFormat(QmitkMimeTypes::DataNodePtrs))
{
MITK_DEBUG("QmitkPythonVariableStackTableModel") << "dropped MITK DataNode";
returnValue = true;
int i = 0;
QList<mitk::DataNode*> dataNodeList = QmitkMimeTypes::ToDataNodePtrList(data);
mitk::DataNode* node = NULL;
foreach(node, dataNodeList)
{
mitk::Image* mitkImage = dynamic_cast<mitk::Image*>(node->GetData());
MITK_DEBUG("QmitkPythonVariableStackTableModel") << "mitkImage is not null " << (mitkImage != 0? "true": "false");
QRegExp rx("^\\d");
QString varName(node->GetName().c_str());
// regex replace every character that is not allowed in a python variable
varName = varName.replace(QRegExp("[.\\+\\-*\\s\\/\\n\\t\\r]"),QString("_"));
if( mitkImage )
{
if ( varName.isEmpty() )
varName = MITK_IMAGE_VAR_NAME;
if ( rx.indexIn(varName) == 0)
varName.prepend("_").prepend(MITK_IMAGE_VAR_NAME);
if( i > 0 )
varName = QString("%1%2").arg(varName).arg(i);
MITK_DEBUG("QmitkPythonVariableStackTableModel") << "varName" << varName.toStdString();
bool exportAsCvImage = mitkImage->GetDimension() == 2 && m_PythonService->IsOpenCvPythonWrappingAvailable();
if( exportAsCvImage )
{
int ret = QMessageBox::question(NULL, "Export option",
"2D image detected. Export as OpenCV image to Python instead of an SimpleITK image?",
QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
exportAsCvImage = ret == QMessageBox::Yes;
if(exportAsCvImage)
{
varName = MITK_IMAGE_VAR_NAME;
m_PythonService->CopyToPythonAsCvImage( mitkImage, varName.toStdString() );
++i;
}
}
if( !exportAsCvImage )
{
if( m_PythonService->IsSimpleItkPythonWrappingAvailable() )
{
m_PythonService->CopyToPythonAsSimpleItkImage( mitkImage, varName.toStdString() );
++i;
}
else
{
MITK_ERROR << "SimpleITK Python wrapping not available. Skipping export for image " << node->GetName();
}
}
}
else
{
mitk::Surface* surface = dynamic_cast<mitk::Surface*>(node->GetData());
MITK_DEBUG("QmitkPythonVariableStackTableModel") << "found surface";
if( surface )
{
if (varName.isEmpty() )
varName = MITK_SURFACE_VAR_NAME;
if ( rx.indexIn(varName) == 0)
varName.prepend("_").prepend(MITK_SURFACE_VAR_NAME);
MITK_DEBUG("QmitkPythonVariableStackTableModel") << "varName" << varName;
if( m_PythonService->IsVtkPythonWrappingAvailable() )
{
m_PythonService->CopyToPythonAsVtkPolyData( surface, varName.toStdString() );
}
else
{
MITK_ERROR << "VTK Python wrapping not available. Skipping export for surface " << node->GetName();
}
}
}
}
}
return returnValue;
}
QVariant QmitkPythonVariableStackTableModel::headerData(int section, Qt::Orientation orientation,
int role) const
{
QVariant headerData;
// show only horizontal header
if ( role == Qt::DisplayRole )
{
if( orientation == Qt::Horizontal )
{
// first column: "Attribute"
if(section == 0)
headerData = "Attribute";
else if(section == 1)
headerData = "Type";
else if(section == 2)
headerData = "Value";
}
}
return headerData;
}
Qt::ItemFlags QmitkPythonVariableStackTableModel::flags(const QModelIndex &index) const
{
Qt::ItemFlags flags = QAbstractItemModel::flags(index);
if(index.isValid())
return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | flags;
else
return Qt::ItemIsDropEnabled | flags;
}
int QmitkPythonVariableStackTableModel::rowCount(const QModelIndex &) const
{
return m_VariableStack.size();
}
int QmitkPythonVariableStackTableModel::columnCount(const QModelIndex &) const
{
return 3;
}
QVariant QmitkPythonVariableStackTableModel::data(const QModelIndex &index, int role) const
{
if (index.isValid() && !m_VariableStack.empty())
{
if(role == Qt::DisplayRole)
{
mitk::PythonVariable item = m_VariableStack.at(index.row());
if(index.column() == 0)
return QString::fromStdString(item.m_Name);
if(index.column() == 1)
return QString::fromStdString(item.m_Type);
if(index.column() == 2)
return QString::fromStdString(item.m_Value);
}
}
return QVariant();
}
QStringList QmitkPythonVariableStackTableModel::mimeTypes() const
{
return QAbstractTableModel::mimeTypes();
QStringList types;
types << "application/x-mitk-datanodes";
types << "application/x-qabstractitemmodeldatalist";
return types;
}
Qt::DropActions QmitkPythonVariableStackTableModel::supportedDropActions() const
{
return Qt::CopyAction | Qt::MoveAction;
}
void QmitkPythonVariableStackTableModel::CommandExecuted(const std::string& pythonCommand)
{
MITK_DEBUG("QmitkPythonVariableStackTableModel") << "command was executed " << pythonCommand;
m_VariableStack = m_PythonService->GetVariableStack();
- QAbstractTableModel::reset();
+ QAbstractTableModel::beginResetModel();
+ QAbstractTableModel::endResetModel();
}
std::vector<mitk::PythonVariable> QmitkPythonVariableStackTableModel::GetVariableStack() const
{
return m_VariableStack;
}
diff --git a/Modules/QtWidgets/CMakeLists.txt b/Modules/QtWidgets/CMakeLists.txt
index c55beb2393..408fe878c0 100644
--- a/Modules/QtWidgets/CMakeLists.txt
+++ b/Modules/QtWidgets/CMakeLists.txt
@@ -1,8 +1,8 @@
MITK_CREATE_MODULE(
DEPENDS MitkPlanarFigure MitkOverlays
- PACKAGE_DEPENDS VTK|vtkGUISupportQt Qt4|QtGui
+ PACKAGE_DEPENDS VTK|vtkGUISupportQt Qt4|QtGui Qt5|Widgets
SUBPROJECTS MITK-CoreUI
EXPORT_DEFINE QMITK_EXPORT
)
add_subdirectory(Testing)
diff --git a/Modules/QtWidgets/QmitkDataStorageListModel.cpp b/Modules/QtWidgets/QmitkDataStorageListModel.cpp
index fe19d6f41c..aff3248a25 100755
--- a/Modules/QtWidgets/QmitkDataStorageListModel.cpp
+++ b/Modules/QtWidgets/QmitkDataStorageListModel.cpp
@@ -1,273 +1,274 @@
/*===================================================================
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 "QmitkDataStorageListModel.h"
//# Own includes
// mitk
#include "mitkStringProperty.h"
//# Toolkit includes
// itk
#include "itkCommand.h"
QmitkDataStorageListModel::QmitkDataStorageListModel(mitk::DataStorage::Pointer dataStorage
, mitk::NodePredicateBase* pred, QObject* parent)
: QAbstractListModel(parent), m_NodePredicate(0), m_DataStorage(0), m_BlockEvents(false)
{
this->SetPredicate(pred);
this->SetDataStorage(dataStorage);
}
QmitkDataStorageListModel::~QmitkDataStorageListModel()
{
// set data storage to 0 so that event listener get removed
this->SetDataStorage(0);
if (m_NodePredicate) delete m_NodePredicate;
}
void QmitkDataStorageListModel::SetDataStorage(mitk::DataStorage::Pointer dataStorage)
{
if( m_DataStorage != dataStorage)
{
// remove old listeners
if(m_DataStorage != 0)
{
this->m_DataStorage->AddNodeEvent.RemoveListener( mitk::MessageDelegate1<QmitkDataStorageListModel
, const mitk::DataNode*>( this, &QmitkDataStorageListModel::NodeAdded ) );
this->m_DataStorage->RemoveNodeEvent.RemoveListener( mitk::MessageDelegate1<QmitkDataStorageListModel
, const mitk::DataNode*>( this, &QmitkDataStorageListModel::NodeRemoved ) );
// remove delete observer
m_DataStorage->RemoveObserver(m_DataStorageDeleteObserverTag);
// this is good coding style ! reset variables whenever they are not used anymore.
m_DataStorageDeleteObserverTag = 0;
}
m_DataStorage = dataStorage;
// remove event listeners
if(m_DataStorage != 0)
{
// subscribe for node added/removed events
this->m_DataStorage->AddNodeEvent.AddListener( mitk::MessageDelegate1<QmitkDataStorageListModel
, const mitk::DataNode*>( this, &QmitkDataStorageListModel::NodeAdded ) );
this->m_DataStorage->RemoveNodeEvent.AddListener( mitk::MessageDelegate1<QmitkDataStorageListModel
, const mitk::DataNode*>( this, &QmitkDataStorageListModel::NodeRemoved ) );
// add itk delete listener on datastorage
itk::MemberCommand<QmitkDataStorageListModel>::Pointer deleteCommand =
itk::MemberCommand<QmitkDataStorageListModel>::New();
deleteCommand->SetCallbackFunction(this, &QmitkDataStorageListModel::OnDelete);
// add observer
m_DataStorageDeleteObserverTag = m_DataStorage->AddObserver(itk::DeleteEvent(), deleteCommand);
}
// reset model
reset();
}
}
Qt::ItemFlags QmitkDataStorageListModel::flags(const QModelIndex&) const
{
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
QVariant QmitkDataStorageListModel::data(const QModelIndex& index, int role) const
{
if(index.isValid())
{
switch ( role )
{
case Qt::DisplayRole:
{
const mitk::DataNode* node = m_DataNodes.at(index.row());
std::string name = node->GetName();
return QVariant(QString::fromStdString(name));
}
break;
}
} // index.isValid()
return QVariant();
}
QVariant QmitkDataStorageListModel::headerData(int /*section*/, Qt::Orientation /*orientation*/, int /*role*/) const
{
return QVariant("Nodes");
}
int QmitkDataStorageListModel::rowCount(const QModelIndex& /*parent*/) const
{
return m_DataNodes.size();
}
std::vector<mitk::DataNode*> QmitkDataStorageListModel::GetDataNodes() const
{
return m_DataNodes;
}
mitk::DataStorage::Pointer QmitkDataStorageListModel::GetDataStorage() const
{
return m_DataStorage;
}
void QmitkDataStorageListModel::SetPredicate(mitk::NodePredicateBase* pred)
{
m_NodePredicate = pred;
reset();
- QAbstractListModel::reset();
+ QAbstractListModel::beginResetModel();
+ QAbstractListModel::endResetModel();
}
mitk::NodePredicateBase* QmitkDataStorageListModel::GetPredicate() const
{
return m_NodePredicate;
}
void QmitkDataStorageListModel::reset()
{
if(m_DataStorage != 0)
{
mitk::DataStorage::SetOfObjects::ConstPointer setOfObjects;
if (m_NodePredicate)
setOfObjects = m_DataStorage->GetSubset(m_NodePredicate);
else
setOfObjects = m_DataStorage->GetAll();
// remove all observes
unsigned int i = 0;
for(std::vector<mitk::DataNode*>::iterator it=m_DataNodes.begin()
; it!=m_DataNodes.end()
; ++it, ++i)
{
(*it)->RemoveObserver(m_DataNodesModifiedObserversTags[i]);
}
// clear vector with nodes
m_DataNodesModifiedObserversTags.clear();
m_DataNodes.clear();
itk::MemberCommand<QmitkDataStorageListModel>::Pointer modifiedCommand;
// copy all selected nodes the vector
for (mitk::DataStorage::SetOfObjects::ConstIterator nodeIt = setOfObjects->Begin()
; nodeIt != setOfObjects->End(); ++nodeIt, ++i) // for each node
{
// add modified observer
modifiedCommand = itk::MemberCommand<QmitkDataStorageListModel>::New();
modifiedCommand->SetCallbackFunction(this, &QmitkDataStorageListModel::OnModified);
m_DataNodesModifiedObserversTags.push_back( m_DataStorage->AddObserver(itk::ModifiedEvent(), modifiedCommand) );
m_DataNodes.push_back( nodeIt.Value().GetPointer());
} // for
} // m_DataStorage != 0
} // reset()
void QmitkDataStorageListModel::NodeAdded( const mitk::DataNode* node )
{
// garantuee no recursions when a new node event is thrown
if(!m_BlockEvents)
{
m_BlockEvents = true;
// check if node should be added to the model
bool addNode = true;
if(m_NodePredicate && !m_NodePredicate->CheckNode(node))
addNode = false;
if(addNode)
{
beginInsertRows(QModelIndex(), m_DataNodes.size(), m_DataNodes.size());
//reset();
m_DataNodes.push_back(const_cast<mitk::DataNode*>(node));
endInsertRows();
}
m_BlockEvents = false;
}
}
void QmitkDataStorageListModel::NodeRemoved( const mitk::DataNode* node )
{
// garantuee no recursions when a new node event is thrown
if(!m_BlockEvents)
{
m_BlockEvents = true;
int row = -1;
//bool removeNode = false;
// check if node is contained in current list, if yes: reset model
for (std::vector<mitk::DataNode*>::const_iterator nodeIt = m_DataNodes.begin()
; nodeIt != m_DataNodes.end(); nodeIt++) // for each node
{
row++;
if( (*nodeIt) == node )
{
// node found, remove it
beginRemoveRows(QModelIndex(), row, row);
m_DataNodes.erase(std::find(m_DataNodes.begin(), m_DataNodes.end(), (*nodeIt)));
endRemoveRows();
break;
}
}
m_BlockEvents = false;
}
}
void QmitkDataStorageListModel::OnModified( const itk::Object *caller, const itk::EventObject & /*event*/ )
{
if(m_BlockEvents) return;
const mitk::DataNode* modifiedNode = dynamic_cast<const mitk::DataNode*>(caller);
if(modifiedNode)
{
int row = std::distance(std::find(m_DataNodes.begin(), m_DataNodes.end(), modifiedNode), m_DataNodes.end());
QModelIndex indexOfChangedProperty = index(row, 1);
emit dataChanged(indexOfChangedProperty, indexOfChangedProperty);
}
}
void QmitkDataStorageListModel::OnDelete( const itk::Object *caller, const itk::EventObject & /*event*/ )
{
if(m_BlockEvents) return;
const mitk::DataStorage* dataStorage = dynamic_cast<const mitk::DataStorage*>(caller);
if(dataStorage)
{
// set datastorage to 0 -> empty model
this->SetDataStorage(0);
}
}
mitk::DataNode::Pointer QmitkDataStorageListModel::getNode( const QModelIndex &index ) const
{
mitk::DataNode::Pointer node;
if(index.isValid())
{
node = m_DataNodes.at(index.row());
}
return node;
}
diff --git a/Modules/QtWidgets/QmitkDataStorageTableModel.cpp b/Modules/QtWidgets/QmitkDataStorageTableModel.cpp
index dbedb4b827..648b893e8c 100644
--- a/Modules/QtWidgets/QmitkDataStorageTableModel.cpp
+++ b/Modules/QtWidgets/QmitkDataStorageTableModel.cpp
@@ -1,525 +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 "QmitkDataStorageTableModel.h"
//# Own includes
#include "mitkNodePredicateBase.h"
#include "mitkProperties.h"
#include "mitkRenderingManager.h"
#include "QmitkEnums.h"
#include "QmitkCustomVariants.h"
#include <QmitkNodeDescriptorManager.h>
//# Toolkit includes
#include <itkCommand.h>
#include <QIcon>
#include <QFile>
//#CTORS/DTOR
QmitkDataStorageTableModel::QmitkDataStorageTableModel(mitk::DataStorage::Pointer _DataStorage
, mitk::NodePredicateBase* _Predicate
, QObject* parent )
: QAbstractTableModel(parent)
, m_DataStorage(0)
, m_Predicate(0)
, m_BlockEvents(false)
, m_SortDescending(false)
{
this->SetPredicate(_Predicate);
this->SetDataStorage(_DataStorage);
}
QmitkDataStorageTableModel::~QmitkDataStorageTableModel()
{
// set data storage 0 to remove event listeners
this->SetDataStorage(0);
}
//# Public GETTER
const mitk::DataStorage::Pointer QmitkDataStorageTableModel::GetDataStorage() const
{
return m_DataStorage.GetPointer();
}
mitk::NodePredicateBase::Pointer QmitkDataStorageTableModel::GetPredicate() const
{
return m_Predicate;
}
mitk::DataNode::Pointer QmitkDataStorageTableModel::GetNode( const QModelIndex &index ) const
{
mitk::DataNode::Pointer node;
if(index.isValid())
{
node = m_NodeSet.at(index.row());
}
return node;
}
QVariant QmitkDataStorageTableModel::headerData(int section, Qt::Orientation orientation,
int role) const
{
QVariant headerData;
// show only horizontal header
if ( role == Qt::DisplayRole )
{
if( orientation == Qt::Horizontal )
{
// first column: "Name"
if(section == 0)
headerData = "Name";
else if(section == 1)
headerData = "Data Type";
else if(section == 2)
headerData = "Visibility";
}
else if( orientation == Qt::Vertical )
{
// show numbers for rows
headerData = section+1;
}
}
return headerData;
}
Qt::ItemFlags QmitkDataStorageTableModel::flags(const QModelIndex &index) const
{
Qt::ItemFlags flags = QAbstractItemModel::flags(index);
// name & visibility is editable
if (index.column() == 0)
{
flags |= Qt::ItemIsEditable;
}
else if (index.column() == 2)
{
flags |= Qt::ItemIsUserCheckable;
}
return flags;
}
int QmitkDataStorageTableModel::rowCount(const QModelIndex &) const
{
return m_NodeSet.size();
}
int QmitkDataStorageTableModel::columnCount(const QModelIndex &) const
{
// show name, type and visible columnn
int columns = 3;
return columns;
}
QVariant QmitkDataStorageTableModel::data(const QModelIndex &index, int role) const
{
QVariant data;
if (index.isValid() && !m_NodeSet.empty())
{
mitk::DataNode::Pointer node = m_NodeSet.at(index.row());
std::string nodeName = node->GetName();
if(nodeName.empty())
nodeName = "unnamed";
// get name
if(index.column() == 0)
{
// get name of node (may also be edited)
if (role == Qt::DisplayRole || role == Qt::EditRole)
{
data = QFile::encodeName(nodeName.c_str());
}
else if (role == QmitkDataNodeRole)
{
data = QVariant::fromValue(node);
}
}
else if (index.column() == 1)
{
QmitkNodeDescriptor* nodeDescriptor
= QmitkNodeDescriptorManager::GetInstance()->GetDescriptor(node);
// get type property of mitk::BaseData
if (role == Qt::DisplayRole)
{
data = nodeDescriptor->GetClassName();
}
// show some nice icons for datatype
else if(role == Qt::DecorationRole)
{
data = nodeDescriptor->GetIcon();
}
}
else if (index.column() == 2)
{
// get visible property of mitk::BaseData
bool visibility = false;
if(node->GetVisibility(visibility, 0) && role == Qt::CheckStateRole)
{
data = (visibility ? Qt::Checked : Qt::Unchecked);
} // node->GetVisibility(visibility, 0) && role == Qt::CheckStateRole
} // index.column() == 2
} // index.isValid() && !m_NodeSet.empty()
return data;
}
//# Public SETTERS
void QmitkDataStorageTableModel::SetPredicate( mitk::NodePredicateBase* _Predicate )
{
// ensure that a new predicate is set in order to avoid unnecessary changed events
if(m_Predicate != _Predicate)
{
m_Predicate = _Predicate;
this->Reset();
}
}
void QmitkDataStorageTableModel::SetDataStorage( mitk::DataStorage::Pointer _DataStorage )
{
// only proceed if we have a new datastorage
if(m_DataStorage.GetPointer() != _DataStorage.GetPointer())
{
// if a data storage was set before remove old event listeners
if(m_DataStorage.IsNotNull())
{
this->m_DataStorage->AddNodeEvent.RemoveListener( mitk::MessageDelegate1<QmitkDataStorageTableModel
, const mitk::DataNode*>( this, &QmitkDataStorageTableModel::AddNode ) );
this->m_DataStorage->RemoveNodeEvent.RemoveListener( mitk::MessageDelegate1<QmitkDataStorageTableModel
, const mitk::DataNode*>( this, &QmitkDataStorageTableModel::RemoveNode ) );
}
// set new data storage
m_DataStorage = _DataStorage.GetPointer();
// if new storage is not 0 subscribe for events
if(m_DataStorage.IsNotNull())
{
// subscribe for node added/removed events
this->m_DataStorage->AddNodeEvent.AddListener( mitk::MessageDelegate1<QmitkDataStorageTableModel
, const mitk::DataNode*>( this, &QmitkDataStorageTableModel::AddNode ) );
this->m_DataStorage->RemoveNodeEvent.AddListener( mitk::MessageDelegate1<QmitkDataStorageTableModel
, const mitk::DataNode*>( this, &QmitkDataStorageTableModel::RemoveNode ) );
}
// Reset model (even if datastorage is 0->will be checked in Reset())
this->Reset();
}
}
void QmitkDataStorageTableModel::AddNode( const mitk::DataNode* node )
{
// garantuee no recursions when a new node event is thrown
if(!m_BlockEvents)
{
// if we have a predicate, check node against predicate first
if(m_Predicate.IsNotNull() && !m_Predicate->CheckNode(node))
return;
// dont add nodes without data (formerly known as helper objects)
if(node->GetData() == 0)
return;
// create listener commands to listen to changes in the name or the visibility of the node
itk::MemberCommand<QmitkDataStorageTableModel>::Pointer propertyModifiedCommand
= itk::MemberCommand<QmitkDataStorageTableModel>::New();
propertyModifiedCommand->SetCallbackFunction(this, &QmitkDataStorageTableModel::PropertyModified);
mitk::BaseProperty* tempProperty = 0;
// add listener for properties
tempProperty = node->GetProperty("visible");
if(tempProperty)
m_VisiblePropertyModifiedObserverTags[tempProperty]
= tempProperty->AddObserver(itk::ModifiedEvent(), propertyModifiedCommand);
tempProperty = node->GetProperty("name");
if(tempProperty)
m_NamePropertyModifiedObserverTags[tempProperty]
= tempProperty->AddObserver(itk::ModifiedEvent(), propertyModifiedCommand);
// emit beginInsertRows event
beginInsertRows(QModelIndex(), m_NodeSet.size(), m_NodeSet.size());
// add node
m_NodeSet.push_back(const_cast<mitk::DataNode*>(node));
// emit endInsertRows event
endInsertRows();
}
}
void QmitkDataStorageTableModel::RemoveNode( const mitk::DataNode* node )
{
// garantuee no recursions when a new node event is thrown
if(!m_BlockEvents)
{
// find corresponding node
std::vector<mitk::DataNode*>::iterator nodeIt
= std::find(m_NodeSet.begin(), m_NodeSet.end(), node);
if(nodeIt != m_NodeSet.end())
{
// now: remove listeners for name property ...
mitk::BaseProperty* tempProperty = 0;
tempProperty = (*nodeIt)->GetProperty("visible");
if(tempProperty)
tempProperty->RemoveObserver(m_VisiblePropertyModifiedObserverTags[tempProperty]);
m_VisiblePropertyModifiedObserverTags.erase(tempProperty);
// ... and visibility property
tempProperty = (*nodeIt)->GetProperty("name");
if(tempProperty)
tempProperty->RemoveObserver(m_NamePropertyModifiedObserverTags[tempProperty]);
m_NamePropertyModifiedObserverTags.erase(tempProperty);
// get an index from iterator
int row = std::distance(m_NodeSet.begin(), nodeIt);
// emit beginRemoveRows event (QModelIndex is empty because we dont have a tree model)
this->beginRemoveRows(QModelIndex(), row, row);
// remove node
m_NodeSet.erase(nodeIt);
// emit endRemoveRows event
endRemoveRows();
}
}
}
void QmitkDataStorageTableModel::PropertyModified( const itk::Object *caller, const itk::EventObject & )
{
if(!m_BlockEvents)
{
// get modified property
const mitk::BaseProperty* modifiedProperty = dynamic_cast<const mitk::BaseProperty*>(caller);
if(modifiedProperty)
{
// find node that holds the modified property
int row = -1;
int column = -1;
std::vector<mitk::DataNode*>::iterator it;
mitk::BaseProperty* visibilityProperty = 0;
mitk::BaseProperty* nameProperty = 0;
// search for property that changed and emit datachanged on the corresponding ModelIndex
for(it=m_NodeSet.begin(); it!=m_NodeSet.end(); it++)
{
// check for the visible property or the name property
visibilityProperty = (*it)->GetProperty("visible");
if(modifiedProperty == visibilityProperty)
{
column = 2;
break;
}
nameProperty = (*it)->GetProperty("name");
if(modifiedProperty == nameProperty)
{
column = 0;
break;
}
}
// if we have the property we have a valid iterator
if( it != m_NodeSet.end() )
row = std::distance(m_NodeSet.begin(), it);
// now emit the dataChanged signal
QModelIndex indexOfChangedProperty = index(row, column);
emit dataChanged(indexOfChangedProperty, indexOfChangedProperty);
}
}
}
bool QmitkDataStorageTableModel::setData(const QModelIndex &index, const QVariant &value,
int role)
{
bool noErr = false;
if (index.isValid() && (role == Qt::EditRole || role == Qt::CheckStateRole))
{
// any change events produced here should not be caught in this class
// --> set m_BlockEvents to true
m_BlockEvents = true;
mitk::DataNode::Pointer node = m_NodeSet.at(index.row());
if(index.column() == 0)
{
node->SetStringProperty("name", value.toString().toStdString().c_str());
}
else if(index.column() == 2)
{
node->SetBoolProperty("visible", (value.toInt() == Qt::Checked ? true : false));
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
// inform listeners about changes
emit dataChanged(index, index);
m_BlockEvents = false;
noErr = true;
}
return noErr;
}
//#Protected SETTER
void QmitkDataStorageTableModel::Reset()
{
mitk::DataStorage::SetOfObjects::ConstPointer _NodeSet;
// remove all nodes now (dont use iterators because removing elements
// would invalidate the iterator)
// start at the last element: first in, last out
unsigned int i = m_NodeSet.size();
while(!m_NodeSet.empty())
{
--i;
this->RemoveNode(m_NodeSet.at(i));
}
// normally now everything should be empty->just to be sure
// erase all arrays again
m_NamePropertyModifiedObserverTags.clear();
m_VisiblePropertyModifiedObserverTags.clear();
m_NodeSet.clear();
// the whole reset depends on the fact if a data storage is set or not
if(m_DataStorage.IsNotNull())
{
if(m_Predicate.IsNotNull())
// get subset
_NodeSet = m_DataStorage->GetSubset(m_Predicate);
// if predicate is NULL, select all nodes
else
{
_NodeSet = m_DataStorage->GetAll();
// remove ghost root node
}
// finally add all nodes to the model
for(mitk::DataStorage::SetOfObjects::const_iterator it=_NodeSet->begin(); it!=_NodeSet->end()
; it++)
{
// save node
this->AddNode(*it);
}
}
}
void QmitkDataStorageTableModel::sort( int column, Qt::SortOrder order /*= Qt::AscendingOrder */ )
{
bool sortDescending = (order == Qt::DescendingOrder) ? true: false;
// do not sort twice !!! (dont know why, but qt calls this func twice. STUPID!)
/*
if(sortDescending != m_SortDescending)
{*/
//m_SortDescending = sortDescending;
DataNodeCompareFunction::CompareCriteria _CompareCriteria
= DataNodeCompareFunction::CompareByName;
DataNodeCompareFunction::CompareOperator _CompareOperator
= sortDescending ? DataNodeCompareFunction::Greater: DataNodeCompareFunction::Less;
if(column == 1)
_CompareCriteria = DataNodeCompareFunction::CompareByClassName;
else if(column == 2)
_CompareCriteria = DataNodeCompareFunction::CompareByVisibility;
DataNodeCompareFunction compareFunc(_CompareCriteria, _CompareOperator);
std::sort(m_NodeSet.begin(), m_NodeSet.end(), compareFunc);
- QAbstractTableModel::reset();
+ QAbstractTableModel::beginResetModel();
+ QAbstractTableModel::endResetModel();
//}
}
std::vector<mitk::DataNode*> QmitkDataStorageTableModel::GetNodeSet() const
{
return m_NodeSet;
}
QmitkDataStorageTableModel::DataNodeCompareFunction::DataNodeCompareFunction( CompareCriteria _CompareCriteria
, CompareOperator _CompareOperator )
: m_CompareCriteria(_CompareCriteria)
, m_CompareOperator(_CompareOperator)
{
}
bool QmitkDataStorageTableModel::DataNodeCompareFunction::operator()
( const mitk::DataNode::Pointer& _Left
, const mitk::DataNode::Pointer& _Right ) const
{
switch(m_CompareCriteria)
{
case CompareByClassName:
if(m_CompareOperator == Less)
return (_Left->GetData()->GetNameOfClass() < _Right->GetData()->GetNameOfClass() );
else
return (_Left->GetData()->GetNameOfClass() > _Right->GetData()->GetNameOfClass() );
break;
case CompareByVisibility:
{
bool _LeftVisibility = false;
bool _RightVisibility = false;
_Left->GetVisibility(_LeftVisibility, 0);
_Right->GetVisibility(_RightVisibility, 0);
if(m_CompareOperator == Less)
return (_LeftVisibility < _RightVisibility);
else
return (_LeftVisibility > _RightVisibility);
}
break;
// CompareByName:
default:
if(m_CompareOperator == Less)
return (_Left->GetName() < _Right->GetName());
else
return (_Left->GetName() > _Right->GetName());
break;
}
}
diff --git a/Modules/QtWidgets/QmitkDataStorageTreeModel.cpp b/Modules/QtWidgets/QmitkDataStorageTreeModel.cpp
index e5c540b57a..09be20d85c 100644
--- a/Modules/QtWidgets/QmitkDataStorageTreeModel.cpp
+++ b/Modules/QtWidgets/QmitkDataStorageTreeModel.cpp
@@ -1,858 +1,860 @@
/*===================================================================
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 <mitkStringProperty.h>
#include <mitkNodePredicateFirstLevel.h>
#include <mitkNodePredicateAnd.h>
#include <mitkNodePredicateData.h>
#include <mitkNodePredicateNot.h>
#include <mitkNodePredicateOr.h>
#include <mitkNodePredicateProperty.h>
#include <mitkPlanarFigure.h>
#include <mitkProperties.h>
#include <mitkRenderingManager.h>
#include "QmitkDataStorageTreeModel.h"
#include "QmitkNodeDescriptorManager.h"
#include <QmitkEnums.h>
#include <QmitkCustomVariants.h>
#include <QmitkMimeTypes.h>
#include <QIcon>
#include <QMimeData>
#include <QTextStream>
#include <QFile>
#include <map>
QmitkDataStorageTreeModel::QmitkDataStorageTreeModel( mitk::DataStorage* _DataStorage
, bool _PlaceNewNodesOnTop
, QObject* parent )
: QAbstractItemModel(parent)
, m_DataStorage(0)
, m_PlaceNewNodesOnTop(_PlaceNewNodesOnTop)
, m_Root(0)
{
this->SetDataStorage(_DataStorage);
}
QmitkDataStorageTreeModel::~QmitkDataStorageTreeModel()
{
// set data storage to 0 = remove all listeners
this->SetDataStorage(0);
m_Root->Delete(); m_Root = 0;
}
mitk::DataNode::Pointer QmitkDataStorageTreeModel::GetNode( const QModelIndex &index ) const
{
return this->TreeItemFromIndex(index)->GetDataNode();
}
const mitk::DataStorage::Pointer QmitkDataStorageTreeModel::GetDataStorage() const
{
return m_DataStorage.GetPointer();
}
QModelIndex QmitkDataStorageTreeModel::index( int row, int column, const QModelIndex & parent ) const
{
TreeItem* parentItem;
if (!parent.isValid())
parentItem = m_Root;
else
parentItem = static_cast<TreeItem*>(parent.internalPointer());
TreeItem *childItem = parentItem->GetChild(row);
if (childItem)
return createIndex(row, column, childItem);
else
return QModelIndex();
}
int QmitkDataStorageTreeModel::rowCount(const QModelIndex &parent) const
{
TreeItem *parentTreeItem = this->TreeItemFromIndex(parent);
return parentTreeItem->GetChildCount();
}
Qt::ItemFlags QmitkDataStorageTreeModel::flags( const QModelIndex& index ) const
{
mitk::DataNode* dataNode = this->TreeItemFromIndex(index)->GetDataNode();
if (index.isValid())
{
if(DicomPropertiesExists(*dataNode))
{
return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
}
return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable
| Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
}else{
return Qt::ItemIsDropEnabled;
}
}
int QmitkDataStorageTreeModel::columnCount( const QModelIndex& /* parent = QModelIndex() */ ) const
{
return 1;
}
QModelIndex QmitkDataStorageTreeModel::parent(const QModelIndex &index) const
{
if (!index.isValid())
return QModelIndex();
TreeItem *childItem = this->TreeItemFromIndex(index);
TreeItem *parentItem = childItem->GetParent();
if (parentItem == m_Root)
return QModelIndex();
return this->createIndex(parentItem->GetIndex(), 0, parentItem);
}
QmitkDataStorageTreeModel::TreeItem* QmitkDataStorageTreeModel::TreeItemFromIndex( const QModelIndex &index ) const
{
if (index.isValid())
return static_cast<TreeItem *>(index.internalPointer());
else
return m_Root;
}
Qt::DropActions QmitkDataStorageTreeModel::supportedDropActions() const
{
return Qt::CopyAction | Qt::MoveAction;
}
Qt::DropActions QmitkDataStorageTreeModel::supportedDragActions() const
{
return Qt::CopyAction | Qt::MoveAction;
}
bool QmitkDataStorageTreeModel::dropMimeData(const QMimeData *data,
Qt::DropAction action, int /*row*/, int /*column*/, const QModelIndex &parent)
{
// Early exit, returning true, but not actually doing anything (ignoring data).
if (action == Qt::IgnoreAction)
{
return true;
}
// Note, we are returning true if we handled it, and false otherwise
bool returnValue = false;
if(data->hasFormat("application/x-qabstractitemmodeldatalist"))
{
returnValue = true;
// First we extract a Qlist of TreeItem* pointers.
QList<TreeItem*> listOfItemsToDrop = ToTreeItemPtrList(data);
// Retrieve the TreeItem* where we are dropping stuff, and its parent.
TreeItem* dropItem = this->TreeItemFromIndex(parent);
TreeItem* parentItem = dropItem->GetParent();
// If item was dropped onto empty space, we select the root node
if(dropItem == m_Root)
{
parentItem = m_Root;
}
// Dragging and Dropping is only allowed within the same parent, so use the first item in list to validate.
// (otherwise, you could have a derived image such as a segmentation, and assign it to another image).
// NOTE: We are assuming the input list is valid... i.e. when it was dragged, all the items had the same parent.
if(listOfItemsToDrop[0] != dropItem && listOfItemsToDrop[0]->GetParent() == parentItem)
{
// Retrieve the index of where we are dropping stuff.
QModelIndex dropItemModelIndex = this->IndexFromTreeItem(dropItem);
QModelIndex parentModelIndex = this->IndexFromTreeItem(parentItem);
// Iterate through the list of TreeItem (which may be at non-consecutive indexes).
QList<TreeItem*>::iterator diIter;
for (diIter = listOfItemsToDrop.begin();
diIter != listOfItemsToDrop.end();
diIter++)
{
// Here we assume that as you remove items, one at a time, that GetIndex() will be valid.
this->beginRemoveRows(parentModelIndex, (*diIter)->GetIndex(), (*diIter)->GetIndex());
parentItem->RemoveChild(*diIter);
this->endRemoveRows();
}
// Select the target index position, or put it at the end of the list.
int dropIndex = dropItemModelIndex.row();
if (dropIndex == -1)
{
dropIndex = parentItem->GetChildCount();
}
// Now insert items again at the drop item position
this->beginInsertRows(parentModelIndex, dropIndex, dropIndex + listOfItemsToDrop.size() - 1);
for (diIter = listOfItemsToDrop.begin();
diIter != listOfItemsToDrop.end();
diIter++)
{
parentItem->InsertChild( (*diIter), dropIndex );
dropIndex++;
}
this->endInsertRows();
// Change Layers to match.
this->AdjustLayerProperty();
}
}
else if(data->hasFormat("application/x-mitk-datanodes"))
{
returnValue = true;
int numberOfNodesDropped = 0;
QList<mitk::DataNode*> dataNodeList = QmitkMimeTypes::ToDataNodePtrList(data);
mitk::DataNode* node = NULL;
foreach(node, dataNodeList)
{
if(node && m_DataStorage.IsNotNull() && !m_DataStorage->Exists(node))
{
m_DataStorage->Add( node );
mitk::BaseData::Pointer basedata = node->GetData();
if (basedata.IsNotNull())
{
mitk::RenderingManager::GetInstance()->InitializeViews(
basedata->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true );
numberOfNodesDropped++;
}
}
}
// Only do a rendering update, if we actually dropped anything.
if (numberOfNodesDropped > 0)
{
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
return returnValue;
}
QStringList QmitkDataStorageTreeModel::mimeTypes() const
{
QStringList types = QAbstractItemModel::mimeTypes();
types << "application/x-qabstractitemmodeldatalist";
types << "application/x-mitk-datanodes";
return types;
}
QMimeData * QmitkDataStorageTreeModel::mimeData(const QModelIndexList & indexes) const
{
return mimeDataFromModelIndexList(indexes);
}
QMimeData *QmitkDataStorageTreeModel::mimeDataFromModelIndexList(const QModelIndexList &indexes)
{
QMimeData * ret = new QMimeData;
QString treeItemAddresses("");
QString dataNodeAddresses("");
QByteArray baTreeItemPtrs;
QByteArray baDataNodePtrs;
QDataStream dsTreeItemPtrs(&baTreeItemPtrs, QIODevice::WriteOnly);
QDataStream dsDataNodePtrs(&baDataNodePtrs, QIODevice::WriteOnly);
for (int i = 0; i < indexes.size(); i++)
{
TreeItem* treeItem = static_cast<TreeItem*>(indexes.at(i).internalPointer());
dsTreeItemPtrs << reinterpret_cast<quintptr>(treeItem);
dsDataNodePtrs << reinterpret_cast<quintptr>(treeItem->GetDataNode().GetPointer());
// --------------- deprecated -----------------
unsigned long long treeItemAddress = reinterpret_cast<unsigned long long>(treeItem);
unsigned long long dataNodeAddress = reinterpret_cast<unsigned long long>(treeItem->GetDataNode().GetPointer());
QTextStream(&treeItemAddresses) << treeItemAddress;
QTextStream(&dataNodeAddresses) << dataNodeAddress;
if (i != indexes.size() - 1)
{
QTextStream(&treeItemAddresses) << ",";
QTextStream(&dataNodeAddresses) << ",";
}
// -------------- end deprecated -------------
}
// ------------------ deprecated -----------------
- ret->setData("application/x-qabstractitemmodeldatalist", QByteArray(treeItemAddresses.toAscii()));
- ret->setData("application/x-mitk-datanodes", QByteArray(dataNodeAddresses.toAscii()));
+ ret->setData("application/x-qabstractitemmodeldatalist", QByteArray(treeItemAddresses.toLatin1()));
+ ret->setData("application/x-mitk-datanodes", QByteArray(dataNodeAddresses.toLatin1()));
// --------------- end deprecated -----------------
ret->setData(QmitkMimeTypes::DataStorageTreeItemPtrs, baTreeItemPtrs);
ret->setData(QmitkMimeTypes::DataNodePtrs, baDataNodePtrs);
return ret;
}
QVariant QmitkDataStorageTreeModel::data( const QModelIndex & index, int role ) const
{
mitk::DataNode* dataNode = this->TreeItemFromIndex(index)->GetDataNode();
// get name of treeItem (may also be edited)
QString nodeName;
if(DicomPropertiesExists(*dataNode))
{
mitk::BaseProperty* seriesDescription = (dataNode->GetProperty("dicom.series.SeriesDescription"));
mitk::BaseProperty* studyDescription = (dataNode->GetProperty("dicom.study.StudyDescription"));
mitk::BaseProperty* patientsName = (dataNode->GetProperty("dicom.patient.PatientsName"));
nodeName += QFile::encodeName(patientsName->GetValueAsString().c_str()) + "\n";
nodeName += QFile::encodeName(studyDescription->GetValueAsString().c_str()) + "\n";
nodeName += QFile::encodeName(seriesDescription->GetValueAsString().c_str());
}
else
{
nodeName = QFile::encodeName(dataNode->GetName().c_str());
}
if(nodeName.isEmpty())
{
nodeName = "unnamed";
}
if (role == Qt::DisplayRole)
return nodeName;
else if(role == Qt::ToolTipRole)
return nodeName;
else if(role == Qt::DecorationRole)
{
QmitkNodeDescriptor* nodeDescriptor
= QmitkNodeDescriptorManager::GetInstance()->GetDescriptor(dataNode);
return nodeDescriptor->GetIcon();
}
else if(role == Qt::CheckStateRole)
{
return dataNode->IsVisible(0);
}
else if(role == QmitkDataNodeRole)
{
return QVariant::fromValue<mitk::DataNode::Pointer>(mitk::DataNode::Pointer(dataNode));
}
else if(role == QmitkDataNodeRawPointerRole)
{
return QVariant::fromValue<mitk::DataNode*>(dataNode);
}
return QVariant();
}
bool QmitkDataStorageTreeModel::DicomPropertiesExists(const mitk::DataNode& node) const
{
bool propertiesExists = false;
mitk::BaseProperty* seriesDescription = (node.GetProperty("dicom.series.SeriesDescription"));
mitk::BaseProperty* studyDescription = (node.GetProperty("dicom.study.StudyDescription"));
mitk::BaseProperty* patientsName = (node.GetProperty("dicom.patient.PatientsName"));
if(patientsName!=NULL && studyDescription!=NULL && seriesDescription!=NULL)
{
if((!patientsName->GetValueAsString().empty())&&
(!studyDescription->GetValueAsString().empty())&&
(!seriesDescription->GetValueAsString().empty()))
{
propertiesExists = true;
}
}
return propertiesExists;
}
QVariant QmitkDataStorageTreeModel::headerData(int /*section*/,
Qt::Orientation orientation,
int role) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole && m_Root)
return QString::fromStdString(m_Root->GetDataNode()->GetName());
return QVariant();
}
void QmitkDataStorageTreeModel::SetDataStorage( mitk::DataStorage* _DataStorage )
{
if(m_DataStorage != _DataStorage) // dont take the same again
{
if(m_DataStorage.IsNotNull())
{
// remove Listener for the data storage itself
m_DataStorage.ObjectDelete.RemoveListener( mitk::MessageDelegate1<QmitkDataStorageTreeModel
, const itk::Object*>( this, &QmitkDataStorageTreeModel::SetDataStorageDeleted ) );
// remove listeners for the nodes
m_DataStorage->AddNodeEvent.RemoveListener( mitk::MessageDelegate1<QmitkDataStorageTreeModel
, const mitk::DataNode*>( this, &QmitkDataStorageTreeModel::AddNode ) );
m_DataStorage->ChangedNodeEvent.RemoveListener( mitk::MessageDelegate1<QmitkDataStorageTreeModel
, const mitk::DataNode*>( this, &QmitkDataStorageTreeModel::SetNodeModified ) );
m_DataStorage->RemoveNodeEvent.RemoveListener( mitk::MessageDelegate1<QmitkDataStorageTreeModel
, const mitk::DataNode*>( this, &QmitkDataStorageTreeModel::RemoveNode ) );
}
// take over the new data storage
m_DataStorage = _DataStorage;
// delete the old root (if necessary, create new)
if(m_Root)
m_Root->Delete();
mitk::DataNode::Pointer rootDataNode = mitk::DataNode::New();
rootDataNode->SetName("Data Manager");
m_Root = new TreeItem(rootDataNode, 0);
- this->reset();
+ this->beginResetModel();
+ this->endResetModel();
if(m_DataStorage.IsNotNull())
{
// add Listener for the data storage itself
m_DataStorage.ObjectDelete.AddListener( mitk::MessageDelegate1<QmitkDataStorageTreeModel
, const itk::Object*>( this, &QmitkDataStorageTreeModel::SetDataStorageDeleted ) );
// add listeners for the nodes
m_DataStorage->AddNodeEvent.AddListener( mitk::MessageDelegate1<QmitkDataStorageTreeModel
, const mitk::DataNode*>( this, &QmitkDataStorageTreeModel::AddNode ) );
m_DataStorage->ChangedNodeEvent.AddListener( mitk::MessageDelegate1<QmitkDataStorageTreeModel
, const mitk::DataNode*>( this, &QmitkDataStorageTreeModel::SetNodeModified ) );
m_DataStorage->RemoveNodeEvent.AddListener( mitk::MessageDelegate1<QmitkDataStorageTreeModel
, const mitk::DataNode*>( this, &QmitkDataStorageTreeModel::RemoveNode ) );
mitk::DataStorage::SetOfObjects::ConstPointer _NodeSet = m_DataStorage->GetSubset(m_Predicate);
// finally add all nodes to the model
this->Update();
}
}
}
void QmitkDataStorageTreeModel::SetDataStorageDeleted( const itk::Object* /*_DataStorage*/ )
{
this->SetDataStorage(0);
}
void QmitkDataStorageTreeModel::AddNodeInternal(const mitk::DataNode *node)
{
if(node == 0
|| m_DataStorage.IsNull()
|| !m_DataStorage->Exists(node)
|| m_Root->Find(node) != 0)
return;
// find out if we have a root node
TreeItem* parentTreeItem = m_Root;
QModelIndex index;
mitk::DataNode* parentDataNode = this->GetParentNode(node);
if(parentDataNode) // no top level data node
{
parentTreeItem = m_Root->Find(parentDataNode); // find the corresponding tree item
if(!parentTreeItem)
{
this->AddNode(parentDataNode);
parentTreeItem = m_Root->Find(parentDataNode);
if(!parentTreeItem)
return;
}
// get the index of this parent with the help of the grand parent
index = this->createIndex(parentTreeItem->GetIndex(), 0, parentTreeItem);
}
// add node
if(m_PlaceNewNodesOnTop)
{
// emit beginInsertRows event
beginInsertRows(index, 0, 0);
parentTreeItem->InsertChild(new TreeItem(
const_cast<mitk::DataNode*>(node)), 0);
}
else
{
beginInsertRows(index, parentTreeItem->GetChildCount()
, parentTreeItem->GetChildCount());
new TreeItem(const_cast<mitk::DataNode*>(node), parentTreeItem);
}
// emit endInsertRows event
endInsertRows();
this->AdjustLayerProperty();
}
void QmitkDataStorageTreeModel::AddNode( const mitk::DataNode* node )
{
if(node == 0
|| m_DataStorage.IsNull()
|| !m_DataStorage->Exists(node)
|| m_Root->Find(node) != 0)
return;
this->AddNodeInternal(node);
}
void QmitkDataStorageTreeModel::SetPlaceNewNodesOnTop(bool _PlaceNewNodesOnTop)
{
m_PlaceNewNodesOnTop = _PlaceNewNodesOnTop;
}
void QmitkDataStorageTreeModel::RemoveNodeInternal( const mitk::DataNode* node )
{
if(!m_Root) return;
TreeItem* treeItem = m_Root->Find(node);
if(!treeItem)
return; // return because there is no treeitem containing this node
TreeItem* parentTreeItem = treeItem->GetParent();
QModelIndex parentIndex = this->IndexFromTreeItem(parentTreeItem);
// emit beginRemoveRows event (QModelIndex is empty because we dont have a tree model)
this->beginRemoveRows(parentIndex, treeItem->GetIndex(), treeItem->GetIndex());
// remove node
std::vector<TreeItem*> children = treeItem->GetChildren();
delete treeItem;
// emit endRemoveRows event
endRemoveRows();
// move all children of deleted node into its parent
for ( std::vector<TreeItem*>::iterator it = children.begin()
; it != children.end(); it++)
{
// emit beginInsertRows event
beginInsertRows(parentIndex, parentTreeItem->GetChildCount(), parentTreeItem->GetChildCount());
// add nodes again
parentTreeItem->AddChild(*it);
// emit endInsertRows event
endInsertRows();
}
this->AdjustLayerProperty();
}
void QmitkDataStorageTreeModel::RemoveNode( const mitk::DataNode* node )
{
if (node == 0)
return;
this->RemoveNodeInternal(node);
}
void QmitkDataStorageTreeModel::SetNodeModified( const mitk::DataNode* node )
{
TreeItem* treeItem = m_Root->Find(node);
if(treeItem) {
TreeItem* parentTreeItem = treeItem->GetParent();
// as the root node should not be removed one should always have a parent item
if(!parentTreeItem)
return;
QModelIndex index = this->createIndex(treeItem->GetIndex(), 0, treeItem);
// now emit the dataChanged signal
emit dataChanged(index, index);
}
}
mitk::DataNode* QmitkDataStorageTreeModel::GetParentNode( const mitk::DataNode* node ) const
{
mitk::DataNode* dataNode = 0;
mitk::DataStorage::SetOfObjects::ConstPointer _Sources = m_DataStorage->GetSources(node);
if(_Sources->Size() > 0)
dataNode = _Sources->front();
return dataNode;
}
bool QmitkDataStorageTreeModel::setData( const QModelIndex &index, const QVariant &value, int role )
{
mitk::DataNode* dataNode = this->TreeItemFromIndex(index)->GetDataNode();
if(!dataNode)
return false;
if(role == Qt::EditRole && !value.toString().isEmpty())
{
dataNode->SetStringProperty("name", value.toString().toStdString().c_str());
mitk::PlanarFigure* planarFigure = dynamic_cast<mitk::PlanarFigure*>(dataNode->GetData());
if (planarFigure != NULL)
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
else if(role == Qt::CheckStateRole)
{
// Please note: value.toInt() returns 2, independentely from the actual checkstate of the index element.
// Therefore the checkstate is being estimated again here.
QVariant qcheckstate = index.data(Qt::CheckStateRole);
int checkstate = qcheckstate.toInt();
bool isVisible = bool(checkstate);
dataNode->SetVisibility(!isVisible);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
// inform listeners about changes
emit dataChanged(index, index);
return true;
}
bool QmitkDataStorageTreeModel::setHeaderData( int /*section*/, Qt::Orientation /*orientation*/, const QVariant& /* value */, int /*role = Qt::EditRole*/ )
{
return false;
}
void QmitkDataStorageTreeModel::AdjustLayerProperty()
{
/// transform the tree into an array and set the layer property descending
std::vector<TreeItem*> vec;
this->TreeToVector(m_Root, vec);
int i = vec.size()-1;
for(std::vector<TreeItem*>::const_iterator it = vec.begin(); it != vec.end(); ++it)
{
mitk::DataNode::Pointer dataNode = (*it)->GetDataNode();
bool fixedLayer = false;
if (!(dataNode->GetBoolProperty("fixedLayer", fixedLayer) && fixedLayer))
dataNode->SetIntProperty("layer", i);
--i;
}
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkDataStorageTreeModel::TreeToVector(TreeItem* parent, std::vector<TreeItem*>& vec) const
{
TreeItem* current;
for(int i = 0; i<parent->GetChildCount(); ++i)
{
current = parent->GetChild(i);
this->TreeToVector(current, vec);
vec.push_back(current);
}
}
QModelIndex QmitkDataStorageTreeModel::IndexFromTreeItem( TreeItem* item ) const
{
if(item == m_Root)
return QModelIndex();
else
return this->createIndex(item->GetIndex(), 0, item);
}
QList<mitk::DataNode::Pointer> QmitkDataStorageTreeModel::GetNodeSet() const
{
QList<mitk::DataNode::Pointer> res;
if(m_Root)
this->TreeToNodeSet(m_Root, res);
return res;
}
void QmitkDataStorageTreeModel::TreeToNodeSet( TreeItem* parent, QList<mitk::DataNode::Pointer>& vec ) const
{
TreeItem* current;
for(int i = 0; i<parent->GetChildCount(); ++i)
{
current = parent->GetChild(i);
vec.push_back(current->GetDataNode());
this->TreeToNodeSet(current, vec);
}
}
QModelIndex QmitkDataStorageTreeModel::GetIndex( const mitk::DataNode* node ) const
{
if(m_Root)
{
TreeItem* item = m_Root->Find(node);
if(item)
return this->IndexFromTreeItem(item);
}
return QModelIndex();
}
QList<QmitkDataStorageTreeModel::TreeItem *> QmitkDataStorageTreeModel::ToTreeItemPtrList(const QMimeData* mimeData)
{
if (mimeData == NULL || !mimeData->hasFormat(QmitkMimeTypes::DataStorageTreeItemPtrs))
{
return QList<TreeItem*>();
}
return ToTreeItemPtrList(mimeData->data(QmitkMimeTypes::DataStorageTreeItemPtrs));
}
QList<QmitkDataStorageTreeModel::TreeItem *> QmitkDataStorageTreeModel::ToTreeItemPtrList(const QByteArray& ba)
{
QList<TreeItem*> result;
QDataStream ds(ba);
while(!ds.atEnd())
{
quintptr treeItemPtr;
ds >> treeItemPtr;
result.push_back(reinterpret_cast<TreeItem*>(treeItemPtr));
}
return result;
}
QmitkDataStorageTreeModel::TreeItem::TreeItem( mitk::DataNode* _DataNode, TreeItem* _Parent )
: m_Parent(_Parent)
, m_DataNode(_DataNode)
{
if(m_Parent)
m_Parent->AddChild(this);
}
QmitkDataStorageTreeModel::TreeItem::~TreeItem()
{
if(m_Parent)
m_Parent->RemoveChild(this);
}
void QmitkDataStorageTreeModel::TreeItem::Delete()
{
while(m_Children.size() > 0)
delete m_Children.back();
delete this;
}
QmitkDataStorageTreeModel::TreeItem* QmitkDataStorageTreeModel::TreeItem::Find( const mitk::DataNode* _DataNode ) const
{
QmitkDataStorageTreeModel::TreeItem* item = 0;
if(_DataNode)
{
if(m_DataNode == _DataNode)
item = const_cast<TreeItem*>(this);
else
{
for(std::vector<TreeItem*>::const_iterator it = m_Children.begin(); it != m_Children.end(); ++it)
{
if(item)
break;
item = (*it)->Find(_DataNode);
}
}
}
return item;
}
int QmitkDataStorageTreeModel::TreeItem::IndexOfChild( const TreeItem* item ) const
{
std::vector<TreeItem*>::const_iterator it = std::find(m_Children.begin(), m_Children.end(), item);
return it != m_Children.end() ? std::distance(m_Children.begin(), it): -1;
}
QmitkDataStorageTreeModel::TreeItem* QmitkDataStorageTreeModel::TreeItem::GetChild( int index ) const
{
return (m_Children.size() > 0 && index >= 0 && index < (int)m_Children.size())? m_Children.at(index): 0;
}
void QmitkDataStorageTreeModel::TreeItem::AddChild( TreeItem* item )
{
this->InsertChild(item);
}
void QmitkDataStorageTreeModel::TreeItem::RemoveChild( TreeItem* item )
{
std::vector<TreeItem*>::iterator it = std::find(m_Children.begin(), m_Children.end(), item);
if(it != m_Children.end())
{
m_Children.erase(it);
item->SetParent(0);
}
}
int QmitkDataStorageTreeModel::TreeItem::GetChildCount() const
{
return m_Children.size();
}
int QmitkDataStorageTreeModel::TreeItem::GetIndex() const
{
if (m_Parent)
return m_Parent->IndexOfChild(this);
return 0;
}
QmitkDataStorageTreeModel::TreeItem* QmitkDataStorageTreeModel::TreeItem::GetParent() const
{
return m_Parent;
}
mitk::DataNode::Pointer QmitkDataStorageTreeModel::TreeItem::GetDataNode() const
{
return m_DataNode;
}
void QmitkDataStorageTreeModel::TreeItem::InsertChild( TreeItem* item, int index )
{
std::vector<TreeItem*>::iterator it = std::find(m_Children.begin(), m_Children.end(), item);
if(it == m_Children.end())
{
if(m_Children.size() > 0 && index >= 0 && index < (int)m_Children.size())
{
it = m_Children.begin();
std::advance(it, index);
m_Children.insert(it, item);
}
else
m_Children.push_back(item);
// add parent if necessary
if(item->GetParent() != this)
item->SetParent(this);
}
}
std::vector<QmitkDataStorageTreeModel::TreeItem*> QmitkDataStorageTreeModel::TreeItem::GetChildren() const
{
return m_Children;
}
void QmitkDataStorageTreeModel::TreeItem::SetParent( TreeItem* _Parent )
{
m_Parent = _Parent;
if(m_Parent)
m_Parent->AddChild(this);
}
void QmitkDataStorageTreeModel::Update()
{
if (m_DataStorage.IsNotNull())
{
- this->reset();
+ this->beginResetModel();
+ this->endResetModel();
mitk::DataStorage::SetOfObjects::ConstPointer _NodeSet = m_DataStorage->GetAll();
for (mitk::DataStorage::SetOfObjects::const_iterator it = _NodeSet->begin(); it != _NodeSet->end(); it++)
{
// save node
this->AddNodeInternal(*it);
}
}
}
diff --git a/Modules/QtWidgets/QmitkFileReaderOptionsDialog.ui b/Modules/QtWidgets/QmitkFileReaderOptionsDialog.ui
index 3ee173c788..5e5e9d6748 100644
--- a/Modules/QtWidgets/QmitkFileReaderOptionsDialog.ui
+++ b/Modules/QtWidgets/QmitkFileReaderOptionsDialog.ui
@@ -1,147 +1,131 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QmitkFileReaderOptionsDialog</class>
<widget class="QDialog" name="QmitkFileReaderOptionsDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
- <width>458</width>
- <height>343</height>
+ <width>272</width>
+ <height>186</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<property name="sizeGripEnabled">
- <bool>true</bool>
+ <bool>false</bool>
</property>
<property name="modal">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetFixedSize</enum>
+ </property>
<item>
<widget class="QLabel" name="m_ReaderLabel">
<property name="text">
<string>Choose file reader</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="m_ReaderComboBox"/>
</item>
<item>
<widget class="QLabel" name="m_FilePathLabel">
<property name="text">
<string/>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="m_OptionsBox">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
<property name="title">
<string>Options</string>
</property>
<property name="flat">
<bool>false</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QStackedWidget" name="m_StackedOptionsWidget"/>
</item>
</layout>
</widget>
</item>
- <item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>10</height>
- </size>
- </property>
- </spacer>
- </item>
<item>
<widget class="QCheckBox" name="m_ReuseOptionsCheckBox">
<property name="text">
- <string>Remember settings for all remaining files of the same type</string>
+ <string>Apply to the next files with same type</string>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>QmitkFileReaderOptionsDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>QmitkFileReaderOptionsDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>m_ReaderComboBox</sender>
<signal>currentIndexChanged(int)</signal>
<receiver>m_StackedOptionsWidget</receiver>
<slot>setCurrentIndex(int)</slot>
<hints>
<hint type="sourcelabel">
<x>199</x>
<y>44</y>
</hint>
<hint type="destinationlabel">
<x>203</x>
<y>167</y>
</hint>
</hints>
</connection>
</connections>
</ui>
diff --git a/Modules/QtWidgets/QmitkFileWriterOptionsDialog.ui b/Modules/QtWidgets/QmitkFileWriterOptionsDialog.ui
index a86d37ed1a..dd38619b01 100644
--- a/Modules/QtWidgets/QmitkFileWriterOptionsDialog.ui
+++ b/Modules/QtWidgets/QmitkFileWriterOptionsDialog.ui
@@ -1,147 +1,131 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QmitkFileWriterOptionsDialog</class>
<widget class="QDialog" name="QmitkFileWriterOptionsDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
- <width>458</width>
- <height>343</height>
+ <width>272</width>
+ <height>186</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<property name="sizeGripEnabled">
- <bool>true</bool>
+ <bool>false</bool>
</property>
<property name="modal">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetFixedSize</enum>
+ </property>
<item>
<widget class="QLabel" name="m_WriterLabel">
<property name="text">
<string>Choose file writer</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="m_WriterComboBox"/>
</item>
<item>
<widget class="QLabel" name="m_FilePathLabel">
<property name="text">
<string/>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QGroupBox" name="m_OptionsBox">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
<property name="title">
<string>Options</string>
</property>
<property name="flat">
<bool>false</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QStackedWidget" name="m_StackedOptionsWidget"/>
</item>
</layout>
</widget>
</item>
- <item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>10</height>
- </size>
- </property>
- </spacer>
- </item>
<item>
<widget class="QCheckBox" name="m_ReuseOptionsCheckBox">
<property name="text">
- <string>Remember settings for all remaining files of the same type</string>
+ <string>Apply to the next files with same type</string>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>QmitkFileWriterOptionsDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>QmitkFileWriterOptionsDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>m_WriterComboBox</sender>
<signal>currentIndexChanged(int)</signal>
<receiver>m_StackedOptionsWidget</receiver>
<slot>setCurrentIndex(int)</slot>
<hints>
<hint type="sourcelabel">
<x>199</x>
<y>44</y>
</hint>
<hint type="destinationlabel">
<x>203</x>
<y>167</y>
</hint>
</hints>
</connection>
</connections>
</ui>
diff --git a/Modules/QtWidgets/QmitkIOUtil.cpp b/Modules/QtWidgets/QmitkIOUtil.cpp
index f3dbd9c264..3a63b77eed 100644
--- a/Modules/QtWidgets/QmitkIOUtil.cpp
+++ b/Modules/QtWidgets/QmitkIOUtil.cpp
@@ -1,527 +1,547 @@
/*===================================================================
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 "QmitkIOUtil.h"
#include <mitkIOUtil.h>
#include <mitkCoreObjectFactory.h>
#include "mitkCoreServices.h"
#include "mitkIMimeTypeProvider.h"
#include "mitkMimeType.h"
#include "mitkCustomMimeType.h"
#include "mitkFileReaderRegistry.h"
#include "mitkFileWriterRegistry.h"
#include "QmitkFileReaderOptionsDialog.h"
#include "QmitkFileWriterOptionsDialog.h"
// QT
#include <QFileDialog>
#include <QMessageBox>
#include <QSet>
#include <QDebug>
//ITK
#include <itksys/SystemTools.hxx>
#include <algorithm>
struct QmitkIOUtil::Impl
{
struct ReaderOptionsDialogFunctor : public ReaderOptionsFunctorBase
{
virtual bool operator()(LoadInfo& loadInfo)
{
QmitkFileReaderOptionsDialog dialog(loadInfo);
if (dialog.exec() == QDialog::Accepted)
{
return !dialog.ReuseOptions();
}
else
{
loadInfo.m_Cancel = true;
return true;
}
}
};
struct WriterOptionsDialogFunctor : public WriterOptionsFunctorBase
{
virtual bool operator()(SaveInfo& saveInfo)
{
QmitkFileWriterOptionsDialog dialog(saveInfo);
if (dialog.exec() == QDialog::Accepted)
{
return !dialog.ReuseOptions();
}
else
{
saveInfo.m_Cancel = true;
return true;
}
}
};
};
struct MimeTypeComparison : public std::unary_function<mitk::MimeType, bool>
{
MimeTypeComparison(const std::string& mimeTypeName)
: m_Name(mimeTypeName)
{}
bool operator()(const mitk::MimeType& mimeType) const
{
return mimeType.GetName() == m_Name;
}
const std::string m_Name;
};
QString QmitkIOUtil::GetFileOpenFilterString()
{
QString filters;
mitk::CoreServicePointer<mitk::IMimeTypeProvider> mimeTypeProvider(mitk::CoreServices::GetMimeTypeProvider());
std::vector<std::string> categories = mimeTypeProvider->GetCategories();
for (std::vector<std::string>::iterator cat = categories.begin(); cat != categories.end(); ++cat)
{
QSet<QString> filterExtensions;
std::vector<mitk::MimeType> mimeTypes = mimeTypeProvider->GetMimeTypesForCategory(*cat);
for (std::vector<mitk::MimeType>::iterator mt = mimeTypes.begin(); mt != mimeTypes.end(); ++mt)
{
std::vector<std::string> extensions = mt->GetExtensions();
for (std::vector<std::string>::iterator ext = extensions.begin(); ext != extensions.end(); ++ext)
{
filterExtensions << QString::fromStdString(*ext);
}
}
QString filter = QString::fromStdString(*cat) + " (";
foreach(const QString& extension, filterExtensions)
{
filter += "*." + extension + " ";
}
filter = filter.replace(filter.size()-1, 1, ')');
filters += ";;" + filter;
}
- filters.prepend("All (*.*)");
+ filters.prepend("All (*)");
return filters;
}
QList<mitk::BaseData::Pointer> QmitkIOUtil::Load(const QStringList& paths, QWidget* parent)
{
std::vector<LoadInfo> loadInfos;
foreach(const QString& file, paths)
{
loadInfos.push_back(LoadInfo(file.toStdString()));
}
Impl::ReaderOptionsDialogFunctor optionsCallback;
std::string errMsg = Load(loadInfos, NULL, NULL, &optionsCallback);
if (!errMsg.empty())
{
QMessageBox::warning(parent, "Error reading files", QString::fromStdString(errMsg));
mitkThrow() << errMsg;
}
QList<mitk::BaseData::Pointer> qResult;
for(std::vector<LoadInfo>::const_iterator iter = loadInfos.begin(), iterEnd = loadInfos.end();
iter != iterEnd; ++iter)
{
for (std::vector<mitk::BaseData::Pointer>::const_iterator dataIter = iter->m_Output.begin(),
dataIterEnd = iter->m_Output.end(); dataIter != dataIterEnd; ++dataIter)
{
qResult << *dataIter;
}
}
return qResult;
}
mitk::DataStorage::SetOfObjects::Pointer QmitkIOUtil::Load(const QStringList& paths, mitk::DataStorage& storage, QWidget* parent)
{
std::vector<LoadInfo> loadInfos;
foreach(const QString& file, paths)
{
loadInfos.push_back(LoadInfo(QFile::encodeName(file).constData()));
}
mitk::DataStorage::SetOfObjects::Pointer nodeResult = mitk::DataStorage::SetOfObjects::New();
Impl::ReaderOptionsDialogFunctor optionsCallback;
std::string errMsg = Load(loadInfos, nodeResult, &storage, &optionsCallback);
if (!errMsg.empty())
{
QMessageBox::warning(parent, "Error reading files", QString::fromStdString(errMsg));
mitkThrow() << errMsg;
}
return nodeResult;
}
QList<mitk::BaseData::Pointer> QmitkIOUtil::Load(const QString& path, QWidget* parent)
{
QStringList paths;
paths << path;
return Load(paths, parent);
}
mitk::DataStorage::SetOfObjects::Pointer QmitkIOUtil::Load(const QString& path, mitk::DataStorage& storage,
QWidget* parent)
{
QStringList paths;
paths << path;
return Load(paths, storage, parent);
}
QString QmitkIOUtil::Save(const mitk::BaseData* data, const QString& defaultBaseName,
const QString& defaultPath, QWidget* parent)
{
std::vector<const mitk::BaseData*> dataVector;
dataVector.push_back(data);
QStringList defaultBaseNames;
defaultBaseNames.push_back(defaultBaseName);
return Save(dataVector, defaultBaseNames, defaultPath, parent).back();
}
QStringList QmitkIOUtil::Save(const std::vector<const mitk::BaseData*>& data,
const QStringList& defaultBaseNames,
const QString& defaultPath,
QWidget* parent)
{
QStringList fileNames;
QString currentPath = defaultPath;
std::vector<SaveInfo> saveInfos;
int counter = 0;
for(std::vector<const mitk::BaseData*>::const_iterator dataIter = data.begin(),
dataIterEnd = data.end(); dataIter != dataIterEnd; ++dataIter, ++counter)
{
SaveInfo saveInfo(*dataIter, mitk::MimeType(), std::string());
SaveFilter filters(saveInfo);
// If there is only the "__all__" filter string, it means there is no writer for this base data
if (filters.Size() < 2)
{
QMessageBox::warning(parent,
"Saving not possible",
QString("No writer available for type \"%1\"").arg(
QString::fromStdString((*dataIter)->GetNameOfClass())));
continue;
}
// Construct a default path and file name
QString filterString = filters.ToString();
QString selectedFilter = filters.GetDefaultFilter();
QString fileName = currentPath;
QString dialogTitle = "Save " + QString::fromStdString((*dataIter)->GetNameOfClass());
if (counter < defaultBaseNames.size())
{
dialogTitle += " \"" + defaultBaseNames[counter] + "\"";
fileName += QDir::separator() + defaultBaseNames[counter];
// We do not append an extension to the file name by default. The extension
// is chosen by the user by either selecting a filter or writing the
// extension in the file name himself (in the file save dialog).
/*
QString defaultExt = filters.GetDefaultExtension();
if (!defaultExt.isEmpty())
{
fileName += "." + defaultExt;
}
*/
}
// Ask the user for a file name
QString nextName = QFileDialog::getSaveFileName(parent,
dialogTitle,
fileName,
filterString,
&selectedFilter);
if (nextName.isEmpty())
{
// We stop asking for further file names, but we still save the
// data where the user already confirmed the save dialog.
break;
}
fileName = nextName;
std::string stdFileName = QFile::encodeName(fileName).constData();
QFileInfo fileInfo(fileName);
currentPath = fileInfo.absolutePath();
QString suffix = fileInfo.completeSuffix();
- mitk::MimeType mimeType = filters.GetMimeTypeForFilter(selectedFilter);
+ mitk::MimeType filterMimeType = filters.GetMimeTypeForFilter(selectedFilter);
+ mitk::MimeType selectedMimeType;
- mitk::CoreServicePointer<mitk::IMimeTypeProvider> mimeTypeProvider(mitk::CoreServices::GetMimeTypeProvider());
- // If the filename contains a suffix, use it but check if it is valid
- if (!suffix.isEmpty())
+ if (fileInfo.exists() && !fileInfo.isFile())
{
- std::vector<mitk::MimeType> availableTypes = mimeTypeProvider->GetMimeTypesForFile(stdFileName);
-
- // Check if the selected mime-type is related to the specified suffix (file extension).
- // If not, get the best matching mime-type for the suffix.
- if (std::find(availableTypes.begin(), availableTypes.end(), mimeType) == availableTypes.end())
- {
- mimeType = mitk::MimeType();
- for (std::vector<mitk::MimeType>::const_iterator availIter = availableTypes.begin(),
- availIterEnd = availableTypes.end(); availIter != availIterEnd; ++availIter)
- {
- if (filters.ContainsMimeType(availIter->GetName()))
- {
- mimeType = *availIter;
- break;
- }
- }
- }
+ QMessageBox::warning(parent, "Saving not possible", QString("The path \"%1\" is not a file").arg(fileName));
+ continue;
+ }
- if (!mimeType.IsValid())
+ // Check if one of the available mime-types match the filename
+ std::vector<mitk::MimeType> filterMimeTypes = filters.GetMimeTypes();
+ for (std::vector<mitk::MimeType>::const_iterator mimeTypeIter = filterMimeTypes.begin(),
+ mimeTypeIterEnd = filterMimeTypes.end(); mimeTypeIter != mimeTypeIterEnd; ++mimeTypeIter)
+ {
+ if (mimeTypeIter->AppliesTo(stdFileName))
{
- // The extension is not valid (no mime-type found), bail out
- QMessageBox::warning(parent,
- "Saving not possible",
- QString("Extension \"%1\" unknown for type \"%2\"")
- .arg(suffix)
- .arg(QString::fromStdString((*dataIter)->GetNameOfClass())));
- continue;
+ selectedMimeType = *mimeTypeIter;
+ break;
}
}
- else
+
+ if (!selectedMimeType.IsValid())
{
- // Create a default suffix, unless the file already exists and the user
- // already confirmed to overwrite it (without using a suffix)
- if (mimeType == SaveFilter::ALL_MIMETYPE())
- {
- // Use the highest ranked mime-type from the list
- mimeType = filters.GetDefaultMimeType();
- }
+ // The file name either does not contain an extension or the
+ // extension is unknown.
+
+ // If the file already exists, we stop here because we are not able
+ // to (over)write the file without adding a custom suffix. If the file
+ // does not exist, we add the default extension from the currently
+ // selected filter. If the "All" filter was selected, we only add the
+ // default extensions if the file name itself does not already contain
+ // an extension.
if (!fileInfo.exists())
{
- suffix = QString::fromStdString(mimeType.GetExtensions().front());
- fileName += "." + suffix;
- // We changed the file name (added a suffix) so ask in case
- // the file aready exists.
- fileInfo = QFileInfo(fileName);
- if (fileInfo.exists())
+ if (filterMimeType == SaveFilter::ALL_MIMETYPE())
{
- if (!fileInfo.isFile())
+ if (suffix.isEmpty())
{
- QMessageBox::warning(parent, "Saving not possible", QString("The path \"%1\" is not a file").arg(fileName));
- continue;
+ // Use the highest ranked mime-type from the list
+ selectedMimeType = filters.GetDefaultMimeType();
}
- if (QMessageBox::question(parent, "Replace File",
- QString("A file named \"%1\" already exists. Do you want to replace it?").arg(fileName)) ==
- QMessageBox::No)
+ }
+ else
+ {
+ selectedMimeType = filterMimeType;
+ }
+
+ if (selectedMimeType.IsValid())
+ {
+ suffix = QString::fromStdString(selectedMimeType.GetExtensions().front());
+ fileName += "." + suffix;
+ stdFileName = QFile::encodeName(fileName).constData();
+ // We changed the file name (added a suffix) so ask in case
+ // the file aready exists.
+ fileInfo = QFileInfo(fileName);
+ if (fileInfo.exists())
{
- continue;
+ if (!fileInfo.isFile())
+ {
+ QMessageBox::warning(parent, "Saving not possible", QString("The path \"%1\" is not a file").arg(fileName));
+ continue;
+ }
+ if (QMessageBox::question(parent, "Replace File",
+ QString("A file named \"%1\" already exists. Do you want to replace it?").arg(fileName)) ==
+ QMessageBox::No)
+ {
+ continue;
+ }
}
}
}
}
+ if (!selectedMimeType.IsValid())
+ {
+ // The extension/filename is not valid (no mime-type found), bail out
+ QMessageBox::warning(parent,
+ "Saving not possible",
+ QString("No mime-type available which can handle \"%1\".")
+ .arg(fileName));
+ continue;
+ }
+
if (!QFileInfo(fileInfo.absolutePath()).isWritable())
{
QMessageBox::warning(parent, "Saving not possible", QString("The path \"%1\" is not writable").arg(fileName));
continue;
}
fileNames.push_back(fileName);
saveInfo.m_Path = stdFileName;
- saveInfo.m_MimeType = mimeType;
+ saveInfo.m_MimeType = selectedMimeType;
// pre-select the best writer for the chosen mime-type
- saveInfo.m_WriterSelector.Select(mimeType.GetName());
+ saveInfo.m_WriterSelector.Select(selectedMimeType.GetName());
saveInfos.push_back(saveInfo);
}
if (!saveInfos.empty())
{
Impl::WriterOptionsDialogFunctor optionsCallback;
std::string errMsg = Save(saveInfos, &optionsCallback);
if (!errMsg.empty())
{
QMessageBox::warning(parent, "Error writing files", QString::fromStdString(errMsg));
mitkThrow() << errMsg;
}
}
return fileNames;
}
void QmitkIOUtil::SaveBaseDataWithDialog(mitk::BaseData* data, std::string fileName, QWidget* /*parent*/)
{
Save(data, fileName);
}
void QmitkIOUtil::SaveSurfaceWithDialog(mitk::Surface::Pointer surface, std::string fileName, QWidget* /*parent*/)
{
Save(surface, fileName);
}
void QmitkIOUtil::SaveImageWithDialog(mitk::Image::Pointer image, std::string fileName, QWidget* /*parent*/)
{
Save(image, fileName);
}
void QmitkIOUtil::SavePointSetWithDialog(mitk::PointSet::Pointer pointset, std::string fileName, QWidget* /*parent*/)
{
Save(pointset, fileName);
}
struct QmitkIOUtil::SaveFilter::Impl
{
Impl(const mitk::IOUtil::SaveInfo& saveInfo)
: m_SaveInfo(saveInfo)
{
// Add an artifical filter for "All"
m_MimeTypes.push_back(ALL_MIMETYPE());
m_FilterStrings.push_back("All (*.*)");
// Get all writers and their mime types for the given base data type
// (this is sorted already)
std::vector<mitk::MimeType> mimeTypes = saveInfo.m_WriterSelector.GetMimeTypes();
for (std::vector<mitk::MimeType>::const_reverse_iterator iter = mimeTypes.rbegin(),
iterEnd = mimeTypes.rend(); iter != iterEnd; ++iter)
{
QList<QString> filterExtensions;
mitk::MimeType mimeType = *iter;
std::vector<std::string> extensions = mimeType.GetExtensions();
for (std::vector<std::string>::iterator extIter = extensions.begin(), extIterEnd = extensions.end();
extIter != extIterEnd; ++extIter)
{
filterExtensions << QString::fromStdString(*extIter);
}
if (m_DefaultExtension.isEmpty())
{
m_DefaultExtension = QString::fromStdString(extensions.front());
}
QString filter = QString::fromStdString(mimeType.GetComment()) + " (";
foreach(const QString& extension, filterExtensions)
{
filter += "*." + extension + " ";
}
filter = filter.replace(filter.size()-1, 1, ')');
m_MimeTypes.push_back(mimeType);
m_FilterStrings.push_back(filter);
}
}
const mitk::IOUtil::SaveInfo m_SaveInfo;
std::vector<mitk::MimeType> m_MimeTypes;
QStringList m_FilterStrings;
QString m_DefaultExtension;
};
mitk::MimeType QmitkIOUtil::SaveFilter::ALL_MIMETYPE()
{
static mitk::CustomMimeType allMimeType(std::string("__all__"));
return mitk::MimeType(allMimeType, -1, -1);
}
QmitkIOUtil::SaveFilter::SaveFilter(const QmitkIOUtil::SaveFilter& other)
: d(new Impl(*other.d))
{
}
QmitkIOUtil::SaveFilter::SaveFilter(const SaveInfo& saveInfo)
: d(new Impl(saveInfo))
{
}
QmitkIOUtil::SaveFilter& QmitkIOUtil::SaveFilter::operator=(const QmitkIOUtil::SaveFilter& other)
{
d.reset(new Impl(*other.d));
return *this;
}
+std::vector<mitk::MimeType> QmitkIOUtil::SaveFilter::GetMimeTypes() const
+{
+ return d->m_MimeTypes;
+}
+
QString QmitkIOUtil::SaveFilter::GetFilterForMimeType(const std::string& mimeType) const
{
std::vector<mitk::MimeType>::const_iterator iter =
std::find_if(d->m_MimeTypes.begin(), d->m_MimeTypes.end(), MimeTypeComparison(mimeType));
if (iter == d->m_MimeTypes.end())
{
return QString();
}
int index = static_cast<int>(iter - d->m_MimeTypes.begin());
if (index < 0 || index >= d->m_FilterStrings.size())
{
return QString();
}
return d->m_FilterStrings[index];
}
mitk::MimeType QmitkIOUtil::SaveFilter::GetMimeTypeForFilter(const QString& filter) const
{
int index = d->m_FilterStrings.indexOf(filter);
if (index < 0)
{
return mitk::MimeType();
}
return d->m_MimeTypes[index];
}
QString QmitkIOUtil::SaveFilter::GetDefaultFilter() const
{
if (d->m_FilterStrings.size() > 1)
{
return d->m_FilterStrings.at(1);
}
else if (d->m_FilterStrings.size() > 0)
{
return d->m_FilterStrings.front();
}
return QString();
}
QString QmitkIOUtil::SaveFilter::GetDefaultExtension() const
{
return d->m_DefaultExtension;
}
mitk::MimeType QmitkIOUtil::SaveFilter::GetDefaultMimeType() const
{
if (d->m_MimeTypes.size() > 1)
{
return d->m_MimeTypes.at(1);
}
else if (d->m_MimeTypes.size() > 0)
{
return d->m_MimeTypes.front();
}
return mitk::MimeType();
}
QString QmitkIOUtil::SaveFilter::ToString() const
{
return d->m_FilterStrings.join(";;");
}
int QmitkIOUtil::SaveFilter::Size() const
{
return d->m_FilterStrings.size();
}
bool QmitkIOUtil::SaveFilter::IsEmpty() const
{
return d->m_FilterStrings.isEmpty();
}
bool QmitkIOUtil::SaveFilter::ContainsMimeType(const std::string& mimeType)
{
return std::find_if(d->m_MimeTypes.begin(), d->m_MimeTypes.end(), MimeTypeComparison(mimeType)) != d->m_MimeTypes.end();
}
diff --git a/Modules/QtWidgets/QmitkIOUtil.h b/Modules/QtWidgets/QmitkIOUtil.h
index 57fd830b33..3cca02851d 100644
--- a/Modules/QtWidgets/QmitkIOUtil.h
+++ b/Modules/QtWidgets/QmitkIOUtil.h
@@ -1,232 +1,229 @@
/*===================================================================
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 _QmitkIOUtil__h_
#define _QmitkIOUtil__h_
#include "MitkQtWidgetsExports.h"
// std
#include <string>
// mitk includes
#include <mitkCommon.h>
#include <mitkBaseData.h>
#include <mitkDataNode.h>
#include <mitkImage.h>
#include <mitkSurface.h>
#include <mitkPointSet.h>
#include <mitkIOUtil.h>
#include <mitkFileWriterWithInformation.h>
//Qt
#include <QList>
#include <QPair>
+#include <QScopedPointer>
+#include <QString>
class QWidget;
class QString;
class QStringList;
namespace mitk {
class DataStorage;
class MimeType;
struct IFileReader;
}
/**
* @brief QmitkIOUtil Provides static helper methods to open and save files with Qt dialogs.
*/
class QMITK_EXPORT QmitkIOUtil : public mitk::IOUtil
{
public:
class QMITK_EXPORT SaveFilter
{
public:
static mitk::MimeType ALL_MIMETYPE();
SaveFilter(const SaveFilter& other);
SaveFilter(const SaveInfo& saveInfo);
SaveFilter& operator=(const SaveFilter& other);
+ std::vector<mitk::MimeType> GetMimeTypes() const;
QString GetFilterForMimeType(const std::string& mimeType) const;
mitk::MimeType GetMimeTypeForFilter(const QString& filter) const;
QString GetDefaultFilter() const;
QString GetDefaultExtension() const;
mitk::MimeType GetDefaultMimeType() const;
QString ToString() const;
int Size() const;
bool IsEmpty() const;
bool ContainsMimeType(const std::string& mimeType);
private:
struct Impl;
QScopedPointer<Impl> d;
};
/**
* @brief GetFilterString
* @return
*/
static QString GetFileOpenFilterString();
/**
* @brief Loads the specified files
*
* This methods tries to load all specified files and pop-ups dialog boxes if further
* user input is required (e.g. ambiguous mime-types or reader options).
*
* If the provided DataStorage is not NULL, some files will be added to it automatically,
* dependeing on the IFileReader used.
*
* @param files A list of files to load.
* @param ds An optional data storage passed to IFileReader instances
* @return A list of BaseData instances which have not already been added to the data storage.
*/
static QList<mitk::BaseData::Pointer> Load(const QStringList& paths, QWidget* parent = NULL);
static mitk::DataStorage::SetOfObjects::Pointer Load(const QStringList& paths, mitk::DataStorage& storage,
QWidget* parent = NULL);
static QList<mitk::BaseData::Pointer> Load(const QString& path, QWidget* parent = NULL);
static mitk::DataStorage::SetOfObjects::Pointer Load(const QString& path, mitk::DataStorage& storage,
QWidget* parent = NULL);
using mitk::IOUtil::Load;
static QString Save(const mitk::BaseData* data, const QString& defaultBaseName,
const QString& defaultPath = QString(), QWidget* parent = NULL);
/**
* @brief Save a list of BaseData objects using a "File Save Dialog".
*
* For each element in the \c data vector, the following algorithm is
* used to find a IFileWriter instance for writing the BaseData object.
*
* First, the user is prompted to select file names for each BaseData object. This
* is equivalent to choosing a specific mime-type, either by selecting a filter
* in the save dialog or by explicitly providing a file name extension:
* <ol>
* <li>Get a list of registered IFileWriter objects for the current BaseData object.
* If no writers are found, a message box displays a warning and
* the process starts from the beginning for the next BaseData object.</li>
* <li>A QFileDialog for prompting the user to select a file name is opened.
* The mime-type associated with each IFileWriter object is used to create
* a filter for file name extensions.
* The best IFileWriter (see FileWriterSelector) for the current BaseData object
* defines the default file name suffix via its associated mime-type. If the
* file name is empty (the user cancelled the dialog), the remaining
* BaseData objects are skipped.
- * <li>The file name suffix is extracted from the user-supplied file name and validated.
- * If the suffix is not empty and it is either not contained in the
- * extension list of the selected filter (from the QFileDialog) or the mime-type
- * containing the suffix as an extension is not contained in the original
- * list of compatible mime-types, a message box displays a warning and
- * the process starts from the beginning with the next BaseData object.
- * If the suffix is empty, a default suffix is created if the file name does
- * not point to an already existing file (in that case, the user already
- * confirmed to overwrite that file). The default suffix is the first entry
- * in the extension list of the selected filter. If the special "all"
- * filter is selected, the first entry from the extensions list of the
- * highest-ranked compatible mime-type for the current base data object is used.
- * The base data object is associated with the mime-type containing the suffix
- * in its extension list. If the suffix is empty (the user is overwriting an
- * existing file without an extension, the associated mime-type is the one
- * of the selected filter or the mime-type of the best matching IFileWriter
- * if the special "all" filter was selected.</li>
+ * <li>The file name is matched against valid mime-types. The first mime-type
+ * which accepts the file name is associated with the current BaseData object.
+ * If no mime-type accepts the supplied file name and the file already
+ * exists, the process starts from the beginning with the next BaseData object.
+ * Otherwise, if the selected filter is the special "all" filter and the
+ * file name does not contain periods (which may or may not mark the start of
+ * a file extension), the current BaseData object is associated with the
+ * default mime-type. If the selected filter is not the special "all" filter,
+ * the mime-type for this filter is associated with the current BaseData object.
+ * The default extension of the associated mime-type is then appended to the
+ * supplied file name.
* <li>The selected/derived file name and associated mime-type is stored in a list
* and the process starts from the beginning for the next BaseData object.</li>
* </ol>
*
* In the second phase, each BaseData object is saved to disk using the specified
* file name and mime-type, according to the following procedure:
* <ol>
* <li>If multiple IFileWriter objects are compatible with the current base data
* object or if the single compatible IFileWriter provides configuration
* options, a dialog window containing a list of IFileWriter objects and
* configurable options is displayed. If the dialog is cancelled by the user,
* neither the current nor the remaining base data objects are saved to disk.
* If the user previously in this phase enabled the "remember options" checkbox
* of the dialog, then the dialog is not shown for base data objects with the
* same data type and associated mime-type if the file writer instance reports
* a higher or equal confidence level for the current base data object.</li>
* <li>The selected writer (either the only available one or the user selected one)
* is used to write the base data object to disk. On failure, an error is
* reported and the second phase continues with the next base data object.</li>
* </ol>
*
* @param data
* @param defaultBaseNames
* @param defaultPath
* @param parent
* @return
*/
static QStringList Save(const std::vector<const mitk::BaseData*>& data, const QStringList& defaultBaseNames,
const QString& defaultPath = QString(), QWidget* parent = NULL);
using mitk::IOUtil::Save;
/**
* @brief SaveBaseDataWithDialog Convenience method to save any data with a Qt dialog.
* @param data BaseData holding the data you wish to save.
* @param fileName The file name where to save the data (including path and extension).
* @param parent An optional QWidget as parent. If no parent is supplied, the QFileDialog can occur anywhere on the screen.
* @deprecatedSince{2014_10} Use Save() instead.
*/
DEPRECATED(static void SaveBaseDataWithDialog(mitk::BaseData *data, std::string fileName, QWidget* parent = NULL));
/**
* @brief SaveSurfaceWithDialog Convenience method to save a surface with a Qt dialog.
* @param surface The surface to save.
* @param fileName The file name where to save the data (including path and extension).
* @param parent An optional QWidget as parent. If no parent is supplied, the QFileDialog can occur anywhere on the screen.
* @deprecatedSince{2014_10} Use Save() instead.
*/
DEPRECATED(static void SaveSurfaceWithDialog(mitk::Surface::Pointer surface, std::string fileName = "", QWidget* parent = NULL));
/**
* @brief SaveImageWithDialog Convenience method to save an image with a Qt dialog.
* @param image The image to save.
* @param fileName The file name where to save the data (including path and extension).
* @param parent An optional QWidget as parent. If no parent is supplied, the QFileDialog can occur anywhere on the screen.
* @deprecatedSince{2014_10} Use Save() instead.
*/
DEPRECATED(static void SaveImageWithDialog(mitk::Image::Pointer image, std::string fileName = "", QWidget* parent = NULL));
/**
* @brief SavePointSetWithDialog Convenience method to save a pointset with a Qt dialog.
* @param pointset The pointset to save.
* @param fileName The file name where to save the data (including path and extension).
* @param parent An optional QWidget as parent. If no parent is supplied, the QFileDialog can occur anywhere on the screen.
* @deprecatedSince{2014_10} Use Save() instead.
*/
DEPRECATED(static void SavePointSetWithDialog(mitk::PointSet::Pointer pointset, std::string fileName = "", QWidget* parent = NULL));
private:
struct Impl;
};
#endif // _QmitkIOUtil__h_
diff --git a/Modules/QtWidgets/QmitkLevelWindowPresetDefinitionDialog.cpp b/Modules/QtWidgets/QmitkLevelWindowPresetDefinitionDialog.cpp
index ae12790b90..ee4bafea7b 100644
--- a/Modules/QtWidgets/QmitkLevelWindowPresetDefinitionDialog.cpp
+++ b/Modules/QtWidgets/QmitkLevelWindowPresetDefinitionDialog.cpp
@@ -1,330 +1,334 @@
/*===================================================================
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 "QmitkLevelWindowPresetDefinitionDialog.h"
#include <QMessageBox>
#include <QTableWidgetItem>
#include <QHeaderView>
QmitkLevelWindowPresetDefinitionDialog::QmitkLevelWindowPresetDefinitionDialog(QWidget* parent, Qt::WindowFlags f)
: QDialog(parent, f), m_TableModel(0), m_SortModel(this)
{
this->setupUi(this);
QObject::connect(addButton, SIGNAL(clicked()), this, SLOT(addPreset()));
QObject::connect(removeButton, SIGNAL(clicked()), this, SLOT(removePreset()));
QObject::connect(changeButton, SIGNAL(clicked()), this, SLOT(changePreset()));
QObject::connect(presetView->horizontalHeader(), SIGNAL(sectionClicked(int)), this, SLOT(sortPresets(int)));
presetView->verticalHeader()->setVisible(false);
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
presetView->horizontalHeader()->setResizeMode(QHeaderView::Fixed);
+#else
+ presetView->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);
+#endif
presetView->setModel(&m_SortModel);
}
QmitkLevelWindowPresetDefinitionDialog::~QmitkLevelWindowPresetDefinitionDialog()
{
delete m_TableModel;
}
void QmitkLevelWindowPresetDefinitionDialog::sortPresets(int index)
{
static Qt::SortOrder order[3] = {Qt::AscendingOrder};
presetView->sortByColumn(index, order[index]);
if (order[index] == Qt::AscendingOrder) order[index] = Qt::DescendingOrder;
else order[index] = Qt::AscendingOrder;
}
void QmitkLevelWindowPresetDefinitionDialog::resizeEvent(QResizeEvent* event)
{
QDialog::resizeEvent(event);
this->resizeColumns();
}
void QmitkLevelWindowPresetDefinitionDialog::showEvent(QShowEvent* event)
{
this->resizeColumns();
QDialog::showEvent(event);
}
void QmitkLevelWindowPresetDefinitionDialog::resizeColumns()
{
int width = presetView->viewport()->size().width() - presetView->columnWidth(1) - presetView->columnWidth(2);
if (width < 50) width = 50;
presetView->setColumnWidth(0, width);
}
void QmitkLevelWindowPresetDefinitionDialog::addPreset()
{
std::string name(presetnameLineEdit->text().toStdString());
if (m_TableModel->contains(name))
{
QMessageBox::critical( this, "Preset definition",
"Presetname already exists.\n"
"You have to enter another one." );
}
else if (presetnameLineEdit->text() == "")
{
QMessageBox::critical( this, "Preset definition",
"Presetname has to be set.\n"
"You have to enter a Presetname." );
}
else
{
m_TableModel->addPreset(name, levelSpinBox->value(), windowSpinBox->value());
}
}
void QmitkLevelWindowPresetDefinitionDialog::removePreset()
{
QModelIndex index(presetView->selectionModel()->currentIndex());
if (!index.isValid()) return;
m_TableModel->removePreset(index);
}
void QmitkLevelWindowPresetDefinitionDialog::changePreset()
{
if (presetView->selectionModel()->hasSelection())
{
std::string name(presetnameLineEdit->text().toStdString());
if (name == "")
{
QMessageBox::critical( this, "Preset definition",
"Presetname has to be set.\n"
"You have to enter a Presetname." );
}
else if (m_TableModel->contains(name)
&& (m_TableModel->getPreset(presetView->selectionModel()->currentIndex()).name
!= name))
{
QMessageBox::critical( this, "Preset definition",
"Presetname already exists.\n"
"You have to enter another one." );
}
else
{
m_TableModel->changePreset(presetView->selectionModel()->currentIndex().row(),
name, levelSpinBox->value(), windowSpinBox->value());
}
}
}
void QmitkLevelWindowPresetDefinitionDialog::setPresets(std::map<std::string, double>& level, std::map<std::string, double>& window, QString initLevel, QString initWindow)
{
levelSpinBox->setValue(initLevel.toInt());
windowSpinBox->setValue(initWindow.toInt());
delete m_TableModel;
m_TableModel = new PresetTableModel(level, window, this);
m_SortModel.setSourceModel(m_TableModel);
QObject::connect(presetView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)), this, SLOT(ListViewSelectionChanged(const QItemSelection&, const QItemSelection&)));
this->sortPresets(0);
presetView->resizeColumnsToContents();
}
std::map<std::string, double> QmitkLevelWindowPresetDefinitionDialog::getLevelPresets()
{
std::map<std::string, double> levels;
m_TableModel->getLevels(levels);
return levels;
}
std::map<std::string, double> QmitkLevelWindowPresetDefinitionDialog::getWindowPresets()
{
std::map<std::string, double> windows;
m_TableModel->getWindows(windows);
return windows;
}
void QmitkLevelWindowPresetDefinitionDialog::ListViewSelectionChanged(const QItemSelection& selected,
const QItemSelection& /*deselected*/)
{
QModelIndexList indexes(selected.indexes());
if (indexes.empty())
{
presetnameLineEdit->setText("");
levelSpinBox->setValue(0);
windowSpinBox->setValue(0);
}
else
{
//use the sorted index to get the entry
PresetTableModel::Entry entry( m_TableModel->getPreset((m_SortModel.mapToSource(indexes.first()))) );
presetnameLineEdit->setText(QString(entry.name.c_str()));
levelSpinBox->setValue((int)entry.level);
windowSpinBox->setValue((int)entry.window);
}
}
QmitkLevelWindowPresetDefinitionDialog::
PresetTableModel::PresetTableModel(std::map<std::string, double>& levels,
std::map<std::string, double>& windows, QObject* parent)
: QAbstractTableModel(parent)
{
for(std::map<std::string, double>::iterator iter = levels.begin(); iter != levels.end(); ++iter )
{
m_Entries.push_back(Entry(iter->first, iter->second, windows[iter->first]));
}
}
void
QmitkLevelWindowPresetDefinitionDialog::
PresetTableModel::getLevels(std::map<std::string, double>& levels)
{
for (std::vector<Entry>::iterator iter = m_Entries.begin(); iter != m_Entries.end(); ++iter)
{
levels[iter->name] = iter->level;
}
}
void
QmitkLevelWindowPresetDefinitionDialog::
PresetTableModel::getWindows(std::map<std::string, double>& windows)
{
for (std::vector<Entry>::iterator iter = m_Entries.begin(); iter != m_Entries.end(); ++iter)
{
windows[iter->name] = iter->window;
}
}
void
QmitkLevelWindowPresetDefinitionDialog::
PresetTableModel::addPreset(std::string& name, double level, double window)
{
this->beginInsertRows(QModelIndex(), (int) m_Entries.size(), (int) m_Entries.size());
m_Entries.push_back(Entry(name, level, window));
this->endInsertRows();
}
bool
QmitkLevelWindowPresetDefinitionDialog::
PresetTableModel::contains(std::string& name)
{
for (std::vector<Entry>::iterator iter = m_Entries.begin(); iter != m_Entries.end(); ++iter)
{
if (iter->name == name) return true;
}
return false;
}
void
QmitkLevelWindowPresetDefinitionDialog::
PresetTableModel::removePreset(const QModelIndex& index)
{
int row = index.row();
this->beginRemoveRows(QModelIndex(), row, row);
m_Entries.erase(m_Entries.begin()+row);
this->endRemoveRows();
}
void
QmitkLevelWindowPresetDefinitionDialog::
PresetTableModel::changePreset(int row, std::string& name, double level, double window)
{
m_Entries[row].name = name;
m_Entries[row].level = level;
m_Entries[row].window = window;
this->dataChanged(index(row, 0), index(row, 2));
}
QmitkLevelWindowPresetDefinitionDialog::PresetTableModel::Entry
QmitkLevelWindowPresetDefinitionDialog::
PresetTableModel::getPreset(const QModelIndex& index) const
{
int row = index.row();
if (row < 0 || (unsigned int)row >= m_Entries.size()) return Entry("", 0, 0);
return m_Entries[row];
}
int
QmitkLevelWindowPresetDefinitionDialog::
PresetTableModel::rowCount(const QModelIndex&) const
{
return (int) m_Entries.size();
}
int
QmitkLevelWindowPresetDefinitionDialog::
PresetTableModel::columnCount(const QModelIndex&) const
{
return 3;
}
QVariant
QmitkLevelWindowPresetDefinitionDialog::
PresetTableModel::data(const QModelIndex& index, int role) const
{
if (role == Qt::DisplayRole)
{
switch (index.column()) {
case 0:
return QVariant(QString(m_Entries[index.row()].name.c_str()));
case 1:
{
return QVariant(m_Entries[index.row()].level);
}
case 2:
return QVariant(m_Entries[index.row()].window);
}
}
return QVariant();
}
QVariant
QmitkLevelWindowPresetDefinitionDialog::
PresetTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role == Qt::DisplayRole && orientation == Qt::Horizontal)
{
switch (section) {
case 0: return QVariant("Preset");
case 1: return QVariant("Level");
case 2: return QVariant("Window");
}
}
return QVariant();
}
diff --git a/Modules/QtWidgets/QmitkMemoryUsageIndicatorView.cpp b/Modules/QtWidgets/QmitkMemoryUsageIndicatorView.cpp
index b5601f6a7a..e9136c41ae 100644
--- a/Modules/QtWidgets/QmitkMemoryUsageIndicatorView.cpp
+++ b/Modules/QtWidgets/QmitkMemoryUsageIndicatorView.cpp
@@ -1,150 +1,150 @@
/*===================================================================
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.
===================================================================*/
/****************************************************************************
** ui.h extension file, included from the uic-generated form implementation.
**
** If you want to add, delete, or rename functions or slots, use
** Qt Designer to update this file, preserving your code.
**
** You should not define a constructor or destructor in this file.
** Instead, write your code in functions called init() and destroy().
** These will automatically be called by the form's constructor and
** destructor.
*****************************************************************************/
#include "QmitkMemoryUsageIndicatorView.h"
#include <mitkMemoryUtilities.h>
#include <qtimer.h>
#include <qimage.h>
#include <qpixmap.h>
#include <qapplication.h>
#include <qeventloop.h>
#include <iostream>
#include <sstream>
#include <iomanip>
#include "QmitkMemoryUsageIndicatorImagesGreen.xpm"
#include "QmitkMemoryUsageIndicatorImagesYellow.xpm"
#include "QmitkMemoryUsageIndicatorImagesOrange.xpm"
#include "QmitkMemoryUsageIndicatorImagesRed.xpm"
QmitkMemoryUsageIndicatorView::QmitkMemoryUsageIndicatorView( QWidget * /*parent*/, Qt::WindowFlags /*f*/ )
{
this->setupUi(this);
QTimer *timer = new QTimer( this );
QObject::connect( timer, SIGNAL( timeout() ), this, SLOT( UpdateMemoryUsage() ) );
timer->start(1000);
- m_LEDGreen = QmitkMemoryUsageIndicatorImagesGreen_xpm;
- m_LEDYellow = QmitkMemoryUsageIndicatorImagesYellow_xpm;
- m_LEDOrange = QmitkMemoryUsageIndicatorImagesOrange_xpm;
- m_LEDRed = QmitkMemoryUsageIndicatorImagesRed_xpm;
+ m_LEDGreen = QPixmap(QmitkMemoryUsageIndicatorImagesGreen_xpm);
+ m_LEDYellow = QPixmap(QmitkMemoryUsageIndicatorImagesYellow_xpm);
+ m_LEDOrange = QPixmap(QmitkMemoryUsageIndicatorImagesOrange_xpm);
+ m_LEDRed = QPixmap(QmitkMemoryUsageIndicatorImagesRed_xpm);
m_LED->setPixmap(m_LEDGreen);
m_PreviousState = 0;
}
QmitkMemoryUsageIndicatorView::~QmitkMemoryUsageIndicatorView()
{
}
void QmitkMemoryUsageIndicatorView::UpdateMemoryUsage()
{
size_t processSize = mitk::MemoryUtilities::GetProcessMemoryUsage();
size_t totalSize = mitk::MemoryUtilities::GetTotalSizeOfPhysicalRam();
float percentage = ( (float) processSize / (float) totalSize ) * 100.0;
m_Label->setText( GetMemoryDescription( processSize, percentage ).c_str() );
if ( percentage < 50.0 )
{
if(m_PreviousState != 0)
{
m_LED->setPixmap(m_LEDGreen);
m_PreviousState = 0;
m_LED->update();
}
}
else if ( percentage < 65.0 )
{
if(m_PreviousState != 1)
{
m_LED->setPixmap(m_LEDYellow);
m_PreviousState = 1;
m_LED->update();
}
}
else if ( percentage < 80.0 )
{
if(m_PreviousState != 2)
{
m_LED->setPixmap(m_LEDOrange);
m_PreviousState = 2;
m_LED->update();
}
}
else
{
if(m_PreviousState != 3)
{
m_LED->setPixmap(m_LEDRed);
m_PreviousState = 3;
m_LED->update();
}
}
}
std::string QmitkMemoryUsageIndicatorView::FormatMemorySize( size_t size )
{
double val = size;
std::string descriptor("B");
if ( val >= 1000.0 )
{
val /= 1024.0;
descriptor = "KB";
}
if ( val >= 1000.0 )
{
val /= 1024.0;
descriptor = "MB";
}
if ( val >= 1000.0 )
{
val /= 1024.0;
descriptor = "GB";
}
std::ostringstream str;
str.imbue(std::locale::classic());
str << std::fixed << std::setprecision(2) << val << " " << descriptor;
return str.str();
}
std::string QmitkMemoryUsageIndicatorView::FormatPercentage( double val )
{
std::ostringstream str;
str.imbue(std::locale::classic());
str << std::fixed << std::setprecision(2) << val << " " << "%";
return str.str();
}
std::string QmitkMemoryUsageIndicatorView::GetMemoryDescription( size_t processSize, float percentage )
{
std::ostringstream str;
str.imbue(std::locale::classic());
str << FormatMemorySize(processSize) << " (" << FormatPercentage( percentage ) <<")" ;
return str.str();
}
diff --git a/Modules/QtWidgets/QmitkMouseModeSwitcher.cpp b/Modules/QtWidgets/QmitkMouseModeSwitcher.cpp
index 58d5d7023f..c1a34f749b 100644
--- a/Modules/QtWidgets/QmitkMouseModeSwitcher.cpp
+++ b/Modules/QtWidgets/QmitkMouseModeSwitcher.cpp
@@ -1,116 +1,116 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "QmitkMouseModeSwitcher.h"
-
+#include <QActionGroup>
QmitkMouseModeSwitcher::QmitkMouseModeSwitcher( QWidget* parent )
:QToolBar(parent)
,m_ActionGroup(new QActionGroup(this))
,m_MouseModeSwitcher(NULL)
,m_ObserverTag(0)
,m_InObservationReaction(false)
{
QToolBar::setOrientation( Qt::Vertical );
QToolBar::setIconSize( QSize(17, 17) );
m_ActionGroup->setExclusive(true); // only one selectable
addButton( mitk::MouseModeSwitcher::MousePointer, tr("Pointer"), QIcon(":/Qmitk/mm_pointer.png"), true ); // toggle ON
addButton( mitk::MouseModeSwitcher::Scroll, tr("Scroll"), QIcon(":/Qmitk/mm_scroll.png") );
addButton( mitk::MouseModeSwitcher::LevelWindow, tr("Level/Window"), QIcon(":/Qmitk/mm_contrast.png") );
addButton( mitk::MouseModeSwitcher::Zoom, tr("Zoom"), QIcon(":/Qmitk/mm_zoom.png") );
addButton( mitk::MouseModeSwitcher::Pan, tr("Pan"), QIcon(":/Qmitk/mm_pan.png") );
}
void QmitkMouseModeSwitcher::addButton( MouseMode id, const QString& toolName, const QIcon& icon, bool on)
{
QAction* action = new QAction( icon, toolName, this );
action->setCheckable(true);
action->setActionGroup(m_ActionGroup);
action->setChecked(on);
action->setData(id);
connect( action, SIGNAL(triggered()), this, SLOT(modeSelectedByUser()) );
QToolBar::addAction( action );
}
QmitkMouseModeSwitcher::~QmitkMouseModeSwitcher()
{
if (m_MouseModeSwitcher)
{
m_MouseModeSwitcher->RemoveObserver( m_ObserverTag );
}
}
void QmitkMouseModeSwitcher::setMouseModeSwitcher( mitk::MouseModeSwitcher* mms )
{
// goodbye / welcome ceremonies
if (m_MouseModeSwitcher)
{
m_MouseModeSwitcher->RemoveObserver( m_ObserverTag );
}
m_MouseModeSwitcher = mms;
if ( m_MouseModeSwitcher )
{
itk::ReceptorMemberCommand<QmitkMouseModeSwitcher>::Pointer command =
itk::ReceptorMemberCommand<QmitkMouseModeSwitcher>::New();
command->SetCallbackFunction(this, &QmitkMouseModeSwitcher::OnMouseModeChanged);
m_ObserverTag = m_MouseModeSwitcher->AddObserver( mitk::MouseModeSwitcher::MouseModeChangedEvent(), command );
}
}
void QmitkMouseModeSwitcher::modeSelectedByUser()
{
if (m_InObservationReaction) return; // this was NOT actually by the user but by ourselves
QAction* action = dynamic_cast<QAction*>(sender());
if (action)
{
MouseMode id = static_cast<MouseMode>( action->data().toInt() );
//qDebug() << "Mouse mode '" << qPrintable(action->text()) << "' selected, trigger mode id " << id;
if (m_MouseModeSwitcher)
{
m_MouseModeSwitcher->SelectMouseMode( id );
}
emit MouseModeSelected( id );
}
}
void QmitkMouseModeSwitcher::OnMouseModeChanged(const itk::EventObject&)
{
m_InObservationReaction = true;
// push button graphically
assert( m_MouseModeSwitcher );
MouseMode activeMode = m_MouseModeSwitcher->GetCurrentMouseMode();
foreach(QAction* action, m_ActionGroup->actions())
{
if ( action->data().toInt() == activeMode )
{
action->setChecked( true );
}
}
m_InObservationReaction = false;
}
diff --git a/Modules/QtWidgets/QmitkMouseModeSwitcher.h b/Modules/QtWidgets/QmitkMouseModeSwitcher.h
index 63f1e6a805..d56296ab5e 100644
--- a/Modules/QtWidgets/QmitkMouseModeSwitcher.h
+++ b/Modules/QtWidgets/QmitkMouseModeSwitcher.h
@@ -1,87 +1,88 @@
/*===================================================================
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 QmitkMouseModeSwitcher_h
#define QmitkMouseModeSwitcher_h
#include "MitkQtWidgetsExports.h"
#include "mitkMouseModeSwitcher.h"
-#include <QtGui>
+#include <QActionGroup>
+#include <QToolBar>
/**
* \ingroup QmitkModule
* \brief Qt toolbar representing mitk::MouseModeSwitcher.
*
* Provides buttons for the interaction modes defined in mitk::MouseModeSwitcher
* and communicates with this non-graphical class.
*
* Can be used in a GUI to provide a mouse mode selector to the user.
*/
class QMITK_EXPORT QmitkMouseModeSwitcher : public QToolBar
{
Q_OBJECT
public:
QmitkMouseModeSwitcher( QWidget* parent = 0 );
virtual ~QmitkMouseModeSwitcher();
typedef mitk::MouseModeSwitcher::MouseMode MouseMode;
public slots:
/**
\brief Connect to non-GUI class.
When a button is pressed, given mitk::MouseModeSwitcher is informed to adapt interactors.
\todo QmitkMouseModeSwitcher could be enhanced to actively observe mitk::MouseModeSwitcher and change available actions or visibility appropriately.
*/
void setMouseModeSwitcher( mitk::MouseModeSwitcher* );
signals:
/**
\brief Mode activated.
This signal is needed for other GUI element to react appropriately.
Sadly this is needed to provide "normal" functionality of QmitkStdMultiWidget,
because this must enable/disable automatic reaction of SliceNavigationControllers
to mouse clicks - depending on which mode is active.
*/
void MouseModeSelected(mitk::MouseModeSwitcher::MouseMode id); // TODO change int to enum of MouseModeSwitcher
protected slots:
void modeSelectedByUser();
void addButton( MouseMode id, const QString& toolName, const QIcon& icon, bool on = false ); // TODO change int to enum of MouseModeSwitcher
protected:
void OnMouseModeChanged(const itk::EventObject&);
QActionGroup* m_ActionGroup;
mitk::MouseModeSwitcher* m_MouseModeSwitcher;
unsigned long m_ObserverTag;
bool m_InObservationReaction;
};
#endif
diff --git a/Modules/QtWidgets/QmitkPropertiesTableEditor.cpp b/Modules/QtWidgets/QmitkPropertiesTableEditor.cpp
index 161c9329ae..5d88497b40 100644
--- a/Modules/QtWidgets/QmitkPropertiesTableEditor.cpp
+++ b/Modules/QtWidgets/QmitkPropertiesTableEditor.cpp
@@ -1,118 +1,122 @@
/*===================================================================
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 "QmitkPropertiesTableEditor.h"
#include "QmitkPropertiesTableModel.h"
#include "QmitkPropertyDelegate.h"
#include "mitkBaseRenderer.h"
#include "mitkFocusManager.h"
#include "mitkGlobalInteraction.h"
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QHeaderView>
#include <QTableView>
#include <QLineEdit>
#include <QLabel>
#include <vtkRenderWindow.h>
QmitkPropertiesTableEditor::QmitkPropertiesTableEditor(QWidget* parent
, Qt::WindowFlags f,mitk::DataNode::Pointer /*_Node*/)
: QWidget(parent, f)
, m_NodePropertiesTableView(0)
, m_Model(0)
{
// set up empty gui elements
this->init();
// set up model
m_Model = new QmitkPropertiesTableModel(m_NodePropertiesTableView, 0);
m_NodePropertiesTableView->setModel(m_Model);
}
QmitkPropertiesTableEditor::~QmitkPropertiesTableEditor()
{
}
void QmitkPropertiesTableEditor::SetPropertyList( mitk::PropertyList::Pointer _List )
{
if(_List.IsNotNull())
{
m_Model->SetPropertyList(_List);
m_NodePropertiesTableView->resizeColumnsToContents();
m_NodePropertiesTableView->resizeRowsToContents();
m_NodePropertiesTableView->horizontalHeader()->setStretchLastSection(true);
m_NodePropertiesTableView->setEditTriggers(QAbstractItemView::CurrentChanged);
}
else
{
m_Model->SetPropertyList(0);
}
}
QmitkPropertiesTableModel* QmitkPropertiesTableEditor::getModel() const
{
return m_Model;
}
void QmitkPropertiesTableEditor::init()
{
// read/ dim
QVBoxLayout* _NodePropertiesLayout = new QVBoxLayout;
QWidget* _PropertyFilterKeyWordPane = new QWidget(QWidget::parentWidget());
QHBoxLayout* _PropertyFilterKeyWordLayout = new QHBoxLayout;
QLabel* _LabelPropertyFilterKeyWord = new QLabel("Filter: ",_PropertyFilterKeyWordPane);
m_TxtPropertyFilterKeyWord = new QLineEdit(_PropertyFilterKeyWordPane);
m_NodePropertiesTableView = new QTableView(QWidget::parentWidget());
// write
setLayout(_NodePropertiesLayout);
_PropertyFilterKeyWordPane->setLayout(_PropertyFilterKeyWordLayout);
_PropertyFilterKeyWordLayout->setMargin(0);
_PropertyFilterKeyWordLayout->addWidget(_LabelPropertyFilterKeyWord);
_PropertyFilterKeyWordLayout->addWidget(m_TxtPropertyFilterKeyWord);
_NodePropertiesLayout->setMargin(0);
_NodePropertiesLayout->addWidget(_PropertyFilterKeyWordPane);
_NodePropertiesLayout->addWidget(m_NodePropertiesTableView);
m_NodePropertiesTableView->setSelectionMode( QAbstractItemView::SingleSelection );
m_NodePropertiesTableView->setSelectionBehavior( QAbstractItemView::SelectItems );
m_NodePropertiesTableView->verticalHeader()->hide();
m_NodePropertiesTableView->setItemDelegate(new QmitkPropertyDelegate(this));
m_NodePropertiesTableView->setAlternatingRowColors(true);
m_NodePropertiesTableView->setSortingEnabled(true);
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
m_NodePropertiesTableView->verticalHeader()->setResizeMode(QHeaderView::ResizeToContents);
+#else
+ m_NodePropertiesTableView->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
+#endif
QObject::connect( m_TxtPropertyFilterKeyWord, SIGNAL( textChanged(const QString &) )
, this, SLOT( PropertyFilterKeyWordTextChanged(const QString &) ) );
}
void QmitkPropertiesTableEditor::PropertyFilterKeyWordTextChanged( const QString & /*text*/ )
{
m_Model->SetFilterPropertiesKeyWord(m_TxtPropertyFilterKeyWord->text().toStdString());
}
QTableView* QmitkPropertiesTableEditor::getTable() const
{
return m_NodePropertiesTableView;
}
diff --git a/Modules/QtWidgets/QmitkPropertiesTableModel.cpp b/Modules/QtWidgets/QmitkPropertiesTableModel.cpp
index 57b267fda5..27824780dc 100644
--- a/Modules/QtWidgets/QmitkPropertiesTableModel.cpp
+++ b/Modules/QtWidgets/QmitkPropertiesTableModel.cpp
@@ -1,543 +1,545 @@
/*===================================================================
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 "QmitkPropertiesTableModel.h"
//# Own includes
#include "mitkStringProperty.h"
#include "mitkColorProperty.h"
#include "mitkProperties.h"
#include "mitkEnumerationProperty.h"
#include "mitkRenderingManager.h"
#include "QmitkCustomVariants.h"
//# Toolkit includes
#include <itkCommand.h>
#include <QColor>
#include <QBrush>
#include <QStringList>
//# PUBLIC CTORS,DTOR
QmitkPropertiesTableModel::QmitkPropertiesTableModel(QObject* parent, mitk::PropertyList::Pointer _PropertyList)
: QAbstractTableModel(parent)
, m_PropertyList(0)
, m_BlockEvents(false)
, m_SortDescending(false)
, m_FilterKeyWord("")
{
this->SetPropertyList(_PropertyList);
}
QmitkPropertiesTableModel::~QmitkPropertiesTableModel()
{
// remove all event listeners by setting the property list to 0
this->SetPropertyList(0);
}
//# PUBLIC GETTER
mitk::PropertyList::Pointer QmitkPropertiesTableModel::GetPropertyList() const
{
return m_PropertyList.GetPointer();
}
Qt::ItemFlags QmitkPropertiesTableModel::flags(const QModelIndex& index) const
{
// no editing so far, return default (enabled, selectable)
Qt::ItemFlags flags = QAbstractItemModel::flags(index);
if (index.column() == PROPERTY_VALUE_COLUMN)
{
// there are also read only property items -> do not allow editing them
if(index.data(Qt::EditRole).isValid())
flags |= Qt::ItemIsEditable;
if(index.data(Qt::CheckStateRole).isValid())
flags |= Qt::ItemIsUserCheckable;
}
return flags;
}
QVariant QmitkPropertiesTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role != Qt::DisplayRole)
return QVariant();
if (orientation == Qt::Horizontal) {
switch (section)
{
case PROPERTY_NAME_COLUMN:
return tr("Name");
case PROPERTY_VALUE_COLUMN:
return tr("Value");
default:
return QVariant();
}
}
return QVariant();
}
QVariant QmitkPropertiesTableModel::data(const QModelIndex& index, int role) const
{
// empty data by default
QVariant data;
if(!index.isValid() || m_SelectedProperties.empty() || index.row() > (int)(m_SelectedProperties.size()-1))
return data;
// the properties name
if(index.column() == PROPERTY_NAME_COLUMN)
{
if(role == Qt::DisplayRole)
data = QString::fromStdString(m_SelectedProperties[index.row()].first);
}
// the real properties value
else if(index.column() == PROPERTY_VALUE_COLUMN)
{
mitk::BaseProperty* baseProp = m_SelectedProperties[index.row()].second;
if (const mitk::ColorProperty* colorProp
= dynamic_cast<const mitk::ColorProperty*>(baseProp))
{
mitk::Color col = colorProp->GetColor();
QColor qcol((int)(col.GetRed() * 255), (int)(col.GetGreen() * 255),(int)( col.GetBlue() * 255));
if(role == Qt::DisplayRole)
data.setValue<QColor>(qcol);
else if(role == Qt::EditRole)
data.setValue<QColor>(qcol);
}
else if(mitk::BoolProperty* boolProp = dynamic_cast<mitk::BoolProperty*>(baseProp))
{
if(role == Qt::CheckStateRole)
data = boolProp->GetValue() ? Qt::Checked : Qt::Unchecked;
}
else if (mitk::StringProperty* stringProp = dynamic_cast<mitk::StringProperty*>(baseProp))
{
if(role == Qt::DisplayRole)
data.setValue<QString>(QString::fromStdString(stringProp->GetValue()));
else if(role == Qt::EditRole)
data.setValue<QString>(QString::fromStdString(stringProp->GetValue()));
}
else if (mitk::IntProperty* intProp = dynamic_cast<mitk::IntProperty*>(baseProp))
{
if(role == Qt::DisplayRole)
data.setValue<int>(intProp->GetValue());
else if(role == Qt::EditRole)
data.setValue<int>(intProp->GetValue());
}
else if (mitk::FloatProperty* floatProp = dynamic_cast<mitk::FloatProperty*>(baseProp))
{
if(role == Qt::DisplayRole)
data.setValue<float>(floatProp->GetValue());
else if(role == Qt::EditRole)
data.setValue<float>(floatProp->GetValue());
}
else if (mitk::EnumerationProperty* enumerationProp = dynamic_cast<mitk::EnumerationProperty*>(baseProp))
{
if(role == Qt::DisplayRole)
data.setValue<QString>(QString::fromStdString(baseProp->GetValueAsString()));
else if(role == Qt::EditRole)
{
QStringList values;
for(mitk::EnumerationProperty::EnumConstIterator it=enumerationProp->Begin(); it!=enumerationProp->End()
; it++)
{
values << QString::fromStdString(it->second);
}
data.setValue<QStringList>(values);
}
}
else
{
if(role == Qt::DisplayRole)
data.setValue<QString>(QString::fromStdString(m_SelectedProperties[index.row()].second->GetValueAsString()));
}
}
return data;
}
int QmitkPropertiesTableModel::rowCount(const QModelIndex& /*parent*/) const
{
// return the number of properties in the properties list.
return m_SelectedProperties.size();
}
int QmitkPropertiesTableModel::columnCount(const QModelIndex & /*parent*/)const
{
return 2;
}
//# PUBLIC SETTER
void QmitkPropertiesTableModel::SetPropertyList( mitk::PropertyList* _PropertyList )
{
// if propertylist really changed
if(m_PropertyList.GetPointer() != _PropertyList)
{
// Remove delete listener if there was a propertylist before
if(m_PropertyList.IsNotNull())
{
m_PropertyList.ObjectDelete.RemoveListener
(mitk::MessageDelegate1<QmitkPropertiesTableModel
, const itk::Object*>( this, &QmitkPropertiesTableModel::PropertyListDelete ));
}
// set new list
m_PropertyList = _PropertyList;
if(m_PropertyList.IsNotNull())
{
m_PropertyList.ObjectDelete.AddListener
(mitk::MessageDelegate1<QmitkPropertiesTableModel
, const itk::Object*>( this, &QmitkPropertiesTableModel::PropertyListDelete ));
}
this->Reset();
}
}
void QmitkPropertiesTableModel::PropertyListDelete( const itk::Object * /*_PropertyList*/ )
{
if(!m_BlockEvents)
{
m_BlockEvents = true;
this->Reset();
m_BlockEvents = false;
}
}
void QmitkPropertiesTableModel::PropertyModified( const itk::Object *caller, const itk::EventObject & /*event*/ )
{
if(!m_BlockEvents)
{
m_BlockEvents = true;
int row = this->FindProperty(dynamic_cast<const mitk::BaseProperty*>(caller));
QModelIndex indexOfChangedProperty = index(row, 1);
emit dataChanged(indexOfChangedProperty, indexOfChangedProperty);
m_BlockEvents = false;
}
}
void QmitkPropertiesTableModel::PropertyDelete( const itk::Object *caller, const itk::EventObject & /*event*/ )
{
if(!m_BlockEvents)
{
m_BlockEvents = true;
int row = this->FindProperty(dynamic_cast<const mitk::BaseProperty*>(caller));
if(row >= 0)
this->Reset();
m_BlockEvents = false;
}
}
bool QmitkPropertiesTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (index.isValid() && !m_SelectedProperties.empty() && index.row() < (int)(m_SelectedProperties.size())
&& (role == Qt::EditRole || Qt::CheckStateRole))
{
// block all events now!
m_BlockEvents = true;
// the properties name
if(index.column() == PROPERTY_VALUE_COLUMN)
{
mitk::BaseProperty* baseProp = m_SelectedProperties[index.row()].second;
if (mitk::ColorProperty* colorProp
= dynamic_cast<mitk::ColorProperty*>(baseProp))
{
QColor qcolor = value.value<QColor>();
if(!qcolor.isValid())
return false;
mitk::Color col = colorProp->GetColor();
col.SetRed(qcolor.red() / 255.0);
col.SetGreen(qcolor.green() / 255.0);
col.SetBlue(qcolor.blue() / 255.0);
colorProp->SetColor(col);
m_PropertyList->InvokeEvent(itk::ModifiedEvent());
m_PropertyList->Modified();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
else if(mitk::BoolProperty* boolProp = dynamic_cast<mitk::BoolProperty*>(baseProp))
{
boolProp->SetValue(value.toInt() == Qt::Checked ? true : false);
m_PropertyList->InvokeEvent(itk::ModifiedEvent());
m_PropertyList->Modified();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
else if (mitk::StringProperty* stringProp = dynamic_cast<mitk::StringProperty*>(baseProp))
{
stringProp->SetValue((value.value<QString>()).toStdString());
m_PropertyList->InvokeEvent(itk::ModifiedEvent());
m_PropertyList->Modified();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
else if (mitk::IntProperty* intProp = dynamic_cast<mitk::IntProperty*>(baseProp))
{
int intValue = value.value<int>();
if (intValue != intProp->GetValue())
{
intProp->SetValue(intValue);
m_PropertyList->InvokeEvent(itk::ModifiedEvent());
m_PropertyList->Modified();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
else if (mitk::FloatProperty* floatProp = dynamic_cast<mitk::FloatProperty*>(baseProp))
{
float floatValue = value.value<float>();
if (floatValue != floatProp->GetValue())
{
floatProp->SetValue(floatValue);
m_PropertyList->InvokeEvent(itk::ModifiedEvent());
m_PropertyList->Modified();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
else if (mitk::EnumerationProperty* enumerationProp = dynamic_cast<mitk::EnumerationProperty*>(baseProp))
{
std::string activatedItem = value.value<QString>().toStdString();
if ( activatedItem != enumerationProp->GetValueAsString() )
{
if ( enumerationProp->IsValidEnumerationValue( activatedItem ) )
{
enumerationProp->SetValue( activatedItem );
m_PropertyList->InvokeEvent( itk::ModifiedEvent() );
m_PropertyList->Modified();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
}
}
// property was changed by us, now we can accept property changes triggered by someone else
m_BlockEvents = false;
emit dataChanged(index, index);
return true;
}
return false;
}
void QmitkPropertiesTableModel::sort( int column, Qt::SortOrder order /*= Qt::AscendingOrder */ )
{
bool sortDescending = (order == Qt::DescendingOrder) ? true: false;
// do not sort twice !!! (dont know why, but qt calls this func twice. STUPID!)
if(sortDescending != m_SortDescending)
{
m_SortDescending = sortDescending;
PropertyDataSetCompareFunction::CompareCriteria _CompareCriteria
= PropertyDataSetCompareFunction::CompareByName;
PropertyDataSetCompareFunction::CompareOperator _CompareOperator
= m_SortDescending ? PropertyDataSetCompareFunction::Greater: PropertyDataSetCompareFunction::Less;
if(column == PROPERTY_VALUE_COLUMN)
_CompareCriteria = PropertyDataSetCompareFunction::CompareByValue;
PropertyDataSetCompareFunction compareFunc(_CompareCriteria, _CompareOperator);
std::sort(m_SelectedProperties.begin(), m_SelectedProperties.end(), compareFunc);
- QAbstractTableModel::reset();
+ QAbstractTableModel::beginResetModel();
+ QAbstractTableModel::endResetModel();
}
}
//# PROTECTED GETTER
int QmitkPropertiesTableModel::FindProperty( const mitk::BaseProperty* _Property ) const
{
int row = -1;
if(_Property)
{
// search for property that changed and emit datachanged on the corresponding ModelIndex
std::vector<PropertyDataSet >::const_iterator propertyIterator;
for( propertyIterator=m_SelectedProperties.begin(); propertyIterator!=m_SelectedProperties.end()
; propertyIterator++)
{
if(propertyIterator->second == _Property)
break;
}
if(propertyIterator != m_SelectedProperties.end())
row = std::distance(m_SelectedProperties.begin(), propertyIterator);
}
return row;
}
//# PROTECTED SETTER
void QmitkPropertiesTableModel::AddSelectedProperty( PropertyDataSet& _PropertyDataSet )
{
// subscribe for modified event
itk::MemberCommand<QmitkPropertiesTableModel>::Pointer _PropertyDataSetModifiedCommand =
itk::MemberCommand<QmitkPropertiesTableModel>::New();
_PropertyDataSetModifiedCommand->SetCallbackFunction(this, &QmitkPropertiesTableModel::PropertyModified);
m_PropertyModifiedObserverTags.push_back(_PropertyDataSet.second->AddObserver(itk::ModifiedEvent(), _PropertyDataSetModifiedCommand));
// subscribe for delete event
itk::MemberCommand<QmitkPropertiesTableModel>::Pointer _PropertyDataSetDeleteCommand =
itk::MemberCommand<QmitkPropertiesTableModel>::New();
_PropertyDataSetDeleteCommand->SetCallbackFunction(this, &QmitkPropertiesTableModel::PropertyDelete);
m_PropertyDeleteObserverTags.push_back(_PropertyDataSet.second->AddObserver(itk::DeleteEvent(), _PropertyDataSetDeleteCommand));
// add to the selection
m_SelectedProperties.push_back(_PropertyDataSet);
}
void QmitkPropertiesTableModel::RemoveSelectedProperty( unsigned int _Index )
{
PropertyDataSet& _PropertyDataSet = m_SelectedProperties.at(_Index);
// remove modified event listener
_PropertyDataSet.second->RemoveObserver(m_PropertyModifiedObserverTags[_Index]);
m_PropertyModifiedObserverTags.erase(m_PropertyModifiedObserverTags.begin()+_Index);
// remove delete event listener
_PropertyDataSet.second->RemoveObserver(m_PropertyDeleteObserverTags[_Index]);
m_PropertyDeleteObserverTags.erase(m_PropertyDeleteObserverTags.begin()+_Index);
// remove from selection
m_SelectedProperties.erase(m_SelectedProperties.begin()+_Index);
}
void QmitkPropertiesTableModel::Reset()
{
// remove all selected properties
while(!m_SelectedProperties.empty())
{
this->RemoveSelectedProperty(m_SelectedProperties.size()-1);
}
std::vector<PropertyDataSet> allPredicates;
if(m_PropertyList.IsNotNull())
{
// first of all: collect all properties from the list
for(mitk::PropertyList::PropertyMap::const_iterator it=m_PropertyList->GetMap()->begin()
; it!=m_PropertyList->GetMap()->end()
; it++)
{
allPredicates.push_back(*it); //% TODO
}
}
// make a subselection if a keyword is specified
if(!m_FilterKeyWord.empty())
{
std::vector<PropertyDataSet> subSelection;
for(std::vector<PropertyDataSet>::iterator it=allPredicates.begin()
; it!=allPredicates.end()
; it++)
{
// add this to the selection if it is matched by the keyword
if((*it).first.find(m_FilterKeyWord) != std::string::npos)
subSelection.push_back((*it));
}
allPredicates.clear();
allPredicates = subSelection;
}
PropertyDataSet tmpPropertyDataSet;
// add all selected now to the Model
for(std::vector<PropertyDataSet>::iterator it=allPredicates.begin()
; it!=allPredicates.end()
; it++)
{
tmpPropertyDataSet = *it;
this->AddSelectedProperty(tmpPropertyDataSet);
}
// sort the list as indicated by m_SortDescending
this->sort(m_SortDescending);
// model was resetted
- QAbstractTableModel::reset();
+ QAbstractTableModel::beginResetModel();
+ QAbstractTableModel::endResetModel();
}
void QmitkPropertiesTableModel::SetFilterPropertiesKeyWord( std::string _FilterKeyWord )
{
m_FilterKeyWord = _FilterKeyWord;
this->Reset();
}
QmitkPropertiesTableModel::PropertyDataSetCompareFunction::PropertyDataSetCompareFunction( CompareCriteria _CompareCriteria
, CompareOperator _CompareOperator )
: m_CompareCriteria(_CompareCriteria)
, m_CompareOperator(_CompareOperator)
{
}
bool QmitkPropertiesTableModel::PropertyDataSetCompareFunction::operator()
( const PropertyDataSet& _Left
, const PropertyDataSet& _Right ) const
{
switch(m_CompareCriteria)
{
case CompareByValue:
if(m_CompareOperator == Less)
return (_Left.second->GetValueAsString() < _Right.second->GetValueAsString());
else
return (_Left.second->GetValueAsString() > _Right.second->GetValueAsString());
break;
// CompareByName:
default:
if(m_CompareOperator == Less)
return (_Left.first < _Right.first);
else
return (_Left.first > _Right.first);
break;
}
}
QmitkPropertiesTableModel::PropertyListElementFilterFunction::PropertyListElementFilterFunction( const std::string& _FilterKeyWord )
: m_FilterKeyWord(_FilterKeyWord)
{
}
bool QmitkPropertiesTableModel::PropertyListElementFilterFunction::operator()( const PropertyDataSet& _Elem ) const
{
if(m_FilterKeyWord.empty())
return true;
return (_Elem.first.find(m_FilterKeyWord) == 0);
}
diff --git a/Modules/QtWidgets/QmitkRenderWindowMenu.cpp b/Modules/QtWidgets/QmitkRenderWindowMenu.cpp
index 2dfbedadc0..76b4986be9 100644
--- a/Modules/QtWidgets/QmitkRenderWindowMenu.cpp
+++ b/Modules/QtWidgets/QmitkRenderWindowMenu.cpp
@@ -1,1027 +1,1019 @@
/*===================================================================
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 "QmitkRenderWindowMenu.h"
#include "mitkResliceMethodProperty.h"
#include "mitkProperties.h"
#include <QHBoxLayout>
#include <QSpacerItem>
#include <QSize>
#include <QPainter>
#include<QGroupBox>
#include<QRadioButton>
#include<QAction>
#include<QLine>
#include<QLabel>
#include<QWidgetAction>
#include <QTimer>
#include "QmitkStdMultiWidget.h"
//#include"iconClose.xpm"
#include"iconFullScreen.xpm"
#include"iconCrosshairMode.xpm"
//#include"iconHoriSplit.xpm"
#include"iconSettings.xpm"
//#include"iconVertiSplit.xpm"
#include"iconLeaveFullScreen.xpm"
#include <math.h>
#ifdef QMITK_USE_EXTERNAL_RENDERWINDOW_MENU
QmitkRenderWindowMenu::QmitkRenderWindowMenu(QWidget *parent, Qt::WindowFlags f, mitk::BaseRenderer *b, QmitkStdMultiWidget* mw )
:QWidget(parent, Qt::Tool | Qt::FramelessWindowHint ),
#else
QmitkRenderWindowMenu::QmitkRenderWindowMenu(QWidget *parent, Qt::WindowFlags f, mitk::BaseRenderer *b, QmitkStdMultiWidget* mw )
:QWidget(parent,f),
#endif
m_Settings(NULL),
m_CrosshairMenu(NULL),
m_Layout(0),
m_LayoutDesign(0),
m_OldLayoutDesign(0),
m_FullScreenMode(false),
m_Entered(false),
m_Hidden(true),
m_Renderer(b),
m_MultiWidget(mw)
{
MITK_DEBUG << "creating renderwindow menu on baserenderer " << b;
//Create Menu Widget
this->CreateMenuWidget();
this->setMinimumWidth(61); //DIRTY.. If you add or remove a button, you need to change the size.
this->setMaximumWidth(61);
this->setAutoFillBackground( true );
//Else part fixes the render window menu issue on Linux bug but caused bugs on Mac OS and Windows
//for Mac OS see bug 3192
//for Windows see bug 12130
//... so Mac OS and Windows must be treated differently:
#if defined(Q_OS_MAC) || defined(_WIN32)
this->show();
this->setWindowOpacity(0.0f);
#else
this->setVisible(false);
#endif
//this->setAttribute( Qt::WA_NoSystemBackground );
//this->setBackgroundRole( QPalette::Dark );
//this->update();
//SetOpacity -- its just posible if the widget is a window.
//Windows indicates that the widget is a window, usually with a window system frame and a title bar,
//irrespective of whether the widget has a parent or not.
/*
this->setWindowFlags( Qt::Window | Qt::FramelessWindowHint);
*/
//this->setAttribute(Qt::WA_TranslucentBackground);
//this->setWindowOpacity(0.75);
currentCrosshairRotationMode = 0;
// for autorotating
m_AutoRotationTimer.setInterval( 75 );
connect( &m_AutoRotationTimer, SIGNAL(timeout()), this, SLOT(AutoRotateNextStep()) );
}
QmitkRenderWindowMenu::~QmitkRenderWindowMenu()
{
if( m_AutoRotationTimer.isActive() )
m_AutoRotationTimer.stop();
}
void QmitkRenderWindowMenu::CreateMenuWidget()
{
QHBoxLayout* layout = new QHBoxLayout(this);
layout->setAlignment( Qt::AlignRight );
layout->setContentsMargins(1,1,1,1);
QSize size( 13, 13 );
m_CrosshairMenu = new QMenu(this);
connect( m_CrosshairMenu, SIGNAL( aboutToShow() ), this, SLOT(OnCrossHairMenuAboutToShow()) );
// button for changing rotation mode
m_CrosshairModeButton = new QPushButton(this);
m_CrosshairModeButton->setMaximumSize(15, 15);
m_CrosshairModeButton->setIconSize(size);
m_CrosshairModeButton->setFlat( true );
m_CrosshairModeButton->setMenu( m_CrosshairMenu );
- m_CrosshairModeButton->setIcon( QIcon( iconCrosshairMode_xpm ) );
+ m_CrosshairModeButton->setIcon(QIcon(QPixmap(iconCrosshairMode_xpm)));
layout->addWidget( m_CrosshairModeButton );
//fullScreenButton
m_FullScreenButton = new QPushButton(this);
m_FullScreenButton->setMaximumSize(15, 15);
m_FullScreenButton->setIconSize(size);
m_FullScreenButton->setFlat( true );
- m_FullScreenButton->setIcon( QIcon( iconFullScreen_xpm ));
+ m_FullScreenButton->setIcon(QIcon(QPixmap(iconFullScreen_xpm)));
layout->addWidget( m_FullScreenButton );
//settingsButton
m_SettingsButton = new QPushButton(this);
m_SettingsButton->setMaximumSize(15, 15);
m_SettingsButton->setIconSize(size);
m_SettingsButton->setFlat( true );
- m_SettingsButton->setIcon( QIcon( iconSettings_xpm ));
+ m_SettingsButton->setIcon(QIcon(QPixmap(iconSettings_xpm)));
layout->addWidget( m_SettingsButton );
//Create Connections -- coming soon?
connect( m_FullScreenButton, SIGNAL( clicked(bool) ), this, SLOT(OnFullScreenButton(bool)) );
connect( m_SettingsButton, SIGNAL( clicked(bool) ), this, SLOT(OnSettingsButton(bool)) );
}
void QmitkRenderWindowMenu::CreateSettingsWidget()
{
m_Settings = new QMenu(this);
m_DefaultLayoutAction = new QAction( "standard layout", m_Settings );
m_DefaultLayoutAction->setDisabled( true );
m_2DImagesUpLayoutAction = new QAction( "2D images top, 3D bottom", m_Settings );
m_2DImagesUpLayoutAction->setDisabled( false );
m_2DImagesLeftLayoutAction = new QAction( "2D images left, 3D right", m_Settings );
m_2DImagesLeftLayoutAction->setDisabled( false );
m_Big3DLayoutAction = new QAction( "Big 3D", m_Settings );
m_Big3DLayoutAction->setDisabled( false );
m_Widget1LayoutAction = new QAction( "Axial plane", m_Settings );
m_Widget1LayoutAction->setDisabled( false );
m_Widget2LayoutAction = new QAction( "Sagittal plane", m_Settings );
m_Widget2LayoutAction->setDisabled( false );
m_Widget3LayoutAction = new QAction( "Coronal plane", m_Settings );
m_Widget3LayoutAction->setDisabled( false );
m_RowWidget3And4LayoutAction = new QAction( "Coronal top, 3D bottom", m_Settings );
m_RowWidget3And4LayoutAction->setDisabled( false );
m_ColumnWidget3And4LayoutAction = new QAction( "Coronal left, 3D right", m_Settings );
m_ColumnWidget3And4LayoutAction->setDisabled( false );
m_SmallUpperWidget2Big3and4LayoutAction = new QAction( "Sagittal top, Coronal n 3D bottom", m_Settings );
m_SmallUpperWidget2Big3and4LayoutAction->setDisabled( false );
m_2x2Dand3DWidgetLayoutAction = new QAction( "Axial n Sagittal left, 3D right", m_Settings );
m_2x2Dand3DWidgetLayoutAction->setDisabled( false );
m_Left2Dand3DRight2DLayoutAction = new QAction( "Axial n 3D left, Sagittal right", m_Settings );
m_Left2Dand3DRight2DLayoutAction->setDisabled( false );
m_Settings->addAction(m_DefaultLayoutAction);
m_Settings->addAction(m_2DImagesUpLayoutAction);
m_Settings->addAction(m_2DImagesLeftLayoutAction);
m_Settings->addAction(m_Big3DLayoutAction);
m_Settings->addAction(m_Widget1LayoutAction);
m_Settings->addAction(m_Widget2LayoutAction);
m_Settings->addAction(m_Widget3LayoutAction);
m_Settings->addAction(m_RowWidget3And4LayoutAction);
m_Settings->addAction(m_ColumnWidget3And4LayoutAction);
m_Settings->addAction(m_SmallUpperWidget2Big3and4LayoutAction);
m_Settings->addAction(m_2x2Dand3DWidgetLayoutAction);
m_Settings->addAction(m_Left2Dand3DRight2DLayoutAction);
m_Settings->setVisible( false );
connect( m_DefaultLayoutAction, SIGNAL( triggered(bool) ), this, SLOT(OnChangeLayoutToDefault(bool)) );
connect( m_2DImagesUpLayoutAction, SIGNAL( triggered(bool) ), this, SLOT(OnChangeLayoutTo2DImagesUp(bool)) );
connect( m_2DImagesLeftLayoutAction, SIGNAL( triggered(bool) ), this, SLOT(OnChangeLayoutTo2DImagesLeft(bool)) );
connect( m_Big3DLayoutAction, SIGNAL( triggered(bool) ), this, SLOT(OnChangeLayoutToBig3D(bool)) );
connect( m_Widget1LayoutAction, SIGNAL( triggered(bool) ), this, SLOT(OnChangeLayoutToWidget1(bool)) );
connect( m_Widget2LayoutAction, SIGNAL( triggered(bool) ), this, SLOT(OnChangeLayoutToWidget2(bool)) );
connect( m_Widget3LayoutAction , SIGNAL( triggered(bool) ), this, SLOT(OnChangeLayoutToWidget3(bool)) );
connect( m_RowWidget3And4LayoutAction, SIGNAL( triggered(bool) ), this, SLOT(OnChangeLayoutToRowWidget3And4(bool)) );
connect( m_ColumnWidget3And4LayoutAction, SIGNAL( triggered(bool) ), this, SLOT(OnChangeLayoutToColumnWidget3And4(bool)) );
connect( m_SmallUpperWidget2Big3and4LayoutAction, SIGNAL( triggered(bool) ), this, SLOT(OnChangeLayoutToSmallUpperWidget2Big3and4(bool)) );
connect( m_2x2Dand3DWidgetLayoutAction, SIGNAL( triggered(bool) ), this, SLOT(OnChangeLayoutTo2x2Dand3DWidget(bool)) );
connect( m_Left2Dand3DRight2DLayoutAction, SIGNAL( triggered(bool) ), this, SLOT(OnChangeLayoutToLeft2Dand3DRight2D(bool)) );
}
void QmitkRenderWindowMenu::paintEvent( QPaintEvent* /*e*/ )
{
QPainter painter(this);
QColor semiTransparentColor = Qt::black;
semiTransparentColor.setAlpha(255);
painter.fillRect(rect(), semiTransparentColor);
}
void QmitkRenderWindowMenu::SetLayoutIndex( unsigned int layoutIndex )
{
m_Layout = layoutIndex;
}
void QmitkRenderWindowMenu::HideMenu( )
{
MITK_DEBUG << "menu hideEvent";
m_Hidden = true;
if( ! m_Entered )
{
//Else part fixes the render window menu issue on Linux bug but caused bugs on Mac OS and Windows
//for Mac OS see bug 3192
//for Windows see bug 12130
//... so Mac OS and Windows must be treated differently:
#if defined(Q_OS_MAC) || defined(_WIN32)
this->setWindowOpacity(0.0f);
#else
this->setVisible(false);
#endif
}
}
void QmitkRenderWindowMenu::ShowMenu( )
{
MITK_DEBUG << "menu showMenu";
m_Hidden = false;
//Else part fixes the render window menu issue on Linux bug but caused bugs on Mac OS and Windows
//for Mac OS see bug 3192
//for Windows see bug 12130
//... so Mac OS and Windows must be treated differently:
#if defined(Q_OS_MAC) || defined(_WIN32)
this->setWindowOpacity(1.0f);
#else
this->setVisible(true);
#endif
}
void QmitkRenderWindowMenu::enterEvent( QEvent * /*e*/ )
{
MITK_DEBUG << "menu enterEvent";
m_Entered=true;
m_Hidden=false;
}
void QmitkRenderWindowMenu::DeferredHideMenu( )
{
MITK_DEBUG << "menu deferredhidemenu";
if(m_Hidden)
{
//Else part fixes the render window menu issue on Linux bug but caused bugs on Mac OS and Windows
//for Mac OS see bug 3192
//for Windows see bug 12130
//... so Mac OS and Windows must be treated differently:
#if defined(Q_OS_MAC) || defined(_WIN32)
this->setWindowOpacity(0.0f);
#else
this->setVisible(false);
#endif
}
// setVisible(false);
// setWindowOpacity(0.0f);
///hide();
}
void QmitkRenderWindowMenu::leaveEvent( QEvent * /*e*/ )
{
MITK_DEBUG << "menu leaveEvent";
smoothHide();
}
/* This method is responsible for non fluttering of
the renderWindowMenu when mouse cursor moves along the renderWindowMenu*/
void QmitkRenderWindowMenu::smoothHide()
{
MITK_DEBUG<< "menu leaveEvent";
m_Entered=false;
m_Hidden = true;
QTimer::singleShot(10,this,SLOT( DeferredHideMenu( ) ) );
}
void QmitkRenderWindowMenu::ChangeFullScreenMode( bool state )
{
this->OnFullScreenButton( state );
}
/// \brief
void QmitkRenderWindowMenu::OnFullScreenButton( bool /*checked*/ )
{
if( !m_FullScreenMode )
{
m_FullScreenMode = true;
m_OldLayoutDesign = m_LayoutDesign;
switch( m_Layout )
{
case AXIAL:
{
emit SignalChangeLayoutDesign( LAYOUT_AXIAL );
break;
}
case SAGITTAL:
{
emit SignalChangeLayoutDesign( LAYOUT_SAGITTAL );
break;
}
case CORONAL:
{
emit SignalChangeLayoutDesign( LAYOUT_CORONAL );
break;
}
case THREE_D:
{
emit SignalChangeLayoutDesign( LAYOUT_BIG3D );
break;
}
}
//Move Widget and show again
this->MoveWidgetToCorrectPos(1.0f);
//change icon
this->ChangeFullScreenIcon();
}
else
{
m_FullScreenMode = false;
emit SignalChangeLayoutDesign( m_OldLayoutDesign );
//Move Widget and show again
this->MoveWidgetToCorrectPos(1.0f);
//change icon
this->ChangeFullScreenIcon();
}
DeferredShowMenu( );
}
/// \brief
void QmitkRenderWindowMenu::OnSettingsButton( bool /*checked*/ )
{
if( m_Settings == NULL )
this->CreateSettingsWidget();
QPoint point = this->mapToGlobal( m_SettingsButton->geometry().topLeft() );
m_Settings->setVisible( true );
m_Settings->exec( point );
}
void QmitkRenderWindowMenu::OnChangeLayoutTo2DImagesUp(bool)
{
//set Full Screen Mode to false, if Layout Design was changed by the LayoutDesign_List
m_FullScreenMode = false;
this->ChangeFullScreenIcon();
m_LayoutDesign = LAYOUT_2DIMAGEUP;
emit SignalChangeLayoutDesign( LAYOUT_2DIMAGEUP );
DeferredShowMenu( );
}
void QmitkRenderWindowMenu::OnChangeLayoutTo2DImagesLeft(bool)
{
//set Full Screen Mode to false, if Layout Design was changed by the LayoutDesign_List
m_FullScreenMode = false;
this->ChangeFullScreenIcon();
m_LayoutDesign = LAYOUT_2DIMAGELEFT;
emit SignalChangeLayoutDesign( LAYOUT_2DIMAGELEFT );
DeferredShowMenu( );
}
void QmitkRenderWindowMenu::OnChangeLayoutToDefault(bool)
{
//set Full Screen Mode to false, if Layout Design was changed by the LayoutDesign_List
m_FullScreenMode = false;
this->ChangeFullScreenIcon();
m_LayoutDesign = LAYOUT_DEFAULT;
emit SignalChangeLayoutDesign( LAYOUT_DEFAULT );
DeferredShowMenu( );
}
void QmitkRenderWindowMenu::DeferredShowMenu()
{
MITK_DEBUG << "deferred show menu";
//Else part fixes the render window menu issue on Linux bug but caused bugs on Mac OS and Windows
//for Mac OS see bug 3192
//for Windows see bug 12130
//... so Mac OS and Windows must be treated differently:
#if defined(Q_OS_MAC) || defined(_WIN32)
this->setWindowOpacity(1.0f);
#else
this->setVisible(true);
#endif
}
void QmitkRenderWindowMenu::OnChangeLayoutToBig3D(bool)
{
MITK_DEBUG << "OnChangeLayoutToBig3D";
//set Full Screen Mode to false, if Layout Design was changed by the LayoutDesign_List
m_FullScreenMode = false;
this->ChangeFullScreenIcon();
m_LayoutDesign = LAYOUT_BIG3D;
emit SignalChangeLayoutDesign( LAYOUT_BIG3D );
DeferredShowMenu( );
}
void QmitkRenderWindowMenu::OnChangeLayoutToWidget1(bool)
{
//set Full Screen Mode to false, if Layout Design was changed by the LayoutDesign_List
m_FullScreenMode = false;
this->ChangeFullScreenIcon();
m_LayoutDesign = LAYOUT_AXIAL;
emit SignalChangeLayoutDesign( LAYOUT_AXIAL );
DeferredShowMenu( );
}
void QmitkRenderWindowMenu::OnChangeLayoutToWidget2(bool)
{
//set Full Screen Mode to false, if Layout Design was changed by the LayoutDesign_List
m_FullScreenMode = false;
this->ChangeFullScreenIcon();
m_LayoutDesign = LAYOUT_SAGITTAL;
emit SignalChangeLayoutDesign( LAYOUT_SAGITTAL );
DeferredShowMenu( );
}
void QmitkRenderWindowMenu::OnChangeLayoutToWidget3(bool)
{
//set Full Screen Mode to false, if Layout Design was changed by the LayoutDesign_List
m_FullScreenMode = false;
this->ChangeFullScreenIcon();
m_LayoutDesign = LAYOUT_CORONAL;
emit SignalChangeLayoutDesign( LAYOUT_CORONAL );
DeferredShowMenu( );
}
void QmitkRenderWindowMenu::OnChangeLayoutToRowWidget3And4(bool)
{
//set Full Screen Mode to false, if Layout Design was changed by the LayoutDesign_List
m_FullScreenMode = false;
this->ChangeFullScreenIcon();
m_LayoutDesign = LAYOUT_ROWWIDGET3AND4;
emit SignalChangeLayoutDesign( LAYOUT_ROWWIDGET3AND4 );
DeferredShowMenu( );
}
void QmitkRenderWindowMenu::OnChangeLayoutToColumnWidget3And4(bool)
{
//set Full Screen Mode to false, if Layout Design was changed by the LayoutDesign_List
m_FullScreenMode = false;
this->ChangeFullScreenIcon();
m_LayoutDesign = LAYOUT_COLUMNWIDGET3AND4;
emit SignalChangeLayoutDesign( LAYOUT_COLUMNWIDGET3AND4 );
DeferredShowMenu( );
}
void QmitkRenderWindowMenu::OnChangeLayoutToSmallUpperWidget2Big3and4(bool)
{
//set Full Screen Mode to false, if Layout Design was changed by the LayoutDesign_List
m_FullScreenMode = false;
this->ChangeFullScreenIcon();
m_LayoutDesign = LAYOUT_SMALLUPPERWIDGET2BIGAND4;
emit SignalChangeLayoutDesign( LAYOUT_SMALLUPPERWIDGET2BIGAND4 );
DeferredShowMenu( );
}
void QmitkRenderWindowMenu::OnChangeLayoutTo2x2Dand3DWidget(bool)
{
//set Full Screen Mode to false, if Layout Design was changed by the LayoutDesign_List
m_FullScreenMode = false;
this->ChangeFullScreenIcon();
m_LayoutDesign = LAYOUT_2X2DAND3DWIDGET;
emit SignalChangeLayoutDesign( LAYOUT_2X2DAND3DWIDGET );
DeferredShowMenu( );
}
void QmitkRenderWindowMenu::OnChangeLayoutToLeft2Dand3DRight2D(bool)
{
//set Full Screen Mode to false, if Layout Design was changed by the LayoutDesign_List
m_FullScreenMode = false;
this->ChangeFullScreenIcon();
m_LayoutDesign = LAYOUT_LEFT2DAND3DRIGHT2D;
emit SignalChangeLayoutDesign( LAYOUT_LEFT2DAND3DRIGHT2D );
DeferredShowMenu( );
}
void QmitkRenderWindowMenu::UpdateLayoutDesignList( int layoutDesignIndex )
{
m_LayoutDesign = layoutDesignIndex;
if( m_Settings == NULL )
this->CreateSettingsWidget();
switch( m_LayoutDesign )
{
case LAYOUT_DEFAULT:
{
m_DefaultLayoutAction->setEnabled(false);
m_2DImagesUpLayoutAction->setEnabled(true);
m_2DImagesLeftLayoutAction->setEnabled(true);
m_Big3DLayoutAction->setEnabled(true);
m_Widget1LayoutAction->setEnabled(true);
m_Widget2LayoutAction->setEnabled(true);
m_Widget3LayoutAction->setEnabled(true);
m_RowWidget3And4LayoutAction->setEnabled(true);
m_ColumnWidget3And4LayoutAction->setEnabled(true);
m_SmallUpperWidget2Big3and4LayoutAction->setEnabled(true);
m_2x2Dand3DWidgetLayoutAction->setEnabled(true);
m_Left2Dand3DRight2DLayoutAction->setEnabled(true);
break;
}
case LAYOUT_2DIMAGEUP:
{
m_DefaultLayoutAction->setEnabled(true);
m_2DImagesUpLayoutAction->setEnabled(false);
m_2DImagesLeftLayoutAction->setEnabled(true);
m_Big3DLayoutAction->setEnabled(true);
m_Widget1LayoutAction->setEnabled(true);
m_Widget2LayoutAction->setEnabled(true);
m_Widget3LayoutAction->setEnabled(true);
m_RowWidget3And4LayoutAction->setEnabled(true);
m_ColumnWidget3And4LayoutAction->setEnabled(true);
m_SmallUpperWidget2Big3and4LayoutAction->setEnabled(true);
m_2x2Dand3DWidgetLayoutAction->setEnabled(true);
m_Left2Dand3DRight2DLayoutAction->setEnabled(true);
break;
}
case LAYOUT_2DIMAGELEFT:
{
m_DefaultLayoutAction->setEnabled(true);
m_2DImagesUpLayoutAction->setEnabled(true);
m_2DImagesLeftLayoutAction->setEnabled(false);
m_Big3DLayoutAction->setEnabled(true);
m_Widget1LayoutAction->setEnabled(true);
m_Widget2LayoutAction->setEnabled(true);
m_Widget3LayoutAction->setEnabled(true);
m_RowWidget3And4LayoutAction->setEnabled(true);
m_ColumnWidget3And4LayoutAction->setEnabled(true);
m_SmallUpperWidget2Big3and4LayoutAction->setEnabled(true);
m_2x2Dand3DWidgetLayoutAction->setEnabled(true);
m_Left2Dand3DRight2DLayoutAction->setEnabled(true);
break;
}
case LAYOUT_BIG3D:
{
m_DefaultLayoutAction->setEnabled(true);
m_2DImagesUpLayoutAction->setEnabled(true);
m_2DImagesLeftLayoutAction->setEnabled(true);
m_Big3DLayoutAction->setEnabled(false);
m_Widget1LayoutAction->setEnabled(true);
m_Widget2LayoutAction->setEnabled(true);
m_Widget3LayoutAction->setEnabled(true);
m_RowWidget3And4LayoutAction->setEnabled(true);
m_ColumnWidget3And4LayoutAction->setEnabled(true);
m_SmallUpperWidget2Big3and4LayoutAction->setEnabled(true);
m_2x2Dand3DWidgetLayoutAction->setEnabled(true);
m_Left2Dand3DRight2DLayoutAction->setEnabled(true);
break;
}
case LAYOUT_AXIAL:
{
m_DefaultLayoutAction->setEnabled(true);
m_2DImagesUpLayoutAction->setEnabled(true);
m_2DImagesLeftLayoutAction->setEnabled(true);
m_Big3DLayoutAction->setEnabled(true);
m_Widget1LayoutAction->setEnabled(false);
m_Widget2LayoutAction->setEnabled(true);
m_Widget3LayoutAction->setEnabled(true);
m_RowWidget3And4LayoutAction->setEnabled(true);
m_ColumnWidget3And4LayoutAction->setEnabled(true);
m_SmallUpperWidget2Big3and4LayoutAction->setEnabled(true);
m_2x2Dand3DWidgetLayoutAction->setEnabled(true);
m_Left2Dand3DRight2DLayoutAction->setEnabled(true);
break;
}
case LAYOUT_SAGITTAL:
{
m_DefaultLayoutAction->setEnabled(true);
m_2DImagesUpLayoutAction->setEnabled(true);
m_2DImagesLeftLayoutAction->setEnabled(true);
m_Big3DLayoutAction->setEnabled(true);
m_Widget1LayoutAction->setEnabled(true);
m_Widget2LayoutAction->setEnabled(false);
m_Widget3LayoutAction->setEnabled(true);
m_RowWidget3And4LayoutAction->setEnabled(true);
m_ColumnWidget3And4LayoutAction->setEnabled(true);
m_SmallUpperWidget2Big3and4LayoutAction->setEnabled(true);
m_2x2Dand3DWidgetLayoutAction->setEnabled(true);
m_Left2Dand3DRight2DLayoutAction->setEnabled(true);
break;
}
case LAYOUT_CORONAL:
{
m_DefaultLayoutAction->setEnabled(true);
m_2DImagesUpLayoutAction->setEnabled(true);
m_2DImagesLeftLayoutAction->setEnabled(true);
m_Big3DLayoutAction->setEnabled(true);
m_Widget1LayoutAction->setEnabled(true);
m_Widget2LayoutAction->setEnabled(true);
m_Widget3LayoutAction->setEnabled(false);
m_RowWidget3And4LayoutAction->setEnabled(true);
m_ColumnWidget3And4LayoutAction->setEnabled(true);
m_SmallUpperWidget2Big3and4LayoutAction->setEnabled(true);
m_2x2Dand3DWidgetLayoutAction->setEnabled(true);
m_Left2Dand3DRight2DLayoutAction->setEnabled(true);
break;
}
case LAYOUT_2X2DAND3DWIDGET:
{
m_DefaultLayoutAction->setEnabled(true);
m_2DImagesUpLayoutAction->setEnabled(true);
m_2DImagesLeftLayoutAction->setEnabled(true);
m_Big3DLayoutAction->setEnabled(true);
m_Widget1LayoutAction->setEnabled(true);
m_Widget2LayoutAction->setEnabled(true);
m_Widget3LayoutAction->setEnabled(true);
m_RowWidget3And4LayoutAction->setEnabled(true);
m_ColumnWidget3And4LayoutAction->setEnabled(true);
m_SmallUpperWidget2Big3and4LayoutAction->setEnabled(true);
m_2x2Dand3DWidgetLayoutAction->setEnabled(false);
m_Left2Dand3DRight2DLayoutAction->setEnabled(true);
break;
}
case LAYOUT_ROWWIDGET3AND4:
{
m_DefaultLayoutAction->setEnabled(true);
m_2DImagesUpLayoutAction->setEnabled(true);
m_2DImagesLeftLayoutAction->setEnabled(true);
m_Big3DLayoutAction->setEnabled(true);
m_Widget1LayoutAction->setEnabled(true);
m_Widget2LayoutAction->setEnabled(true);
m_Widget3LayoutAction->setEnabled(true);
m_RowWidget3And4LayoutAction->setEnabled(false);
m_ColumnWidget3And4LayoutAction->setEnabled(true);
m_SmallUpperWidget2Big3and4LayoutAction->setEnabled(true);
m_2x2Dand3DWidgetLayoutAction->setEnabled(true);
m_Left2Dand3DRight2DLayoutAction->setEnabled(true);
break;
}
case LAYOUT_COLUMNWIDGET3AND4:
{
m_DefaultLayoutAction->setEnabled(true);
m_2DImagesUpLayoutAction->setEnabled(true);
m_2DImagesLeftLayoutAction->setEnabled(true);
m_Big3DLayoutAction->setEnabled(true);
m_Widget1LayoutAction->setEnabled(true);
m_Widget2LayoutAction->setEnabled(true);
m_Widget3LayoutAction->setEnabled(true);
m_RowWidget3And4LayoutAction->setEnabled(true);
m_ColumnWidget3And4LayoutAction->setEnabled(false);
m_SmallUpperWidget2Big3and4LayoutAction->setEnabled(true);
m_2x2Dand3DWidgetLayoutAction->setEnabled(true);
m_Left2Dand3DRight2DLayoutAction->setEnabled(true);
break;
}
case LAYOUT_SMALLUPPERWIDGET2BIGAND4:
{
m_DefaultLayoutAction->setEnabled(true);
m_2DImagesUpLayoutAction->setEnabled(true);
m_2DImagesLeftLayoutAction->setEnabled(true);
m_Big3DLayoutAction->setEnabled(true);
m_Widget1LayoutAction->setEnabled(true);
m_Widget2LayoutAction->setEnabled(true);
m_Widget3LayoutAction->setEnabled(true);
m_RowWidget3And4LayoutAction->setEnabled(true);
m_ColumnWidget3And4LayoutAction->setEnabled(true);
m_SmallUpperWidget2Big3and4LayoutAction->setEnabled(false);
m_2x2Dand3DWidgetLayoutAction->setEnabled(true);
m_Left2Dand3DRight2DLayoutAction->setEnabled(true);
break;
}
case LAYOUT_LEFT2DAND3DRIGHT2D:
{
m_DefaultLayoutAction->setEnabled(true);
m_2DImagesUpLayoutAction->setEnabled(true);
m_2DImagesLeftLayoutAction->setEnabled(true);
m_Big3DLayoutAction->setEnabled(true);
m_Widget1LayoutAction->setEnabled(true);
m_Widget2LayoutAction->setEnabled(true);
m_Widget3LayoutAction->setEnabled(true);
m_RowWidget3And4LayoutAction->setEnabled(true);
m_ColumnWidget3And4LayoutAction->setEnabled(true);
m_SmallUpperWidget2Big3and4LayoutAction->setEnabled(true);
m_2x2Dand3DWidgetLayoutAction->setEnabled(true);
m_Left2Dand3DRight2DLayoutAction->setEnabled(false);
break;
}
}
}
#ifdef QMITK_USE_EXTERNAL_RENDERWINDOW_MENU
void QmitkRenderWindowMenu::MoveWidgetToCorrectPos(float opacity)
#else
void QmitkRenderWindowMenu::MoveWidgetToCorrectPos(float /*opacity*/)
#endif
{
#ifdef QMITK_USE_EXTERNAL_RENDERWINDOW_MENU
int X=floor( double(this->parentWidget()->width() - this->width() - 8.0) );
int Y=7;
QPoint pos = this->parentWidget()->mapToGlobal( QPoint(0,0) );
this->move( X+pos.x(), Y+pos.y() );
if(opacity<0) opacity=0;
else if(opacity>1) opacity=1;
this->setWindowOpacity(opacity);
#else
int moveX= floor( double(this->parentWidget()->width() - this->width() - 4.0) );
this->move( moveX, 3 );
this->show();
#endif
}
void QmitkRenderWindowMenu::ChangeFullScreenIcon()
{
-
- if( m_FullScreenMode )
- {
- const QIcon icon( iconLeaveFullScreen_xpm );
- m_FullScreenButton->setIcon(icon);
- }
- else
- {
- const QIcon icon( iconFullScreen_xpm );
- m_FullScreenButton->setIcon(icon);
- }
+ m_FullScreenButton->setIcon(m_FullScreenMode
+ ? QPixmap(iconLeaveFullScreen_xpm)
+ : QPixmap(iconFullScreen_xpm));
}
void QmitkRenderWindowMenu::OnCrosshairRotationModeSelected(QAction* action)
{
MITK_DEBUG << "selected crosshair mode " << action->data().toInt() ;
emit ChangeCrosshairRotationMode( action->data().toInt() );
}
void QmitkRenderWindowMenu::SetCrossHairVisibility( bool state )
{
if(m_Renderer.IsNotNull())
{
mitk::DataNode *n;
if(this->m_MultiWidget)
{
n = this->m_MultiWidget->GetWidgetPlane1(); if(n) n->SetVisibility(state);
n = this->m_MultiWidget->GetWidgetPlane2(); if(n) n->SetVisibility(state);
n = this->m_MultiWidget->GetWidgetPlane3(); if(n) n->SetVisibility(state);
m_Renderer->GetRenderingManager()->RequestUpdateAll();
}
}
}
void QmitkRenderWindowMenu::OnTSNumChanged(int num)
{
MITK_DEBUG << "Thickslices num: " << num << " on renderer " << m_Renderer.GetPointer();
if(m_Renderer.IsNotNull())
{
if(num==0)
{
m_Renderer->GetCurrentWorldPlaneGeometryNode()->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( 0 ) );
m_Renderer->GetCurrentWorldPlaneGeometryNode()->SetProperty( "reslice.thickslices.num", mitk::IntProperty::New( num ) );
m_Renderer->GetCurrentWorldPlaneGeometryNode()->SetProperty( "reslice.thickslices.showarea", mitk::BoolProperty::New( false ) );
}
else
{
m_Renderer->GetCurrentWorldPlaneGeometryNode()->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( 1 ) );
m_Renderer->GetCurrentWorldPlaneGeometryNode()->SetProperty( "reslice.thickslices.num", mitk::IntProperty::New( num ) );
m_Renderer->GetCurrentWorldPlaneGeometryNode()->SetProperty( "reslice.thickslices.showarea", mitk::BoolProperty::New( true ) );
}
m_TSLabel->setText(QString::number(num*2+1));
m_Renderer->SendUpdateSlice();
m_Renderer->GetRenderingManager()->RequestUpdateAll();
}
}
void QmitkRenderWindowMenu::OnCrossHairMenuAboutToShow()
{
QMenu *crosshairModesMenu = m_CrosshairMenu;
crosshairModesMenu->clear();
QAction* resetViewAction = new QAction(crosshairModesMenu);
resetViewAction->setText("Reset view");
crosshairModesMenu->addAction( resetViewAction );
connect( resetViewAction, SIGNAL(triggered()), this, SIGNAL(ResetView()));
// Show hide crosshairs
{
bool currentState = true;
if(m_Renderer.IsNotNull())
{
mitk::DataStorage *ds=m_Renderer->GetDataStorage();
mitk::DataNode *n;
if(ds)
{
n = this->m_MultiWidget->GetWidgetPlane1(); if(n) { bool v; if(n->GetVisibility(v,0)) currentState&=v; }
n = this->m_MultiWidget->GetWidgetPlane2(); if(n) { bool v; if(n->GetVisibility(v,0)) currentState&=v; }
n = this->m_MultiWidget->GetWidgetPlane3(); if(n) { bool v; if(n->GetVisibility(v,0)) currentState&=v; }
}
}
QAction* showHideCrosshairVisibilityAction = new QAction(crosshairModesMenu);
showHideCrosshairVisibilityAction->setText("Show crosshair");
showHideCrosshairVisibilityAction->setCheckable(true);
showHideCrosshairVisibilityAction->setChecked(currentState);
crosshairModesMenu->addAction( showHideCrosshairVisibilityAction );
connect( showHideCrosshairVisibilityAction, SIGNAL(toggled(bool)), this, SLOT(SetCrossHairVisibility(bool)));
}
// Rotation mode
{
QAction* rotationGroupSeparator = new QAction(crosshairModesMenu);
rotationGroupSeparator->setSeparator(true);
rotationGroupSeparator->setText("Rotation mode");
crosshairModesMenu->addAction( rotationGroupSeparator );
QActionGroup* rotationModeActionGroup = new QActionGroup(crosshairModesMenu);
rotationModeActionGroup->setExclusive(true);
QAction* noCrosshairRotation = new QAction(crosshairModesMenu);
noCrosshairRotation->setActionGroup(rotationModeActionGroup);
noCrosshairRotation->setText("No crosshair rotation");
noCrosshairRotation->setCheckable(true);
noCrosshairRotation->setChecked(currentCrosshairRotationMode==0);
noCrosshairRotation->setData( 0 );
crosshairModesMenu->addAction( noCrosshairRotation );
QAction* singleCrosshairRotation = new QAction(crosshairModesMenu);
singleCrosshairRotation->setActionGroup(rotationModeActionGroup);
singleCrosshairRotation->setText("Crosshair rotation");
singleCrosshairRotation->setCheckable(true);
singleCrosshairRotation->setChecked(currentCrosshairRotationMode==1);
singleCrosshairRotation->setData( 1 );
crosshairModesMenu->addAction( singleCrosshairRotation );
QAction* coupledCrosshairRotation = new QAction(crosshairModesMenu);
coupledCrosshairRotation->setActionGroup(rotationModeActionGroup);
coupledCrosshairRotation->setText("Coupled crosshair rotation");
coupledCrosshairRotation->setCheckable(true);
coupledCrosshairRotation->setChecked(currentCrosshairRotationMode==2);
coupledCrosshairRotation->setData( 2 );
crosshairModesMenu->addAction( coupledCrosshairRotation );
QAction* swivelMode = new QAction(crosshairModesMenu);
swivelMode->setActionGroup(rotationModeActionGroup);
swivelMode->setText("Swivel mode");
swivelMode->setCheckable(true);
swivelMode->setChecked(currentCrosshairRotationMode==3);
swivelMode->setData( 3 );
crosshairModesMenu->addAction( swivelMode );
connect( rotationModeActionGroup, SIGNAL(triggered(QAction*)), this, SLOT(OnCrosshairRotationModeSelected(QAction*)) );
}
// auto rotation support
if( m_Renderer.IsNotNull() && m_Renderer->GetMapperID() == mitk::BaseRenderer::Standard3D )
{
QAction* autoRotationGroupSeparator = new QAction(crosshairModesMenu);
autoRotationGroupSeparator->setSeparator(true);
crosshairModesMenu->addAction( autoRotationGroupSeparator );
QAction* autoRotationAction = crosshairModesMenu->addAction( "Auto Rotation" );
autoRotationAction->setCheckable(true);
autoRotationAction->setChecked( m_AutoRotationTimer.isActive() );
connect( autoRotationAction, SIGNAL(triggered()), this, SLOT(OnAutoRotationActionTriggered()) );
}
// Thickslices support
if( m_Renderer.IsNotNull() && m_Renderer->GetMapperID() == mitk::BaseRenderer::Standard2D )
{
QAction* thickSlicesGroupSeparator = new QAction(crosshairModesMenu);
thickSlicesGroupSeparator->setSeparator(true);
thickSlicesGroupSeparator->setText("ThickSlices mode");
crosshairModesMenu->addAction( thickSlicesGroupSeparator );
QActionGroup* thickSlicesActionGroup = new QActionGroup(crosshairModesMenu);
thickSlicesActionGroup->setExclusive(true);
int currentMode = 0;
{
mitk::ResliceMethodProperty::Pointer m = dynamic_cast<mitk::ResliceMethodProperty*>(m_Renderer->GetCurrentWorldPlaneGeometryNode()->GetProperty( "reslice.thickslices" ));
if( m.IsNotNull() )
currentMode = m->GetValueAsId();
}
int currentNum = 1;
{
mitk::IntProperty::Pointer m = dynamic_cast<mitk::IntProperty*>(m_Renderer->GetCurrentWorldPlaneGeometryNode()->GetProperty( "reslice.thickslices.num" ));
if( m.IsNotNull() )
{
currentNum = m->GetValue();
if(currentNum < 1) currentNum = 1;
if(currentNum > 10) currentNum = 10;
}
}
if(currentMode==0)
currentNum=0;
QSlider *m_TSSlider = new QSlider(crosshairModesMenu);
m_TSSlider->setMinimum(0);
m_TSSlider->setMaximum(9);
m_TSSlider->setValue(currentNum);
m_TSSlider->setOrientation(Qt::Horizontal);
connect( m_TSSlider, SIGNAL( valueChanged(int) ), this, SLOT( OnTSNumChanged(int) ) );
QHBoxLayout* _TSLayout = new QHBoxLayout;
_TSLayout->setContentsMargins(4,4,4,4);
_TSLayout->addWidget(new QLabel("TS: "));
_TSLayout->addWidget(m_TSSlider);
_TSLayout->addWidget(m_TSLabel=new QLabel(QString::number(currentNum*2+1),this));
QWidget* _TSWidget = new QWidget;
_TSWidget->setLayout(_TSLayout);
QWidgetAction *m_TSSliderAction = new QWidgetAction(crosshairModesMenu);
m_TSSliderAction->setDefaultWidget(_TSWidget);
crosshairModesMenu->addAction(m_TSSliderAction);
}
}
void QmitkRenderWindowMenu::NotifyNewWidgetPlanesMode( int mode )
{
currentCrosshairRotationMode = mode;
}
void QmitkRenderWindowMenu::OnAutoRotationActionTriggered()
{
if(m_AutoRotationTimer.isActive())
{
m_AutoRotationTimer.stop();
m_Renderer->GetCameraRotationController()->GetSlice()->PingPongOff();
}
else
{
m_Renderer->GetCameraRotationController()->GetSlice()->PingPongOn();
m_AutoRotationTimer.start();
}
}
void QmitkRenderWindowMenu::AutoRotateNextStep()
{
if(m_Renderer->GetCameraRotationController())
m_Renderer->GetCameraRotationController()->GetSlice()->Next();
}
diff --git a/Modules/QtWidgets/QmitkRenderWindowMenu.h b/Modules/QtWidgets/QmitkRenderWindowMenu.h
index 8b55966a57..dff23edd29 100644
--- a/Modules/QtWidgets/QmitkRenderWindowMenu.h
+++ b/Modules/QtWidgets/QmitkRenderWindowMenu.h
@@ -1,328 +1,331 @@
/*===================================================================
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 QmitkRenderWindowMenu_h
#define QmitkRenderWindowMenu_h
#if defined(_WIN32) || defined(__APPLE__)
#define QMITK_USE_EXTERNAL_RENDERWINDOW_MENU
#endif
#include <MitkQtWidgetsExports.h>
#include "mitkBaseRenderer.h"
#include <QWidget>
#include <QEvent>
#include <QPushButton>
#include <QMenuBar>
#include <QAction>
#include <QLabel>
#include <QTimer>
class QmitkStdMultiWidget;
/**
* \ingroup QmitkModule
* \brief The QmitkRenderWindowMenu is a popup Widget which shows
* up when the mouse curser enter a QmitkRenderWindow.
* The Menu Widget is located in the right top corner of each
* RenderWindow. It includes different settings. For example
* the layout design can be changed with the setting button. Switching
* between full-screen mode and layout design can be done
* with the full-screen button. Splitting the Widget horizontal or
* vertical as well closing the Widget is not implemented yet.
* The popup Widget can be deactivated with ActivateMenuWidget(false) in
* QmitkRenderWindow.
*
* \sa QmitkRenderWindow
* \sa QmitkStdMultiWidget
*
*/
class QMITK_EXPORT QmitkRenderWindowMenu : public QWidget
{
Q_OBJECT
public:
-
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ QmitkRenderWindowMenu( QWidget* parent = 0, Qt::WindowFlags f = 0, mitk::BaseRenderer * b = 0, QmitkStdMultiWidget* mw = 0 );
+#else
QmitkRenderWindowMenu( QWidget* parent = 0, Qt::WFlags f = 0, mitk::BaseRenderer * b = 0, QmitkStdMultiWidget* mw = 0 );
+#endif
virtual ~QmitkRenderWindowMenu();
/*! Return visibility of settings menu. The menu is connected with m_SettingsButton and includes
layout direction (axial, coronal .. ) and layout design (standard layout, 2D images top,
3D bottom ... ). */
bool GetSettingsMenuVisibilty()
{
if( m_Settings == NULL)
return false;
else
return m_Settings->isVisible();
}
/*! Set layout index. Defines layout direction (axial, coronal, sagital or threeD) of the parent. */
void SetLayoutIndex( unsigned int layoutIndex );
/*! Return layout direction of parent (axial, coronal, sagital or threeD) */
unsigned int GetLayoutIndex()
{ return m_Layout; }
/*! Update list of layout design (standard layout, 2D images top, 3D bottom ..). Set action of current layout design
to disable and all other to enable. */
void UpdateLayoutDesignList( int layoutDesignIndex );
/*! Move menu widget to correct position (right upper corner). E.g. it is necessary when the full-screen mode
is activated.*/
#ifdef QMITK_USE_EXTERNAL_RENDERWINDOW_MENU
void MoveWidgetToCorrectPos(float opacity);
#else
void MoveWidgetToCorrectPos(float /*opacity*/);
#endif
void ChangeFullScreenMode( bool state );
void NotifyNewWidgetPlanesMode( int mode );
protected:
/*! Create menu widget. The menu contains five QPushButtons (hori-split, verti-split, full-screen, settings and close button)
and their signal/slot connection for handling. */
void CreateMenuWidget();
/*! Create settings menu which contains layout direction and the different layout designs. */
void CreateSettingsWidget();
/*! Reimplemented from QWidget. The paint event is a request to repaint all or part of a widget.*/
void paintEvent(QPaintEvent *event);
/*! Update list of layout direction (axial, coronal, sagital or threeD). Set action of currect layout direction
to disable and all other to enable. Normaly the user can switch here between the different layout direction, but
this is not supported yet. */
void UpdateLayoutList();
/*! Change Icon of full-screen button depending on full-screen mode. */
void ChangeFullScreenIcon();
int currentCrosshairRotationMode;
public slots:
void SetCrossHairVisibility( bool state ) ;
signals:
void ResetView(); // == "global reinit"
// \brief int parameters are enum from QmitkStdMultiWidget
void ChangeCrosshairRotationMode(int);
/*! emit signal, when layout design changed by the setting menu.*/
void SignalChangeLayoutDesign( int layoutDesign );
public slots:
void DeferredHideMenu( );
void DeferredShowMenu( );
void smoothHide( );
protected slots:
///
/// this function is continously called by a timer
/// to do the auto rotation
///
void AutoRotateNextStep();
///
/// this function is invoked when the auto-rotate action
/// is clicked
///
void OnAutoRotationActionTriggered();
void enterEvent( QEvent* /*e*/ );
void leaveEvent( QEvent* /*e*/ );
void OnTSNumChanged(int);
void OnCrosshairRotationModeSelected(QAction*);
/*! slot for activating/deactivating the full-screen mode. The slot is connected to the clicked() event of m_FullScreenButton.
Activating the full-screen maximize the current widget, deactivating restore If layout design changed by the settings menu,
the full-Screen mode is automatically switch to false. */
void OnFullScreenButton( bool checked );
/*! Slot for opening setting menu. The slot is connected to the clicked() event of m_SettingsButton.
The settings menu includes differen layout directions (axial, coronal, saggital and 3D) as well all layout design
(standard layout, 2D images top, 3D bottom ..)*/
void OnSettingsButton( bool checked );
/*! Slot for changing layout design to standard layout. The slot is connected to the triggered() signal of m_DefaultLayoutAction. */
void OnChangeLayoutToDefault(bool);
/*! Slot for changing layout design to 2D images top, 3D bottom layout. The slot is connected to the triggered() signal of m_2DImagesUpLayoutAction. */
void OnChangeLayoutTo2DImagesUp(bool);
/*! Slot for changing layout design to 2D images left, 3D right layout. The slot is connected to the triggered() signal of m_2DImagesLeftLayoutAction. */
void OnChangeLayoutTo2DImagesLeft(bool);
/*! Slot for changing layout to Big 3D layout. The slot is connected to the triggered() signal of m_Big3DLayoutAction. */
void OnChangeLayoutToBig3D(bool);
/*! Slot for changing layout design to Axial plane layout. The slot is connected to the triggered() signal of m_Widget1LayoutAction. */
void OnChangeLayoutToWidget1(bool);
/*! Slot for changing layout design to Sagittal plane layout. The slot is connected to the triggered() signal of m_Widget2LayoutAction. */
void OnChangeLayoutToWidget2(bool);
/*! Slot for changing layout design to Coronal plane layout. The slot is connected to the triggered() signal of m_Widget3LayoutAction. */
void OnChangeLayoutToWidget3(bool);
/*! Slot for changing layout design to Coronal top, 3D bottom layout. The slot is connected to the triggered() signal of m_RowWidget3And4LayoutAction. */
void OnChangeLayoutToRowWidget3And4(bool);
/*! Slot for changing layout design to Coronal left, 3D right layout. The slot is connected to the triggered() signal of m_ColumnWidget3And4LayoutAction. */
void OnChangeLayoutToColumnWidget3And4(bool);
/*! Slot for changing layout design to Sagittal top, Coronal n 3D bottom layout. The slot is connected to the triggered() signal of m_SmallUpperWidget2Big3and4LayoutAction. */
void OnChangeLayoutToSmallUpperWidget2Big3and4(bool);
/*! Slot for changing layout design to Axial n Sagittal left, 3D right layout. The slot is connected to the triggered() signal of m_2x2Dand3DWidgetLayoutAction. */
void OnChangeLayoutTo2x2Dand3DWidget(bool);
/*! Slot for changing layout design to Axial n 3D left, Sagittal right layout. The slot is connected to the triggered() signal of m_Left2Dand3DRight2DLayoutAction. */
void OnChangeLayoutToLeft2Dand3DRight2D(bool);
void OnCrossHairMenuAboutToShow();
public:
/*! enum for layout direction*/
enum
{
AXIAL,
SAGITTAL,
CORONAL,
THREE_D
};
/*! enum for layout design */
enum
{
LAYOUT_DEFAULT,
LAYOUT_2DIMAGEUP,
LAYOUT_2DIMAGELEFT,
LAYOUT_BIG3D,
LAYOUT_AXIAL,
LAYOUT_SAGITTAL,
LAYOUT_CORONAL,
LAYOUT_2X2DAND3DWIDGET,
LAYOUT_ROWWIDGET3AND4,
LAYOUT_COLUMNWIDGET3AND4,
LAYOUT_ROWWIDGETSMALL3ANDBIG4, //not in use in this class, but we need it here to synchronize with the SdtMultiWidget.
LAYOUT_SMALLUPPERWIDGET2BIGAND4,
LAYOUT_LEFT2DAND3DRIGHT2D
};
void ShowMenu();
void HideMenu();
protected:
QPushButton* m_CrosshairModeButton;
//QAction* m_ShowHideCrosshairVisibilityAction;
/*! QPushButton for activating/deactivating full-screen mode*/
QPushButton* m_FullScreenButton;
/*! QPushButton for open the settings menu*/
QPushButton* m_SettingsButton;
/*! QAction for Default layout design */
QAction* m_DefaultLayoutAction;
/*! QAction for 2D images up layout design */
QAction* m_2DImagesUpLayoutAction;
/*! QAction for 2D images left layout design */
QAction* m_2DImagesLeftLayoutAction;
/*! QAction for big 3D layout design */
QAction* m_Big3DLayoutAction;
/*! QAction for big axial layout design */
QAction* m_Widget1LayoutAction;
/*! QAction for big saggital layout design */
QAction* m_Widget2LayoutAction;
/*! QAction for big coronal layout design */
QAction* m_Widget3LayoutAction;
/*! QAction for coronal top, 3D bottom layout design */
QAction* m_RowWidget3And4LayoutAction;
/*! QAction for coronal left, 3D right layout design */
QAction* m_ColumnWidget3And4LayoutAction;
/*! QAction for sagittal top, coronal n 3D bottom layout design */
QAction* m_SmallUpperWidget2Big3and4LayoutAction;
/*! QAction for axial n sagittal left, 3D right layout design */
QAction* m_2x2Dand3DWidgetLayoutAction;
/*! QAction for axial n 3D left, sagittal right layout design*/
QAction* m_Left2Dand3DRight2DLayoutAction;
QLabel *m_TSLabel;
/*! QMenu containg all layout direction and layout design settings.*/
QMenu* m_Settings;
QMenu* m_CrosshairMenu;
/*! Index of layout direction. 0: axial; 1: saggital; 2: coronal; 3: threeD */
unsigned int m_Layout;
/*! Index of layout design. 0: LAYOUT_DEFAULT; 1: LAYOUT_2DIMAGEUP; 2: LAYOUT_2DIMAGELEFT; 3: LAYOUT_BIG3D
4: LAYOUT_AXIAL; 5: LAYOUT_SAGITTAL; 6: LAYOUT_CORONAL; 7: LAYOUT_2X2DAND3DWIDGET; 8: LAYOUT_ROWWIDGET3AND4;
9: LAYOUT_COLUMNWIDGET3AND4; 10: LAYOUT_ROWWIDGETSMALL3ANDBIG4; 11: LAYOUT_SMALLUPPERWIDGET2BIGAND4; 12: LAYOUT_LEFT2DAND3DRIGHT2D */
unsigned int m_LayoutDesign;
/*! Store index of old layout design. It is used e.g. for the full-screen mode, when deactivating the mode the former layout design will restore.*/
unsigned int m_OldLayoutDesign;
/*! Flag if full-screen mode is activated or deactivated. */
bool m_FullScreenMode;
bool m_Entered;
bool m_Hidden;
private:
mitk::BaseRenderer::Pointer m_Renderer;
QmitkStdMultiWidget* m_MultiWidget;
///
/// a timer for the auto rotate action
///
QTimer m_AutoRotationTimer;
};
#endif // QmitkRenderWindowMenu_H
diff --git a/Modules/QtWidgets/QmitkSliderLevelWindowWidget.cpp b/Modules/QtWidgets/QmitkSliderLevelWindowWidget.cpp
index 348fb788d6..cde0bad1c8 100644
--- a/Modules/QtWidgets/QmitkSliderLevelWindowWidget.cpp
+++ b/Modules/QtWidgets/QmitkSliderLevelWindowWidget.cpp
@@ -1,526 +1,524 @@
/*===================================================================
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 <QmitkSliderLevelWindowWidget.h>
#include <QCursor>
#include <QPainter>
#include <QToolTip>
#include <QMouseEvent>
#include <itkCommand.h>
#include <QmitkLevelWindowWidgetContextMenu.h>
#include <mitkRenderingManager.h>
#include <math.h>
/**
* Constructor
*/
QmitkSliderLevelWindowWidget::QmitkSliderLevelWindowWidget( QWidget * parent, Qt::WindowFlags f )
: QWidget( parent, f )
{
m_Manager = mitk::LevelWindowManager::New();
itk::ReceptorMemberCommand<QmitkSliderLevelWindowWidget>::Pointer command = itk::ReceptorMemberCommand<QmitkSliderLevelWindowWidget>::New();
command->SetCallbackFunction(this, &QmitkSliderLevelWindowWidget::OnPropertyModified);
m_ObserverTag = m_Manager->AddObserver(itk::ModifiedEvent(), command);
m_IsObserverTagSet = true;
setMouseTracking(true);
m_Resize = false;
m_Bottom = false;
m_CtrlPressed = false;
m_MouseDown = false;
m_Font.setPointSize( 6 );
m_MoveHeight = height() - 25;
m_ScaleVisible = true;
m_Contextmenu = new QmitkLevelWindowWidgetContextMenu(this); //, true);
//setBackgroundMode( Qt::NoBackground );
this->hide();
update();
}
QmitkSliderLevelWindowWidget::~QmitkSliderLevelWindowWidget()
{
if ( m_IsObserverTagSet)
{
m_Manager->RemoveObserver(m_ObserverTag);
m_IsObserverTagSet = false;
}
}
void QmitkSliderLevelWindowWidget::setLevelWindowManager(mitk::LevelWindowManager* levelWindowManager)
{
if ( m_IsObserverTagSet)
{
m_Manager->RemoveObserver(m_ObserverTag);
m_IsObserverTagSet = false;
}
m_Manager = levelWindowManager;
if ( m_Manager.IsNotNull() )
{
itk::ReceptorMemberCommand<QmitkSliderLevelWindowWidget>::Pointer command = itk::ReceptorMemberCommand<QmitkSliderLevelWindowWidget>::New();
command->SetCallbackFunction(this, &QmitkSliderLevelWindowWidget::OnPropertyModified);
m_ObserverTag = m_Manager->AddObserver(itk::ModifiedEvent(), command);
m_IsObserverTagSet = true;
}
}
void QmitkSliderLevelWindowWidget::OnPropertyModified(const itk::EventObject& )
{
try
{
m_LevelWindow = m_Manager->GetLevelWindow();
this->show();
update();
}
catch(...)
{
try
{
this->hide();
}
catch(...)
{
}
}
}
void QmitkSliderLevelWindowWidget::paintEvent( QPaintEvent* itkNotUsed(e) )
{
QPixmap pm(width(), height());
- //pm.fill( static_cast<QWidget*>(parent())->paletteBackgroundColor() );
- pm.fill(this, 0, 0);
+ pm.fill(this->palette().color(this->backgroundRole()));
QPainter painter(&pm);
painter.setFont( m_Font );
- //painter.setPen(static_cast<QWidget*>(parent())->paletteForegroundColor());
painter.setPen(this->palette().color(this->foregroundRole()));
QColor c(93,144,169);
QColor cl = c.light();
QColor cd = c.dark();
painter.setBrush(c);
painter.drawRect(m_Rect);
float mr = m_LevelWindow.GetRange();
if ( mr < 1 )
mr = 1;
float fact = (float) m_MoveHeight / mr;
//begin draw scale
if (m_ScaleVisible)
{
int minRange = (int)m_LevelWindow.GetRangeMin();
int maxRange = (int)m_LevelWindow.GetRangeMax();
int yValue = m_MoveHeight + (int)(minRange*fact);
QString s = " 0";
if (minRange <= 0 && maxRange >= 0)
{
painter.drawLine( 5, yValue , 15, yValue);
painter.drawText( 21, yValue + 3, s );
}
int count = 1;
int k = 5;
bool enoughSpace = false;
bool enoughSpace2 = false;
double dStepSize = pow(10,floor(log10(mr/100))+1);
for(int i = m_MoveHeight + (int)(minRange*fact); i < m_MoveHeight;)//negative
{
if (-count*dStepSize < minRange)
break;
yValue = m_MoveHeight + (int)((minRange + count*dStepSize)*fact);
s = QString::number(-count*dStepSize);
if (count % k && ((dStepSize*fact) > 2.5))
{
painter.drawLine( 8, yValue, 12, yValue);
enoughSpace = true;
}
else if (!(count % k))
{
if ((k*dStepSize*fact) > 7)
{
painter.drawLine( 5, yValue, 15, yValue);
painter.drawText( 21, yValue + 3, s );
enoughSpace2 = true;
}
else
{
k += 5;
}
}
if (enoughSpace)
{
i=yValue;
count++;
}
else if (enoughSpace2)
{
i=yValue;
count += k;
}
else
{
i=yValue;
count = k;
}
}
count = 1;
k = 5;
enoughSpace = false;
enoughSpace2 = false;
for(int i = m_MoveHeight + (int)(minRange*fact); i >= 0;)
{
if (count*dStepSize > maxRange)
break;
yValue = m_MoveHeight + (int)((minRange - count*dStepSize)*fact);
s = QString::number(count*dStepSize);
if(count % k && ((dStepSize*fact) > 2.5))
{
if (!(minRange > 0 && (count*dStepSize) < minRange))
painter.drawLine( 8, yValue, 12, yValue);
enoughSpace = true;
}
else if (!(count % k))
{
if ((k*dStepSize*fact) > 7)
{
if (!(minRange > 0 && (count*dStepSize) < minRange))
{
painter.drawLine( 5, yValue, 15, yValue);
painter.drawText( 21, yValue + 3, s );
}
enoughSpace2 = true;
}
else
{
k += 5;
}
}
if (enoughSpace)
{
i=yValue;
count++;
}
else if (enoughSpace2)
{
i=yValue;
count += k;
}
else
{
i=yValue;
count = k;
}
}
}
//end draw scale
painter.setPen (cl);
painter.drawLine(m_Rect.topLeft(),m_Rect.topRight());
painter.drawLine(m_Rect.topLeft(),m_Rect.bottomLeft());
painter.setPen (cd);
painter.drawLine(m_Rect.topRight(),m_Rect.bottomRight());
painter.drawLine(m_Rect.bottomRight(),m_Rect.bottomLeft());
painter.end();
QPainter p (this);
p.drawPixmap(0, 0, pm);
}
/**
*
*/
void QmitkSliderLevelWindowWidget::mouseMoveEvent( QMouseEvent* mouseEvent )
{
if(!mouseEvent)
return;
if ( m_LevelWindow.IsFixed() )
return;
if (!m_MouseDown)
{
if ( mouseEvent->pos().y() >= 0
&& mouseEvent->pos().y() <= (m_Rect.topLeft().y() + 3) )
{
setCursor(Qt::SizeVerCursor);
m_UpperBound.setRect(m_Rect.topLeft().x(), m_Rect.topLeft().y() - 3, 17, 7);
this->setToolTip("Ctrl + left click to change only upper bound");
m_Resize = true;
}
else if ( mouseEvent->pos().y() >= (m_Rect.bottomLeft().y() - 3) )
{
setCursor(Qt::SizeVerCursor);
m_LowerBound.setRect(m_Rect.bottomLeft().x(), m_Rect.bottomLeft().y() - 3, 17, 7);
this->setToolTip("Ctrl + left click to change only lower bound");
m_Resize = true;
m_Bottom = true;
}
else
{
setCursor(Qt::ArrowCursor);
this->setToolTip("Left click and mouse move to adjust the slider");
m_Resize = false;
m_Bottom = false;
}
}
else {
float fact = (float) m_MoveHeight / m_LevelWindow.GetRange();
if ( m_Leftbutton )
{
if (m_Resize && !m_CtrlPressed)
{
double diff = (mouseEvent->pos().y()) / fact;
diff -= (m_StartPos.y()) / fact;
m_StartPos = mouseEvent->pos();
if (diff == 0) return;
float value;
if (m_Bottom)
value = m_LevelWindow.GetWindow() + ( ( 2 * diff ) );
else
value = m_LevelWindow.GetWindow() - ( ( 2 * diff ) );
if ( value < 0 )
value = 0;
m_LevelWindow.SetLevelWindow( m_LevelWindow.GetLevel(), value );
}
else if(m_Resize && m_CtrlPressed)
{
if (!m_Bottom)
{
double diff = (mouseEvent->pos().y()) / fact;
diff -= (m_StartPos.y()) / fact;
m_StartPos = mouseEvent->pos();
if (diff == 0) return;
float value;
value = m_LevelWindow.GetWindow() - ( ( diff ) );
if ( value < 0 )
value = 0;
float oldWindow;
float oldLevel;
float newLevel;
oldWindow = m_LevelWindow.GetWindow();
oldLevel = m_LevelWindow.GetLevel();
newLevel = oldLevel + (value - oldWindow)/2;
if (!((newLevel + value/2) > m_LevelWindow.GetRangeMax()))
m_LevelWindow.SetLevelWindow( newLevel, value );
}
else
{
double diff = (mouseEvent->pos().y()) / fact;
diff -= (m_StartPos.y()) / fact;
m_StartPos = mouseEvent->pos();
if (diff == 0) return;
float value;
value = m_LevelWindow.GetWindow() + ( ( diff ) );
if ( value < 0 )
value = 0;
float oldWindow;
float oldLevel;
float newLevel;
oldWindow = m_LevelWindow.GetWindow();
oldLevel = m_LevelWindow.GetLevel();
newLevel = oldLevel - (value - oldWindow)/2;
if (!((newLevel - value/2) < m_LevelWindow.GetRangeMin()))
m_LevelWindow.SetLevelWindow( newLevel, value );
}
}
else
{
const float minv = m_LevelWindow.GetRangeMin();
const float level = (m_MoveHeight - mouseEvent->pos().y()) / fact + minv;
double diff = (mouseEvent->pos().x()) / fact;
diff -= (m_StartPos.x()) / fact;
m_StartPos = mouseEvent->pos();
float window;
if (m_Bottom)
window = m_LevelWindow.GetWindow() + ( ( 2 * diff ) );
else
window = m_LevelWindow.GetWindow() - ( ( 2 * diff ) );
if ( window < 0 )
window = 0;
m_LevelWindow.SetLevelWindow( level, window );
}
m_Manager->SetLevelWindow(m_LevelWindow);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
}
void QmitkSliderLevelWindowWidget::enterEvent ( QEvent * /*event*/ )
{
/*
if(event->type() != QEvent::MouseMove)
return;*/
//mouseMoveEvent( static_cast< QMouseEvent* > ( event ) );
QPoint p = QCursor::pos();
p = this->mapFromGlobal(p);
QMouseEvent ev(QEvent::MouseMove, p, Qt::NoButton, Qt::NoButton , Qt::NoModifier );
this->mouseMoveEvent( &ev );
}
/**
*
*/
void QmitkSliderLevelWindowWidget::mousePressEvent( QMouseEvent* mouseEvent ) {
if ( m_LevelWindow.IsFixed() )
return;
m_MouseDown = true;
m_StartPos = mouseEvent->pos();
if ( mouseEvent->button() == Qt::LeftButton )
{
if (mouseEvent->modifiers() == Qt::ControlModifier || mouseEvent->modifiers() == Qt::ShiftModifier)
{
m_CtrlPressed = true;
}
else
{
m_CtrlPressed = false;
}
m_Leftbutton = true;
}
else
m_Leftbutton = false;
mouseMoveEvent( mouseEvent );
}
/**
*
*/
void QmitkSliderLevelWindowWidget::resizeEvent ( QResizeEvent * event ) {
m_MoveHeight = event->size().height() - 25;
update();
}
/**
*
*/
void QmitkSliderLevelWindowWidget::mouseReleaseEvent( QMouseEvent* )
{
if ( m_LevelWindow.IsFixed() )
return;
m_MouseDown = false;
}
/**
*
*/
void QmitkSliderLevelWindowWidget::update() {
int rectWidth;
if(m_ScaleVisible)
{
rectWidth = 17;
setMinimumSize ( QSize( 50, 50 ) );
setMaximumSize ( QSize( 50, 2000 ) );
setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding ) );
}
else
{
rectWidth = 26;
setMinimumSize ( QSize( 40, 50 ) );
setMaximumSize ( QSize( 50, 2000 ) );
setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Expanding ) );
}
float mr = m_LevelWindow.GetRange();
if ( mr < 1 )
mr = 1;
float fact = (float) m_MoveHeight / mr;
float rectHeight = m_LevelWindow.GetWindow() * fact;
if ( rectHeight < 15 )
rectHeight = 15;
if ( m_LevelWindow.GetLowerWindowBound() < 0 )
m_Rect.setRect( 2, (int) (m_MoveHeight - (m_LevelWindow.GetUpperWindowBound() - m_LevelWindow.GetRangeMin()) * fact) , rectWidth, (int) rectHeight );
else
m_Rect.setRect( 2, (int) (m_MoveHeight - (m_LevelWindow.GetUpperWindowBound() - m_LevelWindow.GetRangeMin()) * fact), rectWidth, (int) rectHeight );
QWidget::repaint();
}
void QmitkSliderLevelWindowWidget::contextMenuEvent( QContextMenuEvent * )
{
m_Contextmenu->setLevelWindowManager(m_Manager.GetPointer());
QMenu *contextMenu = new QMenu( this );
Q_CHECK_PTR( contextMenu );
if (m_ScaleVisible)
contextMenu->addAction(tr("Hide Scale"), this, SLOT(hideScale()));
else
contextMenu->addAction(tr("Show Scale"), this, SLOT(showScale()));
contextMenu->addSeparator();
m_Contextmenu->getContextMenu(contextMenu);
// Fix: Bug #13327 we need to reset the m_MouseDown value
// otherwise the cursor is not correctly restored afterwards
m_MouseDown = false;
}
void QmitkSliderLevelWindowWidget::hideScale()
{
m_ScaleVisible = false;
update();
}
void QmitkSliderLevelWindowWidget::showScale()
{
m_ScaleVisible = true;
update();
}
void QmitkSliderLevelWindowWidget::setDataStorage(mitk::DataStorage* ds)
{
m_Manager->SetDataStorage(ds);
}
mitk::LevelWindowManager* QmitkSliderLevelWindowWidget::GetManager()
{
return m_Manager.GetPointer();
}
diff --git a/Modules/QtWidgets/QmitkStdMultiWidget.cpp b/Modules/QtWidgets/QmitkStdMultiWidget.cpp
index c6eb5047c7..bf1969311f 100644
--- a/Modules/QtWidgets/QmitkStdMultiWidget.cpp
+++ b/Modules/QtWidgets/QmitkStdMultiWidget.cpp
@@ -1,2206 +1,2205 @@
/*===================================================================
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.
===================================================================*/
#define SMW_INFO MITK_INFO("widget.stdmulti")
#include "QmitkStdMultiWidget.h"
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QGridLayout>
#include <qsplitter.h>
-#include <QMotifStyle>
#include <QList>
#include <QMouseEvent>
#include <QTimer>
#include "mitkProperties.h"
#include "mitkPlaneGeometryDataMapper2D.h"
#include "mitkGlobalInteraction.h"
#include "mitkDisplayInteractor.h"
#include "mitkPointSet.h"
#include "mitkPositionEvent.h"
#include "mitkStateEvent.h"
#include "mitkLine.h"
#include "mitkInteractionConst.h"
#include "mitkDataStorage.h"
#include "mitkOverlayManager.h"
#include "mitkNodePredicateBase.h"
#include "mitkNodePredicateDataType.h"
#include "mitkNodePredicateNot.h"
#include "mitkNodePredicateProperty.h"
#include "mitkStatusBar.h"
#include "mitkImage.h"
#include "mitkVtkLayerController.h"
#include <iomanip>
QmitkStdMultiWidget::QmitkStdMultiWidget(QWidget* parent, Qt::WindowFlags f, mitk::RenderingManager* renderingManager, mitk::BaseRenderer::RenderingMode::Type renderingMode, const QString& name)
: QWidget(parent, f),
mitkWidget1(NULL),
mitkWidget2(NULL),
mitkWidget3(NULL),
mitkWidget4(NULL),
levelWindowWidget(NULL),
QmitkStdMultiWidgetLayout(NULL),
m_Layout(LAYOUT_DEFAULT),
m_PlaneMode(PLANE_MODE_SLICING),
m_RenderingManager(renderingManager),
m_GradientBackgroundFlag(true),
m_TimeNavigationController(NULL),
m_MainSplit(NULL),
m_LayoutSplit(NULL),
m_SubSplit1(NULL),
m_SubSplit2(NULL),
mitkWidget1Container(NULL),
mitkWidget2Container(NULL),
mitkWidget3Container(NULL),
mitkWidget4Container(NULL),
m_PendingCrosshairPositionEvent(false),
m_CrosshairNavigationEnabled(false)
{
/******************************************************
* Use the global RenderingManager if none was specified
* ****************************************************/
if (m_RenderingManager == NULL)
{
m_RenderingManager = mitk::RenderingManager::GetInstance();
}
m_TimeNavigationController = m_RenderingManager->GetTimeNavigationController();
/*******************************/
//Create Widget manually
/*******************************/
//create Layouts
QmitkStdMultiWidgetLayout = new QHBoxLayout( this );
QmitkStdMultiWidgetLayout->setContentsMargins(0,0,0,0);
//Set Layout to widget
this->setLayout(QmitkStdMultiWidgetLayout);
// QmitkNavigationToolBar* toolBar = new QmitkNavigationToolBar();
// QmitkStdMultiWidgetLayout->addWidget( toolBar );
//create main splitter
m_MainSplit = new QSplitter( this );
QmitkStdMultiWidgetLayout->addWidget( m_MainSplit );
//create m_LayoutSplit and add to the mainSplit
m_LayoutSplit = new QSplitter( Qt::Vertical, m_MainSplit );
m_MainSplit->addWidget( m_LayoutSplit );
//create m_SubSplit1 and m_SubSplit2
m_SubSplit1 = new QSplitter( m_LayoutSplit );
m_SubSplit2 = new QSplitter( m_LayoutSplit );
//creae Widget Container
mitkWidget1Container = new QWidget(m_SubSplit1);
mitkWidget2Container = new QWidget(m_SubSplit1);
mitkWidget3Container = new QWidget(m_SubSplit2);
mitkWidget4Container = new QWidget(m_SubSplit2);
mitkWidget1Container->setContentsMargins(0,0,0,0);
mitkWidget2Container->setContentsMargins(0,0,0,0);
mitkWidget3Container->setContentsMargins(0,0,0,0);
mitkWidget4Container->setContentsMargins(0,0,0,0);
//create Widget Layout
QHBoxLayout *mitkWidgetLayout1 = new QHBoxLayout(mitkWidget1Container);
QHBoxLayout *mitkWidgetLayout2 = new QHBoxLayout(mitkWidget2Container);
QHBoxLayout *mitkWidgetLayout3 = new QHBoxLayout(mitkWidget3Container);
QHBoxLayout *mitkWidgetLayout4 = new QHBoxLayout(mitkWidget4Container);
mitkWidgetLayout1->setMargin(0);
mitkWidgetLayout2->setMargin(0);
mitkWidgetLayout3->setMargin(0);
mitkWidgetLayout4->setMargin(0);
//set Layout to Widget Container
mitkWidget1Container->setLayout(mitkWidgetLayout1);
mitkWidget2Container->setLayout(mitkWidgetLayout2);
mitkWidget3Container->setLayout(mitkWidgetLayout3);
mitkWidget4Container->setLayout(mitkWidgetLayout4);
//set SizePolicy
mitkWidget1Container->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
mitkWidget2Container->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
mitkWidget3Container->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
mitkWidget4Container->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
//insert Widget Container into the splitters
m_SubSplit1->addWidget( mitkWidget1Container );
m_SubSplit1->addWidget( mitkWidget2Container );
m_SubSplit2->addWidget( mitkWidget3Container );
m_SubSplit2->addWidget( mitkWidget4Container );
// m_RenderingManager->SetGlobalInteraction( mitk::GlobalInteraction::GetInstance() );
//Create RenderWindows 1
mitkWidget1 = new QmitkRenderWindow(mitkWidget1Container, name + ".widget1", NULL, m_RenderingManager,renderingMode);
mitkWidget1->setMaximumSize(2000,2000);
mitkWidget1->SetLayoutIndex( AXIAL );
mitkWidgetLayout1->addWidget(mitkWidget1);
//Create RenderWindows 2
mitkWidget2 = new QmitkRenderWindow(mitkWidget2Container, name + ".widget2", NULL, m_RenderingManager,renderingMode);
mitkWidget2->setMaximumSize(2000,2000);
- mitkWidget2->setEnabled( TRUE );
+ mitkWidget2->setEnabled( true );
mitkWidget2->SetLayoutIndex( SAGITTAL );
mitkWidgetLayout2->addWidget(mitkWidget2);
//Create RenderWindows 3
mitkWidget3 = new QmitkRenderWindow(mitkWidget3Container, name + ".widget3", NULL, m_RenderingManager,renderingMode);
mitkWidget3->setMaximumSize(2000,2000);
mitkWidget3->SetLayoutIndex( CORONAL );
mitkWidgetLayout3->addWidget(mitkWidget3);
//Create RenderWindows 4
mitkWidget4 = new QmitkRenderWindow(mitkWidget4Container, name + ".widget4", NULL, m_RenderingManager,renderingMode);
mitkWidget4->setMaximumSize(2000,2000);
mitkWidget4->SetLayoutIndex( THREE_D );
mitkWidgetLayout4->addWidget(mitkWidget4);
//create SignalSlot Connection
connect( mitkWidget1, SIGNAL( SignalLayoutDesignChanged(int) ), this, SLOT( OnLayoutDesignChanged(int) ) );
connect( mitkWidget1, SIGNAL( ResetView() ), this, SLOT( ResetCrosshair() ) );
connect( mitkWidget1, SIGNAL( ChangeCrosshairRotationMode(int) ), this, SLOT( SetWidgetPlaneMode(int) ) );
connect( this, SIGNAL(WidgetNotifyNewCrossHairMode(int)), mitkWidget1, SLOT(OnWidgetPlaneModeChanged(int)) );
connect( mitkWidget2, SIGNAL( SignalLayoutDesignChanged(int) ), this, SLOT( OnLayoutDesignChanged(int) ) );
connect( mitkWidget2, SIGNAL( ResetView() ), this, SLOT( ResetCrosshair() ) );
connect( mitkWidget2, SIGNAL( ChangeCrosshairRotationMode(int) ), this, SLOT( SetWidgetPlaneMode(int) ) );
connect( this, SIGNAL(WidgetNotifyNewCrossHairMode(int)), mitkWidget2, SLOT(OnWidgetPlaneModeChanged(int)) );
connect( mitkWidget3, SIGNAL( SignalLayoutDesignChanged(int) ), this, SLOT( OnLayoutDesignChanged(int) ) );
connect( mitkWidget3, SIGNAL( ResetView() ), this, SLOT( ResetCrosshair() ) );
connect( mitkWidget3, SIGNAL( ChangeCrosshairRotationMode(int) ), this, SLOT( SetWidgetPlaneMode(int) ) );
connect( this, SIGNAL(WidgetNotifyNewCrossHairMode(int)), mitkWidget3, SLOT(OnWidgetPlaneModeChanged(int)) );
connect( mitkWidget4, SIGNAL( SignalLayoutDesignChanged(int) ), this, SLOT( OnLayoutDesignChanged(int) ) );
connect( mitkWidget4, SIGNAL( ResetView() ), this, SLOT( ResetCrosshair() ) );
connect( mitkWidget4, SIGNAL( ChangeCrosshairRotationMode(int) ), this, SLOT( SetWidgetPlaneMode(int) ) );
connect( this, SIGNAL(WidgetNotifyNewCrossHairMode(int)), mitkWidget4, SLOT(OnWidgetPlaneModeChanged(int)) );
//Create Level Window Widget
levelWindowWidget = new QmitkLevelWindowWidget( m_MainSplit ); //this
levelWindowWidget->setObjectName(QString::fromUtf8("levelWindowWidget"));
QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
sizePolicy.setHeightForWidth(levelWindowWidget->sizePolicy().hasHeightForWidth());
levelWindowWidget->setSizePolicy(sizePolicy);
levelWindowWidget->setMaximumSize(QSize(50, 2000));
//add LevelWindow Widget to mainSplitter
m_MainSplit->addWidget( levelWindowWidget );
//show mainSplitt and add to Layout
m_MainSplit->show();
//resize Image.
this->resize( QSize(364, 477).expandedTo(minimumSizeHint()) );
//Initialize the widgets.
this->InitializeWidget();
//Activate Widget Menu
this->ActivateMenuWidget( true );
}
void QmitkStdMultiWidget::InitializeWidget()
{
m_PositionTracker = NULL;
// transfer colors in WorldGeometry-Nodes of the associated Renderer
QColor qcolor;
//float color[3] = {1.0f,1.0f,1.0f};
mitk::DataNode::Pointer planeNode;
mitk::IntProperty::Pointer layer;
// of widget 1
planeNode = mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow())->GetCurrentWorldPlaneGeometryNode();
planeNode->SetColor(1.0,0.0,0.0);
layer = mitk::IntProperty::New(1000);
planeNode->SetProperty("layer",layer);
// ... of widget 2
planeNode = mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow())->GetCurrentWorldPlaneGeometryNode();
planeNode->SetColor(0.0,1.0,0.0);
layer = mitk::IntProperty::New(1000);
planeNode->SetProperty("layer",layer);
// ... of widget 3
planeNode = mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow())->GetCurrentWorldPlaneGeometryNode();
planeNode->SetColor(0.0,0.0,1.0);
layer = mitk::IntProperty::New(1000);
planeNode->SetProperty("layer",layer);
// ... of widget 4
planeNode = mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())->GetCurrentWorldPlaneGeometryNode();
planeNode->SetColor(1.0,1.0,0.0);
layer = mitk::IntProperty::New(1000);
planeNode->SetProperty("layer",layer);
mitk::OverlayManager::Pointer OverlayManager = mitk::OverlayManager::New();
mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow())->SetOverlayManager(OverlayManager);
mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow())->SetOverlayManager(OverlayManager);
mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow())->SetOverlayManager(OverlayManager);
mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())->SetOverlayManager(OverlayManager);
mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())->SetMapperID(mitk::BaseRenderer::Standard3D);
// Set plane mode (slicing/rotation behavior) to slicing (default)
m_PlaneMode = PLANE_MODE_SLICING;
// Set default view directions for SNCs
mitkWidget1->GetSliceNavigationController()->SetDefaultViewDirection(
mitk::SliceNavigationController::Axial );
mitkWidget2->GetSliceNavigationController()->SetDefaultViewDirection(
mitk::SliceNavigationController::Sagittal );
mitkWidget3->GetSliceNavigationController()->SetDefaultViewDirection(
mitk::SliceNavigationController::Frontal );
mitkWidget4->GetSliceNavigationController()->SetDefaultViewDirection(
mitk::SliceNavigationController::Original );
/*************************************************/
//Write Layout Names into the viewers -- hardCoded
//Info for later:
//int view = this->GetRenderWindow1()->GetSliceNavigationController()->GetDefaultViewDirection();
//QString layoutName;
//if( view == mitk::SliceNavigationController::Axial )
// layoutName = "Axial";
//else if( view == mitk::SliceNavigationController::Sagittal )
// layoutName = "Sagittal";
//else if( view == mitk::SliceNavigationController::Frontal )
// layoutName = "Coronal";
//else if( view == mitk::SliceNavigationController::Original )
// layoutName = "Original";
//if( view >= 0 && view < 4 )
// //write LayoutName --> Viewer 3D shoudn't write the layoutName.
//Render Window 1 == axial
m_CornerAnnotaions[0].cornerText = vtkCornerAnnotation::New();
m_CornerAnnotaions[0].cornerText->SetText(0, "Axial");
m_CornerAnnotaions[0].cornerText->SetMaximumFontSize(12);
m_CornerAnnotaions[0].textProp = vtkTextProperty::New();
m_CornerAnnotaions[0].textProp->SetColor( 1.0, 0.0, 0.0 );
m_CornerAnnotaions[0].cornerText->SetTextProperty( m_CornerAnnotaions[0].textProp );
m_CornerAnnotaions[0].ren = vtkRenderer::New();
m_CornerAnnotaions[0].ren->AddActor(m_CornerAnnotaions[0].cornerText);
m_CornerAnnotaions[0].ren->InteractiveOff();
mitk::VtkLayerController::GetInstance(this->GetRenderWindow1()->GetRenderWindow())->InsertForegroundRenderer(m_CornerAnnotaions[0].ren,true);
//Render Window 2 == sagittal
m_CornerAnnotaions[1].cornerText = vtkCornerAnnotation::New();
m_CornerAnnotaions[1].cornerText->SetText(0, "Sagittal");
m_CornerAnnotaions[1].cornerText->SetMaximumFontSize(12);
m_CornerAnnotaions[1].textProp = vtkTextProperty::New();
m_CornerAnnotaions[1].textProp->SetColor( 0.0, 1.0, 0.0 );
m_CornerAnnotaions[1].cornerText->SetTextProperty( m_CornerAnnotaions[1].textProp );
m_CornerAnnotaions[1].ren = vtkRenderer::New();
m_CornerAnnotaions[1].ren->AddActor(m_CornerAnnotaions[1].cornerText);
m_CornerAnnotaions[1].ren->InteractiveOff();
mitk::VtkLayerController::GetInstance(this->GetRenderWindow2()->GetRenderWindow())->InsertForegroundRenderer(m_CornerAnnotaions[1].ren,true);
//Render Window 3 == coronal
m_CornerAnnotaions[2].cornerText = vtkCornerAnnotation::New();
m_CornerAnnotaions[2].cornerText->SetText(0, "Coronal");
m_CornerAnnotaions[2].cornerText->SetMaximumFontSize(12);
m_CornerAnnotaions[2].textProp = vtkTextProperty::New();
m_CornerAnnotaions[2].textProp->SetColor( 0.295, 0.295, 1.0 );
m_CornerAnnotaions[2].cornerText->SetTextProperty( m_CornerAnnotaions[2].textProp );
m_CornerAnnotaions[2].ren = vtkRenderer::New();
m_CornerAnnotaions[2].ren->AddActor(m_CornerAnnotaions[2].cornerText);
m_CornerAnnotaions[2].ren->InteractiveOff();
mitk::VtkLayerController::GetInstance(this->GetRenderWindow3()->GetRenderWindow())->InsertForegroundRenderer(m_CornerAnnotaions[2].ren,true);
/*************************************************/
// create a slice rotator
// m_SlicesRotator = mitk::SlicesRotator::New();
// @TODO next line causes sure memory leak
// rotator will be created nonetheless (will be switched on and off)
m_SlicesRotator = mitk::SlicesRotator::New("slices-rotator");
m_SlicesRotator->AddSliceController(
mitkWidget1->GetSliceNavigationController() );
m_SlicesRotator->AddSliceController(
mitkWidget2->GetSliceNavigationController() );
m_SlicesRotator->AddSliceController(
mitkWidget3->GetSliceNavigationController() );
// create a slice swiveller (using the same state-machine as SlicesRotator)
m_SlicesSwiveller = mitk::SlicesSwiveller::New("slices-rotator");
m_SlicesSwiveller->AddSliceController(
mitkWidget1->GetSliceNavigationController() );
m_SlicesSwiveller->AddSliceController(
mitkWidget2->GetSliceNavigationController() );
m_SlicesSwiveller->AddSliceController(
mitkWidget3->GetSliceNavigationController() );
//connect to the "time navigation controller": send time via sliceNavigationControllers
m_TimeNavigationController->ConnectGeometryTimeEvent(
mitkWidget1->GetSliceNavigationController() , false);
m_TimeNavigationController->ConnectGeometryTimeEvent(
mitkWidget2->GetSliceNavigationController() , false);
m_TimeNavigationController->ConnectGeometryTimeEvent(
mitkWidget3->GetSliceNavigationController() , false);
m_TimeNavigationController->ConnectGeometryTimeEvent(
mitkWidget4->GetSliceNavigationController() , false);
mitkWidget1->GetSliceNavigationController()
->ConnectGeometrySendEvent(mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow()));
//reverse connection between sliceNavigationControllers and m_TimeNavigationController
mitkWidget1->GetSliceNavigationController()
->ConnectGeometryTimeEvent(m_TimeNavigationController, false);
mitkWidget2->GetSliceNavigationController()
->ConnectGeometryTimeEvent(m_TimeNavigationController, false);
mitkWidget3->GetSliceNavigationController()
->ConnectGeometryTimeEvent(m_TimeNavigationController, false);
mitkWidget4->GetSliceNavigationController()
->ConnectGeometryTimeEvent(m_TimeNavigationController, false);
m_MouseModeSwitcher = mitk::MouseModeSwitcher::New();
m_LastLeftClickPositionSupplier =
mitk::CoordinateSupplier::New("navigation", NULL);
mitk::GlobalInteraction::GetInstance()->AddListener(
m_LastLeftClickPositionSupplier
);
// setup gradient background
m_GradientBackground1 = mitk::GradientBackground::New();
m_GradientBackground1->SetRenderWindow(
mitkWidget1->GetRenderWindow() );
m_GradientBackground1->Disable();
m_GradientBackground2 = mitk::GradientBackground::New();
m_GradientBackground2->SetRenderWindow(
mitkWidget2->GetRenderWindow() );
m_GradientBackground2->Disable();
m_GradientBackground3 = mitk::GradientBackground::New();
m_GradientBackground3->SetRenderWindow(
mitkWidget3->GetRenderWindow() );
m_GradientBackground3->Disable();
m_GradientBackground4 = mitk::GradientBackground::New();
m_GradientBackground4->SetRenderWindow(
mitkWidget4->GetRenderWindow() );
m_GradientBackground4->SetGradientColors(0.1,0.1,0.1,0.5,0.5,0.5);
m_GradientBackground4->Enable();
// setup the department logo rendering
m_LogoRendering = mitk::LogoOverlay::New();
mitk::BaseRenderer::Pointer renderer4 = mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow());
m_LogoRendering->SetOpacity(0.5);
mitk::Point2D offset;
offset.Fill(0.03);
m_LogoRendering->SetOffsetVector(offset);
m_LogoRendering->SetRelativeSize(0.15);
m_LogoRendering->SetCornerPosition(1);
renderer4->GetOverlayManager()->AddOverlay(m_LogoRendering.GetPointer(),renderer4);
m_RectangleRendering1 = mitk::RenderWindowFrame::New();
m_RectangleRendering1->SetRenderWindow(
mitkWidget1->GetRenderWindow() );
m_RectangleRendering1->Enable(1.0,0.0,0.0);
m_RectangleRendering2 = mitk::RenderWindowFrame::New();
m_RectangleRendering2->SetRenderWindow(
mitkWidget2->GetRenderWindow() );
m_RectangleRendering2->Enable(0.0,1.0,0.0);
m_RectangleRendering3 = mitk::RenderWindowFrame::New();
m_RectangleRendering3->SetRenderWindow(
mitkWidget3->GetRenderWindow() );
m_RectangleRendering3->Enable(0.0,0.0,1.0);
m_RectangleRendering4 = mitk::RenderWindowFrame::New();
m_RectangleRendering4->SetRenderWindow(
mitkWidget4->GetRenderWindow() );
m_RectangleRendering4->Enable(1.0,1.0,0.0);
}
QmitkStdMultiWidget::~QmitkStdMultiWidget()
{
DisablePositionTracking();
DisableNavigationControllerEventListening();
m_TimeNavigationController->Disconnect(mitkWidget1->GetSliceNavigationController());
m_TimeNavigationController->Disconnect(mitkWidget2->GetSliceNavigationController());
m_TimeNavigationController->Disconnect(mitkWidget3->GetSliceNavigationController());
m_TimeNavigationController->Disconnect(mitkWidget4->GetSliceNavigationController());
mitk::VtkLayerController::GetInstance(this->GetRenderWindow1()->GetRenderWindow())->RemoveRenderer( m_CornerAnnotaions[0].ren );
mitk::VtkLayerController::GetInstance(this->GetRenderWindow2()->GetRenderWindow())->RemoveRenderer( m_CornerAnnotaions[1].ren );
mitk::VtkLayerController::GetInstance(this->GetRenderWindow3()->GetRenderWindow())->RemoveRenderer( m_CornerAnnotaions[2].ren );
//Delete CornerAnnotation
m_CornerAnnotaions[0].cornerText->Delete();
m_CornerAnnotaions[0].textProp->Delete();
m_CornerAnnotaions[0].ren->Delete();
m_CornerAnnotaions[1].cornerText->Delete();
m_CornerAnnotaions[1].textProp->Delete();
m_CornerAnnotaions[1].ren->Delete();
m_CornerAnnotaions[2].cornerText->Delete();
m_CornerAnnotaions[2].textProp->Delete();
m_CornerAnnotaions[2].ren->Delete();
}
void QmitkStdMultiWidget::RemovePlanesFromDataStorage()
{
if (m_PlaneNode1.IsNotNull() && m_PlaneNode2.IsNotNull() && m_PlaneNode3.IsNotNull() && m_Node.IsNotNull())
{
if(m_DataStorage.IsNotNull())
{
m_DataStorage->Remove(m_PlaneNode1);
m_DataStorage->Remove(m_PlaneNode2);
m_DataStorage->Remove(m_PlaneNode3);
m_DataStorage->Remove(m_Node);
}
}
}
void QmitkStdMultiWidget::AddPlanesToDataStorage()
{
if (m_PlaneNode1.IsNotNull() && m_PlaneNode2.IsNotNull() && m_PlaneNode3.IsNotNull() && m_Node.IsNotNull())
{
if (m_DataStorage.IsNotNull())
{
m_DataStorage->Add(m_Node);
m_DataStorage->Add(m_PlaneNode1, m_Node);
m_DataStorage->Add(m_PlaneNode2, m_Node);
m_DataStorage->Add(m_PlaneNode3, m_Node);
static_cast<mitk::PlaneGeometryDataMapper2D*>(m_PlaneNode1->GetMapper(mitk::BaseRenderer::Standard2D))->SetDatastorageAndGeometryBaseNode(m_DataStorage, m_Node);
static_cast<mitk::PlaneGeometryDataMapper2D*>(m_PlaneNode2->GetMapper(mitk::BaseRenderer::Standard2D))->SetDatastorageAndGeometryBaseNode(m_DataStorage, m_Node);
static_cast<mitk::PlaneGeometryDataMapper2D*>(m_PlaneNode3->GetMapper(mitk::BaseRenderer::Standard2D))->SetDatastorageAndGeometryBaseNode(m_DataStorage, m_Node);
}
}
}
void QmitkStdMultiWidget::changeLayoutTo2DImagesUp()
{
SMW_INFO << "changing layout to 2D images up... " << std::endl;
//Hide all Menu Widgets
this->HideAllWidgetToolbars();
delete QmitkStdMultiWidgetLayout ;
//create Main Layout
QmitkStdMultiWidgetLayout = new QHBoxLayout( this );
//Set Layout to widget
this->setLayout(QmitkStdMultiWidgetLayout);
//create main splitter
m_MainSplit = new QSplitter( this );
QmitkStdMultiWidgetLayout->addWidget( m_MainSplit );
//create m_LayoutSplit and add to the mainSplit
m_LayoutSplit = new QSplitter( Qt::Vertical, m_MainSplit );
m_MainSplit->addWidget( m_LayoutSplit );
//add LevelWindow Widget to mainSplitter
m_MainSplit->addWidget( levelWindowWidget );
//create m_SubSplit1 and m_SubSplit2
m_SubSplit1 = new QSplitter( m_LayoutSplit );
m_SubSplit2 = new QSplitter( m_LayoutSplit );
//insert Widget Container into splitter top
m_SubSplit1->addWidget( mitkWidget1Container );
m_SubSplit1->addWidget( mitkWidget2Container );
m_SubSplit1->addWidget( mitkWidget3Container );
//set SplitterSize for splitter top
QList<int> splitterSize;
splitterSize.push_back(1000);
splitterSize.push_back(1000);
splitterSize.push_back(1000);
m_SubSplit1->setSizes( splitterSize );
//insert Widget Container into splitter bottom
m_SubSplit2->addWidget( mitkWidget4Container );
//set SplitterSize for splitter m_LayoutSplit
splitterSize.clear();
splitterSize.push_back(400);
splitterSize.push_back(1000);
m_LayoutSplit->setSizes( splitterSize );
//show mainSplitt
m_MainSplit->show();
//show Widget if hidden
if ( mitkWidget1->isHidden() ) mitkWidget1->show();
if ( mitkWidget2->isHidden() ) mitkWidget2->show();
if ( mitkWidget3->isHidden() ) mitkWidget3->show();
if ( mitkWidget4->isHidden() ) mitkWidget4->show();
//Change Layout Name
m_Layout = LAYOUT_2D_IMAGES_UP;
//update Layout Design List
mitkWidget1->LayoutDesignListChanged( LAYOUT_2D_IMAGES_UP );
mitkWidget2->LayoutDesignListChanged( LAYOUT_2D_IMAGES_UP );
mitkWidget3->LayoutDesignListChanged( LAYOUT_2D_IMAGES_UP );
mitkWidget4->LayoutDesignListChanged( LAYOUT_2D_IMAGES_UP );
//update Alle Widgets
this->UpdateAllWidgets();
}
void QmitkStdMultiWidget::changeLayoutTo2DImagesLeft()
{
SMW_INFO << "changing layout to 2D images left... " << std::endl;
//Hide all Menu Widgets
this->HideAllWidgetToolbars();
delete QmitkStdMultiWidgetLayout ;
//create Main Layout
QmitkStdMultiWidgetLayout = new QHBoxLayout( this );
//create main splitter
m_MainSplit = new QSplitter( this );
QmitkStdMultiWidgetLayout->addWidget( m_MainSplit );
//create m_LayoutSplit and add to the mainSplit
m_LayoutSplit = new QSplitter( m_MainSplit );
m_MainSplit->addWidget( m_LayoutSplit );
//add LevelWindow Widget to mainSplitter
m_MainSplit->addWidget( levelWindowWidget );
//create m_SubSplit1 and m_SubSplit2
m_SubSplit1 = new QSplitter( Qt::Vertical, m_LayoutSplit );
m_SubSplit2 = new QSplitter( m_LayoutSplit );
//insert Widget into the splitters
m_SubSplit1->addWidget( mitkWidget1Container );
m_SubSplit1->addWidget( mitkWidget2Container );
m_SubSplit1->addWidget( mitkWidget3Container );
//set splitterSize of SubSplit1
QList<int> splitterSize;
splitterSize.push_back(1000);
splitterSize.push_back(1000);
splitterSize.push_back(1000);
m_SubSplit1->setSizes( splitterSize );
m_SubSplit2->addWidget( mitkWidget4Container );
//set splitterSize of Layout Split
splitterSize.clear();
splitterSize.push_back(400);
splitterSize.push_back(1000);
m_LayoutSplit->setSizes( splitterSize );
//show mainSplitt and add to Layout
m_MainSplit->show();
//show Widget if hidden
if ( mitkWidget1->isHidden() ) mitkWidget1->show();
if ( mitkWidget2->isHidden() ) mitkWidget2->show();
if ( mitkWidget3->isHidden() ) mitkWidget3->show();
if ( mitkWidget4->isHidden() ) mitkWidget4->show();
//update Layout Name
m_Layout = LAYOUT_2D_IMAGES_LEFT;
//update Layout Design List
mitkWidget1->LayoutDesignListChanged( LAYOUT_2D_IMAGES_LEFT );
mitkWidget2->LayoutDesignListChanged( LAYOUT_2D_IMAGES_LEFT );
mitkWidget3->LayoutDesignListChanged( LAYOUT_2D_IMAGES_LEFT );
mitkWidget4->LayoutDesignListChanged( LAYOUT_2D_IMAGES_LEFT );
//update Alle Widgets
this->UpdateAllWidgets();
}
void QmitkStdMultiWidget::changeLayoutToDefault()
{
SMW_INFO << "changing layout to default... " << std::endl;
//Hide all Menu Widgets
this->HideAllWidgetToolbars();
delete QmitkStdMultiWidgetLayout ;
//create Main Layout
QmitkStdMultiWidgetLayout = new QHBoxLayout( this );
//create main splitter
m_MainSplit = new QSplitter( this );
QmitkStdMultiWidgetLayout->addWidget( m_MainSplit );
//create m_LayoutSplit and add to the mainSplit
m_LayoutSplit = new QSplitter( Qt::Vertical, m_MainSplit );
m_MainSplit->addWidget( m_LayoutSplit );
//add LevelWindow Widget to mainSplitter
m_MainSplit->addWidget( levelWindowWidget );
//create m_SubSplit1 and m_SubSplit2
m_SubSplit1 = new QSplitter( m_LayoutSplit );
m_SubSplit2 = new QSplitter( m_LayoutSplit );
//insert Widget container into the splitters
m_SubSplit1->addWidget( mitkWidget1Container );
m_SubSplit1->addWidget( mitkWidget2Container );
m_SubSplit2->addWidget( mitkWidget3Container );
m_SubSplit2->addWidget( mitkWidget4Container );
//set splitter Size
QList<int> splitterSize;
splitterSize.push_back(1000);
splitterSize.push_back(1000);
m_SubSplit1->setSizes( splitterSize );
m_SubSplit2->setSizes( splitterSize );
m_LayoutSplit->setSizes( splitterSize );
//show mainSplitt and add to Layout
m_MainSplit->show();
//show Widget if hidden
if ( mitkWidget1->isHidden() ) mitkWidget1->show();
if ( mitkWidget2->isHidden() ) mitkWidget2->show();
if ( mitkWidget3->isHidden() ) mitkWidget3->show();
if ( mitkWidget4->isHidden() ) mitkWidget4->show();
m_Layout = LAYOUT_DEFAULT;
//update Layout Design List
mitkWidget1->LayoutDesignListChanged( LAYOUT_DEFAULT );
mitkWidget2->LayoutDesignListChanged( LAYOUT_DEFAULT );
mitkWidget3->LayoutDesignListChanged( LAYOUT_DEFAULT );
mitkWidget4->LayoutDesignListChanged( LAYOUT_DEFAULT );
//update Alle Widgets
this->UpdateAllWidgets();
}
void QmitkStdMultiWidget::changeLayoutToBig3D()
{
SMW_INFO << "changing layout to big 3D ..." << std::endl;
//Hide all Menu Widgets
this->HideAllWidgetToolbars();
delete QmitkStdMultiWidgetLayout ;
//create Main Layout
QmitkStdMultiWidgetLayout = new QHBoxLayout( this );
//create main splitter
m_MainSplit = new QSplitter( this );
QmitkStdMultiWidgetLayout->addWidget( m_MainSplit );
//add widget Splitter to main Splitter
m_MainSplit->addWidget( mitkWidget4Container );
//add LevelWindow Widget to mainSplitter
m_MainSplit->addWidget( levelWindowWidget );
//show mainSplitt and add to Layout
m_MainSplit->show();
//show/hide Widgets
mitkWidget1->hide();
mitkWidget2->hide();
mitkWidget3->hide();
if ( mitkWidget4->isHidden() ) mitkWidget4->show();
m_Layout = LAYOUT_BIG_3D;
//update Layout Design List
mitkWidget1->LayoutDesignListChanged( LAYOUT_BIG_3D );
mitkWidget2->LayoutDesignListChanged( LAYOUT_BIG_3D );
mitkWidget3->LayoutDesignListChanged( LAYOUT_BIG_3D );
mitkWidget4->LayoutDesignListChanged( LAYOUT_BIG_3D );
//update Alle Widgets
this->UpdateAllWidgets();
}
void QmitkStdMultiWidget::changeLayoutToWidget1()
{
SMW_INFO << "changing layout to big Widget1 ..." << std::endl;
//Hide all Menu Widgets
this->HideAllWidgetToolbars();
delete QmitkStdMultiWidgetLayout ;
//create Main Layout
QmitkStdMultiWidgetLayout = new QHBoxLayout( this );
//create main splitter
m_MainSplit = new QSplitter( this );
QmitkStdMultiWidgetLayout->addWidget( m_MainSplit );
//add widget Splitter to main Splitter
m_MainSplit->addWidget( mitkWidget1Container );
//add LevelWindow Widget to mainSplitter
m_MainSplit->addWidget( levelWindowWidget );
//show mainSplitt and add to Layout
m_MainSplit->show();
//show/hide Widgets
if ( mitkWidget1->isHidden() ) mitkWidget1->show();
mitkWidget2->hide();
mitkWidget3->hide();
mitkWidget4->hide();
m_Layout = LAYOUT_WIDGET1;
//update Layout Design List
mitkWidget1->LayoutDesignListChanged( LAYOUT_WIDGET1 );
mitkWidget2->LayoutDesignListChanged( LAYOUT_WIDGET1 );
mitkWidget3->LayoutDesignListChanged( LAYOUT_WIDGET1 );
mitkWidget4->LayoutDesignListChanged( LAYOUT_WIDGET1 );
//update Alle Widgets
this->UpdateAllWidgets();
}
void QmitkStdMultiWidget::changeLayoutToWidget2()
{
SMW_INFO << "changing layout to big Widget2 ..." << std::endl;
//Hide all Menu Widgets
this->HideAllWidgetToolbars();
delete QmitkStdMultiWidgetLayout ;
//create Main Layout
QmitkStdMultiWidgetLayout = new QHBoxLayout( this );
//create main splitter
m_MainSplit = new QSplitter( this );
QmitkStdMultiWidgetLayout->addWidget( m_MainSplit );
//add widget Splitter to main Splitter
m_MainSplit->addWidget( mitkWidget2Container );
//add LevelWindow Widget to mainSplitter
m_MainSplit->addWidget( levelWindowWidget );
//show mainSplitt and add to Layout
m_MainSplit->show();
//show/hide Widgets
mitkWidget1->hide();
if ( mitkWidget2->isHidden() ) mitkWidget2->show();
mitkWidget3->hide();
mitkWidget4->hide();
m_Layout = LAYOUT_WIDGET2;
//update Layout Design List
mitkWidget1->LayoutDesignListChanged( LAYOUT_WIDGET2 );
mitkWidget2->LayoutDesignListChanged( LAYOUT_WIDGET2 );
mitkWidget3->LayoutDesignListChanged( LAYOUT_WIDGET2 );
mitkWidget4->LayoutDesignListChanged( LAYOUT_WIDGET2 );
//update Alle Widgets
this->UpdateAllWidgets();
}
void QmitkStdMultiWidget::changeLayoutToWidget3()
{
SMW_INFO << "changing layout to big Widget3 ..." << std::endl;
//Hide all Menu Widgets
this->HideAllWidgetToolbars();
delete QmitkStdMultiWidgetLayout ;
//create Main Layout
QmitkStdMultiWidgetLayout = new QHBoxLayout( this );
//create main splitter
m_MainSplit = new QSplitter( this );
QmitkStdMultiWidgetLayout->addWidget( m_MainSplit );
//add widget Splitter to main Splitter
m_MainSplit->addWidget( mitkWidget3Container );
//add LevelWindow Widget to mainSplitter
m_MainSplit->addWidget( levelWindowWidget );
//show mainSplitt and add to Layout
m_MainSplit->show();
//show/hide Widgets
mitkWidget1->hide();
mitkWidget2->hide();
if ( mitkWidget3->isHidden() ) mitkWidget3->show();
mitkWidget4->hide();
m_Layout = LAYOUT_WIDGET3;
//update Layout Design List
mitkWidget1->LayoutDesignListChanged( LAYOUT_WIDGET3 );
mitkWidget2->LayoutDesignListChanged( LAYOUT_WIDGET3 );
mitkWidget3->LayoutDesignListChanged( LAYOUT_WIDGET3 );
mitkWidget4->LayoutDesignListChanged( LAYOUT_WIDGET3 );
//update Alle Widgets
this->UpdateAllWidgets();
}
void QmitkStdMultiWidget::changeLayoutToRowWidget3And4()
{
SMW_INFO << "changing layout to Widget3 and 4 in a Row..." << std::endl;
//Hide all Menu Widgets
this->HideAllWidgetToolbars();
delete QmitkStdMultiWidgetLayout ;
//create Main Layout
QmitkStdMultiWidgetLayout = new QHBoxLayout( this );
//create main splitter
m_MainSplit = new QSplitter( this );
QmitkStdMultiWidgetLayout->addWidget( m_MainSplit );
//create m_LayoutSplit and add to the mainSplit
m_LayoutSplit = new QSplitter( Qt::Vertical, m_MainSplit );
m_MainSplit->addWidget( m_LayoutSplit );
//add LevelWindow Widget to mainSplitter
m_MainSplit->addWidget( levelWindowWidget );
//add Widgets to splitter
m_LayoutSplit->addWidget( mitkWidget3Container );
m_LayoutSplit->addWidget( mitkWidget4Container );
//set Splitter Size
QList<int> splitterSize;
splitterSize.push_back(1000);
splitterSize.push_back(1000);
m_LayoutSplit->setSizes( splitterSize );
//show mainSplitt and add to Layout
m_MainSplit->show();
//show/hide Widgets
mitkWidget1->hide();
mitkWidget2->hide();
if ( mitkWidget3->isHidden() ) mitkWidget3->show();
if ( mitkWidget4->isHidden() ) mitkWidget4->show();
m_Layout = LAYOUT_ROW_WIDGET_3_AND_4;
//update Layout Design List
mitkWidget1->LayoutDesignListChanged( LAYOUT_ROW_WIDGET_3_AND_4 );
mitkWidget2->LayoutDesignListChanged( LAYOUT_ROW_WIDGET_3_AND_4 );
mitkWidget3->LayoutDesignListChanged( LAYOUT_ROW_WIDGET_3_AND_4 );
mitkWidget4->LayoutDesignListChanged( LAYOUT_ROW_WIDGET_3_AND_4 );
//update Alle Widgets
this->UpdateAllWidgets();
}
void QmitkStdMultiWidget::changeLayoutToColumnWidget3And4()
{
SMW_INFO << "changing layout to Widget3 and 4 in one Column..." << std::endl;
//Hide all Menu Widgets
this->HideAllWidgetToolbars();
delete QmitkStdMultiWidgetLayout ;
//create Main Layout
QmitkStdMultiWidgetLayout = new QHBoxLayout( this );
//create main splitter
m_MainSplit = new QSplitter( this );
QmitkStdMultiWidgetLayout->addWidget( m_MainSplit );
//create m_LayoutSplit and add to the mainSplit
m_LayoutSplit = new QSplitter( m_MainSplit );
m_MainSplit->addWidget( m_LayoutSplit );
//add LevelWindow Widget to mainSplitter
m_MainSplit->addWidget( levelWindowWidget );
//add Widgets to splitter
m_LayoutSplit->addWidget( mitkWidget3Container );
m_LayoutSplit->addWidget( mitkWidget4Container );
//set SplitterSize
QList<int> splitterSize;
splitterSize.push_back(1000);
splitterSize.push_back(1000);
m_LayoutSplit->setSizes( splitterSize );
//show mainSplitt and add to Layout
m_MainSplit->show();
//show/hide Widgets
mitkWidget1->hide();
mitkWidget2->hide();
if ( mitkWidget3->isHidden() ) mitkWidget3->show();
if ( mitkWidget4->isHidden() ) mitkWidget4->show();
m_Layout = LAYOUT_COLUMN_WIDGET_3_AND_4;
//update Layout Design List
mitkWidget1->LayoutDesignListChanged( LAYOUT_COLUMN_WIDGET_3_AND_4 );
mitkWidget2->LayoutDesignListChanged( LAYOUT_COLUMN_WIDGET_3_AND_4 );
mitkWidget3->LayoutDesignListChanged( LAYOUT_COLUMN_WIDGET_3_AND_4 );
mitkWidget4->LayoutDesignListChanged( LAYOUT_COLUMN_WIDGET_3_AND_4 );
//update Alle Widgets
this->UpdateAllWidgets();
}
void QmitkStdMultiWidget::changeLayoutToRowWidgetSmall3andBig4()
{
SMW_INFO << "changing layout to Widget3 and 4 in a Row..." << std::endl;
this->changeLayoutToRowWidget3And4();
m_Layout = LAYOUT_ROW_WIDGET_SMALL3_AND_BIG4;
}
void QmitkStdMultiWidget::changeLayoutToSmallUpperWidget2Big3and4()
{
SMW_INFO << "changing layout to Widget3 and 4 in a Row..." << std::endl;
//Hide all Menu Widgets
this->HideAllWidgetToolbars();
delete QmitkStdMultiWidgetLayout ;
//create Main Layout
QmitkStdMultiWidgetLayout = new QHBoxLayout( this );
//create main splitter
m_MainSplit = new QSplitter( this );
QmitkStdMultiWidgetLayout->addWidget( m_MainSplit );
//create m_LayoutSplit and add to the mainSplit
m_LayoutSplit = new QSplitter( Qt::Vertical, m_MainSplit );
m_MainSplit->addWidget( m_LayoutSplit );
//add LevelWindow Widget to mainSplitter
m_MainSplit->addWidget( levelWindowWidget );
//create m_SubSplit1 and m_SubSplit2
m_SubSplit1 = new QSplitter( Qt::Vertical, m_LayoutSplit );
m_SubSplit2 = new QSplitter( m_LayoutSplit );
//insert Widget into the splitters
m_SubSplit1->addWidget( mitkWidget2Container );
m_SubSplit2->addWidget( mitkWidget3Container );
m_SubSplit2->addWidget( mitkWidget4Container );
//set Splitter Size
QList<int> splitterSize;
splitterSize.push_back(1000);
splitterSize.push_back(1000);
m_SubSplit2->setSizes( splitterSize );
splitterSize.clear();
splitterSize.push_back(500);
splitterSize.push_back(1000);
m_LayoutSplit->setSizes( splitterSize );
//show mainSplitt
m_MainSplit->show();
//show Widget if hidden
mitkWidget1->hide();
if ( mitkWidget2->isHidden() ) mitkWidget2->show();
if ( mitkWidget3->isHidden() ) mitkWidget3->show();
if ( mitkWidget4->isHidden() ) mitkWidget4->show();
m_Layout = LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4;
//update Layout Design List
mitkWidget1->LayoutDesignListChanged( LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4 );
mitkWidget2->LayoutDesignListChanged( LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4 );
mitkWidget3->LayoutDesignListChanged( LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4 );
mitkWidget4->LayoutDesignListChanged( LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4 );
//update Alle Widgets
this->UpdateAllWidgets();
}
void QmitkStdMultiWidget::changeLayoutTo2x2Dand3DWidget()
{
SMW_INFO << "changing layout to 2 x 2D and 3D Widget" << std::endl;
//Hide all Menu Widgets
this->HideAllWidgetToolbars();
delete QmitkStdMultiWidgetLayout ;
//create Main Layout
QmitkStdMultiWidgetLayout = new QHBoxLayout( this );
//create main splitter
m_MainSplit = new QSplitter( this );
QmitkStdMultiWidgetLayout->addWidget( m_MainSplit );
//create m_LayoutSplit and add to the mainSplit
m_LayoutSplit = new QSplitter( m_MainSplit );
m_MainSplit->addWidget( m_LayoutSplit );
//add LevelWindow Widget to mainSplitter
m_MainSplit->addWidget( levelWindowWidget );
//create m_SubSplit1 and m_SubSplit2
m_SubSplit1 = new QSplitter( Qt::Vertical, m_LayoutSplit );
m_SubSplit2 = new QSplitter( m_LayoutSplit );
//add Widgets to splitter
m_SubSplit1->addWidget( mitkWidget1Container );
m_SubSplit1->addWidget( mitkWidget2Container );
m_SubSplit2->addWidget( mitkWidget4Container );
//set Splitter Size
QList<int> splitterSize;
splitterSize.push_back(1000);
splitterSize.push_back(1000);
m_SubSplit1->setSizes( splitterSize );
m_LayoutSplit->setSizes( splitterSize );
//show mainSplitt and add to Layout
m_MainSplit->show();
//show/hide Widgets
if ( mitkWidget1->isHidden() ) mitkWidget1->show();
if ( mitkWidget2->isHidden() ) mitkWidget2->show();
mitkWidget3->hide();
if ( mitkWidget4->isHidden() ) mitkWidget4->show();
m_Layout = LAYOUT_2X_2D_AND_3D_WIDGET;
//update Layout Design List
mitkWidget1->LayoutDesignListChanged( LAYOUT_2X_2D_AND_3D_WIDGET );
mitkWidget2->LayoutDesignListChanged( LAYOUT_2X_2D_AND_3D_WIDGET );
mitkWidget3->LayoutDesignListChanged( LAYOUT_2X_2D_AND_3D_WIDGET );
mitkWidget4->LayoutDesignListChanged( LAYOUT_2X_2D_AND_3D_WIDGET );
//update Alle Widgets
this->UpdateAllWidgets();
}
void QmitkStdMultiWidget::changeLayoutToLeft2Dand3DRight2D()
{
SMW_INFO << "changing layout to 2D and 3D left, 2D right Widget" << std::endl;
//Hide all Menu Widgets
this->HideAllWidgetToolbars();
delete QmitkStdMultiWidgetLayout ;
//create Main Layout
QmitkStdMultiWidgetLayout = new QHBoxLayout( this );
//create main splitter
m_MainSplit = new QSplitter( this );
QmitkStdMultiWidgetLayout->addWidget( m_MainSplit );
//create m_LayoutSplit and add to the mainSplit
m_LayoutSplit = new QSplitter( m_MainSplit );
m_MainSplit->addWidget( m_LayoutSplit );
//add LevelWindow Widget to mainSplitter
m_MainSplit->addWidget( levelWindowWidget );
//create m_SubSplit1 and m_SubSplit2
m_SubSplit1 = new QSplitter( Qt::Vertical, m_LayoutSplit );
m_SubSplit2 = new QSplitter( m_LayoutSplit );
//add Widgets to splitter
m_SubSplit1->addWidget( mitkWidget1Container );
m_SubSplit1->addWidget( mitkWidget4Container );
m_SubSplit2->addWidget( mitkWidget2Container );
//set Splitter Size
QList<int> splitterSize;
splitterSize.push_back(1000);
splitterSize.push_back(1000);
m_SubSplit1->setSizes( splitterSize );
m_LayoutSplit->setSizes( splitterSize );
//show mainSplitt and add to Layout
m_MainSplit->show();
//show/hide Widgets
if ( mitkWidget1->isHidden() ) mitkWidget1->show();
if ( mitkWidget2->isHidden() ) mitkWidget2->show();
mitkWidget3->hide();
if ( mitkWidget4->isHidden() ) mitkWidget4->show();
m_Layout = LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET;
//update Layout Design List
mitkWidget1->LayoutDesignListChanged( LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET );
mitkWidget2->LayoutDesignListChanged( LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET );
mitkWidget3->LayoutDesignListChanged( LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET );
mitkWidget4->LayoutDesignListChanged( LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET );
//update Alle Widgets
this->UpdateAllWidgets();
}
void QmitkStdMultiWidget::changeLayoutTo2DUpAnd3DDown()
{
SMW_INFO << "changing layout to 2D up and 3D down" << std::endl;
//Hide all Menu Widgets
this->HideAllWidgetToolbars();
delete QmitkStdMultiWidgetLayout ;
//create Main Layout
QmitkStdMultiWidgetLayout = new QHBoxLayout( this );
//Set Layout to widget
this->setLayout(QmitkStdMultiWidgetLayout);
//create main splitter
m_MainSplit = new QSplitter( this );
QmitkStdMultiWidgetLayout->addWidget( m_MainSplit );
//create m_LayoutSplit and add to the mainSplit
m_LayoutSplit = new QSplitter( Qt::Vertical, m_MainSplit );
m_MainSplit->addWidget( m_LayoutSplit );
//add LevelWindow Widget to mainSplitter
m_MainSplit->addWidget( levelWindowWidget );
//create m_SubSplit1 and m_SubSplit2
m_SubSplit1 = new QSplitter( m_LayoutSplit );
m_SubSplit2 = new QSplitter( m_LayoutSplit );
//insert Widget Container into splitter top
m_SubSplit1->addWidget( mitkWidget1Container );
//set SplitterSize for splitter top
QList<int> splitterSize;
// splitterSize.push_back(1000);
// splitterSize.push_back(1000);
// splitterSize.push_back(1000);
// m_SubSplit1->setSizes( splitterSize );
//insert Widget Container into splitter bottom
m_SubSplit2->addWidget( mitkWidget4Container );
//set SplitterSize for splitter m_LayoutSplit
splitterSize.clear();
splitterSize.push_back(700);
splitterSize.push_back(700);
m_LayoutSplit->setSizes( splitterSize );
//show mainSplitt
m_MainSplit->show();
//show/hide Widgets
if ( mitkWidget1->isHidden() ) mitkWidget1->show();
mitkWidget2->hide();
mitkWidget3->hide();
if ( mitkWidget4->isHidden() ) mitkWidget4->show();
m_Layout = LAYOUT_2D_UP_AND_3D_DOWN;
//update Layout Design List
mitkWidget1->LayoutDesignListChanged( LAYOUT_2D_UP_AND_3D_DOWN );
mitkWidget2->LayoutDesignListChanged( LAYOUT_2D_UP_AND_3D_DOWN );
mitkWidget3->LayoutDesignListChanged( LAYOUT_2D_UP_AND_3D_DOWN );
mitkWidget4->LayoutDesignListChanged( LAYOUT_2D_UP_AND_3D_DOWN );
//update all Widgets
this->UpdateAllWidgets();
}
void QmitkStdMultiWidget::SetDataStorage( mitk::DataStorage* ds )
{
mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow())->SetDataStorage(ds);
mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow())->SetDataStorage(ds);
mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow())->SetDataStorage(ds);
mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())->SetDataStorage(ds);
m_DataStorage = ds;
}
void QmitkStdMultiWidget::Fit()
{
vtkRenderer * vtkrenderer;
mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow())->GetDisplayGeometry()->Fit();
mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow())->GetDisplayGeometry()->Fit();
mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow())->GetDisplayGeometry()->Fit();
mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())->GetDisplayGeometry()->Fit();
int w = vtkObject::GetGlobalWarningDisplay();
vtkObject::GlobalWarningDisplayOff();
vtkrenderer = mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow())->GetVtkRenderer();
if ( vtkrenderer!= NULL )
vtkrenderer->ResetCamera();
vtkrenderer = mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow())->GetVtkRenderer();
if ( vtkrenderer!= NULL )
vtkrenderer->ResetCamera();
vtkrenderer = mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow())->GetVtkRenderer();
if ( vtkrenderer!= NULL )
vtkrenderer->ResetCamera();
vtkrenderer = mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow())->GetVtkRenderer();
if ( vtkrenderer!= NULL )
vtkrenderer->ResetCamera();
vtkObject::SetGlobalWarningDisplay(w);
}
void QmitkStdMultiWidget::InitPositionTracking()
{
//PoinSetNode for MouseOrientation
m_PositionTrackerNode = mitk::DataNode::New();
m_PositionTrackerNode->SetProperty("name", mitk::StringProperty::New("Mouse Position"));
m_PositionTrackerNode->SetData( mitk::PointSet::New() );
m_PositionTrackerNode->SetColor(1.0,0.33,0.0);
m_PositionTrackerNode->SetProperty("layer", mitk::IntProperty::New(1001));
m_PositionTrackerNode->SetVisibility(true);
m_PositionTrackerNode->SetProperty("inputdevice", mitk::BoolProperty::New(true) );
m_PositionTrackerNode->SetProperty("BaseRendererMapperID", mitk::IntProperty::New(0) );//point position 2D mouse
m_PositionTrackerNode->SetProperty("baserenderer", mitk::StringProperty::New("N/A"));
}
void QmitkStdMultiWidget::AddDisplayPlaneSubTree()
{
// add the displayed planes of the multiwidget to a node to which the subtree
// @a planesSubTree points ...
float white[3] = {1.0f,1.0f,1.0f};
mitk::PlaneGeometryDataMapper2D::Pointer mapper;
// ... of widget 1
mitk::BaseRenderer* renderer1 = mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow());
m_PlaneNode1 = renderer1->GetCurrentWorldPlaneGeometryNode();
m_PlaneNode1->SetColor(white, mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow()));
m_PlaneNode1->SetProperty("visible", mitk::BoolProperty::New(true));
m_PlaneNode1->SetProperty("name", mitk::StringProperty::New(std::string(renderer1->GetName()) + ".plane"));
m_PlaneNode1->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false));
m_PlaneNode1->SetProperty("helper object", mitk::BoolProperty::New(true));
mapper = mitk::PlaneGeometryDataMapper2D::New();
m_PlaneNode1->SetMapper(mitk::BaseRenderer::Standard2D, mapper);
// ... of widget 2
mitk::BaseRenderer* renderer2 = mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow());
m_PlaneNode2 = renderer2->GetCurrentWorldPlaneGeometryNode();
m_PlaneNode2->SetColor(white, mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow()));
m_PlaneNode2->SetProperty("visible", mitk::BoolProperty::New(true));
m_PlaneNode2->SetProperty("name", mitk::StringProperty::New(std::string(renderer2->GetName()) + ".plane"));
m_PlaneNode2->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false));
m_PlaneNode2->SetProperty("helper object", mitk::BoolProperty::New(true));
mapper = mitk::PlaneGeometryDataMapper2D::New();
m_PlaneNode2->SetMapper(mitk::BaseRenderer::Standard2D, mapper);
// ... of widget 3
mitk::BaseRenderer* renderer3 = mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow());
m_PlaneNode3 = renderer3->GetCurrentWorldPlaneGeometryNode();
m_PlaneNode3->SetColor(white, mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow()));
m_PlaneNode3->SetProperty("visible", mitk::BoolProperty::New(true));
m_PlaneNode3->SetProperty("name", mitk::StringProperty::New(std::string(renderer3->GetName()) + ".plane"));
m_PlaneNode3->SetProperty("includeInBoundingBox", mitk::BoolProperty::New(false));
m_PlaneNode3->SetProperty("helper object", mitk::BoolProperty::New(true));
mapper = mitk::PlaneGeometryDataMapper2D::New();
m_PlaneNode3->SetMapper(mitk::BaseRenderer::Standard2D, mapper);
m_Node = mitk::DataNode::New();
m_Node->SetProperty("name", mitk::StringProperty::New("Widgets"));
m_Node->SetProperty("helper object", mitk::BoolProperty::New(true));
}
mitk::SliceNavigationController* QmitkStdMultiWidget::GetTimeNavigationController()
{
return m_TimeNavigationController;
}
void QmitkStdMultiWidget::EnableStandardLevelWindow()
{
levelWindowWidget->disconnect(this);
levelWindowWidget->SetDataStorage(mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow())->GetDataStorage());
levelWindowWidget->show();
}
void QmitkStdMultiWidget::DisableStandardLevelWindow()
{
levelWindowWidget->disconnect(this);
levelWindowWidget->hide();
}
// CAUTION: Legacy code for enabling Qt-signal-controlled view initialization.
// Use RenderingManager::InitializeViews() instead.
bool QmitkStdMultiWidget::InitializeStandardViews( const mitk::Geometry3D * geometry )
{
return m_RenderingManager->InitializeViews( geometry );
}
void QmitkStdMultiWidget::RequestUpdate()
{
m_RenderingManager->RequestUpdate(mitkWidget1->GetRenderWindow());
m_RenderingManager->RequestUpdate(mitkWidget2->GetRenderWindow());
m_RenderingManager->RequestUpdate(mitkWidget3->GetRenderWindow());
m_RenderingManager->RequestUpdate(mitkWidget4->GetRenderWindow());
}
void QmitkStdMultiWidget::ForceImmediateUpdate()
{
m_RenderingManager->ForceImmediateUpdate(mitkWidget1->GetRenderWindow());
m_RenderingManager->ForceImmediateUpdate(mitkWidget2->GetRenderWindow());
m_RenderingManager->ForceImmediateUpdate(mitkWidget3->GetRenderWindow());
m_RenderingManager->ForceImmediateUpdate(mitkWidget4->GetRenderWindow());
}
void QmitkStdMultiWidget::wheelEvent( QWheelEvent * e )
{
emit WheelMoved( e );
}
void QmitkStdMultiWidget::mousePressEvent(QMouseEvent * e)
{
if (e->button() == Qt::LeftButton) {
mitk::Point3D pointValue = this->GetLastLeftClickPosition();
emit LeftMouseClicked(pointValue);
}
}
void QmitkStdMultiWidget::moveEvent( QMoveEvent* e )
{
QWidget::moveEvent( e );
// it is necessary to readjust the position of the overlays as the StdMultiWidget has moved
// unfortunately it's not done by QmitkRenderWindow::moveEvent -> must be done here
emit Moved();
}
void QmitkStdMultiWidget::leaveEvent ( QEvent * /*e*/ )
{
//set cursor back to initial state
m_SlicesRotator->ResetMouseCursor();
}
QmitkRenderWindow* QmitkStdMultiWidget::GetRenderWindow1() const
{
return mitkWidget1;
}
QmitkRenderWindow* QmitkStdMultiWidget::GetRenderWindow2() const
{
return mitkWidget2;
}
QmitkRenderWindow* QmitkStdMultiWidget::GetRenderWindow3() const
{
return mitkWidget3;
}
QmitkRenderWindow* QmitkStdMultiWidget::GetRenderWindow4() const
{
return mitkWidget4;
}
const mitk::Point3D& QmitkStdMultiWidget::GetLastLeftClickPosition() const
{
return m_LastLeftClickPositionSupplier->GetCurrentPoint();
}
const mitk::Point3D QmitkStdMultiWidget::GetCrossPosition() const
{
const mitk::PlaneGeometry *plane1 =
mitkWidget1->GetSliceNavigationController()->GetCurrentPlaneGeometry();
const mitk::PlaneGeometry *plane2 =
mitkWidget2->GetSliceNavigationController()->GetCurrentPlaneGeometry();
const mitk::PlaneGeometry *plane3 =
mitkWidget3->GetSliceNavigationController()->GetCurrentPlaneGeometry();
mitk::Line3D line;
if ( (plane1 != NULL) && (plane2 != NULL)
&& (plane1->IntersectionLine( plane2, line )) )
{
mitk::Point3D point;
if ( (plane3 != NULL)
&& (plane3->IntersectionPoint( line, point )) )
{
return point;
}
}
return m_LastLeftClickPositionSupplier->GetCurrentPoint();
}
void QmitkStdMultiWidget::EnablePositionTracking()
{
if (!m_PositionTracker)
{
m_PositionTracker = mitk::PositionTracker::New("PositionTracker", NULL);
}
mitk::GlobalInteraction* globalInteraction = mitk::GlobalInteraction::GetInstance();
if (globalInteraction)
{
if(m_DataStorage.IsNotNull())
m_DataStorage->Add(m_PositionTrackerNode);
globalInteraction->AddListener(m_PositionTracker);
}
}
void QmitkStdMultiWidget::DisablePositionTracking()
{
mitk::GlobalInteraction* globalInteraction =
mitk::GlobalInteraction::GetInstance();
if(globalInteraction)
{
if (m_DataStorage.IsNotNull())
m_DataStorage->Remove(m_PositionTrackerNode);
globalInteraction->RemoveListener(m_PositionTracker);
}
}
void QmitkStdMultiWidget::EnsureDisplayContainsPoint(
mitk::DisplayGeometry* displayGeometry, const mitk::Point3D& p)
{
mitk::Point2D pointOnPlane;
displayGeometry->Map( p, pointOnPlane );
// point minus origin < width or height ==> outside ?
mitk::Vector2D pointOnRenderWindow_MM;
pointOnRenderWindow_MM = pointOnPlane.GetVectorFromOrigin()
- displayGeometry->GetOriginInMM();
mitk::Vector2D sizeOfDisplay( displayGeometry->GetSizeInMM() );
if ( sizeOfDisplay[0] < pointOnRenderWindow_MM[0]
|| 0 > pointOnRenderWindow_MM[0]
|| sizeOfDisplay[1] < pointOnRenderWindow_MM[1]
|| 0 > pointOnRenderWindow_MM[1] )
{
// point is not visible -> move geometry
mitk::Vector2D offset( (pointOnRenderWindow_MM - sizeOfDisplay / 2.0)
/ displayGeometry->GetScaleFactorMMPerDisplayUnit() );
displayGeometry->MoveBy( offset );
}
}
void QmitkStdMultiWidget::MoveCrossToPosition(const mitk::Point3D& newPosition)
{
// create a PositionEvent with the given position and
// tell the slice navigation controllers to move there
mitk::Point2D p2d;
mitk::PositionEvent event( mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow()), 0, 0, 0,
mitk::Key_unknown, p2d, newPosition );
mitk::StateEvent stateEvent(mitk::EIDLEFTMOUSEBTN, &event);
mitk::StateEvent stateEvent2(mitk::EIDLEFTMOUSERELEASE, &event);
switch ( m_PlaneMode )
{
default:
case PLANE_MODE_SLICING:
mitkWidget1->GetSliceNavigationController()->HandleEvent( &stateEvent );
mitkWidget2->GetSliceNavigationController()->HandleEvent( &stateEvent );
mitkWidget3->GetSliceNavigationController()->HandleEvent( &stateEvent );
// just in case SNCs will develop something that depends on the mouse
// button being released again
mitkWidget1->GetSliceNavigationController()->HandleEvent( &stateEvent2 );
mitkWidget2->GetSliceNavigationController()->HandleEvent( &stateEvent2 );
mitkWidget3->GetSliceNavigationController()->HandleEvent( &stateEvent2 );
break;
case PLANE_MODE_ROTATION:
m_SlicesRotator->HandleEvent( &stateEvent );
// just in case SNCs will develop something that depends on the mouse
// button being released again
m_SlicesRotator->HandleEvent( &stateEvent2 );
break;
case PLANE_MODE_SWIVEL:
m_SlicesSwiveller->HandleEvent( &stateEvent );
// just in case SNCs will develop something that depends on the mouse
// button being released again
m_SlicesSwiveller->HandleEvent( &stateEvent2 );
break;
}
// determine if cross is now out of display
// if so, move the display window
EnsureDisplayContainsPoint( mitk::BaseRenderer::GetInstance(mitkWidget1->GetRenderWindow())
->GetDisplayGeometry(), newPosition );
EnsureDisplayContainsPoint( mitk::BaseRenderer::GetInstance(mitkWidget2->GetRenderWindow())
->GetDisplayGeometry(), newPosition );
EnsureDisplayContainsPoint( mitk::BaseRenderer::GetInstance(mitkWidget3->GetRenderWindow())
->GetDisplayGeometry(), newPosition );
// update displays
m_RenderingManager->RequestUpdateAll();
}
void QmitkStdMultiWidget::HandleCrosshairPositionEvent()
{
if(!m_PendingCrosshairPositionEvent)
{
m_PendingCrosshairPositionEvent=true;
QTimer::singleShot(0,this,SLOT( HandleCrosshairPositionEventDelayed() ) );
}
}
mitk::DataNode::Pointer QmitkStdMultiWidget::GetTopLayerNode(mitk::DataStorage::SetOfObjects::ConstPointer nodes)
{
mitk::Point3D crosshairPos = this->GetCrossPosition();
mitk::DataNode::Pointer node;
int maxlayer = -32768;
if(nodes.IsNotNull())
{
mitk::BaseRenderer* baseRenderer = this->mitkWidget1->GetSliceNavigationController()->GetRenderer();
// find node with largest layer, that is the node shown on top in the render window
for (unsigned int x = 0; x < nodes->size(); x++)
{
if ( (nodes->at(x)->GetData()->GetGeometry() != NULL) &&
nodes->at(x)->GetData()->GetGeometry()->IsInside(crosshairPos) )
{
int layer = 0;
if(!(nodes->at(x)->GetIntProperty("layer", layer))) continue;
if(layer > maxlayer)
{
if( static_cast<mitk::DataNode::Pointer>(nodes->at(x))->IsVisible( baseRenderer ) )
{
node = nodes->at(x);
maxlayer = layer;
}
}
}
}
}
return node;
}
void QmitkStdMultiWidget::HandleCrosshairPositionEventDelayed()
{
m_PendingCrosshairPositionEvent = false;
// find image with highest layer
mitk::TNodePredicateDataType<mitk::Image>::Pointer isImageData = mitk::TNodePredicateDataType<mitk::Image>::New();
mitk::DataStorage::SetOfObjects::ConstPointer nodes = this->m_DataStorage->GetSubset(isImageData).GetPointer();
mitk::DataNode::Pointer node;
mitk::DataNode::Pointer topSourceNode;
mitk::Image::Pointer image;
bool isBinary = false;
node = this->GetTopLayerNode(nodes);
int component = 0;
if(node.IsNotNull())
{
node->GetBoolProperty("binary",isBinary);
if(isBinary)
{
mitk::DataStorage::SetOfObjects::ConstPointer sourcenodes = m_DataStorage->GetSources(node, NULL, true);
if(!sourcenodes->empty())
{
topSourceNode = this->GetTopLayerNode(sourcenodes);
}
if(topSourceNode.IsNotNull())
{
image = dynamic_cast<mitk::Image*>(topSourceNode->GetData());
topSourceNode->GetIntProperty("Image.Displayed Component", component);
}
else
{
image = dynamic_cast<mitk::Image*>(node->GetData());
node->GetIntProperty("Image.Displayed Component", component);
}
}
else
{
image = dynamic_cast<mitk::Image*>(node->GetData());
node->GetIntProperty("Image.Displayed Component", component);
}
}
mitk::Point3D crosshairPos = this->GetCrossPosition();
std::string statusText;
std::stringstream stream;
itk::Index<3> p;
mitk::BaseRenderer* baseRenderer = this->mitkWidget1->GetSliceNavigationController()->GetRenderer();
unsigned int timestep = baseRenderer->GetTimeStep();
if(image.IsNotNull() && (image->GetTimeSteps() > timestep ))
{
image->GetGeometry()->WorldToIndex(crosshairPos, p);
stream.precision(2);
stream<<"Position: <" << std::fixed <<crosshairPos[0] << ", " << std::fixed << crosshairPos[1] << ", " << std::fixed << crosshairPos[2] << "> mm";
stream<<"; Index: <"<<p[0] << ", " << p[1] << ", " << p[2] << "> ";
mitk::ScalarType pixelValue = image->GetPixelValueByIndex(p, timestep, component);
if (fabs(pixelValue)>1000000 || fabs(pixelValue) < 0.01)
{
stream<<"; Time: " << baseRenderer->GetTime() << " ms; Pixelvalue: "<< std::scientific<< pixelValue <<" ";
}
else
{
stream<<"; Time: " << baseRenderer->GetTime() << " ms; Pixelvalue: "<< pixelValue <<" ";
}
}
else
{
stream << "No image information at this position!";
}
statusText = stream.str();
mitk::StatusBar::GetInstance()->DisplayGreyValueText(statusText.c_str());
}
void QmitkStdMultiWidget::EnableNavigationControllerEventListening()
{
// Let NavigationControllers listen to GlobalInteraction
mitk::GlobalInteraction *gi = mitk::GlobalInteraction::GetInstance();
// Listen for SliceNavigationController
mitkWidget1->GetSliceNavigationController()->crosshairPositionEvent.AddListener( mitk::MessageDelegate<QmitkStdMultiWidget>( this, &QmitkStdMultiWidget::HandleCrosshairPositionEvent ) );
mitkWidget2->GetSliceNavigationController()->crosshairPositionEvent.AddListener( mitk::MessageDelegate<QmitkStdMultiWidget>( this, &QmitkStdMultiWidget::HandleCrosshairPositionEvent ) );
mitkWidget3->GetSliceNavigationController()->crosshairPositionEvent.AddListener( mitk::MessageDelegate<QmitkStdMultiWidget>( this, &QmitkStdMultiWidget::HandleCrosshairPositionEvent ) );
switch ( m_PlaneMode )
{
default:
case PLANE_MODE_SLICING:
gi->AddListener( mitkWidget1->GetSliceNavigationController() );
gi->AddListener( mitkWidget2->GetSliceNavigationController() );
gi->AddListener( mitkWidget3->GetSliceNavigationController() );
gi->AddListener( mitkWidget4->GetSliceNavigationController() );
break;
case PLANE_MODE_ROTATION:
gi->AddListener( m_SlicesRotator );
break;
case PLANE_MODE_SWIVEL:
gi->AddListener( m_SlicesSwiveller );
break;
}
gi->AddListener( m_TimeNavigationController );
m_CrosshairNavigationEnabled = true;
}
void QmitkStdMultiWidget::DisableNavigationControllerEventListening()
{
// Do not let NavigationControllers listen to GlobalInteraction
mitk::GlobalInteraction *gi = mitk::GlobalInteraction::GetInstance();
switch ( m_PlaneMode )
{
default:
case PLANE_MODE_SLICING:
gi->RemoveListener( mitkWidget1->GetSliceNavigationController() );
gi->RemoveListener( mitkWidget2->GetSliceNavigationController() );
gi->RemoveListener( mitkWidget3->GetSliceNavigationController() );
gi->RemoveListener( mitkWidget4->GetSliceNavigationController() );
break;
case PLANE_MODE_ROTATION:
m_SlicesRotator->ResetMouseCursor();
gi->RemoveListener( m_SlicesRotator );
break;
case PLANE_MODE_SWIVEL:
m_SlicesSwiveller->ResetMouseCursor();
gi->RemoveListener( m_SlicesSwiveller );
break;
}
gi->RemoveListener( m_TimeNavigationController );
m_CrosshairNavigationEnabled = false;
}
int QmitkStdMultiWidget::GetLayout() const
{
return m_Layout;
}
bool QmitkStdMultiWidget::GetGradientBackgroundFlag() const
{
return m_GradientBackgroundFlag;
}
void QmitkStdMultiWidget::EnableGradientBackground()
{
// gradient background is by default only in widget 4, otherwise
// interferences between 2D rendering and VTK rendering may occur.
//m_GradientBackground1->Enable();
//m_GradientBackground2->Enable();
//m_GradientBackground3->Enable();
m_GradientBackground4->Enable();
m_GradientBackgroundFlag = true;
}
void QmitkStdMultiWidget::DisableGradientBackground()
{
//m_GradientBackground1->Disable();
//m_GradientBackground2->Disable();
//m_GradientBackground3->Disable();
m_GradientBackground4->Disable();
m_GradientBackgroundFlag = false;
}
void QmitkStdMultiWidget::EnableDepartmentLogo()
{
m_LogoRendering->SetVisibility(true);
}
void QmitkStdMultiWidget::DisableDepartmentLogo()
{
m_LogoRendering->SetVisibility(false);
}
bool QmitkStdMultiWidget::IsDepartmentLogoEnabled() const
{
return m_LogoRendering->IsVisible(mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow()));
}
bool QmitkStdMultiWidget::IsCrosshairNavigationEnabled() const
{
return m_CrosshairNavigationEnabled;
}
mitk::SlicesRotator * QmitkStdMultiWidget::GetSlicesRotator() const
{
return m_SlicesRotator;
}
mitk::SlicesSwiveller * QmitkStdMultiWidget::GetSlicesSwiveller() const
{
return m_SlicesSwiveller;
}
void QmitkStdMultiWidget::SetWidgetPlaneVisibility(const char* widgetName, bool visible, mitk::BaseRenderer *renderer)
{
if (m_DataStorage.IsNotNull())
{
mitk::DataNode* n = m_DataStorage->GetNamedNode(widgetName);
if (n != NULL)
n->SetVisibility(visible, renderer);
}
}
void QmitkStdMultiWidget::SetWidgetPlanesVisibility(bool visible, mitk::BaseRenderer *renderer)
{
if (m_PlaneNode1.IsNotNull())
{
m_PlaneNode1->SetVisibility(visible, renderer);
}
if (m_PlaneNode2.IsNotNull())
{
m_PlaneNode2->SetVisibility(visible, renderer);
}
if (m_PlaneNode3.IsNotNull())
{
m_PlaneNode3->SetVisibility(visible, renderer);
}
m_RenderingManager->RequestUpdateAll();
}
void QmitkStdMultiWidget::SetWidgetPlanesLocked(bool locked)
{
//do your job and lock or unlock slices.
GetRenderWindow1()->GetSliceNavigationController()->SetSliceLocked(locked);
GetRenderWindow2()->GetSliceNavigationController()->SetSliceLocked(locked);
GetRenderWindow3()->GetSliceNavigationController()->SetSliceLocked(locked);
}
void QmitkStdMultiWidget::SetWidgetPlanesRotationLocked(bool locked)
{
//do your job and lock or unlock slices.
GetRenderWindow1()->GetSliceNavigationController()->SetSliceRotationLocked(locked);
GetRenderWindow2()->GetSliceNavigationController()->SetSliceRotationLocked(locked);
GetRenderWindow3()->GetSliceNavigationController()->SetSliceRotationLocked(locked);
}
void QmitkStdMultiWidget::SetWidgetPlanesRotationLinked( bool link )
{
m_SlicesRotator->SetLinkPlanes( link );
m_SlicesSwiveller->SetLinkPlanes( link );
emit WidgetPlanesRotationLinked( link );
}
void QmitkStdMultiWidget::SetWidgetPlaneMode( int userMode )
{
MITK_DEBUG << "Changing crosshair mode to " << userMode;
// first of all reset left mouse button interaction to default if PACS interaction style is active
m_MouseModeSwitcher->SelectMouseMode( mitk::MouseModeSwitcher::MousePointer );
emit WidgetNotifyNewCrossHairMode( userMode );
int mode = m_PlaneMode;
bool link = false;
// Convert user interface mode to actual mode
{
switch(userMode)
{
case 0:
mode = PLANE_MODE_SLICING;
link = false;
break;
case 1:
mode = PLANE_MODE_ROTATION;
link = false;
break;
case 2:
mode = PLANE_MODE_ROTATION;
link = true;
break;
case 3:
mode = PLANE_MODE_SWIVEL;
link = false;
break;
}
}
// Slice rotation linked
m_SlicesRotator->SetLinkPlanes( link );
m_SlicesSwiveller->SetLinkPlanes( link );
// Do nothing if mode didn't change
if ( m_PlaneMode == mode )
{
return;
}
mitk::GlobalInteraction *gi = mitk::GlobalInteraction::GetInstance();
// Remove listeners of previous mode
switch ( m_PlaneMode )
{
default:
case PLANE_MODE_SLICING:
// Notify MainTemplate GUI that this mode has been deselected
emit WidgetPlaneModeSlicing( false );
gi->RemoveListener( mitkWidget1->GetSliceNavigationController() );
gi->RemoveListener( mitkWidget2->GetSliceNavigationController() );
gi->RemoveListener( mitkWidget3->GetSliceNavigationController() );
gi->RemoveListener( mitkWidget4->GetSliceNavigationController() );
break;
case PLANE_MODE_ROTATION:
// Notify MainTemplate GUI that this mode has been deselected
emit WidgetPlaneModeRotation( false );
m_SlicesRotator->ResetMouseCursor();
gi->RemoveListener( m_SlicesRotator );
break;
case PLANE_MODE_SWIVEL:
// Notify MainTemplate GUI that this mode has been deselected
emit WidgetPlaneModeSwivel( false );
m_SlicesSwiveller->ResetMouseCursor();
gi->RemoveListener( m_SlicesSwiveller );
break;
}
// Set new mode and add corresponding listener to GlobalInteraction
m_PlaneMode = mode;
switch ( m_PlaneMode )
{
default:
case PLANE_MODE_SLICING:
// Notify MainTemplate GUI that this mode has been selected
emit WidgetPlaneModeSlicing( true );
// Add listeners
gi->AddListener( mitkWidget1->GetSliceNavigationController() );
gi->AddListener( mitkWidget2->GetSliceNavigationController() );
gi->AddListener( mitkWidget3->GetSliceNavigationController() );
gi->AddListener( mitkWidget4->GetSliceNavigationController() );
m_RenderingManager->InitializeViews();
break;
case PLANE_MODE_ROTATION:
// Notify MainTemplate GUI that this mode has been selected
emit WidgetPlaneModeRotation( true );
// Add listener
gi->AddListener( m_SlicesRotator );
break;
case PLANE_MODE_SWIVEL:
// Notify MainTemplate GUI that this mode has been selected
emit WidgetPlaneModeSwivel( true );
// Add listener
gi->AddListener( m_SlicesSwiveller );
break;
}
// Notify MainTemplate GUI that mode has changed
emit WidgetPlaneModeChange(m_PlaneMode);
}
void QmitkStdMultiWidget::SetGradientBackgroundColors( const mitk::Color & upper, const mitk::Color & lower )
{
m_GradientBackground1->SetGradientColors(upper[0], upper[1], upper[2], lower[0], lower[1], lower[2]);
m_GradientBackground2->SetGradientColors(upper[0], upper[1], upper[2], lower[0], lower[1], lower[2]);
m_GradientBackground3->SetGradientColors(upper[0], upper[1], upper[2], lower[0], lower[1], lower[2]);
m_GradientBackground4->SetGradientColors(upper[0], upper[1], upper[2], lower[0], lower[1], lower[2]);
m_GradientBackgroundFlag = true;
}
void QmitkStdMultiWidget::SetDepartmentLogoPath( const char * path )
{
m_LogoRendering->SetLogoImagePath(path);
mitk::BaseRenderer* renderer = mitk::BaseRenderer::GetInstance(mitkWidget4->GetRenderWindow());
m_LogoRendering->Update(renderer);
RequestUpdate();
}
void QmitkStdMultiWidget::SetWidgetPlaneModeToSlicing( bool activate )
{
if ( activate )
{
this->SetWidgetPlaneMode( PLANE_MODE_SLICING );
}
}
void QmitkStdMultiWidget::SetWidgetPlaneModeToRotation( bool activate )
{
if ( activate )
{
this->SetWidgetPlaneMode( PLANE_MODE_ROTATION );
}
}
void QmitkStdMultiWidget::SetWidgetPlaneModeToSwivel( bool activate )
{
if ( activate )
{
this->SetWidgetPlaneMode( PLANE_MODE_SWIVEL );
}
}
void QmitkStdMultiWidget::OnLayoutDesignChanged( int layoutDesignIndex )
{
switch( layoutDesignIndex )
{
case LAYOUT_DEFAULT:
{
this->changeLayoutToDefault();
break;
}
case LAYOUT_2D_IMAGES_UP:
{
this->changeLayoutTo2DImagesUp();
break;
}
case LAYOUT_2D_IMAGES_LEFT:
{
this->changeLayoutTo2DImagesLeft();
break;
}
case LAYOUT_BIG_3D:
{
this->changeLayoutToBig3D();
break;
}
case LAYOUT_WIDGET1:
{
this->changeLayoutToWidget1();
break;
}
case LAYOUT_WIDGET2:
{
this->changeLayoutToWidget2();
break;
}
case LAYOUT_WIDGET3:
{
this->changeLayoutToWidget3();
break;
}
case LAYOUT_2X_2D_AND_3D_WIDGET:
{
this->changeLayoutTo2x2Dand3DWidget();
break;
}
case LAYOUT_ROW_WIDGET_3_AND_4:
{
this->changeLayoutToRowWidget3And4();
break;
}
case LAYOUT_COLUMN_WIDGET_3_AND_4:
{
this->changeLayoutToColumnWidget3And4();
break;
}
case LAYOUT_ROW_WIDGET_SMALL3_AND_BIG4:
{
this->changeLayoutToRowWidgetSmall3andBig4();
break;
}
case LAYOUT_SMALL_UPPER_WIDGET2_BIG3_AND4:
{
this->changeLayoutToSmallUpperWidget2Big3and4();
break;
}
case LAYOUT_2D_AND_3D_LEFT_2D_RIGHT_WIDGET:
{
this->changeLayoutToLeft2Dand3DRight2D();
break;
}
};
}
void QmitkStdMultiWidget::UpdateAllWidgets()
{
mitkWidget1->resize( mitkWidget1Container->frameSize().width()-1, mitkWidget1Container->frameSize().height() );
mitkWidget1->resize( mitkWidget1Container->frameSize().width(), mitkWidget1Container->frameSize().height() );
mitkWidget2->resize( mitkWidget2Container->frameSize().width()-1, mitkWidget2Container->frameSize().height() );
mitkWidget2->resize( mitkWidget2Container->frameSize().width(), mitkWidget2Container->frameSize().height() );
mitkWidget3->resize( mitkWidget3Container->frameSize().width()-1, mitkWidget3Container->frameSize().height() );
mitkWidget3->resize( mitkWidget3Container->frameSize().width(), mitkWidget3Container->frameSize().height() );
mitkWidget4->resize( mitkWidget4Container->frameSize().width()-1, mitkWidget4Container->frameSize().height() );
mitkWidget4->resize( mitkWidget4Container->frameSize().width(), mitkWidget4Container->frameSize().height() );
}
void QmitkStdMultiWidget::HideAllWidgetToolbars()
{
mitkWidget1->HideRenderWindowMenu();
mitkWidget2->HideRenderWindowMenu();
mitkWidget3->HideRenderWindowMenu();
mitkWidget4->HideRenderWindowMenu();
}
void QmitkStdMultiWidget::ActivateMenuWidget( bool state )
{
mitkWidget1->ActivateMenuWidget( state, this );
mitkWidget2->ActivateMenuWidget( state, this );
mitkWidget3->ActivateMenuWidget( state, this );
mitkWidget4->ActivateMenuWidget( state, this );
}
bool QmitkStdMultiWidget::IsMenuWidgetEnabled() const
{
return mitkWidget1->GetActivateMenuWidgetFlag();
}
void QmitkStdMultiWidget::ResetCrosshair()
{
if (m_DataStorage.IsNotNull())
{
m_RenderingManager->InitializeViewsByBoundingObjects(m_DataStorage);
//m_RenderingManager->InitializeViews( m_DataStorage->ComputeVisibleBoundingGeometry3D() );
// reset interactor to normal slicing
this->SetWidgetPlaneMode(PLANE_MODE_SLICING);
}
}
void QmitkStdMultiWidget::EnableColoredRectangles()
{
m_RectangleRendering1->Enable(1.0, 0.0, 0.0);
m_RectangleRendering2->Enable(0.0, 1.0, 0.0);
m_RectangleRendering3->Enable(0.0, 0.0, 1.0);
m_RectangleRendering4->Enable(1.0, 1.0, 0.0);
}
void QmitkStdMultiWidget::DisableColoredRectangles()
{
m_RectangleRendering1->Disable();
m_RectangleRendering2->Disable();
m_RectangleRendering3->Disable();
m_RectangleRendering4->Disable();
}
bool QmitkStdMultiWidget::IsColoredRectanglesEnabled() const
{
return m_RectangleRendering1->IsEnabled();
}
mitk::MouseModeSwitcher* QmitkStdMultiWidget::GetMouseModeSwitcher()
{
return m_MouseModeSwitcher;
}
void QmitkStdMultiWidget::MouseModeSelected( mitk::MouseModeSwitcher::MouseMode mouseMode )
{
if ( mouseMode == 0 )
{
this->EnableNavigationControllerEventListening();
}
else
{
this->DisableNavigationControllerEventListening();
}
}
mitk::DataNode::Pointer QmitkStdMultiWidget::GetWidgetPlane1()
{
return this->m_PlaneNode1;
}
mitk::DataNode::Pointer QmitkStdMultiWidget::GetWidgetPlane2()
{
return this->m_PlaneNode2;
}
mitk::DataNode::Pointer QmitkStdMultiWidget::GetWidgetPlane3()
{
return this->m_PlaneNode3;
}
mitk::DataNode::Pointer QmitkStdMultiWidget::GetWidgetPlane(int id)
{
switch(id)
{
case 1: return this->m_PlaneNode1;
break;
case 2: return this->m_PlaneNode2;
break;
case 3: return this->m_PlaneNode3;
break;
default: return NULL;
}
}
diff --git a/Modules/QtWidgetsExt/CMakeLists.txt b/Modules/QtWidgetsExt/CMakeLists.txt
index fb35dcde93..5bf4886802 100644
--- a/Modules/QtWidgetsExt/CMakeLists.txt
+++ b/Modules/QtWidgetsExt/CMakeLists.txt
@@ -1,6 +1,6 @@
MITK_CREATE_MODULE(
INCLUDE_DIRS QmitkApplicationBase QmitkPropertyObservers
DEPENDS MitkImageStatistics MitkQtWidgets
- PACKAGE_DEPENDS Qt4|QtWebKit Qwt Qxt
+ PACKAGE_DEPENDS CTK|CTKWidgets Qt4|QtWebKit Qt5|Concurrent+Svg+WebKitWidgets+Xml Qwt
WARNINGS_AS_ERRORS
)
diff --git a/Modules/QtWidgetsExt/QmitkCorrespondingPointSetsModel.cpp b/Modules/QtWidgetsExt/QmitkCorrespondingPointSetsModel.cpp
index 1135e759da..7f38e78391 100644
--- a/Modules/QtWidgetsExt/QmitkCorrespondingPointSetsModel.cpp
+++ b/Modules/QtWidgetsExt/QmitkCorrespondingPointSetsModel.cpp
@@ -1,739 +1,748 @@
/*===================================================================
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 "QmitkCorrespondingPointSetsModel.h"
#include <itkCommand.h>
#include "mitkInteractionConst.h"
#include "mitkPointOperation.h"
#include "mitkRenderingManager.h"
#include <mitkEvent.h>
#include <mitkStateEvent.h>
#include <mitkInteractionConst.h>
#include <mitkStepper.h>
#include <QStringListModel>
#include <mitkPointSetInteractor.h>
#include <mitkGlobalInteraction.h>
QmitkCorrespondingPointSetsModel::QmitkCorrespondingPointSetsModel(int, QObject* parent)
: QAbstractTableModel(parent),
m_PointSetNode(NULL),
m_ReferencePointSetNode(NULL),
m_TimeStepper(NULL),
m_SelectedPointSetIndex(-1),
m_Interactor(NULL),
m_MultiWidget( NULL ),
m_PointSetModifiedObserverTag(0),
m_ReferencePointSetModifiedObserverTag(0)
{
}
Qt::ItemFlags QmitkCorrespondingPointSetsModel::flags(const QModelIndex& index) const
{
if (index.isValid())
return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsSelectable | Qt::ItemIsEnabled;
else
return Qt::ItemIsDropEnabled | Qt::ItemIsSelectable | Qt::ItemIsEnabled;
}
Qt::DropActions QmitkCorrespondingPointSetsModel::supportedDropActions() const
{
return Qt::CopyAction | Qt::MoveAction;
}
bool QmitkCorrespondingPointSetsModel::dropMimeData(const QMimeData*, Qt::DropAction action, int row, int, const QModelIndex &parent)
{
if (action == Qt::IgnoreAction)
return true;
int targetRow;
if (row != -1)
targetRow = row;
else if (parent.isValid())
targetRow = parent.row();
else
targetRow = rowCount(QModelIndex());
this->MoveSelectedPoint(targetRow);
return true;
}
QmitkCorrespondingPointSetsModel::~QmitkCorrespondingPointSetsModel()
{
;
}
void QmitkCorrespondingPointSetsModel::RemoveObservers(){
if (m_PointSetNode)
{
mitk::PointSet::Pointer oldPointSet = dynamic_cast<mitk::PointSet*>(m_PointSetNode->GetData());
if (oldPointSet.IsNotNull())
{
oldPointSet->RemoveObserver(m_PointSetModifiedObserverTag);
}
}
if (m_ReferencePointSetNode)
{
mitk::PointSet::Pointer oldPointSet = dynamic_cast<mitk::PointSet*>(m_ReferencePointSetNode->GetData());
if (oldPointSet.IsNotNull())
{
oldPointSet->RemoveObserver(m_ReferencePointSetModifiedObserverTag);
}
}
}
void QmitkCorrespondingPointSetsModel::AddObservers()
{
mitk::PointSet::Pointer pointSet = this->CheckForPointSetInNode(m_PointSetNode);
if ( pointSet.IsNotNull())
{
// add new observer for modified if necessary
itk::ReceptorMemberCommand<QmitkCorrespondingPointSetsModel>::Pointer modCommand = itk::ReceptorMemberCommand<QmitkCorrespondingPointSetsModel>::New();
modCommand->SetCallbackFunction( this, &QmitkCorrespondingPointSetsModel::OnPointSetChanged );
m_PointSetModifiedObserverTag = pointSet->AddObserver( itk::ModifiedEvent(), modCommand );
}
else
{
m_PointSetModifiedObserverTag = 0;
}
pointSet = this->CheckForPointSetInNode(m_ReferencePointSetNode);
if ( pointSet.IsNotNull())
{
// add new observer for modified if necessary
itk::ReceptorMemberCommand<QmitkCorrespondingPointSetsModel>::Pointer modCommand = itk::ReceptorMemberCommand<QmitkCorrespondingPointSetsModel>::New();
modCommand->SetCallbackFunction( this, &QmitkCorrespondingPointSetsModel::OnPointSetChanged );
m_ReferencePointSetModifiedObserverTag = pointSet->AddObserver( itk::ModifiedEvent(), modCommand );
}
else
{
m_ReferencePointSetModifiedObserverTag = 0;
}
}
void QmitkCorrespondingPointSetsModel::OnPointSetChanged(const itk::EventObject&)
{
- QAbstractTableModel::reset();
+ QAbstractTableModel::beginResetModel();
+ QAbstractTableModel::endResetModel();
}
void QmitkCorrespondingPointSetsModel::SetPointSetNodes( std::vector<mitk::DataNode*> nodes )
{
this->RemoveObservers();
if ( nodes.size() > 1 )
{
m_PointSetNode = nodes.front();
m_ReferencePointSetNode = nodes.back();
}
else if ( nodes.size() == 1 )
{
m_PointSetNode = nodes.front();
m_ReferencePointSetNode = NULL;
}
else
{
m_PointSetNode = NULL;
m_ReferencePointSetNode = NULL;
}
this->AddObservers();
- QAbstractTableModel::reset();
+ QAbstractTableModel::beginResetModel();
+ QAbstractTableModel::endResetModel();
}
void QmitkCorrespondingPointSetsModel::SetTimeStep(int t)
{
if (!m_TimeStepper)
return;
m_TimeStepper->SetPos(t);
- QAbstractTableModel::reset();
+ QAbstractTableModel::beginResetModel();
+ QAbstractTableModel::endResetModel();
}
int QmitkCorrespondingPointSetsModel::GetTimeStep() const
{
if (!m_TimeStepper)
return 0;
return m_TimeStepper->GetPos();
}
int QmitkCorrespondingPointSetsModel::rowCount(const QModelIndex&) const
{
if (!m_TimeStepper)
return 0;
mitk::PointSet::Pointer pointSet = this->CheckForPointSetInNode(m_PointSetNode);
mitk::PointSet::Pointer referencePointSet = this->CheckForPointSetInNode(m_ReferencePointSetNode);
int sizePS = 0;
int sizeRPS = 0;
if ( pointSet.IsNotNull() )
{
sizePS = pointSet->GetSize(m_TimeStepper->GetPos());
}
if ( referencePointSet.IsNotNull() )
{
sizeRPS = referencePointSet->GetSize(m_TimeStepper->GetPos());
}
if ( sizePS > sizeRPS )
return sizePS;
return sizeRPS;
}
int QmitkCorrespondingPointSetsModel::columnCount(const QModelIndex&) const
{
return 2;
}
QVariant QmitkCorrespondingPointSetsModel::data(const QModelIndex& index, int role) const
{
mitk::PointSet::Pointer pointSet = NULL;
if ( index.column() == 0 )
pointSet = this->CheckForPointSetInNode(m_PointSetNode);
else if ( index.column() == 1 )
pointSet = this->CheckForPointSetInNode(m_ReferencePointSetNode);
if ( pointSet.IsNull() )
{
return QVariant();
}
if ( !index.isValid() )
{
return QVariant();
}
if ( index.row() >= pointSet->GetSize(m_TimeStepper->GetPos()) )
{
return QVariant();
}
if (role == Qt::DisplayRole)
{
int id;
mitk::PointSet::PointType p;
bool pointFound = this->GetPointForModelIndex(index, p, id);
if (pointFound == false)
return QVariant();
QString s = "";
bool firstProp = true;
if (this->QTPropIdsEnabled())
{
s.append(QString("%0").arg( id, 3));
firstProp = false;
}
if (this->QTPropCoordinatesEnabled())
{
if(!firstProp)
s.append(QString(": "));
s.append(QString("(%0, %1, %2)")
.arg( p[0], 0, 'f', 2 )
.arg( p[1], 0, 'f', 2 )
.arg( p[2], 0, 'f', 2 ));
}
return QVariant(s);
}
else
{
return QVariant();
}
}
QVariant QmitkCorrespondingPointSetsModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role != Qt::DisplayRole)
{
return QVariant();
}
if (orientation == Qt::Horizontal)
{
if (section == 0)
{
if ( m_PointSetNode )
return QString::fromStdString(this->m_PointSetNode->GetName());
}
else if (section == 1)
{
if ( m_ReferencePointSetNode )
return QString::fromStdString(this->m_ReferencePointSetNode->GetName());
}
return QString();
}
return QString("%1").arg(section);
}
bool QmitkCorrespondingPointSetsModel::GetPointForModelIndex(const QModelIndex &index, mitk::PointSet::PointType& p,
int& id) const
{
if (!m_TimeStepper)
return false;
mitk::PointSet::Pointer pointSet = NULL;
if ( index.column() == 0 )
pointSet = this->CheckForPointSetInNode(m_PointSetNode);
else if ( index.column() == 1 )
pointSet = this->CheckForPointSetInNode(m_ReferencePointSetNode);
if (pointSet.IsNull() || !pointSet->GetPointSet(m_TimeStepper->GetPos()))
return false;
if ((index.row() < 0) || (index.row() >= (int)pointSet->GetPointSet(m_TimeStepper->GetPos())->GetPoints()->Size()))
return false;
// get the nth. element, if it exists.
// we can not use the index directly, because PointSet uses a map container,
// where the index is not necessarily the same as the key.
// Therefore we have to count the elements
mitk::PointSet::PointsContainer::Iterator it = pointSet->GetPointSet(m_TimeStepper->GetPos())->GetPoints()->Begin();
for (int i = 0; i < index.row(); ++i)
{
++it;
if (it == pointSet->GetPointSet(m_TimeStepper->GetPos())->GetPoints()->End())
return false;
}
if (it != pointSet->GetPointSet(m_TimeStepper->GetPos())->GetPoints()->End()) // not at the end,
{
p = it->Value();
id = it->Index();
return true;
}
return false;
}
bool QmitkCorrespondingPointSetsModel::GetPointForModelIndex(int row, int column, mitk::PointSet::PointType& p,
int& id) const
{
if (!m_TimeStepper)
return false;
mitk::PointSet::Pointer pointSet = NULL;
if (column == 0 )
pointSet = this->CheckForPointSetInNode(m_PointSetNode);
else if ( column == 1 )
pointSet = this->CheckForPointSetInNode(m_ReferencePointSetNode);
if (pointSet.IsNull() || !pointSet->GetPointSet(m_TimeStepper->GetPos()))
return false;
if ((row < 0) || (row >= (int)pointSet->GetPointSet(m_TimeStepper->GetPos())->GetPoints()->Size()))
return false;
// get the nth. element, if it exists.
// we can not use the index directly, because PointSet uses a map container,
// where the index is not necessarily the same as the key.
// Therefore we have to count the elements
mitk::PointSet::PointsContainer::Iterator it = pointSet->GetPointSet(m_TimeStepper->GetPos())->GetPoints()->Begin();
for (int i = 0; i < row; ++i)
{
++it;
if (it == pointSet->GetPointSet(m_TimeStepper->GetPos())->GetPoints()->End())
return false;
}
if (it != pointSet->GetPointSet(m_TimeStepper->GetPos())->GetPoints()->End()) // not at the end,
{
p = it->Value();
id = it->Index();
return true;
}
return false;
}
bool QmitkCorrespondingPointSetsModel::GetModelIndexForPointID(int id, QModelIndex& index, int column) const
{
if (!m_TimeStepper)
return false;
mitk::PointSet::Pointer pointSet = NULL;
if (column == 0)
pointSet = this->CheckForPointSetInNode(m_PointSetNode);
else if (column == 1)
pointSet = this->CheckForPointSetInNode(m_ReferencePointSetNode);
if (!pointSet.IsNull() || !pointSet->GetPointSet(m_TimeStepper->GetPos()))
{
mitk::PointSet::PointsContainer::Pointer points = pointSet->GetPointSet(m_TimeStepper->GetPos())->GetPoints();
if (!points->IndexExists(id))
return false;
unsigned int idx = 0;
for (mitk::PointSet::PointsContainer::Iterator it = points->Begin(); it != points->End(); ++it)
{
if (static_cast<int>(it->Index()) == id) // we found the correct element
{
index = this->index(idx, column);
return true;
}
idx++;
}
}
return false; // nothing found
}
bool QmitkCorrespondingPointSetsModel::GetModelIndexForSelectedPoint(QModelIndex& index) const
{
if (!m_TimeStepper)
return false;
mitk::DataNode* dataNode = NULL;
if (this->m_SelectedPointSetIndex == 0)
dataNode = this->m_PointSetNode;
else if (this->m_SelectedPointSetIndex == 1)
dataNode = this->m_ReferencePointSetNode;
mitk::PointSet::Pointer pointSet = this->CheckForPointSetInNode(dataNode);
if (pointSet.IsNull())
return false;
return this->GetModelIndexForPointID(
pointSet->SearchSelectedPoint(m_TimeStepper->GetPos()),
index,
this->m_SelectedPointSetIndex);
}
void QmitkCorrespondingPointSetsModel::MoveSelectedPointUp()
{
if (!m_TimeStepper)
return;
mitk::DataNode* dataNode = NULL;
if (this->m_SelectedPointSetIndex == 0)
dataNode = this->m_PointSetNode;
else if (this->m_SelectedPointSetIndex == 1)
dataNode = this->m_ReferencePointSetNode;
mitk::PointSet::Pointer pointSet = this->CheckForPointSetInNode(dataNode);
if (pointSet.IsNull())
return;
int selectedID = pointSet->SearchSelectedPoint(m_TimeStepper->GetPos());
if (selectedID == -1)
return;
mitk::ScalarType tsInMS = pointSet->GetTimeGeometry()->TimeStepToTimePoint(m_TimeStepper->GetPos());
mitk::PointOperation* doOp = new mitk::PointOperation(mitk::OpMOVEPOINTUP,tsInMS, pointSet->GetPoint(selectedID, m_TimeStepper->GetPos()), selectedID, true);
pointSet->ExecuteOperation(doOp);
- QAbstractTableModel::reset();
+ QAbstractTableModel::beginResetModel();
+ QAbstractTableModel::endResetModel();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
emit SignalPointSetChanged();
}
void QmitkCorrespondingPointSetsModel::MoveSelectedPointDown()
{
if (!m_TimeStepper)
return;
mitk::DataNode* dataNode = NULL;
if (this->m_SelectedPointSetIndex == 0)
dataNode = this->m_PointSetNode;
else if (this->m_SelectedPointSetIndex == 1)
dataNode = this->m_ReferencePointSetNode;
mitk::PointSet::Pointer pointSet = this->CheckForPointSetInNode(dataNode);
if (pointSet.IsNull())
return;
int selectedID = pointSet->SearchSelectedPoint(m_TimeStepper->GetPos());
if (selectedID == -1)
return;
mitk::ScalarType tsInMS = pointSet->GetTimeGeometry()->TimeStepToTimePoint(m_TimeStepper->GetPos());
mitk::PointOperation* doOp = new mitk::PointOperation(mitk::OpMOVEPOINTDOWN, tsInMS, pointSet->GetPoint(selectedID, m_TimeStepper->GetPos()), selectedID, true);
pointSet->ExecuteOperation(doOp);
- QAbstractTableModel::reset();
+ QAbstractTableModel::beginResetModel();
+ QAbstractTableModel::endResetModel();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
emit SignalPointSetChanged();
}
int QmitkCorrespondingPointSetsModel::SearchSelectedPoint()
{
if (!m_TimeStepper)
return -1;
mitk::DataNode* dataNode = NULL;
if (this->m_SelectedPointSetIndex == 0)
dataNode = this->m_PointSetNode;
else if (this->m_SelectedPointSetIndex == 1)
dataNode = this->m_ReferencePointSetNode;
mitk::PointSet::Pointer pointSet = this->CheckForPointSetInNode(dataNode);
if (pointSet.IsNull())
return -1;
return pointSet->SearchSelectedPoint(m_TimeStepper->GetPos());
}
void QmitkCorrespondingPointSetsModel::RemoveSelectedPoint()
{
if (!m_TimeStepper)
return;
mitk::DataNode* dataNode = NULL;
if (this->m_SelectedPointSetIndex == 0){
dataNode = this->m_PointSetNode;
}
else if (this->m_SelectedPointSetIndex == 1){
dataNode = this->m_ReferencePointSetNode;
}
if (dataNode == NULL)
return;
//send a DEL event to pointsetinteractor
const mitk::Event* delEvent = new mitk::Event(this->m_MultiWidget->GetRenderWindow1()->GetRenderer(), mitk::Type_KeyPress, mitk::BS_NoButton, mitk::BS_NoButton, mitk::Key_Delete);
mitk::StateEvent* delStateEvent = new mitk::StateEvent(mitk::EIDDELETE, delEvent);
m_Interactor->HandleEvent(delStateEvent);
delete delEvent;
delete delStateEvent;
- QAbstractTableModel::reset();
+ QAbstractTableModel::beginResetModel();
+ QAbstractTableModel::endResetModel();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
emit SignalPointSetChanged();
}
void QmitkCorrespondingPointSetsModel::MoveSelectedPoint(int targetID)
{
if (!m_TimeStepper)
return;
mitk::DataNode* dataNode = NULL;
if (this->m_SelectedPointSetIndex == 0)
dataNode = this->m_PointSetNode;
else if (this->m_SelectedPointSetIndex == 1)
dataNode = this->m_ReferencePointSetNode;
if (dataNode == NULL)
return;
mitk::PointSet::Pointer pointSet = this->CheckForPointSetInNode(dataNode);
if (pointSet.IsNull())
return;
int selectedID = pointSet->SearchSelectedPoint(m_TimeStepper->GetPos());
if (targetID >= pointSet->GetSize())
targetID = pointSet->GetSize()-1;
mitk::PointSet::PointsContainer::Iterator it = pointSet->GetPointSet(m_TimeStepper->GetPos())->GetPoints()->Begin();
for (int i=0; i<targetID; ++i)
it++;
targetID = it->Index();
if (selectedID < 0 || targetID < 0)
return;
int direction = mitk::OpNOTHING;
if (selectedID > targetID)
direction = mitk::OpMOVEPOINTUP;
else if (selectedID < targetID)
direction = mitk::OpMOVEPOINTDOWN;
while (selectedID != targetID){
mitk::ScalarType tsInMS = pointSet->GetTimeGeometry()->TimeStepToTimePoint(m_TimeStepper->GetPos());
mitk::PointOperation* doOp = new mitk::PointOperation(direction, tsInMS, pointSet->GetPoint(selectedID, m_TimeStepper->GetPos()), selectedID, true);
pointSet->ExecuteOperation(doOp);
selectedID = pointSet->SearchSelectedPoint(m_TimeStepper->GetPos());
}
- QAbstractTableModel::reset();
+ QAbstractTableModel::beginResetModel();
+ QAbstractTableModel::endResetModel();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
emit SignalPointSetChanged();
}
mitk::PointSet* QmitkCorrespondingPointSetsModel::CheckForPointSetInNode(mitk::DataNode* node) const
{
if (node != NULL)
{
mitk::PointSet::Pointer pointSet = dynamic_cast<mitk::PointSet*>(node->GetData());
if (pointSet.IsNotNull())
return pointSet;
}
return NULL;
}
bool QmitkCorrespondingPointSetsModel::QTPropCoordinatesEnabled() const
{
return this->QTPropShowCoordinates;
}
void QmitkCorrespondingPointSetsModel::QTPropSetCoordinatesEnabled(bool showCoordinates)
{
this->QTPropShowCoordinates = showCoordinates;
}
bool QmitkCorrespondingPointSetsModel::QTPropIdsEnabled() const
{
return this->QTPropShowIds;
}
void QmitkCorrespondingPointSetsModel::QTPropSetIdsEnabled(bool showIds)
{
this->QTPropShowIds = showIds;
}
std::vector<mitk::DataNode*> QmitkCorrespondingPointSetsModel::GetPointSetNodes(){
std::vector<mitk::DataNode*> pointSetNodes;
if ( this->m_PointSetNode )
pointSetNodes.push_back(this->m_PointSetNode);
if ( this->m_ReferencePointSetNode )
pointSetNodes.push_back(this->m_ReferencePointSetNode);
return pointSetNodes;
}
void QmitkCorrespondingPointSetsModel::SetSelectedPointSetIndex(int index)
{
if (index<-1 || index>1)
return;
this->m_SelectedPointSetIndex = index;
}
void QmitkCorrespondingPointSetsModel::ClearSelectedPointSet()
{
mitk::DataNode* dataNode = NULL;
if (this->m_SelectedPointSetIndex == 0)
dataNode = this->m_PointSetNode;
else if (this->m_SelectedPointSetIndex == 1)
dataNode = this->m_ReferencePointSetNode;
if (dataNode == NULL)
return;
mitk::PointSet* pointSet = dynamic_cast<mitk::PointSet*>(dataNode->GetData());
mitk::PointSet::PointsContainer::Iterator it;
if (this->m_TimeStepper->GetRangeMax()==-1)
{
while( !pointSet->IsEmptyTimeStep(0) )
{
if (pointSet->GetPointSet(0))
{
it = pointSet->GetPointSet(0)->GetPoints()->Begin();
pointSet->SetSelectInfo(it->Index(),true, 0);
this->RemoveSelectedPoint();
}
else
{
break;
}
}
}
else
{
int oldTimeStep = this->m_TimeStepper->GetPos();
for (int i=0; i<this->m_TimeStepper->GetRangeMax(); i++)
{
this->m_TimeStepper->SetPos(i);
while( !pointSet->IsEmptyTimeStep(i) )
{
if (pointSet->GetPointSet(i))
{
it = pointSet->GetPointSet(i)->GetPoints()->Begin();
pointSet->SetSelectInfo(it->Index(),true, i);
this->RemoveSelectedPoint();
}
}
}
this->m_TimeStepper->SetPos(oldTimeStep);
}
- QAbstractTableModel::reset();
+ QAbstractTableModel::beginResetModel();
+ QAbstractTableModel::endResetModel();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
emit SignalPointSetChanged();
}
void QmitkCorrespondingPointSetsModel::ClearCurrentTimeStep()
{
if (!m_TimeStepper)
return;
mitk::DataNode* dataNode = NULL;
if (this->m_SelectedPointSetIndex == 0)
dataNode = this->m_PointSetNode;
else if (this->m_SelectedPointSetIndex == 1)
dataNode = this->m_ReferencePointSetNode;
if (dataNode == NULL)
return;
mitk::PointSet* pointSet = dynamic_cast<mitk::PointSet*>(dataNode->GetData());
mitk::PointSet::PointsContainer::Iterator it;
while( !pointSet->IsEmptyTimeStep(m_TimeStepper->GetPos()) )
{
it = pointSet->GetPointSet(m_TimeStepper->GetPos())->GetPoints()->Begin();
pointSet->SetSelectInfo(it->Index(),true, m_TimeStepper->GetPos());
this->RemoveSelectedPoint();
}
- QAbstractTableModel::reset();
+ QAbstractTableModel::beginResetModel();
+ QAbstractTableModel::endResetModel();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
emit SignalPointSetChanged();
}
mitk::Stepper::Pointer QmitkCorrespondingPointSetsModel::GetStepper()
{
return this->m_TimeStepper;
}
void QmitkCorrespondingPointSetsModel::SetStepper(mitk::Stepper::Pointer stepper)
{
this->m_TimeStepper = stepper;
}
int QmitkCorrespondingPointSetsModel::GetSelectedPointSetIndex()
{
return this->m_SelectedPointSetIndex;
}
void QmitkCorrespondingPointSetsModel::UpdateSelection(mitk::DataNode* selectedNode)
{
this->RemoveInteractor();
if(!selectedNode)
return;
m_Interactor = dynamic_cast<mitk::PointSetInteractor*>(selectedNode->GetInteractor());
if (m_Interactor.IsNull())//if not present, instanciate one
m_Interactor = mitk::PointSetInteractor::New("pointsetinteractor", selectedNode);
//add it to global interaction to activate it
mitk::GlobalInteraction::GetInstance()->AddInteractor( m_Interactor );
}
void QmitkCorrespondingPointSetsModel::RemoveInteractor()
{
if (m_Interactor){
mitk::GlobalInteraction::GetInstance()->RemoveInteractor( m_Interactor );
m_Interactor = NULL;
}
}
QmitkStdMultiWidget* QmitkCorrespondingPointSetsModel::GetMultiWidget()
{
return this->m_MultiWidget;
}
void QmitkCorrespondingPointSetsModel::SetMultiWidget( QmitkStdMultiWidget* multiWidget )
{
this->m_MultiWidget = multiWidget;
this->m_TimeStepper = m_MultiWidget->GetTimeNavigationController()->GetTime();
}
diff --git a/Modules/QtWidgetsExt/QmitkFloatingPointSpanSlider.cpp b/Modules/QtWidgetsExt/QmitkFloatingPointSpanSlider.cpp
deleted file mode 100644
index 9aac03cc38..0000000000
--- a/Modules/QtWidgetsExt/QmitkFloatingPointSpanSlider.cpp
+++ /dev/null
@@ -1,245 +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 "QmitkFloatingPointSpanSlider.h"
-#include <QObject>
-
-QmitkFloatingPointSpanSlider::QmitkFloatingPointSpanSlider(QWidget *parent)
- : QxtSpanSlider(parent), m_LowerValue(0), m_UpperValue(1000),
- m_Minimum(0), m_Maximum(1000), offset(0.0), factor(1.0), m_IntMode(false)
-{
- this->QxtSpanSlider::setMinimum(0);
- this->QxtSpanSlider::setMaximum(1000);
-
- connect(this, SIGNAL(spanChanged(int,int)), this, SLOT(IntSpanChanged(int,int)));
-}
-
-void QmitkFloatingPointSpanSlider::setIntegerMode(bool intMode)
-{
- m_IntMode = intMode;
- this->QxtSpanSlider::setMinimum(m_Minimum);
- this->QxtSpanSlider::setMaximum(m_Maximum);
-}
-
-double QmitkFloatingPointSpanSlider::lowerValue() const
-{
- if (m_IntMode) return this->QxtSpanSlider::lowerValue();
- return m_LowerValue;
-}
-
-double QmitkFloatingPointSpanSlider::upperValue() const
-{
- if (m_IntMode) return this->QxtSpanSlider::upperValue();
- return m_UpperValue;
-}
-
-void QmitkFloatingPointSpanSlider::setLowerValue(double lower)
-{
- m_LowerValue = lower;
- if (m_IntMode)
- {
- this->QxtSpanSlider::setLowerValue(lower);
- }
- else
- {
- this->QxtSpanSlider::setLowerValue(scaleValue(lower));
- emit lowerValueChanged(lower);
- }
-}
-
-void QmitkFloatingPointSpanSlider::setUpperValue(double upper)
-{
- m_UpperValue = upper;
- if (m_IntMode)
- {
- this->QxtSpanSlider::setUpperValue(upper);
- }
- else
- {
- this->QxtSpanSlider::setUpperValue(scaleValue(upper));
- emit upperValueChanged(upper);
- }
-}
-
-void QmitkFloatingPointSpanSlider::setSpan(double lower, double upper)
-{
- m_LowerValue = lower;
- m_UpperValue = upper;
- if (m_IntMode)
- {
- this->QxtSpanSlider::setLowerValue(lower);
- this->QxtSpanSlider::setUpperValue(upper);
- }
- else
- {
- this->QxtSpanSlider::setLowerValue(scaleValue(lower));
- this->QxtSpanSlider::setUpperValue(scaleValue(upper));
- emit spanChanged(lower, upper);
- }
-}
-
-double QmitkFloatingPointSpanSlider::maximum() const
-{
- if (m_IntMode) return this->QxtSpanSlider::maximum();
- return m_Maximum;
-}
-
-double QmitkFloatingPointSpanSlider::minimum() const
-{
- if (m_IntMode) return this->QxtSpanSlider::minimum();
- return m_Minimum;
-}
-
-void QmitkFloatingPointSpanSlider::setMaximum(double max)
-{
- if (m_IntMode)
- {
- this->QxtSpanSlider::setMaximum(max);
- return;
- }
-
- if (max < m_Minimum)
- {
- m_Minimum = max;
- }
- m_Maximum = max;
- scaleSliderToInt();
-
- if (m_LowerValue > m_Maximum)
- {
- m_LowerValue = m_Maximum;
- this->QxtSpanSlider::setLowerValue(scaleValue(m_LowerValue));
- }
- if (m_UpperValue > m_Maximum)
- {
- m_UpperValue = m_Maximum;
- this->QxtSpanSlider::setUpperValue(scaleValue(m_UpperValue));
- }
-}
-
-void QmitkFloatingPointSpanSlider::setMinimum(double min)
-{
- if (m_IntMode)
- {
- this->QxtSpanSlider::setMinimum(min);
- return;
- }
-
- if (min > m_Maximum)
- {
- m_Maximum = min;
- }
- m_Minimum = min;
- scaleSliderToInt();
-
- if (m_LowerValue < m_Minimum)
- {
- m_LowerValue = m_Minimum;
- this->QxtSpanSlider::setLowerValue(scaleValue(m_LowerValue));
- }
- if (m_UpperValue < m_Minimum)
- {
- m_UpperValue = m_Minimum;
- this->QxtSpanSlider::setUpperValue(scaleValue(m_UpperValue));
- }
-}
-
-void QmitkFloatingPointSpanSlider::setRange(double min, double max)
-{
- if (m_IntMode)
- {
- this->QxtSpanSlider::setRange(min, max);
- m_Minimum = minimum();
- m_Maximum = maximum();
- m_LowerValue = lowerValue();
- m_UpperValue = upperValue();
- return;
- }
-
- if (min > max)
- {
- min = max;
- }
- m_Minimum = min;
- m_Maximum = max;
-
- if (m_LowerValue > m_Maximum)
- {
- m_LowerValue = m_Maximum;
- this->QxtSpanSlider::setLowerValue(scaleValue(m_LowerValue));
- }
- else if (m_LowerValue < m_Minimum)
- {
- m_LowerValue = m_Minimum;
- this->QxtSpanSlider::setLowerValue(scaleValue(m_LowerValue));
- }
-
- if (m_UpperValue > m_Maximum)
- {
- m_UpperValue = m_Maximum;
- this->QxtSpanSlider::setUpperValue(scaleValue(m_UpperValue));
- }
- else if (m_UpperValue < m_Minimum)
- {
- m_UpperValue = m_Minimum;
- this->QxtSpanSlider::setUpperValue(scaleValue(m_UpperValue));
- }
-
- scaleSliderToInt();
-}
-
-void QmitkFloatingPointSpanSlider::IntSpanChanged(int lower, int upper)
-{
- if (m_IntMode)
- {
- m_LowerValue = lower;
- m_UpperValue = upper;
- }
- else
- {
- m_LowerValue = unscaleValue(lower);
- m_UpperValue = unscaleValue(upper);
- }
-
- emit spanChanged(m_LowerValue, m_UpperValue);
-}
-
-void QmitkFloatingPointSpanSlider::scaleSliderToInt()
-{
- int tmpLower = unscaleValue(m_LowerValue);
- int tmpUpper = unscaleValue(m_UpperValue);
-
- double range = m_Maximum - m_Minimum;
- factor = range ? 1000.0 / range : 0;
- offset = -m_Minimum;
-
- m_LowerValue = scaleValue(tmpLower);
- m_UpperValue = scaleValue(tmpUpper);
-}
-
-int QmitkFloatingPointSpanSlider::scaleValue(double val)
-{
- int scaled = factor ? (offset + val)*factor : 0;
- return scaled;
-}
-
-double QmitkFloatingPointSpanSlider::unscaleValue(int val)
-{
- double unscaled = factor ? static_cast<double>(val)/factor - offset : 0;
- return unscaled;
-}
-
diff --git a/Modules/QtWidgetsExt/QmitkFloatingPointSpanSlider.h b/Modules/QtWidgetsExt/QmitkFloatingPointSpanSlider.h
deleted file mode 100644
index c97de011a8..0000000000
--- a/Modules/QtWidgetsExt/QmitkFloatingPointSpanSlider.h
+++ /dev/null
@@ -1,87 +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 QMITKFLOATINGPOINTSPANSLIDER_H
-#define QMITKFLOATINGPOINTSPANSLIDER_H
-
-#include <MitkQtWidgetsExtExports.h>
-
-#include <qxtspanslider.h>
-#include <QWidget>
-
-class MitkQtWidgetsExt_EXPORT QmitkFloatingPointSpanSlider : public QxtSpanSlider
-{
- Q_OBJECT
- Q_PROPERTY(double loweralue READ lowerValue WRITE setLowerValue
- NOTIFY lowerValueChanged)
- Q_PROPERTY(double upperValue READ upperValue WRITE setUpperValue
- NOTIFY upperValueChanged)
- Q_PROPERTY(double maximum READ maximum WRITE setMaximum)
- Q_PROPERTY(double minimum READ minimum WRITE setMinimum)
-
-public:
-
- QmitkFloatingPointSpanSlider(QWidget *parent = 0);
-
- void setIntegerMode(bool intMode);
-
- double lowerValue() const;
- double upperValue() const;
-
- double maximum() const;
- double minimum() const;
-
- void setMaximum(double max);
- void setMinimum(double min);
- void setRange(double min, double max);
-
-signals:
-
- void lowerValueChanged(double lower);
- void upperValueChanged(double upper);
- void spanChanged(double lower, double upper);
-
-public slots:
-
- void setLowerValue(double lower);
- void setUpperValue(double upper);
- void setSpan(double lower, double upper);
-
-private slots:
-
- void IntSpanChanged(int lower, int upper);
-
-private:
-
- void scaleSliderToInt();
- inline int scaleValue(double val);
- inline double unscaleValue(int val);
-
- double m_LowerValue;
- double m_UpperValue;
-
- double m_Minimum;
- double m_Maximum;
-
- double offset;
- double factor;
-
- bool m_IntMode;
-};
-
-#endif
-
diff --git a/Modules/QtWidgetsExt/QmitkGnuplotWidget.cpp b/Modules/QtWidgetsExt/QmitkGnuplotWidget.cpp
index b12ae3e7eb..d134224f01 100644
--- a/Modules/QtWidgetsExt/QmitkGnuplotWidget.cpp
+++ b/Modules/QtWidgetsExt/QmitkGnuplotWidget.cpp
@@ -1,221 +1,221 @@
/*===================================================================
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 <QClipboard>
#include <QContextMenuEvent>
#include <QMenu>
#include <ui_QmitkGnuplotWidget.h>
#include "QmitkGnuplotWidget.h"
QmitkGnuplotWidget::QmitkGnuplotWidget(QWidget* parent)
: QWidget(parent),
m_Ui(new Ui::QmitkGnuplotWidget),
m_ContextMenu(NULL),
m_CopyPlotAction(NULL),
m_CopyScriptAction(NULL),
m_Process(new QProcess(this))
{
m_Ui->setupUi(this);
connect(m_Process, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(OnProcessStateChanged(QProcess::ProcessState)));
connect(m_Process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(OnProcessError(QProcess::ProcessError)));
connect(m_Process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(OnProcessFinished(int, QProcess::ExitStatus)));
this->CreateContextMenu();
}
QmitkGnuplotWidget::~QmitkGnuplotWidget()
{
}
void QmitkGnuplotWidget::CreateContextMenu()
{
m_CopyPlotAction = new QAction("Copy &Plot", this);
connect(m_CopyPlotAction, SIGNAL(triggered()), this, SLOT(OnCopyPlot()));
m_CopyScriptAction = new QAction("Copy &Script", this);
connect(m_CopyScriptAction, SIGNAL(triggered()), this, SLOT(OnCopyScript()));
m_ContextMenu = new QMenu(this);
m_ContextMenu->addActions(QList<QAction*>()
<< m_CopyPlotAction
<< m_CopyScriptAction);
}
void QmitkGnuplotWidget::contextMenuEvent(QContextMenuEvent* event)
{
const QPixmap* plot = m_Ui->label->pixmap();
m_CopyPlotAction->setEnabled(plot != NULL && !plot->isNull());
m_CopyScriptAction->setEnabled(!m_Commands.empty());
m_ContextMenu->popup(event->globalPos());
event->accept();
}
void QmitkGnuplotWidget::OnCopyPlot()
{
const QPixmap* plot = m_Ui->label->pixmap();
if (plot != NULL && !plot->isNull())
QApplication::clipboard()->setPixmap(*plot);
}
void QmitkGnuplotWidget::OnCopyScript()
{
if (m_Commands.empty())
return;
QString script = this->CreateSetTermCommand();
Q_FOREACH(const QString& command, m_Commands)
{
script += command + "\n";
}
QApplication::clipboard()->setText(script);
}
void QmitkGnuplotWidget::resizeEvent(QResizeEvent*)
{
m_ModifiedTime.Modified();
if (m_Process->isOpen() || m_Commands.isEmpty() || m_GnuplotPath.isEmpty())
return;
this->Update();
}
QString QmitkGnuplotWidget::GetGnuplotPath() const
{
return m_GnuplotPath;
}
void QmitkGnuplotWidget::SetGnuplotPath(const QString &path)
{
m_GnuplotPath = path;
m_ModifiedTime.Modified();
}
QStringList QmitkGnuplotWidget::GetCommands() const
{
return m_Commands;
}
void QmitkGnuplotWidget::SetCommands(const QStringList& commands)
{
m_Commands = commands;
m_ModifiedTime.Modified();
}
void QmitkGnuplotWidget::Update()
{
if (m_UpdateTime < m_ModifiedTime)
m_Process->start(m_GnuplotPath, QStringList() << "-");
}
QSize QmitkGnuplotWidget::sizeHint() const
{
return QSize(400, 300);
}
QString QmitkGnuplotWidget::CreateSetTermCommand() const
{
return QString("set term pngcairo size %1,%2 enhanced font '%3,%4'\n")
.arg(this->width())
.arg(this->height())
.arg(this->font().family())
.arg(this->font().pointSize());
}
void QmitkGnuplotWidget::OnProcessStateChanged(QProcess::ProcessState state)
{
if (state == QProcess::Running)
{
m_UpdateTime = m_ModifiedTime;
- m_Process->write(this->CreateSetTermCommand().toAscii());
+ m_Process->write(this->CreateSetTermCommand().toLatin1());
Q_FOREACH(const QString& command, m_Commands)
{
- m_Process->write(QString("%1\n").arg(command).toAscii());
+ m_Process->write(QString("%1\n").arg(command).toLatin1());
}
m_Process->write("exit\n");
m_Process->closeWriteChannel();
}
}
void QmitkGnuplotWidget::OnProcessError(QProcess::ProcessError error)
{
switch (error)
{
case QProcess::FailedToStart:
m_Ui->label->setText("Gnuplot failed to start!");
break;
case QProcess::Crashed:
m_Ui->label->setText("Gnuplot crashed!");
break;
case QProcess::Timedout:
m_Ui->label->setText("Gnuplot timed out!");
break;
case QProcess::WriteError:
m_Ui->label->setText("Could not write to gnuplot!");
break;
case QProcess::ReadError:
m_Ui->label->setText("Could not read from gnuplot!");
break;
default:
m_Ui->label->setText("An unknown error occurred!");
break;
}
}
void QmitkGnuplotWidget::OnProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
bool needUpdate = false;
if (exitStatus != QProcess::CrashExit)
{
if (exitCode == 0)
{
if (m_UpdateTime < m_ModifiedTime)
{
needUpdate = true;
}
else
{
m_Ui->label->setPixmap(QPixmap::fromImage(QImage::fromData(m_Process->readAllStandardOutput(), "PNG")));
}
}
else
{
m_Ui->label->setText(QString("Gnuplot exit code: %1!").arg(exitCode));
}
}
m_Process->close();
if (needUpdate)
this->Update();
}
diff --git a/Modules/QtWidgetsExt/QmitkHistogramJSWidget.cpp b/Modules/QtWidgetsExt/QmitkHistogramJSWidget.cpp
index 453cce79dd..76f0ccd1a9 100644
--- a/Modules/QtWidgetsExt/QmitkHistogramJSWidget.cpp
+++ b/Modules/QtWidgetsExt/QmitkHistogramJSWidget.cpp
@@ -1,239 +1,240 @@
/*===================================================================
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 "QmitkHistogramJSWidget.h"
#include "mitkPixelTypeMultiplex.h"
#include <mitkImagePixelReadAccessor.h>
#include <mitkIntensityProfile.h>
#include "mitkRenderingManager.h"
#include "mitkBaseRenderer.h"
#include "mitkImageTimeSelector.h"
#include "mitkExtractSliceFilter.h"
+#include <QWebFrame>
QmitkHistogramJSWidget::QmitkHistogramJSWidget(QWidget *parent) :
QWebView(parent)
{
// set histogram type to barchart in first instance
m_UseLineGraph = false;
m_Page = new QmitkJSWebPage(this);
setPage(m_Page);
// set html from source
connect(page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(AddJSObject()));
QUrl myUrl = QUrl("qrc:///QtWidgetsExt/Histogram.html");
setUrl(myUrl);
// set Scrollbars to be always disabled
page()->mainFrame()->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff);
page()->mainFrame()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff);
m_ParametricPath = ParametricPathType::New();
}
QmitkHistogramJSWidget::~QmitkHistogramJSWidget()
{
}
// adds an Object of Type QmitkHistogramJSWidget to the JavaScript, using QtWebkitBridge
void QmitkHistogramJSWidget::AddJSObject()
{
page()->mainFrame()->addToJavaScriptWindowObject(QString("histogramData"), this);
}
// reloads WebView, everytime its size has been changed, so the size of the Histogram fits to the size of the widget
void QmitkHistogramJSWidget::resizeEvent(QResizeEvent* resizeEvent)
{
QWebView::resizeEvent(resizeEvent);
// workaround for Qt Bug: https://bugs.webkit.org/show_bug.cgi?id=75984
page()->mainFrame()->evaluateJavaScript("disconnectSignals()");
this->reload();
}
// method to expose data to JavaScript by using properties
void QmitkHistogramJSWidget::ComputeHistogram(HistogramType* histogram)
{
m_Histogram = histogram;
HistogramConstIteratorType startIt = m_Histogram->End();
HistogramConstIteratorType endIt = m_Histogram->End();
HistogramConstIteratorType it = m_Histogram->Begin();
ClearData();
unsigned int i = 0;
bool firstValue = false;
// removes frequencies of 0, which are outside the first and last bin
for (; it != m_Histogram->End(); ++it)
{
if (it.GetFrequency() > 0.0)
{
endIt = it;
if (!firstValue)
{
firstValue = true;
startIt = it;
}
}
}
++endIt;
// generating Lists of measurement and frequencies
for (it = startIt ; it != endIt; ++it, ++i)
{
QVariant frequency = QVariant::fromValue(it.GetFrequency());
QVariant measurement = it.GetMeasurementVector()[0];
m_Frequency.insert(i, frequency);
m_Measurement.insert(i, measurement);
}
m_IntensityProfile = false;
this->SignalDataChanged();
}
void QmitkHistogramJSWidget::ClearData()
{
m_Frequency.clear();
m_Measurement.clear();
}
void QmitkHistogramJSWidget::ClearHistogram()
{
this->ClearData();
this->SignalDataChanged();
}
QList<QVariant> QmitkHistogramJSWidget::GetFrequency()
{
return m_Frequency;
}
QList<QVariant> QmitkHistogramJSWidget::GetMeasurement()
{
return m_Measurement;
}
bool QmitkHistogramJSWidget::GetUseLineGraph()
{
return m_UseLineGraph;
}
void QmitkHistogramJSWidget::OnBarRadioButtonSelected()
{
if (m_UseLineGraph)
{
m_UseLineGraph = false;
this->SignalGraphChanged();
}
}
void QmitkHistogramJSWidget::OnLineRadioButtonSelected()
{
if (!m_UseLineGraph)
{
m_UseLineGraph = true;
this->SignalGraphChanged();
}
}
void QmitkHistogramJSWidget::SetImage(mitk::Image* image)
{
m_Image = image;
}
void QmitkHistogramJSWidget::SetPlanarFigure(const mitk::PlanarFigure* planarFigure)
{
m_PlanarFigure = planarFigure;
}
template <class PixelType>
void ReadPixel(mitk::PixelType, mitk::Image::Pointer image, itk::Index<3> indexPoint, double& value)
{
if (image->GetDimension() == 2)
{
mitk::ImagePixelReadAccessor<PixelType,2> readAccess(image, image->GetSliceData(0));
itk::Index<2> idx;
idx[0] = indexPoint[0];
idx[1] = indexPoint[1];
value = readAccess.GetPixelByIndex(idx);
}
else if (image->GetDimension() == 3)
{
mitk::ImagePixelReadAccessor<PixelType,3> readAccess(image, image->GetVolumeData(0));
itk::Index<3> idx;
idx[0] = indexPoint[0];
idx[1] = indexPoint[1];
idx[2] = indexPoint[2];
value = readAccess.GetPixelByIndex(idx);
}
else
{
//unhandled
}
}
void QmitkHistogramJSWidget::ComputeIntensityProfile(unsigned int timeStep)
{
this->ClearData();
m_ParametricPath->Initialize();
if (m_PlanarFigure.IsNull())
{
mitkThrow() << "PlanarFigure not set!";
}
if (m_Image.IsNull())
{
mitkThrow() << "Image not set!";
}
mitk::Image::Pointer image;
if (m_Image->GetDimension() == 4)
{
mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New();
timeSelector->SetInput(m_Image);
timeSelector->SetTimeNr(timeStep);
timeSelector->Update();
image = timeSelector->GetOutput();
}
else
{
image = m_Image;
}
mitk::IntensityProfile::Pointer intensityProfile = mitk::ComputeIntensityProfile(image, const_cast<mitk::PlanarFigure*>(m_PlanarFigure.GetPointer()));
m_Frequency.clear();
m_Measurement.clear();
int i = -1;
mitk::IntensityProfile::ConstIterator end = intensityProfile->End();
for (mitk::IntensityProfile::ConstIterator it = intensityProfile->Begin(); it != end; ++it)
{
m_Frequency.push_back(it.GetMeasurementVector()[0]);
m_Measurement.push_back(++i);
}
m_IntensityProfile = true;
m_UseLineGraph = true;
this->SignalDataChanged();
}
bool QmitkHistogramJSWidget::GetIntensityProfile()
{
return m_IntensityProfile;
}
diff --git a/Modules/QtWidgetsExt/QmitkHistogramJSWidget.h b/Modules/QtWidgetsExt/QmitkHistogramJSWidget.h
index b0de9b52f5..b5c1909c44 100644
--- a/Modules/QtWidgetsExt/QmitkHistogramJSWidget.h
+++ b/Modules/QtWidgetsExt/QmitkHistogramJSWidget.h
@@ -1,278 +1,278 @@
/*===================================================================
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 QMITKHISTOGRAMJSWIDGET_H
#define QMITKHISTOGRAMJSWIDGET_H
#include <QWidget>
#include <QUrl>
-#include <QtWebKit/QtWebKit>
+#include <QWebView>
#include "MitkQtWidgetsExtExports.h"
#include <QVariant>
#include "mitkImage.h"
#include "mitkPlanarFigure.h"
#include <itkPolyLineParametricPath.h>
#include <QmitkWebPage.h>
/**
* \brief Widget which shows a histogram using JavaScript.
*
* This class is a QWebView. It shows the histogram for a selected image
* or segmentation. It also can display an intesity profile for
* path elements, which lais over an image.
*/
class MitkQtWidgetsExt_EXPORT QmitkHistogramJSWidget : public QWebView
{
Q_OBJECT
/**
* \brief Measurement property.
*
* This property is used in JavaScript as member of the current object.
* It holds a QList, containing the measurements of the current histogram.
* @see GetMeasurement()
*/
Q_PROPERTY(QList<QVariant> measurement
READ GetMeasurement)
/**
* \brief Frequency property.
*
* This property is used in JavaScript as member of the current object.
* It holds a QList, containing the frequencies of the current histogram.
* @see GetFrequency()
*/
Q_PROPERTY(QList<QVariant> frequency
READ GetFrequency)
/**
* \brief Line graph property.
*
* This property is used in JavaScript as member of the current object.
* It holds a boolean, which sais wether to use a line or not.
* @see GetUseLineGraph()
*/
Q_PROPERTY(bool useLineGraph
READ GetUseLineGraph)
/**
* @brief Intesity profile property.
*
* This property is used in JavaScript as member of the current object.
* It holds a boolean, which sais wether to use an intesity profile or not.
* @see GetIntensityProfile()
*/
Q_PROPERTY(bool intensityProfile
READ GetIntensityProfile)
public:
typedef mitk::Image::HistogramType HistogramType;
typedef mitk::Image::HistogramType::ConstIterator HistogramConstIteratorType;
typedef itk::PolyLineParametricPath< 3 > ParametricPathType;
typedef itk::ParametricPath< 3 >::Superclass PathType;
typedef mitk::PlanarFigure::PolyLineType VertexContainerType;
explicit QmitkHistogramJSWidget(QWidget *parent = 0);
~QmitkHistogramJSWidget();
/**
* \brief Event which notifies a change of the widget size.
*
* Reimplemented from QWebView::resizeEvent(),
* reloads the webframe
*/
void resizeEvent(QResizeEvent* resizeEvent);
/**
* \brief Calculates the histogram.
*
* This function removes all frequencies of 0 until the first bin and behind the last bin.
* It writes the measurement and frequency, which are given from the HistogramType, into
* m_Measurement and m_Frequency.
* The SignalDataChanged is called, to update the information, which is displayed in the webframe.
*/
void ComputeHistogram(HistogramType* histogram);
/**
* \brief Calculates the intesityprofile.
*
* If an image and a pathelement are set, this function
* calculates an intensity profile for a pathelement which lies over an image.
* Sets m_IntensityProfile and m_UseLineGraph to true.
* The SignalDataChanged is called, to update the information, which is displayed in the webframe.
*/
void ComputeIntensityProfile(unsigned int timeStep = 0);
/**
* \brief Clears the Histogram.
*
* This function clears the data and calls SignalDataChanged to update
* the displayed information in the webframe.
*/
void ClearHistogram();
/**
* \brief Getter for measurement.
*
* @return List of measurements.
*/
QList<QVariant> GetMeasurement();
/**
* \brief Getter for frequency.
*
* @return List of frequencies.
*/
QList<QVariant> GetFrequency();
/**
* \brief Getter for uselineGraph.
*
* @return True if a linegraph should be used.
*/
bool GetUseLineGraph();
/**
* \brief Getter for intensity profile.
*
* @return True if current histogram is an intesityprofile
*/
bool GetIntensityProfile();
/**
* \brief Setter for reference image.
*
* @param image The corresponding image for an intensity profile.
*/
void SetImage(mitk::Image* image);
/**
* \brief Setter for planarFigure.
*
* @param planarFigure The pathelement for an intensity profile.
*/
void SetPlanarFigure(const mitk::PlanarFigure* planarFigure);
private:
/**
* \brief List of frequencies.
*
* A QList which holds the frequencies of the current histogram
* or holds the intesities of current intensity profile.
*/
QList<QVariant> m_Frequency;
/**
* \brief List of measurements.
*
* A QList which holds the measurements of the current histogram
* or holds the distances of current intensity profile.
*/
QList<QVariant> m_Measurement;
/**
* \brief Reference image.
*
* Holds the image to calculate an intesity profile.
*/
mitk::Image::Pointer m_Image;
/**
* \brief Pathelement.
*
* Holds a not closed planar figure to calculate an intesity profile.
*/
mitk::PlanarFigure::ConstPointer m_PlanarFigure;
bool m_UseLineGraph;
bool m_IntensityProfile;
/**
* Holds the current histogram
*/
HistogramType::ConstPointer m_Histogram;
/**
* Path derived either form user-specified path or from PlanarFigure-generated
* path
*/
PathType::ConstPointer m_DerivedPath;
/**
* Parametric path as generated from PlanarFigure
*/
ParametricPathType::Pointer m_ParametricPath;
/**
* \brief Clears data.
*
* Clears the QLists m_Measurement and m_Frequency
*/
void ClearData();
QmitkJSWebPage* m_Page;
private slots:
/**
* \brief Adds an object to JavaScript.
*
* Adds an object of the widget to JavaScript.
* By using this object JavaScript can react to the signals of the widget
* and can access the QProperties as members of the object.
*/
void AddJSObject();
public slots:
/**
* \brief Slot for radiobutton m_barRadioButton.
*
* Sets m_UseLineGraph to false.
* Calls signal GraphChanged to update the graph in the webframe.
*/
void OnBarRadioButtonSelected();
/**
* \brief Slot for radiobutton m_lineRadioButton.
*
* Sets m_UseLineGraph to true.
* Calls signal GraphChanged to update the graph in the webframe.
*/
void OnLineRadioButtonSelected();
signals:
/**
* \brief Signal data has changed.
*
* It has to be called when the data of the histogram or intesity profile has changed.
*/
void SignalDataChanged();
/**
* \brief Signal graph has changed.
*
* It has to be called when the graph changed from barchart to linegraph. Vice versa.
*/
void SignalGraphChanged();
};
#endif
diff --git a/Modules/QtWidgetsExt/QmitkModulesDialog.cpp b/Modules/QtWidgetsExt/QmitkModulesDialog.cpp
index 3c3f339a3a..2f3f0636ac 100644
--- a/Modules/QtWidgetsExt/QmitkModulesDialog.cpp
+++ b/Modules/QtWidgetsExt/QmitkModulesDialog.cpp
@@ -1,66 +1,72 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "QmitkModulesDialog.h"
#include <QHBoxLayout>
#include <QTableView>
#include <QHeaderView>
#include <QSortFilterProxyModel>
#include <QDialogButtonBox>
#include "QmitkModuleTableModel.h"
QmitkModulesDialog::QmitkModulesDialog(QWidget *parent, Qt::WindowFlags f) :
QDialog(parent, f)
{
this->setWindowTitle("MITK Modules");
QVBoxLayout* layout = new QVBoxLayout();
this->setLayout(layout);
QTableView* tableView = new QTableView(this);
QmitkModuleTableModel* tableModel = new QmitkModuleTableModel(tableView);
QSortFilterProxyModel* sortProxyModel = new QSortFilterProxyModel(tableView);
sortProxyModel->setSourceModel(tableModel);
sortProxyModel->setDynamicSortFilter(true);
tableView->setModel(sortProxyModel);
tableView->verticalHeader()->hide();
tableView->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
tableView->setSelectionMode(QAbstractItemView::ExtendedSelection);
tableView->setTextElideMode(Qt::ElideMiddle);
tableView->setSortingEnabled(true);
tableView->sortByColumn(0, Qt::AscendingOrder);
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
tableView->horizontalHeader()->setResizeMode(0, QHeaderView::ResizeToContents);
tableView->horizontalHeader()->setResizeMode(2, QHeaderView::ResizeToContents);
tableView->horizontalHeader()->setResizeMode(5, QHeaderView::ResizeToContents);
+#else
+ tableView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
+ tableView->horizontalHeader()->setSectionResizeMode(2, QHeaderView::ResizeToContents);
+ tableView->horizontalHeader()->setSectionResizeMode(5, QHeaderView::ResizeToContents);
+#endif
tableView->horizontalHeader()->setStretchLastSection(true);
tableView->horizontalHeader()->setCascadingSectionResizes(true);
layout->addWidget(tableView);
QDialogButtonBox* btnBox = new QDialogButtonBox(QDialogButtonBox::Close);
layout->addWidget(btnBox);
this->resize(800, 600);
connect(btnBox, SIGNAL(rejected()), this, SLOT(reject()));
}
diff --git a/Modules/QtWidgetsExt/QmitkPointListModel.cpp b/Modules/QtWidgetsExt/QmitkPointListModel.cpp
index 7967c7ac2e..94b137cf96 100644
--- a/Modules/QtWidgetsExt/QmitkPointListModel.cpp
+++ b/Modules/QtWidgetsExt/QmitkPointListModel.cpp
@@ -1,322 +1,326 @@
/*===================================================================
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 "QmitkPointListModel.h"
#include <itkCommand.h>
#include "mitkInteractionConst.h"
#include "mitkPointOperation.h"
#include "mitkRenderingManager.h"
#include <mitkPointSetDataInteractor.h>
#include <mitkEvent.h>
#include <mitkStateEvent.h>
#include <mitkInteractionConst.h>
#include <mitkInternalEvent.h>
QmitkPointListModel::QmitkPointListModel( mitk::DataNode* pointSetNode, int t, QObject* parent )
:QAbstractListModel(parent),
m_PointSetNode(NULL),
m_PointSetModifiedObserverTag(0),
m_PointSetDeletedObserverTag(0),
m_TimeStep(t)
{
ObserveNewPointSet( pointSetNode );
}
Qt::ItemFlags QmitkPointListModel::flags(const QModelIndex& /*index*/) const
{
// no editing so far, return default (enabled, selectable)
return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
}
QmitkPointListModel::~QmitkPointListModel()
{
this->ObserveNewPointSet( NULL );
}
void QmitkPointListModel::SetPointSetNode( mitk::DataNode* pointSetNode )
{
this->ObserveNewPointSet( pointSetNode );
- QAbstractListModel::reset();
+ QAbstractListModel::beginResetModel();
+ QAbstractListModel::beginResetModel();
emit SignalUpdateSelection();
}
mitk::PointSet* QmitkPointListModel::GetPointSet() const
{
return this->CheckForPointSetInNode(m_PointSetNode);
}
void QmitkPointListModel::SetTimeStep(int t)
{
m_TimeStep = t;
- QAbstractListModel::reset();
+ QAbstractListModel::beginResetModel();
+ QAbstractListModel::endResetModel();
emit SignalUpdateSelection();
}
int QmitkPointListModel::GetTimeStep() const
{
return m_TimeStep;
}
void QmitkPointListModel::ObserveNewPointSet( mitk::DataNode* pointSetNode )
{
//remove old observers
if (m_PointSetNode != NULL)
{
try //here sometimes an exception is thrown which leads to a crash. So catch this exception but give an error message. See bug 18316 for details.
{
mitk::PointSet::Pointer oldPointSet = dynamic_cast<mitk::PointSet*>(m_PointSetNode->GetData());
if (oldPointSet.IsNotNull())
{
oldPointSet->RemoveObserver(m_PointSetModifiedObserverTag);
oldPointSet->RemoveObserver(m_PointSetDeletedObserverTag);
}
}
catch(std::exception& e)
{
MITK_ERROR << "Exception while removing observer from old point set node: " << e.what();
}
}
//get the new pointset
mitk::PointSet::Pointer pointSet = this->CheckForPointSetInNode(pointSetNode);
m_PointSetNode = pointSetNode;
if ( pointSet.IsNotNull())
{
// add new observer for modified if necessary
itk::ReceptorMemberCommand<QmitkPointListModel>::Pointer modCommand = itk::ReceptorMemberCommand<QmitkPointListModel>::New();
modCommand->SetCallbackFunction( this, &QmitkPointListModel::OnPointSetChanged );
m_PointSetModifiedObserverTag = pointSet->AddObserver( itk::ModifiedEvent(), modCommand );
// add new observer for detele if necessary
itk::ReceptorMemberCommand<QmitkPointListModel>::Pointer delCommand = itk::ReceptorMemberCommand<QmitkPointListModel>::New();
delCommand->SetCallbackFunction( this, &QmitkPointListModel::OnPointSetDeleted );
m_PointSetDeletedObserverTag = pointSet->AddObserver( itk::DeleteEvent(), delCommand );
}
else
{
m_PointSetModifiedObserverTag = 0;
m_PointSetDeletedObserverTag = 0;
}
}
void QmitkPointListModel::OnPointSetChanged(const itk::EventObject&)
{
- QAbstractListModel::reset();
+ QAbstractListModel::beginResetModel();
+ QAbstractListModel::endResetModel();
emit SignalUpdateSelection();
}
void QmitkPointListModel::OnPointSetDeleted(const itk::EventObject&)
{
mitk::PointSet::Pointer ps = CheckForPointSetInNode(m_PointSetNode);
if (ps)
{
ps->RemoveObserver(m_PointSetModifiedObserverTag);
ps->RemoveObserver(m_PointSetDeletedObserverTag);
}
m_PointSetModifiedObserverTag = 0;
m_PointSetDeletedObserverTag = 0;
- QAbstractListModel::reset();
+ QAbstractListModel::beginResetModel();
+ QAbstractListModel::endResetModel();
}
int QmitkPointListModel::rowCount(const QModelIndex&) const
{
mitk::PointSet::Pointer pointSet = this->CheckForPointSetInNode(m_PointSetNode);
if ( pointSet.IsNotNull() )
{
return pointSet->GetSize(m_TimeStep);
}
else
{
return 0;
}
}
QVariant QmitkPointListModel::data(const QModelIndex& index, int role) const
{
mitk::PointSet::Pointer pointSet = this->CheckForPointSetInNode(m_PointSetNode);
if ( pointSet.IsNull() )
{
return QVariant();
}
if ( !index.isValid() )
{
return QVariant();
}
if ( index.row() >= pointSet->GetSize(m_TimeStep) )
{
return QVariant();
}
if (role == Qt::DisplayRole)
{
mitk::PointSet::PointsContainer::ElementIdentifier id;
mitk::PointSet::PointType p;
bool pointFound = this->GetPointForModelIndex(index, p, id);
if (pointFound == false)
return QVariant();
QString s = QString("%0: (%1, %2, %3)")
.arg( id, 3)
.arg( p[0], 0, 'f', 3 )
.arg( p[1], 0, 'f', 3 )
.arg( p[2], 0, 'f', 3 );
return QVariant(s);
}
else
{
return QVariant();
}
}
QVariant QmitkPointListModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role != Qt::DisplayRole)
{
return QVariant();
}
if (orientation == Qt::Horizontal)
{
return QString("Coordinates").arg(section);
}
else
{
return QString("Row %1").arg(section);
}
}
bool QmitkPointListModel::GetPointForModelIndex( const QModelIndex &index, mitk::PointSet::PointType& p,
mitk::PointSet::PointIdentifier& id) const
{
mitk::PointSet::Pointer pointSet = this->CheckForPointSetInNode(m_PointSetNode);
if (pointSet.IsNull())
return false;
if ((index.row() < 0) || (index.row() >= (int)pointSet->GetPointSet(m_TimeStep)->GetPoints()->Size()))
return false;
// get the nth. element, if it exists.
// we can not use the index directly, because PointSet uses a map container,
// where the index is not necessarily the same as the key.
// Therefore we have to count the elements
mitk::PointSet::PointsContainer::Iterator it = pointSet->GetPointSet(m_TimeStep)->GetPoints()->Begin();
for (int i = 0; i < index.row(); ++i)
{
++it;
if (it == pointSet->GetPointSet(m_TimeStep)->GetPoints()->End())
return false;
}
if (it != pointSet->GetPointSet(m_TimeStep)->GetPoints()->End()) // not at the end,
{
p = it->Value();
id = it->Index();
return true;
}
return false;
}
bool QmitkPointListModel::GetModelIndexForPointID(mitk::PointSet::PointIdentifier id, QModelIndex& index) const
{
mitk::PointSet::Pointer pointSet = this->CheckForPointSetInNode(m_PointSetNode);
if (pointSet.IsNull())
return false;
mitk::PointSet::PointsContainer::Pointer points = pointSet->GetPointSet(m_TimeStep)->GetPoints();
if (points->IndexExists(id) == false)
return false;
unsigned int idx = 0;
for (mitk::PointSet::PointsContainer::Iterator it = points->Begin(); it != points->End(); ++it)
{
if (it->Index() == id) // we found the correct element
{
index = this->index(idx);
return true;
}
idx++;
}
return false; // nothing found
}
void QmitkPointListModel::MoveSelectedPointUp()
{
mitk::PointSet::Pointer pointSet = this->CheckForPointSetInNode(m_PointSetNode);
if (pointSet.IsNull())
return;
mitk::PointSet::PointIdentifier selectedID;
selectedID = pointSet->SearchSelectedPoint(m_TimeStep);
mitk::ScalarType tsInMS = pointSet->GetTimeGeometry()->TimeStepToTimePoint(m_TimeStep);
mitk::PointOperation* doOp = new mitk::PointOperation(mitk::OpMOVEPOINTUP,tsInMS, pointSet->GetPoint(selectedID, m_TimeStep), selectedID, true);
pointSet->ExecuteOperation(doOp);
mitk::RenderingManager::GetInstance()->RequestUpdateAll(); // Workaround for update problem in Pointset/Mapper
}
void QmitkPointListModel::MoveSelectedPointDown()
{
mitk::PointSet::Pointer pointSet = this->CheckForPointSetInNode(m_PointSetNode);
if (pointSet.IsNull())
return;
mitk::PointSet::PointIdentifier selectedID;
selectedID = pointSet->SearchSelectedPoint(m_TimeStep);
mitk::ScalarType tsInMS = pointSet->GetTimeGeometry()->TimeStepToTimePoint(m_TimeStep);
mitk::PointOperation* doOp = new mitk::PointOperation(mitk::OpMOVEPOINTDOWN, tsInMS, pointSet->GetPoint(selectedID, m_TimeStep), selectedID, true);
pointSet->ExecuteOperation(doOp);
mitk::RenderingManager::GetInstance()->RequestUpdateAll(); // Workaround for update problem in Pointset/Mapper
}
void QmitkPointListModel::RemoveSelectedPoint()
{
mitk::PointSet::Pointer pointSet = this->CheckForPointSetInNode(m_PointSetNode);
if (pointSet.IsNull())
return;
mitk::PointSet::PointIdentifier selectedID;
selectedID = pointSet->SearchSelectedPoint(m_TimeStep);
mitk::ScalarType tsInMS = pointSet->GetTimeGeometry()->TimeStepToTimePoint(m_TimeStep);
mitk::PointOperation* doOp = new mitk::PointOperation(mitk::OpREMOVE, tsInMS, pointSet->GetPoint(selectedID, m_TimeStep), selectedID, true);
pointSet->ExecuteOperation(doOp);
mitk::RenderingManager::GetInstance()->RequestUpdateAll(); // Workaround for update problem in Pointset/Mapper
}
mitk::PointSet* QmitkPointListModel::CheckForPointSetInNode(mitk::DataNode* node) const
{
if (node != NULL)
{
mitk::PointSet::Pointer pointSet = dynamic_cast<mitk::PointSet*>(node->GetData());
if (pointSet.IsNotNull())
return pointSet;
}
return NULL;
}
diff --git a/Modules/QtWidgetsExt/QmitkPropertyObservers/QmitkColorPropertyEditor.cpp b/Modules/QtWidgetsExt/QmitkPropertyObservers/QmitkColorPropertyEditor.cpp
index 27da658354..be6a02cfe5 100644
--- a/Modules/QtWidgetsExt/QmitkPropertyObservers/QmitkColorPropertyEditor.cpp
+++ b/Modules/QtWidgetsExt/QmitkPropertyObservers/QmitkColorPropertyEditor.cpp
@@ -1,296 +1,296 @@
/*===================================================================
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 "QmitkColorPropertyEditor.h"
#include <QLayout>
#include <QPainter>
#include <QApplication>
#include <QMouseEvent>
#include <QCloseEvent>
#include <QDesktopWidget>
#include <mitkRenderingManager.h>
//----- QmitkPopupColorChooser ---------------------------------------------------------
QmitkPopupColorChooser::QmitkPopupColorChooser(QWidget* parent, unsigned int steps, unsigned int size)
: QFrame (parent, Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::Tool | Qt::X11BypassWindowManagerHint),
my_parent(parent)
{
setSteps(steps);
setLineWidth(2);
- setMouseTracking ( TRUE );
+ setMouseTracking ( true );
setFrameStyle ( QFrame::Panel | QFrame::Raised );
setLineWidth( 1 );
ensurePolished();
resize(size, size);
hide();
}
QmitkPopupColorChooser::~QmitkPopupColorChooser()
{
}
void QmitkPopupColorChooser::setSteps(int steps)
{
m_Steps = steps;
m_Steps2 = m_Steps / 2;
m_HStep = 360 / m_Steps;
m_SStep = 512 / m_Steps;
m_VStep = 512 / m_Steps;
}
void QmitkPopupColorChooser::keyReleaseEvent(QKeyEvent*)
{
emit colorSelected( m_OriginalColor );
close();
}
void QmitkPopupColorChooser::mouseMoveEvent (QMouseEvent* e)
{
double x(e->pos().x());
double y(e->pos().y());
x /= width();
if ( x >= 0.0 )
{
x = (int)(x * (float)(m_Steps-1)) / (float)(m_Steps-1);
if (x > 1.0) x = 1.0;
if (x < 0.0) x = 0.0;
}
y /= height();
if (y >= 1.0) y = 0.9;
if (y < 0.0) y = 0.0;
y = (int)(y * (float)m_Steps) / (float)m_Steps;
m_H = static_cast<int>( y * 359.0 );
if ( x >= 0.5 )
{
m_S = static_cast<int>( (1.0 - x) * 511.0 );
if ( m_S > 255 ) m_S = 255;
m_V = 255;
}
else
{
m_S = 255;
if ( x < 0.0 )
m_V = 0;
else
{
m_V = static_cast<int>( x * 511.0 + 511.0 / (float)(m_Steps-1) );
if ( m_V > 255 ) m_V = 255;
}
}
QColor color;
color.setHsv(m_H, m_S, m_V);
emit colorSelected( color );
}
void QmitkPopupColorChooser::mouseReleaseEvent (QMouseEvent*)
{
close ();
}
void QmitkPopupColorChooser::closeEvent (QCloseEvent*e)
{
e->accept ();
releaseKeyboard();
releaseMouse();
if (!m_popupParent) return;
// remember that we (as a popup) might recieve the mouse release
// event instead of the popupParent. This is due to the fact that
// the popupParent popped us up in its mousePressEvent handler. To
// avoid the button remaining in pressed state we simply send a
// faked mouse button release event to it.
// Maleike: parent should not pop us on MouseRelease!
QMouseEvent me( QEvent::MouseButtonRelease, QPoint(0,0), QPoint(0,0), Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
QApplication::sendEvent ( m_popupParent, &me );
}
void QmitkPopupColorChooser::popup(QWidget* parent, const QPoint& point, const mitk::Color* color)
{
m_popupParent = parent;
if (m_popupParent)
{
QPoint newPos;
if (color)
{
QColor qcolor( (int)((*color)[0] * 255.0) , (int)((*color)[1] * 255.0) , (int)((*color)[2] * 255.0) );
int h,s,v;
qcolor.getHsv(&h, &s, &v);
if ( h == -1 ) // set by Qt if color is achromatic ( but this widget does not display grays )
h = 10; // red
int x, y;
float cellwidth = (float)width() / (float)(m_Steps);
if ( s > v ) // restrict to the colors we can display
{ // left side, ramp from v = 255/m_Steps to v = 255
s = 255;
x = (int)(
(
((float)v / 255.0)
*
((float)m_Steps2)
-
1.0
)
*
cellwidth
+ cellwidth/2
);
}
else
{
v = 255;
x = (int)(
(
(1.0 - ((float)s / 255.0))
*
((float)m_Steps2)
)
*
cellwidth
+ cellwidth/2
+ width() / 2
);
}
y = (int)( (float)h/360.0 * (float)m_Steps * cellwidth );
m_OriginalColor.setHsv(h,s,v);
// move to color
newPos.setX( point.x() - x );
newPos.setY( point.y() - y );
}
else
{
// center widget
m_OriginalColor.setHsv(-1, 0, 0);
newPos.setX( point.x() - width() / 2 );
newPos.setY( point.y() - height() / 2 );
}
move ( m_popupParent->mapToGlobal( newPos ) );
}
show();
raise();
grabMouse();
grabKeyboard();
}
void QmitkPopupColorChooser::paintEvent(QPaintEvent*)
{
QPainter painter(this);
drawGradient( &painter );
}
void QmitkPopupColorChooser::drawGradient( QPainter* p)
{
p->setWindow( 0, 0, m_Steps-1, m_Steps ); // defines coordinate system
p->setPen( Qt::NoPen );
QColor c;
for ( unsigned int h = 0; h < m_Steps; ++h )
{
for ( unsigned int v = 1; v < m_Steps2; ++v )
{
c.setHsv( h*m_HStep, 255, v*m_VStep ); // rainbow effect
p->setBrush( c ); // solid fill with color c
p->drawRect( v-1, h, m_Steps2, m_Steps ); // draw the rectangle
}
for ( unsigned int s = 0; s < m_Steps2; ++s )
{
c.setHsv( h*m_HStep, 255 - s*m_SStep, 255 ); // rainbow effect
p->setBrush( c ); // solid fill with color c
p->drawRect( m_Steps2+s-1, h, m_Steps2, m_Steps ); // draw the rectangle
}
}
}
//----- QmitkColorPropertyEditor --------------------------------------------------
// initialization of static pointer to color picker widget
QmitkPopupColorChooser* QmitkColorPropertyEditor::colorChooser = NULL;
int QmitkColorPropertyEditor::colorChooserRefCount = 0;
QmitkColorPropertyEditor::QmitkColorPropertyEditor( const mitk::ColorProperty* property, QWidget* parent )
: QmitkColorPropertyView( property, parent )
{
// our popup belongs to the whole screen, so it could be drawn outside the toplevel window's borders
int scr;
if ( QApplication::desktop()->isVirtualDesktop() )
scr = QApplication::desktop()->screenNumber( parent->mapToGlobal( pos() ) );
else
scr = QApplication::desktop()->screenNumber( parent );
if ( colorChooserRefCount == 0 )
{
colorChooser = new QmitkPopupColorChooser( QApplication::desktop()->screen( scr ), 50 );
}
++colorChooserRefCount;
}
QmitkColorPropertyEditor::~QmitkColorPropertyEditor()
{
--colorChooserRefCount;
if (!colorChooserRefCount)
{
delete colorChooser;
colorChooser = NULL;
}
}
void QmitkColorPropertyEditor::mousePressEvent(QMouseEvent* e)
{
connect( colorChooser, SIGNAL(colorSelected(QColor)), this, SLOT(onColorSelected(QColor)) );
if (m_ColorProperty)
{
colorChooser->popup( this, e->pos(), &(m_ColorProperty->GetColor()) );
}
}
void QmitkColorPropertyEditor::mouseReleaseEvent(QMouseEvent*)
{
disconnect( colorChooser, SIGNAL(colorSelected(QColor)), this, SLOT(onColorSelected(QColor)) );
}
void QmitkColorPropertyEditor::onColorSelected(QColor c)
{
if (m_ColorProperty)
{
int r,g,b;
c.getRgb( &r, &g, &b );
const_cast<mitk::ColorProperty*>(m_ColorProperty)->SetColor( r / 255.0, g / 255.0, b / 255.0 );
const_cast<mitk::ColorProperty*>(m_ColorProperty)->Modified();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
diff --git a/Modules/QtWidgetsExt/QmitkTransferFunctionGeneratorWidget.cpp b/Modules/QtWidgetsExt/QmitkTransferFunctionGeneratorWidget.cpp
index 392ce8550d..dfc6f032ec 100644
--- a/Modules/QtWidgetsExt/QmitkTransferFunctionGeneratorWidget.cpp
+++ b/Modules/QtWidgetsExt/QmitkTransferFunctionGeneratorWidget.cpp
@@ -1,413 +1,413 @@
/*===================================================================
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 "QmitkTransferFunctionGeneratorWidget.h"
#include <mitkImageStatisticsHolder.h>
#include <mitkTransferFunctionProperty.h>
#include <mitkRenderingManager.h>
#include <mitkTransferFunctionInitializer.h>
#include <mitkUnstructuredGrid.h>
#include <QFileDialog>
#include <MitkSceneSerializationExports.h>
#include <mitkTransferFunctionPropertySerializer.h>
#include <vtkUnstructuredGrid.h>
QmitkTransferFunctionGeneratorWidget::QmitkTransferFunctionGeneratorWidget(QWidget* parent,
Qt::WindowFlags f) :
QWidget(parent, f), deltaScale(1.0), deltaMax(1024), deltaMin(1)
{
histoGramm = NULL;
this->setupUi(this);
// LevelWindow Tab
{
connect( m_CrossLevelWindow, SIGNAL( SignalDeltaMove( int, int ) ), this, SLOT( OnDeltaLevelWindow( int, int ) ) );
}
// Threshold Tab
{
connect( m_CrossThreshold, SIGNAL( SignalDeltaMove( int, int ) ), this, SLOT( OnDeltaThreshold( int, int ) ) );
thDelta = 100;
}
// Presets Tab
{
m_TransferFunctionComboBox->setVisible(false);
connect( m_TransferFunctionComboBox, SIGNAL( activated( int ) ), this, SIGNAL(SignalTransferFunctionModeChanged(int)) );
connect( m_TransferFunctionComboBox, SIGNAL( activated( int ) ), this, SLOT(OnPreset(int)) );
connect( m_SavePreset, SIGNAL( clicked() ), this, SLOT( OnSavePreset() ) );
connect( m_LoadPreset, SIGNAL( clicked() ), this, SLOT( OnLoadPreset() ) );
}
presetFileName = ".";
}
int QmitkTransferFunctionGeneratorWidget::AddPreset(const QString &presetName)
{
m_TransferFunctionComboBox->setVisible(true);
m_TransferFunctionComboBox->addItem( presetName);
return m_TransferFunctionComboBox->count()-1;
}
void QmitkTransferFunctionGeneratorWidget::SetPresetsTabEnabled(bool enable)
{
m_PresetTab->setEnabled(enable);
}
void QmitkTransferFunctionGeneratorWidget::SetThresholdTabEnabled(bool enable)
{
m_ThresholdTab->setEnabled(enable);
}
void QmitkTransferFunctionGeneratorWidget::SetBellTabEnabled(bool enable)
{
m_BellTab->setEnabled(enable);
}
void QmitkTransferFunctionGeneratorWidget::OnSavePreset( )
{
if(tfpToChange.IsNull())
return;
mitk::TransferFunction::Pointer tf = tfpToChange->GetValue();
std::string fileName;
std::string fileNameOutput;
- presetFileName = QFileDialog::getSaveFileName( this,"Choose a filename to save the transferfunction",presetFileName, "Transferfunction (*.xml)" );
+ presetFileName = QFileDialog::getSaveFileName( this,"Choose a filename to save the transfer function", presetFileName, "Transferfunction (*.xml)" );
fileName=presetFileName.toLocal8Bit().constData();
MITK_INFO << "Saving Transferfunction under path: " << fileName;
fileNameOutput= ReduceFileName(fileName);
if ( mitk::TransferFunctionPropertySerializer::SerializeTransferFunction( fileName.c_str(), tf ))
m_InfoPreset->setText( QString( (std::string("saved ")+ fileNameOutput).c_str() ) );
else
m_InfoPreset->setText( QString( std::string("saving failed").c_str() ) );
}
void QmitkTransferFunctionGeneratorWidget::OnLoadPreset( )
{
if(tfpToChange.IsNull())
return;
std::string fileName;
std::string fileNameOutput;
- presetFileName = QFileDialog::getOpenFileName( this,"Choose a file to open the transferfunction from",presetFileName, "Transferfunction (*.xml)" );
+ presetFileName = QFileDialog::getOpenFileName( this,"Choose a file to open the transfer function from",presetFileName, "Transferfunction (*.xml)" );
fileName=presetFileName.toLocal8Bit().constData();
MITK_INFO << "Loading Transferfunction from path: " << fileName;
fileNameOutput= ReduceFileName(fileName);
mitk::TransferFunction::Pointer tf = mitk::TransferFunctionPropertySerializer::DeserializeTransferFunction(fileName.c_str());
if(tf.IsNotNull())
{
tfpToChange->SetValue( tf );
m_InfoPreset->setText( QString( (std::string("loaded ")+ fileNameOutput).c_str() ) );
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
emit SignalUpdateCanvas();
}
}
void QmitkTransferFunctionGeneratorWidget::OnPreset(int mode)
{
//first item is only information
if( --mode == -1 )
return;
m_InfoPreset->setText(QString("selected ") + m_TransferFunctionComboBox->currentText());
//revert to first item
m_TransferFunctionComboBox->setCurrentIndex( 0 );
}
static double transformationGlocke ( double x )
{
double z = 0.1;
double a = 2 - 2 * z;
double b = 2 * z - 1;
x = a * x + b;
return x;
}
static double stepFunctionGlocke ( double x )
{
x = 1-(2*x -1.0); // map [0.5;1] to [0,1]
x = x * ( 3*x - 2*x*x ); // apply smoothing function
x = x * x;
return x;
}
double QmitkTransferFunctionGeneratorWidget::ScaleDelta(int d) const
{
return deltaScale*(double)d;
}
void QmitkTransferFunctionGeneratorWidget::OnDeltaLevelWindow(int dx, int dy) // bell
{
if(tfpToChange.IsNull())
return;
thPos += ScaleDelta(dx);
thDelta -= ScaleDelta(dy);
if(thDelta < deltaMin)
thDelta = deltaMin;
if(thDelta > deltaMax)
thDelta = deltaMax;
if(thPos < histoMinimum)
thPos = histoMinimum;
if(thPos > histoMaximum)
thPos = histoMaximum;
std::stringstream ss;
ss << "Click on the cross and move the mouse"<<"\n"
<<"\n"
<< "center at " << thPos << "\n"
<< "width " << thDelta * 2;
m_InfoLevelWindow->setText( QString( ss.str().c_str() ) );
mitk::TransferFunction::Pointer tf = tfpToChange->GetValue();
// grayvalue->opacity
{
vtkPiecewiseFunction *f=tf->GetScalarOpacityFunction();
f->RemoveAllPoints();
for( int r = 0; r<= 6; r++)
{
double relPos = (r / 6.0) * 0.5 + 0.5;
f->AddPoint(thPos+thDelta*(-transformationGlocke(relPos)),stepFunctionGlocke(relPos));
f->AddPoint(thPos+thDelta*( transformationGlocke(relPos)),stepFunctionGlocke(relPos));
}
f->Modified();
}
// gradient at grayvalue->opacity
{
vtkPiecewiseFunction *f=tf->GetGradientOpacityFunction();
f->RemoveAllPoints();
f->AddPoint( 0, 1.0 );
f->Modified();
}
tf->Modified();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
emit SignalUpdateCanvas();
}
static double stepFunctionThreshold ( double x )
{
x = 0.5*x + 0.5; // map [-1;1] to [0,1]
x = x * ( 3*x - 2*x*x ); // apply smoothing function
x = x * x;
return x;
}
void QmitkTransferFunctionGeneratorWidget::OnDeltaThreshold(int dx, int dy) // LEVELWINDOW
{
if(tfpToChange.IsNull())
return;
thPos += ScaleDelta(dx);
thDelta += ScaleDelta(dy);
if(thDelta < deltaMin)
thDelta = deltaMin;
if(thDelta > deltaMax)
thDelta = deltaMax;
if(thPos < histoMinimum)
thPos = histoMinimum;
if(thPos > histoMaximum)
thPos = histoMaximum;
std::stringstream ss;
ss << "Click on the cross and move the mouse"<<"\n"
<<"\n"
<< "threshold at " << thPos << "\n"
<< "width " << thDelta * 2;
m_InfoThreshold->setText( QString( ss.str().c_str() ) );
mitk::TransferFunction::Pointer tf = tfpToChange->GetValue();
// grayvalue->opacity
{
vtkPiecewiseFunction *f=tf->GetScalarOpacityFunction();
f->RemoveAllPoints();
for( int r = 1; r<= 4; r++)
{
double relPos = r / 4.0;
f->AddPoint(thPos+thDelta*(-relPos),stepFunctionThreshold(-relPos));
f->AddPoint(thPos+thDelta*( relPos),stepFunctionThreshold( relPos));
}
f->Modified();
}
// gradient at grayvalue->opacity
{
vtkPiecewiseFunction *f=tf->GetGradientOpacityFunction();
f->RemoveAllPoints();
f->AddPoint( 0, 1.0 );
f->Modified();
}
tf->Modified();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
emit SignalUpdateCanvas();
}
std::string QmitkTransferFunctionGeneratorWidget::ReduceFileName(std::string fileNameLong )
{
if (fileNameLong.length()< 40)
return fileNameLong;
std::string fileNameShort;
std::string fileNameRevert;
for(unsigned int i=0; i< fileNameLong.length(); i++)
{
if(i<3)
{
char x= fileNameLong[i];
fileNameShort= fileNameShort+x;
}
if(i==3)
{
fileNameShort= fileNameShort+"...";
break;
}
}
unsigned int len( fileNameLong.length() );
for(unsigned int i=len-1; i <= len; i--)
{
std::string x=std::string("")+fileNameLong[i];
if ( x.compare("/")==0 || x.compare("\\")==0)
{
fileNameRevert= "/" + fileNameRevert;
break;
}
if (i>=fileNameLong.length()-24)
{
fileNameRevert= x+ fileNameRevert;
}
else
{
fileNameRevert= "/..." + fileNameRevert;
break;
}
}
return fileNameShort+fileNameRevert;
}
QmitkTransferFunctionGeneratorWidget::~QmitkTransferFunctionGeneratorWidget()
{
}
void QmitkTransferFunctionGeneratorWidget::SetDataNode(mitk::DataNode* node)
{
histoGramm = NULL;
if (node)
{
tfpToChange = dynamic_cast<mitk::TransferFunctionProperty*>(node->GetProperty("TransferFunction"));
if(!tfpToChange)
node->SetProperty("TransferFunction", tfpToChange = mitk::TransferFunctionProperty::New() );
mitk::TransferFunction::Pointer tf = tfpToChange->GetValue();
if( mitk::Image* image = dynamic_cast<mitk::Image*>( node->GetData() ) )
{
mitk::ImageStatisticsHolder* statistics = image->GetStatistics();
histoMinimum= statistics->GetScalarValueMin();
histoMaximum= statistics->GetScalarValueMax();
}
else if (mitk::UnstructuredGrid* grid = dynamic_cast<mitk::UnstructuredGrid*>( node->GetData() ) )
{
double* range = grid->GetVtkUnstructuredGrid()->GetScalarRange();
histoMinimum = range[0];
histoMaximum = range[1];
double histoRange = histoMaximum - histoMinimum;
deltaMax = histoRange/4.0;
deltaMin = histoRange/400.0;
deltaScale = histoRange/1024.0;
}
else
{
MITK_WARN << "QmitkTransferFunctonGeneratorWidget does not support " << node->GetData()->GetNameOfClass() << " instances";
}
thPos = ( histoMinimum + histoMaximum ) / 2.0;
}
else
{
tfpToChange = 0;
m_InfoPreset->setText( QString( "" ) );
}
}
diff --git a/Modules/QtWidgetsExt/QmitkTransferFunctionGeneratorWidget.ui b/Modules/QtWidgetsExt/QmitkTransferFunctionGeneratorWidget.ui
index 92c187bfea..be99afbb43 100644
--- a/Modules/QtWidgetsExt/QmitkTransferFunctionGeneratorWidget.ui
+++ b/Modules/QtWidgetsExt/QmitkTransferFunctionGeneratorWidget.ui
@@ -1,416 +1,425 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QmitkTransferFunctionGeneratorWidget</class>
<widget class="QWidget" name="QmitkTransferFunctionGeneratorWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>349</width>
<height>316</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>1</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
- <property name="margin">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>120</height>
</size>
</property>
<property name="toolTip">
<string/>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="m_PresetTab">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<attribute name="title">
<string>Presets</string>
</attribute>
<attribute name="toolTip">
- <string notr="true">Apply internal MITK transferfunction presets.
-Or save and load your own created transferfunctions in a folder in XML format.</string>
+ <string notr="true">Apply internal MITK transfer function presets.
+Or save and load your own created transfer functions in a folder in XML format.</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QComboBox" name="m_TransferFunctionComboBox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
- <string>Choose one of generic MITK internal presets to apply on standard CT data or MR data.</string>
+ <string>Choose one of generic MITK internal presets to apply to standard CT data or MR data.</string>
</property>
<property name="statusTip">
<string>Load a MITK internal preset</string>
</property>
<property name="currentIndex">
<number>-1</number>
</property>
<property name="iconSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="duplicatesEnabled">
<bool>false</bool>
</property>
<property name="frame">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="m_InfoPreset">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>25</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="textFormat">
<enum>Qt::AutoText</enum>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="indent">
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_LoadPreset">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>64</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
- <string>Load a transferfunction in xml-format from the filesystem.
-The load includes all transferfunctions: grayvalue, color and gradient.</string>
+ <string>Load a transfer function in xml-format from the filesystem.
+The load includes all transfer functions: grayvalue, color and gradient.</string>
</property>
<property name="text">
<string>Load</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_SavePreset">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>64</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
- <string>Save a transferfunction in xml-format in the filesystem.
-The save includes all transferfunctions: grayvalue, color and gradient.</string>
+ <string>Save a transfer function in xml-format in the filesystem.
+The save includes all transfer functions: grayvalue, color and gradient.</string>
</property>
<property name="text">
<string>Save</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="m_ThresholdTab">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<attribute name="title">
<string>Threshold</string>
</attribute>
<attribute name="toolTip">
<string>Generate a threshold transfer function interactively.</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QmitkCrossWidget" name="m_CrossThreshold">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
<property name="toolTip">
<string>Click and hold left mouse button on the cross.
Move the mouse to the top and the function will be flatter.
-Move the mouse to the bottom and the function will be steeper.
+Move the mouse to the bottom and the function will be steeper.
Move the mouse to the left and the function moves to the left.
Move the mouse to the right and the function moves to the right. </string>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
- <pixmap resource="resources/QmitkResources.qrc">:/QtWidgetsExt/cross.png</pixmap>
+ <pixmap resource="resources/QtWidgetsExt.qrc">:/QtWidgetsExt/cross.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="indent">
<number>-1</number>
</property>
<property name="textInteractionFlags">
<set>Qt::NoTextInteraction</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="m_InfoThreshold">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="font">
<font>
<pointsize>7</pointsize>
</font>
</property>
<property name="text">
- <string>Click and hold left mouse button on the cross to interactively generate a threshold transferfunction</string>
+ <string>Click and hold left mouse button on the cross to interactively generate a threshold transfer function</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="m_BellTab">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<attribute name="title">
<string>Bell</string>
</attribute>
<attribute name="toolTip">
<string>Generate a bell transfer function interactively.</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QmitkCrossWidget" name="m_CrossLevelWindow">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>48</width>
<height>48</height>
</size>
</property>
<property name="toolTip">
<string>Click and hold left mouse button on the cross.
Move the mouse to the top and the bell will be wider.
-Move the mouse to the bottom and the bell will be flattened.
+Move the mouse to the bottom and the bell will be narrowed.
Move the mouse to the left and the center of the bell moves to the left.
-Move the mouse to the right and the center of the bell moves to the right.</string>
+Move the mouse to the right and the center of the bell moves to the right.</string>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
- <pixmap resource="resources/QmitkResources.qrc">:/QtWidgetsExt/cross.png</pixmap>
+ <pixmap resource="resources/QtWidgetsExt.qrc">:/QtWidgetsExt/cross.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="textInteractionFlags">
<set>Qt::NoTextInteraction</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="m_InfoLevelWindow">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="font">
<font>
<pointsize>7</pointsize>
</font>
</property>
<property name="text">
- <string>Click and hold left mouse button on the cross to interactively generate a bell transferfunction</string>
+ <string>Click and hold left mouse button on the cross to interactively generate a bell transfer function</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QmitkCrossWidget</class>
<extends>QLabel</extends>
<header location="global">QmitkCrossWidget.h</header>
</customwidget>
</customwidgets>
<resources>
- <include location="resources/QmitkResources.qrc"/>
+ <include location="resources/QtWidgetsExt.qrc"/>
</resources>
<connections/>
</ui>
diff --git a/Modules/QtWidgetsExt/QmitkTransferFunctionWidget.cpp b/Modules/QtWidgetsExt/QmitkTransferFunctionWidget.cpp
index 51b1d48376..245e019d3c 100755
--- a/Modules/QtWidgetsExt/QmitkTransferFunctionWidget.cpp
+++ b/Modules/QtWidgetsExt/QmitkTransferFunctionWidget.cpp
@@ -1,268 +1,259 @@
/*===================================================================
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 "QmitkTransferFunctionWidget.h"
#include <mitkTransferFunctionProperty.h>
-#include <QPlastiqueStyle>
QmitkTransferFunctionWidget::QmitkTransferFunctionWidget(QWidget* parent,
Qt::WindowFlags f) :
QWidget(parent, f)
{
this->setupUi(this);
// signals and slots connections
connect(m_XEditScalarOpacity, SIGNAL(textEdited ( const QString & )), this, SLOT(SetXValueScalar( const QString & )));
connect(m_YEditScalarOpacity, SIGNAL(textEdited ( const QString & )), this, SLOT(SetYValueScalar( const QString & )));
connect(m_XEditGradientOpacity, SIGNAL(textEdited ( const QString & )), this, SLOT(SetXValueGradient( const QString & )));
connect(m_YEditGradientOpacity, SIGNAL(textEdited ( const QString & )), this, SLOT(SetYValueGradient( const QString & )));
connect(m_XEditColor, SIGNAL( textEdited ( const QString & ) ), this, SLOT(SetXValueColor( const QString & )));
- QPlastiqueStyle *sliderStyle = new QPlastiqueStyle();
-
- m_RangeSlider->setMaximum(2048);
m_RangeSlider->setMinimum(-2048);
- m_RangeSlider->setHandleMovementMode(QxtSpanSlider::NoOverlapping);
- m_RangeSlider->setStyle(sliderStyle);
- connect(m_RangeSlider, SIGNAL(spanChanged(double,double)),this, SLOT(OnSpanChanged(double,double)));
+ m_RangeSlider->setMaximum(2048);
+ connect(m_RangeSlider, SIGNAL(valuesChanged(int,int)),this, SLOT(OnSpanChanged(int,int)));
//reset button
connect(m_RangeSliderReset, SIGNAL(pressed()), this, SLOT(OnResetSlider()));
m_ScalarOpacityFunctionCanvas->SetQLineEdits(m_XEditScalarOpacity, m_YEditScalarOpacity);
m_GradientOpacityCanvas->SetQLineEdits(m_XEditGradientOpacity, m_YEditGradientOpacity);
m_ColorTransferFunctionCanvas->SetQLineEdits(m_XEditColor, 0);
m_ScalarOpacityFunctionCanvas->SetTitle("Grayvalue -> Opacity");
m_GradientOpacityCanvas->SetTitle("Grayvalue/Gradient -> Opacity");
m_ColorTransferFunctionCanvas->SetTitle("Grayvalue -> Color");
}
QmitkTransferFunctionWidget::~QmitkTransferFunctionWidget()
{
}
-void QmitkTransferFunctionWidget::SetIntegerMode(bool intMode)
-{
- m_RangeSlider->setIntegerMode(intMode);
-}
-
void QmitkTransferFunctionWidget::SetScalarLabel(const QString& scalarLabel)
{
m_textLabelX->setText(scalarLabel);
m_textLabelX_2->setText(scalarLabel);
m_textLabelX_3->setText(scalarLabel);
m_ScalarOpacityFunctionCanvas->SetTitle(scalarLabel + " -> Opacity");
m_GradientOpacityCanvas->SetTitle(scalarLabel + "/Gradient -> Opacity");
m_ColorTransferFunctionCanvas->SetTitle(scalarLabel + " -> Color");
}
void QmitkTransferFunctionWidget::ShowScalarOpacityFunction(bool show)
{
m_ScalarOpacityWidget->setVisible(show);
}
void QmitkTransferFunctionWidget::ShowColorFunction(bool show)
{
m_ColorWidget->setVisible(show);
}
void QmitkTransferFunctionWidget::ShowGradientOpacityFunction(bool show)
{
m_GradientOpacityWidget->setVisible(show);
}
void QmitkTransferFunctionWidget::SetScalarOpacityFunctionEnabled(bool enable)
{
m_ScalarOpacityWidget->setEnabled(enable);
}
void QmitkTransferFunctionWidget::SetColorFunctionEnabled(bool enable)
{
m_ColorWidget->setEnabled(enable);
}
void QmitkTransferFunctionWidget::SetGradientOpacityFunctionEnabled(bool enable)
{
m_GradientOpacityWidget->setEnabled(enable);
}
void QmitkTransferFunctionWidget::SetDataNode(mitk::DataNode* node, const mitk::BaseRenderer* renderer)
{
if (node)
{
tfpToChange = dynamic_cast<mitk::TransferFunctionProperty*>(node->GetProperty("TransferFunction", renderer));
if(!tfpToChange)
{
if (! dynamic_cast<mitk::Image*>(node->GetData()))
{
MITK_WARN << "QmitkTransferFunctionWidget::SetDataNode called with non-image node";
goto turnOff;
}
node->SetProperty("TransferFunction", tfpToChange = mitk::TransferFunctionProperty::New() );
}
mitk::TransferFunction::Pointer tf = tfpToChange->GetValue();
if( mitk::BaseData* data = node->GetData() )
{
mitk::SimpleHistogram *h = histogramCache[data];
m_RangeSliderMin= h->GetMin();
m_RangeSliderMax= h->GetMax();
m_RangeSlider->blockSignals(true);
m_RangeSlider->setMinimum(m_RangeSliderMin);
m_RangeSlider->setMaximum(m_RangeSliderMax);
- m_RangeSlider->setSpan( m_RangeSliderMin, m_RangeSliderMax);
+ m_RangeSlider->setMinimumValue(m_RangeSliderMin);
+ m_RangeSlider->setMaximumValue(m_RangeSliderMax);
m_RangeSlider->blockSignals(false);
m_ScalarOpacityFunctionCanvas->SetHistogram( h );
m_GradientOpacityCanvas->SetHistogram( h );
m_ColorTransferFunctionCanvas->SetHistogram( h );
}
OnUpdateCanvas();
return;
}
turnOff:
m_ScalarOpacityFunctionCanvas->setEnabled(false);
m_ScalarOpacityFunctionCanvas->SetHistogram(0);
m_GradientOpacityCanvas->setEnabled(false);
m_GradientOpacityCanvas->SetHistogram(0);
m_ColorTransferFunctionCanvas->setEnabled(false);
m_ColorTransferFunctionCanvas->SetHistogram(0);
tfpToChange = 0;
}
void QmitkTransferFunctionWidget::OnUpdateCanvas()
{
if(tfpToChange.IsNull())
return;
mitk::TransferFunction::Pointer tf = tfpToChange->GetValue();
if(tf.IsNull())
return;
m_ScalarOpacityFunctionCanvas->SetPiecewiseFunction( tf->GetScalarOpacityFunction() );
m_GradientOpacityCanvas->SetPiecewiseFunction( tf->GetGradientOpacityFunction() );
m_ColorTransferFunctionCanvas->SetColorTransferFunction( tf->GetColorTransferFunction() );
UpdateRanges();
m_ScalarOpacityFunctionCanvas->update();
m_GradientOpacityCanvas->update();
m_ColorTransferFunctionCanvas->update();
}
void QmitkTransferFunctionWidget::SetXValueScalar( const QString text )
{
if ( !text.endsWith( "." ))
{
m_ScalarOpacityFunctionCanvas->SetX(text.toFloat());
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void QmitkTransferFunctionWidget::SetYValueScalar( const QString text )
{
if ( !text.endsWith( "." ))
{
m_ScalarOpacityFunctionCanvas->SetY(text.toFloat());
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void QmitkTransferFunctionWidget::SetXValueGradient( const QString text )
{
if ( !text.endsWith( "." ))
{
m_GradientOpacityCanvas->SetX(text.toFloat());
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void QmitkTransferFunctionWidget::SetYValueGradient( const QString text )
{
if ( !text.endsWith( "." ))
{
m_GradientOpacityCanvas->SetY(text.toFloat());
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void QmitkTransferFunctionWidget::SetXValueColor( const QString text )
{
if ( !text.endsWith( "." ))
{
m_ColorTransferFunctionCanvas->SetX(text.toFloat());
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void QmitkTransferFunctionWidget::UpdateRanges()
{
- double lower = m_RangeSlider->lowerValue();
- double upper = m_RangeSlider->upperValue();
+ int lower = m_RangeSlider->minimumValue();
+ int upper = m_RangeSlider->maximumValue();
m_ScalarOpacityFunctionCanvas->SetMin(lower);
m_ScalarOpacityFunctionCanvas->SetMax(upper);
m_GradientOpacityCanvas->SetMin(lower);
m_GradientOpacityCanvas->SetMax(upper);
m_ColorTransferFunctionCanvas->SetMin(lower);
m_ColorTransferFunctionCanvas->SetMax(upper);
}
-void QmitkTransferFunctionWidget::OnSpanChanged(double, double)
+void QmitkTransferFunctionWidget::OnSpanChanged(int, int)
{
UpdateRanges();
m_GradientOpacityCanvas->update();
m_ColorTransferFunctionCanvas->update();
m_ScalarOpacityFunctionCanvas->update();
}
void QmitkTransferFunctionWidget::OnResetSlider()
{
m_RangeSlider->blockSignals(true);
- m_RangeSlider->setUpperValue(m_RangeSliderMax);
- m_RangeSlider->setLowerValue(m_RangeSliderMin);
+ m_RangeSlider->setMaximumValue(m_RangeSliderMax);
+ m_RangeSlider->setMinimumValue(m_RangeSliderMin);
m_RangeSlider->blockSignals(false);
UpdateRanges();
m_GradientOpacityCanvas->update();
m_ColorTransferFunctionCanvas->update();
m_ScalarOpacityFunctionCanvas->update();
}
diff --git a/Modules/QtWidgetsExt/QmitkTransferFunctionWidget.h b/Modules/QtWidgetsExt/QmitkTransferFunctionWidget.h
index 093e56e891..686f5b79d0 100755
--- a/Modules/QtWidgetsExt/QmitkTransferFunctionWidget.h
+++ b/Modules/QtWidgetsExt/QmitkTransferFunctionWidget.h
@@ -1,90 +1,88 @@
/*===================================================================
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 QMITKTRANSFERFUNCTIONWIDGET_H
#define QMITKTRANSFERFUNCTIONWIDGET_H
#include "ui_QmitkTransferFunctionWidget.h"
#include "MitkQtWidgetsExtExports.h"
#include <mitkCommon.h>
#include <QWidget>
#include <mitkDataNode.h>
#include <mitkTransferFunctionProperty.h>
#include <QSlider>
#include <QPushButton>
#include <QmitkTransferFunctionWidget.h>
namespace mitk {
class BaseRenderer;
}
class MitkQtWidgetsExt_EXPORT QmitkTransferFunctionWidget : public QWidget, public Ui::QmitkTransferFunctionWidget
{
Q_OBJECT
public:
QmitkTransferFunctionWidget(QWidget* parent = 0, Qt::WindowFlags f = 0);
~QmitkTransferFunctionWidget () ;
void SetDataNode(mitk::DataNode* node, const mitk::BaseRenderer* renderer = NULL);
- void SetIntegerMode(bool intMode);
-
void SetScalarLabel(const QString& scalarLabel);
void ShowScalarOpacityFunction(bool show);
void ShowColorFunction(bool show);
void ShowGradientOpacityFunction(bool show);
void SetScalarOpacityFunctionEnabled(bool enable);
void SetColorFunctionEnabled(bool enable);
void SetGradientOpacityFunctionEnabled(bool enable);
public slots:
void SetXValueScalar( const QString text );
void SetYValueScalar( const QString text );
void SetXValueGradient( const QString text );
void SetYValueGradient( const QString text );
void SetXValueColor( const QString text );
void OnUpdateCanvas();
void UpdateRanges();
void OnResetSlider();
- void OnSpanChanged (double lower, double upper);
+ void OnSpanChanged (int lower, int upper);
protected:
mitk::TransferFunctionProperty::Pointer tfpToChange;
- double m_RangeSliderMin;
- double m_RangeSliderMax;
+ int m_RangeSliderMin;
+ int m_RangeSliderMax;
mitk::SimpleHistogramCache histogramCache;
};
#endif
diff --git a/Modules/QtWidgetsExt/QmitkTransferFunctionWidget.ui b/Modules/QtWidgetsExt/QmitkTransferFunctionWidget.ui
index daa42305ef..7332ab3bae 100755
--- a/Modules/QtWidgetsExt/QmitkTransferFunctionWidget.ui
+++ b/Modules/QtWidgetsExt/QmitkTransferFunctionWidget.ui
@@ -1,557 +1,557 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QmitkTransferFunctionWidget</class>
<widget class="QWidget" name="QmitkTransferFunctionWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>300</width>
<height>542</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
<horstretch>1</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
- <widget class="QmitkFloatingPointSpanSlider" name="m_RangeSlider">
+ <widget class="ctkRangeSlider" name="m_RangeSlider">
<property name="toolTip">
<string>Change transfer function window range.</string>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_RangeSliderReset">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>48</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Resets range to histogram minimum and maximum.</string>
</property>
<property name="text">
<string>Reset</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QWidget" name="m_ScalarOpacityWidget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>3</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QmitkPiecewiseFunctionCanvas" name="m_ScalarOpacityFunctionCanvas" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>64</height>
</size>
</property>
<property name="font">
<font/>
</property>
<property name="toolTip">
<string>Left-click to select a point or add a new point.
Hold left mouse button to move selected point.
Click right mouse button to delete a point.</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QLineEdit" name="m_XEditScalarOpacity">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>64</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>64</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Edit x-coordinate (grayvalue) of currently selected point.</string>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="m_textLabelX">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font/>
</property>
<property name="toolTip">
<string>Edit x-coordinate (grayvalue) of currently selected point.</string>
</property>
<property name="text">
<string>Grayvalue</string>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="m_textLabelY">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font/>
</property>
<property name="toolTip">
<string>Edit y-coordinate (opacity) of currently selected point.</string>
</property>
<property name="text">
<string>Opacity</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="m_YEditScalarOpacity">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>64</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>64</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Edit y-coordinate (opacity) of currently selected point.</string>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="m_ColorWidget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QmitkColorTransferFunctionCanvas" name="m_ColorTransferFunctionCanvas" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>48</height>
</size>
</property>
<property name="font">
<font/>
</property>
<property name="toolTip">
<string>Left-click to select a point or add a new point.
Hold left mouse button to move selected point.
Click right mouse button to delete a point.
Double-click left mouse button to change color of a point.</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QLineEdit" name="m_XEditColor">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>64</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>64</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Edit x-coordinate (grayvalue) of currently selected point.</string>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="m_textLabelX_3">
<property name="font">
<font/>
</property>
<property name="toolTip">
<string>Edit x-coordinate (grayvalue) of currently selected point.</string>
</property>
<property name="text">
<string>Grayvalue</string>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="m_GradientOpacityWidget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>2</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QmitkPiecewiseFunctionCanvas" name="m_GradientOpacityCanvas" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>64</height>
</size>
</property>
<property name="font">
<font/>
</property>
<property name="toolTip">
<string>Left-click to select a point or add a new point.
Hold left mouse button to move selected point.
Click right mouse button to delete a point.</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QLineEdit" name="m_XEditGradientOpacity">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>64</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>64</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Edit x-coordinate (grayvalue) of currently selected point.</string>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="m_textLabelX_2">
<property name="font">
<font/>
</property>
<property name="toolTip">
<string>Edit x-coordinate (grayvalue) of currently selected point.</string>
</property>
<property name="text">
<string>Grayvalue</string>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="m_textLabelY_2">
<property name="font">
<font/>
</property>
<property name="toolTip">
<string>Edit y-coordinate (opacity) of currently selected point.</string>
</property>
<property name="text">
<string>Opacity</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="m_YEditGradientOpacity">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>64</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>64</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Edit y-coordinate (opacity) of currently selected point.</string>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QmitkPiecewiseFunctionCanvas</class>
<extends>QWidget</extends>
<header>QmitkPiecewiseFunctionCanvas.h</header>
</customwidget>
<customwidget>
<class>QmitkColorTransferFunctionCanvas</class>
<extends>QWidget</extends>
<header>QmitkColorTransferFunctionCanvas.h</header>
</customwidget>
<customwidget>
- <class>QmitkFloatingPointSpanSlider</class>
- <extends>QSlider</extends>
- <header location="global">QmitkFloatingPointSpanSlider.h</header>
+ <class>ctkRangeSlider</class>
+ <extends>QWidget</extends>
+ <header location="global">ctkRangeSlider.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
diff --git a/Modules/QtWidgetsExt/QmitkWebPage.h b/Modules/QtWidgetsExt/QmitkWebPage.h
index c7a6c33ca8..90a55ae0ee 100644
--- a/Modules/QtWidgetsExt/QmitkWebPage.h
+++ b/Modules/QtWidgetsExt/QmitkWebPage.h
@@ -1,54 +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.
===================================================================*/
-#include <QtWebKit/QtWebKit>
+#include <QWebPage>
#ifndef QMITK_WEBPAGE_H
#define QMITK_WEBPAGE_H
/**
* @brief The QmitkWebPage class
*
* This class reimplements QWebPage as a fix for bug 16158.
*/
class QmitkJSWebPage : public QWebPage
{
Q_OBJECT
public:
/**
* @brief Constructor
*/
QmitkJSWebPage(QObject *parent=0);
/**
* @brief Destructor
*/
virtual ~QmitkJSWebPage();
public slots:
/**
* @brief shouldInterruptJavaScript
*
* Overwritten from QWebView, to stop asking Qt to stop the JavaScript.
* @return false so JavaScript is not stopped
*/
bool shouldInterruptJavaScript();
};
#endif
diff --git a/Modules/QtWidgetsExt/files.cmake b/Modules/QtWidgetsExt/files.cmake
index b388a28ff2..5986b01ad1 100644
--- a/Modules/QtWidgetsExt/files.cmake
+++ b/Modules/QtWidgetsExt/files.cmake
@@ -1,116 +1,114 @@
set(CPP_FILES
QmitkAboutDialog/QmitkAboutDialog.cpp
QmitkPropertyObservers/QmitkBasePropertyView.cpp
QmitkPropertyObservers/QmitkBoolPropertyWidget.cpp
QmitkPropertyObservers/QmitkColorPropertyEditor.cpp
QmitkPropertyObservers/QmitkColorPropertyView.cpp
QmitkPropertyObservers/QmitkEnumerationPropertyWidget.cpp
QmitkPropertyObservers/QmitkNumberPropertyEditor.cpp
QmitkPropertyObservers/QmitkNumberPropertySlider.cpp
QmitkPropertyObservers/QmitkNumberPropertyView.cpp
QmitkPropertyObservers/QmitkPropertyViewFactory.cpp
QmitkPropertyObservers/QmitkStringPropertyEditor.cpp
QmitkPropertyObservers/QmitkStringPropertyOnDemandEdit.cpp
QmitkPropertyObservers/QmitkStringPropertyView.cpp
QmitkPropertyObservers/QmitkUGCombinedRepresentationPropertyWidget.cpp
qclickablelabel.cpp
QmitkBoundingObjectWidget.cpp
QmitkCallbackFromGUIThread.cpp
QmitkColorTransferFunctionCanvas.cpp
QmitkCorrespondingPointSetsModel.cpp
QmitkCorrespondingPointSetsView.cpp
QmitkCorrespondingPointSetsWidget.cpp
QmitkCrossWidget.cpp
QmitkEditPointDialog.cpp
QmitkFileChooser.cpp
- QmitkFloatingPointSpanSlider.cpp
QmitkGnuplotWidget.cpp
QmitkHistogram.cpp
QmitkHistogramJSWidget.cpp
QmitkHistogramWidget.cpp
QmitkHotkeyLineEdit.cpp
QmitkModulesDialog.cpp
QmitkModuleTableModel.cpp
QmitkPiecewiseFunctionCanvas.cpp
QmitkPlotWidget.cpp
QmitkPlotDialog.cpp
QmitkPointListModel.cpp
QmitkPointListView.cpp
QmitkPointListViewWidget.cpp
QmitkPointListWidget.cpp
QmitkPrimitiveMovieNavigatorWidget.cpp
QmitkSelectableGLWidget.cpp
QmitkSliceWidget.cpp
QmitkSliderNavigatorWidget.cpp
QmitkStandardViews.cpp
QmitkStepperAdapter.cpp
QmitkTransferFunctionCanvas.cpp
QmitkTransferFunctionGeneratorWidget.cpp
QmitkTransferFunctionWidget.cpp
QmitkVideoBackground.cpp
QmitkWebPage.cpp
QtWidgetsExtRegisterClasses.cpp
)
set(MOC_H_FILES
QmitkAboutDialog/QmitkAboutDialog.h
QmitkPropertyObservers/QmitkBasePropertyView.h
QmitkPropertyObservers/QmitkBoolPropertyWidget.h
QmitkPropertyObservers/QmitkColorPropertyEditor.h
QmitkPropertyObservers/QmitkColorPropertyView.h
QmitkPropertyObservers/QmitkEnumerationPropertyWidget.h
QmitkPropertyObservers/QmitkNumberPropertyEditor.h
QmitkPropertyObservers/QmitkNumberPropertySlider.h
QmitkPropertyObservers/QmitkNumberPropertyView.h
QmitkPropertyObservers/QmitkStringPropertyEditor.h
QmitkPropertyObservers/QmitkStringPropertyOnDemandEdit.h
QmitkPropertyObservers/QmitkStringPropertyView.h
QmitkPropertyObservers/QmitkUGCombinedRepresentationPropertyWidget.h
qclickablelabel.h
QmitkBoundingObjectWidget.h
QmitkCallbackFromGUIThread.h
QmitkColorTransferFunctionCanvas.h
QmitkCorrespondingPointSetsModel.h
QmitkCorrespondingPointSetsView.h
QmitkCorrespondingPointSetsWidget.h
QmitkCrossWidget.h
QmitkEditPointDialog.h
QmitkFileChooser.h
- QmitkFloatingPointSpanSlider.h
QmitkGnuplotWidget.h
QmitkHistogramJSWidget.h
QmitkHistogramWidget.h
QmitkHotkeyLineEdit.h
QmitkPiecewiseFunctionCanvas.h
QmitkPlotWidget.h
QmitkPointListModel.h
QmitkPointListView.h
QmitkPointListViewWidget.h
QmitkPointListWidget.h
QmitkPrimitiveMovieNavigatorWidget.h
QmitkSelectableGLWidget.h
QmitkSliceWidget.h
QmitkSliderNavigatorWidget.h
QmitkStandardViews.h
QmitkStepperAdapter.h
QmitkTransferFunctionCanvas.h
QmitkTransferFunctionGeneratorWidget.h
QmitkTransferFunctionWidget.h
QmitkVideoBackground.h
QmitkWebPage.h
)
set(UI_FILES
QmitkAboutDialog/QmitkAboutDialogGUI.ui
QmitkGnuplotWidget.ui
QmitkPrimitiveMovieNavigatorWidget.ui
QmitkSelectableGLWidget.ui
QmitkSliceWidget.ui
QmitkSliderNavigator.ui
QmitkTransferFunctionGeneratorWidget.ui
QmitkTransferFunctionWidget.ui
)
set(QRC_FILES
resources/QtWidgetsExt.qrc
)
diff --git a/Modules/QtWidgetsExt/qclickablelabel.cpp b/Modules/QtWidgetsExt/qclickablelabel.cpp
index a6fc72a82d..fb441c85b3 100644
--- a/Modules/QtWidgetsExt/qclickablelabel.cpp
+++ b/Modules/QtWidgetsExt/qclickablelabel.cpp
@@ -1,115 +1,123 @@
/*===================================================================
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 "qclickablelabel.h"
#include <QMouseEvent>
#include <iostream>
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
QClickableLabel::QClickableLabel( QWidget* parent, Qt::WFlags f )
+#else
+QClickableLabel::QClickableLabel( QWidget* parent, Qt::WindowFlags f )
+#endif
:QLabel(parent, f)
{
}
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
QClickableLabel::QClickableLabel( const QString& text, QWidget* parent, Qt::WFlags f )
+#else
+QClickableLabel::QClickableLabel( const QString& text, QWidget* parent, Qt::WindowFlags f )
+#endif
:QLabel(text, parent, f)
{
}
QClickableLabel::~QClickableLabel()
{
}
void QClickableLabel::AddHotspot( const QString& name, const QRect position )
{
m_Hotspots.push_back( position );
m_HotspotIndexForName.insert( std::make_pair( name, (int)m_Hotspots.size()-1 ) );
m_HotspotNameForIndex.insert( std::make_pair( (int)m_Hotspots.size()-1, name ) );
}
void QClickableLabel::RemoveHotspot( const QString& name )
{
NameToIndexMapType::iterator iter = m_HotspotIndexForName.find( name );
if ( iter != m_HotspotIndexForName.end() )
{
RemoveHotspot( iter->second );
}
}
void QClickableLabel::RemoveHotspot( unsigned int hotspotIndex )
{
if ( hotspotIndex < m_Hotspots.size() )
{
m_Hotspots.erase( m_Hotspots.begin() + hotspotIndex );
QString name = m_HotspotNameForIndex[hotspotIndex];
m_HotspotNameForIndex.erase( hotspotIndex );
m_HotspotIndexForName.erase( name );
}
}
void QClickableLabel::RemoveAllHotspots()
{
m_Hotspots.clear();
m_HotspotIndexForName.clear();
m_HotspotNameForIndex.clear();
}
void QClickableLabel::mousePressEvent( QMouseEvent* e )
{
unsigned int index = matchingRect( e->pos() );
if ( index < m_Hotspots.size() )
{
emit mouseReleased( index );
emit mouseReleased( m_HotspotNameForIndex[index] );
}
}
void QClickableLabel::mouseReleaseEvent( QMouseEvent* e )
{
unsigned int index = matchingRect( e->pos() );
if ( index < m_Hotspots.size() )
{
emit mousePressed( index );
emit mousePressed( m_HotspotNameForIndex[index] );
}
}
unsigned int QClickableLabel::matchingRect( const QPoint& p )
{
unsigned int index(0);
for ( RectVectorType::iterator iter = m_Hotspots.begin();
iter != m_Hotspots.end();
++iter )
{
if ( iter->contains(p) )
{
return index;
}
++index;
}
return index;
}
diff --git a/Modules/QtWidgetsExt/qclickablelabel.h b/Modules/QtWidgetsExt/qclickablelabel.h
index 8da31dca32..5daf55ce5f 100644
--- a/Modules/QtWidgetsExt/qclickablelabel.h
+++ b/Modules/QtWidgetsExt/qclickablelabel.h
@@ -1,77 +1,81 @@
/*===================================================================
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 qclickablelabelhincluded
#define qclickablelabelhincluded
#include <QLabel>
#include "MitkQtWidgetsExtExports.h"
#include <vector>
#include <map>
#include "mitkCommon.h"
/**
\brief A QLabel with multiple hotspots, that can be clicked
Specially useful in connection with a pixmap.
Stretched images should be avoided, because the hotspots will not be adjusted in any way.
*/
class MitkQtWidgetsExt_EXPORT QClickableLabel : public QLabel
{
Q_OBJECT
public:
-
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
QClickableLabel( QWidget* parent, Qt::WFlags f = 0 );
QClickableLabel( const QString& text, QWidget* parent, Qt::WFlags f = 0 );
+#else
+ QClickableLabel( QWidget* parent, Qt::WindowFlags f = 0 );
+ QClickableLabel( const QString& text, QWidget* parent, Qt::WindowFlags f = 0 );
+#endif
virtual ~QClickableLabel();
void AddHotspot( const QString& name, const QRect position );
void RemoveHotspot( const QString& name );
void RemoveHotspot( unsigned int hotspotIndex );
void RemoveAllHotspots();
signals:
void mousePressed( const QString& hotspotName );
void mousePressed( unsigned int hotspotIndex );
void mouseReleased( const QString& hotspotName );
void mouseReleased( unsigned int hotspotIndex );
protected:
virtual void mousePressEvent ( QMouseEvent* e );
virtual void mouseReleaseEvent ( QMouseEvent* e );
/// returns index == m_Hotspots.size() if nothing is hit
unsigned int matchingRect( const QPoint& p );
typedef std::vector< QRect > RectVectorType;
RectVectorType m_Hotspots;
typedef std::map< QString, unsigned int > NameToIndexMapType;
typedef std::map< unsigned int, QString > IndexToNameMapType;
NameToIndexMapType m_HotspotIndexForName;
IndexToNameMapType m_HotspotNameForIndex;
};
#endif
diff --git a/Modules/Remeshing/CMakeLists.txt b/Modules/Remeshing/CMakeLists.txt
index ac6516a386..c3da914c8e 100644
--- a/Modules/Remeshing/CMakeLists.txt
+++ b/Modules/Remeshing/CMakeLists.txt
@@ -1,8 +1,7 @@
-if(MITK_USE_ACVD)
- MITK_CREATE_MODULE(
+mitk_create_module(
DEPENDS MitkCore
PACKAGE_DEPENDS ACVD VTK|vtkIOPLY+vtkIOMINC
)
- add_subdirectory(Testing)
-endif()
+add_subdirectory(Testing)
+
diff --git a/Modules/SceneSerializationBase/BasePropertySerializer/mitkTransferFunctionPropertySerializer.cpp b/Modules/SceneSerializationBase/BasePropertySerializer/mitkTransferFunctionPropertySerializer.cpp
index cd2722e8b6..467bdf2aee 100644
--- a/Modules/SceneSerializationBase/BasePropertySerializer/mitkTransferFunctionPropertySerializer.cpp
+++ b/Modules/SceneSerializationBase/BasePropertySerializer/mitkTransferFunctionPropertySerializer.cpp
@@ -1,232 +1,232 @@
/*===================================================================
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 "mitkTransferFunctionPropertySerializer.h"
namespace mitk {
mitk::TransferFunctionPropertySerializer::TransferFunctionPropertySerializer()
{
}
mitk::TransferFunctionPropertySerializer::~TransferFunctionPropertySerializer()
{
}
TiXmlElement* mitk::TransferFunctionPropertySerializer::Serialize()
{
if (const TransferFunctionProperty* prop = dynamic_cast<const TransferFunctionProperty*>(mitk::BasePropertySerializer::m_Property.GetPointer()))
{
TransferFunction* transferfunction = prop->GetValue();
if (!transferfunction)
return NULL;
TiXmlElement* element = new TiXmlElement("TransferFunction");
// serialize scalar opacity function
TiXmlElement* scalarOpacityPointlist = new TiXmlElement( "ScalarOpacity" );
TransferFunction::ControlPoints scalarOpacityPoints = transferfunction->GetScalarOpacityPoints();
for ( TransferFunction::ControlPoints::iterator iter = scalarOpacityPoints.begin();
iter != scalarOpacityPoints.end();
++iter )
{
TiXmlElement* pointel = new TiXmlElement("point");
pointel->SetDoubleAttribute("x", iter->first);
pointel->SetDoubleAttribute("y", iter->second);
scalarOpacityPointlist->LinkEndChild( pointel );
}
element->LinkEndChild( scalarOpacityPointlist );
// serialize gradient opacity function
TiXmlElement* gradientOpacityPointlist = new TiXmlElement( "GradientOpacity" );
TransferFunction::ControlPoints gradientOpacityPoints = transferfunction->GetGradientOpacityPoints();
for ( TransferFunction::ControlPoints::iterator iter = gradientOpacityPoints.begin();
iter != gradientOpacityPoints.end();
++iter )
{
TiXmlElement* pointel = new TiXmlElement("point");
pointel->SetDoubleAttribute("x", iter->first);
pointel->SetDoubleAttribute("y", iter->second);
gradientOpacityPointlist->LinkEndChild( pointel );
}
element->LinkEndChild( gradientOpacityPointlist );
// serialize color function
vtkColorTransferFunction* ctf = transferfunction->GetColorTransferFunction();
if (ctf == NULL)
return NULL;
TiXmlElement* pointlist = new TiXmlElement("Color");
for (int i = 0; i < ctf->GetSize(); i++ )
{
double myVal[6];
ctf->GetNodeValue(i, myVal);
TiXmlElement* pointel = new TiXmlElement("point");
pointel->SetDoubleAttribute("x", myVal[0]);
pointel->SetDoubleAttribute("r", myVal[1]);
pointel->SetDoubleAttribute("g", myVal[2]);
pointel->SetDoubleAttribute("b", myVal[3]);
pointel->SetDoubleAttribute("midpoint", myVal[4]);
pointel->SetDoubleAttribute("sharpness", myVal[5]);
pointlist->LinkEndChild( pointel );
}
element->LinkEndChild( pointlist );
return element;
}
else return NULL;
}
bool mitk::TransferFunctionPropertySerializer::SerializeTransferFunction( const char * filename, TransferFunction::Pointer tf )
{
TransferFunctionPropertySerializer::Pointer tfps=TransferFunctionPropertySerializer::New();
tfps->SetProperty( TransferFunctionProperty::New( tf ) );
TiXmlElement* s=tfps->Serialize();
if(!s)
{
MITK_ERROR << "cant serialize transfer function";
return false;
}
TiXmlDocument document;
TiXmlDeclaration* decl = new TiXmlDeclaration( "1.0", "UTF-8", "" ); // TODO what to write here? encoding? standalone would mean that we provide a DTD somewhere...
document.LinkEndChild( decl );
TiXmlElement* version = new TiXmlElement("Version");
version->SetAttribute("TransferfunctionVersion", 1 );
document.LinkEndChild(version);
document.LinkEndChild(s);
if ( !document.SaveFile( filename ) )
{
MITK_ERROR << "Could not write scene to " << filename << "\nTinyXML reports '" << document.ErrorDesc() << "'";
return false;
}
return true;
}
BaseProperty::Pointer mitk::TransferFunctionPropertySerializer::Deserialize(TiXmlElement* element)
{
if (!element)
return NULL;
TransferFunction::Pointer tf = TransferFunction::New();
// deserialize scalar opacity function
TiXmlElement* scalarOpacityPointlist = element->FirstChildElement("ScalarOpacity");
if (scalarOpacityPointlist == NULL)
return NULL;
tf->ClearScalarOpacityPoints();
for( TiXmlElement* pointElement = scalarOpacityPointlist->FirstChildElement("point"); pointElement != NULL; pointElement = pointElement->NextSiblingElement("point"))
{
double x;
double y;
if (pointElement->QueryDoubleAttribute("x", &x) == TIXML_WRONG_TYPE)
return NULL; // TODO: can we do a better error handling?
if (pointElement->QueryDoubleAttribute("y", &y) == TIXML_WRONG_TYPE)
return NULL; // TODO: can we do a better error handling?
tf->AddScalarOpacityPoint(x, y);
}
TiXmlElement* gradientOpacityPointlist = element->FirstChildElement("GradientOpacity");
if (gradientOpacityPointlist == NULL)
return NULL;
tf->ClearGradientOpacityPoints();
for( TiXmlElement* pointElement = gradientOpacityPointlist->FirstChildElement("point"); pointElement != NULL; pointElement = pointElement->NextSiblingElement("point"))
{
double x;
double y;
if (pointElement->QueryDoubleAttribute("x", &x) == TIXML_WRONG_TYPE)
return NULL; // TODO: can we do a better error handling?
if (pointElement->QueryDoubleAttribute("y", &y) == TIXML_WRONG_TYPE)
return NULL; // TODO: can we do a better error handling?
tf->AddGradientOpacityPoint(x, y);
}
TiXmlElement* rgbPointlist = element->FirstChildElement("Color");
if (rgbPointlist == NULL)
return NULL;
vtkColorTransferFunction* ctf = tf->GetColorTransferFunction();
if (ctf == NULL)
return NULL;
ctf->RemoveAllPoints();
for( TiXmlElement* pointElement = rgbPointlist->FirstChildElement("point"); pointElement != NULL; pointElement = pointElement->NextSiblingElement("point"))
{
double x;
double r,g,b, midpoint, sharpness;
if (pointElement->QueryDoubleAttribute("x", &x) == TIXML_WRONG_TYPE)
return NULL; // TODO: can we do a better error handling?
if (pointElement->QueryDoubleAttribute("r", &r) == TIXML_WRONG_TYPE)
return NULL; // TODO: can we do a better error handling?
if (pointElement->QueryDoubleAttribute("g", &g) == TIXML_WRONG_TYPE)
return NULL; // TODO: can we do a better error handling?
if (pointElement->QueryDoubleAttribute("b", &b) == TIXML_WRONG_TYPE)
return NULL; // TODO: can we do a better error handling?
if (pointElement->QueryDoubleAttribute("midpoint", &midpoint) == TIXML_WRONG_TYPE)
return NULL; // TODO: can we do a better error handling?
if (pointElement->QueryDoubleAttribute("sharpness", &sharpness) == TIXML_WRONG_TYPE)
return NULL; // TODO: can we do a better error handling?
ctf->AddRGBPoint(x, r, g, b, midpoint, sharpness);
}
return TransferFunctionProperty::New(tf).GetPointer();
}
mitk::TransferFunction::Pointer mitk::TransferFunctionPropertySerializer::DeserializeTransferFunction( const char *filePath )
{
TiXmlDocument document( filePath );
if (!document.LoadFile())
{
MITK_ERROR << "Could not open/read/parse " << filePath << "\nTinyXML reports: " << document.ErrorDesc() << std::endl;
return NULL;
}
// find version node --> note version in some variable
int fileVersion = 1;
TiXmlElement* versionObject = document.FirstChildElement("Version");
if (versionObject)
{
if ( versionObject->QueryIntAttribute( "TransferfunctionVersion", &fileVersion ) != TIXML_SUCCESS )
{
MITK_WARN << "Transferfunction file " << filePath << " does not contain version information! Trying version 1 format.";
}
}
TiXmlElement* input = document.FirstChildElement("TransferFunction");
TransferFunctionPropertySerializer::Pointer tfpd = TransferFunctionPropertySerializer::New();
BaseProperty::Pointer bp = tfpd->Deserialize(input);
TransferFunctionProperty::Pointer tfp = dynamic_cast<TransferFunctionProperty*>(bp.GetPointer());
if(tfp.IsNotNull())
{
TransferFunction::Pointer tf = tfp->GetValue();
return tf;
}
- MITK_WARN << "Can't deserialize transferfunction";
+ MITK_WARN << "Can't deserialize transfer function";
return NULL;
}
} // namespace
// important to put this into the GLOBAL namespace (because it starts with 'namespace mitk')
MITK_REGISTER_SERIALIZER(TransferFunctionPropertySerializer);
diff --git a/Modules/Segmentation/Controllers/mitkToolManager.cpp b/Modules/Segmentation/Controllers/mitkToolManager.cpp
index e192402e33..820cf9a8a3 100644
--- a/Modules/Segmentation/Controllers/mitkToolManager.cpp
+++ b/Modules/Segmentation/Controllers/mitkToolManager.cpp
@@ -1,566 +1,602 @@
/*===================================================================
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 "mitkToolManager.h"
#include "mitkGlobalInteraction.h"
#include "mitkCoreObjectFactory.h"
#include <itkObjectFactoryBase.h>
#include <itkCommand.h>
#include <list>
#include "mitkInteractionEventObserver.h"
#include "mitkDisplayInteractor.h"
#include "mitkSegTool2D.h"
#include "usGetModuleContext.h"
#include "usModuleContext.h"
mitk::ToolManager::ToolManager(DataStorage* storage)
:m_ActiveTool(NULL),
m_ActiveToolID(-1),
m_RegisteredClients(0),
m_DataStorage(storage),
m_ExclusiveStateEventPolicy(true)
{
CoreObjectFactory::GetInstance(); // to make sure a CoreObjectFactory was instantiated (and in turn, possible tools are registered) - bug 1029
this->InitializeTools();
//ActivateTool(0); // first one is default
}
mitk::ToolManager::~ToolManager()
{
for (DataVectorType::iterator dataIter = m_WorkingData.begin(); dataIter != m_WorkingData.end(); ++dataIter)
(*dataIter)->RemoveObserver(m_WorkingDataObserverTags[(*dataIter)]);
if(this->GetDataStorage() != NULL)
this->GetDataStorage()->RemoveNodeEvent.RemoveListener( mitk::MessageDelegate1<ToolManager, const mitk::DataNode*>
( this, &ToolManager::OnNodeRemoved ));
if (m_ActiveTool)
{
m_ActiveTool->Deactivated();
m_ActiveToolRegistration.Unregister();
//GlobalInteraction::GetInstance()->RemoveListener( m_ActiveTool );
m_ActiveTool = NULL;
m_ActiveToolID = -1; // no tool active
ActiveToolChanged.Send();
}
for ( NodeTagMapType::iterator observerTagMapIter = m_ReferenceDataObserverTags.begin(); observerTagMapIter != m_ReferenceDataObserverTags.end(); ++observerTagMapIter )
{
observerTagMapIter->first->RemoveObserver( observerTagMapIter->second );
}
}
void mitk::ToolManager::InitializeTools()
{
if(mitk::GlobalInteraction::GetInstance()->IsInitialized())
{
m_Tools.resize(0);
// get a list of all known mitk::Tools
std::list<itk::LightObject::Pointer> thingsThatClaimToBeATool = itk::ObjectFactoryBase::CreateAllInstance("mitkTool");
// remember these tools
for ( std::list<itk::LightObject::Pointer>::iterator iter = thingsThatClaimToBeATool.begin();
iter != thingsThatClaimToBeATool.end();
++iter )
{
if ( Tool* tool = dynamic_cast<Tool*>( iter->GetPointer() ) )
{
tool->InitializeStateMachine();
tool->SetToolManager(this); // important to call right after instantiation
tool->ErrorMessage += MessageDelegate1<mitk::ToolManager, std::string>( this, &ToolManager::OnToolErrorMessage );
tool->GeneralMessage += MessageDelegate1<mitk::ToolManager, std::string>( this, &ToolManager::OnGeneralToolMessage );
m_Tools.push_back( tool );
}
}
}
}
void mitk::ToolManager::OnToolErrorMessage(std::string s)
{
this->ToolErrorMessage(s);
}
void mitk::ToolManager::OnGeneralToolMessage(std::string s)
{
this->GeneralToolMessage(s);
}
const mitk::ToolManager::ToolVectorTypeConst mitk::ToolManager::GetTools()
{
ToolVectorTypeConst resultList;
for ( ToolVectorType::iterator iter = m_Tools.begin();
iter != m_Tools.end();
++iter )
{
resultList.push_back( iter->GetPointer() );
}
return resultList;
}
mitk::Tool* mitk::ToolManager::GetToolById(int id)
{
try
{
return m_Tools.at(id);
}
catch(std::exception&)
{
return NULL;
}
}
bool mitk::ToolManager::ActivateTool(int id)
{
if (id != -1 && !this->GetToolById(id)->CanHandle(this->GetReferenceData(0)->GetData()))
return false;
if(this->GetDataStorage())
{
this->GetDataStorage()->RemoveNodeEvent.AddListener( mitk::MessageDelegate1<ToolManager, const mitk::DataNode*>
( this, &ToolManager::OnNodeRemoved ) );
}
//MITK_INFO << "ToolManager::ActivateTool("<<id<<")"<<std::endl;
//if( GetToolById(id) == NULL ) return false; // NO, invalid IDs are actually used here. Parameter -1 or anything that does not exists will deactivate all tools!
//If a tool is deactivated set the event notification policy of the global interaction to multiple again
if (id == -1)
{
GlobalInteraction::GetInstance()->SetEventNotificationPolicy(GlobalInteraction::INFORM_MULTIPLE);
+
+ // Re-enabling InteractionEventObservers that have been previously disabled for legacy handling of Tools
+ // in new interaction framework
+ for (std::map<us::ServiceReferenceU, EventConfig>::iterator it = m_DisplayInteractorConfigs.begin();
+ it != m_DisplayInteractorConfigs.end(); ++it)
+ {
+ if (it->first)
+ {
+ DisplayInteractor* displayInteractor = static_cast<DisplayInteractor*>(
+ us::GetModuleContext()->GetService<InteractionEventObserver>(it->first));
+ if (displayInteractor != NULL)
+ {
+ // here the regular configuration is loaded again
+ displayInteractor->SetEventConfig(it->second);
+ }
+ }
+ }
+ m_DisplayInteractorConfigs.clear();
}
if ( GetToolById( id ) == m_ActiveTool ) return true; // no change needed
static int nextTool = -1;
nextTool = id;
//MITK_INFO << "ToolManager::ActivateTool("<<id<<"): nextTool = "<<nextTool<<std::endl;
static bool inActivateTool = false;
if (inActivateTool)
{
//MITK_INFO << "ToolManager::ActivateTool("<<id<<"): already inside ActivateTool somehow, returning now "<<std::endl;
return true;
}
inActivateTool = true;
while ( nextTool != m_ActiveToolID )
{
//MITK_INFO <<"ToolManager::ActivateTool: nextTool = " << nextTool << " (active tool = " << m_ActiveToolID<<")"<<std::endl;
if (m_ActiveTool)
{
m_ActiveTool->Deactivated();
//GlobalInteraction::GetInstance()->RemoveListener( m_ActiveTool );
m_ActiveToolRegistration.Unregister();
}
m_ActiveTool = GetToolById( nextTool );
m_ActiveToolID = m_ActiveTool ? nextTool : -1; // current ID if tool is valid, otherwise -1
ActiveToolChanged.Send();
if (m_ActiveTool)
{
if (m_RegisteredClients > 0)
{
m_ActiveTool->Activated();
//GlobalInteraction::GetInstance()->AddListener( m_ActiveTool );
m_ActiveToolRegistration = us::GetModuleContext()->RegisterService<InteractionEventObserver>( m_ActiveTool, us::ServiceProperties() );
//If a tool is activated set event notification policy to one
if (m_ExclusiveStateEventPolicy && dynamic_cast<mitk::SegTool2D*>(m_ActiveTool))
GlobalInteraction::GetInstance()->SetEventNotificationPolicy(GlobalInteraction::INFORM_ONE);
+
+
+ // As a legacy solution the display interaction of the new interaction framework is disabled here to avoid conflicts with tools
+ // Note: this only affects InteractionEventObservers (formerly known as Listeners) all DataNode specific interaction will still be enabled
+ m_DisplayInteractorConfigs.clear();
+ std::vector<us::ServiceReference<InteractionEventObserver> > listEventObserver = us::GetModuleContext()->GetServiceReferences<InteractionEventObserver>();
+ for (std::vector<us::ServiceReference<InteractionEventObserver> >::iterator it = listEventObserver.begin(); it != listEventObserver.end(); ++it)
+ {
+ DisplayInteractor* displayInteractor = dynamic_cast<DisplayInteractor*>(
+ us::GetModuleContext()->GetService<InteractionEventObserver>(*it));
+ if (displayInteractor != NULL)
+ {
+ // remember the original configuration
+ m_DisplayInteractorConfigs.insert(std::make_pair(*it, displayInteractor->GetEventConfig()));
+ // here the alternative configuration is loaded
+ displayInteractor->SetEventConfig("DisplayConfigMITK.xml");
+ }
+ }
}
}
}
inActivateTool = false;
return (m_ActiveTool != NULL);
}
void mitk::ToolManager::SetReferenceData(DataVectorType data)
{
if (data != m_ReferenceData)
{
// remove observers from old nodes
for ( DataVectorType::iterator dataIter = m_ReferenceData.begin(); dataIter != m_ReferenceData.end(); ++dataIter )
{
NodeTagMapType::iterator searchIter = m_ReferenceDataObserverTags.find( *dataIter );
if ( searchIter != m_ReferenceDataObserverTags.end() )
{
//MITK_INFO << "Stopping observation of " << (void*)(*dataIter) << std::endl;
(*dataIter)->RemoveObserver( searchIter->second );
}
}
m_ReferenceData = data;
// TODO tell active tool?
// attach new observers
m_ReferenceDataObserverTags.clear();
for ( DataVectorType::iterator dataIter = m_ReferenceData.begin(); dataIter != m_ReferenceData.end(); ++dataIter )
{
//MITK_INFO << "Observing " << (void*)(*dataIter) << std::endl;
itk::MemberCommand<ToolManager>::Pointer command = itk::MemberCommand<ToolManager>::New();
command->SetCallbackFunction( this, &ToolManager::OnOneOfTheReferenceDataDeleted );
command->SetCallbackFunction( this, &ToolManager::OnOneOfTheReferenceDataDeletedConst );
m_ReferenceDataObserverTags.insert( std::pair<DataNode*, unsigned long>( (*dataIter), (*dataIter)->AddObserver( itk::DeleteEvent(), command ) ) );
}
ReferenceDataChanged.Send();
}
}
void mitk::ToolManager::OnOneOfTheReferenceDataDeletedConst(const itk::Object* caller, const itk::EventObject& e)
{
OnOneOfTheReferenceDataDeleted( const_cast<itk::Object*>(caller), e );
}
void mitk::ToolManager::OnOneOfTheReferenceDataDeleted(itk::Object* caller, const itk::EventObject& itkNotUsed(e))
{
//MITK_INFO << "Deleted: " << (void*)caller << " Removing from reference data list." << std::endl;
DataVectorType v;
for (DataVectorType::iterator dataIter = m_ReferenceData.begin(); dataIter != m_ReferenceData.end(); ++dataIter )
{
//MITK_INFO << " In list: " << (void*)(*dataIter);
if ( (void*)(*dataIter) != (void*)caller )
{
v.push_back( *dataIter );
//MITK_INFO << " kept" << std::endl;
}
else
{
//MITK_INFO << " removed" << std::endl;
m_ReferenceDataObserverTags.erase( *dataIter ); // no tag to remove anymore
}
}
this->SetReferenceData( v );
}
void mitk::ToolManager::SetReferenceData(DataNode* data)
{
//MITK_INFO << "ToolManager::SetReferenceData(" << (void*)data << ")" << std::endl;
DataVectorType v;
if (data)
{
v.push_back(data);
}
SetReferenceData(v);
}
void mitk::ToolManager::SetWorkingData(DataVectorType data)
{
if ( data != m_WorkingData )
{
// remove observers from old nodes
for ( DataVectorType::iterator dataIter = m_WorkingData.begin(); dataIter != m_WorkingData.end(); ++dataIter )
{
NodeTagMapType::iterator searchIter = m_WorkingDataObserverTags.find( *dataIter );
if ( searchIter != m_WorkingDataObserverTags.end() )
{
//MITK_INFO << "Stopping observation of " << (void*)(*dataIter) << std::endl;
(*dataIter)->RemoveObserver( searchIter->second );
}
}
m_WorkingData = data;
// TODO tell active tool?
// Quick workaround for bug #16598
if (m_WorkingData.empty())
this->ActivateTool(-1);
// workaround end
// attach new observers
m_WorkingDataObserverTags.clear();
for ( DataVectorType::iterator dataIter = m_WorkingData.begin(); dataIter != m_WorkingData.end(); ++dataIter )
{
//MITK_INFO << "Observing " << (void*)(*dataIter) << std::endl;
itk::MemberCommand<ToolManager>::Pointer command = itk::MemberCommand<ToolManager>::New();
command->SetCallbackFunction( this, &ToolManager::OnOneOfTheWorkingDataDeleted );
command->SetCallbackFunction( this, &ToolManager::OnOneOfTheWorkingDataDeletedConst );
m_WorkingDataObserverTags.insert( std::pair<DataNode*, unsigned long>( (*dataIter), (*dataIter)->AddObserver( itk::DeleteEvent(), command ) ) );
}
WorkingDataChanged.Send();
}
}
void mitk::ToolManager::OnOneOfTheWorkingDataDeletedConst(const itk::Object* caller, const itk::EventObject& e)
{
OnOneOfTheWorkingDataDeleted( const_cast<itk::Object*>(caller), e );
}
void mitk::ToolManager::OnOneOfTheWorkingDataDeleted(itk::Object* caller, const itk::EventObject& itkNotUsed(e))
{
//MITK_INFO << "Deleted: " << (void*)caller << " Removing from reference data list." << std::endl;
DataVectorType v;
for (DataVectorType::iterator dataIter = m_WorkingData.begin(); dataIter != m_WorkingData.end(); ++dataIter )
{
//MITK_INFO << " In list: " << (void*)(*dataIter);
if ( (void*)(*dataIter) != (void*)caller )
{
v.push_back( *dataIter );
//MITK_INFO << " kept" << std::endl;
}
else
{
//MITK_INFO << " removed" << std::endl;
m_WorkingDataObserverTags.erase( *dataIter ); // no tag to remove anymore
}
}
this->SetWorkingData( v );
}
void mitk::ToolManager::SetWorkingData(DataNode* data)
{
DataVectorType v;
if (data) // don't allow for NULL nodes
{
v.push_back(data);
}
SetWorkingData(v);
}
void mitk::ToolManager::SetRoiData(DataVectorType data)
{
if (data != m_RoiData)
{
// remove observers from old nodes
for ( DataVectorType::iterator dataIter = m_RoiData.begin(); dataIter != m_RoiData.end(); ++dataIter )
{
NodeTagMapType::iterator searchIter = m_RoiDataObserverTags.find( *dataIter );
if ( searchIter != m_RoiDataObserverTags.end() )
{
//MITK_INFO << "Stopping observation of " << (void*)(*dataIter) << std::endl;
(*dataIter)->RemoveObserver( searchIter->second );
}
}
m_RoiData = data;
// TODO tell active tool?
// attach new observers
m_RoiDataObserverTags.clear();
for ( DataVectorType::iterator dataIter = m_RoiData.begin(); dataIter != m_RoiData.end(); ++dataIter )
{
//MITK_INFO << "Observing " << (void*)(*dataIter) << std::endl;
itk::MemberCommand<ToolManager>::Pointer command = itk::MemberCommand<ToolManager>::New();
command->SetCallbackFunction( this, &ToolManager::OnOneOfTheRoiDataDeleted );
command->SetCallbackFunction( this, &ToolManager::OnOneOfTheRoiDataDeletedConst );
m_RoiDataObserverTags.insert( std::pair<DataNode*, unsigned long>( (*dataIter), (*dataIter)->AddObserver( itk::DeleteEvent(), command ) ) );
}
RoiDataChanged.Send();
}
}
void mitk::ToolManager::SetRoiData(DataNode* data)
{
DataVectorType v;
if(data)
{
v.push_back(data);
}
this->SetRoiData(v);
}
void mitk::ToolManager::OnOneOfTheRoiDataDeletedConst(const itk::Object* caller, const itk::EventObject& e)
{
OnOneOfTheRoiDataDeleted( const_cast<itk::Object*>(caller), e );
}
void mitk::ToolManager::OnOneOfTheRoiDataDeleted(itk::Object* caller, const itk::EventObject& itkNotUsed(e))
{
//MITK_INFO << "Deleted: " << (void*)caller << " Removing from roi data list." << std::endl;
DataVectorType v;
for (DataVectorType::iterator dataIter = m_RoiData.begin(); dataIter != m_RoiData.end(); ++dataIter )
{
//MITK_INFO << " In list: " << (void*)(*dataIter);
if ( (void*)(*dataIter) != (void*)caller )
{
v.push_back( *dataIter );
//MITK_INFO << " kept" << std::endl;
}
else
{
//MITK_INFO << " removed" << std::endl;
m_RoiDataObserverTags.erase( *dataIter ); // no tag to remove anymore
}
}
this->SetRoiData( v );
}
mitk::ToolManager::DataVectorType mitk::ToolManager::GetReferenceData()
{
return m_ReferenceData;
}
mitk::DataNode* mitk::ToolManager::GetReferenceData(int idx)
{
try
{
return m_ReferenceData.at(idx);
}
catch(std::exception&)
{
return NULL;
}
}
mitk::ToolManager::DataVectorType mitk::ToolManager::GetWorkingData()
{
return m_WorkingData;
}
mitk::ToolManager::DataVectorType mitk::ToolManager::GetRoiData()
{
return m_RoiData;
}
mitk::DataNode* mitk::ToolManager::GetRoiData(int idx)
{
try
{
return m_RoiData.at(idx);
}
catch(std::exception&)
{
return NULL;
}
}
mitk::DataStorage* mitk::ToolManager::GetDataStorage()
{
if ( m_DataStorage.IsNotNull() )
{
return m_DataStorage;
}
else
{
return NULL;
}
}
void mitk::ToolManager::SetDataStorage(DataStorage& storage)
{
m_DataStorage = &storage;
}
mitk::DataNode* mitk::ToolManager::GetWorkingData(int idx)
{
try
{
return m_WorkingData.at(idx);
}
catch(std::exception&)
{
return NULL;
}
}
int mitk::ToolManager::GetActiveToolID()
{
return m_ActiveToolID;
}
mitk::Tool* mitk::ToolManager::GetActiveTool()
{
return m_ActiveTool;
}
void mitk::ToolManager::RegisterClient()
{
if ( m_RegisteredClients < 1 )
{
if ( m_ActiveTool )
{
m_ActiveTool->Activated();
//GlobalInteraction::GetInstance()->AddListener( m_ActiveTool );
m_ActiveToolRegistration = us::GetModuleContext()->RegisterService<InteractionEventObserver>( m_ActiveTool, us::ServiceProperties() );
}
}
++m_RegisteredClients;
}
void mitk::ToolManager::UnregisterClient()
{
if ( m_RegisteredClients < 1) return;
--m_RegisteredClients;
if ( m_RegisteredClients < 1 )
{
if ( m_ActiveTool )
{
m_ActiveTool->Deactivated();
//GlobalInteraction::GetInstance()->RemoveListener( m_ActiveTool );
m_ActiveToolRegistration.Unregister();
}
}
}
int mitk::ToolManager::GetToolID( const Tool* tool )
{
int id(0);
for ( ToolVectorType::iterator iter = m_Tools.begin();
iter != m_Tools.end();
++iter, ++id )
{
if ( tool == iter->GetPointer() )
{
return id;
}
}
return -1;
}
void mitk::ToolManager::OnNodeRemoved(const mitk::DataNode* node)
{
//check if the data of the node is typeof Image
/*if(dynamic_cast<mitk::Image*>(node->GetData()))
{*/
//check all storage vectors
OnOneOfTheReferenceDataDeleted(const_cast<mitk::DataNode*>(node), itk::DeleteEvent());
OnOneOfTheRoiDataDeleted(const_cast<mitk::DataNode*>(node),itk::DeleteEvent());
OnOneOfTheWorkingDataDeleted(const_cast<mitk::DataNode*>(node),itk::DeleteEvent());
//}
}
void mitk::ToolManager::ActivateExclusiveStateEventPolicy(bool state)
{
m_ExclusiveStateEventPolicy = state;
}
diff --git a/Modules/Segmentation/Controllers/mitkToolManager.h b/Modules/Segmentation/Controllers/mitkToolManager.h
index af32dcc110..c9d04a840f 100644
--- a/Modules/Segmentation/Controllers/mitkToolManager.h
+++ b/Modules/Segmentation/Controllers/mitkToolManager.h
@@ -1,309 +1,310 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef mitkToolManager_h_Included
#define mitkToolManager_h_Included
#include "mitkTool.h"
#include <MitkSegmentationExports.h>
#include "mitkDataNode.h"
#include "mitkDataStorage.h"
#include "mitkWeakPointer.h"
#pragma GCC visibility push(default)
#include <itkEventObject.h>
#pragma GCC visibility pop
#include <vector>
#include <map>
#include "usServiceRegistration.h"
+
namespace mitk
{
class Image;
class PlaneGeometry;
/**
\brief Manages and coordinates instances of mitk::Tool.
\sa QmitkToolSelectionBox
\sa QmitkToolReferenceDataSelectionBox
\sa QmitkToolWorkingDataSelectionBox
\sa Tool
\sa QmitkSegmentationView
\ingroup Interaction
\ingroup ToolManagerEtAl
There is a separate page describing the general design of QmitkSegmentationView: \ref QmitkSegmentationTechnicalPage
This class creates and manages several instances of mitk::Tool.
\li ToolManager creates instances of mitk::Tool by asking the itk::ObjectFactory to list all known implementations of mitk::Tool.
As a result, one has to implement both a subclass of mitk::Tool and a matching subclass of itk::ObjectFactoryBase that is registered
to the top-level itk::ObjectFactory. For an example, see mitkContourToolFactory.h. (this limitiation of one-class-one-factory is due
to the implementation of itk::ObjectFactory).
In MITK, the right place to register the factories to itk::ObjectFactory is the mitk::QMCoreObjectFactory or mitk::SBCoreObjectFactory.
\li One (and only one - or none at all) of the registered tools can be activated using ActivateTool. This tool is registered to mitk::GlobalInteraction
as a listener and will receive all mouse clicks and keyboard strokes that get into the MITK event mechanism. Tools are automatically
unregistered from GlobalInteraction when no clients are registered to ToolManager (see RegisterClient()).
\li ToolManager knows a set of "reference" DataNodes and a set of "working" DataNodes. The first application are segmentation tools, where the
reference is the original image and the working data the (kind of) binary segmentation. However, ToolManager is implemented more generally, so that
there could be other tools that work, e.g., with surfaces.
\li Any "user/client" of ToolManager, i.e. every functionality that wants to use a tool, should call RegisterClient when the tools should be active.
ToolManager keeps track of how many clients want it to be used, and when this count reaches zero, it unregistes the active Tool from GlobalInteraction.
In "normal" settings, the functionality does not need to care about that if it uses a QmitkToolSelectionBox, which does exactly that when it is
enabled/disabled.
\li There is a set of events that are sent by ToolManager. At the moment these are TODO update documentation:
- mitk::ToolReferenceDataChangedEvent whenever somebody calls SetReferenceData. Most of the time this actually means that the data has changed, but
there might be cases where the same data is passed to SetReferenceData a second time, so don't rely on the assumption that something actually changed.
- mitk::ToolSelectedEvent is sent when a (truly) different tool was activated. In reaction to this event you can ask for the active Tool using
GetActiveTool or GetActiveToolID (where NULL or -1 indicate that NO tool is active at the moment).
Design descisions:
\li Not a singleton, because there could be two functionalities using tools, each one with different reference/working data.
$Author$
*/
class MitkSegmentation_EXPORT ToolManager : public itk::Object
{
public:
typedef std::vector<Tool::Pointer> ToolVectorType;
typedef std::vector<Tool::ConstPointer> ToolVectorTypeConst;
typedef std::vector<DataNode*> DataVectorType; // has to be observed for delete events!
typedef std::map<DataNode*, unsigned long> NodeTagMapType;
Message<> NodePropertiesChanged;
Message<> NewNodesGenerated;
Message1<DataVectorType*> NewNodeObjectsGenerated;
Message<> ActiveToolChanged;
Message<> ReferenceDataChanged;
Message<> WorkingDataChanged;
Message<> RoiDataChanged;
Message1<std::string> ToolErrorMessage;
Message1<std::string> GeneralToolMessage;
mitkClassMacro(ToolManager, itk::Object);
mitkNewMacro1Param(ToolManager, DataStorage*);
/**
\brief Gives you a list of all tools.
This is const on purpose.
*/
const ToolVectorTypeConst GetTools();
int GetToolID( const Tool* tool );
/*
\param id The tool of interest.
Counting starts with 0.
*/
Tool* GetToolById(int id);
/**
\param id The tool to activate. Provide -1 for disabling any tools.
Counting starts with 0.
Registeres a listner for NodeRemoved event at DataStorage (see mitk::ToolManager::OnNodeRemoved).
*/
bool ActivateTool(int id);
template <class T>
int GetToolIdByToolType()
{
int id = 0;
for ( ToolVectorType::iterator iter = m_Tools.begin();
iter != m_Tools.end();
++iter, ++id )
{
if ( dynamic_cast<T*>(iter->GetPointer()) )
{
return id;
}
}
return -1;
}
/**
\return -1 for "No tool is active"
*/
int GetActiveToolID();
/**
\return NULL for "No tool is active"
*/
Tool* GetActiveTool();
/*
\brief Set a list of data/images as reference objects.
*/
void SetReferenceData(DataVectorType);
/*
\brief Set single data item/image as reference object.
*/
void SetReferenceData(DataNode*);
/*
\brief Set a list of data/images as working objects.
*/
void SetWorkingData(DataVectorType);
/*
\brief Set single data item/image as working object.
*/
void SetWorkingData(DataNode*);
/*
\brief Set a list of data/images as roi objects.
*/
void SetRoiData(DataVectorType);
/*
\brief Set a single data item/image as roi object.
*/
void SetRoiData(DataNode*);
/**
* If set to true the mitk::GlobalInteraction just informs
* the active tool about new mitk::StateEvent but no other
* Interactor or Statemachine
*/
void ActivateExclusiveStateEventPolicy(bool);
/*
\brief Get the list of reference data.
*/
DataVectorType GetReferenceData();
/*
\brief Get the current reference data.
\warning If there is a list of items, this method will only return the first list item.
*/
DataNode* GetReferenceData(int);
/*
\brief Get the list of working data.
*/
DataVectorType GetWorkingData();
/*
\brief Get the current working data.
\warning If there is a list of items, this method will only return the first list item.
*/
DataNode* GetWorkingData(int);
/*
\brief Get the current roi data
*/
DataVectorType GetRoiData();
/*
\brief Get the roi data at position idx
*/
DataNode* GetRoiData(int idx);
DataStorage* GetDataStorage();
void SetDataStorage(DataStorage& storage);
/*
\brief Tell that someone is using tools.
GUI elements should call this when they become active. This method increases an internal "client count". Tools
are only registered to GlobalInteraction when this count is greater than 0. This is useful to automatically deactivate
tools when you hide their GUI elements.
*/
void RegisterClient();
/*
\brief Tell that someone is NOT using tools.
GUI elements should call this when they become active. This method increases an internal "client count". Tools
are only registered to GlobalInteraction when this count is greater than 0. This is useful to automatically deactivate
tools when you hide their GUI elements.
*/
void UnregisterClient();
/** \brief Initialize all classes derived from mitk::Tool by itkObjectFactoy */
void InitializeTools();
void OnOneOfTheReferenceDataDeletedConst(const itk::Object* caller, const itk::EventObject& e);
void OnOneOfTheReferenceDataDeleted (itk::Object* caller, const itk::EventObject& e);
void OnOneOfTheWorkingDataDeletedConst(const itk::Object* caller, const itk::EventObject& e);
void OnOneOfTheWorkingDataDeleted (itk::Object* caller, const itk::EventObject& e);
void OnOneOfTheRoiDataDeletedConst(const itk::Object* caller, const itk::EventObject& e);
void OnOneOfTheRoiDataDeleted (itk::Object* caller, const itk::EventObject& e);
/*
\brief Connected to tool's messages
This method just resends error messages coming from any of the tools. This way clients (GUIs) only have to observe one message.
*/
void OnToolErrorMessage(std::string s);
void OnGeneralToolMessage(std::string s);
protected:
/**
You may specify a list of tool "groups" that should be available for this ToolManager. Every Tool can report its group
as a string. This constructor will try to find the tool's group inside the supplied string. If there is a match,
the tool is accepted. Effectively, you can provide a human readable list like "default, lymphnodevolumetry, oldERISstuff".
*/
ToolManager(DataStorage* storage); // purposely hidden
virtual ~ToolManager();
ToolVectorType m_Tools;
Tool* m_ActiveTool;
int m_ActiveToolID;
us::ServiceRegistration<InteractionEventObserver> m_ActiveToolRegistration;
DataVectorType m_ReferenceData;
NodeTagMapType m_ReferenceDataObserverTags;
DataVectorType m_WorkingData;
NodeTagMapType m_WorkingDataObserverTags;
DataVectorType m_RoiData;
NodeTagMapType m_RoiDataObserverTags;
int m_RegisteredClients;
WeakPointer<DataStorage> m_DataStorage;
bool m_ExclusiveStateEventPolicy;
/// \brief Callback for NodeRemove events
void OnNodeRemoved(const mitk::DataNode* node);
private:
- //std::map<ServiceReference, EventConfig> m_DisplayInteractorConfigs;
+ std::map<us::ServiceReferenceU, EventConfig> m_DisplayInteractorConfigs;
};
} // namespace
#endif
diff --git a/Modules/Segmentation/Interactions/mitkContourTool.cpp b/Modules/Segmentation/Interactions/mitkContourTool.cpp
index 3f40829574..9c7c8841ff 100644
--- a/Modules/Segmentation/Interactions/mitkContourTool.cpp
+++ b/Modules/Segmentation/Interactions/mitkContourTool.cpp
@@ -1,193 +1,181 @@
/*===================================================================
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 "mitkContourTool.h"
#include "mitkToolManager.h"
#include "mitkOverwriteSliceImageFilter.h"
#include "mitkOverwriteDirectedPlaneImageFilter.h"
#include "mitkAbstractTransformGeometry.h"
#include "mitkBaseRenderer.h"
#include "mitkRenderingManager.h"
//#include "mitkProperties.h"
//#include "mitkPlanarCircle.h"
#include "mitkStateMachineAction.h"
#include "mitkInteractionEvent.h"
mitk::ContourTool::ContourTool(int paintingPixelValue)
:FeedbackContourTool("PressMoveReleaseWithCTRLInversion"),
m_PaintingPixelValue(paintingPixelValue)
{
}
mitk::ContourTool::~ContourTool()
{
}
void mitk::ContourTool::ConnectActionsAndFunctions()
{
CONNECT_FUNCTION( "PrimaryButtonPressed", OnMousePressed);
CONNECT_FUNCTION( "Move", OnMouseMoved);
CONNECT_FUNCTION( "Release", OnMouseReleased);
CONNECT_FUNCTION( "InvertLogic", OnInvertLogic);
}
void mitk::ContourTool::Activated()
{
Superclass::Activated();
}
void mitk::ContourTool::Deactivated()
{
Superclass::Deactivated();
}
/**
Just show the contour, insert the first point.
*/
bool mitk::ContourTool::OnMousePressed( StateMachineAction*, InteractionEvent* interactionEvent )
{
- if ( SegTool2D::CanHandleEvent(interactionEvent) < 1.0 )
- return false;
-
mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
- //const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(interactionEvent->GetEvent());
if (!positionEvent) return false;
m_LastEventSender = positionEvent->GetSender();
m_LastEventSlice = m_LastEventSender->GetSlice();
int timestep = positionEvent->GetSender()->GetTimeStep();
ContourModel* contour = FeedbackContourTool::GetFeedbackContour();
//Clear feedback contour
contour->Initialize();
//expand time bounds because our contour was initialized
contour->Expand( timestep + 1 );
//draw as a closed contour
contour->SetClosed(true,timestep);
//add first mouse position
mitk::Point3D point = positionEvent->GetPositionInWorld();
contour->AddVertex( point, timestep );
FeedbackContourTool::SetFeedbackContourVisible(true);
assert( positionEvent->GetSender()->GetRenderWindow() );
mitk::RenderingManager::GetInstance()->RequestUpdate( positionEvent->GetSender()->GetRenderWindow() );
return true;
}
/**
Insert the point to the feedback contour.
*/
bool mitk::ContourTool::OnMouseMoved( StateMachineAction*, InteractionEvent* interactionEvent )
{
- if ( SegTool2D::CanHandleEvent(interactionEvent) < 1.0 )
- return false;
-
mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
- //const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
if (!positionEvent) return false;
int timestep = positionEvent->GetSender()->GetTimeStep();
ContourModel* contour = FeedbackContourTool::GetFeedbackContour();
mitk::Point3D point = positionEvent->GetPositionInWorld();
contour->AddVertex( point, timestep );
assert( positionEvent->GetSender()->GetRenderWindow() );
mitk::RenderingManager::GetInstance()->RequestUpdate( positionEvent->GetSender()->GetRenderWindow() );
return true;
}
/**
Close the contour, project it to the image slice and fill it in 2D.
*/
bool mitk::ContourTool::OnMouseReleased( StateMachineAction*, InteractionEvent* interactionEvent )
{
// 1. Hide the feedback contour, find out which slice the user clicked, find out which slice of the toolmanager's working image corresponds to that
FeedbackContourTool::SetFeedbackContourVisible(false);
mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
//const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
if (!positionEvent) return false;
assert( positionEvent->GetSender()->GetRenderWindow() );
mitk::RenderingManager::GetInstance()->RequestUpdate( positionEvent->GetSender()->GetRenderWindow() );
- //if ( FeedbackContourTool::CanHandleEvent(stateEvent) < 1.0 ) return false;
-
DataNode* workingNode( m_ToolManager->GetWorkingData(0) );
if (!workingNode) return false;
Image* image = dynamic_cast<Image*>(workingNode->GetData());
const PlaneGeometry* planeGeometry( dynamic_cast<const PlaneGeometry*> (positionEvent->GetSender()->GetCurrentWorldPlaneGeometry() ) );
if ( !image || !planeGeometry ) return false;
const AbstractTransformGeometry* abstractTransformGeometry( dynamic_cast<const AbstractTransformGeometry*> (positionEvent->GetSender()->GetCurrentWorldPlaneGeometry() ) );
if ( !image || abstractTransformGeometry ) return false;
// 2. Slice is known, now we try to get it as a 2D image and project the contour into index coordinates of this slice
Image::Pointer slice = SegTool2D::GetAffectedImageSliceAs2DImage( positionEvent, image );
if ( slice.IsNull() )
{
MITK_ERROR << "Unable to extract slice." << std::endl;
return false;
}
ContourModel* feedbackContour = FeedbackContourTool::GetFeedbackContour();
ContourModel::Pointer projectedContour = FeedbackContourTool::ProjectContourTo2DSlice( slice, feedbackContour, true, false ); // true: actually no idea why this is neccessary, but it works :-(
if (projectedContour.IsNull()) return false;
int timestep = positionEvent->GetSender()->GetTimeStep();
FeedbackContourTool::FillContourInSlice( projectedContour, timestep, slice, m_PaintingPixelValue );
this->WriteBackSegmentationResult(positionEvent, slice);
// 4. Make sure the result is drawn again --> is visible then.
assert( positionEvent->GetSender()->GetRenderWindow() );
return true;
}
/**
Called when the CTRL key is pressed. Will change the painting pixel value from 0 to 1 or from 1 to 0.
*/
bool mitk::ContourTool::OnInvertLogic( StateMachineAction*, InteractionEvent* interactionEvent )
{
- // if ( FeedbackContourTool::CanHandleEvent(stateEvent) < 1.0 ) return false;
-
// Inversion only for 0 and 1 as painting values
if (m_PaintingPixelValue == 1)
{
m_PaintingPixelValue = 0;
FeedbackContourTool::SetFeedbackContourColor( 1.0, 0.0, 0.0 );
}
else if (m_PaintingPixelValue == 0)
{
m_PaintingPixelValue = 1;
FeedbackContourTool::SetFeedbackContourColorDefault();
}
return true;
}
diff --git a/Modules/Segmentation/Interactions/mitkCorrectorTool2D.cpp b/Modules/Segmentation/Interactions/mitkCorrectorTool2D.cpp
index 40d13cbeff..8ee2045b22 100644
--- a/Modules/Segmentation/Interactions/mitkCorrectorTool2D.cpp
+++ b/Modules/Segmentation/Interactions/mitkCorrectorTool2D.cpp
@@ -1,204 +1,191 @@
/*===================================================================
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 "mitkCorrectorTool2D.h"
#include "mitkCorrectorAlgorithm.h"
#include "mitkToolManager.h"
#include "mitkBaseRenderer.h"
#include "mitkRenderingManager.h"
#include "mitkImageReadAccessor.h"
#include "mitkAbstractTransformGeometry.h"
#include "mitkCorrectorTool2D.xpm"
// us
#include <usModule.h>
#include <usModuleResource.h>
#include <usGetModuleContext.h>
#include <usModuleContext.h>
namespace mitk {
MITK_TOOL_MACRO(MitkSegmentation_EXPORT, CorrectorTool2D, "Correction tool");
}
mitk::CorrectorTool2D::CorrectorTool2D(int paintingPixelValue)
:FeedbackContourTool("PressMoveRelease"),
m_PaintingPixelValue(paintingPixelValue)
{
GetFeedbackContour()->SetClosed( false ); // don't close the contour to a polygon
}
mitk::CorrectorTool2D::~CorrectorTool2D()
{
}
void mitk::CorrectorTool2D::ConnectActionsAndFunctions()
{
CONNECT_FUNCTION( "PrimaryButtonPressed", OnMousePressed);
CONNECT_FUNCTION( "Move", OnMouseMoved);
CONNECT_FUNCTION( "Release", OnMouseReleased);
}
const char** mitk::CorrectorTool2D::GetXPM() const
{
return mitkCorrectorTool2D_xpm;
}
us::ModuleResource mitk::CorrectorTool2D::GetIconResource() const
{
us::Module* module = us::GetModuleContext()->GetModule();
us::ModuleResource resource = module->GetResource("Correction_48x48.png");
return resource;
}
us::ModuleResource mitk::CorrectorTool2D::GetCursorIconResource() const
{
us::Module* module = us::GetModuleContext()->GetModule();
us::ModuleResource resource = module->GetResource("Correction_Cursor_32x32.png");
return resource;
}
const char* mitk::CorrectorTool2D::GetName() const
{
return "Correction";
}
void mitk::CorrectorTool2D::Activated()
{
Superclass::Activated();
}
void mitk::CorrectorTool2D::Deactivated()
{
Superclass::Deactivated();
}
bool mitk::CorrectorTool2D::OnMousePressed ( StateMachineAction*, InteractionEvent* interactionEvent )
{
- if ( SegTool2D::CanHandleEvent(interactionEvent) < 1.0 )
- return false;
-
mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
- //const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
if (!positionEvent) return false;
m_LastEventSender = positionEvent->GetSender();
m_LastEventSlice = m_LastEventSender->GetSlice();
int timestep = positionEvent->GetSender()->GetTimeStep();
ContourModel* contour = FeedbackContourTool::GetFeedbackContour();
contour->Clear();
contour->Expand(timestep + 1);
contour->SetClosed(false, timestep);
mitk::Point3D point = positionEvent->GetPositionInWorld();
contour->AddVertex( point, timestep );
FeedbackContourTool::SetFeedbackContourVisible(true);
return true;
}
bool mitk::CorrectorTool2D::OnMouseMoved( StateMachineAction*, InteractionEvent* interactionEvent )
{
- if ( SegTool2D::CanHandleEvent(interactionEvent) < 1.0 )
- return false;
-
mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
- //const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
if (!positionEvent) return false;
int timestep = positionEvent->GetSender()->GetTimeStep();
ContourModel* contour = FeedbackContourTool::GetFeedbackContour();
mitk::Point3D point = positionEvent->GetPositionInWorld();
contour->AddVertex( point, timestep );
assert( positionEvent->GetSender()->GetRenderWindow() );
mitk::RenderingManager::GetInstance()->RequestUpdate( positionEvent->GetSender()->GetRenderWindow() );
return true;
}
bool mitk::CorrectorTool2D::OnMouseReleased( StateMachineAction*, InteractionEvent* interactionEvent )
{
- if ( SegTool2D::CanHandleEvent(interactionEvent) < 1.0 )
- return false;
-
// 1. Hide the feedback contour, find out which slice the user clicked, find out which slice of the toolmanager's working image corresponds to that
FeedbackContourTool::SetFeedbackContourVisible(false);
mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
//const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
if (!positionEvent) return false;
assert( positionEvent->GetSender()->GetRenderWindow() );
mitk::RenderingManager::GetInstance()->RequestUpdate( positionEvent->GetSender()->GetRenderWindow() );
- //if ( FeedbackContourTool::CanHandleEvent(stateEvent) < 1.0 ) return false;
-
DataNode* workingNode( m_ToolManager->GetWorkingData(0) );
if (!workingNode) return false;
Image* image = dynamic_cast<Image*>(workingNode->GetData());
const PlaneGeometry* planeGeometry( dynamic_cast<const PlaneGeometry*> (positionEvent->GetSender()->GetCurrentWorldPlaneGeometry() ) );
if ( !image || !planeGeometry ) return false;
const AbstractTransformGeometry* abstractTransformGeometry( dynamic_cast<const AbstractTransformGeometry*> (positionEvent->GetSender()->GetCurrentWorldPlaneGeometry() ) );
if ( !image || abstractTransformGeometry ) return false;
// 2. Slice is known, now we try to get it as a 2D image and project the contour into index coordinates of this slice
m_WorkingSlice = FeedbackContourTool::GetAffectedImageSliceAs2DImage( positionEvent, image );
if ( m_WorkingSlice.IsNull() )
{
MITK_ERROR << "Unable to extract slice." << std::endl;
return false;
}
int timestep = positionEvent->GetSender()->GetTimeStep();
mitk::ContourModel::Pointer singleTimestepContour = mitk::ContourModel::New();
mitk::ContourModel::VertexIterator it = FeedbackContourTool::GetFeedbackContour()->Begin(timestep);
mitk::ContourModel::VertexIterator end = FeedbackContourTool::GetFeedbackContour()->End(timestep);
while(it!=end)
{
singleTimestepContour->AddVertex((*it)->Coordinates);
it++;
}
CorrectorAlgorithm::Pointer algorithm = CorrectorAlgorithm::New();
algorithm->SetInput( m_WorkingSlice );
algorithm->SetContour( singleTimestepContour );
try
{
algorithm->UpdateLargestPossibleRegion();
}
catch ( std::exception& e )
{
MITK_ERROR << "Caught exception '" << e.what() << "'" << std::endl;
}
mitk::Image::Pointer resultSlice = mitk::Image::New();
resultSlice->Initialize(algorithm->GetOutput());
mitk::ImageReadAccessor imAccess(algorithm->GetOutput());
resultSlice->SetVolume(imAccess.GetData());
this->WriteBackSegmentationResult(positionEvent, resultSlice);
return true;
}
diff --git a/Modules/Segmentation/Interactions/mitkFastMarchingTool.cpp b/Modules/Segmentation/Interactions/mitkFastMarchingTool.cpp
index 0f3bfadf59..79ebce5649 100644
--- a/Modules/Segmentation/Interactions/mitkFastMarchingTool.cpp
+++ b/Modules/Segmentation/Interactions/mitkFastMarchingTool.cpp
@@ -1,484 +1,481 @@
/*===================================================================
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 "mitkFastMarchingTool.h"
#include "mitkToolManager.h"
#include "mitkBaseRenderer.h"
#include "mitkRenderingManager.h"
#include "mitkInteractionConst.h"
#include "itkOrImageFilter.h"
#include "mitkImageTimeSelector.h"
// us
#include <usModule.h>
#include <usModuleResource.h>
#include <usGetModuleContext.h>
#include <usModuleContext.h>
namespace mitk {
MITK_TOOL_MACRO(MitkSegmentation_EXPORT, FastMarchingTool, "FastMarching2D tool");
}
mitk::FastMarchingTool::FastMarchingTool()
:FeedbackContourTool("PressMoveReleaseAndPointSetting"),
m_NeedUpdate(true),
m_CurrentTimeStep(0),
m_LowerThreshold(0),
m_UpperThreshold(200),
m_StoppingValue(100),
m_Sigma(1.0),
m_Alpha(-0.5),
m_Beta(3.0),
m_PositionEvent(0)
{
}
mitk::FastMarchingTool::~FastMarchingTool()
{
if (this->m_SmoothFilter.IsNotNull())
this->m_SmoothFilter->RemoveAllObservers();
if (this->m_SigmoidFilter.IsNotNull())
this->m_SigmoidFilter->RemoveAllObservers();
if (this->m_GradientMagnitudeFilter.IsNotNull())
this->m_GradientMagnitudeFilter->RemoveAllObservers();
if (this->m_FastMarchingFilter.IsNotNull())
this->m_FastMarchingFilter->RemoveAllObservers();
}
void mitk::FastMarchingTool::ConnectActionsAndFunctions()
{
CONNECT_FUNCTION( "ShiftSecondaryButtonPressed", OnAddPoint);
CONNECT_FUNCTION( "ShiftPrimaryButtonPressed", OnAddPoint);
CONNECT_FUNCTION( "DeletePoint", OnDelete);
}
// float mitk::FastMarchingTool::CanHandleEvent( StateEvent const *stateEvent) const
// {
// float returnValue = Superclass::CanHandleEvent(stateEvent);
//
// //we can handle delete
// if(stateEvent->GetId() == 12 )
// {
// returnValue = 1.0;
// }
//
// return returnValue;
// }
const char** mitk::FastMarchingTool::GetXPM() const
{
return NULL;//mitkFastMarchingTool_xpm;
}
us::ModuleResource mitk::FastMarchingTool::GetIconResource() const
{
us::Module* module = us::GetModuleContext()->GetModule();
us::ModuleResource resource = module->GetResource("FastMarching_48x48.png");
return resource;
}
us::ModuleResource mitk::FastMarchingTool::GetCursorIconResource() const
{
us::Module* module = us::GetModuleContext()->GetModule();
us::ModuleResource resource = module->GetResource("FastMarching_Cursor_32x32.png");
return resource;
}
const char* mitk::FastMarchingTool::GetName() const
{
return "2D Fast Marching";
}
void mitk::FastMarchingTool::BuildITKPipeline()
{
m_ReferenceImageSliceAsITK = InternalImageType::New();
m_ReferenceImageSlice = GetAffectedReferenceSlice( m_PositionEvent );
CastToItkImage(m_ReferenceImageSlice, m_ReferenceImageSliceAsITK);
m_ProgressCommand = mitk::ToolCommand::New();
m_SmoothFilter = SmoothingFilterType::New();
m_SmoothFilter->SetInput( m_ReferenceImageSliceAsITK );
m_SmoothFilter->SetTimeStep( 0.05 );
m_SmoothFilter->SetNumberOfIterations( 2 );
m_SmoothFilter->SetConductanceParameter( 9.0 );
m_GradientMagnitudeFilter = GradientFilterType::New();
m_GradientMagnitudeFilter->SetSigma( m_Sigma );
m_SigmoidFilter = SigmoidFilterType::New();
m_SigmoidFilter->SetAlpha( m_Alpha );
m_SigmoidFilter->SetBeta( m_Beta );
m_SigmoidFilter->SetOutputMinimum( 0.0 );
m_SigmoidFilter->SetOutputMaximum( 1.0 );
m_FastMarchingFilter = FastMarchingFilterType::New();
m_FastMarchingFilter->SetStoppingValue( m_StoppingValue );
m_ThresholdFilter = ThresholdingFilterType::New();
m_ThresholdFilter->SetLowerThreshold( m_LowerThreshold );
m_ThresholdFilter->SetUpperThreshold( m_UpperThreshold );
m_ThresholdFilter->SetOutsideValue( 0 );
m_ThresholdFilter->SetInsideValue( 1.0 );
m_SeedContainer = NodeContainer::New();
m_SeedContainer->Initialize();
m_FastMarchingFilter->SetTrialPoints( m_SeedContainer );
if (this->m_SmoothFilter.IsNotNull())
this->m_SmoothFilter->RemoveAllObservers();
if (this->m_SigmoidFilter.IsNotNull())
this->m_SigmoidFilter->RemoveAllObservers();
if (this->m_GradientMagnitudeFilter.IsNotNull())
this->m_GradientMagnitudeFilter->RemoveAllObservers();
if (this->m_FastMarchingFilter.IsNotNull())
this->m_FastMarchingFilter->RemoveAllObservers();
m_SmoothFilter->AddObserver( itk::ProgressEvent(), m_ProgressCommand);
m_GradientMagnitudeFilter->AddObserver( itk::ProgressEvent(), m_ProgressCommand);
m_SigmoidFilter->AddObserver( itk::ProgressEvent(), m_ProgressCommand);
m_FastMarchingFilter->AddObserver( itk::ProgressEvent(), m_ProgressCommand);
m_SmoothFilter->SetInput( m_ReferenceImageSliceAsITK );
m_GradientMagnitudeFilter->SetInput( m_SmoothFilter->GetOutput() );
m_SigmoidFilter->SetInput( m_GradientMagnitudeFilter->GetOutput() );
m_FastMarchingFilter->SetInput( m_SigmoidFilter->GetOutput() );
m_ThresholdFilter->SetInput( m_FastMarchingFilter->GetOutput() );
m_ReferenceImageSliceAsITK = InternalImageType::New();
}
void mitk::FastMarchingTool::SetUpperThreshold(double value)
{
if (m_UpperThreshold != value)
{
m_UpperThreshold = value / 10.0;
m_ThresholdFilter->SetUpperThreshold( m_UpperThreshold );
m_NeedUpdate = true;
}
}
void mitk::FastMarchingTool::SetLowerThreshold(double value)
{
if (m_LowerThreshold != value)
{
m_LowerThreshold = value / 10.0;
m_ThresholdFilter->SetLowerThreshold( m_LowerThreshold );
m_NeedUpdate = true;
}
}
void mitk::FastMarchingTool::SetBeta(double value)
{
if (m_Beta != value)
{
m_Beta = value;
m_SigmoidFilter->SetBeta( m_Beta );
m_NeedUpdate = true;
}
}
void mitk::FastMarchingTool::SetSigma(double value)
{
if (m_Sigma != value)
{
m_Sigma = value;
m_GradientMagnitudeFilter->SetSigma( m_Sigma );
m_NeedUpdate = true;
}
}
void mitk::FastMarchingTool::SetAlpha(double value)
{
if (m_Alpha != value)
{
m_Alpha = value;
m_SigmoidFilter->SetAlpha( m_Alpha );
m_NeedUpdate = true;
}
}
void mitk::FastMarchingTool::SetStoppingValue(double value)
{
if (m_StoppingValue != value)
{
m_StoppingValue = value;
m_FastMarchingFilter->SetStoppingValue( m_StoppingValue );
m_NeedUpdate = true;
}
}
void mitk::FastMarchingTool::Activated()
{
Superclass::Activated();
m_ResultImageNode = mitk::DataNode::New();
m_ResultImageNode->SetName("FastMarching_Preview");
m_ResultImageNode->SetBoolProperty("helper object", true);
m_ResultImageNode->SetColor(0.0, 1.0, 0.0);
m_ResultImageNode->SetVisibility(true);
m_ToolManager->GetDataStorage()->Add( this->m_ResultImageNode, m_ToolManager->GetReferenceData(0));
m_SeedsAsPointSet = mitk::PointSet::New();
m_SeedsAsPointSetNode = mitk::DataNode::New();
m_SeedsAsPointSetNode->SetData(m_SeedsAsPointSet);
m_SeedsAsPointSetNode->SetName("Seeds_Preview");
m_SeedsAsPointSetNode->SetBoolProperty("helper object", true);
m_SeedsAsPointSetNode->SetColor(0.0, 1.0, 0.0);
m_SeedsAsPointSetNode->SetVisibility(true);
m_ToolManager->GetDataStorage()->Add( this->m_SeedsAsPointSetNode, m_ToolManager->GetReferenceData(0));
this->Initialize();
}
void mitk::FastMarchingTool::Deactivated()
{
Superclass::Deactivated();
m_ToolManager->GetDataStorage()->Remove( this->m_ResultImageNode );
m_ToolManager->GetDataStorage()->Remove( this->m_SeedsAsPointSetNode );
this->ClearSeeds();
m_ResultImageNode = NULL;
m_SeedsAsPointSetNode = NULL;
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void mitk::FastMarchingTool::Initialize()
{
m_ReferenceImage = dynamic_cast<mitk::Image*>(m_ToolManager->GetReferenceData(0)->GetData());
if(m_ReferenceImage->GetTimeGeometry()->CountTimeSteps() > 1)
{
mitk::ImageTimeSelector::Pointer timeSelector = ImageTimeSelector::New();
timeSelector->SetInput( m_ReferenceImage );
timeSelector->SetTimeNr( m_CurrentTimeStep );
timeSelector->UpdateLargestPossibleRegion();
m_ReferenceImage = timeSelector->GetOutput();
}
m_NeedUpdate = true;
}
void mitk::FastMarchingTool::ConfirmSegmentation()
{
// combine preview image with current working segmentation
if (dynamic_cast<mitk::Image*>(m_ResultImageNode->GetData()))
{
//logical or combination of preview and segmentation slice
OutputImageType::Pointer workingImageSliceInITK = OutputImageType::New();
mitk::Image::Pointer workingImageSlice;
mitk::Image::Pointer workingImage = dynamic_cast<mitk::Image*>(this->m_ToolManager->GetWorkingData(0)->GetData());
workingImageSlice = GetAffectedImageSliceAs2DImage(m_WorkingPlane, workingImage, m_CurrentTimeStep);
CastToItkImage( workingImageSlice, workingImageSliceInITK );
typedef itk::OrImageFilter<OutputImageType, OutputImageType> OrImageFilterType;
OrImageFilterType::Pointer orFilter = OrImageFilterType::New();
orFilter->SetInput(0, m_ThresholdFilter->GetOutput());
orFilter->SetInput(1, workingImageSliceInITK);
orFilter->Update();
mitk::Image::Pointer segmentationResult = mitk::Image::New();
mitk::CastToMitkImage(orFilter->GetOutput(), segmentationResult);
segmentationResult->GetGeometry()->SetOrigin(workingImageSlice->GetGeometry()->GetOrigin());
segmentationResult->GetGeometry()->SetIndexToWorldTransform(workingImageSlice->GetGeometry()->GetIndexToWorldTransform());
//write to segmentation volume and hide preview image
// again, current time step is not considered
this->WriteBackSegmentationResult(m_WorkingPlane, segmentationResult, m_CurrentTimeStep);
this->m_ResultImageNode->SetVisibility(false);
this->ClearSeeds();
}
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
m_ToolManager->ActivateTool(-1);
}
bool mitk::FastMarchingTool::OnAddPoint( StateMachineAction*, InteractionEvent* interactionEvent )
{
- if ( SegTool2D::CanHandleEvent(interactionEvent) < 1.0 )
- return false;
-
// Add a new seed point for FastMarching algorithm
mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
//const PositionEvent* p = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
if ( positionEvent == NULL ) return false;
if ( m_PositionEvent.IsNotNull() )
m_PositionEvent = NULL;
m_PositionEvent = InteractionPositionEvent::New( positionEvent->GetSender(),
positionEvent->GetPointerPositionOnScreen(),
positionEvent->GetPositionInWorld() );
//if click was on another renderwindow or slice then reset pipeline and preview
if( (m_LastEventSender != m_PositionEvent->GetSender()) || (m_LastEventSlice != m_PositionEvent->GetSender()->GetSlice()) )
{
this->BuildITKPipeline();
this->ClearSeeds();
}
m_LastEventSender = m_PositionEvent->GetSender();
m_LastEventSlice = m_LastEventSender->GetSlice();
m_WorkingPlane = positionEvent->GetSender()->GetCurrentWorldPlaneGeometry()->Clone();
mitk::Point3D clickInIndex;
m_ReferenceImageSlice->GetGeometry()->WorldToIndex(m_PositionEvent->GetPositionInWorld(), clickInIndex);
itk::Index<2> seedPosition;
seedPosition[0] = clickInIndex[0];
seedPosition[1] = clickInIndex[1];
NodeType node;
const double seedValue = 0.0;
node.SetValue( seedValue );
node.SetIndex( seedPosition );
this->m_SeedContainer->InsertElement(this->m_SeedContainer->Size(), node);
m_FastMarchingFilter->Modified();
m_SeedsAsPointSet->InsertPoint(m_SeedsAsPointSet->GetSize(), m_PositionEvent->GetPositionInWorld());
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
m_NeedUpdate = true;
this->Update();
m_ReadyMessage.Send();
return true;
}
bool mitk::FastMarchingTool::OnDelete( StateMachineAction*, InteractionEvent* interactionEvent )
{
// delete last seed point
if(!(this->m_SeedContainer->empty()))
{
//delete last element of seeds container
this->m_SeedContainer->pop_back();
m_FastMarchingFilter->Modified();
//delete last point in pointset - somehow ugly
m_SeedsAsPointSet->GetPointSet()->GetPoints()->DeleteIndex(m_SeedsAsPointSet->GetSize() - 1);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
m_NeedUpdate = true;
this->Update();
}
return true;
}
void mitk::FastMarchingTool::Update()
{
const unsigned int progress_steps = 20;
// update FastMarching pipeline and show result
if (m_NeedUpdate)
{
m_ProgressCommand->AddStepsToDo(progress_steps);
CurrentlyBusy.Send(true);
try
{
m_ThresholdFilter->Update();
}
catch( itk::ExceptionObject & excep )
{
MITK_ERROR << "Exception caught: " << excep.GetDescription();
// progress by max step count, will force
m_ProgressCommand->SetProgress(progress_steps);
CurrentlyBusy.Send(false);
std::string msg = excep.GetDescription();
ErrorMessage.Send(msg);
return;
}
m_ProgressCommand->SetProgress(progress_steps);
CurrentlyBusy.Send(false);
//make output visible
mitk::Image::Pointer result = mitk::Image::New();
CastToMitkImage( m_ThresholdFilter->GetOutput(), result);
result->GetGeometry()->SetOrigin(m_ReferenceImageSlice->GetGeometry()->GetOrigin() );
result->GetGeometry()->SetIndexToWorldTransform(m_ReferenceImageSlice->GetGeometry()->GetIndexToWorldTransform() );
m_ResultImageNode->SetData(result);
m_ResultImageNode->SetVisibility(true);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void mitk::FastMarchingTool::ClearSeeds()
{
// clear seeds for FastMarching as well as the PointSet for visualization
if(this->m_SeedContainer.IsNotNull())
this->m_SeedContainer->Initialize();
if(this->m_SeedsAsPointSet.IsNotNull())
{
this->m_SeedsAsPointSet = mitk::PointSet::New();
this->m_SeedsAsPointSetNode->SetData(this->m_SeedsAsPointSet);
m_SeedsAsPointSetNode->SetName("Seeds_Preview");
m_SeedsAsPointSetNode->SetBoolProperty("helper object", true);
m_SeedsAsPointSetNode->SetColor(0.0, 1.0, 0.0);
m_SeedsAsPointSetNode->SetVisibility(true);
}
if(this->m_FastMarchingFilter.IsNotNull())
m_FastMarchingFilter->Modified();
this->m_NeedUpdate = true;
}
void mitk::FastMarchingTool::Reset()
{
//clear all seeds and preview empty result
this->ClearSeeds();
m_ResultImageNode->SetVisibility(false);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void mitk::FastMarchingTool::SetCurrentTimeStep(int t)
{
if( m_CurrentTimeStep != t )
{
m_CurrentTimeStep = t;
this->Initialize();
}
-}
\ No newline at end of file
+}
diff --git a/Modules/Segmentation/Interactions/mitkLiveWireTool2D.cpp b/Modules/Segmentation/Interactions/mitkLiveWireTool2D.cpp
index 823fb28fe6..2821f08945 100644
--- a/Modules/Segmentation/Interactions/mitkLiveWireTool2D.cpp
+++ b/Modules/Segmentation/Interactions/mitkLiveWireTool2D.cpp
@@ -1,710 +1,680 @@
/*===================================================================
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 <itkGradientMagnitudeImageFilter.h>
#include <mitkBaseRenderer.h>
#include <mitkContour.h>
#include <mitkContourModelUtils.h>
#include <mitkContourUtils.h>
#include <mitkGlobalInteraction.h>
#include <mitkInteractionConst.h>
#include <mitkRenderingManager.h>
#include <mitkToolManager.h>
#include <usGetModuleContext.h>
#include <usModule.h>
#include <usModuleContext.h>
#include <usModuleResource.h>
#include "mitkLiveWireTool2D.h"
#include "mitkLiveWireTool2D.xpm"
namespace mitk
{
MITK_TOOL_MACRO(MitkSegmentation_EXPORT, LiveWireTool2D, "LiveWire tool");
}
static void AddInteractorToGlobalInteraction(mitk::Interactor* interactor)
{
mitk::GlobalInteraction::GetInstance()->AddInteractor(interactor);
}
static void RemoveInteractorFromGlobalInteraction(mitk::Interactor* interactor)
{
mitk::GlobalInteraction::GetInstance()->RemoveInteractor(interactor);
}
class RemoveFromDataStorage
{
public:
RemoveFromDataStorage(mitk::DataStorage::Pointer dataStorage)
: m_DataStorage(dataStorage)
{
}
void operator()(mitk::DataNode* dataNode)
{
m_DataStorage->Remove(dataNode);
}
void operator()(const std::pair<mitk::DataNode::Pointer, mitk::PlaneGeometry::Pointer>& dataNode)
{
m_DataStorage->Remove(dataNode.first);
}
private:
mitk::DataStorage::Pointer m_DataStorage;
};
mitk::LiveWireTool2D::LiveWireTool2D()
: SegTool2D("LiveWireTool"), m_PlaneGeometry(NULL)
{
}
mitk::LiveWireTool2D::~LiveWireTool2D()
{
this->ClearSegmentation();
}
void mitk::LiveWireTool2D::RemoveHelperObjects()
{
DataStorage* dataStorage = m_ToolManager->GetDataStorage();
if (!m_EditingContours.empty())
std::for_each(m_EditingContours.begin(), m_EditingContours.end(), RemoveFromDataStorage(dataStorage));
if (!m_WorkingContours.empty())
std::for_each(m_WorkingContours.begin(), m_WorkingContours.end(), RemoveFromDataStorage(dataStorage));
if (m_EditingContourNode.IsNotNull())
dataStorage->Remove(m_EditingContourNode);
if (m_LiveWireContourNode.IsNotNull())
dataStorage->Remove(m_LiveWireContourNode);
if (m_ContourModelNode.IsNotNull())
dataStorage->Remove(m_ContourModelNode);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void mitk::LiveWireTool2D::ReleaseHelperObjects()
{
this->RemoveHelperObjects();
if (!m_EditingContours.empty())
m_EditingContours.clear();
if (!m_WorkingContours.empty())
m_WorkingContours.clear();
m_EditingContourNode = NULL;
m_EditingContour = NULL;
m_LiveWireContourNode = NULL;
m_LiveWireContour = NULL;
m_ContourModelNode = NULL;
m_Contour = NULL;
}
void mitk::LiveWireTool2D::ReleaseInteractors()
{
this->EnableContourLiveWireInteraction(false);
m_LiveWireInteractors.clear();
}
void mitk::LiveWireTool2D::ConnectActionsAndFunctions()
{
CONNECT_CONDITION("CheckContourClosed", OnCheckPoint);
CONNECT_FUNCTION("InitObject", OnInitLiveWire);
CONNECT_FUNCTION("AddPoint", OnAddPoint);
CONNECT_FUNCTION("CtrlAddPoint", OnAddPoint);
CONNECT_FUNCTION("MovePoint", OnMouseMoveNoDynamicCosts);
CONNECT_FUNCTION("FinishContour", OnFinish);
CONNECT_FUNCTION("DeletePoint", OnLastSegmentDelete);
CONNECT_FUNCTION("CtrlMovePoint", OnMouseMoved);
}
const char** mitk::LiveWireTool2D::GetXPM() const
{
return mitkLiveWireTool2D_xpm;
}
us::ModuleResource mitk::LiveWireTool2D::GetIconResource() const
{
return us::GetModuleContext()->GetModule()->GetResource("LiveWire_48x48.png");
}
us::ModuleResource mitk::LiveWireTool2D::GetCursorIconResource() const
{
return us::GetModuleContext()->GetModule()->GetResource("LiveWire_Cursor_32x32.png");
}
const char* mitk::LiveWireTool2D::GetName() const
{
return "Live Wire";
}
void mitk::LiveWireTool2D::Activated()
{
Superclass::Activated();
this->ResetToStartState();
this->EnableContourLiveWireInteraction(true);
}
void mitk::LiveWireTool2D::Deactivated()
{
Superclass::Deactivated();
this->ConfirmSegmentation();
}
void mitk::LiveWireTool2D::EnableContourLiveWireInteraction(bool on)
{
std::for_each(m_LiveWireInteractors.begin(), m_LiveWireInteractors.end(), on
? AddInteractorToGlobalInteraction
: RemoveInteractorFromGlobalInteraction);
}
void mitk::LiveWireTool2D::ConfirmSegmentation()
{
DataNode* workingNode( m_ToolManager->GetWorkingData(0) );
if (!workingNode)
return;
Image* workingImage = dynamic_cast<Image*>(workingNode->GetData());
if (!workingImage)
return;
// for all contours in list (currently created by tool)
std::vector< std::pair<mitk::DataNode::Pointer, mitk::PlaneGeometry::Pointer> >::iterator itWorkingContours = this->m_WorkingContours.begin();
std::vector<SliceInformation> sliceList;
sliceList.reserve(m_WorkingContours.size());
while(itWorkingContours != this->m_WorkingContours.end() )
{
// if node contains data
if( itWorkingContours->first->GetData() )
{
// if this is a contourModel
mitk::ContourModel* contourModel = dynamic_cast<mitk::ContourModel*>(itWorkingContours->first->GetData());
if( contourModel )
{
// for each timestep of this contourModel
for( TimeStepType currentTimestep = 0; currentTimestep < contourModel->GetTimeGeometry()->CountTimeSteps(); ++currentTimestep)
{
//get the segmentation image slice at current timestep
mitk::Image::Pointer workingSlice = this->GetAffectedImageSliceAs2DImage(itWorkingContours->second, workingImage, currentTimestep);
mitk::ContourModel::Pointer projectedContour = mitk::ContourModelUtils::ProjectContourTo2DSlice(workingSlice, contourModel, true, false);
mitk::ContourModelUtils::FillContourInSlice(projectedContour, workingSlice, 1.0);
//write back to image volume
SliceInformation sliceInfo (workingSlice, itWorkingContours->second, currentTimestep);
sliceList.push_back(sliceInfo);
+ this->WriteSliceToVolume(sliceInfo);
}
}
}
-
++itWorkingContours;
}
- this->WriteBackSegmentationResult(sliceList);
+ this->WriteBackSegmentationResult(sliceList, false);
this->ClearSegmentation();
}
void mitk::LiveWireTool2D::ClearSegmentation()
{
this->ReleaseHelperObjects();
this->ReleaseInteractors();
this->ResetToStartState();
}
bool mitk::LiveWireTool2D::OnInitLiveWire ( StateMachineAction*, InteractionEvent* interactionEvent )
{
- if ( SegTool2D::CanHandleEvent(interactionEvent) < 1.0 )
- return false;
-
mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
- if (!mitk::SegTool2D::CanHandleEvent(interactionEvent))
- return false;
-
if (!positionEvent) return false;
m_LastEventSender = positionEvent->GetSender();
m_LastEventSlice = m_LastEventSender->GetSlice();
int timestep = positionEvent->GetSender()->GetTimeStep();
m_Contour = mitk::ContourModel::New();
m_Contour->Expand(timestep+1);
m_ContourModelNode = mitk::DataNode::New();
m_ContourModelNode->SetData( m_Contour );
m_ContourModelNode->SetName("working contour node");
m_ContourModelNode->SetProperty( "layer", IntProperty::New(100));
m_ContourModelNode->AddProperty( "fixedLayer", BoolProperty::New(true));
m_ContourModelNode->SetProperty( "helper object", mitk::BoolProperty::New(true));
m_ContourModelNode->AddProperty( "contour.color", ColorProperty::New(1, 1, 0), NULL, true );
m_ContourModelNode->AddProperty( "contour.points.color", ColorProperty::New(1.0, 0.0, 0.1), NULL, true );
m_ContourModelNode->AddProperty( "contour.controlpoints.show", BoolProperty::New(true), NULL, true );
m_LiveWireContour = mitk::ContourModel::New();
m_LiveWireContour->Expand(timestep+1);
m_LiveWireContourNode = mitk::DataNode::New();
m_LiveWireContourNode->SetData( m_LiveWireContour );
m_LiveWireContourNode->SetName("active livewire node");
m_LiveWireContourNode->SetProperty( "layer", IntProperty::New(101));
m_LiveWireContourNode->AddProperty( "fixedLayer", BoolProperty::New(true));
m_LiveWireContourNode->SetProperty( "helper object", mitk::BoolProperty::New(true));
m_LiveWireContourNode->AddProperty( "contour.color", ColorProperty::New(0.1, 1.0, 0.1), NULL, true );
m_LiveWireContourNode->AddProperty( "contour.width", mitk::FloatProperty::New( 4.0 ), NULL, true );
m_EditingContour = mitk::ContourModel::New();
m_EditingContour->Expand(timestep+1);
m_EditingContourNode = mitk::DataNode::New();
m_EditingContourNode->SetData( m_EditingContour );
m_EditingContourNode->SetName("editing node");
m_EditingContourNode->SetProperty( "layer", IntProperty::New(102));
m_EditingContourNode->AddProperty( "fixedLayer", BoolProperty::New(true));
m_EditingContourNode->SetProperty( "helper object", mitk::BoolProperty::New(true));
m_EditingContourNode->AddProperty( "contour.color", ColorProperty::New(0.1, 1.0, 0.1), NULL, true );
m_EditingContourNode->AddProperty( "contour.points.color", ColorProperty::New(0.0, 0.0, 1.0), NULL, true );
m_EditingContourNode->AddProperty( "contour.width", mitk::FloatProperty::New( 4.0 ), NULL, true );
mitk::DataNode* workingDataNode = m_ToolManager->GetWorkingData(0);
m_ToolManager->GetDataStorage()->Add(m_ContourModelNode, workingDataNode);
m_ToolManager->GetDataStorage()->Add(m_LiveWireContourNode, workingDataNode);
m_ToolManager->GetDataStorage()->Add(m_EditingContourNode, workingDataNode);
//set current slice as input for ImageToLiveWireContourFilter
m_WorkingSlice = this->GetAffectedReferenceSlice(positionEvent);
//Transfer LiveWire's center based contour output to corner based via the adaption of the input
//slice image. Just in case someone stumbles across the 0.5 here I know what I'm doing ;-).
mitk::Point3D newOrigin = m_WorkingSlice->GetSlicedGeometry()->GetOrigin();
m_WorkingSlice->GetSlicedGeometry()->WorldToIndex(newOrigin, newOrigin);
newOrigin[0] -= 0.5;
newOrigin[1] -= 0.5;
m_WorkingSlice->GetSlicedGeometry()->IndexToWorld(newOrigin, newOrigin);
m_WorkingSlice->GetSlicedGeometry()->SetOrigin(newOrigin);
m_LiveWireFilter = mitk::ImageLiveWireContourModelFilter::New();
m_LiveWireFilter->SetInput(m_WorkingSlice);
//map click to pixel coordinates
mitk::Point3D click = positionEvent->GetPositionInWorld();
itk::Index<3> idx;
m_WorkingSlice->GetGeometry()->WorldToIndex(click, idx);
// get the pixel the gradient in region of 5x5
itk::Index<3> indexWithHighestGradient;
AccessFixedDimensionByItk_2(m_WorkingSlice, FindHighestGradientMagnitudeByITK, 2, idx, indexWithHighestGradient);
// itk::Index to mitk::Point3D
click[0] = indexWithHighestGradient[0];
click[1] = indexWithHighestGradient[1];
click[2] = indexWithHighestGradient[2];
m_WorkingSlice->GetGeometry()->IndexToWorld(click, click);
//set initial start point
m_Contour->AddVertex( click, true, timestep );
m_LiveWireFilter->SetStartPoint(click);
// remember plane geometry to determine if events were triggered in same plane
m_PlaneGeometry = interactionEvent->GetSender()->GetCurrentWorldPlaneGeometry();
m_CreateAndUseDynamicCosts = true;
//render
assert( positionEvent->GetSender()->GetRenderWindow() );
mitk::RenderingManager::GetInstance()->RequestUpdate( positionEvent->GetSender()->GetRenderWindow() );
return true;
}
bool mitk::LiveWireTool2D::OnAddPoint ( StateMachineAction*, InteractionEvent* interactionEvent )
{
- if ( SegTool2D::CanHandleEvent(interactionEvent) < 1.0 )
- return false;
-
//complete LiveWire interaction for last segment
//add current LiveWire contour to the finished contour and reset
//to start new segment and computation
- /* check if event can be handled */
- if (!mitk::SegTool2D::CanHandleEvent(interactionEvent))
- return false;
-
mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
if (!positionEvent) return false;
if (m_PlaneGeometry != NULL)
{
// this checks that the point is in the correct slice
if (m_PlaneGeometry->DistanceFromPlane(positionEvent->GetPositionInWorld()) > mitk::eps)
return false;
- // this also covers the cases where points are outside of the images bounding box
- if (!m_PlaneGeometry->IsInside(positionEvent->GetPositionInWorld()))
- return false;
}
int timestep = positionEvent->GetSender()->GetTimeStep();
//add repulsive points to avoid to get the same path again
typedef mitk::ImageLiveWireContourModelFilter::InternalImageType::IndexType IndexType;
mitk::ContourModel::ConstVertexIterator iter = m_LiveWireContour->IteratorBegin(timestep);
for (;iter != m_LiveWireContour->IteratorEnd(timestep); iter++)
{
IndexType idx;
this->m_WorkingSlice->GetGeometry()->WorldToIndex((*iter)->Coordinates, idx);
this->m_LiveWireFilter->AddRepulsivePoint( idx );
}
//remove duplicate first vertex, it's already contained in m_Contour
m_LiveWireContour->RemoveVertexAt(0, timestep);
// set last added point as control point
m_LiveWireContour->SetControlVertexAt(m_LiveWireContour->GetNumberOfVertices(timestep)-1, timestep);
//merge contours
m_Contour->Concatenate(m_LiveWireContour, timestep);
//clear the livewire contour and reset the corresponding datanode
m_LiveWireContour->Clear(timestep);
//set new start point
m_LiveWireFilter->SetStartPoint(positionEvent->GetPositionInWorld());
if( m_CreateAndUseDynamicCosts )
{
//use dynamic cost map for next update
m_LiveWireFilter->CreateDynamicCostMap(m_Contour);
m_LiveWireFilter->SetUseDynamicCostMap(true);
//m_CreateAndUseDynamicCosts = false;
}
//render
assert( positionEvent->GetSender()->GetRenderWindow() );
mitk::RenderingManager::GetInstance()->RequestUpdate( positionEvent->GetSender()->GetRenderWindow() );
return true;
}
bool mitk::LiveWireTool2D::OnMouseMoved( StateMachineAction*, InteractionEvent* interactionEvent )
{
- if ( SegTool2D::CanHandleEvent(interactionEvent) < 1.0 )
- return false;
-
//compute LiveWire segment from last control point to current mouse position
- if (!mitk::SegTool2D::CanHandleEvent(interactionEvent))
- return false;
mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
if (!positionEvent) return false;
// actual LiveWire computation
int timestep = positionEvent->GetSender()->GetTimeStep();
m_LiveWireFilter->SetEndPoint(positionEvent->GetPositionInWorld());
m_LiveWireFilter->SetTimeStep( timestep );
m_LiveWireFilter->Update();
m_LiveWireContour = this->m_LiveWireFilter->GetOutput();
m_LiveWireContourNode->SetData( this->m_LiveWireContour );
//render
assert( positionEvent->GetSender()->GetRenderWindow() );
positionEvent->GetSender()->GetRenderingManager()->RequestUpdate( positionEvent->GetSender()->GetRenderWindow() );
return true;
}
bool mitk::LiveWireTool2D::OnMouseMoveNoDynamicCosts( StateMachineAction*, InteractionEvent* interactionEvent )
{
//do not use dynamic cost map
m_LiveWireFilter->SetUseDynamicCostMap(false);
OnMouseMoved( NULL, interactionEvent);
m_LiveWireFilter->SetUseDynamicCostMap(true);
return true;
}
bool mitk::LiveWireTool2D::OnCheckPoint( const InteractionEvent* interactionEvent)
{
//check double click on first control point to finish the LiveWire tool
//
//Check distance to first point.
//Transition YES if click close to first control point
//
- if (!mitk::SegTool2D::CanHandleEvent(interactionEvent))
- return false;
-
const mitk::InteractionPositionEvent* positionEvent = dynamic_cast<const mitk::InteractionPositionEvent*>( interactionEvent );
if (positionEvent)
{
int timestep = positionEvent->GetSender()->GetTimeStep();
mitk::Point3D click = positionEvent->GetPositionInWorld();
mitk::Point3D first = this->m_Contour->GetVertexAt(0, timestep)->Coordinates;
if (first.EuclideanDistanceTo(click) < 4.5)
{
// allow to finish
return true;
}
else
{
return false;
}
}
return false;
}
bool mitk::LiveWireTool2D::OnFinish( StateMachineAction*, InteractionEvent* interactionEvent )
{
- if ( SegTool2D::CanHandleEvent(interactionEvent) < 1.0 )
- return false;
-
// finish livewire tool interaction
- if (!mitk::SegTool2D::CanHandleEvent(interactionEvent))
- return false;
-
mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
if (!positionEvent) return false;
// Have to do that here so that the m_LastEventSender is set correctly
mitk::SegTool2D::AddContourmarker();
// actual timestep
int timestep = positionEvent->GetSender()->GetTimeStep();
// remove last control point being added by double click
m_Contour->RemoveVertexAt(m_Contour->GetNumberOfVertices(timestep) - 1, timestep);
// save contour and corresponding plane geometry to list
std::pair<mitk::DataNode::Pointer, mitk::PlaneGeometry::Pointer> cp(m_ContourModelNode, dynamic_cast<mitk::PlaneGeometry*>(positionEvent->GetSender()->GetCurrentWorldPlaneGeometry()->Clone().GetPointer()) );
this->m_WorkingContours.push_back(cp);
std::pair<mitk::DataNode::Pointer, mitk::PlaneGeometry::Pointer> ecp(m_EditingContourNode, dynamic_cast<mitk::PlaneGeometry*>(positionEvent->GetSender()->GetCurrentWorldPlaneGeometry()->Clone().GetPointer()) );
this->m_EditingContours.push_back(ecp);
m_LiveWireFilter->SetUseDynamicCostMap(false);
this->FinishTool();
return true;
}
void mitk::LiveWireTool2D::FinishTool()
{
TimeStepType numberOfTimesteps = m_Contour->GetTimeGeometry()->CountTimeSteps();
//close contour in each timestep
for( int i = 0; i <= numberOfTimesteps; i++)
{
m_Contour->Close(i);
}
m_ToolManager->GetDataStorage()->Remove( m_LiveWireContourNode );
// clear live wire contour node
m_LiveWireContourNode = NULL;
m_LiveWireContour = NULL;
//set the livewire interactor to edit control points
m_ContourInteractor = mitk::ContourModelLiveWireInteractor::New(m_ContourModelNode);
m_ContourInteractor->SetWorkingImage(this->m_WorkingSlice);
m_ContourInteractor->SetEditingContourModelNode(this->m_EditingContourNode);
m_ContourModelNode->SetInteractor(m_ContourInteractor);
this->m_LiveWireInteractors.push_back( m_ContourInteractor );
//add interactor to globalInteraction instance
mitk::GlobalInteraction::GetInstance()->AddInteractor(m_ContourInteractor);
}
bool mitk::LiveWireTool2D::OnLastSegmentDelete( StateMachineAction*, InteractionEvent* interactionEvent )
{
int timestep = interactionEvent->GetSender()->GetTimeStep();
//if last point of current contour will be removed go to start state and remove nodes
if( m_Contour->GetNumberOfVertices(timestep) <= 1 )
{
m_ToolManager->GetDataStorage()->Remove( m_LiveWireContourNode );
m_ToolManager->GetDataStorage()->Remove( m_ContourModelNode );
m_ToolManager->GetDataStorage()->Remove( m_EditingContourNode );
m_LiveWireContour = mitk::ContourModel::New();
m_Contour = mitk::ContourModel::New();
m_ContourModelNode->SetData( m_Contour );
m_LiveWireContourNode->SetData( m_LiveWireContour );
this->ResetToStartState(); //go to start state
}
else //remove last segment from contour and reset livewire contour
{
m_LiveWireContour = mitk::ContourModel::New();
m_LiveWireContourNode->SetData(m_LiveWireContour);
mitk::ContourModel::Pointer newContour = mitk::ContourModel::New();
newContour->Expand(m_Contour->GetTimeSteps());
mitk::ContourModel::VertexIterator begin = m_Contour->IteratorBegin();
//iterate from last point to next active point
mitk::ContourModel::VertexIterator newLast = m_Contour->IteratorBegin() + (m_Contour->GetNumberOfVertices() - 1);
//go at least one down
if(newLast != begin)
{
newLast--;
}
//search next active control point
while(newLast != begin && !((*newLast)->IsControlPoint) )
{
newLast--;
}
//set position of start point for livewire filter to coordinates of the new last point
m_LiveWireFilter->SetStartPoint((*newLast)->Coordinates);
mitk::ContourModel::VertexIterator it = m_Contour->IteratorBegin();
//fill new Contour
while(it <= newLast)
{
newContour->AddVertex((*it)->Coordinates, (*it)->IsControlPoint, timestep);
it++;
}
newContour->SetClosed(m_Contour->IsClosed());
//set new contour visible
m_ContourModelNode->SetData(newContour);
m_Contour = newContour;
assert( interactionEvent->GetSender()->GetRenderWindow() );
mitk::RenderingManager::GetInstance()->RequestUpdate( interactionEvent->GetSender()->GetRenderWindow() );
}
return true;
}
template<typename TPixel, unsigned int VImageDimension>
void mitk::LiveWireTool2D::FindHighestGradientMagnitudeByITK(itk::Image<TPixel, VImageDimension>* inputImage, itk::Index<3> &index, itk::Index<3> &returnIndex)
{
typedef itk::Image<TPixel, VImageDimension> InputImageType;
typedef typename InputImageType::IndexType IndexType;
unsigned long xMAX = inputImage->GetLargestPossibleRegion().GetSize()[0];
unsigned long yMAX = inputImage->GetLargestPossibleRegion().GetSize()[1];
returnIndex[0] = index[0];
returnIndex[1] = index[1];
returnIndex[2] = 0.0;
double gradientMagnitude = 0.0;
double maxGradientMagnitude = 0.0;
/*
the size and thus the region of 7x7 is only used to calculate the gradient magnitude in that region
not for searching the maximum value
*/
//maximum value in each direction for size
typename InputImageType::SizeType size;
size[0] = 7;
size[1] = 7;
//minimum value in each direction for startRegion
IndexType startRegion;
startRegion[0] = index[0] - 3;
startRegion[1] = index[1] - 3;
if(startRegion[0] < 0) startRegion[0] = 0;
if(startRegion[1] < 0) startRegion[1] = 0;
if(xMAX - index[0] < 7) startRegion[0] = xMAX - 7;
if(yMAX - index[1] < 7) startRegion[1] = yMAX - 7;
index[0] = startRegion[0] + 3;
index[1] = startRegion[1] + 3;
typename InputImageType::RegionType region;
region.SetSize( size );
region.SetIndex( startRegion );
typedef typename itk::GradientMagnitudeImageFilter< InputImageType, InputImageType> GradientMagnitudeFilterType;
typename GradientMagnitudeFilterType::Pointer gradientFilter = GradientMagnitudeFilterType::New();
gradientFilter->SetInput(inputImage);
gradientFilter->GetOutput()->SetRequestedRegion(region);
gradientFilter->Update();
typename InputImageType::Pointer gradientMagnImage;
gradientMagnImage = gradientFilter->GetOutput();
IndexType currentIndex;
currentIndex[0] = 0;
currentIndex[1] = 0;
// search max (approximate) gradient magnitude
for( int x = -1; x <= 1; ++x)
{
currentIndex[0] = index[0] + x;
for( int y = -1; y <= 1; ++y)
{
currentIndex[1] = index[1] + y;
gradientMagnitude = gradientMagnImage->GetPixel(currentIndex);
//check for new max
if(maxGradientMagnitude < gradientMagnitude)
{
maxGradientMagnitude = gradientMagnitude;
returnIndex[0] = currentIndex[0];
returnIndex[1] = currentIndex[1];
returnIndex[2] = 0.0;
}//end if
}//end for y
currentIndex[1] = index[1];
}//end for x
}
diff --git a/Modules/Segmentation/Interactions/mitkPaintbrushTool.cpp b/Modules/Segmentation/Interactions/mitkPaintbrushTool.cpp
index b8346091b2..e8c21346b5 100644
--- a/Modules/Segmentation/Interactions/mitkPaintbrushTool.cpp
+++ b/Modules/Segmentation/Interactions/mitkPaintbrushTool.cpp
@@ -1,528 +1,519 @@
/*===================================================================
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 "mitkPaintbrushTool.h"
#include "mitkToolManager.h"
#include "mitkOverwriteSliceImageFilter.h"
#include "mitkBaseRenderer.h"
#include "mitkImageDataItem.h"
#include "ipSegmentation.h"
#include "mitkAbstractTransformGeometry.h"
#include "mitkLevelWindowProperty.h"
#define ROUND(a) ((a)>0 ? (int)((a)+0.5) : -(int)(0.5-(a)))
int mitk::PaintbrushTool::m_Size = 1;
mitk::PaintbrushTool::PaintbrushTool(int paintingPixelValue)
:FeedbackContourTool("PressMoveReleaseWithCTRLInversionAllMouseMoves"),
m_PaintingPixelValue(paintingPixelValue),
m_LastContourSize(0) // other than initial mitk::PaintbrushTool::m_Size (around l. 28)
{
m_MasterContour = ContourModel::New();
m_MasterContour->Initialize();
m_CurrentPlane = NULL;
m_WorkingNode = DataNode::New();
m_WorkingNode->SetProperty( "levelwindow", mitk::LevelWindowProperty::New( mitk::LevelWindow(0, 1) ) );
m_WorkingNode->SetProperty( "binary", mitk::BoolProperty::New(true) );
}
mitk::PaintbrushTool::~PaintbrushTool()
{
}
void mitk::PaintbrushTool::ConnectActionsAndFunctions()
{
CONNECT_FUNCTION( "PrimaryButtonPressed", OnMousePressed);
CONNECT_FUNCTION( "Move", OnPrimaryButtonPressedMoved);
CONNECT_FUNCTION( "MouseMove", OnMouseMoved);
CONNECT_FUNCTION( "Release", OnMouseReleased);
CONNECT_FUNCTION( "InvertLogic", OnInvertLogic);
}
void mitk::PaintbrushTool::Activated()
{
Superclass::Activated();
FeedbackContourTool::SetFeedbackContourVisible(true);
SizeChanged.Send(m_Size);
m_ToolManager->WorkingDataChanged += mitk::MessageDelegate<mitk::PaintbrushTool>( this, &mitk::PaintbrushTool::OnToolManagerWorkingDataModified );
}
void mitk::PaintbrushTool::Deactivated()
{
FeedbackContourTool::SetFeedbackContourVisible(false);
if (m_ToolManager->GetDataStorage()->Exists(m_WorkingNode))
m_ToolManager->GetDataStorage()->Remove(m_WorkingNode);
Superclass::Deactivated();
m_WorkingSlice = NULL;
m_CurrentPlane = NULL;
m_ToolManager->WorkingDataChanged -= mitk::MessageDelegate<mitk::PaintbrushTool>( this, &mitk::PaintbrushTool::OnToolManagerWorkingDataModified );
}
void mitk::PaintbrushTool::SetSize(int value)
{
m_Size = value;
}
mitk::Point2D mitk::PaintbrushTool::upperLeft(mitk::Point2D p)
{
p[0] -= 0.5;
p[1] += 0.5;
return p;
}
void mitk::PaintbrushTool::UpdateContour(const InteractionPositionEvent* positionEvent)
{
//MITK_INFO<<"Update...";
// examine stateEvent and create a contour that matches the pixel mask that we are going to draw
//mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
//const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
if (!positionEvent) return;
// Get Spacing of current Slice
//mitk::Vector3D vSpacing = m_WorkingSlice->GetSlicedGeometry()->GetPlaneGeometry(0)->GetSpacing();
//
// Draw a contour in Square according to selected brush size
//
int radius = (m_Size)/2;
float fradius = static_cast<float>(m_Size) / 2.0f;
ContourModel::Pointer contourInImageIndexCoordinates = ContourModel::New();
// estimate center point of the brush ( relative to the pixel the mouse points on )
// -- left upper corner for even sizes,
// -- midpoint for uneven sizes
mitk::Point2D centerCorrection;
centerCorrection.Fill(0);
// even --> correction of [+0.5, +0.5]
bool evenSize = ((m_Size % 2) == 0);
if( evenSize )
{
centerCorrection[0] += 0.5;
centerCorrection[1] += 0.5;
}
// we will compute the control points for the upper left quarter part of a circle contour
std::vector< mitk::Point2D > quarterCycleUpperRight;
std::vector< mitk::Point2D > quarterCycleLowerRight;
std::vector< mitk::Point2D > quarterCycleLowerLeft;
std::vector< mitk::Point2D > quarterCycleUpperLeft;
mitk::Point2D curPoint;
bool curPointIsInside = true;
curPoint[0] = 0;
curPoint[1] = radius;
quarterCycleUpperRight.push_back( upperLeft(curPoint) );
// to estimate if a pixel is inside the circle, we need to compare against the 'outer radius'
// i.e. the distance from the midpoint [0,0] to the border of the pixel [0,radius]
//const float outer_radius = static_cast<float>(radius) + 0.5;
while (curPoint[1] > 0)
{
// Move right until pixel is outside circle
float curPointX_squared = 0.0f;
float curPointY_squared = (curPoint[1] - centerCorrection[1] ) * (curPoint[1] - centerCorrection[1] );
while( curPointIsInside )
{
// increment posX and chec
curPoint[0]++;
curPointX_squared = (curPoint[0] - centerCorrection[0] ) * (curPoint[0] - centerCorrection[0] );
const float len = sqrt( curPointX_squared + curPointY_squared);
if ( len > fradius )
{
// found first Pixel in this horizontal line, that is outside the circle
curPointIsInside = false;
}
}
quarterCycleUpperRight.push_back( upperLeft(curPoint) );
// Move down until pixel is inside circle
while( !curPointIsInside )
{
// increment posX and chec
curPoint[1]--;
curPointY_squared = (curPoint[1] - centerCorrection[1] ) * (curPoint[1] - centerCorrection[1] );
const float len = sqrt( curPointX_squared + curPointY_squared);
if ( len <= fradius )
{
// found first Pixel in this horizontal line, that is outside the circle
curPointIsInside = true;
quarterCycleUpperRight.push_back( upperLeft(curPoint) );
}
// Quarter cycle is full, when curPoint y position is 0
if (curPoint[1] <= 0)
break;
}
}
// QuarterCycle is full! Now copy quarter cycle to other quarters.
if( !evenSize )
{
std::vector< mitk::Point2D >::const_iterator it = quarterCycleUpperRight.begin();
while( it != quarterCycleUpperRight.end() )
{
mitk::Point2D p;
p = *it;
// the contour points in the lower right corner have same position but with negative y values
p[1] *= -1;
quarterCycleLowerRight.push_back(p);
// the contour points in the lower left corner have same position
// but with both x,y negative
p[0] *= -1;
quarterCycleLowerLeft.push_back(p);
// the contour points in the upper left corner have same position
// but with x negative
p[1] *= -1;
quarterCycleUpperLeft.push_back(p);
it++;
}
}
else
{
std::vector< mitk::Point2D >::const_iterator it = quarterCycleUpperRight.begin();
while( it != quarterCycleUpperRight.end() )
{
mitk::Point2D p,q;
p = *it;
q = p;
// the contour points in the lower right corner have same position but with negative y values
q[1] *= -1;
// correct for moved offset if size even = the midpoint is not the midpoint of the current pixel
// but its upper rigt corner
q[1] += 1;
quarterCycleLowerRight.push_back(q);
q = p;
// the contour points in the lower left corner have same position
// but with both x,y negative
q[1] = -1.0f * q[1] + 1;
q[0] = -1.0f * q[0] + 1;
quarterCycleLowerLeft.push_back(q);
// the contour points in the upper left corner have same position
// but with x negative
q = p;
q[0] *= -1;
q[0] += 1;
quarterCycleUpperLeft.push_back(q);
it++;
}
}
// fill contour with poins in right ordering, starting with the upperRight block
mitk::Point3D tempPoint;
for (unsigned int i=0; i<quarterCycleUpperRight.size(); i++)
{
tempPoint[0] = quarterCycleUpperRight[i][0];
tempPoint[1] = quarterCycleUpperRight[i][1];
tempPoint[2] = 0;
contourInImageIndexCoordinates->AddVertex( tempPoint );
}
// the lower right has to be parsed in reverse order
for (int i=quarterCycleLowerRight.size()-1; i>=0; i--)
{
tempPoint[0] = quarterCycleLowerRight[i][0];
tempPoint[1] = quarterCycleLowerRight[i][1];
tempPoint[2] = 0;
contourInImageIndexCoordinates->AddVertex( tempPoint );
}
for (unsigned int i=0; i<quarterCycleLowerLeft.size(); i++)
{
tempPoint[0] = quarterCycleLowerLeft[i][0];
tempPoint[1] = quarterCycleLowerLeft[i][1];
tempPoint[2] = 0;
contourInImageIndexCoordinates->AddVertex( tempPoint );
}
// the upper left also has to be parsed in reverse order
for (int i=quarterCycleUpperLeft.size()-1; i>=0; i--)
{
tempPoint[0] = quarterCycleUpperLeft[i][0];
tempPoint[1] = quarterCycleUpperLeft[i][1];
tempPoint[2] = 0;
contourInImageIndexCoordinates->AddVertex( tempPoint );
}
m_MasterContour = contourInImageIndexCoordinates;
}
/**
Just show the contour, get one point as the central point and add surrounding points to the contour.
*/
bool mitk::PaintbrushTool::OnMousePressed ( StateMachineAction*, InteractionEvent* interactionEvent )
{
- if ( SegTool2D::CanHandleEvent(interactionEvent) < 1.0 )
- return false;
-
mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
//const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
if (!positionEvent) return false;
m_LastEventSender = positionEvent->GetSender();
m_LastEventSlice = m_LastEventSender->GetSlice();
m_MasterContour->SetClosed(true);
return this->MouseMoved(interactionEvent, true);
}
bool mitk::PaintbrushTool::OnMouseMoved( StateMachineAction*, InteractionEvent* interactionEvent )
{
return MouseMoved(interactionEvent, false);
}
bool mitk::PaintbrushTool::OnPrimaryButtonPressedMoved( StateMachineAction*, InteractionEvent* interactionEvent )
{
return MouseMoved(interactionEvent, true);
}
/**
Insert the point to the feedback contour,finish to build the contour and at the same time the painting function
*/
bool mitk::PaintbrushTool::MouseMoved(mitk::InteractionEvent* interactionEvent, bool leftMouseButtonPressed)
{
- if ( SegTool2D::CanHandleEvent(interactionEvent) < 1.0 )
- return false;
-
mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
//const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
CheckIfCurrentSliceHasChanged( positionEvent );
if ( m_LastContourSize != m_Size )
{
UpdateContour( positionEvent );
m_LastContourSize = m_Size;
}
// stateEvent->GetId() == 530
// || stateEvent->GetId() == 534
// || stateEvent->GetId() == 1
// || stateEvent->GetId() == 5
// );
Point3D worldCoordinates = positionEvent->GetPositionInWorld();
Point3D indexCoordinates;
m_WorkingSlice->GetGeometry()->WorldToIndex( worldCoordinates, indexCoordinates );
MITK_DEBUG << "Mouse at W " << worldCoordinates << std::endl;
MITK_DEBUG << "Mouse at I " << indexCoordinates << std::endl;
// round to nearest voxel center (abort if this hasn't changed)
if ( m_Size % 2 == 0 ) // even
{
indexCoordinates[0] = ROUND( indexCoordinates[0]);// /*+ 0.5*/) + 0.5;
indexCoordinates[1] = ROUND( indexCoordinates[1]);// /*+ 0.5*/ ) + 0.5;
}
else // odd
{
indexCoordinates[0] = ROUND( indexCoordinates[0] ) ;
indexCoordinates[1] = ROUND( indexCoordinates[1] ) ;
}
static Point3D lastPos; // uninitialized: if somebody finds out how this can be initialized in a one-liner, tell me
if ( fabs(indexCoordinates[0] - lastPos[0]) > mitk::eps ||
fabs(indexCoordinates[1] - lastPos[1]) > mitk::eps ||
fabs(indexCoordinates[2] - lastPos[2]) > mitk::eps ||
leftMouseButtonPressed
)
{
lastPos = indexCoordinates;
}
else
{
MITK_DEBUG << "." << std::flush;
return false;
}
MITK_DEBUG << "Mouse at C " << indexCoordinates;
int timestep = positionEvent->GetSender()->GetTimeStep();
ContourModel::Pointer contour = ContourModel::New();
contour->Expand(timestep + 1);
contour->SetClosed(true, timestep);
ContourModel::VertexIterator it = m_MasterContour->Begin();
ContourModel::VertexIterator end = m_MasterContour->End();
while(it != end)
{
Point3D point = (*it)->Coordinates;
point[0] += indexCoordinates[ 0 ];
point[1] += indexCoordinates[ 1 ];
contour->AddVertex( point, timestep );
it++;
}
if (leftMouseButtonPressed)
{
FeedbackContourTool::FillContourInSlice( contour, timestep, m_WorkingSlice, m_PaintingPixelValue );
m_WorkingNode->SetData(m_WorkingSlice);
m_WorkingNode->Modified();
}
// visualize contour
ContourModel::Pointer displayContour = ContourModel::New();
displayContour->Initialize();
//for (unsigned int index = 0; index < contour->GetNumberOfPoints(); ++index)
//{
// Point3D point = contour->GetPoints()->ElementAt(index);
// if ( m_Size % 2 == 0 ) // even
// {
// point[0] += 0.5;
// point[1] += 0.5;
// }
// displayContour->AddVertex( point );
//}
displayContour = FeedbackContourTool::BackProjectContourFrom2DSlice( m_WorkingSlice->GetGeometry(), /*displayContour*/contour );
SetFeedbackContour( *displayContour );
assert( positionEvent->GetSender()->GetRenderWindow() );
RenderingManager::GetInstance()->RequestUpdate( positionEvent->GetSender()->GetRenderWindow() );
return true;
}
bool mitk::PaintbrushTool::OnMouseReleased( StateMachineAction*, InteractionEvent* interactionEvent )
{
- if ( SegTool2D::CanHandleEvent(interactionEvent) < 1.0 )
- return false;
-
- //When mouse is released write segmentationresult back into image
+ //When mouse is released write segmentationresult back into image
mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
//const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
if (!positionEvent) return false;
this->WriteBackSegmentationResult(positionEvent, m_WorkingSlice->Clone());
return true;
}
/**
Called when the CTRL key is pressed. Will change the painting pixel value from 0 to 1 or from 1 to 0.
*/
bool mitk::PaintbrushTool::OnInvertLogic( StateMachineAction*, InteractionEvent* interactionEvent )
{
// Inversion only for 0 and 1 as painting values
if (m_PaintingPixelValue == 1)
{
m_PaintingPixelValue = 0;
FeedbackContourTool::SetFeedbackContourColor( 1.0, 0.0, 0.0 );
}
else if (m_PaintingPixelValue == 0)
{
m_PaintingPixelValue = 1;
FeedbackContourTool::SetFeedbackContourColorDefault();
}
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
return true;
}
void mitk::PaintbrushTool::CheckIfCurrentSliceHasChanged(const InteractionPositionEvent *event)
{
const PlaneGeometry* planeGeometry( dynamic_cast<const PlaneGeometry*> (event->GetSender()->GetCurrentWorldPlaneGeometry() ) );
const AbstractTransformGeometry* abstractTransformGeometry( dynamic_cast<const AbstractTransformGeometry*> (event->GetSender()->GetCurrentWorldPlaneGeometry() ) );
DataNode* workingNode( m_ToolManager->GetWorkingData(0) );
if (!workingNode)
return;
Image::Pointer image = dynamic_cast<Image*>(workingNode->GetData());
if ( !image || !planeGeometry || abstractTransformGeometry )
return;
if(m_CurrentPlane.IsNull() || m_WorkingSlice.IsNull())
{
m_CurrentPlane = const_cast<PlaneGeometry*>(planeGeometry);
m_WorkingSlice = SegTool2D::GetAffectedImageSliceAs2DImage(event, image)->Clone();
m_WorkingNode->ReplaceProperty( "color", workingNode->GetProperty("color") );
m_WorkingNode->SetData(m_WorkingSlice);
}
else
{
bool isSameSlice (false);
isSameSlice = mitk::MatrixEqualElementWise(planeGeometry->GetIndexToWorldTransform()->GetMatrix(),m_CurrentPlane->GetIndexToWorldTransform()->GetMatrix());
isSameSlice = mitk::Equal(planeGeometry->GetIndexToWorldTransform()->GetOffset(),m_CurrentPlane->GetIndexToWorldTransform()->GetOffset());
if (!isSameSlice)
{
m_ToolManager->GetDataStorage()->Remove(m_WorkingNode);
m_CurrentPlane = NULL;
m_WorkingSlice = NULL;
m_WorkingNode = NULL;
m_CurrentPlane = const_cast<PlaneGeometry*>(planeGeometry);
m_WorkingSlice = SegTool2D::GetAffectedImageSliceAs2DImage(event, image)->Clone();
m_WorkingNode = mitk::DataNode::New();
m_WorkingNode->SetProperty( "levelwindow", mitk::LevelWindowProperty::New( mitk::LevelWindow(0, 1) ) );
m_WorkingNode->SetProperty( "binary", mitk::BoolProperty::New(true) );
m_WorkingNode->SetData(m_WorkingSlice);
//So that the paintbrush contour vanished in the previous render window
RenderingManager::GetInstance()->RequestUpdateAll();
}
}
if(!m_ToolManager->GetDataStorage()->Exists(m_WorkingNode))
{
m_WorkingNode->SetProperty( "outline binary", mitk::BoolProperty::New(true) );
m_WorkingNode->SetProperty( "color", workingNode->GetProperty("color") );
m_WorkingNode->SetProperty( "name", mitk::StringProperty::New("Paintbrush_Node") );
m_WorkingNode->SetProperty( "helper object", mitk::BoolProperty::New(true) );
m_WorkingNode->SetProperty( "opacity", mitk::FloatProperty::New(0.8) );
m_WorkingNode->SetProperty( "includeInBoundingBox", mitk::BoolProperty::New(false));
m_WorkingNode->SetVisibility(false, mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget4")));
m_ToolManager->GetDataStorage()->Add(m_WorkingNode);
}
}
void mitk::PaintbrushTool::OnToolManagerWorkingDataModified()
{
//Here we simply set the current working slice to null. The next time the mouse is moved
//within a renderwindow a new slice will be extracted from the new working data
m_WorkingSlice = 0;
}
diff --git a/Modules/Segmentation/Interactions/mitkRegionGrowingTool.cpp b/Modules/Segmentation/Interactions/mitkRegionGrowingTool.cpp
index 18f9d35b54..218cd161c4 100644
--- a/Modules/Segmentation/Interactions/mitkRegionGrowingTool.cpp
+++ b/Modules/Segmentation/Interactions/mitkRegionGrowingTool.cpp
@@ -1,708 +1,691 @@
/*===================================================================
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 "mitkRegionGrowingTool.h"
#include "mitkToolManager.h"
#include "mitkOverwriteSliceImageFilter.h"
#include "mitkImageDataItem.h"
#include "mitkBaseRenderer.h"
#include "mitkRenderingManager.h"
#include "mitkApplicationCursor.h"
#include "ipSegmentation.h"
#include "mitkRegionGrowingTool.xpm"
#include "mitkOverwriteDirectedPlaneImageFilter.h"
#include "mitkExtractDirectedPlaneImageFilterNew.h"
// us
#include <usModule.h>
#include <usModuleResource.h>
#include <usGetModuleContext.h>
#include <usModuleContext.h>
namespace mitk {
MITK_TOOL_MACRO(MitkSegmentation_EXPORT, RegionGrowingTool, "Region growing tool");
}
#define ROUND(a) ((a)>0 ? (int)((a)+0.5) : -(int)(0.5-(a)))
mitk::RegionGrowingTool::RegionGrowingTool()
:FeedbackContourTool("PressMoveRelease"),
m_LowerThreshold(200),
m_UpperThreshold(200),
m_InitialLowerThreshold(200),
m_InitialUpperThreshold(200),
m_ScreenYDifference(0),
m_OriginalPicSlice(NULL),
m_SeedPointMemoryOffset(0),
m_VisibleWindow(0),
m_DefaultWindow(0),
m_MouseDistanceScaleFactor(-0.5),
m_LastWorkingSeed(-1),
m_FillFeedbackContour(true)
{
}
mitk::RegionGrowingTool::~RegionGrowingTool()
{
}
void mitk::RegionGrowingTool::ConnectActionsAndFunctions()
{
CONNECT_FUNCTION( "PrimaryButtonPressed", OnMousePressed);
CONNECT_FUNCTION( "Move", OnMouseMoved);
CONNECT_FUNCTION( "Release", OnMouseReleased);
}
const char** mitk::RegionGrowingTool::GetXPM() const
{
return mitkRegionGrowingTool_xpm;
}
us::ModuleResource mitk::RegionGrowingTool::GetIconResource() const
{
us::Module* module = us::GetModuleContext()->GetModule();
us::ModuleResource resource = module->GetResource("RegionGrowing_48x48.png");
return resource;
}
us::ModuleResource mitk::RegionGrowingTool::GetCursorIconResource() const
{
us::Module* module = us::GetModuleContext()->GetModule();
us::ModuleResource resource = module->GetResource("RegionGrowing_Cursor_32x32.png");
return resource;
}
const char* mitk::RegionGrowingTool::GetName() const
{
return "Region Growing";
}
void mitk::RegionGrowingTool::Activated()
{
Superclass::Activated();
}
void mitk::RegionGrowingTool::Deactivated()
{
Superclass::Deactivated();
}
/**
1 Determine which slice is clicked into
2 Determine if the user clicked inside or outside of the segmentation
3 Depending on the pixel value under the mouse click position, two different things happen: (separated out into OnMousePressedInside and OnMousePressedOutside)
3.1 Create a skeletonization of the segmentation and try to find a nice cut
3.1.1 Call a ipSegmentation algorithm to create a nice cut
3.1.2 Set the result of this algorithm as the feedback contour
3.2 Initialize region growing
3.2.1 Determine memory offset inside the original image
3.2.2 Determine initial region growing parameters from the level window settings of the image
3.2.3 Perform a region growing (which generates a new feedback contour)
*/
bool mitk::RegionGrowingTool::OnMousePressed ( StateMachineAction*, InteractionEvent* interactionEvent )
{
- if ( SegTool2D::CanHandleEvent(interactionEvent) < 1.0 )
- return false;
-
mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
//const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
if (!positionEvent) return false;
m_LastEventSender = positionEvent->GetSender();
m_LastEventSlice = m_LastEventSender->GetSlice();
//ToolLogger::SetVerboseness(3);
MITK_DEBUG << "OnMousePressed" << std::endl;
- if ( FeedbackContourTool::CanHandleEvent(interactionEvent) > 0.0 )
+
+ MITK_DEBUG << "OnMousePressed: FeedbackContourTool says ok" << std::endl;
+
+ // 1. Find out which slice the user clicked, find out which slice of the toolmanager's reference and working image corresponds to that
+ if (positionEvent)
{
- MITK_DEBUG << "OnMousePressed: FeedbackContourTool says ok" << std::endl;
+ MITK_DEBUG << "OnMousePressed: got positionEvent" << std::endl;
- // 1. Find out which slice the user clicked, find out which slice of the toolmanager's reference and working image corresponds to that
- if (positionEvent)
+ m_ReferenceSlice = FeedbackContourTool::GetAffectedReferenceSlice( positionEvent );
+ m_WorkingSlice = FeedbackContourTool::GetAffectedWorkingSlice( positionEvent );
+
+ if ( m_WorkingSlice.IsNotNull() ) // can't do anything without the segmentation
{
- MITK_DEBUG << "OnMousePressed: got positionEvent" << std::endl;
+ MITK_DEBUG << "OnMousePressed: got working slice" << std::endl;
- m_ReferenceSlice = FeedbackContourTool::GetAffectedReferenceSlice( positionEvent );
- m_WorkingSlice = FeedbackContourTool::GetAffectedWorkingSlice( positionEvent );
+ // 2. Determine if the user clicked inside or outside of the segmentation
+ const BaseGeometry* workingSliceGeometry = m_WorkingSlice->GetGeometry();
+ Point3D mprojectedPointIn2D;
+ workingSliceGeometry->WorldToIndex( positionEvent->GetPositionInWorld(), mprojectedPointIn2D);
+ itk::Index<2> projectedPointInWorkingSlice2D;
+ projectedPointInWorkingSlice2D[0] = static_cast<int>( mprojectedPointIn2D[0] - 0.5 );
+ projectedPointInWorkingSlice2D[1] = static_cast<int>( mprojectedPointIn2D[1] - 0.5 );
- if ( m_WorkingSlice.IsNotNull() ) // can't do anything without the segmentation
+ if ( workingSliceGeometry->IsIndexInside( projectedPointInWorkingSlice2D ) )
{
- MITK_DEBUG << "OnMousePressed: got working slice" << std::endl;
+ MITK_DEBUG << "OnMousePressed: point " << positionEvent->GetPositionInWorld() << " (index coordinates " << projectedPointInWorkingSlice2D << ") IS in working slice" << std::endl;
+
+ // Convert to ipMITKSegmentationTYPE (because getting pixels relys on that data type)
+ itk::Image< ipMITKSegmentationTYPE, 2 >::Pointer correctPixelTypeImage;
+ CastToItkImage( m_WorkingSlice, correctPixelTypeImage );
+ assert (correctPixelTypeImage.IsNotNull() );
+
+ // possible bug in CastToItkImage ?
+ // direction maxtrix is wrong/broken/not working after CastToItkImage, leading to a failed assertion in
+ // mitk/Core/DataStructures/mitkSlicedGeometry3D.cpp, 479:
+ // virtual void mitk::SlicedGeometry3D::SetSpacing(const mitk::Vector3D&): Assertion `aSpacing[0]>0 && aSpacing[1]>0 && aSpacing[2]>0' failed
+ // solution here: we overwrite it with an unity matrix
+ itk::Image< ipMITKSegmentationTYPE, 2 >::DirectionType imageDirection;
+ imageDirection.SetIdentity();
+ correctPixelTypeImage->SetDirection(imageDirection);
+
+ Image::Pointer temporarySlice = Image::New();
+ // temporarySlice = ImportItkImage( correctPixelTypeImage );
+ CastToMitkImage( correctPixelTypeImage, temporarySlice );
- // 2. Determine if the user clicked inside or outside of the segmentation
- const BaseGeometry* workingSliceGeometry = m_WorkingSlice->GetGeometry();
- Point3D mprojectedPointIn2D;
- workingSliceGeometry->WorldToIndex( positionEvent->GetPositionInWorld(), mprojectedPointIn2D);
- itk::Index<2> projectedPointInWorkingSlice2D;
- projectedPointInWorkingSlice2D[0] = static_cast<int>( mprojectedPointIn2D[0] - 0.5 );
- projectedPointInWorkingSlice2D[1] = static_cast<int>( mprojectedPointIn2D[1] - 0.5 );
+ mitkIpPicDescriptor* workingPicSlice = mitkIpPicNew();
+ CastToIpPicDescriptor(temporarySlice, workingPicSlice);
- if ( workingSliceGeometry->IsIndexInside( projectedPointInWorkingSlice2D ) )
- {
- MITK_DEBUG << "OnMousePressed: point " << positionEvent->GetPositionInWorld() << " (index coordinates " << projectedPointInWorkingSlice2D << ") IS in working slice" << std::endl;
-
- // Convert to ipMITKSegmentationTYPE (because getting pixels relys on that data type)
- itk::Image< ipMITKSegmentationTYPE, 2 >::Pointer correctPixelTypeImage;
- CastToItkImage( m_WorkingSlice, correctPixelTypeImage );
- assert (correctPixelTypeImage.IsNotNull() );
-
- // possible bug in CastToItkImage ?
- // direction maxtrix is wrong/broken/not working after CastToItkImage, leading to a failed assertion in
- // mitk/Core/DataStructures/mitkSlicedGeometry3D.cpp, 479:
- // virtual void mitk::SlicedGeometry3D::SetSpacing(const mitk::Vector3D&): Assertion `aSpacing[0]>0 && aSpacing[1]>0 && aSpacing[2]>0' failed
- // solution here: we overwrite it with an unity matrix
- itk::Image< ipMITKSegmentationTYPE, 2 >::DirectionType imageDirection;
- imageDirection.SetIdentity();
- correctPixelTypeImage->SetDirection(imageDirection);
-
- Image::Pointer temporarySlice = Image::New();
- // temporarySlice = ImportItkImage( correctPixelTypeImage );
- CastToMitkImage( correctPixelTypeImage, temporarySlice );
+ int initialWorkingOffset = projectedPointInWorkingSlice2D[1] * workingPicSlice->n[0] + projectedPointInWorkingSlice2D[0];
- mitkIpPicDescriptor* workingPicSlice = mitkIpPicNew();
- CastToIpPicDescriptor(temporarySlice, workingPicSlice);
+ if ( initialWorkingOffset < static_cast<int>( workingPicSlice->n[0] * workingPicSlice->n[1] ) &&
+ initialWorkingOffset >= 0 )
+ {
+ // 3. determine the pixel value under the last click
+ bool inside = static_cast<ipMITKSegmentationTYPE*>(workingPicSlice->data)[initialWorkingOffset] != 0;
+ m_PaintingPixelValue = inside ? 0 : 1; // if inside, we want to remove a part, otherwise we want to add something
- int initialWorkingOffset = projectedPointInWorkingSlice2D[1] * workingPicSlice->n[0] + projectedPointInWorkingSlice2D[0];
+ if ( m_LastWorkingSeed >= static_cast<int>( workingPicSlice->n[0] * workingPicSlice->n[1] ) ||
+ m_LastWorkingSeed < 0 )
+ {
+ inside = false;
+ }
- if ( initialWorkingOffset < static_cast<int>( workingPicSlice->n[0] * workingPicSlice->n[1] ) &&
- initialWorkingOffset >= 0 )
+ if ( m_ReferenceSlice.IsNotNull() )
{
- // 3. determine the pixel value under the last click
- bool inside = static_cast<ipMITKSegmentationTYPE*>(workingPicSlice->data)[initialWorkingOffset] != 0;
- m_PaintingPixelValue = inside ? 0 : 1; // if inside, we want to remove a part, otherwise we want to add something
+ MITK_DEBUG << "OnMousePressed: got reference slice" << std::endl;
- if ( m_LastWorkingSeed >= static_cast<int>( workingPicSlice->n[0] * workingPicSlice->n[1] ) ||
- m_LastWorkingSeed < 0 )
+ m_OriginalPicSlice = mitkIpPicNew();
+ CastToIpPicDescriptor(m_ReferenceSlice, m_OriginalPicSlice);
+
+ // 3.1. Switch depending on the pixel value
+ if (inside)
{
- inside = false;
+ OnMousePressedInside( NULL, interactionEvent, workingPicSlice, initialWorkingOffset);
}
-
- if ( m_ReferenceSlice.IsNotNull() )
+ else
{
- MITK_DEBUG << "OnMousePressed: got reference slice" << std::endl;
-
- m_OriginalPicSlice = mitkIpPicNew();
- CastToIpPicDescriptor(m_ReferenceSlice, m_OriginalPicSlice);
-
- // 3.1. Switch depending on the pixel value
- if (inside)
- {
- OnMousePressedInside( NULL, interactionEvent, workingPicSlice, initialWorkingOffset);
- }
- else
- {
- OnMousePressedOutside( NULL, interactionEvent);
- }
+ OnMousePressedOutside( NULL, interactionEvent);
}
}
}
}
}
}
MITK_DEBUG << "end OnMousePressed" << std::endl;
return true;
}
/**
3.1 Create a skeletonization of the segmentation and try to find a nice cut
3.1.1 Call a ipSegmentation algorithm to create a nice cut
3.1.2 Set the result of this algorithm as the feedback contour
*/
bool mitk::RegionGrowingTool::OnMousePressedInside( StateMachineAction*, InteractionEvent* interactionEvent, mitkIpPicDescriptor* workingPicSlice, int initialWorkingOffset)
{
- if ( SegTool2D::CanHandleEvent(interactionEvent) < 1.0 )
- return false;
-
mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
//const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent()); // checked in OnMousePressed
// 3.1.1. Create a skeletonization of the segmentation and try to find a nice cut
// apply the skeletonization-and-cut algorithm
// generate contour to remove
// set m_ReferenceSlice = NULL so nothing will happen during mouse move
// remember to fill the contour with 0 in mouserelease
mitkIpPicDescriptor* segmentationHistory = ipMITKSegmentationCreateGrowerHistory( workingPicSlice, m_LastWorkingSeed, NULL ); // free again
if (segmentationHistory)
{
tCutResult cutContour = ipMITKSegmentationGetCutPoints( workingPicSlice, segmentationHistory, initialWorkingOffset ); // tCutResult is a ipSegmentation type
mitkIpPicFree( segmentationHistory );
if (cutContour.cutIt)
{
int timestep = positionEvent->GetSender()->GetTimeStep();
// 3.1.2 copy point from float* to mitk::Contour
ContourModel::Pointer contourInImageIndexCoordinates = ContourModel::New();
contourInImageIndexCoordinates->Expand(timestep + 1);
contourInImageIndexCoordinates->SetClosed(true, timestep);
Point3D newPoint;
for (int index = 0; index < cutContour.deleteSize; ++index)
{
newPoint[0] = cutContour.deleteCurve[ 2 * index + 0 ] - 0.5;//correction is needed because the output of the algorithm is center based
newPoint[1] = cutContour.deleteCurve[ 2 * index + 1 ] - 0.5;//and we want our contour displayed corner based.
newPoint[2] = 0.0;
contourInImageIndexCoordinates->AddVertex( newPoint, timestep );
}
free(cutContour.traceline);
free(cutContour.deleteCurve); // perhaps visualize this for fun?
free(cutContour.onGradient);
ContourModel::Pointer contourInWorldCoordinates = FeedbackContourTool::BackProjectContourFrom2DSlice( m_WorkingSlice->GetGeometry(), contourInImageIndexCoordinates, true ); // true: sub 0.5 for ipSegmentation correction
FeedbackContourTool::SetFeedbackContour( *contourInWorldCoordinates );
FeedbackContourTool::SetFeedbackContourVisible(true);
mitk::RenderingManager::GetInstance()->RequestUpdate( positionEvent->GetSender()->GetRenderWindow() );
m_FillFeedbackContour = true;
}
else
{
m_FillFeedbackContour = false;
}
}
else
{
m_FillFeedbackContour = false;
}
m_ReferenceSlice = NULL;
return true;
}
/**
3.2 Initialize region growing
3.2.1 Determine memory offset inside the original image
3.2.2 Determine initial region growing parameters from the level window settings of the image
3.2.3 Perform a region growing (which generates a new feedback contour)
*/
bool mitk::RegionGrowingTool::OnMousePressedOutside( StateMachineAction*, InteractionEvent* interactionEvent )
{
- if ( SegTool2D::CanHandleEvent(interactionEvent) < 1.0 )
- return false;
-
mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
//const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent()); // checked in OnMousePressed
// 3.2 If we have a reference image, then perform an initial region growing, considering the reference image's level window
// if click was outside the image, don't continue
const BaseGeometry* sliceGeometry = m_ReferenceSlice->GetGeometry();
Point3D mprojectedPointIn2D;
sliceGeometry->WorldToIndex( positionEvent->GetPositionInWorld(), mprojectedPointIn2D );
itk::Index<2> projectedPointIn2D;
projectedPointIn2D[0] = static_cast<int>( mprojectedPointIn2D[0] - 0.5 );
projectedPointIn2D[1] = static_cast<int>( mprojectedPointIn2D[1] - 0.5 );
if ( sliceGeometry->IsIndexInside( mprojectedPointIn2D ) )
{
MITK_DEBUG << "OnMousePressed: point " << positionEvent->GetPositionInWorld() << " (index coordinates " << mprojectedPointIn2D << ") IS in reference slice" << std::endl;
// 3.2.1 Remember Y cursor position and initial seed point
m_LastScreenPosition = positionEvent->GetPointerPositionOnScreen();
m_ScreenYDifference = 0;
m_SeedPointMemoryOffset = projectedPointIn2D[1] * m_OriginalPicSlice->n[0] + projectedPointIn2D[0];
m_LastWorkingSeed = m_SeedPointMemoryOffset; // remember for skeletonization
if ( m_SeedPointMemoryOffset < static_cast<int>( m_OriginalPicSlice->n[0] * m_OriginalPicSlice->n[1] ) &&
m_SeedPointMemoryOffset >= 0 )
{
// 3.2.2 Get level window from reference DataNode
// Use some logic to determine initial gray value bounds
LevelWindow lw(0, 500);
m_ToolManager->GetReferenceData(0)->GetLevelWindow(lw); // will fill lw if levelwindow property is present, otherwise won't touch it.
ScalarType currentVisibleWindow = lw.GetWindow();
if (!mitk::Equal(currentVisibleWindow, m_VisibleWindow))
{
m_InitialLowerThreshold = currentVisibleWindow / 20.0;
m_InitialUpperThreshold = currentVisibleWindow / 20.0;
m_LowerThreshold = m_InitialLowerThreshold;
m_UpperThreshold = m_InitialUpperThreshold;
// 3.2.3. Actually perform region growing
mitkIpPicDescriptor* result = PerformRegionGrowingAndUpdateContour(positionEvent->GetSender()->GetTimeStep());
ipMITKSegmentationFree( result);
// display the contour
FeedbackContourTool::SetFeedbackContourVisible(true);
mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
m_FillFeedbackContour = true;
}
}
return true;
}
return false;
}
/**
If in region growing mode (m_ReferenceSlice != NULL), then
1. Calculate the new thresholds from mouse position (relative to first position)
2. Perform a new region growing and update the feedback contour
*/
bool mitk::RegionGrowingTool::OnMouseMoved( StateMachineAction*, InteractionEvent* interactionEvent )
{
- if ( SegTool2D::CanHandleEvent(interactionEvent) < 1.0 )
- return false;
-
if ( m_ReferenceSlice.IsNotNull() && m_OriginalPicSlice )
{
mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
//const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
if (positionEvent)
{
m_ScreenYDifference += positionEvent->GetPointerPositionOnScreen()[1] - m_LastScreenPosition[1];
m_LastScreenPosition = positionEvent->GetPointerPositionOnScreen();
m_LowerThreshold = std::max<mitk::ScalarType>(0.0, m_InitialLowerThreshold - m_ScreenYDifference * m_MouseDistanceScaleFactor);
m_UpperThreshold = std::max<mitk::ScalarType>(0.0, m_InitialUpperThreshold - m_ScreenYDifference * m_MouseDistanceScaleFactor);
// 2. Perform region growing again and show the result
mitkIpPicDescriptor* result = PerformRegionGrowingAndUpdateContour(positionEvent->GetSender()->GetTimeStep());
ipMITKSegmentationFree( result );
// 3. Update the contour
mitk::RenderingManager::GetInstance()->ForceImmediateUpdate(positionEvent->GetSender()->GetRenderWindow());
}
}
return true;
}
/**
If the feedback contour should be filled, then it is done here. (Contour is NOT filled, when skeletonization is done but no nice cut was found)
*/
bool mitk::RegionGrowingTool::OnMouseReleased( StateMachineAction*, InteractionEvent* interactionEvent )
{
- if ( SegTool2D::CanHandleEvent(interactionEvent) < 1.0 )
- return false;
-
// 1. If we have a working slice, use the contour to fill a new piece on segmentation on it (or erase a piece that was selected by ipMITKSegmentationGetCutPoints)
if ( m_WorkingSlice.IsNotNull() && m_OriginalPicSlice )
{
mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
//const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
if (positionEvent)
{
// remember parameters for next time
m_InitialLowerThreshold = m_LowerThreshold;
m_InitialUpperThreshold = m_UpperThreshold;
int timestep = positionEvent->GetSender()->GetTimeStep();
if (m_FillFeedbackContour)
{
// 3. use contour to fill a region in our working slice
ContourModel* feedbackContour( FeedbackContourTool::GetFeedbackContour() );
if (feedbackContour)
{
ContourModel::Pointer projectedContour = FeedbackContourTool::ProjectContourTo2DSlice( m_WorkingSlice, feedbackContour, false, false ); // false: don't add any 0.5
// false: don't constrain the contour to the image's inside
if (projectedContour.IsNotNull())
{
FeedbackContourTool::FillContourInSlice( projectedContour, timestep, m_WorkingSlice, m_PaintingPixelValue );
const PlaneGeometry* planeGeometry( dynamic_cast<const PlaneGeometry*> (positionEvent->GetSender()->GetCurrentWorldPlaneGeometry() ) );
//MITK_DEBUG << "OnMouseReleased: wri<<ting back to dimension " << affectedDimension << ", slice " << affectedSlice << " in working image" << std::endl;
// 4. write working slice back into image volume
this->WriteBackSegmentationResult(positionEvent, m_WorkingSlice);
}
}
}
FeedbackContourTool::SetFeedbackContourVisible(false);
mitk::RenderingManager::GetInstance()->RequestUpdate( positionEvent->GetSender()->GetRenderWindow() );
}
}
m_ReferenceSlice = NULL; // don't leak
m_WorkingSlice = NULL;
m_OriginalPicSlice = NULL;
return true;
}
/**
Uses ipSegmentation algorithms to do the actual region growing. The result (binary image) is first smoothed by a 5x5 circle mask, then
its contour is extracted and converted to MITK coordinates.
*/
mitkIpPicDescriptor* mitk::RegionGrowingTool::PerformRegionGrowingAndUpdateContour(int timestep)
{
// 1. m_OriginalPicSlice and m_SeedPointMemoryOffset are set to sensitive values, as well as m_LowerThreshold and m_UpperThreshold
assert (m_OriginalPicSlice);
if (m_OriginalPicSlice->n[0] != 256 || m_OriginalPicSlice->n[1] != 256) // ???
assert( (m_SeedPointMemoryOffset < static_cast<int>( m_OriginalPicSlice->n[0] * m_OriginalPicSlice->n[1] )) && (m_SeedPointMemoryOffset >= 0) ); // inside the image
// 2. ipSegmentation is used to perform region growing
float ignored;
int oneContourOffset( 0 );
mitkIpPicDescriptor* regionGrowerResult = ipMITKSegmentationGrowRegion4N( m_OriginalPicSlice,
m_SeedPointMemoryOffset, // seed point
true, // grayvalue interval relative to seed point gray value?
m_LowerThreshold,
m_UpperThreshold,
0, // continue until done (maxIterations == 0)
NULL, // allocate new memory (only this time, on mouse move we'll reuse the old buffer)
oneContourOffset, // a pixel that is near the resulting contour
ignored // ignored by us
);
if (!regionGrowerResult || oneContourOffset == -1)
{
ContourModel::Pointer dummyContour = ContourModel::New();
dummyContour->Initialize();
FeedbackContourTool::SetFeedbackContour( *dummyContour );
if (regionGrowerResult) ipMITKSegmentationFree(regionGrowerResult);
return NULL;
}
// 3. We smooth the result a little to reduce contour complexity
bool smoothResult( true ); // currently fixed, perhaps remove else block
mitkIpPicDescriptor* smoothedRegionGrowerResult;
if (smoothResult)
{
// Smooth the result (otherwise very detailed contour)
smoothedRegionGrowerResult = SmoothIPPicBinaryImage( regionGrowerResult, oneContourOffset );
ipMITKSegmentationFree( regionGrowerResult );
}
else
{
smoothedRegionGrowerResult = regionGrowerResult;
}
// 4. convert the result of region growing into a mitk::Contour
// At this point oneContourOffset could be useless, if smoothing destroyed a thin bridge. In these
// cases, we have two or more unconnected segmentation regions, and we don't know, which one is touched by oneContourOffset.
// In the bad case, the contour is not the one around our seedpoint, so the result looks very strange to the user.
// -> we remove the point where the contour started so far. Then we look from the bottom of the image for the first segmentation pixel
// and start another contour extraction from there. This is done, until the seedpoint is inside the contour
int numberOfContourPoints( 0 );
int newBufferSize( 0 );
float* contourPoints = ipMITKSegmentationGetContour8N( smoothedRegionGrowerResult, oneContourOffset, numberOfContourPoints, newBufferSize ); // memory allocated with malloc
if (contourPoints)
{
while ( !ipMITKSegmentationIsInsideContour( contourPoints, // contour
numberOfContourPoints, // points in contour
m_SeedPointMemoryOffset % smoothedRegionGrowerResult->n[0], // test point x
m_SeedPointMemoryOffset / smoothedRegionGrowerResult->n[0] // test point y
) )
{
// we decide that this cannot be part of the segmentation because the seedpoint is not contained in the contour (fill the 4-neighborhood with 0)
ipMITKSegmentationReplaceRegion4N( smoothedRegionGrowerResult, oneContourOffset, 0 );
// move the contour offset to the last row (x position of the seed point)
int rowLength = smoothedRegionGrowerResult->n[0]; // number of pixels in a row
oneContourOffset = m_SeedPointMemoryOffset % smoothedRegionGrowerResult->n[0] // x of seed point
+ rowLength*(smoothedRegionGrowerResult->n[1]-1); // y of last row
while ( oneContourOffset >=0
&& (*(static_cast<ipMITKSegmentationTYPE*>(smoothedRegionGrowerResult->data) + oneContourOffset) == 0) )
{
oneContourOffset -= rowLength; // if pixel at data+oneContourOffset is 0, then move up one row
}
if ( oneContourOffset < 0 )
{
break; // just use the last contour we found
}
free(contourPoints); // release contour memory
contourPoints = ipMITKSegmentationGetContour8N( smoothedRegionGrowerResult, oneContourOffset, numberOfContourPoints, newBufferSize ); // memory allocated with malloc
}
// copy point from float* to mitk::Contour
ContourModel::Pointer contourInImageIndexCoordinates = ContourModel::New();
contourInImageIndexCoordinates->Expand(timestep + 1);
contourInImageIndexCoordinates->SetClosed(true, timestep);
Point3D newPoint;
for (int index = 0; index < numberOfContourPoints; ++index)
{
newPoint[0] = contourPoints[ 2 * index + 0 ] - 0.5;//correction is needed because the output of the algorithm is center based
newPoint[1] = contourPoints[ 2 * index + 1 ] - 0.5;//and we want our contour displayed corner based.
newPoint[2] = 0;
contourInImageIndexCoordinates->AddVertex( newPoint, timestep );
}
free(contourPoints);
ContourModel::Pointer contourInWorldCoordinates = FeedbackContourTool::BackProjectContourFrom2DSlice( m_ReferenceSlice->GetGeometry(), contourInImageIndexCoordinates, true ); // true: sub 0.5 for ipSegmentation correctio
FeedbackContourTool::SetFeedbackContour( *contourInWorldCoordinates );
}
// 5. Result HAS TO BE freed by caller, contains the binary region growing result
return smoothedRegionGrowerResult;
}
/**
Helper method for SmoothIPPicBinaryImage. Smoothes a given part of and image.
\param sourceImage The original binary image.
\param dest The smoothed image (will be written without bounds checking).
\param contourOfs One offset of the contour. Is updated if a pixel is changed (which might change the contour).
\param maskOffsets Memory offsets that describe the smoothing mask.
\param maskSize Entries of the mask.
\param startOffset First pixel that should be smoothed using this mask.
\param endOffset Last pixel that should be smoothed using this mask.
*/
void mitk::RegionGrowingTool::SmoothIPPicBinaryImageHelperForRows( mitkIpPicDescriptor* sourceImage, mitkIpPicDescriptor* dest, int &contourOfs, int* maskOffsets, int maskSize, int startOffset, int endOffset )
{
// work on the very first row
ipMITKSegmentationTYPE* current;
ipMITKSegmentationTYPE* source = ((ipMITKSegmentationTYPE*)sourceImage->data) + startOffset; // + 1! don't read at start-1
ipMITKSegmentationTYPE* end = ((ipMITKSegmentationTYPE*)dest->data) + endOffset;
int ofs = startOffset;
int minority = (maskSize - 1) / 2;
for (current = ((ipMITKSegmentationTYPE*)dest->data) + startOffset; current<end; current++)
{
mitkIpInt1_t sum( 0 );
for (int i = 0; i < maskSize; ++i)
{
sum += *(source+maskOffsets[i]);
}
if (sum > minority)
{
*current = 1;
contourOfs = ofs;
}
else
{
*current = 0;
}
++source;
++ofs;
}
}
/**
Smoothes a binary ipPic image with a 5x5 mask. The image borders (some first and last rows) are treated differently.
*/
mitkIpPicDescriptor* mitk::RegionGrowingTool::SmoothIPPicBinaryImage( mitkIpPicDescriptor* image, int &contourOfs, mitkIpPicDescriptor* dest )
{
if (!image) return NULL;
// Original code from /trunk/mbi-qm/Qmitk/Qmitk2DSegTools/RegionGrowerTool.cpp (first version by T. Boettger?). Reformatted and documented and restructured.
#define MSK_SIZE5x5 21
#define MSK_SIZE3x3 5
#define MSK_SIZE3x1 3
// mask is an array of coordinates that form a rastered circle like this
//
// OOO
// OOOOO
// OOOOO
// OOOOO
// OOO
//
//
int mask5x5[MSK_SIZE5x5][2]
= {
/******/ {-1,-2}, {0,-2}, {1,-2}, /*****/
{-2,-1}, {-1,-1}, {0,-1}, {1,-1}, {2,-1},
{-2, 0}, {-1, 0}, {0, 0}, {1, 0}, {2, 0},
{-2, 1}, {-1, 1}, {0, 1}, {1, 1}, {2, 1},
/******/ {-1, 2}, {0, 2}, {1, 2} /*****/
};
int mask3x3[MSK_SIZE3x3][2]
= {
/******/ {0,-1}, /*****/
{-1, 0}, {0, 0}, {1, 0},
/******/ {0, 1} /*****/
};
int mask3x1[MSK_SIZE3x1][2]
= {
{-1, 0}, {0, 0}, {1, 0}
};
// The following lines iterate over all the pixels of a (sliced) image (except the first and last three rows).
// For each pixel, all the coordinates around it (according to mask) are evaluated (this means 21 pixels).
// If more than 10 of the evaluated pixels are non-zero, then the central pixel is set to 1, else to 0.
// This is determining a majority. If there is no clear majority, then the central pixel itself "decides".
int maskOffset5x5[MSK_SIZE5x5];
int line = image->n[0];
for (int i=0; i<MSK_SIZE5x5; i++)
{
maskOffset5x5[i] = mask5x5[i][0] + line * mask5x5[i][1]; // calculate memory offsets from the x,y mask elements
}
int maskOffset3x3[MSK_SIZE3x3];
for (int i=0; i<MSK_SIZE3x3; i++)
{
maskOffset3x3[i] = mask3x3[i][0] + line * mask3x3[i][1]; // calculate memory offsets from the x,y mask elements
}
int maskOffset3x1[MSK_SIZE3x1];
for (int i=0; i<MSK_SIZE3x1; i++)
{
maskOffset3x1[i] = mask3x1[i][0] + line * mask3x1[i][1]; // calculate memory offsets from the x,y mask elements
}
if (!dest)
{
// create pic if necessary
dest = ipMITKSegmentationNew( image );
}
int spareOut3Rows = 3*image->n[0];
int spareOut1Rows = 1*image->n[0];
if ( image->n[1] > 0 ) SmoothIPPicBinaryImageHelperForRows( image, dest, contourOfs, maskOffset3x1, MSK_SIZE3x1, 1, dest->n[0] );
if ( image->n[1] > 3 ) SmoothIPPicBinaryImageHelperForRows( image, dest, contourOfs, maskOffset3x3, MSK_SIZE3x3, spareOut1Rows, dest->n[0]*3 );
if ( image->n[1] > 6 ) SmoothIPPicBinaryImageHelperForRows( image, dest, contourOfs, maskOffset5x5, MSK_SIZE5x5, spareOut3Rows, dest->n[0]*dest->n[1] - spareOut3Rows );
if ( image->n[1] > 8 ) SmoothIPPicBinaryImageHelperForRows( image, dest, contourOfs, maskOffset3x3, MSK_SIZE3x3, dest->n[0]*dest->n[1] -spareOut3Rows, dest->n[0]*dest->n[1] - spareOut1Rows );
if ( image->n[1] > 10) SmoothIPPicBinaryImageHelperForRows( image, dest, contourOfs, maskOffset3x1, MSK_SIZE3x1, dest->n[0]*dest->n[1] -spareOut1Rows, dest->n[0]*dest->n[1] - 1 );
// correction for first pixel (sorry for the ugliness)
if ( *((ipMITKSegmentationTYPE*)(dest->data)+1) == 1 )
{
*((ipMITKSegmentationTYPE*)(dest->data)+0) = 1;
}
if (dest->n[0] * dest->n[1] > 2)
{
// correction for last pixel
if ( *((ipMITKSegmentationTYPE*)(dest->data)+dest->n[0]*dest->n[1]-2) == 1 )
{
*((ipMITKSegmentationTYPE*)(dest->data)+dest->n[0]*dest->n[1]-1) = 1;
}
}
return dest;
}
diff --git a/Modules/Segmentation/Interactions/mitkSegTool2D.cpp b/Modules/Segmentation/Interactions/mitkSegTool2D.cpp
index 93f5d1827f..363d7d85c5 100644
--- a/Modules/Segmentation/Interactions/mitkSegTool2D.cpp
+++ b/Modules/Segmentation/Interactions/mitkSegTool2D.cpp
@@ -1,472 +1,476 @@
/*===================================================================
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 "mitkSegTool2D.h"
#include "mitkToolManager.h"
#include "mitkDataStorage.h"
#include "mitkBaseRenderer.h"
#include "mitkPlaneGeometry.h"
#include "mitkExtractImageFilter.h"
#include "mitkExtractDirectedPlaneImageFilter.h"
//Include of the new ImageExtractor
#include "mitkExtractDirectedPlaneImageFilterNew.h"
#include "mitkPlanarCircle.h"
#include "mitkOverwriteSliceImageFilter.h"
#include "mitkOverwriteDirectedPlaneImageFilter.h"
#include "mitkMorphologicalOperations.h"
#include "usGetModuleContext.h"
//Includes for 3DSurfaceInterpolation
#include "mitkImageToContourFilter.h"
#include "mitkSurfaceInterpolationController.h"
//includes for resling and overwriting
#include <mitkExtractSliceFilter.h>
#include <mitkVtkImageOverwrite.h>
#include <vtkSmartPointer.h>
#include <vtkImageData.h>
#include <mitkDiffSliceOperationApplier.h>
#include "mitkOperationEvent.h"
#include "mitkUndoController.h"
#include "mitkAbstractTransformGeometry.h"
#define ROUND(a) ((a)>0 ? (int)((a)+0.5) : -(int)(0.5-(a)))
bool mitk::SegTool2D::m_SurfaceInterpolationEnabled = true;
mitk::SegTool2D::SegTool2D(const char* type)
:Tool(type),
m_LastEventSender(NULL),
m_LastEventSlice(0),
m_Contourmarkername ("Position"),
m_ShowMarkerNodes (false)
{
}
mitk::SegTool2D::~SegTool2D()
{
}
-float mitk::SegTool2D::CanHandleEvent( InteractionEvent const *stateEvent) const
+bool mitk::SegTool2D::FilterEvents(InteractionEvent* interactionEvent, DataNode*dataNode)
{
- const InteractionPositionEvent* positionEvent = dynamic_cast<const InteractionPositionEvent*>( stateEvent );
- if (!positionEvent) return 0.0;
+ const InteractionPositionEvent* positionEvent = dynamic_cast<const InteractionPositionEvent*>( interactionEvent );
- if ( positionEvent->GetSender()->GetMapperID() != BaseRenderer::Standard2D )
- return 0.0; // we don't want anything but 2D
-
- return 1.0;
+ bool isValidEvent = (
+ positionEvent && // Only events of type mitk::InteractionPositionEvent
+ interactionEvent->GetSender()->GetMapperID() == BaseRenderer::Standard2D // Only events from the 2D renderwindows
+ );
+ return isValidEvent;
}
bool mitk::SegTool2D::DetermineAffectedImageSlice( const Image* image, const PlaneGeometry* plane, int& affectedDimension, int& affectedSlice )
{
assert(image);
assert(plane);
// compare normal of plane to the three axis vectors of the image
Vector3D normal = plane->GetNormal();
Vector3D imageNormal0 = image->GetSlicedGeometry()->GetAxisVector(0);
Vector3D imageNormal1 = image->GetSlicedGeometry()->GetAxisVector(1);
Vector3D imageNormal2 = image->GetSlicedGeometry()->GetAxisVector(2);
normal.Normalize();
imageNormal0.Normalize();
imageNormal1.Normalize();
imageNormal2.Normalize();
imageNormal0.SetVnlVector( vnl_cross_3d<ScalarType>(normal.GetVnlVector(),imageNormal0.GetVnlVector()) );
imageNormal1.SetVnlVector( vnl_cross_3d<ScalarType>(normal.GetVnlVector(),imageNormal1.GetVnlVector()) );
imageNormal2.SetVnlVector( vnl_cross_3d<ScalarType>(normal.GetVnlVector(),imageNormal2.GetVnlVector()) );
double eps( 0.00001 );
// axial
if ( imageNormal2.GetNorm() <= eps )
{
affectedDimension = 2;
}
// sagittal
else if ( imageNormal1.GetNorm() <= eps )
{
affectedDimension = 1;
}
// frontal
else if ( imageNormal0.GetNorm() <= eps )
{
affectedDimension = 0;
}
else
{
affectedDimension = -1; // no idea
return false;
}
// determine slice number in image
BaseGeometry* imageGeometry = image->GetGeometry(0);
Point3D testPoint = imageGeometry->GetCenter();
Point3D projectedPoint;
plane->Project( testPoint, projectedPoint );
Point3D indexPoint;
imageGeometry->WorldToIndex( projectedPoint, indexPoint );
affectedSlice = ROUND( indexPoint[affectedDimension] );
MITK_DEBUG << "indexPoint " << indexPoint << " affectedDimension " << affectedDimension << " affectedSlice " << affectedSlice;
// check if this index is still within the image
if ( affectedSlice < 0 || affectedSlice >= static_cast<int>(image->GetDimension(affectedDimension)) ) return false;
return true;
}
void mitk::SegTool2D::UpdateSurfaceInterpolation (const Image* slice, const Image* workingImage, const PlaneGeometry *plane, bool detectIntersection)
{
if (!m_SurfaceInterpolationEnabled)
return;
ImageToContourFilter::Pointer contourExtractor = ImageToContourFilter::New();
mitk::Surface::Pointer contour;
if (detectIntersection)
{
// Test whether there is something to extract or whether the slice just contains intersections of others
mitk::Image::Pointer slice2 = slice->Clone();
mitk::MorphologicalOperations::Erode(slice2, 2, mitk::MorphologicalOperations::Ball);
contourExtractor->SetInput(slice2);
contourExtractor->Update();
contour = contourExtractor->GetOutput();
if (contour->GetVtkPolyData()->GetNumberOfPoints() == 0)
{
// Remove contour!
mitk::SurfaceInterpolationController::ContourPositionInformation contourInfo;
contourInfo.contourNormal = plane->GetNormal();
contourInfo.contourPoint = plane->GetOrigin();
mitk::SurfaceInterpolationController::GetInstance()->RemoveContour(contourInfo);
return;
}
}
contourExtractor->SetInput(slice);
contourExtractor->Update();
contour = contourExtractor->GetOutput();
if (contour->GetVtkPolyData()->GetNumberOfPoints() != 0 && workingImage->GetDimension() == 3)
{
mitk::SurfaceInterpolationController::GetInstance()->AddNewContour( contour );
contour->DisconnectPipeline();
}
else
{
// Remove contour!
mitk::SurfaceInterpolationController::ContourPositionInformation contourInfo;
contourInfo.contourNormal = plane->GetNormal();
contourInfo.contourPoint = plane->GetOrigin();
mitk::SurfaceInterpolationController::GetInstance()->RemoveContour(contourInfo);
}
}
mitk::Image::Pointer mitk::SegTool2D::GetAffectedImageSliceAs2DImage(const InteractionPositionEvent* positionEvent, const Image* image)
{
if (!positionEvent) return NULL;
assert( positionEvent->GetSender() ); // sure, right?
unsigned int timeStep = positionEvent->GetSender()->GetTimeStep( image ); // get the timestep of the visible part (time-wise) of the image
// first, we determine, which slice is affected
const PlaneGeometry* planeGeometry( dynamic_cast<const PlaneGeometry*> (positionEvent->GetSender()->GetCurrentWorldPlaneGeometry() ) );
return this->GetAffectedImageSliceAs2DImage(planeGeometry, image, timeStep);
}
mitk::Image::Pointer mitk::SegTool2D::GetAffectedImageSliceAs2DImage(const PlaneGeometry* planeGeometry, const Image* image, unsigned int timeStep)
{
if ( !image || !planeGeometry ) return NULL;
//Make sure that for reslicing and overwriting the same alogrithm is used. We can specify the mode of the vtk reslicer
vtkSmartPointer<mitkVtkImageOverwrite> reslice = vtkSmartPointer<mitkVtkImageOverwrite>::New();
//set to false to extract a slice
reslice->SetOverwriteMode(false);
reslice->Modified();
//use ExtractSliceFilter with our specific vtkImageReslice for overwriting and extracting
mitk::ExtractSliceFilter::Pointer extractor = mitk::ExtractSliceFilter::New(reslice);
extractor->SetInput( image );
extractor->SetTimeStep( timeStep );
extractor->SetWorldGeometry( planeGeometry );
extractor->SetVtkOutputRequest(false);
extractor->SetResliceTransformByGeometry( image->GetTimeGeometry()->GetGeometryForTimeStep( timeStep ) );
extractor->Modified();
extractor->Update();
Image::Pointer slice = extractor->GetOutput();
/*============= BEGIN undo feature block ========================*/
//specify the undo operation with the non edited slice
m_undoOperation = new DiffSliceOperation(const_cast<mitk::Image*>(image), extractor->GetVtkOutput(), dynamic_cast<SlicedGeometry3D*>(slice->GetGeometry()), timeStep, const_cast<mitk::PlaneGeometry*>(planeGeometry));
/*============= END undo feature block ========================*/
return slice;
}
mitk::Image::Pointer mitk::SegTool2D::GetAffectedWorkingSlice(const InteractionPositionEvent* positionEvent)
{
DataNode* workingNode( m_ToolManager->GetWorkingData(0) );
if ( !workingNode ) return NULL;
Image* workingImage = dynamic_cast<Image*>(workingNode->GetData());
if ( !workingImage ) return NULL;
return GetAffectedImageSliceAs2DImage( positionEvent, workingImage );
}
mitk::Image::Pointer mitk::SegTool2D::GetAffectedReferenceSlice(const InteractionPositionEvent* positionEvent)
{
DataNode* referenceNode( m_ToolManager->GetReferenceData(0) );
if ( !referenceNode ) return NULL;
Image* referenceImage = dynamic_cast<Image*>(referenceNode->GetData());
if ( !referenceImage ) return NULL;
return GetAffectedImageSliceAs2DImage( positionEvent, referenceImage );
}
void mitk::SegTool2D::WriteBackSegmentationResult (const InteractionPositionEvent* positionEvent, Image* slice)
{
if(!positionEvent) return;
const PlaneGeometry* planeGeometry( dynamic_cast<const PlaneGeometry*> (positionEvent->GetSender()->GetCurrentWorldPlaneGeometry() ) );
const AbstractTransformGeometry* abstractTransformGeometry( dynamic_cast<const AbstractTransformGeometry*> (positionEvent->GetSender()->GetCurrentWorldPlaneGeometry() ) );
if( planeGeometry && slice && !abstractTransformGeometry)
{
DataNode* workingNode( m_ToolManager->GetWorkingData(0) );
Image* image = dynamic_cast<Image*>(workingNode->GetData());
unsigned int timeStep = positionEvent->GetSender()->GetTimeStep( image );
this->WriteBackSegmentationResult(planeGeometry, slice, timeStep);
}
}
void mitk::SegTool2D::WriteBackSegmentationResult (const PlaneGeometry* planeGeometry, Image* slice, unsigned int timeStep)
{
if(!planeGeometry || !slice) return;
SliceInformation sliceInfo (slice, const_cast<mitk::PlaneGeometry*>(planeGeometry), timeStep);
this->WriteSliceToVolume(sliceInfo);
DataNode* workingNode( m_ToolManager->GetWorkingData(0) );
Image* image = dynamic_cast<Image*>(workingNode->GetData());
this->UpdateSurfaceInterpolation(slice, image, planeGeometry, false);
if (m_SurfaceInterpolationEnabled)
this->AddContourmarker();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
-void mitk::SegTool2D::WriteBackSegmentationResult(std::vector<mitk::SegTool2D::SliceInformation> sliceList)
+void mitk::SegTool2D::WriteBackSegmentationResult(std::vector<mitk::SegTool2D::SliceInformation> sliceList, bool writeSliceToVolume)
{
std::vector<mitk::Surface::Pointer> contourList;
contourList.reserve(sliceList.size());
ImageToContourFilter::Pointer contourExtractor = ImageToContourFilter::New();
DataNode* workingNode( m_ToolManager->GetWorkingData(0) );
Image* image = dynamic_cast<Image*>(workingNode->GetData());
for (unsigned int i = 0; i < sliceList.size(); ++i)
{
SliceInformation currentSliceInfo = sliceList.at(i);
- this->WriteSliceToVolume(currentSliceInfo);
+ if(writeSliceToVolume)
+ this->WriteSliceToVolume(currentSliceInfo);
if (m_SurfaceInterpolationEnabled && image->GetDimension() == 3)
{
currentSliceInfo.slice->DisconnectPipeline();
contourExtractor->SetInput(currentSliceInfo.slice);
contourExtractor->Update();
mitk::Surface::Pointer contour = contourExtractor->GetOutput();
contour->DisconnectPipeline();
contourList.push_back(contour);
}
}
mitk::SurfaceInterpolationController::GetInstance()->AddNewContours(contourList);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void mitk::SegTool2D::WriteSliceToVolume(mitk::SegTool2D::SliceInformation sliceInfo)
{
DataNode* workingNode( m_ToolManager->GetWorkingData(0) );
Image* image = dynamic_cast<Image*>(workingNode->GetData());
//Make sure that for reslicing and overwriting the same alogrithm is used. We can specify the mode of the vtk reslicer
vtkSmartPointer<mitkVtkImageOverwrite> reslice = vtkSmartPointer<mitkVtkImageOverwrite>::New();
//Set the slice as 'input'
reslice->SetInputSlice(sliceInfo.slice->GetVtkImageData());
//set overwrite mode to true to write back to the image volume
reslice->SetOverwriteMode(true);
reslice->Modified();
mitk::ExtractSliceFilter::Pointer extractor = mitk::ExtractSliceFilter::New(reslice);
extractor->SetInput( image );
extractor->SetTimeStep( sliceInfo.timestep );
extractor->SetWorldGeometry( sliceInfo.plane );
extractor->SetVtkOutputRequest(true);
extractor->SetResliceTransformByGeometry( image->GetGeometry( sliceInfo.timestep ) );
extractor->Modified();
extractor->Update();
//the image was modified within the pipeline, but not marked so
image->Modified();
image->GetVtkImageData()->Modified();
/*============= BEGIN undo feature block ========================*/
//specify the undo operation with the edited slice
m_doOperation = new DiffSliceOperation(image, extractor->GetVtkOutput(),dynamic_cast<SlicedGeometry3D*>(sliceInfo.slice->GetGeometry()), sliceInfo.timestep, sliceInfo.plane);
//create an operation event for the undo stack
OperationEvent* undoStackItem = new OperationEvent( DiffSliceOperationApplier::GetInstance(), m_doOperation, m_undoOperation, "Segmentation" );
//add it to the undo controller
UndoController::GetCurrentUndoModel()->SetOperationEvent( undoStackItem );
//clear the pointers as the operation are stored in the undocontroller and also deleted from there
m_undoOperation = NULL;
m_doOperation = NULL;
/*============= END undo feature block ========================*/
}
void mitk::SegTool2D::SetShowMarkerNodes(bool status)
{
m_ShowMarkerNodes = status;
}
void mitk::SegTool2D::SetEnable3DInterpolation(bool enabled)
{
m_SurfaceInterpolationEnabled = enabled;
}
-unsigned int mitk::SegTool2D::AddContourmarker()
+int mitk::SegTool2D::AddContourmarker()
{
+ if (m_LastEventSender == NULL)
+ return -1;
+
us::ServiceReference<PlanePositionManagerService> serviceRef =
us::GetModuleContext()->GetServiceReference<PlanePositionManagerService>();
PlanePositionManagerService* service = us::GetModuleContext()->GetService(serviceRef);
unsigned int slicePosition = m_LastEventSender->GetSliceNavigationController()->GetSlice()->GetPos();
// the first geometry is needed otherwise restoring the position is not working
const mitk::PlaneGeometry* plane = dynamic_cast<const PlaneGeometry*> (dynamic_cast< const mitk::SlicedGeometry3D*>(
m_LastEventSender->GetSliceNavigationController()->GetCurrentGeometry3D())->GetPlaneGeometry(0));
unsigned int size = service->GetNumberOfPlanePositions();
unsigned int id = service->AddNewPlanePosition(plane, slicePosition);
mitk::PlanarCircle::Pointer contourMarker = mitk::PlanarCircle::New();
mitk::Point2D p1;
plane->Map(plane->GetCenter(), p1);
mitk::Point2D p2 = p1;
p2[0] -= plane->GetSpacing()[0];
p2[1] -= plane->GetSpacing()[1];
contourMarker->PlaceFigure( p1 );
contourMarker->SetCurrentControlPoint( p1 );
contourMarker->SetPlaneGeometry( const_cast<PlaneGeometry*>(plane));
std::stringstream markerStream;
mitk::DataNode* workingNode (m_ToolManager->GetWorkingData(0));
markerStream << m_Contourmarkername ;
markerStream << " ";
markerStream << id+1;
DataNode::Pointer rotatedContourNode = DataNode::New();
rotatedContourNode->SetData(contourMarker);
rotatedContourNode->SetProperty( "name", StringProperty::New(markerStream.str()) );
rotatedContourNode->SetProperty( "isContourMarker", BoolProperty::New(true));
rotatedContourNode->SetBoolProperty( "PlanarFigureInitializedWindow", true, m_LastEventSender );
rotatedContourNode->SetProperty( "includeInBoundingBox", BoolProperty::New(false));
rotatedContourNode->SetProperty( "helper object", mitk::BoolProperty::New(!m_ShowMarkerNodes));
rotatedContourNode->SetProperty( "planarfigure.drawcontrolpoints", BoolProperty::New(false));
rotatedContourNode->SetProperty( "planarfigure.drawname", BoolProperty::New(false));
rotatedContourNode->SetProperty( "planarfigure.drawoutline", BoolProperty::New(false));
rotatedContourNode->SetProperty( "planarfigure.drawshadow", BoolProperty::New(false));
if (plane)
{
if ( id == size )
{
m_ToolManager->GetDataStorage()->Add(rotatedContourNode, workingNode);
}
else
{
mitk::NodePredicateProperty::Pointer isMarker = mitk::NodePredicateProperty::New("isContourMarker", mitk::BoolProperty::New(true));
mitk::DataStorage::SetOfObjects::ConstPointer markers = m_ToolManager->GetDataStorage()->GetDerivations(workingNode,isMarker);
for ( mitk::DataStorage::SetOfObjects::const_iterator iter = markers->begin();
iter != markers->end();
++iter)
{
std::string nodeName = (*iter)->GetName();
unsigned int t = nodeName.find_last_of(" ");
unsigned int markerId = atof(nodeName.substr(t+1).c_str())-1;
if(id == markerId)
{
return id;
}
}
m_ToolManager->GetDataStorage()->Add(rotatedContourNode, workingNode);
}
}
return id;
}
void mitk::SegTool2D::InteractiveSegmentationBugMessage( const std::string& message )
{
MITK_ERROR << "********************************************************************************" << std::endl
<< " " << message << std::endl
<< "********************************************************************************" << std::endl
<< " " << std::endl
<< " If your image is rotated or the 2D views don't really contain the patient image, try to press the button next to the image selection. " << std::endl
<< " " << std::endl
<< " Please file a BUG REPORT: " << std::endl
<< " http://bugs.mitk.org" << std::endl
<< " Contain the following information:" << std::endl
<< " - What image were you working on?" << std::endl
<< " - Which region of the image?" << std::endl
<< " - Which tool did you use?" << std::endl
<< " - What did you do?" << std::endl
<< " - What happened (not)? What did you expect?" << std::endl;
}
diff --git a/Modules/Segmentation/Interactions/mitkSegTool2D.h b/Modules/Segmentation/Interactions/mitkSegTool2D.h
index a6a07efe19..360308a2bd 100644
--- a/Modules/Segmentation/Interactions/mitkSegTool2D.h
+++ b/Modules/Segmentation/Interactions/mitkSegTool2D.h
@@ -1,181 +1,183 @@
/*===================================================================
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 mitkSegTool2D_h_Included
#define mitkSegTool2D_h_Included
#include "mitkCommon.h"
#include <MitkSegmentationExports.h>
#include "mitkTool.h"
#include "mitkImage.h"
#include "mitkStateEvent.h"
#include "mitkInteractionPositionEvent.h"
#include "mitkPlanePositionManager.h"
#include "mitkRestorePlanePositionOperation.h"
#include "mitkInteractionConst.h"
#include <mitkDiffSliceOperation.h>
namespace mitk
{
class BaseRenderer;
/**
\brief Abstract base class for segmentation tools.
\sa Tool
\ingroup Interaction
\ingroup ToolManagerEtAl
Implements 2D segmentation specific helper methods, that might be of use to
all kind of 2D segmentation tools. At the moment these are:
- Determination of the slice where the user paints upon (DetermineAffectedImageSlice)
- Projection of a 3D contour onto a 2D plane/slice
SegTool2D tries to structure the interaction a bit. If you pass "PressMoveRelease" as the interaction type
of your derived tool, you might implement the methods OnMousePressed, OnMouseMoved, and OnMouseReleased.
Yes, your guess about when they are called is correct.
\warning Only to be instantiated by mitk::ToolManager.
$Author$
*/
class MitkSegmentation_EXPORT SegTool2D : public Tool
{
public:
mitkClassMacro(SegTool2D, Tool);
/**
\brief Calculates for a given Image and PlaneGeometry, which slice of the image (in index corrdinates) is meant by the plane.
\return false, if no slice direction seems right (e.g. rotated planes)
\param affectedDimension The image dimension, which is constant for all points in the plane, e.g. Axial --> 2
\param affectedSlice The index of the image slice
*/
static bool DetermineAffectedImageSlice( const Image* image, const PlaneGeometry* plane, int& affectedDimension, int& affectedSlice );
/**
* @brief Updates the surface interpolation by extracting the contour form the given slice.
* @param slice the slice from which the contour should be extracted
* @param workingImage the segmentation image
* @param plane the plane in which the slice lies
* @param detectIntersection if true the slice is eroded before contour extraction. If the slice is empty after the erosion it is most
* likely an intersecting contour an will not be added to the SurfaceInterpolationController
*/
static void UpdateSurfaceInterpolation (const Image* slice, const Image* workingImage, const PlaneGeometry *plane, bool detectIntersection);
void SetShowMarkerNodes(bool);
/**
* \brief Enables or disables the 3D interpolation after writing back the 2D segmentation result, and defaults to true.
*/
void SetEnable3DInterpolation(bool);
protected:
SegTool2D(); // purposely hidden
SegTool2D(const char*); // purposely hidden
virtual ~SegTool2D();
struct SliceInformation
{
mitk::Image::Pointer slice;
mitk::PlaneGeometry* plane;
unsigned int timestep;
SliceInformation () {}
SliceInformation (mitk::Image* slice, mitk::PlaneGeometry* plane, unsigned int timestep)
{
this->slice = slice;
this->plane = plane;
this->timestep = timestep;
}
};
/**
- * \brief Calculates how good the data, this statemachine handles, is hit by the event.
+ * \brief Filters events that cannot be handle by 2D segmentation tools
*
+ * Current an event is discarded if it was not sent by a 2D renderwindow and if it is
+ * not of type InteractionPositionEvent
*/
- virtual float CanHandleEvent( InteractionEvent const *stateEvent) const;
+ virtual bool FilterEvents(InteractionEvent *interactionEvent, DataNode *dataNode);
/**
\brief Extract the slice of an image that the user just scribbles on.
\return NULL if SegTool2D is either unable to determine which slice was affected, or if there was some problem getting the image data at that position.
*/
Image::Pointer GetAffectedImageSliceAs2DImage(const InteractionPositionEvent*, const Image* image);
/**
\brief Extract the slice of an image cut by given plane.
\return NULL if SegTool2D is either unable to determine which slice was affected, or if there was some problem getting the image data at that position.
*/
Image::Pointer GetAffectedImageSliceAs2DImage(const PlaneGeometry* planeGeometry, const Image* image, unsigned int timeStep);
/**
\brief Extract the slice of the currently selected working image that the user just scribbles on.
\return NULL if SegTool2D is either unable to determine which slice was affected, or if there was some problem getting the image data at that position,
or just no working image is selected.
*/
Image::Pointer GetAffectedWorkingSlice(const InteractionPositionEvent*);
/**
\brief Extract the slice of the currently selected reference image that the user just scribbles on.
\return NULL if SegTool2D is either unable to determine which slice was affected, or if there was some problem getting the image data at that position,
or just no reference image is selected.
*/
Image::Pointer GetAffectedReferenceSlice(const InteractionPositionEvent*);
void WriteBackSegmentationResult (const InteractionPositionEvent*, Image*);
void WriteBackSegmentationResult (const PlaneGeometry* planeGeometry, Image*, unsigned int timeStep);
- void WriteBackSegmentationResult (std::vector<SliceInformation> sliceList);
+ void WriteBackSegmentationResult (std::vector<SliceInformation> sliceList, bool writeSliceToVolume = true);
+ void WriteSliceToVolume (SliceInformation sliceInfo);
/**
\brief Adds a new node called Contourmarker to the datastorage which holds a mitk::PlanarFigure.
By selecting this node the slicestack will be reoriented according to the PlanarFigure's Geometry
*/
- unsigned int AddContourmarker ();
+ int AddContourmarker();
void InteractiveSegmentationBugMessage( const std::string& message );
BaseRenderer* m_LastEventSender;
unsigned int m_LastEventSlice;
private:
- void WriteSliceToVolume (SliceInformation sliceInfo);
//The prefix of the contourmarkername. Suffix is a consecutive number
const std::string m_Contourmarkername;
bool m_ShowMarkerNodes;
static bool m_SurfaceInterpolationEnabled;
DiffSliceOperation* m_doOperation;
DiffSliceOperation* m_undoOperation;
};
} // namespace
#endif
diff --git a/Modules/Segmentation/Interactions/mitkSetRegionTool.cpp b/Modules/Segmentation/Interactions/mitkSetRegionTool.cpp
index cb06c84c52..7755be5232 100644
--- a/Modules/Segmentation/Interactions/mitkSetRegionTool.cpp
+++ b/Modules/Segmentation/Interactions/mitkSetRegionTool.cpp
@@ -1,338 +1,323 @@
/*===================================================================
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 "mitkSetRegionTool.h"
#include "mitkToolManager.h"
#include "mitkOverwriteSliceImageFilter.h"
#include "mitkAbstractTransformGeometry.h"
#include "ipSegmentation.h"
#include "mitkBaseRenderer.h"
#include "mitkImageDataItem.h"
#include "mitkLegacyAdaptors.h"
#include "mitkOverwriteDirectedPlaneImageFilter.h"
mitk::SetRegionTool::SetRegionTool(int paintingPixelValue)
:FeedbackContourTool("PressMoveReleaseWithCTRLInversion"),
m_PaintingPixelValue(paintingPixelValue),
m_FillContour(false),
m_StatusFillWholeSlice(false)
{
}
mitk::SetRegionTool::~SetRegionTool()
{
}
void mitk::SetRegionTool::ConnectActionsAndFunctions()
{
CONNECT_FUNCTION( "PrimaryButtonPressed", OnMousePressed);
CONNECT_FUNCTION( "Release", OnMouseReleased);
CONNECT_FUNCTION( "InvertLogic", OnInvertLogic);
}
void mitk::SetRegionTool::Activated()
{
Superclass::Activated();
}
void mitk::SetRegionTool::Deactivated()
{
Superclass::Deactivated();
}
bool mitk::SetRegionTool::OnMousePressed ( StateMachineAction*, InteractionEvent* interactionEvent )
{
- if ( SegTool2D::CanHandleEvent(interactionEvent) < 1.0 )
- return false;
-
mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
//const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
if (!positionEvent) return false;
m_LastEventSender = positionEvent->GetSender();
m_LastEventSlice = m_LastEventSender->GetSlice();
int timeStep = positionEvent->GetSender()->GetTimeStep();
- if ( FeedbackContourTool::CanHandleEvent(interactionEvent) < 1.0 ) return false;
-
-
// 1. Get the working image
Image::Pointer workingSlice = FeedbackContourTool::GetAffectedWorkingSlice( positionEvent );
if ( workingSlice.IsNull() ) return false; // can't do anything without the segmentation
// if click was outside the image, don't continue
const BaseGeometry* sliceGeometry = workingSlice->GetGeometry();
itk::Index<2> projectedPointIn2D;
sliceGeometry->WorldToIndex( positionEvent->GetPositionInWorld(), projectedPointIn2D );
if ( !sliceGeometry->IsIndexInside( projectedPointIn2D ) )
{
MITK_ERROR << "point apparently not inside segmentation slice" << std::endl;
return false; // can't use that as a seed point
}
// Convert to ipMITKSegmentationTYPE (because ipMITKSegmentationGetContour8N relys on that data type)
itk::Image< ipMITKSegmentationTYPE, 2 >::Pointer correctPixelTypeImage;
CastToItkImage( workingSlice, correctPixelTypeImage );
assert (correctPixelTypeImage.IsNotNull() );
// possible bug in CastToItkImage ?
// direction maxtrix is wrong/broken/not working after CastToItkImage, leading to a failed assertion in
// mitk/Core/DataStructures/mitkSlicedGeometry3D.cpp, 479:
// virtual void mitk::SlicedGeometry3D::SetSpacing(const mitk::Vector3D&): Assertion `aSpacing[0]>0 && aSpacing[1]>0 && aSpacing[2]>0' failed
// solution here: we overwrite it with an unity matrix
itk::Image< ipMITKSegmentationTYPE, 2 >::DirectionType imageDirection;
imageDirection.SetIdentity();
correctPixelTypeImage->SetDirection(imageDirection);
Image::Pointer temporarySlice = Image::New();
// temporarySlice = ImportItkImage( correctPixelTypeImage );
CastToMitkImage( correctPixelTypeImage, temporarySlice );
// check index positions
mitkIpPicDescriptor* originalPicSlice = mitkIpPicNew();
CastToIpPicDescriptor( temporarySlice, originalPicSlice );
int m_SeedPointMemoryOffset = projectedPointIn2D[1] * originalPicSlice->n[0] + projectedPointIn2D[0];
if ( m_SeedPointMemoryOffset >= static_cast<int>( originalPicSlice->n[0] * originalPicSlice->n[1] ) ||
m_SeedPointMemoryOffset < 0 )
{
MITK_ERROR << "Memory offset calculation if mitk::SetRegionTool has some serious flaw! Aborting.." << std::endl;
return false;
}
// 2. Determine the contour that surronds the selected "piece of the image"
// find a contour seed point
unsigned int oneContourOffset = static_cast<unsigned int>( m_SeedPointMemoryOffset ); // safe because of earlier check if m_SeedPointMemoryOffset < 0
/**
* The logic of finding a starting point for the contour is the following:
*
* - If the initial seed point is 0, we are either inside a hole or outside of every segmentation.
* We move to the right until we hit a 1, which must be part of a contour.
*
* - If the initial seed point is 1, then ...
* we now do the same (running to the right) until we hit a 1
*
* In both cases the found contour point is used to extract a contour and
* then a test is applied to find out if the initial seed point is contained
* in the contour. If this is the case, filling should be applied, otherwise
* nothing is done.
*/
unsigned int size = originalPicSlice->n[0] * originalPicSlice->n[1];
/*
unsigned int rowSize = originalPicSlice->n[0];
*/
ipMITKSegmentationTYPE* data = static_cast<ipMITKSegmentationTYPE*>(originalPicSlice->data);
if ( data[oneContourOffset] == 0 ) // initial seed 0
{
for ( ; oneContourOffset < size; ++oneContourOffset )
{
if ( data[oneContourOffset] > 0 ) break;
}
}
else if ( data[oneContourOffset] == 1 ) // initial seed 1
{
unsigned int lastValidPixel = size-1; // initialization, will be changed lateron
bool inSeg = true; // inside segmentation?
for ( ; oneContourOffset < size; ++oneContourOffset )
{
if ( ( data[oneContourOffset] == 0 ) && inSeg ) // pixel 0 and inside-flag set: this happens at the first pixel outside a filled region
{
inSeg = false;
lastValidPixel = oneContourOffset - 1; // store the last pixel position inside a filled region
break;
}
else // pixel 1, inside-flag doesn't matter: this happens while we are inside a filled region
{
inSeg = true; // first iteration lands here
}
}
oneContourOffset = lastValidPixel;
}
else
{
MITK_ERROR << "Fill/Erase was never intended to work with other than binary images." << std::endl;
m_FillContour = false;
return false;
}
if (oneContourOffset == size) // nothing found until end of slice
{
m_FillContour = false;
return false;
}
int numberOfContourPoints( 0 );
int newBufferSize( 0 );
//MITK_INFO << "getting contour from offset " << oneContourOffset << " ("<<oneContourOffset%originalPicSlice->n[0]<<","<<oneContourOffset/originalPicSlice->n[0]<<")"<<std::endl;
float* contourPoints = ipMITKSegmentationGetContour8N( originalPicSlice, oneContourOffset, numberOfContourPoints, newBufferSize ); // memory allocated with malloc
//MITK_INFO << "contourPoints " << contourPoints << " (N="<<numberOfContourPoints<<")"<<std::endl;
assert(contourPoints == NULL || numberOfContourPoints > 0);
bool cursorInsideContour = ipMITKSegmentationIsInsideContour( contourPoints, numberOfContourPoints, projectedPointIn2D[0], projectedPointIn2D[1]);
// decide if contour should be filled or not
m_FillContour = cursorInsideContour;
if (m_FillContour)
{
// copy point from float* to mitk::Contour
ContourModel::Pointer contourInImageIndexCoordinates = ContourModel::New();
contourInImageIndexCoordinates->Expand(timeStep + 1);
contourInImageIndexCoordinates->SetClosed(true, timeStep);
Point3D newPoint;
for (int index = 0; index < numberOfContourPoints; ++index)
{
newPoint[0] = contourPoints[ 2 * index + 0 ] - 0.5;
newPoint[1] = contourPoints[ 2 * index + 1] - 0.5;
newPoint[2] = 0;
contourInImageIndexCoordinates->AddVertex(newPoint, timeStep);
}
m_SegmentationContourInWorldCoordinates = FeedbackContourTool::BackProjectContourFrom2DSlice( workingSlice->GetGeometry(), contourInImageIndexCoordinates, true ); // true, correct the result from ipMITKSegmentationGetContour8N
// 3. Show the contour
FeedbackContourTool::SetFeedbackContour( *m_SegmentationContourInWorldCoordinates );
FeedbackContourTool::SetFeedbackContourVisible(true);
mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
}
// always generate a second contour, containing the whole image (used when CTRL is pressed)
{
// copy point from float* to mitk::Contour
ContourModel::Pointer contourInImageIndexCoordinates = ContourModel::New();
contourInImageIndexCoordinates->Expand(timeStep + 1);
contourInImageIndexCoordinates->SetClosed(true, timeStep);
Point3D newPoint;
newPoint[0] = 0; newPoint[1] = 0; newPoint[2] = 0.0;
contourInImageIndexCoordinates->AddVertex( newPoint, timeStep );
newPoint[0] = originalPicSlice->n[0]; newPoint[1] = 0; newPoint[2] = 0.0;
contourInImageIndexCoordinates->AddVertex( newPoint, timeStep );
newPoint[0] = originalPicSlice->n[0]; newPoint[1] = originalPicSlice->n[1]; newPoint[2] = 0.0;
contourInImageIndexCoordinates->AddVertex( newPoint, timeStep );
newPoint[0] = 0; newPoint[1] = originalPicSlice->n[1]; newPoint[2] = 0.0;
contourInImageIndexCoordinates->AddVertex( newPoint, timeStep );
m_WholeImageContourInWorldCoordinates = FeedbackContourTool::BackProjectContourFrom2DSlice( workingSlice->GetGeometry(), contourInImageIndexCoordinates, true ); // true, correct the result from ipMITKSegmentationGetContour8N
// 3. Show the contour
FeedbackContourTool::SetFeedbackContour( *m_SegmentationContourInWorldCoordinates );
FeedbackContourTool::SetFeedbackContourVisible(true);
mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
}
free(contourPoints);
return true;
}
bool mitk::SetRegionTool::OnMouseReleased( StateMachineAction*, InteractionEvent* interactionEvent )
{
- if ( SegTool2D::CanHandleEvent(interactionEvent) < 1.0 )
- return false;
-
// 1. Hide the feedback contour, find out which slice the user clicked, find out which slice of the toolmanager's working image corresponds to that
FeedbackContourTool::SetFeedbackContourVisible(false);
mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
- //const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
if (!positionEvent) return false;
assert( positionEvent->GetSender()->GetRenderWindow() );
mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
int timeStep = positionEvent->GetSender()->GetTimeStep();
if (!m_FillContour && !m_StatusFillWholeSlice) return true;
- if ( FeedbackContourTool::CanHandleEvent(interactionEvent) < 1.0 ) return false;
-
DataNode* workingNode( m_ToolManager->GetWorkingData(0) );
if (!workingNode) return false;
Image* image = dynamic_cast<Image*>(workingNode->GetData());
const AbstractTransformGeometry* abstractTransformGeometry( dynamic_cast<const AbstractTransformGeometry*> (positionEvent->GetSender()->GetCurrentWorldPlaneGeometry() ) );
const PlaneGeometry* planeGeometry( dynamic_cast<const PlaneGeometry*> (positionEvent->GetSender()->GetCurrentWorldPlaneGeometry() ) );
if ( !image || !planeGeometry || abstractTransformGeometry ) return false;
Image::Pointer slice = FeedbackContourTool::GetAffectedImageSliceAs2DImage( positionEvent, image );
if ( slice.IsNull() )
{
MITK_ERROR << "Unable to extract slice." << std::endl;
return false;
}
ContourModel* feedbackContour( FeedbackContourTool::GetFeedbackContour() );
ContourModel::Pointer projectedContour = FeedbackContourTool::ProjectContourTo2DSlice( slice, feedbackContour, false, false ); // false: don't add 0.5 (done by FillContourInSlice)
// false: don't constrain the contour to the image's inside
if (projectedContour.IsNull()) return false;
FeedbackContourTool::FillContourInSlice( projectedContour, timeStep, slice, m_PaintingPixelValue );
this->WriteBackSegmentationResult(positionEvent, slice);
m_WholeImageContourInWorldCoordinates = NULL;
m_SegmentationContourInWorldCoordinates = NULL;
return true;
}
/**
Called when the CTRL key is pressed. Will change the painting pixel value from 0 to 1 or from 1 to 0.
*/
bool mitk::SetRegionTool::OnInvertLogic( StateMachineAction*, InteractionEvent* interactionEvent )
{
- if ( FeedbackContourTool::CanHandleEvent(interactionEvent) < 1.0 ) return false;
-
mitk::InteractionPositionEvent* positionEvent = dynamic_cast<mitk::InteractionPositionEvent*>( interactionEvent );
- //const PositionEvent* positionEvent = dynamic_cast<const PositionEvent*>(stateEvent->GetEvent());
if (!positionEvent) return false;
if (m_StatusFillWholeSlice)
{
// use contour extracted from image data
if (m_SegmentationContourInWorldCoordinates.IsNotNull())
FeedbackContourTool::SetFeedbackContour( *m_SegmentationContourInWorldCoordinates );
mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
}
else
{
// use some artificial contour
if (m_WholeImageContourInWorldCoordinates.IsNotNull())
FeedbackContourTool::SetFeedbackContour( *m_WholeImageContourInWorldCoordinates );
mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
}
m_StatusFillWholeSlice = !m_StatusFillWholeSlice;
return true;
}
diff --git a/Modules/SegmentationUI/Qmitk/QmitkAdaptiveRegionGrowingToolGUI.cpp b/Modules/SegmentationUI/Qmitk/QmitkAdaptiveRegionGrowingToolGUI.cpp
index 1c40262485..447f12fd68 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkAdaptiveRegionGrowingToolGUI.cpp
+++ b/Modules/SegmentationUI/Qmitk/QmitkAdaptiveRegionGrowingToolGUI.cpp
@@ -1,849 +1,855 @@
/*===================================================================
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 "QmitkAdaptiveRegionGrowingToolGUI.h"
#include "QmitkStdMultiWidget.h"
#include <qmessagebox.h>
#include "mitkNodePredicateDataType.h"
#include "mitkProperties.h"
#include "mitkITKImageImport.h"
#include "mitkImageAccessByItk.h"
#include "mitkTransferFunctionProperty.h"
#include "mitkImageTimeSelector.h"
#include "mitkImageStatisticsHolder.h"
#include <itkConnectedAdaptiveThresholdImageFilter.h>
#include <itkMinimumMaximumImageCalculator.h>
#include <itkBinaryThresholdImageFilter.h>
#include <itkImageIterator.h>
#include "itkOrImageFilter.h"
#include "mitkImageCast.h"
#include "QmitkConfirmSegmentationDialog.h"
#include "mitkPixelTypeMultiplex.h"
#include "mitkImagePixelReadAccessor.h"
MITK_TOOL_GUI_MACRO( , QmitkAdaptiveRegionGrowingToolGUI, "")
QmitkAdaptiveRegionGrowingToolGUI::QmitkAdaptiveRegionGrowingToolGUI(QWidget* parent) :
QmitkToolGUI(), m_MultiWidget(NULL), m_UseVolumeRendering(false), m_UpdateSuggestedThreshold(true), m_SuggestedThValue(0.0), m_DataStorage(NULL)
{
this->setParent(parent);
m_Controls.setupUi(this);
m_Controls.m_ThresholdSlider->setDecimals(1);
m_Controls.m_ThresholdSlider->setSpinBoxAlignment(Qt::AlignVCenter);
m_Controls.m_PreviewSlider->setEnabled(false);
m_Controls.m_PreviewSlider->setSingleStep(0.5);
//Not yet available
//m_Controls.m_PreviewSlider->InvertedAppearance(true);
this->CreateConnections();
this->SetDataNodeNames("labeledRGSegmentation","RGResult","RGFeedbackSurface");
connect( this, SIGNAL(NewToolAssociated(mitk::Tool*)), this, SLOT(OnNewToolAssociated(mitk::Tool*)) );
}
QmitkAdaptiveRegionGrowingToolGUI::~QmitkAdaptiveRegionGrowingToolGUI()
{
//Removing the observer of the PointSet node
if (m_RegionGrow3DTool->GetPointSetNode().IsNotNull())
{
m_RegionGrow3DTool->GetPointSetNode()->GetData()->RemoveObserver(m_PointSetAddObserverTag);
+ m_RegionGrow3DTool->GetPointSetNode()->GetData()->RemoveObserver(m_PointSetMoveObserverTag);
}
this->RemoveHelperNodes();
}
void QmitkAdaptiveRegionGrowingToolGUI::OnNewToolAssociated(mitk::Tool* tool)
{
m_RegionGrow3DTool = dynamic_cast<mitk::AdaptiveRegionGrowingTool*> (tool);
if(m_RegionGrow3DTool.IsNotNull())
{
SetInputImageNode( this->m_RegionGrow3DTool->GetReferenceData() );
this->m_DataStorage = this->m_RegionGrow3DTool->GetDataStorage();
this->EnableControls(true);
//Watch for point added or modified
itk::SimpleMemberCommand<QmitkAdaptiveRegionGrowingToolGUI>::Pointer pointAddedCommand = itk::SimpleMemberCommand<QmitkAdaptiveRegionGrowingToolGUI>::New();
pointAddedCommand->SetCallbackFunction(this, &QmitkAdaptiveRegionGrowingToolGUI::OnPointAdded);
m_PointSetAddObserverTag = m_RegionGrow3DTool->GetPointSetNode()->GetData()->AddObserver( mitk::PointSetAddEvent(), pointAddedCommand);
- m_PointSetAddObserverTag = m_RegionGrow3DTool->GetPointSetNode()->GetData()->AddObserver( mitk::PointSetMoveEvent(), pointAddedCommand);
+ m_PointSetMoveObserverTag = m_RegionGrow3DTool->GetPointSetNode()->GetData()->AddObserver( mitk::PointSetMoveEvent(), pointAddedCommand);
}
else
{
this->EnableControls(false);
}
}
void QmitkAdaptiveRegionGrowingToolGUI::RemoveHelperNodes()
{
mitk::DataNode::Pointer imageNode = m_DataStorage->GetNamedNode( m_NAMEFORLABLEDSEGMENTATIONIMAGE);
if( imageNode.IsNotNull() )
{
m_DataStorage->Remove(imageNode);
}
}
void QmitkAdaptiveRegionGrowingToolGUI::CreateConnections()
{
//Connecting GUI components
connect( (QObject*) (m_Controls.m_pbRunSegmentation), SIGNAL(clicked()), this, SLOT(RunSegmentation()));
connect( m_Controls.m_PreviewSlider, SIGNAL(valueChanged(double)), this, SLOT(ChangeLevelWindow(double)));
connect( (QObject*) (m_Controls.m_pbConfirmSegementation), SIGNAL(clicked()), this, SLOT(ConfirmSegmentation()));
connect( (QObject*) (m_Controls.m_cbVolumeRendering), SIGNAL(toggled(bool)), this, SLOT(UseVolumeRendering(bool) ));
connect( m_Controls.m_ThresholdSlider, SIGNAL(maximumValueChanged(double)), this, SLOT(SetUpperThresholdValue(double)));
connect( m_Controls.m_ThresholdSlider, SIGNAL(minimumValueChanged(double)), this, SLOT(SetLowerThresholdValue(double)));
}
void QmitkAdaptiveRegionGrowingToolGUI::SetDataNodeNames(std::string labledSegmentation, std::string binaryImage, std::string surface)
{
m_NAMEFORLABLEDSEGMENTATIONIMAGE = labledSegmentation;
m_NAMEFORBINARYIMAGE = binaryImage;
m_NAMEFORSURFACE = surface;
}
void QmitkAdaptiveRegionGrowingToolGUI::SetDataStorage(mitk::DataStorage* dataStorage)
{
m_DataStorage = dataStorage;
}
void QmitkAdaptiveRegionGrowingToolGUI::SetMultiWidget(QmitkStdMultiWidget* multiWidget)
{
m_MultiWidget = multiWidget;
}
void QmitkAdaptiveRegionGrowingToolGUI::SetInputImageNode(mitk::DataNode* node)
{
m_InputImageNode = node;
mitk::Image* inputImage = dynamic_cast<mitk::Image*>(m_InputImageNode->GetData());
if (inputImage)
{
mitk::ScalarType max = inputImage->GetStatistics()->GetScalarValueMax();
mitk::ScalarType min = inputImage->GetStatistics()->GetScalarValueMin();
m_Controls.m_ThresholdSlider->setMaximum(max);
m_Controls.m_ThresholdSlider->setMinimum(min);
// Just for initialization
m_Controls.m_ThresholdSlider->setMaximumValue(max);
m_Controls.m_ThresholdSlider->setMinimumValue(min);
}
}
template <typename TPixel>
static void AccessPixel(mitk::PixelType ptype, const mitk::Image::Pointer im, mitk::Point3D p, int & val)
{
mitk::ImagePixelReadAccessor<TPixel,3> access(im);
val = access.GetPixelByWorldCoordinates(p);
}
void QmitkAdaptiveRegionGrowingToolGUI::OnPointAdded()
{
if (m_RegionGrow3DTool.IsNull())
return;
mitk::DataNode* node = m_RegionGrow3DTool->GetPointSetNode();
if (node != NULL)
{
mitk::PointSet::Pointer pointSet = dynamic_cast<mitk::PointSet*>(node->GetData());
if (pointSet.IsNull())
{
QMessageBox::critical(NULL, "QmitkAdaptiveRegionGrowingToolGUI", "PointSetNode does not contain a pointset");
return;
}
m_Controls.m_lblSetSeedpoint->setText("");
mitk::Image* image = dynamic_cast<mitk::Image*>(m_InputImageNode->GetData());
+
mitk::Point3D seedPoint = pointSet->GetPointSet(mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1") )->GetTimeStep())->GetPoints()->ElementAt(0);
- mitkPixelTypeMultiplex3(AccessPixel,image->GetChannelDescriptor().GetPixelType(),image,seedPoint,m_SeedpointValue);
+
+ if (image->GetGeometry()->IsInside(seedPoint))
+ mitkPixelTypeMultiplex3(AccessPixel,image->GetChannelDescriptor().GetPixelType(),image,seedPoint,m_SeedpointValue)
+ else
+ return;
/* In this case the seedpoint is placed e.g. in the lung or bronchialtree
* The lowerFactor sets the windowsize depending on the regiongrowing direction
*/
m_CurrentRGDirectionIsUpwards = true;
if (m_SeedpointValue < -500)
{
m_CurrentRGDirectionIsUpwards = false;
}
// Initializing the region by the area around the seedpoint
m_SeedPointValueMean = 0;
itk::Index<3> currentIndex, runningIndex;
mitk::ScalarType pixelValues[125];
unsigned int pos (0);
image->GetGeometry(0)->WorldToIndex(seedPoint, currentIndex);
runningIndex = currentIndex;
for(int i = runningIndex[0]-2; i <= runningIndex[0]+2; i++)
{
for(int j = runningIndex[1]-2; j <= runningIndex[1]+2; j++)
{
for(int k = runningIndex[2]-2; k <= runningIndex[2]+2; k++)
{
currentIndex[0] = i;
currentIndex[1] = j;
currentIndex[2] = k;
if(image->GetGeometry()->IsIndexInside(currentIndex))
{
int component = 0;
m_InputImageNode->GetIntProperty("Image.Displayed Component", component);
pixelValues[pos] = image->GetPixelValueByIndex(currentIndex, 0, component);
pos++;
}
else
{
pixelValues[pos] = -10000000;
pos++;
}
}
}
}
//Now calculation mean of the pixelValues
unsigned int numberOfValues(0);
for (unsigned int i = 0; i < 125; i++)
{
if(pixelValues[i] > -10000000)
{
m_SeedPointValueMean += pixelValues[i];
numberOfValues++;
}
}
m_SeedPointValueMean = m_SeedPointValueMean/numberOfValues;
/*
* Here the upper- and lower threshold is calculated:
* The windowSize is 20% of the maximum range of the intensity values existing in the current image
* If the RG direction is upwards the lower TH is meanSeedValue-0.15*windowSize and upper TH is meanSeedValue+0.85*windowsSize
* if the RG direction is downwards the lower TH is meanSeedValue-0.85*windowSize and upper TH is meanSeedValue+0.15*windowsSize
*/
mitk::ScalarType min = image->GetStatistics()->GetScalarValueMin();
mitk::ScalarType max = image->GetStatistics()->GetScalarValueMax();
mitk::ScalarType windowSize = max - min;
windowSize = 0.15*windowSize;
if (m_CurrentRGDirectionIsUpwards)
{
m_LOWERTHRESHOLD = m_SeedPointValueMean;
if (m_SeedpointValue < m_SeedPointValueMean)
m_LOWERTHRESHOLD = m_SeedpointValue;
m_UPPERTHRESHOLD = m_SeedpointValue + windowSize;
if (m_UPPERTHRESHOLD > max)
m_UPPERTHRESHOLD = max;
m_Controls.m_ThresholdSlider->setMaximumValue(m_UPPERTHRESHOLD);
m_Controls.m_ThresholdSlider->setMinimumValue(m_LOWERTHRESHOLD);
}
else
{
m_UPPERTHRESHOLD = m_SeedPointValueMean;
if (m_SeedpointValue > m_SeedPointValueMean)
m_UPPERTHRESHOLD = m_SeedpointValue;
m_LOWERTHRESHOLD = m_SeedpointValue - windowSize;
if (m_LOWERTHRESHOLD < min)
m_LOWERTHRESHOLD = min;
m_Controls.m_ThresholdSlider->setMinimumValue(m_LOWERTHRESHOLD);
m_Controls.m_ThresholdSlider->setMaximumValue(m_UPPERTHRESHOLD);
}
}
}
void QmitkAdaptiveRegionGrowingToolGUI::RunSegmentation()
{
if (m_InputImageNode.IsNull())
{
QMessageBox::information( NULL, "Adaptive Region Growing functionality", "Please specify the image in Datamanager!");
return;
}
mitk::DataNode::Pointer node = m_RegionGrow3DTool->GetPointSetNode();
if (node.IsNull())
{
QMessageBox::information( NULL, "Adaptive Region Growing functionality", "Please insert a seed point inside the image.\n\nFirst press the \"Define Seed Point\" button,\nthen click left mouse button inside the image.");
return;
}
//safety if no pointSet or pointSet empty
mitk::PointSet::Pointer seedPointSet = dynamic_cast<mitk::PointSet*> (node->GetData());
if (seedPointSet.IsNull())
{
m_Controls.m_pbRunSegmentation->setEnabled(true);
QMessageBox::information( NULL, "Adaptive Region Growing functionality", "The seed point is empty! Please choose a new seed point.");
return;
}
int timeStep = mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1") )->GetTimeStep();
if (!(seedPointSet->GetSize(timeStep)))
{
m_Controls.m_pbRunSegmentation->setEnabled(true);
QMessageBox::information( NULL, "Adaptive Region Growing functionality", "The seed point is empty! Please choose a new seed point.");
return;
}
QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) );
mitk::PointSet::PointType seedPoint = seedPointSet->GetPointSet(timeStep)->GetPoints()->Begin().Value();
mitk::Image::Pointer orgImage = dynamic_cast<mitk::Image*> (m_InputImageNode->GetData());
if (orgImage.IsNotNull())
{
if (orgImage->GetDimension() == 4)
{
mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New();
timeSelector->SetInput(orgImage);
timeSelector->SetTimeNr( timeStep );
timeSelector->UpdateLargestPossibleRegion();
mitk::Image* timedImage = timeSelector->GetOutput();
AccessByItk_2( timedImage , StartRegionGrowing, timedImage->GetGeometry(), seedPoint);
}
else if (orgImage->GetDimension() == 3)
{
//QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); //set the cursor to waiting
AccessByItk_2(orgImage, StartRegionGrowing, orgImage->GetGeometry(), seedPoint);
//QApplication::restoreOverrideCursor();//reset cursor
}
else
{
QApplication::restoreOverrideCursor();//reset cursor
QMessageBox::information( NULL, "Adaptive Region Growing functionality", "Only images of dimension 3 or 4 can be processed!");
return;
}
}
EnableControls(true); // Segmentation ran successfully, so enable all controls.
node->SetVisibility(true);
QApplication::restoreOverrideCursor();//reset cursor
}
template<typename TPixel, unsigned int VImageDimension>
void QmitkAdaptiveRegionGrowingToolGUI::StartRegionGrowing(itk::Image<TPixel, VImageDimension>* itkImage, mitk::BaseGeometry* imageGeometry, mitk::PointSet::PointType seedPoint)
{
typedef itk::Image<TPixel, VImageDimension> InputImageType;
typedef typename InputImageType::IndexType IndexType;
typedef itk::ConnectedAdaptiveThresholdImageFilter<InputImageType, InputImageType> RegionGrowingFilterType;
typename RegionGrowingFilterType::Pointer regionGrower = RegionGrowingFilterType::New();
typedef itk::MinimumMaximumImageCalculator<InputImageType> MinMaxValueFilterType;
if ( !imageGeometry->IsInside(seedPoint) )
{
QApplication::restoreOverrideCursor();//reset cursor to be able to click ok with the regular mouse cursor
QMessageBox::information( NULL, "Segmentation functionality", "The seed point is outside of the image! Please choose a position inside the image!");
return;
}
IndexType seedIndex;
imageGeometry->WorldToIndex( seedPoint, seedIndex);// convert world coordinates to image indices
if (m_SeedpointValue>m_UPPERTHRESHOLD || m_SeedpointValue<m_LOWERTHRESHOLD)
{
QApplication::restoreOverrideCursor();//reset cursor to be able to click ok with the regular mouse cursor
QMessageBox::information( NULL, "Segmentation functionality", "The seed point is outside the defined thresholds! Please set a new seed point or adjust the thresholds.");
MITK_INFO << "Mean: " <<m_SeedPointValueMean;
return;
}
//Setting the direction of the regiongrowing. For dark structures e.g. the lung the regiongrowing
//is performed starting at the upper value going to the lower one
regionGrower->SetGrowingDirectionIsUpwards( m_CurrentRGDirectionIsUpwards );
regionGrower->SetInput( itkImage );
regionGrower->AddSeed( seedIndex );
//In some cases we have to subtract 1 for the lower threshold and add 1 to the upper.
//Otherwise no region growing is done. Maybe a bug in the ConnectiveAdaptiveThresholdFilter
regionGrower->SetLower( m_LOWERTHRESHOLD-1 );
regionGrower->SetUpper( m_UPPERTHRESHOLD+1);
try
{
regionGrower->Update();
}
catch(itk::ExceptionObject &exc)
{
QMessageBox errorInfo;
errorInfo.setWindowTitle("Adaptive RG Segmentation Functionality");
errorInfo.setIcon(QMessageBox::Critical);
errorInfo.setText("An error occurred during region growing!");
errorInfo.setDetailedText(exc.what());
errorInfo.exec();
return; // can't work
}
catch( ... )
{
QMessageBox::critical( NULL, "Adaptive RG Segmentation Functionality", "An error occurred during region growing!");
return;
}
mitk::Image::Pointer resultImage = mitk::ImportItkImage(regionGrower->GetOutput())->Clone();
//initialize slider
m_Controls.m_PreviewSlider->setMinimum(m_LOWERTHRESHOLD);
mitk::ScalarType max = m_LOWERTHRESHOLD+resultImage->GetStatistics()->GetScalarValueMax();
if (max < m_UPPERTHRESHOLD)
m_Controls.m_PreviewSlider->setMaximum(max);
else
m_Controls.m_PreviewSlider->setMaximum(m_UPPERTHRESHOLD);
this->m_DetectedLeakagePoint = regionGrower->GetLeakagePoint();
if(m_CurrentRGDirectionIsUpwards)
{
m_Controls.m_PreviewSlider->setValue(m_SeedPointValueMean-1);
}
else
{
m_Controls.m_PreviewSlider->setValue(m_SeedPointValueMean+1);
}
this->m_SliderInitialized = true;
//create new node and then delete the old one if there is one
mitk::DataNode::Pointer newNode = mitk::DataNode::New();
newNode->SetData( resultImage );
// set some properties
newNode->SetProperty("name", mitk::StringProperty::New(m_NAMEFORLABLEDSEGMENTATIONIMAGE));
newNode->SetProperty("helper object", mitk::BoolProperty::New(true));
newNode->SetProperty("color", mitk::ColorProperty::New(0.0,1.0,0.0));
newNode->SetProperty("layer", mitk::IntProperty::New(1));
newNode->SetProperty("opacity", mitk::FloatProperty::New(0.7));
//delete the old image, if there was one:
mitk::DataNode::Pointer binaryNode = m_DataStorage->GetNamedNode(m_NAMEFORLABLEDSEGMENTATIONIMAGE);
m_DataStorage->Remove(binaryNode);
// now add result to data tree
m_DataStorage->Add( newNode, m_InputImageNode );
this->InitializeLevelWindow();
if(m_UseVolumeRendering)
this->EnableVolumeRendering(true);
m_UpdateSuggestedThreshold = true;// reset first stored threshold value
//Setting progress to finished
mitk::ProgressBar::GetInstance()->Progress(357);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkAdaptiveRegionGrowingToolGUI::InitializeLevelWindow()
{
//get the preview from the datatree
mitk::DataNode::Pointer newNode = m_DataStorage->GetNamedNode( m_NAMEFORLABLEDSEGMENTATIONIMAGE);
mitk::LevelWindow tempLevelWindow;
newNode->GetLevelWindow(tempLevelWindow, NULL, "levelwindow");
mitk::ScalarType* level = new mitk::ScalarType(0.0);
mitk::ScalarType* window = new mitk::ScalarType(1.0);
int upper;
if (m_CurrentRGDirectionIsUpwards)
{
upper = m_UPPERTHRESHOLD - m_SeedpointValue;
}
else
{
upper = m_SeedpointValue - m_LOWERTHRESHOLD;
}
tempLevelWindow.SetRangeMinMax(mitk::ScalarType(0), mitk::ScalarType(upper));
//get the suggested threshold from the detected leakage-point and adjust the slider
if (m_CurrentRGDirectionIsUpwards)
{
this->m_Controls.m_PreviewSlider->setValue(m_SeedpointValue);
*level = m_UPPERTHRESHOLD - (m_SeedpointValue) + 0.5;
}
else
{
this->m_Controls.m_PreviewSlider->setValue(m_SeedpointValue);
*level = (m_SeedpointValue) - m_LOWERTHRESHOLD + 0.5;
}
tempLevelWindow.SetLevelWindow(*level, *window);
newNode->SetLevelWindow(tempLevelWindow, NULL, "levelwindow");
//update the widgets
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
m_SliderInitialized = true;
//inquiry need to fix bug#1828
static int lastSliderPosition = 0;
if ((this->m_SeedpointValue + this->m_DetectedLeakagePoint - 1) == lastSliderPosition)
{
this->ChangeLevelWindow(lastSliderPosition);
}
lastSliderPosition = this->m_SeedpointValue + this->m_DetectedLeakagePoint-1;
if(m_MultiWidget)
{
this->m_MultiWidget->levelWindowWidget->GetManager()->SetAutoTopMostImage(false);
this->m_MultiWidget->levelWindowWidget->GetManager()->SetLevelWindowProperty(static_cast<mitk::LevelWindowProperty*>(newNode->GetProperty("levelwindow")));
}
if (m_UseVolumeRendering)
this->UpdateVolumeRenderingThreshold((int) (*level + 0.5));//lower threshold for labeled image
}
void QmitkAdaptiveRegionGrowingToolGUI::ChangeLevelWindow(double newValue)
{
if (m_SliderInitialized)
{
//do nothing, if no preview exists
mitk::DataNode::Pointer newNode = m_DataStorage->GetNamedNode( m_NAMEFORLABLEDSEGMENTATIONIMAGE);
if (newNode.IsNull())
return;
mitk::LevelWindow tempLevelWindow;
newNode->GetLevelWindow(tempLevelWindow, NULL, "levelwindow"); //get the levelWindow associated with the preview
mitk::ScalarType level;// = this->m_UPPERTHRESHOLD - newValue + 0.5;
mitk::ScalarType* window = new mitk::ScalarType(1);
//adjust the levelwindow according to the position of the slider (newvalue)
if (m_CurrentRGDirectionIsUpwards)
{
level = m_UPPERTHRESHOLD - newValue + 0.5;
tempLevelWindow.SetLevelWindow(level, *window);
}
else
{
level = newValue - m_LOWERTHRESHOLD +0.5;
tempLevelWindow.SetLevelWindow(level, *window);
}
newNode->SetLevelWindow(tempLevelWindow, NULL, "levelwindow");
if (m_UseVolumeRendering)
this->UpdateVolumeRenderingThreshold((int) (level - 0.5));//lower threshold for labeled image
newNode->SetVisibility(true);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void QmitkAdaptiveRegionGrowingToolGUI::DecreaseSlider()
{
//moves the slider one step to the left, when the "-"-button is pressed
if (this->m_Controls.m_PreviewSlider->value() != this->m_Controls.m_PreviewSlider->minimum())
{
int newValue = this->m_Controls.m_PreviewSlider->value() - 1;
this->ChangeLevelWindow(newValue);
this->m_Controls.m_PreviewSlider->setValue(newValue);
}
}
void QmitkAdaptiveRegionGrowingToolGUI::IncreaseSlider()
{
//moves the slider one step to the right, when the "+"-button is pressed
if (this->m_Controls.m_PreviewSlider->value() != this->m_Controls.m_PreviewSlider->maximum())
{
int newValue = this->m_Controls.m_PreviewSlider->value() + 1;
this->ChangeLevelWindow(newValue);
this->m_Controls.m_PreviewSlider->setValue(newValue);
}
}
void QmitkAdaptiveRegionGrowingToolGUI::ConfirmSegmentation()
{
//get image node
if(m_InputImageNode.IsNull())
{
QMessageBox::critical( NULL, "Adaptive region growing functionality", "Please specify the image in Datamanager!");
return;
}
//get image data
mitk::Image::Pointer orgImage = dynamic_cast<mitk::Image*> (m_InputImageNode->GetData());
if(orgImage.IsNull())
{
QMessageBox::critical( NULL, "Adaptive region growing functionality", "No Image found!");
return;
}
//get labeled segmentation
mitk::Image::Pointer labeledSeg = (mitk::Image*)m_DataStorage->GetNamedObject<mitk::Image>(m_NAMEFORLABLEDSEGMENTATIONIMAGE);
if(labeledSeg.IsNull())
{
QMessageBox::critical( NULL, "Adaptive region growing functionality", "No Segmentation Preview found!");
return;
}
mitk::DataNode::Pointer newNode = m_DataStorage->GetNamedNode( m_NAMEFORLABLEDSEGMENTATIONIMAGE);
if (newNode.IsNull())
return;
QmitkConfirmSegmentationDialog dialog;
QString segName = QString::fromStdString(m_RegionGrow3DTool->GetCurrentSegmentationName());
dialog.SetSegmentationName(segName);
int result = dialog.exec();
switch(result)
{
case QmitkConfirmSegmentationDialog::CREATE_NEW_SEGMENTATION:
m_RegionGrow3DTool->SetOverwriteExistingSegmentation(false);
break;
case QmitkConfirmSegmentationDialog::OVERWRITE_SEGMENTATION:
m_RegionGrow3DTool->SetOverwriteExistingSegmentation(true);
break;
case QmitkConfirmSegmentationDialog::CANCEL_SEGMENTATION:
return;
}
mitk::Image* img = dynamic_cast<mitk::Image*>(newNode->GetData());
AccessByItk(img, ITKThresholding);
// disable volume rendering preview after the segmentation node was created
this->EnableVolumeRendering(false);
newNode->SetVisibility(false);
m_Controls.m_cbVolumeRendering->setChecked(false);
//TODO disable slider etc...
}
template<typename TPixel, unsigned int VImageDimension>
void QmitkAdaptiveRegionGrowingToolGUI::ITKThresholding(itk::Image<TPixel, VImageDimension>* itkImage)
{
mitk::Image::Pointer originalSegmentation = dynamic_cast<mitk::Image*>(this->m_RegionGrow3DTool->
GetTargetSegmentationNode()->GetData());
int timeStep = mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1") )->GetTimeStep();
if (originalSegmentation)
{
typedef itk::Image<TPixel, VImageDimension> InputImageType;
typedef itk::Image<unsigned char, VImageDimension> SegmentationType;
//select single 3D volume if we have more than one time step
typename SegmentationType::Pointer originalSegmentationInITK = SegmentationType::New();
if(originalSegmentation->GetTimeGeometry()->CountTimeSteps() > 1)
{
mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New();
timeSelector->SetInput( originalSegmentation );
timeSelector->SetTimeNr( timeStep );
timeSelector->UpdateLargestPossibleRegion();
CastToItkImage( timeSelector->GetOutput(), originalSegmentationInITK );
}
else //use original
{
CastToItkImage( originalSegmentation, originalSegmentationInITK );
}
//Fill current preiview image in segmentation image
originalSegmentationInITK->FillBuffer(0);
itk::ImageRegionIterator<SegmentationType> itOutput( originalSegmentationInITK, originalSegmentationInITK->GetLargestPossibleRegion() );
itk::ImageRegionIterator<InputImageType> itInput( itkImage, itkImage->GetLargestPossibleRegion() );
itOutput.GoToBegin();
itInput.GoToBegin();
//calculate threhold from slider value
int currentTreshold = 0;
if (m_CurrentRGDirectionIsUpwards)
{
currentTreshold = m_UPPERTHRESHOLD - m_Controls.m_PreviewSlider->value() + 1;
}
else
{
currentTreshold = m_Controls.m_PreviewSlider->value() - m_LOWERTHRESHOLD;
}
//iterate over image and set pixel in segmentation according to thresholded labeled image
while( !itOutput.IsAtEnd() && !itInput.IsAtEnd() )
{
//Use threshold slider to determine if pixel is set to 1
if( itInput.Value() != 0 && itInput.Value() > currentTreshold )
{
itOutput.Set( 1 );
}
++itOutput;
++itInput;
}
//combine current working segmentation image with our region growing result
originalSegmentation->SetVolume( (void*)(originalSegmentationInITK->GetPixelContainer()->GetBufferPointer()), timeStep);
originalSegmentation->Modified();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void QmitkAdaptiveRegionGrowingToolGUI::EnableControls(bool enable)
{
if (m_RegionGrow3DTool.IsNull())
return;
// Check if seed point is already set, if not leave RunSegmentation disabled
//if even m_DataStorage is NULL leave node NULL
mitk::DataNode::Pointer node = m_RegionGrow3DTool->GetPointSetNode();
if (node.IsNull()) {
this->m_Controls.m_pbRunSegmentation->setEnabled(false);
}
else
{
this->m_Controls.m_pbRunSegmentation->setEnabled(enable);
}
// Check if a segmentation exists, if not leave segmentation dependent disabled.
//if even m_DataStorage is NULL leave node NULL
node = m_DataStorage?m_DataStorage->GetNamedNode(m_NAMEFORLABLEDSEGMENTATIONIMAGE):NULL;
if (node.IsNull())
{
this->m_Controls.m_PreviewSlider->setEnabled(false);
this->m_Controls.m_pbConfirmSegementation->setEnabled(false);
}
else
{
this->m_Controls.m_PreviewSlider->setEnabled(enable);
this->m_Controls.m_pbConfirmSegementation->setEnabled(enable);
}
this->m_Controls.m_cbVolumeRendering->setEnabled(enable);
}
void QmitkAdaptiveRegionGrowingToolGUI::EnableVolumeRendering(bool enable)
{
mitk::DataNode::Pointer node = m_DataStorage->GetNamedNode( m_NAMEFORLABLEDSEGMENTATIONIMAGE);
if(node.IsNull())
return;
if(m_MultiWidget)
m_MultiWidget->SetWidgetPlanesVisibility(!enable);
if (enable)
{
node->SetBoolProperty("volumerendering", enable);
node->SetBoolProperty("volumerendering.uselod", true);
}
else
{
node->SetBoolProperty("volumerendering", enable);
}
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkAdaptiveRegionGrowingToolGUI::UpdateVolumeRenderingThreshold(int thValue)
{
mitk::DataNode::Pointer node = m_DataStorage->GetNamedNode( m_NAMEFORLABLEDSEGMENTATIONIMAGE);
mitk::TransferFunction::Pointer tf = mitk::TransferFunction::New();
if (m_UpdateSuggestedThreshold)
{
m_SuggestedThValue = thValue;
m_UpdateSuggestedThreshold = false;
}
// grayvalue->opacity
{
vtkPiecewiseFunction *f = tf->GetScalarOpacityFunction();
f->RemoveAllPoints();
f->AddPoint(0, 0);
f->AddPoint(thValue+0.5, 0);
f->AddPoint(thValue+1.5, 1);
f->AddPoint(1000, 1);
f->ClampingOn();
f->Modified();
}
// grayvalue->color
{
float a = 255.0;
vtkColorTransferFunction *ctf = tf->GetColorTransferFunction();
ctf->RemoveAllPoints();
//ctf->AddRGBPoint(-1000, 0.0, 0.0, 0.0);
ctf->AddRGBPoint(m_SuggestedThValue+1, 203/a, 104/a, 102/a);
ctf->AddRGBPoint(m_SuggestedThValue, 255/a, 0/a, 0/a);
ctf->ClampingOn();
ctf->Modified();
}
// GradientOpacityFunction
{
vtkPiecewiseFunction *gof = tf->GetGradientOpacityFunction();
gof->RemoveAllPoints();
gof->AddPoint(-10000, 1);
gof->AddPoint(10000, 1);
gof->ClampingOn();
gof->Modified();
}
mitk::TransferFunctionProperty::Pointer tfp = mitk::TransferFunctionProperty::New();
tfp->SetValue(tf);
node->SetProperty("TransferFunction", tfp);
}
void QmitkAdaptiveRegionGrowingToolGUI::UseVolumeRendering(bool on)
{
m_UseVolumeRendering = on;
this->EnableVolumeRendering(on);
}
void QmitkAdaptiveRegionGrowingToolGUI::SetLowerThresholdValue( double lowerThreshold )
{
m_LOWERTHRESHOLD = lowerThreshold;
}
void QmitkAdaptiveRegionGrowingToolGUI::SetUpperThresholdValue( double upperThreshold)
{
m_UPPERTHRESHOLD = upperThreshold;
}
void QmitkAdaptiveRegionGrowingToolGUI::Deactivated()
{
// make the segmentation preview node invisible
mitk::DataNode::Pointer node = m_DataStorage->GetNamedNode( m_NAMEFORLABLEDSEGMENTATIONIMAGE);
if( node.IsNotNull() )
{
node->SetVisibility(false);
}
// disable volume rendering preview after the segmentation node was created
this->EnableVolumeRendering(false);
m_Controls.m_cbVolumeRendering->setChecked(false);
}
void QmitkAdaptiveRegionGrowingToolGUI::Activated()
{
}
diff --git a/Modules/SegmentationUI/Qmitk/QmitkAdaptiveRegionGrowingToolGUI.h b/Modules/SegmentationUI/Qmitk/QmitkAdaptiveRegionGrowingToolGUI.h
index 467cd69ad5..690313b614 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkAdaptiveRegionGrowingToolGUI.h
+++ b/Modules/SegmentationUI/Qmitk/QmitkAdaptiveRegionGrowingToolGUI.h
@@ -1,233 +1,234 @@
/*===================================================================
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 QMITK_QmitkAdaptiveRegionGrowingToolGUI_H
#define QMITK_QmitkAdaptiveRegionGrowingToolGUI_H
#include "mitkDataStorage.h"
#include "itkImage.h"
#include "mitkGeometry3D.h"
#include "mitkPointSet.h"
#include "qwidget.h"
#include "ui_QmitkAdaptiveRegionGrowingToolGUIControls.h"
#include <MitkSegmentationUIExports.h>
#include "QmitkToolGUI.h"
#include "mitkAdaptiveRegionGrowingTool.h"
class QmitkStdMultiWidget;
class DataNode;
class QmitkAdaptiveRegionGrowingToolGUIControls;
/*!
*
* \brief QmitkAdaptiveRegionGrowingToolGUI
*
* Adaptive Region Growing View class of the segmentation.
*
*/
class MitkSegmentationUI_EXPORT QmitkAdaptiveRegionGrowingToolGUI : public QmitkToolGUI
{
Q_OBJECT
public:
/**
* @brief mitkClassMacro
*/
mitkClassMacro(QmitkAdaptiveRegionGrowingToolGUI, QmitkToolGUI);
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
QmitkAdaptiveRegionGrowingToolGUI(QWidget* parent=0);
/** \brief Method to create the connections for the component. This Method is obligatory even if no connections is needed*/
virtual void CreateConnections();
///** \brief Method to set the default data storage.*/
virtual void SetDataStorage(mitk::DataStorage* dataStorage);
/**
* @brief Method to set the used multiwidget.
* @param multiWidget
*/
void SetMultiWidget(QmitkStdMultiWidget* multiWidget);
/**
* @brief Method to set the name of a data node.
* @param labledSegmentation Name of the labeled segmentation
* @param binaryImage Name of the binary image
* @param surface Name of the surface
*/
void SetDataNodeNames(std::string labledSegmentation, std::string binaryImage, /*std::string vesselTree,*/ std::string surface);
/**
* @brief Method to enable/disable controls for region growing
*
* This method checks if a seed point is set and a segmentation exists.
* @param enable/disable controls
*/
void EnableControls(bool enable);
/**
* @brief Method to set the input image node
* @param data node
*/
void SetInputImageNode(mitk::DataNode* node);
void Deactivated();
void Activated();
/**
* @brief The created GUI from the .ui-File. This Attribute is obligatory
*/
Ui::QmitkAdaptiveRegionGrowingToolGUIControls m_Controls;
protected slots:
/**
* @brief Method to start the segmentation
*
* This method is called, when the "Start Segmentation" button is clicked.
*/
void RunSegmentation();
/**
* @brief Method to change the level window
*
* This method is called, when the level window slider is changed via the slider in the control widget
* @param new value
*/
void ChangeLevelWindow(double newValue);
/**
* @brief Method to increase the preview slider
*
* This method is called, when the + button is clicked and increases the value by 1
*/
void IncreaseSlider();
/**
* @brief Method to decrease the preview slider
*
* This method is called, when the - button is clicked and decreases the value by 1
*/
void DecreaseSlider();
/**
* @brief Method to confirm the preview segmentation
*
* This method is called, when the "Confirm Segmentation" button is clicked.
*/
void ConfirmSegmentation();
/**
* @brief Method to switch the volume rendering on/off
* @param on/off
*/
void UseVolumeRendering(bool on);
/**
* @brief Method to set the lower threshold
*
* This method is called, when the minimum threshold slider has changed
* @param lower threshold
*/
void SetLowerThresholdValue(double lowerThreshold);
/**
* @brief Method to set upper threshold
*
* This Method is called, when the maximum threshold slider has changed
* @param upper threshold
*/
void SetUpperThresholdValue(double upperThreshold);
/**
* @brief Method to determine which tool to activate
*
* This method listens to the tool manager and activates this tool if requested otherwise disables this view
*/
void OnNewToolAssociated(mitk::Tool*);
protected:
mitk::AdaptiveRegionGrowingTool::Pointer m_RegionGrow3DTool;
/** \brief Destructor. */
virtual ~QmitkAdaptiveRegionGrowingToolGUI();
//Pointer to the main widget to be able to reach the renderer
QmitkStdMultiWidget* m_MultiWidget;
mitk::DataStorage* m_DataStorage;
mitk::DataNode::Pointer m_InputImageNode;
/**
* @brief Method to calculate parameter settings, when a seed point is set
*/
void OnPointAdded();
private:
std::string m_NAMEFORORGIMAGE;
std::string m_NAMEFORLABLEDSEGMENTATIONIMAGE;
std::string m_NAMEFORBINARYIMAGE;
std::string m_NAMEFORSURFACE;
mitk::ScalarType m_LOWERTHRESHOLD; //Hounsfield value
mitk::ScalarType m_UPPERTHRESHOLD; //Hounsfield value
mitk::ScalarType m_SeedPointValueMean;
void RemoveHelperNodes();
int m_DetectedLeakagePoint;
bool m_CurrentRGDirectionIsUpwards; // defines fixed threshold (true = LOWERTHRESHOLD fixed, false = UPPERTHRESHOLD fixed)
int m_SeedpointValue;
bool m_SliderInitialized;
bool m_UseVolumeRendering;
bool m_UpdateSuggestedThreshold;
float m_SuggestedThValue;
long m_PointSetAddObserverTag;
+ long m_PointSetMoveObserverTag;
template < typename TPixel, unsigned int VImageDimension >
void StartRegionGrowing( itk::Image< TPixel, VImageDimension >* itkImage, mitk::BaseGeometry* imageGeometry, mitk::PointSet::PointType seedPoint );
template < typename TPixel, unsigned int VImageDimension >
void ITKThresholding( itk::Image< TPixel, VImageDimension >* inputImage );
void InitializeLevelWindow();
void EnableVolumeRendering(bool enable);
void UpdateVolumeRenderingThreshold(int thValue);
};
#endif
diff --git a/Modules/SegmentationUI/Qmitk/QmitkSlicesInterpolator.cpp b/Modules/SegmentationUI/Qmitk/QmitkSlicesInterpolator.cpp
index 629bda6e9c..7d2448eef5 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkSlicesInterpolator.cpp
+++ b/Modules/SegmentationUI/Qmitk/QmitkSlicesInterpolator.cpp
@@ -1,1136 +1,1162 @@
/*===================================================================
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 "QmitkSlicesInterpolator.h"
#include "QmitkStdMultiWidget.h"
#include "QmitkSelectableGLWidget.h"
#include "mitkToolManager.h"
#include "mitkLevelWindowProperty.h"
#include "mitkColorProperty.h"
#include "mitkProperties.h"
#include "mitkRenderingManager.h"
#include "mitkOverwriteSliceImageFilter.h"
#include "mitkProgressBar.h"
#include "mitkGlobalInteraction.h"
#include "mitkOperationEvent.h"
#include "mitkUndoController.h"
#include "mitkInteractionConst.h"
#include "mitkApplyDiffImageOperation.h"
#include "mitkDiffImageApplier.h"
#include "mitkSegTool2D.h"
#include "mitkCoreObjectFactory.h"
#include "mitkSurfaceToImageFilter.h"
#include "mitkSliceNavigationController.h"
#include <mitkVtkImageOverwrite.h>
#include <mitkExtractSliceFilter.h>
#include <mitkImageTimeSelector.h>
#include <mitkImageWriteAccessor.h>
#include <itkCommand.h>
#include <QCheckBox>
#include <QPushButton>
#include <QMenu>
#include <QCursor>
#include <QVBoxLayout>
#include <QMessageBox>
//#define ROUND(a) ((a)>0 ? (int)((a)+0.5) : -(int)(0.5-(a)))
float SURFACE_COLOR_RGB [3] = {0.49f, 1.0f, 0.16f};
const std::map<QAction*, mitk::SliceNavigationController*> QmitkSlicesInterpolator::createActionToSliceDimension()
{
std::map<QAction*, mitk::SliceNavigationController*> actionToSliceDimension;
foreach(mitk::SliceNavigationController* slicer, m_ControllerToDeleteObserverTag.keys())
{
actionToSliceDimension[new QAction(QString::fromStdString(slicer->GetViewDirectionAsString()),0)] = slicer;
}
return actionToSliceDimension;
}
QmitkSlicesInterpolator::QmitkSlicesInterpolator(QWidget* parent, const char* /*name*/)
:QWidget(parent),
// ACTION_TO_SLICEDIMENSION( createActionToSliceDimension() ),
m_Interpolator( mitk::SegmentationInterpolationController::New() ),
m_SurfaceInterpolator(mitk::SurfaceInterpolationController::GetInstance()),
m_ToolManager(NULL),
m_Initialized(false),
m_LastSNC(0),
m_LastSliceIndex(0),
m_2DInterpolationEnabled(false),
m_3DInterpolationEnabled(false)
{
m_GroupBoxEnableExclusiveInterpolationMode = new QGroupBox("Interpolation", this);
QVBoxLayout* vboxLayout = new QVBoxLayout(m_GroupBoxEnableExclusiveInterpolationMode);
m_CmbInterpolation = new QComboBox(m_GroupBoxEnableExclusiveInterpolationMode);
m_CmbInterpolation->addItem("Disabled");
m_CmbInterpolation->addItem("2-Dimensional");
m_CmbInterpolation->addItem("3-Dimensional");
vboxLayout->addWidget(m_CmbInterpolation);
m_BtnApply2D = new QPushButton("Confirm for single slice", m_GroupBoxEnableExclusiveInterpolationMode);
vboxLayout->addWidget(m_BtnApply2D);
m_BtnApplyForAllSlices2D = new QPushButton("Confirm for all slices", m_GroupBoxEnableExclusiveInterpolationMode);
vboxLayout->addWidget(m_BtnApplyForAllSlices2D);
m_BtnApply3D = new QPushButton("Confirm", m_GroupBoxEnableExclusiveInterpolationMode);
vboxLayout->addWidget(m_BtnApply3D);
m_BtnReinit3DInterpolation = new QPushButton("Reinit Interpolation", m_GroupBoxEnableExclusiveInterpolationMode);
vboxLayout->addWidget(m_BtnReinit3DInterpolation);
m_ChkShowPositionNodes = new QCheckBox("Show Position Nodes", m_GroupBoxEnableExclusiveInterpolationMode);
vboxLayout->addWidget(m_ChkShowPositionNodes);
this->HideAllInterpolationControls();
connect(m_CmbInterpolation, SIGNAL(currentIndexChanged(int)), this, SLOT(OnInterpolationMethodChanged(int)));
connect(m_BtnApply2D, SIGNAL(clicked()), this, SLOT(OnAcceptInterpolationClicked()));
connect(m_BtnApplyForAllSlices2D, SIGNAL(clicked()), this, SLOT(OnAcceptAllInterpolationsClicked()));
connect(m_BtnApply3D, SIGNAL(clicked()), this, SLOT(OnAccept3DInterpolationClicked()));
connect(m_BtnReinit3DInterpolation, SIGNAL(clicked()), this, SLOT(OnReinit3DInterpolation()));
connect(m_ChkShowPositionNodes, SIGNAL(toggled(bool)), this, SLOT(OnShowMarkers(bool)));
connect(m_ChkShowPositionNodes, SIGNAL(toggled(bool)), this, SIGNAL(SignalShowMarkerNodes(bool)));
QHBoxLayout* layout = new QHBoxLayout(this);
layout->addWidget(m_GroupBoxEnableExclusiveInterpolationMode);
this->setLayout(layout);
itk::ReceptorMemberCommand<QmitkSlicesInterpolator>::Pointer command = itk::ReceptorMemberCommand<QmitkSlicesInterpolator>::New();
command->SetCallbackFunction( this, &QmitkSlicesInterpolator::OnInterpolationInfoChanged );
InterpolationInfoChangedObserverTag = m_Interpolator->AddObserver( itk::ModifiedEvent(), command );
itk::ReceptorMemberCommand<QmitkSlicesInterpolator>::Pointer command2 = itk::ReceptorMemberCommand<QmitkSlicesInterpolator>::New();
command2->SetCallbackFunction( this, &QmitkSlicesInterpolator::OnSurfaceInterpolationInfoChanged );
SurfaceInterpolationInfoChangedObserverTag = m_SurfaceInterpolator->AddObserver( itk::ModifiedEvent(), command2 );
// feedback node and its visualization properties
m_FeedbackNode = mitk::DataNode::New();
mitk::CoreObjectFactory::GetInstance()->SetDefaultProperties( m_FeedbackNode );
m_FeedbackNode->SetProperty( "binary", mitk::BoolProperty::New(true) );
m_FeedbackNode->SetProperty( "outline binary", mitk::BoolProperty::New(true) );
m_FeedbackNode->SetProperty( "color", mitk::ColorProperty::New(255.0, 255.0, 0.0) );
m_FeedbackNode->SetProperty( "texture interpolation", mitk::BoolProperty::New(false) );
m_FeedbackNode->SetProperty( "layer", mitk::IntProperty::New( 20 ) );
m_FeedbackNode->SetProperty( "levelwindow", mitk::LevelWindowProperty::New( mitk::LevelWindow(0, 1) ) );
m_FeedbackNode->SetProperty( "name", mitk::StringProperty::New("Interpolation feedback") );
m_FeedbackNode->SetProperty( "opacity", mitk::FloatProperty::New(0.8) );
m_FeedbackNode->SetProperty( "helper object", mitk::BoolProperty::New(true) );
m_InterpolatedSurfaceNode = mitk::DataNode::New();
m_InterpolatedSurfaceNode->SetProperty( "color", mitk::ColorProperty::New(SURFACE_COLOR_RGB) );
m_InterpolatedSurfaceNode->SetProperty( "name", mitk::StringProperty::New("Surface Interpolation feedback") );
m_InterpolatedSurfaceNode->SetProperty( "opacity", mitk::FloatProperty::New(0.5) );
m_InterpolatedSurfaceNode->SetProperty( "line width", mitk::IntProperty::New(4) );
m_InterpolatedSurfaceNode->SetProperty( "includeInBoundingBox", mitk::BoolProperty::New(false));
m_InterpolatedSurfaceNode->SetProperty( "helper object", mitk::BoolProperty::New(true) );
m_InterpolatedSurfaceNode->SetVisibility(false);
m_3DContourNode = mitk::DataNode::New();
m_3DContourNode->SetProperty( "color", mitk::ColorProperty::New(0.0, 0.0, 0.0) );
m_3DContourNode->SetProperty("hidden object", mitk::BoolProperty::New(true));
m_3DContourNode->SetProperty( "name", mitk::StringProperty::New("Drawn Contours") );
m_3DContourNode->SetProperty("material.representation", mitk::VtkRepresentationProperty::New(VTK_WIREFRAME));
m_3DContourNode->SetProperty("material.wireframeLineWidth", mitk::FloatProperty::New(2.0f));
m_3DContourNode->SetProperty("3DContourContainer", mitk::BoolProperty::New(true));
m_3DContourNode->SetProperty( "includeInBoundingBox", mitk::BoolProperty::New(false));
m_3DContourNode->SetVisibility(false, mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1")));
m_3DContourNode->SetVisibility(false, mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget2")));
m_3DContourNode->SetVisibility(false, mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget3")));
m_3DContourNode->SetVisibility(false, mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget4")));
QWidget::setContentsMargins(0, 0, 0, 0);
if ( QWidget::layout() != NULL )
{
QWidget::layout()->setContentsMargins(0, 0, 0, 0);
}
//For running 3D Interpolation in background
// create a QFuture and a QFutureWatcher
connect(&m_Watcher, SIGNAL(started()), this, SLOT(StartUpdateInterpolationTimer()));
connect(&m_Watcher, SIGNAL(finished()), this, SLOT(OnSurfaceInterpolationFinished()));
connect(&m_Watcher, SIGNAL(finished()), this, SLOT(StopUpdateInterpolationTimer()));
m_Timer = new QTimer(this);
connect(m_Timer, SIGNAL(timeout()), this, SLOT(ChangeSurfaceColor()));
}
void QmitkSlicesInterpolator::SetDataStorage( mitk::DataStorage::Pointer storage )
{
m_DataStorage = storage;
m_SurfaceInterpolator->SetDataStorage(storage);
}
mitk::DataStorage* QmitkSlicesInterpolator::GetDataStorage()
{
if ( m_DataStorage.IsNotNull() )
{
return m_DataStorage;
}
else
{
return NULL;
}
}
void QmitkSlicesInterpolator::Initialize(mitk::ToolManager* toolManager, const QList<mitk::SliceNavigationController *> &controllers)
{
Q_ASSERT(!controllers.empty());
if (m_Initialized)
{
// remove old observers
Uninitialize();
}
m_ToolManager = toolManager;
if (m_ToolManager)
{
// set enabled only if a segmentation is selected
mitk::DataNode* node = m_ToolManager->GetWorkingData(0);
QWidget::setEnabled( node != NULL );
// react whenever the set of selected segmentation changes
m_ToolManager->WorkingDataChanged += mitk::MessageDelegate<QmitkSlicesInterpolator>( this, &QmitkSlicesInterpolator::OnToolManagerWorkingDataModified );
m_ToolManager->ReferenceDataChanged += mitk::MessageDelegate<QmitkSlicesInterpolator>( this, &QmitkSlicesInterpolator::OnToolManagerReferenceDataModified );
// connect to the slice navigation controller. after each change, call the interpolator
foreach(mitk::SliceNavigationController* slicer, controllers)
{
//Has to be initialized
m_LastSNC = slicer;
m_TimeStep.insert(slicer, slicer->GetTime()->GetPos());
itk::MemberCommand<QmitkSlicesInterpolator>::Pointer deleteCommand = itk::MemberCommand<QmitkSlicesInterpolator>::New();
deleteCommand->SetCallbackFunction( this, &QmitkSlicesInterpolator::OnSliceNavigationControllerDeleted);
m_ControllerToDeleteObserverTag.insert(slicer, slicer->AddObserver(itk::DeleteEvent(), deleteCommand));
itk::MemberCommand<QmitkSlicesInterpolator>::Pointer timeChangedCommand = itk::MemberCommand<QmitkSlicesInterpolator>::New();
timeChangedCommand->SetCallbackFunction( this, &QmitkSlicesInterpolator::OnTimeChanged);
m_ControllerToTimeObserverTag.insert(slicer, slicer->AddObserver(mitk::SliceNavigationController::TimeGeometryEvent(NULL,0), timeChangedCommand));
itk::MemberCommand<QmitkSlicesInterpolator>::Pointer sliceChangedCommand = itk::MemberCommand<QmitkSlicesInterpolator>::New();
sliceChangedCommand->SetCallbackFunction( this, &QmitkSlicesInterpolator::OnSliceChanged);
m_ControllerToSliceObserverTag.insert(slicer, slicer->AddObserver(mitk::SliceNavigationController::GeometrySliceEvent(NULL,0), sliceChangedCommand));
}
ACTION_TO_SLICEDIMENSION = createActionToSliceDimension();
}
m_Initialized = true;
}
void QmitkSlicesInterpolator::Uninitialize()
{
if (m_ToolManager.IsNotNull())
{
m_ToolManager->WorkingDataChanged -= mitk::MessageDelegate<QmitkSlicesInterpolator>(this, &QmitkSlicesInterpolator::OnToolManagerWorkingDataModified);
m_ToolManager->ReferenceDataChanged -= mitk::MessageDelegate<QmitkSlicesInterpolator>(this, &QmitkSlicesInterpolator::OnToolManagerReferenceDataModified);
}
foreach(mitk::SliceNavigationController* slicer, m_ControllerToSliceObserverTag.keys())
{
slicer->RemoveObserver(m_ControllerToDeleteObserverTag.take(slicer));
slicer->RemoveObserver(m_ControllerToTimeObserverTag.take(slicer));
slicer->RemoveObserver(m_ControllerToSliceObserverTag.take(slicer));
}
ACTION_TO_SLICEDIMENSION.clear();
m_ToolManager = NULL;
m_Initialized = false;
}
QmitkSlicesInterpolator::~QmitkSlicesInterpolator()
{
if (m_Initialized)
{
// remove old observers
Uninitialize();
}
if(m_DataStorage->Exists(m_3DContourNode))
m_DataStorage->Remove(m_3DContourNode);
if(m_DataStorage->Exists(m_InterpolatedSurfaceNode))
m_DataStorage->Remove(m_InterpolatedSurfaceNode);
// remove observer
m_Interpolator->RemoveObserver( InterpolationInfoChangedObserverTag );
m_SurfaceInterpolator->RemoveObserver( SurfaceInterpolationInfoChangedObserverTag );
delete m_Timer;
}
/**
External enableization...
*/
void QmitkSlicesInterpolator::setEnabled( bool enable )
{
QWidget::setEnabled(enable);
//Set the gui elements of the different interpolation modi enabled
if (enable)
{
if (m_2DInterpolationEnabled)
{
this->Show2DInterpolationControls(true);
m_Interpolator->Activate2DInterpolation(true);
}
else if (m_3DInterpolationEnabled)
{
this->Show3DInterpolationControls(true);
this->Show3DInterpolationResult(true);
}
}
//Set all gui elements of the interpolation disabled
else
{
this->HideAllInterpolationControls();
this->Show3DInterpolationResult(false);
}
}
void QmitkSlicesInterpolator::On2DInterpolationEnabled(bool status)
{
OnInterpolationActivated(status);
m_Interpolator->Activate2DInterpolation(status);
}
void QmitkSlicesInterpolator::On3DInterpolationEnabled(bool status)
{
On3DInterpolationActivated(status);
}
void QmitkSlicesInterpolator::OnInterpolationDisabled(bool status)
{
if (status)
{
OnInterpolationActivated(!status);
On3DInterpolationActivated(!status);
this->Show3DInterpolationResult(false);
}
}
void QmitkSlicesInterpolator::HideAllInterpolationControls()
{
this->Show2DInterpolationControls(false);
this->Show3DInterpolationControls(false);
}
void QmitkSlicesInterpolator::Show2DInterpolationControls(bool show)
{
m_BtnApply2D->setVisible(show);
m_BtnApplyForAllSlices2D->setVisible(show);
}
void QmitkSlicesInterpolator::Show3DInterpolationControls(bool show)
{
m_BtnApply3D->setVisible(show);
m_ChkShowPositionNodes->setVisible(show);
m_BtnReinit3DInterpolation->setVisible(show);
}
void QmitkSlicesInterpolator::OnInterpolationMethodChanged(int index)
{
switch(index)
{
case 0: // Disabled
m_GroupBoxEnableExclusiveInterpolationMode->setTitle("Interpolation");
this->HideAllInterpolationControls();
this->OnInterpolationActivated(false);
this->On3DInterpolationActivated(false);
this->Show3DInterpolationResult(false);
m_Interpolator->Activate2DInterpolation(false);
break;
case 1: // 2D
m_GroupBoxEnableExclusiveInterpolationMode->setTitle("Interpolation (Enabled)");
this->HideAllInterpolationControls();
this->Show2DInterpolationControls(true);
this->OnInterpolationActivated(true);
this->On3DInterpolationActivated(false);
m_Interpolator->Activate2DInterpolation(true);
break;
case 2: // 3D
m_GroupBoxEnableExclusiveInterpolationMode->setTitle("Interpolation (Enabled)");
this->HideAllInterpolationControls();
this->Show3DInterpolationControls(true);
this->OnInterpolationActivated(false);
this->On3DInterpolationActivated(true);
m_Interpolator->Activate2DInterpolation(false);
break;
default:
MITK_ERROR << "Unknown interpolation method!";
m_CmbInterpolation->setCurrentIndex(0);
break;
}
}
void QmitkSlicesInterpolator::OnShowMarkers(bool state)
{
mitk::DataStorage::SetOfObjects::ConstPointer allContourMarkers = m_DataStorage->GetSubset(mitk::NodePredicateProperty::New("isContourMarker"
, mitk::BoolProperty::New(true)));
for (mitk::DataStorage::SetOfObjects::ConstIterator it = allContourMarkers->Begin(); it != allContourMarkers->End(); ++it)
{
it->Value()->SetProperty("helper object", mitk::BoolProperty::New(!state));
}
}
void QmitkSlicesInterpolator::OnToolManagerWorkingDataModified()
{
if (m_ToolManager->GetWorkingData(0) != 0)
{
m_Segmentation = dynamic_cast<mitk::Image*>(m_ToolManager->GetWorkingData(0)->GetData());
m_BtnReinit3DInterpolation->setEnabled(true);
}
else
{
//If no workingdata is set, remove the interpolation feedback
this->GetDataStorage()->Remove(m_FeedbackNode);
m_FeedbackNode->SetData(NULL);
this->GetDataStorage()->Remove(m_3DContourNode);
m_3DContourNode->SetData(NULL);
this->GetDataStorage()->Remove(m_InterpolatedSurfaceNode);
m_InterpolatedSurfaceNode->SetData(NULL);
m_BtnReinit3DInterpolation->setEnabled(false);
return;
}
//Updating the current selected segmentation for the 3D interpolation
SetCurrentContourListID();
if (m_2DInterpolationEnabled)
{
OnInterpolationActivated( true ); // re-initialize if needed
}
this->CheckSupportedImageDimension();
}
void QmitkSlicesInterpolator::OnToolManagerReferenceDataModified()
{
}
void QmitkSlicesInterpolator::OnTimeChanged(itk::Object* sender, const itk::EventObject& e)
{
//Check if we really have a GeometryTimeEvent
if (!dynamic_cast<const mitk::SliceNavigationController::GeometryTimeEvent*>(&e))
return;
mitk::SliceNavigationController* slicer = dynamic_cast<mitk::SliceNavigationController*>(sender);
Q_ASSERT(slicer);
m_TimeStep[slicer];
if (m_LastSNC == slicer)
{
slicer->SendSlice();//will trigger a new interpolation
}
}
void QmitkSlicesInterpolator::OnSliceChanged(itk::Object *sender, const itk::EventObject &e)
{
//Check whether we really have a GeometrySliceEvent
if (!dynamic_cast<const mitk::SliceNavigationController::GeometrySliceEvent*>(&e))
return;
mitk::SliceNavigationController* slicer = dynamic_cast<mitk::SliceNavigationController*>(sender);
if (TranslateAndInterpolateChangedSlice(e, slicer))
{
slicer->GetRenderer()->RequestUpdate();
}
}
bool QmitkSlicesInterpolator::TranslateAndInterpolateChangedSlice(const itk::EventObject& e, mitk::SliceNavigationController* slicer)
{
if (!m_2DInterpolationEnabled) return false;
try
{
const mitk::SliceNavigationController::GeometrySliceEvent& event = dynamic_cast<const mitk::SliceNavigationController::GeometrySliceEvent&>(e);
mitk::TimeGeometry* tsg = event.GetTimeGeometry();
if (tsg && m_TimeStep.contains(slicer))
{
mitk::SlicedGeometry3D* slicedGeometry = dynamic_cast<mitk::SlicedGeometry3D*>(tsg->GetGeometryForTimeStep(m_TimeStep[slicer]).GetPointer());
if (slicedGeometry)
{
m_LastSNC = slicer;
mitk::PlaneGeometry* plane = dynamic_cast<mitk::PlaneGeometry*>(slicedGeometry->GetPlaneGeometry( event.GetPos() ));
if (plane)
Interpolate( plane, m_TimeStep[slicer], slicer );
return true;
}
}
}
catch(std::bad_cast)
{
return false; // so what
}
return false;
}
void QmitkSlicesInterpolator::Interpolate( mitk::PlaneGeometry* plane, unsigned int timeStep, mitk::SliceNavigationController* slicer )
{
if (m_ToolManager)
{
mitk::DataNode* node = m_ToolManager->GetWorkingData(0);
if (node)
{
m_Segmentation = dynamic_cast<mitk::Image*>(node->GetData());
if (m_Segmentation)
{
int clickedSliceDimension(-1);
int clickedSliceIndex(-1);
// calculate real slice position, i.e. slice of the image and not slice of the TimeSlicedGeometry
mitk::SegTool2D::DetermineAffectedImageSlice( m_Segmentation, plane, clickedSliceDimension, clickedSliceIndex );
mitk::Image::Pointer interpolation = m_Interpolator->Interpolate( clickedSliceDimension, clickedSliceIndex, plane, timeStep );
m_FeedbackNode->SetData( interpolation );
m_LastSNC = slicer;
m_LastSliceIndex = clickedSliceIndex;
}
}
}
}
void QmitkSlicesInterpolator::OnSurfaceInterpolationFinished()
{
mitk::Surface::Pointer interpolatedSurface = m_SurfaceInterpolator->GetInterpolationResult();
mitk::DataNode* workingNode = m_ToolManager->GetWorkingData(0);
if(interpolatedSurface.IsNotNull() && workingNode &&
workingNode->IsVisible(mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget3"))))
{
m_BtnApply3D->setEnabled(true);
m_InterpolatedSurfaceNode->SetData(interpolatedSurface);
m_3DContourNode->SetData(m_SurfaceInterpolator->GetContoursAsSurface());
this->Show3DInterpolationResult(true);
if( !m_DataStorage->Exists(m_InterpolatedSurfaceNode) )
{
m_DataStorage->Add(m_InterpolatedSurfaceNode);
}
if (!m_DataStorage->Exists(m_3DContourNode))
{
m_DataStorage->Add(m_3DContourNode, workingNode);
}
}
else if (interpolatedSurface.IsNull())
{
m_BtnApply3D->setEnabled(false);
if (m_DataStorage->Exists(m_InterpolatedSurfaceNode))
{
this->Show3DInterpolationResult(false);
}
}
m_BtnReinit3DInterpolation->setEnabled(true);
foreach (mitk::SliceNavigationController* slicer, m_ControllerToTimeObserverTag.keys())
{
slicer->GetRenderer()->RequestUpdate();
}
}
void QmitkSlicesInterpolator::OnAcceptInterpolationClicked()
{
if (m_Segmentation && m_FeedbackNode->GetData())
{
//making interpolation separately undoable
mitk::UndoStackItem::IncCurrObjectEventId();
mitk::UndoStackItem::IncCurrGroupEventId();
mitk::UndoStackItem::ExecuteIncrement();
//Make sure that for reslicing and overwriting the same alogrithm is used. We can specify the mode of the vtk reslicer
vtkSmartPointer<mitkVtkImageOverwrite> reslice = vtkSmartPointer<mitkVtkImageOverwrite>::New();
// Set slice as input
mitk::Image::Pointer slice = dynamic_cast<mitk::Image*>(m_FeedbackNode->GetData());
reslice->SetInputSlice(slice->GetSliceData()->GetVtkImageAccessor(slice)->GetVtkImageData());
//set overwrite mode to true to write back to the image volume
reslice->SetOverwriteMode(true);
reslice->Modified();
mitk::ExtractSliceFilter::Pointer extractor = mitk::ExtractSliceFilter::New(reslice);
extractor->SetInput( m_Segmentation );
unsigned int timestep = m_LastSNC->GetTime()->GetPos();
extractor->SetTimeStep( timestep );
extractor->SetWorldGeometry( m_LastSNC->GetCurrentPlaneGeometry() );
extractor->SetVtkOutputRequest(true);
extractor->SetResliceTransformByGeometry( m_Segmentation->GetTimeGeometry()->GetGeometryForTimeStep( timestep ) );
extractor->Modified();
extractor->Update();
//the image was modified within the pipeline, but not marked so
m_Segmentation->Modified();
m_Segmentation->GetVtkImageData()->Modified();
m_FeedbackNode->SetData(NULL);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void QmitkSlicesInterpolator::AcceptAllInterpolations(mitk::SliceNavigationController* slicer)
{
/*
* What exactly is done here:
* 1. We create an empty diff image for the current segmentation
* 2. All interpolated slices are written into the diff image
* 3. Then the diffimage is applied to the original segmentation
*/
if (m_Segmentation)
{
//making interpolation separately undoable
mitk::UndoStackItem::IncCurrObjectEventId();
mitk::UndoStackItem::IncCurrGroupEventId();
mitk::UndoStackItem::ExecuteIncrement();
mitk::Image::Pointer image3D = m_Segmentation;
unsigned int timeStep( slicer->GetTime()->GetPos() );
if (m_Segmentation->GetDimension() == 4)
{
mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New();
timeSelector->SetInput( m_Segmentation );
timeSelector->SetTimeNr( timeStep );
timeSelector->Update();
image3D = timeSelector->GetOutput();
}
// create a empty diff image for the undo operation
mitk::Image::Pointer diffImage = mitk::Image::New();
diffImage->Initialize( image3D );
// Create scope for ImageWriteAccessor so that the accessor is destroyed
// after the image is initialized. Otherwise later image access will lead to an error
{
mitk::ImageWriteAccessor imAccess(diffImage);
// Set all pixels to zero
mitk::PixelType pixelType( mitk::MakeScalarPixelType<unsigned char>() );
memset( imAccess.GetData(), 0, (pixelType.GetBpe() >> 3) * diffImage->GetDimension(0) * diffImage->GetDimension(1) * diffImage->GetDimension(2) );
}
// Since we need to shift the plane it must be clone so that the original plane isn't altered
mitk::PlaneGeometry::Pointer reslicePlane = slicer->GetCurrentPlaneGeometry()->Clone();
int sliceDimension(-1);
int sliceIndex(-1);
mitk::SegTool2D::DetermineAffectedImageSlice( m_Segmentation, reslicePlane, sliceDimension, sliceIndex );
unsigned int zslices = m_Segmentation->GetDimension( sliceDimension );
mitk::ProgressBar::GetInstance()->AddStepsToDo(zslices);
mitk::Point3D origin = reslicePlane->GetOrigin();
unsigned int totalChangedSlices(0);
for (unsigned int sliceIndex = 0; sliceIndex < zslices; ++sliceIndex)
{
// Transforming the current origin of the reslice plane
// so that it matches the one of the next slice
m_Segmentation->GetSlicedGeometry()->WorldToIndex(origin, origin);
origin[sliceDimension] = sliceIndex;
m_Segmentation->GetSlicedGeometry()->IndexToWorld(origin, origin);
reslicePlane->SetOrigin(origin);
//Set the slice as 'input'
mitk::Image::Pointer interpolation = m_Interpolator->Interpolate( sliceDimension, sliceIndex, reslicePlane, timeStep );
if (interpolation.IsNotNull()) // we don't check if interpolation is necessary/sensible - but m_Interpolator does
{
//Setting up the reslicing pipeline which allows us to write the interpolation results back into
//the image volume
vtkSmartPointer<mitkVtkImageOverwrite> reslice = vtkSmartPointer<mitkVtkImageOverwrite>::New();
//set overwrite mode to true to write back to the image volume
reslice->SetInputSlice(interpolation->GetSliceData()->GetVtkImageAccessor(interpolation)->GetVtkImageData());
reslice->SetOverwriteMode(true);
reslice->Modified();
mitk::ExtractSliceFilter::Pointer diffslicewriter = mitk::ExtractSliceFilter::New(reslice);
diffslicewriter->SetInput( diffImage );
diffslicewriter->SetTimeStep( timeStep );
diffslicewriter->SetWorldGeometry(reslicePlane);
diffslicewriter->SetVtkOutputRequest(true);
diffslicewriter->SetResliceTransformByGeometry( diffImage->GetTimeGeometry()->GetGeometryForTimeStep( timeStep ) );
diffslicewriter->Modified();
diffslicewriter->Update();
++totalChangedSlices;
}
mitk::ProgressBar::GetInstance()->Progress();
}
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
if (totalChangedSlices > 0)
{
// store undo stack items
if ( true )
{
// create do/undo operations
mitk::ApplyDiffImageOperation* doOp = new mitk::ApplyDiffImageOperation( mitk::OpTEST, m_Segmentation, diffImage, timeStep );
mitk::ApplyDiffImageOperation* undoOp = new mitk::ApplyDiffImageOperation( mitk::OpTEST, m_Segmentation, diffImage, timeStep );
undoOp->SetFactor( -1.0 );
std::stringstream comment;
comment << "Confirm all interpolations (" << totalChangedSlices << ")";
mitk::OperationEvent* undoStackItem = new mitk::OperationEvent( mitk::DiffImageApplier::GetInstanceForUndo(), doOp, undoOp, comment.str() );
mitk::UndoController::GetCurrentUndoModel()->SetOperationEvent( undoStackItem );
// acutally apply the changes here to the original image
mitk::DiffImageApplier::GetInstanceForUndo()->ExecuteOperation( doOp );
}
}
m_FeedbackNode->SetData(NULL);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void QmitkSlicesInterpolator::FinishInterpolation(mitk::SliceNavigationController* slicer)
{
//this redirect is for calling from outside
if (slicer == NULL)
OnAcceptAllInterpolationsClicked();
else
AcceptAllInterpolations( slicer );
}
void QmitkSlicesInterpolator::OnAcceptAllInterpolationsClicked()
{
QMenu orientationPopup(this);
std::map<QAction*, mitk::SliceNavigationController*>::const_iterator it;
for(it = ACTION_TO_SLICEDIMENSION.begin(); it != ACTION_TO_SLICEDIMENSION.end(); it++)
orientationPopup.addAction(it->first);
connect( &orientationPopup, SIGNAL(triggered(QAction*)), this, SLOT(OnAcceptAllPopupActivated(QAction*)) );
orientationPopup.exec( QCursor::pos() );
}
void QmitkSlicesInterpolator::OnAccept3DInterpolationClicked()
{
if (m_InterpolatedSurfaceNode.IsNotNull() && m_InterpolatedSurfaceNode->GetData())
{
mitk::SurfaceToImageFilter::Pointer s2iFilter = mitk::SurfaceToImageFilter::New();
s2iFilter->MakeOutputBinaryOn();
s2iFilter->SetInput(dynamic_cast<mitk::Surface*>(m_InterpolatedSurfaceNode->GetData()));
// check if ToolManager holds valid ReferenceData
if (m_ToolManager->GetReferenceData(0) == NULL || m_ToolManager->GetWorkingData(0) == NULL)
{
return;
}
s2iFilter->SetImage(dynamic_cast<mitk::Image*>(m_ToolManager->GetReferenceData(0)->GetData()));
s2iFilter->Update();
mitk::DataNode* segmentationNode = m_ToolManager->GetWorkingData(0);
- segmentationNode->SetData(s2iFilter->GetOutput());
+ mitk::Image* oldSeg = dynamic_cast<mitk::Image*>(segmentationNode->GetData());
+ mitk::Image::Pointer newSeg = s2iFilter->GetOutput();
+ if (oldSeg)
+ m_SurfaceInterpolator->ReplaceInterpolationSession(oldSeg, newSeg);
+ else
+ return;
+
+ segmentationNode->SetData(newSeg);
m_CmbInterpolation->setCurrentIndex(0);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
mitk::DataNode::Pointer segSurface = mitk::DataNode::New();
float rgb[3];
segmentationNode->GetColor(rgb);
segSurface->SetColor(rgb);
segSurface->SetData(m_InterpolatedSurfaceNode->GetData());
std::stringstream stream;
stream << segmentationNode->GetName();
stream << "_";
stream << "3D-interpolation";
segSurface->SetName(stream.str());
segSurface->SetProperty( "opacity", mitk::FloatProperty::New(0.7) );
- segSurface->SetProperty( "includeInBoundingBox", mitk::BoolProperty::New(false));
+ segSurface->SetProperty( "includeInBoundingBox", mitk::BoolProperty::New(true));
+ segSurface->SetProperty( "3DInterpolationResult", mitk::BoolProperty::New(true));
m_DataStorage->Add(segSurface, segmentationNode);
this->Show3DInterpolationResult(false);
}
}
void QmitkSlicesInterpolator::OnReinit3DInterpolation()
{
mitk::NodePredicateProperty::Pointer pred = mitk::NodePredicateProperty::New("3DContourContainer", mitk::BoolProperty::New(true));
mitk::DataStorage::SetOfObjects::ConstPointer contourNodes = m_DataStorage->GetDerivations( m_ToolManager->GetWorkingData(0), pred);
if (contourNodes->Size() != 0)
{
m_3DContourNode = contourNodes->at(0);
}
else
{
QMessageBox errorInfo;
errorInfo.setWindowTitle("Reinitialize surface interpolation");
errorInfo.setIcon(QMessageBox::Information);
errorInfo.setText("No contours available for the selected segmentation!");
errorInfo.exec();
}
mitk::Surface::Pointer contours = dynamic_cast<mitk::Surface*>(m_3DContourNode->GetData());
if (contours)
mitk::SurfaceInterpolationController::GetInstance()->ReinitializeInterpolation(contours);
m_BtnReinit3DInterpolation->setEnabled(false);
}
void QmitkSlicesInterpolator::OnAcceptAllPopupActivated(QAction* action)
{
try
{
std::map<QAction*, mitk::SliceNavigationController*>::const_iterator iter = ACTION_TO_SLICEDIMENSION.find( action );
if (iter != ACTION_TO_SLICEDIMENSION.end())
{
mitk::SliceNavigationController* slicer = iter->second;
AcceptAllInterpolations( slicer );
}
}
catch(...)
{
/* Showing message box with possible memory error */
QMessageBox errorInfo;
errorInfo.setWindowTitle("Interpolation Process");
errorInfo.setIcon(QMessageBox::Critical);
errorInfo.setText("An error occurred during interpolation. Possible cause: Not enough memory!");
errorInfo.exec();
//additional error message on std::cerr
std::cerr << "Ill construction in " __FILE__ " l. " << __LINE__ << std::endl;
}
}
void QmitkSlicesInterpolator::OnInterpolationActivated(bool on)
{
m_2DInterpolationEnabled = on;
try
{
if ( m_DataStorage.IsNotNull() )
{
if (on && !m_DataStorage->Exists(m_FeedbackNode))
{
m_DataStorage->Add( m_FeedbackNode );
}
}
}
catch(...)
{
// don't care (double add/remove)
}
if (m_ToolManager)
{
mitk::DataNode* workingNode = m_ToolManager->GetWorkingData(0);
mitk::DataNode* referenceNode = m_ToolManager->GetReferenceData(0);
QWidget::setEnabled( workingNode != NULL );
m_BtnApply2D->setEnabled( on );
m_FeedbackNode->SetVisibility( on );
if (!on)
{
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
return;
}
if (workingNode)
{
mitk::Image* segmentation = dynamic_cast<mitk::Image*>(workingNode->GetData());
if (segmentation)
{
m_Interpolator->SetSegmentationVolume( segmentation );
if (referenceNode)
{
mitk::Image* referenceImage = dynamic_cast<mitk::Image*>(referenceNode->GetData());
m_Interpolator->SetReferenceVolume( referenceImage ); // may be NULL
}
}
}
}
UpdateVisibleSuggestion();
}
void QmitkSlicesInterpolator::Run3DInterpolation()
{
m_SurfaceInterpolator->Interpolate();
}
void QmitkSlicesInterpolator::StartUpdateInterpolationTimer()
{
m_Timer->start(500);
}
void QmitkSlicesInterpolator::StopUpdateInterpolationTimer()
{
m_Timer->stop();
m_InterpolatedSurfaceNode->SetProperty("color", mitk::ColorProperty::New(SURFACE_COLOR_RGB));
mitk::RenderingManager::GetInstance()->RequestUpdate(mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget4"))->GetRenderWindow());
}
void QmitkSlicesInterpolator::ChangeSurfaceColor()
{
float currentColor[3];
m_InterpolatedSurfaceNode->GetColor(currentColor);
if( currentColor[2] == SURFACE_COLOR_RGB[2])
{
m_InterpolatedSurfaceNode->SetProperty("color", mitk::ColorProperty::New(1.0f,1.0f,1.0f));
}
else
{
m_InterpolatedSurfaceNode->SetProperty("color", mitk::ColorProperty::New(SURFACE_COLOR_RGB));
}
m_InterpolatedSurfaceNode->Update();
mitk::RenderingManager::GetInstance()->RequestUpdate(mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget4"))->GetRenderWindow());
}
void QmitkSlicesInterpolator::On3DInterpolationActivated(bool on)
{
m_3DInterpolationEnabled = on;
this->CheckSupportedImageDimension();
try
{
if ( m_DataStorage.IsNotNull() && m_ToolManager && m_3DInterpolationEnabled)
{
mitk::DataNode* workingNode = m_ToolManager->GetWorkingData(0);
if (workingNode)
{
bool isInterpolationResult(false);
workingNode->GetBoolProperty("3DInterpolationResult",isInterpolationResult);
+ mitk::NodePredicateAnd::Pointer pred = mitk::NodePredicateAnd::New(mitk::NodePredicateProperty::New("3DInterpolationResult", mitk::BoolProperty::New(true)),
+ mitk::NodePredicateDataType::New("Surface"));
+ mitk::DataStorage::SetOfObjects::ConstPointer interpolationResults =
+ m_DataStorage->GetDerivations(workingNode, pred);
+
+ for (unsigned int i = 0; i < interpolationResults->Size(); ++i)
+ {
+ mitk::DataNode::Pointer currNode = interpolationResults->at(i);
+ if (currNode.IsNotNull())
+ m_DataStorage->Remove(currNode);
+ }
if ((workingNode->IsVisible(mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget3")))) &&
!isInterpolationResult && m_3DInterpolationEnabled)
{
int ret = QMessageBox::Yes;
if (m_SurfaceInterpolator->EstimatePortionOfNeededMemory() > 0.5)
{
QMessageBox msgBox;
msgBox.setText("Due to short handed system memory the 3D interpolation may be very slow!");
msgBox.setInformativeText("Are you sure you want to activate the 3D interpolation?");
msgBox.setStandardButtons(QMessageBox::No | QMessageBox::Yes);
ret = msgBox.exec();
}
if (m_Watcher.isRunning())
m_Watcher.waitForFinished();
if (ret == QMessageBox::Yes)
{
m_Future = QtConcurrent::run(this, &QmitkSlicesInterpolator::Run3DInterpolation);
m_Watcher.setFuture(m_Future);
}
else
{
m_CmbInterpolation->setCurrentIndex(0);
}
}
else if (!m_3DInterpolationEnabled)
{
this->Show3DInterpolationResult(false);
m_BtnApply3D->setEnabled(m_3DInterpolationEnabled);
}
}
else
{
QWidget::setEnabled( false );
m_ChkShowPositionNodes->setEnabled(m_3DInterpolationEnabled);
}
}
if (!m_3DInterpolationEnabled)
{
this->Show3DInterpolationResult(false);
m_BtnApply3D->setEnabled(m_3DInterpolationEnabled);
}
}
catch(...)
{
MITK_ERROR<<"Error with 3D surface interpolation!";
}
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkSlicesInterpolator::EnableInterpolation(bool on)
{
// only to be called from the outside world
// just a redirection to OnInterpolationActivated
OnInterpolationActivated(on);
}
void QmitkSlicesInterpolator::Enable3DInterpolation(bool on)
{
// only to be called from the outside world
// just a redirection to OnInterpolationActivated
On3DInterpolationActivated(on);
}
void QmitkSlicesInterpolator::UpdateVisibleSuggestion()
{
if (m_2DInterpolationEnabled && m_LastSNC)
{
// determine which one is the current view, try to do an initial interpolation
mitk::BaseRenderer* renderer = m_LastSNC->GetRenderer();
if (renderer && renderer->GetMapperID() == mitk::BaseRenderer::Standard2D)
{
const mitk::TimeGeometry* timeGeometry = dynamic_cast<const mitk::TimeGeometry*>( renderer->GetWorldGeometry() );
if (timeGeometry)
{
mitk::SliceNavigationController::GeometrySliceEvent event( const_cast<mitk::TimeGeometry*>(timeGeometry), renderer->GetSlice() );
TranslateAndInterpolateChangedSlice(event, m_LastSNC);
}
}
}
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkSlicesInterpolator::OnInterpolationInfoChanged(const itk::EventObject& /*e*/)
{
// something (e.g. undo) changed the interpolation info, we should refresh our display
UpdateVisibleSuggestion();
}
void QmitkSlicesInterpolator::OnSurfaceInterpolationInfoChanged(const itk::EventObject& /*e*/)
{
if(m_3DInterpolationEnabled)
{
if (m_Watcher.isRunning())
m_Watcher.waitForFinished();
m_Future = QtConcurrent::run(this, &QmitkSlicesInterpolator::Run3DInterpolation);
m_Watcher.setFuture(m_Future);
}
}
void QmitkSlicesInterpolator:: SetCurrentContourListID()
{
// New ContourList = hide current interpolation
Show3DInterpolationResult(false);
if ( m_DataStorage.IsNotNull() && m_ToolManager && m_LastSNC )
{
mitk::DataNode* workingNode = m_ToolManager->GetWorkingData(0);
if (workingNode)
{
bool isInterpolationResult(false);
workingNode->GetBoolProperty("3DInterpolationResult",isInterpolationResult);
if (!isInterpolationResult)
{
QWidget::setEnabled( true );
- //TODO Aufruf hier pruefen!
- mitk::Vector3D spacing = workingNode->GetData()->GetGeometry( m_LastSNC->GetTime()->GetPos() )->GetSpacing();
+ // In case the time is not valid use 0 to access the time geometry of the working node
+ unsigned int time_position = 0;
+ if( m_LastSNC->GetTime() != NULL )
+ time_position = m_LastSNC->GetTime()->GetPos();
+
+ mitk::Vector3D spacing = workingNode->GetData()->GetGeometry( time_position )->GetSpacing();
double minSpacing (100);
double maxSpacing (0);
for (int i =0; i < 3; i++)
{
if (spacing[i] < minSpacing)
{
minSpacing = spacing[i];
}
else if (spacing[i] > maxSpacing)
{
maxSpacing = spacing[i];
}
}
m_SurfaceInterpolator->SetMaxSpacing(maxSpacing);
m_SurfaceInterpolator->SetMinSpacing(minSpacing);
m_SurfaceInterpolator->SetDistanceImageVolume(50000);
mitk::Image* segmentationImage = dynamic_cast<mitk::Image*>(workingNode->GetData());
if (segmentationImage->GetDimension() == 3)
m_SurfaceInterpolator->SetCurrentInterpolationSession(segmentationImage);
else
MITK_INFO<<"3D Interpolation is only supported for 3D images at the moment!";
if (m_3DInterpolationEnabled)
{
if (m_Watcher.isRunning())
m_Watcher.waitForFinished();
m_Future = QtConcurrent::run(this, &QmitkSlicesInterpolator::Run3DInterpolation);
m_Watcher.setFuture(m_Future);
}
}
}
else
{
QWidget::setEnabled(false);
}
}
}
void QmitkSlicesInterpolator::Show3DInterpolationResult(bool status)
{
if (m_InterpolatedSurfaceNode.IsNotNull())
m_InterpolatedSurfaceNode->SetVisibility(status);
if (m_3DContourNode.IsNotNull())
m_3DContourNode->SetVisibility(status, mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget4")));
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkSlicesInterpolator::CheckSupportedImageDimension()
{
- if (m_3DInterpolationEnabled && m_Segmentation->GetDimension() != 3)
+ if (m_ToolManager->GetWorkingData(0))
+ m_Segmentation = dynamic_cast<mitk::Image*>(m_ToolManager->GetWorkingData(0)->GetData());
+
+ if (m_3DInterpolationEnabled && m_Segmentation && m_Segmentation->GetDimension() != 3)
{
QMessageBox info;
info.setWindowTitle("3D Interpolation Process");
info.setIcon(QMessageBox::Information);
info.setText("3D Interpolation is only supported for 3D images at the moment!");
info.exec();
m_CmbInterpolation->setCurrentIndex(0);
}
}
void QmitkSlicesInterpolator::OnSliceNavigationControllerDeleted(const itk::Object *sender, const itk::EventObject& /*e*/)
{
//Don't know how to avoid const_cast here?!
mitk::SliceNavigationController* slicer = dynamic_cast<mitk::SliceNavigationController*>(const_cast<itk::Object*>(sender));
if (slicer)
{
m_ControllerToTimeObserverTag.remove(slicer);
m_ControllerToSliceObserverTag.remove(slicer);
m_ControllerToDeleteObserverTag.remove(slicer);
}
}
diff --git a/Modules/SegmentationUI/Qmitk/QmitkToolGUIArea.cpp b/Modules/SegmentationUI/Qmitk/QmitkToolGUIArea.cpp
index 08fffdd694..2c3b98cc90 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkToolGUIArea.cpp
+++ b/Modules/SegmentationUI/Qmitk/QmitkToolGUIArea.cpp
@@ -1,28 +1,32 @@
/*===================================================================
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 "QmitkToolGUIArea.h"
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
QmitkToolGUIArea::QmitkToolGUIArea( QWidget* parent, Qt::WFlags f )
+#else
+QmitkToolGUIArea::QmitkToolGUIArea( QWidget* parent, Qt::WindowFlags f )
+#endif
:QWidget(parent,f)
{
QWidget::setContentsMargins(0, 0, 0, 0);
}
QmitkToolGUIArea::~QmitkToolGUIArea()
{
}
diff --git a/Modules/SegmentationUI/Qmitk/QmitkToolGUIArea.h b/Modules/SegmentationUI/Qmitk/QmitkToolGUIArea.h
index 658ca80b86..c54224c3d8 100644
--- a/Modules/SegmentationUI/Qmitk/QmitkToolGUIArea.h
+++ b/Modules/SegmentationUI/Qmitk/QmitkToolGUIArea.h
@@ -1,51 +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 QmitkToolGUIArea_h_Included
#define QmitkToolGUIArea_h_Included
#include "mitkCommon.h"
#include <MitkSegmentationUIExports.h>
#include <qwidget.h>
/**
\brief Dummy class for putting into a GUI (mainly using Qt Designer).
This class is nothing more than a QWidget. It is good for use with QmitkToolSelectionBox as a place to display GUIs for active tools.
Last contributor: $Author$
*/
class MitkSegmentationUI_EXPORT QmitkToolGUIArea : public QWidget
{
Q_OBJECT
public:
-
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
QmitkToolGUIArea( QWidget* parent = 0, Qt::WFlags f = 0 );
+#else
+ QmitkToolGUIArea( QWidget* parent = 0, Qt::WindowFlags f = 0 );
+#endif
virtual ~QmitkToolGUIArea();
signals:
public slots:
protected slots:
protected:
};
#endif
diff --git a/Modules/SurfaceInterpolation/Testing/mitkSurfaceInterpolationControllerTest.cpp b/Modules/SurfaceInterpolation/Testing/mitkSurfaceInterpolationControllerTest.cpp
index 3c8977830f..b22d421a5a 100644
--- a/Modules/SurfaceInterpolation/Testing/mitkSurfaceInterpolationControllerTest.cpp
+++ b/Modules/SurfaceInterpolation/Testing/mitkSurfaceInterpolationControllerTest.cpp
@@ -1,398 +1,465 @@
/*===================================================================
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 <mitkSurfaceInterpolationController.h>
#include <mitkTestFixture.h>
#include <mitkTestingMacros.h>
#include <vtkRegularPolygonSource.h>
#include <vtkDebugLeaks.h>
class mitkSurfaceInterpolationControllerTestSuite : public mitk::TestFixture
{
CPPUNIT_TEST_SUITE(mitkSurfaceInterpolationControllerTestSuite);
MITK_TEST(TestSingleton);
MITK_TEST(TestSetCurrentInterpolationSession);
+ MITK_TEST(TestReplaceInterpolationSession);
MITK_TEST(TestRemoveAllInterpolationSessions);
MITK_TEST(TestRemoveInterpolationSession);
MITK_TEST(TestOnSegmentationDeleted);
/// \todo Workaround for memory leak in TestAddNewContour. Bug 18096.
vtkDebugLeaks::SetExitError(0);
MITK_TEST(TestAddNewContour);
MITK_TEST(TestRemoveContour);
CPPUNIT_TEST_SUITE_END();
private:
mitk::SurfaceInterpolationController::Pointer m_Controller;
public:
mitk::Image::Pointer createImage(unsigned int *dimensions)
{
mitk::Image::Pointer newImage = mitk::Image::New();
mitk::PixelType p_type = mitk::MakeScalarPixelType<unsigned char>();
newImage->Initialize(p_type, 3, dimensions);
return newImage;
}
void setUp()
{
m_Controller = mitk::SurfaceInterpolationController::GetInstance();
vtkSmartPointer<vtkRegularPolygonSource> polygonSource = vtkSmartPointer<vtkRegularPolygonSource>::New();
polygonSource->SetRadius(100);
polygonSource->SetNumberOfSides(7);
polygonSource->Update();
mitk::Surface::Pointer surface = mitk::Surface::New();
surface->SetVtkPolyData(polygonSource->GetOutput());
}
void TestSingleton()
{
mitk::SurfaceInterpolationController::Pointer controller2 = mitk::SurfaceInterpolationController::GetInstance();
CPPUNIT_ASSERT_MESSAGE("SurfaceInterpolationController pointers are not equal!", m_Controller.GetPointer() == controller2.GetPointer());
}
void TestSetCurrentInterpolationSession()
{
// Create image for testing
unsigned int dimensions1[] = {10, 10, 10};
mitk::Image::Pointer segmentation_1 = createImage(dimensions1);
unsigned int dimensions2[] = {20, 10, 30};
mitk::Image::Pointer segmentation_2 = createImage(dimensions2);
// Test 1
m_Controller->SetCurrentInterpolationSession(segmentation_1);
MITK_ASSERT_EQUAL(m_Controller->GetCurrentSegmentation(), segmentation_1->Clone(), "Segmentation images are not equal");
CPPUNIT_ASSERT_MESSAGE("Segmentation images are not equal", m_Controller->GetCurrentSegmentation().GetPointer() == segmentation_1.GetPointer());
CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 1", m_Controller->GetNumberOfInterpolationSessions() == 1);
// Test 2
m_Controller->SetCurrentInterpolationSession(segmentation_2);
MITK_ASSERT_EQUAL(m_Controller->GetCurrentSegmentation(), segmentation_2->Clone(), "Segmentation images are not equal");
CPPUNIT_ASSERT_MESSAGE("Segmentation images are not equal", m_Controller->GetCurrentSegmentation().GetPointer() == segmentation_2.GetPointer());
CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 2", m_Controller->GetNumberOfInterpolationSessions() == 2);
// Test 3
m_Controller->SetCurrentInterpolationSession(segmentation_1);
MITK_ASSERT_EQUAL(m_Controller->GetCurrentSegmentation(), segmentation_1->Clone(), "Segmentation images are not equal");
CPPUNIT_ASSERT_MESSAGE("Segmentation images are not equal", m_Controller->GetCurrentSegmentation().GetPointer() == segmentation_1.GetPointer());
CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 2", m_Controller->GetNumberOfInterpolationSessions() == 2);
// Test 4
m_Controller->SetCurrentInterpolationSession(segmentation_1);
MITK_ASSERT_EQUAL(m_Controller->GetCurrentSegmentation(), segmentation_1->Clone(), "Segmentation images are not equal");
CPPUNIT_ASSERT_MESSAGE("Segmentation images are not equal", m_Controller->GetCurrentSegmentation().GetPointer() == segmentation_1.GetPointer());
CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 2", m_Controller->GetNumberOfInterpolationSessions() == 2);
// Test 5
m_Controller->SetCurrentInterpolationSession(0);
CPPUNIT_ASSERT_MESSAGE("Segmentation images are not equal", m_Controller->GetCurrentSegmentation().IsNull());
CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 2", m_Controller->GetNumberOfInterpolationSessions() == 2);
}
+ void TestReplaceInterpolationSession()
+ {
+ // Create segmentation image
+ unsigned int dimensions1[] = {10, 10, 10};
+ mitk::Image::Pointer segmentation_1 = createImage(dimensions1);
+ m_Controller->SetCurrentInterpolationSession(segmentation_1);
+
+ // Create some contours
+ double center_1[3] = {1.25f ,3.43f ,4.44f};
+ double normal_1[3] = {0.25f ,1.76f, 0.93f};
+ vtkSmartPointer<vtkRegularPolygonSource> p_source = vtkSmartPointer<vtkRegularPolygonSource>::New();
+ p_source->SetNumberOfSides(20);
+ p_source->SetCenter(center_1);
+ p_source->SetRadius(4);
+ p_source->SetNormal(normal_1);
+ p_source->Update();
+ vtkPolyData* poly_1 = p_source->GetOutput();
+ mitk::Surface::Pointer surf_1 = mitk::Surface::New();
+ surf_1->SetVtkPolyData(poly_1);
+
+ double center_2[3] = {4.0f ,4.0f ,4.0f};
+ double normal_2[3] = {1.0f ,0.0f, 0.0f};
+ vtkSmartPointer<vtkRegularPolygonSource> p_source_2 = vtkSmartPointer<vtkRegularPolygonSource>::New();
+ p_source_2->SetNumberOfSides(80);
+ p_source_2->SetCenter(center_2);
+ p_source_2->SetRadius(4);
+ p_source_2->SetNormal(normal_2);
+ p_source_2->Update();
+ vtkPolyData* poly_2 = p_source_2->GetOutput();
+ mitk::Surface::Pointer surf_2 = mitk::Surface::New();
+ surf_2->SetVtkPolyData(poly_2);
+
+ // Add contours
+ m_Controller->AddNewContour(surf_1);
+ m_Controller->AddNewContour(surf_2);
+
+ // Check if all contours are there
+ mitk::SurfaceInterpolationController::ContourPositionInformation contourInfo1;
+ contourInfo1.contourNormal = normal_1;
+ contourInfo1.contourPoint = center_1;
+
+ mitk::SurfaceInterpolationController::ContourPositionInformation contourInfo2;
+ contourInfo2.contourNormal = normal_2;
+ contourInfo2.contourPoint = center_2;
+
+ mitk::Image::Pointer segmentation_2 = createImage(dimensions1);
+ bool success = m_Controller->ReplaceInterpolationSession(segmentation_1, segmentation_2);
+ const mitk::Surface* contour_1 = m_Controller->GetContour(contourInfo1);
+ const mitk::Surface* contour_2 = m_Controller->GetContour(contourInfo2);
+
+ CPPUNIT_ASSERT_MESSAGE("Replace session failed!", success == true);
+ CPPUNIT_ASSERT_MESSAGE("Wrong number of contours!", m_Controller->GetNumberOfContours() == 2);
+ CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_1->GetVtkPolyData()), *(contour_1->GetVtkPolyData()), 0.000001, true));
+ CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_2->GetVtkPolyData()), *(contour_2->GetVtkPolyData()), 0.000001, true));
+ CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 1", m_Controller->GetNumberOfInterpolationSessions() == 1);
+ CPPUNIT_ASSERT_MESSAGE("Segmentation images are not equal", m_Controller->GetCurrentSegmentation().GetPointer() == segmentation_2.GetPointer());
+
+ unsigned int dimensions2[] = {10, 20, 10};
+ mitk::Image::Pointer segmentation_3 = createImage(dimensions2);
+ success = m_Controller->ReplaceInterpolationSession(segmentation_2, segmentation_3);
+ CPPUNIT_ASSERT_MESSAGE("Replace session failed!", success == false);
+ CPPUNIT_ASSERT_MESSAGE("Wrong number of contours!", m_Controller->GetNumberOfContours() == 2);
+ CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 1", m_Controller->GetNumberOfInterpolationSessions() == 1);
+ CPPUNIT_ASSERT_MESSAGE("Segmentation images are not equal", m_Controller->GetCurrentSegmentation().GetPointer() == segmentation_2.GetPointer());
+ }
+
void TestRemoveAllInterpolationSessions()
{
// Create image for testing
unsigned int dimensions1[] = {10, 10, 10};
mitk::Image::Pointer segmentation_1 = createImage(dimensions1);
unsigned int dimensions2[] = {20, 10, 30};
mitk::Image::Pointer segmentation_2 = createImage(dimensions2);
// Test 1
m_Controller->SetCurrentInterpolationSession(segmentation_1);
m_Controller->SetCurrentInterpolationSession(segmentation_2);
m_Controller->RemoveAllInterpolationSessions();
CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 0", m_Controller->GetNumberOfInterpolationSessions() == 0);
}
void TestRemoveInterpolationSession()
{
// Create image for testing
unsigned int dimensions1[] = {10, 10, 10};
mitk::Image::Pointer segmentation_1 = createImage(dimensions1);
unsigned int dimensions2[] = {20, 10, 30};
mitk::Image::Pointer segmentation_2 = createImage(dimensions2);
// Test 1
m_Controller->SetCurrentInterpolationSession(segmentation_1);
m_Controller->SetCurrentInterpolationSession(segmentation_2);
CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 2", m_Controller->GetNumberOfInterpolationSessions() == 2);
// Test current segmentation should not be null if another one was removed
m_Controller->RemoveInterpolationSession(segmentation_1);
CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 1", m_Controller->GetNumberOfInterpolationSessions() == 1);
CPPUNIT_ASSERT_MESSAGE("Segmentation images are not equal", m_Controller->GetCurrentSegmentation().GetPointer() == segmentation_2.GetPointer());
CPPUNIT_ASSERT_MESSAGE("Current segmentation is null after another one was removed", m_Controller->GetCurrentSegmentation().IsNotNull());
m_Controller->SetCurrentInterpolationSession(segmentation_1);
CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 2", m_Controller->GetNumberOfInterpolationSessions() == 2);
// Test current segmentation should not be null if another one was removed
m_Controller->RemoveInterpolationSession(segmentation_1);
CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 1", m_Controller->GetNumberOfInterpolationSessions() == 1);
CPPUNIT_ASSERT_MESSAGE("Current segmentation is not null after session was removed", m_Controller->GetCurrentSegmentation().IsNull());
}
void TestOnSegmentationDeleted()
{
{
// Create image for testing
unsigned int dimensions1[] = {10, 10, 10};
mitk::Image::Pointer segmentation_1 = createImage(dimensions1);
m_Controller->SetCurrentInterpolationSession(segmentation_1);
}
CPPUNIT_ASSERT_MESSAGE("Number of interpolation session not 0", m_Controller->GetNumberOfInterpolationSessions() == 0);
}
void TestAddNewContour()
{
// Create segmentation image
unsigned int dimensions1[] = {10, 10, 10};
mitk::Image::Pointer segmentation_1 = createImage(dimensions1);
m_Controller->SetCurrentInterpolationSession(segmentation_1);
// Create some contours
double center_1[3] = {1.25f ,3.43f ,4.44f};
double normal_1[3] = {0.25f ,1.76f, 0.93f};
vtkSmartPointer<vtkRegularPolygonSource> p_source = vtkSmartPointer<vtkRegularPolygonSource>::New();
p_source->SetNumberOfSides(20);
p_source->SetCenter(center_1);
p_source->SetRadius(4);
p_source->SetNormal(normal_1);
p_source->Update();
vtkPolyData* poly_1 = p_source->GetOutput();
mitk::Surface::Pointer surf_1 = mitk::Surface::New();
surf_1->SetVtkPolyData(poly_1);
double center_2[3] = {4.0f ,4.0f ,4.0f};
double normal_2[3] = {1.0f ,0.0f, 0.0f};
vtkSmartPointer<vtkRegularPolygonSource> p_source_2 = vtkSmartPointer<vtkRegularPolygonSource>::New();
p_source_2->SetNumberOfSides(80);
p_source_2->SetCenter(center_2);
p_source_2->SetRadius(4);
p_source_2->SetNormal(normal_2);
p_source_2->Update();
vtkPolyData* poly_2 = p_source_2->GetOutput();
mitk::Surface::Pointer surf_2 = mitk::Surface::New();
surf_2->SetVtkPolyData(poly_2);
double center_3[3] = {4.0f ,4.0f ,3.0f};
double normal_3[3] = {0.0f ,0.0f, 1.0f};
vtkSmartPointer<vtkRegularPolygonSource> p_source_3 = vtkSmartPointer<vtkRegularPolygonSource>::New();
p_source_3->SetNumberOfSides(10);
p_source_3->SetCenter(center_3);
p_source_3->SetRadius(4);
p_source_3->SetNormal(normal_3);
p_source_3->Update();
vtkPolyData* poly_3 = p_source_3->GetOutput();
mitk::Surface::Pointer surf_3 = mitk::Surface::New();
surf_3->SetVtkPolyData(poly_3);
// Add contours
m_Controller->AddNewContour(surf_1);
m_Controller->AddNewContour(surf_2);
m_Controller->AddNewContour(surf_3);
// Check if all contours are there
mitk::SurfaceInterpolationController::ContourPositionInformation contourInfo1;
contourInfo1.contourNormal = normal_1;
contourInfo1.contourPoint = center_1;
mitk::SurfaceInterpolationController::ContourPositionInformation contourInfo2;
contourInfo2.contourNormal = normal_2;
contourInfo2.contourPoint = center_2;
mitk::SurfaceInterpolationController::ContourPositionInformation contourInfo3;
contourInfo3.contourNormal = normal_3;
contourInfo3.contourPoint = center_3;
const mitk::Surface* contour_1 = m_Controller->GetContour(contourInfo1);
const mitk::Surface* contour_2 = m_Controller->GetContour(contourInfo2);
const mitk::Surface* contour_3 = m_Controller->GetContour(contourInfo3);
CPPUNIT_ASSERT_MESSAGE("Wrong number of contours!", m_Controller->GetNumberOfContours() == 3);
CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_1->GetVtkPolyData()), *(contour_1->GetVtkPolyData()), 0.000001, true));
CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_2->GetVtkPolyData()), *(contour_2->GetVtkPolyData()), 0.000001, true));
CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_3->GetVtkPolyData()), *(contour_3->GetVtkPolyData()), 0.000001, true));
// Create another segmentation image
unsigned int dimensions2[] = {20, 20, 20};
mitk::Image::Pointer segmentation_2 = createImage(dimensions2);
m_Controller->SetCurrentInterpolationSession(segmentation_2);
// Create some contours
double center_4[3] = {10.0f ,10.0f ,10.0f};
double normal_4[3] = {0.0f ,1.0f, 0.0f};
vtkSmartPointer<vtkRegularPolygonSource> p_source_4 = vtkSmartPointer<vtkRegularPolygonSource>::New();
p_source_4->SetNumberOfSides(8);
p_source_4->SetCenter(center_4);
p_source_4->SetRadius(5);
p_source_4->SetNormal(normal_4);
p_source_4->Update();
vtkPolyData* poly_4 = p_source_4->GetOutput();
mitk::Surface::Pointer surf_4 = mitk::Surface::New();
surf_4->SetVtkPolyData(poly_4);
double center_5[3] = {3.0f ,10.0f ,10.0f};
double normal_5[3] = {1.0f ,0.0f, 0.0f};
vtkSmartPointer<vtkRegularPolygonSource> p_source_5 = vtkSmartPointer<vtkRegularPolygonSource>::New();
p_source_5->SetNumberOfSides(16);
p_source_5->SetCenter(center_5);
p_source_5->SetRadius(8);
p_source_5->SetNormal(normal_5);
p_source_5->Update();
vtkPolyData* poly_5 = p_source_5->GetOutput();
mitk::Surface::Pointer surf_5 = mitk::Surface::New();
surf_5->SetVtkPolyData(poly_5);
double center_6[3] = {10.0f ,10.0f ,3.0f};
double normal_6[3] = {0.0f ,0.0f, 1.0f};
vtkSmartPointer<vtkRegularPolygonSource> p_source_6 = vtkSmartPointer<vtkRegularPolygonSource>::New();
p_source_6->SetNumberOfSides(100);
p_source_6->SetCenter(center_6);
p_source_6->SetRadius(5);
p_source_6->SetNormal(normal_6);
p_source_6->Update();
vtkPolyData* poly_6 = p_source_6->GetOutput();
mitk::Surface::Pointer surf_6 = mitk::Surface::New();
surf_6->SetVtkPolyData(poly_6);
mitk::SurfaceInterpolationController::ContourPositionInformation contourInfo4;
contourInfo4.contourNormal = normal_4;
contourInfo4.contourPoint = center_4;
mitk::SurfaceInterpolationController::ContourPositionInformation contourInfo5;
contourInfo5.contourNormal = normal_5;
contourInfo5.contourPoint = center_5;
mitk::SurfaceInterpolationController::ContourPositionInformation contourInfo6;
contourInfo6.contourNormal = normal_6;
contourInfo6.contourPoint = center_6;
// Add contours
m_Controller->AddNewContour(surf_4);
m_Controller->AddNewContour(surf_5);
m_Controller->AddNewContour(surf_6);
// Check if all contours are there
mitk::Surface* contour_4 = const_cast<mitk::Surface*>(m_Controller->GetContour(contourInfo4));
mitk::Surface* contour_5 = const_cast<mitk::Surface*>(m_Controller->GetContour(contourInfo5));
mitk::Surface* contour_6 = const_cast<mitk::Surface*>(m_Controller->GetContour(contourInfo6));
CPPUNIT_ASSERT_MESSAGE("Wrong number of contours!", m_Controller->GetNumberOfContours() == 3);
CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_4->GetVtkPolyData()), *(contour_4->GetVtkPolyData()), 0.000001, true));
CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_5->GetVtkPolyData()), *(contour_5->GetVtkPolyData()), 0.000001, true));
CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_6->GetVtkPolyData()), *(contour_6->GetVtkPolyData()), 0.000001, true));
// Modify some contours
vtkSmartPointer<vtkRegularPolygonSource> p_source_7 = vtkSmartPointer<vtkRegularPolygonSource>::New();
p_source_7->SetNumberOfSides(200);
p_source_7->SetCenter(3.0,10.0,10.0);
p_source_7->SetRadius(5);
p_source_7->SetNormal(1, 0, 0);
p_source_7->Update();
vtkPolyData* poly_7 = p_source_7->GetOutput();
mitk::Surface::Pointer surf_7 = mitk::Surface::New();
surf_7->SetVtkPolyData(poly_7);
m_Controller->AddNewContour(surf_7);
mitk::Surface* contour_7 = const_cast<mitk::Surface*>(m_Controller->GetContour(contourInfo5));
CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_7->GetVtkPolyData()), *(contour_7->GetVtkPolyData()), 0.000001, true));
// Change session and test if all contours are available
m_Controller->SetCurrentInterpolationSession(segmentation_1);
mitk::Surface* contour_8 = const_cast<mitk::Surface*>(m_Controller->GetContour(contourInfo1));
mitk::Surface* contour_9 = const_cast<mitk::Surface*>(m_Controller->GetContour(contourInfo2));
mitk::Surface* contour_10 = const_cast<mitk::Surface*>(m_Controller->GetContour(contourInfo3));
CPPUNIT_ASSERT_MESSAGE("Wrong number of contours!", m_Controller->GetNumberOfContours() == 3);
CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_1->GetVtkPolyData()), *(contour_8->GetVtkPolyData()), 0.000001, true));
CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_2->GetVtkPolyData()), *(contour_9->GetVtkPolyData()), 0.000001, true));
CPPUNIT_ASSERT_MESSAGE("Contours not equal!", mitk::Equal(*(surf_3->GetVtkPolyData()), *(contour_10->GetVtkPolyData()), 0.000001, true));
}
void TestRemoveContour()
{
// Create segmentation image
unsigned int dimensions1[] = {10, 10, 10};
mitk::Image::Pointer segmentation_1 = createImage(dimensions1);
m_Controller->SetCurrentInterpolationSession(segmentation_1);
// Create some contours
double center_1[3] = {4.0f ,4.0f ,4.0f};
double normal_1[3] = {0.0f ,1.0f, 0.0f};
vtkSmartPointer<vtkRegularPolygonSource> p_source = vtkSmartPointer<vtkRegularPolygonSource>::New();
p_source->SetNumberOfSides(20);
p_source->SetCenter(center_1);
p_source->SetRadius(4);
p_source->SetNormal(normal_1);
p_source->Update();
vtkPolyData* poly_1 = p_source->GetOutput();
mitk::Surface::Pointer surf_1 = mitk::Surface::New();
surf_1->SetVtkPolyData(poly_1);
double center_2[3] = {4.0f ,4.0f ,4.0f};
double normal_2[3] = {1.0f ,0.0f, 0.0f};
vtkSmartPointer<vtkRegularPolygonSource> p_source_2 = vtkSmartPointer<vtkRegularPolygonSource>::New();
p_source_2->SetNumberOfSides(80);
p_source_2->SetCenter(center_2);
p_source_2->SetRadius(4);
p_source_2->SetNormal(normal_2);
p_source_2->Update();
vtkPolyData* poly_2 = p_source_2->GetOutput();
mitk::Surface::Pointer surf_2 = mitk::Surface::New();
surf_2->SetVtkPolyData(poly_2);
// Add contours
m_Controller->AddNewContour(surf_1);
m_Controller->AddNewContour(surf_2);
CPPUNIT_ASSERT_MESSAGE("Wrong number of contours!", m_Controller->GetNumberOfContours() == 2);
mitk::SurfaceInterpolationController::ContourPositionInformation contourInfo3;
contourInfo3.contour = surf_1->Clone();
contourInfo3.contourNormal = normal_1;
contourInfo3.contourPoint = center_1;
// Shift the new contour so that it is different
contourInfo3.contourPoint += 0.5;
bool success = m_Controller->RemoveContour(contourInfo3);
CPPUNIT_ASSERT_MESSAGE("Remove failed - contour was unintentionally removed!", (m_Controller->GetNumberOfContours() == 2) && !success);
mitk::SurfaceInterpolationController::ContourPositionInformation contourInfo2;
contourInfo2.contourNormal = normal_2;
contourInfo2.contourPoint = center_2;
contourInfo2.contour = surf_2;
success = m_Controller->RemoveContour(contourInfo2);
CPPUNIT_ASSERT_MESSAGE("Remove failed - contour was not removed!", (m_Controller->GetNumberOfContours() == 1) && success);
// Let's see if the other contour No. 1 is still there
contourInfo3.contourPoint -= 0.5;
const mitk::Surface* remainingContour = m_Controller->GetContour(contourInfo3);
CPPUNIT_ASSERT_MESSAGE("Remove failed - contour was accidentally removed!",
(m_Controller->GetNumberOfContours() == 1) &&
mitk::Equal(*(surf_1->GetVtkPolyData()), *(remainingContour->GetVtkPolyData()), 0.000001, true) &&success);
}
};
MITK_TEST_SUITE_REGISTRATION(mitkSurfaceInterpolationController)
diff --git a/Modules/SurfaceInterpolation/mitkSurfaceInterpolationController.cpp b/Modules/SurfaceInterpolation/mitkSurfaceInterpolationController.cpp
index 036348812c..dc6a5fc40d 100644
--- a/Modules/SurfaceInterpolation/mitkSurfaceInterpolationController.cpp
+++ b/Modules/SurfaceInterpolation/mitkSurfaceInterpolationController.cpp
@@ -1,547 +1,577 @@
/*===================================================================
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 "mitkSurfaceInterpolationController.h"
#include "mitkMemoryUtilities.h"
#include "mitkImageAccessByItk.h"
#include "mitkImageCast.h"
#include "mitkImageToSurfaceFilter.h"
// Check whether the given contours are coplanar
bool ContoursCoplanar(mitk::SurfaceInterpolationController::ContourPositionInformation leftHandSide, mitk::SurfaceInterpolationController::ContourPositionInformation rightHandSide)
{
// Here we check two things:
// 1. Whether the normals of both contours are at least parallel
// 2. Whether both contours lie in the same plane
// Check for coplanarity:
// a. Span a vector between two points one from each contour
// b. Calculate dot product for the vector and one of the normals
// c. If the dot is zero the two vectors are orthogonal and the contours are coplanar
double vec[3];
vec[0] = leftHandSide.contourPoint[0] - rightHandSide.contourPoint[0];
vec[1] = leftHandSide.contourPoint[1] - rightHandSide.contourPoint[1];
vec[2] = leftHandSide.contourPoint[2] - rightHandSide.contourPoint[2];
double n[3];
n[0] = rightHandSide.contourNormal[0];
n[1] = rightHandSide.contourNormal[1];
n[2] = rightHandSide.contourNormal[2];
double dot = vtkMath::Dot(n, vec);
double n2[3];
n2[0] = leftHandSide.contourNormal[0];
n2[1] = leftHandSide.contourNormal[1];
n2[2] = leftHandSide.contourNormal[2];
// The normals of both contours have to be parallel but not of the same orientation
double lengthLHS = leftHandSide.contourNormal.GetNorm();
double lengthRHS = rightHandSide.contourNormal.GetNorm();
double dot2 = vtkMath::Dot(n, n2);
bool contoursParallel = mitk::Equal(fabs(lengthLHS*lengthRHS), fabs(dot2), 0.001);
if (mitk::Equal(dot, 0.0, 0.001) && contoursParallel)
return true;
else
return false;
}
mitk::SurfaceInterpolationController::ContourPositionInformation CreateContourPositionInformation(mitk::Surface::Pointer contour)
{
mitk::SurfaceInterpolationController::ContourPositionInformation contourInfo;
contourInfo.contour = contour;
double n[3];
double p[3];
contour->GetVtkPolyData()->GetPoints()->GetPoint(0, p);
vtkPolygon::ComputeNormal(contour->GetVtkPolyData()->GetPoints(), n);
contourInfo.contourNormal = n;
contourInfo.contourPoint = p;
return contourInfo;
}
mitk::SurfaceInterpolationController::SurfaceInterpolationController()
:m_SelectedSegmentation(0)
{
m_ReduceFilter = ReduceContourSetFilter::New();
m_NormalsFilter = ComputeContourSetNormalsFilter::New();
m_InterpolateSurfaceFilter = CreateDistanceImageFromSurfaceFilter::New();
m_ReduceFilter->SetUseProgressBar(false);
// m_ReduceFilter->SetProgressStepSize(1);
m_NormalsFilter->SetUseProgressBar(true);
m_NormalsFilter->SetProgressStepSize(1);
m_InterpolateSurfaceFilter->SetUseProgressBar(true);
m_InterpolateSurfaceFilter->SetProgressStepSize(7);
m_Contours = Surface::New();
m_PolyData = vtkSmartPointer<vtkPolyData>::New();
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
m_PolyData->SetPoints(points);
m_InterpolationResult = 0;
m_CurrentNumberOfReducedContours = 0;
}
mitk::SurfaceInterpolationController::~SurfaceInterpolationController()
{
//Removing all observers
std::map<mitk::Image*, unsigned long>::iterator dataIter = m_SegmentationObserverTags.begin();
for (; dataIter != m_SegmentationObserverTags.end(); ++dataIter )
{
(*dataIter).first->RemoveObserver( (*dataIter).second );
}
m_SegmentationObserverTags.clear();
}
mitk::SurfaceInterpolationController* mitk::SurfaceInterpolationController::GetInstance()
{
static mitk::SurfaceInterpolationController::Pointer m_Instance;
if ( m_Instance.IsNull() )
{
m_Instance = SurfaceInterpolationController::New();
}
return m_Instance;
}
void mitk::SurfaceInterpolationController::AddNewContour (mitk::Surface::Pointer newContour)
{
if( newContour->GetVtkPolyData()->GetNumberOfPoints() > 0)
{
ContourPositionInformation contourInfo = CreateContourPositionInformation(newContour);
this->AddToInterpolationPipeline(contourInfo);
this->Modified();
}
}
void mitk::SurfaceInterpolationController::AddNewContours(std::vector<mitk::Surface::Pointer> newContours)
{
for (unsigned int i = 0; i < newContours.size(); ++i)
{
if( newContours.at(i)->GetVtkPolyData()->GetNumberOfPoints() > 0)
{
ContourPositionInformation contourInfo = CreateContourPositionInformation(newContours.at(i));
this->AddToInterpolationPipeline(contourInfo);
}
}
this->Modified();
}
void mitk::SurfaceInterpolationController::AddToInterpolationPipeline(ContourPositionInformation contourInfo)
{
int pos (-1);
ContourPositionInformationList currentContourList = m_ListOfInterpolationSessions[m_SelectedSegmentation];
mitk::Surface* newContour = contourInfo.contour;
for (unsigned int i = 0; i < currentContourList.size(); i++)
{
ContourPositionInformation contourFromList = currentContourList.at(i);
if (ContoursCoplanar(contourInfo, contourFromList))
{
pos = i;
break;
}
}
//Don't save a new empty contour
if (pos == -1 && newContour->GetVtkPolyData()->GetNumberOfPoints() > 0)
{
m_ReduceFilter->SetInput(m_ListOfInterpolationSessions[m_SelectedSegmentation].size(), newContour);
m_ListOfInterpolationSessions[m_SelectedSegmentation].push_back(contourInfo);
}
else if (pos != -1 && newContour->GetVtkPolyData()->GetNumberOfPoints() > 0)
{
m_ListOfInterpolationSessions[m_SelectedSegmentation].at(pos) = contourInfo;
m_ReduceFilter->SetInput(pos, newContour);
}
else if (newContour->GetVtkPolyData()->GetNumberOfPoints() == 0)
{
this->RemoveContour(contourInfo);
}
m_ReduceFilter->Update();
m_CurrentNumberOfReducedContours = m_ReduceFilter->GetNumberOfOutputs();
for (unsigned int i = 0; i < m_CurrentNumberOfReducedContours; i++)
{
m_NormalsFilter->SetInput(i, m_ReduceFilter->GetOutput(i));
m_InterpolateSurfaceFilter->SetInput(i, m_NormalsFilter->GetOutput(i));
}
}
bool mitk::SurfaceInterpolationController::RemoveContour(ContourPositionInformation contourInfo)
{
if(!m_SelectedSegmentation)
return false;
ContourPositionInformationList::iterator it = m_ListOfInterpolationSessions[m_SelectedSegmentation].begin();
while (it != m_ListOfInterpolationSessions[m_SelectedSegmentation].end())
{
ContourPositionInformation currentContour = (*it);
if (ContoursCoplanar(currentContour, contourInfo))
{
m_ListOfInterpolationSessions[m_SelectedSegmentation].erase(it);
this->ReinitializeInterpolation();
return true;
}
++it;
}
return false;
}
const mitk::Surface* mitk::SurfaceInterpolationController::GetContour(ContourPositionInformation contourInfo)
{
ContourPositionInformationList contourList = m_ListOfInterpolationSessions[m_SelectedSegmentation];
for (unsigned int i = 0; i < contourList.size(); ++i)
{
ContourPositionInformation currentContour = contourList.at(i);
if (ContoursCoplanar(contourInfo, currentContour))
return currentContour.contour;
}
return 0;
}
unsigned int mitk::SurfaceInterpolationController::GetNumberOfContours()
{
return m_ListOfInterpolationSessions[m_SelectedSegmentation].size();
}
void mitk::SurfaceInterpolationController::Interpolate()
{
if (m_CurrentNumberOfReducedContours< 2)
{
//If no interpolation is possible reset the interpolation result
m_InterpolationResult = 0;
return;
}
//Setting up progress bar
mitk::ProgressBar::GetInstance()->AddStepsToDo(10);
// create a surface from the distance-image
mitk::ImageToSurfaceFilter::Pointer imageToSurfaceFilter = mitk::ImageToSurfaceFilter::New();
imageToSurfaceFilter->SetInput( m_InterpolateSurfaceFilter->GetOutput() );
imageToSurfaceFilter->SetThreshold( 0 );
imageToSurfaceFilter->SetSmooth(true);
imageToSurfaceFilter->SetSmoothIteration(20);
imageToSurfaceFilter->Update();
m_InterpolationResult = imageToSurfaceFilter->GetOutput();
vtkSmartPointer<vtkAppendPolyData> polyDataAppender = vtkSmartPointer<vtkAppendPolyData>::New();
for (unsigned int i = 0; i < m_ListOfInterpolationSessions[m_SelectedSegmentation].size(); i++)
{
polyDataAppender->AddInputData(m_ListOfInterpolationSessions[m_SelectedSegmentation].at(i).contour->GetVtkPolyData());
}
polyDataAppender->Update();
m_Contours->SetVtkPolyData(polyDataAppender->GetOutput());
//Last progress step
mitk::ProgressBar::GetInstance()->Progress(20);
m_InterpolationResult->DisconnectPipeline();
}
mitk::Surface::Pointer mitk::SurfaceInterpolationController::GetInterpolationResult()
{
return m_InterpolationResult;
}
mitk::Surface* mitk::SurfaceInterpolationController::GetContoursAsSurface()
{
return m_Contours;
}
void mitk::SurfaceInterpolationController::SetDataStorage(DataStorage::Pointer ds)
{
m_DataStorage = ds;
}
void mitk::SurfaceInterpolationController::SetMinSpacing(double minSpacing)
{
m_ReduceFilter->SetMinSpacing(minSpacing);
}
void mitk::SurfaceInterpolationController::SetMaxSpacing(double maxSpacing)
{
m_ReduceFilter->SetMaxSpacing(maxSpacing);
m_NormalsFilter->SetMaxSpacing(maxSpacing);
}
void mitk::SurfaceInterpolationController::SetDistanceImageVolume(unsigned int distImgVolume)
{
m_InterpolateSurfaceFilter->SetDistanceImageVolume(distImgVolume);
}
mitk::Image::Pointer mitk::SurfaceInterpolationController::GetCurrentSegmentation()
{
return m_SelectedSegmentation;
}
mitk::Image* mitk::SurfaceInterpolationController::GetImage()
{
return m_InterpolateSurfaceFilter->GetOutput();
}
double mitk::SurfaceInterpolationController::EstimatePortionOfNeededMemory()
{
double numberOfPointsAfterReduction = m_ReduceFilter->GetNumberOfPointsAfterReduction()*3;
double sizeOfPoints = pow(numberOfPointsAfterReduction,2)*sizeof(double);
double totalMem = mitk::MemoryUtilities::GetTotalSizeOfPhysicalRam();
double percentage = sizeOfPoints/totalMem;
return percentage;
}
unsigned int mitk::SurfaceInterpolationController::GetNumberOfInterpolationSessions()
{
return m_ListOfInterpolationSessions.size();
}
template<typename TPixel, unsigned int VImageDimension>
void mitk::SurfaceInterpolationController::GetImageBase(itk::Image<TPixel, VImageDimension>* input, itk::ImageBase<3>::Pointer& result)
{
result->Graft(input);
}
void mitk::SurfaceInterpolationController::SetCurrentSegmentationInterpolationList(mitk::Image::Pointer segmentation)
{
this->SetCurrentInterpolationSession(segmentation);
}
void mitk::SurfaceInterpolationController::SetCurrentInterpolationSession(mitk::Image::Pointer currentSegmentationImage)
{
if (currentSegmentationImage.GetPointer() == m_SelectedSegmentation)
return;
if (currentSegmentationImage.IsNull())
{
m_SelectedSegmentation = 0;
return;
}
m_SelectedSegmentation = currentSegmentationImage.GetPointer();
ContourListMap::iterator it = m_ListOfInterpolationSessions.find(currentSegmentationImage.GetPointer());
// If the session does not exist yet create a new ContourPositionPairList otherwise reinitialize the interpolation pipeline
if (it == m_ListOfInterpolationSessions.end())
{
ContourPositionInformationList newList;
m_ListOfInterpolationSessions.insert(std::pair<mitk::Image*, ContourPositionInformationList>(m_SelectedSegmentation, newList));
m_InterpolationResult = 0;
m_CurrentNumberOfReducedContours = 0;
itk::MemberCommand<SurfaceInterpolationController>::Pointer command = itk::MemberCommand<SurfaceInterpolationController>::New();
command->SetCallbackFunction(this, &SurfaceInterpolationController::OnSegmentationDeleted);
m_SegmentationObserverTags.insert( std::pair<mitk::Image*, unsigned long>( m_SelectedSegmentation, m_SelectedSegmentation->AddObserver( itk::DeleteEvent(), command ) ) );
}
this->ReinitializeInterpolation();
}
+bool mitk::SurfaceInterpolationController::ReplaceInterpolationSession(mitk::Image::Pointer oldSession, mitk::Image::Pointer newSession)
+{
+ if (oldSession.IsNull() || newSession.IsNull())
+ return false;
+
+ if (oldSession.GetPointer() == newSession.GetPointer())
+ return false;
+
+ if (!mitk::Equal(*(oldSession->GetGeometry()), *(newSession->GetGeometry()), mitk::eps, false))
+ return false;
+
+ ContourListMap::iterator it = m_ListOfInterpolationSessions.find(oldSession.GetPointer());
+
+ if (it == m_ListOfInterpolationSessions.end())
+ return false;
+
+ ContourPositionInformationList oldList = (*it).second;
+ m_ListOfInterpolationSessions.insert(std::pair<mitk::Image*, ContourPositionInformationList>(newSession.GetPointer(), oldList));
+ itk::MemberCommand<SurfaceInterpolationController>::Pointer command = itk::MemberCommand<SurfaceInterpolationController>::New();
+ command->SetCallbackFunction(this, &SurfaceInterpolationController::OnSegmentationDeleted);
+ m_SegmentationObserverTags.insert( std::pair<mitk::Image*, unsigned long>( newSession, newSession->AddObserver( itk::DeleteEvent(), command ) ) );
+
+ if (m_SelectedSegmentation == oldSession)
+ m_SelectedSegmentation = newSession;
+ m_NormalsFilter->SetSegmentationBinaryImage(m_SelectedSegmentation);
+
+ this->RemoveInterpolationSession(oldSession);
+ return true;
+}
+
void mitk::SurfaceInterpolationController::RemoveSegmentationFromContourList(mitk::Image *segmentation)
{
this->RemoveInterpolationSession(segmentation);
}
void mitk::SurfaceInterpolationController::RemoveInterpolationSession(mitk::Image::Pointer segmentationImage)
{
if (segmentationImage)
{
if (m_SelectedSegmentation == segmentationImage)
{
m_NormalsFilter->SetSegmentationBinaryImage(NULL);
m_SelectedSegmentation = 0;
}
m_ListOfInterpolationSessions.erase(segmentationImage);
// Remove observer
std::map<mitk::Image*, unsigned long>::iterator pos = m_SegmentationObserverTags.find(segmentationImage);
if (pos != m_SegmentationObserverTags.end())
{
segmentationImage->RemoveObserver((*pos).second);
m_SegmentationObserverTags.erase(pos);
}
}
}
void mitk::SurfaceInterpolationController::RemoveAllInterpolationSessions()
{
//Removing all observers
std::map<mitk::Image*, unsigned long>::iterator dataIter = m_SegmentationObserverTags.begin();
while (dataIter != m_SegmentationObserverTags.end())
{
mitk::Image* image = (*dataIter).first;
image->RemoveObserver((*dataIter).second);
++dataIter;
}
m_SegmentationObserverTags.clear();
m_SelectedSegmentation = 0;
m_ListOfInterpolationSessions.clear();
}
void mitk::SurfaceInterpolationController::ReinitializeInterpolation(mitk::Surface::Pointer contours)
{
// 1. detect coplanar contours
// 2. merge coplanar contours into a single surface
// 4. add contour to pipeline
// Split the surface into separate polygons
vtkSmartPointer<vtkCellArray> existingPolys;
vtkSmartPointer<vtkPoints> existingPoints;
existingPolys = contours->GetVtkPolyData()->GetPolys();
existingPoints = contours->GetVtkPolyData()->GetPoints();
existingPolys->InitTraversal();
vtkSmartPointer<vtkIdList> ids = vtkSmartPointer<vtkIdList>::New();
typedef std::pair<mitk::Vector3D, mitk::Point3D> PointNormalPair;
std::vector<ContourPositionInformation> list;
std::vector<vtkSmartPointer<vtkPoints> > pointsList;
int count (0);
for( existingPolys->InitTraversal(); existingPolys->GetNextCell(ids);)
{
// Get the points
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
existingPoints->GetPoints(ids, points);
++count;
pointsList.push_back(points);
PointNormalPair p_n;
double n[3];
vtkPolygon::ComputeNormal(points, n);
p_n.first = n;
double p[3];
existingPoints->GetPoint(ids->GetId(0), p);
p_n.second = p;
ContourPositionInformation p_info;
p_info.contourNormal = n;
p_info.contourPoint = p;
list.push_back(p_info);
continue;
}
// Detect and sort coplanar polygons
std::vector<ContourPositionInformation>::iterator outer = list.begin();
std::vector< std::vector< vtkSmartPointer<vtkPoints> > > relatedPoints;
while (outer != list.end())
{
std::vector<ContourPositionInformation>::iterator inner = outer;
++inner;
std::vector< vtkSmartPointer<vtkPoints> > rel;
std::vector< vtkSmartPointer<vtkPoints> >::iterator pointsIter = pointsList.begin();
rel.push_back((*pointsIter));
pointsIter = pointsList.erase(pointsIter);
while (inner != list.end())
{
if(ContoursCoplanar((*outer),(*inner)))
{
inner = list.erase(inner);
rel.push_back((*pointsIter));
pointsIter = pointsList.erase(pointsIter);
}
else
{
++inner;
++pointsIter;
}
}
relatedPoints.push_back(rel);
++outer;
}
// Build the separate surfaces again
std::vector<mitk::Surface::Pointer> finalSurfaces;
for (unsigned int i = 0; i < relatedPoints.size(); ++i)
{
vtkSmartPointer<vtkPolyData> contourSurface = vtkSmartPointer<vtkPolyData>::New();
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
vtkSmartPointer<vtkCellArray> polygons = vtkSmartPointer<vtkCellArray>::New();
unsigned int pointId (0);
for (unsigned int j = 0; j < relatedPoints.at(i).size(); ++j)
{
unsigned int numPoints = relatedPoints.at(i).at(j)->GetNumberOfPoints();
vtkSmartPointer<vtkPolygon> polygon = vtkSmartPointer<vtkPolygon>::New();
polygon->GetPointIds()->SetNumberOfIds(numPoints);
polygon->GetPoints()->SetNumberOfPoints(numPoints);
vtkSmartPointer<vtkPoints> currentPoints = relatedPoints.at(i).at(j);
for (unsigned k = 0; k < numPoints; ++k)
{
points->InsertPoint(pointId, currentPoints->GetPoint(k));
polygon->GetPointIds()->SetId(k, pointId);
++pointId;
}
polygons->InsertNextCell(polygon);
}
contourSurface->SetPoints(points);
contourSurface->SetPolys(polygons);
contourSurface->BuildLinks();
mitk::Surface::Pointer surface = mitk::Surface::New();
surface->SetVtkPolyData(contourSurface);
finalSurfaces.push_back(surface);
}
// Add detected contours to interpolation pipeline
this->AddNewContours(finalSurfaces);
}
void mitk::SurfaceInterpolationController::OnSegmentationDeleted(const itk::Object *caller, const itk::EventObject &/*event*/)
{
mitk::Image* tempImage = dynamic_cast<mitk::Image*>(const_cast<itk::Object*>(caller));
if (tempImage)
{
if (m_SelectedSegmentation == tempImage)
{
m_NormalsFilter->SetSegmentationBinaryImage(NULL);
m_SelectedSegmentation = 0;
}
m_SegmentationObserverTags.erase(tempImage);
m_ListOfInterpolationSessions.erase(tempImage);
}
}
void mitk::SurfaceInterpolationController::ReinitializeInterpolation()
{
m_NormalsFilter->SetSegmentationBinaryImage(m_SelectedSegmentation);
// If session has changed reset the pipeline
m_ReduceFilter->Reset();
m_NormalsFilter->Reset();
m_InterpolateSurfaceFilter->Reset();
itk::ImageBase<3>::Pointer itkImage = itk::ImageBase<3>::New();
AccessFixedDimensionByItk_1( m_SelectedSegmentation, GetImageBase, 3, itkImage );
m_InterpolateSurfaceFilter->SetReferenceImage(itkImage.GetPointer());
for (unsigned int i = 0; i < m_ListOfInterpolationSessions[m_SelectedSegmentation].size(); i++)
{
m_ReduceFilter->SetInput(i, m_ListOfInterpolationSessions[m_SelectedSegmentation].at(i).contour);
}
m_ReduceFilter->Update();
m_CurrentNumberOfReducedContours = m_ReduceFilter->GetNumberOfOutputs();
for (unsigned int i = 0; i < m_CurrentNumberOfReducedContours; i++)
{
m_NormalsFilter->SetInput(i, m_ReduceFilter->GetOutput(i));
m_InterpolateSurfaceFilter->SetInput(i, m_NormalsFilter->GetOutput(i));
}
Modified();
}
diff --git a/Modules/SurfaceInterpolation/mitkSurfaceInterpolationController.h b/Modules/SurfaceInterpolation/mitkSurfaceInterpolationController.h
index 12285d0361..50654d7785 100644
--- a/Modules/SurfaceInterpolation/mitkSurfaceInterpolationController.h
+++ b/Modules/SurfaceInterpolation/mitkSurfaceInterpolationController.h
@@ -1,226 +1,236 @@
/*===================================================================
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 mitkSurfaceInterpolationController_h_Included
#define mitkSurfaceInterpolationController_h_Included
#include "mitkCommon.h"
#include <MitkSurfaceInterpolationExports.h>
#include "mitkRestorePlanePositionOperation.h"
#include "mitkSurface.h"
#include "mitkInteractionConst.h"
#include "mitkColorProperty.h"
#include "mitkProperties.h"
#include "mitkCreateDistanceImageFromSurfaceFilter.h"
#include "mitkReduceContourSetFilter.h"
#include "mitkComputeContourSetNormalsFilter.h"
#include "mitkDataNode.h"
#include "mitkDataStorage.h"
#include "mitkWeakPointer.h"
#include "vtkPolygon.h"
#include "vtkPoints.h"
#include "vtkCellArray.h"
#include "vtkPolyData.h"
#include "vtkSmartPointer.h"
#include "vtkAppendPolyData.h"
#include "vtkMarchingCubes.h"
#include "vtkImageData.h"
#include "mitkVtkRepresentationProperty.h"
#include "vtkProperty.h"
#include "mitkProgressBar.h"
namespace mitk
{
class MitkSurfaceInterpolation_EXPORT SurfaceInterpolationController : public itk::Object
{
public:
mitkClassMacro(SurfaceInterpolationController, itk::Object)
itkFactorylessNewMacro(Self)
itkCloneMacro(Self)
struct ContourPositionInformation {
Surface::Pointer contour;
Vector3D contourNormal;
Point3D contourPoint;
};
typedef std::vector<ContourPositionInformation> ContourPositionInformationList;
typedef std::map<mitk::Image*, ContourPositionInformationList> ContourListMap;
static SurfaceInterpolationController* GetInstance();
/**
* @brief Adds a new extracted contour to the list
* @param newContour the contour to be added. If a contour at that position
* already exists the related contour will be updated
*/
void AddNewContour (Surface::Pointer newContour);
/**
* @brief Removes the contour for a given plane for the current selected segmenation
* @param contourInfo the contour which should be removed
* @return true if a contour was found and removed, false if no contour was found
*/
bool RemoveContour (ContourPositionInformation contourInfo);
/**
* @brief Adds new extracted contours to the list. If one or more contours at a given position
* already exist they will be updated respectively
* @param newContours the list of the contours
*/
void AddNewContours (std::vector<Surface::Pointer> newContours);
/**
* @brief Returns the contour for a given plane for the current selected segmenation
* @param ontourInfo the contour which should be returned
* @return the contour as an mitk::Surface. If no contour is available at the give position NULL is returned
*/
const mitk::Surface* GetContour (ContourPositionInformation contourInfo);
/**
* @brief Returns the number of available contours for the current selected segmentation
* @return the number of contours
*/
unsigned int GetNumberOfContours();
/**
* Interpolates the 3D surface from the given extracted contours
*/
void Interpolate ();
mitk::Surface::Pointer GetInterpolationResult();
/**
* Sets the minimum spacing of the current selected segmentation
* This is needed since the contour points we reduced before they are used to interpolate the surface
*/
void SetMinSpacing(double minSpacing);
/**
* Sets the minimum spacing of the current selected segmentation
* This is needed since the contour points we reduced before they are used to interpolate the surface
*/
void SetMaxSpacing(double maxSpacing);
/**
* Sets the volume i.e. the number of pixels that the distance image should have
* By evaluation we found out that 50.000 pixel delivers a good result
*/
void SetDistanceImageVolume(unsigned int distImageVolume);
/**
* @brief Get the current selected segmentation for which the interpolation is performed
* @return the current segmentation image
*/
mitk::Image::Pointer GetCurrentSegmentation();
Surface* GetContoursAsSurface();
void SetDataStorage(DataStorage::Pointer ds);
/**
* Sets the current list of contourpoints which is used for the surface interpolation
* @param segmentation The current selected segmentation
* \deprecatedSince{2014_03}
*/
DEPRECATED (void SetCurrentSegmentationInterpolationList(mitk::Image::Pointer segmentation));
/**
* Sets the current list of contourpoints which is used for the surface interpolation
* @param segmentation The current selected segmentation
*/
void SetCurrentInterpolationSession(mitk::Image::Pointer currentSegmentationImage);
/**
* Removes the segmentation and all its contours from the list
* @param segmentation The segmentation to be removed
* \deprecatedSince{2014_03}
*/
DEPRECATED (void RemoveSegmentationFromContourList(mitk::Image* segmentation));
/**
* @brief Remove interpolation session
* @param segmentationImage the session to be removed
*/
void RemoveInterpolationSession(mitk::Image::Pointer segmentationImage);
+ /**
+ * Replaces the current interpolation session with a new one. All contours form the old
+ * session will be applied to the new session. This only works if the two images have the
+ * geometry
+ * @param oldSession the session which should be replaced
+ * @param newSession the new session which replaces the old one
+ * @return true it the the replacement was successful, false if not (e.g. the image's geometry differs)
+ */
+ bool ReplaceInterpolationSession(mitk::Image::Pointer oldSession, mitk::Image::Pointer newSession);
+
/**
* @brief Removes all sessions
*/
void RemoveAllInterpolationSessions();
/**
* @brief Reinitializes the interpolation using the provided contour data
* @param contours a mitk::Surface which contains the contours as polys in the vtkPolyData
*/
void ReinitializeInterpolation(mitk::Surface::Pointer contours);
mitk::Image* GetImage();
/**
* Estimates the memory which is needed to build up the equationsystem for the interpolation.
* \returns The percentage of the real memory which will be used by the interpolation
*/
double EstimatePortionOfNeededMemory();
unsigned int GetNumberOfInterpolationSessions();
protected:
SurfaceInterpolationController();
~SurfaceInterpolationController();
template<typename TPixel, unsigned int VImageDimension> void GetImageBase(itk::Image<TPixel, VImageDimension>* input, itk::ImageBase<3>::Pointer& result);
private:
void OnSegmentationDeleted(const itk::Object *caller, const itk::EventObject &event);
void ReinitializeInterpolation();
void AddToInterpolationPipeline(ContourPositionInformation contourInfo);
ReduceContourSetFilter::Pointer m_ReduceFilter;
ComputeContourSetNormalsFilter::Pointer m_NormalsFilter;
CreateDistanceImageFromSurfaceFilter::Pointer m_InterpolateSurfaceFilter;
Surface::Pointer m_Contours;
vtkSmartPointer<vtkPolyData> m_PolyData;
mitk::DataStorage::Pointer m_DataStorage;
ContourListMap m_ListOfInterpolationSessions;
mitk::Surface::Pointer m_InterpolationResult;
unsigned int m_CurrentNumberOfReducedContours;
mitk::Image* m_SelectedSegmentation;
std::map<mitk::Image*, unsigned long> m_SegmentationObserverTags;
};
}
#endif
diff --git a/Modules/ToFHardware/Testing/mitkToFImageRecorderTest.cpp b/Modules/ToFHardware/Testing/mitkToFImageRecorderTest.cpp
index 2623414640..18b2671b58 100644
--- a/Modules/ToFHardware/Testing/mitkToFImageRecorderTest.cpp
+++ b/Modules/ToFHardware/Testing/mitkToFImageRecorderTest.cpp
@@ -1,151 +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 <mitkImage.h>
#include <mitkTestingMacros.h>
#include <mitkImageSliceSelector.h>
#include <mitkTestFixture.h>
#include <mitkToFImageRecorder.h>
#include <mitkToFCameraMITKPlayerDevice.h>
#include <mitkToFConfig.h>
#include <mitkIOUtil.h>
class mitkToFImageRecorderTestSuite : public mitk::TestFixture
{
CPPUNIT_TEST_SUITE(mitkToFImageRecorderTestSuite);
- //Removed due to random fails on linux continuous bug #12977
+ //See bug #12997
// MITK_TEST(StartRecording_ValidDepthImage_WritesImageToFile);
// MITK_TEST(StartRecording_ValidAmplitudeImage_WritesImageToFile);
// MITK_TEST(StartRecording_ValidIntensityImage_WritesImageToFile);
CPPUNIT_TEST_SUITE_END();
private:
/** Members used inside the different (sub-)tests. All members are initialized via setUp().
* Every recorder needs a device. Here we use a player device.
* The player device needs data to load. The ground truth is loaded via IOUtil.
*/
mitk::ToFImageRecorder::Pointer m_ToFImageRecorder;
mitk::ToFCameraMITKPlayerDevice::Pointer m_PlayerDevice;
std::string m_DistanceImageName;
std::string m_AmplitudeImageName;
std::string m_IntensityImageName;
mitk::Image::Pointer m_GroundTruthDepthImage;
mitk::Image::Pointer m_GroundTruthIntensityImage;
mitk::Image::Pointer m_GroundTruthAmplitudeImage;
public:
/**
* @brief Setup a recorder including a device. Here, we use a player, because in an automatic test
* hardware is not useful.
*/
void setUp()
{
m_ToFImageRecorder = mitk::ToFImageRecorder::New();
- m_DistanceImageName = "test_DistanceImage.nrrd";
- m_AmplitudeImageName = "test_AmplitudeImage.nrrd";
- m_IntensityImageName = "test_IntensityImage.nrrd";
+ m_DistanceImageName = mitk::IOUtil::CreateTemporaryFile();
+ m_AmplitudeImageName = mitk::IOUtil::CreateTemporaryFile();
+ m_IntensityImageName = mitk::IOUtil::CreateTemporaryFile();
+ //The recorder would automatically append the default extension ".nrrd"
+ //but we have to append it here, because the data is later loaded with
+ //IOUtil which does not know what kind of data to load/look for.
+ m_DistanceImageName.append("Distance.nrrd");
+ m_AmplitudeImageName.append("Amplitude.nrrd");
+ m_IntensityImageName.append("Intensity.nrrd");
m_PlayerDevice = mitk::ToFCameraMITKPlayerDevice::New();
m_ToFImageRecorder->SetCameraDevice(m_PlayerDevice);
//the test data set has 20 frames, so we record 20 per default
m_ToFImageRecorder->SetNumOfFrames(20);
m_ToFImageRecorder->SetRecordMode(mitk::ToFImageRecorder::PerFrames);
std::string dirName = MITK_TOF_DATA_DIR;
std::string distanceFileName = dirName + "/PMDCamCube2_MF0_IT0_20Images_DistanceImage.pic";
std::string amplitudeFileName = dirName + "/PMDCamCube2_MF0_IT0_20Images_AmplitudeImage.pic";
std::string intensityFileName = dirName + "/PMDCamCube2_MF0_IT0_20Images_IntensityImage.pic";
m_PlayerDevice->SetProperty("DistanceImageFileName",mitk::StringProperty::New(distanceFileName));
m_PlayerDevice->SetProperty("AmplitudeImageFileName",mitk::StringProperty::New(amplitudeFileName));
m_PlayerDevice->SetProperty("IntensityImageFileName",mitk::StringProperty::New(intensityFileName));
//comparing against IOUtil seems fair enough
m_GroundTruthDepthImage = mitk::IOUtil::LoadImage(distanceFileName);
m_GroundTruthAmplitudeImage = mitk::IOUtil::LoadImage(amplitudeFileName);
m_GroundTruthIntensityImage = mitk::IOUtil::LoadImage(intensityFileName);
m_PlayerDevice->ConnectCamera();
m_PlayerDevice->StartCamera();
-
}
void tearDown()
{
m_PlayerDevice->StopCamera();
m_PlayerDevice->DisconnectCamera();
}
void StartRecording_ValidDepthImage_WritesImageToFile()
{
m_ToFImageRecorder->SetDistanceImageFileName(m_DistanceImageName);
m_ToFImageRecorder->StartRecording();
- m_ToFImageRecorder->WaitForThreadBeingTerminated(); // wait to allow recording
+ m_ToFImageRecorder->WaitForThreadBeingTerminated();
m_ToFImageRecorder->StopRecording();
mitk::Image::Pointer recordedImage = mitk::IOUtil::LoadImage(m_DistanceImageName);
MITK_ASSERT_EQUAL( m_GroundTruthDepthImage, recordedImage, "Recorded image should be equal to the test data.");
+ //delete the tmp image
if( remove( m_DistanceImageName.c_str() ) != 0 )
{
- MITK_ERROR<<"File: test_distance.nrrd not successfully deleted!";
+ MITK_ERROR<<"File: "<< m_DistanceImageName << " not successfully deleted!";
}
}
void StartRecording_ValidAmplitudeImage_WritesImageToFile()
{
m_ToFImageRecorder->SetAmplitudeImageFileName(m_AmplitudeImageName);
m_ToFImageRecorder->SetAmplitudeImageSelected(true);
m_ToFImageRecorder->SetDistanceImageSelected(false);
m_ToFImageRecorder->StartRecording();
- m_ToFImageRecorder->WaitForThreadBeingTerminated(); // wait to allow recording
+ m_ToFImageRecorder->WaitForThreadBeingTerminated();
m_ToFImageRecorder->StopRecording();
mitk::Image::Pointer recordedImage = mitk::IOUtil::LoadImage(m_AmplitudeImageName);
MITK_ASSERT_EQUAL( m_GroundTruthAmplitudeImage, recordedImage, "Recorded image should be equal to the test data.");
+ //delete the tmp image
if( remove( m_AmplitudeImageName.c_str() ) != 0 )
{
- MITK_ERROR<<"File: test_amplitude.nrrd not successfully deleted!";
+ MITK_ERROR<<"File: "<< m_AmplitudeImageName << " not successfully deleted!";
}
}
void StartRecording_ValidIntensityImage_WritesImageToFile()
{
m_ToFImageRecorder->SetIntensityImageFileName(m_IntensityImageName);
m_ToFImageRecorder->SetIntensityImageSelected(true);
m_ToFImageRecorder->SetDistanceImageSelected(false);
m_ToFImageRecorder->StartRecording();
- m_ToFImageRecorder->WaitForThreadBeingTerminated(); // wait to allow recording
+ m_ToFImageRecorder->WaitForThreadBeingTerminated();
m_ToFImageRecorder->StopRecording();
mitk::Image::Pointer recordedImage = mitk::IOUtil::LoadImage(m_IntensityImageName);
MITK_ASSERT_EQUAL( m_GroundTruthIntensityImage, recordedImage, "Recorded image should be equal to the test data.");
+ //delete the tmp image
if( remove( m_IntensityImageName.c_str() ) != 0 )
{
- MITK_ERROR<<"File: test_intensity.nrrd not successfully deleted!";
+ MITK_ERROR<<"File: "<< m_IntensityImageName << " not successfully deleted!";
}
}
};
MITK_TEST_SUITE_REGISTRATION(mitkToFImageRecorder)
diff --git a/Modules/ToFHardware/mitkToFImageRecorder.cpp b/Modules/ToFHardware/mitkToFImageRecorder.cpp
index 7eb8605e30..a2db8c7f7d 100644
--- a/Modules/ToFHardware/mitkToFImageRecorder.cpp
+++ b/Modules/ToFHardware/mitkToFImageRecorder.cpp
@@ -1,268 +1,315 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkToFImageRecorder.h"
#include "mitkRealTimeClock.h"
#include "itkMultiThreader.h"
#include <itksys/SystemTools.hxx>
#pragma GCC visibility push(default)
#include <itkEventObject.h>
#pragma GCC visibility pop
namespace mitk
{
ToFImageRecorder::ToFImageRecorder()
{
this->m_ToFCameraDevice = NULL;
this->m_MultiThreader = itk::MultiThreader::New();
this->m_AbortMutex = itk::FastMutexLock::New();
this->m_ThreadID = 0;
this->m_NumOfFrames = 1; //lets record one frame per default
this->m_ToFImageWriter = NULL;
this->m_DistanceImageSelected = true; //lets assume a device only has depth data by default
this->m_AmplitudeImageSelected = false;
this->m_IntensityImageSelected = false;
this->m_RGBImageSelected = false;
this->m_Abort = false;
this->m_ToFCaptureWidth = 0;
this->m_ToFCaptureHeight = 0;
this->m_RGBCaptureWidth = 0;
this->m_RGBCaptureHeight = 0;
this->m_FileFormat = ".nrrd"; //lets make nrrd the default
this->m_ToFPixelNumber = 0;
this->m_RGBPixelNumber = 0;
this->m_SourceDataSize = 0;
this->m_ToFImageType = ToFImageWriter::ToFImageType3D;
this->m_RecordMode = ToFImageRecorder::PerFrames;
this->m_DistanceImageFileName = "";
this->m_AmplitudeImageFileName = "";
this->m_IntensityImageFileName = "";
this->m_RGBImageFileName = "";
this->m_ImageSequence = 0;
this->m_DistanceArray = NULL;
this->m_AmplitudeArray = NULL;
this->m_IntensityArray = NULL;
this->m_RGBArray = NULL;
this->m_SourceDataArray = NULL;
}
ToFImageRecorder::~ToFImageRecorder()
{
delete[] m_DistanceArray;
delete[] m_AmplitudeArray;
delete[] m_IntensityArray;
delete[] m_RGBArray;
delete[] m_SourceDataArray;
}
void ToFImageRecorder::StopRecording()
{
this->m_AbortMutex->Lock();
this->m_Abort = true;
this->m_AbortMutex->Unlock();
}
void ToFImageRecorder::StartRecording()
{
if (this->m_ToFCameraDevice.IsNull())
{
throw std::invalid_argument("ToFCameraDevice is NULL.");
return;
}
if (this->m_FileFormat.compare(".csv") == 0)
{
this->m_ToFImageWriter = ToFImageCsvWriter::New();
}
else if(this->m_FileFormat.compare(".nrrd") == 0)
{
this->m_ToFImageWriter = ToFNrrdImageWriter::New();
this->m_ToFImageWriter->SetExtension(m_FileFormat);
}
else
{
throw std::logic_error("No file format specified!");
}
this->m_RGBCaptureWidth = this->m_ToFCameraDevice->GetRGBCaptureWidth();
this->m_RGBCaptureHeight = this->m_ToFCameraDevice->GetRGBCaptureHeight();
this->m_RGBPixelNumber = this->m_RGBCaptureWidth * this->m_RGBCaptureHeight;
this->m_ToFCaptureWidth = this->m_ToFCameraDevice->GetCaptureWidth();
this->m_ToFCaptureHeight = this->m_ToFCameraDevice->GetCaptureHeight();
this->m_ToFPixelNumber = this->m_ToFCaptureWidth * this->m_ToFCaptureHeight;
this->m_SourceDataSize = this->m_ToFCameraDevice->GetSourceDataSize();
// allocate buffer
if(m_IntensityArray == NULL)
{
this->m_IntensityArray = new float[m_ToFPixelNumber];
}
if(this->m_DistanceArray == NULL)
{
this->m_DistanceArray = new float[m_ToFPixelNumber];
}
if(this->m_AmplitudeArray == NULL)
{
this->m_AmplitudeArray = new float[m_ToFPixelNumber];
}
if(this->m_RGBArray == NULL)
{
this->m_RGBArray = new unsigned char[m_RGBPixelNumber*3];
}
if(this->m_SourceDataArray == NULL)
{
this->m_SourceDataArray = new char[m_SourceDataSize];
}
this->m_ToFImageWriter->SetDistanceImageFileName(this->m_DistanceImageFileName);
this->m_ToFImageWriter->SetAmplitudeImageFileName(this->m_AmplitudeImageFileName);
this->m_ToFImageWriter->SetIntensityImageFileName(this->m_IntensityImageFileName);
this->m_ToFImageWriter->SetRGBImageFileName(this->m_RGBImageFileName);
this->m_ToFImageWriter->SetRGBCaptureWidth(this->m_RGBCaptureWidth);
this->m_ToFImageWriter->SetRGBCaptureHeight(this->m_RGBCaptureHeight);
//this->m_ToFImageWriter->SetToFCaptureHeight(this->m_ToFCaptureHeight);
this->m_ToFImageWriter->SetToFCaptureWidth(this->m_ToFCaptureWidth);
this->m_ToFImageWriter->SetToFCaptureHeight(this->m_ToFCaptureHeight);
this->m_ToFImageWriter->SetToFImageType(this->m_ToFImageType);
this->m_ToFImageWriter->SetDistanceImageSelected(this->m_DistanceImageSelected);
this->m_ToFImageWriter->SetAmplitudeImageSelected(this->m_AmplitudeImageSelected);
this->m_ToFImageWriter->SetIntensityImageSelected(this->m_IntensityImageSelected);
this->m_ToFImageWriter->SetRGBImageSelected(this->m_RGBImageSelected);
this->m_ToFImageWriter->Open();
this->m_AbortMutex->Lock();
this->m_Abort = false;
this->m_AbortMutex->Unlock();
- this->m_ThreadID = this->m_MultiThreader->SpawnThread(this->RecordData, this);
+// this->m_ThreadID = this->m_MultiThreader->SpawnThread(this->RecordData, this);
+
+ ToFCameraDevice::Pointer toFCameraDevice = this->GetCameraDevice();
+
+ mitk::RealTimeClock::Pointer realTimeClock;
+ realTimeClock = mitk::RealTimeClock::New();
+ double t1 = 0;
+ t1 = realTimeClock->GetCurrentStamp();
+ int requiredImageSequence = 0;
+ int numOfFramesRecorded = 0;
+
+ bool abort = false;
+ this->m_AbortMutex->Lock();
+ abort = this->m_Abort;
+ this->m_AbortMutex->Unlock();
+
+ while ( !abort )
+ {
+ if ( ((this->m_RecordMode == ToFImageRecorder::PerFrames) && (numOfFramesRecorded < this->m_NumOfFrames)) ||
+ (this->m_RecordMode == ToFImageRecorder::Infinite) )
+ {
+
+ toFCameraDevice->GetAllImages(this->m_DistanceArray, this->m_AmplitudeArray,
+ this->m_IntensityArray, this->m_SourceDataArray, requiredImageSequence, this->m_ImageSequence, this->m_RGBArray );
+
+ if (this->m_ImageSequence >= requiredImageSequence)
+ {
+ if (this->m_ImageSequence > requiredImageSequence)
+ {
+ MITK_INFO << "Problem! required: " << requiredImageSequence << " captured: " << this->m_ImageSequence;
+ }
+ requiredImageSequence = this->m_ImageSequence + 1;
+ this->m_ToFImageWriter->Add( this->m_DistanceArray,
+ this->m_AmplitudeArray, this->m_IntensityArray, this->m_RGBArray );
+ numOfFramesRecorded++;
+ }
+ this->m_AbortMutex->Lock();
+ abort = this->m_Abort;
+ this->m_AbortMutex->Unlock();
+ }
+ else
+ {
+ abort = true;
+ }
+ } // end of while loop
+
+ this->InvokeEvent(itk::AbortEvent());
+
+ this->m_ToFImageWriter->Close();
}
void ToFImageRecorder::WaitForThreadBeingTerminated()
{
this->m_MultiThreader->TerminateThread(this->m_ThreadID);
}
ITK_THREAD_RETURN_TYPE ToFImageRecorder::RecordData(void* pInfoStruct)
{
struct itk::MultiThreader::ThreadInfoStruct * pInfo = (struct itk::MultiThreader::ThreadInfoStruct*)pInfoStruct;
if (pInfo == NULL)
{
return ITK_THREAD_RETURN_VALUE;
}
if (pInfo->UserData == NULL)
{
return ITK_THREAD_RETURN_VALUE;
}
ToFImageRecorder* toFImageRecorder = (ToFImageRecorder*)pInfo->UserData;
if (toFImageRecorder!=NULL)
{
ToFCameraDevice::Pointer toFCameraDevice = toFImageRecorder->GetCameraDevice();
mitk::RealTimeClock::Pointer realTimeClock;
realTimeClock = mitk::RealTimeClock::New();
int n = 100;
double t1 = 0;
double t2 = 0;
t1 = realTimeClock->GetCurrentStamp();
- bool overflow = false;
bool printStatus = false;
int requiredImageSequence = 0;
int numOfFramesRecorded = 0;
bool abort = false;
toFImageRecorder->m_AbortMutex->Lock();
abort = toFImageRecorder->m_Abort;
toFImageRecorder->m_AbortMutex->Unlock();
while ( !abort )
{
if ( ((toFImageRecorder->m_RecordMode == ToFImageRecorder::PerFrames) && (numOfFramesRecorded < toFImageRecorder->m_NumOfFrames)) ||
(toFImageRecorder->m_RecordMode == ToFImageRecorder::Infinite) )
{
toFCameraDevice->GetAllImages(toFImageRecorder->m_DistanceArray, toFImageRecorder->m_AmplitudeArray,
toFImageRecorder->m_IntensityArray, toFImageRecorder->m_SourceDataArray, requiredImageSequence, toFImageRecorder->m_ImageSequence, toFImageRecorder->m_RGBArray );
if (toFImageRecorder->m_ImageSequence >= requiredImageSequence)
{
if (toFImageRecorder->m_ImageSequence > requiredImageSequence)
{
MITK_INFO << "Problem! required: " << requiredImageSequence << " captured: " << toFImageRecorder->m_ImageSequence;
}
requiredImageSequence = toFImageRecorder->m_ImageSequence + 1;
toFImageRecorder->m_ToFImageWriter->Add( toFImageRecorder->m_DistanceArray,
toFImageRecorder->m_AmplitudeArray, toFImageRecorder->m_IntensityArray, toFImageRecorder->m_RGBArray );
numOfFramesRecorded++;
if (numOfFramesRecorded % n == 0)
{
printStatus = true;
}
if (printStatus)
{
t2 = realTimeClock->GetCurrentStamp() - t1;
MITK_INFO << " Framerate (fps): " << n / (t2/1000) << " Sequence: " << toFImageRecorder->m_ImageSequence;
t1 = realTimeClock->GetCurrentStamp();
printStatus = false;
}
}
toFImageRecorder->m_AbortMutex->Lock();
abort = toFImageRecorder->m_Abort;
toFImageRecorder->m_AbortMutex->Unlock();
}
else
{
abort = true;
}
} // end of while loop
toFImageRecorder->InvokeEvent(itk::AbortEvent());
toFImageRecorder->m_ToFImageWriter->Close();
}
return ITK_THREAD_RETURN_VALUE;
}
void ToFImageRecorder::SetCameraDevice(ToFCameraDevice* aToFCameraDevice)
{
this->m_ToFCameraDevice = aToFCameraDevice;
}
ToFCameraDevice* ToFImageRecorder::GetCameraDevice()
{
return this->m_ToFCameraDevice;
}
ToFImageWriter::ToFImageType ToFImageRecorder::GetToFImageType()
{
return this->m_ToFImageType;
}
void ToFImageRecorder::SetToFImageType(ToFImageWriter::ToFImageType toFImageType)
{
this->m_ToFImageType = toFImageType;
}
ToFImageRecorder::RecordMode ToFImageRecorder::GetRecordMode()
{
return this->m_RecordMode;
}
void ToFImageRecorder::SetRecordMode(ToFImageRecorder::RecordMode recordMode)
{
this->m_RecordMode = recordMode;
}
}
diff --git a/Modules/ToFHardware/mitkToFImageWriter.cpp b/Modules/ToFHardware/mitkToFImageWriter.cpp
index e8cde63503..c52ff3d4d4 100644
--- a/Modules/ToFHardware/mitkToFImageWriter.cpp
+++ b/Modules/ToFHardware/mitkToFImageWriter.cpp
@@ -1,67 +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 <mitkToFImageWriter.h>
#include <mitkCommon.h>
// itk includes
#include "itksys/SystemTools.hxx"
namespace mitk
{
ToFImageWriter::ToFImageWriter():m_Extension(".nrrd"),
m_DistanceImageFileName(), m_AmplitudeImageFileName(), m_IntensityImageFileName(), m_RGBImageFileName(),
m_NumOfFrames(0), m_DistanceImageSelected(true), m_AmplitudeImageSelected(false),
m_IntensityImageSelected(false), m_RGBImageSelected(false), m_ToFCaptureWidth(200),m_ToFCaptureHeight(200),
m_RGBCaptureWidth(200),m_RGBCaptureHeight(200),
m_ToFPixelNumber(0), m_ToFImageSizeInBytes(0),
m_RGBPixelNumber(0), m_RGBImageSizeInBytes(0),
m_ToFImageType(ToFImageWriter::ToFImageType3D)
{
}
ToFImageWriter::~ToFImageWriter()
{
}
void ToFImageWriter::CheckForFileExtension(std::string& fileName)
{
std::string baseFilename = itksys::SystemTools::GetFilenameWithoutLastExtension( fileName );
std::string extension = itksys::SystemTools::GetFilenameLastExtension( fileName );
if( extension.length() != 0 && extension != this->m_Extension)
{
- MITK_ERROR << "Wrong file extension! The default extension is " << this->m_Extension.c_str() << ", currently the requested file extension is " << extension.c_str() <<"!";
+ MITK_ERROR << "Wrong file extension for " << baseFilename <<
+ " The default extension is " << this->m_Extension.c_str() <<
+ ", currently the requested file extension is " <<
+ extension.c_str() <<"!";
this->m_Extension = extension;
}
size_t found = fileName.find( this->m_Extension ); // !!! HAS to be at the very end of the filename (not somewhere in the middle)
if( found == std::string::npos)
{
fileName.append(this->m_Extension);
}
}
ToFImageWriter::ToFImageType ToFImageWriter::GetToFImageType()
{
return this->m_ToFImageType;
}
void ToFImageWriter::SetToFImageType(ToFImageWriter::ToFImageType toFImageType)
{
this->m_ToFImageType = toFImageType;
}
} // end namespace mitk
diff --git a/Modules/ToFUI/Qmitk/QmitkToFCompositeFilterWidget.cpp b/Modules/ToFUI/Qmitk/QmitkToFCompositeFilterWidget.cpp
index 5e5caf3514..8727b078df 100644
--- a/Modules/ToFUI/Qmitk/QmitkToFCompositeFilterWidget.cpp
+++ b/Modules/ToFUI/Qmitk/QmitkToFCompositeFilterWidget.cpp
@@ -1,290 +1,283 @@
/*===================================================================
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 <QmitkToFCompositeFilterWidget.h>
-//QT headers
-#include <QPlastiqueStyle>
-
#include <mitkProperties.h>
#include <mitkNodePredicateAnd.h>
#include <mitkNodePredicateDataType.h>
#include <mitkNodePredicateProperty.h>
const std::string QmitkToFCompositeFilterWidget::VIEW_ID = "org.mitk.views.qmitktofcompositefilterwidget";
QmitkToFCompositeFilterWidget::QmitkToFCompositeFilterWidget(QWidget* parent, Qt::WindowFlags f): QWidget(parent, f)
{
this->m_ToFCompositeFilter = NULL;
m_Controls = NULL;
CreateQtPartControl(this);
}
QmitkToFCompositeFilterWidget::~QmitkToFCompositeFilterWidget()
{
}
void QmitkToFCompositeFilterWidget::CreateQtPartControl(QWidget *parent)
{
if (!m_Controls)
{
// create GUI widgets
m_Controls = new Ui::QmitkToFCompositeFilterWidgetControls;
m_Controls->setupUi(parent);
- QPlastiqueStyle *sliderStyle = new QPlastiqueStyle();
-
int min = m_Controls->m_ThresholdFilterMinValueSpinBox->value();
int max = m_Controls->m_ThresholdFilterMaxValueSpinBox->value();
m_Controls->m_ThresholdFilterRangeSlider->setMinimum(min);
m_Controls->m_ThresholdFilterRangeSlider->setMaximum(max);
- m_Controls->m_ThresholdFilterRangeSlider->setLowerValue(min);
- m_Controls->m_ThresholdFilterRangeSlider->setUpperValue(max);
- m_Controls->m_ThresholdFilterRangeSlider->setHandleMovementMode(QxtSpanSlider::NoOverlapping);
- m_Controls->m_ThresholdFilterRangeSlider->setStyle(sliderStyle);
+ m_Controls->m_ThresholdFilterRangeSlider->setMinimumValue(min);
+ m_Controls->m_ThresholdFilterRangeSlider->setMaximumValue(max);
this->CreateConnections();
this->OnShowAdvancedOptionsCheckboxChecked(false);
}
}
void QmitkToFCompositeFilterWidget::CreateConnections()
{
if ( m_Controls )
{
connect(m_Controls->m_TemporalMedianFilterNumOfFramesSpinBox, SIGNAL(valueChanged(int)), this, SLOT(OnTemporalMedianFilterNumOfFramesSpinBoxValueChanged(int)));
connect(m_Controls->m_BilateralFilterDomainSigmaSpinBox, SIGNAL(valueChanged(double)), this, SLOT(OnBilateralFilterDomainSigmaSpinBoxValueChanged(double)));
connect(m_Controls->m_BilateralFilterRangeSigmaSpinBox, SIGNAL(valueChanged(double)), this, SLOT(OnBilateralFilterRangeSigmaSpinBoxValueChanged(double)));
connect(m_Controls->m_BilateralFilterKernelRadiusSpinBox, SIGNAL(valueChanged(int)), this, SLOT(OnBilateralFilterKernelRadiusSpinBoxValueChanged(int)));
connect(m_Controls->m_ThresholdFilterMinValueSpinBox, SIGNAL(valueChanged(int)), this, SLOT(OnThresholdFilterMinValueChanged(int)));
connect(m_Controls->m_ThresholdFilterMaxValueSpinBox, SIGNAL(valueChanged(int)), this, SLOT(OnThresholdFilterMaxValueChanged(int)));
connect( (QObject*)(m_Controls->m_TemporalMedianFilterCheckBox), SIGNAL(toggled(bool)), this, SLOT(OnTemporalMedianFilterCheckBoxChecked(bool)) );
connect( (QObject*)(m_Controls->m_AverageFilterCheckBox), SIGNAL(toggled(bool)), this, SLOT(OnAverageFilterCheckBoxChecked(bool)) );
connect( (QObject*)(m_Controls->m_ThresholdFilterCheckBox), SIGNAL(toggled(bool)), this, SLOT(OnThresholdFilterCheckBoxChecked(bool)) );
connect( (QObject*)(m_Controls->maskSegmentationCheckBox), SIGNAL(toggled(bool)), this, SLOT(OnMaskSegmentationCheckBoxChecked(bool)) );
connect( (QObject*)(m_Controls->m_BilateralFilterCheckBox), SIGNAL(toggled(bool)), this, SLOT(OnBilateralFilterCheckBoxChecked(bool)) );
connect( (QObject*)(m_Controls->m_MedianFilterCheckBox), SIGNAL(toggled(bool)), this, SLOT(OnMedianFilterCheckBoxChecked(bool)) );
connect( (QObject*)(m_Controls->m_ShowAdvancedOptionsCheckbox), SIGNAL(toggled(bool)), this, SLOT(OnShowAdvancedOptionsCheckboxChecked(bool)) );
connect(m_Controls->m_ThresholdFilterRangeSlider, SIGNAL(spanChanged(int, int) ),this, SLOT( OnSpanChanged(int , int ) ));
//reset button
connect(m_Controls->m_ThresholdFilterRangeSliderReset, SIGNAL(pressed()), this, SLOT(OnResetThresholdFilterRangeSlider()));
}
}
void QmitkToFCompositeFilterWidget::SetToFCompositeFilter(mitk::ToFCompositeFilter* toFCompositeFilter)
{
this->m_ToFCompositeFilter = toFCompositeFilter;
}
mitk::ToFCompositeFilter* QmitkToFCompositeFilterWidget::GetToFCompositeFilter()
{
if (this->m_ToFCompositeFilter.IsNull())
{
this->m_ToFCompositeFilter = mitk::ToFCompositeFilter::New();
}
return this->m_ToFCompositeFilter;
}
void QmitkToFCompositeFilterWidget::SetDataStorage(mitk::DataStorage::Pointer dataStorage)
{
m_DataStorage = dataStorage;
m_Controls->maskImageComboBox->SetDataStorage(dataStorage);
m_Controls->maskImageComboBox->SetPredicate(mitk::NodePredicateAnd::New(mitk::NodePredicateDataType::New("Image"),mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true))));
}
void QmitkToFCompositeFilterWidget::UpdateFilterParameter()
{
OnTemporalMedianFilterCheckBoxChecked(m_Controls->m_TemporalMedianFilterCheckBox->isChecked());
OnAverageFilterCheckBoxChecked(m_Controls->m_AverageFilterCheckBox->isChecked());
OnMedianFilterCheckBoxChecked(m_Controls->m_MedianFilterCheckBox->isChecked());
OnThresholdFilterCheckBoxChecked(m_Controls->m_ThresholdFilterCheckBox->isChecked());
OnBilateralFilterCheckBoxChecked(m_Controls->m_BilateralFilterCheckBox->isChecked());
}
void QmitkToFCompositeFilterWidget::SetWidgetConfiguration(bool threshold, bool mask, bool tempMedian, bool tempAverage, bool median, bool bilateral )
{
m_Controls->m_ThresholdFilterCheckBox->setChecked(threshold);
m_Controls->maskSegmentationCheckBox->setChecked(mask);
m_Controls->m_TemporalMedianFilterCheckBox->setChecked(tempMedian);
m_Controls->m_AverageFilterCheckBox->setChecked(tempAverage);
m_Controls->m_MedianFilterCheckBox->setChecked(median);
m_Controls->m_BilateralFilterCheckBox->setChecked(bilateral);
}
void QmitkToFCompositeFilterWidget::SetStandardParametersBilateralFilter(double domainSigma, double rangeSigma, int kernelRadius)
{
m_Controls->m_BilateralFilterDomainSigmaSpinBox->setValue(domainSigma);
m_Controls->m_BilateralFilterRangeSigmaSpinBox->setValue(rangeSigma);
m_Controls->m_BilateralFilterKernelRadiusSpinBox->setValue(kernelRadius);
}
void QmitkToFCompositeFilterWidget::SetStandardParametersThresholdFilter(int min, int max)
{
m_Controls->m_ThresholdFilterMinValueSpinBox->setValue(min);
m_Controls->m_ThresholdFilterMaxValueSpinBox->setValue(max);
}
void QmitkToFCompositeFilterWidget::SetStandardParameterTemporalAveraging(int nImages)
{
m_Controls->m_TemporalMedianFilterNumOfFramesSpinBox->setValue(nImages);
}
void QmitkToFCompositeFilterWidget::OnTemporalMedianFilterCheckBoxChecked(bool checked)
{
this->m_ToFCompositeFilter->SetApplyTemporalMedianFilter(checked);
// disable average filter if temporal median filter is enabled
if (checked)
{
m_Controls->m_AverageFilterCheckBox->setChecked(false);
this->m_ToFCompositeFilter->SetApplyAverageFilter(false);
}
}
void QmitkToFCompositeFilterWidget::OnAverageFilterCheckBoxChecked(bool checked)
{
this->m_ToFCompositeFilter->SetApplyAverageFilter(checked);
// disable temporal median filter if average filter is enabled
if (checked)
{
m_Controls->m_TemporalMedianFilterCheckBox->setChecked(false);
this->m_ToFCompositeFilter->SetApplyTemporalMedianFilter(false);
}
}
void QmitkToFCompositeFilterWidget::OnShowAdvancedOptionsCheckboxChecked(bool checked)
{
- this->m_Controls->m_AverageFilterCheckBox->setShown(checked);
- this->m_Controls->m_BilateralFilterCheckBox->setShown(checked);
- this->m_Controls->m_BilateralFilterDomainSigmaSpinBox->setShown(checked);
- this->m_Controls->m_BilateralFilterKernelRadiusSpinBox->setShown(checked);
- this->m_Controls->m_BilateralFilterRangeSigmaSpinBox->setShown(checked);
- this->m_Controls->m_MedianFilterCheckBox->setShown(checked);
- this->m_Controls->m_TemporalMedianFilterCheckBox->setShown(checked);
- this->m_Controls->m_TemporalMedianFilterNumOfFramesSpinBox->setShown(checked);
- this->m_Controls->m_ThresholdFilterCheckBox->setShown(checked);
- this->m_Controls->m_ThresholdFilterMaxValueSpinBox->setShown(checked);
- this->m_Controls->m_ThresholdFilterMinValueSpinBox->setShown(checked);
- this->m_Controls->m_ThresholdFilterRangeSlider->setShown(checked);
- this->m_Controls->m_ThresholdFilterRangeSliderReset->setShown(checked);
- this->m_Controls->label_3->setShown(checked);
- this->m_Controls->label_4->setShown(checked);
- this->m_Controls->label_12->setShown(checked);
- this->m_Controls->maskImageComboBox->setShown(checked);
- this->m_Controls->maskSegmentationCheckBox->setShown(checked);
+ this->m_Controls->m_AverageFilterCheckBox->setVisible(checked);
+ this->m_Controls->m_BilateralFilterCheckBox->setVisible(checked);
+ this->m_Controls->m_BilateralFilterDomainSigmaSpinBox->setVisible(checked);
+ this->m_Controls->m_BilateralFilterKernelRadiusSpinBox->setVisible(checked);
+ this->m_Controls->m_BilateralFilterRangeSigmaSpinBox->setVisible(checked);
+ this->m_Controls->m_MedianFilterCheckBox->setVisible(checked);
+ this->m_Controls->m_TemporalMedianFilterCheckBox->setVisible(checked);
+ this->m_Controls->m_TemporalMedianFilterNumOfFramesSpinBox->setVisible(checked);
+ this->m_Controls->m_ThresholdFilterCheckBox->setVisible(checked);
+ this->m_Controls->m_ThresholdFilterMaxValueSpinBox->setVisible(checked);
+ this->m_Controls->m_ThresholdFilterMinValueSpinBox->setVisible(checked);
+ this->m_Controls->m_ThresholdFilterRangeSlider->setVisible(checked);
+ this->m_Controls->m_ThresholdFilterRangeSliderReset->setVisible(checked);
+ this->m_Controls->label_3->setVisible(checked);
+ this->m_Controls->label_4->setVisible(checked);
+ this->m_Controls->label_12->setVisible(checked);
+ this->m_Controls->maskImageComboBox->setVisible(checked);
+ this->m_Controls->maskSegmentationCheckBox->setVisible(checked);
}
void QmitkToFCompositeFilterWidget::OnThresholdFilterCheckBoxChecked(bool checked)
{
this->m_ToFCompositeFilter->SetApplyThresholdFilter(checked);
}
void QmitkToFCompositeFilterWidget::OnMaskSegmentationCheckBoxChecked(bool checked)
{
this->m_ToFCompositeFilter->SetApplyMaskSegmentation(checked);
if (checked)
{
mitk::DataNode::Pointer maskImageNode = m_Controls->maskImageComboBox->GetSelectedNode();
if (maskImageNode.IsNotNull())
{
mitk::Image::Pointer maskImage = dynamic_cast<mitk::Image*>(maskImageNode->GetData());
this->m_ToFCompositeFilter->SetSegmentationMask(maskImage);
}
}
}
void QmitkToFCompositeFilterWidget::OnMedianFilterCheckBoxChecked(bool checked)
{
this->m_ToFCompositeFilter->SetApplyMedianFilter(checked);
}
void QmitkToFCompositeFilterWidget::OnBilateralFilterCheckBoxChecked(bool checked)
{
this->m_ToFCompositeFilter->SetApplyBilateralFilter(checked);
}
void QmitkToFCompositeFilterWidget::OnTemporalMedianFilterNumOfFramesSpinBoxValueChanged(int value)
{
this->m_ToFCompositeFilter->SetTemporalMedianFilterParameter(value);
}
void QmitkToFCompositeFilterWidget::OnBilateralFilterDomainSigmaSpinBoxValueChanged(double value)
{
SetBilateralFilterParameter();
}
void QmitkToFCompositeFilterWidget::OnBilateralFilterRangeSigmaSpinBoxValueChanged(double value)
{
SetBilateralFilterParameter();
}
void QmitkToFCompositeFilterWidget::OnBilateralFilterKernelRadiusSpinBoxValueChanged(int value)
{
SetBilateralFilterParameter();
}
void QmitkToFCompositeFilterWidget::OnThresholdFilterMinValueChanged(int value)
{
- m_Controls->m_ThresholdFilterRangeSlider->setLowerValue(value);
+ m_Controls->m_ThresholdFilterRangeSlider->setMinimumValue(value);
SetThresholdFilterParameter();
}
void QmitkToFCompositeFilterWidget::OnThresholdFilterMaxValueChanged(int value)
{
- m_Controls->m_ThresholdFilterRangeSlider->setUpperValue(value);
+ m_Controls->m_ThresholdFilterRangeSlider->setMaximumValue(value);
SetThresholdFilterParameter();
}
void QmitkToFCompositeFilterWidget::SetThresholdFilterParameter()
{
int min = m_Controls->m_ThresholdFilterMinValueSpinBox->value();
int max = m_Controls->m_ThresholdFilterMaxValueSpinBox->value();
this->m_ToFCompositeFilter->SetThresholdFilterParameter(min, max);
}
void QmitkToFCompositeFilterWidget::SetBilateralFilterParameter()
{
double domainSigma = m_Controls->m_BilateralFilterDomainSigmaSpinBox->value();
double rangeSigma = m_Controls->m_BilateralFilterRangeSigmaSpinBox->value();
int kernelRadius = m_Controls->m_BilateralFilterKernelRadiusSpinBox->value();
this->m_ToFCompositeFilter->SetBilateralFilterParameter(domainSigma, rangeSigma, kernelRadius);
}
void QmitkToFCompositeFilterWidget::OnSpanChanged(int lower, int upper)
{
- int lowerVal = m_Controls->m_ThresholdFilterRangeSlider->lowerValue();
- int upperVal = m_Controls->m_ThresholdFilterRangeSlider->upperValue();
+ int lowerVal = m_Controls->m_ThresholdFilterRangeSlider->minimumValue();
+ int upperVal = m_Controls->m_ThresholdFilterRangeSlider->maximumValue();
m_Controls->m_ThresholdFilterMinValueSpinBox->setValue(lowerVal);
m_Controls->m_ThresholdFilterMaxValueSpinBox->setValue(upperVal);
}
void QmitkToFCompositeFilterWidget::OnResetThresholdFilterRangeSlider()
{
int lower = 1;
int upper = 7000;
- m_Controls->m_ThresholdFilterRangeSlider->setLowerValue(lower);
- m_Controls->m_ThresholdFilterRangeSlider->setUpperValue(upper);
+ m_Controls->m_ThresholdFilterRangeSlider->setMinimumValue(lower);
+ m_Controls->m_ThresholdFilterRangeSlider->setMaximumValue(upper);
m_Controls->m_ThresholdFilterMinValueSpinBox->setValue(lower);
m_Controls->m_ThresholdFilterMaxValueSpinBox->setValue(upper);
}
diff --git a/Modules/ToFUI/Qmitk/QmitkToFCompositeFilterWidgetControls.ui b/Modules/ToFUI/Qmitk/QmitkToFCompositeFilterWidgetControls.ui
index 672e5a8e6e..81ff4de855 100644
--- a/Modules/ToFUI/Qmitk/QmitkToFCompositeFilterWidgetControls.ui
+++ b/Modules/ToFUI/Qmitk/QmitkToFCompositeFilterWidgetControls.ui
@@ -1,244 +1,244 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QmitkToFCompositeFilterWidgetControls</class>
<widget class="QWidget" name="QmitkToFCompositeFilterWidgetControls">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>467</width>
<height>210</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="windowTitle">
<string>QmitkToFCompositeFilter</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="text">
<string>ToF Preprocessing</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="m_ShowAdvancedOptionsCheckbox">
<property name="text">
<string>Show Advanced Options</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QCheckBox" name="m_ThresholdFilterCheckBox">
<property name="text">
<string>Threshold Filter</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="m_ThresholdFilterMinValueSpinBox">
<property name="maximum">
<number>7000</number>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
- <widget class="QxtSpanSlider" name="m_ThresholdFilterRangeSlider">
+ <widget class="ctkRangeSlider" name="m_ThresholdFilterRangeSlider">
<property name="toolTip">
<string>modify actual seen window by dragging left and right slider. </string>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_ThresholdFilterRangeSliderReset">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>48</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Resets range to histogram minimum and maximum.</string>
</property>
<property name="text">
<string>Reset</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QSpinBox" name="m_ThresholdFilterMaxValueSpinBox">
<property name="maximum">
<number>7000</number>
</property>
<property name="value">
<number>7000</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QCheckBox" name="maskSegmentationCheckBox">
<property name="text">
<string>Mask segmentation</string>
</property>
</widget>
</item>
<item>
<widget class="QmitkDataStorageComboBox" name="maskImageComboBox"/>
</item>
</layout>
</item>
<item row="3" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QCheckBox" name="m_TemporalMedianFilterCheckBox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Median Filter (t)</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="m_AverageFilterCheckBox">
<property name="text">
<string>Average Filter </string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="m_TemporalMedianFilterNumOfFramesSpinBox">
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>10</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="m_MedianFilterCheckBox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Median Filter</string>
</property>
</widget>
</item>
<item row="5" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QCheckBox" name="m_BilateralFilterCheckBox">
<property name="text">
<string>Bilateral Filter</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>σ_d: </string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="m_BilateralFilterDomainSigmaSpinBox">
<property name="value">
<double>2.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>σ_r:</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="m_BilateralFilterRangeSigmaSpinBox">
<property name="value">
<double>60.000000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_12">
<property name="text">
<string>radius:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="m_BilateralFilterKernelRadiusSpinBox"/>
</item>
</layout>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
- <class>QxtSpanSlider</class>
- <extends>QSlider</extends>
- <header location="global">qxtspanslider.h</header>
+ <class>ctkRangeSlider</class>
+ <extends>QWidget</extends>
+ <header location="global">ctkRangeSlider.h</header>
</customwidget>
<customwidget>
<class>QmitkDataStorageComboBox</class>
<extends>QComboBox</extends>
<header>QmitkDataStorageComboBox.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
diff --git a/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.cpp b/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.cpp
index 7124eaa534..9cc3aa692d 100644
--- a/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.cpp
+++ b/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.cpp
@@ -1,426 +1,427 @@
/*===================================================================
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.
===================================================================*/
#define _USE_MATH_DEFINES
#include "QmitkToFRecorderWidget.h"
//QT headers
-#include <qmessagebox.h>
+#include <QMessageBox>
#include <QComboBox>
#include <QLabel>
#include <QLayout>
#include <QGridLayout>
#include <QCheckBox>
+#include <QFileDialog>
//mitk headers
#include <mitkToFImageWriter.h>
//itk headers
#pragma GCC visibility push(default)
#include <itkEventObject.h>
#pragma GCC visibility pop
#include <itksys/SystemTools.hxx>
struct QFileDialogArgs;
class QFileDialogPrivate;
const std::string QmitkToFRecorderWidget::VIEW_ID = "org.mitk.views.qmitktofrecorderwidget";
QmitkToFRecorderWidget::QmitkToFRecorderWidget(QWidget* parent, Qt::WindowFlags f): QWidget(parent, f)
{
this->m_ToFImageRecorder = NULL;
this->m_ToFImageGrabber = NULL;
this->m_RecordMode = mitk::ToFImageRecorder::PerFrames;
this-> m_Controls = NULL;
CreateQtPartControl(this);
}
QmitkToFRecorderWidget::~QmitkToFRecorderWidget()
{
}
void QmitkToFRecorderWidget::CreateQtPartControl(QWidget *parent)
{
if (!m_Controls)
{
// create GUI widgets
this->m_Controls = new Ui::QmitkToFRecorderWidgetControls;
this->m_Controls->setupUi(parent);
this->CreateConnections();
}
}
void QmitkToFRecorderWidget::CreateConnections()
{
if ( m_Controls )
{
connect( (QObject*)(m_Controls->m_PlayButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnPlay()) );
connect( (QObject*)(m_Controls->m_StopButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnStop()) );
connect( (QObject*)(m_Controls->m_StartRecordingButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnStartRecorder()) );
connect( (QObject*)(m_Controls->m_RecordModeComboBox), SIGNAL(currentIndexChanged(int)),(QObject*) this, SLOT(OnChangeRecordModeComboBox(int)) );
connect(this, SIGNAL(RecordingStopped()), this, SLOT(OnRecordingStopped()), Qt::BlockingQueuedConnection);
}
}
void QmitkToFRecorderWidget::SetParameter(mitk::ToFImageGrabber* toFImageGrabber, mitk::ToFImageRecorder* toFImageRecorder)
{
this->m_ToFImageGrabber = toFImageGrabber;
this->m_ToFImageRecorder = toFImageRecorder;
this->m_StopRecordingCommand = CommandType::New();
this->m_StopRecordingCommand->SetCallbackFunction(this, &QmitkToFRecorderWidget::StopRecordingCallback);
this->m_ToFImageRecorder->RemoveAllObservers();
this->m_ToFImageRecorder->AddObserver(itk::AbortEvent(), this->m_StopRecordingCommand);
m_Controls->m_PlayButton->setChecked(false);
m_Controls->m_PlayButton->setEnabled(true);
m_Controls->m_StartRecordingButton->setChecked(false);
m_Controls->m_RecorderGroupBox->setEnabled(true);
}
void QmitkToFRecorderWidget::StopRecordingCallback()
{
emit RecordingStopped();
}
void QmitkToFRecorderWidget::ResetGUIToInitial()
{
m_Controls->m_PlayButton->setChecked(false);
m_Controls->m_PlayButton->setEnabled(true);
m_Controls->m_RecorderGroupBox->setEnabled(false);
}
void QmitkToFRecorderWidget::OnRecordingStopped()
{
m_Controls->m_StartRecordingButton->setChecked(false);
m_Controls->m_RecorderGroupBox->setEnabled(true);
}
void QmitkToFRecorderWidget::OnStop()
{
StopCamera();
StopRecorder();
ResetGUIToInitial();
emit ToFCameraStopped();
}
void QmitkToFRecorderWidget::OnPlay()
{
m_Controls->m_PlayButton->setChecked(true);
m_Controls->m_PlayButton->setEnabled(false);
m_Controls->m_RecorderGroupBox->setEnabled(true);
this->repaint();
StartCamera();
emit ToFCameraStarted();
}
void QmitkToFRecorderWidget::StartCamera()
{
if (!m_ToFImageGrabber->IsCameraActive())
{
m_ToFImageGrabber->StartCamera();
}
}
void QmitkToFRecorderWidget::StopCamera()
{
if( m_ToFImageGrabber.IsNotNull() )
m_ToFImageGrabber->StopCamera();
}
void QmitkToFRecorderWidget::StopRecorder()
{
if( m_ToFImageRecorder.IsNotNull() )
{
this->m_ToFImageRecorder->StopRecording();
}
}
void QmitkToFRecorderWidget::OnStartRecorder()
{
m_Controls->m_StartRecordingButton->setChecked(true);
m_Controls->m_RecorderGroupBox->setEnabled(false);
this->repaint();
int numOfFrames = m_Controls->m_NumOfFramesSpinBox->value();
try
{
bool fileOK = true;
bool distanceImageSelected = true;
bool amplitudeImageSelected = false;
bool intensityImageSelected = false;
bool rgbImageSelected = false;
bool rawDataSelected = false;
//Set check boxes in dialog according to device properties
m_ToFImageGrabber->GetCameraDevice()->GetBoolProperty("HasAmplitudeImage",amplitudeImageSelected);
m_ToFImageGrabber->GetCameraDevice()->GetBoolProperty("HasIntensityImage",intensityImageSelected);
m_ToFImageGrabber->GetCameraDevice()->GetBoolProperty("HasRGBImage",rgbImageSelected);
QString tmpFileName("");
QString selectedFilter("");
QString imageFileName("");
mitk::ToFImageWriter::ToFImageType tofImageType;
tmpFileName = QmitkToFRecorderWidget::getSaveFileName(tofImageType,
distanceImageSelected, amplitudeImageSelected, intensityImageSelected, rgbImageSelected, rawDataSelected,
NULL, "Save Image To...", imageFileName, "NRRD Images (*.nrrd);;PIC Images - deprecated (*.pic);;Text (*.csv)", &selectedFilter);
if (tmpFileName.isEmpty())
{
fileOK = false;
}
else
{
imageFileName = tmpFileName;
}
if (fileOK)
{
std::string dir = itksys::SystemTools::GetFilenamePath( imageFileName.toStdString() );
std::string baseFilename = itksys::SystemTools::GetFilenameWithoutLastExtension( imageFileName.toStdString() );
std::string extension = itksys::SystemTools::GetFilenameLastExtension( imageFileName.toStdString() );
int integrationTime = this->m_ToFImageGrabber->GetIntegrationTime();
int modulationFreq = this->m_ToFImageGrabber->GetModulationFrequency();
QString integrationTimeStr;
integrationTimeStr.setNum(integrationTime);
QString modulationFreqStr;
modulationFreqStr.setNum(modulationFreq);
QString numOfFramesStr("");
if (this->m_RecordMode == mitk::ToFImageRecorder::PerFrames)
{
numOfFramesStr.setNum(numOfFrames);
}
std::string distImageFileName = prepareFilename(dir, baseFilename, modulationFreqStr.toStdString(),
integrationTimeStr.toStdString(), numOfFramesStr.toStdString(), extension, "_DistanceImage");
MITK_INFO << "Save distance data to: " << distImageFileName;
std::string amplImageFileName = prepareFilename(dir, baseFilename, modulationFreqStr.toStdString(),
integrationTimeStr.toStdString(), numOfFramesStr.toStdString(), extension, "_AmplitudeImage");
MITK_INFO << "Save amplitude data to: " << amplImageFileName;
std::string intenImageFileName = prepareFilename(dir, baseFilename, modulationFreqStr.toStdString(),
integrationTimeStr.toStdString(), numOfFramesStr.toStdString(), extension, "_IntensityImage");
MITK_INFO << "Save intensity data to: " << intenImageFileName;
std::string rgbImageFileName = prepareFilename(dir, baseFilename, modulationFreqStr.toStdString(),
integrationTimeStr.toStdString(), numOfFramesStr.toStdString(), extension, "_RGBImage");
MITK_INFO << "Save intensity data to: " << rgbImageFileName;
if (selectedFilter.compare("Text (*.csv)") == 0)
{
this->m_ToFImageRecorder->SetFileFormat(".csv");
}
else if (selectedFilter.compare("PIC Images - deprecated (*.pic)") == 0)
{
//default
this->m_ToFImageRecorder->SetFileFormat(".pic");
QMessageBox::warning(NULL, "Deprecated File Format!",
"Please note that *.pic file format is deprecated and not longer supported! The suggested file format for images is *.nrrd!");
}
else if (selectedFilter.compare("NRRD Images (*.nrrd)") == 0)
{
this->m_ToFImageRecorder->SetFileFormat(".nrrd");
}
else
{
QMessageBox::warning(NULL, "Unsupported file format!", "Please specify one of the supported file formats *.nrrd, *.csv!");
return;
}
numOfFrames = m_Controls->m_NumOfFramesSpinBox->value();
this->m_ToFImageRecorder->SetDistanceImageFileName(distImageFileName);
this->m_ToFImageRecorder->SetAmplitudeImageFileName(amplImageFileName);
this->m_ToFImageRecorder->SetIntensityImageFileName(intenImageFileName);
this->m_ToFImageRecorder->SetRGBImageFileName(rgbImageFileName);
this->m_ToFImageRecorder->SetToFImageType(tofImageType);
this->m_ToFImageRecorder->SetDistanceImageSelected(distanceImageSelected);
this->m_ToFImageRecorder->SetAmplitudeImageSelected(amplitudeImageSelected);
this->m_ToFImageRecorder->SetIntensityImageSelected(intensityImageSelected);
this->m_ToFImageRecorder->SetRGBImageSelected(rgbImageSelected);
this->m_ToFImageRecorder->SetRecordMode(this->m_RecordMode);
this->m_ToFImageRecorder->SetNumOfFrames(numOfFrames);
emit RecordingStarted();
this->m_ToFImageRecorder->StartRecording();
}
else
{
this->OnRecordingStopped();
}
}
catch(std::exception& e)
{
QMessageBox::critical(NULL, "Error", QString(e.what()));
this->OnRecordingStopped();
}
}
QString QmitkToFRecorderWidget::getSaveFileName(mitk::ToFImageWriter::ToFImageType& tofImageType,
bool& distanceImageSelected,
bool& amplitudeImageSelected,
bool& intensityImageSelected,
bool& rgbImageSelected,
bool& rawDataSelected,
QWidget *parent,
const QString &caption,
const QString &dir,
const QString &filter,
QString *selectedFilter,
QFileDialog::Options options
)
{
QString selectedFileName = "";
QComboBox* combo = new QComboBox;
combo->addItem("3D");
combo->addItem("2D + t");
QHBoxLayout* checkBoxGroup = new QHBoxLayout();
QCheckBox* distanceImageCheckBox = new QCheckBox;
distanceImageCheckBox->setText("Distance image");
distanceImageCheckBox->setChecked(distanceImageSelected);
QCheckBox* amplitudeImageCheckBox = new QCheckBox;
amplitudeImageCheckBox->setText("Amplitude image");
amplitudeImageCheckBox->setChecked(amplitudeImageSelected);
amplitudeImageCheckBox->setEnabled(amplitudeImageSelected);
if(!amplitudeImageSelected)
amplitudeImageCheckBox->setToolTip(QString("This device does not provide amplitude data."));
QCheckBox* intensityImageCheckBox = new QCheckBox;
intensityImageCheckBox->setText("Intensity image");
intensityImageCheckBox->setChecked(intensityImageSelected);
intensityImageCheckBox->setEnabled(intensityImageSelected);
if(!intensityImageSelected)
intensityImageCheckBox->setToolTip(QString("This device does not provide intensity data."));
QCheckBox* rgbImageCheckBox = new QCheckBox;
rgbImageCheckBox->setText("RGB image");
rgbImageCheckBox->setChecked(rgbImageSelected);
rgbImageCheckBox->setEnabled(rgbImageSelected);
if(!rgbImageSelected)
rgbImageCheckBox->setToolTip(QString("This device does not provide RGB data."));
QCheckBox* rawDataCheckBox = new QCheckBox;
rawDataCheckBox->setText("Raw data");
rawDataCheckBox->setChecked(false);
rawDataCheckBox->setEnabled(false);
checkBoxGroup->addWidget(distanceImageCheckBox);
checkBoxGroup->addWidget(amplitudeImageCheckBox);
checkBoxGroup->addWidget(intensityImageCheckBox);
checkBoxGroup->addWidget(rgbImageCheckBox);
checkBoxGroup->addWidget(rawDataCheckBox);
QFileDialog* fileDialog = new QFileDialog(parent, caption, dir, filter);
QLayout* layout = fileDialog->layout();
QGridLayout* gridbox = qobject_cast<QGridLayout*>(layout);
if (gridbox)
{
gridbox->addWidget(new QLabel("ToF-Image type:"));
gridbox->addWidget(combo);
int lastRow = gridbox->rowCount();
gridbox->addLayout(checkBoxGroup, lastRow, 0, 1, -1);
}
fileDialog->setLayout(gridbox);
fileDialog->setAcceptMode(QFileDialog::AcceptSave);
if (selectedFilter)
{
fileDialog->selectNameFilter(*selectedFilter);
}
if (fileDialog->exec() == QDialog::Accepted)
{
if (selectedFilter)
{
- *selectedFilter = fileDialog->selectedFilter();
+ *selectedFilter = fileDialog->selectedNameFilter();
}
if (combo->currentIndex() == 0)
{
tofImageType = mitk::ToFImageWriter::ToFImageType3D;
}
else
{
tofImageType = mitk::ToFImageWriter::ToFImageType2DPlusT;
}
distanceImageSelected = distanceImageCheckBox->isChecked();
amplitudeImageSelected = amplitudeImageCheckBox->isChecked();
intensityImageSelected = intensityImageCheckBox->isChecked();
rgbImageSelected = rgbImageCheckBox->isChecked();
rawDataSelected = rawDataCheckBox->isChecked();
selectedFileName = fileDialog->selectedFiles().value(0);
}
delete fileDialog;
return selectedFileName;
}
std::string QmitkToFRecorderWidget::prepareFilename(std::string dir,
std::string baseFilename,
std::string modulationFreq,
std::string integrationTime,
std::string numOfFrames,
std::string extension,
std::string imageType)
{
std::string filenName("");
filenName.append(dir);
filenName.append("/");
filenName.append(baseFilename);
filenName.append("_MF");
filenName.append(modulationFreq);
filenName.append("_IT");
filenName.append(integrationTime);
filenName.append("_");
filenName.append(numOfFrames);
filenName.append("Images");
filenName.append(imageType);
filenName.append(extension);
return filenName;
}
void QmitkToFRecorderWidget::OnChangeRecordModeComboBox(int index)
{
if (index == 0)
{
this->m_RecordMode = mitk::ToFImageRecorder::PerFrames;
m_Controls->m_NumOfFramesSpinBox->setEnabled(true);
}
else
{
this->m_RecordMode = mitk::ToFImageRecorder::Infinite;
m_Controls->m_NumOfFramesSpinBox->setEnabled(false);
}
}
diff --git a/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.h b/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.h
index a1372a1378..0972499787 100644
--- a/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.h
+++ b/Modules/ToFUI/Qmitk/QmitkToFRecorderWidget.h
@@ -1,189 +1,189 @@
/*===================================================================
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 _QMITKTOFRECORDERWIDGET_H_INCLUDED
#define _QMITKTOFRECORDERWIDGET_H_INCLUDED
#include <MitkToFUIExports.h>
#include <ui_QmitkToFRecorderWidgetControls.h>
//QT headers
#include <QWidget>
#include <QString>
-#include <QtGui/qdialog.h>
-#include <qfiledialog.h>
+#include <QDialog>
+#include <QFileDialog>
//itk headers
#include "itkCommand.h"
//mitk headers
#include <mitkToFImageGrabber.h>
#include <mitkToFImageRecorder.h>
class QmitkStdMultiWidget;
struct QFileDialogArgs;
class QFileIconProvider;
class QFileDialogPrivate;
/**
* @brief Widget allowing to play / record ToF data
*
* @ingroup ToFUI
*/
class MitkToFUI_EXPORT QmitkToFRecorderWidget :public QWidget
{
//this is needed for all Qt objects that should have a MOC object (everything that derives from QObject)
Q_OBJECT
public:
static const std::string VIEW_ID;
QmitkToFRecorderWidget(QWidget* p = 0, Qt::WindowFlags f1 = 0);
virtual ~QmitkToFRecorderWidget();
/* @brief This method is part of the widget an needs not to be called seperately. */
virtual void CreateQtPartControl(QWidget *parent);
/* @brief This method is part of the widget an needs not to be called seperately. (Creation of the connections of main and control widget.)*/
virtual void CreateConnections();
/*!
\brief Set the parameters used for this widget
\param ToFImageGrabber image grabber providing images from a ToF device
\param tofImageRecorder image recorder allowing to record ToF images
*/
void SetParameter(mitk::ToFImageGrabber* ToFImageGrabber, mitk::ToFImageRecorder* toFImageRecorder);
/*!
\brief resets the GUI elements to the initial state. Play button: enabled, Stop button: disabled, Recording box: disabled
*/
void ResetGUIToInitial();
signals:
/*!
\brief signal emitted when "Play" button is pressed
*/
void ToFCameraStarted();
/*!
\brief signal emitted when "Stop" button is pressed
*/
void ToFCameraStopped();
/*!
\brief signal emitted when recording is started
*/
void RecordingStarted();
/*!
\brief signal emitted AbortEvent() in ToFImageRecorder is observed
*/
void RecordingStopped();
public slots:
/*!
\brief slot invoking to start the camera.
Calls StartCamera() and emits ToFCameraStarted signal
*/
void OnPlay();
/*!
\brief slot invoking to stop the camera and the recorder.
Calls StopCamera() and StopRecorder and emits ToFCameraStarted signal. Resets GUI to initial state.
*/
void OnStop();
/*!
\brief slot invoking to start the recording
After letting the user chose a file location for the record, m_ImageRecorder->StartRecording() is inoved.
*/
void OnStartRecorder();
/*!
\brief slot resetting the GUI elements of the recording box
*/
void OnRecordingStopped();
/*!
\brief slot activating/deactivating "number of frames" spin box dependent on recording mode (PerFrame / Infinite)
*/
void OnChangeRecordModeComboBox(int index);
protected:
/*!
\brief starts the camera by calling ToFImageGrabber::StartCamera()
*/
void StartCamera();
/*!
\brief stops the camera by calling ToFImageGrabber::StopCamera()
*/
void StopCamera();
/*!
\brief stops the recording by calling ToFImageRecorder::StopRecording()
*/
void StopRecorder();
/*!
\brief emits RecordingStopped signal.
*/
void StopRecordingCallback();
/*!
\brief adapted version of QFileDialog::getSaveFileName()
The user is now asked to choose which images he wants to save
(Distance and/or Intensity and/or Amplitude image) and which type the saved
image should have (3D, 2D+t).
*/
static QString getSaveFileName(mitk::ToFImageWriter::ToFImageType& tofImageType,
bool& distanceImageSelected,
bool& amplitudeImageSelected,
bool& intensityImageSelected,
bool& rgbImageSelected,
bool& rawDataSelected,
QWidget *parent = 0,
const QString &caption = QString(),
const QString &dir = QString(),
const QString &filter = QString(),
QString *selectedFilter = 0,
QFileDialog::Options options = 0
);
/*!
\brief method creating a filename from the given information
\param dir directory to save the file
\param baseFilename base file name entered by the user
\param modulationFreq modulation frequency of the camera
\param integrationTime integration time of the camera
\param numOfFrames number of frames recorded
\param extension file extension
\param imageType type of image (DistanceImage, IntensityImage, AmplitudeImage)
\return dir+"/"+baseFilename+"_MF"+modulationFreq+"_IT"+integrationTime+"_"+numOfFrames+"Images"+imageType+extension
*/
std::string prepareFilename(std::string dir,
std::string baseFilename,
std::string modulationFreq,
std::string integrationTime,
std::string numOfFrames,
std::string extension,
std::string imageType);
Ui::QmitkToFRecorderWidgetControls* m_Controls; ///< member holding the UI elements of this widget
mitk::ToFImageGrabber::Pointer m_ToFImageGrabber; ///< member holding the ToFImageGrabber for acquiring ToF images
mitk::ToFImageRecorder::Pointer m_ToFImageRecorder; ///< member holding the recorder for ToF images
mitk::ToFImageRecorder::RecordMode m_RecordMode; ///< member holding the RecordMode of the recorder (PerFrame / Infinite)
typedef itk::SimpleMemberCommand<QmitkToFRecorderWidget> CommandType;
CommandType::Pointer m_StopRecordingCommand; ///< itkCommand for abort of recording
private:
};
#endif // _QMITKTOFRECORDERWIDGET_H_INCLUDED
diff --git a/Modules/ToFUI/Qmitk/QmitkToFSurfaceGenerationWidget.cpp b/Modules/ToFUI/Qmitk/QmitkToFSurfaceGenerationWidget.cpp
index 411703ab1a..611bf9fd82 100644
--- a/Modules/ToFUI/Qmitk/QmitkToFSurfaceGenerationWidget.cpp
+++ b/Modules/ToFUI/Qmitk/QmitkToFSurfaceGenerationWidget.cpp
@@ -1,294 +1,294 @@
/*===================================================================
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 "QmitkToFSurfaceGenerationWidget.h"
#include <mitkTransferFunction.h>
#include <mitkTransferFunctionProperty.h>
//QT headers
#include <QString>
#include <mitkSmartPointerProperty.h>
#include <mitkRenderingManager.h>
#include <vtkCamera.h>
const std::string QmitkToFSurfaceGenerationWidget::VIEW_ID = "org.mitk.views.qmitktofsurfacegenerationwidget";
QmitkToFSurfaceGenerationWidget::QmitkToFSurfaceGenerationWidget(QWidget* parent, Qt::WindowFlags f): QWidget(parent, f)
, m_Controls(NULL),
m_ToFDistanceImageToSurfaceFilter(NULL),
m_ToFImageGrabber(NULL),
m_CameraIntrinsics(NULL),
m_Active(false)
{
CreateQtPartControl(this);
}
QmitkToFSurfaceGenerationWidget::~QmitkToFSurfaceGenerationWidget()
{
}
void QmitkToFSurfaceGenerationWidget::CreateQtPartControl(QWidget *parent)
{
if (!m_Controls)
{
// create GUI widgets
m_Controls = new Ui::QmitkToFSurfaceGenerationWidgetControls;
m_Controls->setupUi(parent);
this->CreateConnections();
this->OnShowAdvancedOptionsCheckboxChecked(false);
}
}
void QmitkToFSurfaceGenerationWidget::CreateConnections()
{
if ( m_Controls )
{
connect( (QObject*)(m_Controls->m_Compute3DDataCheckbox), SIGNAL(toggled(bool)), this, SLOT(OnCompute3DDataCheckboxChecked(bool)) );
connect( (QObject*)(m_Controls->m_DistanceColorMapCheckbox), SIGNAL(toggled(bool)), this, SLOT(OnDistanceColorMapCheckBoxChecked(bool)) );
connect( (QObject*)(m_Controls->m_RGBTextureCheckbox), SIGNAL(toggled(bool)), this, SLOT(OnRGBTextureCheckBoxChecked(bool)) );
connect( (QObject*)(m_Controls->m_TriangulationThresholdSpinbox), SIGNAL(valueChanged(double)), this, SLOT(OnTriangulationThresholdSpinBoxChanged()) );
connect( (QObject*)(m_Controls->m_ShowAdvancedOptionsCheckbox), SIGNAL(toggled(bool)), this, SLOT(OnShowAdvancedOptionsCheckboxChecked(bool)) );
connect( (QObject*)(m_Controls->m_RepresentationCombobox), SIGNAL(currentIndexChanged(int)),(QObject*) this, SLOT(OnRepresentationChanged(int)) );
connect( (QObject*)(m_Controls->m_ReconstructionCombobox), SIGNAL(currentIndexChanged(int)),(QObject*) this, SLOT(OnReconstructionChanged(int)) );
}
}
mitk::ToFDistanceImageToSurfaceFilter::Pointer QmitkToFSurfaceGenerationWidget::GetToFDistanceImageToSurfaceFilter()
{
return m_ToFDistanceImageToSurfaceFilter;
}
void QmitkToFSurfaceGenerationWidget::OnShowAdvancedOptionsCheckboxChecked(bool checked)
{
- this->m_Controls->m_TextureGroupBox->setShown(checked);
- this->m_Controls->m_TriangulationThresholdSpinbox->setShown(checked);
- this->m_Controls->m_ReconstructionCombobox->setShown(checked);
- this->m_Controls->m_RepresentationCombobox->setShown(checked);
- this->m_Controls->label->setShown(checked);
- this->m_Controls->label_2->setShown(checked);
- this->m_Controls->label_3->setShown(checked);
+ this->m_Controls->m_TextureGroupBox->setVisible(checked);
+ this->m_Controls->m_TriangulationThresholdSpinbox->setVisible(checked);
+ this->m_Controls->m_ReconstructionCombobox->setVisible(checked);
+ this->m_Controls->m_RepresentationCombobox->setVisible(checked);
+ this->m_Controls->label->setVisible(checked);
+ this->m_Controls->label_2->setVisible(checked);
+ this->m_Controls->label_3->setVisible(checked);
}
void QmitkToFSurfaceGenerationWidget::Initialize(mitk::ToFDistanceImageToSurfaceFilter::Pointer filter,
mitk::ToFImageGrabber::Pointer grabber,
mitk::CameraIntrinsics::Pointer intrinsics,
mitk::DataNode::Pointer surface,
vtkSmartPointer<vtkCamera> camera,
bool generateSurface,
bool showAdvancedOptions)
{
m_ToFDistanceImageToSurfaceFilter = filter;
m_ToFImageGrabber = grabber;
m_CameraIntrinsics = intrinsics;
m_Active = true;
m_Camera3d = camera;
bool hasSurface = false;
m_ToFImageGrabber->GetCameraDevice()->GetBoolProperty("HasSurface", hasSurface);
if(hasSurface)
{
this->m_Surface = mitk::Surface::New();
}
else
{
this->m_Surface = this->m_ToFDistanceImageToSurfaceFilter->GetOutput(0);
}
m_SurfaceNode = surface;
m_SurfaceNode->SetData(m_Surface);
this->FindReconstructionModeProperty();
m_Controls->m_ShowAdvancedOptionsCheckbox->setChecked(showAdvancedOptions);
this->OnShowAdvancedOptionsCheckboxChecked(showAdvancedOptions);
m_Controls->m_Compute3DDataCheckbox->setChecked(generateSurface);
}
bool QmitkToFSurfaceGenerationWidget::IsActive()
{
if(!m_Active)
{
MITK_ERROR << "QmitkToFSurfaceGenerationWidget is not active - please call QmitkToFSurfaceGenerationWidget::Initialize() first";
}
return m_Active;
}
void QmitkToFSurfaceGenerationWidget::OnTriangulationThresholdSpinBoxChanged()
{
if(IsActive())
{
this->m_ToFDistanceImageToSurfaceFilter->SetTriangulationThreshold( this->m_Controls->m_TriangulationThresholdSpinbox->value() );
this->m_ToFImageGrabber->GetCameraDevice()->SetFloatProperty("TriangulationThreshold", this->m_Controls->m_TriangulationThresholdSpinbox->value());
}
}
void QmitkToFSurfaceGenerationWidget::OnReconstructionChanged(int index)
{
if(IsActive())
{
mitk::ToFDistanceImageToSurfaceFilter::ReconstructionModeType type = mitk::ToFDistanceImageToSurfaceFilter::WithInterPixelDistance;
switch (index)
{
case 0:
{
type = mitk::ToFDistanceImageToSurfaceFilter::WithInterPixelDistance;
break;
}
case 1:
{
type = mitk::ToFDistanceImageToSurfaceFilter::WithOutInterPixelDistance;
break;
}
case 2:
{
type = mitk::ToFDistanceImageToSurfaceFilter::Kinect;
break;
}
default:
{
MITK_ERROR << "ReconstructionModeType does not exist or is not known in QmitkToFSurfaceGenerationWidget.";
break;
}
}
this->m_ToFDistanceImageToSurfaceFilter->SetReconstructionMode( type );
}
}
void QmitkToFSurfaceGenerationWidget::OnRepresentationChanged(int index)
{
if(IsActive())
{
bool generateTriangularMesh = false; //PointCloud case
if( index == 0) //Surface case
{
generateTriangularMesh = true;
}
this->m_ToFDistanceImageToSurfaceFilter->SetGenerateTriangularMesh(generateTriangularMesh);
this->m_ToFImageGrabber->GetCameraDevice()->SetBoolProperty("GenerateTriangularMesh", generateTriangularMesh);
this->m_ToFDistanceImageToSurfaceFilter->SetTriangulationThreshold( this->m_Controls->m_TriangulationThresholdSpinbox->value() );
this->m_ToFImageGrabber->GetCameraDevice()->SetFloatProperty("TriangulationThreshold", this->m_Controls->m_TriangulationThresholdSpinbox->value());
this->m_Controls->m_TriangulationThresholdSpinbox->setEnabled(generateTriangularMesh);
}
}
void QmitkToFSurfaceGenerationWidget::OnRGBTextureCheckBoxChecked(bool checked)
{
if(IsActive())
{
if(m_ToFImageGrabber->GetBoolProperty("HasRGBImage"))
{
if (checked)
{
// enable texture
this->m_SurfaceNode->SetProperty("Surface.Texture",mitk::SmartPointerProperty::New(this->m_ToFImageGrabber->GetOutput(3)));
} else {
// disable texture
this->m_SurfaceNode->GetPropertyList()->DeleteProperty("Surface.Texture");
}
}
}
}
void QmitkToFSurfaceGenerationWidget::OnDistanceColorMapCheckBoxChecked(bool checked)
{
if(m_SurfaceNode.IsNotNull())
{
this->m_SurfaceNode->SetBoolProperty("scalar visibility", checked);
}
}
bool QmitkToFSurfaceGenerationWidget::UpdateSurface()
{
if(IsActive())
{
//##### Code for surface #####
if (m_Controls->m_Compute3DDataCheckbox->isChecked())
{
bool hasSurface = false;
this->m_ToFImageGrabber->GetCameraDevice()->GetBoolProperty("HasSurface", hasSurface);
if(hasSurface)
{
mitk::SmartPointerProperty::Pointer surfaceProp = dynamic_cast< mitk::SmartPointerProperty * >(this->m_ToFImageGrabber->GetCameraDevice()->GetProperty("ToFSurface"));
this->m_Surface->SetVtkPolyData( dynamic_cast< mitk::Surface* >( surfaceProp->GetSmartPointer().GetPointer() )->GetVtkPolyData() );
}
else
{
this->m_Surface = m_ToFDistanceImageToSurfaceFilter->GetOutput(0);
}
//update pipeline
this->m_Surface->Update();
return true;
}
//##### End code for surface #####
}
return false;
}
void QmitkToFSurfaceGenerationWidget::OnCompute3DDataCheckboxChecked(bool checked)
{
if(checked)
{
//initialize the surface once
MITK_DEBUG << "OnSurfaceCheckboxChecked true";
this->m_SurfaceNode->SetData(this->m_Surface);
this->OnRepresentationChanged(m_Controls->m_RepresentationCombobox->currentIndex());
//we need to initialize (reinit) the surface, to make it fit into the renderwindow
mitk::RenderingManager::GetInstance()->InitializeViews(
this->m_Surface->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_3DWINDOWS, true);
// correctly place the vtk camera for appropriate surface rendering
//1m distance to camera should be a nice default value for most cameras
m_Camera3d->SetPosition(0,0,0);
m_Camera3d->SetViewUp(0,-1,0);
m_Camera3d->SetFocalPoint(0,0,1);
if (this->m_CameraIntrinsics.IsNotNull())
{
// compute view angle from camera intrinsics
m_Camera3d->SetViewAngle(mitk::ToFProcessingCommon::CalculateViewAngle(m_CameraIntrinsics,m_ToFImageGrabber->GetCaptureWidth()));
}
else
{
m_Camera3d->SetViewAngle(45);
}
m_Camera3d->SetClippingRange(1, 10000);
}
}
void QmitkToFSurfaceGenerationWidget::FindReconstructionModeProperty()
{
bool KinectReconstructionMode = false;
m_ToFImageGrabber->GetCameraDevice()->GetBoolProperty("KinectReconstructionMode",KinectReconstructionMode);
if(KinectReconstructionMode)
{
//set the reconstruction mode for kinect
this->m_ToFDistanceImageToSurfaceFilter->SetReconstructionMode(mitk::ToFDistanceImageToSurfaceFilter::Kinect);
m_Controls->m_ReconstructionCombobox->setDisabled(true);
m_Controls->m_ReconstructionCombobox->setCurrentIndex(2);
}
else
{
m_Controls->m_ReconstructionCombobox->setEnabled(true);
}
}
mitk::Surface::Pointer QmitkToFSurfaceGenerationWidget::GetSurface()
{
return m_Surface;
}
diff --git a/Modules/ToFUI/Qmitk/QmitkToFVisualisationSettingsWidget.cpp b/Modules/ToFUI/Qmitk/QmitkToFVisualisationSettingsWidget.cpp
index f98ed5e916..cca32ec016 100644
--- a/Modules/ToFUI/Qmitk/QmitkToFVisualisationSettingsWidget.cpp
+++ b/Modules/ToFUI/Qmitk/QmitkToFVisualisationSettingsWidget.cpp
@@ -1,423 +1,419 @@
/*===================================================================
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 "QmitkToFVisualisationSettingsWidget.h"
#include <mitkTransferFunction.h>
#include <mitkTransferFunctionProperty.h>
#include <mitkImageStatisticsHolder.h>
//QT headers
-#include <QPlastiqueStyle>
#include <QString>
#include <mitkTransferFunctionProperty.h>
#include <mitkTransferFunction.h>
const std::string QmitkToFVisualisationSettingsWidget::VIEW_ID = "org.mitk.views.qmitktofvisualisationsettingswidget";
QmitkToFVisualisationSettingsWidget::QmitkToFVisualisationSettingsWidget(QWidget* parent, Qt::WindowFlags f): QWidget(parent, f)
, m_Controls(NULL)
, m_RangeSliderMin(0)
, m_RangeSliderMax(0)
, m_MitkDistanceImageNode(NULL)
, m_MitkAmplitudeImageNode(NULL)
, m_MitkIntensityImageNode(NULL)
, m_Widget1ColorTransferFunction(NULL)
, m_Widget2ColorTransferFunction(NULL)
, m_Widget3ColorTransferFunction(NULL)
, m_Widget1TransferFunctionType(1)
, m_Widget2TransferFunctionType(0)
, m_Widget3TransferFunctionType(0)
{
CreateQtPartControl(this);
}
QmitkToFVisualisationSettingsWidget::~QmitkToFVisualisationSettingsWidget()
{
}
void QmitkToFVisualisationSettingsWidget::CreateQtPartControl(QWidget *parent)
{
if (!m_Controls)
{
// create GUI widgets
m_Controls = new Ui::QmitkToFVisualisationSettingsWidgetControls;
m_Controls->setupUi(parent);
this->CreateConnections();
}
}
void QmitkToFVisualisationSettingsWidget::CreateConnections()
{
if ( m_Controls )
{
connect( (QObject*)(m_Controls->m_SelectWidgetCombobox), SIGNAL(currentIndexChanged(int)),(QObject*) this, SLOT(OnWidgetSelected(int)) );
connect( (QObject*)(m_Controls->m_SelectTransferFunctionTypeCombobox), SIGNAL(currentIndexChanged(int)),(QObject*) this, SLOT(OnTransferFunctionTypeSelected(int)) );
connect( (QObject*)(m_Controls->m_TransferFunctionResetButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnTransferFunctionReset()) );
connect(m_Controls->m_XEditColor, SIGNAL(returnPressed()), this, SLOT(OnSetXValueColor()));
connect(m_Controls->m_RangeSliderMaxEdit, SIGNAL(returnPressed()), this, SLOT(OnRangeSliderMaxChanged()));
connect(m_Controls->m_RangeSliderMinEdit, SIGNAL(returnPressed()), this, SLOT(OnRangeSliderMinChanged()));
connect(m_Controls->m_RangeSliderReset, SIGNAL(pressed()), this, SLOT(OnResetSlider()));
connect(m_Controls->m_RangeSlider, SIGNAL(spanChanged(int, int) ),this, SLOT( OnSpanChanged(int , int ) ));
connect(m_Controls->m_AdvancedOptionsCheckbox, SIGNAL(toggled(bool) ),this, SLOT( OnShowAdvancedOptionsCheckboxChecked(bool) ));
- QPlastiqueStyle *sliderStyle = new QPlastiqueStyle();
m_Controls->m_RangeSlider->setMaximum(2048);
m_Controls->m_RangeSlider->setMinimum(-2048);
- m_Controls->m_RangeSlider->setHandleMovementMode(QxtSpanSlider::NoOverlapping);
- m_Controls->m_RangeSlider->setStyle(sliderStyle);
m_Controls->m_ColorTransferFunctionCanvas->SetQLineEdits(m_Controls->m_XEditColor, 0);
m_Controls->m_ColorTransferFunctionCanvas->SetTitle(""/*"Value -> Grayscale/Color"*/);
this->OnShowAdvancedOptionsCheckboxChecked(false);
}
}
void QmitkToFVisualisationSettingsWidget::OnSetXValueColor()
{
m_Controls->m_ColorTransferFunctionCanvas->SetX(m_Controls->m_XEditColor->text().toFloat());
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkToFVisualisationSettingsWidget::OnRangeSliderMaxChanged()
{
m_Controls->m_RangeSlider->setMaximum(m_Controls->m_RangeSliderMaxEdit->text().toInt());
UpdateRanges();
m_Controls->m_ColorTransferFunctionCanvas->update();
}
void QmitkToFVisualisationSettingsWidget::OnRangeSliderMinChanged()
{
m_Controls->m_RangeSlider->setMinimum(m_Controls->m_RangeSliderMinEdit->text().toInt());
UpdateRanges();
m_Controls->m_ColorTransferFunctionCanvas->update();
}
void QmitkToFVisualisationSettingsWidget::OnSpanChanged(int /*lower*/, int /*upper*/)
{
UpdateRanges();
m_Controls->m_ColorTransferFunctionCanvas->update();
}
void QmitkToFVisualisationSettingsWidget::OnResetSlider()
{
- m_Controls->m_RangeSlider->setUpperValue(m_RangeSliderMax);
- m_Controls->m_RangeSlider->setLowerValue(m_RangeSliderMin);
+ m_Controls->m_RangeSlider->setMaximumValue(m_RangeSliderMax);
+ m_Controls->m_RangeSlider->setMinimumValue(m_RangeSliderMin);
UpdateRanges();
m_Controls->m_ColorTransferFunctionCanvas->update();
}
void QmitkToFVisualisationSettingsWidget::UpdateRanges()
{
- int lower = m_Controls->m_RangeSlider->lowerValue();
- int upper = m_Controls->m_RangeSlider->upperValue();
+ int lower = m_Controls->m_RangeSlider->minimumValue();
+ int upper = m_Controls->m_RangeSlider->maximumValue();
m_Controls->m_ColorTransferFunctionCanvas->SetMin(lower);
m_Controls->m_ColorTransferFunctionCanvas->SetMax(upper);
}
void QmitkToFVisualisationSettingsWidget::UpdateSurfaceProperty()
{
if(this->m_MitkSurfaceNode.IsNotNull())
{
mitk::TransferFunction::Pointer transferFunction = mitk::TransferFunction::New();
transferFunction->SetColorTransferFunction(this->GetSelectedColorTransferFunction());
this->m_MitkSurfaceNode->SetProperty("Surface.TransferFunction", mitk::TransferFunctionProperty::New(transferFunction));
}
}
void QmitkToFVisualisationSettingsWidget::Initialize(mitk::DataNode* distanceImageNode, mitk::DataNode* amplitudeImageNode,
mitk::DataNode* intensityImageNode, mitk::DataNode* surfaceNode)
{
this->m_MitkDistanceImageNode = distanceImageNode;
this->m_MitkAmplitudeImageNode = amplitudeImageNode;
this->m_MitkIntensityImageNode = intensityImageNode;
this->m_MitkSurfaceNode = surfaceNode;
// Initialize transfer functions for image DataNodes such that:
// Widget1 (Distance): color from red (2nd min) to blue (max)
// Widget2 (Amplitude): grey value from black (2nd min) to white (max)
// Widget3 (Intensity): grey value from black (2nd min) to white (max)
if (!m_MitkDistanceImageNode && !m_MitkAmplitudeImageNode && !m_MitkIntensityImageNode)
{
m_Controls->m_ColorTransferFunctionCanvas->setEnabled(false);
}
else
{
m_Controls->m_ColorTransferFunctionCanvas->setEnabled(true);
int numberOfImages = 0;
if (m_MitkDistanceImageNode)
{
m_Widget1ColorTransferFunction = vtkColorTransferFunction::New();
this->m_Widget1TransferFunctionType = 1;
m_Controls->m_SelectTransferFunctionTypeCombobox->setCurrentIndex(this->m_Widget1TransferFunctionType);
numberOfImages++;
}
if (m_MitkAmplitudeImageNode)
{
m_Widget2ColorTransferFunction = vtkColorTransferFunction::New();
this->m_Widget2TransferFunctionType = 0;
numberOfImages++;
}
if (m_MitkIntensityImageNode)
{
m_Widget3ColorTransferFunction = vtkColorTransferFunction::New();
this->m_Widget3TransferFunctionType = 0;
numberOfImages++;
}
m_Controls->m_SelectWidgetCombobox->setMaxCount(numberOfImages);
}
this->ReinitTransferFunction(0,1);
this->ReinitTransferFunction(1,0);
this->ReinitTransferFunction(2,0);
}
void QmitkToFVisualisationSettingsWidget::UpdateCanvas()
{
m_Controls->m_ColorTransferFunctionCanvas->SetColorTransferFunction( this->GetSelectedColorTransferFunction() );
UpdateRanges();
m_Controls->m_ColorTransferFunctionCanvas->update();
}
void QmitkToFVisualisationSettingsWidget::OnTransferFunctionTypeSelected(int index)
{
int currentWidgetIndex = m_Controls->m_SelectWidgetCombobox->currentIndex();
if (currentWidgetIndex == 0)
{
this->m_Widget1TransferFunctionType = index;
}
else if (currentWidgetIndex == 1)
{
this->m_Widget2TransferFunctionType = index;
}
else if (currentWidgetIndex == 2)
{
this->m_Widget3TransferFunctionType = index;
}
else
{
return;
}
this->UpdateSurfaceProperty();
}
void QmitkToFVisualisationSettingsWidget::OnShowAdvancedOptionsCheckboxChecked(bool checked)
{
- this->m_Controls->m_MappingGroupBox->setShown(checked);
- this->m_Controls->m_SelectTransferFunctionTypeCombobox->setShown(checked);
- this->m_Controls->m_SelectWidgetCombobox->setShown(checked);
- this->m_Controls->m_TransferFunctionResetButton->setShown(checked);
+ this->m_Controls->m_MappingGroupBox->setVisible(checked);
+ this->m_Controls->m_SelectTransferFunctionTypeCombobox->setVisible(checked);
+ this->m_Controls->m_SelectWidgetCombobox->setVisible(checked);
+ this->m_Controls->m_TransferFunctionResetButton->setVisible(checked);
}
void QmitkToFVisualisationSettingsWidget::OnWidgetSelected(int index)
{
int currentWidgetIndex = index;
double valMin[6];
double valMax[6];
int numPoints;
if (currentWidgetIndex == 0)
{
m_Controls->m_SelectTransferFunctionTypeCombobox->setCurrentIndex(this->m_Widget1TransferFunctionType);
numPoints = this->m_Widget1ColorTransferFunction->GetSize();
this->m_Widget1ColorTransferFunction->GetNodeValue( 0, valMin );
this->m_Widget1ColorTransferFunction->GetNodeValue( numPoints-1, valMax );
m_Controls->m_ColorTransferFunctionCanvas->SetColorTransferFunction( this->m_Widget1ColorTransferFunction );
}
else if (currentWidgetIndex == 1)
{
m_Controls->m_SelectTransferFunctionTypeCombobox->setCurrentIndex(this->m_Widget2TransferFunctionType);
numPoints = this->m_Widget2ColorTransferFunction->GetSize();
this->m_Widget2ColorTransferFunction->GetNodeValue( 0, valMin );
this->m_Widget2ColorTransferFunction->GetNodeValue( numPoints-1, valMax );
m_Controls->m_ColorTransferFunctionCanvas->SetColorTransferFunction( this->m_Widget2ColorTransferFunction );
}
else if (currentWidgetIndex == 2)
{
m_Controls->m_SelectTransferFunctionTypeCombobox->setCurrentIndex(this->m_Widget3TransferFunctionType);
numPoints = this->m_Widget3ColorTransferFunction->GetSize();
this->m_Widget3ColorTransferFunction->GetNodeValue( 0, valMin );
this->m_Widget3ColorTransferFunction->GetNodeValue( numPoints-1, valMax );
m_Controls->m_ColorTransferFunctionCanvas->SetColorTransferFunction( this->m_Widget3ColorTransferFunction );
}
else if (currentWidgetIndex == 3)
{
}
else
{
return;
}
m_RangeSliderMin = valMin[0];
m_RangeSliderMax = valMax[0];
int border = (m_RangeSliderMax - m_RangeSliderMin) * 0.1;
m_Controls->m_RangeSlider->setMinimum(m_RangeSliderMin - border);
m_Controls->m_RangeSlider->setMaximum(m_RangeSliderMax + border);
m_Controls->m_RangeSliderMinEdit->setText(QString("").setNum(m_RangeSliderMin - border));
m_Controls->m_RangeSliderMaxEdit->setText(QString("").setNum(m_RangeSliderMax + border));
- m_Controls->m_RangeSlider->setSpan( m_RangeSliderMin, m_RangeSliderMax);
+ m_Controls->m_RangeSlider->setRange( m_RangeSliderMin, m_RangeSliderMax);
UpdateRanges();
m_Controls->m_ColorTransferFunctionCanvas->update();
this->UpdateSurfaceProperty();
}
void QmitkToFVisualisationSettingsWidget::ResetTransferFunction(vtkColorTransferFunction* colorTransferFunction, int type, double min, double max)
{
colorTransferFunction->RemoveAllPoints();
if (type == 0)
{
colorTransferFunction->AddRGBPoint(min, 0, 0, 0);
colorTransferFunction->AddRGBPoint(max, 1, 1, 1);
}
else
{
if (min>0.01)
{
colorTransferFunction->AddRGBPoint(0.0, 0, 0, 0);
colorTransferFunction->AddRGBPoint(min-0.01, 0, 0, 0);
}
colorTransferFunction->AddRGBPoint(min, 1, 0, 0);
colorTransferFunction->AddRGBPoint(min+(max-min)/2, 1, 1, 0);
colorTransferFunction->AddRGBPoint(max, 0, 0, 1);
}
colorTransferFunction->SetColorSpaceToHSV();
}
void QmitkToFVisualisationSettingsWidget::ReinitTransferFunction(int widget, int type)
{
switch (widget)
{
case 0:
{
mitk::Image::Pointer distanceImage = dynamic_cast<mitk::Image*>(m_MitkDistanceImageNode->GetData());
// use second minimum to draw 0 values (that are usually segmented) black
m_RangeSliderMin = distanceImage->GetStatistics()->GetScalarValue2ndMin();
m_RangeSliderMax = distanceImage->GetStatistics()->GetScalarValueMax();
MITK_INFO<<"Distance Min: "<<m_RangeSliderMin;
MITK_INFO<<"Distance Max: "<<m_RangeSliderMax;
ResetTransferFunction(this->m_Widget1ColorTransferFunction, type, this->m_RangeSliderMin, this->m_RangeSliderMax);
m_Controls->m_ColorTransferFunctionCanvas->SetColorTransferFunction( this->m_Widget1ColorTransferFunction );
mitk::TransferFunction::Pointer tf1 = mitk::TransferFunction::New();
tf1->SetColorTransferFunction( m_Widget1ColorTransferFunction );
m_MitkDistanceImageNode->SetProperty("Image Rendering.Transfer Function",mitk::TransferFunctionProperty::New(tf1));
break;
}
case 1:
{
if (m_MitkAmplitudeImageNode)
{
mitk::Image::Pointer amplitudeImage = dynamic_cast<mitk::Image*>(m_MitkAmplitudeImageNode->GetData());
if (amplitudeImage.IsNotNull())
{
m_RangeSliderMin = amplitudeImage->GetStatistics()->GetScalarValueMin();
m_RangeSliderMax = amplitudeImage->GetStatistics()->GetScalarValueMax();
MITK_INFO<<"Amplitude Min: "<<m_RangeSliderMin;
MITK_INFO<<"Amplitude Max: "<<m_RangeSliderMax;
ResetTransferFunction(this->m_Widget2ColorTransferFunction, type, this->m_RangeSliderMin, this->m_RangeSliderMax);
m_Controls->m_ColorTransferFunctionCanvas->SetColorTransferFunction( this->m_Widget2ColorTransferFunction );
mitk::TransferFunction::Pointer tf2 = mitk::TransferFunction::New();
tf2->SetColorTransferFunction( m_Widget2ColorTransferFunction );
m_MitkAmplitudeImageNode->SetProperty("Image Rendering.Transfer Function",mitk::TransferFunctionProperty::New(tf2));
}
}
break;
}
case 2:
{
if (m_MitkIntensityImageNode)
{
mitk::Image::Pointer intensityImage = dynamic_cast<mitk::Image*>(m_MitkIntensityImageNode->GetData());
if (intensityImage.IsNotNull())
{
m_RangeSliderMin = intensityImage->GetStatistics()->GetScalarValueMin();
m_RangeSliderMax = intensityImage->GetStatistics()->GetScalarValueMax();
MITK_INFO<<"Intensity Min: "<<m_RangeSliderMin;
MITK_INFO<<"Intensity Max: "<<m_RangeSliderMax;
ResetTransferFunction(this->m_Widget3ColorTransferFunction, type, this->m_RangeSliderMin, this->m_RangeSliderMax);
m_Controls->m_ColorTransferFunctionCanvas->SetColorTransferFunction( this->m_Widget3ColorTransferFunction );
mitk::TransferFunction::Pointer tf3 = mitk::TransferFunction::New();
tf3->SetColorTransferFunction( m_Widget3ColorTransferFunction );
m_MitkIntensityImageNode->SetProperty("Image Rendering.Transfer Function",mitk::TransferFunctionProperty::New(tf3));
}
}
break;
}
default:
break;
}
this->UpdateSurfaceProperty();
}
void QmitkToFVisualisationSettingsWidget::OnTransferFunctionReset()
{
int currentTransferFunctionTypeIndex = m_Controls->m_SelectTransferFunctionTypeCombobox->currentIndex();
int currentWidgetIndex = m_Controls->m_SelectWidgetCombobox->currentIndex();
this->ReinitTransferFunction(currentWidgetIndex,currentTransferFunctionTypeIndex);
int border = (m_RangeSliderMax - m_RangeSliderMin) * 0.1;
m_Controls->m_RangeSlider->setMinimum(m_RangeSliderMin - border);
m_Controls->m_RangeSlider->setMaximum(m_RangeSliderMax + border);
m_Controls->m_RangeSliderMinEdit->setText(QString("").setNum(m_RangeSliderMin - border));
m_Controls->m_RangeSliderMaxEdit->setText(QString("").setNum(m_RangeSliderMax + border));
- m_Controls->m_RangeSlider->setSpan( m_RangeSliderMin, m_RangeSliderMax);
+ m_Controls->m_RangeSlider->setRange( m_RangeSliderMin, m_RangeSliderMax);
UpdateRanges();
m_Controls->m_ColorTransferFunctionCanvas->update();
this->UpdateSurfaceProperty();
}
vtkColorTransferFunction* QmitkToFVisualisationSettingsWidget::GetWidget1ColorTransferFunction()
{
return this->m_Widget1ColorTransferFunction;
}
vtkColorTransferFunction* QmitkToFVisualisationSettingsWidget::GetWidget2ColorTransferFunction()
{
return this->m_Widget2ColorTransferFunction;
}
vtkColorTransferFunction* QmitkToFVisualisationSettingsWidget::GetWidget3ColorTransferFunction()
{
return this->m_Widget3ColorTransferFunction;
}
vtkColorTransferFunction* QmitkToFVisualisationSettingsWidget::GetSelectedColorTransferFunction()
{
int currentWidgetIndex = m_Controls->m_SelectWidgetCombobox->currentIndex();
if (currentWidgetIndex==0)
{
return this->m_Widget1ColorTransferFunction;
}
else if (currentWidgetIndex==1)
{
return this->m_Widget2ColorTransferFunction;
}
else if (currentWidgetIndex==2)
{
return this->m_Widget3ColorTransferFunction;
}
else
{
return this->m_Widget3ColorTransferFunction;
}
}
int QmitkToFVisualisationSettingsWidget::GetSelectedImageIndex()
{
return this->m_Controls->m_SelectWidgetCombobox->currentIndex();
}
diff --git a/Modules/ToFUI/Qmitk/QmitkToFVisualisationSettingsWidgetControls.ui b/Modules/ToFUI/Qmitk/QmitkToFVisualisationSettingsWidgetControls.ui
index 9d8aebea7f..dc1e7ca403 100644
--- a/Modules/ToFUI/Qmitk/QmitkToFVisualisationSettingsWidgetControls.ui
+++ b/Modules/ToFUI/Qmitk/QmitkToFVisualisationSettingsWidgetControls.ui
@@ -1,445 +1,445 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QmitkToFVisualisationSettingsWidgetControls</class>
<widget class="QWidget" name="QmitkToFVisualisationSettingsWidgetControls">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>482</width>
<height>230</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="windowTitle">
<string>QmitkToFVisualisationSettings</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="text">
<string>ToF Visualization</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="m_AdvancedOptionsCheckbox">
<property name="text">
<string>Show advanced options</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<layout class="QHBoxLayout" name="m_AdvancedLayout">
<item>
<widget class="QComboBox" name="m_SelectWidgetCombobox">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>50</height>
</size>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<property name="maxVisibleItems">
<number>3</number>
</property>
<property name="insertPolicy">
<enum>QComboBox::InsertAtBottom</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
<property name="iconSize">
<size>
<width>30</width>
<height>30</height>
</size>
</property>
<property name="frame">
<bool>true</bool>
</property>
<item>
<property name="text">
<string>Distance</string>
</property>
<property name="icon">
<iconset resource="../resources/QmitkToFUtilWidget.qrc">
<normaloff>:/images/widget1.png</normaloff>:/images/widget1.png</iconset>
</property>
</item>
<item>
<property name="text">
<string>Amplitude</string>
</property>
<property name="icon">
<iconset resource="../resources/QmitkToFUtilWidget.qrc">
<normaloff>:/images/widget2.png</normaloff>:/images/widget2.png</iconset>
</property>
</item>
<item>
<property name="text">
<string>Intensity</string>
</property>
<property name="icon">
<iconset resource="../resources/QmitkToFUtilWidget.qrc">
<normaloff>:/images/widget3.png</normaloff>:/images/widget3.png</iconset>
</property>
</item>
</widget>
</item>
<item>
<widget class="QComboBox" name="m_SelectTransferFunctionTypeCombobox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>150</width>
<height>50</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>50</height>
</size>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<property name="maxVisibleItems">
<number>3</number>
</property>
<property name="insertPolicy">
<enum>QComboBox::InsertAtBottom</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
<property name="iconSize">
<size>
<width>100</width>
<height>35</height>
</size>
</property>
<property name="frame">
<bool>true</bool>
</property>
<item>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../resources/QmitkToFUtilWidget.qrc">
<normaloff>:/images/grayscale.png</normaloff>:/images/grayscale.png</iconset>
</property>
</item>
<item>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../resources/QmitkToFUtilWidget.qrc">
<normaloff>:/images/color.png</normaloff>:/images/color.png</iconset>
</property>
</item>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_TransferFunctionResetButton">
<property name="minimumSize">
<size>
<width>100</width>
<height>50</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>50</height>
</size>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Fit scale</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0" colspan="2">
<widget class="QGroupBox" name="m_MappingGroupBox">
<property name="title">
<string>Gray value/color mapping</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="5">
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
- <widget class="QxtSpanSlider" name="m_RangeSlider">
+ <widget class="ctkRangeSlider" name="m_RangeSlider">
<property name="toolTip">
<string>modify actual seen window by dragging left and right slider. </string>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="m_RangeSliderReset">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>48</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Resets range to histogram minimum and maximum.</string>
</property>
<property name="text">
<string>Reset</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0" colspan="5">
<widget class="QmitkColorTransferFunctionCanvas" name="m_ColorTransferFunctionCanvas" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>28</height>
</size>
</property>
<property name="font">
<font/>
</property>
<property name="toolTip">
<string>Left-click to select a point or add a new point.
Hold left mouse button to move selected point.
Click right mouse button to delete a point.
Double-click left mouse button to change color of a point.</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLineEdit" name="m_RangeSliderMinEdit">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>48</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>48</width>
<height>16777215</height>
</size>
</property>
<property name="font">
<font>
<pointsize>7</pointsize>
</font>
</property>
<property name="toolTip">
<string>Edit x-coordinate (grayvalue) of currently selected point.</string>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="1">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>86</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="2">
<widget class="QLineEdit" name="m_XEditColor">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>48</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>48</width>
<height>16777215</height>
</size>
</property>
<property name="font">
<font>
<pointsize>7</pointsize>
</font>
</property>
<property name="toolTip">
<string>Edit x-coordinate (grayvalue) of currently selected point.</string>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="3">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>85</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="4">
<widget class="QLineEdit" name="m_RangeSliderMaxEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>48</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>48</width>
<height>16777215</height>
</size>
</property>
<property name="font">
<font>
<pointsize>7</pointsize>
</font>
</property>
<property name="toolTip">
<string>Edit x-coordinate (grayvalue) of currently selected point.</string>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
- <class>QxtSpanSlider</class>
- <extends>QSlider</extends>
- <header location="global">qxtspanslider.h</header>
+ <class>ctkRangeSlider</class>
+ <extends>QWidget</extends>
+ <header location="global">ctkRangeSlider.h</header>
</customwidget>
<customwidget>
<class>QmitkColorTransferFunctionCanvas</class>
<extends>QWidget</extends>
<header>QmitkColorTransferFunctionCanvas.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../resources/QmitkToFUtilWidget.qrc"/>
</resources>
<connections/>
</ui>
diff --git a/Modules/US/Testing/files.cmake b/Modules/US/Testing/files.cmake
index a5d518e1f3..c3b51c1dd7 100644
--- a/Modules/US/Testing/files.cmake
+++ b/Modules/US/Testing/files.cmake
@@ -1,19 +1,19 @@
SET(MODULE_TESTS
mitkUSDeviceTest.cpp
mitkUSProbeTest.cpp
# -----------------------------------------------------------------------
# ------------------ Deavtivated Tests ----------------------------------
# see http://bugs.mitk.org/show_bug.cgi?id=18180
- #mitkUSImageLoggingFilterTest.cpp
+ mitkUSImageLoggingFilterTest.cpp
# -----------------------------------------------------------------------
)
SET(MODULE_CUSTOM_TESTS
mitkUSImageVideoSourceTest.cpp
)
diff --git a/Modules/US/Testing/mitkUSImageLoggingFilterTest.cpp b/Modules/US/Testing/mitkUSImageLoggingFilterTest.cpp
index b36f646f22..113df66d9e 100644
--- a/Modules/US/Testing/mitkUSImageLoggingFilterTest.cpp
+++ b/Modules/US/Testing/mitkUSImageLoggingFilterTest.cpp
@@ -1,184 +1,184 @@
/*===================================================================
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 "mitkUSImageLoggingFilter.h"
#include <mitkTestingMacros.h>
#include <mitkTestFixture.h>
#include <mitkTestingConfig.h>
#include <mitkIOUtil.h>
#include "mitkImageGenerator.h"
#include "itksys/SystemTools.hxx"
#include "Poco/File.h"
class mitkUSImageLoggingFilterTestSuite : public mitk::TestFixture
{
CPPUNIT_TEST_SUITE(mitkUSImageLoggingFilterTestSuite);
MITK_TEST(TestInstantiation);
MITK_TEST(TestSavingValidTestImage);
MITK_TEST(TestSavingAfterMupltipleUpdateCalls);
MITK_TEST(TestFilterWithEmptyImages);
MITK_TEST(TestFilterWithInvalidPath);
MITK_TEST(TestWrongImageFileExtensions);
MITK_TEST(TestJpgFileExtension);
CPPUNIT_TEST_SUITE_END();
private:
mitk::USImageLoggingFilter::Pointer m_TestFilter;
std::string m_TemporaryTestDirectory;
mitk::Image::Pointer m_RandomRestImage1;
mitk::Image::Pointer m_RandomRestImage2;
mitk::Image::Pointer m_RandomSingleSliceImage;
mitk::Image::Pointer m_RealTestImage;
public:
void setUp()
{
m_TestFilter = mitk::USImageLoggingFilter::New();
m_TemporaryTestDirectory = mitk::IOUtil::GetTempPath();
m_RandomRestImage1 = mitk::ImageGenerator::GenerateRandomImage<float>(100, 100, 100, 1, 0.2, 0.3, 0.4);
m_RandomRestImage2 = mitk::ImageGenerator::GenerateRandomImage<float>(100, 100, 100, 1, 0.2, 0.3, 0.4);
- m_RandomSingleSliceImage = mitk::ImageGenerator::GenerateRandomImage<float>(100, 100, 1, 1, 0.2, 0.3, 0.4);
+ m_RandomSingleSliceImage = mitk::ImageGenerator::GenerateRandomImage<unsigned char>(100, 100, 1, 1, 0.2, 0.3, 0.4);
m_RealTestImage = mitk::IOUtil::LoadImage(GetTestDataFilePath("Pic3D.nrrd"));
}
void tearDown()
{
m_TestFilter = NULL;
m_RandomRestImage1 = NULL;
m_RandomRestImage2 = NULL;
m_RealTestImage = NULL;
m_RandomSingleSliceImage = NULL;
}
void TestInstantiation()
{
CPPUNIT_ASSERT_MESSAGE("Testing instantiation",m_TestFilter.IsNotNull());
}
void TestSavingValidTestImage()
{
//######################## Test with valid test images ################################
m_TestFilter->SetInput(m_RandomRestImage1);
m_TestFilter->SetInput("secondImage",m_RandomRestImage2);
m_TestFilter->Update();
MITK_TEST_OUTPUT(<<"Tested method Update() with valid data.");
std::vector<std::string> filenames;
std::string csvFileName;
m_TestFilter->SaveImages(m_TemporaryTestDirectory,filenames,csvFileName);
MITK_TEST_OUTPUT(<<"Tested method SaveImages(...).");
CPPUNIT_ASSERT_MESSAGE("Testing if correct number of images was saved",filenames.size() == 1);
CPPUNIT_ASSERT_MESSAGE("Testing if image file exists",Poco::File(filenames.at(0).c_str()).exists());
CPPUNIT_ASSERT_MESSAGE("Testing if csv file exists",Poco::File(csvFileName.c_str()).exists());
//clean up
std::remove(filenames.at(0).c_str());
std::remove(csvFileName.c_str());
}
void TestSavingAfterMupltipleUpdateCalls()
{
//######################## Test multiple calls of update ################################
m_TestFilter->SetInput(m_RandomRestImage1);
m_TestFilter->SetInput("secondImage",m_RandomRestImage2);
for(int i=0; i<5; i++)
{
m_TestFilter->Update();
std::stringstream testmessage;
testmessage << "testmessage" << i;
m_TestFilter->AddMessageToCurrentImage(testmessage.str());
itksys::SystemTools::Delay(50);
}
MITK_TEST_OUTPUT(<<"Call Update() 5 times.");
std::vector<std::string> filenames;
std::string csvFileName;
m_TestFilter->SaveImages(m_TemporaryTestDirectory,filenames,csvFileName);
MITK_TEST_OUTPUT(<<"Tested method SaveImages(...).");
CPPUNIT_ASSERT_MESSAGE("Testing if correct number of images was saved",filenames.size() == 5);
CPPUNIT_ASSERT_MESSAGE("Testing if file 1 exists",Poco::File(filenames.at(0).c_str()).exists());
CPPUNIT_ASSERT_MESSAGE("Testing if file 2 exists",Poco::File(filenames.at(1).c_str()).exists());
CPPUNIT_ASSERT_MESSAGE("Testing if file 3 exists",Poco::File(filenames.at(2).c_str()).exists());
CPPUNIT_ASSERT_MESSAGE("Testing if file 4 exists",Poco::File(filenames.at(3).c_str()).exists());
CPPUNIT_ASSERT_MESSAGE("Testing if file 5 exists",Poco::File(filenames.at(4).c_str()).exists());
CPPUNIT_ASSERT_MESSAGE("Testing if csv file exists",Poco::File(csvFileName.c_str()).exists());
//clean up
for(size_t i=0; i<filenames.size(); i++) std::remove(filenames.at(i).c_str());
std::remove(csvFileName.c_str());
}
void TestFilterWithEmptyImages()
{
//create empty test images
mitk::Image::Pointer testImage = mitk::Image::New();
mitk::Image::Pointer testImage2 = mitk::Image::New();
//set both as input for the filter
m_TestFilter->SetInput(testImage);
CPPUNIT_ASSERT_MESSAGE("Testing SetInput(...) for first input.",m_TestFilter->GetNumberOfInputs()==1);
m_TestFilter->SetInput("secondImage",testImage2);
CPPUNIT_ASSERT_MESSAGE("Testing SetInput(...) for second input.",m_TestFilter->GetNumberOfInputs()==2);
//images are empty, but update method should not crash
CPPUNIT_ASSERT_NO_THROW_MESSAGE("Tested method Update() with invalid data.",m_TestFilter->Update());
}
void TestFilterWithInvalidPath()
{
#ifdef WIN32
std::string filename = "XV:/342INVALID<>"; //invalid filename for windows
#else
std::string filename = "/dsfdsf:$�$342INVALID"; //invalid filename for linux
#endif
m_TestFilter->SetInput(m_RealTestImage);
m_TestFilter->Update();
CPPUNIT_ASSERT_THROW_MESSAGE("Testing if correct exception if thrown if an invalid path is given.",
m_TestFilter->SaveImages(filename),
mitk::Exception);
}
void TestWrongImageFileExtensions()
{
CPPUNIT_ASSERT_MESSAGE("Testing invalid extension.",!m_TestFilter->SetImageFilesExtension(".INVALID"));
}
void TestJpgFileExtension()
{
CPPUNIT_ASSERT_MESSAGE("Testing setting of jpg extension.",m_TestFilter->SetImageFilesExtension(".jpg"));
m_TestFilter->SetInput(m_RandomSingleSliceImage);
m_TestFilter->Update();
std::vector<std::string> filenames;
std::string csvFileName;
m_TestFilter->SaveImages(m_TemporaryTestDirectory,filenames,csvFileName);
CPPUNIT_ASSERT_MESSAGE("Testing if correct number of images was saved",filenames.size() == 1);
CPPUNIT_ASSERT_MESSAGE("Testing if jpg image file exists",Poco::File(filenames.at(0).c_str()).exists());
CPPUNIT_ASSERT_MESSAGE("Testing if csv file exists",Poco::File(csvFileName.c_str()).exists());
//clean up
std::remove(filenames.at(0).c_str());
std::remove(csvFileName.c_str());
}
};
MITK_TEST_SUITE_REGISTRATION(mitkUSImageLoggingFilter)
diff --git a/Plugins/PluginList.cmake b/Plugins/PluginList.cmake
index 1a6e6ada9d..d6b37284cb 100644
--- a/Plugins/PluginList.cmake
+++ b/Plugins/PluginList.cmake
@@ -1,58 +1,50 @@
# Plug-ins must be ordered according to their dependencies
-if (MITK_USE_Qt4)
set(MITK_EXT_PLUGINS
org.mitk.core.services:ON
org.mitk.gui.common:ON
org.mitk.planarfigure:ON
org.mitk.core.ext:OFF
org.mitk.core.jobs:OFF
org.mitk.diffusionimaging:OFF
org.mitk.simulation:OFF
org.mitk.gui.qt.application:ON
org.mitk.gui.qt.coreapplication:OFF
org.mitk.gui.qt.ext:OFF
org.mitk.gui.qt.extapplication:OFF
org.mitk.gui.qt.common:ON
org.mitk.gui.qt.stdmultiwidgeteditor:ON
org.mitk.gui.qt.common.legacy:OFF
org.mitk.gui.qt.cmdlinemodules:OFF
org.mitk.gui.qt.diffusionimagingapp:OFF
org.mitk.gui.qt.datamanager:ON
org.mitk.gui.qt.datamanagerlight:OFF
org.mitk.gui.qt.properties:ON
org.mitk.gui.qt.basicimageprocessing:OFF
org.mitk.gui.qt.dicom:OFF
org.mitk.gui.qt.diffusionimaging:OFF
org.mitk.gui.qt.dtiatlasapp:OFF
org.mitk.gui.qt.igtexamples:OFF
org.mitk.gui.qt.igttracking:OFF
org.mitk.gui.qt.imagecropper:OFF
org.mitk.gui.qt.imagenavigator:ON
org.mitk.gui.qt.viewnavigator:OFF
org.mitk.gui.qt.materialeditor:OFF
org.mitk.gui.qt.measurementtoolbox:OFF
org.mitk.gui.qt.moviemaker:OFF
org.mitk.gui.qt.pointsetinteraction:OFF
org.mitk.gui.qt.python:OFF
org.mitk.gui.qt.registration:OFF
org.mitk.gui.qt.remeshing:OFF
org.mitk.gui.qt.segmentation:OFF
org.mitk.gui.qt.simulation:OFF
+ org.mitk.gui.qt.aicpregistration:OFF
org.mitk.gui.qt.toftutorial:OFF
org.mitk.gui.qt.tofutil:OFF
org.mitk.gui.qt.ugvisualization:OFF
org.mitk.gui.qt.ultrasound:OFF
org.mitk.gui.qt.volumevisualization:OFF
org.mitk.gui.qt.eventrecorder:OFF
org.mitk.gui.qt.xnat:OFF
)
-
-else()
-
-set(MITK_EXT_PLUGINS
- # empty so far
-)
-
-endif()
diff --git a/Plugins/org.mitk.core.ext/src/internal/mitkCoreExtActivator.cpp b/Plugins/org.mitk.core.ext/src/internal/mitkCoreExtActivator.cpp
index 5ce1bbef45..74dd244710 100755
--- a/Plugins/org.mitk.core.ext/src/internal/mitkCoreExtActivator.cpp
+++ b/Plugins/org.mitk.core.ext/src/internal/mitkCoreExtActivator.cpp
@@ -1,70 +1,72 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "mitkCoreExtActivator.h"
#include "mitkCoreExtConstants.h"
#include "mitkInputDeviceRegistry.h"
#include <berryPlatform.h>
#include <berryIPreferencesService.h>
#include <QtPlugin>
namespace mitk
{
void CoreExtActivator::start(ctkPluginContext* context)
{
Q_UNUSED(context)
this->StartInputDeviceModules();
}
void CoreExtActivator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
void mitk::CoreExtActivator::StartInputDeviceModules()
{
IInputDeviceRegistry::Pointer inputDeviceRegistry(new mitk::InputDeviceRegistry());
berry::Platform::GetServiceRegistry().RegisterService(
mitk::CoreExtConstants::INPUTDEVICE_SERVICE,
inputDeviceRegistry);
// Gets the last setting of the preferences; if a device was selected,
// it will still be activated after a restart
berry::IPreferencesService::Pointer prefService = berry::Platform::GetServiceRegistry()
.GetServiceById<berry::IPreferencesService>(berry::IPreferencesService::ID);
berry::IPreferences::Pointer extPreferencesNode =
prefService->GetSystemPreferences()->Node(CoreExtConstants::INPUTDEVICE_PREFERENCES);
// Initializes the modules
std::vector<IInputDeviceDescriptor::Pointer> descriptors(inputDeviceRegistry->GetInputDevices());
for (std::vector<IInputDeviceDescriptor::Pointer>::const_iterator it = descriptors.begin();
it != descriptors.end(); ++it)
{
if (extPreferencesNode->GetBool((*it)->GetID(), false))
{
IInputDevice::Pointer temp = (*it)->CreateInputDevice();
temp->RegisterInputDevice();
}
}
} // end method StartInputDeviceModules
} // end namespace mitk
-Q_EXPORT_PLUGIN2(org_mitk_core_ext, mitk::CoreExtActivator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_core_ext, mitk::CoreExtActivator)
+#endif
diff --git a/Plugins/org.mitk.core.ext/src/internal/mitkCoreExtActivator.h b/Plugins/org.mitk.core.ext/src/internal/mitkCoreExtActivator.h
index 9c9742f32a..bbbf9881a1 100755
--- a/Plugins/org.mitk.core.ext/src/internal/mitkCoreExtActivator.h
+++ b/Plugins/org.mitk.core.ext/src/internal/mitkCoreExtActivator.h
@@ -1,63 +1,66 @@
/*===================================================================
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 MITKCOREEXTACTIVATOR_H_
#define MITKCOREEXTACTIVATOR_H_
#include <ctkPluginActivator.h>
#include <org_mitk_core_ext_Export.h>
#include <mitkExportMacros.h>
namespace mitk
{
/**
* @brief The activator class for the org.mitk.core.ext plug-in.
* @ingroup org_mitk_core_ext_internal
*
* When the plug-in is started by the framework, it calls a global function to initialize
* the mitkCoreExt module.
*
*/
class MITK_LOCAL CoreExtActivator : public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_core_ext")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
/**
* Starts this plug-in and registers object factories.
*
* @param context
* The context for the plug-in.
*/
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
private:
/**
* Activates the input device modules.
*/
void StartInputDeviceModules();
}; // end class CoreExtActivator
} //end namespace mitk
#endif /* MITKCOREEXTACTIVATOR_H_ */
diff --git a/Plugins/org.mitk.core.jobs/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.core.jobs/src/internal/mitkPluginActivator.cpp
index 0d608ccb5e..785033cfa0 100644
--- a/Plugins/org.mitk.core.jobs/src/internal/mitkPluginActivator.cpp
+++ b/Plugins/org.mitk.core.jobs/src/internal/mitkPluginActivator.cpp
@@ -1,34 +1,36 @@
/*===================================================================
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 "mitkPluginActivator.h"
#include <QtPlugin>
namespace mitk {
void PluginActivator::start(ctkPluginContext* context)
{
Q_UNUSED(context)
}
void PluginActivator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_mitk_core_jobs, mitk::PluginActivator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_core_jobs, mitk::PluginActivator)
+#endif
diff --git a/Plugins/org.mitk.core.jobs/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.core.jobs/src/internal/mitkPluginActivator.h
index 12053e09e3..bdba95af92 100644
--- a/Plugins/org.mitk.core.jobs/src/internal/mitkPluginActivator.h
+++ b/Plugins/org.mitk.core.jobs/src/internal/mitkPluginActivator.h
@@ -1,39 +1,42 @@
/*===================================================================
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 MITKPLUGINACTIVATOR_H
#define MITKPLUGINACTIVATOR_H
#include <ctkPluginActivator.h>
#include <mitkExportMacros.h>
namespace mitk {
class MITK_LOCAL PluginActivator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_core_jobs")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
}; // PluginActivator
}
#endif // MITKPLUGINACTIVATOR_H
diff --git a/Plugins/org.mitk.core.services/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.core.services/src/internal/mitkPluginActivator.cpp
index a992be822f..84ac6db2e1 100644
--- a/Plugins/org.mitk.core.services/src/internal/mitkPluginActivator.cpp
+++ b/Plugins/org.mitk.core.services/src/internal/mitkPluginActivator.cpp
@@ -1,284 +1,286 @@
/*===================================================================
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 "mitkPluginActivator.h"
#include "mitkLog.h"
#include <QString>
#include <QFileInfo>
#include "internal/mitkDataStorageService.h"
#include <usModuleRegistry.h>
#include <usModule.h>
#include <usModuleContext.h>
#include <mitkVtkLoggingAdapter.h>
#include <mitkItkLoggingAdapter.h>
namespace mitk
{
class InterfaceMapToQObjectAdapter : public QObject
{
public:
InterfaceMapToQObjectAdapter(const us::InterfaceMap& im)
: interfaceMap(im)
{}
// This method is called by the Qt meta object system. It is usually
// generated by the moc, but we create it manually to be able to return
// a MITK micro service object (derived from itk::LightObject). It basically
// works as if the micro service class had used the Q_INTERFACES macro in
// its declaration. Now we can successfully do a
// qobject_cast<mitk::SomeMicroServiceInterface>(lightObjectToQObjectAdapter)
void* qt_metacast(const char *_clname)
{
if (!_clname) return 0;
if (!strcmp(_clname, "InterfaceMapToQObjectAdapter"))
return static_cast<void*>(const_cast<InterfaceMapToQObjectAdapter*>(this));
us::InterfaceMap::const_iterator iter = interfaceMap.find(_clname);
if (iter != interfaceMap.end())
return iter->second;
return QObject::qt_metacast(_clname);
}
private:
us::InterfaceMap interfaceMap;
};
const std::string org_mitk_core_services_Activator::PLUGIN_ID = "org.mitk.core.services";
void org_mitk_core_services_Activator::start(ctkPluginContext* context)
{
pluginContext = context;
//initialize logging
mitk::LoggingBackend::Register();
QString logFilenamePrefix = "mitk";
QFileInfo path = context->getDataFile(logFilenamePrefix);
try
{
mitk::LoggingBackend::RotateLogFiles(path.absoluteFilePath().toStdString());
}
catch(mitk::Exception& e)
{
MITK_ERROR << "Problem during logfile initialization: " << e.GetDescription() << " Caution: Logging to harddisc might be disabled!";
}
mitk::VtkLoggingAdapter::Initialize();
mitk::ItkLoggingAdapter::Initialize();
//initialize data storage service
DataStorageService* service = new DataStorageService();
dataStorageService = IDataStorageService::Pointer(service);
context->registerService<mitk::IDataStorageService>(service);
// Get the MitkCore Module Context
mitkContext = us::ModuleRegistry::GetModule(1)->GetModuleContext();
// Process all already registered services
std::vector<us::ServiceReferenceU> refs = mitkContext->GetServiceReferences("");
for (std::vector<us::ServiceReferenceU>::const_iterator i = refs.begin();
i != refs.end(); ++i)
{
this->AddMitkService(*i);
}
mitkContext->AddServiceListener(this, &org_mitk_core_services_Activator::MitkServiceChanged);
}
void org_mitk_core_services_Activator::stop(ctkPluginContext* /*context*/)
{
mitkContext->RemoveServiceListener(this, &org_mitk_core_services_Activator::MitkServiceChanged);
foreach(ctkServiceRegistration reg, mapMitkIdToRegistration.values())
{
reg.unregister();
}
mapMitkIdToRegistration.clear();
qDeleteAll(mapMitkIdToAdapter);
mapMitkIdToAdapter.clear();
//clean up logging
mitk::LoggingBackend::Unregister();
dataStorageService = 0;
mitkContext = 0;
pluginContext = 0;
}
void org_mitk_core_services_Activator::MitkServiceChanged(const us::ServiceEvent event)
{
switch (event.GetType())
{
case us::ServiceEvent::REGISTERED:
{
this->AddMitkService(event.GetServiceReference());
break;
}
case us::ServiceEvent::UNREGISTERING:
{
long mitkServiceId = us::any_cast<long>(event.GetServiceReference().GetProperty(us::ServiceConstants::SERVICE_ID()));
ctkServiceRegistration reg = mapMitkIdToRegistration.take(mitkServiceId);
if (reg)
{
reg.unregister();
}
delete mapMitkIdToAdapter.take(mitkServiceId);
break;
}
case us::ServiceEvent::MODIFIED:
{
long mitkServiceId = us::any_cast<long>(event.GetServiceReference().GetProperty(us::ServiceConstants::SERVICE_ID()));
ctkDictionary newProps = CreateServiceProperties(event.GetServiceReference());
mapMitkIdToRegistration[mitkServiceId].setProperties(newProps);
break;
}
default:
break; // do nothing
}
}
void org_mitk_core_services_Activator::AddMitkService(const us::ServiceReferenceU& ref)
{
// Get the MITK micro service object
us::InterfaceMap mitkService = mitkContext->GetService(ref);
if (mitkService.empty()) return;
// Get the interface names against which the service was registered
QStringList qclazzes;
for(us::InterfaceMap::const_iterator clazz = mitkService.begin();
clazz != mitkService.end(); ++clazz)
{
qclazzes << QString::fromStdString(clazz->first);
}
long mitkServiceId = us::any_cast<long>(ref.GetProperty(us::ServiceConstants::SERVICE_ID()));
QObject* adapter = new InterfaceMapToQObjectAdapter(mitkService);
mapMitkIdToAdapter[mitkServiceId] = adapter;
ctkDictionary props = CreateServiceProperties(ref);
mapMitkIdToRegistration[mitkServiceId] = pluginContext->registerService(qclazzes, adapter, props);
}
ctkDictionary org_mitk_core_services_Activator::CreateServiceProperties(const us::ServiceReferenceU& ref)
{
ctkDictionary props;
long mitkServiceId = us::any_cast<long>(ref.GetProperty(us::ServiceConstants::SERVICE_ID()));
props.insert("mitk.serviceid", QVariant::fromValue(mitkServiceId));
// Add all other properties from the MITK micro service
std::vector<std::string> keys;
ref.GetPropertyKeys(keys);
for (std::vector<std::string>::const_iterator it = keys.begin(); it != keys.end(); ++it)
{
QString key = QString::fromStdString(*it);
us::Any value = ref.GetProperty(*it);
// We cannot add any mitk::Any object, we need to query the type
const std::type_info& objType = value.Type();
if (objType == typeid(std::string))
{
props.insert(key, QString::fromStdString(us::ref_any_cast<std::string>(value)));
}
else if (objType == typeid(std::vector<std::string>))
{
const std::vector<std::string>& list = us::ref_any_cast<std::vector<std::string> >(value);
QStringList qlist;
for (std::vector<std::string>::const_iterator str = list.begin();
str != list.end(); ++str)
{
qlist << QString::fromStdString(*str);
}
props.insert(key, qlist);
}
else if (objType == typeid(std::list<std::string>))
{
const std::list<std::string>& list = us::ref_any_cast<std::list<std::string> >(value);
QStringList qlist;
for (std::list<std::string>::const_iterator str = list.begin();
str != list.end(); ++str)
{
qlist << QString::fromStdString(*str);
}
props.insert(key, qlist);
}
else if (objType == typeid(char))
{
props.insert(key, QChar(us::ref_any_cast<char>(value)));
}
else if (objType == typeid(unsigned char))
{
props.insert(key, QChar(us::ref_any_cast<unsigned char>(value)));
}
else if (objType == typeid(bool))
{
props.insert(key, us::any_cast<bool>(value));
}
else if (objType == typeid(short))
{
props.insert(key, us::any_cast<short>(value));
}
else if (objType == typeid(unsigned short))
{
props.insert(key, us::any_cast<unsigned short>(value));
}
else if (objType == typeid(int))
{
props.insert(key, us::any_cast<int>(value));
}
else if (objType == typeid(unsigned int))
{
props.insert(key, us::any_cast<unsigned int>(value));
}
else if (objType == typeid(float))
{
props.insert(key, us::any_cast<float>(value));
}
else if (objType == typeid(double))
{
props.insert(key, us::any_cast<double>(value));
}
else if (objType == typeid(long long int))
{
props.insert(key, us::any_cast<long long int>(value));
}
else if (objType == typeid(unsigned long long int))
{
props.insert(key, us::any_cast<unsigned long long int>(value));
}
}
return props;
}
org_mitk_core_services_Activator::org_mitk_core_services_Activator()
: mitkContext(0), pluginContext(0)
{
}
}
-Q_EXPORT_PLUGIN2(org_mitk_core_services, mitk::org_mitk_core_services_Activator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_core_services, mitk::org_mitk_core_services_Activator)
+#endif
diff --git a/Plugins/org.mitk.core.services/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.core.services/src/internal/mitkPluginActivator.h
index 770cd816f7..185be7b434 100644
--- a/Plugins/org.mitk.core.services/src/internal/mitkPluginActivator.h
+++ b/Plugins/org.mitk.core.services/src/internal/mitkPluginActivator.h
@@ -1,67 +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.
===================================================================*/
#ifndef MITKCORESERVICESPLUGIN_H_
#define MITKCORESERVICESPLUGIN_H_
#include <berryPlugin.h>
#include <berryIBundleContext.h>
#include "mitkIDataStorageService.h"
#include <usServiceEvent.h>
namespace us {
class ModuleContext;
}
namespace mitk
{
class org_mitk_core_services_Activator : public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_core_services")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
static const std::string PLUGIN_ID;
org_mitk_core_services_Activator();
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
void MitkServiceChanged(const us::ServiceEvent event);
private:
mitk::IDataStorageService::Pointer dataStorageService;
QMap<long, QObject*> mapMitkIdToAdapter;
QMap<long, ctkServiceRegistration> mapMitkIdToRegistration;
us::ModuleContext* mitkContext;
ctkPluginContext* pluginContext;
void AddMitkService(const us::ServiceReferenceU& ref);
ctkDictionary CreateServiceProperties(const us::ServiceReferenceU& ref);
};
typedef org_mitk_core_services_Activator PluginActivator;
}
#endif /*MITKCORESERVICESPLUGIN_H_*/
diff --git a/Plugins/org.mitk.diffusionimaging/src/internal/mitkDiffusionImagingActivator.cpp b/Plugins/org.mitk.diffusionimaging/src/internal/mitkDiffusionImagingActivator.cpp
index 8d979b58d5..40d92b2cdf 100644
--- a/Plugins/org.mitk.diffusionimaging/src/internal/mitkDiffusionImagingActivator.cpp
+++ b/Plugins/org.mitk.diffusionimaging/src/internal/mitkDiffusionImagingActivator.cpp
@@ -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.
===================================================================*/
#include "mitkDiffusionImagingActivator.h"
#include "QmitkNodeDescriptorManager.h"
#include "mitkNodePredicateDataType.h"
#include <QtPlugin>
void
mitk::DiffusionImagingActivator::start(ctkPluginContext* context)
{
Q_UNUSED(context)
QmitkNodeDescriptorManager* manager =
QmitkNodeDescriptorManager::GetInstance();
mitk::NodePredicateDataType::Pointer isDiffusionImage = mitk::NodePredicateDataType::New("DiffusionImage");
QmitkNodeDescriptor* desc = new QmitkNodeDescriptor(QObject::tr("DiffusionImage"), QString(":/QmitkDiffusionImaging/QBallData24.png"), isDiffusionImage, manager);
manager->AddDescriptor(desc);
mitk::NodePredicateDataType::Pointer isTensorImage = mitk::NodePredicateDataType::New("TensorImage");
manager->AddDescriptor(new QmitkNodeDescriptor(QObject::tr("TensorImage"), QString(":/QmitkDiffusionImaging/recontensor.png"), isTensorImage, manager));
mitk::NodePredicateDataType::Pointer isQBallImage = mitk::NodePredicateDataType::New("QBallImage");
manager->AddDescriptor(new QmitkNodeDescriptor(QObject::tr("QBallImage"), QString(":/QmitkDiffusionImaging/reconodf.png"), isQBallImage, manager));
mitk::NodePredicateDataType::Pointer isFiberBundle = mitk::NodePredicateDataType::New("FiberBundle");
manager->AddDescriptor(new QmitkNodeDescriptor(QObject::tr("FiberBundle"), QString(":/QmitkDiffusionImaging/FiberBundle.png"), isFiberBundle, manager));
mitk::NodePredicateDataType::Pointer isFiberBundleX = mitk::NodePredicateDataType::New("FiberBundleX");
manager->AddDescriptor(new QmitkNodeDescriptor(QObject::tr("FiberBundleX"), QString(":/QmitkDiffusionImaging/FiberBundleX.png"), isFiberBundleX, manager));
mitk::NodePredicateDataType::Pointer isConnectomicsNetwork = mitk::NodePredicateDataType::New("ConnectomicsNetwork");
manager->AddDescriptor(new QmitkNodeDescriptor(QObject::tr("ConnectomicsNetwork"), QString(":/QmitkDiffusionImaging/ConnectomicsNetwork.png"), isConnectomicsNetwork, manager));
}
void
mitk::DiffusionImagingActivator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
-Q_EXPORT_PLUGIN2(org_mitk_diffusionimaging, mitk::DiffusionImagingActivator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_diffusionimaging, mitk::DiffusionImagingActivator)
+#endif
diff --git a/Plugins/org.mitk.diffusionimaging/src/internal/mitkDiffusionImagingActivator.h b/Plugins/org.mitk.diffusionimaging/src/internal/mitkDiffusionImagingActivator.h
index 40dfce9ee3..b17942daf0 100644
--- a/Plugins/org.mitk.diffusionimaging/src/internal/mitkDiffusionImagingActivator.h
+++ b/Plugins/org.mitk.diffusionimaging/src/internal/mitkDiffusionImagingActivator.h
@@ -1,54 +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 MITKDIFFUSIONIMAGINGACTIVATOR_H_
#define MITKDIFFUSIONIMAGINGACTIVATOR_H_
#include <ctkPluginActivator.h>
#include <mitkExportMacros.h>
namespace mitk
{
/**
* \ingroup org_mitk_diffusionimaging_internal
*
* \brief The plug-in activator for the diffusion imaging module
*
* When the plug-in is started by the framework, it initialzes diffusion imaging
* specific things.
*/
class MITK_LOCAL DiffusionImagingActivator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_diffusionimaging")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
/**
* Registers diffusion imaging object factories.
*/
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
};
}
#endif /* MITKDIFFUSIONIMAGINGACTIVATOR_H_ */
diff --git a/Plugins/org.mitk.gui.common/src/internal/org_mitk_gui_common_Activator.cpp b/Plugins/org.mitk.gui.common/src/internal/org_mitk_gui_common_Activator.cpp
index 20d00cc540..f2d00c4087 100644
--- a/Plugins/org.mitk.gui.common/src/internal/org_mitk_gui_common_Activator.cpp
+++ b/Plugins/org.mitk.gui.common/src/internal/org_mitk_gui_common_Activator.cpp
@@ -1,46 +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.
===================================================================*/
#include "org_mitk_gui_common_Activator.h"
#include <QtPlugin>
namespace mitk {
ctkPluginContext* org_mitk_gui_common_Activator::m_Context = 0;
void org_mitk_gui_common_Activator::start(ctkPluginContext* context)
{
m_Context = context;
}
void org_mitk_gui_common_Activator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
m_Context = 0;
}
ctkPluginContext *org_mitk_gui_common_Activator::GetContext()
{
return m_Context;
}
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_common, mitk::org_mitk_gui_common_Activator)
-
-
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_common, mitk::org_mitk_gui_common_Activator)
+#endif
diff --git a/Plugins/org.mitk.gui.common/src/internal/org_mitk_gui_common_Activator.h b/Plugins/org.mitk.gui.common/src/internal/org_mitk_gui_common_Activator.h
index 70f690c427..43ce20e790 100644
--- a/Plugins/org.mitk.gui.common/src/internal/org_mitk_gui_common_Activator.h
+++ b/Plugins/org.mitk.gui.common/src/internal/org_mitk_gui_common_Activator.h
@@ -1,48 +1,51 @@
/*===================================================================
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 MITKPLUGINACTIVATOR_H
#define MITKPLUGINACTIVATOR_H
#include <ctkPluginActivator.h>
namespace mitk {
class org_mitk_gui_common_Activator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_common")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
static ctkPluginContext* GetContext();
private:
static ctkPluginContext* m_Context;
}; // org_mitk_gui_common_Activator
typedef org_mitk_gui_common_Activator PluginActivator;
}
#endif // MITKPLUGINACTIVATOR_H
diff --git a/Plugins/org.mitk.gui.qt.aicpregistration/CMakeLists.txt b/Plugins/org.mitk.gui.qt.aicpregistration/CMakeLists.txt
new file mode 100644
index 0000000000..1b9dc085f1
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.aicpregistration/CMakeLists.txt
@@ -0,0 +1,7 @@
+project(org_mitk_gui_qt_aicpregistration)
+
+MACRO_CREATE_MITK_CTK_PLUGIN(
+ EXPORT_DIRECTIVE AICPREGISTRATION_EXPORT
+ EXPORTED_INCLUDE_SUFFIXES src
+ MODULE_DEPENDS MitkQtWidgetsExt MitkAlgorithmsExt
+)
diff --git a/Plugins/org.mitk.gui.qt.aicpregistration/documentation/UserManual/Manual.dox b/Plugins/org.mitk.gui.qt.aicpregistration/documentation/UserManual/Manual.dox
new file mode 100644
index 0000000000..4da7b4f2b5
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.aicpregistration/documentation/UserManual/Manual.dox
@@ -0,0 +1,80 @@
+/**
+\page org_mitk_gui_qt_aicpregistration The Anisotropic Iterative Closest Point Registration Plugin
+
+\imageMacro{"QmitkAICPRegistration_Icon.xpm","Icon of the A-ICP Registration Plugin",2}
+
+\tableofcontents
+
+\section org_mitk_gui_qt_aicpregistrationOverview Overview
+
+The Surfaceregistration plugin allows the user to compute a transformation
+between two surfaces and align them in 3D space. It performs the
+registration with the anisotropic iterative closest point algorithm (A-ICP)
+presented in L. Maier-Hein et al. "Convergent Iterative Closest-Point Algorithm to Accomodate
+Anisotropic and Inhomogenous Localization Error.", IEEE T Pattern Anal 34 (8),
+1520-1532, 2012. With the plugin it's also possible to compute
+the target registration error (TRE) between the two aligned surfaces with a given
+set of target points. In order to register the surfaces they need to be initially
+aligned to be able to run the fine registration with the A-ICP algorithm.
+
+\imageMacro{"QmitkAICPRegistration_Plugin.png","Overview of the A-ICP Registration Plugin.",28}
+
+\section org_mitk_gui_qt_aicpregistrationUsage Usage
+
+In order to run a registration at least two surfaces need to be loaded into
+the data manager. Once the surfaces are loaded, a moving and a
+fixed surface can be selected in the associated combo boxes of the plugin.
+When the <b>Register Surfaces</b> button is pressed the registration is started
+and the moving surface is transformed onto the fixed surface.
+
+\imageMacro{"QmitkAICPRegistration_Input.png","Select the surfaces to register.",28}
+
+\section org_mitk_gui_qt_aicpregistrationTargetRegistrationErrorCalculation Target Registration Error Calculation
+
+To compute the target registration error, enable the calculation via the checkbox
+in the target registration view. Once the TRE computation is enabled the
+combo boxes are activated to select the according target point sets.
+
+\imageMacro{"QmitkAICPRegistration_TRECalculation.png","Usage of the TRE calculation view.",28}
+
+\section org_mitk_gui_qt_aicpregistrationRegistrationSettings Registration Settings
+
+The following additional settings are available in the plugin to configure the algorithm:
+<ul>
+ <li>A trimmed version of the algorithm.
+ <li>Set the threshold for the algorithm to converge.
+ <li>Limit the iterations.
+ <li>Set the search radius.
+</ul>
+
+\imageMacro{"QmitkAICPRegistration_Settings.png","Additional registration settings.",28}
+
+\subsection org_mitk_gui_qt_aicpregistrationTrimmedRegistration Trimmed Registration
+
+This option enables a trimmed version of the algorithm to register partial overlapping
+surfaces. Once the option is enabled the user can specify the overlapping part of the surface.
+Valid values for the overlapping part lie between 0 an 1.
+The trimmed version of the algorithm uses only a fixed percentage of all correspondences found
+during one iteration. Only the best correspondences will be used during the registration process.
+
+\subsection org_mitk_gui_qt_aicpregistrationThreshold Threshold
+
+The user can specify the threshold which is used as a termination constraint for the algorithm.
+When the the change of the fiducial registration error (FRE)
+between to registrations falls under the specified threshold the algorithm terminates.
+Larger values can speedup the registration process at the cost of a more accurate result.
+
+\subsection org_mitk_gui_qt_aicpregistrationMaximumIterations Maximum Iterations
+
+The maximum amount of iterations used by the algorithm can be specified by the user.
+Once the algorithm reaches the maximum amount of iterations it will stop the registration process.
+
+\subsection org_mitk_gui_qt_aicpregistrationSearchRadius Search Radius
+
+The user can specify the search radius in mm used during the correspondence search
+in a kd tree. The default value is 30 mm. A small radius can speedup the
+algorithm but can in addition also lead in bad correspondences and therefore in an incorrect
+alignment of the surfaces.
+
+*/
+
diff --git a/Plugins/org.mitk.gui.qt.aicpregistration/documentation/UserManual/QmitkAICPRegistration_Icon.xpm b/Plugins/org.mitk.gui.qt.aicpregistration/documentation/UserManual/QmitkAICPRegistration_Icon.xpm
new file mode 100644
index 0000000000..c157c2b5b9
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.aicpregistration/documentation/UserManual/QmitkAICPRegistration_Icon.xpm
@@ -0,0 +1,364 @@
+/* XPM */
+static char * icon_xpm[] = {
+"100 100 261 2",
+" c None",
+". c #FFFFFF",
+"+ c #F3F3F3",
+"@ c #E6E6E6",
+"# c #F6F6F6",
+"$ c #8B8B8B",
+"% c #000000",
+"& c #A1A1A1",
+"* c #F6F7F5",
+"= c #949F7C",
+"- c #4F6228",
+"; c #D4D9CB",
+"> c #5A6C35",
+", c #515151",
+"' c #DEE1D7",
+") c #131313",
+"! c #FBFBFA",
+"~ c #ECEEE8",
+"{ c #9DA787",
+"] c #829067",
+"^ c #FEFEFE",
+"/ c #51632A",
+"( c #FCFDFC",
+"_ c #9FA98A",
+": c #7A895C",
+"< c #ABB498",
+"[ c #FCFCFB",
+"} c #B7BFA7",
+"| c #A1AB8C",
+"1 c #B0B89E",
+"2 c #D0D5C5",
+"3 c #FDFDFC",
+"4 c #627340",
+"5 c #BDC4AE",
+"6 c #F3F5F1",
+"7 c #FAFAF9",
+"8 c #7B895E",
+"9 c #060703",
+"0 c #0D1006",
+"a c #738254",
+"b c #8F9B76",
+"c c #738255",
+"d c #F6F7F4",
+"e c #79875B",
+"f c #FDFDFD",
+"g c #D5D5D5",
+"h c #B0B89F",
+"i c #758356",
+"j c #62733F",
+"k c #191F0C",
+"l c #7C8A5F",
+"m c #576932",
+"n c #5A6C36",
+"o c #78875B",
+"p c #839168",
+"q c #ACB59A",
+"r c #B4BCA3",
+"s c #919D79",
+"t c #758457",
+"u c #425121",
+"v c #2B3515",
+"w c #54672F",
+"x c #829066",
+"y c #79875C",
+"z c #6A7A49",
+"A c #60713D",
+"B c #7E8C62",
+"C c #596B34",
+"D c #FAFBFA",
+"E c #506329",
+"F c #939F7C",
+"G c #2A2A2A",
+"H c #F4F5F2",
+"I c #F5F6F4",
+"J c #6D7D4E",
+"K c #C4CAB6",
+"L c #F9FAF8",
+"M c #51642A",
+"N c #4F6229",
+"O c #A9B296",
+"P c #7E8D62",
+"Q c #A4AE90",
+"R c #D4D9CA",
+"S c #D5D9CC",
+"T c #AFB89D",
+"U c #8D9A75",
+"V c #839067",
+"W c #718052",
+"X c #AAB397",
+"Y c #6B6B6B",
+"Z c #5A5A5A",
+"` c #5082BD",
+" . c #7AA0CD",
+".. c #D6E2EF",
+"+. c #CFDDED",
+"@. c #4A7EBB",
+"#. c #759CCB",
+"$. c #D5E1EF",
+"%. c #CEDCEC",
+"&. c #FDFEFE",
+"*. c #BDD0E6",
+"=. c #C4D5E9",
+"-. c #FCFDFE",
+";. c #D1DEEE",
+">. c #F9FAFC",
+",. c #DAE4F1",
+"'. c #EFF4F9",
+"). c #EFF3F8",
+"!. c #E9EFF6",
+"~. c #CCDBEC",
+"{. c #E2EAF3",
+"]. c #D8E3F0",
+"^. c #F9FBFC",
+"/. c #E5EDF5",
+"(. c #4E81BC",
+"_. c #AAC2DF",
+":. c #5586BF",
+"<. c #7CA2CE",
+"[. c #6F98C8",
+"}. c #ADC5E0",
+"|. c #5183BD",
+"1. c #80A4CF",
+"2. c #6591C5",
+"3. c #F0F4F9",
+"4. c #4B7FBB",
+"5. c #B9CDE5",
+"6. c #7BA1CD",
+"7. c #BFD1E7",
+"8. c #F5F8FB",
+"9. c #608EC3",
+"0. c #B3C8E2",
+"a. c #F2F6FA",
+"b. c #4B7EBB",
+"c. c #BCCFE6",
+"d. c #92B1D6",
+"e. c #5F8DC3",
+"f. c #F8FAFC",
+"g. c #5384BE",
+"h. c #7FA4CF",
+"i. c #EBF1F7",
+"j. c #D2DFEE",
+"k. c #FAFBFD",
+"l. c #DFE8F3",
+"m. c #E3EBF4",
+"n. c #789FCC",
+"o. c #5485BE",
+"p. c #81A5CF",
+"q. c #5686BF",
+"r. c #9BB8D9",
+"s. c #95B4D7",
+"t. c #9CB8D9",
+"u. c #5E8CC2",
+"v. c #5284BE",
+"w. c #8DAED4",
+"x. c #7CA1CD",
+"y. c #F1F5F9",
+"z. c #E7EEF6",
+"A. c #E5ECF4",
+"B. c #CDDBEC",
+"C. c #FDFDFE",
+"D. c #4C7FBB",
+"E. c #7DA2CE",
+"F. c #F3F6FA",
+"G. c #FBFCFD",
+"H. c #B1C7E1",
+"I. c #7099C9",
+"J. c #85A8D1",
+"K. c #5283BE",
+"L. c #ACC4DF",
+"M. c #E1EAF4",
+"N. c #4C80BC",
+"O. c #D4E1EF",
+"P. c #B4C9E2",
+"Q. c #9CB8DA",
+"R. c #DDE6F2",
+"S. c #96B4D7",
+"T. c #4F81BC",
+"U. c #618EC3",
+"V. c #6390C4",
+"W. c #89ABD2",
+"X. c #D7E2F0",
+"Y. c #5C8AC1",
+"Z. c #B0C6E1",
+"`. c #8CADD3",
+" + c #CAD9EB",
+".+ c #86A8D1",
+"++ c #5283BD",
+"@+ c #4D80BC",
+"#+ c #6D96C8",
+"$+ c #B8CCE4",
+"%+ c #FAFCFD",
+"&+ c #D9E4F0",
+"*+ c #C2D3E8",
+"=+ c #CFDCEC",
+"-+ c #F8F3F3",
+";+ c #EEE0E0",
+">+ c #B06A68",
+",+ c #953735",
+"'+ c #AC6361",
+")+ c #903533",
+"!+ c #792C2B",
+"~+ c #F7F7F7",
+"{+ c #7C2E2C",
+"]+ c #B67674",
+"^+ c #FEFDFD",
+"/+ c #FDFBFB",
+"(+ c #963A38",
+"_+ c #EDDDDC",
+":+ c #A65856",
+"<+ c #0B0404",
+"[+ c #DFC3C2",
+"}+ c #D0A6A5",
+"|+ c #F1E6E6",
+"1+ c #963937",
+"2+ c #FAF7F7",
+"3+ c #B67675",
+"4+ c #E9D7D6",
+"5+ c #993F3D",
+"6+ c #AC6362",
+"7+ c #9C6B69",
+"8+ c #ECDCDC",
+"9+ c #953836",
+"0+ c #B4716F",
+"a+ c #E1C7C6",
+"b+ c #BF8786",
+"c+ c #FDFCFC",
+"d+ c #463D3D",
+"e+ c #983D3B",
+"f+ c #2F1110",
+"g+ c #E6D0D0",
+"h+ c #0D0707",
+"i+ c #B06A69",
+"j+ c #9E4947",
+"k+ c #FCFAFA",
+"l+ c #FBF9F9",
+"m+ c #C18A89",
+"n+ c #C4908F",
+"o+ c #FBF8F8",
+"p+ c #99403E",
+"q+ c #C69594",
+"r+ c #BA7D7C",
+"s+ c #E8D3D3",
+"t+ c #BD8382",
+"u+ c #973B39",
+"v+ c #FAF6F6",
+"w+ c #E0C4C4",
+"x+ c #AD6462",
+"y+ c #F7F0F0",
+"z+ c #3C2B2A",
+"A+ c #020202",
+"B+ c #010101",
+"C+ c #2C2C2C",
+"D+ c #CEA3A2",
+"E+ c #F2E7E7",
+"F+ c #E3CBCA",
+"G+ c #D2ABAA",
+"H+ c #F5EEED",
+"I+ c #9F4948",
+"J+ c #AF6867",
+"K+ c #EAD7D7",
+"L+ c #9E4847",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + @ @ @ @ @ @ @ @ @ @ @ # . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . $ % % % % % % % % % % % & . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . $ % % % % % % % % % % % & . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % % % . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % % % . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % % % . . . . . . . * . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % % % . . . . . . = - . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % % % . . . . ; - - - . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % % % . . . > - - - - . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % % % % % % % % % % % , . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % % % . ' - - - - - - . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % % % % % % % % % % % , . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % % % - - - - - - - - . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) % % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ! ~ { - % % % - - - - - - - - . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) % % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ] - - - - - % % % - - - - - - - - . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) % % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ^ - - - - - - - % % % - - - - - - - - . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) % % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - - - - - - - - % % % - - - - - - - - . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) % % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ~ - - - - - - - - % % % - - - - - - - / . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . ( _ : < [ ^ . . . . . . . . ) % % } : | 1 2 ! [ 3 ^ . . . . . . . . . . . . ^ 4 - - - - - - - - - - - - - - - - % % % - - - - - - 5 . . . . . . . . . . ",
+". . . . . . . . . . . . . % % % % % % % % % % % % - - - - - - 6 . . . 7 8 - 9 % % - - - - - - - - - - 1 . . . % % % % % % % % % % % 0 - - - - - - - - - - - - - % % % - - - a . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . % % % % % % % % % % % % - - - - - - - b . c - - - 9 % % - - - - - - - - - - - - d . % % % % % % % % % % % 0 - - - - - - - - - - - - - % % % e f . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . g % % h - - - - - - - - - - - - - - - - - 9 % % - - - - - - - - - - - - - a i j - - k % % - - - - - - - - - - - - - - - - - - % % % . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . g % % - - - - - - - - - - - - - - - - - - 9 % % - - - - - - - - - - - - - - - - - - k % % - - - - - - - - - - - - - - - - - - % % % . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . l m m n o p q r g % % - - - - - - - - - - - - - - - - - - 9 % % - - - - - - - - - - - - - - - - - - k % % - - - - - - - - - - - - - - - - - s % % % . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . t - - - - - - - u % % - - - - - - - - - - - - - - - - - - 9 % % - - - - - - - - - - - - - - - - - - k % % - - - - - - - - - - - - - v % % % % % % % % % % % & . . . . . . . . . . . . ",
+". . . . . . . . . t - - - - - - - u % % - - - - - - - - - - - - - - - - - - 9 % % - - - - - - - - - - - - - - - - - - k % % - - - - - - - - - - - - - v % % % % % % % % % % % & . . . . . . . . . . . . ",
+". . . . . . . . . t - - - - - - - u % % - - - - - - - - - - - - - - - - - - 9 % % w x y z A - - - - - - - - - - - - - k % % - - - B . . . . . . . . . $ % % % % % % % % % % % & . . . . . . . . . . . . ",
+". . . . . . . . . t - - - - - - - u % % - - - - - - C D E - - - - - - - - - 9 % % . . . . . . . F - - - - - - % % % % % % % % % % % G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . t - - - - - - - u % % - - - - - H . . . I J - - - - - - K ) % % . . . . . . . . L M - - - - % % % % % % % % % % % G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . t - - - - - - - u % % - - - N . . . . . . . . . . . . . . ) % % . . . . . . . . . . . O P Q O R . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . t - - - - - - - u % % - - i . . . . . . . . . . . % % % % % % % % % % % , . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . S T T = U V W - u % % X . . . . . . . . . . . . . % % % % % % % % % % % , . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . Y Y Y Y Z % % Y Y Y Y Y . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . % % % % % % % % % % % % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . % % % % % % % % % % % % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . ` ` ` ` . . . . . . . . . . . . . . . . . ` ` ` .. . . . . . . . . . . . . . . . . ` ` ` ... . . . . . . . . . . . . . . . . ` ` ` +.. . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . @.@.@.@.. . . . . . . . . . . . . . . . . @.@.@.#.. . . . . . . . . . . . . . . . . @.@.@.$.. . . . . . . . . . . . . . . . . @.@.@.%.. . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . @.@.@.@.. . . . . . . . . . . . . . . . . @.@.@.#.. . . . . . . . . . . . . . . . . @.@.@.$.. . . . . . . . . . . . . . . . . @.@.@.%.. . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . @.@.@.@.. . . . . . . . . . . . . . . . . @.@.@.#.. . . . . . . . . . . . . . . . . @.@.@.$.. . . . . . . . . . . . . . . . . @.@.@.%.. . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . @.@.@.@.. . . . . . . . . . . . . . . . . @.@.@.#.. . . . . . . . . . . . . . . . . @.@.@.$.. . . . . . . . . . . . . . . . . @.@.@.%.. . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . @.@.@.@.. . . . . . . . . . . . . . . . . @.@.@.#.. . . . . . . . . . . . . . . . . @.@.@.$.. . . . . . . . . . . . . . . . . @.@.@.%.. . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . @.@.@.@.. . . . . . . . . . . . . . . . . @.@.@.#.. . . . . . . . . . . . . . . . . @.@.@.$.. . . . . . . . . . . . . . . . . @.@.@.%.. . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . @.@.@.@.. . . . . . . . . . . . . . . . . @.@.@.#.. . . . . . . . . . . . . . . . . @.@.@.$.. . . . . . . . . . . . . . . . . @.@.@.%.. . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . @.@.@.@.. . . . . . . . . . . . . . . . . @.@.@.#.. . . . . . . . . . . . . . . . . @.@.@.$.. . . . . . . . . . . . . . . . . @.@.@.%.. . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . &.*.^ . . . @.@.@.@.. . . . =.. . . . . . -.;.. . . . @.@.@.#.. . . >.,.. . . . . . '.$.. . . . @.@.@.$.. . . '.).. . . . . . !.~.. . . . @.@.@.%.. . . {.].. . . . . . . . . . . ",
+". . . . . . . . . . . @.@.@.^.. . @.@.@.@.. . . @.@.@.. . . . /.@.@.@.. . . @.@.@.#.. . *.@.@.(.. . . . _.@.@.:.. . . @.@.@.$.. . <.@.@.[.. . . . }.@.@.|.. . . @.@.@.%.. . 1.@.@.2.. . . . . . . . . . ",
+". . . . . . . . . . 3.@.@.@.4.. . @.@.@.@.. . @.@.@.@.. . . . 5.@.@.@.6.. . @.@.@.#.. . @.@.@.@.. . . . @.@.@.@.7.. . @.@.@.$.. 8.@.@.@.@.. . . . 9.@.@.@.0.. . @.@.@.%.. a.@.@.@.@.. . . . . . . . . . ",
+". . . . . . . . . . . b.@.@.@.c.. @.@.@.@.. d.@.@.@.e.. . . . . @.@.@.@.f.. @.@.@.#.. g.@.@.@.h.. . . . ^.@.@.@.@.. . @.@.@.$.. @.@.@.@.i.. . . . . @.@.@.@.^ . @.@.@.%.. @.@.@.@.j.. . . . . . . . . . ",
+". . . . . . . . . . . k.@.@.@.@.. @.@.@.@.f.@.@.@.@.. . . . . . l.@.@.@.@.. @.@.@.#.m.@.@.@.4.. . . . . . n.@.@.@.o.. @.@.@.$.p.@.@.@.q.. . . . . . r.@.@.@.@.. @.@.@.%.s.@.@.@.|.. . . . . . . . . . . ",
+". . . . . . . . . . . . t.@.@.@.u.@.@.@.@.@.@.@.@.*.. . . . . . . v.@.@.@.w.@.@.@.x.@.@.@.@.y.. . . . . . . @.@.@.@.z.@.@.@.A.@.@.@.@.. . . . . . . . b.@.@.@.B.@.@.@.%.@.@.@.@.C.. . . . . . . . . . . ",
+". . . . . . . . . . . . . @.@.@.@.@.@.@.@.@.@.@.D.. . . . . . . . . @.@.@.@.@.@.@.@.@.@.@.E.. . . . . . . . i.@.@.@.@.@.@.@.@.@.@.@.=.. . . . . . . . F.@.@.@.@.@.@.@.@.@.@.@.=.. . . . . . . . . . . . ",
+". . . . . . . . . . . . . G.@.@.@.@.@.@.@.@.@.@.G.. . . . . . . . . H.@.@.@.@.@.@.@.@.@.@.. . . . . . . . . . I.@.@.@.@.@.@.@.@.@.q.. . . . . . . . . . J.@.@.@.@.@.@.@.@.@.K.. . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . I.@.@.@.@.@.@.@.@.L.. . . . . . . . . . . @.@.@.@.@.@.@.@.@.M.. . . . . . . . . . . @.@.@.@.@.@.@.@.@.^ . . . . . . . . . . . @.@.@.@.@.@.@.@.@.^ . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . @.@.@.@.@.@.@.N.. . . . . . . . . . . . -.@.@.@.@.@.@.@.o.. . . . . . . . . . . . O.@.@.@.@.@.@.@.P.. . . . . . . . . . . . f.@.@.@.@.@.@.@.Q.. . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . R.@.@.@.@.@.@.. . . . . . . . . . . . . . S.@.@.@.@.@.@.. . . . . . . . . . . . . . T.@.@.@.@.@.@.. . . . . . . . . . . . . . U.@.@.@.@.@.b.. . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . V.@.@.@.@.W.. . . . . . . . . . . . . . . @.@.@.@.@.X.. . . . . . . . . . . . . . C.@.@.@.@.@.^.. . . . . . . . . . . . . . . @.@.@.@.@.a.. . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . ^ @.@.@.@.. . . . . . . . . . . . . . . . a.@.@.@.Y.. . . . . . . . . . . . . . . . Z.@.@.@.`.. . . . . . . . . . . . . . . . +@.@.@..+. . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . $.@.@.).. . . . . . . . . . . . . . . . . V.@.@.. . . . . . . . . . . . . . . . . . (.@.@.. . . . . . . . . . . . . . . . . . ++@.@.. . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . @+#+. . . . . . . . . . . . . . . . . . . @.$+. . . . . . . . . . . . . . . . . . . @.%+. . . . . . . . . . . . . . . . . . . @.. . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . &+. . . . . . . . . . . . . . . . . . . . *+. . . . . . . . . . . . . . . . . . . . =+. . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . -+;+% % % % % % % % % % % % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . >+,+,+,+% % % % % % % % % % % % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . '+,+,+,+)+)+)+)+!+% % ~+~+~+~+~+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . '+,+,+,+,+,+,+,+{+% % ,+]+^+. . . . . . . /+(+,+,+% % % % % % % % % % % , . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . '+,+,+,+,+,+,+,+{+% % ,+,+,+,+_+. ;+:+,+,+,+,+,+,+% % % % % % % % % % % , . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . '+,+,+,+,+,+,+,+{+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+<+% % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . '+,+,+,+,+,+,+,+{+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+<+% % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . '+,+,+,+,+,+,+,+{+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+<+% % . . [+}+|+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . '+,+,+1+,+,+,+,+{+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+<+% % ,+,+,+,+,+,+,+,+,+;+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . 2+3+. . . 4+5+,+{+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+<+% % ,+,+,+,+,+,+,+,+,+,+,+6+3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . 7+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+<+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+1+8+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . g % % 9+,+,+,+,+,+,+,+,+,+,+,+0+9+,+,+,+,+<+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+% % % % % % % % % % % G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . g % % . a+,+,+,+,+,+,+b+c+. . . ^+,+,+,+,+<+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+% % % % % % % % % % % G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . g % % . . . . . . . . . . . . . . ^+,+,+,+<+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+d+% % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . % % % % % % % % % % % % . . . . . . . . . . . e+,+<+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+f+% % . . . . . . . . . . . . . $ % % % % % % % % % % % & . . . . . . . . . . . . ",
+". . . . . . . . . . . . . % % % % % % % % % % % % . . . . . . . . . . . . g+h+% % ,+,+,+i+j+,+,+,+,+,+,+,+,+,+,+,+,+,+f+% % . . . . . . . k+l+. . . . $ % % % % % % % % % % % & . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) % % . . . . . . . m+,+,+,+,+,+,+,+,+,+,+f+% % ,+,+,+,+,+,+,+,+,+,+,+n+^+. . . . o+% % % ,+,+,+p+q+r+r+r+. . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) % % . . . . . . . . . s+,+,+,+,+,+,+,+,+f+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+t+. 8+,+% % % ,+,+,+,+,+,+,+,+. . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) % % . . . . . . . . . . . u+,+,+,+,+,+,+f+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+% % % ,+,+,+,+,+,+,+,+. . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) % % . . . . . . . . . . . . ,+,+,+,+,+,+f+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+% % % ,+,+,+,+,+,+,+,+. . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) % % . . . . . . . . . . . . v+,+,+,+,+,+f+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+% % % ,+,+,+,+,+,+,+,+. . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) % % . . . . . . . . . . . . . w+,+,+,+,+f+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+% % % ,+,+,+,+,+,+,+,+. . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) % % . . . . . . . . . . . . . . c+x+,+,+f+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+% % % ,+,+,+,+,+,+,+,+. . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) % % . . . . . . . . . . . . . . . . . y+z+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+% % % ,+,+,+,+,+,+,+,+. . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) % % . . . . . . . . . . . . . . A+A+A+A+% % % B+B+A+A+C+. . . . k+,+,+,+,+,+,+,+,+% % % ,+D+^+E+F+F+f G+. . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) % % . . . . . . . . . . . . . . % % % % % % % % % % % G . . . . . . . H+I+,+,+,+,+% % % J+. . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) % % . . . . . . . . . . . . . . % % % % % % % % % % % G . . . . . . . . . . K+6+L+% % % . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % % % % % % % % % % % , . . . . . . . . . . . . . . . . . . . . . . . . . . . . . $ % % % % % % % % % % % & . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % % % % % % % % % % % , . . . . . . . . . . . . . . . . . . . . . . . . . . . . . $ % % % % % % % % % % % & . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % % % % % % % % % % % , . . . . . . . . . . . . . . . . . . . . . . . . . . . . . $ % % % % % % % % % % % & . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "};
diff --git a/Plugins/org.mitk.gui.qt.aicpregistration/documentation/UserManual/QmitkAICPRegistration_Input.png b/Plugins/org.mitk.gui.qt.aicpregistration/documentation/UserManual/QmitkAICPRegistration_Input.png
new file mode 100644
index 0000000000..9e5379340d
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.aicpregistration/documentation/UserManual/QmitkAICPRegistration_Input.png differ
diff --git a/Plugins/org.mitk.gui.qt.aicpregistration/documentation/UserManual/QmitkAICPRegistration_Plugin.png b/Plugins/org.mitk.gui.qt.aicpregistration/documentation/UserManual/QmitkAICPRegistration_Plugin.png
new file mode 100644
index 0000000000..0694385996
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.aicpregistration/documentation/UserManual/QmitkAICPRegistration_Plugin.png differ
diff --git a/Plugins/org.mitk.gui.qt.aicpregistration/documentation/UserManual/QmitkAICPRegistration_Settings.png b/Plugins/org.mitk.gui.qt.aicpregistration/documentation/UserManual/QmitkAICPRegistration_Settings.png
new file mode 100644
index 0000000000..5f58622ba7
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.aicpregistration/documentation/UserManual/QmitkAICPRegistration_Settings.png differ
diff --git a/Plugins/org.mitk.gui.qt.aicpregistration/documentation/UserManual/QmitkAICPRegistration_TRECalculation.png b/Plugins/org.mitk.gui.qt.aicpregistration/documentation/UserManual/QmitkAICPRegistration_TRECalculation.png
new file mode 100644
index 0000000000..bf633dfc79
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.aicpregistration/documentation/UserManual/QmitkAICPRegistration_TRECalculation.png differ
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/documentation/doxygen/modules.dox b/Plugins/org.mitk.gui.qt.aicpregistration/documentation/doxygen/modules.dox
similarity index 53%
rename from Plugins/org.mitk.gui.qt.moviemaker/documentation/doxygen/modules.dox
rename to Plugins/org.mitk.gui.qt.aicpregistration/documentation/doxygen/modules.dox
index 07f1421b2a..4759a2a0ea 100644
--- a/Plugins/org.mitk.gui.qt.moviemaker/documentation/doxygen/modules.dox
+++ b/Plugins/org.mitk.gui.qt.aicpregistration/documentation/doxygen/modules.dox
@@ -1,16 +1,16 @@
/**
- \defgroup org_mitk_gui_qt_moviemaker org.mitk.gui.qt.moviemaker
+ \defgroup org_mitk_gui_qt_aicperegistration org.mitk.gui.qt.surfaceregistration
\ingroup MITKPlugins
\brief Describe your plugin here.
-
+
*/
/**
- \defgroup org_mitk_gui_qt_moviemaker_internal Internal
- \ingroup org_mitk_gui_qt_moviemaker
+ \defgroup org_mitk_gui_qt_aicpregistration_internal Internal
+ \ingroup org_mitk_gui_qt_aicpregistration
- \brief This subcategory includes the internal classes of the org.mitk.gui.qt.moviemaker plugin. Other
+ \brief This subcategory includes the internal classes of the org.mitk.gui.qt.aicpregistration plugin. Other
plugins must not rely on these classes. They contain implementation details and their interface
may change at any time. We mean it.
*/
diff --git a/Plugins/org.mitk.gui.qt.aicpregistration/files.cmake b/Plugins/org.mitk.gui.qt.aicpregistration/files.cmake
new file mode 100644
index 0000000000..759cd2017c
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.aicpregistration/files.cmake
@@ -0,0 +1,42 @@
+set(SRC_CPP_FILES
+
+)
+
+set(INTERNAL_CPP_FILES
+ org_mitk_gui_qt_aicpregistration_Activator.cpp
+ QmitkAICPRegistrationView.cpp
+)
+
+set(UI_FILES
+ src/internal/QmitkAICPRegistrationViewControls.ui
+)
+
+set(MOC_H_FILES
+ src/internal/org_mitk_gui_qt_aicpregistration_Activator.h
+ src/internal/QmitkAICPRegistrationView.h
+)
+
+# list of resource files which can be used by the plug-in
+# system without loading the plug-ins shared library,
+# for example the icon used in the menu and tabs for the
+# plug-in views in the workbench
+set(CACHED_RESOURCE_FILES
+ resources/QmitkAICPRegistration_Icon.xpm
+ plugin.xml
+)
+
+# list of Qt .qrc files which contain additional resources
+# specific to this plugin
+set(QRC_FILES
+
+)
+
+set(CPP_FILES )
+
+foreach(file ${SRC_CPP_FILES})
+ set(CPP_FILES ${CPP_FILES} src/${file})
+endforeach(file ${SRC_CPP_FILES})
+
+foreach(file ${INTERNAL_CPP_FILES})
+ set(CPP_FILES ${CPP_FILES} src/internal/${file})
+endforeach(file ${INTERNAL_CPP_FILES})
diff --git a/Plugins/org.mitk.gui.qt.aicpregistration/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.aicpregistration/manifest_headers.cmake
new file mode 100644
index 0000000000..90b4a677d8
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.aicpregistration/manifest_headers.cmake
@@ -0,0 +1,5 @@
+set(Plugin-Name "AICPRegistration")
+set(Plugin-Version "0.1")
+set(Plugin-Vendor "DKFZ, Medical and Biological Informatics")
+set(Plugin-ContactAddress "")
+set(Require-Plugin org.mitk.gui.qt.common)
diff --git a/Plugins/org.mitk.gui.qt.aicpregistration/plugin.xml b/Plugins/org.mitk.gui.qt.aicpregistration/plugin.xml
new file mode 100644
index 0000000000..40187f532e
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.aicpregistration/plugin.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plugin>
+
+ <extension point="org.blueberry.ui.views">
+ <view id="org.mitk.views.aicpregistration"
+ name="AICP-Registration"
+ class="QmitkAICPRegistrationView"
+ icon="resources/QmitkAICPRegistration_Icon.xpm" />
+ </extension>
+
+</plugin>
diff --git a/Plugins/org.mitk.gui.qt.aicpregistration/resources/QmitkAICPRegistration_Icon.xpm b/Plugins/org.mitk.gui.qt.aicpregistration/resources/QmitkAICPRegistration_Icon.xpm
new file mode 100644
index 0000000000..c157c2b5b9
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.aicpregistration/resources/QmitkAICPRegistration_Icon.xpm
@@ -0,0 +1,364 @@
+/* XPM */
+static char * icon_xpm[] = {
+"100 100 261 2",
+" c None",
+". c #FFFFFF",
+"+ c #F3F3F3",
+"@ c #E6E6E6",
+"# c #F6F6F6",
+"$ c #8B8B8B",
+"% c #000000",
+"& c #A1A1A1",
+"* c #F6F7F5",
+"= c #949F7C",
+"- c #4F6228",
+"; c #D4D9CB",
+"> c #5A6C35",
+", c #515151",
+"' c #DEE1D7",
+") c #131313",
+"! c #FBFBFA",
+"~ c #ECEEE8",
+"{ c #9DA787",
+"] c #829067",
+"^ c #FEFEFE",
+"/ c #51632A",
+"( c #FCFDFC",
+"_ c #9FA98A",
+": c #7A895C",
+"< c #ABB498",
+"[ c #FCFCFB",
+"} c #B7BFA7",
+"| c #A1AB8C",
+"1 c #B0B89E",
+"2 c #D0D5C5",
+"3 c #FDFDFC",
+"4 c #627340",
+"5 c #BDC4AE",
+"6 c #F3F5F1",
+"7 c #FAFAF9",
+"8 c #7B895E",
+"9 c #060703",
+"0 c #0D1006",
+"a c #738254",
+"b c #8F9B76",
+"c c #738255",
+"d c #F6F7F4",
+"e c #79875B",
+"f c #FDFDFD",
+"g c #D5D5D5",
+"h c #B0B89F",
+"i c #758356",
+"j c #62733F",
+"k c #191F0C",
+"l c #7C8A5F",
+"m c #576932",
+"n c #5A6C36",
+"o c #78875B",
+"p c #839168",
+"q c #ACB59A",
+"r c #B4BCA3",
+"s c #919D79",
+"t c #758457",
+"u c #425121",
+"v c #2B3515",
+"w c #54672F",
+"x c #829066",
+"y c #79875C",
+"z c #6A7A49",
+"A c #60713D",
+"B c #7E8C62",
+"C c #596B34",
+"D c #FAFBFA",
+"E c #506329",
+"F c #939F7C",
+"G c #2A2A2A",
+"H c #F4F5F2",
+"I c #F5F6F4",
+"J c #6D7D4E",
+"K c #C4CAB6",
+"L c #F9FAF8",
+"M c #51642A",
+"N c #4F6229",
+"O c #A9B296",
+"P c #7E8D62",
+"Q c #A4AE90",
+"R c #D4D9CA",
+"S c #D5D9CC",
+"T c #AFB89D",
+"U c #8D9A75",
+"V c #839067",
+"W c #718052",
+"X c #AAB397",
+"Y c #6B6B6B",
+"Z c #5A5A5A",
+"` c #5082BD",
+" . c #7AA0CD",
+".. c #D6E2EF",
+"+. c #CFDDED",
+"@. c #4A7EBB",
+"#. c #759CCB",
+"$. c #D5E1EF",
+"%. c #CEDCEC",
+"&. c #FDFEFE",
+"*. c #BDD0E6",
+"=. c #C4D5E9",
+"-. c #FCFDFE",
+";. c #D1DEEE",
+">. c #F9FAFC",
+",. c #DAE4F1",
+"'. c #EFF4F9",
+"). c #EFF3F8",
+"!. c #E9EFF6",
+"~. c #CCDBEC",
+"{. c #E2EAF3",
+"]. c #D8E3F0",
+"^. c #F9FBFC",
+"/. c #E5EDF5",
+"(. c #4E81BC",
+"_. c #AAC2DF",
+":. c #5586BF",
+"<. c #7CA2CE",
+"[. c #6F98C8",
+"}. c #ADC5E0",
+"|. c #5183BD",
+"1. c #80A4CF",
+"2. c #6591C5",
+"3. c #F0F4F9",
+"4. c #4B7FBB",
+"5. c #B9CDE5",
+"6. c #7BA1CD",
+"7. c #BFD1E7",
+"8. c #F5F8FB",
+"9. c #608EC3",
+"0. c #B3C8E2",
+"a. c #F2F6FA",
+"b. c #4B7EBB",
+"c. c #BCCFE6",
+"d. c #92B1D6",
+"e. c #5F8DC3",
+"f. c #F8FAFC",
+"g. c #5384BE",
+"h. c #7FA4CF",
+"i. c #EBF1F7",
+"j. c #D2DFEE",
+"k. c #FAFBFD",
+"l. c #DFE8F3",
+"m. c #E3EBF4",
+"n. c #789FCC",
+"o. c #5485BE",
+"p. c #81A5CF",
+"q. c #5686BF",
+"r. c #9BB8D9",
+"s. c #95B4D7",
+"t. c #9CB8D9",
+"u. c #5E8CC2",
+"v. c #5284BE",
+"w. c #8DAED4",
+"x. c #7CA1CD",
+"y. c #F1F5F9",
+"z. c #E7EEF6",
+"A. c #E5ECF4",
+"B. c #CDDBEC",
+"C. c #FDFDFE",
+"D. c #4C7FBB",
+"E. c #7DA2CE",
+"F. c #F3F6FA",
+"G. c #FBFCFD",
+"H. c #B1C7E1",
+"I. c #7099C9",
+"J. c #85A8D1",
+"K. c #5283BE",
+"L. c #ACC4DF",
+"M. c #E1EAF4",
+"N. c #4C80BC",
+"O. c #D4E1EF",
+"P. c #B4C9E2",
+"Q. c #9CB8DA",
+"R. c #DDE6F2",
+"S. c #96B4D7",
+"T. c #4F81BC",
+"U. c #618EC3",
+"V. c #6390C4",
+"W. c #89ABD2",
+"X. c #D7E2F0",
+"Y. c #5C8AC1",
+"Z. c #B0C6E1",
+"`. c #8CADD3",
+" + c #CAD9EB",
+".+ c #86A8D1",
+"++ c #5283BD",
+"@+ c #4D80BC",
+"#+ c #6D96C8",
+"$+ c #B8CCE4",
+"%+ c #FAFCFD",
+"&+ c #D9E4F0",
+"*+ c #C2D3E8",
+"=+ c #CFDCEC",
+"-+ c #F8F3F3",
+";+ c #EEE0E0",
+">+ c #B06A68",
+",+ c #953735",
+"'+ c #AC6361",
+")+ c #903533",
+"!+ c #792C2B",
+"~+ c #F7F7F7",
+"{+ c #7C2E2C",
+"]+ c #B67674",
+"^+ c #FEFDFD",
+"/+ c #FDFBFB",
+"(+ c #963A38",
+"_+ c #EDDDDC",
+":+ c #A65856",
+"<+ c #0B0404",
+"[+ c #DFC3C2",
+"}+ c #D0A6A5",
+"|+ c #F1E6E6",
+"1+ c #963937",
+"2+ c #FAF7F7",
+"3+ c #B67675",
+"4+ c #E9D7D6",
+"5+ c #993F3D",
+"6+ c #AC6362",
+"7+ c #9C6B69",
+"8+ c #ECDCDC",
+"9+ c #953836",
+"0+ c #B4716F",
+"a+ c #E1C7C6",
+"b+ c #BF8786",
+"c+ c #FDFCFC",
+"d+ c #463D3D",
+"e+ c #983D3B",
+"f+ c #2F1110",
+"g+ c #E6D0D0",
+"h+ c #0D0707",
+"i+ c #B06A69",
+"j+ c #9E4947",
+"k+ c #FCFAFA",
+"l+ c #FBF9F9",
+"m+ c #C18A89",
+"n+ c #C4908F",
+"o+ c #FBF8F8",
+"p+ c #99403E",
+"q+ c #C69594",
+"r+ c #BA7D7C",
+"s+ c #E8D3D3",
+"t+ c #BD8382",
+"u+ c #973B39",
+"v+ c #FAF6F6",
+"w+ c #E0C4C4",
+"x+ c #AD6462",
+"y+ c #F7F0F0",
+"z+ c #3C2B2A",
+"A+ c #020202",
+"B+ c #010101",
+"C+ c #2C2C2C",
+"D+ c #CEA3A2",
+"E+ c #F2E7E7",
+"F+ c #E3CBCA",
+"G+ c #D2ABAA",
+"H+ c #F5EEED",
+"I+ c #9F4948",
+"J+ c #AF6867",
+"K+ c #EAD7D7",
+"L+ c #9E4847",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + @ @ @ @ @ @ @ @ @ @ @ # . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . $ % % % % % % % % % % % & . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . $ % % % % % % % % % % % & . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % % % . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % % % . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % % % . . . . . . . * . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % % % . . . . . . = - . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % % % . . . . ; - - - . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % % % . . . > - - - - . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % % % % % % % % % % % , . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % % % . ' - - - - - - . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % % % % % % % % % % % , . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % % % - - - - - - - - . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) % % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ! ~ { - % % % - - - - - - - - . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) % % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ] - - - - - % % % - - - - - - - - . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) % % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ^ - - - - - - - % % % - - - - - - - - . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) % % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - - - - - - - - % % % - - - - - - - - . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) % % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ~ - - - - - - - - % % % - - - - - - - / . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . ( _ : < [ ^ . . . . . . . . ) % % } : | 1 2 ! [ 3 ^ . . . . . . . . . . . . ^ 4 - - - - - - - - - - - - - - - - % % % - - - - - - 5 . . . . . . . . . . ",
+". . . . . . . . . . . . . % % % % % % % % % % % % - - - - - - 6 . . . 7 8 - 9 % % - - - - - - - - - - 1 . . . % % % % % % % % % % % 0 - - - - - - - - - - - - - % % % - - - a . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . % % % % % % % % % % % % - - - - - - - b . c - - - 9 % % - - - - - - - - - - - - d . % % % % % % % % % % % 0 - - - - - - - - - - - - - % % % e f . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . g % % h - - - - - - - - - - - - - - - - - 9 % % - - - - - - - - - - - - - a i j - - k % % - - - - - - - - - - - - - - - - - - % % % . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . g % % - - - - - - - - - - - - - - - - - - 9 % % - - - - - - - - - - - - - - - - - - k % % - - - - - - - - - - - - - - - - - - % % % . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . l m m n o p q r g % % - - - - - - - - - - - - - - - - - - 9 % % - - - - - - - - - - - - - - - - - - k % % - - - - - - - - - - - - - - - - - s % % % . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . t - - - - - - - u % % - - - - - - - - - - - - - - - - - - 9 % % - - - - - - - - - - - - - - - - - - k % % - - - - - - - - - - - - - v % % % % % % % % % % % & . . . . . . . . . . . . ",
+". . . . . . . . . t - - - - - - - u % % - - - - - - - - - - - - - - - - - - 9 % % - - - - - - - - - - - - - - - - - - k % % - - - - - - - - - - - - - v % % % % % % % % % % % & . . . . . . . . . . . . ",
+". . . . . . . . . t - - - - - - - u % % - - - - - - - - - - - - - - - - - - 9 % % w x y z A - - - - - - - - - - - - - k % % - - - B . . . . . . . . . $ % % % % % % % % % % % & . . . . . . . . . . . . ",
+". . . . . . . . . t - - - - - - - u % % - - - - - - C D E - - - - - - - - - 9 % % . . . . . . . F - - - - - - % % % % % % % % % % % G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . t - - - - - - - u % % - - - - - H . . . I J - - - - - - K ) % % . . . . . . . . L M - - - - % % % % % % % % % % % G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . t - - - - - - - u % % - - - N . . . . . . . . . . . . . . ) % % . . . . . . . . . . . O P Q O R . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . t - - - - - - - u % % - - i . . . . . . . . . . . % % % % % % % % % % % , . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . S T T = U V W - u % % X . . . . . . . . . . . . . % % % % % % % % % % % , . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . Y Y Y Y Z % % Y Y Y Y Y . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . % % % % % % % % % % % % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . % % % % % % % % % % % % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . ` ` ` ` . . . . . . . . . . . . . . . . . ` ` ` .. . . . . . . . . . . . . . . . . ` ` ` ... . . . . . . . . . . . . . . . . ` ` ` +.. . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . @.@.@.@.. . . . . . . . . . . . . . . . . @.@.@.#.. . . . . . . . . . . . . . . . . @.@.@.$.. . . . . . . . . . . . . . . . . @.@.@.%.. . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . @.@.@.@.. . . . . . . . . . . . . . . . . @.@.@.#.. . . . . . . . . . . . . . . . . @.@.@.$.. . . . . . . . . . . . . . . . . @.@.@.%.. . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . @.@.@.@.. . . . . . . . . . . . . . . . . @.@.@.#.. . . . . . . . . . . . . . . . . @.@.@.$.. . . . . . . . . . . . . . . . . @.@.@.%.. . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . @.@.@.@.. . . . . . . . . . . . . . . . . @.@.@.#.. . . . . . . . . . . . . . . . . @.@.@.$.. . . . . . . . . . . . . . . . . @.@.@.%.. . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . @.@.@.@.. . . . . . . . . . . . . . . . . @.@.@.#.. . . . . . . . . . . . . . . . . @.@.@.$.. . . . . . . . . . . . . . . . . @.@.@.%.. . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . @.@.@.@.. . . . . . . . . . . . . . . . . @.@.@.#.. . . . . . . . . . . . . . . . . @.@.@.$.. . . . . . . . . . . . . . . . . @.@.@.%.. . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . @.@.@.@.. . . . . . . . . . . . . . . . . @.@.@.#.. . . . . . . . . . . . . . . . . @.@.@.$.. . . . . . . . . . . . . . . . . @.@.@.%.. . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . @.@.@.@.. . . . . . . . . . . . . . . . . @.@.@.#.. . . . . . . . . . . . . . . . . @.@.@.$.. . . . . . . . . . . . . . . . . @.@.@.%.. . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . &.*.^ . . . @.@.@.@.. . . . =.. . . . . . -.;.. . . . @.@.@.#.. . . >.,.. . . . . . '.$.. . . . @.@.@.$.. . . '.).. . . . . . !.~.. . . . @.@.@.%.. . . {.].. . . . . . . . . . . ",
+". . . . . . . . . . . @.@.@.^.. . @.@.@.@.. . . @.@.@.. . . . /.@.@.@.. . . @.@.@.#.. . *.@.@.(.. . . . _.@.@.:.. . . @.@.@.$.. . <.@.@.[.. . . . }.@.@.|.. . . @.@.@.%.. . 1.@.@.2.. . . . . . . . . . ",
+". . . . . . . . . . 3.@.@.@.4.. . @.@.@.@.. . @.@.@.@.. . . . 5.@.@.@.6.. . @.@.@.#.. . @.@.@.@.. . . . @.@.@.@.7.. . @.@.@.$.. 8.@.@.@.@.. . . . 9.@.@.@.0.. . @.@.@.%.. a.@.@.@.@.. . . . . . . . . . ",
+". . . . . . . . . . . b.@.@.@.c.. @.@.@.@.. d.@.@.@.e.. . . . . @.@.@.@.f.. @.@.@.#.. g.@.@.@.h.. . . . ^.@.@.@.@.. . @.@.@.$.. @.@.@.@.i.. . . . . @.@.@.@.^ . @.@.@.%.. @.@.@.@.j.. . . . . . . . . . ",
+". . . . . . . . . . . k.@.@.@.@.. @.@.@.@.f.@.@.@.@.. . . . . . l.@.@.@.@.. @.@.@.#.m.@.@.@.4.. . . . . . n.@.@.@.o.. @.@.@.$.p.@.@.@.q.. . . . . . r.@.@.@.@.. @.@.@.%.s.@.@.@.|.. . . . . . . . . . . ",
+". . . . . . . . . . . . t.@.@.@.u.@.@.@.@.@.@.@.@.*.. . . . . . . v.@.@.@.w.@.@.@.x.@.@.@.@.y.. . . . . . . @.@.@.@.z.@.@.@.A.@.@.@.@.. . . . . . . . b.@.@.@.B.@.@.@.%.@.@.@.@.C.. . . . . . . . . . . ",
+". . . . . . . . . . . . . @.@.@.@.@.@.@.@.@.@.@.D.. . . . . . . . . @.@.@.@.@.@.@.@.@.@.@.E.. . . . . . . . i.@.@.@.@.@.@.@.@.@.@.@.=.. . . . . . . . F.@.@.@.@.@.@.@.@.@.@.@.=.. . . . . . . . . . . . ",
+". . . . . . . . . . . . . G.@.@.@.@.@.@.@.@.@.@.G.. . . . . . . . . H.@.@.@.@.@.@.@.@.@.@.. . . . . . . . . . I.@.@.@.@.@.@.@.@.@.q.. . . . . . . . . . J.@.@.@.@.@.@.@.@.@.K.. . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . I.@.@.@.@.@.@.@.@.L.. . . . . . . . . . . @.@.@.@.@.@.@.@.@.M.. . . . . . . . . . . @.@.@.@.@.@.@.@.@.^ . . . . . . . . . . . @.@.@.@.@.@.@.@.@.^ . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . @.@.@.@.@.@.@.N.. . . . . . . . . . . . -.@.@.@.@.@.@.@.o.. . . . . . . . . . . . O.@.@.@.@.@.@.@.P.. . . . . . . . . . . . f.@.@.@.@.@.@.@.Q.. . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . R.@.@.@.@.@.@.. . . . . . . . . . . . . . S.@.@.@.@.@.@.. . . . . . . . . . . . . . T.@.@.@.@.@.@.. . . . . . . . . . . . . . U.@.@.@.@.@.b.. . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . V.@.@.@.@.W.. . . . . . . . . . . . . . . @.@.@.@.@.X.. . . . . . . . . . . . . . C.@.@.@.@.@.^.. . . . . . . . . . . . . . . @.@.@.@.@.a.. . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . ^ @.@.@.@.. . . . . . . . . . . . . . . . a.@.@.@.Y.. . . . . . . . . . . . . . . . Z.@.@.@.`.. . . . . . . . . . . . . . . . +@.@.@..+. . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . $.@.@.).. . . . . . . . . . . . . . . . . V.@.@.. . . . . . . . . . . . . . . . . . (.@.@.. . . . . . . . . . . . . . . . . . ++@.@.. . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . @+#+. . . . . . . . . . . . . . . . . . . @.$+. . . . . . . . . . . . . . . . . . . @.%+. . . . . . . . . . . . . . . . . . . @.. . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . &+. . . . . . . . . . . . . . . . . . . . *+. . . . . . . . . . . . . . . . . . . . =+. . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . -+;+% % % % % % % % % % % % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . >+,+,+,+% % % % % % % % % % % % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . '+,+,+,+)+)+)+)+!+% % ~+~+~+~+~+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . '+,+,+,+,+,+,+,+{+% % ,+]+^+. . . . . . . /+(+,+,+% % % % % % % % % % % , . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . '+,+,+,+,+,+,+,+{+% % ,+,+,+,+_+. ;+:+,+,+,+,+,+,+% % % % % % % % % % % , . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . '+,+,+,+,+,+,+,+{+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+<+% % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . '+,+,+,+,+,+,+,+{+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+<+% % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . '+,+,+,+,+,+,+,+{+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+<+% % . . [+}+|+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . '+,+,+1+,+,+,+,+{+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+<+% % ,+,+,+,+,+,+,+,+,+;+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . 2+3+. . . 4+5+,+{+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+<+% % ,+,+,+,+,+,+,+,+,+,+,+6+3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . 7+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+<+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+1+8+. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . g % % 9+,+,+,+,+,+,+,+,+,+,+,+0+9+,+,+,+,+<+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+% % % % % % % % % % % G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . g % % . a+,+,+,+,+,+,+b+c+. . . ^+,+,+,+,+<+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+% % % % % % % % % % % G . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . g % % . . . . . . . . . . . . . . ^+,+,+,+<+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+d+% % . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . % % % % % % % % % % % % . . . . . . . . . . . e+,+<+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+f+% % . . . . . . . . . . . . . $ % % % % % % % % % % % & . . . . . . . . . . . . ",
+". . . . . . . . . . . . . % % % % % % % % % % % % . . . . . . . . . . . . g+h+% % ,+,+,+i+j+,+,+,+,+,+,+,+,+,+,+,+,+,+f+% % . . . . . . . k+l+. . . . $ % % % % % % % % % % % & . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) % % . . . . . . . m+,+,+,+,+,+,+,+,+,+,+f+% % ,+,+,+,+,+,+,+,+,+,+,+n+^+. . . . o+% % % ,+,+,+p+q+r+r+r+. . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) % % . . . . . . . . . s+,+,+,+,+,+,+,+,+f+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+t+. 8+,+% % % ,+,+,+,+,+,+,+,+. . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) % % . . . . . . . . . . . u+,+,+,+,+,+,+f+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+% % % ,+,+,+,+,+,+,+,+. . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) % % . . . . . . . . . . . . ,+,+,+,+,+,+f+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+% % % ,+,+,+,+,+,+,+,+. . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) % % . . . . . . . . . . . . v+,+,+,+,+,+f+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+% % % ,+,+,+,+,+,+,+,+. . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) % % . . . . . . . . . . . . . w+,+,+,+,+f+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+% % % ,+,+,+,+,+,+,+,+. . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) % % . . . . . . . . . . . . . . c+x+,+,+f+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+% % % ,+,+,+,+,+,+,+,+. . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) % % . . . . . . . . . . . . . . . . . y+z+% % ,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+,+% % % ,+,+,+,+,+,+,+,+. . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) % % . . . . . . . . . . . . . . A+A+A+A+% % % B+B+A+A+C+. . . . k+,+,+,+,+,+,+,+,+% % % ,+D+^+E+F+F+f G+. . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) % % . . . . . . . . . . . . . . % % % % % % % % % % % G . . . . . . . H+I+,+,+,+,+% % % J+. . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ) % % . . . . . . . . . . . . . . % % % % % % % % % % % G . . . . . . . . . . K+6+L+% % % . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % % % % % % % % % % % , . . . . . . . . . . . . . . . . . . . . . . . . . . . . . $ % % % % % % % % % % % & . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % % % % % % % % % % % , . . . . . . . . . . . . . . . . . . . . . . . . . . . . . $ % % % % % % % % % % % & . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . % % % % % % % % % % % , . . . . . . . . . . . . . . . . . . . . . . . . . . . . . $ % % % % % % % % % % % & . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ",
+". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "};
diff --git a/Plugins/org.mitk.gui.qt.aicpregistration/src/internal/QmitkAICPRegistrationView.cpp b/Plugins/org.mitk.gui.qt.aicpregistration/src/internal/QmitkAICPRegistrationView.cpp
new file mode 100644
index 0000000000..e41362fcea
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.aicpregistration/src/internal/QmitkAICPRegistrationView.cpp
@@ -0,0 +1,427 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+
+// Blueberry
+#include <berryISelectionService.h>
+#include <berryIWorkbenchWindow.h>
+
+// Qmitk
+#include "QmitkAICPRegistrationView.h"
+
+// Qt
+#include <QMessageBox>
+#include <QThread>
+
+// MITK
+#include <mitkSurface.h>
+#include <mitkPointSet.h>
+#include <mitkNodePredicateDataType.h>
+#include <mitkAnisotropicIterativeClosestPointRegistration.h>
+#include <mitkCovarianceMatrixCalculator.h>
+#include <mitkAnisotropicRegistrationCommon.h>
+
+// vtk
+#include <vtkSmartPointer.h>
+#include <vtkPolyData.h>
+#include <vtkCleanPolyData.h>
+
+const std::string QmitkAICPRegistrationView::VIEW_ID = "org.mitk.views.aicpregistration";
+
+ /**
+ * @brief Pimpl holding the datastructures used by the
+ * QmitkAICPRegistrationView.
+ */
+class AICPRegistrationViewData
+{
+
+public:
+ QThread* m_RegistrationThread;
+ UIWorker* m_Worker;
+ double m_Threshold;
+ double m_MaxIterations;
+ double m_TrimmFactor;
+ double m_SearchRadius;
+
+ // anisotropic registration
+ mitk::AnisotropicIterativeClosestPointRegistration::Pointer m_AICP;
+
+ // covariance matrix calculator
+ mitk::CovarianceMatrixCalculator::Pointer m_MatrixCalculator;
+
+ vtkSmartPointer<vtkCleanPolyData> m_CleanPolyData;
+
+ mitk::Surface::Pointer m_MovingSurface;
+
+ mitk::Surface::Pointer m_FixedSurface;
+
+ // c tor
+ AICPRegistrationViewData()
+ : m_RegistrationThread(new QThread()),
+ m_Worker(new UIWorker()),
+ m_Threshold(0.00001),
+ m_MaxIterations(1000),
+ m_TrimmFactor(0.0),
+ m_SearchRadius(30.0),
+ m_AICP(mitk::AnisotropicIterativeClosestPointRegistration::New()),
+ m_MatrixCalculator(mitk::CovarianceMatrixCalculator::New()),
+ m_CleanPolyData(vtkSmartPointer<vtkCleanPolyData>::New()),
+ m_MovingSurface(NULL),
+ m_FixedSurface(NULL)
+ {
+ }
+
+ // cleanup
+ ~AICPRegistrationViewData()
+ {
+ if ( m_RegistrationThread )
+ delete m_RegistrationThread;
+ if ( m_Worker )
+ delete m_Worker;
+
+ m_AICP = NULL;
+ m_MatrixCalculator = NULL;
+ m_CleanPolyData = NULL;
+ m_MovingSurface = NULL;
+ m_FixedSurface = NULL;
+ }
+};
+
+QmitkAICPRegistrationView::QmitkAICPRegistrationView()
+{
+ d = new AICPRegistrationViewData();
+}
+
+QmitkAICPRegistrationView::~QmitkAICPRegistrationView()
+{
+ if ( d )
+ delete d;
+}
+
+void QmitkAICPRegistrationView::SetFocus(){}
+
+void QmitkAICPRegistrationView::CreateQtPartControl( QWidget *parent )
+{
+ // create GUI widgets from the Qt Designer's .ui file
+ m_Controls.setupUi( parent );
+
+ // connect signals and slots
+ connect ( m_Controls.m_EnableTreCalculation,SIGNAL(clicked()),this, SLOT(OnEnableTreCalculation()) );
+ connect ( m_Controls.m_RegisterSurfaceButton, SIGNAL(clicked()), this, SLOT(OnStartRegistration()) );
+ connect ( m_Controls.m_EnableTrimming, SIGNAL(clicked()), this, SLOT(OnEnableTrimming()) );
+ connect ( d->m_Worker, SIGNAL( RegistrationFinished()), this, SLOT( OnRegistrationFinished()) );
+ connect(d->m_RegistrationThread,SIGNAL(started()), d->m_Worker,SLOT(RegistrationThreadFunc()) );
+
+ // move the u worker to the thread
+ d->m_Worker->moveToThread(d->m_RegistrationThread);
+
+ // setup tooltips
+ m_Controls.m_MovingSurfaceComboBox->setToolTip("Set the moving surface of the A-ICP algorithm");
+ m_Controls.m_FixedSurfaceComboBox->setToolTip("Set the fixed surface of the A-ICP algorithm");
+ m_Controls.m_EnableTreCalculation->setToolTip("Enable the trimmed version of the algorithm.");
+ m_Controls.m_TrimmFactorSpinbox->setToolTip("Set the trimmfactor. The algorithm will use a percentage of the Moving pointset for the registration. Valid number are between 0 and 1.");
+ m_Controls.m_ThresholdSpinbox->setToolTip("Set the threshold to wich the algorithm will converge.");
+ m_Controls.m_MaxIterationsSpinbox->setToolTip("The maximum number of iterations used by the algorithm.");
+ m_Controls.m_SearchRadius->setToolTip("Set the search radius in mm for the calculation of the correspondences.");
+ m_Controls.m_RegisterSurfaceButton->setToolTip("Start the registration.");
+ m_Controls.m_EnableTrimming->setToolTip("Enables the trimmed version of the algorithm.");
+ m_Controls.m_TrimmFactorSpinbox->setToolTip("Set teh overlapping part of the surface in %. The valid range is between 0 and 1.");
+ m_Controls.m_MovingTargets->setToolTip("Select the targets for the moving surface.");
+ m_Controls.m_FixedTargets->setToolTip("Select the targets for the fixed surface.");
+
+ // init combo boxes
+ m_Controls.m_FixedSurfaceComboBox->SetDataStorage(this->GetDataStorage());
+ m_Controls.m_FixedSurfaceComboBox->SetPredicate(mitk::NodePredicateDataType::New("Surface"));
+
+ m_Controls.m_MovingSurfaceComboBox->SetDataStorage(this->GetDataStorage());
+ m_Controls.m_MovingSurfaceComboBox->SetPredicate(mitk::NodePredicateDataType::New("Surface"));
+
+ m_Controls.m_MovingTargets->SetDataStorage(this->GetDataStorage());
+ m_Controls.m_MovingTargets->SetPredicate(mitk::NodePredicateDataType::New("PointSet"));
+
+ m_Controls.m_FixedTargets->SetDataStorage(this->GetDataStorage());
+ m_Controls.m_FixedTargets->SetPredicate(mitk::NodePredicateDataType::New("PointSet"));
+
+ // disable target selection
+ m_Controls.m_TargetSelectFrame->setEnabled(false);
+
+ // disable trimming options
+ m_Controls.m_TrimmFactorLabel->setEnabled(false);
+ m_Controls.m_TrimmFactorSpinbox->setEnabled(false);
+}
+
+
+bool QmitkAICPRegistrationView::CheckInput()
+{
+ QMessageBox msg;
+ msg.setIcon(QMessageBox::Critical);
+
+ if ( m_Controls.m_MovingSurfaceComboBox->GetSelectedNode().IsNull() ||
+ m_Controls.m_FixedSurfaceComboBox->GetSelectedNode().IsNull() )
+ {
+ const char* message = "No Surfaces selected.";
+ MITK_ERROR << message;
+ msg.setText(message);
+ msg.exec();
+ return false;
+ }
+
+ if ( m_Controls.m_EnableTreCalculation->isChecked() )
+ {
+ if ( m_Controls.m_FixedTargets->GetSelectedNode().IsNull() ||
+ m_Controls.m_MovingTargets->GetSelectedNode().IsNull() )
+ {
+ const char* message = "TRE calculation is enabled, but no target points are selected.";
+ msg.setText(message);
+ msg.exec();
+ return false;
+ }
+ }
+ return true;
+}
+
+void QmitkAICPRegistrationView::OnStartRegistration()
+{
+ d->m_Threshold = m_Controls.m_ThresholdSpinbox->value();
+ d->m_MaxIterations = m_Controls.m_MaxIterationsSpinbox->value();
+ d->m_SearchRadius = m_Controls.m_SearchRadius->value();
+ d->m_TrimmFactor = 0.0;
+
+ if ( m_Controls.m_EnableTrimming->isChecked() )
+ {
+ d->m_TrimmFactor = m_Controls.m_TrimmFactorSpinbox->value();
+ }
+
+ if (! CheckInput() )
+ return;
+
+ d->m_MovingSurface = dynamic_cast<mitk::Surface*>(
+ m_Controls.m_MovingSurfaceComboBox->GetSelectedNode()->GetData() );
+
+ d->m_FixedSurface = dynamic_cast<mitk::Surface*>(
+ m_Controls.m_FixedSurfaceComboBox->GetSelectedNode()->GetData() );
+
+ // sanity check
+ if ( d->m_FixedSurface.IsNull() || d->m_MovingSurface.IsNull() )
+ {
+ const char* message = "Input surfaces are NULL.";
+ QMessageBox msg;
+ msg.setIcon(QMessageBox::Critical);
+ msg.setText(message);
+ MITK_ERROR << message;
+ return;
+ }
+
+ // enable trimming
+ if ( m_Controls.m_EnableTrimming->isChecked() )
+ {
+ d->m_TrimmFactor = m_Controls.m_TrimmFactorSpinbox->value();
+ }
+
+ // set data into the UI thread
+ d->m_Worker->SetRegistrationData(d);
+
+ // start thread
+ d->m_RegistrationThread->start();
+
+ // disable registration button
+ m_Controls.m_RegisterSurfaceButton->setEnabled(false);
+
+ mitk::RenderingManager::GetInstance()->RequestUpdateAll();
+}
+
+void QmitkAICPRegistrationView::OnEnableTreCalculation()
+{
+ if ( m_Controls.m_EnableTreCalculation->isChecked() )
+ m_Controls.m_TargetSelectFrame->setEnabled(true);
+ else
+ m_Controls.m_TargetSelectFrame->setEnabled(false);
+}
+
+void QmitkAICPRegistrationView::OnEnableTrimming()
+{
+ if ( m_Controls.m_EnableTrimming->isChecked() )
+ {
+ // disable trimming options
+ m_Controls.m_TrimmFactorLabel->setEnabled(true);
+ m_Controls.m_TrimmFactorSpinbox->setEnabled(true);
+ } else {
+ // disable trimming options
+ m_Controls.m_TrimmFactorLabel->setEnabled(false);
+ m_Controls.m_TrimmFactorSpinbox->setEnabled(false);
+ }
+}
+
+void QmitkAICPRegistrationView::OnRegistrationFinished()
+{
+ typedef itk::Matrix<double,3,3> Matrix3x3;
+ typedef itk::Vector<double,3> TranslationVector;
+
+ double tre = -1.0;
+ Matrix3x3 rotation = d->m_AICP->GetRotation();
+ TranslationVector translation = d->m_AICP->GetTranslation();
+
+ // exit the thread
+ d->m_RegistrationThread->quit();
+
+ MITK_INFO << "Rotation: \n" << rotation << "Translation: " << translation;
+ MITK_INFO << "FRE: " << d->m_AICP->GetFRE();
+
+ // compute TRE
+ if ( m_Controls.m_EnableTreCalculation->isChecked() )
+ {
+ mitk::PointSet* movingTargets = dynamic_cast<mitk::PointSet*> (
+ m_Controls.m_MovingTargets->GetSelectedNode()->GetData() );
+
+ mitk::PointSet* fixedTargets = dynamic_cast<mitk::PointSet*> (
+ m_Controls.m_FixedTargets->GetSelectedNode()->GetData() );
+
+ // sanity check
+ if ( movingTargets && fixedTargets )
+ {
+ // swap the moving and the fixed point set, since we use the inverse
+ // transform
+ tre = mitk::AnisotropicRegistrationCommon::ComputeTargetRegistrationError(
+ movingTargets,
+ fixedTargets,
+ rotation,
+ translation
+ );
+ MITK_INFO << "TRE: " << tre;
+
+ // transform the fixed point set
+ for ( int i = 0; i < movingTargets->GetSize(); ++i )
+ {
+ mitk::Point3D p = movingTargets->GetPoint(i);
+
+ p = rotation * p + translation;
+
+ movingTargets->SetPoint(i,p);
+ }
+ }
+ }
+ // display result in textbox ( the inverse transform )
+ QString text("");
+ std::ostringstream oss;
+
+ oss << "<b>Iterations:</b> "<< d->m_AICP->GetNumberOfIterations()
+ << "<br><b>FRE:</b> " << d->m_AICP->GetFRE()
+ << "<br><b>TRE:</b> ";
+
+ if ( tre != -1.0)
+ oss << tre;
+ else
+ oss << "N/A";
+
+ oss << "<br><br><b>Rotation:</b><br>";
+
+ for ( int i = 0; i < 3; ++i ) {
+ for ( int j = 0; j < 3; ++j )
+ oss << rotation[i][j] << " ";
+ oss << "<br>";
+ }
+
+ oss << "<br><b>Translation:</b><br>" << translation << "<br>";
+
+ std::string s(oss.str());
+ text.append(s.c_str());
+
+ m_Controls.m_TextEdit->clear();
+ m_Controls.m_TextEdit->append(text);
+
+ mitk::AnisotropicRegistrationCommon::TransformPoints (
+ d->m_MovingSurface->GetVtkPolyData()->GetPoints(),
+ d->m_MovingSurface->GetVtkPolyData()->GetPoints(),
+ rotation,
+ translation
+ );
+
+ // set modified flag to update rendering
+ d->m_MovingSurface->GetVtkPolyData()->Modified();
+
+ // reanable registration button
+ m_Controls.m_RegisterSurfaceButton->setEnabled(true);
+
+ //update view
+ mitk::RenderingManager::GetInstance()->RequestUpdateAll();
+}
+
+void UIWorker::SetRegistrationData(AICPRegistrationViewData *data)
+{
+ this->d = data;
+}
+
+void UIWorker::RegistrationThreadFunc()
+{
+ typedef itk::Matrix<double,3,3> Matrix3x3;
+ typedef itk::Vector<double,3> TranslationVector;
+ typedef std::vector<Matrix3x3> CovarianceMatrixList;
+
+ // moving surface
+ mitk::Surface::Pointer X = mitk::Surface::New();
+ // helper
+ vtkPolyData* data_X = vtkPolyData::New();
+ // fixed surface
+ mitk::Surface::Pointer Y = mitk::Surface::New();
+ // helper
+ vtkPolyData* data_Y = vtkPolyData::New();
+
+ // clean the poly data to prevent manifold edges and duplicated vertices
+ d->m_CleanPolyData->SetInputData(d->m_MovingSurface->GetVtkPolyData());
+ d->m_CleanPolyData->Update();
+ // copy the polys
+ data_X->DeepCopy(d->m_CleanPolyData->GetOutput());
+ X->SetVtkPolyData(data_X);
+
+ d->m_CleanPolyData->SetInputData(d->m_FixedSurface->GetVtkPolyData());
+ d->m_CleanPolyData->Update();
+ data_Y->DeepCopy(d->m_CleanPolyData->GetOutput());
+ Y->SetVtkPolyData(data_Y);
+
+ // compute the covariance matrices for the moving surface (X)
+ d->m_MatrixCalculator->SetInputSurface(X);
+ d->m_MatrixCalculator->ComputeCovarianceMatrices();
+ CovarianceMatrixList sigmas_X = d->m_MatrixCalculator->GetCovarianceMatrices();
+ const double meanVarX = d->m_MatrixCalculator->GetMeanVariance();
+
+ // compute the covariance matrices for the fixed surface (Y)
+ d->m_MatrixCalculator->SetInputSurface(Y);
+ d->m_MatrixCalculator->ComputeCovarianceMatrices();
+ CovarianceMatrixList sigmas_Y = d->m_MatrixCalculator->GetCovarianceMatrices();
+ const double meanVarY = d->m_MatrixCalculator->GetMeanVariance();
+
+ // the FRE normalization factor
+ const double normalizationFactor = sqrt( meanVarX + meanVarY);
+
+ // set up parameters
+ d->m_AICP->SetMovingSurface(X);
+ d->m_AICP->SetFixedSurface(Y);
+ d->m_AICP->SetCovarianceMatricesMovingSurface(sigmas_X);
+ d->m_AICP->SetCovarianceMatricesFixedSurface(sigmas_Y);
+ d->m_AICP->SetFRENormalizationFactor(normalizationFactor);
+ d->m_AICP->SetMaxIterations(d->m_MaxIterations);
+ d->m_AICP->SetSearchRadius(d->m_SearchRadius);
+ d->m_AICP->SetThreshold(d->m_Threshold);
+ d->m_AICP->SetTrimmFactor(d->m_TrimmFactor);
+
+ // run the algorithm
+ d->m_AICP->Update();
+
+ data_X->Delete();
+ data_Y->Delete();
+
+ emit RegistrationFinished();
+}
diff --git a/Plugins/org.mitk.gui.qt.aicpregistration/src/internal/QmitkAICPRegistrationView.h b/Plugins/org.mitk.gui.qt.aicpregistration/src/internal/QmitkAICPRegistrationView.h
new file mode 100644
index 0000000000..f844ea60f2
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.aicpregistration/src/internal/QmitkAICPRegistrationView.h
@@ -0,0 +1,121 @@
+/*===================================================================
+
+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 QmitkAICPRegistrationView_h
+#define QmitkAICPRegistrationView_h
+
+#include <berryISelectionListener.h>
+
+#include <QmitkAbstractView.h>
+#include <QWidget>
+#include "ui_QmitkAICPRegistrationViewControls.h"
+
+// forwarddeclaration
+class AICPRegistrationViewData;
+
+/**
+ * \brief Implemenation of a worker thread class.
+ *
+ * Worker class that runs the registration
+ * in a seperate QThread to prevent the registration from blocking the
+ * GUI.
+ */
+class UIWorker : public QObject
+{
+ Q_OBJECT
+
+ private:
+ /** Pimpl with the registration data.*/
+ AICPRegistrationViewData* d;
+
+ public slots:
+
+ /** Method that runs the registration algorithm in a seperate QThread.*/
+ void RegistrationThreadFunc();
+
+ signals:
+
+ /** Signal emitted when the registration was successful.*/
+ void RegistrationFinished();
+
+ public:
+
+ /** Set the data used for the registration.*/
+ void SetRegistrationData(AICPRegistrationViewData* data);
+};
+
+/**
+ \brief QmitkAICPRegistrationView provides a simple UI to register two
+ surfaces with the AnisotropicIterativeClosestPointRegistration
+ algorithm.
+
+ \sa QmitkAbstractView
+ \ingroup ${plugin_target}_internal
+*/
+class QmitkAICPRegistrationView : public QmitkAbstractView
+{
+ // this is needed for all Qt objects that should have a Qt meta-object
+ // (everything that derives from QObject and wants to have signal/slots)
+ Q_OBJECT
+
+ public:
+
+ static const std::string VIEW_ID;
+
+ QmitkAICPRegistrationView();
+
+ ~QmitkAICPRegistrationView();
+
+ protected slots:
+
+ /** Starts the registration. When the method is called a seperate UIWorker
+ * thread will be run in the background to prevent blocking the GUI.
+ */
+ void OnStartRegistration();
+
+ /** Enables/disables the calculation of the Target Registration Error (TRE).
+ */
+ void OnEnableTreCalculation();
+
+ /** Enables/disables the trimmed version of the A-ICP algorithm.*/
+ void OnEnableTrimming();
+
+ public slots:
+
+ /** Method called when the algorithm is finishes. This method will setup
+ * the GUI.
+ */
+ void OnRegistrationFinished();
+
+ protected:
+
+ virtual void CreateQtPartControl(QWidget *parent);
+
+ virtual void SetFocus();
+
+ Ui::QmitkAICPRegistrationViewControls m_Controls;
+
+ private:
+
+ AICPRegistrationViewData* d;
+
+ /** Check for the correct input data.*/
+ bool CheckInput();
+
+};
+
+#endif // QmitkAICPRegistrationView_h
diff --git a/Plugins/org.mitk.gui.qt.aicpregistration/src/internal/QmitkAICPRegistrationViewControls.ui b/Plugins/org.mitk.gui.qt.aicpregistration/src/internal/QmitkAICPRegistrationViewControls.ui
new file mode 100644
index 0000000000..85dad8aa0d
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.aicpregistration/src/internal/QmitkAICPRegistrationViewControls.ui
@@ -0,0 +1,391 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>QmitkAICPRegistrationViewControls</class>
+ <widget class="QWidget" name="QmitkAICPRegistrationViewControls">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>472</width>
+ <height>764</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>QmitkTemplate</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QGroupBox" name="m_InputGroup">
+ <property name="title">
+ <string>Input Surfaces</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="m_MovingSurfaceLabel">
+ <property name="text">
+ <string>Moving Surface (X):</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QmitkDataStorageComboBox" name="m_MovingSurfaceComboBox"/>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QLabel" name="m_FixedSurfaceLabel">
+ <property name="text">
+ <string>Fixed Surface (Y):</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QmitkDataStorageComboBox" name="m_FixedSurfaceComboBox"/>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="m_targetGroup">
+ <property name="title">
+ <string>Target Registration Error Calculation</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <widget class="QCheckBox" name="m_EnableTreCalculation">
+ <property name="text">
+ <string>Enable TRE Calculation</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_9">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QFrame" name="m_TargetSelectFrame">
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_10">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_5">
+ <item>
+ <widget class="QLabel" name="m_MovingTargetsLabel">
+ <property name="text">
+ <string>Moving Surface Targets:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QmitkDataStorageComboBox" name="m_MovingTargets"/>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_6">
+ <item>
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Fixed Surface Targets: </string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QmitkDataStorageComboBox" name="m_FixedTargets"/>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Registration Settings</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_9">
+ <item>
+ <spacer name="horizontalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="m_ThresholdLabel">
+ <property name="text">
+ <string>Threshold:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDoubleSpinBox" name="m_ThresholdSpinbox">
+ <property name="decimals">
+ <number>6</number>
+ </property>
+ <property name="singleStep">
+ <double>0.000001000000000</double>
+ </property>
+ <property name="value">
+ <double>0.000001000000000</double>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_10">
+ <item>
+ <spacer name="horizontalSpacer_5">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="m_MaxIterLabel">
+ <property name="text">
+ <string>Max. Iterations:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="m_MaxIterationsSpinbox">
+ <property name="maximum">
+ <number>10000</number>
+ </property>
+ <property name="singleStep">
+ <number>10</number>
+ </property>
+ <property name="value">
+ <number>1000</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_12">
+ <item>
+ <spacer name="horizontalSpacer_6">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Search Radius:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDoubleSpinBox" name="m_SearchRadius">
+ <property name="minimum">
+ <double>1.000000000000000</double>
+ </property>
+ <property name="maximum">
+ <double>1000.000000000000000</double>
+ </property>
+ <property name="value">
+ <double>30.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <item>
+ <widget class="QCheckBox" name="m_EnableTrimming">
+ <property name="text">
+ <string>Enable Trimming</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="m_TrimmFactorLabel">
+ <property name="text">
+ <string>Overlap:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDoubleSpinBox" name="m_TrimmFactorSpinbox">
+ <property name="decimals">
+ <number>2</number>
+ </property>
+ <property name="maximum">
+ <double>0.990000000000000</double>
+ </property>
+ <property name="singleStep">
+ <double>0.100000000000000</double>
+ </property>
+ <property name="value">
+ <double>0.500000000000000</double>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="m_ResultGroup">
+ <property name="title">
+ <string>Results:</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_8">
+ <item>
+ <widget class="QTextEdit" name="m_TextEdit">
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>200</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>200</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_7">
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="m_RegisterSurfaceButton">
+ <property name="text">
+ <string>Register Surfaces</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <customwidgets>
+ <customwidget>
+ <class>QmitkDataStorageComboBox</class>
+ <extends>QComboBox</extends>
+ <header>QmitkDataStorageComboBox.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/mitkBasicImageProcessingActivator.cpp b/Plugins/org.mitk.gui.qt.aicpregistration/src/internal/org_mitk_gui_qt_aicpregistration_Activator.cpp
similarity index 57%
copy from Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/mitkBasicImageProcessingActivator.cpp
copy to Plugins/org.mitk.gui.qt.aicpregistration/src/internal/org_mitk_gui_qt_aicpregistration_Activator.cpp
index be704411ad..2b02c4d3b7 100644
--- a/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/mitkBasicImageProcessingActivator.cpp
+++ b/Plugins/org.mitk.gui.qt.aicpregistration/src/internal/org_mitk_gui_qt_aicpregistration_Activator.cpp
@@ -1,35 +1,38 @@
/*===================================================================
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 "mitkBasicImageProcessingActivator.h"
-#include "QmitkBasicImageProcessingView.h"
+
+
+#include "org_mitk_gui_qt_aicpregistration_Activator.h"
#include <QtPlugin>
+#include "QmitkAICPRegistrationView.h"
+
namespace mitk {
-void BasicImageProcessingActivator::start(ctkPluginContext* context)
+void org_mitk_gui_qt_aicpregistration_Activator::start(ctkPluginContext* context)
{
- BERRY_REGISTER_EXTENSION_CLASS(QmitkBasicImageProcessing, context)
+ BERRY_REGISTER_EXTENSION_CLASS(QmitkAICPRegistrationView, context)
}
-void BasicImageProcessingActivator::stop(ctkPluginContext* context)
+void org_mitk_gui_qt_aicpregistration_Activator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_basicimageprocessing, mitk::BasicImageProcessingActivator)
+Q_EXPORT_PLUGIN2(org_mitk_gui_qt_aicpregistration, mitk::org_mitk_gui_qt_aicpregistration_Activator)
diff --git a/Plugins/org.mitk.gui.qt.coreapplication/src/internal/org_mitk_gui_qt_coreapplication_Activator.h b/Plugins/org.mitk.gui.qt.aicpregistration/src/internal/org_mitk_gui_qt_aicpregistration_Activator.h
similarity index 73%
copy from Plugins/org.mitk.gui.qt.coreapplication/src/internal/org_mitk_gui_qt_coreapplication_Activator.h
copy to Plugins/org.mitk.gui.qt.aicpregistration/src/internal/org_mitk_gui_qt_aicpregistration_Activator.h
index 9ac0220f38..c2d13fe144 100644
--- a/Plugins/org.mitk.gui.qt.coreapplication/src/internal/org_mitk_gui_qt_coreapplication_Activator.h
+++ b/Plugins/org.mitk.gui.qt.aicpregistration/src/internal/org_mitk_gui_qt_aicpregistration_Activator.h
@@ -1,42 +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 MITKPLUGINACTIVATOR_H
-#define MITKPLUGINACTIVATOR_H
+#ifndef org_mitk_gui_qt_aicpregistration_Activator_h
+#define org_mitk_gui_qt_aicpregistration_Activator_h
#include <ctkPluginActivator.h>
namespace mitk {
-class org_mitk_gui_qt_coreapplication_Activator :
+class org_mitk_gui_qt_aicpregistration_Activator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
-}; // org_mitk_gui_common_Activator
-
-typedef org_mitk_gui_qt_coreapplication_Activator PluginActivator;
+}; // org_mitk_gui_qt_surfaceregistration_Activator
}
-#endif // MITKPLUGINACTIVATOR_H
+#endif // org_mitk_gui_qt_surfaceregistration_Activator_h
diff --git a/Plugins/org.mitk.gui.qt.application/CMakeLists.txt b/Plugins/org.mitk.gui.qt.application/CMakeLists.txt
index 7d52d7bed3..6b8916ba8a 100644
--- a/Plugins/org.mitk.gui.qt.application/CMakeLists.txt
+++ b/Plugins/org.mitk.gui.qt.application/CMakeLists.txt
@@ -1,8 +1,9 @@
project(org_mitk_gui_qt_application)
MACRO_CREATE_MITK_CTK_PLUGIN(
EXPORT_DIRECTIVE MITK_QT_APP
EXPORTED_INCLUDE_SUFFIXES src
MODULE_DEPENDS MitkQtWidgets
+ PACKAGE_DEPENDS Qt4|QtCore Qt5|OpenGL+Xml
SUBPROJECTS MITK-CoreUI
)
diff --git a/Plugins/org.mitk.gui.qt.application/src/QmitkDefaultDropTargetListener.cpp b/Plugins/org.mitk.gui.qt.application/src/QmitkDefaultDropTargetListener.cpp
index 73e6e9a065..c496bb4c6e 100644
--- a/Plugins/org.mitk.gui.qt.application/src/QmitkDefaultDropTargetListener.cpp
+++ b/Plugins/org.mitk.gui.qt.application/src/QmitkDefaultDropTargetListener.cpp
@@ -1,92 +1,93 @@
/*===================================================================
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 "QmitkDefaultDropTargetListener.h"
#include <QDebug>
#include <QDropEvent>
+#include <QMimeData>
#include <QStringList>
#include <QUrl>
#include "internal/org_mitk_gui_qt_application_Activator.h"
#include <berryIPreferencesService.h>
#include <berryPlatformUI.h>
#include <mitkWorkbenchUtil.h>
class QmitkDefaultDropTargetListenerPrivate
{
public:
berry::IPreferences::Pointer GetPreferences() const
{
berry::IPreferencesService::Pointer prefService = mitk::PluginActivator::GetInstance()->GetPreferencesService();
if (prefService)
{
return prefService->GetSystemPreferences()->Node("/General");
}
return berry::IPreferences::Pointer(0);
}
bool GetOpenEditor() const
{
berry::IPreferences::Pointer prefs = GetPreferences();
if(prefs.IsNotNull())
{
return prefs->GetBool("OpenEditor", true);
}
return true;
}
};
QmitkDefaultDropTargetListener::QmitkDefaultDropTargetListener()
: berry::IDropTargetListener(), d(new QmitkDefaultDropTargetListenerPrivate())
{
}
QmitkDefaultDropTargetListener::~QmitkDefaultDropTargetListener()
{
}
berry::IDropTargetListener::Events::Types QmitkDefaultDropTargetListener::GetDropTargetEventTypes() const
{
return Events::DROP;
}
void QmitkDefaultDropTargetListener::DropEvent(QDropEvent *event)
{
qDebug() << event->mimeData()->formats();
qDebug() << event->mimeData()->text();
QList<QUrl> fileNames = event->mimeData()->urls();
if (fileNames.empty())
return;
QStringList fileNames2;
//TODO Qt 4.7 API
//fileNames2.reserve(fileNames.size());
foreach(QUrl url, fileNames)
{
fileNames2.push_back(url.toLocalFile());
}
mitk::WorkbenchUtil::LoadFiles(fileNames2,
berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow(),
d->GetOpenEditor());
event->accept();
}
diff --git a/Plugins/org.mitk.gui.qt.application/src/internal/org_mitk_gui_qt_application_Activator.cpp b/Plugins/org.mitk.gui.qt.application/src/internal/org_mitk_gui_qt_application_Activator.cpp
index b9b06decb9..4d3c0aa5cf 100644
--- a/Plugins/org.mitk.gui.qt.application/src/internal/org_mitk_gui_qt_application_Activator.cpp
+++ b/Plugins/org.mitk.gui.qt.application/src/internal/org_mitk_gui_qt_application_Activator.cpp
@@ -1,73 +1,75 @@
/*===================================================================
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_application_Activator.h"
#include "QmitkGeneralPreferencePage.h"
#include "QmitkEditorsPreferencePage.h"
#include <QmitkRegisterClasses.h>
#include <QtPlugin>
namespace mitk
{
org_mitk_gui_qt_application_Activator* org_mitk_gui_qt_application_Activator::m_Instance = 0;
ctkPluginContext* org_mitk_gui_qt_application_Activator::m_Context = 0;
void org_mitk_gui_qt_application_Activator::start(ctkPluginContext* context)
{
this->m_Instance = this;
this->m_Context = context;
BERRY_REGISTER_EXTENSION_CLASS(QmitkGeneralPreferencePage, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkEditorsPreferencePage, context)
QmitkRegisterClasses();
this->m_PrefServiceTracker.reset(new ctkServiceTracker<berry::IPreferencesService*>(context));
this->m_PrefServiceTracker->open();
}
void org_mitk_gui_qt_application_Activator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
this->m_PrefServiceTracker.reset();
this->m_Context = 0;
this->m_Instance = 0;
}
ctkPluginContext* org_mitk_gui_qt_application_Activator::GetContext()
{
return m_Context;
}
org_mitk_gui_qt_application_Activator *org_mitk_gui_qt_application_Activator::GetInstance()
{
return m_Instance;
}
berry::IPreferencesService::Pointer org_mitk_gui_qt_application_Activator::GetPreferencesService()
{
return berry::IPreferencesService::Pointer(m_PrefServiceTracker->getService());
}
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_application, mitk::org_mitk_gui_qt_application_Activator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_application, mitk::org_mitk_gui_qt_application_Activator)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.application/src/internal/org_mitk_gui_qt_application_Activator.h b/Plugins/org.mitk.gui.qt.application/src/internal/org_mitk_gui_qt_application_Activator.h
index 3f9a16243a..4ff5371dc5 100644
--- a/Plugins/org.mitk.gui.qt.application/src/internal/org_mitk_gui_qt_application_Activator.h
+++ b/Plugins/org.mitk.gui.qt.application/src/internal/org_mitk_gui_qt_application_Activator.h
@@ -1,58 +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 MITKPLUGINACTIVATOR_H
#define MITKPLUGINACTIVATOR_H
#include <ctkPluginActivator.h>
#include <ctkServiceTracker.h>
#include <berryIPreferencesService.h>
namespace mitk {
class org_mitk_gui_qt_application_Activator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_application")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
static ctkPluginContext* GetContext();
static org_mitk_gui_qt_application_Activator* GetInstance();
berry::IPreferencesService::Pointer GetPreferencesService();
private:
static org_mitk_gui_qt_application_Activator* m_Instance;
static ctkPluginContext* m_Context;
QScopedPointer<ctkServiceTracker<berry::IPreferencesService*> > m_PrefServiceTracker;
}; // org_mitk_gui_common_Activator
typedef org_mitk_gui_qt_application_Activator PluginActivator;
}
#endif // MITKPLUGINACTIVATOR_H
diff --git a/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/QmitkBasicImageProcessingView.cpp b/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/QmitkBasicImageProcessingView.cpp
index aff7c6d02b..60d3d933e7 100644
--- a/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/QmitkBasicImageProcessingView.cpp
+++ b/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/QmitkBasicImageProcessingView.cpp
@@ -1,1355 +1,1355 @@
/*===================================================================
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 "QmitkBasicImageProcessingView.h"
// QT includes (GUI)
#include <qlabel.h>
#include <qspinbox.h>
#include <qpushbutton.h>
#include <qcheckbox.h>
#include <qgroupbox.h>
#include <qradiobutton.h>
#include <qmessagebox.h>
// Berry includes (selection service)
#include <berryISelectionService.h>
#include <berryIWorkbenchWindow.h>
// MITK includes (GUI)
#include "QmitkStdMultiWidget.h"
#include "QmitkDataNodeSelectionProvider.h"
#include "mitkDataNodeObject.h"
// MITK includes (general)
#include "mitkNodePredicateDataType.h"
#include "mitkNodePredicateDimension.h"
#include "mitkNodePredicateAnd.h"
#include "mitkImageTimeSelector.h"
#include "mitkVectorImageMapper2D.h"
#include "mitkProperties.h"
// Includes for image casting between ITK and MITK
#include "mitkImageCast.h"
#include "mitkITKImageImport.h"
// ITK includes (general)
#include <itkVectorImage.h>
#include <itkImageFileWriter.h>
// Morphological Operations
#include <itkBinaryBallStructuringElement.h>
#include <itkGrayscaleDilateImageFilter.h>
#include <itkGrayscaleErodeImageFilter.h>
#include <itkGrayscaleMorphologicalOpeningImageFilter.h>
#include <itkGrayscaleMorphologicalClosingImageFilter.h>
// Smoothing
#include <itkMedianImageFilter.h>
#include <itkDiscreteGaussianImageFilter.h>
#include <itkTotalVariationDenoisingImageFilter.h>
// Threshold
#include <itkBinaryThresholdImageFilter.h>
// Inversion
#include <itkInvertIntensityImageFilter.h>
// Derivatives
#include <itkGradientMagnitudeRecursiveGaussianImageFilter.h>
#include <itkLaplacianImageFilter.h>
#include <itkSobelEdgeDetectionImageFilter.h>
// Resampling
#include <itkResampleImageFilter.h>
#include <itkNearestNeighborInterpolateImageFunction.h>
#include <itkCastImageFilter.h>
#include <itkLinearInterpolateImageFunction.h>
// Image Arithmetics
#include <itkAddImageFilter.h>
#include <itkSubtractImageFilter.h>
#include <itkMultiplyImageFilter.h>
#include <itkDivideImageFilter.h>
// Boolean operations
#include <itkOrImageFilter.h>
#include <itkAndImageFilter.h>
#include <itkXorImageFilter.h>
// Flip Image
#include <itkFlipImageFilter.h>
#include <itkRescaleIntensityImageFilter.h>
// Convenient Definitions
typedef itk::Image<short, 3> ImageType;
typedef itk::Image<unsigned char, 3> SegmentationImageType;
typedef itk::Image<double, 3> FloatImageType;
typedef itk::Image<itk::Vector<float,3>, 3> VectorImageType;
typedef itk::BinaryBallStructuringElement<ImageType::PixelType, 3> BallType;
typedef itk::GrayscaleDilateImageFilter<ImageType, ImageType, BallType> DilationFilterType;
typedef itk::GrayscaleErodeImageFilter<ImageType, ImageType, BallType> ErosionFilterType;
typedef itk::GrayscaleMorphologicalOpeningImageFilter<ImageType, ImageType, BallType> OpeningFilterType;
typedef itk::GrayscaleMorphologicalClosingImageFilter<ImageType, ImageType, BallType> ClosingFilterType;
typedef itk::MedianImageFilter< ImageType, ImageType > MedianFilterType;
typedef itk::DiscreteGaussianImageFilter< ImageType, ImageType> GaussianFilterType;
typedef itk::TotalVariationDenoisingImageFilter<FloatImageType, FloatImageType> TotalVariationFilterType;
typedef itk::TotalVariationDenoisingImageFilter<VectorImageType, VectorImageType> VectorTotalVariationFilterType;
typedef itk::BinaryThresholdImageFilter< ImageType, ImageType > ThresholdFilterType;
typedef itk::InvertIntensityImageFilter< ImageType, ImageType > InversionFilterType;
typedef itk::GradientMagnitudeRecursiveGaussianImageFilter< ImageType, ImageType > GradientFilterType;
typedef itk::LaplacianImageFilter< FloatImageType, FloatImageType > LaplacianFilterType;
typedef itk::SobelEdgeDetectionImageFilter< FloatImageType, FloatImageType > SobelFilterType;
typedef itk::ResampleImageFilter< ImageType, ImageType > ResampleImageFilterType;
typedef itk::ResampleImageFilter< ImageType, ImageType > ResampleImageFilterType2;
typedef itk::CastImageFilter< ImageType, FloatImageType > ImagePTypeToFloatPTypeCasterType;
typedef itk::AddImageFilter< ImageType, ImageType, ImageType > AddFilterType;
typedef itk::SubtractImageFilter< ImageType, ImageType, ImageType > SubtractFilterType;
typedef itk::MultiplyImageFilter< ImageType, ImageType, ImageType > MultiplyFilterType;
typedef itk::DivideImageFilter< ImageType, ImageType, FloatImageType > DivideFilterType;
typedef itk::OrImageFilter< ImageType, ImageType > OrImageFilterType;
typedef itk::AndImageFilter< ImageType, ImageType > AndImageFilterType;
typedef itk::XorImageFilter< ImageType, ImageType > XorImageFilterType;
typedef itk::FlipImageFilter< ImageType > FlipImageFilterType;
typedef itk::LinearInterpolateImageFunction< ImageType, double > LinearInterpolatorType;
typedef itk::NearestNeighborInterpolateImageFunction< ImageType, double > NearestInterpolatorType;
QmitkBasicImageProcessing::QmitkBasicImageProcessing()
: QmitkFunctionality(),
m_Controls(NULL),
m_SelectedImageNode(NULL),
m_TimeStepperAdapter(NULL),
m_SelectionListener(NULL)
{
}
QmitkBasicImageProcessing::~QmitkBasicImageProcessing()
{
//berry::ISelectionService* s = GetSite()->GetWorkbenchWindow()->GetSelectionService();
//if(s)
// s->RemoveSelectionListener(m_SelectionListener);
}
void QmitkBasicImageProcessing::CreateQtPartControl(QWidget *parent)
{
if (m_Controls == NULL)
{
m_Controls = new Ui::QmitkBasicImageProcessingViewControls;
m_Controls->setupUi(parent);
this->CreateConnections();
//setup predictaes for combobox
mitk::NodePredicateDimension::Pointer dimensionPredicate = mitk::NodePredicateDimension::New(3);
mitk::NodePredicateDataType::Pointer imagePredicate = mitk::NodePredicateDataType::New("Image");
m_Controls->m_ImageSelector2->SetDataStorage(this->GetDefaultDataStorage());
m_Controls->m_ImageSelector2->SetPredicate(mitk::NodePredicateAnd::New(dimensionPredicate, imagePredicate));
}
m_Controls->gbTwoImageOps->hide();
m_SelectedImageNode = mitk::DataStorageSelection::New(this->GetDefaultDataStorage(), false);
}
void QmitkBasicImageProcessing::CreateConnections()
{
if ( m_Controls )
{
connect( (QObject*)(m_Controls->cbWhat1), SIGNAL( activated(int) ), this, SLOT( SelectAction(int) ) );
connect( (QObject*)(m_Controls->btnDoIt), SIGNAL(clicked()),(QObject*) this, SLOT(StartButtonClicked()));
connect( (QObject*)(m_Controls->cbWhat2), SIGNAL( activated(int) ), this, SLOT( SelectAction2(int) ) );
connect( (QObject*)(m_Controls->btnDoIt2), SIGNAL(clicked()),(QObject*) this, SLOT(StartButton2Clicked()));
connect( (QObject*)(m_Controls->rBOneImOp), SIGNAL( clicked() ), this, SLOT( ChangeGUI() ) );
connect( (QObject*)(m_Controls->rBTwoImOp), SIGNAL( clicked() ), this, SLOT( ChangeGUI() ) );
connect( (QObject*)(m_Controls->cbParam4), SIGNAL( activated(int) ), this, SLOT( SelectInterpolator(int) ) );
}
m_TimeStepperAdapter = new QmitkStepperAdapter((QObject*) m_Controls->sliceNavigatorTime,
GetActiveStdMultiWidget()->GetTimeNavigationController()->GetTime(), "sliceNavigatorTimeFromBIP");
}
void QmitkBasicImageProcessing::Activated()
{
QmitkFunctionality::Activated();
this->m_Controls->cbWhat1->clear();
- this->m_Controls->cbWhat1->insertItem( NOACTIONSELECTED, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Please select operation", 0, QApplication::UnicodeUTF8) ));
- this->m_Controls->cbWhat1->insertItem( CATEGORY_DENOISING, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "--- Denoising ---", 0, QApplication::UnicodeUTF8) ));
- this->m_Controls->cbWhat1->insertItem( GAUSSIAN, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Gaussian", 0, QApplication::UnicodeUTF8) ));
- this->m_Controls->cbWhat1->insertItem( MEDIAN, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Median", 0, QApplication::UnicodeUTF8) ));
- this->m_Controls->cbWhat1->insertItem( TOTALVARIATION, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Total Variation", 0, QApplication::UnicodeUTF8) ));
- this->m_Controls->cbWhat1->insertItem( CATEGORY_MORPHOLOGICAL, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "--- Morphological ---", 0, QApplication::UnicodeUTF8) ));
- this->m_Controls->cbWhat1->insertItem( DILATION, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Dilation", 0, QApplication::UnicodeUTF8) ));
- this->m_Controls->cbWhat1->insertItem( EROSION, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Erosion", 0, QApplication::UnicodeUTF8) ));
- this->m_Controls->cbWhat1->insertItem( OPENING, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Opening", 0, QApplication::UnicodeUTF8) ));
- this->m_Controls->cbWhat1->insertItem( CLOSING, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Closing", 0, QApplication::UnicodeUTF8) ));
- this->m_Controls->cbWhat1->insertItem( CATEGORY_EDGE_DETECTION, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "--- Edge Detection ---", 0, QApplication::UnicodeUTF8) ));
- this->m_Controls->cbWhat1->insertItem( GRADIENT, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Gradient", 0, QApplication::UnicodeUTF8) ));
- this->m_Controls->cbWhat1->insertItem( LAPLACIAN, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Laplacian (2nd Derivative)", 0, QApplication::UnicodeUTF8) ));
- this->m_Controls->cbWhat1->insertItem( SOBEL, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Sobel Operator", 0, QApplication::UnicodeUTF8) ));
- this->m_Controls->cbWhat1->insertItem( CATEGORY_MISC, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "--- Misc ---", 0, QApplication::UnicodeUTF8) ));
- this->m_Controls->cbWhat1->insertItem( THRESHOLD, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Threshold", 0, QApplication::UnicodeUTF8) ));
- this->m_Controls->cbWhat1->insertItem( INVERSION, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Image Inversion", 0, QApplication::UnicodeUTF8) ));
- this->m_Controls->cbWhat1->insertItem( DOWNSAMPLING, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Downsampling", 0, QApplication::UnicodeUTF8) ));
- this->m_Controls->cbWhat1->insertItem( FLIPPING, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Flipping", 0, QApplication::UnicodeUTF8) ));
- this->m_Controls->cbWhat1->insertItem( RESAMPLING, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Resample to", 0, QApplication::UnicodeUTF8) ));
- this->m_Controls->cbWhat1->insertItem( RESCALE, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Rescale image values", 0, QApplication::UnicodeUTF8) ));
+ this->m_Controls->cbWhat1->insertItem( NOACTIONSELECTED, "Please select operation");
+ this->m_Controls->cbWhat1->insertItem( CATEGORY_DENOISING, "--- Denoising ---");
+ this->m_Controls->cbWhat1->insertItem( GAUSSIAN, "Gaussian");
+ this->m_Controls->cbWhat1->insertItem( MEDIAN, "Median");
+ this->m_Controls->cbWhat1->insertItem( TOTALVARIATION, "Total Variation");
+ this->m_Controls->cbWhat1->insertItem( CATEGORY_MORPHOLOGICAL, "--- Morphological ---");
+ this->m_Controls->cbWhat1->insertItem( DILATION, "Dilation");
+ this->m_Controls->cbWhat1->insertItem( EROSION, "Erosion");
+ this->m_Controls->cbWhat1->insertItem( OPENING, "Opening");
+ this->m_Controls->cbWhat1->insertItem( CLOSING, "Closing");
+ this->m_Controls->cbWhat1->insertItem( CATEGORY_EDGE_DETECTION, "--- Edge Detection ---");
+ this->m_Controls->cbWhat1->insertItem( GRADIENT, "Gradient");
+ this->m_Controls->cbWhat1->insertItem( LAPLACIAN, "Laplacian (2nd Derivative)");
+ this->m_Controls->cbWhat1->insertItem( SOBEL, "Sobel Operator");
+ this->m_Controls->cbWhat1->insertItem( CATEGORY_MISC, "--- Misc ---");
+ this->m_Controls->cbWhat1->insertItem( THRESHOLD, "Threshold");
+ this->m_Controls->cbWhat1->insertItem( INVERSION, "Image Inversion");
+ this->m_Controls->cbWhat1->insertItem( DOWNSAMPLING, "Downsampling");
+ this->m_Controls->cbWhat1->insertItem( FLIPPING, "Flipping");
+ this->m_Controls->cbWhat1->insertItem( RESAMPLING, "Resample to");
+ this->m_Controls->cbWhat1->insertItem( RESCALE, "Rescale image values");
this->m_Controls->cbWhat2->clear();
- this->m_Controls->cbWhat2->insertItem( TWOIMAGESNOACTIONSELECTED, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Please select on operation", 0, QApplication::UnicodeUTF8) ) );
- this->m_Controls->cbWhat2->insertItem( CATEGORY_ARITHMETIC, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "--- Arithmetric operations ---", 0, QApplication::UnicodeUTF8) ) );
- this->m_Controls->cbWhat2->insertItem( ADD, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Add to Image 1:", 0, QApplication::UnicodeUTF8) ) );
- this->m_Controls->cbWhat2->insertItem( SUBTRACT, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Subtract from Image 1:", 0, QApplication::UnicodeUTF8) ) );
- this->m_Controls->cbWhat2->insertItem( MULTIPLY, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Multiply with Image 1:", 0, QApplication::UnicodeUTF8) ) );
- this->m_Controls->cbWhat2->insertItem( RESAMPLE_TO, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Resample Image 1 to fit geometry:", 0, QApplication::UnicodeUTF8) ) );
- this->m_Controls->cbWhat2->insertItem( DIVIDE, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Divide Image 1 by:", 0, QApplication::UnicodeUTF8) ) );
- this->m_Controls->cbWhat2->insertItem( CATEGORY_BOOLEAN, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "--- Boolean operations ---", 0, QApplication::UnicodeUTF8) ) );
- this->m_Controls->cbWhat2->insertItem( AND, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "AND", 0, QApplication::UnicodeUTF8) ) );
- this->m_Controls->cbWhat2->insertItem( OR, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "OR", 0, QApplication::UnicodeUTF8) ) );
- this->m_Controls->cbWhat2->insertItem( XOR, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "XOR", 0, QApplication::UnicodeUTF8) ) );
+ this->m_Controls->cbWhat2->insertItem( TWOIMAGESNOACTIONSELECTED, "Please select on operation" );
+ this->m_Controls->cbWhat2->insertItem( CATEGORY_ARITHMETIC, "--- Arithmetric operations ---" );
+ this->m_Controls->cbWhat2->insertItem( ADD, "Add to Image 1:" );
+ this->m_Controls->cbWhat2->insertItem( SUBTRACT, "Subtract from Image 1:" );
+ this->m_Controls->cbWhat2->insertItem( MULTIPLY, "Multiply with Image 1:" );
+ this->m_Controls->cbWhat2->insertItem( RESAMPLE_TO, "Resample Image 1 to fit geometry:" );
+ this->m_Controls->cbWhat2->insertItem( DIVIDE, "Divide Image 1 by:" );
+ this->m_Controls->cbWhat2->insertItem( CATEGORY_BOOLEAN, "--- Boolean operations ---" );
+ this->m_Controls->cbWhat2->insertItem( AND, "AND" );
+ this->m_Controls->cbWhat2->insertItem( OR, "OR" );
+ this->m_Controls->cbWhat2->insertItem( XOR, "XOR" );
this->m_Controls->cbParam4->clear();
- this->m_Controls->cbParam4->insertItem( LINEAR, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Linear", 0, QApplication::UnicodeUTF8) ) );
- this->m_Controls->cbParam4->insertItem( NEAREST, QString( QApplication::translate("QmitkBasicImageProcessingViewControls", "Nearest neighbor", 0, QApplication::UnicodeUTF8) ) );
+ this->m_Controls->cbParam4->insertItem( LINEAR, "Linear" );
+ this->m_Controls->cbParam4->insertItem( NEAREST, "Nearest neighbor" );
m_Controls->dsbParam1->hide();
m_Controls->dsbParam2->hide();
m_Controls->dsbParam3->hide();
m_Controls->tlParam3->hide();
m_Controls->tlParam4->hide();
m_Controls->cbParam4->hide();
}
//datamanager selection changed
void QmitkBasicImageProcessing::OnSelectionChanged(std::vector<mitk::DataNode*> nodes)
{
//any nodes there?
if (!nodes.empty())
{
// reset GUI
// this->ResetOneImageOpPanel();
m_Controls->sliceNavigatorTime->setEnabled(false);
m_Controls->leImage1->setText("Select an Image in Data Manager");
m_Controls->tlWhat1->setEnabled(false);
m_Controls->cbWhat1->setEnabled(false);
m_Controls->tlWhat2->setEnabled(false);
m_Controls->cbWhat2->setEnabled(false);
m_SelectedImageNode->RemoveAllNodes();
//get the selected Node
mitk::DataNode* _DataNode = nodes.front();
*m_SelectedImageNode = _DataNode;
//try to cast to image
mitk::Image::Pointer tempImage = dynamic_cast<mitk::Image*>(m_SelectedImageNode->GetNode()->GetData());
//no image
if( tempImage.IsNull() || (tempImage->IsInitialized() == false) )
{
m_Controls->leImage1->setText("Not an image.");
return;
}
//2D image
if( tempImage->GetDimension() < 3)
{
m_Controls->leImage1->setText("2D images are not supported.");
return;
}
//image
m_Controls->leImage1->setText(QString(m_SelectedImageNode->GetNode()->GetName().c_str()));
// button coding
if ( tempImage->GetDimension() > 3 )
{
m_Controls->sliceNavigatorTime->setEnabled(true);
m_Controls->tlTime->setEnabled(true);
}
m_Controls->tlWhat1->setEnabled(true);
m_Controls->cbWhat1->setEnabled(true);
m_Controls->tlWhat2->setEnabled(true);
m_Controls->cbWhat2->setEnabled(true);
}
}
void QmitkBasicImageProcessing::ChangeGUI()
{
if(m_Controls->rBOneImOp->isChecked())
{
m_Controls->gbTwoImageOps->hide();
m_Controls->gbOneImageOps->show();
}
else if(m_Controls->rBTwoImOp->isChecked())
{
m_Controls->gbOneImageOps->hide();
m_Controls->gbTwoImageOps->show();
}
}
void QmitkBasicImageProcessing::ResetOneImageOpPanel()
{
m_Controls->tlParam1->setText("Param1");
m_Controls->tlParam2->setText("Param2");
m_Controls->cbWhat1->setCurrentIndex(0);
m_Controls->tlTime->setEnabled(false);
this->ResetParameterPanel();
m_Controls->btnDoIt->setEnabled(false);
m_Controls->cbHideOrig->setEnabled(false);
}
void QmitkBasicImageProcessing::ResetParameterPanel()
{
m_Controls->tlParam->setEnabled(false);
m_Controls->tlParam1->setEnabled(false);
m_Controls->tlParam2->setEnabled(false);
m_Controls->tlParam3->setEnabled(false);
m_Controls->tlParam4->setEnabled(false);
m_Controls->sbParam1->setEnabled(false);
m_Controls->sbParam2->setEnabled(false);
m_Controls->dsbParam1->setEnabled(false);
m_Controls->dsbParam2->setEnabled(false);
m_Controls->dsbParam3->setEnabled(false);
m_Controls->cbParam4->setEnabled(false);
m_Controls->sbParam1->setValue(0);
m_Controls->sbParam2->setValue(0);
m_Controls->dsbParam1->setValue(0);
m_Controls->dsbParam2->setValue(0);
m_Controls->dsbParam3->setValue(0);
m_Controls->sbParam1->show();
m_Controls->sbParam2->show();
m_Controls->dsbParam1->hide();
m_Controls->dsbParam2->hide();
m_Controls->dsbParam3->hide();
m_Controls->cbParam4->hide();
m_Controls->tlParam3->hide();
m_Controls->tlParam4->hide();
}
void QmitkBasicImageProcessing::ResetTwoImageOpPanel()
{
m_Controls->cbWhat2->setCurrentIndex(0);
m_Controls->tlImage2->setEnabled(false);
m_Controls->m_ImageSelector2->setEnabled(false);
m_Controls->btnDoIt2->setEnabled(false);
}
void QmitkBasicImageProcessing::SelectAction(int action)
{
if ( ! m_SelectedImageNode->GetNode() ) return;
// Prepare GUI
this->ResetParameterPanel();
m_Controls->btnDoIt->setEnabled(false);
m_Controls->cbHideOrig->setEnabled(false);
QString text1 = "No Parameters";
QString text2 = "No Parameters";
QString text3 = "No Parameters";
QString text4 = "No Parameters";
if (action != 19)
{
m_Controls->dsbParam1->hide();
m_Controls->dsbParam2->hide();
m_Controls->dsbParam3->hide();
m_Controls->tlParam3->hide();
m_Controls->tlParam4->hide();
m_Controls->sbParam1->show();
m_Controls->sbParam2->show();
m_Controls->cbParam4->hide();
}
// check which operation the user has selected and set parameters and GUI accordingly
switch (action)
{
case 2:
{
m_SelectedAction = GAUSSIAN;
m_Controls->tlParam1->setEnabled(true);
m_Controls->sbParam1->setEnabled(true);
text1 = "&Variance:";
m_Controls->sbParam1->setMinimum( 0 );
m_Controls->sbParam1->setMaximum( 200 );
m_Controls->sbParam1->setValue( 2 );
break;
}
case 3:
{
m_SelectedAction = MEDIAN;
m_Controls->tlParam1->setEnabled(true);
m_Controls->sbParam1->setEnabled(true);
text1 = "&Radius:";
m_Controls->sbParam1->setMinimum( 0 );
m_Controls->sbParam1->setMaximum( 200 );
m_Controls->sbParam1->setValue( 3 );
break;
}
case 4:
{
m_SelectedAction = TOTALVARIATION;
m_Controls->tlParam1->setEnabled(true);
m_Controls->sbParam1->setEnabled(true);
m_Controls->tlParam2->setEnabled(true);
m_Controls->sbParam2->setEnabled(true);
text1 = "Number Iterations:";
text2 = "Regularization\n(Lambda/1000):";
m_Controls->sbParam1->setMinimum( 1 );
m_Controls->sbParam1->setMaximum( 1000 );
m_Controls->sbParam1->setValue( 40 );
m_Controls->sbParam2->setMinimum( 0 );
m_Controls->sbParam2->setMaximum( 100000 );
m_Controls->sbParam2->setValue( 1 );
break;
}
case 6:
{
m_SelectedAction = DILATION;
m_Controls->tlParam1->setEnabled(true);
m_Controls->sbParam1->setEnabled(true);
text1 = "&Radius:";
m_Controls->sbParam1->setMinimum( 0 );
m_Controls->sbParam1->setMaximum( 200 );
m_Controls->sbParam1->setValue( 3 );
break;
}
case 7:
{
m_SelectedAction = EROSION;
m_Controls->tlParam1->setEnabled(true);
m_Controls->sbParam1->setEnabled(true);
text1 = "&Radius:";
m_Controls->sbParam1->setMinimum( 0 );
m_Controls->sbParam1->setMaximum( 200 );
m_Controls->sbParam1->setValue( 3 );
break;
}
case 8:
{
m_SelectedAction = OPENING;
m_Controls->tlParam1->setEnabled(true);
m_Controls->sbParam1->setEnabled(true);
text1 = "&Radius:";
m_Controls->sbParam1->setMinimum( 0 );
m_Controls->sbParam1->setMaximum( 200 );
m_Controls->sbParam1->setValue( 3 );
break;
}
case 9:
{
m_SelectedAction = CLOSING;
m_Controls->tlParam1->setEnabled(true);
m_Controls->sbParam1->setEnabled(true);
text1 = "&Radius:";
m_Controls->sbParam1->setMinimum( 0 );
m_Controls->sbParam1->setMaximum( 200 );
m_Controls->sbParam1->setValue( 3 );
break;
}
case 11:
{
m_SelectedAction = GRADIENT;
m_Controls->tlParam1->setEnabled(true);
m_Controls->sbParam1->setEnabled(true);
text1 = "Sigma of Gaussian Kernel:\n(in Image Spacing Units)";
m_Controls->sbParam1->setMinimum( 0 );
m_Controls->sbParam1->setMaximum( 200 );
m_Controls->sbParam1->setValue( 2 );
break;
}
case 12:
{
m_SelectedAction = LAPLACIAN;
break;
}
case 13:
{
m_SelectedAction = SOBEL;
break;
}
case 15:
{
m_SelectedAction = THRESHOLD;
m_Controls->tlParam1->setEnabled(true);
m_Controls->sbParam1->setEnabled(true);
m_Controls->tlParam2->setEnabled(true);
m_Controls->sbParam2->setEnabled(true);
text1 = "Lower threshold:";
text2 = "Upper threshold:";
m_Controls->sbParam1->setMinimum( -100000 );
m_Controls->sbParam1->setMaximum( 100000 );
m_Controls->sbParam1->setValue( 0 );
m_Controls->sbParam2->setMinimum( -100000 );
m_Controls->sbParam2->setMaximum( 100000 );
m_Controls->sbParam2->setValue( 300 );
break;
}
case 16:
{
m_SelectedAction = INVERSION;
break;
}
case 17:
{
m_SelectedAction = DOWNSAMPLING;
m_Controls->tlParam1->setEnabled(true);
m_Controls->sbParam1->setEnabled(true);
text1 = "Downsampling by Factor:";
m_Controls->sbParam1->setMinimum( 1 );
m_Controls->sbParam1->setMaximum( 100 );
m_Controls->sbParam1->setValue( 2 );
break;
}
case 18:
{
m_SelectedAction = FLIPPING;
m_Controls->tlParam1->setEnabled(true);
m_Controls->sbParam1->setEnabled(true);
text1 = "Flip across axis:";
m_Controls->sbParam1->setMinimum( 0 );
m_Controls->sbParam1->setMaximum( 2 );
m_Controls->sbParam1->setValue( 1 );
break;
}
case 19:
{
m_SelectedAction = RESAMPLING;
m_Controls->tlParam1->setEnabled(true);
m_Controls->sbParam1->setEnabled(false);
m_Controls->sbParam1->hide();
m_Controls->dsbParam1->show();
m_Controls->dsbParam1->setEnabled(true);
m_Controls->tlParam2->setEnabled(true);
m_Controls->sbParam2->setEnabled(false);
m_Controls->sbParam2->hide();
m_Controls->dsbParam2->show();
m_Controls->dsbParam2->setEnabled(true);
m_Controls->tlParam3->show();
m_Controls->tlParam3->setEnabled(true);
m_Controls->dsbParam3->show();
m_Controls->dsbParam3->setEnabled(true);
m_Controls->tlParam4->show();
m_Controls->tlParam4->setEnabled(true);
m_Controls->cbParam4->show();
m_Controls->cbParam4->setEnabled(true);
m_Controls->dsbParam1->setMinimum(0.01);
m_Controls->dsbParam1->setMaximum(10.0);
m_Controls->dsbParam1->setSingleStep(0.1);
m_Controls->dsbParam1->setValue(0.3);
m_Controls->dsbParam2->setMinimum(0.01);
m_Controls->dsbParam2->setMaximum(10.0);
m_Controls->dsbParam2->setSingleStep(0.1);
m_Controls->dsbParam2->setValue(0.3);
m_Controls->dsbParam3->setMinimum(0.01);
m_Controls->dsbParam3->setMaximum(10.0);
m_Controls->dsbParam3->setSingleStep(0.1);
m_Controls->dsbParam3->setValue(1.5);
text1 = "x-spacing:";
text2 = "y-spacing:";
text3 = "z-spacing:";
text4 = "Interplation:";
break;
}
case 20:
{
m_SelectedAction = RESCALE;
m_Controls->dsbParam1->show();
m_Controls->tlParam1->show();
m_Controls->dsbParam1->setEnabled(true);
m_Controls->tlParam1->setEnabled(true);
m_Controls->dsbParam2->show();
m_Controls->tlParam2->show();
m_Controls->dsbParam2->setEnabled(true);
m_Controls->tlParam2->setEnabled(true);
text1 = "Output minimum:";
text2 = "Output maximum:";
break;
}
default: return;
}
m_Controls->tlParam->setEnabled(true);
m_Controls->tlParam1->setText(text1);
m_Controls->tlParam2->setText(text2);
m_Controls->tlParam3->setText(text3);
m_Controls->tlParam4->setText(text4);
m_Controls->btnDoIt->setEnabled(true);
m_Controls->cbHideOrig->setEnabled(true);
}
void QmitkBasicImageProcessing::StartButtonClicked()
{
if(!m_SelectedImageNode->GetNode()) return;
this->BusyCursorOn();
mitk::Image::Pointer newImage;
try
{
newImage = dynamic_cast<mitk::Image*>(m_SelectedImageNode->GetNode()->GetData());
}
catch ( std::exception &e )
{
QString exceptionString = "An error occured during image loading:\n";
exceptionString.append( e.what() );
QMessageBox::warning( NULL, "Basic Image Processing", exceptionString , QMessageBox::Ok, QMessageBox::NoButton );
this->BusyCursorOff();
return;
}
// check if input image is valid, casting does not throw exception when casting from 'NULL-Object'
if ( (! newImage) || (newImage->IsInitialized() == false) )
{
this->BusyCursorOff();
QMessageBox::warning( NULL, "Basic Image Processing", "Input image is broken or not initialized. Returning.", QMessageBox::Ok, QMessageBox::NoButton );
return;
}
// check if operation is done on 4D a image time step
if(newImage->GetDimension() > 3)
{
mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New();
timeSelector->SetInput(newImage);
timeSelector->SetTimeNr( ((QmitkSliderNavigatorWidget*)m_Controls->sliceNavigatorTime)->GetPos() );
timeSelector->Update();
newImage = timeSelector->GetOutput();
}
// check if image or vector image
ImageType::Pointer itkImage = ImageType::New();
VectorImageType::Pointer itkVecImage = VectorImageType::New();
int isVectorImage = newImage->GetPixelType().GetNumberOfComponents();
if(isVectorImage > 1)
{
CastToItkImage( newImage, itkVecImage );
}
else
{
CastToItkImage( newImage, itkImage );
}
std::stringstream nameAddition("");
int param1 = m_Controls->sbParam1->value();
int param2 = m_Controls->sbParam2->value();
double dparam1 = m_Controls->dsbParam1->value();
double dparam2 = m_Controls->dsbParam2->value();
double dparam3 = m_Controls->dsbParam3->value();
try{
switch (m_SelectedAction)
{
case GAUSSIAN:
{
GaussianFilterType::Pointer gaussianFilter = GaussianFilterType::New();
gaussianFilter->SetInput( itkImage );
gaussianFilter->SetVariance( param1 );
gaussianFilter->UpdateLargestPossibleRegion();
newImage = mitk::ImportItkImage(gaussianFilter->GetOutput())->Clone();
nameAddition << "_Gaussian_var_" << param1;
std::cout << "Gaussian filtering successful." << std::endl;
break;
}
case MEDIAN:
{
MedianFilterType::Pointer medianFilter = MedianFilterType::New();
MedianFilterType::InputSizeType size;
size.Fill(param1);
medianFilter->SetRadius( size );
medianFilter->SetInput(itkImage);
medianFilter->UpdateLargestPossibleRegion();
newImage = mitk::ImportItkImage(medianFilter->GetOutput())->Clone();
nameAddition << "_Median_radius_" << param1;
std::cout << "Median Filtering successful." << std::endl;
break;
}
case TOTALVARIATION:
{
if(isVectorImage > 1)
{
VectorTotalVariationFilterType::Pointer TVFilter
= VectorTotalVariationFilterType::New();
TVFilter->SetInput( itkVecImage.GetPointer() );
TVFilter->SetNumberIterations(param1);
TVFilter->SetLambda(double(param2)/1000.);
TVFilter->UpdateLargestPossibleRegion();
newImage = mitk::ImportItkImage(TVFilter->GetOutput())->Clone();
}
else
{
ImagePTypeToFloatPTypeCasterType::Pointer floatCaster = ImagePTypeToFloatPTypeCasterType::New();
floatCaster->SetInput( itkImage );
floatCaster->Update();
FloatImageType::Pointer fImage = floatCaster->GetOutput();
TotalVariationFilterType::Pointer TVFilter
= TotalVariationFilterType::New();
TVFilter->SetInput( fImage.GetPointer() );
TVFilter->SetNumberIterations(param1);
TVFilter->SetLambda(double(param2)/1000.);
TVFilter->UpdateLargestPossibleRegion();
newImage = mitk::ImportItkImage(TVFilter->GetOutput())->Clone();
}
nameAddition << "_TV_Iter_" << param1 << "_L_" << param2;
std::cout << "Total Variation Filtering successful." << std::endl;
break;
}
case DILATION:
{
BallType binaryBall;
binaryBall.SetRadius( param1 );
binaryBall.CreateStructuringElement();
DilationFilterType::Pointer dilationFilter = DilationFilterType::New();
dilationFilter->SetInput( itkImage );
dilationFilter->SetKernel( binaryBall );
dilationFilter->UpdateLargestPossibleRegion();
newImage = mitk::ImportItkImage(dilationFilter->GetOutput())->Clone();
nameAddition << "_Dilated_by_" << param1;
std::cout << "Dilation successful." << std::endl;
break;
}
case EROSION:
{
BallType binaryBall;
binaryBall.SetRadius( param1 );
binaryBall.CreateStructuringElement();
ErosionFilterType::Pointer erosionFilter = ErosionFilterType::New();
erosionFilter->SetInput( itkImage );
erosionFilter->SetKernel( binaryBall );
erosionFilter->UpdateLargestPossibleRegion();
newImage = mitk::ImportItkImage(erosionFilter->GetOutput())->Clone();
nameAddition << "_Eroded_by_" << param1;
std::cout << "Erosion successful." << std::endl;
break;
}
case OPENING:
{
BallType binaryBall;
binaryBall.SetRadius( param1 );
binaryBall.CreateStructuringElement();
OpeningFilterType::Pointer openFilter = OpeningFilterType::New();
openFilter->SetInput( itkImage );
openFilter->SetKernel( binaryBall );
openFilter->UpdateLargestPossibleRegion();
newImage = mitk::ImportItkImage(openFilter->GetOutput())->Clone();
nameAddition << "_Opened_by_" << param1;
std::cout << "Opening successful." << std::endl;
break;
}
case CLOSING:
{
BallType binaryBall;
binaryBall.SetRadius( param1 );
binaryBall.CreateStructuringElement();
ClosingFilterType::Pointer closeFilter = ClosingFilterType::New();
closeFilter->SetInput( itkImage );
closeFilter->SetKernel( binaryBall );
closeFilter->UpdateLargestPossibleRegion();
newImage = mitk::ImportItkImage(closeFilter->GetOutput())->Clone();
nameAddition << "_Closed_by_" << param1;
std::cout << "Closing successful." << std::endl;
break;
}
case GRADIENT:
{
GradientFilterType::Pointer gradientFilter = GradientFilterType::New();
gradientFilter->SetInput( itkImage );
gradientFilter->SetSigma( param1 );
gradientFilter->UpdateLargestPossibleRegion();
newImage = mitk::ImportItkImage(gradientFilter->GetOutput())->Clone();
nameAddition << "_Gradient_sigma_" << param1;
std::cout << "Gradient calculation successful." << std::endl;
break;
}
case LAPLACIAN:
{
// the laplace filter requires a float type image as input, we need to cast the itkImage
// to correct type
ImagePTypeToFloatPTypeCasterType::Pointer caster = ImagePTypeToFloatPTypeCasterType::New();
caster->SetInput( itkImage );
caster->Update();
FloatImageType::Pointer fImage = caster->GetOutput();
LaplacianFilterType::Pointer laplacianFilter = LaplacianFilterType::New();
laplacianFilter->SetInput( fImage );
laplacianFilter->UpdateLargestPossibleRegion();
newImage = mitk::ImportItkImage(laplacianFilter->GetOutput())->Clone();
nameAddition << "_Second_Derivative";
std::cout << "Laplacian filtering successful." << std::endl;
break;
}
case SOBEL:
{
// the sobel filter requires a float type image as input, we need to cast the itkImage
// to correct type
ImagePTypeToFloatPTypeCasterType::Pointer caster = ImagePTypeToFloatPTypeCasterType::New();
caster->SetInput( itkImage );
caster->Update();
FloatImageType::Pointer fImage = caster->GetOutput();
SobelFilterType::Pointer sobelFilter = SobelFilterType::New();
sobelFilter->SetInput( fImage );
sobelFilter->UpdateLargestPossibleRegion();
newImage = mitk::ImportItkImage(sobelFilter->GetOutput())->Clone();
nameAddition << "_Sobel";
std::cout << "Edge Detection successful." << std::endl;
break;
}
case THRESHOLD:
{
ThresholdFilterType::Pointer thFilter = ThresholdFilterType::New();
thFilter->SetLowerThreshold(param1 < param2 ? param1 : param2);
thFilter->SetUpperThreshold(param2 > param1 ? param2 : param1);
thFilter->SetInsideValue(1);
thFilter->SetOutsideValue(0);
thFilter->SetInput(itkImage);
thFilter->UpdateLargestPossibleRegion();
newImage = mitk::ImportItkImage(thFilter->GetOutput())->Clone();
nameAddition << "_Threshold";
std::cout << "Thresholding successful." << std::endl;
break;
}
case INVERSION:
{
InversionFilterType::Pointer invFilter = InversionFilterType::New();
mitk::ScalarType min = newImage->GetScalarValueMin();
mitk::ScalarType max = newImage->GetScalarValueMax();
invFilter->SetMaximum( max + min );
invFilter->SetInput(itkImage);
invFilter->UpdateLargestPossibleRegion();
newImage = mitk::ImportItkImage(invFilter->GetOutput())->Clone();
nameAddition << "_Inverted";
std::cout << "Image inversion successful." << std::endl;
break;
}
case DOWNSAMPLING:
{
ResampleImageFilterType::Pointer downsampler = ResampleImageFilterType::New();
downsampler->SetInput( itkImage );
NearestInterpolatorType::Pointer interpolator = NearestInterpolatorType::New();
downsampler->SetInterpolator( interpolator );
downsampler->SetDefaultPixelValue( 0 );
ResampleImageFilterType::SpacingType spacing = itkImage->GetSpacing();
spacing *= (double) param1;
downsampler->SetOutputSpacing( spacing );
downsampler->SetOutputOrigin( itkImage->GetOrigin() );
downsampler->SetOutputDirection( itkImage->GetDirection() );
ResampleImageFilterType::SizeType size = itkImage->GetLargestPossibleRegion().GetSize();
for ( int i = 0; i < 3; ++i )
{
size[i] /= param1;
}
downsampler->SetSize( size );
downsampler->UpdateLargestPossibleRegion();
newImage = mitk::ImportItkImage(downsampler->GetOutput())->Clone();
nameAddition << "_Downsampled_by_" << param1;
std::cout << "Downsampling successful." << std::endl;
break;
}
case FLIPPING:
{
FlipImageFilterType::Pointer flipper = FlipImageFilterType::New();
flipper->SetInput( itkImage );
itk::FixedArray<bool, 3> flipAxes;
for(int i=0; i<3; ++i)
{
if(i == param1)
{
flipAxes[i] = true;
}
else
{
flipAxes[i] = false;
}
}
flipper->SetFlipAxes(flipAxes);
flipper->UpdateLargestPossibleRegion();
newImage = mitk::ImportItkImage(flipper->GetOutput())->Clone();
std::cout << "Image flipping successful." << std::endl;
break;
}
case RESAMPLING:
{
std::string selectedInterpolator;
ResampleImageFilterType::Pointer resampler = ResampleImageFilterType::New();
switch (m_SelectedInterpolation)
{
case LINEAR:
{
LinearInterpolatorType::Pointer interpolator = LinearInterpolatorType::New();
resampler->SetInterpolator(interpolator);
selectedInterpolator = "Linear";
break;
}
case NEAREST:
{
NearestInterpolatorType::Pointer interpolator = NearestInterpolatorType::New();
resampler->SetInterpolator(interpolator);
selectedInterpolator = "Nearest";
break;
}
default:
{
LinearInterpolatorType::Pointer interpolator = LinearInterpolatorType::New();
resampler->SetInterpolator(interpolator);
selectedInterpolator = "Linear";
break;
}
}
resampler->SetInput( itkImage );
resampler->SetOutputOrigin( itkImage->GetOrigin() );
ImageType::SizeType input_size = itkImage->GetLargestPossibleRegion().GetSize();
ImageType::SpacingType input_spacing = itkImage->GetSpacing();
ImageType::SizeType output_size;
ImageType::SpacingType output_spacing;
output_size[0] = input_size[0] * (input_spacing[0] / dparam1);
output_size[1] = input_size[1] * (input_spacing[1] / dparam2);
output_size[2] = input_size[2] * (input_spacing[2] / dparam3);
output_spacing [0] = dparam1;
output_spacing [1] = dparam2;
output_spacing [2] = dparam3;
resampler->SetSize( output_size );
resampler->SetOutputSpacing( output_spacing );
resampler->SetOutputDirection( itkImage->GetDirection() );
resampler->UpdateLargestPossibleRegion();
ImageType::Pointer resampledImage = resampler->GetOutput();
newImage = mitk::ImportItkImage( resampledImage );
nameAddition << "_Resampled_" << selectedInterpolator;
std::cout << "Resampling successful." << std::endl;
break;
}
case RESCALE:
{
FloatImageType::Pointer floatImage = FloatImageType::New();
CastToItkImage( newImage, floatImage );
itk::RescaleIntensityImageFilter<FloatImageType,FloatImageType>::Pointer filter = itk::RescaleIntensityImageFilter<FloatImageType,FloatImageType>::New();
filter->SetInput(0, floatImage);
filter->SetOutputMinimum(dparam1);
filter->SetOutputMaximum(dparam2);
filter->Update();
floatImage = filter->GetOutput();
newImage = mitk::Image::New();
newImage->InitializeByItk(floatImage.GetPointer());
newImage->SetVolume(floatImage->GetBufferPointer());
nameAddition << "_Rescaled";
std::cout << "Rescaling successful." << std::endl;
break;
}
default:
this->BusyCursorOff();
return;
}
}
catch (...)
{
this->BusyCursorOff();
QMessageBox::warning(NULL, "Warning", "Problem when applying filter operation. Check your input...");
return;
}
newImage->DisconnectPipeline();
// adjust level/window to new image
mitk::LevelWindow levelwindow;
levelwindow.SetAuto( newImage );
mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New();
levWinProp->SetLevelWindow( levelwindow );
// compose new image name
std::string name = m_SelectedImageNode->GetNode()->GetName();
if (name.find(".pic.gz") == name.size() -7 )
{
name = name.substr(0,name.size() -7);
}
name.append( nameAddition.str() );
// create final result MITK data storage node
mitk::DataNode::Pointer result = mitk::DataNode::New();
result->SetProperty( "levelwindow", levWinProp );
result->SetProperty( "name", mitk::StringProperty::New( name.c_str() ) );
result->SetData( newImage );
// for vector images, a different mapper is needed
if(isVectorImage > 1)
{
mitk::VectorImageMapper2D::Pointer mapper =
mitk::VectorImageMapper2D::New();
result->SetMapper(1,mapper);
}
// reset GUI to ease further processing
// this->ResetOneImageOpPanel();
// add new image to data storage and set as active to ease further processing
GetDefaultDataStorage()->Add( result, m_SelectedImageNode->GetNode() );
if ( m_Controls->cbHideOrig->isChecked() == true )
m_SelectedImageNode->GetNode()->SetProperty( "visible", mitk::BoolProperty::New(false) );
// TODO!! m_Controls->m_ImageSelector1->SetSelectedNode(result);
// show the results
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
this->BusyCursorOff();
}
void QmitkBasicImageProcessing::SelectAction2(int operation)
{
// check which operation the user has selected and set parameters and GUI accordingly
switch (operation)
{
case 2:
m_SelectedOperation = ADD;
break;
case 3:
m_SelectedOperation = SUBTRACT;
break;
case 4:
m_SelectedOperation = MULTIPLY;
break;
case 5:
m_SelectedOperation = DIVIDE;
break;
case 6:
m_SelectedOperation = RESAMPLE_TO;
break;
case 8:
m_SelectedOperation = AND;
break;
case 9:
m_SelectedOperation = OR;
break;
case 10:
m_SelectedOperation = XOR;
break;
default:
// this->ResetTwoImageOpPanel();
return;
}
m_Controls->tlImage2->setEnabled(true);
m_Controls->m_ImageSelector2->setEnabled(true);
m_Controls->btnDoIt2->setEnabled(true);
}
void QmitkBasicImageProcessing::StartButton2Clicked()
{
mitk::Image::Pointer newImage1 = dynamic_cast<mitk::Image*>
(m_SelectedImageNode->GetNode()->GetData());
mitk::Image::Pointer newImage2 = dynamic_cast<mitk::Image*>
(m_Controls->m_ImageSelector2->GetSelectedNode()->GetData());
// check if images are valid
if( (!newImage1) || (!newImage2) || (newImage1->IsInitialized() == false) || (newImage2->IsInitialized() == false) )
{
itkGenericExceptionMacro(<< "At least one of the input images are broken or not initialized. Returning");
return;
}
this->BusyCursorOn();
// this->ResetTwoImageOpPanel();
// check if 4D image and use filter on correct time step
int time = ((QmitkSliderNavigatorWidget*)m_Controls->sliceNavigatorTime)->GetPos();
if(newImage1->GetDimension() > 3)
{
mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New();
timeSelector->SetInput(newImage1);
timeSelector->SetTimeNr( time );
timeSelector->UpdateLargestPossibleRegion();
newImage1 = timeSelector->GetOutput();
newImage1->DisconnectPipeline();
timeSelector->SetInput(newImage2);
timeSelector->SetTimeNr( time );
timeSelector->UpdateLargestPossibleRegion();
newImage2 = timeSelector->GetOutput();
newImage2->DisconnectPipeline();
}
// reset GUI for better usability
// this->ResetTwoImageOpPanel();
ImageType::Pointer itkImage1 = ImageType::New();
ImageType::Pointer itkImage2 = ImageType::New();
CastToItkImage( newImage1, itkImage1 );
CastToItkImage( newImage2, itkImage2 );
// Remove temp image
newImage2 = NULL;
std::string nameAddition = "";
try
{
switch (m_SelectedOperation)
{
case ADD:
{
AddFilterType::Pointer addFilter = AddFilterType::New();
addFilter->SetInput1( itkImage1 );
addFilter->SetInput2( itkImage2 );
addFilter->UpdateLargestPossibleRegion();
newImage1 = mitk::ImportItkImage(addFilter->GetOutput())->Clone();
nameAddition = "_Added";
}
break;
case SUBTRACT:
{
SubtractFilterType::Pointer subFilter = SubtractFilterType::New();
subFilter->SetInput1( itkImage1 );
subFilter->SetInput2( itkImage2 );
subFilter->UpdateLargestPossibleRegion();
newImage1 = mitk::ImportItkImage(subFilter->GetOutput())->Clone();
nameAddition = "_Subtracted";
}
break;
case MULTIPLY:
{
MultiplyFilterType::Pointer multFilter = MultiplyFilterType::New();
multFilter->SetInput1( itkImage1 );
multFilter->SetInput2( itkImage2 );
multFilter->UpdateLargestPossibleRegion();
newImage1 = mitk::ImportItkImage(multFilter->GetOutput())->Clone();
nameAddition = "_Multiplied";
}
break;
case DIVIDE:
{
DivideFilterType::Pointer divFilter = DivideFilterType::New();
divFilter->SetInput1( itkImage1 );
divFilter->SetInput2( itkImage2 );
divFilter->UpdateLargestPossibleRegion();
newImage1 = mitk::ImportItkImage<FloatImageType>(divFilter->GetOutput())->Clone();
nameAddition = "_Divided";
}
break;
case AND:
{
AndImageFilterType::Pointer andFilter = AndImageFilterType::New();
andFilter->SetInput1( itkImage1 );
andFilter->SetInput2( itkImage2 );
andFilter->UpdateLargestPossibleRegion();
newImage1 = mitk::ImportItkImage(andFilter->GetOutput())->Clone();
nameAddition = "_AND";
break;
}
case OR:
{
OrImageFilterType::Pointer orFilter = OrImageFilterType::New();
orFilter->SetInput1( itkImage1 );
orFilter->SetInput2( itkImage2 );
orFilter->UpdateLargestPossibleRegion();
newImage1 = mitk::ImportItkImage(orFilter->GetOutput())->Clone();
nameAddition = "_OR";
break;
}
case XOR:
{
XorImageFilterType::Pointer xorFilter = XorImageFilterType::New();
xorFilter->SetInput1( itkImage1 );
xorFilter->SetInput2( itkImage2 );
xorFilter->UpdateLargestPossibleRegion();
newImage1 = mitk::ImportItkImage(xorFilter->GetOutput())->Clone();
nameAddition = "_XOR";
break;
}
case RESAMPLE_TO:
{
itk::NearestNeighborInterpolateImageFunction<ImageType>::Pointer nn_interpolator
= itk::NearestNeighborInterpolateImageFunction<ImageType>::New();
ResampleImageFilterType2::Pointer resampleFilter = ResampleImageFilterType2::New();
resampleFilter->SetInput( itkImage1 );
resampleFilter->SetReferenceImage( itkImage2 );
resampleFilter->SetUseReferenceImage( true );
resampleFilter->SetInterpolator( nn_interpolator );
resampleFilter->SetDefaultPixelValue( 0 );
try
{
resampleFilter->UpdateLargestPossibleRegion();
}
catch( const itk::ExceptionObject &e)
{
MITK_WARN << "Updating resampling filter failed. ";
MITK_WARN << "REASON: " << e.what();
}
ImageType::Pointer resampledImage = resampleFilter->GetOutput();
newImage1 = mitk::ImportItkImage( resampledImage )->Clone();
nameAddition = "_Resampled";
break;
}
default:
std::cout << "Something went wrong..." << std::endl;
this->BusyCursorOff();
return;
}
}
catch (const itk::ExceptionObject& e )
{
this->BusyCursorOff();
QMessageBox::warning(NULL, "ITK Exception", e.what() );
QMessageBox::warning(NULL, "Warning", "Problem when applying arithmetic operation to two images. Check dimensions of input images.");
return;
}
// disconnect pipeline; images will not be reused
newImage1->DisconnectPipeline();
itkImage1 = NULL;
itkImage2 = NULL;
// adjust level/window to new image and compose new image name
mitk::LevelWindow levelwindow;
levelwindow.SetAuto( newImage1 );
mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New();
levWinProp->SetLevelWindow( levelwindow );
std::string name = m_SelectedImageNode->GetNode()->GetName();
if (name.find(".pic.gz") == name.size() -7 )
{
name = name.substr(0,name.size() -7);
}
// create final result MITK data storage node
mitk::DataNode::Pointer result = mitk::DataNode::New();
result->SetProperty( "levelwindow", levWinProp );
result->SetProperty( "name", mitk::StringProperty::New( (name + nameAddition ).c_str() ));
result->SetData( newImage1 );
GetDefaultDataStorage()->Add( result, m_SelectedImageNode->GetNode() );
// show only the newly created image
m_SelectedImageNode->GetNode()->SetProperty( "visible", mitk::BoolProperty::New(false) );
m_Controls->m_ImageSelector2->GetSelectedNode()->SetProperty( "visible", mitk::BoolProperty::New(false) );
// show the newly created image
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
this->BusyCursorOff();
}
void QmitkBasicImageProcessing::SelectInterpolator(int interpolator)
{
switch (interpolator)
{
case 0:
{
m_SelectedInterpolation = LINEAR;
break;
}
case 1:
{
m_SelectedInterpolation = NEAREST;
break;
}
}
}
diff --git a/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/mitkBasicImageProcessingActivator.cpp b/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/mitkBasicImageProcessingActivator.cpp
index be704411ad..7683d4082e 100644
--- a/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/mitkBasicImageProcessingActivator.cpp
+++ b/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/mitkBasicImageProcessingActivator.cpp
@@ -1,35 +1,37 @@
/*===================================================================
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 "mitkBasicImageProcessingActivator.h"
#include "QmitkBasicImageProcessingView.h"
#include <QtPlugin>
namespace mitk {
void BasicImageProcessingActivator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(QmitkBasicImageProcessing, context)
}
void BasicImageProcessingActivator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_basicimageprocessing, mitk::BasicImageProcessingActivator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_basicimageprocessing, mitk::BasicImageProcessingActivator)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/mitkBasicImageProcessingActivator.h b/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/mitkBasicImageProcessingActivator.h
index 062920d5ca..45c6f516f7 100644
--- a/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/mitkBasicImageProcessingActivator.h
+++ b/Plugins/org.mitk.gui.qt.basicimageprocessing/src/internal/mitkBasicImageProcessingActivator.h
@@ -1,39 +1,42 @@
/*===================================================================
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 MITKBASICIMAGEPROCESSINGACTIVATOR_H
#define MITKBASICIMAGEPROCESSINGACTIVATOR_H
#include <ctkPluginActivator.h>
#include <mitkExportMacros.h>
namespace mitk {
class MITK_LOCAL BasicImageProcessingActivator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_basicimageprocessing")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
}; // basicImageProcessingActivator
}
#endif // MITKBASICIMAGEPROCESSINGACTIVATOR_H
diff --git a/Plugins/org.mitk.gui.qt.cmdlinemodules/CMakeLists.txt b/Plugins/org.mitk.gui.qt.cmdlinemodules/CMakeLists.txt
index 7983a10989..55809c14af 100644
--- a/Plugins/org.mitk.gui.qt.cmdlinemodules/CMakeLists.txt
+++ b/Plugins/org.mitk.gui.qt.cmdlinemodules/CMakeLists.txt
@@ -1,8 +1,8 @@
project(org_mitk_gui_qt_cmdlinemodules)
MACRO_CREATE_MITK_CTK_PLUGIN(
EXPORT_DIRECTIVE CLI_EXPORT
EXPORTED_INCLUDE_SUFFIXES src
MODULE_DEPENDS MitkQtWidgetsExt
- PACKAGE_DEPENDS CTK Qt4|QtUiTools
+ PACKAGE_DEPENDS CTK|CTKCommandLineModulesFrontendQtGui+CTKCommandLineModulesBackendLocalProcess Qt4|QtUiTools Qt5|UiTools+XmlPatterns
)
diff --git a/Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/org_mitk_gui_qt_cmdlinemodules_Activator.cpp b/Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/org_mitk_gui_qt_cmdlinemodules_Activator.cpp
index 82cca91141..6ea064a91b 100644
--- a/Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/org_mitk_gui_qt_cmdlinemodules_Activator.cpp
+++ b/Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/org_mitk_gui_qt_cmdlinemodules_Activator.cpp
@@ -1,39 +1,41 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) University College London (UCL).
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_cmdlinemodules_Activator.h"
#include <QtPlugin>
#include "CommandLineModulesView.h"
#include "CommandLineModulesPreferencesPage.h"
namespace mitk {
void org_mitk_gui_qt_cmdlinemodules_Activator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(CommandLineModulesView, context)
BERRY_REGISTER_EXTENSION_CLASS(CommandLineModulesPreferencesPage, context)
}
void org_mitk_gui_qt_cmdlinemodules_Activator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_cmdlinemodules, mitk::org_mitk_gui_qt_cmdlinemodules_Activator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_cmdlinemodules, mitk::org_mitk_gui_qt_cmdlinemodules_Activator)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/org_mitk_gui_qt_cmdlinemodules_Activator.h b/Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/org_mitk_gui_qt_cmdlinemodules_Activator.h
index fc5db1913c..cc926ecf91 100644
--- a/Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/org_mitk_gui_qt_cmdlinemodules_Activator.h
+++ b/Plugins/org.mitk.gui.qt.cmdlinemodules/src/internal/org_mitk_gui_qt_cmdlinemodules_Activator.h
@@ -1,45 +1,48 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) University College London (UCL).
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 org_mitk_gui_qt_cmdlinemodules_Activator_h
#define org_mitk_gui_qt_cmdlinemodules_Activator_h
#include <ctkPluginActivator.h>
namespace mitk {
/**
* \class org_mitk_gui_qt_cmdlinemodules_Activator
* \brief Blueberry plugin activator for CommandLineModulesView.
* \author Matt Clarkson (m.clarkson@ucl.ac.uk)
* \ingroup org_mitk_gui_qt_cmdlinemodules_internal
*/
class org_mitk_gui_qt_cmdlinemodules_Activator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_cmdlinemodules")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
}; // org_mitk_gui_qt_cmdlinemodules_Activator
}
#endif // org_mitk_gui_qt_cmdlinemodules_Activator_h
diff --git a/Plugins/org.mitk.gui.qt.common.legacy/src/internal/QmitkCommonLegacyActivator.cpp b/Plugins/org.mitk.gui.qt.common.legacy/src/internal/QmitkCommonLegacyActivator.cpp
index bf1b683410..8253eea225 100644
--- a/Plugins/org.mitk.gui.qt.common.legacy/src/internal/QmitkCommonLegacyActivator.cpp
+++ b/Plugins/org.mitk.gui.qt.common.legacy/src/internal/QmitkCommonLegacyActivator.cpp
@@ -1,50 +1,52 @@
/*===================================================================
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 "QmitkCommonLegacyActivator.h"
#include <QtPlugin>
#include <berryPlatformUI.h>
#include <mitkLogMacros.h>
void
QmitkCommonLegacyActivator::start(ctkPluginContext* context)
{
Q_UNUSED(context)
if(berry::PlatformUI::IsWorkbenchRunning())
{
m_FunctionalityCoordinator = QmitkFunctionalityCoordinator::Pointer(new QmitkFunctionalityCoordinator);
m_FunctionalityCoordinator->Start();
}
else
{
MITK_ERROR << "BlueBerry Workbench not running!";
}
}
void
QmitkCommonLegacyActivator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
m_FunctionalityCoordinator->Stop();
m_FunctionalityCoordinator = 0;
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_common_legacy, QmitkCommonLegacyActivator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_common_legacy, QmitkCommonLegacyActivator)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.common.legacy/src/internal/QmitkCommonLegacyActivator.h b/Plugins/org.mitk.gui.qt.common.legacy/src/internal/QmitkCommonLegacyActivator.h
index b3f8d9040a..859ec03dd1 100644
--- a/Plugins/org.mitk.gui.qt.common.legacy/src/internal/QmitkCommonLegacyActivator.h
+++ b/Plugins/org.mitk.gui.qt.common.legacy/src/internal/QmitkCommonLegacyActivator.h
@@ -1,48 +1,51 @@
/*===================================================================
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 QMITKCOMMONLEGACYACTIVATOR_H_
#define QMITKCOMMONLEGACYACTIVATOR_H_
#include <ctkPluginActivator.h>
#include "QmitkFunctionalityCoordinator.h"
/**
* \ingroup org_mitk_gui_qt_common_legacy_internal
*/
class QmitkCommonLegacyActivator : public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_common_legacy")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
/**
* Sets default StateMachine to EventMapper.
*/
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
private:
QmitkFunctionalityCoordinator::Pointer m_FunctionalityCoordinator;
};
#endif /* QMITKCOMMONLEGACYACTIVATOR_H_ */
diff --git a/Plugins/org.mitk.gui.qt.common/src/QmitkDnDFrameWidget.cpp b/Plugins/org.mitk.gui.qt.common/src/QmitkDnDFrameWidget.cpp
index 71b3d0f9f2..c7cb65fafd 100644
--- a/Plugins/org.mitk.gui.qt.common/src/QmitkDnDFrameWidget.cpp
+++ b/Plugins/org.mitk.gui.qt.common/src/QmitkDnDFrameWidget.cpp
@@ -1,90 +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 <QmitkDnDFrameWidget.h>
#include <berryIPreferencesService.h>
#include <berryPlatformUI.h>
#include "internal/QmitkCommonActivator.h"
#include <mitkWorkbenchUtil.h>
#include <QDragEnterEvent>
-
+#include <QMimeData>
class QmitkDnDFrameWidgetPrivate
{
public:
berry::IPreferences::Pointer GetPreferences() const
{
berry::IPreferencesService::Pointer prefService = QmitkCommonActivator::GetInstance()->GetPreferencesService();
if (prefService.IsNotNull())
{
return prefService->GetSystemPreferences()->Node("/General");
}
return berry::IPreferences::Pointer(0);
}
bool GetOpenEditor() const
{
berry::IPreferences::Pointer prefs = GetPreferences();
if(prefs.IsNotNull())
{
return prefs->GetBool("OpenEditor", true);
}
return true;
}
};
QmitkDnDFrameWidget::QmitkDnDFrameWidget(QWidget *parent)
: QWidget(parent), d(new QmitkDnDFrameWidgetPrivate())
{
setAcceptDrops(true);
}
QmitkDnDFrameWidget::~QmitkDnDFrameWidget()
{
}
void QmitkDnDFrameWidget::dragEnterEvent( QDragEnterEvent *event )
{ // accept drags
event->acceptProposedAction();
}
void QmitkDnDFrameWidget::dropEvent( QDropEvent * event )
{ //open dragged files
QList<QUrl> fileNames = event->mimeData()->urls();
if (fileNames.empty())
return;
QStringList fileNames2;
//TODO Qt 4.7 API
//fileNames2.reserve(fileNames.size());
foreach(QUrl url, fileNames)
{
fileNames2.push_back(url.toLocalFile());
}
mitk::WorkbenchUtil::LoadFiles(fileNames2,
berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow(),
d->GetOpenEditor());
event->accept();
}
diff --git a/Plugins/org.mitk.gui.qt.common/src/internal/QmitkCommonActivator.cpp b/Plugins/org.mitk.gui.qt.common/src/internal/QmitkCommonActivator.cpp
index 404d31559c..43cad98bcc 100644
--- a/Plugins/org.mitk.gui.qt.common/src/internal/QmitkCommonActivator.cpp
+++ b/Plugins/org.mitk.gui.qt.common/src/internal/QmitkCommonActivator.cpp
@@ -1,72 +1,74 @@
/*===================================================================
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 "QmitkCommonActivator.h"
#include <berryPlatformUI.h>
#include <mitkLogMacros.h>
QmitkCommonActivator* QmitkCommonActivator::m_Instance = 0;
ctkPluginContext* QmitkCommonActivator::m_Context = 0;
ctkPluginContext* QmitkCommonActivator::GetContext()
{
return m_Context;
}
QmitkCommonActivator* QmitkCommonActivator::GetInstance()
{
return m_Instance;
}
berry::IPreferencesService::Pointer QmitkCommonActivator::GetPreferencesService()
{
return berry::IPreferencesService::Pointer(m_PrefServiceTracker->getService());
}
void
QmitkCommonActivator::start(ctkPluginContext* context)
{
this->m_Instance = this;
this->m_Context = context;
this->m_PrefServiceTracker.reset(new ctkServiceTracker<berry::IPreferencesService*>(context));
if(berry::PlatformUI::IsWorkbenchRunning())
{
m_ViewCoordinator = QmitkViewCoordinator::Pointer(new QmitkViewCoordinator);
m_ViewCoordinator->Start();
}
else
{
MITK_ERROR << "BlueBerry Workbench not running!";
}
}
void
QmitkCommonActivator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
m_ViewCoordinator->Stop();
m_ViewCoordinator = 0;
this->m_PrefServiceTracker.reset();
this->m_Context = 0;
this->m_Instance = 0;
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_common, QmitkCommonActivator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_common, QmitkCommonActivator)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.common/src/internal/QmitkCommonActivator.h b/Plugins/org.mitk.gui.qt.common/src/internal/QmitkCommonActivator.h
index a863bb1a0e..2934c38384 100644
--- a/Plugins/org.mitk.gui.qt.common/src/internal/QmitkCommonActivator.h
+++ b/Plugins/org.mitk.gui.qt.common/src/internal/QmitkCommonActivator.h
@@ -1,65 +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 QMITKCOMMONACTIVATOR_H_
#define QMITKCOMMONACTIVATOR_H_
#include <ctkPluginActivator.h>
#include <ctkServiceTracker.h>
#include <berryIPreferencesService.h>
#include "QmitkViewCoordinator.h"
/**
* \ingroup org_mitk_gui_qt_common_internal
*
* \brief The plug-in activator for the StateMachine
*
* When the plug-in is started by the framework, it initializes StateMachine
* specific things.
*/
class QmitkCommonActivator : public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_common")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
static ctkPluginContext* GetContext();
static QmitkCommonActivator* GetInstance();
berry::IPreferencesService::Pointer GetPreferencesService();
/**
* Sets default StateMachine to EventMapper.
*/
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
private:
static QmitkCommonActivator* m_Instance;
static ctkPluginContext* m_Context;
QmitkViewCoordinator::Pointer m_ViewCoordinator;
QScopedPointer<ctkServiceTracker<berry::IPreferencesService*> > m_PrefServiceTracker;
};
#endif /* QMITKCOMMONACTIVATOR_H_ */
diff --git a/Plugins/org.mitk.gui.qt.coreapplication/src/internal/org_mitk_gui_qt_coreapplication_Activator.cpp b/Plugins/org.mitk.gui.qt.coreapplication/src/internal/org_mitk_gui_qt_coreapplication_Activator.cpp
index 4ae0c85594..581e263b88 100644
--- a/Plugins/org.mitk.gui.qt.coreapplication/src/internal/org_mitk_gui_qt_coreapplication_Activator.cpp
+++ b/Plugins/org.mitk.gui.qt.coreapplication/src/internal/org_mitk_gui_qt_coreapplication_Activator.cpp
@@ -1,42 +1,42 @@
/*===================================================================
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_coreapplication_Activator.h"
#include "QmitkCoreApplication.h"
#include "QmitkDefaultPerspective.h"
#include <QtPlugin>
namespace mitk {
void org_mitk_gui_qt_coreapplication_Activator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(QmitkCoreApplication, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkDefaultPerspective, context)
}
void org_mitk_gui_qt_coreapplication_Activator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_coreapplication, mitk::org_mitk_gui_qt_coreapplication_Activator)
-
-
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_coreapplication, mitk::org_mitk_gui_qt_coreapplication_Activator)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.coreapplication/src/internal/org_mitk_gui_qt_coreapplication_Activator.h b/Plugins/org.mitk.gui.qt.coreapplication/src/internal/org_mitk_gui_qt_coreapplication_Activator.h
index 9ac0220f38..0002eaf3ac 100644
--- a/Plugins/org.mitk.gui.qt.coreapplication/src/internal/org_mitk_gui_qt_coreapplication_Activator.h
+++ b/Plugins/org.mitk.gui.qt.coreapplication/src/internal/org_mitk_gui_qt_coreapplication_Activator.h
@@ -1,42 +1,45 @@
/*===================================================================
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 MITKPLUGINACTIVATOR_H
#define MITKPLUGINACTIVATOR_H
#include <ctkPluginActivator.h>
namespace mitk {
class org_mitk_gui_qt_coreapplication_Activator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_coreapplication")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
}; // org_mitk_gui_common_Activator
typedef org_mitk_gui_qt_coreapplication_Activator PluginActivator;
}
#endif // MITKPLUGINACTIVATOR_H
diff --git a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp
index 53244e0e2a..66c3997950 100644
--- a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp
+++ b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.cpp
@@ -1,1033 +1,1058 @@
/*===================================================================
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 "QmitkDataManagerView.h"
#include <itkOtsuThresholdImageFilter.h>
//# Own Includes
//## mitk
#include "mitkDataStorageEditorInput.h"
#include "mitkIDataStorageReference.h"
#include "mitkNodePredicateDataType.h"
#include "mitkCoreObjectFactory.h"
#include "mitkColorProperty.h"
#include "mitkCommon.h"
#include "mitkNodePredicateData.h"
#include "mitkNodePredicateNot.h"
#include "mitkNodePredicateOr.h"
#include "mitkNodePredicateProperty.h"
#include "mitkEnumerationProperty.h"
#include "mitkLookupTableProperty.h"
#include "mitkProperties.h"
#include <mitkNodePredicateAnd.h>
#include <mitkITKImageImport.h>
#include <mitkIDataStorageService.h>
#include <mitkIRenderingManager.h>
#include <mitkImageCast.h>
//## Qmitk
#include <QmitkDnDFrameWidget.h>
#include <QmitkIOUtil.h>
#include <QmitkDataStorageTreeModel.h>
#include <QmitkCustomVariants.h>
#include <QmitkFileSaveAction.h>
#include <QmitkDataStorageFilterProxyModel.h>
#include <QmitkNumberPropertySlider.h>
#include "src/internal/QmitkNodeTableViewKeyFilter.h"
#include "src/internal/QmitkInfoDialog.h"
#include "src/internal/QmitkDataManagerItemDelegate.h"
//## Berry
#include <berryIEditorPart.h>
#include <berryIWorkbenchPage.h>
#include <berryIPreferencesService.h>
#include <berryPlatform.h>
#include <berryPlatformUI.h>
#include <berryIEditorRegistry.h>
//# Toolkit Includes
#include <QTableView>
#include <QGroupBox>
#include <QGridLayout>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QLabel>
#include <QListView>
#include <QMenu>
#include <QAction>
#include <QComboBox>
#include <QApplication>
#include <QCursor>
#include <QHeaderView>
#include <QTreeView>
#include <QWidgetAction>
#include <QSplitter>
#include <QPushButton>
-#include <QMotifStyle>
#include <QFileDialog>
#include <QMessageBox>
#include <QToolBar>
#include <QKeyEvent>
#include <QColor>
#include <QColorDialog>
#include <QSizePolicy>
#include <QSortFilterProxyModel>
#include <QSignalMapper>
#include "mitkDataNodeObject.h"
#include "mitkIContextMenuAction.h"
#include "berryIExtensionPointService.h"
#include "mitkRenderingModeProperty.h"
const std::string QmitkDataManagerView::VIEW_ID = "org.mitk.views.datamanager";
QmitkDataManagerView::QmitkDataManagerView()
: m_GlobalReinitOnNodeDelete(true),
m_ItemDelegate(NULL)
{
}
QmitkDataManagerView::~QmitkDataManagerView()
{
//Remove all registered actions from each descriptor
for (std::vector< std::pair< QmitkNodeDescriptor*, QAction* > >::iterator it = m_DescriptorActionList.begin();it != m_DescriptorActionList.end(); it++)
{
// first== the NodeDescriptor; second== the registered QAction
(it->first)->RemoveAction(it->second);
}
}
void QmitkDataManagerView::CreateQtPartControl(QWidget* parent)
{
m_CurrentRowCount = 0;
m_Parent = parent;
//# Preferences
berry::IPreferencesService::Pointer prefService
= berry::Platform::GetServiceRegistry()
.GetServiceById<berry::IPreferencesService>(berry::IPreferencesService::ID);
berry::IBerryPreferences::Pointer prefs
= (prefService->GetSystemPreferences()->Node(VIEW_ID))
.Cast<berry::IBerryPreferences>();
assert( prefs );
prefs->OnChanged.AddListener( berry::MessageDelegate1<QmitkDataManagerView
, const berry::IBerryPreferences*>( this
, &QmitkDataManagerView::OnPreferencesChanged ) );
//# GUI
m_NodeTreeModel = new QmitkDataStorageTreeModel(this->GetDataStorage());
m_NodeTreeModel->setParent( parent );
m_NodeTreeModel->SetPlaceNewNodesOnTop(
prefs->GetBool("Place new nodes on top", true) );
m_SurfaceDecimation = prefs->GetBool("Use surface decimation", false);
// Prepare filters
m_HelperObjectFilterPredicate = mitk::NodePredicateOr::New(
mitk::NodePredicateProperty::New("helper object", mitk::BoolProperty::New(true)),
mitk::NodePredicateProperty::New("hidden object", mitk::BoolProperty::New(true)));
m_NodeWithNoDataFilterPredicate = mitk::NodePredicateData::New(0);
m_FilterModel = new QmitkDataStorageFilterProxyModel();
m_FilterModel->setSourceModel(m_NodeTreeModel);
m_FilterModel->AddFilterPredicate(m_HelperObjectFilterPredicate);
m_FilterModel->AddFilterPredicate(m_NodeWithNoDataFilterPredicate);
//# Tree View (experimental)
m_NodeTreeView = new QTreeView;
m_NodeTreeView->setHeaderHidden(true);
m_NodeTreeView->setSelectionMode( QAbstractItemView::ExtendedSelection );
m_NodeTreeView->setSelectionBehavior( QAbstractItemView::SelectRows );
m_NodeTreeView->setAlternatingRowColors(true);
m_NodeTreeView->setDragEnabled(true);
m_NodeTreeView->setDropIndicatorShown(true);
m_NodeTreeView->setAcceptDrops(true);
m_NodeTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
m_NodeTreeView->setModel(m_FilterModel);
m_NodeTreeView->setTextElideMode(Qt::ElideMiddle);
m_NodeTreeView->installEventFilter(new QmitkNodeTableViewKeyFilter(this));
m_ItemDelegate = new QmitkDataManagerItemDelegate(m_NodeTreeView);
m_NodeTreeView->setItemDelegate(m_ItemDelegate);
QObject::connect( m_NodeTreeView, SIGNAL(customContextMenuRequested(const QPoint&))
, this, SLOT(NodeTableViewContextMenuRequested(const QPoint&)) );
QObject::connect( m_NodeTreeModel, SIGNAL(rowsInserted (const QModelIndex&, int, int))
, this, SLOT(NodeTreeViewRowsInserted ( const QModelIndex&, int, int )) );
QObject::connect( m_NodeTreeModel, SIGNAL(rowsRemoved (const QModelIndex&, int, int))
, this, SLOT(NodeTreeViewRowsRemoved( const QModelIndex&, int, int )) );
QObject::connect( m_NodeTreeView->selectionModel()
, SIGNAL( selectionChanged ( const QItemSelection &, const QItemSelection & ) )
, this
, SLOT( NodeSelectionChanged ( const QItemSelection &, const QItemSelection & ) ) );
//# m_NodeMenu
m_NodeMenu = new QMenu(m_NodeTreeView);
// # Actions
berry::IEditorRegistry* editorRegistry = berry::PlatformUI::GetWorkbench()->GetEditorRegistry();
std::list<berry::IEditorDescriptor::Pointer> editors = editorRegistry->GetEditors("*.mitk");
if (editors.size() > 1)
{
m_ShowInMapper = new QSignalMapper(this);
foreach(berry::IEditorDescriptor::Pointer descriptor, editors)
{
QAction* action = new QAction(QString::fromStdString(descriptor->GetLabel()), this);
m_ShowInActions << action;
m_ShowInMapper->connect(action, SIGNAL(triggered()), m_ShowInMapper, SLOT(map()));
m_ShowInMapper->setMapping(action, QString::fromStdString(descriptor->GetId()));
}
connect(m_ShowInMapper, SIGNAL(mapped(QString)), this, SLOT(ShowIn(QString)));
}
QmitkNodeDescriptor* unknownDataNodeDescriptor =
QmitkNodeDescriptorManager::GetInstance()->GetUnknownDataNodeDescriptor();
QmitkNodeDescriptor* imageDataNodeDescriptor =
QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("Image");
+ QmitkNodeDescriptor* diffusionImageDataNodeDescriptor =
+ QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("DiffusionImage");
+
QmitkNodeDescriptor* surfaceDataNodeDescriptor =
QmitkNodeDescriptorManager::GetInstance()->GetDescriptor("Surface");
QAction* globalReinitAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Refresh_48.png"), "Global Reinit", this);
QObject::connect( globalReinitAction, SIGNAL( triggered(bool) )
, this, SLOT( GlobalReinit(bool) ) );
unknownDataNodeDescriptor->AddAction(globalReinitAction);
m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(unknownDataNodeDescriptor, globalReinitAction));
QAction* saveAction = new QmitkFileSaveAction(QIcon(":/org.mitk.gui.qt.datamanager/Save_48.png"),
this->GetSite()->GetWorkbenchWindow());
unknownDataNodeDescriptor->AddAction(saveAction);
m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(unknownDataNodeDescriptor,saveAction));
QAction* removeAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Remove_48.png"), "Remove", this);
QObject::connect( removeAction, SIGNAL( triggered(bool) )
, this, SLOT( RemoveSelectedNodes(bool) ) );
unknownDataNodeDescriptor->AddAction(removeAction);
m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(unknownDataNodeDescriptor,removeAction));
QAction* reinitAction = new QAction(QIcon(":/org.mitk.gui.qt.datamanager/Refresh_48.png"), "Reinit", this);
QObject::connect( reinitAction, SIGNAL( triggered(bool) )
, this, SLOT( ReinitSelectedNodes(bool) ) );
unknownDataNodeDescriptor->AddAction(reinitAction);
m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(unknownDataNodeDescriptor,reinitAction));
// find contextMenuAction extension points and add them to the node descriptor
berry::IExtensionPointService::Pointer extensionPointService = berry::Platform::GetExtensionPointService();
berry::IConfigurationElement::vector cmActions(
extensionPointService->GetConfigurationElementsFor("org.mitk.gui.qt.datamanager.contextMenuActions") );
berry::IConfigurationElement::vector::iterator cmActionsIt;
std::string cmNodeDescriptorName;
std::string cmLabel;
std::string cmIcon;
std::string cmClass;
QmitkNodeDescriptor* tmpDescriptor;
QAction* contextMenuAction;
QVariant cmActionDataIt;
m_ConfElements.clear();
int i=1;
for (cmActionsIt = cmActions.begin()
; cmActionsIt != cmActions.end()
; ++cmActionsIt)
{
cmIcon.erase();
if((*cmActionsIt)->GetAttribute("nodeDescriptorName", cmNodeDescriptorName)
&& (*cmActionsIt)->GetAttribute("label", cmLabel)
&& (*cmActionsIt)->GetAttribute("class", cmClass))
{
- (*cmActionsIt)->GetAttribute("icon", cmIcon);
// create context menu entry here
tmpDescriptor = QmitkNodeDescriptorManager::GetInstance()->GetDescriptor(QString::fromStdString(cmNodeDescriptorName));
if(!tmpDescriptor)
{
MITK_WARN << "cannot add action \"" << cmLabel << "\" because descriptor " << cmNodeDescriptorName << " does not exist";
continue;
}
- contextMenuAction = new QAction( QString::fromStdString(cmLabel), parent);
+ // check if the user specified an icon attribute
+ if ( (*cmActionsIt)->GetAttribute("icon", cmIcon) )
+ {
+ contextMenuAction = new QAction( QIcon( QString::fromStdString(cmIcon)),
+ QString::fromStdString(cmLabel), parent);
+ }
+ else
+ {
+ contextMenuAction = new QAction( QString::fromStdString(cmLabel), parent);
+ }
tmpDescriptor->AddAction(contextMenuAction);
m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(tmpDescriptor,contextMenuAction));
m_ConfElements[contextMenuAction] = *cmActionsIt;
cmActionDataIt.setValue<int>(i);
contextMenuAction->setData( cmActionDataIt );
connect( contextMenuAction, SIGNAL( triggered(bool) ) , this, SLOT( ContextMenuActionTriggered(bool) ) );
++i;
}
}
m_OpacitySlider = new QSlider;
m_OpacitySlider->setMinimum(0);
m_OpacitySlider->setMaximum(100);
m_OpacitySlider->setOrientation(Qt::Horizontal);
QObject::connect( m_OpacitySlider, SIGNAL( valueChanged(int) )
, this, SLOT( OpacityChanged(int) ) );
QLabel* _OpacityLabel = new QLabel("Opacity: ");
QHBoxLayout* _OpacityWidgetLayout = new QHBoxLayout;
_OpacityWidgetLayout->setContentsMargins(4,4,4,4);
_OpacityWidgetLayout->addWidget(_OpacityLabel);
_OpacityWidgetLayout->addWidget(m_OpacitySlider);
QWidget* _OpacityWidget = new QWidget;
_OpacityWidget->setLayout(_OpacityWidgetLayout);
QWidgetAction* opacityAction = new QWidgetAction(this);
opacityAction ->setDefaultWidget(_OpacityWidget);
QObject::connect( opacityAction , SIGNAL( changed() )
, this, SLOT( OpacityActionChanged() ) );
unknownDataNodeDescriptor->AddAction(opacityAction , false);
m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(unknownDataNodeDescriptor,opacityAction));
m_ColorButton = new QPushButton;
m_ColorButton->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Minimum);
//m_ColorButton->setText("Change color");
QObject::connect( m_ColorButton, SIGNAL( clicked() )
, this, SLOT( ColorChanged() ) );
QLabel* _ColorLabel = new QLabel("Color: ");
_ColorLabel->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Minimum);
QHBoxLayout* _ColorWidgetLayout = new QHBoxLayout;
_ColorWidgetLayout->setContentsMargins(4,4,4,4);
_ColorWidgetLayout->addWidget(_ColorLabel);
_ColorWidgetLayout->addWidget(m_ColorButton);
QWidget* _ColorWidget = new QWidget;
_ColorWidget->setLayout(_ColorWidgetLayout);
QWidgetAction* colorAction = new QWidgetAction(this);
colorAction->setDefaultWidget(_ColorWidget);
QObject::connect( colorAction, SIGNAL( changed() )
, this, SLOT( ColorActionChanged() ) );
unknownDataNodeDescriptor->AddAction(colorAction, false);
m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(unknownDataNodeDescriptor,colorAction));
m_ComponentSlider = new QmitkNumberPropertySlider;
m_ComponentSlider->setOrientation(Qt::Horizontal);
//QObject::connect( m_OpacitySlider, SIGNAL( valueChanged(int) )
// , this, SLOT( OpacityChanged(int) ) );
QLabel* _ComponentLabel = new QLabel("Component: ");
QHBoxLayout* _ComponentWidgetLayout = new QHBoxLayout;
_ComponentWidgetLayout->setContentsMargins(4,4,4,4);
_ComponentWidgetLayout->addWidget(_ComponentLabel);
_ComponentWidgetLayout->addWidget(m_ComponentSlider);
QLabel* _ComponentValueLabel = new QLabel();
_ComponentWidgetLayout->addWidget(_ComponentValueLabel);
connect(m_ComponentSlider, SIGNAL(valueChanged(int)), _ComponentValueLabel, SLOT(setNum(int)));
QWidget* _ComponentWidget = new QWidget;
_ComponentWidget->setLayout(_ComponentWidgetLayout);
QWidgetAction* componentAction = new QWidgetAction(this);
componentAction->setDefaultWidget(_ComponentWidget);
QObject::connect( componentAction , SIGNAL( changed() )
, this, SLOT( ComponentActionChanged() ) );
imageDataNodeDescriptor->AddAction(componentAction, false);
m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(imageDataNodeDescriptor,componentAction));
+ if (diffusionImageDataNodeDescriptor!=NULL)
+ {
+ diffusionImageDataNodeDescriptor->AddAction(componentAction, false);
+ m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(diffusionImageDataNodeDescriptor,componentAction));
+ }
m_TextureInterpolation = new QAction("Texture Interpolation", this);
m_TextureInterpolation->setCheckable ( true );
QObject::connect( m_TextureInterpolation, SIGNAL( changed() )
, this, SLOT( TextureInterpolationChanged() ) );
QObject::connect( m_TextureInterpolation, SIGNAL( toggled(bool) )
, this, SLOT( TextureInterpolationToggled(bool) ) );
imageDataNodeDescriptor->AddAction(m_TextureInterpolation, false);
m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(imageDataNodeDescriptor,m_TextureInterpolation));
+ if (diffusionImageDataNodeDescriptor!=NULL)
+ {
+ diffusionImageDataNodeDescriptor->AddAction(m_TextureInterpolation, false);
+ m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(diffusionImageDataNodeDescriptor,m_TextureInterpolation));
+ }
m_ColormapAction = new QAction("Colormap", this);
m_ColormapAction->setMenu(new QMenu);
QObject::connect( m_ColormapAction->menu(), SIGNAL( aboutToShow() )
, this, SLOT( ColormapMenuAboutToShow() ) );
imageDataNodeDescriptor->AddAction(m_ColormapAction, false);
m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(imageDataNodeDescriptor, m_ColormapAction));
+ if (diffusionImageDataNodeDescriptor!=NULL)
+ {
+ diffusionImageDataNodeDescriptor->AddAction(m_ColormapAction, false);
+ m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(diffusionImageDataNodeDescriptor, m_ColormapAction));
+ }
m_SurfaceRepresentation = new QAction("Surface Representation", this);
m_SurfaceRepresentation->setMenu(new QMenu);
QObject::connect( m_SurfaceRepresentation->menu(), SIGNAL( aboutToShow() )
, this, SLOT( SurfaceRepresentationMenuAboutToShow() ) );
surfaceDataNodeDescriptor->AddAction(m_SurfaceRepresentation, false);
m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(surfaceDataNodeDescriptor, m_SurfaceRepresentation));
QAction* showOnlySelectedNodes
= new QAction(QIcon(":/org.mitk.gui.qt.datamanager/ShowSelectedNode_48.png")
, "Show only selected nodes", this);
QObject::connect( showOnlySelectedNodes, SIGNAL( triggered(bool) )
, this, SLOT( ShowOnlySelectedNodes(bool) ) );
unknownDataNodeDescriptor->AddAction(showOnlySelectedNodes);
m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(unknownDataNodeDescriptor, showOnlySelectedNodes));
QAction* toggleSelectedVisibility
= new QAction(QIcon(":/org.mitk.gui.qt.datamanager/InvertShowSelectedNode_48.png")
, "Toggle visibility", this);
QObject::connect( toggleSelectedVisibility, SIGNAL( triggered(bool) )
, this, SLOT( ToggleVisibilityOfSelectedNodes(bool) ) );
unknownDataNodeDescriptor->AddAction(toggleSelectedVisibility);
m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(unknownDataNodeDescriptor,toggleSelectedVisibility));
QAction* actionShowInfoDialog
= new QAction(QIcon(":/org.mitk.gui.qt.datamanager/ShowDataInfo_48.png")
, "Details...", this);
QObject::connect( actionShowInfoDialog, SIGNAL( triggered(bool) )
, this, SLOT( ShowInfoDialogForSelectedNodes(bool) ) );
unknownDataNodeDescriptor->AddAction(actionShowInfoDialog);
m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(unknownDataNodeDescriptor,actionShowInfoDialog));
//obsolete...
//QAction* otsuFilterAction = new QAction("Apply Otsu Filter", this);
//QObject::connect( otsuFilterAction, SIGNAL( triggered(bool) )
// , this, SLOT( OtsuFilter(bool) ) );
// //Otsu filter does not work properly, remove it temporarily
// imageDataNodeDescriptor->AddAction(otsuFilterAction);
// m_DescriptorActionList.push_back(std::pair<QmitkNodeDescriptor*, QAction*>(imageDataNodeDescriptor,otsuFilterAction));
QGridLayout* _DndFrameWidgetLayout = new QGridLayout;
_DndFrameWidgetLayout->addWidget(m_NodeTreeView, 0, 0);
_DndFrameWidgetLayout->setContentsMargins(0,0,0,0);
m_DndFrameWidget = new QmitkDnDFrameWidget(m_Parent);
m_DndFrameWidget->setLayout(_DndFrameWidgetLayout);
QVBoxLayout* layout = new QVBoxLayout(parent);
layout->addWidget(m_DndFrameWidget);
layout->setContentsMargins(0,0,0,0);
m_Parent->setLayout(layout);
}
void QmitkDataManagerView::SetFocus()
{
}
void QmitkDataManagerView::ContextMenuActionTriggered( bool )
{
QAction* action = qobject_cast<QAction*> ( sender() );
std::map<QAction*, berry::IConfigurationElement::Pointer>::iterator it
= m_ConfElements.find( action );
if( it == m_ConfElements.end() )
{
MITK_WARN << "associated conf element for action " << action->text().toStdString() << " not found";
return;
}
berry::IConfigurationElement::Pointer confElem = it->second;
mitk::IContextMenuAction* contextMenuAction = confElem->CreateExecutableExtension<mitk::IContextMenuAction>("class");
std::string className;
std::string smoothed;
confElem->GetAttribute("class", className);
confElem->GetAttribute("smoothed", smoothed);
if(className == "QmitkCreatePolygonModelAction")
{
contextMenuAction->SetDataStorage(this->GetDataStorage());
if(smoothed == "false")
{
contextMenuAction->SetSmoothed(false);
}
else
{
contextMenuAction->SetSmoothed(true);
}
contextMenuAction->SetDecimated(m_SurfaceDecimation);
}
else if(className == "QmitkStatisticsAction")
{
contextMenuAction->SetFunctionality(this);
}
else if(className == "QmitkCreateSimulationAction")
{
contextMenuAction->SetDataStorage(this->GetDataStorage());
}
contextMenuAction->Run( this->GetCurrentSelection() ); // run the action
}
void QmitkDataManagerView::OnPreferencesChanged(const berry::IBerryPreferences* prefs)
{
if( m_NodeTreeModel->GetPlaceNewNodesOnTopFlag() != prefs->GetBool("Place new nodes on top", true) )
m_NodeTreeModel->SetPlaceNewNodesOnTop( !m_NodeTreeModel->GetPlaceNewNodesOnTopFlag() );
bool hideHelperObjects = !prefs->GetBool("Show helper objects", false);
if (m_FilterModel->HasFilterPredicate(m_HelperObjectFilterPredicate) != hideHelperObjects)
{
if (hideHelperObjects)
{
m_FilterModel->AddFilterPredicate(m_HelperObjectFilterPredicate);
}
else
{
m_FilterModel->RemoveFilterPredicate(m_HelperObjectFilterPredicate);
}
}
bool hideNodesWithNoData = !prefs->GetBool("Show nodes containing no data", false);
if (m_FilterModel->HasFilterPredicate(m_NodeWithNoDataFilterPredicate) != hideNodesWithNoData)
{
if (hideNodesWithNoData)
{
m_FilterModel->AddFilterPredicate(m_NodeWithNoDataFilterPredicate);
}
else
{
m_FilterModel->RemoveFilterPredicate(m_NodeWithNoDataFilterPredicate);
}
}
m_GlobalReinitOnNodeDelete = prefs->GetBool("Call global reinit if node is deleted", true);
m_NodeTreeView->expandAll();
m_SurfaceDecimation = prefs->GetBool("Use surface decimation", false);
this->GlobalReinit();
}
void QmitkDataManagerView::NodeTableViewContextMenuRequested( const QPoint & pos )
{
QModelIndex selectedProxy = m_NodeTreeView->indexAt ( pos );
QModelIndex selected = m_FilterModel->mapToSource(selectedProxy);
mitk::DataNode::Pointer node = m_NodeTreeModel->GetNode(selected);
QList<mitk::DataNode::Pointer> selectedNodes = this->GetCurrentSelection();
if(!selectedNodes.isEmpty())
{
m_NodeMenu->clear();
QList<QAction*> actions;
if(selectedNodes.size() == 1 )
{
actions = QmitkNodeDescriptorManager::GetInstance()->GetActions(node);
for(QList<QAction*>::iterator it = actions.begin(); it != actions.end(); ++it)
{
(*it)->setData(QVariant::fromValue(node.GetPointer()));
}
}
else
actions = QmitkNodeDescriptorManager::GetInstance()->GetActions(selectedNodes);
if (!m_ShowInActions.isEmpty())
{
QMenu* showInMenu = m_NodeMenu->addMenu("Show In");
showInMenu->addActions(m_ShowInActions);
}
m_NodeMenu->addActions(actions);
m_NodeMenu->popup(QCursor::pos());
}
}
void QmitkDataManagerView::OpacityChanged(int value)
{
mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex()));
if(node)
{
float opacity = static_cast<float>(value)/100.0f;
node->SetFloatProperty("opacity", opacity);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void QmitkDataManagerView::OpacityActionChanged()
{
mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex()));
if(node)
{
float opacity = 0.0;
if(node->GetFloatProperty("opacity", opacity))
{
m_OpacitySlider->setValue(static_cast<int>(opacity*100));
}
}
}
void QmitkDataManagerView::ComponentActionChanged()
{
mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex()));
mitk::IntProperty* componentProperty = NULL;
int numComponents = 0;
if(node)
{
componentProperty =
dynamic_cast<mitk::IntProperty*>(node->GetProperty("Image.Displayed Component"));
mitk::Image* img = dynamic_cast<mitk::Image*>(node->GetData());
if (img != NULL)
{
numComponents = img->GetPixelType().GetNumberOfComponents();
}
}
if (componentProperty && numComponents > 1)
{
m_ComponentSlider->SetProperty(componentProperty);
m_ComponentSlider->setMinValue(0);
m_ComponentSlider->setMaxValue(numComponents-1);
}
else
{
m_ComponentSlider->SetProperty(static_cast<mitk::IntProperty*>(NULL));
}
}
void QmitkDataManagerView::ColorChanged()
{
mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex()));
if(node)
{
mitk::Color color;
mitk::ColorProperty::Pointer colorProp;
node->GetProperty(colorProp,"color");
if(colorProp.IsNull())
return;
color = colorProp->GetValue();
QColor initial(color.GetRed()*255,color.GetGreen()*255,color.GetBlue()*255);
QColor qcolor = QColorDialog::getColor(initial,0,QString("Change color"));
if (!qcolor.isValid())
return;
m_ColorButton->setAutoFillBackground(true);
node->SetProperty("color",mitk::ColorProperty::New(qcolor.red()/255.0,qcolor.green()/255.0,qcolor.blue()/255.0));
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void QmitkDataManagerView::ColorActionChanged()
{
mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex()));
if(node)
{
mitk::Color color;
mitk::ColorProperty::Pointer colorProp;
node->GetProperty(colorProp,"color");
if(colorProp.IsNull())
return;
color = colorProp->GetValue();
QString styleSheet = "background-color:rgb(";
styleSheet.append(QString::number(color[0]*255));
styleSheet.append(",");
styleSheet.append(QString::number(color[1]*255));
styleSheet.append(",");
styleSheet.append(QString::number(color[2]*255));
styleSheet.append(")");
m_ColorButton->setStyleSheet(styleSheet);
}
}
void QmitkDataManagerView::TextureInterpolationChanged()
{
mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex()));
if(node)
{
bool textureInterpolation = false;
node->GetBoolProperty("texture interpolation", textureInterpolation);
m_TextureInterpolation->setChecked(textureInterpolation);
}
}
void QmitkDataManagerView::TextureInterpolationToggled( bool checked )
{
mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex()));
if(node)
{
node->SetBoolProperty("texture interpolation", checked);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void QmitkDataManagerView::ColormapActionToggled( bool /*checked*/ )
{
mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex()));
if(!node)
return;
mitk::LookupTableProperty::Pointer lookupTableProperty =
dynamic_cast<mitk::LookupTableProperty*>(node->GetProperty("LookupTable"));
if (!lookupTableProperty)
return;
QAction* senderAction = qobject_cast<QAction*>(QObject::sender());
if(!senderAction)
return;
std::string activatedItem = senderAction->text().toStdString();
mitk::LookupTable::Pointer lookupTable = lookupTableProperty->GetValue();
if (!lookupTable)
return;
lookupTable->SetType(activatedItem);
lookupTableProperty->SetValue(lookupTable);
mitk::RenderingModeProperty::Pointer renderingMode =
dynamic_cast<mitk::RenderingModeProperty*>(node->GetProperty("Image Rendering.Mode"));
renderingMode->SetValue(mitk::RenderingModeProperty::LOOKUPTABLE_LEVELWINDOW_COLOR);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkDataManagerView::ColormapMenuAboutToShow()
{
mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex()));
if(!node)
return;
mitk::LookupTableProperty::Pointer lookupTableProperty =
dynamic_cast<mitk::LookupTableProperty*>(node->GetProperty("LookupTable"));
if (!lookupTableProperty)
{
mitk::LookupTable::Pointer mitkLut = mitk::LookupTable::New();
lookupTableProperty = mitk::LookupTableProperty::New();
lookupTableProperty->SetLookupTable(mitkLut);
node->SetProperty("LookupTable", lookupTableProperty);
}
mitk::LookupTable::Pointer lookupTable = lookupTableProperty->GetValue();
if (!lookupTable)
return;
m_ColormapAction->menu()->clear();
QAction* tmp;
int i = 0;
std::string lutType = lookupTable->typenameList[i];
while (lutType != "END_OF_ARRAY")
{
tmp = m_ColormapAction->menu()->addAction(QString::fromStdString(lutType));
tmp->setCheckable(true);
if (lutType == lookupTable->GetActiveTypeAsString())
{
tmp->setChecked(true);
}
QObject::connect(tmp, SIGNAL(triggered(bool)), this, SLOT(ColormapActionToggled(bool)));
lutType = lookupTable->typenameList[++i];
}
}
void QmitkDataManagerView::SurfaceRepresentationMenuAboutToShow()
{
mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex()));
if(!node)
return;
mitk::EnumerationProperty* representationProp =
dynamic_cast<mitk::EnumerationProperty*> (node->GetProperty("material.representation"));
if(!representationProp)
return;
// clear menu
m_SurfaceRepresentation->menu()->clear();
QAction* tmp;
// create menu entries
for(mitk::EnumerationProperty::EnumConstIterator it=representationProp->Begin(); it!=representationProp->End()
; it++)
{
tmp = m_SurfaceRepresentation->menu()->addAction(QString::fromStdString(it->second));
tmp->setCheckable(true);
if(it->second == representationProp->GetValueAsString())
{
tmp->setChecked(true);
}
QObject::connect( tmp, SIGNAL( triggered(bool) )
, this, SLOT( SurfaceRepresentationActionToggled(bool) ) );
}
}
void QmitkDataManagerView::SurfaceRepresentationActionToggled( bool /*checked*/ )
{
mitk::DataNode* node = m_NodeTreeModel->GetNode(m_FilterModel->mapToSource(m_NodeTreeView->selectionModel()->currentIndex()));
if(!node)
return;
mitk::EnumerationProperty* representationProp =
dynamic_cast<mitk::EnumerationProperty*> (node->GetProperty("material.representation"));
if(!representationProp)
return;
QAction* senderAction = qobject_cast<QAction*> ( QObject::sender() );
if(!senderAction)
return;
std::string activatedItem = senderAction->text().toStdString();
if ( activatedItem != representationProp->GetValueAsString() )
{
if ( representationProp->IsValidEnumerationValue( activatedItem ) )
{
representationProp->SetValue( activatedItem );
representationProp->InvokeEvent( itk::ModifiedEvent() );
representationProp->Modified();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
}
void QmitkDataManagerView::ReinitSelectedNodes( bool )
{
mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart();
if (renderWindow == NULL)
renderWindow = this->OpenRenderWindowPart(false);
QList<mitk::DataNode::Pointer> selectedNodes = this->GetCurrentSelection();
foreach(mitk::DataNode::Pointer node, selectedNodes)
{
mitk::BaseData::Pointer basedata = node->GetData();
if ( basedata.IsNotNull() &&
basedata->GetTimeGeometry()->IsValid() )
{
renderWindow->GetRenderingManager()->InitializeViews(
basedata->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true );
renderWindow->GetRenderingManager()->RequestUpdateAll();
}
}
}
void QmitkDataManagerView::RemoveSelectedNodes( bool )
{
QModelIndexList indexesOfSelectedRowsFiltered = m_NodeTreeView->selectionModel()->selectedRows();
QModelIndexList indexesOfSelectedRows;
for (int i = 0; i < indexesOfSelectedRowsFiltered.size(); ++i)
{
indexesOfSelectedRows.push_back(m_FilterModel->mapToSource(indexesOfSelectedRowsFiltered[i]));
}
if(indexesOfSelectedRows.size() < 1)
{
return;
}
std::vector<mitk::DataNode*> selectedNodes;
mitk::DataNode* node = 0;
QString question = tr("Do you really want to remove ");
for (QModelIndexList::iterator it = indexesOfSelectedRows.begin()
; it != indexesOfSelectedRows.end(); it++)
{
node = m_NodeTreeModel->GetNode(*it);
// if node is not defined or if the node contains geometry data do not remove it
if ( node != 0 /*& strcmp(node->GetData()->GetNameOfClass(), "PlaneGeometryData") != 0*/ )
{
selectedNodes.push_back(node);
question.append(QString::fromStdString(node->GetName()));
question.append(", ");
}
}
// remove the last two characters = ", "
question = question.remove(question.size()-2, 2);
question.append(" from data storage?");
QMessageBox::StandardButton answerButton = QMessageBox::question( m_Parent
, tr("DataManager")
, question
, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
if(answerButton == QMessageBox::Yes)
{
for (std::vector<mitk::DataNode*>::iterator it = selectedNodes.begin()
; it != selectedNodes.end(); it++)
{
node = *it;
this->GetDataStorage()->Remove(node);
if (m_GlobalReinitOnNodeDelete)
this->GlobalReinit(false);
}
}
}
void QmitkDataManagerView::MakeAllNodesInvisible( bool )
{
QList<mitk::DataNode::Pointer> nodes = m_NodeTreeModel->GetNodeSet();
foreach(mitk::DataNode::Pointer node, nodes)
{
node->SetVisibility(false);
}
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkDataManagerView::ShowOnlySelectedNodes( bool )
{
QList<mitk::DataNode::Pointer> selectedNodes = this->GetCurrentSelection();
QList<mitk::DataNode::Pointer> allNodes = m_NodeTreeModel->GetNodeSet();
foreach(mitk::DataNode::Pointer node, allNodes)
{
node->SetVisibility(selectedNodes.contains(node));
}
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkDataManagerView::ToggleVisibilityOfSelectedNodes( bool )
{
QList<mitk::DataNode::Pointer> selectedNodes = this->GetCurrentSelection();
bool isVisible = false;
foreach(mitk::DataNode::Pointer node, selectedNodes)
{
isVisible = false;
node->GetBoolProperty("visible", isVisible);
node->SetVisibility(!isVisible);
}
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkDataManagerView::ShowInfoDialogForSelectedNodes( bool )
{
QList<mitk::DataNode::Pointer> selectedNodes = this->GetCurrentSelection();
QmitkInfoDialog _QmitkInfoDialog(selectedNodes, this->m_Parent);
_QmitkInfoDialog.exec();
}
-void QmitkDataManagerView::NodeChanged(const mitk::DataNode* node)
+void QmitkDataManagerView::NodeChanged(const mitk::DataNode* /*node*/)
{
// m_FilterModel->invalidate();
// fix as proposed by R. Khlebnikov in the mitk-users mail from 02.09.2014
QMetaObject::invokeMethod( m_FilterModel, "invalidate", Qt::QueuedConnection );
}
QItemSelectionModel *QmitkDataManagerView::GetDataNodeSelectionModel() const
{
return m_NodeTreeView->selectionModel();
}
void QmitkDataManagerView::GlobalReinit( bool )
{
mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart();
if (renderWindow == NULL)
renderWindow = this->OpenRenderWindowPart(false);
// no render window available
if (renderWindow == NULL) return;
mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(this->GetDataStorage());
}
void QmitkDataManagerView::OtsuFilter( bool )
{
QList<mitk::DataNode::Pointer> selectedNodes = this->GetCurrentSelection();
mitk::Image::Pointer mitkImage = 0;
foreach(mitk::DataNode::Pointer node, selectedNodes)
{
mitkImage = dynamic_cast<mitk::Image*>( node->GetData() );
if(mitkImage.IsNull())
continue;
try
{
// get selected mitk image
const unsigned short dim = 3;
typedef short InputPixelType;
typedef unsigned char OutputPixelType;
typedef itk::Image< InputPixelType, dim > InputImageType;
typedef itk::Image< OutputPixelType, dim > OutputImageType;
typedef itk::OtsuThresholdImageFilter< InputImageType, OutputImageType > FilterType;
FilterType::Pointer filter = FilterType::New();
filter->SetOutsideValue( 1 );
filter->SetInsideValue( 0 );
InputImageType::Pointer itkImage;
mitk::CastToItkImage(mitkImage, itkImage);
filter->SetInput( itkImage );
filter->Update();
mitk::DataNode::Pointer resultNode = mitk::DataNode::New();
std::string nameOfResultImage = node->GetName();
nameOfResultImage.append("Otsu");
resultNode->SetProperty("name", mitk::StringProperty::New(nameOfResultImage) );
resultNode->SetProperty("binary", mitk::BoolProperty::New(true) );
resultNode->SetData( mitk::ImportItkImage(filter->GetOutput())->Clone());
this->GetDataStorage()->Add(resultNode, node);
}
catch( std::exception& err )
{
MITK_ERROR(this->GetClassName()) << err.what();
}
}
}
void QmitkDataManagerView::NodeTreeViewRowsRemoved (
const QModelIndex & /*parent*/, int /*start*/, int /*end*/ )
{
m_CurrentRowCount = m_NodeTreeModel->rowCount();
}
void QmitkDataManagerView::NodeTreeViewRowsInserted( const QModelIndex & parent, int, int )
{
m_NodeTreeView->setExpanded(parent, true);
// a new row was inserted
if( m_CurrentRowCount == 0 && m_NodeTreeModel->rowCount() == 1 )
{
this->OpenRenderWindowPart();
m_CurrentRowCount = m_NodeTreeModel->rowCount();
}
}
void QmitkDataManagerView::NodeSelectionChanged( const QItemSelection & /*selected*/, const QItemSelection & /*deselected*/ )
{
QList<mitk::DataNode::Pointer> nodes = m_NodeTreeModel->GetNodeSet();
foreach(mitk::DataNode::Pointer node, nodes)
{
if ( node.IsNotNull() )
node->SetBoolProperty("selected", false);
}
nodes.clear();
nodes = this->GetCurrentSelection();
foreach(mitk::DataNode::Pointer node, nodes)
{
if ( node.IsNotNull() )
node->SetBoolProperty("selected", true);
}
//changing the selection does NOT require any rendering processes!
//mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkDataManagerView::ShowIn(const QString &editorId)
{
berry::IWorkbenchPage::Pointer page = this->GetSite()->GetPage();
berry::IEditorInput::Pointer input(new mitk::DataStorageEditorInput(this->GetDataStorageReference()));
page->OpenEditor(input, editorId.toStdString(), false, berry::IWorkbenchPage::MATCH_ID);
}
mitk::IRenderWindowPart* QmitkDataManagerView::OpenRenderWindowPart(bool activatedEditor)
{
if (activatedEditor)
{
return this->GetRenderWindowPart(QmitkAbstractView::ACTIVATE | QmitkAbstractView::OPEN);
}
else
{
return this->GetRenderWindowPart(QmitkAbstractView::BRING_TO_FRONT | QmitkAbstractView::OPEN);
}
}
diff --git a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.h b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.h
index aa5e0386b6..b6b0d4a63c 100644
--- a/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.h
+++ b/Plugins/org.mitk.gui.qt.datamanager/src/QmitkDataManagerView.h
@@ -1,269 +1,269 @@
/*===================================================================
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 QMITKDATAMANAGERVIEW_H_
#define QMITKDATAMANAGERVIEW_H_
// BlueBerry includes
#include <berryIBerryPreferences.h>
/// Qmitk
#include <QmitkAbstractView.h>
#include <QmitkNodeDescriptorManager.h>
/// Qt
#include <QItemSelection>
#include <org_mitk_gui_qt_datamanager_Export.h>
// Forward declarations
class QMenu;
class QAction;
class QComboBox;
class QWidgetAction;
class QSlider;
class QModelIndex;
class QTreeView;
class QPushButton;
class QToolBar;
class QMenu;
class QSignalMapper;
class QmitkDnDFrameWidget;
class QmitkDataStorageTreeModel;
class QmitkDataManagerItemDelegate;
class QmitkNumberPropertySlider;
class QmitkDataStorageFilterProxyModel;
///
/// \ingroup org_mitk_gui_qt_datamanager_internal
///
/// \brief A View class that can show all data tree nodes of a certain DataStorage
///
/// \TODO: complete PACS support, in save dialog show regular filename
///
class MITK_QT_DATAMANAGER QmitkDataManagerView : public QmitkAbstractView
{
Q_OBJECT
public:
static const std::string VIEW_ID; // = "org.mitk.extapp.defaultperspective"
///
/// \brief Standard ctor.
///
QmitkDataManagerView();
///
/// \brief Standard dtor.
///
virtual ~QmitkDataManagerView();
public slots:
///
/// Invoked when the opacity slider changed
///
void OpacityChanged(int value);
///
/// Invoked when the opacity action changed
/// In this function the the opacity slider is set to the selected nodes opacity value
///
void OpacityActionChanged();
/// Invoked when the component action changed
/// In this function the the opacity slider is set to the selected nodes opacity value
///
void ComponentActionChanged();
///
/// Invoked when the color button is pressed
///
void ColorChanged();
///
/// Invoked when the color action changed
///
void ColorActionChanged();
///
/// Invoked when the color button is pressed
///
void TextureInterpolationChanged();
///
/// Invoked when the color action changed
///
void TextureInterpolationToggled ( bool checked );
///
/// \brief Agreggates available colormaps
///
void ColormapMenuAboutToShow ();
///
/// \brief changes the active colormap
///
void ColormapActionToggled (bool);
///
/// SurfaceRepresentationActionToggled
///
void SurfaceRepresentationMenuAboutToShow ();
///
/// SurfaceRepresentationActionToggled
///
void SurfaceRepresentationActionToggled ( bool checked );
///
/// \brief Shows a node context menu.
///
void NodeTableViewContextMenuRequested( const QPoint & index );
///
/// \brief Invoked when an element should be removed.
///
void RemoveSelectedNodes( bool checked = false );
///
/// \brief Invoked when an element should be reinitiliased.
///
void ReinitSelectedNodes( bool checked = false );
///
/// \brief Invoked when the visibility of the selected nodes should be toggled.
///
void MakeAllNodesInvisible ( bool checked = false );
///
/// \brief Makes all selected nodes visible, all other nodes invisible.
///
void ShowOnlySelectedNodes ( bool checked = false );
///
/// \brief Invoked when the visibility of the selected nodes should be toggled.
///
void ToggleVisibilityOfSelectedNodes ( bool checked = false );
///
/// \brief Invoked when infos of the selected nodes should be shown in a dialog.
///
void ShowInfoDialogForSelectedNodes ( bool checked = false );
///
/// \brief Reinits everything.
///
void GlobalReinit ( bool checked = false );
///
/// Invoked when the preferences were changed
///
void OnPreferencesChanged(const berry::IBerryPreferences*);
///
/// \brief will be toggled when a extension point context menu action is toggled
/// this is a proxy method which will load the corresponding extension class
/// and run IContextMenuAction
///
void ContextMenuActionTriggered( bool );
/// Invoked when the median action is invoked
void OtsuFilter( bool checked = false );
/// When rows are inserted auto expand them
void NodeTreeViewRowsInserted ( const QModelIndex & parent, int start, int end );
/// will setup m_CurrentRowCount
void NodeTreeViewRowsRemoved ( const QModelIndex & parent, int start, int end );
/// Whenever the selection changes set the "selected" property respectively
void NodeSelectionChanged( const QItemSelection & selected, const QItemSelection & deselected );
/// Opens the editor with the given id using the current data storage
void ShowIn(const QString& editorId);
protected:
///
/// \brief Create the view here.
///
virtual void CreateQtPartControl(QWidget* parent);
void SetFocus();
///
/// \brief Shows a file open dialog.
///
void FileOpen( const char * fileName, mitk::DataNode* parentNode );
///
/// React to node changes. Overridden from QmitkAbstractView.
///
- virtual void NodeChanged(const mitk::DataNode* node);
+ virtual void NodeChanged(const mitk::DataNode* /*node*/);
protected:
QWidget* m_Parent;
QmitkDnDFrameWidget* m_DndFrameWidget;
///
/// \brief A plain widget as the base pane.
///
QmitkDataStorageTreeModel* m_NodeTreeModel;
QmitkDataStorageFilterProxyModel* m_FilterModel;
mitk::NodePredicateBase::Pointer m_HelperObjectFilterPredicate;
mitk::NodePredicateBase::Pointer m_NodeWithNoDataFilterPredicate;
///
/// Holds the preferences for the datamanager.
///
berry::IBerryPreferences::Pointer m_DataManagerPreferencesNode;
///
/// saves the configuration elements for the context menu actions from extension points
///
std::map<QAction*, berry::IConfigurationElement::Pointer> m_ConfElements;
///
/// \brief The Table view to show the selected nodes.
///
QTreeView* m_NodeTreeView;
///
/// \brief The context menu that shows up when right clicking on a node.
///
QMenu* m_NodeMenu;
///
/// \brief flag indicating whether a surface created from a selected decimation is decimated with vtkQuadricDecimation or not
///
bool m_SurfaceDecimation;
///# A list of ALL actions for the Context Menu
std::vector< std::pair< QmitkNodeDescriptor*, QAction* > > m_DescriptorActionList;
/// A Slider widget to change the opacity of a node
QSlider* m_OpacitySlider;
/// A Slider widget to change the rendered vector component of an image
QmitkNumberPropertySlider* m_ComponentSlider;
/// button to change the color of a node
QPushButton* m_ColorButton;
/// TextureInterpolation action
QAction* m_TextureInterpolation;
/// SurfaceRepresentation action
QAction* m_SurfaceRepresentation;
/// Lookuptable selection action
QAction* m_ColormapAction;
/// Maps "Show in" actions to editor ids
QSignalMapper* m_ShowInMapper;
/// A list of "Show in" actions
QList<QAction*> m_ShowInActions;
/// saves the current amount of rows shown in the datamanager
size_t m_CurrentRowCount;
/// if true, GlobalReinit() is called if a node is deleted
bool m_GlobalReinitOnNodeDelete;
QmitkDataManagerItemDelegate* m_ItemDelegate;
private:
QItemSelectionModel* GetDataNodeSelectionModel() const;
/// Reopen multi widget editor if it has been closed
mitk::IRenderWindowPart *OpenRenderWindowPart(bool activatedEditor = true);
};
#endif /*QMITKDATAMANAGERVIEW_H_*/
diff --git a/Plugins/org.mitk.gui.qt.datamanager/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.datamanager/src/internal/mitkPluginActivator.cpp
index 28251ba02b..93e95d4c09 100644
--- a/Plugins/org.mitk.gui.qt.datamanager/src/internal/mitkPluginActivator.cpp
+++ b/Plugins/org.mitk.gui.qt.datamanager/src/internal/mitkPluginActivator.cpp
@@ -1,40 +1,42 @@
/*===================================================================
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 "mitkPluginActivator.h"
#include <QtPlugin>
#include "../QmitkDataManagerView.h"
#include "../QmitkDataManagerPreferencePage.h"
#include "../QmitkDataManagerHotkeysPrefPage.h"
namespace mitk {
void PluginActivator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(QmitkDataManagerView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkDataManagerPreferencePage, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkDataManagerHotkeysPrefPage, context)
}
void PluginActivator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_datamanager, mitk::PluginActivator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_datamanager, mitk::PluginActivator)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.datamanager/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.datamanager/src/internal/mitkPluginActivator.h
index 489bd853ca..d55dc02e3e 100644
--- a/Plugins/org.mitk.gui.qt.datamanager/src/internal/mitkPluginActivator.h
+++ b/Plugins/org.mitk.gui.qt.datamanager/src/internal/mitkPluginActivator.h
@@ -1,40 +1,43 @@
/*===================================================================
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 MITKPLUGINACTIVATOR_H
#define MITKPLUGINACTIVATOR_H
#include <ctkPluginActivator.h>
#include <mitkExportMacros.h>
namespace mitk {
class MITK_LOCAL PluginActivator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_datamanager")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
}; // PluginActivator
}
#endif // MITKPLUGINACTIVATOR_H
diff --git a/Plugins/org.mitk.gui.qt.datamanagerlight/src/internal/QmitkDataManagerLightView.cpp b/Plugins/org.mitk.gui.qt.datamanagerlight/src/internal/QmitkDataManagerLightView.cpp
index f8f7065f46..78817ff6fd 100644
--- a/Plugins/org.mitk.gui.qt.datamanagerlight/src/internal/QmitkDataManagerLightView.cpp
+++ b/Plugins/org.mitk.gui.qt.datamanagerlight/src/internal/QmitkDataManagerLightView.cpp
@@ -1,251 +1,258 @@
/*===================================================================
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 "QmitkDataManagerLightView.h"
#include "mitkNodePredicateDataType.h"
-#include <QtGui>
+#include <QApplication>
+#include <QFileDialog>
+#include <QGridLayout>
+#include <QIcon>
+#include <QLabel>
+#include <QListWidget>
+#include <QMessageBox>
+#include <QPushButton>
#include <mitkCoreObjectFactory.h>
#include <mitkNodePredicateNot.h>
#include <mitkNodePredicateProperty.h>
#include <mitkIRenderingManager.h>
#include <mitkIOUtil.h>
const std::string QmitkDataManagerLightView::VIEW_ID = "org.mitk.views.datamanagerlight";
struct QmitkDataManagerLightViewData
{
// static
mitk::NodePredicateBase::Pointer m_Predicate;
QIcon m_ItemIcon;
// data
QList<mitk::DataNode*> m_DataNodes;
int m_CurrentIndex;
// widget
QListWidget* m_ListWidget;
QLabel* m_ImageInfoLabel;
QPushButton* m_RemoveButton;
};
QmitkDataManagerLightView::QmitkDataManagerLightView()
: d( new QmitkDataManagerLightViewData )
{
d->m_Predicate = mitk::NodePredicateDataType::New("Image");
d->m_ItemIcon = QIcon(":/org.mitk.gui.qt.datamanagerlight/Image_24.png");
d->m_CurrentIndex = -1;
d->m_ListWidget = 0;
d->m_ImageInfoLabel = 0;
d->m_RemoveButton = 0;
}
QmitkDataManagerLightView::~QmitkDataManagerLightView()
{
delete d;
}
void QmitkDataManagerLightView::NodeAdded(const mitk::DataNode *node)
{
if( d->m_Predicate->CheckNode(node) )
{
mitk::DataNode* nonConstNode = const_cast<mitk::DataNode*>(node);
d->m_DataNodes.append(nonConstNode);
d->m_ListWidget->addItem( new QListWidgetItem( d->m_ItemIcon, QString::fromStdString( node->GetName() ) ) );
}
}
void QmitkDataManagerLightView::NodeRemoved(const mitk::DataNode *node)
{
this->RemoveNode( const_cast<mitk::DataNode*>(node) );
}
void QmitkDataManagerLightView::NodeChanged(const mitk::DataNode *node)
{
MITK_DEBUG << "NodeChanged";
if( d->m_DataNodes.contains(const_cast<mitk::DataNode*>(node)) )
this->ToggleVisibility();
}
void QmitkDataManagerLightView::RemoveNode(mitk::DataNode *node)
{
mitk::DataNode* nonConstNode = const_cast<mitk::DataNode*>(node);
int index = d->m_DataNodes.indexOf(nonConstNode);
if( index >= 0 )
{
MITK_DEBUG << "removing node at: " << index;
QListWidgetItem* item = d->m_ListWidget->takeItem(index);
delete item;
d->m_DataNodes.removeAt(index);
MITK_DEBUG << "item deleted";
}
}
void QmitkDataManagerLightView::CreateQtPartControl(QWidget* parent)
{
QPushButton* loadButton = new QPushButton(QIcon(":/org.mitk.gui.qt.datamanagerlight/Load_48.png"), "Load");
d->m_RemoveButton = new QPushButton(QIcon(":/org.mitk.gui.qt.datamanagerlight/Remove_48.png"), "Remove");
d->m_RemoveButton->setEnabled(false);
d->m_ListWidget = new QListWidget;
d->m_ImageInfoLabel = new QLabel;
QGridLayout* layout = new QGridLayout;
layout->addWidget( loadButton, 0,0 );
layout->addWidget( d->m_RemoveButton, 0,1 );
layout->addWidget( d->m_ImageInfoLabel, 1,0, 1, 2 );
layout->addWidget( d->m_ListWidget, 2,0,1,2 );
parent->setLayout(layout);
connect(d->m_ListWidget, SIGNAL(currentRowChanged(int)), this, SLOT(on_DataItemList_currentRowChanged(int)) );
connect(loadButton, SIGNAL(pressed()), this, SLOT(on_Load_pressed()) );
connect(d->m_RemoveButton, SIGNAL(pressed()), this, SLOT(on_Remove_pressed()) );
this->ListSelectionChanged();
}
void QmitkDataManagerLightView::SetFocus()
{
d->m_ListWidget->setFocus();
}
void QmitkDataManagerLightView::on_DataItemList_currentRowChanged(int currentRow)
{
MITK_DEBUG << "DataItemList currentRowChanged: " << currentRow;
Q_UNUSED(currentRow)
this->ListSelectionChanged();
}
void QmitkDataManagerLightView::ListSelectionChanged()
{
d->m_CurrentIndex = d->m_ListWidget->currentRow();
MITK_DEBUG << "the currently selected index: " << d->m_CurrentIndex;
QString newLabelText = "Current patient: ";
if( d->m_CurrentIndex >= 0 )
{
// TODO WHERE IS THE PATIENT NAME?
std::string name = d->m_DataNodes.at(d->m_CurrentIndex)->GetName();
newLabelText.append( QString("<strong>%1</strong>" ).arg( QString::fromStdString(name) ) );
d->m_RemoveButton->setEnabled(true);
}
else
{
newLabelText.append("<strong>Unknown</strong>");
d->m_RemoveButton->setEnabled(false);
}
d->m_ImageInfoLabel->setText(newLabelText);
this->ToggleVisibility();
}
void QmitkDataManagerLightView::on_Load_pressed()
{
MITK_DEBUG << "on_Load_pressed";
QStringList fileNames = QFileDialog::getOpenFileNames(NULL, "Load data", "", mitk::CoreObjectFactory::GetInstance()->GetFileExtensions());
for ( QStringList::Iterator it = fileNames.begin(); it != fileNames.end(); ++it )
{
- FileOpen((*it).toAscii(), 0);
+ FileOpen((*it).toLatin1(), 0);
}
}
void QmitkDataManagerLightView::FileOpen( const char * fileName, mitk::DataNode* /*parentNode*/ )
{
try
{
QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) );
mitk::IOUtil::Load(fileName, *this->GetDataStorage());
mitk::RenderingManager::GetInstance()->InitializeViews();
}
catch ( itk::ExceptionObject & ex )
{
MITK_ERROR << "Exception during file open: " << ex;
}
QApplication::restoreOverrideCursor();
}
void QmitkDataManagerLightView::on_Remove_pressed()
{
d->m_CurrentIndex = d->m_ListWidget->currentRow();
MITK_DEBUG << "the currently selected index: " << d->m_CurrentIndex;
mitk::DataNode* node = d->m_DataNodes.at(d->m_CurrentIndex);
QString question = tr("Do you really want to remove ");
// TODO patient name?
question.append( QString::fromStdString( node->GetName() ) );
question.append(" ?");
QMessageBox::StandardButton answerButton = QMessageBox::question( NULL
, tr("DataManagerLight")
, question
, QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
if(answerButton == QMessageBox::Yes)
{
this->GetDataStorage()->Remove(node);
this->GlobalReinit();
}
}
void QmitkDataManagerLightView::GlobalReinit()
{
mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart();
// no render window available
if (renderWindow == NULL) return;
// get all nodes that have not set "includeInBoundingBox" to false
mitk::NodePredicateNot::Pointer pred
= mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("includeInBoundingBox"
, mitk::BoolProperty::New(false)));
mitk::DataStorage::SetOfObjects::ConstPointer rs = this->GetDataStorage()->GetSubset(pred);
// calculate bounding geometry of these nodes
mitk::TimeGeometry::Pointer bounds = this->GetDataStorage()->ComputeBoundingGeometry3D(rs, "visible");
// initialize the views to the bounding geometry
renderWindow->GetRenderingManager()->InitializeViews(bounds);
}
void QmitkDataManagerLightView::ToggleVisibility()
{
bool changedAnything = false;
bool isVisible = false;
for(size_t i=0; i<d->m_DataNodes.size(); ++i)
{
isVisible = false;
d->m_DataNodes.at(i)->GetVisibility(isVisible, 0 );
if( d->m_CurrentIndex == i && isVisible == false )
{
d->m_DataNodes.at(i)->SetVisibility(true);
changedAnything = true;
}
else if( d->m_CurrentIndex != i && isVisible == true )
{
d->m_DataNodes.at(i)->SetVisibility(false);
changedAnything = true;
}
}
if( changedAnything )
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
diff --git a/Plugins/org.mitk.gui.qt.datamanagerlight/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.datamanagerlight/src/internal/mitkPluginActivator.cpp
index f90ad379a6..fcfdc2351a 100644
--- a/Plugins/org.mitk.gui.qt.datamanagerlight/src/internal/mitkPluginActivator.cpp
+++ b/Plugins/org.mitk.gui.qt.datamanagerlight/src/internal/mitkPluginActivator.cpp
@@ -1,34 +1,36 @@
/*===================================================================
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 "mitkPluginActivator.h"
#include <QtPlugin>
#include "QmitkDataManagerLightView.h"
namespace mitk {
void PluginActivator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(QmitkDataManagerLightView, context)
}
void PluginActivator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_datamanagerlight, mitk::PluginActivator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_datamanagerlight, mitk::PluginActivator)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.datamanagerlight/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.datamanagerlight/src/internal/mitkPluginActivator.h
index 489bd853ca..3543c69b38 100644
--- a/Plugins/org.mitk.gui.qt.datamanagerlight/src/internal/mitkPluginActivator.h
+++ b/Plugins/org.mitk.gui.qt.datamanagerlight/src/internal/mitkPluginActivator.h
@@ -1,40 +1,43 @@
/*===================================================================
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 MITKPLUGINACTIVATOR_H
#define MITKPLUGINACTIVATOR_H
#include <ctkPluginActivator.h>
#include <mitkExportMacros.h>
namespace mitk {
class MITK_LOCAL PluginActivator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_datamanagerlight")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
}; // PluginActivator
}
#endif // MITKPLUGINACTIVATOR_H
diff --git a/Plugins/org.mitk.gui.qt.dicom/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.dicom/src/internal/mitkPluginActivator.cpp
index 29953d3894..7aec5f01b0 100644
--- a/Plugins/org.mitk.gui.qt.dicom/src/internal/mitkPluginActivator.cpp
+++ b/Plugins/org.mitk.gui.qt.dicom/src/internal/mitkPluginActivator.cpp
@@ -1,45 +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.
===================================================================*/
#include "mitkPluginActivator.h"
#include <QtPlugin>
#include "QmitkDicomBrowser.h"
#include "QmitkDicomPreferencePage.h"
namespace mitk {
ctkPluginContext* PluginActivator::pluginContext = 0;
void PluginActivator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(QmitkDicomBrowser, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkDicomPreferencePage, context)
pluginContext = context;
}
void PluginActivator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
pluginContext = NULL;
}
ctkPluginContext* PluginActivator::getContext()
{
return pluginContext;
}
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_dicom, mitk::PluginActivator)
\ No newline at end of file
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_dicom, mitk::PluginActivator)
+#endif
+
diff --git a/Plugins/org.mitk.gui.qt.dicom/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.dicom/src/internal/mitkPluginActivator.h
index 90aa1c78d5..4344913a9a 100644
--- a/Plugins/org.mitk.gui.qt.dicom/src/internal/mitkPluginActivator.h
+++ b/Plugins/org.mitk.gui.qt.dicom/src/internal/mitkPluginActivator.h
@@ -1,41 +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.
===================================================================*/
#ifndef MITKPLUGINACTIVATOR_H
#define MITKPLUGINACTIVATOR_H
#include <ctkPluginActivator.h>
namespace mitk {
class PluginActivator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_dicom")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
static ctkPluginContext* getContext();
private:
static ctkPluginContext* pluginContext;
}; // PluginActivator
}
#endif // MITKPLUGINACTIVATOR_H
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/DataImport/dicom1.png b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/DataImport/dicom1.png
index 0151f56bea..85ca20974f 100644
Binary files a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/DataImport/dicom1.png and b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/DataImport/dicom1.png differ
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/PreprocessingGUI_1.png b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/PreprocessingGUI_1.png
new file mode 100644
index 0000000000..d4dabb35fb
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/PreprocessingGUI_1.png differ
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/PreprocessingGUI_2.png b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/PreprocessingGUI_2.png
new file mode 100644
index 0000000000..40fe8e568e
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/PreprocessingGUI_2.png differ
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/PreprocessingGUI_3.png b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/PreprocessingGUI_3.png
new file mode 100644
index 0000000000..bee492bc62
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/PreprocessingGUI_3.png differ
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/PreprocessingGUI_4.png b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/PreprocessingGUI_4.png
new file mode 100644
index 0000000000..d138e18f0e
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/PreprocessingGUI_4.png differ
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/QmitkDiffusionImagingPreprocessingPage.dox b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/QmitkDiffusionImagingPreprocessingPage.dox
index ea1537cd97..96cabdde4f 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/QmitkDiffusionImagingPreprocessingPage.dox
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/QmitkDiffusionImagingPreprocessingPage.dox
@@ -1,9 +1,26 @@
/**
-\page QmitkDiffusionImagingPreprocessingPage Preprocessing of Diffusion Images
+\page org_mitk_views_diffusionpreprocessing Preprocessing of Diffusion Images
\section QmitkDiffusionImagingPreprocessingPagePreprocessing Preprocessing
-The preprocessing view gives an overview over the important features of a diffusion weighted image like the number of gradient directions, b-value and the measurement frame. Additionally it allows the extraction of the B0 image, reduction of gradient directions and the generation of a binary brain mask. The image volume can be modified by applying a new mesurement frame, which is useful if the measurement frame is not set correctly in the image header, or by averaging redundant gradient directions.
+The Preprocessing View bundles a selection of features and tools for dealing with diffusion weighted MR images. It can be used to modify header and geometry information, manipulate gradients and gradient images as well as calculating ADC maps.
-\imageMacro{prepro1.png,"Preprocessing",9.97}
-*/
\ No newline at end of file
+\section QmitkDiffusionImagingPreprocessingPageDetails Details
+
+\imageMacro{PreprocessingGUI_1.png,"Gradients tab",9.97}
+
+The Gradients tab allows you to examine the number of b values and how many gradients were acquired for each. Here you can also visualize the gradients as points on a sphere, mirror opposite gradients so all are oriented within the same half sphere, round b values and merge similar gradients.
+
+\imageMacro{PreprocessingGUI_2.png,"Image values tab",9.97}
+
+The Image values tab enables you to manipulate the voxel values by e.g. resampling images, averaging repetitions of the same gradient, normalizing the image values or merging several DWIs into one.
+
+\imageMacro{PreprocessingGUI_3.png,"Header tab",9.97}
+
+In the Header tab you can selectively change geometry information of the image and delete or extract specific gradient volumes.
+
+\imageMacro{PreprocessingGUI_4.png,"Other tab",9.97}
+
+Miscellaneous tools in the Other tab allow for ADC map calculation and the extraction of the b0 image with the possibility of averaging all b0 images.
+
+*/
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/QmitkDiffusionImagingRegistration.dox b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/QmitkDiffusionImagingRegistration.dox
index 354700a564..771863b4ba 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/QmitkDiffusionImagingRegistration.dox
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/QmitkDiffusionImagingRegistration.dox
@@ -1,16 +1,16 @@
/**
-\page QmitkDiffusionImagingDWIRegistrationPage DWI Registration
+\page org_mitk_views_diffusionregistrationview DWI Registration
\section QmitkDiffusionImagingUserManualDWIRegistration DWI Registration
The DWI registration view allows head-motion and eddy-current correction. First the b=0 images (if more than 1) are registered and averaged. The averaged image then serves as fixed image for the alignment of the remaining (weighted, b>0) images.
\imageMacro{registration_basic.png,"Basic DWI Registration Interface",8.00}
In the basic settings, a selected DW image in the Data Manager is marked as Input Data and the <i> Start Head Motion Correction </i> button is enabled. If more than one DW images are selected, they will be processed in a consecutive manner. For larger sets of dw images to be processed, the <i> Advanced </i> settings can be used.
\imageMacro{registration_batch.png,"Batch Processing DWI Registration Interface",8.00}
Here all valid .dwi data located in the given input folder will be processed through the head motion correction and the output will be stored in the current working directory or in a custom folder if specified in the user interface. The output image will have the _MC postfix attached to the input's name.
-*/
\ No newline at end of file
+*/
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/QmitkDiffusionImagingVisualization.dox b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/QmitkDiffusionImagingVisualization.dox
index eff05db5ed..cc1e7156ce 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/QmitkDiffusionImagingVisualization.dox
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/QmitkDiffusionImagingVisualization.dox
@@ -1,19 +1,19 @@
/**
-\page QmitkDiffusionImagingVisualization ODF Visualization
+\page org_mitk_views_controlvisualizationpropertiesview ODF Visualization
\section QmitkDiffusionImagingVisualizationSettings ODF Visualization Setting
In this small view, the visualization of ODFs and diffusion images can be configured. Depending on the selected image in the data storage, different options are shown here.
For tensor or q-ball images, the visibility of glyphs in the different render windows (T)ransversal, (S)agittal, and (C)oronal can be configured here. The maximal number of glyphs to display can also be configured here for. This is usefull to keep the system response time during rendering feasible. The other options configure normalization and scaling of the glyphs.
In diffusion images, a slider lets you choose the desired image channel from the vector of images (each gradient direction one image) for rendering. Furthermore reinit can be performed and texture interpolation toggled.
This is how a visualization with activated glyphs should look like:
\imageMacro{visualization3.png,"Q-ball image with ODF glyph visibility toggled ON",16.00}
*/
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/QmitkOdfDetailsViewUserManual.dox b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/QmitkOdfDetailsViewUserManual.dox
index 96495480d4..257071dffa 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/QmitkOdfDetailsViewUserManual.dox
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/QmitkOdfDetailsViewUserManual.dox
@@ -1,8 +1,8 @@
/**
\page org_mitk_views_odfdetails ODF Details View
This view provides detailed information about the orentation distribution function at the current crosshair position (if a Tensor/Q-Ball image is selected). A visualization of the ODF as well as statistical information are displayed.
-\imageMacro{odfdetails.png,"The Gibbs Tracking View",10.01}
+\imageMacro{odfdetails.png,"The ODF Details View",10.01}
*/
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/prepro1.png b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/prepro1.png
deleted file mode 100644
index 90b679ee66..0000000000
Binary files a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/prepro1.png and /dev/null differ
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/qballs1.png b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/qballs1.png
index 379f21dc7e..1493a30fdf 100644
Binary files a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/qballs1.png and b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/qballs1.png differ
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/qballs2.png b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/qballs2.png
index b208895fc7..981d387842 100644
Binary files a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/qballs2.png and b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/qballs2.png differ
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/qballs3.png b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/qballs3.png
index 8f5155ae2f..9eea5739a5 100644
Binary files a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/qballs3.png and b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/qballs3.png differ
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/residuals.png b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/residuals.png
index 626fbaf6e3..f9d4996e15 100644
Binary files a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/residuals.png and b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/residuals.png differ
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/tensor1.png b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/tensor1.png
index 6aae4ff4d9..23af1def89 100644
Binary files a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/tensor1.png and b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/tensor1.png differ
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/tensor4.png b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/tensor4.png
index c4708fff21..546ab70b2f 100644
Binary files a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/tensor4.png and b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/tensor4.png differ
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/visualization3.png b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/visualization3.png
index acc816f8d7..1f0a0fd15b 100644
Binary files a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/visualization3.png and b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Preproc_Recons/visualization3.png differ
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/QmitkDiffusionImagingPortalPage.dox b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/QmitkDiffusionImagingPortalPage.dox
index 0ba46fa6f0..571689e8e1 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/QmitkDiffusionImagingPortalPage.dox
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/QmitkDiffusionImagingPortalPage.dox
@@ -1,84 +1,84 @@
/**
\page org_mitk_gui_qt_diffusionimaging MITK Diffusion Imaging (MITK-DI)
\tableofcontents
This module provides means to diffusion weighted image reconstruction, visualization and quantification. Diffusion tensors as well as different q-ball reconstruction schemes are supported. Q-ball imaging aims at recovering more detailed information about the orientations of fibers from diffusion MRI measurements and, in particular, to resolve the orientations of crossing fibers.
\section org_mitk_gui_qt_diffusionimagingComponents Components
MITK Diffusion consists of further components, which have their own documentation, see:
\subsection org_mitk_gui_qt_diffusionimagingComponentsDataImport Data Import
\li \subpage QmitkDiffusionImagingDataImportPage
\subsection org_mitk_gui_qt_diffusionimagingComponentsPreprocessingAndReconstruction Preprocessing and Reconstruction
Register or denoise original data and convert it into tensor or q-ball images.
- \li \subpage QmitkDiffusionImagingDWIRegistrationPage
- \li \subpage QmitkDiffusionImagingPreprocessingPage
+ \li \subpage org_mitk_views_diffusionregistrationview
+ \li \subpage org_mitk_views_diffusionpreprocessing
\li \subpage QmitkDiffusionImagingReconstructionPage
- \li \subpage QmitkDiffusionImagingVisualization
+ \li \subpage org_mitk_views_controlvisualizationpropertiesview
\li \subpage org_mitk_views_odfdetails
\li \subpage org_mitk_views_odfmaximaextraction
\li \subpage org_mitk_views_denoisingview
\subsection org_mitk_gui_qt_diffusionimagingComponentsFiberTracking Fiber Tracking
Create and work with fiber tractographies.
\li \subpage org_mitk_views_fiberprocessing
\li \subpage org_mitk_views_gibbstracking
\li \subpage org_mitk_views_stochasticfibertracking
\li \subpage org_mitk_views_fiberextraction
\li \subpage org_mitk_views_fiberprocessing
\li \subpage org_mitk_views_streamlinetracking
\li \subpage org_mitk_views_fiberfoxview
\li \subpage org_mitk_views_fieldmapgenerator
\subsection org_mitk_gui_qt_diffusionimagingComponentsQuantification Quantification
Create parameter maps and quantify different properties.
- \li \subpage QmitkDiffusionImagingQuantificationPage
+ \li \subpage org_mitk_views_diffusionquantification
\li \subpage org_mitk_views_ivim
\li \subpage org_mitk_views_partialvolumeanalysisview
\li \subpage org_mitk_views_tractbasedspatialstatistics
\subsection org_mitk_gui_qt_diffusionimagingComponentsConnectomics Connectomics
Create and analyse connectome networks.
\li \subpage org_mitk_diffusionimagingapp_perspectives_connectomics
\section org_mitk_gui_qt_diffusionimagingIssues Known Issues
\li <b>Dicom Import:</b> The dicom import has so far only been implemented for Siemens dicom images. MITK-DI is capable of reading the nrrd format, which is documented elsewhere [1, 2]. These files can be created by combining the raw image data with a corresponding textual header file. The file extension should be changed from *.nrrd to *.dwi or from *.nhdr to *.hdwi respectively in order to let MITK-DI recognize the diffusion related header information provided in the files.
\section org_mitk_gui_qt_diffusionimagingTechnicalDetails Technical Information for Developers
The diffusion imaging module uses additional properties beside the ones in use in other modules, for further information see \ref DiffusionImagingPropertiesPage .
\section org_mitk_gui_qt_diffusionimagingReferences References
Further reading regarding diffusion:
1. http://teem.sourceforge.net/nrrd/format.html
2. http://www.cmake.org/Wiki/Getting_Started_with_the_NRRD_Format
3. C.F.Westin, S.E.Maier, H.Mamata, A.Nabavi, F.A.Jolesz, R.Kikinis, "Processing and visualization for Diffusion tensor MRI", Medical image Analysis, 2002, pp 93-108
5. Tuch, D.S., 2004. Q-ball imaging. Magn Reson Med 52, 1358-1372.
6. Descoteaux, M., Angelino, E., Fitzgibbons, S., Deriche, R., 2007. Regularized, fast, and robust analytical Q-ball imaging. Magn Reson Med 58, 497-510.
7. Aganj, I., Lenglet, C., Sapiro, G., 2009. ODF reconstruction in q-ball imaging with solid angle consideration. Proceedings of the Sixth IEEE International Symposium on Biomedical Imaging Boston, MA.
8. Goh, A., Lenglet, C., Thompson, P.M., Vidal, R., 2009. Estimating Orientation Distribution Functions with Probability Density Constraints and Spatial Regularity. Med Image Comput Comput Assist Interv Int Conf Med Image Comput Comput Assist Interv LNCS 5761, 877 ff.
9. J.-D. Tournier, S. Mori, A. Leemans., 2011. Diffusion Tensor Imaging and Beyond. Magn Reson Med 65, 1532-1556.
-*/
\ No newline at end of file
+*/
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Quantification/QmitkDiffusionImagingQuantificationPage.dox b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Quantification/QmitkDiffusionImagingQuantificationPage.dox
index c3ca35f105..cec142beed 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Quantification/QmitkDiffusionImagingQuantificationPage.dox
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Quantification/QmitkDiffusionImagingQuantificationPage.dox
@@ -1,8 +1,8 @@
/**
-\page QmitkDiffusionImagingQuantificationPage Quantification
+\page org_mitk_views_diffusionquantification Scalar Indices
-The quantification view allows the derivation of different scalar anisotropy measures for the reconstructed tensors (Fractional Anisotropy, Relative Anisotropy, Axial Diffusivity, Radial Diffusivity) or q-balls (Generalized Fractional Anisotropy).
+The scalar indices view allows the derivation of different scalar anisotropy measures for the reconstructed tensors (Fractional Anisotropy, Relative Anisotropy, Axial Diffusivity, Radial Diffusivity) or q-balls (Generalized Fractional Anisotropy).
-\imageMacro{quantification.png,"Anisotropy quantification",2}
-*/
\ No newline at end of file
+\imageMacro{ScalarIndicesGUI.png,"Anisotropy quantification",2}
+*/
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Quantification/ScalarIndicesGUI.png b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Quantification/ScalarIndicesGUI.png
new file mode 100644
index 0000000000..e3688f56cc
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Quantification/ScalarIndicesGUI.png differ
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Quantification/quantification.png b/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Quantification/quantification.png
deleted file mode 100644
index a768b66dca..0000000000
Binary files a/Plugins/org.mitk.gui.qt.diffusionimaging/documentation/UserManual/Quantification/quantification.png and /dev/null differ
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/QmitkIVIMWidget.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/QmitkIVIMWidget.cpp
index cd3f7aa0b5..13ca553e98 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/QmitkIVIMWidget.cpp
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/QmitkIVIMWidget.cpp
@@ -1,150 +1,150 @@
/*===================================================================
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 "QmitkIVIMWidget.h"
#include "mitkHistogramGenerator.h"
#include <qwt_scale_engine.h>
#include <qwt_legend.h>
QmitkIVIMWidget::QmitkIVIMWidget( QWidget * parent )
: QmitkPlotWidget(parent)
{
// this->SetAxisTitle( QwtPlot::xBottom, "Grayvalue" );
// this->SetAxisTitle( QwtPlot::yLeft, "Probability" );
// this->Replot();
QFrame* canvas = qobject_cast<QFrame*>(m_Plot->canvas());
if (canvas)
{
canvas->setLineWidth(0);
canvas->setContentsMargins(0,0,0,0);
}
QwtLogScaleEngine* logScale = new QwtLogScaleEngine();
m_Plot->setAxisScaleEngine(0, logScale);
m_Plot->setAxisScale( 0, 0.15, 1.0 );
}
QmitkIVIMWidget::~QmitkIVIMWidget()
{
}
void QmitkIVIMWidget::DrawGauss()
{
}
void QmitkIVIMWidget::ClearItemModel()
{
}
std::vector<double> QmitkIVIMWidget::vec(const vnl_vector<double>& vector)
{
std::vector<double> retval(vector.size());
for(unsigned int i=0; i<vector.size(); i++)
{
retval.at(i) = vector[i];
}
return retval;
}
void QmitkIVIMWidget::SetParameters( IVIMFilterType::IVIMSnapshot snap )
{
this->Clear();
if (snap.bvalues.empty())
return;
QString s("f=%1, D=%2, D*=%3");
s = s.arg(snap.currentF,4);
s = s.arg(snap.currentD,4);
s = s.arg(snap.currentDStar,4);
- int curveId = this->InsertCurve( s.toAscii() );
+ int curveId = this->InsertCurve( s.toLatin1() );
this->SetCurvePen( curveId, QPen( Qt::NoPen ) );
curveId = this->InsertCurve( "ignored measurement points" );
this->SetCurveData( curveId, vec(snap.bvalues), vec(snap.allmeas) );
this->SetCurvePen( curveId, QPen(Qt::NoPen) );
QwtSymbol* whiteSymbol = new QwtSymbol(QwtSymbol::Diamond, QColor(Qt::white), QColor(Qt::black), QSize(10,10));
this->SetCurveSymbol(curveId, whiteSymbol);
if(snap.currentDStar != 0)
{
curveId = this->InsertCurve( "additional points second fit" );
this->SetCurveData( curveId, vec(snap.bvals2), vec(snap.meas2) );
this->SetCurvePen( curveId, QPen( Qt::NoPen ) );
QwtSymbol* blackSymbol = new QwtSymbol(QwtSymbol::Diamond, QColor(Qt::black), QColor(Qt::black), QSize(10,10));
this->SetCurveSymbol(curveId, blackSymbol);
}
curveId = this->InsertCurve( "points first fit" );
this->SetCurveData( curveId, vec(snap.bvals1), vec(snap.meas1) );
this->SetCurvePen( curveId, QPen( Qt::NoPen ) );
QwtSymbol* redSymbol = new QwtSymbol(QwtSymbol::Diamond, QColor(Qt::red), QColor(Qt::red), QSize(10,10));
this->SetCurveSymbol(curveId, redSymbol);
QPen pen;
pen.setColor( QColor(Qt::red) );
pen.setWidth(2);
double maxb = snap.bvalues.max_value();
vnl_vector<double> xvals(2);
vnl_vector<double> yvals(2);
xvals[0] = 0;
xvals[1] = maxb;
yvals[0] = 1-snap.currentFunceiled;
yvals[1] = yvals[0]*exp(-maxb * snap.currentD);
curveId = this->InsertCurve( "contribution of D to the signal" );
this->SetCurveData( curveId, vec(xvals), vec(yvals) );
this->SetCurvePen( curveId, pen );
if(snap.currentDStar != 0)
{
pen.setColor(Qt::black);
int nsampling = 50;
xvals.set_size(nsampling);
yvals.set_size(nsampling);
double f = 1-snap.currentFunceiled;
for(int i=0; i<nsampling; i++)
{
xvals[i] = (((1.0)*i)/(1.0*nsampling))*maxb;
yvals[i] = f*exp(- xvals[i] * snap.currentD) + (1-f)*exp(- xvals[i] * (snap.currentD+snap.currentDStar));
}
curveId = this->InsertCurve( "resulting fit of the model" );
this->SetCurveData( curveId, vec(xvals), vec(yvals) );
this->SetCurvePen( curveId, pen );
}
// QMargins margins;
// margins.setBottom(0);
// margins.setLeft(0);
// margins.setRight(0);
// margins.setTop(0);
QwtLegend* legend = new QwtLegend();
// legend->setContentsMargins(margins);
m_Plot->insertLegend(legend, QwtPlot::BottomLegend);
this->Replot();
}
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/QmitkTbssRoiAnalysisWidget.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/QmitkTbssRoiAnalysisWidget.cpp
index c5f67dc846..372a08f150 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/QmitkTbssRoiAnalysisWidget.cpp
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/QmitkTbssRoiAnalysisWidget.cpp
@@ -1,967 +1,967 @@
/*===================================================================
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 "QmitkTbssRoiAnalysisWidget.h"
#include "mitkImagePixelReadAccessor.h"
#include "mitkPixelTypeMultiplex.h"
#include <qwt_plot_marker.h>
#include <qwt_plot_picker.h>
#include <qwt_picker_machine.h>
#include <vtkCellArray.h>
QmitkTbssRoiAnalysisWidget::QmitkTbssRoiAnalysisWidget( QWidget * parent )
: QmitkPlotWidget(parent)
{
m_PlotPicker = new QwtPlotPicker(m_Plot->canvas());
m_PlotPicker->setStateMachine(new QwtPickerDragPointMachine());
m_PlotPicker->setTrackerMode(QwtPicker::ActiveOnly);
m_PlottingFiberBundle = false;
}
void QmitkTbssRoiAnalysisWidget::DoPlotFiberBundles(mitk::FiberBundleX *fib, mitk::Image* img,
mitk::PlanarFigure* startRoi, mitk::PlanarFigure* endRoi, bool avg, int number)
{
TractContainerType tracts = CreateTracts(fib, startRoi, endRoi);
TractContainerType resampledTracts = ParameterizeTracts(tracts, number);
// Now we have the resampled tracts. Next we should use these points to read out the values
mitkPixelTypeMultiplex3(PlotFiberBundles,img->GetImageDescriptor()->GetChannelTypeById(0),resampledTracts, img, avg);
m_CurrentTracts = resampledTracts;
}
TractContainerType QmitkTbssRoiAnalysisWidget::CreateTracts(mitk::FiberBundleX *fib,
mitk::PlanarFigure *startRoi,
mitk::PlanarFigure *endRoi)
{
- mitk::PlaneGeometry* startGeometry2D = dynamic_cast<mitk::PlaneGeometry*>( const_cast<mitk::Geometry2D*>(startRoi->GetGeometry2D()) );
- mitk::PlaneGeometry* endGeometry2D = dynamic_cast<mitk::PlaneGeometry*>( const_cast<mitk::Geometry2D*>(endRoi->GetGeometry2D()) );
+ mitk::PlaneGeometry* startGeometry2D = const_cast<mitk::PlaneGeometry*>(startRoi->GetPlaneGeometry());
+ mitk::PlaneGeometry* endGeometry2D = const_cast<mitk::PlaneGeometry*>(endRoi->GetPlaneGeometry());
mitk::Point3D startCenter = startRoi->GetWorldControlPoint(0); //center Point of start roi
mitk::Point3D endCenter = endRoi->GetWorldControlPoint(0); //center Point of end roi
mitk::FiberBundleX::Pointer inStart = fib->ExtractFiberSubset(startRoi);
mitk::FiberBundleX::Pointer inBoth = inStart->ExtractFiberSubset(endRoi);
int num = inBoth->GetNumFibers();
TractContainerType tracts;
vtkSmartPointer<vtkPolyData> fiberPolyData = inBoth->GetFiberPolyData();
vtkCellArray* lines = fiberPolyData->GetLines();
lines->InitTraversal();
// Now find out for each fiber which ROI is encountered first. If this is the startRoi, the direction is ok
// Otherwise the plot should be in the reverse direction
for( int fiberID( 0 ); fiberID < num; fiberID++ )
{
vtkIdType numPointsInCell(0);
vtkIdType* pointsInCell(NULL);
lines->GetNextCell ( numPointsInCell, pointsInCell );
int startId = 0;
int endId = 0;
mitk::ScalarType minDistStart = std::numeric_limits<mitk::ScalarType>::max();
mitk::ScalarType minDistEnd = std::numeric_limits<mitk::ScalarType>::max();
for( int pointInCellID( 0 ); pointInCellID < numPointsInCell ; pointInCellID++)
{
mitk::ScalarType *p = fiberPolyData->GetPoint( pointsInCell[ pointInCellID ] );
mitk::Point3D point;
point[0] = p[0];
point[1] = p[1];
point[2] = p[2];
mitk::ScalarType distanceToStart = point.EuclideanDistanceTo(startCenter);
mitk::ScalarType distanceToEnd = point.EuclideanDistanceTo(endCenter);
if(distanceToStart < minDistStart)
{
minDistStart = distanceToStart;
startId = pointInCellID;
}
if(distanceToEnd < minDistEnd)
{
minDistEnd = distanceToEnd;
endId = pointInCellID;
}
}
/* We found the start and end points of of the part that should be plottet for
the current fiber. now we need to plot them. If the endId is smaller than the startId the plot order
must be reversed*/
TractType singleTract;
PointType point;
if(startId < endId)
{
// Calculate the intersection of the ROI with the startRoi and decide if the startId is part of the roi or must be cut of
mitk::ScalarType *p = fiberPolyData->GetPoint( pointsInCell[ startId ] );
mitk::Vector3D p0;
p0[0] = p[0]; p0[1] = p[1]; p0[2] = p[2];
p = fiberPolyData->GetPoint( pointsInCell[ startId+1 ] );
mitk::Vector3D p1;
p1[0] = p[0]; p1[1] = p[1]; p1[2] = p[2];
// Check if p and p2 are both on the same side of the plane
mitk::Vector3D normal = startGeometry2D->GetNormal();
mitk::Point3D pStart;
pStart[0] = p0[0]; pStart[1] = p0[1]; pStart[2] = p0[2];
mitk::Point3D pSecond;
pSecond[0] = p1[0]; pSecond[1] = p1[1]; pSecond[2] = p1[2];
bool startOnPositive = startGeometry2D->IsAbove(pStart);
bool secondOnPositive = startGeometry2D->IsAbove(pSecond);
mitk::Vector3D onPlane;
onPlane[0] = startCenter[0]; onPlane[1] = startCenter[1]; onPlane[2] = startCenter[2];
if(! (secondOnPositive ^ startOnPositive) )
{
/* startId and startId+1 lie on the same side of the plane, so we need
need startId-1 to calculate the intersection with the planar figure*/
p = fiberPolyData->GetPoint( pointsInCell[ startId-1 ] );
p1[0] = p[0]; p1[1] = p[1]; p1[2] = p[2];
}
mitk::ScalarType d = ( (onPlane-p0)*normal) / ( (p0-p1) * normal );
mitk::Vector3D newPoint = (p0-p1);
point[0] = d*newPoint[0] + p0[0];
point[1] = d*newPoint[1] + p0[1];
point[2] = d*newPoint[2] + p0[2];
singleTract.push_back(point);
if(! (secondOnPositive ^ startOnPositive) )
{
/* StartId and startId+1 lie on the same side of the plane
so startId is also part of the ROI*/
mitk::ScalarType *start = fiberPolyData->GetPoint( pointsInCell[startId] );
point[0] = start[0]; point[1] = start[1]; point[2] = start[2];
singleTract.push_back(point);
}
for( int pointInCellID( startId+1 ); pointInCellID < endId ; pointInCellID++)
{
// push back point
mitk::ScalarType *p = fiberPolyData->GetPoint( pointsInCell[ pointInCellID ] );
point[0] = p[0]; point[1] = p[1]; point[2] = p[2];
singleTract.push_back( point );
}
/* endId must be included if endId and endId-1 lie on the same side of the
plane defined by endRoi*/
p = fiberPolyData->GetPoint( pointsInCell[ endId ] );
p0[0] = p[0]; p0[1] = p[1]; p0[2] = p[2];
p = fiberPolyData->GetPoint( pointsInCell[ endId-1 ] );
p1[0] = p[0]; p1[1] = p[1]; p1[2] = p[2];
mitk::Point3D pLast;
pLast[0] = p0[0]; pLast[1] = p0[1]; pLast[2] = p0[2];
mitk::Point3D pBeforeLast;
pBeforeLast[0] = p1[0]; pBeforeLast[1] = p1[1]; pBeforeLast[2] = p1[2];
normal = endGeometry2D->GetNormal();
bool lastOnPositive = endGeometry2D->IsAbove(pLast);
bool secondLastOnPositive = endGeometry2D->IsAbove(pBeforeLast);
onPlane[0] = endCenter[0];
onPlane[1] = endCenter[1];
onPlane[2] = endCenter[2];
if(! (lastOnPositive ^ secondLastOnPositive) )
{
/* endId and endId-1 lie on the same side of the plane, so we need
need endId+1 to calculate the intersection with the planar figure.
this should exist since we know that the fiber crosses the planar figure
endId is also part of the tract and can be inserted here */
p = fiberPolyData->GetPoint( pointsInCell[ endId ] );
point[0] = p[0]; point[1] = p[1]; point[2] = p[2];
singleTract.push_back( point );
p = fiberPolyData->GetPoint( pointsInCell[ endId+1 ] );
}
d = ( (onPlane-p0)*normal) / ( (p0-p1) * normal );
newPoint = (p0-p1);
point[0] = d*newPoint[0] + p0[0];
point[1] = d*newPoint[1] + p0[1];
point[2] = d*newPoint[2] + p0[2];
singleTract.push_back(point);
}
else{
// Calculate the intersection of the ROI with the startRoi and decide if the startId is part of the roi or must be cut of
mitk::ScalarType *p = fiberPolyData->GetPoint( pointsInCell[ startId ] );
mitk::Vector3D p0;
p0[0] = p[0]; p0[1] = p[1]; p0[2] = p[2];
p = fiberPolyData->GetPoint( pointsInCell[ startId-1 ] );
mitk::Vector3D p1;
p1[0] = p[0]; p1[1] = p[1]; p1[2] = p[2];
// Check if p and p2 are both on the same side of the plane
mitk::Vector3D normal = startGeometry2D->GetNormal();
mitk::Point3D pStart;
pStart[0] = p0[0]; pStart[1] = p0[1]; pStart[2] = p0[2];
mitk::Point3D pSecond;
pSecond[0] = p1[0]; pSecond[1] = p1[1]; pSecond[2] = p1[2];
bool startOnPositive = startGeometry2D->IsAbove(pStart);
bool secondOnPositive = startGeometry2D->IsAbove(pSecond);
mitk::Vector3D onPlane;
onPlane[0] = startCenter[0]; onPlane[1] = startCenter[1]; onPlane[2] = startCenter[2];
if(! (secondOnPositive ^ startOnPositive) )
{
/* startId and startId+1 lie on the same side of the plane, so we need
need startId-1 to calculate the intersection with the planar figure*/
p = fiberPolyData->GetPoint( pointsInCell[ startId-1 ] );
p1[0] = p[0]; p1[1] = p[1]; p1[2] = p[2];
}
mitk::ScalarType d = ( (onPlane-p0)*normal) / ( (p0-p1) * normal );
mitk::Vector3D newPoint = (p0-p1);
point[0] = d*newPoint[0] + p0[0];
point[1] = d*newPoint[1] + p0[1];
point[2] = d*newPoint[2] + p0[2];
singleTract.push_back(point);
if(! (secondOnPositive ^ startOnPositive) )
{
/* StartId and startId+1 lie on the same side of the plane
so startId is also part of the ROI*/
mitk::ScalarType *start = fiberPolyData->GetPoint( pointsInCell[startId] );
point[0] = start[0]; point[1] = start[1]; point[2] = start[2];
singleTract.push_back(point);
}
for( int pointInCellID( startId-1 ); pointInCellID > endId ; pointInCellID--)
{
// push back point
mitk::ScalarType *p = fiberPolyData->GetPoint( pointsInCell[ pointInCellID ] );
point[0] = p[0]; point[1] = p[1]; point[2] = p[2];
singleTract.push_back( point );
}
/* endId must be included if endId and endI+1 lie on the same side of the
plane defined by endRoi*/
p = fiberPolyData->GetPoint( pointsInCell[ endId ] );
p0[0] = p[0]; p0[1] = p[1]; p0[2] = p[2];
p = fiberPolyData->GetPoint( pointsInCell[ endId+1 ] );
p1[0] = p[0]; p1[1] = p[1]; p1[2] = p[2];
mitk::Point3D pLast;
pLast[0] = p0[0]; pLast[1] = p0[1]; pLast[2] = p0[2];
mitk::Point3D pBeforeLast;
pBeforeLast[0] = p1[0]; pBeforeLast[1] = p1[1]; pBeforeLast[2] = p1[2];
bool lastOnPositive = endGeometry2D->IsAbove(pLast);
bool secondLastOnPositive = endGeometry2D->IsAbove(pBeforeLast);
normal = endGeometry2D->GetNormal();
onPlane[0] = endCenter[0];
onPlane[1] = endCenter[1];
onPlane[2] = endCenter[2];
if(! (lastOnPositive ^ secondLastOnPositive) )
{
/* endId and endId+1 lie on the same side of the plane, so we need
need endId-1 to calculate the intersection with the planar figure.
this should exist since we know that the fiber crosses the planar figure
endId is also part of the tract and can be inserted here */
p = fiberPolyData->GetPoint( pointsInCell[ endId ] );
point[0] = p[0]; point[1] = p[1]; point[2] = p[2];
singleTract.push_back( point );
p = fiberPolyData->GetPoint( pointsInCell[ endId-1 ] );
}
d = ( (onPlane-p0)*normal) / ( (p0-p1) * normal );
newPoint = (p0-p1);
point[0] = d*newPoint[0] + p0[0];
point[1] = d*newPoint[1] + p0[1];
point[2] = d*newPoint[2] + p0[2];
singleTract.push_back(point);
}
tracts.push_back(singleTract);
}
return tracts;
}
void QmitkTbssRoiAnalysisWidget::PlotFiberBetweenRois(mitk::FiberBundleX *fib, mitk::Image* img,
mitk::PlanarFigure* startRoi, mitk::PlanarFigure* endRoi, bool avg, int number)
{
if(fib == NULL || img == NULL || startRoi == NULL || endRoi == NULL)
return;
m_Fib = fib;
m_CurrentImage = img;
m_CurrentStartRoi = startRoi;
m_CurrentEndRoi = endRoi;
DoPlotFiberBundles(fib, img, startRoi, endRoi, avg, number);
}
void QmitkTbssRoiAnalysisWidget::ModifyPlot(int number, bool avg)
{
if(m_Fib == NULL || m_CurrentTbssImage == NULL || m_CurrentStartRoi == NULL || m_CurrentEndRoi == NULL)
return;
if(m_PlottingFiberBundle)
{
DoPlotFiberBundles(m_Fib, m_CurrentImage, m_CurrentStartRoi, m_CurrentEndRoi, avg, number);
}
else
{
PlotFiber4D(m_CurrentTbssImage, m_Fib, m_CurrentStartRoi, m_CurrentEndRoi, number);
}
}
TractContainerType QmitkTbssRoiAnalysisWidget::ParameterizeTracts(TractContainerType tracts, int number)
{
TractContainerType resampledTracts;
for(TractContainerType::iterator it = tracts.begin(); it != tracts.end(); ++it)
{
TractType resampledTract;
TractType tract = *it;
// Calculate the total length
mitk::ScalarType totalLength = 0;
if(tract.size() < 2)
continue;
PointType p0 = tract.at(0);
for(unsigned int i = 1; i<tract.size(); i++)
{
PointType p1 = tract.at(i);
mitk::ScalarType length = p0.EuclideanDistanceTo(p1);
totalLength += length;
p0 = p1;
}
mitk::ScalarType stepSize = totalLength / number;
p0 = tract.at(0);
PointType p1 = tract.at(1);
unsigned int tractCounter = 2;
mitk::ScalarType distance = p0.EuclideanDistanceTo(p1);
mitk::ScalarType locationBetween = 0;
for(mitk::ScalarType position = 0;
position <= totalLength+0.001 && resampledTract.size() <= (number+1);
position+=stepSize)
{
/* In case we walked to far we need to find the next segment we are on and on what relative position on that
tract we are on. Small correction for rounding errors */
while(locationBetween > distance+0.001)
{
if(tractCounter == tract.size())
std::cout << "problem";
// Determine by what distance we are no on the next segment
locationBetween = locationBetween - distance;
p0 = p1;
p1 = tract.at(tractCounter);
tractCounter++;
distance = p0.EuclideanDistanceTo(p1);
}
// Direction
PointType::VectorType direction = p1-p0;
direction.Normalize();
PointType newSample = p0 + direction*locationBetween;
resampledTract.push_back(newSample);
locationBetween += stepSize;
}
resampledTracts.push_back(resampledTract);
}
return resampledTracts;
}
mitk::Point3D QmitkTbssRoiAnalysisWidget::GetPositionInWorld(int index)
{
mitk::ScalarType xSum = 0.0;
mitk::ScalarType ySum = 0.0;
mitk::ScalarType zSum = 0.0;
for(TractContainerType::iterator it = m_CurrentTracts.begin();
it!=m_CurrentTracts.end(); ++it)
{
TractType tract = *it;
PointType p = tract.at(index);
xSum += p[0];
ySum += p[1];
zSum += p[2];
}
int number = m_CurrentTracts.size();
mitk::ScalarType xPos = xSum / number;
mitk::ScalarType yPos = ySum / number;
mitk::ScalarType zPos = zSum / number;
mitk::Point3D pos;
pos[0] = xPos;
pos[1] = yPos;
pos[2] = zPos;
return pos;
}
std::vector< std::vector<mitk::ScalarType> > QmitkTbssRoiAnalysisWidget::CalculateGroupProfiles()
{
MITK_INFO << "make profiles!";
std::vector< std::vector<mitk::ScalarType> > profiles;
int size = m_Projections->GetVectorLength();
for(int s=0; s<size; s++)
{
// Iterate trough the roi
std::vector<mitk::ScalarType> profile;
RoiType::iterator it;
it = m_Roi.begin();
while(it != m_Roi.end())
{
itk::Index<3> ix = *it;
profile.push_back(m_Projections->GetPixel(ix).GetElement(s));
it++;
}
profiles.push_back(profile);
}
m_IndividualProfiles = profiles;
// Calculate the averages
// Here a check could be build in to check whether all profiles have
// the same length, but this should normally be the case if the input
// data were corrected with the TBSS Module.
std::vector< std::vector<mitk::ScalarType> > groupProfiles;
std::vector< std::pair<std::string, int> >::iterator it;
it = m_Groups.begin();
int c = 0; //the current profile number
while(it != m_Groups.end() && profiles.size() > 0)
{
std::pair<std::string, int> p = *it;
int size = p.second;
//initialize a vector of the right length with zeroes
std::vector<mitk::ScalarType> averageProfile;
for(unsigned int i=0; i<profiles.at(0).size(); i++)
{
averageProfile.push_back(0.0);
}
// Average the right number of profiles
for(int i=0; i<size; i++)
{
for(unsigned int j=0; j<averageProfile.size(); ++j)
{
averageProfile.at(j) = averageProfile.at(j) + profiles.at(c).at(j);
}
c++;
}
// Divide by the number of profiles to get group average
for(unsigned int i=0; i<averageProfile.size(); i++)
{
averageProfile.at(i) = averageProfile.at(i) / size;
}
groupProfiles.push_back(averageProfile);
++it;
}
return groupProfiles;
}
void QmitkTbssRoiAnalysisWidget::DrawProfiles()
{
std::vector <std::vector<mitk::ScalarType> > groupProfiles = CalculateGroupProfiles();
Plot(groupProfiles);
}
void QmitkTbssRoiAnalysisWidget::Plot(std::vector <std::vector<mitk::ScalarType> > groupProfiles)
{
this->Clear();
m_Vals.clear();
std::vector<mitk::ScalarType> v1;
std::vector<mitk::ScalarType> xAxis;
for(unsigned int i=0; i<groupProfiles.at(0).size(); ++i)
{
xAxis.push_back((mitk::ScalarType)i);
}
// fill m_Vals. This might be used by the user to copy data to the clipboard
for(unsigned int i=0; i<groupProfiles.size(); i++)
{
v1.clear();
for(unsigned int j=0; j<groupProfiles.at(i).size(); j++)
{
v1.push_back(groupProfiles.at(i).at(j));
}
m_Vals.push_back(v1);
}
std::string title = m_Measure + " profiles on the ";
title.append(m_Structure);
this->SetPlotTitle( title.c_str() );
QPen pen( Qt::SolidLine );
pen.setWidth(2);
std::vector< std::pair<std::string, int> >::iterator it;
it = m_Groups.begin();
int c = 0; //the current profile number
QColor colors[4] = {Qt::green, Qt::blue, Qt::yellow, Qt::red};
while(it != m_Groups.end() && groupProfiles.size() > 0)
{
std::pair< std::string, int > group = *it;
pen.setColor(colors[c]);
int curveId = this->InsertCurve( group.first.c_str() );
this->SetCurveData( curveId, xAxis, groupProfiles.at(c) );
this->SetCurvePen( curveId, pen );
c++;
it++;
}
QwtLegend *legend = new QwtLegend;
this->SetLegend(legend, QwtPlot::RightLegend, 0.5);
std::cout << m_Measure << std::endl;
this->m_Plot->setAxisTitle(0, m_Measure.c_str());
this->m_Plot->setAxisTitle(3, "Position");
this->Replot();
}
std::vector< std::vector<mitk::ScalarType> > QmitkTbssRoiAnalysisWidget::CalculateGroupProfilesFibers(mitk::TbssImage::Pointer tbssImage,
mitk::FiberBundleX *fib,
mitk::PlanarFigure* startRoi,
mitk::PlanarFigure* endRoi,
int number)
{
TractContainerType tracts = CreateTracts(fib, startRoi, endRoi);
TractContainerType resampledTracts = ParameterizeTracts(tracts, number);
int nTracts = resampledTracts.size();
this->Clear();
// For every group we have m fibers * n subjects of profiles to fill
std::vector< std::vector<mitk::ScalarType> > profiles;
// calculate individual profiles by going through all n subjects
int size = m_Projections->GetVectorLength();
for(int s=0; s<size; s++)
{
// Iterate through all tracts
for(int t=0; t<nTracts; t++)
{
// Iterate trough the tract
std::vector<mitk::ScalarType> profile;
TractType::iterator it = resampledTracts[t].begin();
while(it != resampledTracts[t].end())
{
PointType p = *it;
PointType index;
tbssImage->GetGeometry()->WorldToIndex(p, index);
itk::Index<3> ix;
ix[0] = index[0];
ix[1] = index[1];
ix[2] = index[2];
// Get value from image
profile.push_back(m_Projections->GetPixel(ix).GetElement(s));
it++;
}
profiles.push_back(profile);
}
}
m_IndividualProfiles = profiles;
// Now create the group averages (every group contains m fibers * n_i group members
std::vector< std::pair<std::string, int> >::iterator it;
it = m_Groups.begin();
int c = 0; //the current profile number
// Calculate the group averages
std::vector< std::vector<mitk::ScalarType> > groupProfiles;
while(it != m_Groups.end() && profiles.size() > 0)
{
std::pair<std::string, int> p = *it;
int size = p.second;
//initialize a vector of the right length with zeroes
std::vector<mitk::ScalarType> averageProfile;
for(unsigned int i=0; i<profiles.at(0).size(); i++)
{
averageProfile.push_back(0.0);
}
// Average the right number of profiles
for(int i=0; i<size*nTracts; i++)
{
for(unsigned int j=0; j<averageProfile.size(); ++j)
{
averageProfile.at(j) = averageProfile.at(j) + profiles.at(c).at(j);
}
c++;
}
// Divide by the number of profiles to get group average
for(unsigned int i=0; i<averageProfile.size(); i++)
{
averageProfile.at(i) = averageProfile.at(i) / (size*nTracts);
}
groupProfiles.push_back(averageProfile);
++it;
}
return groupProfiles;
}
void QmitkTbssRoiAnalysisWidget::PlotFiber4D(mitk::TbssImage::Pointer tbssImage,
mitk::FiberBundleX *fib,
mitk::PlanarFigure* startRoi,
mitk::PlanarFigure* endRoi,
int number)
{
m_PlottingFiberBundle = false;
m_Fib = fib;
m_CurrentStartRoi = startRoi;
m_CurrentEndRoi = endRoi;
m_CurrentTbssImage = tbssImage;
std::vector <std::vector<mitk::ScalarType> > groupProfiles = CalculateGroupProfilesFibers(tbssImage, fib, startRoi, endRoi, number);
Plot(groupProfiles);
}
template <typename T>
void QmitkTbssRoiAnalysisWidget::PlotFiberBundles(const mitk::PixelType ptype, TractContainerType tracts, mitk::Image *img, bool avg)
{
m_PlottingFiberBundle = true;
this->Clear();
std::vector<TractType>::iterator it = tracts.begin();
std::vector< std::vector <mitk::ScalarType > > profiles;
mitk::ImagePixelReadAccessor<T,3> imAccess(img,img->GetVolumeData(0));
it = tracts.begin();
while(it != tracts.end())
{
TractType tract = *it;
TractType::iterator tractIt = tract.begin();
std::vector<mitk::ScalarType> profile;
while(tractIt != tract.end())
{
PointType p = *tractIt;
// Get value from image
profile.push_back( (mitk::ScalarType) imAccess.GetPixelByWorldCoordinates(p) );
++tractIt;
}
profiles.push_back(profile);
std::cout << std::endl;
++it;
}
if(profiles.size() == 0)
return;
m_IndividualProfiles = profiles;
std::string title = "Fiber bundle plot";
this->SetPlotTitle( title.c_str() );
// initialize average profile
std::vector<mitk::ScalarType> averageProfile;
std::vector<mitk::ScalarType> profile = profiles.at(0); // can do this because we checked the size of profiles before
for(unsigned int i=0; i<profile.size(); ++i)
{
averageProfile.push_back(0.0);
}
std::vector< std::vector<mitk::ScalarType> >::iterator profit = profiles.begin();
int id=0;
while(profit != profiles.end())
{
std::vector<mitk::ScalarType> profile = *profit;
std::vector<mitk::ScalarType> xAxis;
for(unsigned int i=0; i<profile.size(); ++i)
{
xAxis.push_back((mitk::ScalarType)i);
averageProfile.at(i) += profile.at(i) / profiles.size();
}
int curveId = this->InsertCurve( "" );
this->SetCurveData( curveId, xAxis, profile );
++profit;
id++;
}
m_Average = averageProfile;
if(avg)
{
// Draw the average profile
std::vector<mitk::ScalarType> xAxis;
for(unsigned int i=0; i<averageProfile.size(); ++i)
{
xAxis.push_back((mitk::ScalarType)i);
}
int curveId = this->InsertCurve( "" );
this->SetCurveData( curveId, xAxis, averageProfile );
QPen pen( Qt::SolidLine );
pen.setWidth(3);
pen.setColor(Qt::red);
this->SetCurvePen( curveId, pen );
id++;
}
this->Replot();
}
void QmitkTbssRoiAnalysisWidget::drawBar(int x)
{
m_Plot->detachItems(QwtPlotItem::Rtti_PlotMarker, true);
QwtPlotMarker *mX = new QwtPlotMarker();
//mX->setLabel(QString::fromLatin1("selected point"));
mX->setLabelAlignment(Qt::AlignLeft | Qt::AlignBottom);
mX->setLabelOrientation(Qt::Vertical);
mX->setLineStyle(QwtPlotMarker::VLine);
mX->setLinePen(QPen(Qt::black, 0, Qt::SolidLine));
mX->setXValue(x);
mX->attach(m_Plot);
this->Replot();
}
QmitkTbssRoiAnalysisWidget::~QmitkTbssRoiAnalysisWidget()
{
delete m_PlotPicker;
}
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesView.cpp
index 57cafeefa5..c9059bb39f 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesView.cpp
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesView.cpp
@@ -1,1831 +1,1829 @@
/*===================================================================
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 "QmitkControlVisualizationPropertiesView.h"
#include "mitkNodePredicateDataType.h"
#include "mitkDataNodeObject.h"
#include "mitkOdfNormalizationMethodProperty.h"
#include "mitkOdfScaleByProperty.h"
#include "mitkResliceMethodProperty.h"
#include "mitkRenderingManager.h"
#include "mitkTbssImage.h"
#include "mitkPlanarFigure.h"
#include "mitkFiberBundleX.h"
#include "QmitkDataStorageComboBox.h"
#include "QmitkStdMultiWidget.h"
#include "mitkFiberBundleInteractor.h"
#include "mitkPlanarFigureInteractor.h"
#include <mitkQBallImage.h>
#include <mitkTensorImage.h>
#include <mitkDiffusionImage.h>
#include <mitkConnectomicsNetwork.h>
#include "mitkGlobalInteraction.h"
#include "usModuleRegistry.h"
#include "mitkPlaneGeometry.h"
#include "berryIWorkbenchWindow.h"
#include "berryIWorkbenchPage.h"
#include "berryISelectionService.h"
#include "berryConstants.h"
#include "berryPlatformUI.h"
#include "itkRGBAPixel.h"
#include <itkTractDensityImageFilter.h>
#include "qwidgetaction.h"
#include "qcolordialog.h"
#include <itkMultiThreader.h>
#define ROUND(a) ((a)>0 ? (int)((a)+0.5) : -(int)(0.5-(a)))
static bool DetermineAffectedImageSlice( const mitk::Image* image, const mitk::PlaneGeometry* plane, int& affectedDimension, int& affectedSlice )
{
assert(image);
assert(plane);
// compare normal of plane to the three axis vectors of the image
mitk::Vector3D normal = plane->GetNormal();
mitk::Vector3D imageNormal0 = image->GetSlicedGeometry()->GetAxisVector(0);
mitk::Vector3D imageNormal1 = image->GetSlicedGeometry()->GetAxisVector(1);
mitk::Vector3D imageNormal2 = image->GetSlicedGeometry()->GetAxisVector(2);
normal.Normalize();
imageNormal0.Normalize();
imageNormal1.Normalize();
imageNormal2.Normalize();
imageNormal0.SetVnlVector( vnl_cross_3d<mitk::ScalarType>(normal.GetVnlVector(),imageNormal0.GetVnlVector()) );
imageNormal1.SetVnlVector( vnl_cross_3d<mitk::ScalarType>(normal.GetVnlVector(),imageNormal1.GetVnlVector()) );
imageNormal2.SetVnlVector( vnl_cross_3d<mitk::ScalarType>(normal.GetVnlVector(),imageNormal2.GetVnlVector()) );
double eps( 0.00001 );
// axial
if ( imageNormal2.GetNorm() <= eps )
{
affectedDimension = 2;
}
// sagittal
else if ( imageNormal1.GetNorm() <= eps )
{
affectedDimension = 1;
}
// frontal
else if ( imageNormal0.GetNorm() <= eps )
{
affectedDimension = 0;
}
else
{
affectedDimension = -1; // no idea
return false;
}
// determine slice number in image
mitk::BaseGeometry* imageGeometry = image->GetGeometry(0);
mitk::Point3D testPoint = imageGeometry->GetCenter();
mitk::Point3D projectedPoint;
plane->Project( testPoint, projectedPoint );
mitk::Point3D indexPoint;
imageGeometry->WorldToIndex( projectedPoint, indexPoint );
affectedSlice = ROUND( indexPoint[affectedDimension] );
MITK_DEBUG << "indexPoint " << indexPoint << " affectedDimension " << affectedDimension << " affectedSlice " << affectedSlice;
// check if this index is still within the image
if ( affectedSlice < 0 || affectedSlice >= static_cast<int>(image->GetDimension(affectedDimension)) ) return false;
return true;
}
const std::string QmitkControlVisualizationPropertiesView::VIEW_ID = "org.mitk.views.controlvisualizationpropertiesview";
using namespace berry;
struct CvpSelListener : ISelectionListener
{
berryObjectMacro(CvpSelListener);
CvpSelListener(QmitkControlVisualizationPropertiesView* view)
{
m_View = view;
}
void ApplySettings(mitk::DataNode::Pointer node)
{
bool tex_int;
node->GetBoolProperty("texture interpolation", tex_int);
if(tex_int)
{
m_View->m_Controls->m_TextureIntON->setIcon(*m_View->m_IconTexON);
m_View->m_Controls->m_TextureIntON->setChecked(true);
m_View->m_TexIsOn = true;
}
else
{
m_View->m_Controls->m_TextureIntON->setIcon(*m_View->m_IconTexOFF);
m_View->m_Controls->m_TextureIntON->setChecked(false);
m_View->m_TexIsOn = false;
}
int val;
node->GetIntProperty("ShowMaxNumber", val);
m_View->m_Controls->m_ShowMaxNumber->setValue(val);
m_View->m_Controls->m_NormalizationDropdown->setCurrentIndex(dynamic_cast<mitk::EnumerationProperty*>(node->GetProperty("Normalization"))->GetValueAsId());
float fval;
node->GetFloatProperty("Scaling",fval);
m_View->m_Controls->m_ScalingFactor->setValue(fval);
m_View->m_Controls->m_AdditionalScaling->setCurrentIndex(dynamic_cast<mitk::EnumerationProperty*>(node->GetProperty("ScaleBy"))->GetValueAsId());
node->GetFloatProperty("IndexParam1",fval);
m_View->m_Controls->m_IndexParam1->setValue(fval);
node->GetFloatProperty("IndexParam2",fval);
m_View->m_Controls->m_IndexParam2->setValue(fval);
}
void DoSelectionChanged(ISelection::ConstPointer selection)
{
// save current selection in member variable
m_View->m_CurrentSelection = selection.Cast<const IStructuredSelection>();
m_View->m_Controls->m_VisibleOdfsON_T->setVisible(false);
m_View->m_Controls->m_VisibleOdfsON_S->setVisible(false);
m_View->m_Controls->m_VisibleOdfsON_C->setVisible(false);
m_View->m_Controls->m_TextureIntON->setVisible(false);
m_View->m_Controls->m_ImageControlsFrame->setVisible(false);
m_View->m_Controls->m_PlanarFigureControlsFrame->setVisible(false);
m_View->m_Controls->m_BundleControlsFrame->setVisible(false);
m_View->m_SelectedNode = 0;
if(m_View->m_CurrentSelection.IsNull())
return;
if(m_View->m_CurrentSelection->Size() == 1)
{
mitk::DataNodeObject::Pointer nodeObj = m_View->m_CurrentSelection->Begin()->Cast<mitk::DataNodeObject>();
if(nodeObj.IsNotNull())
{
mitk::DataNode::Pointer node = nodeObj->GetDataNode();
// check if node has data,
// if some helper nodes are shown in the DataManager, the GetData() returns 0x0 which would lead to SIGSEV
mitk::BaseData* nodeData = node->GetData();
if(nodeData != NULL )
{
if(dynamic_cast<mitk::PlanarFigure*>(nodeData) != 0)
{
m_View->m_Controls->m_PlanarFigureControlsFrame->setVisible(true);
m_View->m_SelectedNode = node;
float val;
node->GetFloatProperty("planarfigure.line.width", val);
m_View->m_Controls->m_PFWidth->setValue((int)(val*10.0));
QString label = "Width %1";
label = label.arg(val);
m_View->m_Controls->label_pfwidth->setText(label);
float color[3];
node->GetColor( color, NULL, "planarfigure.default.line.color");
QString styleSheet = "background-color:rgb(";
styleSheet.append(QString::number(color[0]*255.0));
styleSheet.append(",");
styleSheet.append(QString::number(color[1]*255.0));
styleSheet.append(",");
styleSheet.append(QString::number(color[2]*255.0));
styleSheet.append(")");
m_View->m_Controls->m_PFColor->setAutoFillBackground(true);
m_View->m_Controls->m_PFColor->setStyleSheet(styleSheet);
node->GetColor( color, NULL, "color");
styleSheet = "background-color:rgb(";
styleSheet.append(QString::number(color[0]*255.0));
styleSheet.append(",");
styleSheet.append(QString::number(color[1]*255.0));
styleSheet.append(",");
styleSheet.append(QString::number(color[2]*255.0));
styleSheet.append(")");
m_View->PlanarFigureFocus();
}
if(dynamic_cast<mitk::FiberBundleX*>(nodeData) != 0)
{
m_View->m_Controls->m_BundleControlsFrame->setVisible(true);
m_View->m_SelectedNode = node;
if(m_View->m_CurrentPickingNode != 0 && node.GetPointer() != m_View->m_CurrentPickingNode)
{
m_View->m_Controls->m_Crosshair->setEnabled(false);
}
else
{
m_View->m_Controls->m_Crosshair->setEnabled(true);
}
int width;
node->GetIntProperty("LineWidth", width);
m_View->m_Controls->m_LineWidth->setValue(width);
float range;
node->GetFloatProperty("Fiber2DSliceThickness",range);
mitk::FiberBundleX::Pointer fib = dynamic_cast<mitk::FiberBundleX*>(node->GetData());
mitk::BaseGeometry::Pointer geo = fib->GetGeometry();
mitk::ScalarType max = geo->GetExtentInMM(0);
max = std::max(max, geo->GetExtentInMM(1));
max = std::max(max, geo->GetExtentInMM(2));
m_View->m_Controls->m_FiberThicknessSlider->setMaximum(max * 10);
m_View->m_Controls->m_FiberThicknessSlider->setValue(range * 10);
}
} // check node data != NULL
}
}
if(m_View->m_CurrentSelection->Size() > 0 && m_View->m_SelectedNode == 0)
{
m_View->m_Controls->m_ImageControlsFrame->setVisible(true);
bool foundDiffusionImage = false;
bool foundQBIVolume = false;
bool foundTensorVolume = false;
bool foundImage = false;
bool foundMultipleOdfImages = false;
bool foundRGBAImage = false;
bool foundTbssImage = false;
// do something with the selected items
if(m_View->m_CurrentSelection)
{
// iterate selection
for (IStructuredSelection::iterator i = m_View->m_CurrentSelection->Begin();
i != m_View->m_CurrentSelection->End(); ++i)
{
// extract datatree node
if (mitk::DataNodeObject::Pointer nodeObj = i->Cast<mitk::DataNodeObject>())
{
mitk::DataNode::Pointer node = nodeObj->GetDataNode();
mitk::BaseData* nodeData = node->GetData();
if(nodeData != NULL )
{
// only look at interesting types
if(QString("DiffusionImage").compare(nodeData->GetNameOfClass())==0)
{
foundDiffusionImage = true;
bool tex_int;
node->GetBoolProperty("texture interpolation", tex_int);
if(tex_int)
{
m_View->m_Controls->m_TextureIntON->setIcon(*m_View->m_IconTexON);
m_View->m_Controls->m_TextureIntON->setChecked(true);
m_View->m_TexIsOn = true;
}
else
{
m_View->m_Controls->m_TextureIntON->setIcon(*m_View->m_IconTexOFF);
m_View->m_Controls->m_TextureIntON->setChecked(false);
m_View->m_TexIsOn = false;
}
int val;
node->GetIntProperty("DisplayChannel", val);
m_View->m_Controls->m_DisplayIndex->setValue(val);
m_View->m_Controls->m_DisplayIndexSpinBox->setValue(val);
QString label = "Channel %1";
label = label.arg(val);
m_View->m_Controls->label_channel->setText(label);
int maxVal = (dynamic_cast<mitk::DiffusionImage<short>* >(nodeData))->GetVectorImage()->GetVectorLength();
m_View->m_Controls->m_DisplayIndex->setMaximum(maxVal-1);
m_View->m_Controls->m_DisplayIndexSpinBox->setMaximum(maxVal-1);
}
if(QString("TbssImage").compare(nodeData->GetNameOfClass())==0)
{
foundTbssImage = true;
bool tex_int;
node->GetBoolProperty("texture interpolation", tex_int);
if(tex_int)
{
m_View->m_Controls->m_TextureIntON->setIcon(*m_View->m_IconTexON);
m_View->m_Controls->m_TextureIntON->setChecked(true);
m_View->m_TexIsOn = true;
}
else
{
m_View->m_Controls->m_TextureIntON->setIcon(*m_View->m_IconTexOFF);
m_View->m_Controls->m_TextureIntON->setChecked(false);
m_View->m_TexIsOn = false;
}
int val;
node->GetIntProperty("DisplayChannel", val);
m_View->m_Controls->m_DisplayIndex->setValue(val);
m_View->m_Controls->m_DisplayIndexSpinBox->setValue(val);
QString label = "Channel %1";
label = label.arg(val);
m_View->m_Controls->label_channel->setText(label);
int maxVal = (dynamic_cast<mitk::TbssImage* >(nodeData))->GetImage()->GetVectorLength();
m_View->m_Controls->m_DisplayIndex->setMaximum(maxVal-1);
m_View->m_Controls->m_DisplayIndexSpinBox->setMaximum(maxVal-1);
}
else if(QString("QBallImage").compare(nodeData->GetNameOfClass())==0)
{
foundMultipleOdfImages = foundQBIVolume || foundTensorVolume;
foundQBIVolume = true;
ApplySettings(node);
}
else if(QString("TensorImage").compare(nodeData->GetNameOfClass())==0)
{
foundMultipleOdfImages = foundQBIVolume || foundTensorVolume;
foundTensorVolume = true;
ApplySettings(node);
}
else if(QString("Image").compare(nodeData->GetNameOfClass())==0)
{
foundImage = true;
mitk::Image::Pointer img = dynamic_cast<mitk::Image*>(nodeData);
if(img.IsNotNull()
&& img->GetPixelType().GetPixelType() == itk::ImageIOBase::RGBA
&& img->GetPixelType().GetComponentType() == itk::ImageIOBase::UCHAR )
{
foundRGBAImage = true;
}
bool tex_int;
node->GetBoolProperty("texture interpolation", tex_int);
if(tex_int)
{
m_View->m_Controls->m_TextureIntON->setIcon(*m_View->m_IconTexON);
m_View->m_Controls->m_TextureIntON->setChecked(true);
m_View->m_TexIsOn = true;
}
else
{
m_View->m_Controls->m_TextureIntON->setIcon(*m_View->m_IconTexOFF);
m_View->m_Controls->m_TextureIntON->setChecked(false);
m_View->m_TexIsOn = false;
}
}
} // END CHECK node != NULL
}
}
}
m_View->m_FoundSingleOdfImage = (foundQBIVolume || foundTensorVolume)
&& !foundMultipleOdfImages;
m_View->m_Controls->m_NumberGlyphsFrame->setVisible(m_View->m_FoundSingleOdfImage);
m_View->m_Controls->m_NormalizationDropdown->setVisible(m_View->m_FoundSingleOdfImage);
m_View->m_Controls->label->setVisible(m_View->m_FoundSingleOdfImage);
m_View->m_Controls->m_ScalingFactor->setVisible(m_View->m_FoundSingleOdfImage);
m_View->m_Controls->m_AdditionalScaling->setVisible(m_View->m_FoundSingleOdfImage);
m_View->m_Controls->m_NormalizationScalingFrame->setVisible(m_View->m_FoundSingleOdfImage);
m_View->m_Controls->OpacMinFrame->setVisible(foundRGBAImage || m_View->m_FoundSingleOdfImage);
// changed for SPIE paper, Principle curvature scaling
//m_View->m_Controls->params_frame->setVisible(m_View->m_FoundSingleOdfImage);
m_View->m_Controls->params_frame->setVisible(false);
m_View->m_Controls->m_VisibleOdfsON_T->setVisible(m_View->m_FoundSingleOdfImage);
m_View->m_Controls->m_VisibleOdfsON_S->setVisible(m_View->m_FoundSingleOdfImage);
m_View->m_Controls->m_VisibleOdfsON_C->setVisible(m_View->m_FoundSingleOdfImage);
bool foundAnyImage = foundDiffusionImage ||
foundQBIVolume || foundTensorVolume || foundImage || foundTbssImage;
m_View->m_Controls->m_Reinit->setVisible(foundAnyImage);
m_View->m_Controls->m_TextureIntON->setVisible(foundAnyImage);
m_View->m_Controls->m_TSMenu->setVisible(foundAnyImage);
}
}
void SelectionChanged(IWorkbenchPart::Pointer part, ISelection::ConstPointer selection)
{
// check, if selection comes from datamanager
if (part)
{
QString partname(part->GetPartName().c_str());
if(partname.compare("Data Manager")==0)
{
// apply selection
DoSelectionChanged(selection);
}
}
}
QmitkControlVisualizationPropertiesView* m_View;
};
QmitkControlVisualizationPropertiesView::QmitkControlVisualizationPropertiesView()
: QmitkFunctionality(),
m_Controls(NULL),
m_MultiWidget(NULL),
m_NodeUsedForOdfVisualization(NULL),
m_IconTexOFF(new QIcon(":/QmitkDiffusionImaging/texIntOFFIcon.png")),
m_IconTexON(new QIcon(":/QmitkDiffusionImaging/texIntONIcon.png")),
m_IconGlyOFF_T(new QIcon(":/QmitkDiffusionImaging/glyphsoff_T.png")),
m_IconGlyON_T(new QIcon(":/QmitkDiffusionImaging/glyphson_T.png")),
m_IconGlyOFF_C(new QIcon(":/QmitkDiffusionImaging/glyphsoff_C.png")),
m_IconGlyON_C(new QIcon(":/QmitkDiffusionImaging/glyphson_C.png")),
m_IconGlyOFF_S(new QIcon(":/QmitkDiffusionImaging/glyphsoff_S.png")),
m_IconGlyON_S(new QIcon(":/QmitkDiffusionImaging/glyphson_S.png")),
m_CurrentSelection(0),
m_CurrentPickingNode(0),
m_GlyIsOn_S(false),
m_GlyIsOn_C(false),
m_GlyIsOn_T(false),
m_FiberBundleObserverTag(0),
m_Color(NULL)
{
currentThickSlicesMode = 1;
m_MyMenu = NULL;
int numThread = itk::MultiThreader::GetGlobalMaximumNumberOfThreads();
if (numThread > 12)
numThread = 12;
itk::MultiThreader::SetGlobalDefaultNumberOfThreads(numThread);
}
QmitkControlVisualizationPropertiesView::QmitkControlVisualizationPropertiesView(const QmitkControlVisualizationPropertiesView& other)
{
Q_UNUSED(other)
throw std::runtime_error("Copy constructor not implemented");
}
QmitkControlVisualizationPropertiesView::~QmitkControlVisualizationPropertiesView()
{
if(m_SlicesRotationObserverTag1 )
{
mitk::SlicesCoordinator::Pointer coordinator = m_MultiWidget->GetSlicesRotator();
if( coordinator.IsNotNull() )
coordinator->RemoveObserver(m_SlicesRotationObserverTag1);
}
if( m_SlicesRotationObserverTag2)
{
mitk::SlicesCoordinator::Pointer coordinator = m_MultiWidget->GetSlicesRotator();
if( coordinator.IsNotNull() )
coordinator->RemoveObserver(m_SlicesRotationObserverTag1);
}
this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->RemovePostSelectionListener(/*"org.mitk.views.datamanager",*/ m_SelListener);
}
void QmitkControlVisualizationPropertiesView::OnThickSlicesModeSelected( QAction* action )
{
currentThickSlicesMode = action->data().toInt();
switch(currentThickSlicesMode)
{
default:
case 1:
this->m_Controls->m_TSMenu->setText("MIP");
break;
case 2:
this->m_Controls->m_TSMenu->setText("SUM");
break;
case 3:
this->m_Controls->m_TSMenu->setText("WEIGH");
break;
}
mitk::DataNode* n;
n = this->m_MultiWidget->GetWidgetPlane1(); if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( currentThickSlicesMode ) );
n = this->m_MultiWidget->GetWidgetPlane2(); if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( currentThickSlicesMode ) );
n = this->m_MultiWidget->GetWidgetPlane3(); if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( currentThickSlicesMode ) );
mitk::BaseRenderer::Pointer renderer =
this->GetActiveStdMultiWidget()->GetRenderWindow1()->GetRenderer();
if(renderer.IsNotNull())
{
renderer->SendUpdateSlice();
}
renderer = this->GetActiveStdMultiWidget()->GetRenderWindow2()->GetRenderer();
if(renderer.IsNotNull())
{
renderer->SendUpdateSlice();
}
renderer = this->GetActiveStdMultiWidget()->GetRenderWindow3()->GetRenderer();
if(renderer.IsNotNull())
{
renderer->SendUpdateSlice();
}
renderer->GetRenderingManager()->RequestUpdateAll();
}
void QmitkControlVisualizationPropertiesView::OnTSNumChanged(int num)
{
if(num==0)
{
mitk::DataNode* n;
n = this->m_MultiWidget->GetWidgetPlane1();
if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( 0 ) );
if(n) n->SetProperty( "reslice.thickslices.num", mitk::IntProperty::New( num ) );
if(n) n->SetProperty( "reslice.thickslices.showarea", mitk::BoolProperty::New( false ) );
n = this->m_MultiWidget->GetWidgetPlane2();
if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( 0 ) );
if(n) n->SetProperty( "reslice.thickslices.num", mitk::IntProperty::New( num ) );
if(n) n->SetProperty( "reslice.thickslices.showarea", mitk::BoolProperty::New( false ) );
n = this->m_MultiWidget->GetWidgetPlane3();
if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( 0 ) );
if(n) n->SetProperty( "reslice.thickslices.num", mitk::IntProperty::New( num ) );
if(n) n->SetProperty( "reslice.thickslices.showarea", mitk::BoolProperty::New( false ) );
}
else
{
mitk::DataNode* n;
n = this->m_MultiWidget->GetWidgetPlane1();
if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( currentThickSlicesMode ) );
if(n) n->SetProperty( "reslice.thickslices.num", mitk::IntProperty::New( num ) );
if(n) n->SetProperty( "reslice.thickslices.showarea", mitk::BoolProperty::New( (num>0) ) );
n = this->m_MultiWidget->GetWidgetPlane2();
if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( currentThickSlicesMode ) );
if(n) n->SetProperty( "reslice.thickslices.num", mitk::IntProperty::New( num ) );
if(n) n->SetProperty( "reslice.thickslices.showarea", mitk::BoolProperty::New( (num>0) ) );
n = this->m_MultiWidget->GetWidgetPlane3();
if(n) n->SetProperty( "reslice.thickslices", mitk::ResliceMethodProperty::New( currentThickSlicesMode ) );
if(n) n->SetProperty( "reslice.thickslices.num", mitk::IntProperty::New( num ) );
if(n) n->SetProperty( "reslice.thickslices.showarea", mitk::BoolProperty::New( (num>0) ) );
}
m_TSLabel->setText(QString::number(num*2+1));
mitk::BaseRenderer::Pointer renderer = this->GetActiveStdMultiWidget()->GetRenderWindow1()->GetRenderer();
if(renderer.IsNotNull())
renderer->SendUpdateSlice();
renderer = this->GetActiveStdMultiWidget()->GetRenderWindow2()->GetRenderer();
if(renderer.IsNotNull())
renderer->SendUpdateSlice();
renderer = this->GetActiveStdMultiWidget()->GetRenderWindow3()->GetRenderer();
if(renderer.IsNotNull())
renderer->SendUpdateSlice();
renderer->GetRenderingManager()->RequestUpdateAll(mitk::RenderingManager::REQUEST_UPDATE_2DWINDOWS);
}
void QmitkControlVisualizationPropertiesView::CreateQtPartControl(QWidget *parent)
{
if (!m_Controls)
{
// create GUI widgets
m_Controls = new Ui::QmitkControlVisualizationPropertiesViewControls;
m_Controls->setupUi(parent);
this->CreateConnections();
// hide warning (ODFs in rotated planes)
m_Controls->m_lblRotatedPlanesWarning->hide();
m_MyMenu = new QMenu(parent);
// button for changing rotation mode
m_Controls->m_TSMenu->setMenu( m_MyMenu );
//m_CrosshairModeButton->setIcon( QIcon( iconCrosshairMode_xpm ) );
m_Controls->params_frame->setVisible(false);
QIcon icon5(":/QmitkDiffusionImaging/Refresh_48.png");
m_Controls->m_Reinit->setIcon(icon5);
m_Controls->m_Focus->setIcon(icon5);
QIcon iconColor(":/QmitkDiffusionImaging/color24.gif");
m_Controls->m_PFColor->setIcon(iconColor);
m_Controls->m_Color->setIcon(iconColor);
QIcon iconReset(":/QmitkDiffusionImaging/reset.png");
m_Controls->m_ResetColoring->setIcon(iconReset);
m_Controls->m_PFColor->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
QIcon iconCrosshair(":/QmitkDiffusionImaging/crosshair.png");
m_Controls->m_Crosshair->setIcon(iconCrosshair);
// was is los
QIcon iconPaint(":/QmitkDiffusionImaging/paint2.png");
m_Controls->m_TDI->setIcon(iconPaint);
QIcon iconFiberFade(":/QmitkDiffusionImaging/MapperEfx2D.png");
m_Controls->m_FiberFading2D->setIcon(iconFiberFade);
m_Controls->m_TextureIntON->setCheckable(true);
#ifndef DIFFUSION_IMAGING_EXTENDED
int size = m_Controls->m_AdditionalScaling->count();
for(int t=0; t<size; t++)
{
if(m_Controls->m_AdditionalScaling->itemText(t).toStdString() == "Scale by ASR")
{
- m_Controls->m_AdditionalScaling->removeItem(t);
+ m_Controls->m_AdditionalScaling->removeItem(t);
}
}
#endif
m_Controls->m_OpacitySlider->setRange(0.0,1.0);
- m_Controls->m_OpacitySlider->setLowerValue(0.0);
- m_Controls->m_OpacitySlider->setUpperValue(0.0);
+ m_Controls->m_OpacitySlider->setMinimumValue(0.0);
+ m_Controls->m_OpacitySlider->setMaximumValue(0.0);
m_Controls->m_ScalingFrame->setVisible(false);
m_Controls->m_NormalizationFrame->setVisible(false);
}
m_IsInitialized = false;
m_SelListener = berry::ISelectionListener::Pointer(new CvpSelListener(this));
this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->AddPostSelectionListener(/*"org.mitk.views.datamanager",*/ m_SelListener);
berry::ISelection::ConstPointer sel(
this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.datamanager"));
m_CurrentSelection = sel.Cast<const IStructuredSelection>();
m_SelListener.Cast<CvpSelListener>()->DoSelectionChanged(sel);
m_IsInitialized = true;
}
void QmitkControlVisualizationPropertiesView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget)
{
m_MultiWidget = &stdMultiWidget;
if (m_MultiWidget)
{
mitk::SlicesCoordinator* coordinator = m_MultiWidget->GetSlicesRotator();
if (coordinator)
{
itk::ReceptorMemberCommand<QmitkControlVisualizationPropertiesView>::Pointer command2 = itk::ReceptorMemberCommand<QmitkControlVisualizationPropertiesView>::New();
command2->SetCallbackFunction( this, &QmitkControlVisualizationPropertiesView::SliceRotation );
m_SlicesRotationObserverTag1 = coordinator->AddObserver( mitk::SliceRotationEvent(), command2 );
}
coordinator = m_MultiWidget->GetSlicesSwiveller();
if (coordinator)
{
itk::ReceptorMemberCommand<QmitkControlVisualizationPropertiesView>::Pointer command2 = itk::ReceptorMemberCommand<QmitkControlVisualizationPropertiesView>::New();
command2->SetCallbackFunction( this, &QmitkControlVisualizationPropertiesView::SliceRotation );
m_SlicesRotationObserverTag2 = coordinator->AddObserver( mitk::SliceRotationEvent(), command2 );
}
}
}
void QmitkControlVisualizationPropertiesView::SliceRotation(const itk::EventObject&)
{
// test if plane rotated
if( m_GlyIsOn_T || m_GlyIsOn_C || m_GlyIsOn_S )
{
if( this->IsPlaneRotated() )
{
// show label
m_Controls->m_lblRotatedPlanesWarning->show();
}
else
{
//hide label
m_Controls->m_lblRotatedPlanesWarning->hide();
}
}
}
void QmitkControlVisualizationPropertiesView::StdMultiWidgetNotAvailable()
{
m_MultiWidget = NULL;
}
void QmitkControlVisualizationPropertiesView::NodeRemoved(const mitk::DataNode* node)
{
}
#include <mitkMessage.h>
void QmitkControlVisualizationPropertiesView::CreateConnections()
{
if ( m_Controls )
{
connect( (QObject*)(m_Controls->m_DisplayIndex), SIGNAL(valueChanged(int)), this, SLOT(DisplayIndexChanged(int)) );
connect( (QObject*)(m_Controls->m_DisplayIndexSpinBox), SIGNAL(valueChanged(int)), this, SLOT(DisplayIndexChanged(int)) );
connect( (QObject*)(m_Controls->m_TextureIntON), SIGNAL(clicked()), this, SLOT(TextIntON()) );
connect( (QObject*)(m_Controls->m_Reinit), SIGNAL(clicked()), this, SLOT(Reinit()) );
connect( (QObject*)(m_Controls->m_VisibleOdfsON_T), SIGNAL(clicked()), this, SLOT(VisibleOdfsON_T()) );
connect( (QObject*)(m_Controls->m_VisibleOdfsON_S), SIGNAL(clicked()), this, SLOT(VisibleOdfsON_S()) );
connect( (QObject*)(m_Controls->m_VisibleOdfsON_C), SIGNAL(clicked()), this, SLOT(VisibleOdfsON_C()) );
connect( (QObject*)(m_Controls->m_ShowMaxNumber), SIGNAL(editingFinished()), this, SLOT(ShowMaxNumberChanged()) );
connect( (QObject*)(m_Controls->m_NormalizationDropdown), SIGNAL(currentIndexChanged(int)), this, SLOT(NormalizationDropdownChanged(int)) );
connect( (QObject*)(m_Controls->m_ScalingFactor), SIGNAL(valueChanged(double)), this, SLOT(ScalingFactorChanged(double)) );
connect( (QObject*)(m_Controls->m_AdditionalScaling), SIGNAL(currentIndexChanged(int)), this, SLOT(AdditionalScaling(int)) );
connect( (QObject*)(m_Controls->m_IndexParam1), SIGNAL(valueChanged(double)), this, SLOT(IndexParam1Changed(double)) );
connect( (QObject*)(m_Controls->m_IndexParam2), SIGNAL(valueChanged(double)), this, SLOT(IndexParam2Changed(double)) );
connect( (QObject*)(m_Controls->m_ScalingCheckbox), SIGNAL(clicked()), this, SLOT(ScalingCheckbox()) );
connect( (QObject*)(m_Controls->m_OpacitySlider), SIGNAL(spanChanged(double,double)), this, SLOT(OpacityChanged(double,double)) );
connect((QObject*) m_Controls->m_Color, SIGNAL(clicked()), (QObject*) this, SLOT(BundleRepresentationColor()));
connect((QObject*) m_Controls->m_ResetColoring, SIGNAL(clicked()), (QObject*) this, SLOT(BundleRepresentationResetColoring()));
connect((QObject*) m_Controls->m_Focus, SIGNAL(clicked()), (QObject*) this, SLOT(PlanarFigureFocus()));
connect((QObject*) m_Controls->m_FiberFading2D, SIGNAL(clicked()), (QObject*) this, SLOT( Fiber2DfadingEFX() ) );
connect((QObject*) m_Controls->m_FiberThicknessSlider, SIGNAL(sliderReleased()), (QObject*) this, SLOT( FiberSlicingThickness2D() ) );
connect((QObject*) m_Controls->m_FiberThicknessSlider, SIGNAL(valueChanged(int)), (QObject*) this, SLOT( FiberSlicingUpdateLabel(int) ));
connect((QObject*) m_Controls->m_Crosshair, SIGNAL(clicked()), (QObject*) this, SLOT(SetInteractor()));
connect((QObject*) m_Controls->m_PFWidth, SIGNAL(valueChanged(int)), (QObject*) this, SLOT(PFWidth(int)));
connect((QObject*) m_Controls->m_PFColor, SIGNAL(clicked()), (QObject*) this, SLOT(PFColor()));
connect((QObject*) m_Controls->m_TDI, SIGNAL(clicked()), (QObject*) this, SLOT(GenerateTdi()));
connect((QObject*) m_Controls->m_LineWidth, SIGNAL(editingFinished()), (QObject*) this, SLOT(LineWidthChanged()));
}
}
void QmitkControlVisualizationPropertiesView::Activated()
{
berry::ISelection::ConstPointer sel(
this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.datamanager"));
m_CurrentSelection = sel.Cast<const IStructuredSelection>();
m_SelListener.Cast<CvpSelListener>()->DoSelectionChanged(sel);
QmitkFunctionality::Activated();
}
void QmitkControlVisualizationPropertiesView::Deactivated()
{
QmitkFunctionality::Deactivated();
}
int QmitkControlVisualizationPropertiesView::GetSizeFlags(bool width)
{
if(!width)
{
return berry::Constants::MIN | berry::Constants::MAX | berry::Constants::FILL;
}
else
{
return 0;
}
}
int QmitkControlVisualizationPropertiesView::ComputePreferredSize(bool width, int /*availableParallel*/, int /*availablePerpendicular*/, int preferredResult)
{
if(width==false)
{
return m_FoundSingleOdfImage ? 120 : 80;
}
else
{
return preferredResult;
}
}
// set diffusion image channel to b0 volume
void QmitkControlVisualizationPropertiesView::NodeAdded(const mitk::DataNode *node)
{
mitk::DataNode* notConst = const_cast<mitk::DataNode*>(node);
if (dynamic_cast<mitk::DiffusionImage<short>*>(notConst->GetData()))
{
mitk::DiffusionImage<short>::Pointer dimg = dynamic_cast<mitk::DiffusionImage<short>*>(notConst->GetData());
// if there is no b0 image in the dataset, the GetB0Indices() returns a vector of size 0
// and hence we cannot set the Property directly to .front()
int displayChannelPropertyValue = 0;
mitk::DiffusionImage<short>::BValueMap map = dimg->GetBValueMap();
if( map[0].size() > 0)
displayChannelPropertyValue = map[0].front();
notConst->SetIntProperty("DisplayChannel", displayChannelPropertyValue );
}
}
/* OnSelectionChanged is registered to SelectionService, therefore no need to
implement SelectionService Listener explicitly */
void QmitkControlVisualizationPropertiesView::OnSelectionChanged( std::vector<mitk::DataNode*> nodes )
{
// deactivate channel slider if no diffusion weighted image or tbss image is selected
m_Controls->m_DisplayIndex->setVisible(false);
m_Controls->m_DisplayIndexSpinBox->setVisible(false);
m_Controls->label_channel->setVisible(false);
for( std::vector<mitk::DataNode*>::iterator it = nodes.begin(); it != nodes.end(); ++it )
{
mitk::DataNode::Pointer node = *it;
// check if node has data,
// if some helper nodes are shown in the DataManager, the GetData() returns 0x0 which would lead to SIGSEV
mitk::BaseData* nodeData = node->GetData();
if(nodeData == NULL)
continue;
if (node.IsNotNull() && (dynamic_cast<mitk::TbssImage*>(nodeData) ||
dynamic_cast<mitk::DiffusionImage<short>*>(nodeData)))
{
m_Controls->m_DisplayIndex->setVisible(true);
m_Controls->m_DisplayIndexSpinBox->setVisible(true);
m_Controls->label_channel->setVisible(true);
}
else if (node.IsNotNull() && dynamic_cast<mitk::FiberBundleX*>(node->GetData()))
{
if (m_Color.IsNotNull())
m_Color->RemoveObserver(m_FiberBundleObserverTag);
itk::ReceptorMemberCommand<QmitkControlVisualizationPropertiesView>::Pointer command = itk::ReceptorMemberCommand<QmitkControlVisualizationPropertiesView>::New();
command->SetCallbackFunction( this, &QmitkControlVisualizationPropertiesView::SetFiberBundleCustomColor );
m_Color = dynamic_cast<mitk::ColorProperty*>(node->GetProperty("color", NULL));
if (m_Color.IsNotNull())
m_FiberBundleObserverTag = m_Color->AddObserver( itk::ModifiedEvent(), command );
}
}
for( std::vector<mitk::DataNode*>::iterator it = nodes.begin(); it != nodes.end(); ++it )
{
mitk::DataNode::Pointer node = *it;
// check if node has data,
// if some helper nodes are shown in the DataManager, the GetData() returns 0x0 which would lead to SIGSEV
mitk::BaseData* nodeData = node->GetData();
if(nodeData == NULL)
continue;
if( node.IsNotNull() && (dynamic_cast<mitk::QBallImage*>(nodeData) || dynamic_cast<mitk::TensorImage*>(nodeData)) )
{
if(m_NodeUsedForOdfVisualization.IsNotNull())
{
m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_S", false);
m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_C", false);
m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_T", false);
}
m_NodeUsedForOdfVisualization = node;
m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_S", m_GlyIsOn_S);
m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_C", m_GlyIsOn_C);
m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_T", m_GlyIsOn_T);
if(m_MultiWidget)
m_MultiWidget->RequestUpdate();
m_Controls->m_TSMenu->setVisible(false); // deactivate mip etc. for tensor and q-ball images
break;
}
else if( node.IsNotNull() && dynamic_cast<mitk::ConnectomicsNetwork*>(nodeData) )
m_Controls->m_TSMenu->setVisible(false);
else
m_Controls->m_TSMenu->setVisible(true);
}
// if selection changes, set the current selction member and call SellListener::DoSelectionChanged
berry::ISelection::ConstPointer sel(
this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.datamanager"));
m_CurrentSelection = sel.Cast<const IStructuredSelection>();
m_SelListener.Cast<CvpSelListener>()->DoSelectionChanged(sel);
// adapt thick slice controls
// THICK SLICE SUPPORT
if( nodes.size() < 1)
return;
mitk::DataNode::Pointer node = nodes.at(0);
if( node.IsNull() )
return;
QMenu *myMenu = m_MyMenu;
myMenu->clear();
QActionGroup* thickSlicesActionGroup = new QActionGroup(myMenu);
thickSlicesActionGroup->setExclusive(true);
int currentTSMode = 0;
{
mitk::ResliceMethodProperty::Pointer m = dynamic_cast<mitk::ResliceMethodProperty*>(node->GetProperty( "reslice.thickslices" ));
if( m.IsNotNull() )
currentTSMode = m->GetValueAsId();
}
int maxTS = 30;
for( std::vector<mitk::DataNode*>::iterator it = nodes.begin(); it != nodes.end(); ++it )
{
mitk::Image* image = dynamic_cast<mitk::Image*>((*it)->GetData());
if (image)
{
int size = std::max(image->GetDimension(0), std::max(image->GetDimension(1), image->GetDimension(2)));
if (size>maxTS)
maxTS=size;
}
}
maxTS /= 2;
int currentNum = 0;
{
mitk::IntProperty::Pointer m = dynamic_cast<mitk::IntProperty*>(node->GetProperty( "reslice.thickslices.num" ));
if( m.IsNotNull() )
{
currentNum = m->GetValue();
if(currentNum < 0) currentNum = 0;
if(currentNum > maxTS) currentNum = maxTS;
}
}
if(currentTSMode==0)
currentNum=0;
QSlider *m_TSSlider = new QSlider(myMenu);
m_TSSlider->setMinimum(0);
m_TSSlider->setMaximum(maxTS-1);
m_TSSlider->setValue(currentNum);
m_TSSlider->setOrientation(Qt::Horizontal);
connect( m_TSSlider, SIGNAL( valueChanged(int) ), this, SLOT( OnTSNumChanged(int) ) );
QHBoxLayout* _TSLayout = new QHBoxLayout;
_TSLayout->setContentsMargins(4,4,4,4);
_TSLayout->addWidget(m_TSSlider);
_TSLayout->addWidget(m_TSLabel=new QLabel(QString::number(currentNum*2+1),myMenu));
QWidget* _TSWidget = new QWidget;
_TSWidget->setLayout(_TSLayout);
QActionGroup* thickSliceModeActionGroup = new QActionGroup(myMenu);
thickSliceModeActionGroup->setExclusive(true);
QWidgetAction *m_TSSliderAction = new QWidgetAction(myMenu);
m_TSSliderAction->setDefaultWidget(_TSWidget);
myMenu->addAction(m_TSSliderAction);
QAction* mipThickSlicesAction = new QAction(myMenu);
mipThickSlicesAction->setActionGroup(thickSliceModeActionGroup);
mipThickSlicesAction->setText("MIP (max. intensity proj.)");
mipThickSlicesAction->setCheckable(true);
mipThickSlicesAction->setChecked(currentThickSlicesMode==1);
mipThickSlicesAction->setData(1);
myMenu->addAction( mipThickSlicesAction );
QAction* sumThickSlicesAction = new QAction(myMenu);
sumThickSlicesAction->setActionGroup(thickSliceModeActionGroup);
sumThickSlicesAction->setText("SUM (sum intensity proj.)");
sumThickSlicesAction->setCheckable(true);
sumThickSlicesAction->setChecked(currentThickSlicesMode==2);
sumThickSlicesAction->setData(2);
myMenu->addAction( sumThickSlicesAction );
QAction* weightedThickSlicesAction = new QAction(myMenu);
weightedThickSlicesAction->setActionGroup(thickSliceModeActionGroup);
weightedThickSlicesAction->setText("WEIGHTED (gaussian proj.)");
weightedThickSlicesAction->setCheckable(true);
weightedThickSlicesAction->setChecked(currentThickSlicesMode==3);
weightedThickSlicesAction->setData(3);
myMenu->addAction( weightedThickSlicesAction );
connect( thickSliceModeActionGroup, SIGNAL(triggered(QAction*)), this, SLOT(OnThickSlicesModeSelected(QAction*)) );
}
mitk::DataStorage::SetOfObjects::Pointer
QmitkControlVisualizationPropertiesView::ActiveSet(std::string classname)
{
if (m_CurrentSelection)
{
mitk::DataStorage::SetOfObjects::Pointer set =
mitk::DataStorage::SetOfObjects::New();
int at = 0;
for (IStructuredSelection::iterator i = m_CurrentSelection->Begin();
i != m_CurrentSelection->End();
++i)
{
if (mitk::DataNodeObject::Pointer nodeObj = i->Cast<mitk::DataNodeObject>())
{
mitk::DataNode::Pointer node = nodeObj->GetDataNode();
// check if node has data,
// if some helper nodes are shown in the DataManager, the GetData() returns 0x0 which would lead to SIGSEV
const mitk::BaseData* nodeData = node->GetData();
if(nodeData == NULL)
continue;
if(QString(classname.c_str()).compare(nodeData->GetNameOfClass())==0)
{
set->InsertElement(at++, node);
}
}
}
return set;
}
return 0;
}
void QmitkControlVisualizationPropertiesView::SetBoolProp(
mitk::DataStorage::SetOfObjects::Pointer set,
std::string name, bool value)
{
if(set.IsNotNull())
{
mitk::DataStorage::SetOfObjects::const_iterator itemiter( set->begin() );
mitk::DataStorage::SetOfObjects::const_iterator itemiterend( set->end() );
while ( itemiter != itemiterend )
{
(*itemiter)->SetBoolProperty(name.c_str(), value);
++itemiter;
}
}
}
void QmitkControlVisualizationPropertiesView::SetIntProp(
mitk::DataStorage::SetOfObjects::Pointer set,
std::string name, int value)
{
if(set.IsNotNull())
{
mitk::DataStorage::SetOfObjects::const_iterator itemiter( set->begin() );
mitk::DataStorage::SetOfObjects::const_iterator itemiterend( set->end() );
while ( itemiter != itemiterend )
{
(*itemiter)->SetIntProperty(name.c_str(), value);
++itemiter;
}
}
}
void QmitkControlVisualizationPropertiesView::SetFloatProp(
mitk::DataStorage::SetOfObjects::Pointer set,
std::string name, float value)
{
if(set.IsNotNull())
{
mitk::DataStorage::SetOfObjects::const_iterator itemiter( set->begin() );
mitk::DataStorage::SetOfObjects::const_iterator itemiterend( set->end() );
while ( itemiter != itemiterend )
{
(*itemiter)->SetFloatProperty(name.c_str(), value);
++itemiter;
}
}
}
void QmitkControlVisualizationPropertiesView::SetLevelWindowProp(
mitk::DataStorage::SetOfObjects::Pointer set,
std::string name, mitk::LevelWindow value)
{
if(set.IsNotNull())
{
mitk::LevelWindowProperty::Pointer prop = mitk::LevelWindowProperty::New(value);
mitk::DataStorage::SetOfObjects::const_iterator itemiter( set->begin() );
mitk::DataStorage::SetOfObjects::const_iterator itemiterend( set->end() );
while ( itemiter != itemiterend )
{
(*itemiter)->SetProperty(name.c_str(), prop);
++itemiter;
}
}
}
void QmitkControlVisualizationPropertiesView::SetEnumProp(
mitk::DataStorage::SetOfObjects::Pointer set,
std::string name, mitk::EnumerationProperty::Pointer value)
{
if(set.IsNotNull())
{
mitk::DataStorage::SetOfObjects::const_iterator itemiter( set->begin() );
mitk::DataStorage::SetOfObjects::const_iterator itemiterend( set->end() );
while ( itemiter != itemiterend )
{
(*itemiter)->SetProperty(name.c_str(), value);
++itemiter;
}
}
}
void QmitkControlVisualizationPropertiesView::DisplayIndexChanged(int dispIndex)
{
m_Controls->m_DisplayIndex->setValue(dispIndex);
m_Controls->m_DisplayIndexSpinBox->setValue(dispIndex);
QString label = "Channel %1";
label = label.arg(dispIndex);
m_Controls->label_channel->setText(label);
std::vector<std::string> sets;
sets.push_back("DiffusionImage");
sets.push_back("TbssImage");
std::vector<std::string>::iterator it = sets.begin();
while(it != sets.end())
{
std::string s = *it;
mitk::DataStorage::SetOfObjects::Pointer set =
ActiveSet(s);
if(set.IsNotNull())
{
mitk::DataStorage::SetOfObjects::const_iterator itemiter( set->begin() );
mitk::DataStorage::SetOfObjects::const_iterator itemiterend( set->end() );
while ( itemiter != itemiterend )
{
(*itemiter)->SetIntProperty("DisplayChannel", dispIndex);
++itemiter;
}
//m_MultiWidget->RequestUpdate();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
it++;
}
}
void QmitkControlVisualizationPropertiesView::Reinit()
{
if (m_CurrentSelection)
{
mitk::DataNodeObject::Pointer nodeObj =
m_CurrentSelection->Begin()->Cast<mitk::DataNodeObject>();
mitk::DataNode::Pointer node = nodeObj->GetDataNode();
mitk::BaseData::Pointer basedata = node->GetData();
if (basedata.IsNotNull())
{
mitk::RenderingManager::GetInstance()->InitializeViews(
basedata->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true );
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
}
void QmitkControlVisualizationPropertiesView::TextIntON()
{
if(m_TexIsOn)
{
m_Controls->m_TextureIntON->setIcon(*m_IconTexOFF);
}
else
{
m_Controls->m_TextureIntON->setIcon(*m_IconTexON);
}
mitk::DataStorage::SetOfObjects::Pointer set =
ActiveSet("DiffusionImage");
SetBoolProp(set,"texture interpolation", !m_TexIsOn);
set = ActiveSet("TensorImage");
SetBoolProp(set,"texture interpolation", !m_TexIsOn);
set = ActiveSet("QBallImage");
SetBoolProp(set,"texture interpolation", !m_TexIsOn);
set = ActiveSet("Image");
SetBoolProp(set,"texture interpolation", !m_TexIsOn);
m_TexIsOn = !m_TexIsOn;
if(m_MultiWidget)
m_MultiWidget->RequestUpdate();
}
void QmitkControlVisualizationPropertiesView::VisibleOdfsON_S()
{
m_GlyIsOn_S = m_Controls->m_VisibleOdfsON_S->isChecked();
if (m_NodeUsedForOdfVisualization.IsNull())
{
MITK_WARN << "ODF visualization activated but m_NodeUsedForOdfVisualization is NULL";
return;
}
m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_S", m_GlyIsOn_S);
VisibleOdfsON(0);
}
void QmitkControlVisualizationPropertiesView::VisibleOdfsON_T()
{
m_GlyIsOn_T = m_Controls->m_VisibleOdfsON_T->isChecked();
if (m_NodeUsedForOdfVisualization.IsNull())
{
MITK_WARN << "ODF visualization activated but m_NodeUsedForOdfVisualization is NULL";
return;
}
m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_T", m_GlyIsOn_T);
VisibleOdfsON(1);
}
void QmitkControlVisualizationPropertiesView::VisibleOdfsON_C()
{
m_GlyIsOn_C = m_Controls->m_VisibleOdfsON_C->isChecked();
if (m_NodeUsedForOdfVisualization.IsNull())
{
MITK_WARN << "ODF visualization activated but m_NodeUsedForOdfVisualization is NULL";
return;
}
m_NodeUsedForOdfVisualization->SetBoolProperty("VisibleOdfs_C", m_GlyIsOn_C);
VisibleOdfsON(2);
}
bool QmitkControlVisualizationPropertiesView::IsPlaneRotated()
{
// for all 2D renderwindows of m_MultiWidget check alignment
mitk::PlaneGeometry::ConstPointer displayPlane = dynamic_cast<const mitk::PlaneGeometry*>( m_MultiWidget->GetRenderWindow1()->GetRenderer()->GetCurrentWorldGeometry2D() );
if (displayPlane.IsNull()) return false;
mitk::Image* currentImage = dynamic_cast<mitk::Image* >( m_NodeUsedForOdfVisualization->GetData() );
if( currentImage == NULL )
{
MITK_ERROR << " Casting problems. Returning false";
return false;
}
int affectedDimension(-1);
int affectedSlice(-1);
return !(DetermineAffectedImageSlice( currentImage, displayPlane, affectedDimension, affectedSlice ));
}
void QmitkControlVisualizationPropertiesView::VisibleOdfsON(int view)
{
if(m_MultiWidget)
m_MultiWidget->RequestUpdate();
}
void QmitkControlVisualizationPropertiesView::ShowMaxNumberChanged()
{
int maxNr = m_Controls->m_ShowMaxNumber->value();
if ( maxNr < 1 )
{
m_Controls->m_ShowMaxNumber->setValue( 1 );
maxNr = 1;
}
mitk::DataStorage::SetOfObjects::Pointer set =
ActiveSet("QBallImage");
SetIntProp(set,"ShowMaxNumber", maxNr);
set = ActiveSet("TensorImage");
SetIntProp(set,"ShowMaxNumber", maxNr);
if(m_MultiWidget)
m_MultiWidget->RequestUpdate();
}
void QmitkControlVisualizationPropertiesView::NormalizationDropdownChanged(int normDropdown)
{
typedef mitk::OdfNormalizationMethodProperty PropType;
PropType::Pointer normMeth = PropType::New();
switch(normDropdown)
{
case 0:
normMeth->SetNormalizationToMinMax();
break;
case 1:
normMeth->SetNormalizationToMax();
break;
case 2:
normMeth->SetNormalizationToNone();
break;
case 3:
normMeth->SetNormalizationToGlobalMax();
break;
default:
normMeth->SetNormalizationToMinMax();
}
mitk::DataStorage::SetOfObjects::Pointer set =
ActiveSet("QBallImage");
SetEnumProp(set,"Normalization", normMeth.GetPointer());
set = ActiveSet("TensorImage");
SetEnumProp(set,"Normalization", normMeth.GetPointer());
// if(m_MultiWidget)
// m_MultiWidget->RequestUpdate();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkControlVisualizationPropertiesView::ScalingFactorChanged(double scalingFactor)
{
mitk::DataStorage::SetOfObjects::Pointer set =
ActiveSet("QBallImage");
SetFloatProp(set,"Scaling", scalingFactor);
set = ActiveSet("TensorImage");
SetFloatProp(set,"Scaling", scalingFactor);
if(m_MultiWidget)
m_MultiWidget->RequestUpdate();
}
void QmitkControlVisualizationPropertiesView::AdditionalScaling(int additionalScaling)
{
typedef mitk::OdfScaleByProperty PropType;
PropType::Pointer scaleBy = PropType::New();
switch(additionalScaling)
{
case 0:
scaleBy->SetScaleByNothing();
break;
case 1:
scaleBy->SetScaleByGFA();
//m_Controls->params_frame->setVisible(true);
break;
#ifdef DIFFUSION_IMAGING_EXTENDED
case 2:
scaleBy->SetScaleByPrincipalCurvature();
// commented in for SPIE paper, Principle curvature scaling
//m_Controls->params_frame->setVisible(true);
break;
#endif
default:
scaleBy->SetScaleByNothing();
}
mitk::DataStorage::SetOfObjects::Pointer set =
ActiveSet("QBallImage");
SetEnumProp(set,"ScaleBy", scaleBy.GetPointer());
set = ActiveSet("TensorImage");
SetEnumProp(set,"ScaleBy", scaleBy.GetPointer());
if(m_MultiWidget)
m_MultiWidget->RequestUpdate();
}
void QmitkControlVisualizationPropertiesView::IndexParam1Changed(double param1)
{
mitk::DataStorage::SetOfObjects::Pointer set =
ActiveSet("QBallImage");
SetFloatProp(set,"IndexParam1", param1);
set = ActiveSet("TensorImage");
SetFloatProp(set,"IndexParam1", param1);
if(m_MultiWidget)
m_MultiWidget->RequestUpdate();
}
void QmitkControlVisualizationPropertiesView::IndexParam2Changed(double param2)
{
mitk::DataStorage::SetOfObjects::Pointer set =
ActiveSet("QBallImage");
SetFloatProp(set,"IndexParam2", param2);
set = ActiveSet("TensorImage");
SetFloatProp(set,"IndexParam2", param2);
if(m_MultiWidget)
m_MultiWidget->RequestUpdate();
}
void QmitkControlVisualizationPropertiesView::OpacityChanged(double l, double u)
{
mitk::LevelWindow olw;
olw.SetRangeMinMax(l*255, u*255);
mitk::DataStorage::SetOfObjects::Pointer set =
ActiveSet("QBallImage");
SetLevelWindowProp(set,"opaclevelwindow", olw);
set = ActiveSet("TensorImage");
SetLevelWindowProp(set,"opaclevelwindow", olw);
set = ActiveSet("Image");
SetLevelWindowProp(set,"opaclevelwindow", olw);
m_Controls->m_OpacityMinFaLabel->setText(QString::number(l,'f',2) + " : " + QString::number(u,'f',2));
if(m_MultiWidget)
m_MultiWidget->RequestUpdate();
}
void QmitkControlVisualizationPropertiesView::ScalingCheckbox()
{
m_Controls->m_ScalingFrame->setVisible(
m_Controls->m_ScalingCheckbox->isChecked());
if(!m_Controls->m_ScalingCheckbox->isChecked())
{
m_Controls->m_AdditionalScaling->setCurrentIndex(0);
m_Controls->m_ScalingFactor->setValue(1.0);
}
}
void QmitkControlVisualizationPropertiesView::Fiber2DfadingEFX()
{
if (m_SelectedNode && dynamic_cast<mitk::FiberBundleX*>(m_SelectedNode->GetData()) )
{
bool currentMode;
m_SelectedNode->GetBoolProperty("Fiber2DfadeEFX", currentMode);
m_SelectedNode->SetProperty("Fiber2DfadeEFX", mitk::BoolProperty::New(!currentMode));
dynamic_cast<mitk::FiberBundleX*>(m_SelectedNode->GetData())->RequestUpdate2D();
mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll();
}
}
void QmitkControlVisualizationPropertiesView::FiberSlicingThickness2D()
{
if (m_SelectedNode && dynamic_cast<mitk::FiberBundleX*>(m_SelectedNode->GetData()))
{
float fibThickness = m_Controls->m_FiberThicknessSlider->value() * 0.1;
float currentThickness = 0;
m_SelectedNode->GetFloatProperty("Fiber2DSliceThickness", currentThickness);
if (fabs(fibThickness-currentThickness)<0.001)
return;
m_SelectedNode->SetProperty("Fiber2DSliceThickness", mitk::FloatProperty::New(fibThickness));
dynamic_cast<mitk::FiberBundleX*>(m_SelectedNode->GetData())->RequestUpdate2D();
mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll();
}
}
void QmitkControlVisualizationPropertiesView::FiberSlicingUpdateLabel(int value)
{
QString label = "Range %1 mm";
label = label.arg(value * 0.1);
m_Controls->label_range->setText(label);
this->FiberSlicingThickness2D();
}
void QmitkControlVisualizationPropertiesView::SetFiberBundleCustomColor(const itk::EventObject& /*e*/)
{
float color[3];
m_SelectedNode->GetColor(color);
m_Controls->m_Color->setAutoFillBackground(true);
QString styleSheet = "background-color:rgb(";
styleSheet.append(QString::number(color[0]*255.0));
styleSheet.append(",");
styleSheet.append(QString::number(color[1]*255.0));
styleSheet.append(",");
styleSheet.append(QString::number(color[2]*255.0));
styleSheet.append(")");
m_Controls->m_Color->setStyleSheet(styleSheet);
m_SelectedNode->SetProperty("color",mitk::ColorProperty::New(color[0], color[1], color[2]));
mitk::FiberBundleX::Pointer fib = dynamic_cast<mitk::FiberBundleX*>(m_SelectedNode->GetData());
fib->SetColorCoding(mitk::FiberBundleX::COLORCODING_CUSTOM);
mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll();
}
void QmitkControlVisualizationPropertiesView::BundleRepresentationColor()
{
if(m_SelectedNode)
{
QColor color = QColorDialog::getColor();
if (!color.isValid())
return;
m_Controls->m_Color->setAutoFillBackground(true);
QString styleSheet = "background-color:rgb(";
styleSheet.append(QString::number(color.red()));
styleSheet.append(",");
styleSheet.append(QString::number(color.green()));
styleSheet.append(",");
styleSheet.append(QString::number(color.blue()));
styleSheet.append(")");
m_Controls->m_Color->setStyleSheet(styleSheet);
m_SelectedNode->SetProperty("color",mitk::ColorProperty::New(color.red()/255.0, color.green()/255.0, color.blue()/255.0));
mitk::FiberBundleX::Pointer fib = dynamic_cast<mitk::FiberBundleX*>(m_SelectedNode->GetData());
fib->SetColorCoding(mitk::FiberBundleX::COLORCODING_CUSTOM);
mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll();
}
}
void QmitkControlVisualizationPropertiesView::BundleRepresentationResetColoring()
{
if(m_SelectedNode)
{
MITK_INFO << "reset colorcoding to oBased";
m_Controls->m_Color->setAutoFillBackground(true);
QString styleSheet = "background-color:rgb(255,255,255)";
m_Controls->m_Color->setStyleSheet(styleSheet);
// m_SelectedNode->SetProperty("color",NULL);
m_SelectedNode->SetProperty("color",mitk::ColorProperty::New(1.0, 1.0, 1.0));
mitk::FiberBundleX::Pointer fib = dynamic_cast<mitk::FiberBundleX*>(m_SelectedNode->GetData());
fib->SetColorCoding(mitk::FiberBundleX::COLORCODING_ORIENTATION_BASED);
fib->DoColorCodingOrientationBased();
mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll();
}
}
void QmitkControlVisualizationPropertiesView::PlanarFigureFocus()
{
if(m_SelectedNode)
{
mitk::PlanarFigure* _PlanarFigure = 0;
_PlanarFigure = dynamic_cast<mitk::PlanarFigure*> (m_SelectedNode->GetData());
- if (_PlanarFigure && _PlanarFigure->GetGeometry2D())
+ if (_PlanarFigure && _PlanarFigure->GetPlaneGeometry())
{
QmitkRenderWindow* selectedRenderWindow = 0;
bool PlanarFigureInitializedWindow = false;
QmitkRenderWindow* RenderWindow1 =
this->GetActiveStdMultiWidget()->GetRenderWindow1();
if (m_SelectedNode->GetBoolProperty("PlanarFigureInitializedWindow",
PlanarFigureInitializedWindow, RenderWindow1->GetRenderer()))
{
selectedRenderWindow = RenderWindow1;
}
QmitkRenderWindow* RenderWindow2 =
this->GetActiveStdMultiWidget()->GetRenderWindow2();
if (!selectedRenderWindow && m_SelectedNode->GetBoolProperty(
"PlanarFigureInitializedWindow", PlanarFigureInitializedWindow,
RenderWindow2->GetRenderer()))
{
selectedRenderWindow = RenderWindow2;
}
QmitkRenderWindow* RenderWindow3 =
this->GetActiveStdMultiWidget()->GetRenderWindow3();
if (!selectedRenderWindow && m_SelectedNode->GetBoolProperty(
"PlanarFigureInitializedWindow", PlanarFigureInitializedWindow,
RenderWindow3->GetRenderer()))
{
selectedRenderWindow = RenderWindow3;
}
QmitkRenderWindow* RenderWindow4 =
this->GetActiveStdMultiWidget()->GetRenderWindow4();
if (!selectedRenderWindow && m_SelectedNode->GetBoolProperty(
"PlanarFigureInitializedWindow", PlanarFigureInitializedWindow,
RenderWindow4->GetRenderer()))
{
selectedRenderWindow = RenderWindow4;
}
- const mitk::PlaneGeometry
- * _PlaneGeometry =
- dynamic_cast<const mitk::PlaneGeometry*> (_PlanarFigure->GetGeometry2D());
+ const mitk::PlaneGeometry* _PlaneGeometry = _PlanarFigure->GetPlaneGeometry();
mitk::VnlVector normal = _PlaneGeometry->GetNormalVnl();
mitk::Geometry2D::ConstPointer worldGeometry1 =
RenderWindow1->GetRenderer()->GetCurrentWorldGeometry2D();
mitk::PlaneGeometry::ConstPointer _Plane1 =
dynamic_cast<const mitk::PlaneGeometry*>( worldGeometry1.GetPointer() );
mitk::VnlVector normal1 = _Plane1->GetNormalVnl();
mitk::Geometry2D::ConstPointer worldGeometry2 =
RenderWindow2->GetRenderer()->GetCurrentWorldGeometry2D();
mitk::PlaneGeometry::ConstPointer _Plane2 =
dynamic_cast<const mitk::PlaneGeometry*>( worldGeometry2.GetPointer() );
mitk::VnlVector normal2 = _Plane2->GetNormalVnl();
mitk::Geometry2D::ConstPointer worldGeometry3 =
RenderWindow3->GetRenderer()->GetCurrentWorldGeometry2D();
mitk::PlaneGeometry::ConstPointer _Plane3 =
dynamic_cast<const mitk::PlaneGeometry*>( worldGeometry3.GetPointer() );
mitk::VnlVector normal3 = _Plane3->GetNormalVnl();
normal[0] = fabs(normal[0]); normal[1] = fabs(normal[1]); normal[2] = fabs(normal[2]);
normal1[0] = fabs(normal1[0]); normal1[1] = fabs(normal1[1]); normal1[2] = fabs(normal1[2]);
normal2[0] = fabs(normal2[0]); normal2[1] = fabs(normal2[1]); normal2[2] = fabs(normal2[2]);
normal3[0] = fabs(normal3[0]); normal3[1] = fabs(normal3[1]); normal3[2] = fabs(normal3[2]);
double ang1 = angle(normal, normal1);
double ang2 = angle(normal, normal2);
double ang3 = angle(normal, normal3);
if(ang1 < ang2 && ang1 < ang3)
{
selectedRenderWindow = RenderWindow1;
}
else
{
if(ang2 < ang3)
{
selectedRenderWindow = RenderWindow2;
}
else
{
selectedRenderWindow = RenderWindow3;
}
}
// make node visible
if (selectedRenderWindow)
{
const mitk::Point3D& centerP = _PlaneGeometry->GetOrigin();
selectedRenderWindow->GetSliceNavigationController()->ReorientSlices(
centerP, _PlaneGeometry->GetNormal());
}
}
// set interactor for new node (if not already set)
mitk::PlanarFigureInteractor::Pointer figureInteractor
= dynamic_cast<mitk::PlanarFigureInteractor*>(m_SelectedNode->GetDataInteractor().GetPointer());
if(figureInteractor.IsNull())
{
figureInteractor = mitk::PlanarFigureInteractor::New();
us::Module* planarFigureModule = us::ModuleRegistry::GetModule( "MitkPlanarFigure" );
figureInteractor->LoadStateMachine("PlanarFigureInteraction.xml", planarFigureModule );
figureInteractor->SetEventConfig( "PlanarFigureConfig.xml", planarFigureModule );
figureInteractor->SetDataNode( m_SelectedNode );
}
m_SelectedNode->SetProperty("planarfigure.iseditable",mitk::BoolProperty::New(true));
}
}
void QmitkControlVisualizationPropertiesView::SetInteractor()
{
typedef std::vector<mitk::DataNode*> Container;
Container _NodeSet = this->GetDataManagerSelection();
mitk::DataNode* node = 0;
mitk::FiberBundleX* bundle = 0;
mitk::FiberBundleInteractor::Pointer bundleInteractor = 0;
// finally add all nodes to the model
for(Container::const_iterator it=_NodeSet.begin(); it!=_NodeSet.end()
; it++)
{
node = const_cast<mitk::DataNode*>(*it);
bundle = dynamic_cast<mitk::FiberBundleX*>(node->GetData());
if(bundle)
{
bundleInteractor = dynamic_cast<mitk::FiberBundleInteractor*>(node->GetInteractor());
if(bundleInteractor.IsNotNull())
mitk::GlobalInteraction::GetInstance()->RemoveInteractor(bundleInteractor);
if(!m_Controls->m_Crosshair->isChecked())
{
m_Controls->m_Crosshair->setChecked(false);
this->GetActiveStdMultiWidget()->GetRenderWindow4()->setCursor(Qt::ArrowCursor);
m_CurrentPickingNode = 0;
}
else
{
m_Controls->m_Crosshair->setChecked(true);
bundleInteractor = mitk::FiberBundleInteractor::New("FiberBundleInteractor", node);
mitk::GlobalInteraction::GetInstance()->AddInteractor(bundleInteractor);
this->GetActiveStdMultiWidget()->GetRenderWindow4()->setCursor(Qt::CrossCursor);
m_CurrentPickingNode = node;
}
}
}
}
void QmitkControlVisualizationPropertiesView::PFWidth(int w)
{
double width = w/10.0;
m_SelectedNode->SetProperty("planarfigure.line.width", mitk::FloatProperty::New(width) );
m_SelectedNode->SetProperty("planarfigure.shadow.widthmodifier", mitk::FloatProperty::New(width) );
m_SelectedNode->SetProperty("planarfigure.outline.width", mitk::FloatProperty::New(width) );
m_SelectedNode->SetProperty("planarfigure.helperline.width", mitk::FloatProperty::New(width) );
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
QString label = "Width %1";
label = label.arg(width);
m_Controls->label_pfwidth->setText(label);
}
void QmitkControlVisualizationPropertiesView::PFColor()
{
QColor color = QColorDialog::getColor();
if (!color.isValid())
return;
m_Controls->m_PFColor->setAutoFillBackground(true);
QString styleSheet = "background-color:rgb(";
styleSheet.append(QString::number(color.red()));
styleSheet.append(",");
styleSheet.append(QString::number(color.green()));
styleSheet.append(",");
styleSheet.append(QString::number(color.blue()));
styleSheet.append(")");
m_Controls->m_PFColor->setStyleSheet(styleSheet);
m_SelectedNode->SetProperty( "planarfigure.default.line.color", mitk::ColorProperty::New(color.red()/255.0, color.green()/255.0, color.blue()/255.0));
m_SelectedNode->SetProperty( "planarfigure.default.outline.color", mitk::ColorProperty::New(color.red()/255.0, color.green()/255.0, color.blue()/255.0));
m_SelectedNode->SetProperty( "planarfigure.default.helperline.color", mitk::ColorProperty::New(color.red()/255.0, color.green()/255.0, color.blue()/255.0));
m_SelectedNode->SetProperty( "planarfigure.default.markerline.color", mitk::ColorProperty::New(color.red()/255.0, color.green()/255.0, color.blue()/255.0));
m_SelectedNode->SetProperty( "planarfigure.default.marker.color", mitk::ColorProperty::New(color.red()/255.0, color.green()/255.0, color.blue()/255.0));
m_SelectedNode->SetProperty( "planarfigure.hover.line.color", mitk::ColorProperty::New(color.red()/255.0, color.green()/255.0, color.blue()/255.0) );
m_SelectedNode->SetProperty( "planarfigure.hover.outline.color", mitk::ColorProperty::New(color.red()/255.0, color.green()/255.0, color.blue()/255.0) );
m_SelectedNode->SetProperty( "planarfigure.hover.helperline.color", mitk::ColorProperty::New(color.red()/255.0, color.green()/255.0, color.blue()/255.0) );
m_SelectedNode->SetProperty( "color", mitk::ColorProperty::New(color.red()/255.0, color.green()/255.0, color.blue()/255.0));
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkControlVisualizationPropertiesView::GenerateTdi()
{
if(m_SelectedNode)
{
mitk::FiberBundleX* bundle = dynamic_cast<mitk::FiberBundleX*>(m_SelectedNode->GetData());
if(!bundle)
return;
typedef float OutPixType;
typedef itk::Image<OutPixType, 3> OutImageType;
// run generator
itk::TractDensityImageFilter< OutImageType >::Pointer generator = itk::TractDensityImageFilter< OutImageType >::New();
generator->SetFiberBundle(bundle);
generator->SetOutputAbsoluteValues(true);
generator->SetUpsamplingFactor(1);
generator->Update();
// get result
OutImageType::Pointer outImg = generator->GetOutput();
mitk::Image::Pointer img = mitk::Image::New();
img->InitializeByItk(outImg.GetPointer());
img->SetVolume(outImg->GetBufferPointer());
// to datastorage
mitk::DataNode::Pointer node = mitk::DataNode::New();
node->SetData(img);
QString name(m_SelectedNode->GetName().c_str());
name += "_TDI";
node->SetName(name.toStdString());
node->SetVisibility(true);
GetDataStorage()->Add(node);
}
}
void QmitkControlVisualizationPropertiesView::LineWidthChanged()
{
if(m_SelectedNode && dynamic_cast<mitk::FiberBundleX*>(m_SelectedNode->GetData()))
{
int newWidth = m_Controls->m_LineWidth->value();
int currentWidth = 0;
m_SelectedNode->GetIntProperty("LineWidth", currentWidth);
if (currentWidth==newWidth)
return;
m_SelectedNode->SetIntProperty("LineWidth", newWidth);
dynamic_cast<mitk::FiberBundleX*>(m_SelectedNode->GetData())->RequestUpdate2D();
dynamic_cast<mitk::FiberBundleX*>(m_SelectedNode->GetData())->RequestUpdate3D();
mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll();
}
}
void QmitkControlVisualizationPropertiesView::Welcome()
{
berry::PlatformUI::GetWorkbench()->GetIntroManager()->ShowIntro(
GetSite()->GetWorkbenchWindow(), false);
}
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesViewControls.ui b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesViewControls.ui
index 449b6158de..01ef2755f9 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesViewControls.ui
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkControlVisualizationPropertiesViewControls.ui
@@ -1,965 +1,965 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QmitkControlVisualizationPropertiesViewControls</class>
<widget class="QWidget" name="QmitkControlVisualizationPropertiesViewControls">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>567</width>
<height>619</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>100</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="windowTitle">
<string>QmitkTemplate</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="m_ImageControlsFrame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="frame_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QToolButton" name="m_Reinit">
<property name="toolTip">
<string>Reinit view</string>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string/>
</property>
<property name="text">
<string/>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="m_TextureIntON">
<property name="toolTip">
<string>Texture interpolation ON</string>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string/>
</property>
<property name="text">
<string/>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="m_VisibleOdfsON_T">
<property name="toolTip">
<string>Toggle visibility of ODF glyphs (axial)</string>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string/>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../resources/QmitkDiffusionImaging.qrc">
<normaloff>:/QmitkDiffusionImaging/glyphsoff_T.png</normaloff>
<normalon>:/QmitkDiffusionImaging/glyphson_T.png</normalon>:/QmitkDiffusionImaging/glyphsoff_T.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="m_VisibleOdfsON_S">
<property name="toolTip">
<string>Toggle visibility of ODF glyphs (sagittal)</string>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string/>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../resources/QmitkDiffusionImaging.qrc">
<normaloff>:/QmitkDiffusionImaging/glyphsoff_S.png</normaloff>
<normalon>:/QmitkDiffusionImaging/glyphson_S.png</normalon>:/QmitkDiffusionImaging/glyphsoff_S.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="m_VisibleOdfsON_C">
<property name="toolTip">
<string>Toggle visibility of ODF glyphs (coronal)</string>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string/>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../resources/QmitkDiffusionImaging.qrc">
<normaloff>:/QmitkDiffusionImaging/glyphsoff_C.png</normaloff>
<normalon>:/QmitkDiffusionImaging/glyphson_C.png</normalon>:/QmitkDiffusionImaging/glyphsoff_C.png</iconset>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="m_TSMenu">
<property name="toolTip">
<string>Multislice Projection</string>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string/>
</property>
<property name="text">
<string>MIP</string>
</property>
<property name="popupMode">
<enum>QToolButton::MenuButtonPopup</enum>
</property>
<property name="arrowType">
<enum>Qt::NoArrow</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_channel">
<property name="text">
<string>Channel</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="m_DisplayIndex">
<property name="maximum">
<number>300</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="m_DisplayIndexSpinBox"/>
</item>
<item>
<widget class="QFrame" name="m_NumberGlyphsFrame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_glyphs">
<property name="text">
<string>#Glyphs</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="m_ShowMaxNumber">
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="OpacMinFrame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Opacity</string>
</property>
</widget>
</item>
<item>
- <widget class="QmitkFloatingPointSpanSlider" name="m_OpacitySlider">
+ <widget class="ctkRangeSlider" name="m_OpacitySlider">
<property name="maximum">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="m_OpacityMinFaLabel">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>0.0 : 0.0</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="m_NormalizationScalingFrame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="horizontalSpacing">
<number>6</number>
</property>
<property name="verticalSpacing">
<number>0</number>
</property>
<item row="1" column="1">
<widget class="QFrame" name="m_ScalingFrame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QComboBox" name="m_AdditionalScaling">
<property name="frame">
<bool>false</bool>
</property>
<item>
<property name="text">
<string>None</string>
</property>
</item>
<item>
<property name="text">
<string>By GFA</string>
</property>
</item>
<item>
<property name="text">
<string>By ASR</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>*</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="m_ScalingFactor">
<property name="toolTip">
<string>Additional scaling factor</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="m_ScalingCheckbox">
<property name="text">
<string>Scaling</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QFrame" name="m_NormalizationFrame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
</layout>
</widget>
</item>
<item row="0" column="0">
<widget class="QComboBox" name="m_NormalizationDropdown">
<property name="toolTip">
<string>ODF normalization</string>
</property>
<property name="frame">
<bool>false</bool>
</property>
<item>
<property name="text">
<string>Min-Max</string>
</property>
</item>
<item>
<property name="text">
<string>Max</string>
</property>
</item>
<item>
<property name="text">
<string>None</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="params_frame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Param1</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="m_IndexParam1">
<property name="maximum">
<double>9999.989999999999782</double>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Param2</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="m_IndexParam2">
<property name="maximum">
<double>9999.989999999999782</double>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="m_BundleControlsFrame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="frame_5">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_11">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QToolButton" name="m_Color">
<property name="toolTip">
<string>Uniform Color for Bundle</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="m_ResetColoring">
<property name="toolTip">
<string>Reset to Default Coloring</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="m_Crosshair">
<property name="toolTip">
<string>Position Crosshair by 3D-Click</string>
</property>
<property name="statusTip">
<string/>
</property>
<property name="text">
<string/>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="m_TDI">
<property name="toolTip">
<string comment="Generate Tract Density Image" extracomment="Generate Tract Density Image">Generate Tract Density Image</string>
</property>
<property name="whatsThis">
<string/>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="m_FiberFading2D">
<property name="toolTip">
<string>2D Fiberfading on/off</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_6">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_10">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string> 2D Clipping</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="m_FiberThicknessSlider">
<property name="maximum">
<number>100</number>
</property>
<property name="pageStep">
<number>10</number>
</property>
<property name="value">
<number>10</number>
</property>
<property name="sliderPosition">
<number>10</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_range">
<property name="minimumSize">
<size>
<width>90</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>10000</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Range</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_linewidth">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_6">
<property name="text">
<string>Line Width</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="m_LineWidth">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>10</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="m_PlanarFigureControlsFrame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_7">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QToolButton" name="m_Focus">
<property name="toolTip">
<string>Focus Planar Figure</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="m_PFColor">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string comment="Select ROI color." extracomment="Select ROI color.">Select ROI color.</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="m_PFWidth">
<property name="toolTip">
<string comment="Adjust 2D line width." extracomment="Adjust 2D line width.">Adjust 2D line width.</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>20</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_pfwidth">
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Width</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLabel" name="m_lblRotatedPlanesWarning">
<property name="font">
<font>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; color:#ff0000;&quot;&gt; ODF Visualisation not possible in rotated planes. &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; color:#ff0000;&quot;&gt; Use 'Reinit' on the image node to reset. &lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::AutoText</enum>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
- <class>QmitkFloatingPointSpanSlider</class>
- <extends>QSlider</extends>
- <header>QmitkFloatingPointSpanSlider.h</header>
+ <class>ctkRangeSlider</class>
+ <extends>QWidget</extends>
+ <header>ctkRangeSlider.h</header>
</customwidget>
</customwidgets>
<includes>
<include location="local">QmitkDataStorageComboBox.h</include>
</includes>
<resources>
<include location="../../resources/QmitkDiffusionImaging.qrc"/>
</resources>
<connections/>
</ui>
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDenoisingView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDenoisingView.cpp
index 6107a87178..6ccec586f7 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDenoisingView.cpp
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDenoisingView.cpp
@@ -1,508 +1,508 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
// Blueberry
#include <berryISelectionService.h>
#include <berryIWorkbenchWindow.h>
// Qmitk
#include "QmitkDenoisingView.h"
#include <mitkImageCast.h>
#include <mitkProgressBar.h>
QmitkDenoisingWorker::QmitkDenoisingWorker(QmitkDenoisingView *view)
: m_View(view)
{
}
void QmitkDenoisingWorker::run()
{
if (m_View->m_ImageNode.IsNotNull())
{
switch (m_View->m_SelectedFilter)
{
case QmitkDenoisingView::NOFILTERSELECTED:
case QmitkDenoisingView::GAUSS:
{
break;
}
case QmitkDenoisingView::NLM:
{
try
{
m_View->m_CompletedCalculation = true;
m_View->m_NonLocalMeansFilter->Update();
}
catch (itk::ExceptionObject& e)
{
m_View->m_CompletedCalculation = false;
MITK_ERROR << e.what();
}
break;
}
}
m_View->m_DenoisingThread.quit();
}
}
const std::string QmitkDenoisingView::VIEW_ID = "org.mitk.views.denoisingview";
QmitkDenoisingView::QmitkDenoisingView()
: QmitkFunctionality()
, m_Controls( 0 )
, m_ImageNode(NULL)
, m_BrainMaskNode(NULL)
, m_DenoisingWorker(this)
, m_ThreadIsRunning(false)
, m_NonLocalMeansFilter(NULL)
, m_InputImage(NULL)
, m_LastProgressCount(0)
, m_MaxProgressCount(0)
, m_SelectedFilter(NOFILTERSELECTED)
{
m_DenoisingWorker.moveToThread(&m_DenoisingThread);
connect(&m_DenoisingThread, SIGNAL(started()), this, SLOT(BeforeThread()));
connect(&m_DenoisingThread, SIGNAL(started()), &m_DenoisingWorker, SLOT(run()));
connect(&m_DenoisingThread, SIGNAL(finished()), this, SLOT(AfterThread()));
connect(&m_DenoisingThread, SIGNAL(terminated()), this, SLOT(AfterThread()));
m_DenoisingTimer = new QTimer(this);
}
QmitkDenoisingView::~QmitkDenoisingView()
{
delete m_DenoisingTimer;
}
void QmitkDenoisingView::CreateQtPartControl( QWidget *parent )
{
// build up qt view, unless already done
if ( !m_Controls )
{
// create GUI widgets from the Qt Designer's .ui file
m_Controls = new Ui::QmitkDenoisingViewControls;
m_Controls->setupUi( parent );
CreateConnections();
ResetParameterPanel();
}
}
void QmitkDenoisingView::CreateConnections()
{
if ( m_Controls )
{
connect( (QObject*)(m_Controls->m_ApplyButton), SIGNAL(clicked()), this, SLOT(StartDenoising()));
connect( (QObject*)(m_Controls->m_SelectFilterComboBox), SIGNAL(activated(int)), this, SLOT(SelectFilter(int)));
connect( m_DenoisingTimer, SIGNAL(timeout()), this, SLOT(UpdateProgress()));
}
}
void QmitkDenoisingView::Activated()
{
QmitkFunctionality::Activated();
m_Controls->m_SelectFilterComboBox->clear();
- m_Controls->m_SelectFilterComboBox->insertItem(NOFILTERSELECTED, QString( QApplication::translate("QmitkDenoisingView", "Please select a filter", 0, QApplication::UnicodeUTF8) ));
- m_Controls->m_SelectFilterComboBox->insertItem(NLM, QString( QApplication::translate("QmitkDenoisingView", "Non-local means filter", 0, QApplication::UnicodeUTF8) ));
- m_Controls->m_SelectFilterComboBox->insertItem(GAUSS, QString( QApplication::translate("QmitkDenoisingView", "Discrete gaussian filter", 0, QApplication::UnicodeUTF8) ));
+ m_Controls->m_SelectFilterComboBox->insertItem(NOFILTERSELECTED, "Please select a filter");
+ m_Controls->m_SelectFilterComboBox->insertItem(NLM, "Non-local means filter");
+ m_Controls->m_SelectFilterComboBox->insertItem(GAUSS, "Discrete gaussian filter");
}
void QmitkDenoisingView::OnSelectionChanged( std::vector<mitk::DataNode*> nodes )
{
if (m_ThreadIsRunning)
return;
if (m_SelectedFilter != NOFILTERSELECTED)
{
m_Controls->m_InputImageLabel->setText("<font color='red'>mandatory</font>");
}
else
{
m_Controls->m_InputImageLabel->setText("mandatory");
}
m_Controls->m_InputBrainMaskLabel->setText("optional");
m_Controls->m_ApplyButton->setEnabled(false);
m_ImageNode = NULL;
m_BrainMaskNode = NULL;
// iterate selection
for( std::vector<mitk::DataNode*>::iterator it = nodes.begin(); it != nodes.end(); ++it )
{
mitk::DataNode::Pointer node = *it;
if( node.IsNotNull() && dynamic_cast<DiffusionImageType*>(node->GetData()))
{
m_Controls->m_InputImageLabel->setText(node->GetName().c_str());
m_ImageNode = node;
}
bool isBinary = false;
node->GetBoolProperty("binary", isBinary);
// look for a brainmask in selection
if( node.IsNotNull() && static_cast<mitk::Image*>(node->GetData()) && isBinary)
{
m_Controls->m_InputBrainMaskLabel->setText(node->GetName().c_str());
m_BrainMaskNode = node;
}
}
// Preparation of GUI to start denoising if a filter is selected
if (m_ImageNode.IsNotNull() && m_SelectedFilter != NOFILTERSELECTED)
{
m_Controls->m_ApplyButton->setEnabled(true);
}
}
void QmitkDenoisingView::StartDenoising()
{
if (!m_ThreadIsRunning)
{
if (m_ImageNode.IsNotNull())
{
m_LastProgressCount = 0;
switch (m_SelectedFilter)
{
case NOFILTERSELECTED:
{
break;
}
case NLM:
{
// initialize NLM
m_InputImage = dynamic_cast<DiffusionImageType*> (m_ImageNode->GetData());
m_NonLocalMeansFilter = NonLocalMeansDenoisingFilterType::New();
if (m_BrainMaskNode.IsNotNull())
{
// use brainmask if set
m_ImageMask = dynamic_cast<mitk::Image*>(m_BrainMaskNode->GetData());
itk::Image<DiffusionPixelType, 3>::Pointer itkMask;
mitk::CastToItkImage(m_ImageMask, itkMask);
m_NonLocalMeansFilter->SetInputMask(itkMask);
itk::ImageRegionIterator< itk::Image<DiffusionPixelType, 3> > mit(itkMask, itkMask->GetLargestPossibleRegion());
mit.GoToBegin();
itk::Image<DiffusionPixelType, 3>::IndexType minIndex;
itk::Image<DiffusionPixelType, 3>::IndexType maxIndex;
minIndex.Fill(10000);
maxIndex.Fill(0);
while (!mit.IsAtEnd())
{
if (mit.Get())
{
// calculation of the start & end index of the smallest masked region
minIndex[0] = minIndex[0] < mit.GetIndex()[0] ? minIndex[0] : mit.GetIndex()[0];
minIndex[1] = minIndex[1] < mit.GetIndex()[1] ? minIndex[1] : mit.GetIndex()[1];
minIndex[2] = minIndex[2] < mit.GetIndex()[2] ? minIndex[2] : mit.GetIndex()[2];
maxIndex[0] = maxIndex[0] > mit.GetIndex()[0] ? maxIndex[0] : mit.GetIndex()[0];
maxIndex[1] = maxIndex[1] > mit.GetIndex()[1] ? maxIndex[1] : mit.GetIndex()[1];
maxIndex[2] = maxIndex[2] > mit.GetIndex()[2] ? maxIndex[2] : mit.GetIndex()[2];
}
++mit;
}
itk::Image<DiffusionPixelType, 3>::SizeType size;
size[0] = maxIndex[0] - minIndex[0] + 1;
size[1] = maxIndex[1] - minIndex[1] + 1;
size[2] = maxIndex[2] - minIndex[2] + 1;
m_MaxProgressCount = size[0] * size[1] * size[2];
}
else
{
// initialize the progressbar
m_MaxProgressCount = m_InputImage->GetDimension(0) * m_InputImage->GetDimension(1) * m_InputImage->GetDimension(2);
}
mitk::ProgressBar::GetInstance()->AddStepsToDo(m_MaxProgressCount);
m_NonLocalMeansFilter->SetInputImage(m_InputImage->GetVectorImage());
m_NonLocalMeansFilter->SetUseRicianAdaption(m_Controls->m_RicianCheckbox->isChecked());
m_NonLocalMeansFilter->SetUseJointInformation(m_Controls->m_JointInformationCheckbox->isChecked());
m_NonLocalMeansFilter->SetSearchRadius(m_Controls->m_SpinBoxParameter1->value());
m_NonLocalMeansFilter->SetComparisonRadius(m_Controls->m_SpinBoxParameter2->value());
m_NonLocalMeansFilter->SetVariance(m_Controls->m_DoubleSpinBoxParameter3->value());
// start denoising in detached thread
m_DenoisingThread.start(QThread::HighestPriority);
break;
}
case GAUSS:
{
// initialize GAUSS and run
m_InputImage = dynamic_cast<DiffusionImageType*> (m_ImageNode->GetData());
ExtractFilterType::Pointer extractor = ExtractFilterType::New();
extractor->SetInput(m_InputImage->GetVectorImage());
ComposeFilterType::Pointer composer = ComposeFilterType::New();
for (unsigned int i = 0; i < m_InputImage->GetVectorImage()->GetVectorLength(); ++i)
{
extractor->SetIndex(i);
extractor->Update();
m_GaussianFilter = GaussianFilterType::New();
m_GaussianFilter->SetVariance(m_Controls->m_SpinBoxParameter1->value());
if (m_BrainMaskNode.IsNotNull())
{
m_ImageMask = dynamic_cast<mitk::Image*>(m_BrainMaskNode->GetData());
itk::Image<DiffusionPixelType, 3>::Pointer itkMask = itk::Image<DiffusionPixelType, 3>::New();
mitk::CastToItkImage(m_ImageMask, itkMask);
itk::MaskImageFilter<itk::Image<DiffusionPixelType, 3> , itk::Image<DiffusionPixelType, 3> >::Pointer maskImageFilter = itk::MaskImageFilter<itk::Image<DiffusionPixelType, 3> , itk::Image<DiffusionPixelType, 3> >::New();
maskImageFilter->SetInput(extractor->GetOutput());
maskImageFilter->SetMaskImage(itkMask);
maskImageFilter->Update();
m_GaussianFilter->SetInput(maskImageFilter->GetOutput());
}
else
{
m_GaussianFilter->SetInput(extractor->GetOutput());
}
m_GaussianFilter->Update();
composer->SetInput(i, m_GaussianFilter->GetOutput());
}
composer->Update();
DiffusionImageType::Pointer image = DiffusionImageType::New();
image->SetVectorImage(composer->GetOutput());
image->SetReferenceBValue(m_InputImage->GetReferenceBValue());
image->SetDirections(m_InputImage->GetDirections());
image->InitializeFromVectorImage();
mitk::DataNode::Pointer imageNode = mitk::DataNode::New();
imageNode->SetData( image );
QString name = m_ImageNode->GetName().c_str();
imageNode->SetName((name+"_gauss_"+QString::number(m_Controls->m_SpinBoxParameter1->value())).toStdString().c_str());
GetDefaultDataStorage()->Add(imageNode);
break;
}
}
}
}
else
{
m_NonLocalMeansFilter->AbortGenerateDataOn();
m_CompletedCalculation = false;
}
}
void QmitkDenoisingView::ResetParameterPanel()
{
m_Controls->m_DwiLabel->setEnabled(false);
m_Controls->m_InputImageLabel->setEnabled(false);
m_Controls->m_BrainMaskLabel->setEnabled(false);
m_Controls->m_InputBrainMaskLabel->setEnabled(false);
m_Controls->m_ParameterBox->hide();
m_Controls->m_LabelParameter_1->hide();
m_Controls->m_LabelParameter_2->hide();
m_Controls->m_LabelParameter_3->hide();
m_Controls->m_SpinBoxParameter1->hide();
m_Controls->m_SpinBoxParameter2->hide();
m_Controls->m_DoubleSpinBoxParameter3->hide();
m_Controls->m_RicianLabel->hide();
m_Controls->m_RicianCheckbox->hide();
m_Controls->m_JointInformationLabel->hide();
m_Controls->m_JointInformationCheckbox->hide();
m_Controls->m_ApplyButton->setEnabled(false);
}
void QmitkDenoisingView::SelectFilter(int filter)
{
if (m_ThreadIsRunning)
return;
//Prepare GUI
this->ResetParameterPanel();
switch (filter)
{
case 0:
{
m_SelectedFilter = NOFILTERSELECTED;
break;
}
case 1:
{
m_SelectedFilter = NLM;
m_Controls->m_DwiLabel->setEnabled(true);
m_Controls->m_InputImageLabel->setEnabled(true);
m_Controls->m_BrainMaskLabel->setEnabled(true);
m_Controls->m_InputBrainMaskLabel->setEnabled(true);
m_Controls->m_ParameterBox->show();
m_Controls->m_LabelParameter_1->show();
m_Controls->m_LabelParameter_1->setText("Search Radius:");
m_Controls->m_LabelParameter_2->show();
m_Controls->m_LabelParameter_2->setText("Comparision Radius:");
m_Controls->m_LabelParameter_3->show();
m_Controls->m_LabelParameter_3->setText("Noise variance:");
m_Controls->m_SpinBoxParameter1->show();
m_Controls->m_SpinBoxParameter1->setValue(4);
m_Controls->m_SpinBoxParameter2->show();
m_Controls->m_SpinBoxParameter2->setValue(1);
m_Controls->m_DoubleSpinBoxParameter3->show();
m_Controls->m_DoubleSpinBoxParameter3->setValue(1.0);
m_Controls->m_RicianLabel->show();
m_Controls->m_RicianCheckbox->show();
m_Controls->m_RicianCheckbox->setChecked(true);
m_Controls->m_JointInformationLabel->show();
m_Controls->m_JointInformationCheckbox->show();
m_Controls->m_JointInformationCheckbox->setChecked(false);
break;
}
case 2:
{
m_SelectedFilter = GAUSS;
m_Controls->m_DwiLabel->setEnabled(true);
m_Controls->m_InputImageLabel->setEnabled(true);
m_Controls->m_BrainMaskLabel->setEnabled(true);
m_Controls->m_InputBrainMaskLabel->setEnabled(true);
m_Controls->m_ParameterBox->show();
m_Controls->m_LabelParameter_1->show();
m_Controls->m_LabelParameter_1->setText("Variance:");
m_Controls->m_SpinBoxParameter1->show();
m_Controls->m_SpinBoxParameter1->setValue(2);
break;
}
}
if (m_ImageNode.IsNull())
{
if (m_SelectedFilter != NOFILTERSELECTED)
m_Controls->m_InputImageLabel->setText("<font color='red'>mandatory</font>");
else
m_Controls->m_InputImageLabel->setText("mandatory");
}
if (m_ImageNode.IsNotNull())
{
m_Controls->m_ApplyButton->setEnabled(false);
switch(filter)
{
case NOFILTERSELECTED:
{
break;
}
case NLM:
case GAUSS:
{
m_Controls->m_ApplyButton->setEnabled(true);
break;
}
}
}
}
void QmitkDenoisingView::BeforeThread()
{
m_ThreadIsRunning = true;
// initialize timer to update the progressbar at each timestep
m_DenoisingTimer->start(500);
m_Controls->m_ParameterBox->setEnabled(false);
m_Controls->m_ApplyButton->setText("Abort");
}
void QmitkDenoisingView::AfterThread()
{
m_ThreadIsRunning = false;
// stop timer to stop updates of progressbar
m_DenoisingTimer->stop();
// make sure progressbar is finished
mitk::ProgressBar::GetInstance()->Progress(m_MaxProgressCount);
if (m_CompletedCalculation)
{
switch (m_SelectedFilter)
{
case NOFILTERSELECTED:
case GAUSS:
{
break;
}
case NLM:
{
DiffusionImageType::Pointer image = DiffusionImageType::New();
image->SetVectorImage(m_NonLocalMeansFilter->GetOutput());
image->SetReferenceBValue(m_InputImage->GetReferenceBValue());
image->SetDirections(m_InputImage->GetDirections());
image->InitializeFromVectorImage();
mitk::DataNode::Pointer imageNode = mitk::DataNode::New();
imageNode->SetData( image );
QString name = m_ImageNode->GetName().c_str();
//TODO: Rician adaption & joint information in name
if (m_Controls->m_RicianCheckbox->isChecked() && !m_Controls->m_JointInformationCheckbox->isChecked())
{
imageNode->SetName((name+"_NLMr_"+QString::number(m_Controls->m_SpinBoxParameter1->value())+"-"+QString::number(m_Controls->m_SpinBoxParameter2->value())).toStdString().c_str());
}
else if(!m_Controls->m_RicianCheckbox->isChecked() && m_Controls->m_JointInformationCheckbox->isChecked())
{
imageNode->SetName((name+"_NLMv_"+QString::number(m_Controls->m_SpinBoxParameter1->value())+"-"+QString::number(m_Controls->m_SpinBoxParameter2->value())).toStdString().c_str());
}
else if(m_Controls->m_RicianCheckbox->isChecked() && m_Controls->m_JointInformationCheckbox->isChecked())
{
imageNode->SetName((name+"_NLMvr_"+QString::number(m_Controls->m_SpinBoxParameter1->value())+"-"+QString::number(m_Controls->m_SpinBoxParameter2->value())).toStdString().c_str());
}
else
{
imageNode->SetName((name+"_NLM_"+QString::number(m_Controls->m_SpinBoxParameter1->value())+"-"+QString::number(m_Controls->m_SpinBoxParameter2->value())).toStdString().c_str());
}
GetDefaultDataStorage()->Add(imageNode);
break;
}
}
}
m_Controls->m_ParameterBox->setEnabled(true);
m_Controls->m_ApplyButton->setText("Apply");
}
void QmitkDenoisingView::UpdateProgress()
{
switch (m_SelectedFilter)
{
case NOFILTERSELECTED:
case GAUSS:
{
break;
}
case NLM:
{
unsigned int currentProgressCount = m_NonLocalMeansFilter->GetCurrentVoxelCount();
mitk::ProgressBar::GetInstance()->Progress(currentProgressCount-m_LastProgressCount);
m_LastProgressCount = currentProgressCount;
break;
}
}
}
\ No newline at end of file
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionDicomImportView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionDicomImportView.cpp
index 56386594c1..4ae704a475 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionDicomImportView.cpp
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionDicomImportView.cpp
@@ -1,558 +1,558 @@
/*===================================================================
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 "QmitkDiffusionDicomImportView.h"
// qt includes
#include <QFileDialog>
// itk includes
#include "itkTimeProbesCollectorBase.h"
#include "itkGDCMSeriesFileNames.h"
#include "itksys/SystemTools.hxx"
// mitk includes
#include "mitkProgressBar.h"
#include "mitkStatusBar.h"
#include "mitkProperties.h"
#include "mitkRenderingManager.h"
#include "mitkMemoryUtilities.h"
#include "mitkIOUtil.h"
// diffusion module includes
#include "mitkDicomDiffusionImageHeaderReader.h"
#include "mitkDicomDiffusionImageReader.h"
#include "mitkDiffusionImage.h"
#include "mitkDiffusionDICOMFileReader.h"
#include "mitkDICOMTagBasedSorter.h"
#include "mitkDICOMSortByTag.h"
#include "mitkSortByImagePositionPatient.h"
#include "gdcmDirectory.h"
#include "gdcmScanner.h"
#include "gdcmSorter.h"
#include "gdcmIPPSorter.h"
#include "gdcmAttribute.h"
#include "gdcmVersion.h"
#include <itksys/SystemTools.hxx>
#include <itksys/Directory.hxx>
#include <QMessageBox>
const std::string QmitkDiffusionDicomImport::VIEW_ID = "org.mitk.views.diffusiondicomimport";
QmitkDiffusionDicomImport::QmitkDiffusionDicomImport(QObject* /*parent*/, const char* /*name*/)
: QmitkFunctionality(), m_Controls(NULL), m_MultiWidget(NULL),
m_OutputFolderName(""), m_OutputFolderNameSet(false)
{
}
QmitkDiffusionDicomImport::QmitkDiffusionDicomImport(const QmitkDiffusionDicomImport& other)
{
Q_UNUSED(other)
throw std::runtime_error("Copy constructor not implemented");
}
QmitkDiffusionDicomImport::~QmitkDiffusionDicomImport()
{}
void QmitkDiffusionDicomImport::CreateQtPartControl(QWidget *parent)
{
m_Parent = parent;
if (m_Controls == NULL)
{
m_Controls = new Ui::QmitkDiffusionDicomImportControls;
m_Controls->setupUi(parent);
this->CreateConnections();
m_Controls->m_DicomLoadRecursiveCheckbox->setChecked(false);
m_Controls->m_DicomLoadAverageDuplicatesCheckbox->setChecked(false);
m_Controls->m_DicomLoadRecursiveCheckbox->setVisible(true);
m_Controls->m_OverrideOptionCheckbox->setVisible(false);
m_Controls->m_SubdirPrefixLineEdit->setVisible(false);
m_Controls->m_SetPrefixButton->setVisible(false);
m_Controls->m_ResetPrefixButton->setVisible(false);
AverageClicked();
}
}
void QmitkDiffusionDicomImport::CreateConnections()
{
if ( m_Controls )
{
connect( m_Controls->m_AddFoldersButton, SIGNAL(clicked()), this, SLOT(DicomLoadAddFolderNames()) );
connect( m_Controls->m_DeleteFoldersButton, SIGNAL(clicked()), this, SLOT(DicomLoadDeleteFolderNames()) );
//connect( m_Controls->m_DicomLoadStartLoadButton, SIGNAL(clicked()), this, SLOT(DicomLoadStartLoad()) );
connect( m_Controls->m_DicomLoadStartLoadButton, SIGNAL(clicked()), this, SLOT(NewDicomLoadStartLoad()) );
connect( m_Controls->m_DicomLoadAverageDuplicatesCheckbox, SIGNAL(clicked()), this, SLOT(AverageClicked()) );
connect( m_Controls->m_OutputSetButton, SIGNAL(clicked()), this, SLOT(OutputSet()) );
connect( m_Controls->m_OutputClearButton, SIGNAL(clicked()), this, SLOT(OutputClear()) );
connect( m_Controls->m_Remove, SIGNAL(clicked()), this, SLOT(Remove()) );
connect( m_Controls->m_SetPrefixButton, SIGNAL(clicked()), this, SLOT(SetPrefixButtonPushed()));
connect( m_Controls->m_ResetPrefixButton, SIGNAL(clicked()), this, SLOT(ResetPrefixButtonPushed()));
connect( m_Controls->m_DicomLoadRecursiveCheckbox, SIGNAL(clicked()), this, SLOT(RecursiveSettingsChanged()) );
}
}
void QmitkDiffusionDicomImport::RecursiveSettingsChanged()
{
m_Controls->m_SubdirPrefixLineEdit->setVisible( m_Controls->m_DicomLoadRecursiveCheckbox->isChecked() );
m_Controls->m_SetPrefixButton->setVisible( m_Controls->m_DicomLoadRecursiveCheckbox->isChecked() );
m_Controls->m_SubdirPrefixLineEdit->clear();
this->m_Controls->m_SubdirPrefixLineEdit->setEnabled(true);
}
void QmitkDiffusionDicomImport::SetPrefixButtonPushed()
{
m_Prefix = this->m_Controls->m_SubdirPrefixLineEdit->text().toStdString();
if( !this->m_Controls->m_ResetPrefixButton->isVisible() )
this->m_Controls->m_ResetPrefixButton->setVisible(true);
this->m_Controls->m_SubdirPrefixLineEdit->setEnabled(false);
this->m_Controls->m_ResetPrefixButton->setEnabled(true);
this->m_Controls->m_SetPrefixButton->setEnabled(false);
}
void QmitkDiffusionDicomImport::ResetPrefixButtonPushed()
{
m_Controls->m_SubdirPrefixLineEdit->clear();
this->m_Controls->m_SubdirPrefixLineEdit->setEnabled(true);
this->m_Controls->m_ResetPrefixButton->setEnabled(false);
this->m_Controls->m_SetPrefixButton->setEnabled(true);
}
void QmitkDiffusionDicomImport::Remove()
{
int i = m_Controls->listWidget->currentRow();
m_Controls->listWidget->takeItem(i);
}
void QmitkDiffusionDicomImport::OutputSet()
{
// SELECT FOLDER DIALOG
QFileDialog* w = new QFileDialog( m_Parent, QString("Select folders containing DWI data") );
w->setFileMode( QFileDialog::Directory );
// RETRIEVE SELECTION
if ( w->exec() != QDialog::Accepted )
return;
m_OutputFolderName = w->selectedFiles()[0];
m_OutputFolderNameSet = true;
m_Controls->m_OutputLabel->setText(m_OutputFolderName);
// show file override option checkbox
m_Controls->m_OverrideOptionCheckbox->setVisible(true);
}
void QmitkDiffusionDicomImport::OutputClear()
{
m_OutputFolderName = "";
m_OutputFolderNameSet = false;
m_Controls->m_OutputLabel->setText("... optional out-folder ...");
// hide file override option checkbox - no output specified
m_Controls->m_OverrideOptionCheckbox->setVisible(false);
}
void QmitkDiffusionDicomImport::AverageClicked()
{
m_Controls->m_Blur->setEnabled(m_Controls->m_DicomLoadAverageDuplicatesCheckbox->isChecked());
}
void QmitkDiffusionDicomImport::Activated()
{
QmitkFunctionality::Activated();
}
void QmitkDiffusionDicomImport::DicomLoadDeleteFolderNames()
{
m_Controls->listWidget->clear();
}
void QmitkDiffusionDicomImport::DicomLoadAddFolderNames()
{
// SELECT FOLDER DIALOG
QFileDialog* w = new QFileDialog( m_Parent, QString("Select folders containing DWI data") );
w->setFileMode( QFileDialog::Directory );
// RETRIEVE SELECTION
if ( w->exec() != QDialog::Accepted )
return;
m_Controls->listWidget->addItems(w->selectedFiles());
}
bool SortBySeriesUID(gdcm::DataSet const & ds1, gdcm::DataSet const & ds2 )
{
gdcm::Attribute<0x0020,0x000e> at1;
at1.Set( ds1 );
gdcm::Attribute<0x0020,0x000e> at2;
at2.Set( ds2 );
return at1 < at2;
}
bool SortByAcquisitionNumber(gdcm::DataSet const & ds1, gdcm::DataSet const & ds2 )
{
gdcm::Attribute<0x0020,0x0012> at1;
at1.Set( ds1 );
gdcm::Attribute<0x0020,0x0012> at2;
at2.Set( ds2 );
return at1 < at2;
}
bool SortBySeqName(gdcm::DataSet const & ds1, gdcm::DataSet const & ds2 )
{
gdcm::Attribute<0x0018, 0x0024> at1;
at1.Set( ds1 );
gdcm::Attribute<0x0018, 0x0024> at2;
at2.Set( ds2 );
std::string str1 = at1.GetValue().Trim();
std::string str2 = at2.GetValue().Trim();
return std::lexicographical_compare(str1.begin(), str1.end(),
str2.begin(), str2.end() );
}
void QmitkDiffusionDicomImport::Status(QString status)
{
- mitk::StatusBar::GetInstance()->DisplayText(status.toAscii());
+ mitk::StatusBar::GetInstance()->DisplayText(status.toLatin1());
MITK_INFO << status.toStdString().c_str();
}
void QmitkDiffusionDicomImport::Status(std::string status)
{
mitk::StatusBar::GetInstance()->DisplayText(status.c_str());
MITK_INFO << status.c_str();
}
void QmitkDiffusionDicomImport::Status(const char* status)
{
mitk::StatusBar::GetInstance()->DisplayText(status);
MITK_INFO << status;
}
void QmitkDiffusionDicomImport::Error(QString status)
{
- mitk::StatusBar::GetInstance()->DisplayErrorText(status.toAscii());
+ mitk::StatusBar::GetInstance()->DisplayErrorText(status.toLatin1());
MITK_ERROR << status.toStdString().c_str();
}
void QmitkDiffusionDicomImport::Error(std::string status)
{
mitk::StatusBar::GetInstance()->DisplayErrorText(status.c_str());
MITK_ERROR << status.c_str();
}
void QmitkDiffusionDicomImport::Error(const char* status)
{
mitk::StatusBar::GetInstance()->DisplayErrorText(status);
MITK_ERROR << status;
}
void QmitkDiffusionDicomImport::PrintMemoryUsage()
{
size_t processSize = mitk::MemoryUtilities::GetProcessMemoryUsage();
size_t totalSize = mitk::MemoryUtilities::GetTotalSizeOfPhysicalRam();
float percentage = ( (float) processSize / (float) totalSize ) * 100.0;
MITK_INFO << "Current memory usage: " << GetMemoryDescription( processSize, percentage );
}
std::string QmitkDiffusionDicomImport::FormatMemorySize( size_t size )
{
double val = size;
std::string descriptor("B");
if ( val >= 1000.0 )
{
val /= 1024.0;
descriptor = "KB";
}
if ( val >= 1000.0 )
{
val /= 1024.0;
descriptor = "MB";
}
if ( val >= 1000.0 )
{
val /= 1024.0;
descriptor = "GB";
}
std::ostringstream str;
str << std::fixed << std::setprecision(2) << val << " " << descriptor;
return str.str();
}
std::string QmitkDiffusionDicomImport::FormatPercentage( double val )
{
std::ostringstream str;
str << std::fixed << std::setprecision(2) << val << " " << "%";
return str.str();
}
std::string QmitkDiffusionDicomImport::GetMemoryDescription( size_t processSize, float percentage )
{
std::ostringstream str;
str << FormatMemorySize(processSize) << " (" << FormatPercentage( percentage ) <<")" ;
return str.str();
}
void QmitkDiffusionDicomImport::NewDicomLoadStartLoad()
{
itk::TimeProbesCollectorBase clock;
bool imageSuccessfullySaved = true;
bool has_prefix = true;
try
{
const std::string& locale = "C";
const std::string& currLocale = setlocale( LC_ALL, NULL );
if ( locale.compare(currLocale)!=0 )
{
try
{
MITK_INFO << " ** Changing locale from " << setlocale(LC_ALL, NULL) << " to '" << locale << "'";
setlocale(LC_ALL, locale.c_str());
}
catch(...)
{
MITK_INFO << "Could not set locale " << locale;
}
}
int nrFolders = m_Controls->listWidget->count();
if(!nrFolders)
{
Error(QString("No input folders were selected. ABORTING."));
return;
}
Status(QString("GDCM %1 used for DICOM parsing and sorting!").arg(gdcm::Version::GetVersion()));
PrintMemoryUsage();
QString status;
mitk::DataNode::Pointer node;
mitk::ProgressBar::GetInstance()->AddStepsToDo(2*nrFolders);
gdcm::Directory::FilenamesType complete_list;
while(m_Controls->listWidget->count())
{
// RETREIVE FOLDERNAME
QListWidgetItem * item = m_Controls->listWidget->takeItem(0);
QString folderName = item->text();
if( this->m_Controls->m_DicomLoadRecursiveCheckbox->isChecked() )
{
std::string subdir_prefix = "";
if( has_prefix )
{
subdir_prefix = this->m_Prefix;
}
itksys::Directory rootdir;
rootdir.Load( folderName.toStdString().c_str() );
for( unsigned int idx=0; idx<rootdir.GetNumberOfFiles(); idx++)
{
std::string current_path = rootdir.GetFile(idx);
std::string directory_path = std::string(rootdir.GetPath()) + std::string("/") + current_path;
MITK_INFO("dicom.loader.inputrootdir.test") << "ProbePath: " << current_path;
MITK_INFO("dicom.loader.inputrootdir.test") << "IsDirectory: " << itksys::SystemTools::FileIsDirectory( itksys::SystemTools::ConvertToOutputPath( directory_path.c_str() ).c_str() )
<< " StartsWith: " << itksys::SystemTools::StringStartsWith( current_path.c_str(), subdir_prefix.c_str() );
// test for prefix
if( itksys::SystemTools::FileIsDirectory( itksys::SystemTools::ConvertToOutputPath( directory_path.c_str() ).c_str() )
&& itksys::SystemTools::StringStartsWith( current_path.c_str(), subdir_prefix.c_str() )
)
{
gdcm::Directory d;
d.Load( itksys::SystemTools::ConvertToOutputPath( directory_path.c_str() ) , false);
MITK_INFO("dicom.load.subdir.attempt") << "In directory " << itksys::SystemTools::ConvertToOutputPath( directory_path.c_str() );
const gdcm::Directory::FilenamesType &l1 = d.GetFilenames();
const unsigned int ntotalfiles = l1.size();
Status(QString(" ... found %1 different files").arg(ntotalfiles));
for( unsigned int i=0; i< ntotalfiles; i++)
{
complete_list.push_back( l1.at(i) );
}
}
}
}
else
{
gdcm::Directory d;
d.Load( folderName.toStdString().c_str(), this->m_Controls->m_DicomLoadRecursiveCheckbox->isChecked() ); // recursive !
const gdcm::Directory::FilenamesType &l1 = d.GetFilenames();
const unsigned int ntotalfiles = l1.size();
Status(QString(" ... found %1 different files").arg(ntotalfiles));
for( unsigned int i=0; i< ntotalfiles; i++)
{
complete_list.push_back( l1.at(i) );
}
}
}
{
mitk::DiffusionDICOMFileReader::Pointer gdcmReader = mitk::DiffusionDICOMFileReader::New();
mitk::DICOMTagBasedSorter::Pointer tagSorter = mitk::DICOMTagBasedSorter::New();
// Use tags as in Qmitk
// all the things that split by tag in DicomSeriesReader
tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0028, 0x0010) ); // Number of Rows
tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0028, 0x0011) ); // Number of Columns
tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0028, 0x0030) ); // Pixel Spacing
tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0018, 0x1164) ); // Imager Pixel Spacing
tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0020, 0x0037) ); // Image Orientation (Patient) // TODO add tolerance parameter (l. 1572 of original code)
// TODO handle as real vectors! cluster with configurable errors!
tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0020, 0x000e) ); // Series Instance UID
tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0018, 0x0050) ); // Slice Thickness
tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0028, 0x0008) ); // Number of Frames
//tagSorter->AddDistinguishingTag( mitk::DICOMTag(0x0020, 0x0052) ); // Frame of Reference UID
// gdcmReader->AddSortingElement( tagSorter );
//mitk::DICOMFileReaderTestHelper::TestOutputsContainInputs( gdcmReader );
mitk::DICOMSortCriterion::ConstPointer sorting =
mitk::SortByImagePositionPatient::New( // Image Position (Patient)
//mitk::DICOMSortByTag::New( mitk::DICOMTag(0x0020, 0x0013), // instance number
mitk::DICOMSortByTag::New( mitk::DICOMTag(0x0020, 0x0012), // aqcuisition number
mitk::DICOMSortByTag::New( mitk::DICOMTag(0x0008, 0x0032), // aqcuisition time
mitk::DICOMSortByTag::New( mitk::DICOMTag(0x0018, 0x1060), // trigger time
mitk::DICOMSortByTag::New( mitk::DICOMTag(0x0008, 0x0018) // SOP instance UID (last resort, not really meaningful but decides clearly)
).GetPointer()
).GetPointer()
).GetPointer()
).GetPointer()
// ).GetPointer()
).GetPointer();
tagSorter->SetSortCriterion( sorting );
// mosaic
gdcmReader->SetResolveMosaic( this->m_Controls->m_SplitMosaicCheckBox->isChecked() );
gdcmReader->AddSortingElement( tagSorter );
gdcmReader->SetInputFiles( complete_list );
try
{
gdcmReader->AnalyzeInputFiles();
}
catch( const itk::ExceptionObject &e)
{
MITK_ERROR << "Failed to analyze data. " << e.what();
}
catch( const std::exception &se)
{
MITK_ERROR << "Std Exception " << se.what();
}
gdcmReader->LoadImages();
for( int o = 0; o < gdcmReader->GetNumberOfOutputs(); o++ )
{
mitk::Image::Pointer loaded_image = gdcmReader->GetOutput(o).GetMitkImage();
mitk::DiffusionImage<short>::Pointer d_img = static_cast<mitk::DiffusionImage<short>*>( loaded_image.GetPointer() );
std::stringstream ss;
ss << "ImportedData_" << o;
node = mitk::DataNode::New();
node->SetData( d_img );
std::string outname;
d_img->GetPropertyList()->GetStringProperty("diffusion.dicom.importname", outname );
node->SetName( outname.c_str() );
GetDefaultDataStorage()->Add(node);
//SetDwiNodeProperties(node, ss.str() );
//Status(QString("Image %1 added to datastorage").arg(descr));
}
}
Status("Timing information");
clock.Report();
if(!m_OutputFolderNameSet && node.IsNotNull())
{
mitk::BaseData::Pointer basedata = node->GetData();
if (basedata.IsNotNull())
{
mitk::RenderingManager::GetInstance()->InitializeViews(
basedata->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true );
}
}
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
try
{
MITK_INFO << " ** Changing locale back from " << setlocale(LC_ALL, NULL) << " to '" << currLocale << "'";
setlocale(LC_ALL, currLocale.c_str());
}
catch(...)
{
MITK_INFO << "Could not reset locale " << currLocale;
}
}
catch (itk::ExceptionObject &ex)
{
Error(QString("%1\n%2\n%3\n%4\n%5\n%6").arg(ex.GetNameOfClass()).arg(ex.GetFile()).arg(ex.GetLine()).arg(ex.GetLocation()).arg(ex.what()).arg(ex.GetDescription()));
return ;
}
if (!imageSuccessfullySaved)
QMessageBox::warning(NULL,"WARNING","One or more files could not be saved! The according files where moved to the datastorage.");
Status(QString("Finished import with memory:"));
PrintMemoryUsage();
}
void QmitkDiffusionDicomImport::SetDwiNodeProperties(mitk::DataNode::Pointer node, std::string name)
{
node->SetProperty( "IsDWIRawVolume", mitk::BoolProperty::New( true ) );
// set foldername as string property
mitk::StringProperty::Pointer nameProp = mitk::StringProperty::New( name );
node->SetProperty( "name", nameProp );
}
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionQuantificationView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionQuantificationView.cpp
index af9c7bf41d..507ee54a37 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionQuantificationView.cpp
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkDiffusionQuantificationView.cpp
@@ -1,569 +1,569 @@
/*===================================================================
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 "QmitkDiffusionQuantificationView.h"
#include "mitkDiffusionImagingConfigure.h"
#include "itkTimeProbe.h"
#include "itkImage.h"
#include "mitkNodePredicateDataType.h"
#include "mitkDataNodeObject.h"
#include "mitkQBallImage.h"
#include <mitkTensorImage.h>
#include "mitkImageCast.h"
#include "mitkStatusBar.h"
#include "itkDiffusionQballGeneralizedFaImageFilter.h"
#include "itkShiftScaleImageFilter.h"
#include "itkTensorFractionalAnisotropyImageFilter.h"
#include "itkTensorRelativeAnisotropyImageFilter.h"
#include "itkTensorDerivedMeasurementsFilter.h"
#include "QmitkDataStorageComboBox.h"
#include "QmitkStdMultiWidget.h"
#include <QMessageBox>
#include "berryIWorkbenchWindow.h"
#include "berryISelectionService.h"
const std::string QmitkDiffusionQuantificationView::VIEW_ID = "org.mitk.views.diffusionquantification";
QmitkDiffusionQuantificationView::QmitkDiffusionQuantificationView()
: QmitkFunctionality(),
m_Controls(NULL),
m_MultiWidget(NULL)
{
m_QBallImages = mitk::DataStorage::SetOfObjects::New();
m_TensorImages = mitk::DataStorage::SetOfObjects::New();
}
QmitkDiffusionQuantificationView::QmitkDiffusionQuantificationView(const QmitkDiffusionQuantificationView& other)
{
Q_UNUSED(other)
throw std::runtime_error("Copy constructor not implemented");
}
QmitkDiffusionQuantificationView::~QmitkDiffusionQuantificationView()
{
}
void QmitkDiffusionQuantificationView::CreateQtPartControl(QWidget *parent)
{
if (!m_Controls)
{
// create GUI widgets
m_Controls = new Ui::QmitkDiffusionQuantificationViewControls;
m_Controls->setupUi(parent);
this->CreateConnections();
GFACheckboxClicked();
#ifndef DIFFUSION_IMAGING_EXTENDED
m_Controls->m_StandardGFACheckbox->setVisible(false);
m_Controls->frame_3->setVisible(false);
m_Controls->m_CurvatureButton->setVisible(false);
#endif
}
}
void QmitkDiffusionQuantificationView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget)
{
m_MultiWidget = &stdMultiWidget;
}
void QmitkDiffusionQuantificationView::StdMultiWidgetNotAvailable()
{
m_MultiWidget = NULL;
}
void QmitkDiffusionQuantificationView::CreateConnections()
{
if ( m_Controls )
{
connect( (QObject*)(m_Controls->m_StandardGFACheckbox), SIGNAL(clicked()), this, SLOT(GFACheckboxClicked()) );
connect( (QObject*)(m_Controls->m_GFAButton), SIGNAL(clicked()), this, SLOT(GFA()) );
connect( (QObject*)(m_Controls->m_CurvatureButton), SIGNAL(clicked()), this, SLOT(Curvature()) );
connect( (QObject*)(m_Controls->m_FAButton), SIGNAL(clicked()), this, SLOT(FA()) );
connect( (QObject*)(m_Controls->m_RAButton), SIGNAL(clicked()), this, SLOT(RA()) );
connect( (QObject*)(m_Controls->m_ADButton), SIGNAL(clicked()), this, SLOT(AD()) );
connect( (QObject*)(m_Controls->m_RDButton), SIGNAL(clicked()), this, SLOT(RD()) );
connect( (QObject*)(m_Controls->m_MDButton), SIGNAL(clicked()), this, SLOT(MD()) );
connect( (QObject*)(m_Controls->m_ClusteringAnisotropy), SIGNAL(clicked()), this, SLOT(ClusterAnisotropy()) );
}
}
void QmitkDiffusionQuantificationView::OnSelectionChanged( std::vector<mitk::DataNode*> nodes )
{
m_QBallImages = mitk::DataStorage::SetOfObjects::New();
m_TensorImages = mitk::DataStorage::SetOfObjects::New();
bool foundQBIVolume = false;
bool foundTensorVolume = false;
mitk::DataNode::Pointer selNode = NULL;
int c=0;
for( std::vector<mitk::DataNode*>::iterator it = nodes.begin(); it != nodes.end(); ++it )
{
mitk::DataNode::Pointer node = *it;
if( node.IsNotNull() && dynamic_cast<mitk::QBallImage*>(node->GetData()) )
{
foundQBIVolume = true;
m_QBallImages->push_back(node);
selNode = node;
c++;
}
else if( node.IsNotNull() && dynamic_cast<mitk::TensorImage*>(node->GetData()) )
{
foundTensorVolume = true;
m_TensorImages->push_back(node);
selNode = node;
c++;
}
}
m_Controls->m_GFAButton->setEnabled(foundQBIVolume);
m_Controls->m_CurvatureButton->setEnabled(foundQBIVolume);
if (c>0)
{
m_Controls->m_InputData->setTitle("Input Data");
m_Controls->m_InputImageLabel->setText(selNode->GetName().c_str());
}
else
{
m_Controls->m_InputData->setTitle("Please Select Input Data");
m_Controls->m_InputImageLabel->setText("<font color='red'>mandatory</font>");
}
m_Controls->m_FAButton->setEnabled(foundTensorVolume);
m_Controls->m_RAButton->setEnabled(foundTensorVolume);
m_Controls->m_ADButton->setEnabled(foundTensorVolume);
m_Controls->m_RDButton->setEnabled(foundTensorVolume);
m_Controls->m_MDButton->setEnabled(foundTensorVolume);
m_Controls->m_ClusteringAnisotropy->setEnabled(foundTensorVolume);
}
void QmitkDiffusionQuantificationView::Activated()
{
QmitkFunctionality::Activated();
}
void QmitkDiffusionQuantificationView::Deactivated()
{
QmitkFunctionality::Deactivated();
}
void QmitkDiffusionQuantificationView::GFACheckboxClicked()
{
m_Controls->frame_2->setVisible(m_Controls->m_StandardGFACheckbox->isChecked());
}
void QmitkDiffusionQuantificationView::GFA()
{
if(m_Controls->m_StandardGFACheckbox->isChecked())
{
QBIQuantify(13);
}
else
{
QBIQuantify(0);
}
}
void QmitkDiffusionQuantificationView::Curvature()
{
QBIQuantify(12);
}
void QmitkDiffusionQuantificationView::FA()
{
TensorQuantify(0);
}
void QmitkDiffusionQuantificationView::RA()
{
TensorQuantify(1);
}
void QmitkDiffusionQuantificationView::AD()
{
TensorQuantify(2);
}
void QmitkDiffusionQuantificationView::RD()
{
TensorQuantify(3);
}
void QmitkDiffusionQuantificationView::ClusterAnisotropy()
{
TensorQuantify(4);
}
void QmitkDiffusionQuantificationView::MD()
{
TensorQuantify(5);
}
void QmitkDiffusionQuantificationView::QBIQuantify(int method)
{
QBIQuantification(m_QBallImages, method);
}
void QmitkDiffusionQuantificationView::TensorQuantify(int method)
{
TensorQuantification(m_TensorImages, method);
}
void QmitkDiffusionQuantificationView::QBIQuantification(
mitk::DataStorage::SetOfObjects::Pointer inImages, int method)
{
itk::TimeProbe clock;
QString status;
int nrFiles = inImages->size();
if (!nrFiles) return;
mitk::DataStorage::SetOfObjects::const_iterator itemiter( inImages->begin() );
mitk::DataStorage::SetOfObjects::const_iterator itemiterend( inImages->end() );
std::vector<mitk::DataNode::Pointer> nodes;
while ( itemiter != itemiterend ) // for all items
{
typedef float TOdfPixelType;
const int odfsize = QBALL_ODFSIZE;
typedef itk::Vector<TOdfPixelType,odfsize> OdfVectorType;
typedef itk::Image<OdfVectorType,3> OdfVectorImgType;
mitk::Image* vol =
static_cast<mitk::Image*>((*itemiter)->GetData());
OdfVectorImgType::Pointer itkvol = OdfVectorImgType::New();
mitk::CastToItkImage(vol, itkvol);
std::string nodename;
(*itemiter)->GetStringProperty("name", nodename);
++itemiter;
float p1 = m_Controls->m_ParamKEdit->text().toFloat();
float p2 = m_Controls->m_ParamPEdit->text().toFloat();
// COMPUTE RA
clock.Start();
MBI_INFO << "Computing GFA ";
mitk::StatusBar::GetInstance()->DisplayText(status.sprintf(
- "Computing GFA for %s", nodename.c_str()).toAscii());
+ "Computing GFA for %s", nodename.c_str()).toLatin1());
typedef OdfVectorType::ValueType RealValueType;
typedef itk::Image< RealValueType, 3 > RAImageType;
typedef itk::DiffusionQballGeneralizedFaImageFilter<TOdfPixelType,TOdfPixelType,odfsize>
GfaFilterType;
GfaFilterType::Pointer gfaFilter = GfaFilterType::New();
gfaFilter->SetInput(itkvol);
std::string newname;
newname.append(nodename);
switch(method)
{
case 0:
{
gfaFilter->SetComputationMethod(GfaFilterType::GFA_STANDARD);
newname.append("GFA");
break;
}
case 1:
{
gfaFilter->SetComputationMethod(GfaFilterType::GFA_QUANTILES_HIGH_LOW);
newname.append("01");
break;
}
case 2:
{
gfaFilter->SetComputationMethod(GfaFilterType::GFA_QUANTILE_HIGH);
newname.append("02");
break;
}
case 3:
{
gfaFilter->SetComputationMethod(GfaFilterType::GFA_MAX_ODF_VALUE);
newname.append("03");
break;
}
case 4:
{
gfaFilter->SetComputationMethod(GfaFilterType::GFA_DECONVOLUTION_COEFFS);
newname.append("04");
break;
}
case 5:
{
gfaFilter->SetComputationMethod(GfaFilterType::GFA_MIN_MAX_NORMALIZED_STANDARD);
newname.append("05");
break;
}
case 6:
{
gfaFilter->SetComputationMethod(GfaFilterType::GFA_NORMALIZED_ENTROPY);
newname.append("06");
break;
}
case 7:
{
gfaFilter->SetComputationMethod(GfaFilterType::GFA_NEMATIC_ORDER_PARAMETER);
newname.append("07");
break;
}
case 8:
{
gfaFilter->SetComputationMethod(GfaFilterType::GFA_QUANTILES_LOW_HIGH);
newname.append("08");
break;
}
case 9:
{
gfaFilter->SetComputationMethod(GfaFilterType::GFA_QUANTILE_LOW);
newname.append("09");
break;
}
case 10:
{
gfaFilter->SetComputationMethod(GfaFilterType::GFA_MIN_ODF_VALUE);
newname.append("10");
break;
}
case 11:
{
gfaFilter->SetComputationMethod(GfaFilterType::GFA_STD_BY_MAX);
newname.append("11");
break;
}
case 12:
{
p1 = m_Controls->MinAngle->text().toFloat();
p2 = m_Controls->MaxAngle->text().toFloat();
gfaFilter->SetComputationMethod(GfaFilterType::GFA_PRINCIPLE_CURVATURE);
QString paramString;
paramString = paramString.append("PC%1-%2").arg(p1).arg(p2);
- newname.append(paramString.toAscii());
+ newname.append(paramString.toLatin1());
gfaFilter->SetParam1(p1);
gfaFilter->SetParam2(p2);
break;
}
case 13:
{
gfaFilter->SetComputationMethod(GfaFilterType::GFA_GENERALIZED_GFA);
QString paramString;
paramString = paramString.append("GFAK%1P%2").arg(p1).arg(p2);
- newname.append(paramString.toAscii());
+ newname.append(paramString.toLatin1());
gfaFilter->SetParam1(p1);
gfaFilter->SetParam2(p2);
break;
}
default:
{
newname.append("0");
gfaFilter->SetComputationMethod(GfaFilterType::GFA_STANDARD);
}
}
gfaFilter->Update();
clock.Stop();
typedef itk::Image<TOdfPixelType, 3> ImgType;
ImgType::Pointer img = ImgType::New();
img->SetSpacing( gfaFilter->GetOutput()->GetSpacing() ); // Set the image spacing
img->SetOrigin( gfaFilter->GetOutput()->GetOrigin() ); // Set the image origin
img->SetDirection( gfaFilter->GetOutput()->GetDirection() ); // Set the image direction
img->SetLargestPossibleRegion( gfaFilter->GetOutput()->GetLargestPossibleRegion());
img->SetBufferedRegion( gfaFilter->GetOutput()->GetLargestPossibleRegion() );
img->Allocate();
itk::ImageRegionIterator<ImgType> ot (img, img->GetLargestPossibleRegion() );
ot.GoToBegin();
itk::ImageRegionConstIterator<GfaFilterType::OutputImageType> it
(gfaFilter->GetOutput(), gfaFilter->GetOutput()->GetLargestPossibleRegion() );
for (it.GoToBegin(); !it.IsAtEnd(); ++it)
{
GfaFilterType::OutputImageType::PixelType val = it.Get();
ot.Set(val * m_Controls->m_ScaleImageValuesBox->value());
++ot;
}
// GFA TO DATATREE
mitk::Image::Pointer image = mitk::Image::New();
image->InitializeByItk( img.GetPointer() );
image->SetVolume( img->GetBufferPointer() );
mitk::DataNode::Pointer node=mitk::DataNode::New();
node->SetData( image );
node->SetProperty( "name", mitk::StringProperty::New(newname) );
nodes.push_back(node);
mitk::StatusBar::GetInstance()->DisplayText("Computation complete.");
}
std::vector<mitk::DataNode::Pointer>::iterator nodeIt;
for(nodeIt = nodes.begin(); nodeIt != nodes.end(); ++nodeIt)
GetDefaultDataStorage()->Add(*nodeIt);
m_MultiWidget->RequestUpdate();
}
void QmitkDiffusionQuantificationView::TensorQuantification(
mitk::DataStorage::SetOfObjects::Pointer inImages, int method)
{
itk::TimeProbe clock;
QString status;
int nrFiles = inImages->size();
if (!nrFiles) return;
mitk::DataStorage::SetOfObjects::const_iterator itemiter( inImages->begin() );
mitk::DataStorage::SetOfObjects::const_iterator itemiterend( inImages->end() );
std::vector<mitk::DataNode::Pointer> nodes;
while ( itemiter != itemiterend ) // for all items
{
typedef float TTensorPixelType;
typedef itk::DiffusionTensor3D< TTensorPixelType > TensorPixelType;
typedef itk::Image< TensorPixelType, 3 > TensorImageType;
mitk::Image* vol =
static_cast<mitk::Image*>((*itemiter)->GetData());
TensorImageType::Pointer itkvol = TensorImageType::New();
mitk::CastToItkImage(vol, itkvol);
std::string nodename;
(*itemiter)->GetStringProperty("name", nodename);
++itemiter;
// COMPUTE FA
clock.Start();
MBI_INFO << "Computing FA ";
mitk::StatusBar::GetInstance()->DisplayText(status.sprintf(
- "Computing FA for %s", nodename.c_str()).toAscii());
+ "Computing FA for %s", nodename.c_str()).toLatin1());
typedef itk::Image< TTensorPixelType, 3 > FAImageType;
typedef itk::ShiftScaleImageFilter<FAImageType, FAImageType>
ShiftScaleFilterType;
ShiftScaleFilterType::Pointer multi =
ShiftScaleFilterType::New();
multi->SetShift(0.0);
multi->SetScale(m_Controls->m_ScaleImageValuesBox->value());//itk::NumericTraits<RealValueType>::max()
typedef itk::TensorDerivedMeasurementsFilter<TTensorPixelType> MeasurementsType;
if(method == 0) //FA
{
/* typedef itk::TensorFractionalAnisotropyImageFilter<
TensorImageType, FAImageType > FilterType;
FilterType::Pointer anisotropyFilter = FilterType::New();
anisotropyFilter->SetInput( itkvol.GetPointer() );
anisotropyFilter->Update();
multi->SetInput(anisotropyFilter->GetOutput());
nodename = QString(nodename.c_str()).append("_FA").toStdString();*/
MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New();
measurementsCalculator->SetInput(itkvol.GetPointer() );
measurementsCalculator->SetMeasure(MeasurementsType::FA);
measurementsCalculator->Update();
multi->SetInput(measurementsCalculator->GetOutput());
nodename = QString(nodename.c_str()).append("_FA").toStdString();
}
else if(method == 1) //RA
{
/*typedef itk::TensorRelativeAnisotropyImageFilter<
TensorImageType, FAImageType > FilterType;
FilterType::Pointer anisotropyFilter = FilterType::New();
anisotropyFilter->SetInput( itkvol.GetPointer() );
anisotropyFilter->Update();
multi->SetInput(anisotropyFilter->GetOutput());
nodename = QString(nodename.c_str()).append("_RA").toStdString();*/
MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New();
measurementsCalculator->SetInput(itkvol.GetPointer() );
measurementsCalculator->SetMeasure(MeasurementsType::RA);
measurementsCalculator->Update();
multi->SetInput(measurementsCalculator->GetOutput());
nodename = QString(nodename.c_str()).append("_RA").toStdString();
}
else if(method == 2) // AD (Axial diffusivity)
{
MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New();
measurementsCalculator->SetInput(itkvol.GetPointer() );
measurementsCalculator->SetMeasure(MeasurementsType::AD);
measurementsCalculator->Update();
multi->SetInput(measurementsCalculator->GetOutput());
nodename = QString(nodename.c_str()).append("_AD").toStdString();
}
else if(method == 3) // RD (Radial diffusivity, (Lambda2+Lambda3)/2
{
MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New();
measurementsCalculator->SetInput(itkvol.GetPointer() );
measurementsCalculator->SetMeasure(MeasurementsType::RD);
measurementsCalculator->Update();
multi->SetInput(measurementsCalculator->GetOutput());
nodename = QString(nodename.c_str()).append("_RD").toStdString();
}
else if(method == 4) // 1-(Lambda2+Lambda3)/(2*Lambda1)
{
MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New();
measurementsCalculator->SetInput(itkvol.GetPointer() );
measurementsCalculator->SetMeasure(MeasurementsType::CA);
measurementsCalculator->Update();
multi->SetInput(measurementsCalculator->GetOutput());
nodename = QString(nodename.c_str()).append("_CA").toStdString();
}
else if(method == 5) // MD (Mean Diffusivity, (Lambda1+Lambda2+Lambda3)/3 )
{
MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New();
measurementsCalculator->SetInput(itkvol.GetPointer() );
measurementsCalculator->SetMeasure(MeasurementsType::MD);
measurementsCalculator->Update();
multi->SetInput(measurementsCalculator->GetOutput());
nodename = QString(nodename.c_str()).append("_MD").toStdString();
}
multi->Update();
clock.Stop();
// FA TO DATATREE
mitk::Image::Pointer image = mitk::Image::New();
image->InitializeByItk( multi->GetOutput() );
image->SetVolume( multi->GetOutput()->GetBufferPointer() );
mitk::DataNode::Pointer node=mitk::DataNode::New();
node->SetData( image );
node->SetProperty( "name", mitk::StringProperty::New(nodename) );
nodes.push_back(node);
mitk::StatusBar::GetInstance()->DisplayText("Computation complete.");
}
std::vector<mitk::DataNode::Pointer>::iterator nodeIt;
for(nodeIt = nodes.begin(); nodeIt != nodes.end(); ++nodeIt)
GetDefaultDataStorage()->Add(*nodeIt);
m_MultiWidget->RequestUpdate();
}
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberExtractionView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberExtractionView.cpp
index 8c6e62d33f..b112c5139d 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberExtractionView.cpp
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberExtractionView.cpp
@@ -1,1218 +1,1218 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
// Blueberry
#include <berryISelectionService.h>
#include <berryIWorkbenchWindow.h>
// Qmitk
#include "QmitkFiberExtractionView.h"
#include <QmitkStdMultiWidget.h>
// Qt
#include <QMessageBox>
// MITK
#include <mitkNodePredicateProperty.h>
#include <mitkImageCast.h>
#include <mitkPointSet.h>
#include <mitkPlanarCircle.h>
#include <mitkPlanarPolygon.h>
#include <mitkPlanarRectangle.h>
#include <mitkPlanarFigureInteractor.h>
#include <mitkGlobalInteraction.h>
#include <mitkImageAccessByItk.h>
#include <mitkDataNodeObject.h>
#include <mitkDiffusionImage.h>
#include <mitkTensorImage.h>
#include "usModuleRegistry.h"
// ITK
#include <itkResampleImageFilter.h>
#include <itkGaussianInterpolateImageFunction.h>
#include <itkImageRegionIteratorWithIndex.h>
#include <itkTractsToFiberEndingsImageFilter.h>
#include <itkTractDensityImageFilter.h>
#include <itkImageRegion.h>
#include <itkTractsToRgbaImageFilter.h>
#include <math.h>
const std::string QmitkFiberExtractionView::VIEW_ID = "org.mitk.views.fiberextraction";
const std::string id_DataManager = "org.mitk.views.datamanager";
using namespace mitk;
QmitkFiberExtractionView::QmitkFiberExtractionView()
: QmitkFunctionality()
, m_Controls( 0 )
, m_MultiWidget( NULL )
, m_CircleCounter(0)
, m_PolygonCounter(0)
, m_UpsamplingFactor(1)
{
}
// Destructor
QmitkFiberExtractionView::~QmitkFiberExtractionView()
{
}
void QmitkFiberExtractionView::CreateQtPartControl( QWidget *parent )
{
// build up qt view, unless already done
if ( !m_Controls )
{
// create GUI widgets from the Qt Designer's .ui file
m_Controls = new Ui::QmitkFiberExtractionViewControls;
m_Controls->setupUi( parent );
m_Controls->doExtractFibersButton->setDisabled(true);
m_Controls->PFCompoANDButton->setDisabled(true);
m_Controls->PFCompoORButton->setDisabled(true);
m_Controls->PFCompoNOTButton->setDisabled(true);
m_Controls->m_PlanarFigureButtonsFrame->setEnabled(false);
m_Controls->m_RectangleButton->setVisible(false);
connect( m_Controls->m_CircleButton, SIGNAL( clicked() ), this, SLOT( OnDrawCircle() ) );
connect( m_Controls->m_PolygonButton, SIGNAL( clicked() ), this, SLOT( OnDrawPolygon() ) );
connect(m_Controls->PFCompoANDButton, SIGNAL(clicked()), this, SLOT(GenerateAndComposite()) );
connect(m_Controls->PFCompoORButton, SIGNAL(clicked()), this, SLOT(GenerateOrComposite()) );
connect(m_Controls->PFCompoNOTButton, SIGNAL(clicked()), this, SLOT(GenerateNotComposite()) );
connect(m_Controls->m_JoinBundles, SIGNAL(clicked()), this, SLOT(JoinBundles()) );
connect(m_Controls->m_SubstractBundles, SIGNAL(clicked()), this, SLOT(SubstractBundles()) );
connect(m_Controls->m_GenerateRoiImage, SIGNAL(clicked()), this, SLOT(GenerateRoiImage()) );
connect(m_Controls->m_Extract3dButton_2, SIGNAL(clicked()), this, SLOT(ExtractNotPassingMask()));
connect(m_Controls->m_Extract3dButton, SIGNAL(clicked()), this, SLOT(ExtractPassingMask()));
connect( m_Controls->m_ExtractMask, SIGNAL(clicked()), this, SLOT(ExtractEndingInMask()) );
connect( m_Controls->doExtractFibersButton, SIGNAL(clicked()), this, SLOT(DoFiberExtraction()) );
connect( m_Controls->m_RemoveOutsideMaskButton, SIGNAL(clicked()), this, SLOT(DoRemoveOutsideMask()));
connect( m_Controls->m_RemoveInsideMaskButton, SIGNAL(clicked()), this, SLOT(DoRemoveInsideMask()));
}
}
void QmitkFiberExtractionView::DoRemoveInsideMask()
{
if (m_MaskImageNode.IsNull())
return;
mitk::Image::Pointer mitkMask = dynamic_cast<mitk::Image*>(m_MaskImageNode->GetData());
for (unsigned int i=0; i<m_SelectedFB.size(); i++)
{
mitk::FiberBundleX::Pointer fib = dynamic_cast<mitk::FiberBundleX*>(m_SelectedFB.at(i)->GetData());
QString name(m_SelectedFB.at(i)->GetName().c_str());
itkUCharImageType::Pointer mask = itkUCharImageType::New();
mitk::CastToItkImage(mitkMask, mask);
mitk::FiberBundleX::Pointer newFib = fib->RemoveFibersOutside(mask, true);
if (newFib->GetNumFibers()<=0)
{
QMessageBox::information(NULL, "No output generated:", "The resulting fiber bundle contains no fibers.");
continue;
}
DataNode::Pointer newNode = DataNode::New();
newNode->SetData(newFib);
name += "_Cut";
newNode->SetName(name.toStdString());
GetDefaultDataStorage()->Add(newNode);
m_SelectedFB.at(i)->SetVisibility(false);
}
}
void QmitkFiberExtractionView::DoRemoveOutsideMask()
{
if (m_MaskImageNode.IsNull())
return;
mitk::Image::Pointer mitkMask = dynamic_cast<mitk::Image*>(m_MaskImageNode->GetData());
for (unsigned int i=0; i<m_SelectedFB.size(); i++)
{
mitk::FiberBundleX::Pointer fib = dynamic_cast<mitk::FiberBundleX*>(m_SelectedFB.at(i)->GetData());
QString name(m_SelectedFB.at(i)->GetName().c_str());
itkUCharImageType::Pointer mask = itkUCharImageType::New();
mitk::CastToItkImage(mitkMask, mask);
mitk::FiberBundleX::Pointer newFib = fib->RemoveFibersOutside(mask);
if (newFib->GetNumFibers()<=0)
{
QMessageBox::information(NULL, "No output generated:", "The resulting fiber bundle contains no fibers.");
continue;
}
DataNode::Pointer newNode = DataNode::New();
newNode->SetData(newFib);
name += "_Cut";
newNode->SetName(name.toStdString());
GetDefaultDataStorage()->Add(newNode);
m_SelectedFB.at(i)->SetVisibility(false);
}
}
void QmitkFiberExtractionView::ExtractEndingInMask()
{
if (m_MaskImageNode.IsNull())
return;
mitk::Image::Pointer mitkMask = dynamic_cast<mitk::Image*>(m_MaskImageNode->GetData());
for (unsigned int i=0; i<m_SelectedFB.size(); i++)
{
mitk::FiberBundleX::Pointer fib = dynamic_cast<mitk::FiberBundleX*>(m_SelectedFB.at(i)->GetData());
QString name(m_SelectedFB.at(i)->GetName().c_str());
itkUCharImageType::Pointer mask = itkUCharImageType::New();
mitk::CastToItkImage(mitkMask, mask);
mitk::FiberBundleX::Pointer newFib = fib->ExtractFiberSubset(mask, false);
if (newFib->GetNumFibers()<=0)
{
QMessageBox::information(NULL, "No output generated:", "The resulting fiber bundle contains no fibers.");
continue;
}
DataNode::Pointer newNode = DataNode::New();
newNode->SetData(newFib);
name += "_ending-in-mask";
newNode->SetName(name.toStdString());
GetDefaultDataStorage()->Add(newNode);
m_SelectedFB.at(i)->SetVisibility(false);
}
}
void QmitkFiberExtractionView::ExtractNotPassingMask()
{
if (m_MaskImageNode.IsNull())
return;
mitk::Image::Pointer mitkMask = dynamic_cast<mitk::Image*>(m_MaskImageNode->GetData());
for (unsigned int i=0; i<m_SelectedFB.size(); i++)
{
mitk::FiberBundleX::Pointer fib = dynamic_cast<mitk::FiberBundleX*>(m_SelectedFB.at(i)->GetData());
QString name(m_SelectedFB.at(i)->GetName().c_str());
itkUCharImageType::Pointer mask = itkUCharImageType::New();
mitk::CastToItkImage<itkUCharImageType>(mitkMask, mask);
mitk::FiberBundleX::Pointer newFib = fib->ExtractFiberSubset(mask, true, true);
if (newFib->GetNumFibers()<=0)
{
QMessageBox::information(NULL, "No output generated:", "The resulting fiber bundle contains no fibers.");
continue;
}
DataNode::Pointer newNode = DataNode::New();
newNode->SetData(newFib);
name += "_not-passing-mask";
newNode->SetName(name.toStdString());
GetDefaultDataStorage()->Add(newNode);
m_SelectedFB.at(i)->SetVisibility(false);
}
}
void QmitkFiberExtractionView::ExtractPassingMask()
{
if (m_MaskImageNode.IsNull())
return;
mitk::Image::Pointer mitkMask = dynamic_cast<mitk::Image*>(m_MaskImageNode->GetData());
for (unsigned int i=0; i<m_SelectedFB.size(); i++)
{
mitk::FiberBundleX::Pointer fib = dynamic_cast<mitk::FiberBundleX*>(m_SelectedFB.at(i)->GetData());
QString name(m_SelectedFB.at(i)->GetName().c_str());
itkUCharImageType::Pointer mask = itkUCharImageType::New();
mitk::CastToItkImage(mitkMask, mask);
mitk::FiberBundleX::Pointer newFib = fib->ExtractFiberSubset(mask, true);
if (newFib->GetNumFibers()<=0)
{
QMessageBox::information(NULL, "No output generated:", "The resulting fiber bundle contains no fibers.");
continue;
}
DataNode::Pointer newNode = DataNode::New();
newNode->SetData(newFib);
name += "_passing-mask";
newNode->SetName(name.toStdString());
GetDefaultDataStorage()->Add(newNode);
m_SelectedFB.at(i)->SetVisibility(false);
}
}
void QmitkFiberExtractionView::GenerateRoiImage()
{
if (m_SelectedPF.empty())
return;
mitk::BaseGeometry::Pointer geometry;
if (!m_SelectedFB.empty())
{
mitk::FiberBundleX::Pointer fib = dynamic_cast<mitk::FiberBundleX*>(m_SelectedFB.front()->GetData());
geometry = fib->GetGeometry();
}
else if (m_SelectedImage)
geometry = m_SelectedImage->GetGeometry();
else
return;
itk::Vector<double,3> spacing = geometry->GetSpacing();
spacing /= m_UpsamplingFactor;
mitk::Point3D newOrigin = geometry->GetOrigin();
mitk::Geometry3D::BoundsArrayType bounds = geometry->GetBounds();
newOrigin[0] += bounds.GetElement(0);
newOrigin[1] += bounds.GetElement(2);
newOrigin[2] += bounds.GetElement(4);
itk::Matrix<double, 3, 3> direction;
itk::ImageRegion<3> imageRegion;
for (int i=0; i<3; i++)
for (int j=0; j<3; j++)
direction[j][i] = geometry->GetMatrixColumn(i)[j]/spacing[j];
imageRegion.SetSize(0, geometry->GetExtent(0)*m_UpsamplingFactor);
imageRegion.SetSize(1, geometry->GetExtent(1)*m_UpsamplingFactor);
imageRegion.SetSize(2, geometry->GetExtent(2)*m_UpsamplingFactor);
m_PlanarFigureImage = itkUCharImageType::New();
m_PlanarFigureImage->SetSpacing( spacing ); // Set the image spacing
m_PlanarFigureImage->SetOrigin( newOrigin ); // Set the image origin
m_PlanarFigureImage->SetDirection( direction ); // Set the image direction
m_PlanarFigureImage->SetRegions( imageRegion );
m_PlanarFigureImage->Allocate();
m_PlanarFigureImage->FillBuffer( 0 );
Image::Pointer tmpImage = Image::New();
tmpImage->InitializeByItk(m_PlanarFigureImage.GetPointer());
tmpImage->SetVolume(m_PlanarFigureImage->GetBufferPointer());
std::string name = m_SelectedPF.at(0)->GetName();
WritePfToImage(m_SelectedPF.at(0), tmpImage);
for (unsigned int i=1; i<m_SelectedPF.size(); i++)
{
name += "+";
name += m_SelectedPF.at(i)->GetName();
WritePfToImage(m_SelectedPF.at(i), tmpImage);
}
DataNode::Pointer node = DataNode::New();
tmpImage = Image::New();
tmpImage->InitializeByItk(m_PlanarFigureImage.GetPointer());
tmpImage->SetVolume(m_PlanarFigureImage->GetBufferPointer());
node->SetData(tmpImage);
node->SetName(name);
this->GetDefaultDataStorage()->Add(node);
}
void QmitkFiberExtractionView::WritePfToImage(mitk::DataNode::Pointer node, mitk::Image* image)
{
if (dynamic_cast<mitk::PlanarFigure*>(node->GetData()))
{
m_PlanarFigure = dynamic_cast<mitk::PlanarFigure*>(node->GetData());
AccessFixedDimensionByItk_2(
image,
InternalReorientImagePlane, 3,
m_PlanarFigure->GetGeometry(), -1);
AccessFixedDimensionByItk_2(
m_InternalImage,
InternalCalculateMaskFromPlanarFigure,
3, 2, node->GetName() );
}
else if (dynamic_cast<mitk::PlanarFigureComposite*>(node->GetData()))
{
mitk::PlanarFigureComposite* pfc = dynamic_cast<mitk::PlanarFigureComposite*>(node->GetData());
for (int j=0; j<pfc->getNumberOfChildren(); j++)
{
WritePfToImage(pfc->getDataNodeAt(j), image);
}
}
}
template < typename TPixel, unsigned int VImageDimension >
void QmitkFiberExtractionView::InternalReorientImagePlane( const itk::Image< TPixel, VImageDimension > *image, mitk::BaseGeometry* planegeo3D, int additionalIndex )
{
typedef itk::Image< TPixel, VImageDimension > ImageType;
typedef itk::Image< float, VImageDimension > FloatImageType;
typedef itk::ResampleImageFilter<ImageType, FloatImageType, double> ResamplerType;
typename ResamplerType::Pointer resampler = ResamplerType::New();
mitk::PlaneGeometry* planegeo = dynamic_cast<mitk::PlaneGeometry*>(planegeo3D);
float upsamp = m_UpsamplingFactor;
float gausssigma = 0.5;
// Spacing
typename ResamplerType::SpacingType spacing = planegeo->GetSpacing();
spacing[0] = image->GetSpacing()[0] / upsamp;
spacing[1] = image->GetSpacing()[1] / upsamp;
spacing[2] = image->GetSpacing()[2];
resampler->SetOutputSpacing( spacing );
// Size
typename ResamplerType::SizeType size;
size[0] = planegeo->GetExtentInMM(0) / spacing[0];
size[1] = planegeo->GetExtentInMM(1) / spacing[1];
size[2] = 1;
resampler->SetSize( size );
// Origin
typename mitk::Point3D orig = planegeo->GetOrigin();
typename mitk::Point3D corrorig;
planegeo3D->WorldToIndex(orig,corrorig);
corrorig[0] += 0.5/upsamp;
corrorig[1] += 0.5/upsamp;
corrorig[2] += 0;
planegeo3D->IndexToWorld(corrorig,corrorig);
resampler->SetOutputOrigin(corrorig );
// Direction
typename ResamplerType::DirectionType direction;
typename mitk::AffineTransform3D::MatrixType matrix = planegeo->GetIndexToWorldTransform()->GetMatrix();
for(int c=0; c<matrix.ColumnDimensions; c++)
{
double sum = 0;
for(int r=0; r<matrix.RowDimensions; r++)
sum += matrix(r,c)*matrix(r,c);
for(int r=0; r<matrix.RowDimensions; r++)
direction(r,c) = matrix(r,c)/sqrt(sum);
}
resampler->SetOutputDirection( direction );
// Gaussian interpolation
if(gausssigma != 0)
{
double sigma[3];
for( unsigned int d = 0; d < 3; d++ )
sigma[d] = gausssigma * image->GetSpacing()[d];
double alpha = 2.0;
typedef itk::GaussianInterpolateImageFunction<ImageType, double> GaussianInterpolatorType;
typename GaussianInterpolatorType::Pointer interpolator = GaussianInterpolatorType::New();
interpolator->SetInputImage( image );
interpolator->SetParameters( sigma, alpha );
resampler->SetInterpolator( interpolator );
}
else
{
typedef typename itk::LinearInterpolateImageFunction<ImageType, double> InterpolatorType;
typename InterpolatorType::Pointer interpolator = InterpolatorType::New();
interpolator->SetInputImage( image );
resampler->SetInterpolator( interpolator );
}
resampler->SetInput( image );
resampler->SetDefaultPixelValue(0);
resampler->Update();
if(additionalIndex < 0)
{
this->m_InternalImage = mitk::Image::New();
this->m_InternalImage->InitializeByItk( resampler->GetOutput() );
this->m_InternalImage->SetVolume( resampler->GetOutput()->GetBufferPointer() );
}
}
template < typename TPixel, unsigned int VImageDimension >
void QmitkFiberExtractionView::InternalCalculateMaskFromPlanarFigure( itk::Image< TPixel, VImageDimension > *image, unsigned int axis, std::string )
{
typedef itk::Image< TPixel, VImageDimension > ImageType;
typedef itk::CastImageFilter< ImageType, itkUCharImageType > CastFilterType;
// Generate mask image as new image with same header as input image and
// initialize with "1".
itkUCharImageType::Pointer newMaskImage = itkUCharImageType::New();
newMaskImage->SetSpacing( image->GetSpacing() ); // Set the image spacing
newMaskImage->SetOrigin( image->GetOrigin() ); // Set the image origin
newMaskImage->SetDirection( image->GetDirection() ); // Set the image direction
newMaskImage->SetRegions( image->GetLargestPossibleRegion() );
newMaskImage->Allocate();
newMaskImage->FillBuffer( 1 );
// Generate VTK polygon from (closed) PlanarFigure polyline
// (The polyline points are shifted by -0.5 in z-direction to make sure
// that the extrusion filter, which afterwards elevates all points by +0.5
// in z-direction, creates a 3D object which is cut by the the plane z=0)
- const Geometry2D *planarFigureGeometry2D = m_PlanarFigure->GetGeometry2D();
+ const PlaneGeometry *planarFigurePlaneGeometry = m_PlanarFigure->GetPlaneGeometry();
const PlanarFigure::PolyLineType planarFigurePolyline = m_PlanarFigure->GetPolyLine( 0 );
const BaseGeometry *imageGeometry3D = m_InternalImage->GetGeometry( 0 );
vtkPolyData *polyline = vtkPolyData::New();
polyline->Allocate( 1, 1 );
// Determine x- and y-dimensions depending on principal axis
int i0, i1;
switch ( axis )
{
case 0:
i0 = 1;
i1 = 2;
break;
case 1:
i0 = 0;
i1 = 2;
break;
case 2:
default:
i0 = 0;
i1 = 1;
break;
}
// Create VTK polydata object of polyline contour
vtkPoints *points = vtkPoints::New();
PlanarFigure::PolyLineType::const_iterator it;
unsigned int numberOfPoints = 0;
for ( it = planarFigurePolyline.begin(); it != planarFigurePolyline.end(); ++it )
{
Point3D point3D;
// Convert 2D point back to the local index coordinates of the selected image
- Point2D point2D = it->Point;
- planarFigureGeometry2D->WorldToIndex(point2D, point2D);
+ Point2D point2D = *it;
+ planarFigurePlaneGeometry->WorldToIndex(point2D, point2D);
point2D[0] -= 0.5/m_UpsamplingFactor;
point2D[1] -= 0.5/m_UpsamplingFactor;
- planarFigureGeometry2D->IndexToWorld(point2D, point2D);
- planarFigureGeometry2D->Map( point2D, point3D );
+ planarFigurePlaneGeometry->IndexToWorld(point2D, point2D);
+ planarFigurePlaneGeometry->Map( point2D, point3D );
// Polygons (partially) outside of the image bounds can not be processed further due to a bug in vtkPolyDataToImageStencil
if ( !imageGeometry3D->IsInside( point3D ) )
{
float bounds[2] = {0,0};
bounds[0] =
this->m_InternalImage->GetLargestPossibleRegion().GetSize().GetElement(i0);
bounds[1] =
this->m_InternalImage->GetLargestPossibleRegion().GetSize().GetElement(i1);
imageGeometry3D->WorldToIndex( point3D, point3D );
if (point3D[i0]<0)
point3D[i0] = 0.0;
else if (point3D[i0]>bounds[0])
point3D[i0] = bounds[0]-0.001;
if (point3D[i1]<0)
point3D[i1] = 0.0;
else if (point3D[i1]>bounds[1])
point3D[i1] = bounds[1]-0.001;
points->InsertNextPoint( point3D[i0], point3D[i1], -0.5 );
numberOfPoints++;
}
else
{
imageGeometry3D->WorldToIndex( point3D, point3D );
// Add point to polyline array
points->InsertNextPoint( point3D[i0], point3D[i1], -0.5 );
numberOfPoints++;
}
}
polyline->SetPoints( points );
points->Delete();
vtkIdType *ptIds = new vtkIdType[numberOfPoints];
for ( vtkIdType i = 0; i < numberOfPoints; ++i )
ptIds[i] = i;
polyline->InsertNextCell( VTK_POLY_LINE, numberOfPoints, ptIds );
// Extrude the generated contour polygon
vtkLinearExtrusionFilter *extrudeFilter = vtkLinearExtrusionFilter::New();
extrudeFilter->SetInputData( polyline );
extrudeFilter->SetScaleFactor( 1 );
extrudeFilter->SetExtrusionTypeToNormalExtrusion();
extrudeFilter->SetVector( 0.0, 0.0, 1.0 );
// Make a stencil from the extruded polygon
vtkPolyDataToImageStencil *polyDataToImageStencil = vtkPolyDataToImageStencil::New();
polyDataToImageStencil->SetInputConnection( extrudeFilter->GetOutputPort() );
// Export from ITK to VTK (to use a VTK filter)
typedef itk::VTKImageImport< itkUCharImageType > ImageImportType;
typedef itk::VTKImageExport< itkUCharImageType > ImageExportType;
typename ImageExportType::Pointer itkExporter = ImageExportType::New();
itkExporter->SetInput( newMaskImage );
vtkImageImport *vtkImporter = vtkImageImport::New();
this->ConnectPipelines( itkExporter, vtkImporter );
vtkImporter->Update();
// Apply the generated image stencil to the input image
vtkImageStencil *imageStencilFilter = vtkImageStencil::New();
imageStencilFilter->SetInputConnection( vtkImporter->GetOutputPort() );
imageStencilFilter->SetStencilConnection(polyDataToImageStencil->GetOutputPort() );
imageStencilFilter->ReverseStencilOff();
imageStencilFilter->SetBackgroundValue( 0 );
imageStencilFilter->Update();
// Export from VTK back to ITK
vtkImageExport *vtkExporter = vtkImageExport::New();
vtkExporter->SetInputConnection( imageStencilFilter->GetOutputPort() );
vtkExporter->Update();
typename ImageImportType::Pointer itkImporter = ImageImportType::New();
this->ConnectPipelines( vtkExporter, itkImporter );
itkImporter->Update();
// calculate cropping bounding box
m_InternalImageMask3D = itkImporter->GetOutput();
m_InternalImageMask3D->SetDirection(image->GetDirection());
itk::ImageRegionConstIterator<itkUCharImageType>
itmask(m_InternalImageMask3D, m_InternalImageMask3D->GetLargestPossibleRegion());
itk::ImageRegionIterator<ImageType>
itimage(image, image->GetLargestPossibleRegion());
itmask.GoToBegin();
itimage.GoToBegin();
typename ImageType::SizeType lowersize = {{9999999999,9999999999,9999999999}};
typename ImageType::SizeType uppersize = {{0,0,0}};
while( !itmask.IsAtEnd() )
{
if(itmask.Get() == 0)
itimage.Set(0);
else
{
typename ImageType::IndexType index = itimage.GetIndex();
typename ImageType::SizeType signedindex;
signedindex[0] = index[0];
signedindex[1] = index[1];
signedindex[2] = index[2];
lowersize[0] = signedindex[0] < lowersize[0] ? signedindex[0] : lowersize[0];
lowersize[1] = signedindex[1] < lowersize[1] ? signedindex[1] : lowersize[1];
lowersize[2] = signedindex[2] < lowersize[2] ? signedindex[2] : lowersize[2];
uppersize[0] = signedindex[0] > uppersize[0] ? signedindex[0] : uppersize[0];
uppersize[1] = signedindex[1] > uppersize[1] ? signedindex[1] : uppersize[1];
uppersize[2] = signedindex[2] > uppersize[2] ? signedindex[2] : uppersize[2];
}
++itmask;
++itimage;
}
typename ImageType::IndexType index;
index[0] = lowersize[0];
index[1] = lowersize[1];
index[2] = lowersize[2];
typename ImageType::SizeType size;
size[0] = uppersize[0] - lowersize[0] + 1;
size[1] = uppersize[1] - lowersize[1] + 1;
size[2] = uppersize[2] - lowersize[2] + 1;
itk::ImageRegion<3> cropRegion = itk::ImageRegion<3>(index, size);
// crop internal mask
typedef itk::RegionOfInterestImageFilter< itkUCharImageType, itkUCharImageType > ROIMaskFilterType;
typename ROIMaskFilterType::Pointer roi2 = ROIMaskFilterType::New();
roi2->SetRegionOfInterest(cropRegion);
roi2->SetInput(m_InternalImageMask3D);
roi2->Update();
m_InternalImageMask3D = roi2->GetOutput();
Image::Pointer tmpImage = Image::New();
tmpImage->InitializeByItk(m_InternalImageMask3D.GetPointer());
tmpImage->SetVolume(m_InternalImageMask3D->GetBufferPointer());
Image::Pointer tmpImage2 = Image::New();
tmpImage2->InitializeByItk(m_PlanarFigureImage.GetPointer());
const BaseGeometry *pfImageGeometry3D = tmpImage2->GetGeometry( 0 );
const BaseGeometry *intImageGeometry3D = tmpImage->GetGeometry( 0 );
typedef itk::ImageRegionIteratorWithIndex<itkUCharImageType> IteratorType;
IteratorType imageIterator (m_InternalImageMask3D, m_InternalImageMask3D->GetRequestedRegion());
imageIterator.GoToBegin();
while ( !imageIterator.IsAtEnd() )
{
unsigned char val = imageIterator.Value();
if (val>0)
{
itk::Index<3> index = imageIterator.GetIndex();
Point3D point;
point[0] = index[0];
point[1] = index[1];
point[2] = index[2];
intImageGeometry3D->IndexToWorld(point, point);
pfImageGeometry3D->WorldToIndex(point, point);
point[i0] += 0.5;
point[i1] += 0.5;
index[0] = point[0];
index[1] = point[1];
index[2] = point[2];
if (pfImageGeometry3D->IsIndexInside(index))
m_PlanarFigureImage->SetPixel(index, 1);
}
++imageIterator;
}
// Clean up VTK objects
polyline->Delete();
extrudeFilter->Delete();
polyDataToImageStencil->Delete();
vtkImporter->Delete();
imageStencilFilter->Delete();
//vtkExporter->Delete(); // TODO: crashes when outcommented; memory leak??
delete[] ptIds;
}
void QmitkFiberExtractionView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget)
{
m_MultiWidget = &stdMultiWidget;
}
void QmitkFiberExtractionView::StdMultiWidgetNotAvailable()
{
m_MultiWidget = NULL;
}
void QmitkFiberExtractionView::UpdateGui()
{
m_Controls->m_FibLabel->setText("<font color='red'>mandatory</font>");
m_Controls->m_PfLabel->setText("<font color='grey'>needed for extraction</font>");
m_Controls->m_InputData->setTitle("Please Select Input Data");
m_Controls->m_Extract3dButton_2->setEnabled(false);
m_Controls->m_Extract3dButton->setEnabled(false);
m_Controls->m_ExtractMask->setEnabled(false);
m_Controls->m_RemoveOutsideMaskButton->setEnabled(false);
m_Controls->m_RemoveInsideMaskButton->setEnabled(false);
m_Controls->doExtractFibersButton->setEnabled(false);
m_Controls->PFCompoANDButton->setEnabled(false);
m_Controls->PFCompoORButton->setEnabled(false);
m_Controls->PFCompoNOTButton->setEnabled(false);
m_Controls->m_GenerateRoiImage->setEnabled(false);
m_Controls->m_JoinBundles->setEnabled(false);
m_Controls->m_SubstractBundles->setEnabled(false);
m_Controls->doExtractFibersButton->setEnabled(false);
m_Controls->m_PlanarFigureButtonsFrame->setEnabled(false);
// are fiber bundles selected?
if ( !m_SelectedFB.empty() )
{
m_Controls->m_FibLabel->setText(QString(m_SelectedFB.at(0)->GetName().c_str()));
m_Controls->m_PlanarFigureButtonsFrame->setEnabled(true);
// one bundle and one planar figure needed to extract fibers
if (!m_SelectedPF.empty())
{
m_Controls->m_InputData->setTitle("Input Data");
m_Controls->m_PfLabel->setText(QString(m_SelectedPF.at(0)->GetName().c_str()));
m_Controls->doExtractFibersButton->setEnabled(true);
}
// more than two bundles needed to join/subtract
if (m_SelectedFB.size() > 1)
{
m_Controls->m_FibLabel->setText("multiple bundles selected");
m_Controls->m_JoinBundles->setEnabled(true);
m_Controls->m_SubstractBundles->setEnabled(true);
}
if (m_MaskImageNode.IsNotNull())
{
m_Controls->m_Extract3dButton_2->setEnabled(true);
m_Controls->m_Extract3dButton->setEnabled(true);
m_Controls->m_ExtractMask->setEnabled(true);
m_Controls->m_RemoveOutsideMaskButton->setEnabled(true);
m_Controls->m_RemoveInsideMaskButton->setEnabled(true);
}
}
// are planar figures selected?
if ( !m_SelectedPF.empty() )
{
if ( !m_SelectedFB.empty() || m_SelectedImage.IsNotNull())
m_Controls->m_GenerateRoiImage->setEnabled(true);
if (m_SelectedPF.size() > 1)
{
m_Controls->PFCompoANDButton->setEnabled(true);
m_Controls->PFCompoORButton->setEnabled(true);
}
else
m_Controls->PFCompoNOTButton->setEnabled(true);
}
}
void QmitkFiberExtractionView::NodeRemoved(const mitk::DataNode* node)
{
std::vector<mitk::DataNode*> nodes;
OnSelectionChanged(nodes);
}
void QmitkFiberExtractionView::NodeAdded(const mitk::DataNode* node)
{
std::vector<mitk::DataNode*> nodes;
OnSelectionChanged(nodes);
}
void QmitkFiberExtractionView::OnSelectionChanged( std::vector<mitk::DataNode*> nodes )
{
//reset existing Vectors containing FiberBundles and PlanarFigures from a previous selection
m_SelectedFB.clear();
m_SelectedPF.clear();
m_SelectedSurfaces.clear();
m_SelectedImage = NULL;
m_MaskImageNode = NULL;
for( std::vector<mitk::DataNode*>::iterator it = nodes.begin(); it != nodes.end(); ++it )
{
mitk::DataNode::Pointer node = *it;
if ( dynamic_cast<mitk::FiberBundleX*>(node->GetData()) )
m_SelectedFB.push_back(node);
else if (dynamic_cast<mitk::PlanarPolygon*>(node->GetData()) || dynamic_cast<mitk::PlanarFigureComposite*>(node->GetData()) || dynamic_cast<mitk::PlanarCircle*>(node->GetData()))
m_SelectedPF.push_back(node);
else if (dynamic_cast<mitk::Image*>(node->GetData()))
{
m_SelectedImage = dynamic_cast<mitk::Image*>(node->GetData());
bool isBinary = false;
node->GetPropertyValue<bool>("binary", isBinary);
if (isBinary)
m_MaskImageNode = node;
}
else if (dynamic_cast<mitk::Surface*>(node->GetData()))
m_SelectedSurfaces.push_back(dynamic_cast<mitk::Surface*>(node->GetData()));
}
if (m_SelectedFB.empty())
{
int maxLayer = 0;
itk::VectorContainer<unsigned int, mitk::DataNode::Pointer>::ConstPointer nodes = this->GetDefaultDataStorage()->GetAll();
for (unsigned int i=0; i<nodes->Size(); i++)
if (dynamic_cast<mitk::FiberBundleX*>(nodes->at(i)->GetData()))
{
mitk::DataStorage::SetOfObjects::ConstPointer sources = GetDataStorage()->GetSources(nodes->at(i));
if (sources->Size()>0)
continue;
int layer = 0;
nodes->at(i)->GetPropertyValue("layer", layer);
if (layer>=maxLayer)
{
maxLayer = layer;
m_SelectedFB.clear();
m_SelectedFB.push_back(nodes->at(i));
}
}
}
if (m_SelectedPF.empty())
{
int maxLayer = 0;
itk::VectorContainer<unsigned int, mitk::DataNode::Pointer>::ConstPointer nodes = this->GetDefaultDataStorage()->GetAll();
for (unsigned int i=0; i<nodes->Size(); i++)
if (dynamic_cast<mitk::PlanarPolygon*>(nodes->at(i)->GetData()) || dynamic_cast<mitk::PlanarFigureComposite*>(nodes->at(i)->GetData()) || dynamic_cast<mitk::PlanarCircle*>(nodes->at(i)->GetData()))
{
mitk::DataStorage::SetOfObjects::ConstPointer sources = GetDataStorage()->GetSources(nodes->at(i));
if (sources->Size()>0)
continue;
int layer = 0;
nodes->at(i)->GetPropertyValue("layer", layer);
if (layer>=maxLayer)
{
maxLayer = layer;
m_SelectedPF.clear();
m_SelectedPF.push_back(nodes->at(i));
}
}
}
UpdateGui();
}
void QmitkFiberExtractionView::OnDrawPolygon()
{
mitk::PlanarPolygon::Pointer figure = mitk::PlanarPolygon::New();
figure->ClosedOn();
this->AddFigureToDataStorage(figure, QString("Polygon%1").arg(++m_PolygonCounter));
}
void QmitkFiberExtractionView::OnDrawCircle()
{
mitk::PlanarCircle::Pointer figure = mitk::PlanarCircle::New();
this->AddFigureToDataStorage(figure, QString("Circle%1").arg(++m_CircleCounter));
}
void QmitkFiberExtractionView::Activated()
{
}
void QmitkFiberExtractionView::AddFigureToDataStorage(mitk::PlanarFigure* figure, const QString& name, const char *, mitk::BaseProperty* )
{
// initialize figure's geometry with empty geometry
mitk::PlaneGeometry::Pointer emptygeometry = mitk::PlaneGeometry::New();
- figure->SetGeometry2D( emptygeometry );
+ figure->SetPlaneGeometry( emptygeometry );
//set desired data to DataNode where Planarfigure is stored
mitk::DataNode::Pointer newNode = mitk::DataNode::New();
newNode->SetName(name.toStdString());
newNode->SetData(figure);
newNode->SetBoolProperty("planarfigure.3drendering", true);
mitk::PlanarFigureInteractor::Pointer figureInteractor = dynamic_cast<mitk::PlanarFigureInteractor*>(newNode->GetDataInteractor().GetPointer());
if(figureInteractor.IsNull())
{
figureInteractor = mitk::PlanarFigureInteractor::New();
us::Module* planarFigureModule = us::ModuleRegistry::GetModule( "MitkPlanarFigure" );
figureInteractor->LoadStateMachine("PlanarFigureInteraction.xml", planarFigureModule );
figureInteractor->SetEventConfig( "PlanarFigureConfig.xml", planarFigureModule );
figureInteractor->SetDataNode(newNode);
}
// figure drawn on the topmost layer / image
GetDataStorage()->Add(newNode );
for(unsigned int i = 0; i < m_SelectedPF.size(); i++)
m_SelectedPF[i]->SetSelected(false);
newNode->SetSelected(true);
m_SelectedPF.clear();
m_SelectedPF.push_back(newNode);
UpdateGui();
}
void QmitkFiberExtractionView::DoFiberExtraction()
{
if ( m_SelectedFB.empty() || m_SelectedPF.empty() ){
QMessageBox::information( NULL, "Warning", "No fibe bundle selected!");
return;
}
std::vector<mitk::DataNode::Pointer> fiberBundles = m_SelectedFB;
mitk::DataNode::Pointer planarFigure = m_SelectedPF.at(0);
for (unsigned int i=0; i<fiberBundles.size(); i++)
{
mitk::FiberBundleX::Pointer fib = dynamic_cast<mitk::FiberBundleX*>(fiberBundles.at(i)->GetData());
mitk::BaseData::Pointer roi = planarFigure->GetData();
mitk::FiberBundleX::Pointer extFB = fib->ExtractFiberSubset(roi);
if (extFB->GetNumFibers()<=0)
{
QMessageBox::information(NULL, "No output generated:", "The resulting fiber bundle contains no fibers.");
continue;
}
mitk::DataNode::Pointer node;
node = mitk::DataNode::New();
node->SetData(extFB);
QString name(fiberBundles.at(i)->GetName().c_str());
name += "_";
name += planarFigure->GetName().c_str();
node->SetName(name.toStdString());
fiberBundles.at(i)->SetVisibility(false);
GetDataStorage()->Add(node);
}
}
void QmitkFiberExtractionView::GenerateAndComposite()
{
mitk::PlanarFigureComposite::Pointer PFCAnd = mitk::PlanarFigureComposite::New();
PFCAnd->setOperationType(mitk::PFCOMPOSITION_AND_OPERATION);
for( std::vector<mitk::DataNode::Pointer>::iterator it = m_SelectedPF.begin(); it != m_SelectedPF.end(); ++it )
{
mitk::DataNode::Pointer nodePF = *it;
PFCAnd->addPlanarFigure( nodePF->GetData() );
PFCAnd->addDataNode( nodePF );
PFCAnd->setDisplayName("AND");
}
AddCompositeToDatastorage(PFCAnd);
}
void QmitkFiberExtractionView::GenerateOrComposite()
{
mitk::PlanarFigureComposite::Pointer PFCOr = mitk::PlanarFigureComposite::New();
PFCOr->setOperationType(mitk::PFCOMPOSITION_OR_OPERATION);
for( std::vector<mitk::DataNode::Pointer>::iterator it = m_SelectedPF.begin(); it != m_SelectedPF.end(); ++it )
{
mitk::DataNode::Pointer nodePF = *it;
PFCOr->addPlanarFigure( nodePF->GetData() );
PFCOr->addDataNode( nodePF );
PFCOr->setDisplayName("OR");
}
AddCompositeToDatastorage(PFCOr);
}
void QmitkFiberExtractionView::GenerateNotComposite()
{
mitk::PlanarFigureComposite::Pointer PFCNot = mitk::PlanarFigureComposite::New();
PFCNot->setOperationType(mitk::PFCOMPOSITION_NOT_OPERATION);
for( std::vector<mitk::DataNode::Pointer>::iterator it = m_SelectedPF.begin(); it != m_SelectedPF.end(); ++it )
{
mitk::DataNode::Pointer nodePF = *it;
PFCNot->addPlanarFigure( nodePF->GetData() );
PFCNot->addDataNode( nodePF );
PFCNot->setDisplayName("NOT");
}
AddCompositeToDatastorage(PFCNot);
}
/* CLEANUP NEEDED */
void QmitkFiberExtractionView::AddCompositeToDatastorage(mitk::PlanarFigureComposite::Pointer pfc, mitk::DataNode::Pointer parentNode )
{
mitk::DataNode::Pointer newPFCNode;
newPFCNode = mitk::DataNode::New();
newPFCNode->SetName( pfc->getDisplayName() );
newPFCNode->SetData(pfc);
switch (pfc->getOperationType()) {
case 0:
{
if (parentNode.IsNotNull())
GetDataStorage()->Add(newPFCNode, parentNode);
else
GetDataStorage()->Add(newPFCNode);
//iterate through its childs
for(int i=0; i<pfc->getNumberOfChildren(); ++i)
{
mitk::BaseData::Pointer tmpPFchild = pfc->getChildAt(i);
mitk::DataNode::Pointer savedPFchildNode = pfc->getDataNodeAt(i);
mitk::PlanarFigureComposite::Pointer pfcompcast= dynamic_cast<mitk::PlanarFigureComposite*>(tmpPFchild.GetPointer());
if ( pfcompcast.IsNotNull() )
{
// child is of type planar Figure composite
// make new node of the child, cuz later the child has to be removed of its old position in datamanager
// feed new dataNode with information of the savedDataNode, which is gonna be removed soon
mitk::DataNode::Pointer newChildPFCNode;
newChildPFCNode = mitk::DataNode::New();
newChildPFCNode->SetData(tmpPFchild);
newChildPFCNode->SetName( savedPFchildNode->GetName() );
pfcompcast->setDisplayName( savedPFchildNode->GetName() ); //name might be changed in DataManager by user
//update inside vector the dataNodePointer
pfc->replaceDataNodeAt(i, newChildPFCNode);
AddCompositeToDatastorage(pfcompcast, newPFCNode); //the current PFCNode becomes the childs parent
// remove savedNode here, cuz otherwise its children will change their position in the dataNodeManager
// without having its parent anymore
GetDataStorage()->Remove(savedPFchildNode);
}
else
{
// child is not of type PlanarFigureComposite, so its one of the planarFigures
// create new dataNode containing the data of the old dataNode, but position in dataManager will be
// modified cuz we re setting a (new) parent.
mitk::DataNode::Pointer newPFchildNode = mitk::DataNode::New();
newPFchildNode->SetName(savedPFchildNode->GetName() );
newPFchildNode->SetData(tmpPFchild);
newPFchildNode->SetVisibility(true);
newPFchildNode->SetBoolProperty("planarfigure.3drendering", true);
// replace the dataNode in PFComp DataNodeVector
pfc->replaceDataNodeAt(i, newPFchildNode);
// remove old child position in dataStorage
GetDataStorage()->Remove(savedPFchildNode);
//add new child to datamanager with its new position as child of newPFCNode parent
GetDataStorage()->Add(newPFchildNode, newPFCNode);
}
}
break;
}
case 1:
{
if (!parentNode.IsNull())
GetDataStorage()->Add(newPFCNode, parentNode);
else
GetDataStorage()->Add(newPFCNode);
for(int i=0; i<pfc->getNumberOfChildren(); ++i)
{
mitk::BaseData::Pointer tmpPFchild = pfc->getChildAt(i);
mitk::DataNode::Pointer savedPFchildNode = pfc->getDataNodeAt(i);
mitk::PlanarFigureComposite::Pointer pfcompcast= dynamic_cast<mitk::PlanarFigureComposite*>(tmpPFchild.GetPointer());
if ( !pfcompcast.IsNull() )
{
// child is of type planar Figure composite
// make new node of the child, cuz later the child has to be removed of its old position in datamanager
// feed new dataNode with information of the savedDataNode, which is gonna be removed soon
mitk::DataNode::Pointer newChildPFCNode;
newChildPFCNode = mitk::DataNode::New();
newChildPFCNode->SetData(tmpPFchild);
newChildPFCNode->SetName( savedPFchildNode->GetName() );
pfcompcast->setDisplayName( savedPFchildNode->GetName() ); //name might be changed in DataManager by user
//update inside vector the dataNodePointer
pfc->replaceDataNodeAt(i, newChildPFCNode);
AddCompositeToDatastorage(pfcompcast, newPFCNode); //the current PFCNode becomes the childs parent
// remove old child position in dataStorage
GetDataStorage()->Remove(savedPFchildNode);
}
else
{
// child is not of type PlanarFigureComposite, so its one of the planarFigures
// create new dataNode containing the data of the old dataNode, but position in dataManager will be
// modified cuz we re setting a (new) parent.
mitk::DataNode::Pointer newPFchildNode = mitk::DataNode::New();
newPFchildNode->SetName(savedPFchildNode->GetName() );
newPFchildNode->SetData(tmpPFchild);
newPFchildNode->SetVisibility(true);
newPFchildNode->SetBoolProperty("planarfigure.3drendering", true);
// replace the dataNode in PFComp DataNodeVector
pfc->replaceDataNodeAt(i, newPFchildNode);
// remove old child position in dataStorage
GetDataStorage()->Remove(savedPFchildNode);
//add new child to datamanager with its new position as child of newPFCNode parent
GetDataStorage()->Add(newPFchildNode, newPFCNode);
}
}
break;
}
case 2:
{
if (!parentNode.IsNull())
GetDataStorage()->Add(newPFCNode, parentNode);
else
GetDataStorage()->Add(newPFCNode);
//iterate through its childs
for(int i=0; i<pfc->getNumberOfChildren(); ++i)
{
mitk::BaseData::Pointer tmpPFchild = pfc->getChildAt(i);
mitk::DataNode::Pointer savedPFchildNode = pfc->getDataNodeAt(i);
mitk::PlanarFigureComposite::Pointer pfcompcast= dynamic_cast<mitk::PlanarFigureComposite*>(tmpPFchild.GetPointer());
if ( !pfcompcast.IsNull() )
{ // child is of type planar Figure composite
// makeRemoveBundle new node of the child, cuz later the child has to be removed of its old position in datamanager
// feed new dataNode with information of the savedDataNode, which is gonna be removed soon
mitk::DataNode::Pointer newChildPFCNode;
newChildPFCNode = mitk::DataNode::New();
newChildPFCNode->SetData(tmpPFchild);
newChildPFCNode->SetName( savedPFchildNode->GetName() );
pfcompcast->setDisplayName( savedPFchildNode->GetName() ); //name might be changed in DataManager by user
//update inside vector the dataNodePointer
pfc->replaceDataNodeAt(i, newChildPFCNode);
AddCompositeToDatastorage(pfcompcast, newPFCNode); //the current PFCNode becomes the childs parent
// remove old child position in dataStorage
GetDataStorage()->Remove(savedPFchildNode);
}
else
{
// child is not of type PlanarFigureComposite, so its one of the planarFigures
// create new dataNode containing the data of the old dataNode, but position in dataManager will be
// modified cuz we re setting a (new) parent.
mitk::DataNode::Pointer newPFchildNode = mitk::DataNode::New();
newPFchildNode->SetName(savedPFchildNode->GetName() );
newPFchildNode->SetData(tmpPFchild);
newPFchildNode->SetVisibility(true);
newPFchildNode->SetBoolProperty("planarfigure.3drendering", true);
// replace the dataNode in PFComp DataNodeVector
pfc->replaceDataNodeAt(i, newPFchildNode);
// remove old child position in dataStorage
GetDataStorage()->Remove(savedPFchildNode);
//add new child to datamanager with its new position as child of newPFCNode parent
GetDataStorage()->Add(newPFchildNode, newPFCNode);
}
}
break;
}
default:
MITK_DEBUG << "we have an UNDEFINED composition... ERROR" ;
break;
}
for(unsigned int i = 0; i < m_SelectedPF.size(); i++)
m_SelectedPF[i]->SetSelected(false);
newPFCNode->SetSelected(true);
m_SelectedPF.clear();
m_SelectedPF.push_back(newPFCNode);
UpdateGui();
}
void QmitkFiberExtractionView::JoinBundles()
{
if ( m_SelectedFB.size()<2 ){
QMessageBox::information( NULL, "Warning", "Select at least two fiber bundles!");
MITK_WARN("QmitkFiberExtractionView") << "Select at least two fiber bundles!";
return;
}
mitk::FiberBundleX::Pointer newBundle = dynamic_cast<mitk::FiberBundleX*>(m_SelectedFB.at(0)->GetData());
m_SelectedFB.at(0)->SetVisibility(false);
QString name("");
name += QString(m_SelectedFB.at(0)->GetName().c_str());
for (unsigned int i=1; i<m_SelectedFB.size(); i++)
{
newBundle = newBundle->AddBundle(dynamic_cast<mitk::FiberBundleX*>(m_SelectedFB.at(i)->GetData()));
name += "+"+QString(m_SelectedFB.at(i)->GetName().c_str());
m_SelectedFB.at(i)->SetVisibility(false);
}
mitk::DataNode::Pointer fbNode = mitk::DataNode::New();
fbNode->SetData(newBundle);
fbNode->SetName(name.toStdString());
fbNode->SetVisibility(true);
GetDataStorage()->Add(fbNode);
}
void QmitkFiberExtractionView::SubstractBundles()
{
if ( m_SelectedFB.size()<2 ){
QMessageBox::information( NULL, "Warning", "Select at least two fiber bundles!");
MITK_WARN("QmitkFiberExtractionView") << "Select at least two fiber bundles!";
return;
}
mitk::FiberBundleX::Pointer newBundle = dynamic_cast<mitk::FiberBundleX*>(m_SelectedFB.at(0)->GetData());
m_SelectedFB.at(0)->SetVisibility(false);
QString name("");
name += QString(m_SelectedFB.at(0)->GetName().c_str());
for (unsigned int i=1; i<m_SelectedFB.size(); i++)
{
newBundle = newBundle->SubtractBundle(dynamic_cast<mitk::FiberBundleX*>(m_SelectedFB.at(i)->GetData()));
if (newBundle.IsNull())
break;
name += "-"+QString(m_SelectedFB.at(i)->GetName().c_str());
m_SelectedFB.at(i)->SetVisibility(false);
}
if (newBundle.IsNull())
{
QMessageBox::information(NULL, "No output generated:", "The resulting fiber bundle contains no fibers. Did you select the fiber bundles in the correct order? X-Y is not equal to Y-X!");
return;
}
mitk::DataNode::Pointer fbNode = mitk::DataNode::New();
fbNode->SetData(newBundle);
fbNode->SetName(name.toStdString());
fbNode->SetVisibility(true);
GetDataStorage()->Add(fbNode);
}
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxView.cpp
index e1e77dd053..758a1a77ad 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxView.cpp
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkFiberfoxView.cpp
@@ -1,2631 +1,2632 @@
/*===================================================================
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.
===================================================================*/
//misc
#define _USE_MATH_DEFINES
#include <math.h>
// Blueberry
#include <berryISelectionService.h>
#include <berryIWorkbenchWindow.h>
// Qmitk
#include "QmitkFiberfoxView.h"
// MITK
#include <mitkImage.h>
#include <mitkDiffusionImage.h>
#include <mitkImageToItk.h>
#include <mitkImageCast.h>
#include <mitkProperties.h>
#include <mitkPlanarFigureInteractor.h>
#include <mitkDataStorage.h>
#include <itkFibersFromPlanarFiguresFilter.h>
#include <itkTractsToDWIImageFilter.h>
#include <mitkTensorImage.h>
#include <mitkILinkedRenderWindowPart.h>
#include <mitkGlobalInteraction.h>
#include <mitkImageToItk.h>
#include <mitkImageCast.h>
#include <mitkImageGenerator.h>
#include <mitkNodePredicateDataType.h>
#include <itkScalableAffineTransform.h>
#include <mitkLevelWindowProperty.h>
#include <mitkNodePredicateOr.h>
#include <mitkNodePredicateAnd.h>
#include <mitkNodePredicateNot.h>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/foreach.hpp>
#include <QFileDialog>
#include <QMessageBox>
#include "usModuleRegistry.h"
#include <mitkChiSquareNoiseModel.h>
#include <itksys/SystemTools.hxx>
#include <mitkIOUtil.h>
#include <QScrollBar>
#include <itkInvertIntensityImageFilter.h>
#include <QDialogButtonBox>
#include <itkAdcImageFilter.h>
#include <itkShiftScaleImageFilter.h>
#define _USE_MATH_DEFINES
#include <math.h>
QmitkFiberfoxWorker::QmitkFiberfoxWorker(QmitkFiberfoxView* view)
: m_View(view)
{
}
void QmitkFiberfoxWorker::run()
{
try{
switch (m_FilterType)
{
case 0:
m_View->m_TractsToDwiFilter->Update();
break;
case 1:
m_View->m_ArtifactsToDwiFilter->Update();
break;
}
}
catch( ... )
{
}
m_View->m_Thread.quit();
}
const std::string QmitkFiberfoxView::VIEW_ID = "org.mitk.views.fiberfoxview";
QmitkFiberfoxView::QmitkFiberfoxView()
: QmitkAbstractView()
, m_Controls( 0 )
, m_SelectedImage( NULL )
, m_Worker(this)
, m_ThreadIsRunning(false)
{
m_Worker.moveToThread(&m_Thread);
connect(&m_Thread, SIGNAL(started()), this, SLOT(BeforeThread()));
connect(&m_Thread, SIGNAL(started()), &m_Worker, SLOT(run()));
connect(&m_Thread, SIGNAL(finished()), this, SLOT(AfterThread()));
connect(&m_Thread, SIGNAL(terminated()), this, SLOT(AfterThread()));
m_SimulationTimer = new QTimer(this);
}
void QmitkFiberfoxView::KillThread()
{
MITK_INFO << "Aborting DWI simulation.";
switch (m_Worker.m_FilterType)
{
case 0:
m_TractsToDwiFilter->SetAbortGenerateData(true);
break;
case 1:
m_ArtifactsToDwiFilter->SetAbortGenerateData(true);
break;
}
m_Controls->m_AbortSimulationButton->setEnabled(false);
m_Controls->m_AbortSimulationButton->setText("Aborting simulation ...");
}
void QmitkFiberfoxView::BeforeThread()
{
m_SimulationTime = QTime::currentTime();
m_SimulationTimer->start(100);
m_Controls->m_AbortSimulationButton->setVisible(true);
m_Controls->m_GenerateImageButton->setVisible(false);
m_Controls->m_SimulationStatusText->setVisible(true);
m_ThreadIsRunning = true;
}
void QmitkFiberfoxView::AfterThread()
{
UpdateSimulationStatus();
m_SimulationTimer->stop();
m_Controls->m_AbortSimulationButton->setVisible(false);
m_Controls->m_AbortSimulationButton->setEnabled(true);
m_Controls->m_AbortSimulationButton->setText("Abort simulation");
m_Controls->m_GenerateImageButton->setVisible(true);
m_ThreadIsRunning = false;
QString statusText;
FiberfoxParameters<double> parameters;
mitk::DiffusionImage<short>::Pointer mitkImage = mitk::DiffusionImage<short>::New();
switch (m_Worker.m_FilterType)
{
case 0:
{
statusText = QString(m_TractsToDwiFilter->GetStatusText().c_str());
if (m_TractsToDwiFilter->GetAbortGenerateData())
{
MITK_INFO << "Simulation aborted.";
return;
}
parameters = m_TractsToDwiFilter->GetParameters();
mitkImage->SetVectorImage( m_TractsToDwiFilter->GetOutput() );
mitkImage->SetReferenceBValue(parameters.m_SignalGen.m_Bvalue);
mitkImage->SetDirections(parameters.m_SignalGen.GetGradientDirections());
mitkImage->InitializeFromVectorImage();
parameters.m_Misc.m_ResultNode->SetData( mitkImage );
parameters.m_Misc.m_ResultNode->SetName(parameters.m_Misc.m_ParentNode->GetName()
+"_D"+QString::number(parameters.m_SignalGen.m_ImageRegion.GetSize(0)).toStdString()
+"-"+QString::number(parameters.m_SignalGen.m_ImageRegion.GetSize(1)).toStdString()
+"-"+QString::number(parameters.m_SignalGen.m_ImageRegion.GetSize(2)).toStdString()
+"_S"+QString::number(parameters.m_SignalGen.m_ImageSpacing[0]).toStdString()
+"-"+QString::number(parameters.m_SignalGen.m_ImageSpacing[1]).toStdString()
+"-"+QString::number(parameters.m_SignalGen.m_ImageSpacing[2]).toStdString()
+"_b"+QString::number(parameters.m_SignalGen.m_Bvalue).toStdString()
+"_"+parameters.m_Misc.m_SignalModelString
+parameters.m_Misc.m_ArtifactModelString);
GetDataStorage()->Add(parameters.m_Misc.m_ResultNode, parameters.m_Misc.m_ParentNode);
parameters.m_Misc.m_ResultNode->SetProperty( "levelwindow", mitk::LevelWindowProperty::New(m_TractsToDwiFilter->GetLevelWindow()) );
if (m_Controls->m_VolumeFractionsBox->isChecked())
{
std::vector< itk::TractsToDWIImageFilter< short >::ItkDoubleImgType::Pointer > volumeFractions = m_TractsToDwiFilter->GetVolumeFractions();
for (unsigned int k=0; k<volumeFractions.size(); k++)
{
mitk::Image::Pointer image = mitk::Image::New();
image->InitializeByItk(volumeFractions.at(k).GetPointer());
image->SetVolume(volumeFractions.at(k)->GetBufferPointer());
mitk::DataNode::Pointer node = mitk::DataNode::New();
node->SetData( image );
node->SetName(parameters.m_Misc.m_ParentNode->GetName()+"_CompartmentVolume-"+QString::number(k).toStdString());
GetDataStorage()->Add(node, parameters.m_Misc.m_ParentNode);
}
}
m_TractsToDwiFilter = NULL;
break;
}
case 1:
{
statusText = QString(m_ArtifactsToDwiFilter->GetStatusText().c_str());
if (m_ArtifactsToDwiFilter->GetAbortGenerateData())
{
MITK_INFO << "Simulation aborted.";
return;
}
parameters = m_ArtifactsToDwiFilter->GetParameters().CopyParameters<double>();
mitk::DiffusionImage<short>::Pointer diffImg = dynamic_cast<mitk::DiffusionImage<short>*>(parameters.m_Misc.m_ParentNode->GetData());
mitkImage = mitk::DiffusionImage<short>::New();
mitkImage->SetVectorImage( m_ArtifactsToDwiFilter->GetOutput() );
mitkImage->SetReferenceBValue(diffImg->GetReferenceBValue());
mitkImage->SetDirections(diffImg->GetDirections());
mitkImage->InitializeFromVectorImage();
parameters.m_Misc.m_ResultNode->SetData( mitkImage );
parameters.m_Misc.m_ResultNode->SetName(parameters.m_Misc.m_ParentNode->GetName()+parameters.m_Misc.m_ArtifactModelString);
GetDataStorage()->Add(parameters.m_Misc.m_ResultNode, parameters.m_Misc.m_ParentNode);
m_ArtifactsToDwiFilter = NULL;
break;
}
}
mitk::BaseData::Pointer basedata = parameters.m_Misc.m_ResultNode->GetData();
if (basedata.IsNotNull())
{
mitk::RenderingManager::GetInstance()->InitializeViews(
basedata->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true );
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
if (!parameters.m_Misc.m_OutputPath.empty())
{
try{
QString outputFileName(parameters.m_Misc.m_OutputPath.c_str());
outputFileName += parameters.m_Misc.m_ResultNode->GetName().c_str();
outputFileName.replace(QString("."), QString("_"));
outputFileName += ".dwi";
QString status("Saving output image to ");
status += outputFileName;
m_Controls->m_SimulationStatusText->append(status);
mitk::IOUtil::SaveBaseData(mitkImage, outputFileName.toStdString());
m_Controls->m_SimulationStatusText->append("File saved successfully.");
}
catch (itk::ExceptionObject &e)
{
QString status("Exception during DWI writing: ");
status += e.GetDescription();
m_Controls->m_SimulationStatusText->append(status);
}
catch (...)
{
m_Controls->m_SimulationStatusText->append("Unknown exception during DWI writing!");
}
}
parameters.m_SignalGen.m_FrequencyMap = NULL;
}
void QmitkFiberfoxView::UpdateSimulationStatus()
{
QString statusText;
switch (m_Worker.m_FilterType)
{
case 0:
statusText = QString(m_TractsToDwiFilter->GetStatusText().c_str());
break;
case 1:
statusText = QString(m_ArtifactsToDwiFilter->GetStatusText().c_str());
break;
}
if (QString::compare(m_SimulationStatusText,statusText)!=0)
{
m_Controls->m_SimulationStatusText->clear();
statusText = "<pre>"+statusText+"</pre>";
m_Controls->m_SimulationStatusText->setText(statusText);
QScrollBar *vScrollBar = m_Controls->m_SimulationStatusText->verticalScrollBar();
vScrollBar->triggerAction(QScrollBar::SliderToMaximum);
}
}
// Destructor
QmitkFiberfoxView::~QmitkFiberfoxView()
{
delete m_SimulationTimer;
}
void QmitkFiberfoxView::CreateQtPartControl( QWidget *parent )
{
// build up qt view, unless already done
if ( !m_Controls )
{
// create GUI widgets from the Qt Designer's .ui file
m_Controls = new Ui::QmitkFiberfoxViewControls;
m_Controls->setupUi( parent );
// commented out
m_Controls->m_DiffusionDirectionBox->setVisible(false);
m_Controls->label_3->setVisible(false);
m_Controls->m_SeparationAngleBox->setVisible(false);
m_Controls->label_4->setVisible(false);
//
m_Controls->m_StickWidget1->setVisible(true);
m_Controls->m_StickWidget2->setVisible(false);
m_Controls->m_ZeppelinWidget1->setVisible(false);
m_Controls->m_ZeppelinWidget2->setVisible(false);
m_Controls->m_TensorWidget1->setVisible(false);
m_Controls->m_TensorWidget2->setVisible(false);
m_Controls->m_BallWidget1->setVisible(true);
m_Controls->m_BallWidget2->setVisible(false);
m_Controls->m_AstrosticksWidget1->setVisible(false);
m_Controls->m_AstrosticksWidget2->setVisible(false);
m_Controls->m_DotWidget1->setVisible(false);
m_Controls->m_DotWidget2->setVisible(false);
m_Controls->m_PrototypeWidget1->setVisible(false);
m_Controls->m_PrototypeWidget2->setVisible(false);
m_Controls->m_PrototypeWidget3->setVisible(false);
m_Controls->m_PrototypeWidget4->setVisible(false);
m_Controls->m_PrototypeWidget3->SetMinFa(0.0);
m_Controls->m_PrototypeWidget3->SetMaxFa(0.15);
m_Controls->m_PrototypeWidget4->SetMinFa(0.0);
m_Controls->m_PrototypeWidget4->SetMaxFa(0.15);
m_Controls->m_PrototypeWidget3->SetMinAdc(0.0);
m_Controls->m_PrototypeWidget3->SetMaxAdc(0.001);
m_Controls->m_PrototypeWidget4->SetMinAdc(0.003);
m_Controls->m_PrototypeWidget4->SetMaxAdc(0.004);
m_Controls->m_Comp4FractionFrame->setVisible(false);
m_Controls->m_DiffusionPropsMessage->setVisible(false);
m_Controls->m_GeometryMessage->setVisible(false);
m_Controls->m_AdvancedSignalOptionsFrame->setVisible(false);
m_Controls->m_AdvancedFiberOptionsFrame->setVisible(false);
m_Controls->m_VarianceBox->setVisible(false);
m_Controls->m_NoiseFrame->setVisible(false);
m_Controls->m_GhostFrame->setVisible(false);
m_Controls->m_DistortionsFrame->setVisible(false);
m_Controls->m_EddyFrame->setVisible(false);
m_Controls->m_SpikeFrame->setVisible(false);
m_Controls->m_AliasingFrame->setVisible(false);
m_Controls->m_MotionArtifactFrame->setVisible(false);
m_ParameterFile = QDir::currentPath()+"/param.ffp";
m_Controls->m_AbortSimulationButton->setVisible(false);
m_Controls->m_SimulationStatusText->setVisible(false);
m_Controls->m_FrequencyMapBox->SetDataStorage(this->GetDataStorage());
mitk::TNodePredicateDataType<mitk::Image>::Pointer isMitkImage = mitk::TNodePredicateDataType<mitk::Image>::New();
mitk::NodePredicateDataType::Pointer isDwi = mitk::NodePredicateDataType::New("DiffusionImage");
mitk::NodePredicateDataType::Pointer isDti = mitk::NodePredicateDataType::New("TensorImage");
mitk::NodePredicateDataType::Pointer isQbi = mitk::NodePredicateDataType::New("QBallImage");
mitk::NodePredicateOr::Pointer isDiffusionImage = mitk::NodePredicateOr::New(isDwi, isDti);
isDiffusionImage = mitk::NodePredicateOr::New(isDiffusionImage, isQbi);
mitk::NodePredicateNot::Pointer noDiffusionImage = mitk::NodePredicateNot::New(isDiffusionImage);
mitk::NodePredicateAnd::Pointer finalPredicate = mitk::NodePredicateAnd::New(isMitkImage, noDiffusionImage);
m_Controls->m_FrequencyMapBox->SetPredicate(finalPredicate);
m_Controls->m_Comp4VolumeFraction->SetDataStorage(this->GetDataStorage());
m_Controls->m_Comp4VolumeFraction->SetPredicate(finalPredicate);
connect( m_SimulationTimer, SIGNAL(timeout()), this, SLOT(UpdateSimulationStatus()) );
connect((QObject*) m_Controls->m_AbortSimulationButton, SIGNAL(clicked()), (QObject*) this, SLOT(KillThread()));
connect((QObject*) m_Controls->m_GenerateImageButton, SIGNAL(clicked()), (QObject*) this, SLOT(GenerateImage()));
connect((QObject*) m_Controls->m_GenerateFibersButton, SIGNAL(clicked()), (QObject*) this, SLOT(GenerateFibers()));
connect((QObject*) m_Controls->m_CircleButton, SIGNAL(clicked()), (QObject*) this, SLOT(OnDrawROI()));
connect((QObject*) m_Controls->m_FlipButton, SIGNAL(clicked()), (QObject*) this, SLOT(OnFlipButton()));
connect((QObject*) m_Controls->m_JoinBundlesButton, SIGNAL(clicked()), (QObject*) this, SLOT(JoinBundles()));
connect((QObject*) m_Controls->m_VarianceBox, SIGNAL(valueChanged(double)), (QObject*) this, SLOT(OnVarianceChanged(double)));
connect((QObject*) m_Controls->m_DistributionBox, SIGNAL(currentIndexChanged(int)), (QObject*) this, SLOT(OnDistributionChanged(int)));
connect((QObject*) m_Controls->m_FiberDensityBox, SIGNAL(valueChanged(int)), (QObject*) this, SLOT(OnFiberDensityChanged(int)));
connect((QObject*) m_Controls->m_FiberSamplingBox, SIGNAL(valueChanged(double)), (QObject*) this, SLOT(OnFiberSamplingChanged(double)));
connect((QObject*) m_Controls->m_TensionBox, SIGNAL(valueChanged(double)), (QObject*) this, SLOT(OnTensionChanged(double)));
connect((QObject*) m_Controls->m_ContinuityBox, SIGNAL(valueChanged(double)), (QObject*) this, SLOT(OnContinuityChanged(double)));
connect((QObject*) m_Controls->m_BiasBox, SIGNAL(valueChanged(double)), (QObject*) this, SLOT(OnBiasChanged(double)));
connect((QObject*) m_Controls->m_AddNoise, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(OnAddNoise(int)));
connect((QObject*) m_Controls->m_AddGhosts, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(OnAddGhosts(int)));
connect((QObject*) m_Controls->m_AddDistortions, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(OnAddDistortions(int)));
connect((QObject*) m_Controls->m_AddEddy, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(OnAddEddy(int)));
connect((QObject*) m_Controls->m_AddSpikes, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(OnAddSpikes(int)));
connect((QObject*) m_Controls->m_AddAliasing, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(OnAddAliasing(int)));
connect((QObject*) m_Controls->m_AddMotion, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(OnAddMotion(int)));
connect((QObject*) m_Controls->m_ConstantRadiusBox, SIGNAL(stateChanged(int)), (QObject*) this, SLOT(OnConstantRadius(int)));
connect((QObject*) m_Controls->m_CopyBundlesButton, SIGNAL(clicked()), (QObject*) this, SLOT(CopyBundles()));
connect((QObject*) m_Controls->m_TransformBundlesButton, SIGNAL(clicked()), (QObject*) this, SLOT(ApplyTransform()));
connect((QObject*) m_Controls->m_AlignOnGrid, SIGNAL(clicked()), (QObject*) this, SLOT(AlignOnGrid()));
connect((QObject*) m_Controls->m_Compartment1Box, SIGNAL(currentIndexChanged(int)), (QObject*) this, SLOT(Comp1ModelFrameVisibility(int)));
connect((QObject*) m_Controls->m_Compartment2Box, SIGNAL(currentIndexChanged(int)), (QObject*) this, SLOT(Comp2ModelFrameVisibility(int)));
connect((QObject*) m_Controls->m_Compartment3Box, SIGNAL(currentIndexChanged(int)), (QObject*) this, SLOT(Comp3ModelFrameVisibility(int)));
connect((QObject*) m_Controls->m_Compartment4Box, SIGNAL(currentIndexChanged(int)), (QObject*) this, SLOT(Comp4ModelFrameVisibility(int)));
connect((QObject*) m_Controls->m_AdvancedOptionsBox, SIGNAL( stateChanged(int)), (QObject*) this, SLOT(ShowAdvancedOptions(int)));
connect((QObject*) m_Controls->m_AdvancedOptionsBox_2, SIGNAL( stateChanged(int)), (QObject*) this, SLOT(ShowAdvancedOptions(int)));
connect((QObject*) m_Controls->m_SaveParametersButton, SIGNAL(clicked()), (QObject*) this, SLOT(SaveParameters()));
connect((QObject*) m_Controls->m_LoadParametersButton, SIGNAL(clicked()), (QObject*) this, SLOT(LoadParameters()));
connect((QObject*) m_Controls->m_OutputPathButton, SIGNAL(clicked()), (QObject*) this, SLOT(SetOutputPath()));
}
}
template< class ScalarType >
FiberfoxParameters< ScalarType > QmitkFiberfoxView::UpdateImageParameters()
{
FiberfoxParameters< ScalarType > parameters;
parameters.m_Misc.m_OutputPath = "";
parameters.m_Misc.m_CheckAdvancedFiberOptionsBox = m_Controls->m_AdvancedOptionsBox->isChecked();
parameters.m_Misc.m_CheckAdvancedSignalOptionsBox = m_Controls->m_AdvancedOptionsBox_2->isChecked();
parameters.m_Misc.m_CheckOutputVolumeFractionsBox = m_Controls->m_VolumeFractionsBox->isChecked();
string outputPath = m_Controls->m_SavePathEdit->text().toStdString();
if (outputPath.compare("-")!=0)
{
parameters.m_Misc.m_OutputPath = outputPath;
parameters.m_Misc.m_OutputPath += "/";
}
if (m_MaskImageNode.IsNotNull())
{
mitk::Image::Pointer mitkMaskImage = dynamic_cast<mitk::Image*>(m_MaskImageNode->GetData());
mitk::CastToItkImage<ItkUcharImgType>(mitkMaskImage, parameters.m_SignalGen.m_MaskImage);
itk::ImageDuplicator<ItkUcharImgType>::Pointer duplicator = itk::ImageDuplicator<ItkUcharImgType>::New();
duplicator->SetInputImage(parameters.m_SignalGen.m_MaskImage);
duplicator->Update();
parameters.m_SignalGen.m_MaskImage = duplicator->GetOutput();
}
if (m_SelectedDWI.IsNotNull()) // use parameters of selected DWI
{
mitk::DiffusionImage<short>::Pointer dwi = dynamic_cast<mitk::DiffusionImage<short>*>(m_SelectedDWI->GetData());
parameters.m_SignalGen.m_ImageRegion = dwi->GetVectorImage()->GetLargestPossibleRegion();
parameters.m_SignalGen.m_ImageSpacing = dwi->GetVectorImage()->GetSpacing();
parameters.m_SignalGen.m_ImageOrigin = dwi->GetVectorImage()->GetOrigin();
parameters.m_SignalGen.m_ImageDirection = dwi->GetVectorImage()->GetDirection();
parameters.m_SignalGen.m_Bvalue = dwi->GetReferenceBValue();
parameters.m_SignalGen.SetGradienDirections(dwi->GetDirections());
}
else if (m_SelectedImage.IsNotNull()) // use geometry of selected image
{
mitk::Image::Pointer img = dynamic_cast<mitk::Image*>(m_SelectedImage->GetData());
itk::Image< float, 3 >::Pointer itkImg = itk::Image< float, 3 >::New();
CastToItkImage< itk::Image< float, 3 > >(img, itkImg);
parameters.m_SignalGen.m_ImageRegion = itkImg->GetLargestPossibleRegion();
parameters.m_SignalGen.m_ImageSpacing = itkImg->GetSpacing();
parameters.m_SignalGen.m_ImageOrigin = itkImg->GetOrigin();
parameters.m_SignalGen.m_ImageDirection = itkImg->GetDirection();
parameters.m_SignalGen.SetNumWeightedVolumes(m_Controls->m_NumGradientsBox->value());
parameters.m_SignalGen.m_Bvalue = m_Controls->m_BvalueBox->value();
}
else // use GUI parameters
{
parameters.m_SignalGen.m_ImageRegion.SetSize(0, m_Controls->m_SizeX->value());
parameters.m_SignalGen.m_ImageRegion.SetSize(1, m_Controls->m_SizeY->value());
parameters.m_SignalGen.m_ImageRegion.SetSize(2, m_Controls->m_SizeZ->value());
parameters.m_SignalGen.m_ImageSpacing[0] = m_Controls->m_SpacingX->value();
parameters.m_SignalGen.m_ImageSpacing[1] = m_Controls->m_SpacingY->value();
parameters.m_SignalGen.m_ImageSpacing[2] = m_Controls->m_SpacingZ->value();
parameters.m_SignalGen.m_ImageOrigin[0] = parameters.m_SignalGen.m_ImageSpacing[0]/2;
parameters.m_SignalGen.m_ImageOrigin[1] = parameters.m_SignalGen.m_ImageSpacing[1]/2;
parameters.m_SignalGen.m_ImageOrigin[2] = parameters.m_SignalGen.m_ImageSpacing[2]/2;
parameters.m_SignalGen.m_ImageDirection.SetIdentity();
parameters.m_SignalGen.SetNumWeightedVolumes(m_Controls->m_NumGradientsBox->value());
parameters.m_SignalGen.m_Bvalue = m_Controls->m_BvalueBox->value();
parameters.m_SignalGen.GenerateGradientHalfShell();
}
// signal relaxation
parameters.m_SignalGen.m_DoSimulateRelaxation = m_Controls->m_RelaxationBox->isChecked();
parameters.m_SignalGen.m_SimulateKspaceAcquisition = parameters.m_SignalGen.m_DoSimulateRelaxation;
if (parameters.m_SignalGen.m_DoSimulateRelaxation && m_SelectedBundles.size()>0 )
parameters.m_Misc.m_ArtifactModelString += "_RELAX";
// N/2 ghosts
parameters.m_Misc.m_CheckAddGhostsBox = m_Controls->m_AddGhosts->isChecked();
if (m_Controls->m_AddGhosts->isChecked())
{
parameters.m_SignalGen.m_SimulateKspaceAcquisition = true;
parameters.m_Misc.m_ArtifactModelString += "_GHOST";
parameters.m_SignalGen.m_KspaceLineOffset = m_Controls->m_kOffsetBox->value();
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Ghost", DoubleProperty::New(parameters.m_SignalGen.m_KspaceLineOffset));
}
else
parameters.m_SignalGen.m_KspaceLineOffset = 0;
// Aliasing
parameters.m_Misc.m_CheckAddAliasingBox = m_Controls->m_AddAliasing->isChecked();
if (m_Controls->m_AddAliasing->isChecked())
{
parameters.m_SignalGen.m_SimulateKspaceAcquisition = true;
parameters.m_Misc.m_ArtifactModelString += "_ALIASING";
parameters.m_SignalGen.m_CroppingFactor = (100-m_Controls->m_WrapBox->value())/100;
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Aliasing", DoubleProperty::New(m_Controls->m_WrapBox->value()));
}
// Spikes
parameters.m_Misc.m_CheckAddSpikesBox = m_Controls->m_AddSpikes->isChecked();
if (m_Controls->m_AddSpikes->isChecked())
{
parameters.m_SignalGen.m_SimulateKspaceAcquisition = true;
parameters.m_SignalGen.m_Spikes = m_Controls->m_SpikeNumBox->value();
parameters.m_SignalGen.m_SpikeAmplitude = m_Controls->m_SpikeScaleBox->value();
parameters.m_Misc.m_ArtifactModelString += "_SPIKES";
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Spikes.Number", IntProperty::New(parameters.m_SignalGen.m_Spikes));
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Spikes.Amplitude", DoubleProperty::New(parameters.m_SignalGen.m_SpikeAmplitude));
}
// gibbs ringing
parameters.m_SignalGen.m_DoAddGibbsRinging = m_Controls->m_AddGibbsRinging->isChecked();
if (m_Controls->m_AddGibbsRinging->isChecked())
{
parameters.m_SignalGen.m_SimulateKspaceAcquisition = true;
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Ringing", BoolProperty::New(true));
parameters.m_Misc.m_ArtifactModelString += "_RINGING";
}
// add distortions
parameters.m_Misc.m_CheckAddDistortionsBox = m_Controls->m_AddDistortions->isChecked();
if (m_Controls->m_AddDistortions->isChecked() && m_Controls->m_FrequencyMapBox->GetSelectedNode().IsNotNull())
{
mitk::DataNode::Pointer fMapNode = m_Controls->m_FrequencyMapBox->GetSelectedNode();
mitk::Image* img = dynamic_cast<mitk::Image*>(fMapNode->GetData());
ItkDoubleImgType::Pointer itkImg = ItkDoubleImgType::New();
CastToItkImage< ItkDoubleImgType >(img, itkImg);
if (m_SelectedImage.IsNull()) // use geometry of frequency map
{
parameters.m_SignalGen.m_ImageRegion = itkImg->GetLargestPossibleRegion();
parameters.m_SignalGen.m_ImageSpacing = itkImg->GetSpacing();
parameters.m_SignalGen.m_ImageOrigin = itkImg->GetOrigin();
parameters.m_SignalGen.m_ImageDirection = itkImg->GetDirection();
}
if (parameters.m_SignalGen.m_ImageRegion.GetSize(0)==itkImg->GetLargestPossibleRegion().GetSize(0) &&
parameters.m_SignalGen.m_ImageRegion.GetSize(1)==itkImg->GetLargestPossibleRegion().GetSize(1) &&
parameters.m_SignalGen.m_ImageRegion.GetSize(2)==itkImg->GetLargestPossibleRegion().GetSize(2))
{
parameters.m_SignalGen.m_SimulateKspaceAcquisition = true;
itk::ImageDuplicator<ItkDoubleImgType>::Pointer duplicator = itk::ImageDuplicator<ItkDoubleImgType>::New();
duplicator->SetInputImage(itkImg);
duplicator->Update();
parameters.m_SignalGen.m_FrequencyMap = duplicator->GetOutput();
parameters.m_Misc.m_ArtifactModelString += "_DISTORTED";
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Distortions", BoolProperty::New(true));
}
}
parameters.m_SignalGen.m_EddyStrength = 0;
parameters.m_Misc.m_CheckAddEddyCurrentsBox = m_Controls->m_AddEddy->isChecked();
if (m_Controls->m_AddEddy->isChecked())
{
parameters.m_SignalGen.m_EddyStrength = m_Controls->m_EddyGradientStrength->value();
parameters.m_Misc.m_ArtifactModelString += "_EDDY";
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Eddy-strength", DoubleProperty::New(parameters.m_SignalGen.m_EddyStrength));
}
// Motion
parameters.m_SignalGen.m_DoAddMotion = m_Controls->m_AddMotion->isChecked();
parameters.m_SignalGen.m_DoRandomizeMotion = m_Controls->m_RandomMotion->isChecked();
parameters.m_SignalGen.m_Translation[0] = m_Controls->m_MaxTranslationBoxX->value();
parameters.m_SignalGen.m_Translation[1] = m_Controls->m_MaxTranslationBoxY->value();
parameters.m_SignalGen.m_Translation[2] = m_Controls->m_MaxTranslationBoxZ->value();
parameters.m_SignalGen.m_Rotation[0] = m_Controls->m_MaxRotationBoxX->value();
parameters.m_SignalGen.m_Rotation[1] = m_Controls->m_MaxRotationBoxY->value();
parameters.m_SignalGen.m_Rotation[2] = m_Controls->m_MaxRotationBoxZ->value();
if ( m_Controls->m_AddMotion->isChecked() && m_SelectedBundles.size()>0 )
{
parameters.m_Misc.m_ArtifactModelString += "_MOTION";
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Motion.Random", BoolProperty::New(parameters.m_SignalGen.m_DoRandomizeMotion));
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Motion.Translation-x", DoubleProperty::New(parameters.m_SignalGen.m_Translation[0]));
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Motion.Translation-y", DoubleProperty::New(parameters.m_SignalGen.m_Translation[1]));
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Motion.Translation-z", DoubleProperty::New(parameters.m_SignalGen.m_Translation[2]));
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Motion.Rotation-x", DoubleProperty::New(parameters.m_SignalGen.m_Rotation[0]));
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Motion.Rotation-y", DoubleProperty::New(parameters.m_SignalGen.m_Rotation[1]));
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Motion.Rotation-z", DoubleProperty::New(parameters.m_SignalGen.m_Rotation[2]));
}
// other imaging parameters
parameters.m_SignalGen.m_tLine = m_Controls->m_LineReadoutTimeBox->value();
parameters.m_SignalGen.m_tInhom = m_Controls->m_T2starBox->value();
parameters.m_SignalGen.m_tEcho = m_Controls->m_TEbox->value();
parameters.m_SignalGen.m_DoDisablePartialVolume = m_Controls->m_EnforcePureFiberVoxelsBox->isChecked();
parameters.m_SignalGen.m_AxonRadius = m_Controls->m_FiberRadius->value();
parameters.m_SignalGen.m_SignalScale = m_Controls->m_SignalScaleBox->value();
// adjust echo time if needed
if ( parameters.m_SignalGen.m_tEcho < parameters.m_SignalGen.m_ImageRegion.GetSize(1)*parameters.m_SignalGen.m_tLine )
{
this->m_Controls->m_TEbox->setValue( parameters.m_SignalGen.m_ImageRegion.GetSize(1)*parameters.m_SignalGen.m_tLine );
parameters.m_SignalGen.m_tEcho = m_Controls->m_TEbox->value();
QMessageBox::information( NULL, "Warning", "Echo time is too short! Time not sufficient to read slice. Automaticall adjusted to "+QString::number(parameters.m_SignalGen.m_tEcho)+" ms");
}
// Noise
parameters.m_Misc.m_CheckAddNoiseBox = m_Controls->m_AddNoise->isChecked();
if (m_Controls->m_AddNoise->isChecked())
{
double noiseVariance = m_Controls->m_NoiseLevel->value();
{
switch (m_Controls->m_NoiseDistributionBox->currentIndex())
{
case 0:
{
parameters.m_NoiseModel = new mitk::RicianNoiseModel<ScalarType>();
parameters.m_Misc.m_ArtifactModelString += "_RICIAN-";
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Noise-Distribution", StringProperty::New("Rician"));
break;
}
case 1:
{
parameters.m_NoiseModel = new mitk::ChiSquareNoiseModel<ScalarType>();
parameters.m_Misc.m_ArtifactModelString += "_CHISQUARED-";
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Noise-Distribution", StringProperty::New("Chi-squared"));
break;
}
default:
{
parameters.m_NoiseModel = new mitk::RicianNoiseModel<ScalarType>();
parameters.m_Misc.m_ArtifactModelString += "_RICIAN-";
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Noise-Distribution", StringProperty::New("Rician"));
}
}
}
parameters.m_NoiseModel->SetNoiseVariance(noiseVariance);
parameters.m_Misc.m_ArtifactModelString += QString::number(noiseVariance).toStdString();
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Noise-Variance", DoubleProperty::New(noiseVariance));
}
// adjusting line readout time to the adapted image size needed for the DFT
unsigned int y = parameters.m_SignalGen.m_ImageRegion.GetSize(1);
y += y%2;
if ( y>parameters.m_SignalGen.m_ImageRegion.GetSize(1) )
parameters.m_SignalGen.m_tLine *= (double)parameters.m_SignalGen.m_ImageRegion.GetSize(1)/y;
// signal models
{
// compartment 1
switch (m_Controls->m_Compartment1Box->currentIndex())
{
case 0:
{
mitk::StickModel<ScalarType>* model = new mitk::StickModel<ScalarType>();
model->SetGradientList(parameters.m_SignalGen.GetGradientDirections());
model->SetBvalue(parameters.m_SignalGen.m_Bvalue);
model->SetDiffusivity(m_Controls->m_StickWidget1->GetD());
model->SetT2(m_Controls->m_StickWidget1->GetT2());
model->m_CompartmentId = 1;
parameters.m_FiberModelList.push_back(model);
parameters.m_Misc.m_SignalModelString += "Stick";
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.Description", StringProperty::New("Intra-axonal compartment") );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.Model", StringProperty::New("Stick") );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.D", DoubleProperty::New(m_Controls->m_StickWidget1->GetD()) );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.T2", DoubleProperty::New(model->GetT2()) );
break;
}
case 1:
{
mitk::TensorModel<ScalarType>* model = new mitk::TensorModel<ScalarType>();
model->SetGradientList(parameters.m_SignalGen.GetGradientDirections());
model->SetBvalue(parameters.m_SignalGen.m_Bvalue);
model->SetDiffusivity1(m_Controls->m_ZeppelinWidget1->GetD1());
model->SetDiffusivity2(m_Controls->m_ZeppelinWidget1->GetD2());
model->SetDiffusivity3(m_Controls->m_ZeppelinWidget1->GetD2());
model->SetT2(m_Controls->m_ZeppelinWidget1->GetT2());
model->m_CompartmentId = 1;
parameters.m_FiberModelList.push_back(model);
parameters.m_Misc.m_SignalModelString += "Zeppelin";
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.Description", StringProperty::New("Intra-axonal compartment") );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.Model", StringProperty::New("Zeppelin") );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.D1", DoubleProperty::New(m_Controls->m_ZeppelinWidget1->GetD1()) );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.D2", DoubleProperty::New(m_Controls->m_ZeppelinWidget1->GetD2()) );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.T2", DoubleProperty::New(model->GetT2()) );
break;
}
case 2:
{
mitk::TensorModel<ScalarType>* model = new mitk::TensorModel<ScalarType>();
model->SetGradientList(parameters.m_SignalGen.GetGradientDirections());
model->SetBvalue(parameters.m_SignalGen.m_Bvalue);
model->SetDiffusivity1(m_Controls->m_TensorWidget1->GetD1());
model->SetDiffusivity2(m_Controls->m_TensorWidget1->GetD2());
model->SetDiffusivity3(m_Controls->m_TensorWidget1->GetD3());
model->SetT2(m_Controls->m_TensorWidget1->GetT2());
model->m_CompartmentId = 1;
parameters.m_FiberModelList.push_back(model);
parameters.m_Misc.m_SignalModelString += "Tensor";
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.Description", StringProperty::New("Intra-axonal compartment") );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.Model", StringProperty::New("Tensor") );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.D1", DoubleProperty::New(m_Controls->m_TensorWidget1->GetD1()) );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.D2", DoubleProperty::New(m_Controls->m_TensorWidget1->GetD2()) );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.D3", DoubleProperty::New(m_Controls->m_TensorWidget1->GetD3()) );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.T2", DoubleProperty::New(model->GetT2()) );
break;
}
case 3:
{
mitk::RawShModel<ScalarType>* model = new mitk::RawShModel<ScalarType>();
parameters.m_SignalGen.m_DoSimulateRelaxation = false;
model->SetGradientList(parameters.m_SignalGen.GetGradientDirections());
model->SetMaxNumKernels(m_Controls->m_PrototypeWidget1->GetNumberOfSamples());
model->SetFaRange(m_Controls->m_PrototypeWidget1->GetMinFa(), m_Controls->m_PrototypeWidget1->GetMaxFa());
model->SetAdcRange(m_Controls->m_PrototypeWidget1->GetMinAdc(), m_Controls->m_PrototypeWidget1->GetMaxAdc());
model->m_CompartmentId = 1;
parameters.m_FiberModelList.push_back(model);
parameters.m_Misc.m_SignalModelString += "Prototype";
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.Description", StringProperty::New("Intra-axonal compartment") );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment1.Model", StringProperty::New("Prototype") );
break;
}
}
// compartment 2
switch (m_Controls->m_Compartment2Box->currentIndex())
{
case 0:
break;
case 1:
{
mitk::StickModel<ScalarType>* model = new mitk::StickModel<ScalarType>();
model->SetGradientList(parameters.m_SignalGen.GetGradientDirections());
model->SetBvalue(parameters.m_SignalGen.m_Bvalue);
model->SetDiffusivity(m_Controls->m_StickWidget2->GetD());
model->SetT2(m_Controls->m_StickWidget2->GetT2());
model->m_CompartmentId = 2;
parameters.m_FiberModelList.push_back(model);
parameters.m_Misc.m_SignalModelString += "Stick";
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.Description", StringProperty::New("Inter-axonal compartment") );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.Model", StringProperty::New("Stick") );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.D", DoubleProperty::New(m_Controls->m_StickWidget2->GetD()) );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.T2", DoubleProperty::New(model->GetT2()) );
break;
}
case 2:
{
mitk::TensorModel<ScalarType>* model = new mitk::TensorModel<ScalarType>();
model->SetGradientList(parameters.m_SignalGen.GetGradientDirections());
model->SetBvalue(parameters.m_SignalGen.m_Bvalue);
model->SetDiffusivity1(m_Controls->m_ZeppelinWidget2->GetD1());
model->SetDiffusivity2(m_Controls->m_ZeppelinWidget2->GetD2());
model->SetDiffusivity3(m_Controls->m_ZeppelinWidget2->GetD2());
model->SetT2(m_Controls->m_ZeppelinWidget2->GetT2());
model->m_CompartmentId = 2;
parameters.m_FiberModelList.push_back(model);
parameters.m_Misc.m_SignalModelString += "Zeppelin";
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.Description", StringProperty::New("Inter-axonal compartment") );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.Model", StringProperty::New("Zeppelin") );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.D1", DoubleProperty::New(m_Controls->m_ZeppelinWidget2->GetD1()) );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.D2", DoubleProperty::New(m_Controls->m_ZeppelinWidget2->GetD2()) );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.T2", DoubleProperty::New(model->GetT2()) );
break;
}
case 3:
{
mitk::TensorModel<ScalarType>* model = new mitk::TensorModel<ScalarType>();
model->SetGradientList(parameters.m_SignalGen.GetGradientDirections());
model->SetBvalue(parameters.m_SignalGen.m_Bvalue);
model->SetDiffusivity1(m_Controls->m_TensorWidget2->GetD1());
model->SetDiffusivity2(m_Controls->m_TensorWidget2->GetD2());
model->SetDiffusivity3(m_Controls->m_TensorWidget2->GetD3());
model->SetT2(m_Controls->m_TensorWidget2->GetT2());
model->m_CompartmentId = 2;
parameters.m_FiberModelList.push_back(model);
parameters.m_Misc.m_SignalModelString += "Tensor";
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.Description", StringProperty::New("Inter-axonal compartment") );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.Model", StringProperty::New("Tensor") );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.D1", DoubleProperty::New(m_Controls->m_TensorWidget2->GetD1()) );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.D2", DoubleProperty::New(m_Controls->m_TensorWidget2->GetD2()) );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.D3", DoubleProperty::New(m_Controls->m_TensorWidget2->GetD3()) );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment2.T2", DoubleProperty::New(model->GetT2()) );
break;
}
}
// compartment 3
switch (m_Controls->m_Compartment3Box->currentIndex())
{
case 0:
{
mitk::BallModel<ScalarType>* model = new mitk::BallModel<ScalarType>();
model->SetGradientList(parameters.m_SignalGen.GetGradientDirections());
model->SetBvalue(parameters.m_SignalGen.m_Bvalue);
model->SetDiffusivity(m_Controls->m_BallWidget1->GetD());
model->SetT2(m_Controls->m_BallWidget1->GetT2());
model->m_CompartmentId = 3;
parameters.m_NonFiberModelList.push_back(model);
parameters.m_Misc.m_SignalModelString += "Ball";
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.Description", StringProperty::New("Extra-axonal compartment 1") );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.Model", StringProperty::New("Ball") );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.D", DoubleProperty::New(m_Controls->m_BallWidget1->GetD()) );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.T2", DoubleProperty::New(model->GetT2()) );
break;
}
case 1:
{
mitk::AstroStickModel<ScalarType>* model = new mitk::AstroStickModel<ScalarType>();
model->SetGradientList(parameters.m_SignalGen.GetGradientDirections());
model->SetBvalue(parameters.m_SignalGen.m_Bvalue);
model->SetDiffusivity(m_Controls->m_AstrosticksWidget1->GetD());
model->SetT2(m_Controls->m_AstrosticksWidget1->GetT2());
model->SetRandomizeSticks(m_Controls->m_AstrosticksWidget1->GetRandomizeSticks());
model->m_CompartmentId = 3;
parameters.m_NonFiberModelList.push_back(model);
parameters.m_Misc.m_SignalModelString += "Astrosticks";
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.Description", StringProperty::New("Extra-axonal compartment 1") );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.Model", StringProperty::New("Astrosticks") );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.D", DoubleProperty::New(m_Controls->m_AstrosticksWidget1->GetD()) );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.T2", DoubleProperty::New(model->GetT2()) );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.RandomSticks", BoolProperty::New(m_Controls->m_AstrosticksWidget1->GetRandomizeSticks()) );
break;
}
case 2:
{
mitk::DotModel<ScalarType>* model = new mitk::DotModel<ScalarType>();
model->SetGradientList(parameters.m_SignalGen.GetGradientDirections());
model->SetT2(m_Controls->m_DotWidget1->GetT2());
model->m_CompartmentId = 3;
parameters.m_NonFiberModelList.push_back(model);
parameters.m_Misc.m_SignalModelString += "Dot";
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.Description", StringProperty::New("Extra-axonal compartment 1") );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.Model", StringProperty::New("Dot") );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.T2", DoubleProperty::New(model->GetT2()) );
break;
}
case 3:
{
mitk::RawShModel<ScalarType>* model = new mitk::RawShModel<ScalarType>();
parameters.m_SignalGen.m_DoSimulateRelaxation = false;
model->SetGradientList(parameters.m_SignalGen.GetGradientDirections());
model->SetMaxNumKernels(m_Controls->m_PrototypeWidget3->GetNumberOfSamples());
model->SetFaRange(m_Controls->m_PrototypeWidget3->GetMinFa(), m_Controls->m_PrototypeWidget3->GetMaxFa());
model->SetAdcRange(m_Controls->m_PrototypeWidget3->GetMinAdc(), m_Controls->m_PrototypeWidget3->GetMaxAdc());
model->m_CompartmentId = 3;
parameters.m_NonFiberModelList.push_back(model);
parameters.m_Misc.m_SignalModelString += "Prototype";
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.Description", StringProperty::New("Extra-axonal compartment 1") );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment3.Model", StringProperty::New("Prototype") );
break;
}
}
// compartment 4
ItkDoubleImgType::Pointer comp4VolumeImage = NULL;
ItkDoubleImgType::Pointer comp3VolumeImage = NULL;
if (m_Controls->m_Compartment4Box->currentIndex()>0)
{
mitk::DataNode::Pointer volumeNode = m_Controls->m_Comp4VolumeFraction->GetSelectedNode();
if (volumeNode.IsNull())
{
QMessageBox::information( NULL, "Information", "No volume fraction image selected! Second extra-axonal compartment has been disabled for this simultation.");
MITK_WARN << "No volume fraction image selected! Second extra-axonal compartment has been disabled.";
}
else
{
MITK_INFO << "Rescaling volume fraction image...";
comp4VolumeImage = ItkDoubleImgType::New();
mitk::Image* img = dynamic_cast<mitk::Image*>(volumeNode->GetData());
CastToItkImage< ItkDoubleImgType >(img, comp4VolumeImage);
double max = itk::NumericTraits<double>::min();
double min = itk::NumericTraits<double>::max();
itk::ImageRegionIterator< ItkDoubleImgType > it(comp4VolumeImage, comp4VolumeImage->GetLargestPossibleRegion());
while(!it.IsAtEnd())
{
if (parameters.m_SignalGen.m_MaskImage.IsNotNull() && parameters.m_SignalGen.m_MaskImage->GetPixel(it.GetIndex())<=0)
{
it.Set(0.0);
++it;
continue;
}
if (it.Get()>max)
max = it.Get();
if (it.Get()<min)
min = it.Get();
++it;
}
itk::ShiftScaleImageFilter< ItkDoubleImgType, ItkDoubleImgType >::Pointer scaler = itk::ShiftScaleImageFilter< ItkDoubleImgType, ItkDoubleImgType >::New();
scaler->SetInput(comp4VolumeImage);
scaler->SetShift(-min);
scaler->SetScale(1.0/(max-min));
scaler->Update();
comp4VolumeImage = scaler->GetOutput();
// itk::ImageFileWriter< ItkDoubleImgType >::Pointer wr = itk::ImageFileWriter< ItkDoubleImgType >::New();
// wr->SetInput(comp4VolumeImage);
// wr->SetFileName("/local/comp4.nrrd");
// wr->Update();
// if (max>1 || min<0) // are volume fractions between 0 and 1?
// {
// itk::RescaleIntensityImageFilter<ItkDoubleImgType,ItkDoubleImgType>::Pointer rescaler = itk::RescaleIntensityImageFilter<ItkDoubleImgType,ItkDoubleImgType>::New();
// rescaler->SetInput(0, comp4VolumeImage);
// rescaler->SetOutputMaximum(1);
// rescaler->SetOutputMinimum(0);
// rescaler->Update();
// comp4VolumeImage = rescaler->GetOutput();
// }
itk::InvertIntensityImageFilter< ItkDoubleImgType, ItkDoubleImgType >::Pointer inverter = itk::InvertIntensityImageFilter< ItkDoubleImgType, ItkDoubleImgType >::New();
inverter->SetMaximum(1.0);
inverter->SetInput(comp4VolumeImage);
inverter->Update();
comp3VolumeImage = inverter->GetOutput();
}
}
if (comp4VolumeImage.IsNotNull())
{
switch (m_Controls->m_Compartment4Box->currentIndex())
{
case 0:
break;
case 1:
{
mitk::BallModel<ScalarType>* model = new mitk::BallModel<ScalarType>();
model->SetGradientList(parameters.m_SignalGen.GetGradientDirections());
model->SetBvalue(parameters.m_SignalGen.m_Bvalue);
model->SetDiffusivity(m_Controls->m_BallWidget2->GetD());
model->SetT2(m_Controls->m_BallWidget2->GetT2());
model->SetVolumeFractionImage(comp4VolumeImage);
model->m_CompartmentId = 4;
parameters.m_NonFiberModelList.back()->SetVolumeFractionImage(comp3VolumeImage);
parameters.m_NonFiberModelList.push_back(model);
parameters.m_Misc.m_SignalModelString += "Ball";
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.Description", StringProperty::New("Extra-axonal compartment 2") );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.Model", StringProperty::New("Ball") );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.D", DoubleProperty::New(m_Controls->m_BallWidget2->GetD()) );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.T2", DoubleProperty::New(model->GetT2()) );
break;
}
case 2:
{
mitk::AstroStickModel<ScalarType>* model = new mitk::AstroStickModel<ScalarType>();
model->SetGradientList(parameters.m_SignalGen.GetGradientDirections());
model->SetBvalue(parameters.m_SignalGen.m_Bvalue);
model->SetDiffusivity(m_Controls->m_AstrosticksWidget2->GetD());
model->SetT2(m_Controls->m_AstrosticksWidget2->GetT2());
model->SetRandomizeSticks(m_Controls->m_AstrosticksWidget2->GetRandomizeSticks());
parameters.m_NonFiberModelList.back()->SetVolumeFractionImage(comp3VolumeImage);
model->SetVolumeFractionImage(comp4VolumeImage);
model->m_CompartmentId = 4;
parameters.m_NonFiberModelList.push_back(model);
parameters.m_Misc.m_SignalModelString += "Astrosticks";
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.Description", StringProperty::New("Extra-axonal compartment 2") );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.Model", StringProperty::New("Astrosticks") );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.D", DoubleProperty::New(m_Controls->m_AstrosticksWidget2->GetD()) );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.T2", DoubleProperty::New(model->GetT2()) );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.RandomSticks", BoolProperty::New(m_Controls->m_AstrosticksWidget2->GetRandomizeSticks()) );
break;
}
case 3:
{
mitk::DotModel<ScalarType>* model = new mitk::DotModel<ScalarType>();
model->SetGradientList(parameters.m_SignalGen.GetGradientDirections());
model->SetT2(m_Controls->m_DotWidget2->GetT2());
model->SetVolumeFractionImage(comp4VolumeImage);
model->m_CompartmentId = 4;
parameters.m_NonFiberModelList.back()->SetVolumeFractionImage(comp3VolumeImage);
parameters.m_NonFiberModelList.push_back(model);
parameters.m_Misc.m_SignalModelString += "Dot";
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.Description", StringProperty::New("Extra-axonal compartment 2") );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.Model", StringProperty::New("Dot") );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.T2", DoubleProperty::New(model->GetT2()) );
break;
}
case 4:
{
mitk::RawShModel<ScalarType>* model = new mitk::RawShModel<ScalarType>();
parameters.m_SignalGen.m_DoSimulateRelaxation = false;
model->SetGradientList(parameters.m_SignalGen.GetGradientDirections());
model->SetMaxNumKernels(m_Controls->m_PrototypeWidget4->GetNumberOfSamples());
model->SetFaRange(m_Controls->m_PrototypeWidget4->GetMinFa(), m_Controls->m_PrototypeWidget4->GetMaxFa());
model->SetAdcRange(m_Controls->m_PrototypeWidget4->GetMinAdc(), m_Controls->m_PrototypeWidget4->GetMaxAdc());
model->SetVolumeFractionImage(comp4VolumeImage);
model->m_CompartmentId = 4;
parameters.m_NonFiberModelList.back()->SetVolumeFractionImage(comp3VolumeImage);
parameters.m_NonFiberModelList.push_back(model);
parameters.m_Misc.m_SignalModelString += "Prototype";
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.Description", StringProperty::New("Extra-axonal compartment 2") );
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Compartment4.Model", StringProperty::New("Prototype") );
break;
}
}
}
}
parameters.m_SignalGen.m_FiberSeparationThreshold = m_Controls->m_SeparationAngleBox->value();
switch (m_Controls->m_DiffusionDirectionBox->currentIndex())
{
case 0:
parameters.m_SignalGen.m_DiffusionDirectionMode = SignalGenerationParameters::FIBER_TANGENT_DIRECTIONS;
break;
case 1:
parameters.m_SignalGen.m_DiffusionDirectionMode = SignalGenerationParameters::MAIN_FIBER_DIRECTIONS;
break;
case 2:
parameters.m_SignalGen.m_DiffusionDirectionMode = SignalGenerationParameters::RANDOM_DIRECTIONS;
parameters.m_SignalGen.m_DoAddMotion = false;
parameters.m_SignalGen.m_DoAddGibbsRinging = false;
parameters.m_SignalGen.m_KspaceLineOffset = 0.0;
parameters.m_SignalGen.m_FrequencyMap = NULL;
parameters.m_SignalGen.m_CroppingFactor = 1.0;
parameters.m_SignalGen.m_EddyStrength = 0;
break;
default:
parameters.m_SignalGen.m_DiffusionDirectionMode = SignalGenerationParameters::FIBER_TANGENT_DIRECTIONS;
}
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.SignalScale", IntProperty::New(parameters.m_SignalGen.m_SignalScale));
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.FiberRadius", IntProperty::New(parameters.m_SignalGen.m_AxonRadius));
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Tinhom", DoubleProperty::New(parameters.m_SignalGen.m_tInhom));
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Tline", DoubleProperty::New(parameters.m_SignalGen.m_tLine));
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.TE", DoubleProperty::New(parameters.m_SignalGen.m_tEcho));
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.b-value", DoubleProperty::New(parameters.m_SignalGen.m_Bvalue));
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.NoPartialVolume", BoolProperty::New(parameters.m_SignalGen.m_DoDisablePartialVolume));
parameters.m_Misc.m_ResultNode->AddProperty("Fiberfox.Relaxation", BoolProperty::New(parameters.m_SignalGen.m_DoSimulateRelaxation));
parameters.m_Misc.m_ResultNode->AddProperty("binary", BoolProperty::New(false));
parameters.m_Misc.m_CheckRealTimeFibersBox = m_Controls->m_RealTimeFibers->isChecked();
parameters.m_Misc.m_CheckAdvancedFiberOptionsBox = m_Controls->m_AdvancedOptionsBox->isChecked();
parameters.m_Misc.m_CheckIncludeFiducialsBox = m_Controls->m_IncludeFiducials->isChecked();
parameters.m_Misc.m_CheckConstantRadiusBox = m_Controls->m_ConstantRadiusBox->isChecked();
switch(m_Controls->m_DistributionBox->currentIndex())
{
case 0:
parameters.m_FiberGen.m_Distribution = FiberGenerationParameters::DISTRIBUTE_UNIFORM;
break;
case 1:
parameters.m_FiberGen.m_Distribution = FiberGenerationParameters::DISTRIBUTE_GAUSSIAN;
break;
default:
parameters.m_FiberGen.m_Distribution = FiberGenerationParameters::DISTRIBUTE_UNIFORM;
}
parameters.m_FiberGen.m_Variance = m_Controls->m_VarianceBox->value();
parameters.m_FiberGen.m_Density = m_Controls->m_FiberDensityBox->value();
parameters.m_FiberGen.m_Sampling = m_Controls->m_FiberSamplingBox->value();
parameters.m_FiberGen.m_Tension = m_Controls->m_TensionBox->value();
parameters.m_FiberGen.m_Continuity = m_Controls->m_ContinuityBox->value();
parameters.m_FiberGen.m_Bias = m_Controls->m_BiasBox->value();
parameters.m_FiberGen.m_Rotation[0] = m_Controls->m_XrotBox->value();
parameters.m_FiberGen.m_Rotation[1] = m_Controls->m_YrotBox->value();
parameters.m_FiberGen.m_Rotation[2] = m_Controls->m_ZrotBox->value();
parameters.m_FiberGen.m_Translation[0] = m_Controls->m_XtransBox->value();
parameters.m_FiberGen.m_Translation[1] = m_Controls->m_YtransBox->value();
parameters.m_FiberGen.m_Translation[2] = m_Controls->m_ZtransBox->value();
parameters.m_FiberGen.m_Scale[0] = m_Controls->m_XscaleBox->value();
parameters.m_FiberGen.m_Scale[1] = m_Controls->m_YscaleBox->value();
parameters.m_FiberGen.m_Scale[2] = m_Controls->m_ZscaleBox->value();
return parameters;
}
void QmitkFiberfoxView::SaveParameters()
{
FiberfoxParameters<> ffParamaters = UpdateImageParameters<double>();
QString filename = QFileDialog::getSaveFileName(
0,
tr("Save Parameters"),
m_ParameterFile,
tr("Fiberfox Parameters (*.ffp)") );
bool ok = true;
bool first = true;
bool dosampling = false;
mitk::DiffusionImage<short>::Pointer diffImg;
itk::Image< itk::DiffusionTensor3D< double >, 3 >::Pointer tensorImage = NULL;
const int shOrder = 2;
typedef itk::AnalyticalDiffusionQballReconstructionImageFilter<short,short,float,shOrder,QBALL_ODFSIZE> QballFilterType;
QballFilterType::CoefficientImageType::Pointer itkFeatureImage = NULL;
ItkDoubleImgType::Pointer adcImage = NULL;
for (unsigned int i=0; i<ffParamaters.m_FiberModelList.size()+ffParamaters.m_NonFiberModelList.size(); i++)
{
mitk::RawShModel<>* model = NULL;
if (i<ffParamaters.m_FiberModelList.size())
model = dynamic_cast< mitk::RawShModel<>* >(ffParamaters.m_FiberModelList.at(i));
else
model = dynamic_cast< mitk::RawShModel<>* >(ffParamaters.m_NonFiberModelList.at(i-ffParamaters.m_FiberModelList.size()));
if (model!=0 && model->GetNumberOfKernels()<=0)
{
if (first==true)
{
if (QMessageBox::question(NULL, "Prototype signal sampling", "Do you want to sample prototype signals from the selected diffusion-weighted imag and save them?",QMessageBox::Yes,QMessageBox::No)==QMessageBox::Yes)
dosampling = true;
first = false;
if (dosampling && m_SelectedDWI.IsNull())
{
QMessageBox::information(NULL, "Parameter file not saved", "No diffusion-weighted image selected to sample signal from.");
return;
}
else if (dosampling)
{
diffImg = dynamic_cast<mitk::DiffusionImage<short>*>(m_SelectedDWI->GetData());
typedef itk::DiffusionTensor3DReconstructionImageFilter< short, short, double > TensorReconstructionImageFilterType;
TensorReconstructionImageFilterType::Pointer filter = TensorReconstructionImageFilterType::New();
filter->SetGradientImage( diffImg->GetDirections(), diffImg->GetVectorImage() );
filter->SetBValue(diffImg->GetReferenceBValue());
filter->Update();
tensorImage = filter->GetOutput();
const int NumCoeffs = (shOrder*shOrder + shOrder + 2)/2 + shOrder;
QballFilterType::Pointer qballfilter = QballFilterType::New();
qballfilter->SetGradientImage( diffImg->GetDirections(), diffImg->GetVectorImage() );
qballfilter->SetBValue(diffImg->GetReferenceBValue());
qballfilter->SetLambda(0.006);
qballfilter->SetNormalizationMethod(QballFilterType::QBAR_RAW_SIGNAL);
qballfilter->Update();
itkFeatureImage = qballfilter->GetCoefficientImage();
itk::AdcImageFilter< short, double >::Pointer adcFilter = itk::AdcImageFilter< short, double >::New();
adcFilter->SetInput(diffImg->GetVectorImage());
adcFilter->SetGradientDirections(diffImg->GetDirections());
adcFilter->SetB_value(diffImg->GetReferenceBValue());
adcFilter->Update();
adcImage = adcFilter->GetOutput();
}
}
if (dosampling && m_SelectedDWI.IsNotNull())
{
ok = model->SampleKernels(diffImg, ffParamaters.m_SignalGen.m_MaskImage, tensorImage, itkFeatureImage, adcImage);
if (!ok)
{
QMessageBox::information( NULL, "Parameter file not saved", "No valid prototype signals could be sampled.");
return;
}
}
}
}
ffParamaters.SaveParameters(filename.toStdString());
m_ParameterFile = filename;
}
void QmitkFiberfoxView::LoadParameters()
{
QString filename = QFileDialog::getOpenFileName(0, tr("Load Parameters"), QString(itksys::SystemTools::GetFilenamePath(m_ParameterFile.toStdString()).c_str()), tr("Fiberfox Parameters (*.ffp)") );
if(filename.isEmpty() || filename.isNull())
return;
m_ParameterFile = filename;
FiberfoxParameters<> parameters;
parameters.LoadParameters(filename.toStdString());
m_Controls->m_RealTimeFibers->setChecked(parameters.m_Misc.m_CheckRealTimeFibersBox);
m_Controls->m_AdvancedOptionsBox->setChecked(parameters.m_Misc.m_CheckAdvancedFiberOptionsBox);
m_Controls->m_IncludeFiducials->setChecked(parameters.m_Misc.m_CheckIncludeFiducialsBox);
m_Controls->m_ConstantRadiusBox->setChecked(parameters.m_Misc.m_CheckConstantRadiusBox);
m_Controls->m_DistributionBox->setCurrentIndex(parameters.m_FiberGen.m_Distribution);
m_Controls->m_VarianceBox->setValue(parameters.m_FiberGen.m_Variance);
m_Controls->m_FiberDensityBox->setValue(parameters.m_FiberGen.m_Density);
m_Controls->m_FiberSamplingBox->setValue(parameters.m_FiberGen.m_Sampling);
m_Controls->m_TensionBox->setValue(parameters.m_FiberGen.m_Tension);
m_Controls->m_ContinuityBox->setValue(parameters.m_FiberGen.m_Continuity);
m_Controls->m_BiasBox->setValue(parameters.m_FiberGen.m_Bias);
m_Controls->m_XrotBox->setValue(parameters.m_FiberGen.m_Rotation[0]);
m_Controls->m_YrotBox->setValue(parameters.m_FiberGen.m_Rotation[1]);
m_Controls->m_ZrotBox->setValue(parameters.m_FiberGen.m_Rotation[2]);
m_Controls->m_XtransBox->setValue(parameters.m_FiberGen.m_Translation[0]);
m_Controls->m_YtransBox->setValue(parameters.m_FiberGen.m_Translation[1]);
m_Controls->m_ZtransBox->setValue(parameters.m_FiberGen.m_Translation[2]);
m_Controls->m_XscaleBox->setValue(parameters.m_FiberGen.m_Scale[0]);
m_Controls->m_YscaleBox->setValue(parameters.m_FiberGen.m_Scale[1]);
m_Controls->m_ZscaleBox->setValue(parameters.m_FiberGen.m_Scale[2]);
// image generation parameters
m_Controls->m_SizeX->setValue(parameters.m_SignalGen.m_ImageRegion.GetSize(0));
m_Controls->m_SizeY->setValue(parameters.m_SignalGen.m_ImageRegion.GetSize(1));
m_Controls->m_SizeZ->setValue(parameters.m_SignalGen.m_ImageRegion.GetSize(2));
m_Controls->m_SpacingX->setValue(parameters.m_SignalGen.m_ImageSpacing[0]);
m_Controls->m_SpacingY->setValue(parameters.m_SignalGen.m_ImageSpacing[1]);
m_Controls->m_SpacingZ->setValue(parameters.m_SignalGen.m_ImageSpacing[2]);
m_Controls->m_NumGradientsBox->setValue(parameters.m_SignalGen.GetNumWeightedVolumes());
m_Controls->m_BvalueBox->setValue(parameters.m_SignalGen.m_Bvalue);
m_Controls->m_SignalScaleBox->setValue(parameters.m_SignalGen.m_SignalScale);
m_Controls->m_TEbox->setValue(parameters.m_SignalGen.m_tEcho);
m_Controls->m_LineReadoutTimeBox->setValue(parameters.m_SignalGen.m_tLine);
m_Controls->m_T2starBox->setValue(parameters.m_SignalGen.m_tInhom);
m_Controls->m_FiberRadius->setValue(parameters.m_SignalGen.m_AxonRadius);
m_Controls->m_RelaxationBox->setChecked(parameters.m_SignalGen.m_DoSimulateRelaxation);
m_Controls->m_EnforcePureFiberVoxelsBox->setChecked(parameters.m_SignalGen.m_DoDisablePartialVolume);
if (parameters.m_NoiseModel!=NULL)
{
m_Controls->m_AddNoise->setChecked(parameters.m_Misc.m_CheckAddNoiseBox);
if (dynamic_cast<mitk::RicianNoiseModel<double>*>(parameters.m_NoiseModel))
m_Controls->m_NoiseDistributionBox->setCurrentIndex(0);
else if (dynamic_cast<mitk::ChiSquareNoiseModel<double>*>(parameters.m_NoiseModel))
m_Controls->m_NoiseDistributionBox->setCurrentIndex(1);
m_Controls->m_NoiseLevel->setValue(parameters.m_NoiseModel->GetNoiseVariance());
}
else
m_Controls->m_AddNoise->setChecked(false);
m_Controls->m_VolumeFractionsBox->setChecked(parameters.m_Misc.m_CheckOutputVolumeFractionsBox);
m_Controls->m_AdvancedOptionsBox_2->setChecked(parameters.m_Misc.m_CheckAdvancedSignalOptionsBox);
m_Controls->m_AddGhosts->setChecked(parameters.m_Misc.m_CheckAddGhostsBox);
m_Controls->m_AddAliasing->setChecked(parameters.m_Misc.m_CheckAddAliasingBox);
m_Controls->m_AddDistortions->setChecked(parameters.m_Misc.m_CheckAddDistortionsBox);
m_Controls->m_AddSpikes->setChecked(parameters.m_Misc.m_CheckAddSpikesBox);
m_Controls->m_AddEddy->setChecked(parameters.m_Misc.m_CheckAddEddyCurrentsBox);
m_Controls->m_kOffsetBox->setValue(parameters.m_SignalGen.m_KspaceLineOffset);
m_Controls->m_WrapBox->setValue(100*(1-parameters.m_SignalGen.m_CroppingFactor));
m_Controls->m_SpikeNumBox->setValue(parameters.m_SignalGen.m_Spikes);
m_Controls->m_SpikeScaleBox->setValue(parameters.m_SignalGen.m_SpikeAmplitude);
m_Controls->m_EddyGradientStrength->setValue(parameters.m_SignalGen.m_EddyStrength);
m_Controls->m_AddGibbsRinging->setChecked(parameters.m_SignalGen.m_DoAddGibbsRinging);
m_Controls->m_AddMotion->setChecked(parameters.m_SignalGen.m_DoAddMotion);
m_Controls->m_RandomMotion->setChecked(parameters.m_SignalGen.m_DoRandomizeMotion);
m_Controls->m_MaxTranslationBoxX->setValue(parameters.m_SignalGen.m_Translation[0]);
m_Controls->m_MaxTranslationBoxY->setValue(parameters.m_SignalGen.m_Translation[1]);
m_Controls->m_MaxTranslationBoxZ->setValue(parameters.m_SignalGen.m_Translation[2]);
m_Controls->m_MaxRotationBoxX->setValue(parameters.m_SignalGen.m_Rotation[0]);
m_Controls->m_MaxRotationBoxY->setValue(parameters.m_SignalGen.m_Rotation[1]);
m_Controls->m_MaxRotationBoxZ->setValue(parameters.m_SignalGen.m_Rotation[2]);
m_Controls->m_DiffusionDirectionBox->setCurrentIndex(parameters.m_SignalGen.m_DiffusionDirectionMode);
m_Controls->m_SeparationAngleBox->setValue(parameters.m_SignalGen.m_FiberSeparationThreshold);
m_Controls->m_Compartment1Box->setCurrentIndex(0);
m_Controls->m_Compartment2Box->setCurrentIndex(0);
m_Controls->m_Compartment3Box->setCurrentIndex(0);
m_Controls->m_Compartment4Box->setCurrentIndex(0);
for (unsigned int i=0; i<parameters.m_FiberModelList.size()+parameters.m_NonFiberModelList.size(); i++)
{
mitk::DiffusionSignalModel<ScalarType>* signalModel = NULL;
if (i<parameters.m_FiberModelList.size())
signalModel = parameters.m_FiberModelList.at(i);
else
signalModel = parameters.m_NonFiberModelList.at(i-parameters.m_FiberModelList.size());
switch (signalModel->m_CompartmentId)
{
case 1:
{
if (dynamic_cast<mitk::StickModel<>*>(signalModel))
{
mitk::StickModel<>* model = dynamic_cast<mitk::StickModel<>*>(signalModel);
m_Controls->m_StickWidget1->SetT2(model->GetT2());
m_Controls->m_StickWidget1->SetD(model->GetDiffusivity());
m_Controls->m_Compartment1Box->setCurrentIndex(0);
break;
}
else if (dynamic_cast<mitk::TensorModel<>*>(signalModel))
{
mitk::TensorModel<>* model = dynamic_cast<mitk::TensorModel<>*>(signalModel);
m_Controls->m_TensorWidget1->SetT2(model->GetT2());
m_Controls->m_TensorWidget1->SetD1(model->GetDiffusivity1());
m_Controls->m_TensorWidget1->SetD2(model->GetDiffusivity2());
m_Controls->m_TensorWidget1->SetD3(model->GetDiffusivity3());
m_Controls->m_Compartment1Box->setCurrentIndex(2);
break;
}
else if (dynamic_cast<mitk::RawShModel<>*>(signalModel))
{
mitk::RawShModel<>* model = dynamic_cast<mitk::RawShModel<>*>(signalModel);
m_Controls->m_PrototypeWidget1->SetNumberOfSamples(model->GetMaxNumKernels());
m_Controls->m_PrototypeWidget1->SetMinFa(model->GetFaRange().first);
m_Controls->m_PrototypeWidget1->SetMaxFa(model->GetFaRange().second);
m_Controls->m_PrototypeWidget1->SetMinAdc(model->GetAdcRange().first);
m_Controls->m_PrototypeWidget1->SetMaxAdc(model->GetAdcRange().second);
m_Controls->m_Compartment1Box->setCurrentIndex(3);
break;
}
break;
}
case 2:
{
if (dynamic_cast<mitk::StickModel<>*>(signalModel))
{
mitk::StickModel<>* model = dynamic_cast<mitk::StickModel<>*>(signalModel);
m_Controls->m_StickWidget2->SetT2(model->GetT2());
m_Controls->m_StickWidget2->SetD(model->GetDiffusivity());
m_Controls->m_Compartment2Box->setCurrentIndex(1);
break;
}
else if (dynamic_cast<mitk::TensorModel<>*>(signalModel))
{
mitk::TensorModel<>* model = dynamic_cast<mitk::TensorModel<>*>(signalModel);
m_Controls->m_TensorWidget2->SetT2(model->GetT2());
m_Controls->m_TensorWidget2->SetD1(model->GetDiffusivity1());
m_Controls->m_TensorWidget2->SetD2(model->GetDiffusivity2());
m_Controls->m_TensorWidget2->SetD3(model->GetDiffusivity3());
m_Controls->m_Compartment2Box->setCurrentIndex(3);
break;
}
break;
}
case 3:
{
if (dynamic_cast<mitk::BallModel<>*>(signalModel))
{
mitk::BallModel<>* model = dynamic_cast<mitk::BallModel<>*>(signalModel);
m_Controls->m_BallWidget1->SetT2(model->GetT2());
m_Controls->m_BallWidget1->SetD(model->GetDiffusivity());
m_Controls->m_Compartment3Box->setCurrentIndex(0);
break;
}
else if (dynamic_cast<mitk::AstroStickModel<>*>(signalModel))
{
mitk::AstroStickModel<>* model = dynamic_cast<mitk::AstroStickModel<>*>(signalModel);
m_Controls->m_AstrosticksWidget1->SetT2(model->GetT2());
m_Controls->m_AstrosticksWidget1->SetD(model->GetDiffusivity());
m_Controls->m_AstrosticksWidget1->SetRandomizeSticks(model->GetRandomizeSticks());
m_Controls->m_Compartment3Box->setCurrentIndex(1);
break;
}
else if (dynamic_cast<mitk::DotModel<>*>(signalModel))
{
mitk::DotModel<>* model = dynamic_cast<mitk::DotModel<>*>(signalModel);
m_Controls->m_DotWidget1->SetT2(model->GetT2());
m_Controls->m_Compartment3Box->setCurrentIndex(2);
break;
}
else if (dynamic_cast<mitk::RawShModel<>*>(signalModel))
{
mitk::RawShModel<>* model = dynamic_cast<mitk::RawShModel<>*>(signalModel);
m_Controls->m_PrototypeWidget3->SetNumberOfSamples(model->GetMaxNumKernels());
m_Controls->m_PrototypeWidget3->SetMinFa(model->GetFaRange().first);
m_Controls->m_PrototypeWidget3->SetMaxFa(model->GetFaRange().second);
m_Controls->m_PrototypeWidget3->SetMinAdc(model->GetAdcRange().first);
m_Controls->m_PrototypeWidget3->SetMaxAdc(model->GetAdcRange().second);
m_Controls->m_Compartment3Box->setCurrentIndex(3);
break;
}
break;
}
case 4:
{
if (dynamic_cast<mitk::BallModel<>*>(signalModel))
{
mitk::BallModel<>* model = dynamic_cast<mitk::BallModel<>*>(signalModel);
m_Controls->m_BallWidget2->SetT2(model->GetT2());
m_Controls->m_BallWidget2->SetD(model->GetDiffusivity());
m_Controls->m_Compartment4Box->setCurrentIndex(1);
break;
}
else if (dynamic_cast<mitk::AstroStickModel<>*>(signalModel))
{
mitk::AstroStickModel<>* model = dynamic_cast<mitk::AstroStickModel<>*>(signalModel);
m_Controls->m_AstrosticksWidget2->SetT2(model->GetT2());
m_Controls->m_AstrosticksWidget2->SetD(model->GetDiffusivity());
m_Controls->m_AstrosticksWidget2->SetRandomizeSticks(model->GetRandomizeSticks());
m_Controls->m_Compartment4Box->setCurrentIndex(2);
break;
}
else if (dynamic_cast<mitk::DotModel<>*>(signalModel))
{
mitk::DotModel<>* model = dynamic_cast<mitk::DotModel<>*>(signalModel);
m_Controls->m_DotWidget2->SetT2(model->GetT2());
m_Controls->m_Compartment4Box->setCurrentIndex(3);
break;
}
else if (dynamic_cast<mitk::RawShModel<>*>(signalModel))
{
mitk::RawShModel<>* model = dynamic_cast<mitk::RawShModel<>*>(signalModel);
m_Controls->m_PrototypeWidget4->SetNumberOfSamples(model->GetMaxNumKernels());
m_Controls->m_PrototypeWidget4->SetMinFa(model->GetFaRange().first);
m_Controls->m_PrototypeWidget4->SetMaxFa(model->GetFaRange().second);
m_Controls->m_PrototypeWidget4->SetMinAdc(model->GetAdcRange().first);
m_Controls->m_PrototypeWidget4->SetMaxAdc(model->GetAdcRange().second);
m_Controls->m_Compartment4Box->setCurrentIndex(4);
break;
}
break;
}
}
}
}
void QmitkFiberfoxView::ShowAdvancedOptions(int state)
{
if (state)
{
m_Controls->m_AdvancedFiberOptionsFrame->setVisible(true);
m_Controls->m_AdvancedSignalOptionsFrame->setVisible(true);
m_Controls->m_AdvancedOptionsBox->setChecked(true);
m_Controls->m_AdvancedOptionsBox_2->setChecked(true);
}
else
{
m_Controls->m_AdvancedFiberOptionsFrame->setVisible(false);
m_Controls->m_AdvancedSignalOptionsFrame->setVisible(false);
m_Controls->m_AdvancedOptionsBox->setChecked(false);
m_Controls->m_AdvancedOptionsBox_2->setChecked(false);
}
}
void QmitkFiberfoxView::Comp1ModelFrameVisibility(int index)
{
m_Controls->m_StickWidget1->setVisible(false);
m_Controls->m_ZeppelinWidget1->setVisible(false);
m_Controls->m_TensorWidget1->setVisible(false);
m_Controls->m_PrototypeWidget1->setVisible(false);
switch (index)
{
case 0:
m_Controls->m_StickWidget1->setVisible(true);
break;
case 1:
m_Controls->m_ZeppelinWidget1->setVisible(true);
break;
case 2:
m_Controls->m_TensorWidget1->setVisible(true);
break;
case 3:
m_Controls->m_PrototypeWidget1->setVisible(true);
break;
}
}
void QmitkFiberfoxView::Comp2ModelFrameVisibility(int index)
{
m_Controls->m_StickWidget2->setVisible(false);
m_Controls->m_ZeppelinWidget2->setVisible(false);
m_Controls->m_TensorWidget2->setVisible(false);
switch (index)
{
case 0:
break;
case 1:
m_Controls->m_StickWidget2->setVisible(true);
break;
case 2:
m_Controls->m_ZeppelinWidget2->setVisible(true);
break;
case 3:
m_Controls->m_TensorWidget2->setVisible(true);
break;
}
}
void QmitkFiberfoxView::Comp3ModelFrameVisibility(int index)
{
m_Controls->m_BallWidget1->setVisible(false);
m_Controls->m_AstrosticksWidget1->setVisible(false);
m_Controls->m_DotWidget1->setVisible(false);
m_Controls->m_PrototypeWidget3->setVisible(false);
switch (index)
{
case 0:
m_Controls->m_BallWidget1->setVisible(true);
break;
case 1:
m_Controls->m_AstrosticksWidget1->setVisible(true);
break;
case 2:
m_Controls->m_DotWidget1->setVisible(true);
break;
case 3:
m_Controls->m_PrototypeWidget3->setVisible(true);
break;
}
}
void QmitkFiberfoxView::Comp4ModelFrameVisibility(int index)
{
m_Controls->m_BallWidget2->setVisible(false);
m_Controls->m_AstrosticksWidget2->setVisible(false);
m_Controls->m_DotWidget2->setVisible(false);
m_Controls->m_PrototypeWidget4->setVisible(false);
m_Controls->m_Comp4FractionFrame->setVisible(false);
switch (index)
{
case 0:
break;
case 1:
m_Controls->m_BallWidget2->setVisible(true);
m_Controls->m_Comp4FractionFrame->setVisible(true);
break;
case 2:
m_Controls->m_AstrosticksWidget2->setVisible(true);
m_Controls->m_Comp4FractionFrame->setVisible(true);
break;
case 3:
m_Controls->m_DotWidget2->setVisible(true);
m_Controls->m_Comp4FractionFrame->setVisible(true);
break;
case 4:
m_Controls->m_PrototypeWidget4->setVisible(true);
m_Controls->m_Comp4FractionFrame->setVisible(true);
break;
}
}
void QmitkFiberfoxView::OnConstantRadius(int value)
{
if (value>0 && m_Controls->m_RealTimeFibers->isChecked())
GenerateFibers();
}
void QmitkFiberfoxView::OnAddMotion(int value)
{
if (value>0)
m_Controls->m_MotionArtifactFrame->setVisible(true);
else
m_Controls->m_MotionArtifactFrame->setVisible(false);
}
void QmitkFiberfoxView::OnAddAliasing(int value)
{
if (value>0)
m_Controls->m_AliasingFrame->setVisible(true);
else
m_Controls->m_AliasingFrame->setVisible(false);
}
void QmitkFiberfoxView::OnAddSpikes(int value)
{
if (value>0)
m_Controls->m_SpikeFrame->setVisible(true);
else
m_Controls->m_SpikeFrame->setVisible(false);
}
void QmitkFiberfoxView::OnAddEddy(int value)
{
if (value>0)
m_Controls->m_EddyFrame->setVisible(true);
else
m_Controls->m_EddyFrame->setVisible(false);
}
void QmitkFiberfoxView::OnAddDistortions(int value)
{
if (value>0)
m_Controls->m_DistortionsFrame->setVisible(true);
else
m_Controls->m_DistortionsFrame->setVisible(false);
}
void QmitkFiberfoxView::OnAddGhosts(int value)
{
if (value>0)
m_Controls->m_GhostFrame->setVisible(true);
else
m_Controls->m_GhostFrame->setVisible(false);
}
void QmitkFiberfoxView::OnAddNoise(int value)
{
if (value>0)
m_Controls->m_NoiseFrame->setVisible(true);
else
m_Controls->m_NoiseFrame->setVisible(false);
}
void QmitkFiberfoxView::OnDistributionChanged(int value)
{
if (value==1)
m_Controls->m_VarianceBox->setVisible(true);
else
m_Controls->m_VarianceBox->setVisible(false);
if (m_Controls->m_RealTimeFibers->isChecked())
GenerateFibers();
}
void QmitkFiberfoxView::OnVarianceChanged(double)
{
if (m_Controls->m_RealTimeFibers->isChecked())
GenerateFibers();
}
void QmitkFiberfoxView::OnFiberDensityChanged(int)
{
if (m_Controls->m_RealTimeFibers->isChecked())
GenerateFibers();
}
void QmitkFiberfoxView::OnFiberSamplingChanged(double)
{
if (m_Controls->m_RealTimeFibers->isChecked())
GenerateFibers();
}
void QmitkFiberfoxView::OnTensionChanged(double)
{
if (m_Controls->m_RealTimeFibers->isChecked())
GenerateFibers();
}
void QmitkFiberfoxView::OnContinuityChanged(double)
{
if (m_Controls->m_RealTimeFibers->isChecked())
GenerateFibers();
}
void QmitkFiberfoxView::OnBiasChanged(double)
{
if (m_Controls->m_RealTimeFibers->isChecked())
GenerateFibers();
}
void QmitkFiberfoxView::AlignOnGrid()
{
for (unsigned int i=0; i<m_SelectedFiducials.size(); i++)
{
mitk::PlanarEllipse::Pointer pe = dynamic_cast<mitk::PlanarEllipse*>(m_SelectedFiducials.at(i)->GetData());
mitk::Point3D wc0 = pe->GetWorldControlPoint(0);
mitk::DataStorage::SetOfObjects::ConstPointer parentFibs = GetDataStorage()->GetSources(m_SelectedFiducials.at(i));
for( mitk::DataStorage::SetOfObjects::const_iterator it = parentFibs->begin(); it != parentFibs->end(); ++it )
{
mitk::DataNode::Pointer pFibNode = *it;
if ( pFibNode.IsNotNull() && dynamic_cast<mitk::FiberBundleX*>(pFibNode->GetData()) )
{
mitk::DataStorage::SetOfObjects::ConstPointer parentImgs = GetDataStorage()->GetSources(pFibNode);
for( mitk::DataStorage::SetOfObjects::const_iterator it2 = parentImgs->begin(); it2 != parentImgs->end(); ++it2 )
{
mitk::DataNode::Pointer pImgNode = *it2;
if ( pImgNode.IsNotNull() && dynamic_cast<mitk::Image*>(pImgNode->GetData()) )
{
mitk::Image::Pointer img = dynamic_cast<mitk::Image*>(pImgNode->GetData());
mitk::BaseGeometry::Pointer geom = img->GetGeometry();
itk::Index<3> idx;
geom->WorldToIndex(wc0, idx);
mitk::Point3D cIdx; cIdx[0]=idx[0]; cIdx[1]=idx[1]; cIdx[2]=idx[2];
mitk::Point3D world;
geom->IndexToWorld(cIdx,world);
mitk::Vector3D trans = world - wc0;
pe->GetGeometry()->Translate(trans);
break;
}
}
break;
}
}
}
for(unsigned int i=0; i<m_SelectedBundles2.size(); i++ )
{
mitk::DataNode::Pointer fibNode = m_SelectedBundles2.at(i);
mitk::DataStorage::SetOfObjects::ConstPointer sources = GetDataStorage()->GetSources(fibNode);
for( mitk::DataStorage::SetOfObjects::const_iterator it = sources->begin(); it != sources->end(); ++it )
{
mitk::DataNode::Pointer imgNode = *it;
if ( imgNode.IsNotNull() && dynamic_cast<mitk::Image*>(imgNode->GetData()) )
{
mitk::DataStorage::SetOfObjects::ConstPointer derivations = GetDataStorage()->GetDerivations(fibNode);
for( mitk::DataStorage::SetOfObjects::const_iterator it2 = derivations->begin(); it2 != derivations->end(); ++it2 )
{
mitk::DataNode::Pointer fiducialNode = *it2;
if ( fiducialNode.IsNotNull() && dynamic_cast<mitk::PlanarEllipse*>(fiducialNode->GetData()) )
{
mitk::PlanarEllipse::Pointer pe = dynamic_cast<mitk::PlanarEllipse*>(fiducialNode->GetData());
mitk::Point3D wc0 = pe->GetWorldControlPoint(0);
mitk::Image::Pointer img = dynamic_cast<mitk::Image*>(imgNode->GetData());
mitk::BaseGeometry::Pointer geom = img->GetGeometry();
itk::Index<3> idx;
geom->WorldToIndex(wc0, idx);
mitk::Point3D cIdx; cIdx[0]=idx[0]; cIdx[1]=idx[1]; cIdx[2]=idx[2];
mitk::Point3D world;
geom->IndexToWorld(cIdx,world);
mitk::Vector3D trans = world - wc0;
pe->GetGeometry()->Translate(trans);
}
}
break;
}
}
}
for(unsigned int i=0; i<m_SelectedImages.size(); i++ )
{
mitk::Image::Pointer img = dynamic_cast<mitk::Image*>(m_SelectedImages.at(i)->GetData());
mitk::DataStorage::SetOfObjects::ConstPointer derivations = GetDataStorage()->GetDerivations(m_SelectedImages.at(i));
for( mitk::DataStorage::SetOfObjects::const_iterator it = derivations->begin(); it != derivations->end(); ++it )
{
mitk::DataNode::Pointer fibNode = *it;
if ( fibNode.IsNotNull() && dynamic_cast<mitk::FiberBundleX*>(fibNode->GetData()) )
{
mitk::DataStorage::SetOfObjects::ConstPointer derivations2 = GetDataStorage()->GetDerivations(fibNode);
for( mitk::DataStorage::SetOfObjects::const_iterator it2 = derivations2->begin(); it2 != derivations2->end(); ++it2 )
{
mitk::DataNode::Pointer fiducialNode = *it2;
if ( fiducialNode.IsNotNull() && dynamic_cast<mitk::PlanarEllipse*>(fiducialNode->GetData()) )
{
mitk::PlanarEllipse::Pointer pe = dynamic_cast<mitk::PlanarEllipse*>(fiducialNode->GetData());
mitk::Point3D wc0 = pe->GetWorldControlPoint(0);
mitk::BaseGeometry::Pointer geom = img->GetGeometry();
itk::Index<3> idx;
geom->WorldToIndex(wc0, idx);
mitk::Point3D cIdx; cIdx[0]=idx[0]; cIdx[1]=idx[1]; cIdx[2]=idx[2];
mitk::Point3D world;
geom->IndexToWorld(cIdx,world);
mitk::Vector3D trans = world - wc0;
pe->GetGeometry()->Translate(trans);
}
}
}
}
}
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
if (m_Controls->m_RealTimeFibers->isChecked())
GenerateFibers();
}
void QmitkFiberfoxView::OnFlipButton()
{
if (m_SelectedFiducial.IsNull())
return;
std::map<mitk::DataNode*, QmitkPlanarFigureData>::iterator it = m_DataNodeToPlanarFigureData.find(m_SelectedFiducial.GetPointer());
if( it != m_DataNodeToPlanarFigureData.end() )
{
QmitkPlanarFigureData& data = it->second;
data.m_Flipped += 1;
data.m_Flipped %= 2;
}
if (m_Controls->m_RealTimeFibers->isChecked())
GenerateFibers();
}
QmitkFiberfoxView::GradientListType QmitkFiberfoxView::GenerateHalfShell(int NPoints)
{
NPoints *= 2;
GradientListType pointshell;
int numB0 = NPoints/20;
if (numB0==0)
numB0=1;
GradientType g;
g.Fill(0.0);
for (int i=0; i<numB0; i++)
pointshell.push_back(g);
if (NPoints==0)
return pointshell;
vnl_vector<double> theta; theta.set_size(NPoints);
vnl_vector<double> phi; phi.set_size(NPoints);
double C = sqrt(4*M_PI);
phi(0) = 0.0;
phi(NPoints-1) = 0.0;
for(int i=0; i<NPoints; i++)
{
theta(i) = acos(-1.0+2.0*i/(NPoints-1.0)) - M_PI / 2.0;
if( i>0 && i<NPoints-1)
{
phi(i) = (phi(i-1) + C /
sqrt(NPoints*(1-(-1.0+2.0*i/(NPoints-1.0))*(-1.0+2.0*i/(NPoints-1.0)))));
// % (2*DIST_POINTSHELL_PI);
}
}
for(int i=0; i<NPoints; i++)
{
g[2] = sin(theta(i));
if (g[2]<0)
continue;
g[0] = cos(theta(i)) * cos(phi(i));
g[1] = cos(theta(i)) * sin(phi(i));
pointshell.push_back(g);
}
return pointshell;
}
template<int ndirs>
std::vector<itk::Vector<double,3> > QmitkFiberfoxView::MakeGradientList()
{
std::vector<itk::Vector<double,3> > retval;
vnl_matrix_fixed<double, 3, ndirs>* U =
itk::PointShell<ndirs, vnl_matrix_fixed<double, 3, ndirs> >::DistributePointShell();
// Add 0 vector for B0
int numB0 = ndirs/10;
if (numB0==0)
numB0=1;
itk::Vector<double,3> v;
v.Fill(0.0);
for (int i=0; i<numB0; i++)
{
retval.push_back(v);
}
for(int i=0; i<ndirs;i++)
{
itk::Vector<double,3> v;
v[0] = U->get(0,i); v[1] = U->get(1,i); v[2] = U->get(2,i);
retval.push_back(v);
}
return retval;
}
void QmitkFiberfoxView::OnAddBundle()
{
if (m_SelectedImage.IsNull())
return;
mitk::DataStorage::SetOfObjects::ConstPointer children = GetDataStorage()->GetDerivations(m_SelectedImage);
mitk::FiberBundleX::Pointer bundle = mitk::FiberBundleX::New();
mitk::DataNode::Pointer node = mitk::DataNode::New();
node->SetData( bundle );
QString name = QString("Bundle_%1").arg(children->size());
node->SetName(name.toStdString());
m_SelectedBundles.push_back(node);
UpdateGui();
GetDataStorage()->Add(node, m_SelectedImage);
}
void QmitkFiberfoxView::OnDrawROI()
{
if (m_SelectedBundles.empty())
OnAddBundle();
if (m_SelectedBundles.empty())
return;
mitk::DataStorage::SetOfObjects::ConstPointer children = GetDataStorage()->GetDerivations(m_SelectedBundles.at(0));
mitk::PlanarEllipse::Pointer figure = mitk::PlanarEllipse::New();
mitk::DataNode::Pointer node = mitk::DataNode::New();
node->SetData( figure );
node->SetBoolProperty("planarfigure.3drendering", true);
QList<mitk::DataNode::Pointer> nodes = this->GetDataManagerSelection();
for( int i=0; i<nodes.size(); i++)
nodes.at(i)->SetSelected(false);
m_SelectedFiducial = node;
QString name = QString("Fiducial_%1").arg(children->size());
node->SetName(name.toStdString());
node->SetSelected(true);
this->DisableCrosshairNavigation();
mitk::PlanarFigureInteractor::Pointer figureInteractor = dynamic_cast<mitk::PlanarFigureInteractor*>(node->GetDataInteractor().GetPointer());
if(figureInteractor.IsNull())
{
figureInteractor = mitk::PlanarFigureInteractor::New();
us::Module* planarFigureModule = us::ModuleRegistry::GetModule( "MitkPlanarFigure" );
figureInteractor->LoadStateMachine("PlanarFigureInteraction.xml", planarFigureModule );
figureInteractor->SetEventConfig( "PlanarFigureConfig.xml", planarFigureModule );
figureInteractor->SetDataNode( node );
}
UpdateGui();
GetDataStorage()->Add(node, m_SelectedBundles.at(0));
}
bool CompareLayer(mitk::DataNode::Pointer i,mitk::DataNode::Pointer j)
{
int li = -1;
i->GetPropertyValue("layer", li);
int lj = -1;
j->GetPropertyValue("layer", lj);
return li<lj;
}
void QmitkFiberfoxView::GenerateFibers()
{
if (m_SelectedBundles.empty())
{
if (m_SelectedFiducial.IsNull())
return;
mitk::DataStorage::SetOfObjects::ConstPointer parents = GetDataStorage()->GetSources(m_SelectedFiducial);
for( mitk::DataStorage::SetOfObjects::const_iterator it = parents->begin(); it != parents->end(); ++it )
if(dynamic_cast<mitk::FiberBundleX*>((*it)->GetData()))
m_SelectedBundles.push_back(*it);
if (m_SelectedBundles.empty())
return;
}
FiberfoxParameters<double> parameters = UpdateImageParameters<double>();
for (unsigned int i=0; i<m_SelectedBundles.size(); i++)
{
mitk::DataStorage::SetOfObjects::ConstPointer children = GetDataStorage()->GetDerivations(m_SelectedBundles.at(i));
std::vector< mitk::DataNode::Pointer > childVector;
for( mitk::DataStorage::SetOfObjects::const_iterator it = children->begin(); it != children->end(); ++it )
childVector.push_back(*it);
sort(childVector.begin(), childVector.end(), CompareLayer);
vector< mitk::PlanarEllipse::Pointer > fib;
vector< unsigned int > flip;
float radius = 1;
int count = 0;
for( std::vector< mitk::DataNode::Pointer >::const_iterator it = childVector.begin(); it != childVector.end(); ++it )
{
mitk::DataNode::Pointer node = *it;
if ( node.IsNotNull() && dynamic_cast<mitk::PlanarEllipse*>(node->GetData()) )
{
mitk::PlanarEllipse* ellipse = dynamic_cast<mitk::PlanarEllipse*>(node->GetData());
if (m_Controls->m_ConstantRadiusBox->isChecked())
{
ellipse->SetTreatAsCircle(true);
mitk::Point2D c = ellipse->GetControlPoint(0);
mitk::Point2D p = ellipse->GetControlPoint(1);
mitk::Vector2D v = p-c;
if (count==0)
{
radius = v.GetVnlVector().magnitude();
ellipse->SetControlPoint(1, p);
+ ellipse->Modified();
}
else
{
v.Normalize();
v *= radius;
ellipse->SetControlPoint(1, c+v);
+ ellipse->Modified();
}
}
fib.push_back(ellipse);
std::map<mitk::DataNode*, QmitkPlanarFigureData>::iterator it = m_DataNodeToPlanarFigureData.find(node.GetPointer());
if( it != m_DataNodeToPlanarFigureData.end() )
{
QmitkPlanarFigureData& data = it->second;
flip.push_back(data.m_Flipped);
}
else
flip.push_back(0);
}
count++;
}
if (fib.size()>1)
{
parameters.m_FiberGen.m_Fiducials.push_back(fib);
parameters.m_FiberGen.m_FlipList.push_back(flip);
}
else if (fib.size()>0)
m_SelectedBundles.at(i)->SetData( mitk::FiberBundleX::New() );
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
itk::FibersFromPlanarFiguresFilter::Pointer filter = itk::FibersFromPlanarFiguresFilter::New();
filter->SetParameters(parameters.m_FiberGen);
filter->Update();
vector< mitk::FiberBundleX::Pointer > fiberBundles = filter->GetFiberBundles();
for (unsigned int i=0; i<fiberBundles.size(); i++)
{
m_SelectedBundles.at(i)->SetData( fiberBundles.at(i) );
if (fiberBundles.at(i)->GetNumFibers()>50000)
m_SelectedBundles.at(i)->SetVisibility(false);
}
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkFiberfoxView::GenerateImage()
{
if (m_SelectedBundles.empty() && m_SelectedDWI.IsNull())
{
mitk::Image::Pointer image = mitk::ImageGenerator::GenerateGradientImage<unsigned int>(
m_Controls->m_SizeX->value(),
m_Controls->m_SizeY->value(),
m_Controls->m_SizeZ->value(),
m_Controls->m_SpacingX->value(),
m_Controls->m_SpacingY->value(),
m_Controls->m_SpacingZ->value());
mitk::DataNode::Pointer node = mitk::DataNode::New();
node->SetData( image );
node->SetName("Dummy");
unsigned int window = m_Controls->m_SizeX->value()*m_Controls->m_SizeY->value()*m_Controls->m_SizeZ->value();
unsigned int level = window/2;
mitk::LevelWindow lw; lw.SetLevelWindow(level, window);
node->SetProperty( "levelwindow", mitk::LevelWindowProperty::New( lw ) );
GetDataStorage()->Add(node);
m_SelectedImage = node;
mitk::BaseData::Pointer basedata = node->GetData();
if (basedata.IsNotNull())
{
mitk::RenderingManager::GetInstance()->InitializeViews( basedata->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true );
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
UpdateGui();
}
else if (!m_SelectedBundles.empty())
SimulateImageFromFibers(m_SelectedBundles.at(0));
else if (m_SelectedDWI.IsNotNull())
SimulateForExistingDwi(m_SelectedDWI);
}
void QmitkFiberfoxView::SimulateForExistingDwi(mitk::DataNode* imageNode)
{
if (!dynamic_cast<mitk::DiffusionImage<short>*>(imageNode->GetData()))
return;
FiberfoxParameters<short> parameters = UpdateImageParameters<short>();
if (parameters.m_NoiseModel==NULL &&
parameters.m_SignalGen.m_Spikes==0 &&
parameters.m_SignalGen.m_FrequencyMap.IsNull() &&
parameters.m_SignalGen.m_KspaceLineOffset<=0.000001 &&
!parameters.m_SignalGen.m_DoAddGibbsRinging &&
!(parameters.m_SignalGen.m_EddyStrength>0) &&
parameters.m_SignalGen.m_CroppingFactor>0.999)
{
QMessageBox::information( NULL, "Simulation cancelled", "No valid artifact enabled! Motion artifacts and relaxation effects can NOT be added to an existing diffusion weighted image.");
return;
}
mitk::DiffusionImage<short>::Pointer diffImg = dynamic_cast<mitk::DiffusionImage<short>*>(imageNode->GetData());
m_ArtifactsToDwiFilter = itk::AddArtifactsToDwiImageFilter< short >::New();
m_ArtifactsToDwiFilter->SetInput(diffImg->GetVectorImage());
parameters.m_Misc.m_ParentNode = imageNode;
m_ArtifactsToDwiFilter->SetParameters(parameters);
m_Worker.m_FilterType = 1;
m_Thread.start(QThread::LowestPriority);
}
void QmitkFiberfoxView::SimulateImageFromFibers(mitk::DataNode* fiberNode)
{
mitk::FiberBundleX::Pointer fiberBundle = dynamic_cast<mitk::FiberBundleX*>(fiberNode->GetData());
if (fiberBundle->GetNumFibers()<=0)
return;
FiberfoxParameters<double> parameters = UpdateImageParameters<double>();
m_TractsToDwiFilter = itk::TractsToDWIImageFilter< short >::New();
parameters.m_Misc.m_ParentNode = fiberNode;
if (m_SelectedDWI.IsNotNull())
{
bool first = true;
bool ok = true;
mitk::DiffusionImage<short>::Pointer diffImg = dynamic_cast<mitk::DiffusionImage<short>*>(m_SelectedDWI->GetData());
itk::Image< itk::DiffusionTensor3D< double >, 3 >::Pointer tensorImage = NULL;
const int shOrder = 2;
typedef itk::AnalyticalDiffusionQballReconstructionImageFilter<short,short,float,shOrder,QBALL_ODFSIZE> QballFilterType;
QballFilterType::CoefficientImageType::Pointer itkFeatureImage = NULL;
ItkDoubleImgType::Pointer adcImage = NULL;
for (unsigned int i=0; i<parameters.m_FiberModelList.size()+parameters.m_NonFiberModelList.size(); i++)
{
mitk::RawShModel<>* model = NULL;
if (i<parameters.m_FiberModelList.size())
model = dynamic_cast< mitk::RawShModel<>* >(parameters.m_FiberModelList.at(i));
else
model = dynamic_cast< mitk::RawShModel<>* >(parameters.m_NonFiberModelList.at(i-parameters.m_FiberModelList.size()));
if (model!=0 && model->GetNumberOfKernels()<=0)
{
if (first==true)
{
typedef itk::DiffusionTensor3DReconstructionImageFilter< short, short, double > TensorReconstructionImageFilterType;
TensorReconstructionImageFilterType::Pointer filter = TensorReconstructionImageFilterType::New();
filter->SetGradientImage( diffImg->GetDirections(), diffImg->GetVectorImage() );
filter->SetBValue(diffImg->GetReferenceBValue());
filter->Update();
tensorImage = filter->GetOutput();
const int NumCoeffs = (shOrder*shOrder + shOrder + 2)/2 + shOrder;
QballFilterType::Pointer qballfilter = QballFilterType::New();
qballfilter->SetGradientImage( diffImg->GetDirections(), diffImg->GetVectorImage() );
qballfilter->SetBValue(diffImg->GetReferenceBValue());
qballfilter->SetLambda(0.006);
qballfilter->SetNormalizationMethod(QballFilterType::QBAR_RAW_SIGNAL);
qballfilter->Update();
itkFeatureImage = qballfilter->GetCoefficientImage();
itk::AdcImageFilter< short, double >::Pointer adcFilter = itk::AdcImageFilter< short, double >::New();
adcFilter->SetInput(diffImg->GetVectorImage());
adcFilter->SetGradientDirections(diffImg->GetDirections());
adcFilter->SetB_value(diffImg->GetReferenceBValue());
adcFilter->Update();
adcImage = adcFilter->GetOutput();
}
ok = model->SampleKernels(diffImg, parameters.m_SignalGen.m_MaskImage, tensorImage, itkFeatureImage, adcImage);
if (!ok)
break;
}
}
if (!ok)
{
QMessageBox::information( NULL, "Simulation cancelled", "No valid prototype signals could be sampled.");
return;
}
}
else if ( m_Controls->m_Compartment1Box->currentIndex()==3 || m_Controls->m_Compartment3Box->currentIndex()==3 || m_Controls->m_Compartment4Box->currentIndex()==4 )
{
QMessageBox::information( NULL, "Simulation cancelled", "Prototype signal but no diffusion-weighted image selected to sample signal from.");
return;
}
m_TractsToDwiFilter->SetParameters(parameters);
m_TractsToDwiFilter->SetFiberBundle(fiberBundle);
m_Worker.m_FilterType = 0;
m_Thread.start(QThread::LowestPriority);
}
void QmitkFiberfoxView::ApplyTransform()
{
vector< mitk::DataNode::Pointer > selectedBundles;
for(unsigned int i=0; i<m_SelectedImages.size(); i++ )
{
mitk::DataStorage::SetOfObjects::ConstPointer derivations = GetDataStorage()->GetDerivations(m_SelectedImages.at(i));
for( mitk::DataStorage::SetOfObjects::const_iterator it = derivations->begin(); it != derivations->end(); ++it )
{
mitk::DataNode::Pointer fibNode = *it;
if ( fibNode.IsNotNull() && dynamic_cast<mitk::FiberBundleX*>(fibNode->GetData()) )
selectedBundles.push_back(fibNode);
}
}
if (selectedBundles.empty())
selectedBundles = m_SelectedBundles2;
if (!selectedBundles.empty())
{
for (std::vector<mitk::DataNode::Pointer>::const_iterator it = selectedBundles.begin(); it!=selectedBundles.end(); ++it)
{
mitk::FiberBundleX::Pointer fib = dynamic_cast<mitk::FiberBundleX*>((*it)->GetData());
fib->RotateAroundAxis(m_Controls->m_XrotBox->value(), m_Controls->m_YrotBox->value(), m_Controls->m_ZrotBox->value());
fib->TranslateFibers(m_Controls->m_XtransBox->value(), m_Controls->m_YtransBox->value(), m_Controls->m_ZtransBox->value());
fib->ScaleFibers(m_Controls->m_XscaleBox->value(), m_Controls->m_YscaleBox->value(), m_Controls->m_ZscaleBox->value());
// handle child fiducials
if (m_Controls->m_IncludeFiducials->isChecked())
{
mitk::DataStorage::SetOfObjects::ConstPointer derivations = GetDataStorage()->GetDerivations(*it);
for( mitk::DataStorage::SetOfObjects::const_iterator it2 = derivations->begin(); it2 != derivations->end(); ++it2 )
{
mitk::DataNode::Pointer fiducialNode = *it2;
if ( fiducialNode.IsNotNull() && dynamic_cast<mitk::PlanarEllipse*>(fiducialNode->GetData()) )
{
mitk::PlanarEllipse* pe = dynamic_cast<mitk::PlanarEllipse*>(fiducialNode->GetData());
mitk::BaseGeometry* geom = pe->GetGeometry();
// translate
mitk::Vector3D world;
world[0] = m_Controls->m_XtransBox->value();
world[1] = m_Controls->m_YtransBox->value();
world[2] = m_Controls->m_ZtransBox->value();
geom->Translate(world);
// calculate rotation matrix
double x = m_Controls->m_XrotBox->value()*M_PI/180;
double y = m_Controls->m_YrotBox->value()*M_PI/180;
double z = m_Controls->m_ZrotBox->value()*M_PI/180;
itk::Matrix< double, 3, 3 > rotX; rotX.SetIdentity();
rotX[1][1] = cos(x);
rotX[2][2] = rotX[1][1];
rotX[1][2] = -sin(x);
rotX[2][1] = -rotX[1][2];
itk::Matrix< double, 3, 3 > rotY; rotY.SetIdentity();
rotY[0][0] = cos(y);
rotY[2][2] = rotY[0][0];
rotY[0][2] = sin(y);
rotY[2][0] = -rotY[0][2];
itk::Matrix< double, 3, 3 > rotZ; rotZ.SetIdentity();
rotZ[0][0] = cos(z);
rotZ[1][1] = rotZ[0][0];
rotZ[0][1] = -sin(z);
rotZ[1][0] = -rotZ[0][1];
itk::Matrix< double, 3, 3 > rot = rotZ*rotY*rotX;
// transform control point coordinate into geometry translation
geom->SetOrigin(pe->GetWorldControlPoint(0));
mitk::Point2D cp; cp.Fill(0.0);
pe->SetControlPoint(0, cp);
// rotate fiducial
geom->GetIndexToWorldTransform()->SetMatrix(rot*geom->GetIndexToWorldTransform()->GetMatrix());
// implicit translation
mitk::Vector3D trans;
trans[0] = geom->GetOrigin()[0]-fib->GetGeometry()->GetCenter()[0];
trans[1] = geom->GetOrigin()[1]-fib->GetGeometry()->GetCenter()[1];
trans[2] = geom->GetOrigin()[2]-fib->GetGeometry()->GetCenter()[2];
mitk::Vector3D newWc = rot*trans;
newWc = newWc-trans;
geom->Translate(newWc);
pe->Modified();
}
}
}
}
}
else
{
for (unsigned int i=0; i<m_SelectedFiducials.size(); i++)
{
mitk::PlanarEllipse* pe = dynamic_cast<mitk::PlanarEllipse*>(m_SelectedFiducials.at(i)->GetData());
mitk::BaseGeometry* geom = pe->GetGeometry();
// translate
mitk::Vector3D world;
world[0] = m_Controls->m_XtransBox->value();
world[1] = m_Controls->m_YtransBox->value();
world[2] = m_Controls->m_ZtransBox->value();
geom->Translate(world);
// calculate rotation matrix
double x = m_Controls->m_XrotBox->value()*M_PI/180;
double y = m_Controls->m_YrotBox->value()*M_PI/180;
double z = m_Controls->m_ZrotBox->value()*M_PI/180;
itk::Matrix< double, 3, 3 > rotX; rotX.SetIdentity();
rotX[1][1] = cos(x);
rotX[2][2] = rotX[1][1];
rotX[1][2] = -sin(x);
rotX[2][1] = -rotX[1][2];
itk::Matrix< double, 3, 3 > rotY; rotY.SetIdentity();
rotY[0][0] = cos(y);
rotY[2][2] = rotY[0][0];
rotY[0][2] = sin(y);
rotY[2][0] = -rotY[0][2];
itk::Matrix< double, 3, 3 > rotZ; rotZ.SetIdentity();
rotZ[0][0] = cos(z);
rotZ[1][1] = rotZ[0][0];
rotZ[0][1] = -sin(z);
rotZ[1][0] = -rotZ[0][1];
itk::Matrix< double, 3, 3 > rot = rotZ*rotY*rotX;
// transform control point coordinate into geometry translation
geom->SetOrigin(pe->GetWorldControlPoint(0));
mitk::Point2D cp; cp.Fill(0.0);
pe->SetControlPoint(0, cp);
// rotate fiducial
geom->GetIndexToWorldTransform()->SetMatrix(rot*geom->GetIndexToWorldTransform()->GetMatrix());
pe->Modified();
}
if (m_Controls->m_RealTimeFibers->isChecked())
GenerateFibers();
}
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkFiberfoxView::CopyBundles()
{
if ( m_SelectedBundles.size()<1 ){
QMessageBox::information( NULL, "Warning", "Select at least one fiber bundle!");
MITK_WARN("QmitkFiberProcessingView") << "Select at least one fiber bundle!";
return;
}
for (std::vector<mitk::DataNode::Pointer>::const_iterator it = m_SelectedBundles.begin(); it!=m_SelectedBundles.end(); ++it)
{
// find parent image
mitk::DataNode::Pointer parentNode;
mitk::DataStorage::SetOfObjects::ConstPointer parentImgs = GetDataStorage()->GetSources(*it);
for( mitk::DataStorage::SetOfObjects::const_iterator it2 = parentImgs->begin(); it2 != parentImgs->end(); ++it2 )
{
mitk::DataNode::Pointer pImgNode = *it2;
if ( pImgNode.IsNotNull() && dynamic_cast<mitk::Image*>(pImgNode->GetData()) )
{
parentNode = pImgNode;
break;
}
}
mitk::FiberBundleX::Pointer fib = dynamic_cast<mitk::FiberBundleX*>((*it)->GetData());
mitk::FiberBundleX::Pointer newBundle = fib->GetDeepCopy();
QString name((*it)->GetName().c_str());
name += "_copy";
mitk::DataNode::Pointer fbNode = mitk::DataNode::New();
fbNode->SetData(newBundle);
fbNode->SetName(name.toStdString());
fbNode->SetVisibility(true);
if (parentNode.IsNotNull())
GetDataStorage()->Add(fbNode, parentNode);
else
GetDataStorage()->Add(fbNode);
// copy child fiducials
if (m_Controls->m_IncludeFiducials->isChecked())
{
mitk::DataStorage::SetOfObjects::ConstPointer derivations = GetDataStorage()->GetDerivations(*it);
for( mitk::DataStorage::SetOfObjects::const_iterator it2 = derivations->begin(); it2 != derivations->end(); ++it2 )
{
mitk::DataNode::Pointer fiducialNode = *it2;
if ( fiducialNode.IsNotNull() && dynamic_cast<mitk::PlanarEllipse*>(fiducialNode->GetData()) )
{
- mitk::PlanarEllipse::Pointer pe = mitk::PlanarEllipse::New();
- pe->DeepCopy(dynamic_cast<mitk::PlanarEllipse*>(fiducialNode->GetData()));
+ mitk::PlanarEllipse::Pointer pe = dynamic_cast<mitk::PlanarEllipse*>(fiducialNode->GetData())->Clone();
mitk::DataNode::Pointer newNode = mitk::DataNode::New();
newNode->SetData(pe);
newNode->SetName(fiducialNode->GetName());
newNode->SetBoolProperty("planarfigure.3drendering", true);
GetDataStorage()->Add(newNode, fbNode);
}
}
}
}
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkFiberfoxView::JoinBundles()
{
if ( m_SelectedBundles.size()<2 ){
QMessageBox::information( NULL, "Warning", "Select at least two fiber bundles!");
MITK_WARN("QmitkFiberProcessingView") << "Select at least two fiber bundles!";
return;
}
std::vector<mitk::DataNode::Pointer>::const_iterator it = m_SelectedBundles.begin();
mitk::FiberBundleX::Pointer newBundle = dynamic_cast<mitk::FiberBundleX*>((*it)->GetData());
QString name("");
name += QString((*it)->GetName().c_str());
++it;
for (; it!=m_SelectedBundles.end(); ++it)
{
newBundle = newBundle->AddBundle(dynamic_cast<mitk::FiberBundleX*>((*it)->GetData()));
name += "+"+QString((*it)->GetName().c_str());
}
mitk::DataNode::Pointer fbNode = mitk::DataNode::New();
fbNode->SetData(newBundle);
fbNode->SetName(name.toStdString());
fbNode->SetVisibility(true);
GetDataStorage()->Add(fbNode);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkFiberfoxView::UpdateGui()
{
m_Controls->m_FiberBundleLabel->setText("<font color='red'>mandatory</font>");
m_Controls->m_GeometryFrame->setEnabled(true);
m_Controls->m_GeometryMessage->setVisible(false);
m_Controls->m_DiffusionPropsMessage->setVisible(false);
m_Controls->m_FiberGenMessage->setVisible(true);
m_Controls->m_TransformBundlesButton->setEnabled(false);
m_Controls->m_CopyBundlesButton->setEnabled(false);
m_Controls->m_GenerateFibersButton->setEnabled(false);
m_Controls->m_FlipButton->setEnabled(false);
m_Controls->m_CircleButton->setEnabled(false);
m_Controls->m_BvalueBox->setEnabled(true);
m_Controls->m_NumGradientsBox->setEnabled(true);
m_Controls->m_JoinBundlesButton->setEnabled(false);
m_Controls->m_AlignOnGrid->setEnabled(false);
if (m_SelectedFiducial.IsNotNull())
{
m_Controls->m_TransformBundlesButton->setEnabled(true);
m_Controls->m_FlipButton->setEnabled(true);
m_Controls->m_AlignOnGrid->setEnabled(true);
}
if (m_SelectedImage.IsNotNull() || !m_SelectedBundles.empty())
{
m_Controls->m_TransformBundlesButton->setEnabled(true);
m_Controls->m_CircleButton->setEnabled(true);
m_Controls->m_FiberGenMessage->setVisible(false);
m_Controls->m_AlignOnGrid->setEnabled(true);
}
if (m_MaskImageNode.IsNotNull() || m_SelectedImage.IsNotNull())
{
m_Controls->m_GeometryMessage->setVisible(true);
m_Controls->m_GeometryFrame->setEnabled(false);
}
if (m_SelectedDWI.IsNotNull())
{
m_Controls->m_DiffusionPropsMessage->setVisible(true);
m_Controls->m_BvalueBox->setEnabled(false);
m_Controls->m_NumGradientsBox->setEnabled(false);
m_Controls->m_GeometryMessage->setVisible(true);
m_Controls->m_GeometryFrame->setEnabled(false);
}
if (!m_SelectedBundles.empty())
{
m_Controls->m_CopyBundlesButton->setEnabled(true);
m_Controls->m_GenerateFibersButton->setEnabled(true);
m_Controls->m_FiberBundleLabel->setText(m_SelectedBundles.at(0)->GetName().c_str());
if (m_SelectedBundles.size()>1)
m_Controls->m_JoinBundlesButton->setEnabled(true);
}
}
void QmitkFiberfoxView::OnSelectionChanged( berry::IWorkbenchPart::Pointer, const QList<mitk::DataNode::Pointer>& nodes )
{
m_SelectedBundles2.clear();
m_SelectedImages.clear();
m_SelectedFiducials.clear();
m_SelectedFiducial = NULL;
m_SelectedBundles.clear();
m_SelectedImage = NULL;
m_SelectedDWI = NULL;
m_MaskImageNode = NULL;
m_Controls->m_TissueMaskLabel->setText("<font color='grey'>optional</font>");
// iterate all selected objects, adjust warning visibility
for( int i=0; i<nodes.size(); i++)
{
mitk::DataNode::Pointer node = nodes.at(i);
if ( node.IsNotNull() && dynamic_cast<mitk::DiffusionImage<short>*>(node->GetData()) )
{
m_SelectedDWI = node;
m_SelectedImage = node;
m_SelectedImages.push_back(node);
}
else if( node.IsNotNull() && dynamic_cast<mitk::Image*>(node->GetData()) )
{
m_SelectedImages.push_back(node);
m_SelectedImage = node;
bool isbinary = false;
node->GetPropertyValue<bool>("binary", isbinary);
if (isbinary)
{
m_MaskImageNode = node;
m_Controls->m_TissueMaskLabel->setText(m_MaskImageNode->GetName().c_str());
}
}
else if ( node.IsNotNull() && dynamic_cast<mitk::FiberBundleX*>(node->GetData()) )
{
m_SelectedBundles2.push_back(node);
if (m_Controls->m_RealTimeFibers->isChecked())
{
m_SelectedBundles.push_back(node);
mitk::FiberBundleX::Pointer newFib = dynamic_cast<mitk::FiberBundleX*>(node->GetData());
if (newFib->GetNumFibers()!=m_Controls->m_FiberDensityBox->value())
GenerateFibers();
}
else
m_SelectedBundles.push_back(node);
}
else if ( node.IsNotNull() && dynamic_cast<mitk::PlanarEllipse*>(node->GetData()) )
{
m_SelectedFiducials.push_back(node);
m_SelectedFiducial = node;
m_SelectedBundles.clear();
mitk::DataStorage::SetOfObjects::ConstPointer parents = GetDataStorage()->GetSources(node);
for( mitk::DataStorage::SetOfObjects::const_iterator it = parents->begin(); it != parents->end(); ++it )
{
mitk::DataNode::Pointer pNode = *it;
if ( pNode.IsNotNull() && dynamic_cast<mitk::FiberBundleX*>(pNode->GetData()) )
m_SelectedBundles.push_back(pNode);
}
}
}
UpdateGui();
}
void QmitkFiberfoxView::EnableCrosshairNavigation()
{
MITK_DEBUG << "EnableCrosshairNavigation";
// enable the crosshair navigation
if (mitk::ILinkedRenderWindowPart* linkedRenderWindow =
dynamic_cast<mitk::ILinkedRenderWindowPart*>(this->GetRenderWindowPart()))
{
MITK_DEBUG << "enabling linked navigation";
linkedRenderWindow->EnableLinkedNavigation(true);
// linkedRenderWindow->EnableSlicingPlanes(true);
}
if (m_Controls->m_RealTimeFibers->isChecked())
GenerateFibers();
}
void QmitkFiberfoxView::DisableCrosshairNavigation()
{
MITK_DEBUG << "DisableCrosshairNavigation";
// disable the crosshair navigation during the drawing
if (mitk::ILinkedRenderWindowPart* linkedRenderWindow =
dynamic_cast<mitk::ILinkedRenderWindowPart*>(this->GetRenderWindowPart()))
{
MITK_DEBUG << "disabling linked navigation";
linkedRenderWindow->EnableLinkedNavigation(false);
// linkedRenderWindow->EnableSlicingPlanes(false);
}
}
void QmitkFiberfoxView::NodeRemoved(const mitk::DataNode* node)
{
mitk::DataNode* nonConstNode = const_cast<mitk::DataNode*>(node);
std::map<mitk::DataNode*, QmitkPlanarFigureData>::iterator it = m_DataNodeToPlanarFigureData.find(nonConstNode);
if (dynamic_cast<FiberBundleX*>(node->GetData()))
{
m_SelectedBundles.clear();
m_SelectedBundles2.clear();
}
else if (dynamic_cast<Image*>(node->GetData()))
m_SelectedImages.clear();
if( it != m_DataNodeToPlanarFigureData.end() )
{
QmitkPlanarFigureData& data = it->second;
// remove observers
data.m_Figure->RemoveObserver( data.m_EndPlacementObserverTag );
data.m_Figure->RemoveObserver( data.m_SelectObserverTag );
data.m_Figure->RemoveObserver( data.m_StartInteractionObserverTag );
data.m_Figure->RemoveObserver( data.m_EndInteractionObserverTag );
m_DataNodeToPlanarFigureData.erase( it );
}
}
void QmitkFiberfoxView::NodeAdded( const mitk::DataNode* node )
{
// add observer for selection in renderwindow
mitk::PlanarFigure* figure = dynamic_cast<mitk::PlanarFigure*>(node->GetData());
bool isPositionMarker (false);
node->GetBoolProperty("isContourMarker", isPositionMarker);
if( figure && !isPositionMarker )
{
MITK_DEBUG << "figure added. will add interactor if needed.";
mitk::PlanarFigureInteractor::Pointer figureInteractor
= dynamic_cast<mitk::PlanarFigureInteractor*>(node->GetDataInteractor().GetPointer());
mitk::DataNode* nonConstNode = const_cast<mitk::DataNode*>( node );
if(figureInteractor.IsNull())
{
figureInteractor = mitk::PlanarFigureInteractor::New();
us::Module* planarFigureModule = us::ModuleRegistry::GetModule( "MitkPlanarFigure" );
figureInteractor->LoadStateMachine("PlanarFigureInteraction.xml", planarFigureModule );
figureInteractor->SetEventConfig( "PlanarFigureConfig.xml", planarFigureModule );
figureInteractor->SetDataNode( nonConstNode );
}
MITK_DEBUG << "will now add observers for planarfigure";
QmitkPlanarFigureData data;
data.m_Figure = figure;
// // add observer for event when figure has been placed
typedef itk::SimpleMemberCommand< QmitkFiberfoxView > SimpleCommandType;
// SimpleCommandType::Pointer initializationCommand = SimpleCommandType::New();
// initializationCommand->SetCallbackFunction( this, &QmitkFiberfoxView::PlanarFigureInitialized );
// data.m_EndPlacementObserverTag = figure->AddObserver( mitk::EndPlacementPlanarFigureEvent(), initializationCommand );
// add observer for event when figure is picked (selected)
typedef itk::MemberCommand< QmitkFiberfoxView > MemberCommandType;
MemberCommandType::Pointer selectCommand = MemberCommandType::New();
selectCommand->SetCallbackFunction( this, &QmitkFiberfoxView::PlanarFigureSelected );
data.m_SelectObserverTag = figure->AddObserver( mitk::SelectPlanarFigureEvent(), selectCommand );
// add observer for event when interaction with figure starts
SimpleCommandType::Pointer startInteractionCommand = SimpleCommandType::New();
startInteractionCommand->SetCallbackFunction( this, &QmitkFiberfoxView::DisableCrosshairNavigation);
data.m_StartInteractionObserverTag = figure->AddObserver( mitk::StartInteractionPlanarFigureEvent(), startInteractionCommand );
// add observer for event when interaction with figure starts
SimpleCommandType::Pointer endInteractionCommand = SimpleCommandType::New();
endInteractionCommand->SetCallbackFunction( this, &QmitkFiberfoxView::EnableCrosshairNavigation);
data.m_EndInteractionObserverTag = figure->AddObserver( mitk::EndInteractionPlanarFigureEvent(), endInteractionCommand );
m_DataNodeToPlanarFigureData[nonConstNode] = data;
}
}
void QmitkFiberfoxView::PlanarFigureSelected( itk::Object* object, const itk::EventObject& )
{
mitk::TNodePredicateDataType<mitk::PlanarFigure>::Pointer isPf = mitk::TNodePredicateDataType<mitk::PlanarFigure>::New();
mitk::DataStorage::SetOfObjects::ConstPointer allPfs = this->GetDataStorage()->GetSubset( isPf );
for ( mitk::DataStorage::SetOfObjects::const_iterator it = allPfs->begin(); it!=allPfs->end(); ++it)
{
mitk::DataNode* node = *it;
if( node->GetData() == object )
{
node->SetSelected(true);
m_SelectedFiducial = node;
}
else
node->SetSelected(false);
}
UpdateGui();
this->RequestRenderWindowUpdate();
}
void QmitkFiberfoxView::SetFocus()
{
m_Controls->m_CircleButton->setFocus();
}
void QmitkFiberfoxView::SetOutputPath()
{
// SELECT FOLDER DIALOG
string outputPath = QFileDialog::getExistingDirectory(NULL, "Save images to...", QString(outputPath.c_str())).toStdString();
if (outputPath.empty())
m_Controls->m_SavePathEdit->setText("-");
else
{
outputPath += "/";
m_Controls->m_SavePathEdit->setText(QString(outputPath.c_str()));
}
}
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkIVIMView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkIVIMView.cpp
index e5ca91a8f4..d7a48764db 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkIVIMView.cpp
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkIVIMView.cpp
@@ -1,826 +1,826 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
// Blueberry
#include <berryISelectionService.h>
#include <berryIWorkbenchWindow.h>
// Qmitk
#include "QmitkIVIMView.h"
#include "QmitkStdMultiWidget.h"
// qt
#include "qmessagebox.h"
#include "qclipboard.h"
// mitk
#include "mitkDiffusionImage.h"
#include "mitkImageCast.h"
// itk
#include "itkScalarImageToHistogramGenerator.h"
#include "itkRegionOfInterestImageFilter.h"
#include "itkImageRegionConstIteratorWithIndex.h"
// itk/mitk
#include "itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter.h"
#include "itkRegularizedIVIMReconstructionFilter.h"
#include "mitkImageCast.h"
const std::string QmitkIVIMView::VIEW_ID = "org.mitk.views.ivim";
QmitkIVIMView::QmitkIVIMView()
: QmitkFunctionality()
, m_Controls( 0 )
, m_MultiWidget( NULL )
, m_SliceObserverTag1(0), m_SliceObserverTag2(0), m_SliceObserverTag3(0)
, m_DiffusionImageNode(NULL)
, m_MaskImageNode(NULL)
, m_Active(false)
{
}
QmitkIVIMView::~QmitkIVIMView()
{
// QmitkStdMultiWidget* MultiWidget = this->GetActiveStdMultiWidget(false);
// if(MultiWidget)
// {
// //unregister observers when view is destroyed
// if( MultiWidget->mitkWidget1 != NULL && m_SliceObserverTag1 != 0)
// {
// mitk::SliceNavigationController* slicer = MultiWidget->mitkWidget1->GetSliceNavigationController();
// slicer->RemoveObserver( m_SliceObserverTag1 );
// }
// if( MultiWidget->mitkWidget2 != NULL && m_SliceObserverTag2 != 0)
// {
// mitk::SliceNavigationController* slicer = MultiWidget->mitkWidget2->GetSliceNavigationController();
// slicer->RemoveObserver( m_SliceObserverTag2 );
// }
// if( MultiWidget->mitkWidget3!= NULL && m_SliceObserverTag3 != 0)
// {
// mitk::SliceNavigationController* slicer = MultiWidget->mitkWidget3->GetSliceNavigationController();
// slicer->RemoveObserver( m_SliceObserverTag3 );
// }
// }
}
void QmitkIVIMView::CreateQtPartControl( QWidget *parent )
{
// build up qt view, unless already done
if ( !m_Controls )
{
// create GUI widgets from the Qt Designer's .ui file
m_Controls = new Ui::QmitkIVIMViewControls;
m_Controls->setupUi( parent );
connect( m_Controls->m_ButtonStart, SIGNAL(clicked()), this, SLOT(FittIVIMStart()) );
connect( m_Controls->m_ButtonAutoThres, SIGNAL(clicked()), this, SLOT(AutoThreshold()) );
connect( m_Controls->m_MethodCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(MethodCombo(int)) );
connect( m_Controls->m_DStarSlider, SIGNAL(valueChanged(int)), this, SLOT(DStarSlider(int)) );
connect( m_Controls->m_BThreshSlider, SIGNAL(valueChanged(int)), this, SLOT(BThreshSlider(int)) );
connect( m_Controls->m_S0ThreshSlider, SIGNAL(valueChanged(int)), this, SLOT(S0ThreshSlider(int)) );
connect( m_Controls->m_NumItSlider, SIGNAL(valueChanged(int)), this, SLOT(NumItsSlider(int)) );
connect( m_Controls->m_LambdaSlider, SIGNAL(valueChanged(int)), this, SLOT(LambdaSlider(int)) );
connect( m_Controls->m_CheckDStar, SIGNAL(clicked()), this, SLOT(Checkbox()) );
connect( m_Controls->m_CheckD, SIGNAL(clicked()), this, SLOT(Checkbox()) );
connect( m_Controls->m_Checkf, SIGNAL(clicked()), this, SLOT(Checkbox()) );
connect( m_Controls->m_ChooseMethod, SIGNAL(clicked()), this, SLOT(ChooseMethod()) );
connect( m_Controls->m_CurveClipboard, SIGNAL(clicked()), this, SLOT(ClipboardCurveButtonClicked()) );
connect( m_Controls->m_ValuesClipboard, SIGNAL(clicked()), this, SLOT(ClipboardStatisticsButtonClicked()) );
}
QString dstar = QString::number(m_Controls->m_DStarSlider->value()/1000.0);
m_Controls->m_DStarLabel->setText(dstar);
QString bthresh = QString::number(m_Controls->m_BThreshSlider->value()*5.0);
m_Controls->m_BThreshLabel->setText(bthresh);
QString s0thresh = QString::number(m_Controls->m_S0ThreshSlider->value()*0.5);
m_Controls->m_S0ThreshLabel->setText(s0thresh);
QString numits = QString::number(m_Controls->m_NumItSlider->value());
m_Controls->m_NumItsLabel->setText(numits);
QString lambda = QString::number(m_Controls->m_LambdaSlider->value()*.00001);
m_Controls->m_LambdaLabel->setText(lambda);
m_Controls->m_MethodCombo->setVisible(m_Controls->m_ChooseMethod->isChecked());
m_Controls->m_Warning->setVisible(false);
MethodCombo(m_Controls->m_MethodCombo->currentIndex());
}
void QmitkIVIMView::Checkbox()
{
itk::StartEvent dummy;
OnSliceChanged(dummy);
}
void QmitkIVIMView::MethodCombo(int val)
{
switch(val)
{
case 0:
m_Controls->m_DstarFrame->setVisible(false);
m_Controls->m_NeglSiFrame->setVisible(true);
m_Controls->m_NeglBframe->setVisible(false);
m_Controls->m_IterationsFrame->setVisible(false);
m_Controls->m_LambdaFrame->setVisible(false);
break;
case 1:
m_Controls->m_DstarFrame->setVisible(true);
m_Controls->m_NeglSiFrame->setVisible(true);
m_Controls->m_NeglBframe->setVisible(false);
m_Controls->m_IterationsFrame->setVisible(false);
m_Controls->m_LambdaFrame->setVisible(false);
break;
case 2:
m_Controls->m_DstarFrame->setVisible(false);
m_Controls->m_NeglSiFrame->setVisible(true);
m_Controls->m_NeglBframe->setVisible(true);
m_Controls->m_IterationsFrame->setVisible(false);
m_Controls->m_LambdaFrame->setVisible(false);
break;
case 3:
m_Controls->m_DstarFrame->setVisible(false);
m_Controls->m_NeglSiFrame->setVisible(true);
m_Controls->m_NeglBframe->setVisible(true);
m_Controls->m_IterationsFrame->setVisible(false);
m_Controls->m_LambdaFrame->setVisible(false);
break;
case 4:
m_Controls->m_DstarFrame->setVisible(false);
m_Controls->m_NeglSiFrame->setVisible(false);
m_Controls->m_NeglBframe->setVisible(false);
m_Controls->m_IterationsFrame->setVisible(false);
m_Controls->m_LambdaFrame->setVisible(false);
break;
}
itk::StartEvent dummy;
OnSliceChanged(dummy);
}
void QmitkIVIMView::DStarSlider (int val)
{
QString sval = QString::number(val/1000.0);
m_Controls->m_DStarLabel->setText(sval);
itk::StartEvent dummy;
OnSliceChanged(dummy);
}
void QmitkIVIMView::BThreshSlider (int val)
{
QString sval = QString::number(val*5.0);
m_Controls->m_BThreshLabel->setText(sval);
itk::StartEvent dummy;
OnSliceChanged(dummy);
}
void QmitkIVIMView::S0ThreshSlider (int val)
{
QString sval = QString::number(val*0.5);
m_Controls->m_S0ThreshLabel->setText(sval);
itk::StartEvent dummy;
OnSliceChanged(dummy);
}
void QmitkIVIMView::NumItsSlider (int val)
{
QString sval = QString::number(val);
m_Controls->m_NumItsLabel->setText(sval);
itk::StartEvent dummy;
OnSliceChanged(dummy);
}
void QmitkIVIMView::LambdaSlider (int val)
{
QString sval = QString::number(val*.00001);
m_Controls->m_LambdaLabel->setText(sval);
itk::StartEvent dummy;
OnSliceChanged(dummy);
}
void QmitkIVIMView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget)
{
m_MultiWidget = &stdMultiWidget;
{
mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget1->GetSliceNavigationController();
itk::ReceptorMemberCommand<QmitkIVIMView>::Pointer command = itk::ReceptorMemberCommand<QmitkIVIMView>::New();
command->SetCallbackFunction( this, &QmitkIVIMView::OnSliceChanged );
m_SliceObserverTag1 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(NULL, 0), command );
}
{
mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget2->GetSliceNavigationController();
itk::ReceptorMemberCommand<QmitkIVIMView>::Pointer command = itk::ReceptorMemberCommand<QmitkIVIMView>::New();
command->SetCallbackFunction( this, &QmitkIVIMView::OnSliceChanged );
m_SliceObserverTag2 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(NULL, 0), command );
}
{
mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget3->GetSliceNavigationController();
itk::ReceptorMemberCommand<QmitkIVIMView>::Pointer command = itk::ReceptorMemberCommand<QmitkIVIMView>::New();
command->SetCallbackFunction( this, &QmitkIVIMView::OnSliceChanged );
m_SliceObserverTag3 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(NULL, 0), command );
}
}
void QmitkIVIMView::StdMultiWidgetNotAvailable()
{
{
mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget1->GetSliceNavigationController();
slicer->RemoveObserver( m_SliceObserverTag1 );
}
{
mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget2->GetSliceNavigationController();
slicer->RemoveObserver( m_SliceObserverTag2 );
}
{
mitk::SliceNavigationController* slicer = m_MultiWidget->mitkWidget3->GetSliceNavigationController();
slicer->RemoveObserver( m_SliceObserverTag3 );
}
m_MultiWidget = NULL;
}
void QmitkIVIMView::OnSelectionChanged( std::vector<mitk::DataNode*> nodes )
{
bool foundOneDiffusionImage = false;
m_Controls->m_InputData->setTitle("Please Select Input Data");
m_Controls->m_DiffusionImageLabel->setText("<font color='red'>mandatory</font>");
m_Controls->m_MaskImageLabel->setText("<font color='grey'>optional</font>");
m_MaskImageNode = NULL;
m_DiffusionImageNode = NULL;
// iterate all selected objects, adjust warning visibility
for( std::vector<mitk::DataNode*>::iterator it = nodes.begin(); it != nodes.end(); ++it )
{
mitk::DataNode::Pointer node = *it;
if( node.IsNotNull() && dynamic_cast<mitk::Image*>(node->GetData()) )
{
if( dynamic_cast<mitk::DiffusionImage<short>*>(node->GetData()) )
{
m_DiffusionImageNode = node;
foundOneDiffusionImage = true;
m_Controls->m_DiffusionImageLabel->setText(node->GetName().c_str());
}
else
{
bool isBinary = false;
node->GetPropertyValue<bool>("binary", isBinary);
if (isBinary)
{
m_MaskImageNode = node;
m_Controls->m_MaskImageLabel->setText(node->GetName().c_str());
}
}
}
}
if (m_DiffusionImageNode.IsNotNull())
{
m_Controls->m_VisualizeResultsWidget->setVisible(true);
m_Controls->m_InputData->setTitle("Input Data");
}
else
{
m_Controls->m_VisualizeResultsWidget->setVisible(false);
m_Controls->m_DiffusionImageLabel->setText("<font color='red'>mandatory</font>");
}
m_Controls->m_ButtonStart->setEnabled( foundOneDiffusionImage );
m_Controls->m_ButtonAutoThres->setEnabled( foundOneDiffusionImage );
m_Controls->m_ControlsFrame->setEnabled( foundOneDiffusionImage );
m_Controls->m_BottomControlsFrame->setEnabled( foundOneDiffusionImage );
itk::StartEvent dummy;
OnSliceChanged(dummy);
}
void QmitkIVIMView::AutoThreshold()
{
std::vector<mitk::DataNode*> nodes = this->GetDataManagerSelection();
if (nodes.empty()) return;
if (!nodes.front())
{
// Nothing selected. Inform the user and return
QMessageBox::information( NULL, "Template", "Please load and select a diffusion image before starting image processing.");
return;
}
typedef mitk::DiffusionImage<short> DiffImgType;
DiffImgType* dimg = dynamic_cast<DiffImgType*>(nodes.front()->GetData());
if (!dimg)
{
// Nothing selected. Inform the user and return
QMessageBox::information( NULL, "Template", "No valid diffusion image was found.");
return;
}
// find bzero index
int index = -1;
DiffImgType::GradientDirectionContainerType::Pointer directions = dimg->GetDirections();
for(DiffImgType::GradientDirectionContainerType::ConstIterator it = directions->Begin();
it != directions->End(); ++it)
{
index++;
DiffImgType::GradientDirectionType g = it.Value();
if(g[0] == 0 && g[1] == 0 && g[2] == 0 )
break;
}
typedef itk::VectorImage<short,3> VecImgType;
VecImgType::Pointer vecimg = dimg->GetVectorImage();
int vecLength = vecimg->GetVectorLength();
index = index > vecLength-1 ? vecLength-1 : index;
MITK_INFO << "Performing Histogram Analysis on Channel" << index;
typedef itk::Image<short,3> ImgType;
ImgType::Pointer img = ImgType::New();
mitk::CastToItkImage(dimg, img);
itk::ImageRegionIterator<ImgType> itw (img, img->GetLargestPossibleRegion() );
itw.GoToBegin();
itk::ImageRegionConstIterator<VecImgType> itr (vecimg, vecimg->GetLargestPossibleRegion() );
itr.GoToBegin();
while(!itr.IsAtEnd())
{
itw.Set(itr.Get().GetElement(index));
++itr;
++itw;
}
typedef itk::Statistics::ScalarImageToHistogramGenerator< ImgType >
HistogramGeneratorType;
typedef HistogramGeneratorType::HistogramType HistogramType;
HistogramGeneratorType::Pointer histogramGenerator = HistogramGeneratorType::New();
histogramGenerator->SetInput( img );
histogramGenerator->SetMarginalScale( 10 ); // Defines y-margin width of histogram
histogramGenerator->SetNumberOfBins( 100 ); // CT range [-1024, +2048] --> bin size 4 values
histogramGenerator->SetHistogramMin( dimg->GetScalarValueMin() );
histogramGenerator->SetHistogramMax( dimg->GetScalarValueMax() * .5 );
histogramGenerator->Compute();
HistogramType::ConstIterator iter = histogramGenerator->GetOutput()->Begin();
float maxFreq = 0;
float maxValue = 0;
while ( iter != histogramGenerator->GetOutput()->End() )
{
if(iter.GetFrequency() > maxFreq)
{
maxFreq = iter.GetFrequency();
maxValue = iter.GetMeasurementVector()[0];
}
++iter;
}
maxValue *= 2;
int sliderPos = maxValue * 2;
m_Controls->m_S0ThreshSlider->setValue(sliderPos);
S0ThreshSlider(sliderPos);
}
void QmitkIVIMView::FittIVIMStart()
{
std::vector<mitk::DataNode*> nodes = this->GetDataManagerSelection();
mitk::DiffusionImage<short>* img = 0;
for ( unsigned int i=0; i<nodes.size(); i++ )
{
img = dynamic_cast<mitk::DiffusionImage<short>*>(nodes.at(i)->GetData());
if (img)
break;
}
if (!img)
{
QMessageBox::information( NULL, "Template", "No valid diffusion image was found.");
return;
}
typedef itk::VectorImage<short,3> VecImgType;
VecImgType::Pointer vecimg = img->GetVectorImage();
OutImgType::IndexType dummy;
FittIVIM(vecimg, img->GetDirections(), img->GetReferenceBValue(), true, dummy);
OutputToDatastorage(nodes);
}
void QmitkIVIMView::OnSliceChanged(const itk::EventObject& /*e*/)
{
if(!m_Visible)
return;
m_Controls->m_Warning->setVisible(false);
if(!m_Controls || m_DiffusionImageNode.IsNull())
return;
m_Controls->m_VisualizeResultsWidget->setVisible(false);
mitk::DiffusionImage<short>::Pointer diffusionImg = dynamic_cast<mitk::DiffusionImage<short>*>(m_DiffusionImageNode->GetData());
mitk::Image::Pointer maskImg = NULL;
if (m_MaskImageNode.IsNotNull())
maskImg = dynamic_cast<mitk::Image*>(m_MaskImageNode->GetData());
if (!m_MultiWidget) return;
typedef itk::VectorImage<short,3> VecImgType;
VecImgType::Pointer vecimg = (VecImgType*)diffusionImg->GetVectorImage().GetPointer();
VecImgType::Pointer roiImage = VecImgType::New();
bool success = false;
if(maskImg.IsNull())
{
int roisize = 0;
if(m_Controls->m_MethodCombo->currentIndex() == 4)
roisize = 5;
mitk::Point3D pos = m_MultiWidget->GetCrossPosition();
VecImgType::IndexType crosspos;
diffusionImg->GetGeometry()->WorldToIndex(pos, crosspos);
if (!vecimg->GetLargestPossibleRegion().IsInside(crosspos))
{
m_Controls->m_Warning->setText(QString("Crosshair position not inside of selected diffusion weighted image. Reinit needed!"));
m_Controls->m_Warning->setVisible(true);
return;
}
else
m_Controls->m_Warning->setVisible(false);
VecImgType::IndexType index;
index[0] = crosspos[0] - roisize; index[0] = index[0] < 0 ? 0 : index[0];
index[1] = crosspos[1] - roisize; index[1] = index[1] < 0 ? 0 : index[1];
index[2] = crosspos[2] - roisize; index[2] = index[2] < 0 ? 0 : index[2];
VecImgType::SizeType size;
size[0] = roisize*2+1;
size[1] = roisize*2+1;
size[2] = roisize*2+1;
VecImgType::SizeType maxSize = vecimg->GetLargestPossibleRegion().GetSize();
size[0] = index[0]+size[0] > maxSize[0] ? maxSize[0]-index[0] : size[0];
size[1] = index[1]+size[1] > maxSize[1] ? maxSize[1]-index[1] : size[1];
size[2] = index[2]+size[2] > maxSize[2] ? maxSize[2]-index[2] : size[2];
VecImgType::RegionType region;
region.SetSize( size );
region.SetIndex( index );
vecimg->SetRequestedRegion( region );
VecImgType::IndexType newstart;
newstart.Fill(0);
VecImgType::RegionType newregion;
newregion.SetSize( size );
newregion.SetIndex( newstart );
roiImage->CopyInformation( vecimg );
roiImage->SetRegions( newregion );
roiImage->SetOrigin( pos );
roiImage->Allocate();
roiImage->SetPixel(newstart, vecimg->GetPixel(index));
success = FittIVIM(roiImage, diffusionImg->GetDirections(), diffusionImg->GetReferenceBValue(), false, crosspos);
}
else
{
typedef itk::Image<float,3> MaskImgType;
MaskImgType::Pointer maskItk;
CastToItkImage( maskImg, maskItk );
mitk::Point3D pos;
pos[0] = 0;
pos[1] = 0;
pos[2] = 0;
VecImgType::IndexType index;
index[0] = 0;
index[1] = 0;
index[2] = 0;
VecImgType::SizeType size;
size[0] = 1;
size[1] = 1;
size[2] = 1;
VecImgType::RegionType region;
region.SetSize( size );
region.SetIndex( index );
vecimg->SetRequestedRegion( region );
// iterators over output and input
itk::ImageRegionConstIteratorWithIndex<VecImgType>
vecit(vecimg, vecimg->GetLargestPossibleRegion());
itk::VariableLengthVector<double> avg(vecimg->GetVectorLength());
avg.Fill(0);
float numPixels = 0;
while ( ! vecit.IsAtEnd() )
{
VecImgType::PointType point;
vecimg->TransformIndexToPhysicalPoint(vecit.GetIndex(), point);
MaskImgType::IndexType index;
maskItk->TransformPhysicalPointToIndex(point, index);
if(maskItk->GetPixel(index) != 0)
{
avg += vecit.Get();
numPixels += 1.0;
}
// update iterators
++vecit;
}
avg /= numPixels;
m_Controls->m_Warning->setText(QString("Averaging ")+QString::number((int)numPixels)+QString(" voxels!"));
m_Controls->m_Warning->setVisible(true);
roiImage->CopyInformation( vecimg );
roiImage->SetRegions( region );
roiImage->SetOrigin( pos );
roiImage->Allocate();
roiImage->SetPixel(index, avg);
success = FittIVIM(roiImage, diffusionImg->GetDirections(), diffusionImg->GetReferenceBValue(), false, index);
}
vecimg->SetRegions( vecimg->GetLargestPossibleRegion() );
if (success)
{
m_Controls->m_VisualizeResultsWidget->setVisible(true);
m_Controls->m_VisualizeResultsWidget->SetParameters(m_Snap);
}
}
bool QmitkIVIMView::FittIVIM(itk::VectorImage<short,3>* vecimg, DirContainerType* dirs, float bval, bool multivoxel, OutImgType::IndexType &crosspos)
{
IVIMFilterType::Pointer filter = IVIMFilterType::New();
filter->SetInput(vecimg);
filter->SetGradientDirections(dirs);
filter->SetBValue(bval);
switch(m_Controls->m_MethodCombo->currentIndex())
{
case 0:
filter->SetMethod(IVIMFilterType::IVIM_FIT_ALL);
filter->SetS0Thres(m_Controls->m_S0ThreshLabel->text().toDouble());
break;
case 1:
filter->SetMethod(IVIMFilterType::IVIM_DSTAR_FIX);
filter->SetDStar(m_Controls->m_DStarLabel->text().toDouble());
filter->SetS0Thres(m_Controls->m_S0ThreshLabel->text().toDouble());
break;
case 2:
filter->SetMethod(IVIMFilterType::IVIM_D_THEN_DSTAR);
filter->SetBThres(m_Controls->m_BThreshLabel->text().toDouble());
filter->SetS0Thres(m_Controls->m_S0ThreshLabel->text().toDouble());
filter->SetFitDStar(m_Controls->m_CheckDStar->isChecked());
break;
case 3:
filter->SetMethod(IVIMFilterType::IVIM_LINEAR_D_THEN_F);
filter->SetBThres(m_Controls->m_BThreshLabel->text().toDouble());
filter->SetS0Thres(m_Controls->m_S0ThreshLabel->text().toDouble());
filter->SetFitDStar(m_Controls->m_CheckDStar->isChecked());
break;
case 4:
filter->SetMethod(IVIMFilterType::IVIM_REGULARIZED);
filter->SetBThres(m_Controls->m_BThreshLabel->text().toDouble());
filter->SetS0Thres(m_Controls->m_S0ThreshLabel->text().toDouble());
filter->SetNumberIterations(m_Controls->m_NumItsLabel->text().toInt());
filter->SetLambda(m_Controls->m_LambdaLabel->text().toDouble());
filter->SetFitDStar(m_Controls->m_CheckDStar->isChecked());
break;
}
if(!multivoxel)
{
filter->SetFitDStar(true);
}
filter->SetNumberOfThreads(1);
filter->SetVerbose(false);
filter->SetCrossPosition(crosspos);
try{
filter->Update();
m_Snap = filter->GetSnapshot();
m_DStarMap = filter->GetOutput(2);
m_DMap = filter->GetOutput(1);
m_fMap = filter->GetOutput();
}
catch (itk::ExceptionObject &ex)
{
MITK_INFO << ex ;
m_Controls->m_Warning->setText(QString("IVIM fit not possible: ")+ex.GetDescription());
m_Controls->m_Warning->setVisible(true);
return false;
}
return true;
}
void QmitkIVIMView::OutputToDatastorage(std::vector<mitk::DataNode*> nodes)
{
// Outputs to Datastorage
QString basename(nodes.front()->GetName().c_str());
if(m_Controls->m_CheckDStar->isChecked())
{
mitk::Image::Pointer dstarimage = mitk::Image::New();
dstarimage->InitializeByItk(m_DStarMap.GetPointer());
dstarimage->SetVolume(m_DStarMap->GetBufferPointer());
QString newname2 = basename; newname2 = newname2.append("_DStarMap_%1").arg(m_Controls->m_MethodCombo->currentText());
mitk::DataNode::Pointer node2=mitk::DataNode::New();
node2->SetData( dstarimage );
- node2->SetName(newname2.toAscii());
+ node2->SetName(newname2.toLatin1());
GetDefaultDataStorage()->Add(node2);
}
if(m_Controls->m_CheckD->isChecked())
{
mitk::Image::Pointer dimage = mitk::Image::New();
dimage->InitializeByItk(m_DMap.GetPointer());
dimage->SetVolume(m_DMap->GetBufferPointer());
QString newname1 = basename; newname1 = newname1.append("_DMap_%1").arg(m_Controls->m_MethodCombo->currentText());
mitk::DataNode::Pointer node1=mitk::DataNode::New();
node1->SetData( dimage );
- node1->SetName(newname1.toAscii());
+ node1->SetName(newname1.toLatin1());
GetDefaultDataStorage()->Add(node1);
}
if(m_Controls->m_Checkf->isChecked())
{
mitk::Image::Pointer image = mitk::Image::New();
image->InitializeByItk(m_fMap.GetPointer());
image->SetVolume(m_fMap->GetBufferPointer());
QString newname0 = basename; newname0 = newname0.append("_fMap_%1").arg(m_Controls->m_MethodCombo->currentText());
mitk::DataNode::Pointer node=mitk::DataNode::New();
node->SetData( image );
- node->SetName(newname0.toAscii());
+ node->SetName(newname0.toLatin1());
GetDefaultDataStorage()->Add(node);
}
m_MultiWidget->RequestUpdate();
// reset the data node labels, the selection in DataManager is lost after adding
// a new node -> we cannot directly proceed twice, the DWI ( and MASK) image have to be selected again
m_Controls->m_InputData->setTitle("Please Select Input Data");
m_Controls->m_DiffusionImageLabel->setText("<font color='red'>mandatory</font>");
m_Controls->m_MaskImageLabel->setText("<font color='grey'>optional</font>");
m_MaskImageNode = NULL;
m_DiffusionImageNode = NULL;
}
void QmitkIVIMView::ChooseMethod()
{
m_Controls->m_MethodCombo->setVisible(m_Controls->m_ChooseMethod->isChecked());
}
void QmitkIVIMView::ClipboardCurveButtonClicked()
{
if(true)
{
QString clipboard("Measurement Points\n");
for ( unsigned int i=0; i<m_Snap.bvalues.size(); i++)
{
clipboard = clipboard.append( "%L1 \t" )
.arg( m_Snap.bvalues[i], 0, 'f', 2 );
}
clipboard = clipboard.append( "\n" );
for ( unsigned int i=0; i<m_Snap.allmeas.size(); i++)
{
clipboard = clipboard.append( "%L1 \t" )
.arg( m_Snap.allmeas[i], 0, 'f', 2 );
}
clipboard = clipboard.append( "\n" );
clipboard = clipboard.append( "1st Linear Fit of D and f \n" );
double maxb = m_Snap.bvalues.max_value();
clipboard = clipboard.append( "%L1 \t %L2 \n %L3 \t %L4 \n" )
.arg( (float) 0, 0, 'f', 2 )
.arg( maxb, 0, 'f', 2 )
.arg(1-m_Snap.currentFunceiled, 0, 'f', 2 )
.arg((1-m_Snap.currentFunceiled)*exp(-maxb * m_Snap.currentD), 0, 'f', 2 );
int nsampling = 50;
double f = 1-m_Snap.currentFunceiled;
clipboard = clipboard.append("Final Model\n");
for(int i=0; i<nsampling; i++)
{
double x = (((1.0)*i)/(1.0*nsampling))*maxb;
clipboard = clipboard.append( "%L1 \t" )
.arg( x, 0, 'f', 2 );
}
clipboard = clipboard.append( "\n" );
for(int i=0; i<nsampling; i++)
{
double x = (((1.0)*i)/(1.0*nsampling))*maxb;
double y = f*exp(- x * m_Snap.currentD) + (1-f)*exp(- x * (m_Snap.currentD+m_Snap.currentDStar));
clipboard = clipboard.append( "%L1 \t" )
.arg( y, 0, 'f', 2 );
}
clipboard = clipboard.append( "\n" );
QApplication::clipboard()->setText(
clipboard, QClipboard::Clipboard );
}
else
{
QApplication::clipboard()->clear();
}
}
void QmitkIVIMView::ClipboardStatisticsButtonClicked()
{
if ( true )
{
QString clipboard( "f \t D \t D* \n" );
clipboard = clipboard.append( "%L1 \t %L2 \t %L3" )
.arg( m_Snap.currentF, 0, 'f', 10 )
.arg( m_Snap.currentD, 0, 'f', 10 )
.arg( m_Snap.currentDStar, 0, 'f', 10 ) ;
QApplication::clipboard()->setText(
clipboard, QClipboard::Clipboard );
}
else
{
QApplication::clipboard()->clear();
}
}
void QmitkIVIMView::Activated()
{
m_Active = true;
}
void QmitkIVIMView::Deactivated()
{
m_Active = false;
}
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPartialVolumeAnalysisView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPartialVolumeAnalysisView.cpp
index bda3c06a86..c873ab9b97 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPartialVolumeAnalysisView.cpp
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPartialVolumeAnalysisView.cpp
@@ -1,2170 +1,2168 @@
/*===================================================================
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 "QmitkPartialVolumeAnalysisView.h"
#include <limits>
#include <qlabel.h>
#include <qspinbox.h>
#include <qpushbutton.h>
#include <qcheckbox.h>
#include <qgroupbox.h>
#include <qradiobutton.h>
#include <qlineedit.h>
#include <qclipboard.h>
#include <qfiledialog.h>
#include <berryIEditorPart.h>
#include <berryIWorkbenchPage.h>
#include <berryPlatform.h>
#include "QmitkStdMultiWidget.h"
#include "QmitkStdMultiWidgetEditor.h"
#include "QmitkSliderNavigatorWidget.h"
#include <QMessageBox>
#include "mitkNodePredicateDataType.h"
#include "mitkNodePredicateOr.h"
#include "mitkImageTimeSelector.h"
#include "mitkProperties.h"
#include "mitkProgressBar.h"
#include "mitkImageCast.h"
#include "mitkImageToItk.h"
#include "mitkITKImageImport.h"
#include "mitkDataNodeObject.h"
#include "mitkNodePredicateData.h"
#include "mitkPlanarFigureInteractor.h"
#include "mitkGlobalInteraction.h"
#include "mitkTensorImage.h"
#include "mitkPlanarCircle.h"
#include "mitkPlanarRectangle.h"
#include "mitkPlanarPolygon.h"
#include "mitkPartialVolumeAnalysisClusteringCalculator.h"
#include "mitkDiffusionImage.h"
#include "usModuleRegistry.h"
#include <itkVectorImage.h>
#include "itkTensorDerivedMeasurementsFilter.h"
#include "itkDiffusionTensor3D.h"
#include "itkCartesianToPolarVectorImageFilter.h"
#include "itkPolarToCartesianVectorImageFilter.h"
#include "itkBinaryThresholdImageFilter.h"
#include "itkMaskImageFilter.h"
#include "itkCastImageFilter.h"
#include "itkImageMomentsCalculator.h"
#include <itkResampleImageFilter.h>
#include <itkGaussianInterpolateImageFunction.h>
#include <itkNearestNeighborInterpolateImageFunction.h>
#include <vnl/vnl_vector.h>
#define _USE_MATH_DEFINES
#include <math.h>
#define PVA_PI M_PI
const std::string QmitkPartialVolumeAnalysisView::VIEW_ID =
"org.mitk.views.partialvolumeanalysisview";
class QmitkRequestStatisticsUpdateEvent : public QEvent
{
public:
enum Type
{
StatisticsUpdateRequest = QEvent::MaxUser - 1025
};
QmitkRequestStatisticsUpdateEvent()
: QEvent( (QEvent::Type) StatisticsUpdateRequest ) {};
};
typedef itk::Image<short, 3> ImageType;
typedef itk::Image<float, 3> FloatImageType;
typedef itk::Image<itk::Vector<float,3>, 3> VectorImageType;
inline bool my_isnan(float x)
{
volatile float d = x;
if(d!=d)
return true;
if(d==d)
return false;
return d != d;
}
QmitkPartialVolumeAnalysisView::QmitkPartialVolumeAnalysisView(QObject * /*parent*/, const char * /*name*/)
: //QmitkFunctionality(),
m_Controls( NULL ),
m_TimeStepperAdapter( NULL ),
m_MeasurementInfoRenderer(0),
m_MeasurementInfoAnnotation(0),
m_SelectedImageNodes( ),
m_SelectedImage( NULL ),
m_SelectedMaskNode( NULL ),
m_SelectedImageMask( NULL ),
m_SelectedPlanarFigureNodes(0),
m_SelectedPlanarFigure( NULL ),
m_IsTensorImage(false),
m_FAImage(0),
m_RDImage(0),
m_ADImage(0),
m_MDImage(0),
m_CAImage(0),
// m_DirectionImage(0),
m_DirectionComp1Image(0),
m_DirectionComp2Image(0),
m_AngularErrorImage(0),
m_SelectedRenderWindow(NULL),
m_LastRenderWindow(NULL),
m_ImageObserverTag( -1 ),
m_ImageMaskObserverTag( -1 ),
m_PlanarFigureObserverTag( -1 ),
m_CurrentStatisticsValid( false ),
m_StatisticsUpdatePending( false ),
m_GaussianSigmaChangedSliding(false),
m_NumberBinsSliding(false),
m_UpsamplingChangedSliding(false),
m_ClusteringResult(NULL),
m_EllipseCounter(0),
m_RectangleCounter(0),
m_PolygonCounter(0),
m_CurrentFigureNodeInitialized(false),
m_QuantifyClass(2),
m_IconTexOFF(new QIcon(":/QmitkPartialVolumeAnalysisView/texIntOFFIcon.png")),
m_IconTexON(new QIcon(":/QmitkPartialVolumeAnalysisView/texIntONIcon.png")),
m_TexIsOn(true),
m_Visible(false)
{
}
QmitkPartialVolumeAnalysisView::~QmitkPartialVolumeAnalysisView()
{
if ( m_SelectedImage.IsNotNull() )
m_SelectedImage->RemoveObserver( m_ImageObserverTag );
if ( m_SelectedImageMask.IsNotNull() )
m_SelectedImageMask->RemoveObserver( m_ImageMaskObserverTag );
if ( m_SelectedPlanarFigure.IsNotNull() )
{
m_SelectedPlanarFigure->RemoveObserver( m_PlanarFigureObserverTag );
m_SelectedPlanarFigure->RemoveObserver( m_InitializedObserverTag );
}
this->GetDataStorage()->AddNodeEvent -= mitk::MessageDelegate1<QmitkPartialVolumeAnalysisView
, const mitk::DataNode*>( this, &QmitkPartialVolumeAnalysisView::NodeAddedInDataStorage );
m_SelectedPlanarFigureNodes->NodeChanged.RemoveListener( mitk::MessageDelegate1<QmitkPartialVolumeAnalysisView
, const mitk::DataNode*>( this, &QmitkPartialVolumeAnalysisView::NodeChanged ) );
m_SelectedPlanarFigureNodes->NodeRemoved.RemoveListener( mitk::MessageDelegate1<QmitkPartialVolumeAnalysisView
, const mitk::DataNode*>( this, &QmitkPartialVolumeAnalysisView::NodeRemoved ) );
m_SelectedPlanarFigureNodes->PropertyChanged.RemoveListener( mitk::MessageDelegate2<QmitkPartialVolumeAnalysisView
, const mitk::DataNode*, const mitk::BaseProperty*>( this, &QmitkPartialVolumeAnalysisView::PropertyChanged ) );
m_SelectedImageNodes->NodeChanged.RemoveListener( mitk::MessageDelegate1<QmitkPartialVolumeAnalysisView
, const mitk::DataNode*>( this, &QmitkPartialVolumeAnalysisView::NodeChanged ) );
m_SelectedImageNodes->NodeRemoved.RemoveListener( mitk::MessageDelegate1<QmitkPartialVolumeAnalysisView
, const mitk::DataNode*>( this, &QmitkPartialVolumeAnalysisView::NodeRemoved ) );
m_SelectedImageNodes->PropertyChanged.RemoveListener( mitk::MessageDelegate2<QmitkPartialVolumeAnalysisView
, const mitk::DataNode*, const mitk::BaseProperty*>( this, &QmitkPartialVolumeAnalysisView::PropertyChanged ) );
}
void QmitkPartialVolumeAnalysisView::CreateQtPartControl(QWidget *parent)
{
if (m_Controls == NULL)
{
m_Controls = new Ui::QmitkPartialVolumeAnalysisViewControls;
m_Controls->setupUi(parent);
this->CreateConnections();
}
SetHistogramVisibility();
m_Controls->m_TextureIntON->setIcon(*m_IconTexON);
m_Controls->m_SimilarAnglesFrame->setVisible(false);
m_Controls->m_SimilarAnglesLabel->setVisible(false);
vtkTextProperty *textProp = vtkTextProperty::New();
textProp->SetColor(1.0, 1.0, 1.0);
m_MeasurementInfoAnnotation = vtkCornerAnnotation::New();
m_MeasurementInfoAnnotation->SetMaximumFontSize(12);
m_MeasurementInfoAnnotation->SetTextProperty(textProp);
m_MeasurementInfoRenderer = vtkRenderer::New();
m_MeasurementInfoRenderer->AddActor(m_MeasurementInfoAnnotation);
m_SelectedPlanarFigureNodes = mitk::DataStorageSelection::New(this->GetDataStorage(), false);
m_SelectedPlanarFigureNodes->NodeChanged.AddListener( mitk::MessageDelegate1<QmitkPartialVolumeAnalysisView
, const mitk::DataNode*>( this, &QmitkPartialVolumeAnalysisView::NodeChanged ) );
m_SelectedPlanarFigureNodes->NodeRemoved.AddListener( mitk::MessageDelegate1<QmitkPartialVolumeAnalysisView
, const mitk::DataNode*>( this, &QmitkPartialVolumeAnalysisView::NodeRemoved ) );
m_SelectedPlanarFigureNodes->PropertyChanged.AddListener( mitk::MessageDelegate2<QmitkPartialVolumeAnalysisView
, const mitk::DataNode*, const mitk::BaseProperty*>( this, &QmitkPartialVolumeAnalysisView::PropertyChanged ) );
m_SelectedImageNodes = mitk::DataStorageSelection::New(this->GetDataStorage(), false);
m_SelectedImageNodes->PropertyChanged.AddListener( mitk::MessageDelegate2<QmitkPartialVolumeAnalysisView
, const mitk::DataNode*, const mitk::BaseProperty*>( this, &QmitkPartialVolumeAnalysisView::PropertyChanged ) );
m_SelectedImageNodes->NodeChanged.AddListener( mitk::MessageDelegate1<QmitkPartialVolumeAnalysisView
, const mitk::DataNode*>( this, &QmitkPartialVolumeAnalysisView::NodeChanged ) );
m_SelectedImageNodes->NodeRemoved.AddListener( mitk::MessageDelegate1<QmitkPartialVolumeAnalysisView
, const mitk::DataNode*>( this, &QmitkPartialVolumeAnalysisView::NodeRemoved ) );
this->GetDataStorage()->AddNodeEvent.AddListener( mitk::MessageDelegate1<QmitkPartialVolumeAnalysisView
, const mitk::DataNode*>( this, &QmitkPartialVolumeAnalysisView::NodeAddedInDataStorage ) );
Select(NULL,true,true);
SetAdvancedVisibility();
}
void QmitkPartialVolumeAnalysisView::SetHistogramVisibility()
{
m_Controls->m_HistogramWidget->setVisible(m_Controls->m_DisplayHistogramCheckbox->isChecked());
}
void QmitkPartialVolumeAnalysisView::SetAdvancedVisibility()
{
m_Controls->frame_7->setVisible(m_Controls->m_AdvancedCheckbox->isChecked());
}
void QmitkPartialVolumeAnalysisView::CreateConnections()
{
if ( m_Controls )
{
connect( m_Controls->m_DisplayHistogramCheckbox, SIGNAL( clicked() )
, this, SLOT( SetHistogramVisibility() ) );
connect( m_Controls->m_AdvancedCheckbox, SIGNAL( clicked() )
, this, SLOT( SetAdvancedVisibility() ) );
connect( m_Controls->m_NumberBinsSlider, SIGNAL( sliderReleased () ),
this, SLOT( NumberBinsReleasedSlider( ) ) );
connect( m_Controls->m_UpsamplingSlider, SIGNAL( sliderReleased( ) ),
this, SLOT( UpsamplingReleasedSlider( ) ) );
connect( m_Controls->m_GaussianSigmaSlider, SIGNAL( sliderReleased( ) ),
this, SLOT( GaussianSigmaReleasedSlider( ) ) );
connect( m_Controls->m_SimilarAnglesSlider, SIGNAL( sliderReleased( ) ),
this, SLOT( SimilarAnglesReleasedSlider( ) ) );
connect( m_Controls->m_NumberBinsSlider, SIGNAL( valueChanged (int) ),
this, SLOT( NumberBinsChangedSlider( int ) ) );
connect( m_Controls->m_UpsamplingSlider, SIGNAL( valueChanged( int ) ),
this, SLOT( UpsamplingChangedSlider( int ) ) );
connect( m_Controls->m_GaussianSigmaSlider, SIGNAL( valueChanged( int ) ),
this, SLOT( GaussianSigmaChangedSlider( int ) ) );
connect( m_Controls->m_SimilarAnglesSlider, SIGNAL( valueChanged( int ) ),
this, SLOT( SimilarAnglesChangedSlider(int) ) );
connect( m_Controls->m_OpacitySlider, SIGNAL( valueChanged( int ) ),
this, SLOT( OpacityChangedSlider(int) ) );
connect( (QObject*)(m_Controls->m_ButtonCopyHistogramToClipboard), SIGNAL(clicked()),(QObject*) this, SLOT(ToClipBoard()));
connect( m_Controls->m_CircleButton, SIGNAL( clicked() )
, this, SLOT( ActionDrawEllipseTriggered() ) );
connect( m_Controls->m_RectangleButton, SIGNAL( clicked() )
, this, SLOT( ActionDrawRectangleTriggered() ) );
connect( m_Controls->m_PolygonButton, SIGNAL( clicked() )
, this, SLOT( ActionDrawPolygonTriggered() ) );
connect( m_Controls->m_GreenRadio, SIGNAL( clicked(bool) )
, this, SLOT( GreenRadio(bool) ) );
connect( m_Controls->m_PartialVolumeRadio, SIGNAL( clicked(bool) )
, this, SLOT( PartialVolumeRadio(bool) ) );
connect( m_Controls->m_BlueRadio, SIGNAL( clicked(bool) )
, this, SLOT( BlueRadio(bool) ) );
connect( m_Controls->m_AllRadio, SIGNAL( clicked(bool) )
, this, SLOT( AllRadio(bool) ) );
connect( m_Controls->m_EstimateCircle, SIGNAL( clicked() )
, this, SLOT( EstimateCircle() ) );
connect( (QObject*)(m_Controls->m_TextureIntON), SIGNAL(clicked()), this, SLOT(TextIntON()) );
connect( m_Controls->m_ExportClusteringResultsButton, SIGNAL(clicked()), this, SLOT(ExportClusteringResults()));
}
}
void QmitkPartialVolumeAnalysisView::ExportClusteringResults()
{
if (m_ClusteringResult.IsNull() || m_SelectedImage.IsNull())
return;
mitk::BaseGeometry* geometry = m_SelectedImage->GetGeometry();
itk::Image< short, 3>::Pointer referenceImage = itk::Image< short, 3>::New();
itk::Vector<double,3> newSpacing = geometry->GetSpacing();
mitk::Point3D newOrigin = geometry->GetOrigin();
mitk::Geometry3D::BoundsArrayType bounds = geometry->GetBounds();
newOrigin[0] += bounds.GetElement(0);
newOrigin[1] += bounds.GetElement(2);
newOrigin[2] += bounds.GetElement(4);
itk::Matrix<double, 3, 3> newDirection;
itk::ImageRegion<3> imageRegion;
for (int i=0; i<3; i++)
for (int j=0; j<3; j++)
newDirection[j][i] = geometry->GetMatrixColumn(i)[j]/newSpacing[j];
imageRegion.SetSize(0, geometry->GetExtent(0));
imageRegion.SetSize(1, geometry->GetExtent(1));
imageRegion.SetSize(2, geometry->GetExtent(2));
// apply new image parameters
referenceImage->SetSpacing( newSpacing );
referenceImage->SetOrigin( newOrigin );
referenceImage->SetDirection( newDirection );
referenceImage->SetRegions( imageRegion );
referenceImage->Allocate();
typedef itk::Image< float, 3 > OutType;
mitk::Image::Pointer mitkInImage = dynamic_cast<mitk::Image*>(m_ClusteringResult->GetData());
typedef itk::Image< itk::RGBAPixel<unsigned char>, 3 > ItkRgbaImageType;
typedef mitk::ImageToItk< ItkRgbaImageType > CasterType;
CasterType::Pointer caster = CasterType::New();
caster->SetInput(mitkInImage);
caster->Update();
ItkRgbaImageType::Pointer itkInImage = caster->GetOutput();
typedef itk::ExtractChannelFromRgbaImageFilter< itk::Image< short, 3>, OutType > ExtractionFilterType;
ExtractionFilterType::Pointer filter = ExtractionFilterType::New();
filter->SetInput(itkInImage);
filter->SetChannel(ExtractionFilterType::ALPHA);
filter->SetReferenceImage(referenceImage);
filter->Update();
OutType::Pointer outImg = filter->GetOutput();
mitk::Image::Pointer img = mitk::Image::New(); img->InitializeByItk(outImg.GetPointer());
img->SetVolume(outImg->GetBufferPointer());
// init data node
mitk::DataNode::Pointer node = mitk::DataNode::New();
node->SetData(img);
node->SetName("Clustering Result");
GetDataStorage()->Add(node);
}
void QmitkPartialVolumeAnalysisView::EstimateCircle()
{
typedef itk::Image<unsigned char, 3> SegImageType;
SegImageType::Pointer mask_itk = SegImageType::New();
typedef mitk::ImageToItk<SegImageType> CastType;
CastType::Pointer caster = CastType::New();
caster->SetInput(m_SelectedImageMask);
caster->Update();
typedef itk::ImageMomentsCalculator< SegImageType > MomentsType;
MomentsType::Pointer momentsCalc = MomentsType::New();
momentsCalc->SetImage(caster->GetOutput());
momentsCalc->Compute();
MomentsType::VectorType cog = momentsCalc->GetCenterOfGravity();
MomentsType::MatrixType axes = momentsCalc->GetPrincipalAxes();
MomentsType::VectorType moments = momentsCalc->GetPrincipalMoments();
// moments-coord conversion
// third coordinate min oder max?
// max-min = extent
MomentsType::AffineTransformPointer trafo = momentsCalc->GetPhysicalAxesToPrincipalAxesTransform();
itk::ImageRegionIterator<SegImageType>
itimage(caster->GetOutput(), caster->GetOutput()->GetLargestPossibleRegion());
itimage = itimage.Begin();
double max = -9999999999.0;
double min = 9999999999.0;
while( !itimage.IsAtEnd() )
{
if(itimage.Get())
{
ImageType::IndexType index = itimage.GetIndex();
itk::Point<float,3> point;
caster->GetOutput()->TransformIndexToPhysicalPoint(index,point);
itk::Point<float,3> newPoint;
newPoint = trafo->TransformPoint(point);
if(newPoint[2]<min)
min = newPoint[2];
if(newPoint[2]>max)
max = newPoint[2];
}
++itimage;
}
double extent = max - min;
MITK_DEBUG << "EXTENT = " << extent;
mitk::Point3D origin;
mitk::Vector3D right, bottom, normal;
double factor = 1000.0;
mitk::FillVector3D(origin, cog[0]-factor*axes[1][0]-factor*axes[2][0],
cog[1]-factor*axes[1][1]-factor*axes[2][1],
cog[2]-factor*axes[1][2]-factor*axes[2][2]);
// mitk::FillVector3D(normal, axis[0][0],axis[0][1],axis[0][2]);
mitk::FillVector3D(bottom, 2*factor*axes[1][0], 2*factor*axes[1][1], 2*factor*axes[1][2]);
mitk::FillVector3D(right, 2*factor*axes[2][0], 2*factor*axes[2][1], 2*factor*axes[2][2]);
mitk::PlaneGeometry::Pointer planegeometry = mitk::PlaneGeometry::New();
planegeometry->InitializeStandardPlane(right.Get_vnl_vector(), bottom.Get_vnl_vector());
planegeometry->SetOrigin(origin);
double len1 = sqrt(axes[1][0]*axes[1][0] + axes[1][1]*axes[1][1] + axes[1][2]*axes[1][2]);
double len2 = sqrt(axes[2][0]*axes[2][0] + axes[2][1]*axes[2][1] + axes[2][2]*axes[2][2]);
mitk::Point2D point1;
point1[0] = factor*len1;
point1[1] = factor*len2;
mitk::Point2D point2;
point2[0] = factor*len1+extent*.5;
point2[1] = factor*len2;
mitk::PlanarCircle::Pointer circle = mitk::PlanarCircle::New();
- circle->SetGeometry2D(planegeometry);
+ circle->SetPlaneGeometry(planegeometry);
circle->PlaceFigure( point1 );
circle->SetControlPoint(0,point1);
circle->SetControlPoint(1,point2);
//circle->SetCurrentControlPoint( point2 );
mitk::PlanarFigure::PolyLineType polyline = circle->GetPolyLine( 0 );
MITK_DEBUG << "SIZE of planar figure polyline: " << polyline.size();
AddFigureToDataStorage(circle, "Circle");
}
bool QmitkPartialVolumeAnalysisView::AssertDrawingIsPossible(bool checked)
{
if (m_SelectedImageNodes->GetNode().IsNull())
{
checked = false;
this->HandleException("Please select an image!", dynamic_cast<QWidget *>(this->parent()), true);
return false;
}
//this->GetActiveStdMultiWidget()->SetWidgetPlanesVisibility(false);
return checked;
}
void QmitkPartialVolumeAnalysisView::ActionDrawEllipseTriggered()
{
bool checked = m_Controls->m_CircleButton->isChecked();
if(!this->AssertDrawingIsPossible(checked))
return;
mitk::PlanarCircle::Pointer figure = mitk::PlanarCircle::New();
// using PV_ prefix for planar figures from this view
// to distinguish them from that ones created throught the measurement view
this->AddFigureToDataStorage(figure, QString("PV_Circle%1").arg(++m_EllipseCounter));
MITK_DEBUG << "PlanarCircle created ...";
}
void QmitkPartialVolumeAnalysisView::ActionDrawRectangleTriggered()
{
bool checked = m_Controls->m_RectangleButton->isChecked();
if(!this->AssertDrawingIsPossible(checked))
return;
mitk::PlanarRectangle::Pointer figure = mitk::PlanarRectangle::New();
// using PV_ prefix for planar figures from this view
// to distinguish them from that ones created throught the measurement view
this->AddFigureToDataStorage(figure, QString("PV_Rectangle%1").arg(++m_RectangleCounter));
MITK_DEBUG << "PlanarRectangle created ...";
}
void QmitkPartialVolumeAnalysisView::ActionDrawPolygonTriggered()
{
bool checked = m_Controls->m_PolygonButton->isChecked();
if(!this->AssertDrawingIsPossible(checked))
return;
mitk::PlanarPolygon::Pointer figure = mitk::PlanarPolygon::New();
figure->ClosedOn();
// using PV_ prefix for planar figures from this view
// to distinguish them from that ones created throught the measurement view
this->AddFigureToDataStorage(figure, QString("PV_Polygon%1").arg(++m_PolygonCounter));
MITK_DEBUG << "PlanarPolygon created ...";
}
void QmitkPartialVolumeAnalysisView::AddFigureToDataStorage(mitk::PlanarFigure* figure, const QString& name,
const char *propertyKey, mitk::BaseProperty *property )
{
mitk::DataNode::Pointer newNode = mitk::DataNode::New();
newNode->SetName(name.toStdString());
newNode->SetData(figure);
// Add custom property, if available
if ( (propertyKey != NULL) && (property != NULL) )
{
newNode->AddProperty( propertyKey, property );
}
// figure drawn on the topmost layer / image
this->GetDataStorage()->Add(newNode, m_SelectedImageNodes->GetNode() );
QList<mitk::DataNode::Pointer> selectedNodes = this->GetDataManagerSelection();
for(unsigned int i = 0; i < selectedNodes.size(); i++)
{
selectedNodes[i]->SetSelected(false);
}
std::vector<mitk::DataNode *> selectedPFNodes = m_SelectedPlanarFigureNodes->GetNodes();
for(unsigned int i = 0; i < selectedPFNodes.size(); i++)
{
selectedPFNodes[i]->SetSelected(false);
}
newNode->SetSelected(true);
Select(newNode);
}
void QmitkPartialVolumeAnalysisView::PlanarFigureInitialized()
{
if(m_SelectedPlanarFigureNodes->GetNode().IsNull())
return;
m_CurrentFigureNodeInitialized = true;
this->Select(m_SelectedPlanarFigureNodes->GetNode());
m_Controls->m_CircleButton->setChecked(false);
m_Controls->m_RectangleButton->setChecked(false);
m_Controls->m_PolygonButton->setChecked(false);
//this->GetActiveStdMultiWidget()->SetWidgetPlanesVisibility(true);
this->RequestStatisticsUpdate();
}
void QmitkPartialVolumeAnalysisView::PlanarFigureFocus(mitk::DataNode* node)
{
mitk::PlanarFigure* _PlanarFigure = 0;
_PlanarFigure = dynamic_cast<mitk::PlanarFigure*> (node->GetData());
if (_PlanarFigure)
{
FindRenderWindow(node);
- const mitk::PlaneGeometry
- * _PlaneGeometry =
- dynamic_cast<const mitk::PlaneGeometry*> (_PlanarFigure->GetGeometry2D());
+ const mitk::PlaneGeometry* _PlaneGeometry = _PlanarFigure->GetPlaneGeometry();
// make node visible
if (m_SelectedRenderWindow)
{
mitk::Point3D centerP = _PlaneGeometry->GetOrigin();
m_SelectedRenderWindow->GetSliceNavigationController()->ReorientSlices(
centerP, _PlaneGeometry->GetNormal());
m_SelectedRenderWindow->GetSliceNavigationController()->SelectSliceByPoint(
centerP);
}
}
}
void QmitkPartialVolumeAnalysisView::FindRenderWindow(mitk::DataNode* node)
{
if (node && dynamic_cast<mitk::PlanarFigure*> (node->GetData()))
{
m_SelectedRenderWindow = 0;
bool PlanarFigureInitializedWindow = false;
foreach(QmitkRenderWindow * window, this->GetRenderWindowPart()->GetQmitkRenderWindows().values())
{
if (!m_SelectedRenderWindow && node->GetBoolProperty("PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, window->GetRenderer()))
{
m_SelectedRenderWindow = window;
}
}
}
}
void QmitkPartialVolumeAnalysisView::OnSelectionChanged(berry::IWorkbenchPart::Pointer part, const QList<mitk::DataNode::Pointer> &nodes)
{
m_Controls->m_InputData->setTitle("Please Select Input Data");
if (!m_Visible)
return;
if ( nodes.empty() )
{
if (m_ClusteringResult.IsNotNull())
{
this->GetDataStorage()->Remove(m_ClusteringResult);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
Select(NULL, true, true);
}
for (int i=0; i<nodes.size(); i++)
Select(nodes.at(i));
}
void QmitkPartialVolumeAnalysisView::Select( mitk::DataNode::Pointer node, bool clearMaskOnFirstArgNULL, bool clearImageOnFirstArgNULL )
{
// Clear any unreferenced images
this->RemoveOrphanImages();
bool somethingChanged = false;
if(node.IsNull())
{
somethingChanged = true;
if(clearMaskOnFirstArgNULL)
{
if ( (m_SelectedImageMask.IsNotNull()) && (m_ImageMaskObserverTag >= 0) )
{
m_SelectedImageMask->RemoveObserver( m_ImageMaskObserverTag );
m_ImageMaskObserverTag = -1;
}
if ( (m_SelectedPlanarFigure.IsNotNull()) && (m_PlanarFigureObserverTag >= 0) )
{
m_SelectedPlanarFigure->RemoveObserver( m_PlanarFigureObserverTag );
m_PlanarFigureObserverTag = -1;
}
if ( (m_SelectedPlanarFigure.IsNotNull()) && (m_InitializedObserverTag >= 0) )
{
m_SelectedPlanarFigure->RemoveObserver( m_InitializedObserverTag );
m_InitializedObserverTag = -1;
}
m_SelectedPlanarFigure = NULL;
m_SelectedPlanarFigureNodes->RemoveAllNodes();
m_CurrentFigureNodeInitialized = false;
m_SelectedRenderWindow = 0;
m_SelectedMaskNode = NULL;
m_SelectedImageMask = NULL;
}
if(clearImageOnFirstArgNULL)
{
if ( (m_SelectedImage.IsNotNull()) && (m_ImageObserverTag >= 0) )
{
m_SelectedImage->RemoveObserver( m_ImageObserverTag );
m_ImageObserverTag = -1;
}
m_SelectedImageNodes->RemoveAllNodes();
m_SelectedImage = NULL;
m_IsTensorImage = false;
m_FAImage = NULL;
m_RDImage = NULL;
m_ADImage = NULL;
m_MDImage = NULL;
m_CAImage = NULL;
m_DirectionComp1Image = NULL;
m_DirectionComp2Image = NULL;
m_AngularErrorImage = NULL;
m_Controls->m_SimilarAnglesFrame->setVisible(false);
m_Controls->m_SimilarAnglesLabel->setVisible(false);
}
}
else
{
typedef itk::SimpleMemberCommand< QmitkPartialVolumeAnalysisView > ITKCommandType;
ITKCommandType::Pointer changeListener;
changeListener = ITKCommandType::New();
changeListener->SetCallbackFunction( this, &QmitkPartialVolumeAnalysisView::RequestStatisticsUpdate );
// Get selected element
mitk::TensorImage *selectedTensorImage = dynamic_cast< mitk::TensorImage * >( node->GetData() );
mitk::Image *selectedImage = dynamic_cast< mitk::Image * >( node->GetData() );
mitk::PlanarFigure *selectedPlanar = dynamic_cast< mitk::PlanarFigure * >( node->GetData() );
bool isMask = false;
bool isImage = false;
bool isPlanar = false;
bool isTensorImage = false;
if (selectedTensorImage != NULL)
{
isTensorImage = true;
}
else if(selectedImage != NULL)
{
node->GetPropertyValue("binary", isMask);
isImage = !isMask;
}
else if ( (selectedPlanar != NULL) )
{
isPlanar = true;
}
// image
if(isImage && selectedImage->GetDimension()==3)
{
if(selectedImage != m_SelectedImage.GetPointer())
{
somethingChanged = true;
if ( (m_SelectedImage.IsNotNull()) && (m_ImageObserverTag >= 0) )
{
m_SelectedImage->RemoveObserver( m_ImageObserverTag );
m_ImageObserverTag = -1;
}
*m_SelectedImageNodes = node;
m_SelectedImage = selectedImage;
m_IsTensorImage = false;
m_FAImage = NULL;
m_RDImage = NULL;
m_ADImage = NULL;
m_MDImage = NULL;
m_CAImage = NULL;
m_DirectionComp1Image = NULL;
m_DirectionComp2Image = NULL;
m_AngularErrorImage = NULL;
// Add change listeners to selected objects
m_ImageObserverTag = m_SelectedImage->AddObserver(
itk::ModifiedEvent(), changeListener );
m_Controls->m_SimilarAnglesFrame->setVisible(false);
m_Controls->m_SimilarAnglesLabel->setVisible(false);
m_Controls->m_SelectedImageLabel->setText( m_SelectedImageNodes->GetNode()->GetName().c_str() );
}
}
//planar
if(isPlanar)
{
if(selectedPlanar != m_SelectedPlanarFigure.GetPointer())
{
MITK_DEBUG << "Planar selection changed";
somethingChanged = true;
// Possibly previous change listeners
if ( (m_SelectedPlanarFigure.IsNotNull()) && (m_PlanarFigureObserverTag >= 0) )
{
m_SelectedPlanarFigure->RemoveObserver( m_PlanarFigureObserverTag );
m_PlanarFigureObserverTag = -1;
}
if ( (m_SelectedPlanarFigure.IsNotNull()) && (m_InitializedObserverTag >= 0) )
{
m_SelectedPlanarFigure->RemoveObserver( m_InitializedObserverTag );
m_InitializedObserverTag = -1;
}
m_SelectedPlanarFigure = selectedPlanar;
*m_SelectedPlanarFigureNodes = node;
m_CurrentFigureNodeInitialized = selectedPlanar->IsPlaced();
m_SelectedMaskNode = NULL;
m_SelectedImageMask = NULL;
m_PlanarFigureObserverTag = m_SelectedPlanarFigure->AddObserver(
mitk::EndInteractionPlanarFigureEvent(), changeListener );
if(!m_CurrentFigureNodeInitialized)
{
typedef itk::SimpleMemberCommand< QmitkPartialVolumeAnalysisView > ITKCommandType;
ITKCommandType::Pointer initializationCommand;
initializationCommand = ITKCommandType::New();
// set the callback function of the member command
initializationCommand->SetCallbackFunction( this, &QmitkPartialVolumeAnalysisView::PlanarFigureInitialized );
// add an observer
m_InitializedObserverTag = selectedPlanar->AddObserver( mitk::EndPlacementPlanarFigureEvent(), initializationCommand );
}
m_Controls->m_SelectedMaskLabel->setText( m_SelectedPlanarFigureNodes->GetNode()->GetName().c_str() );
PlanarFigureFocus(node);
}
}
//mask
this->m_Controls->m_EstimateCircle->setEnabled(isMask && selectedImage->GetDimension()==3);
if(isMask && selectedImage->GetDimension()==3)
{
if(selectedImage != m_SelectedImage.GetPointer())
{
somethingChanged = true;
if ( (m_SelectedImageMask.IsNotNull()) && (m_ImageMaskObserverTag >= 0) )
{
m_SelectedImageMask->RemoveObserver( m_ImageMaskObserverTag );
m_ImageMaskObserverTag = -1;
}
m_SelectedMaskNode = node;
m_SelectedImageMask = selectedImage;
m_SelectedPlanarFigure = NULL;
m_SelectedPlanarFigureNodes->RemoveAllNodes();
m_ImageMaskObserverTag = m_SelectedImageMask->AddObserver(
itk::ModifiedEvent(), changeListener );
m_Controls->m_SelectedMaskLabel->setText( m_SelectedMaskNode->GetName().c_str() );
}
}
//tensor image
if(isTensorImage && selectedTensorImage->GetDimension()==3)
{
if(selectedImage != m_SelectedImage.GetPointer())
{
somethingChanged = true;
if ( (m_SelectedImage.IsNotNull()) && (m_ImageObserverTag >= 0) )
{
m_SelectedImage->RemoveObserver( m_ImageObserverTag );
m_ImageObserverTag = -1;
}
*m_SelectedImageNodes = node;
m_SelectedImage = selectedImage;
m_IsTensorImage = true;
ExtractTensorImages(selectedImage);
// Add change listeners to selected objects
m_ImageObserverTag = m_SelectedImage->AddObserver(
itk::ModifiedEvent(), changeListener );
m_Controls->m_SimilarAnglesFrame->setVisible(true);
m_Controls->m_SimilarAnglesLabel->setVisible(true);
m_Controls->m_SelectedImageLabel->setText( m_SelectedImageNodes->GetNode()->GetName().c_str() );
}
}
}
if(somethingChanged)
{
this->SetMeasurementInfoToRenderWindow("");
if(m_SelectedPlanarFigure.IsNull() && m_SelectedImageMask.IsNull() )
{
m_Controls->m_SelectedMaskLabel->setText("<font color='red'>mandatory</font>");
m_Controls->m_ResampleOptionsFrame->setEnabled(false);
m_Controls->m_HistogramWidget->setEnabled(false);
m_Controls->m_ClassSelector->setEnabled(false);
m_Controls->m_DisplayHistogramCheckbox->setEnabled(false);
m_Controls->m_AdvancedCheckbox->setEnabled(false);
m_Controls->frame_7->setEnabled(false);
}
else
{
m_Controls->m_ResampleOptionsFrame->setEnabled(true);
m_Controls->m_HistogramWidget->setEnabled(true);
m_Controls->m_ClassSelector->setEnabled(true);
m_Controls->m_DisplayHistogramCheckbox->setEnabled(true);
m_Controls->m_AdvancedCheckbox->setEnabled(true);
m_Controls->frame_7->setEnabled(true);
}
// Clear statistics / histogram GUI if nothing is selected
if ( m_SelectedImage.IsNull() )
{
m_Controls->m_PlanarFigureButtonsFrame->setEnabled(false);
m_Controls->m_OpacityFrame->setEnabled(false);
m_Controls->m_SelectedImageLabel->setText("<font color='red'>mandatory</font>");
}
else
{
m_Controls->m_PlanarFigureButtonsFrame->setEnabled(true);
m_Controls->m_OpacityFrame->setEnabled(true);
}
if( !m_Visible || m_SelectedImage.IsNull()
|| (m_SelectedPlanarFigure.IsNull() && m_SelectedImageMask.IsNull()) )
{
m_Controls->m_InputData->setTitle("Please Select Input Data");
m_Controls->m_HistogramWidget->ClearItemModel();
m_CurrentStatisticsValid = false;
}
else
{
m_Controls->m_InputData->setTitle("Input Data");
this->RequestStatisticsUpdate();
}
}
}
void QmitkPartialVolumeAnalysisView::ShowClusteringResults()
{
typedef itk::Image<unsigned char, 3> MaskImageType;
mitk::Image::Pointer mask = 0;
MaskImageType::Pointer itkmask = 0;
if(m_IsTensorImage && m_Controls->m_SimilarAnglesSlider->value() != 0)
{
typedef itk::Image<float, 3> AngularErrorImageType;
typedef mitk::ImageToItk<AngularErrorImageType> CastType;
CastType::Pointer caster = CastType::New();
caster->SetInput(m_AngularErrorImage);
caster->Update();
typedef itk::BinaryThresholdImageFilter< AngularErrorImageType, MaskImageType > ThreshType;
ThreshType::Pointer thresh = ThreshType::New();
thresh->SetUpperThreshold((90-m_Controls->m_SimilarAnglesSlider->value())*(PVA_PI/180.0));
thresh->SetInsideValue(1.0);
thresh->SetInput(caster->GetOutput());
thresh->Update();
itkmask = thresh->GetOutput();
mask = mitk::Image::New();
mask->InitializeByItk(itkmask.GetPointer());
mask->SetVolume(itkmask->GetBufferPointer());
// GetDefaultDataStorage()->Remove(m_newnode);
// m_newnode = mitk::DataNode::New();
// m_newnode->SetData(mask);
// m_newnode->SetName("masking node");
// m_newnode->SetIntProperty( "layer", 1002 );
// GetDefaultDataStorage()->Add(m_newnode, m_SelectedImageNodes->GetNode());
}
mitk::Image::Pointer clusteredImage;
ClusteringType::Pointer clusterer = ClusteringType::New();
if(m_QuantifyClass==3)
{
if(m_IsTensorImage)
{
double *green_fa, *green_rd, *green_ad, *green_md;
//double *greengray_fa, *greengray_rd, *greengray_ad, *greengray_md;
double *gray_fa, *gray_rd, *gray_ad, *gray_md;
//double *redgray_fa, *redgray_rd, *redgray_ad, *redgray_md;
double *red_fa, *red_rd, *red_ad, *red_md;
mitk::Image* tmpImg = m_CurrentStatisticsCalculator->GetInternalAdditionalResampledImage(0);
mitk::Image::ConstPointer imgToCluster = tmpImg;
red_fa = clusterer->PerformQuantification(imgToCluster, m_CurrentRGBClusteringResults->rgbChannels->r, mask);
green_fa = clusterer->PerformQuantification(imgToCluster, m_CurrentRGBClusteringResults->rgbChannels->g, mask);
gray_fa = clusterer->PerformQuantification(imgToCluster, m_CurrentRGBClusteringResults->rgbChannels->b, mask);
tmpImg = m_CurrentStatisticsCalculator->GetInternalAdditionalResampledImage(3);
mitk::Image::ConstPointer imgToCluster3 = tmpImg;
red_rd = clusterer->PerformQuantification(imgToCluster3, m_CurrentRGBClusteringResults->rgbChannels->r, mask);
green_rd = clusterer->PerformQuantification(imgToCluster3, m_CurrentRGBClusteringResults->rgbChannels->g, mask);
gray_rd = clusterer->PerformQuantification(imgToCluster3, m_CurrentRGBClusteringResults->rgbChannels->b, mask);
tmpImg = m_CurrentStatisticsCalculator->GetInternalAdditionalResampledImage(4);
mitk::Image::ConstPointer imgToCluster4 = tmpImg;
red_ad = clusterer->PerformQuantification(imgToCluster4, m_CurrentRGBClusteringResults->rgbChannels->r, mask);
green_ad = clusterer->PerformQuantification(imgToCluster4, m_CurrentRGBClusteringResults->rgbChannels->g, mask);
gray_ad = clusterer->PerformQuantification(imgToCluster4, m_CurrentRGBClusteringResults->rgbChannels->b, mask);
tmpImg = m_CurrentStatisticsCalculator->GetInternalAdditionalResampledImage(5);
mitk::Image::ConstPointer imgToCluster5 = tmpImg;
red_md = clusterer->PerformQuantification(imgToCluster5, m_CurrentRGBClusteringResults->rgbChannels->r, mask);
green_md = clusterer->PerformQuantification(imgToCluster5, m_CurrentRGBClusteringResults->rgbChannels->g, mask);
gray_md = clusterer->PerformQuantification(imgToCluster5, m_CurrentRGBClusteringResults->rgbChannels->b, mask);
// clipboard
QString clipboardText("FA\t%1\t%2\t\t%3\t%4\t\t%5\t%6\t");
clipboardText = clipboardText
.arg(red_fa[0]).arg(red_fa[1])
.arg(gray_fa[0]).arg(gray_fa[1])
.arg(green_fa[0]).arg(green_fa[1]);
QString clipboardText3("RD\t%1\t%2\t\t%3\t%4\t\t%5\t%6\t");
clipboardText3 = clipboardText3
.arg(red_rd[0]).arg(red_rd[1])
.arg(gray_rd[0]).arg(gray_rd[1])
.arg(green_rd[0]).arg(green_rd[1]);
QString clipboardText4("AD\t%1\t%2\t\t%3\t%4\t\t%5\t%6\t");
clipboardText4 = clipboardText4
.arg(red_ad[0]).arg(red_ad[1])
.arg(gray_ad[0]).arg(gray_ad[1])
.arg(green_ad[0]).arg(green_ad[1]);
QString clipboardText5("MD\t%1\t%2\t\t%3\t%4\t\t%5\t%6");
clipboardText5 = clipboardText5
.arg(red_md[0]).arg(red_md[1])
.arg(gray_md[0]).arg(gray_md[1])
.arg(green_md[0]).arg(green_md[1]);
QApplication::clipboard()->setText(clipboardText+clipboardText3+clipboardText4+clipboardText5, QClipboard::Clipboard);
// now paint infos also on renderwindow
QString plainInfoText("%1 %2 %3 \n");
plainInfoText = plainInfoText
.arg("Red ", 20)
.arg("Gray ", 20)
.arg("Green", 20);
QString plainInfoText0("FA:%1 ± %2%3 ± %4%5 ± %6\n");
plainInfoText0 = plainInfoText0
.arg(red_fa[0], 10, 'g', 2, QLatin1Char( ' ' )).arg(red_fa[1], -10, 'g', 2, QLatin1Char( ' ' ))
.arg(gray_fa[0], 10, 'g', 2, QLatin1Char( ' ' )).arg(gray_fa[1], -10, 'g', 2, QLatin1Char( ' ' ))
.arg(green_fa[0], 10, 'g', 2, QLatin1Char( ' ' )).arg(green_fa[1], -10, 'g', 2, QLatin1Char( ' ' ));
QString plainInfoText3("RDx10³:%1 ± %2%3 ± %4%5 ± %6\n");
plainInfoText3 = plainInfoText3
.arg(1000.0 * red_rd[0], 10, 'g', 2, QLatin1Char( ' ' )).arg(1000.0 * red_rd[1], -10, 'g', 2, QLatin1Char( ' ' ))
.arg(1000.0 * gray_rd[0], 10, 'g', 2, QLatin1Char( ' ' )).arg(1000.0 * gray_rd[1], -10, 'g', 2, QLatin1Char( ' ' ))
.arg(1000.0 * green_rd[0], 10, 'g', 2, QLatin1Char( ' ' )).arg(1000.0 * green_rd[1], -10, 'g', 2, QLatin1Char( ' ' ));
QString plainInfoText4("ADx10³:%1 ± %2%3 ± %4%5 ± %6\n");
plainInfoText4 = plainInfoText4
.arg(1000.0 * red_ad[0], 10, 'g', 2, QLatin1Char( ' ' )).arg(1000.0 * red_ad[1], -10, 'g', 2, QLatin1Char( ' ' ))
.arg(1000.0 * gray_ad[0], 10, 'g', 2, QLatin1Char( ' ' )).arg(1000.0 * gray_ad[1], -10, 'g', 2, QLatin1Char( ' ' ))
.arg(1000.0 * green_ad[0], 10, 'g', 2, QLatin1Char( ' ' )).arg(1000.0 * green_ad[1], -10, 'g', 2, QLatin1Char( ' ' ));
QString plainInfoText5("MDx10³:%1 ± %2%3 ± %4%5 ± %6");
plainInfoText5 = plainInfoText5
.arg(1000.0 * red_md[0], 10, 'g', 2, QLatin1Char( ' ' )).arg(1000.0 * red_md[1], -10, 'g', 2, QLatin1Char( ' ' ))
.arg(1000.0 * gray_md[0], 10, 'g', 2, QLatin1Char( ' ' )).arg(1000.0 * gray_md[1], -10, 'g', 2, QLatin1Char( ' ' ))
.arg(1000.0 * green_md[0], 10, 'g', 2, QLatin1Char( ' ' )).arg(1000.0 * green_md[1], -10, 'g', 2, QLatin1Char( ' ' ));
this->SetMeasurementInfoToRenderWindow(plainInfoText+plainInfoText0+plainInfoText3+plainInfoText4+plainInfoText5);
}
else
{
double* green;
double* gray;
double* red;
mitk::Image* tmpImg = m_CurrentStatisticsCalculator->GetInternalImage();
mitk::Image::ConstPointer imgToCluster = tmpImg;
red = clusterer->PerformQuantification(imgToCluster, m_CurrentRGBClusteringResults->rgbChannels->r);
green = clusterer->PerformQuantification(imgToCluster, m_CurrentRGBClusteringResults->rgbChannels->g);
gray = clusterer->PerformQuantification(imgToCluster, m_CurrentRGBClusteringResults->rgbChannels->b);
// clipboard
QString clipboardText("%1\t%2\t\t%3\t%4\t\t%5\t%6");
clipboardText = clipboardText.arg(red[0]).arg(red[1])
.arg(gray[0]).arg(gray[1])
.arg(green[0]).arg(green[1]);
QApplication::clipboard()->setText(clipboardText, QClipboard::Clipboard);
// now paint infos also on renderwindow
QString plainInfoText("Red: %1 ± %2\nGray: %3 ± %4\nGreen: %5 ± %6");
plainInfoText = plainInfoText.arg(red[0]).arg(red[1])
.arg(gray[0]).arg(gray[1])
.arg(green[0]).arg(green[1]);
this->SetMeasurementInfoToRenderWindow(plainInfoText);
}
clusteredImage = m_CurrentRGBClusteringResults->rgb;
}
else
{
if(m_IsTensorImage)
{
double *red_fa, *red_rd, *red_ad, *red_md;
mitk::Image* tmpImg = m_CurrentStatisticsCalculator->GetInternalAdditionalResampledImage(0);
mitk::Image::ConstPointer imgToCluster = tmpImg;
red_fa = clusterer->PerformQuantification(imgToCluster, m_CurrentPerformClusteringResults->clusteredImage, mask);
tmpImg = m_CurrentStatisticsCalculator->GetInternalAdditionalResampledImage(3);
mitk::Image::ConstPointer imgToCluster3 = tmpImg;
red_rd = clusterer->PerformQuantification(imgToCluster3, m_CurrentPerformClusteringResults->clusteredImage, mask);
tmpImg = m_CurrentStatisticsCalculator->GetInternalAdditionalResampledImage(4);
mitk::Image::ConstPointer imgToCluster4 = tmpImg;
red_ad = clusterer->PerformQuantification(imgToCluster4, m_CurrentPerformClusteringResults->clusteredImage, mask);
tmpImg = m_CurrentStatisticsCalculator->GetInternalAdditionalResampledImage(5);
mitk::Image::ConstPointer imgToCluster5 = tmpImg;
red_md = clusterer->PerformQuantification(imgToCluster5, m_CurrentPerformClusteringResults->clusteredImage, mask);
// clipboard
QString clipboardText("FA\t%1\t%2\t");
clipboardText = clipboardText
.arg(red_fa[0]).arg(red_fa[1]);
QString clipboardText3("RD\t%1\t%2\t");
clipboardText3 = clipboardText3
.arg(red_rd[0]).arg(red_rd[1]);
QString clipboardText4("AD\t%1\t%2\t");
clipboardText4 = clipboardText4
.arg(red_ad[0]).arg(red_ad[1]);
QString clipboardText5("MD\t%1\t%2\t");
clipboardText5 = clipboardText5
.arg(red_md[0]).arg(red_md[1]);
QApplication::clipboard()->setText(clipboardText+clipboardText3+clipboardText4+clipboardText5, QClipboard::Clipboard);
// now paint infos also on renderwindow
QString plainInfoText("%1 \n");
plainInfoText = plainInfoText
.arg("Red ", 20);
QString plainInfoText0("FA:%1 ± %2\n");
plainInfoText0 = plainInfoText0
.arg(red_fa[0], 10, 'g', 2, QLatin1Char( ' ' )).arg(red_fa[1], -10, 'g', 2, QLatin1Char( ' ' ));
QString plainInfoText3("RDx10³:%1 ± %2\n");
plainInfoText3 = plainInfoText3
.arg(1000.0 * red_rd[0], 10, 'g', 2, QLatin1Char( ' ' )).arg(1000.0 * red_rd[1], -10, 'g', 2, QLatin1Char( ' ' ));
QString plainInfoText4("ADx10³:%1 ± %2\n");
plainInfoText4 = plainInfoText4
.arg(1000.0 * red_ad[0], 10, 'g', 2, QLatin1Char( ' ' )).arg(1000.0 * red_ad[1], -10, 'g', 2, QLatin1Char( ' ' ));
QString plainInfoText5("MDx10³:%1 ± %2");
plainInfoText5 = plainInfoText5
.arg(1000.0 * red_md[0], 10, 'g', 2, QLatin1Char( ' ' )).arg(1000.0 * red_md[1], -10, 'g', 2, QLatin1Char( ' ' ));
this->SetMeasurementInfoToRenderWindow(plainInfoText+plainInfoText0+plainInfoText3+plainInfoText4+plainInfoText5);
}
else
{
double* quant;
mitk::Image* tmpImg = m_CurrentStatisticsCalculator->GetInternalImage();
mitk::Image::ConstPointer imgToCluster = tmpImg;
quant = clusterer->PerformQuantification(imgToCluster, m_CurrentPerformClusteringResults->clusteredImage);
// clipboard
QString clipboardText("%1\t%2");
clipboardText = clipboardText.arg(quant[0]).arg(quant[1]);
QApplication::clipboard()->setText(clipboardText, QClipboard::Clipboard);
// now paint infos also on renderwindow
QString plainInfoText("Measurement: %1 ± %2");
plainInfoText = plainInfoText.arg(quant[0]).arg(quant[1]);
this->SetMeasurementInfoToRenderWindow(plainInfoText);
}
clusteredImage = m_CurrentPerformClusteringResults->displayImage;
}
if(mask.IsNotNull())
{
typedef itk::Image<itk::RGBAPixel<unsigned char>,3> RGBImageType;
typedef mitk::ImageToItk<RGBImageType> ClusterCasterType;
ClusterCasterType::Pointer clCaster = ClusterCasterType::New();
clCaster->SetInput(clusteredImage);
clCaster->Update();
clCaster->GetOutput();
typedef itk::MaskImageFilter< RGBImageType, MaskImageType, RGBImageType > MaskType;
MaskType::Pointer masker = MaskType::New();
masker->SetInput1(clCaster->GetOutput());
masker->SetInput2(itkmask);
masker->Update();
clusteredImage = mitk::Image::New();
clusteredImage->InitializeByItk(masker->GetOutput());
clusteredImage->SetVolume(masker->GetOutput()->GetBufferPointer());
}
if(m_ClusteringResult.IsNotNull())
{
this->GetDataStorage()->Remove(m_ClusteringResult);
}
m_ClusteringResult = mitk::DataNode::New();
m_ClusteringResult->SetBoolProperty("helper object", true);
m_ClusteringResult->SetIntProperty( "layer", 1000 );
m_ClusteringResult->SetBoolProperty("texture interpolation", m_TexIsOn);
m_ClusteringResult->SetData(clusteredImage);
m_ClusteringResult->SetName("Clusterprobs");
this->GetDataStorage()->Add(m_ClusteringResult, m_SelectedImageNodes->GetNode());
if(m_SelectedPlanarFigure.IsNotNull() && m_SelectedPlanarFigureNodes->GetNode().IsNotNull())
{
m_SelectedPlanarFigureNodes->GetNode()->SetIntProperty( "layer", 1001 );
}
this->RequestRenderWindowUpdate();
}
void QmitkPartialVolumeAnalysisView::UpdateStatistics()
{
if(!m_CurrentFigureNodeInitialized && m_SelectedPlanarFigure.IsNotNull())
{
MITK_DEBUG << "Selected planar figure not initialized. No stats calculation performed.";
return;
}
// Remove any cached images that are no longer referenced elsewhere
this->RemoveOrphanImages();
QmitkStdMultiWidget *multiWidget = 0;
QmitkStdMultiWidgetEditor * multiWidgetEdit = 0;
multiWidgetEdit = dynamic_cast<QmitkStdMultiWidgetEditor *>(this->GetRenderWindowPart());
if(multiWidgetEdit){
multiWidget = multiWidgetEdit->GetStdMultiWidget();
}
if ( multiWidget == NULL )
{
return;
}
if ( m_SelectedImage.IsNotNull() )
{
// Check if a the selected image is a multi-channel image. If yes, statistics
// cannot be calculated currently.
if ( !m_IsTensorImage && m_SelectedImage->GetPixelType().GetNumberOfComponents() > 1 )
{
QMessageBox::information( NULL, "Warning", "Non-tensor multi-component images not supported.");
m_Controls->m_HistogramWidget->ClearItemModel();
m_CurrentStatisticsValid = false;
return;
}
m_CurrentStatisticsCalculator = NULL;
if(!m_IsTensorImage)
{
// Retrieve HistogramStatisticsCalculator from has map (or create a new one
// for this image if non-existant)
PartialVolumeAnalysisMapType::iterator it =
m_PartialVolumeAnalysisMap.find( m_SelectedImage );
if ( it != m_PartialVolumeAnalysisMap.end() )
{
m_CurrentStatisticsCalculator = it->second;
}
}
if(m_CurrentStatisticsCalculator.IsNull())
{
m_CurrentStatisticsCalculator = mitk::PartialVolumeAnalysisHistogramCalculator::New();
m_CurrentStatisticsCalculator->SetPlanarFigureThickness(m_Controls->m_PlanarFiguresThickness->value());
if(m_IsTensorImage)
{
m_CurrentStatisticsCalculator->SetImage( m_CAImage );
m_CurrentStatisticsCalculator->AddAdditionalResamplingImage( m_FAImage );
m_CurrentStatisticsCalculator->AddAdditionalResamplingImage( m_DirectionComp1Image );
m_CurrentStatisticsCalculator->AddAdditionalResamplingImage( m_DirectionComp2Image );
m_CurrentStatisticsCalculator->AddAdditionalResamplingImage( m_RDImage );
m_CurrentStatisticsCalculator->AddAdditionalResamplingImage( m_ADImage );
m_CurrentStatisticsCalculator->AddAdditionalResamplingImage( m_MDImage );
}
else
{
m_CurrentStatisticsCalculator->SetImage( m_SelectedImage );
}
m_PartialVolumeAnalysisMap[m_SelectedImage] = m_CurrentStatisticsCalculator;
MITK_DEBUG << "Creating StatisticsCalculator";
}
std::string maskName;
std::string maskType;
unsigned int maskDimension;
if ( m_SelectedImageMask.IsNotNull() )
{
mitk::PixelType pixelType = m_SelectedImageMask->GetPixelType();
MITK_DEBUG << pixelType.GetPixelTypeAsString();
if(pixelType.GetComponentTypeAsString() == "char")
{
MITK_DEBUG << "Pixel type is char instead of uchar";
return;
}
if(pixelType.GetBitsPerComponent() == 16)
{
//convert from short to uchar
typedef itk::Image<short, 3> ShortImageType;
typedef itk::Image<unsigned char, 3> CharImageType;
CharImageType::Pointer charImage;
ShortImageType::Pointer shortImage;
mitk::CastToItkImage(m_SelectedImageMask, shortImage);
typedef itk::CastImageFilter<ShortImageType, CharImageType> ImageCasterType;
ImageCasterType::Pointer caster = ImageCasterType::New();
caster->SetInput( shortImage );
caster->Update();
charImage = caster->GetOutput();
mitk::CastToMitkImage(charImage, m_SelectedImageMask);
}
m_CurrentStatisticsCalculator->SetImageMask( m_SelectedImageMask );
m_CurrentStatisticsCalculator->SetMaskingModeToImage();
maskName = m_SelectedMaskNode->GetName();
maskType = m_SelectedImageMask->GetNameOfClass();
maskDimension = 3;
std::stringstream maskLabel;
maskLabel << maskName;
if ( maskDimension > 0 )
{
maskLabel << " [" << maskDimension << "D " << maskType << "]";
}
m_Controls->m_SelectedMaskLabel->setText( maskLabel.str().c_str() );
}
else if ( m_SelectedPlanarFigure.IsNotNull() && m_SelectedPlanarFigureNodes->GetNode().IsNotNull())
{
m_CurrentStatisticsCalculator->SetPlanarFigure( m_SelectedPlanarFigure );
m_CurrentStatisticsCalculator->SetMaskingModeToPlanarFigure();
maskName = m_SelectedPlanarFigureNodes->GetNode()->GetName();
maskType = m_SelectedPlanarFigure->GetNameOfClass();
maskDimension = 2;
}
else
{
m_CurrentStatisticsCalculator->SetMaskingModeToNone();
maskName = "-";
maskType = "";
maskDimension = 0;
}
bool statisticsChanged = false;
bool statisticsCalculationSuccessful = false;
// Initialize progress bar
mitk::ProgressBar::GetInstance()->AddStepsToDo( 100 );
// Install listener for progress events and initialize progress bar
typedef itk::SimpleMemberCommand< QmitkPartialVolumeAnalysisView > ITKCommandType;
ITKCommandType::Pointer progressListener;
progressListener = ITKCommandType::New();
progressListener->SetCallbackFunction( this, &QmitkPartialVolumeAnalysisView::UpdateProgressBar );
unsigned long progressObserverTag = m_CurrentStatisticsCalculator
->AddObserver( itk::ProgressEvent(), progressListener );
ClusteringType::ParamsType *cparams = 0;
ClusteringType::ClusterResultType *cresult = 0;
ClusteringType::HistType *chist = 0;
try
{
m_CurrentStatisticsCalculator->SetNumberOfBins(m_Controls->m_NumberBins->text().toInt());
m_CurrentStatisticsCalculator->SetUpsamplingFactor(m_Controls->m_Upsampling->text().toDouble());
m_CurrentStatisticsCalculator->SetGaussianSigma(m_Controls->m_GaussianSigma->text().toDouble());
// Compute statistics
statisticsChanged =
m_CurrentStatisticsCalculator->ComputeStatistics( );
mitk::Image* tmpImg = m_CurrentStatisticsCalculator->GetInternalImage();
mitk::Image::ConstPointer imgToCluster = tmpImg;
if(imgToCluster.IsNotNull())
{
// perform clustering
const HistogramType *histogram = m_CurrentStatisticsCalculator->GetHistogram( );
if(histogram != NULL)
{
ClusteringType::Pointer clusterer = ClusteringType::New();
clusterer->SetStepsNumIntegration(200);
clusterer->SetMaxIt(1000);
mitk::Image::Pointer pFiberImg;
if(m_QuantifyClass==3)
{
if(m_Controls->m_Quantiles->isChecked())
{
m_CurrentRGBClusteringResults = clusterer->PerformRGBQuantiles(imgToCluster, histogram, m_Controls->m_q1->value(),m_Controls->m_q2->value());
}
else
{
m_CurrentRGBClusteringResults = clusterer->PerformRGBClustering(imgToCluster, histogram);
}
pFiberImg = m_CurrentRGBClusteringResults->rgbChannels->r;
cparams = m_CurrentRGBClusteringResults->params;
cresult = m_CurrentRGBClusteringResults->result;
chist = m_CurrentRGBClusteringResults->hist;
}
else
{
if(m_Controls->m_Quantiles->isChecked())
{
m_CurrentPerformClusteringResults =
clusterer->PerformQuantiles(imgToCluster, histogram, m_Controls->m_q1->value(),m_Controls->m_q2->value());
}
else
{
m_CurrentPerformClusteringResults =
clusterer->PerformClustering(imgToCluster, histogram, m_QuantifyClass);
}
pFiberImg = m_CurrentPerformClusteringResults->clusteredImage;
cparams = m_CurrentPerformClusteringResults->params;
cresult = m_CurrentPerformClusteringResults->result;
chist = m_CurrentPerformClusteringResults->hist;
}
if(m_IsTensorImage)
{
m_AngularErrorImage = clusterer->CaculateAngularErrorImage(
m_CurrentStatisticsCalculator->GetInternalAdditionalResampledImage(1),
m_CurrentStatisticsCalculator->GetInternalAdditionalResampledImage(2),
pFiberImg);
// GetDefaultDataStorage()->Remove(m_newnode2);
// m_newnode2 = mitk::DataNode::New();
// m_newnode2->SetData(m_AngularErrorImage);
// m_newnode2->SetName(("AngularError"));
// m_newnode2->SetIntProperty( "layer", 1003 );
// GetDefaultDataStorage()->Add(m_newnode2, m_SelectedImageNodes->GetNode());
// newnode = mitk::DataNode::New();
// newnode->SetData(m_CurrentStatisticsCalculator->GetInternalAdditionalResampledImage(1));
// newnode->SetName(("Comp1"));
// GetDefaultDataStorage()->Add(newnode, m_SelectedImageNodes->GetNode());
// newnode = mitk::DataNode::New();
// newnode->SetData(m_CurrentStatisticsCalculator->GetInternalAdditionalResampledImage(2));
// newnode->SetName(("Comp2"));
// GetDefaultDataStorage()->Add(newnode, m_SelectedImageNodes->GetNode());
}
ShowClusteringResults();
}
}
statisticsCalculationSuccessful = true;
}
catch ( const std::runtime_error &e )
{
QMessageBox::information( NULL, "Warning", e.what());
}
catch ( const std::exception &e )
{
MITK_ERROR << "Caught exception: " << e.what();
QMessageBox::information( NULL, "Warning", e.what());
}
m_CurrentStatisticsCalculator->RemoveObserver( progressObserverTag );
// Make sure that progress bar closes
mitk::ProgressBar::GetInstance()->Progress( 100 );
if ( statisticsCalculationSuccessful )
{
if ( statisticsChanged )
{
// Do not show any error messages
m_CurrentStatisticsValid = true;
}
// m_Controls->m_HistogramWidget->SetHistogramModeToDirectHistogram();
m_Controls->m_HistogramWidget->SetParameters(
cparams, cresult, chist );
// m_Controls->m_HistogramWidget->UpdateItemModelFromHistogram();
}
else
{
m_Controls->m_SelectedMaskLabel->setText("<font color='red'>mandatory</font>");
// Clear statistics and histogram
m_Controls->m_HistogramWidget->ClearItemModel();
m_CurrentStatisticsValid = false;
// If a (non-closed) PlanarFigure is selected, display a line profile widget
if ( m_SelectedPlanarFigure.IsNotNull() )
{
// TODO: enable line profile widget
//m_Controls->m_StatisticsWidgetStack->setCurrentIndex( 1 );
//m_Controls->m_LineProfileWidget->SetImage( m_SelectedImage );
//m_Controls->m_LineProfileWidget->SetPlanarFigure( m_SelectedPlanarFigure );
//m_Controls->m_LineProfileWidget->UpdateItemModelFromPath();
}
}
}
}
void QmitkPartialVolumeAnalysisView::SetMeasurementInfoToRenderWindow(const QString& text)
{
FindRenderWindow(m_SelectedPlanarFigureNodes->GetNode());
if(m_LastRenderWindow != m_SelectedRenderWindow)
{
if(m_LastRenderWindow)
{
QObject::disconnect( m_LastRenderWindow, SIGNAL( destroyed(QObject*) )
, this, SLOT( OnRenderWindowDelete(QObject*) ) );
}
m_LastRenderWindow = m_SelectedRenderWindow;
if(m_LastRenderWindow)
{
QObject::connect( m_LastRenderWindow, SIGNAL( destroyed(QObject*) )
, this, SLOT( OnRenderWindowDelete(QObject*) ) );
}
}
if(m_LastRenderWindow && m_SelectedPlanarFigureNodes->GetNode().IsNotNull())
{
if (!text.isEmpty())
{
m_MeasurementInfoAnnotation->SetText(1, text.toLatin1().data());
mitk::VtkLayerController::GetInstance(m_LastRenderWindow->GetRenderWindow())->InsertForegroundRenderer(
m_MeasurementInfoRenderer, true);
}
else
{
if (mitk::VtkLayerController::GetInstance(
m_LastRenderWindow->GetRenderWindow()) ->IsRendererInserted(
m_MeasurementInfoRenderer))
mitk::VtkLayerController::GetInstance(m_LastRenderWindow->GetRenderWindow())->RemoveRenderer(
m_MeasurementInfoRenderer);
}
}
else
{
QmitkStdMultiWidget *multiWidget = 0;
QmitkStdMultiWidgetEditor * multiWidgetEdit = 0;
multiWidgetEdit = dynamic_cast<QmitkStdMultiWidgetEditor *>(this->GetRenderWindowPart());
if(multiWidgetEdit){
multiWidget = multiWidgetEdit->GetStdMultiWidget();
}
if ( multiWidget == NULL )
{
return;
}
if (!text.isEmpty())
{
m_MeasurementInfoAnnotation->SetText(1, text.toLatin1().data());
mitk::VtkLayerController::GetInstance(multiWidget->GetRenderWindow1()->GetRenderWindow())->InsertForegroundRenderer(
m_MeasurementInfoRenderer, true);
}
else
{
if (mitk::VtkLayerController::GetInstance(
multiWidget->GetRenderWindow1()->GetRenderWindow()) ->IsRendererInserted(
m_MeasurementInfoRenderer))
mitk::VtkLayerController::GetInstance(multiWidget->GetRenderWindow1()->GetRenderWindow())->RemoveRenderer(
m_MeasurementInfoRenderer);
}
}
}
void QmitkPartialVolumeAnalysisView::UpdateProgressBar()
{
mitk::ProgressBar::GetInstance()->Progress();
}
void QmitkPartialVolumeAnalysisView::RequestStatisticsUpdate()
{
if ( !m_StatisticsUpdatePending )
{
QApplication::postEvent( this, new QmitkRequestStatisticsUpdateEvent );
m_StatisticsUpdatePending = true;
}
}
void QmitkPartialVolumeAnalysisView::RemoveOrphanImages()
{
PartialVolumeAnalysisMapType::iterator it = m_PartialVolumeAnalysisMap.begin();
while ( it != m_PartialVolumeAnalysisMap.end() )
{
mitk::Image *image = it->first;
mitk::PartialVolumeAnalysisHistogramCalculator *calculator = it->second;
++it;
mitk::NodePredicateData::Pointer hasImage = mitk::NodePredicateData::New( image );
if ( this->GetDataStorage()->GetNode( hasImage ) == NULL )
{
if ( m_SelectedImage == image )
{
m_SelectedImage = NULL;
m_SelectedImageNodes->RemoveAllNodes();
}
if ( m_CurrentStatisticsCalculator == calculator )
{
m_CurrentStatisticsCalculator = NULL;
}
m_PartialVolumeAnalysisMap.erase( image );
it = m_PartialVolumeAnalysisMap.begin();
}
}
}
void QmitkPartialVolumeAnalysisView::ExtractTensorImages(
mitk::Image::Pointer tensorimage)
{
typedef itk::Image< itk::DiffusionTensor3D<float>, 3> TensorImageType;
typedef mitk::ImageToItk<TensorImageType> CastType;
CastType::Pointer caster = CastType::New();
caster->SetInput(tensorimage);
caster->Update();
TensorImageType::Pointer image = caster->GetOutput();
typedef itk::TensorDerivedMeasurementsFilter<float> MeasurementsType;
MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New();
measurementsCalculator->SetInput(image );
measurementsCalculator->SetMeasure(MeasurementsType::FA);
measurementsCalculator->Update();
MeasurementsType::OutputImageType::Pointer fa = measurementsCalculator->GetOutput();
m_FAImage = mitk::Image::New();
m_FAImage->InitializeByItk(fa.GetPointer());
m_FAImage->SetVolume(fa->GetBufferPointer());
// mitk::DataNode::Pointer node = mitk::DataNode::New();
// node->SetData(m_FAImage);
// GetDefaultDataStorage()->Add(node);
measurementsCalculator = MeasurementsType::New();
measurementsCalculator->SetInput(image );
measurementsCalculator->SetMeasure(MeasurementsType::CA);
measurementsCalculator->Update();
MeasurementsType::OutputImageType::Pointer ca = measurementsCalculator->GetOutput();
m_CAImage = mitk::Image::New();
m_CAImage->InitializeByItk(ca.GetPointer());
m_CAImage->SetVolume(ca->GetBufferPointer());
// node = mitk::DataNode::New();
// node->SetData(m_CAImage);
// GetDefaultDataStorage()->Add(node);
measurementsCalculator = MeasurementsType::New();
measurementsCalculator->SetInput(image );
measurementsCalculator->SetMeasure(MeasurementsType::RD);
measurementsCalculator->Update();
MeasurementsType::OutputImageType::Pointer rd = measurementsCalculator->GetOutput();
m_RDImage = mitk::Image::New();
m_RDImage->InitializeByItk(rd.GetPointer());
m_RDImage->SetVolume(rd->GetBufferPointer());
// node = mitk::DataNode::New();
// node->SetData(m_CAImage);
// GetDefaultDataStorage()->Add(node);
measurementsCalculator = MeasurementsType::New();
measurementsCalculator->SetInput(image );
measurementsCalculator->SetMeasure(MeasurementsType::AD);
measurementsCalculator->Update();
MeasurementsType::OutputImageType::Pointer ad = measurementsCalculator->GetOutput();
m_ADImage = mitk::Image::New();
m_ADImage->InitializeByItk(ad.GetPointer());
m_ADImage->SetVolume(ad->GetBufferPointer());
// node = mitk::DataNode::New();
// node->SetData(m_CAImage);
// GetDefaultDataStorage()->Add(node);
measurementsCalculator = MeasurementsType::New();
measurementsCalculator->SetInput(image );
measurementsCalculator->SetMeasure(MeasurementsType::RA);
measurementsCalculator->Update();
MeasurementsType::OutputImageType::Pointer md = measurementsCalculator->GetOutput();
m_MDImage = mitk::Image::New();
m_MDImage->InitializeByItk(md.GetPointer());
m_MDImage->SetVolume(md->GetBufferPointer());
// node = mitk::DataNode::New();
// node->SetData(m_CAImage);
// GetDefaultDataStorage()->Add(node);
typedef DirectionsFilterType::OutputImageType DirImageType;
DirectionsFilterType::Pointer dirFilter = DirectionsFilterType::New();
dirFilter->SetInput(image );
dirFilter->Update();
itk::ImageRegionIterator<DirImageType>
itd(dirFilter->GetOutput(), dirFilter->GetOutput()->GetLargestPossibleRegion());
itd = itd.Begin();
while( !itd.IsAtEnd() )
{
DirImageType::PixelType direction = itd.Get();
direction[0] = fabs(direction[0]);
direction[1] = fabs(direction[1]);
direction[2] = fabs(direction[2]);
itd.Set(direction);
++itd;
}
typedef itk::CartesianToPolarVectorImageFilter<
DirImageType, DirImageType, true> C2PFilterType;
C2PFilterType::Pointer cpFilter = C2PFilterType::New();
cpFilter->SetInput(dirFilter->GetOutput());
cpFilter->Update();
DirImageType::Pointer dir = cpFilter->GetOutput();
typedef itk::Image<float, 3> CompImageType;
CompImageType::Pointer comp1 = CompImageType::New();
comp1->SetSpacing( dir->GetSpacing() ); // Set the image spacing
comp1->SetOrigin( dir->GetOrigin() ); // Set the image origin
comp1->SetDirection( dir->GetDirection() ); // Set the image direction
comp1->SetRegions( dir->GetLargestPossibleRegion() );
comp1->Allocate();
CompImageType::Pointer comp2 = CompImageType::New();
comp2->SetSpacing( dir->GetSpacing() ); // Set the image spacing
comp2->SetOrigin( dir->GetOrigin() ); // Set the image origin
comp2->SetDirection( dir->GetDirection() ); // Set the image direction
comp2->SetRegions( dir->GetLargestPossibleRegion() );
comp2->Allocate();
itk::ImageRegionConstIterator<DirImageType>
it(dir, dir->GetLargestPossibleRegion());
itk::ImageRegionIterator<CompImageType>
it1(comp1, comp1->GetLargestPossibleRegion());
itk::ImageRegionIterator<CompImageType>
it2(comp2, comp2->GetLargestPossibleRegion());
it = it.Begin();
it1 = it1.Begin();
it2 = it2.Begin();
while( !it.IsAtEnd() )
{
it1.Set(it.Get()[1]);
it2.Set(it.Get()[2]);
++it;
++it1;
++it2;
}
m_DirectionComp1Image = mitk::Image::New();
m_DirectionComp1Image->InitializeByItk(comp1.GetPointer());
m_DirectionComp1Image->SetVolume(comp1->GetBufferPointer());
m_DirectionComp2Image = mitk::Image::New();
m_DirectionComp2Image->InitializeByItk(comp2.GetPointer());
m_DirectionComp2Image->SetVolume(comp2->GetBufferPointer());
}
void QmitkPartialVolumeAnalysisView::OnRenderWindowDelete(QObject * obj)
{
if(obj == m_LastRenderWindow)
m_LastRenderWindow = 0;
if(obj == m_SelectedRenderWindow)
m_SelectedRenderWindow = 0;
}
bool QmitkPartialVolumeAnalysisView::event( QEvent *event )
{
if ( event->type() == (QEvent::Type) QmitkRequestStatisticsUpdateEvent::StatisticsUpdateRequest )
{
// Update statistics
m_StatisticsUpdatePending = false;
this->UpdateStatistics();
return true;
}
return false;
}
bool QmitkPartialVolumeAnalysisView::IsExclusiveFunctionality() const
{
return true;
}
void QmitkPartialVolumeAnalysisView::Activated()
{
mitk::DataStorage::SetOfObjects::ConstPointer _NodeSet = this->GetDataStorage()->GetAll();
mitk::DataNode* node = 0;
mitk::PlanarFigure* figure = 0;
mitk::PlanarFigureInteractor::Pointer figureInteractor = 0;
// finally add all nodes to the model
for(mitk::DataStorage::SetOfObjects::ConstIterator it=_NodeSet->Begin(); it!=_NodeSet->End()
; it++)
{
node = const_cast<mitk::DataNode*>(it->Value().GetPointer());
figure = dynamic_cast<mitk::PlanarFigure*>(node->GetData());
if(figure)
{
figureInteractor = dynamic_cast<mitk::PlanarFigureInteractor*>(node->GetDataInteractor().GetPointer());
if(figureInteractor.IsNull())
{
figureInteractor = mitk::PlanarFigureInteractor::New();
us::Module* planarFigureModule = us::ModuleRegistry::GetModule( "MitkPlanarFigure" );
figureInteractor->LoadStateMachine("PlanarFigureInteraction.xml", planarFigureModule );
figureInteractor->SetEventConfig( "PlanarFigureConfig.xml", planarFigureModule );
figureInteractor->SetDataNode( node );
}
}
}
}
void QmitkPartialVolumeAnalysisView::Deactivated()
{
}
void QmitkPartialVolumeAnalysisView::ActivatedZombieView(berry::IWorkbenchPartReference::Pointer reference)
{
this->SetMeasurementInfoToRenderWindow("");
mitk::DataStorage::SetOfObjects::ConstPointer _NodeSet = this->GetDataStorage()->GetAll();
mitk::DataNode* node = 0;
mitk::PlanarFigure* figure = 0;
mitk::PlanarFigureInteractor::Pointer figureInteractor = 0;
// finally add all nodes to the model
for(mitk::DataStorage::SetOfObjects::ConstIterator it=_NodeSet->Begin(); it!=_NodeSet->End()
; it++)
{
node = const_cast<mitk::DataNode*>(it->Value().GetPointer());
figure = dynamic_cast<mitk::PlanarFigure*>(node->GetData());
if(figure)
{
figureInteractor = dynamic_cast<mitk::PlanarFigureInteractor*>(node->GetDataInteractor().GetPointer());
if(figureInteractor)
figureInteractor->SetDataNode( NULL );
}
}
}
void QmitkPartialVolumeAnalysisView::Hidden()
{
if (m_ClusteringResult.IsNotNull())
{
this->GetDataStorage()->Remove(m_ClusteringResult);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
Select(NULL, true, true);
m_Visible = false;
}
void QmitkPartialVolumeAnalysisView::Visible()
{
m_Visible = true;
berry::IWorkbenchPart::Pointer bla;
if (!this->GetCurrentSelection().empty())
{
this->OnSelectionChanged(bla, this->GetCurrentSelection());
}
else
{
this->OnSelectionChanged(bla, this->GetDataManagerSelection());
}
}
void QmitkPartialVolumeAnalysisView::SetFocus()
{
}
void QmitkPartialVolumeAnalysisView::GreenRadio(bool checked)
{
if(checked)
{
m_Controls->m_PartialVolumeRadio->setChecked(false);
m_Controls->m_BlueRadio->setChecked(false);
m_Controls->m_AllRadio->setChecked(false);
m_Controls->m_ExportClusteringResultsButton->setEnabled(true);
}
m_QuantifyClass = 0;
RequestStatisticsUpdate();
}
void QmitkPartialVolumeAnalysisView::PartialVolumeRadio(bool checked)
{
if(checked)
{
m_Controls->m_GreenRadio->setChecked(false);
m_Controls->m_BlueRadio->setChecked(false);
m_Controls->m_AllRadio->setChecked(false);
m_Controls->m_ExportClusteringResultsButton->setEnabled(true);
}
m_QuantifyClass = 1;
RequestStatisticsUpdate();
}
void QmitkPartialVolumeAnalysisView::BlueRadio(bool checked)
{
if(checked)
{
m_Controls->m_PartialVolumeRadio->setChecked(false);
m_Controls->m_GreenRadio->setChecked(false);
m_Controls->m_AllRadio->setChecked(false);
m_Controls->m_ExportClusteringResultsButton->setEnabled(true);
}
m_QuantifyClass = 2;
RequestStatisticsUpdate();
}
void QmitkPartialVolumeAnalysisView::AllRadio(bool checked)
{
if(checked)
{
m_Controls->m_BlueRadio->setChecked(false);
m_Controls->m_PartialVolumeRadio->setChecked(false);
m_Controls->m_GreenRadio->setChecked(false);
m_Controls->m_ExportClusteringResultsButton->setEnabled(false);
}
m_QuantifyClass = 3;
RequestStatisticsUpdate();
}
void QmitkPartialVolumeAnalysisView::NumberBinsChangedSlider(int v )
{
m_Controls->m_NumberBins->setText(QString("%1").arg(m_Controls->m_NumberBinsSlider->value()*5.0));
}
void QmitkPartialVolumeAnalysisView::UpsamplingChangedSlider( int v)
{
m_Controls->m_Upsampling->setText(QString("%1").arg(m_Controls->m_UpsamplingSlider->value()/10.0));
}
void QmitkPartialVolumeAnalysisView::GaussianSigmaChangedSlider(int v )
{
m_Controls->m_GaussianSigma->setText(QString("%1").arg(m_Controls->m_GaussianSigmaSlider->value()/100.0));
}
void QmitkPartialVolumeAnalysisView::SimilarAnglesChangedSlider(int v )
{
m_Controls->m_SimilarAngles->setText(QString("%1°").arg(90-m_Controls->m_SimilarAnglesSlider->value()));
ShowClusteringResults();
}
void QmitkPartialVolumeAnalysisView::OpacityChangedSlider(int v )
{
if(m_SelectedImageNodes->GetNode().IsNotNull())
{
float opacImag = 1.0f-(v-5)/5.0f;
opacImag = opacImag < 0 ? 0 : opacImag;
m_SelectedImageNodes->GetNode()->SetFloatProperty("opacity", opacImag);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
if(m_ClusteringResult.IsNotNull())
{
float opacClust = v/5.0f;
opacClust = opacClust > 1 ? 1 : opacClust;
m_ClusteringResult->SetFloatProperty("opacity", opacClust);
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void QmitkPartialVolumeAnalysisView::NumberBinsReleasedSlider( )
{
RequestStatisticsUpdate();
}
void QmitkPartialVolumeAnalysisView::UpsamplingReleasedSlider( )
{
RequestStatisticsUpdate();
}
void QmitkPartialVolumeAnalysisView::GaussianSigmaReleasedSlider( )
{
RequestStatisticsUpdate();
}
void QmitkPartialVolumeAnalysisView::SimilarAnglesReleasedSlider( )
{
}
void QmitkPartialVolumeAnalysisView::ToClipBoard()
{
std::vector<std::vector<double>* > vals = m_Controls->m_HistogramWidget->m_Vals;
QString clipboardText;
for (std::vector<std::vector<double>* >::iterator it = vals.begin(); it
!= vals.end(); ++it)
{
for (std::vector<double>::iterator it2 = (**it).begin(); it2 != (**it).end(); ++it2)
{
clipboardText.append(QString("%1 \t").arg(*it2));
}
clipboardText.append(QString("\n"));
}
QApplication::clipboard()->setText(clipboardText, QClipboard::Clipboard);
}
void QmitkPartialVolumeAnalysisView::PropertyChanged(const mitk::DataNode* /*node*/, const mitk::BaseProperty* /*prop*/)
{
}
void QmitkPartialVolumeAnalysisView::NodeChanged(const mitk::DataNode* /*node*/)
{
}
void QmitkPartialVolumeAnalysisView::NodeRemoved(const mitk::DataNode* node)
{
if (dynamic_cast<mitk::PlanarFigure*>(node->GetData()))
this->GetDataStorage()->Remove(m_ClusteringResult);
if( node == m_SelectedPlanarFigureNodes->GetNode().GetPointer()
|| node == m_SelectedMaskNode.GetPointer() )
{
this->Select(NULL,true,false);
SetMeasurementInfoToRenderWindow("");
}
if( node == m_SelectedImageNodes->GetNode().GetPointer() )
{
this->Select(NULL,false,true);
SetMeasurementInfoToRenderWindow("");
}
}
void QmitkPartialVolumeAnalysisView::NodeAddedInDataStorage(const mitk::DataNode* node)
{
if(!m_Visible)
return;
mitk::DataNode* nonConstNode = const_cast<mitk::DataNode*>(node);
mitk::PlanarFigure* figure = dynamic_cast<mitk::PlanarFigure*>(nonConstNode->GetData());
if(figure)
{
// set interactor for new node (if not already set)
mitk::PlanarFigureInteractor::Pointer figureInteractor
= dynamic_cast<mitk::PlanarFigureInteractor*>(node->GetDataInteractor().GetPointer());
if(figureInteractor.IsNull())
{
figureInteractor = mitk::PlanarFigureInteractor::New();
us::Module* planarFigureModule = us::ModuleRegistry::GetModule( "MitkPlanarFigure" );
figureInteractor->LoadStateMachine("PlanarFigureInteraction.xml", planarFigureModule );
figureInteractor->SetEventConfig( "PlanarFigureConfig.xml", planarFigureModule );
figureInteractor->SetDataNode( nonConstNode );
}
// remove uninitialized old planars
if( m_SelectedPlanarFigureNodes->GetNode().IsNotNull() && m_CurrentFigureNodeInitialized == false )
{
mitk::Interactor::Pointer oldInteractor = m_SelectedPlanarFigureNodes->GetNode()->GetInteractor();
if(oldInteractor.IsNotNull())
mitk::GlobalInteraction::GetInstance()->RemoveInteractor(oldInteractor);
this->GetDataStorage()->Remove(m_SelectedPlanarFigureNodes->GetNode());
}
}
}
void QmitkPartialVolumeAnalysisView::TextIntON()
{
if(m_ClusteringResult.IsNotNull())
{
if(m_TexIsOn)
{
m_Controls->m_TextureIntON->setIcon(*m_IconTexOFF);
}
else
{
m_Controls->m_TextureIntON->setIcon(*m_IconTexON);
}
m_ClusteringResult->SetBoolProperty("texture interpolation", !m_TexIsOn);
m_TexIsOn = !m_TexIsOn;
this->RequestRenderWindowUpdate();
}
}
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingView.cpp
index 96d82570d6..f088491113 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingView.cpp
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingView.cpp
@@ -1,1775 +1,1781 @@
/*===================================================================
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.
===================================================================*/
//#define MBILOG_ENABLE_DEBUG
#include "QmitkPreprocessingView.h"
#include "mitkDiffusionImagingConfigure.h"
// qt includes
#include <QMessageBox>
// itk includes
#include "itkTimeProbe.h"
#include "itkB0ImageExtractionImageFilter.h"
#include "itkB0ImageExtractionToSeparateImageFilter.h"
#include "itkBrainMaskExtractionImageFilter.h"
#include "itkCastImageFilter.h"
#include "itkVectorContainer.h"
#include <itkElectrostaticRepulsionDiffusionGradientReductionFilter.h>
#include <itkMergeDiffusionImagesFilter.h>
#include <itkDwiGradientLengthCorrectionFilter.h>
#include <itkDwiNormilzationFilter.h>
// Multishell includes
#include <itkRadialMultishellToSingleshellImageFilter.h>
// Multishell Functors
#include <itkADCAverageFunctor.h>
#include <itkKurtosisFitFunctor.h>
#include <itkBiExpFitFunctor.h>
#include <itkADCFitFunctor.h>
// mitk includes
#include "QmitkDataStorageComboBox.h"
#include "QmitkStdMultiWidget.h"
#include "mitkProgressBar.h"
#include "mitkStatusBar.h"
#include "mitkNodePredicateDataType.h"
#include "mitkProperties.h"
#include "mitkVtkResliceInterpolationProperty.h"
#include "mitkLookupTable.h"
#include "mitkLookupTableProperty.h"
#include "mitkTransferFunction.h"
#include "mitkTransferFunctionProperty.h"
#include "mitkDataNodeObject.h"
#include "mitkOdfNormalizationMethodProperty.h"
#include "mitkOdfScaleByProperty.h"
#include <mitkPointSet.h>
#include <itkAdcImageFilter.h>
#include <itkBrainMaskExtractionImageFilter.h>
#include <mitkImageCast.h>
#include <mitkRotationOperation.h>
#include <QTableWidgetItem>
#include <QTableWidget>
#include <mitkInteractionConst.h>
#include <mitkImageAccessByItk.h>
#include <itkResampleDwiImageFilter.h>
#include <itkResampleImageFilter.h>
#include <itkImageDuplicator.h>
#include <itkMaskImageFilter.h>
#include <mitkNodePredicateProperty.h>
#include <mitkNodePredicateAnd.h>
#include <mitkNodePredicateNot.h>
#include <mitkNodePredicateOr.h>
#include <itkCropImageFilter.h>
#include <itkDiffusionTensor3DReconstructionImageFilter.h>
#include <itkRemoveDwiChannelFilter.h>
#include <itkExtractDwiChannelFilter.h>
const std::string QmitkPreprocessingView::VIEW_ID =
"org.mitk.views.preprocessing";
#define DI_INFO MITK_INFO("DiffusionImaging")
typedef float TTensorPixelType;
QmitkPreprocessingView::QmitkPreprocessingView()
: QmitkFunctionality(),
m_Controls(NULL),
m_MultiWidget(NULL),
m_DiffusionImage(NULL)
{
}
QmitkPreprocessingView::~QmitkPreprocessingView()
{
}
void QmitkPreprocessingView::CreateQtPartControl(QWidget *parent)
{
if (!m_Controls)
{
// create GUI widgets
m_Controls = new Ui::QmitkPreprocessingViewControls;
m_Controls->setupUi(parent);
this->CreateConnections();
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
m_Controls->m_MeasurementFrameTable->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
m_Controls->m_MeasurementFrameTable->verticalHeader()->setResizeMode(QHeaderView::Stretch);
-
m_Controls->m_DirectionMatrixTable->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
m_Controls->m_DirectionMatrixTable->verticalHeader()->setResizeMode(QHeaderView::Stretch);
+#else
+ m_Controls->m_MeasurementFrameTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
+ m_Controls->m_MeasurementFrameTable->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
+ m_Controls->m_DirectionMatrixTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
+ m_Controls->m_DirectionMatrixTable->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
+#endif
}
}
void QmitkPreprocessingView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget)
{
m_MultiWidget = &stdMultiWidget;
}
void QmitkPreprocessingView::StdMultiWidgetNotAvailable()
{
m_MultiWidget = NULL;
}
void QmitkPreprocessingView::CreateConnections()
{
if ( m_Controls )
{
m_Controls->m_NormalizationMaskBox->SetDataStorage(this->GetDataStorage());
mitk::TNodePredicateDataType<mitk::Image>::Pointer isMitkImage = mitk::TNodePredicateDataType<mitk::Image>::New();
mitk::NodePredicateDataType::Pointer isDwi = mitk::NodePredicateDataType::New("DiffusionImage");
mitk::NodePredicateDataType::Pointer isDti = mitk::NodePredicateDataType::New("TensorImage");
mitk::NodePredicateDataType::Pointer isQbi = mitk::NodePredicateDataType::New("QBallImage");
mitk::NodePredicateOr::Pointer isDiffusionImage = mitk::NodePredicateOr::New(isDwi, isDti);
isDiffusionImage = mitk::NodePredicateOr::New(isDiffusionImage, isQbi);
mitk::NodePredicateNot::Pointer noDiffusionImage = mitk::NodePredicateNot::New(isDiffusionImage);
mitk::NodePredicateAnd::Pointer finalPredicate = mitk::NodePredicateAnd::New(isMitkImage, noDiffusionImage);
mitk::NodePredicateProperty::Pointer isBinaryPredicate = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true));
finalPredicate = mitk::NodePredicateAnd::New(finalPredicate, isBinaryPredicate);
m_Controls->m_NormalizationMaskBox->SetPredicate(finalPredicate);
m_Controls->m_ExtractBrainMask->setVisible(false);
m_Controls->m_BrainMaskIterationsBox->setVisible(false);
m_Controls->m_ResampleIntFrame->setVisible(false);
connect( (QObject*)(m_Controls->m_ButtonAverageGradients), SIGNAL(clicked()), this, SLOT(AverageGradients()) );
connect( (QObject*)(m_Controls->m_ButtonExtractB0), SIGNAL(clicked()), this, SLOT(ExtractB0()) );
connect( (QObject*)(m_Controls->m_ModifyMeasurementFrame), SIGNAL(clicked()), this, SLOT(DoApplyMesurementFrame()) );
connect( (QObject*)(m_Controls->m_ReduceGradientsButton), SIGNAL(clicked()), this, SLOT(DoReduceGradientDirections()) );
connect( (QObject*)(m_Controls->m_ShowGradientsButton), SIGNAL(clicked()), this, SLOT(DoShowGradientDirections()) );
connect( (QObject*)(m_Controls->m_MirrorGradientToHalfSphereButton), SIGNAL(clicked()), this, SLOT(DoHalfSphereGradientDirections()) );
connect( (QObject*)(m_Controls->m_MergeDwisButton), SIGNAL(clicked()), this, SLOT(MergeDwis()) );
connect( (QObject*)(m_Controls->m_ProjectSignalButton), SIGNAL(clicked()), this, SLOT(DoProjectSignal()) );
connect( (QObject*)(m_Controls->m_B_ValueMap_Rounder_SpinBox), SIGNAL(valueChanged(int)), this, SLOT(UpdateDwiBValueMapRounder(int)));
connect( (QObject*)(m_Controls->m_CreateLengthCorrectedDwi), SIGNAL(clicked()), this, SLOT(DoLengthCorrection()) );
connect( (QObject*)(m_Controls->m_CalcAdcButton), SIGNAL(clicked()), this, SLOT(DoAdcCalculation()) );
connect( (QObject*)(m_Controls->m_NormalizeImageValuesButton), SIGNAL(clicked()), this, SLOT(DoDwiNormalization()) );
connect( (QObject*)(m_Controls->m_ModifyDirection), SIGNAL(clicked()), this, SLOT(DoApplyDirectionMatrix()) );
connect( (QObject*)(m_Controls->m_ModifySpacingButton), SIGNAL(clicked()), this, SLOT(DoApplySpacing()) );
connect( (QObject*)(m_Controls->m_ModifyOriginButton), SIGNAL(clicked()), this, SLOT(DoApplyOrigin()) );
connect( (QObject*)(m_Controls->m_ResampleImageButton), SIGNAL(clicked()), this, SLOT(DoResampleImage()) );
connect( (QObject*)(m_Controls->m_ResampleTypeBox), SIGNAL(currentIndexChanged(int)), this, SLOT(DoUpdateInterpolationGui(int)) );
connect( (QObject*)(m_Controls->m_CropImageButton), SIGNAL(clicked()), this, SLOT(DoCropImage()) );
connect( (QObject*)(m_Controls->m_RemoveGradientButton), SIGNAL(clicked()), this, SLOT(DoRemoveGradient()) );
connect( (QObject*)(m_Controls->m_ExtractGradientButton), SIGNAL(clicked()), this, SLOT(DoExtractGradient()) );
// connect( (QObject*)(m_Controls->m_ExtractBrainMask), SIGNAL(clicked()), this, SLOT(DoExtractBrainMask()) );
}
}
void QmitkPreprocessingView::DoRemoveGradient()
{
if (m_DiffusionImage.IsNull())
return;
std::vector< unsigned int > channelsToRemove; channelsToRemove.push_back(m_Controls->m_RemoveGradientBox->value());
itk::RemoveDwiChannelFilter< short >::Pointer filter = itk::RemoveDwiChannelFilter< short >::New();
filter->SetInput(m_DiffusionImage->GetVectorImage());
filter->SetChannelIndices(channelsToRemove);
filter->SetDirections(m_DiffusionImage->GetDirections());
filter->Update();
MitkDwiType::Pointer image = MitkDwiType::New();
image->SetVectorImage( filter->GetOutput() );
image->SetReferenceBValue( m_DiffusionImage->GetReferenceBValue() );
image->SetDirections( filter->GetNewDirections() );
image->InitializeFromVectorImage();
mitk::DataNode::Pointer imageNode = mitk::DataNode::New();
imageNode->SetData( image );
QString name = m_SelectedDiffusionNodes.back()->GetName().c_str();
imageNode->SetName((name+"_removedgradients").toStdString().c_str());
GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back());
mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true );
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkPreprocessingView::DoExtractGradient()
{
if (m_DiffusionImage.IsNull())
return;
unsigned int channel = m_Controls->m_ExtractGradientBox->value();
itk::ExtractDwiChannelFilter< short >::Pointer filter = itk::ExtractDwiChannelFilter< short >::New();
filter->SetInput(m_DiffusionImage->GetVectorImage());
filter->SetChannelIndex(channel);
filter->Update();
mitk::Image::Pointer mitkImage = mitk::Image::New();
mitkImage->InitializeByItk( filter->GetOutput() );
mitkImage->SetImportChannel( filter->GetOutput()->GetBufferPointer() );
mitk::DataNode::Pointer imageNode = mitk::DataNode::New();
imageNode->SetData( mitkImage );
QString name = m_SelectedDiffusionNodes.back()->GetName().c_str();
imageNode->SetName((name+"_direction-"+QString::number(channel)).toStdString().c_str());
GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back());
mitk::RenderingManager::GetInstance()->InitializeViews(imageNode->GetData()->GetTimeGeometry(),mitk::RenderingManager::REQUEST_UPDATE_ALL, true);
}
void QmitkPreprocessingView::DoCropImage()
{
if (m_DiffusionImage.IsNotNull())
{
ItkDwiType::SizeType lower;
ItkDwiType::SizeType upper;
lower[0] = m_Controls->m_XstartBox->value();
lower[1] = m_Controls->m_YstartBox->value();
lower[2] = m_Controls->m_ZstartBox->value();
upper[0] = m_Controls->m_XendBox->value();
upper[1] = m_Controls->m_YendBox->value();
upper[2] = m_Controls->m_ZendBox->value();
itk::CropImageFilter< ItkDwiType, ItkDwiType >::Pointer cropper = itk::CropImageFilter< ItkDwiType, ItkDwiType >::New();
cropper->SetLowerBoundaryCropSize(lower);
cropper->SetUpperBoundaryCropSize(upper);
cropper->SetInput(m_DiffusionImage->GetVectorImage());
cropper->Update();
MitkDwiType::Pointer image = MitkDwiType::New();
image->SetVectorImage( cropper->GetOutput() );
image->SetReferenceBValue( m_DiffusionImage->GetReferenceBValue() );
image->SetDirections( m_DiffusionImage->GetDirections() );
image->InitializeFromVectorImage();
mitk::DataNode::Pointer imageNode = mitk::DataNode::New();
imageNode->SetData( image );
QString name = m_SelectedDiffusionNodes.back()->GetName().c_str();
imageNode->SetName((name+"_cropped").toStdString().c_str());
GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back());
mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true );
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true );
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
else if(m_SelectedImage.IsNotNull())
{
AccessFixedDimensionByItk(m_SelectedImage, TemplatedCropImage,3);
}
}
template < typename TPixel, unsigned int VImageDimension >
void QmitkPreprocessingView::TemplatedCropImage( itk::Image<TPixel, VImageDimension>* itkImage)
{
ItkDwiType::SizeType lower;
ItkDwiType::SizeType upper;
lower[0] = m_Controls->m_XstartBox->value();
lower[1] = m_Controls->m_YstartBox->value();
lower[2] = m_Controls->m_ZstartBox->value();
upper[0] = m_Controls->m_XendBox->value();
upper[1] = m_Controls->m_YendBox->value();
upper[2] = m_Controls->m_ZendBox->value();
typedef itk::Image<TPixel, VImageDimension> ImageType;
typename itk::CropImageFilter< ImageType, ImageType >::Pointer cropper = itk::CropImageFilter< ImageType, ImageType >::New();
cropper->SetLowerBoundaryCropSize(lower);
cropper->SetUpperBoundaryCropSize(upper);
cropper->SetInput(itkImage);
cropper->Update();
mitk::Image::Pointer image = mitk::Image::New();
image->InitializeByItk( cropper->GetOutput() );
image->SetVolume( cropper->GetOutput()->GetBufferPointer() );
mitk::DataNode::Pointer imageNode = mitk::DataNode::New();
imageNode->SetData( image );
QString name = m_SelectedImageNode->GetName().c_str();
imageNode->SetName((name+"_cropped").toStdString().c_str());
GetDefaultDataStorage()->Add(imageNode, m_SelectedImageNode);
mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true );
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkPreprocessingView::DoApplySpacing()
{
if (m_DiffusionImage.IsNotNull())
{
mitk::Vector3D spacing;
spacing[0] = m_Controls->m_HeaderSpacingX->value();
spacing[1] = m_Controls->m_HeaderSpacingY->value();
spacing[2] = m_Controls->m_HeaderSpacingZ->value();
MitkDwiType::Pointer image = m_DiffusionImage->Clone();
image->GetVectorImage()->SetSpacing(spacing);
image->InitializeFromVectorImage();
mitk::DataNode::Pointer imageNode = mitk::DataNode::New();
imageNode->SetData( image );
QString name = m_SelectedDiffusionNodes.back()->GetName().c_str();
imageNode->SetName((name+"_newspacing").toStdString().c_str());
GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back());
mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true );
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
else if(m_SelectedImage.IsNotNull())
{
AccessFixedDimensionByItk(m_SelectedImage, TemplatedSetImageSpacing,3);
}
}
template < typename TPixel, unsigned int VImageDimension >
void QmitkPreprocessingView::TemplatedSetImageSpacing( itk::Image<TPixel, VImageDimension>* itkImage)
{
mitk::Vector3D spacing;
spacing[0] = m_Controls->m_HeaderSpacingX->value();
spacing[1] = m_Controls->m_HeaderSpacingY->value();
spacing[2] = m_Controls->m_HeaderSpacingZ->value();
typedef itk::ImageDuplicator< itk::Image<TPixel, VImageDimension> > DuplicateFilterType;
typename DuplicateFilterType::Pointer duplicator = DuplicateFilterType::New();
duplicator->SetInputImage( itkImage );
duplicator->Update();
typename itk::Image<TPixel, VImageDimension>::Pointer newImage = duplicator->GetOutput();
newImage->SetSpacing(spacing);
mitk::Image::Pointer image = mitk::Image::New();
image->InitializeByItk( newImage.GetPointer() );
image->SetVolume( newImage->GetBufferPointer() );
mitk::DataNode::Pointer imageNode = mitk::DataNode::New();
imageNode->SetData( image );
QString name = m_SelectedImageNode->GetName().c_str();
imageNode->SetName((name+"_newspacing").toStdString().c_str());
GetDefaultDataStorage()->Add(imageNode, m_SelectedImageNode);
mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true );
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkPreprocessingView::DoApplyOrigin()
{
if (m_DiffusionImage.IsNotNull())
{
mitk::Vector3D origin;
origin[0] = m_Controls->m_HeaderOriginX->value();
origin[1] = m_Controls->m_HeaderOriginY->value();
origin[2] = m_Controls->m_HeaderOriginZ->value();
MitkDwiType::Pointer image = m_DiffusionImage->Clone();
image->GetVectorImage()->SetOrigin(origin);
image->InitializeFromVectorImage();
mitk::DataNode::Pointer imageNode = mitk::DataNode::New();
imageNode->SetData( image );
QString name = m_SelectedDiffusionNodes.back()->GetName().c_str();
imageNode->SetName((name+"_neworigin").toStdString().c_str());
GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back());
mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true );
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
else if(m_SelectedImage.IsNotNull())
{
AccessFixedDimensionByItk(m_SelectedImage, TemplatedSetImageOrigin,3);
}
}
template < typename TPixel, unsigned int VImageDimension >
void QmitkPreprocessingView::TemplatedSetImageOrigin( itk::Image<TPixel, VImageDimension>* itkImage)
{
mitk::Vector3D origin;
origin[0] = m_Controls->m_HeaderOriginX->value();
origin[1] = m_Controls->m_HeaderOriginY->value();
origin[2] = m_Controls->m_HeaderOriginZ->value();
typedef itk::ImageDuplicator< itk::Image<TPixel, VImageDimension> > DuplicateFilterType;
typename DuplicateFilterType::Pointer duplicator = DuplicateFilterType::New();
duplicator->SetInputImage( itkImage );
duplicator->Update();
typename itk::Image<TPixel, VImageDimension>::Pointer newImage = duplicator->GetOutput();
newImage->SetOrigin(origin);
mitk::Image::Pointer image = mitk::Image::New();
image->InitializeByItk( newImage.GetPointer() );
image->SetVolume( newImage->GetBufferPointer() );
mitk::DataNode::Pointer imageNode = mitk::DataNode::New();
imageNode->SetData( image );
QString name = m_SelectedImageNode->GetName().c_str();
imageNode->SetName((name+"_neworigin").toStdString().c_str());
GetDefaultDataStorage()->Add(imageNode, m_SelectedImageNode);
mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true );
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkPreprocessingView::DoUpdateInterpolationGui(int i)
{
switch (i)
{
case 0:
{
m_Controls->m_ResampleIntFrame->setVisible(false);
m_Controls->m_ResampleDoubleFrame->setVisible(true);
break;
}
case 1:
{
m_Controls->m_ResampleIntFrame->setVisible(false);
m_Controls->m_ResampleDoubleFrame->setVisible(true);
if (m_DiffusionImage.IsNotNull())
{
ItkDwiType::Pointer itkDwi = m_DiffusionImage->GetVectorImage();
m_Controls->m_ResampleDoubleX->setValue(itkDwi->GetSpacing()[0]);
m_Controls->m_ResampleDoubleY->setValue(itkDwi->GetSpacing()[1]);
m_Controls->m_ResampleDoubleZ->setValue(itkDwi->GetSpacing()[2]);
}
else if (m_SelectedImage.IsNotNull())
{
mitk::BaseGeometry* geom = m_SelectedImage->GetGeometry();
m_Controls->m_ResampleDoubleX->setValue(geom->GetSpacing()[0]);
m_Controls->m_ResampleDoubleY->setValue(geom->GetSpacing()[1]);
m_Controls->m_ResampleDoubleZ->setValue(geom->GetSpacing()[2]);
}
break;
}
case 2:
{
m_Controls->m_ResampleIntFrame->setVisible(true);
m_Controls->m_ResampleDoubleFrame->setVisible(false);
if (m_DiffusionImage.IsNotNull())
{
ItkDwiType::Pointer itkDwi = m_DiffusionImage->GetVectorImage();
m_Controls->m_ResampleIntX->setValue(itkDwi->GetLargestPossibleRegion().GetSize(0));
m_Controls->m_ResampleIntY->setValue(itkDwi->GetLargestPossibleRegion().GetSize(1));
m_Controls->m_ResampleIntZ->setValue(itkDwi->GetLargestPossibleRegion().GetSize(2));
}
else if (m_SelectedImage.IsNotNull())
{
mitk::BaseGeometry* geom = m_SelectedImage->GetGeometry();
m_Controls->m_ResampleIntX->setValue(geom->GetExtent(0));
m_Controls->m_ResampleIntY->setValue(geom->GetExtent(1));
m_Controls->m_ResampleIntZ->setValue(geom->GetExtent(2));
}
break;
}
default:
{
m_Controls->m_ResampleIntFrame->setVisible(false);
m_Controls->m_ResampleDoubleFrame->setVisible(true);
}
}
}
void QmitkPreprocessingView::DoExtractBrainMask()
{
// if (m_SelectedImage.IsNull())
// return;
// typedef itk::Image<unsigned short, 3> ShortImageType;
// ShortImageType::Pointer itkImage = ShortImageType::New();
// mitk::CastToItkImage(m_SelectedImage, itkImage);
// typedef itk::BrainMaskExtractionImageFilter< unsigned char > FilterType;
// FilterType::Pointer filter = FilterType::New();
// filter->SetInput(itkImage);
// filter->SetMaxNumIterations(m_Controls->m_BrainMaskIterationsBox->value());
// filter->Update();
// mitk::Image::Pointer image = mitk::Image::New();
// image->InitializeByItk( filter->GetOutput() );
// image->SetVolume( filter->GetOutput()->GetBufferPointer() );
// mitk::DataNode::Pointer imageNode = mitk::DataNode::New();
// imageNode->SetData( image );
// imageNode->SetName("BRAINMASK");
// GetDefaultDataStorage()->Add(imageNode);
}
void QmitkPreprocessingView::DoResampleImage()
{
if (m_DiffusionImage.IsNotNull())
{
typedef itk::ResampleDwiImageFilter< short > ResampleFilter;
ResampleFilter::Pointer resampler = ResampleFilter::New();
resampler->SetInput(m_DiffusionImage->GetVectorImage());
switch (m_Controls->m_ResampleTypeBox->currentIndex())
{
case 0:
{
itk::Vector< double, 3 > samplingFactor;
samplingFactor[0] = m_Controls->m_ResampleDoubleX->value();
samplingFactor[1] = m_Controls->m_ResampleDoubleY->value();
samplingFactor[2] = m_Controls->m_ResampleDoubleZ->value();
resampler->SetSamplingFactor(samplingFactor);
break;
}
case 1:
{
itk::Vector< double, 3 > newSpacing;
newSpacing[0] = m_Controls->m_ResampleDoubleX->value();
newSpacing[1] = m_Controls->m_ResampleDoubleY->value();
newSpacing[2] = m_Controls->m_ResampleDoubleZ->value();
resampler->SetNewSpacing(newSpacing);
break;
}
case 2:
{
itk::ImageRegion<3> newRegion;
newRegion.SetSize(0, m_Controls->m_ResampleIntX->value());
newRegion.SetSize(1, m_Controls->m_ResampleIntY->value());
newRegion.SetSize(2, m_Controls->m_ResampleIntZ->value());
resampler->SetNewImageSize(newRegion);
break;
}
default:
{
MITK_WARN << "Unknown resampling parameters!";
return;
}
}
QString outAdd;
switch (m_Controls->m_InterpolatorBox->currentIndex())
{
case 0:
{
resampler->SetInterpolation(ResampleFilter::Interpolate_NearestNeighbour);
outAdd = "NearestNeighbour";
break;
}
case 1:
{
resampler->SetInterpolation(ResampleFilter::Interpolate_Linear);
outAdd = "Linear";
break;
}
case 2:
{
resampler->SetInterpolation(ResampleFilter::Interpolate_BSpline);
outAdd = "BSpline";
break;
}
case 3:
{
resampler->SetInterpolation(ResampleFilter::Interpolate_WindowedSinc);
outAdd = "WindowedSinc";
break;
}
default:
{
resampler->SetInterpolation(ResampleFilter::Interpolate_NearestNeighbour);
outAdd = "NearestNeighbour";
}
}
resampler->Update();
typedef mitk::DiffusionImage<DiffusionPixelType> DiffusionImageType;
DiffusionImageType::Pointer image = DiffusionImageType::New();
image->SetVectorImage( resampler->GetOutput() );
image->SetReferenceBValue( m_DiffusionImage->GetReferenceBValue() );
image->SetDirections( m_DiffusionImage->GetDirections() );
image->InitializeFromVectorImage();
mitk::DataNode::Pointer imageNode = mitk::DataNode::New();
imageNode->SetData( image );
QString name = m_SelectedDiffusionNodes.back()->GetName().c_str();
imageNode->SetName((name+"_resampled_"+outAdd).toStdString().c_str());
GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back());
}
else if (m_SelectedImage.IsNotNull())
{
AccessFixedDimensionByItk(m_SelectedImage, TemplatedResampleImage,3);
}
}
template < typename TPixel, unsigned int VImageDimension >
void QmitkPreprocessingView::TemplatedResampleImage( itk::Image<TPixel, VImageDimension>* itkImage)
{
itk::Vector< double, 3 > newSpacing;
itk::ImageRegion<3> newRegion;
switch (m_Controls->m_ResampleTypeBox->currentIndex())
{
case 0:
{
itk::Vector< double, 3 > sampling;
sampling[0] = m_Controls->m_ResampleDoubleX->value();
sampling[1] = m_Controls->m_ResampleDoubleY->value();
sampling[2] = m_Controls->m_ResampleDoubleZ->value();
newSpacing = itkImage->GetSpacing();
newSpacing[0] /= sampling[0];
newSpacing[1] /= sampling[1];
newSpacing[2] /= sampling[2];
newRegion = itkImage->GetLargestPossibleRegion();
newRegion.SetSize(0, newRegion.GetSize(0)*sampling[0]);
newRegion.SetSize(1, newRegion.GetSize(1)*sampling[1]);
newRegion.SetSize(2, newRegion.GetSize(2)*sampling[2]);
break;
}
case 1:
{
newSpacing[0] = m_Controls->m_ResampleDoubleX->value();
newSpacing[1] = m_Controls->m_ResampleDoubleY->value();
newSpacing[2] = m_Controls->m_ResampleDoubleZ->value();
itk::Vector< double, 3 > oldSpacing = itkImage->GetSpacing();
itk::Vector< double, 3 > sampling;
sampling[0] = oldSpacing[0]/newSpacing[0];
sampling[1] = oldSpacing[1]/newSpacing[1];
sampling[2] = oldSpacing[2]/newSpacing[2];
newRegion = itkImage->GetLargestPossibleRegion();
newRegion.SetSize(0, newRegion.GetSize(0)*sampling[0]);
newRegion.SetSize(1, newRegion.GetSize(1)*sampling[1]);
newRegion.SetSize(2, newRegion.GetSize(2)*sampling[2]);
break;
}
case 2:
{
newRegion.SetSize(0, m_Controls->m_ResampleIntX->value());
newRegion.SetSize(1, m_Controls->m_ResampleIntY->value());
newRegion.SetSize(2, m_Controls->m_ResampleIntZ->value());
itk::ImageRegion<3> oldRegion = itkImage->GetLargestPossibleRegion();
itk::Vector< double, 3 > sampling;
sampling[0] = (double)newRegion.GetSize(0)/oldRegion.GetSize(0);
sampling[1] = (double)newRegion.GetSize(1)/oldRegion.GetSize(1);
sampling[2] = (double)newRegion.GetSize(2)/oldRegion.GetSize(2);
newSpacing = itkImage->GetSpacing();
newSpacing[0] /= sampling[0];
newSpacing[1] /= sampling[1];
newSpacing[2] /= sampling[2];
break;
}
default:
{
MITK_WARN << "Unknown resampling parameters!";
return;
}
}
itk::Point<double,3> origin = itkImage->GetOrigin();
origin[0] -= itkImage->GetSpacing()[0]/2;
origin[1] -= itkImage->GetSpacing()[1]/2;
origin[2] -= itkImage->GetSpacing()[2]/2;
origin[0] += newSpacing[0]/2;
origin[1] += newSpacing[1]/2;
origin[2] += newSpacing[2]/2;
typedef itk::Image<TPixel, VImageDimension> ImageType;
typename ImageType::Pointer outImage = ImageType::New();
outImage->SetSpacing( newSpacing );
outImage->SetOrigin( origin );
outImage->SetDirection( itkImage->GetDirection() );
outImage->SetLargestPossibleRegion( newRegion );
outImage->SetBufferedRegion( newRegion );
outImage->SetRequestedRegion( newRegion );
outImage->Allocate();
typedef itk::ResampleImageFilter<ImageType, ImageType> ResampleFilter;
typename ResampleFilter::Pointer resampler = ResampleFilter::New();
resampler->SetInput(itkImage);
resampler->SetOutputParametersFromImage(outImage);
QString outAdd;
switch (m_Controls->m_InterpolatorBox->currentIndex())
{
case 0:
{
typename itk::NearestNeighborInterpolateImageFunction<ImageType>::Pointer interp = itk::NearestNeighborInterpolateImageFunction<ImageType>::New();
resampler->SetInterpolator(interp);
outAdd = "NearestNeighbour";
break;
}
case 1:
{
typename itk::LinearInterpolateImageFunction<ImageType>::Pointer interp = itk::LinearInterpolateImageFunction<ImageType>::New();
resampler->SetInterpolator(interp);
outAdd = "Linear";
break;
}
case 2:
{
typename itk::BSplineInterpolateImageFunction<ImageType>::Pointer interp = itk::BSplineInterpolateImageFunction<ImageType>::New();
resampler->SetInterpolator(interp);
outAdd = "BSpline";
break;
}
case 3:
{
typename itk::WindowedSincInterpolateImageFunction<ImageType, 3>::Pointer interp = itk::WindowedSincInterpolateImageFunction<ImageType, 3>::New();
resampler->SetInterpolator(interp);
outAdd = "WindowedSinc";
break;
}
default:
{
typename itk::NearestNeighborInterpolateImageFunction<ImageType>::Pointer interp = itk::NearestNeighborInterpolateImageFunction<ImageType>::New();
resampler->SetInterpolator(interp);
outAdd = "NearestNeighbour";
}
}
resampler->Update();
mitk::Image::Pointer image = mitk::Image::New();
image->InitializeByItk( resampler->GetOutput() );
image->SetVolume( resampler->GetOutput()->GetBufferPointer() );
mitk::DataNode::Pointer imageNode = mitk::DataNode::New();
imageNode->SetData( image );
QString name = m_SelectedImageNode->GetName().c_str();
imageNode->SetName((name+"_resampled_"+outAdd).toStdString().c_str());
GetDefaultDataStorage()->Add(imageNode, m_SelectedImageNode);
}
void QmitkPreprocessingView::DoApplyDirectionMatrix()
{
if (m_DiffusionImage.IsNotNull())
{
MitkDwiType::Pointer newDwi = m_DiffusionImage->Clone();
ItkDwiType::DirectionType newDirection;
for (int r=0; r<3; r++)
for (int c=0; c<3; c++)
{
QTableWidgetItem* item = m_Controls->m_DirectionMatrixTable->item(r,c);
if (!item)
return;
newDirection[r][c] = item->text().toDouble();
}
ItkDwiType::Pointer itkDwi = newDwi->GetVectorImage();
typedef mitk::DiffusionImage<DiffusionPixelType> MitkDwiType;
vnl_matrix_fixed< double,3,3 > oldInverseDirection = itkDwi->GetDirection().GetInverse();
MitkDwiType::GradientDirectionContainerType::Pointer oldGradients = m_DiffusionImage->GetDirectionsWithoutMeasurementFrame();
MitkDwiType::GradientDirectionContainerType::Pointer newGradients = MitkDwiType::GradientDirectionContainerType::New();
for (unsigned int i=0; i<oldGradients->Size(); i++)
{
MitkDwiType::GradientDirectionType g = oldGradients->GetElement(i);
double mag = g.magnitude();
MitkDwiType::GradientDirectionType newG = oldInverseDirection*g;
newG = newDirection.GetVnlMatrix()*newG;
newG.normalize();
newGradients->InsertElement(i, newG*mag);
}
newDwi->SetDirections(newGradients);
itkDwi->SetDirection(newDirection);
newDwi->InitializeFromVectorImage();
mitk::DataNode::Pointer imageNode = mitk::DataNode::New();
imageNode->SetData( newDwi );
QString name = m_SelectedDiffusionNodes.back()->GetName().c_str();
imageNode->SetName((name+"_newdirection").toStdString().c_str());
GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back());
mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true );
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
else if (m_SelectedImage.IsNotNull())
{
AccessFixedDimensionByItk(m_SelectedImage, TemplatedApplyRotation,3);
}
}
template < typename TPixel, unsigned int VImageDimension >
void QmitkPreprocessingView::TemplatedApplyRotation( itk::Image<TPixel, VImageDimension>* itkImage)
{
ItkDwiType::DirectionType newDirection;
for (int r=0; r<3; r++)
for (int c=0; c<3; c++)
{
QTableWidgetItem* item = m_Controls->m_DirectionMatrixTable->item(r,c);
if (!item)
return;
newDirection[r][c] = item->text().toDouble();
}
typedef itk::Image<TPixel, VImageDimension> ImageType;
typename ImageType::Pointer newImage = ImageType::New();
newImage->SetSpacing( itkImage->GetSpacing() );
newImage->SetOrigin( itkImage->GetOrigin() );
newImage->SetDirection( newDirection );
newImage->SetLargestPossibleRegion( itkImage->GetLargestPossibleRegion() );
newImage->SetBufferedRegion( itkImage->GetLargestPossibleRegion() );
newImage->SetRequestedRegion( itkImage->GetLargestPossibleRegion() );
newImage->Allocate();
newImage->FillBuffer(0);
itk::ImageRegionIterator< itk::Image<TPixel, VImageDimension> > it(itkImage, itkImage->GetLargestPossibleRegion());
while(!it.IsAtEnd())
{
newImage->SetPixel(it.GetIndex(), it.Get());
++it;
}
mitk::Image::Pointer newMitkImage = mitk::Image::New();
newMitkImage->InitializeByItk(newImage.GetPointer());
newMitkImage->SetVolume(newImage->GetBufferPointer());
mitk::DataNode::Pointer imageNode = mitk::DataNode::New();
imageNode->SetData( newMitkImage );
QString name = m_SelectedImageNode->GetName().c_str();
imageNode->SetName((name+"_newdirection").toStdString().c_str());
GetDefaultDataStorage()->Add(imageNode, m_SelectedImageNode);
mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true );
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkPreprocessingView::DoProjectSignal()
{
switch(m_Controls->m_ProjectionMethodBox->currentIndex())
{
case 0:
DoADCAverage();
break;
case 1:
DoAKCFit();
break;
case 2:
DoBiExpFit();
break;
default:
DoADCAverage();
}
}
void QmitkPreprocessingView::DoDwiNormalization()
{
if (m_DiffusionImage.IsNull())
return;
int b0Index = -1;
for (unsigned int i=0; i<m_DiffusionImage->GetNumberOfChannels(); i++)
{
GradientDirectionType g = m_DiffusionImage->GetDirections()->GetElement(i);
if (g.magnitude()<0.001)
{
b0Index = i;
break;
}
}
if (b0Index==-1)
return;
typedef mitk::DiffusionImage<DiffusionPixelType> DiffusionImageType;
typedef itk::DwiNormilzationFilter<short> FilterType;
FilterType::Pointer filter = FilterType::New();
filter->SetInput(m_DiffusionImage->GetVectorImage());
filter->SetGradientDirections(m_DiffusionImage->GetDirections());
UcharImageType::Pointer itkImage = NULL;
if (m_Controls->m_NormalizationMaskBox->GetSelectedNode().IsNotNull())
{
itkImage = UcharImageType::New();
mitk::CastToItkImage(dynamic_cast<mitk::Image*>(m_Controls->m_NormalizationMaskBox->GetSelectedNode()->GetData()), itkImage);
filter->SetMaskImage(itkImage);
}
// determin normalization reference
switch(m_Controls->m_NormalizationReferenceBox->currentIndex())
{
case 0: // normalize relative to mean white matter signal intensity
{
typedef itk::DiffusionTensor3DReconstructionImageFilter< short, short, double > TensorReconstructionImageFilterType;
TensorReconstructionImageFilterType::Pointer dtFilter = TensorReconstructionImageFilterType::New();
dtFilter->SetGradientImage( m_DiffusionImage->GetDirections(), m_DiffusionImage->GetVectorImage() );
dtFilter->SetBValue(m_DiffusionImage->GetReferenceBValue());
dtFilter->Update();
itk::Image< itk::DiffusionTensor3D< double >, 3 >::Pointer tensorImage = dtFilter->GetOutput();
itk::ImageRegionIterator< itk::Image< itk::DiffusionTensor3D< double >, 3 > > inIt(tensorImage, tensorImage->GetLargestPossibleRegion());
double ref = 0;
unsigned int count = 0;
while ( !inIt.IsAtEnd() )
{
if (itkImage.IsNotNull() && itkImage->GetPixel(inIt.GetIndex())<=0)
{
++inIt;
continue;
}
double FA = inIt.Get().GetFractionalAnisotropy();
if (FA>0.4 && FA<0.99)
{
ref += m_DiffusionImage->GetVectorImage()->GetPixel(inIt.GetIndex())[b0Index];
count++;
}
++inIt;
}
if (count>0)
{
ref /= count;
filter->SetUseGlobalReference(true);
filter->SetReference(ref);
}
break;
}
case 1: // normalize relative to mean CSF signal intensity
{
itk::AdcImageFilter< short, double >::Pointer adcFilter = itk::AdcImageFilter< short, double >::New();
adcFilter->SetInput(m_DiffusionImage->GetVectorImage());
adcFilter->SetGradientDirections(m_DiffusionImage->GetDirections());
adcFilter->SetB_value(m_DiffusionImage->GetReferenceBValue());
adcFilter->Update();
ItkDoubleImageType::Pointer adcImage = adcFilter->GetOutput();
itk::ImageRegionIterator<ItkDoubleImageType> inIt(adcImage, adcImage->GetLargestPossibleRegion());
double max = 0.0030;
double ref = 0;
unsigned int count = 0;
while ( !inIt.IsAtEnd() )
{
if (itkImage.IsNotNull() && itkImage->GetPixel(inIt.GetIndex())<=0)
{
++inIt;
continue;
}
if (inIt.Get()>max && inIt.Get()<0.004)
{
ref += m_DiffusionImage->GetVectorImage()->GetPixel(inIt.GetIndex())[b0Index];
count++;
}
++inIt;
}
if (count>0)
{
ref /= count;
filter->SetUseGlobalReference(true);
filter->SetReference(ref);
}
break;
}
case 2:
{
filter->SetUseGlobalReference(false);
}
}
filter->Update();
DiffusionImageType::Pointer image = DiffusionImageType::New();
image->SetVectorImage( filter->GetOutput() );
image->SetReferenceBValue( m_DiffusionImage->GetReferenceBValue() );
image->SetDirections( m_DiffusionImage->GetDirections() );
image->InitializeFromVectorImage();
mitk::DataNode::Pointer imageNode = mitk::DataNode::New();
imageNode->SetData( image );
QString name = m_SelectedDiffusionNodes.back()->GetName().c_str();
imageNode->SetName((name+"_normalized").toStdString().c_str());
GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back());
}
void QmitkPreprocessingView::DoLengthCorrection()
{
if (m_DiffusionImage.IsNull())
return;
typedef mitk::DiffusionImage<DiffusionPixelType> DiffusionImageType;
typedef itk::DwiGradientLengthCorrectionFilter FilterType;
FilterType::Pointer filter = FilterType::New();
filter->SetRoundingValue( m_Controls->m_B_ValueMap_Rounder_SpinBox->value());
filter->SetReferenceBValue(m_DiffusionImage->GetReferenceBValue());
filter->SetReferenceGradientDirectionContainer(m_DiffusionImage->GetDirections());
filter->Update();
DiffusionImageType::Pointer image = DiffusionImageType::New();
image->SetVectorImage( m_DiffusionImage->GetVectorImage());
image->SetReferenceBValue( filter->GetNewBValue() );
image->SetDirections( filter->GetOutputGradientDirectionContainer());
image->InitializeFromVectorImage();
mitk::DataNode::Pointer imageNode = mitk::DataNode::New();
imageNode->SetData( image );
QString name = m_SelectedDiffusionNodes.back()->GetName().c_str();
imageNode->SetName((name+"_rounded").toStdString().c_str());
GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back());
}
void QmitkPreprocessingView::UpdateDwiBValueMapRounder(int i)
{
if (m_DiffusionImage.IsNull())
return;
//m_DiffusionImage->UpdateBValueMap();
UpdateBValueTableWidget(i);
}
void QmitkPreprocessingView::CallMultishellToSingleShellFilter(itk::DWIVoxelFunctor * functor, mitk::DiffusionImage<DiffusionPixelType>::Pointer ImPtr, QString imageName, mitk::DataNode* parent)
{
typedef itk::RadialMultishellToSingleshellImageFilter<DiffusionPixelType, DiffusionPixelType> FilterType;
// filter input parameter
const mitk::DiffusionImage<DiffusionPixelType>::BValueMap
&originalShellMap = ImPtr->GetBValueMap();
const mitk::DiffusionImage<DiffusionPixelType>::ImageType
*vectorImage = ImPtr->GetVectorImage();
const mitk::DiffusionImage<DiffusionPixelType>::GradientDirectionContainerType::Pointer
gradientContainer = ImPtr->GetDirections();
const unsigned int
&bValue = ImPtr->GetReferenceBValue();
mitk::DataNode::Pointer imageNode = 0;
// filter call
FilterType::Pointer filter = FilterType::New();
filter->SetInput(vectorImage);
filter->SetOriginalGradientDirections(gradientContainer);
filter->SetOriginalBValueMap(originalShellMap);
filter->SetOriginalBValue(bValue);
filter->SetFunctor(functor);
filter->Update();
// create new DWI image
mitk::DiffusionImage<DiffusionPixelType>::Pointer outImage = mitk::DiffusionImage<DiffusionPixelType>::New();
outImage->SetVectorImage( filter->GetOutput() );
outImage->SetReferenceBValue( m_Controls->m_targetBValueSpinBox->value() );
outImage->SetDirections( filter->GetTargetGradientDirections() );
outImage->InitializeFromVectorImage();
imageNode = mitk::DataNode::New();
imageNode->SetData( outImage );
imageNode->SetName(imageName.toStdString().c_str());
GetDefaultDataStorage()->Add(imageNode, parent);
// if(m_Controls->m_OutputRMSErrorImage->isChecked()){
// // create new Error image
// FilterType::ErrorImageType::Pointer errImage = filter->GetErrorImage();
// mitk::Image::Pointer mitkErrImage = mitk::Image::New();
// mitkErrImage->InitializeByItk<FilterType::ErrorImageType>(errImage);
// mitkErrImage->SetVolume(errImage->GetBufferPointer());
// imageNode = mitk::DataNode::New();
// imageNode->SetData( mitkErrImage );
// imageNode->SetName((imageName+"_Error").toStdString().c_str());
// GetDefaultDataStorage()->Add(imageNode);
// }
}
void QmitkPreprocessingView::DoBiExpFit()
{
itk::BiExpFitFunctor::Pointer functor = itk::BiExpFitFunctor::New();
for (unsigned int i=0; i<m_SelectedDiffusionNodes.size(); i++)
{
mitk::DiffusionImage<DiffusionPixelType>::Pointer inImage =
dynamic_cast< mitk::DiffusionImage<DiffusionPixelType>* >(m_SelectedDiffusionNodes.at(i)->GetData());
QString name(m_SelectedDiffusionNodes.at(i)->GetName().c_str());
const mitk::DiffusionImage<DiffusionPixelType>::BValueMap & originalShellMap = inImage->GetBValueMap();
mitk::DiffusionImage<DiffusionPixelType>::BValueMap::const_iterator it = originalShellMap.begin();
++it;/* skip b=0*/ unsigned int s = 0; /*shell index */
vnl_vector<double> bValueList(originalShellMap.size()-1);
while(it != originalShellMap.end())
bValueList.put(s++,(it++)->first);
const double targetBValue = m_Controls->m_targetBValueSpinBox->value();
functor->setListOfBValues(bValueList);
functor->setTargetBValue(targetBValue);
CallMultishellToSingleShellFilter(functor,inImage,name + "_BiExp", m_SelectedDiffusionNodes.at(i));
}
}
void QmitkPreprocessingView::DoAKCFit()
{
itk::KurtosisFitFunctor::Pointer functor = itk::KurtosisFitFunctor::New();
for (unsigned int i=0; i<m_SelectedDiffusionNodes.size(); i++)
{
mitk::DiffusionImage<DiffusionPixelType>::Pointer inImage =
dynamic_cast< mitk::DiffusionImage<DiffusionPixelType>* >(m_SelectedDiffusionNodes.at(i)->GetData());
QString name(m_SelectedDiffusionNodes.at(i)->GetName().c_str());
const mitk::DiffusionImage<DiffusionPixelType>::BValueMap & originalShellMap = inImage->GetBValueMap();
mitk::DiffusionImage<DiffusionPixelType>::BValueMap::const_iterator it = originalShellMap.begin();
++it;/* skip b=0*/ unsigned int s = 0; /*shell index */
vnl_vector<double> bValueList(originalShellMap.size()-1);
while(it != originalShellMap.end())
bValueList.put(s++,(it++)->first);
const double targetBValue = m_Controls->m_targetBValueSpinBox->value();
functor->setListOfBValues(bValueList);
functor->setTargetBValue(targetBValue);
CallMultishellToSingleShellFilter(functor,inImage,name + "_AKC", m_SelectedDiffusionNodes.at(i));
}
}
void QmitkPreprocessingView::DoADCFit()
{
// later
}
void QmitkPreprocessingView::DoADCAverage()
{
itk::ADCAverageFunctor::Pointer functor = itk::ADCAverageFunctor::New();
for (unsigned int i=0; i<m_SelectedDiffusionNodes.size(); i++)
{
mitk::DiffusionImage<DiffusionPixelType>::Pointer inImage =
dynamic_cast< mitk::DiffusionImage<DiffusionPixelType>* >(m_SelectedDiffusionNodes.at(i)->GetData());
QString name(m_SelectedDiffusionNodes.at(i)->GetName().c_str());
const mitk::DiffusionImage<DiffusionPixelType>::BValueMap & originalShellMap = inImage->GetBValueMap();
mitk::DiffusionImage<DiffusionPixelType>::BValueMap::const_iterator it = originalShellMap.begin();
++it;/* skip b=0*/ unsigned int s = 0; /*shell index */
vnl_vector<double> bValueList(originalShellMap.size()-1);
while(it != originalShellMap.end())
bValueList.put(s++,(it++)->first);
const double targetBValue = m_Controls->m_targetBValueSpinBox->value();
functor->setListOfBValues(bValueList);
functor->setTargetBValue(targetBValue);
CallMultishellToSingleShellFilter(functor,inImage,name + "_ADC", m_SelectedDiffusionNodes.at(i));
}
}
void QmitkPreprocessingView::DoAdcCalculation()
{
if (m_DiffusionImage.IsNull())
return;
typedef mitk::DiffusionImage< DiffusionPixelType > DiffusionImageType;
typedef itk::AdcImageFilter< DiffusionPixelType, double > FilterType;
for (unsigned int i=0; i<m_SelectedDiffusionNodes.size(); i++)
{
DiffusionImageType::Pointer inImage = dynamic_cast< DiffusionImageType* >(m_SelectedDiffusionNodes.at(i)->GetData());
FilterType::Pointer filter = FilterType::New();
filter->SetInput(inImage->GetVectorImage());
filter->SetGradientDirections(inImage->GetDirections());
filter->SetB_value(inImage->GetReferenceBValue());
filter->Update();
mitk::Image::Pointer image = mitk::Image::New();
image->InitializeByItk( filter->GetOutput() );
image->SetVolume( filter->GetOutput()->GetBufferPointer() );
mitk::DataNode::Pointer imageNode = mitk::DataNode::New();
imageNode->SetData( image );
QString name = m_SelectedDiffusionNodes.at(i)->GetName().c_str();
imageNode->SetName((name+"_ADC").toStdString().c_str());
GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.at(i));
}
}
void QmitkPreprocessingView::UpdateBValueTableWidget(int i)
{
if (m_DiffusionImage.IsNull())
{
m_Controls->m_B_ValueMap_TableWidget->clear();
m_Controls->m_B_ValueMap_TableWidget->setRowCount(1);
QStringList headerList;
headerList << "b-Value" << "Number of gradients";
m_Controls->m_B_ValueMap_TableWidget->setHorizontalHeaderLabels(headerList);
m_Controls->m_B_ValueMap_TableWidget->setItem(0,0,new QTableWidgetItem("-"));
m_Controls->m_B_ValueMap_TableWidget->setItem(0,1,new QTableWidgetItem("-"));
}else{
typedef mitk::DiffusionImage<short>::BValueMap BValueMap;
typedef mitk::DiffusionImage<short>::BValueMap::iterator BValueMapIterator;
BValueMapIterator it;
BValueMap roundedBValueMap = m_DiffusionImage->GetBValueMap();
m_Controls->m_B_ValueMap_TableWidget->clear();
m_Controls->m_B_ValueMap_TableWidget->setRowCount(roundedBValueMap.size() );
QStringList headerList;
headerList << "b-Value" << "Number of gradients";
m_Controls->m_B_ValueMap_TableWidget->setHorizontalHeaderLabels(headerList);
int i = 0 ;
for(it = roundedBValueMap.begin() ;it != roundedBValueMap.end(); it++)
{
m_Controls->m_B_ValueMap_TableWidget->setItem(i,0,new QTableWidgetItem(QString::number(it->first)));
QTableWidgetItem* item = m_Controls->m_B_ValueMap_TableWidget->item(i,0);
item->setFlags(item->flags() & ~Qt::ItemIsEditable);
m_Controls->m_B_ValueMap_TableWidget->setItem(i,1,new QTableWidgetItem(QString::number(it->second.size())));
i++;
}
}
}
template < typename TPixel, unsigned int VImageDimension >
void QmitkPreprocessingView::TemplatedUpdateGui( itk::Image<TPixel, VImageDimension>* itkImage)
{
for (int r=0; r<3; r++)
for (int c=0; c<3; c++)
{
QTableWidgetItem* item = m_Controls->m_DirectionMatrixTable->item(r,c);
delete item;
item = new QTableWidgetItem();
item->setTextAlignment(Qt::AlignCenter | Qt::AlignVCenter);
item->setText(QString::number(itkImage->GetDirection()[r][c]));
m_Controls->m_DirectionMatrixTable->setItem(r,c,item);
}
}
void QmitkPreprocessingView::OnSelectionChanged( std::vector<mitk::DataNode*> nodes )
{
bool foundDwiVolume = false;
bool foundImageVolume = false;
m_DiffusionImage = NULL;
m_SelectedImage = NULL;
m_SelectedImageNode = NULL;
m_SelectedDiffusionNodes.clear();
// iterate selection
for( std::vector<mitk::DataNode*>::iterator it = nodes.begin(); it != nodes.end(); ++it )
{
mitk::DataNode::Pointer node = *it;
if( node.IsNotNull() && dynamic_cast<mitk::DiffusionImage<short>*>(node->GetData()) )
{
foundDwiVolume = true;
foundImageVolume = true;
m_DiffusionImage = dynamic_cast<mitk::DiffusionImage<DiffusionPixelType>*>(node->GetData());
m_Controls->m_DiffusionImageLabel->setText(node->GetName().c_str());
m_SelectedDiffusionNodes.push_back(node);
}
else if( node.IsNotNull() && dynamic_cast<mitk::Image*>(node->GetData()) )
{
foundImageVolume = true;
m_SelectedImage = dynamic_cast<mitk::Image*>(node->GetData());
m_Controls->m_DiffusionImageLabel->setText(node->GetName().c_str());
m_SelectedImageNode = node;
}
}
m_Controls->m_ButtonAverageGradients->setEnabled(foundDwiVolume);
m_Controls->m_ButtonExtractB0->setEnabled(foundDwiVolume);
m_Controls->m_CheckExtractAll->setEnabled(foundDwiVolume);
m_Controls->m_ModifyMeasurementFrame->setEnabled(foundDwiVolume);
m_Controls->m_MeasurementFrameTable->setEnabled(foundDwiVolume);
m_Controls->m_ReduceGradientsButton->setEnabled(foundDwiVolume);
m_Controls->m_ShowGradientsButton->setEnabled(foundDwiVolume);
m_Controls->m_MirrorGradientToHalfSphereButton->setEnabled(foundDwiVolume);
m_Controls->m_MergeDwisButton->setEnabled(foundDwiVolume);
m_Controls->m_B_ValueMap_Rounder_SpinBox->setEnabled(foundDwiVolume);
m_Controls->m_ProjectSignalButton->setEnabled(foundDwiVolume);
m_Controls->m_CreateLengthCorrectedDwi->setEnabled(foundDwiVolume);
m_Controls->m_CalcAdcButton->setEnabled(foundDwiVolume);
m_Controls->m_targetBValueSpinBox->setEnabled(foundDwiVolume);
m_Controls->m_NormalizeImageValuesButton->setEnabled(foundDwiVolume);
m_Controls->m_DirectionMatrixTable->setEnabled(foundImageVolume);
m_Controls->m_ModifyDirection->setEnabled(foundImageVolume);
m_Controls->m_ExtractBrainMask->setEnabled(foundImageVolume);
m_Controls->m_ResampleImageButton->setEnabled(foundImageVolume);
m_Controls->m_ModifySpacingButton->setEnabled(foundImageVolume);
m_Controls->m_ModifyOriginButton->setEnabled(foundImageVolume);
m_Controls->m_CropImageButton->setEnabled(foundImageVolume);
m_Controls->m_RemoveGradientButton->setEnabled(foundDwiVolume);
m_Controls->m_ExtractGradientButton->setEnabled(foundDwiVolume);
// reset sampling frame to 1 and update all ealted components
m_Controls->m_B_ValueMap_Rounder_SpinBox->setValue(1);
UpdateBValueTableWidget(m_Controls->m_B_ValueMap_Rounder_SpinBox->value());
DoUpdateInterpolationGui(m_Controls->m_ResampleTypeBox->currentIndex());
if (foundDwiVolume)
{
m_Controls->m_InputData->setTitle("Input Data");
vnl_matrix_fixed< double, 3, 3 > mf = m_DiffusionImage->GetMeasurementFrame();
for (int r=0; r<3; r++)
for (int c=0; c<3; c++)
{
// Measurement frame
{
QTableWidgetItem* item = m_Controls->m_MeasurementFrameTable->item(r,c);
delete item;
item = new QTableWidgetItem();
item->setTextAlignment(Qt::AlignCenter | Qt::AlignVCenter);
item->setText(QString::number(mf.get(r,c)));
m_Controls->m_MeasurementFrameTable->setItem(r,c,item);
}
// Direction matrix
{
QTableWidgetItem* item = m_Controls->m_DirectionMatrixTable->item(r,c);
delete item;
item = new QTableWidgetItem();
item->setTextAlignment(Qt::AlignCenter | Qt::AlignVCenter);
item->setText(QString::number(m_DiffusionImage->GetVectorImage()->GetDirection()[r][c]));
m_Controls->m_DirectionMatrixTable->setItem(r,c,item);
}
}
//calculate target bValue for MultishellToSingleShellfilter
const mitk::DiffusionImage<DiffusionPixelType>::BValueMap & bValMap = m_DiffusionImage->GetBValueMap();
mitk::DiffusionImage<DiffusionPixelType>::BValueMap::const_iterator it = bValMap.begin();
unsigned int targetBVal = 0;
while(it != bValMap.end())
targetBVal += (it++)->first;
targetBVal /= (float)bValMap.size()-1;
m_Controls->m_targetBValueSpinBox->setValue(targetBVal);
m_Controls->m_HeaderSpacingX->setValue(m_DiffusionImage->GetGeometry()->GetSpacing()[0]);
m_Controls->m_HeaderSpacingY->setValue(m_DiffusionImage->GetGeometry()->GetSpacing()[1]);
m_Controls->m_HeaderSpacingZ->setValue(m_DiffusionImage->GetGeometry()->GetSpacing()[2]);
m_Controls->m_HeaderOriginX->setValue(m_DiffusionImage->GetGeometry()->GetOrigin()[0]);
m_Controls->m_HeaderOriginY->setValue(m_DiffusionImage->GetGeometry()->GetOrigin()[1]);
m_Controls->m_HeaderOriginZ->setValue(m_DiffusionImage->GetGeometry()->GetOrigin()[2]);
m_Controls->m_XstartBox->setMaximum(m_DiffusionImage->GetGeometry()->GetExtent(0)-1);
m_Controls->m_YstartBox->setMaximum(m_DiffusionImage->GetGeometry()->GetExtent(1)-1);
m_Controls->m_ZstartBox->setMaximum(m_DiffusionImage->GetGeometry()->GetExtent(2)-1);
m_Controls->m_XendBox->setMaximum(m_DiffusionImage->GetGeometry()->GetExtent(0)-1);
m_Controls->m_YendBox->setMaximum(m_DiffusionImage->GetGeometry()->GetExtent(1)-1);
m_Controls->m_ZendBox->setMaximum(m_DiffusionImage->GetGeometry()->GetExtent(2)-1);
m_Controls->m_RemoveGradientBox->setMaximum(m_DiffusionImage->GetDirections()->Size()-1);
m_Controls->m_ExtractGradientBox->setMaximum(m_DiffusionImage->GetDirections()->Size()-1);
}
else if (foundImageVolume)
{
for (int r=0; r<3; r++)
for (int c=0; c<3; c++)
{
QTableWidgetItem* item = m_Controls->m_MeasurementFrameTable->item(r,c);
delete item;
item = new QTableWidgetItem();
m_Controls->m_MeasurementFrameTable->setItem(r,c,item);
}
m_Controls->m_HeaderSpacingX->setValue(m_SelectedImage->GetGeometry()->GetSpacing()[0]);
m_Controls->m_HeaderSpacingY->setValue(m_SelectedImage->GetGeometry()->GetSpacing()[1]);
m_Controls->m_HeaderSpacingZ->setValue(m_SelectedImage->GetGeometry()->GetSpacing()[2]);
m_Controls->m_HeaderOriginX->setValue(m_SelectedImage->GetGeometry()->GetOrigin()[0]);
m_Controls->m_HeaderOriginY->setValue(m_SelectedImage->GetGeometry()->GetOrigin()[1]);
m_Controls->m_HeaderOriginZ->setValue(m_SelectedImage->GetGeometry()->GetOrigin()[2]);
m_Controls->m_XstartBox->setMaximum(m_SelectedImage->GetGeometry()->GetExtent(0)-1);
m_Controls->m_YstartBox->setMaximum(m_SelectedImage->GetGeometry()->GetExtent(1)-1);
m_Controls->m_ZstartBox->setMaximum(m_SelectedImage->GetGeometry()->GetExtent(2)-1);
m_Controls->m_XendBox->setMaximum(m_SelectedImage->GetGeometry()->GetExtent(0)-1);
m_Controls->m_YendBox->setMaximum(m_SelectedImage->GetGeometry()->GetExtent(1)-1);
m_Controls->m_ZendBox->setMaximum(m_SelectedImage->GetGeometry()->GetExtent(2)-1);
AccessFixedDimensionByItk(m_SelectedImage, TemplatedUpdateGui,3);
}
else
{
for (int r=0; r<3; r++)
for (int c=0; c<3; c++)
{
{
QTableWidgetItem* item = m_Controls->m_MeasurementFrameTable->item(r,c);
delete item;
item = new QTableWidgetItem();
m_Controls->m_MeasurementFrameTable->setItem(r,c,item);
}
{
QTableWidgetItem* item = m_Controls->m_DirectionMatrixTable->item(r,c);
delete item;
item = new QTableWidgetItem();
m_Controls->m_DirectionMatrixTable->setItem(r,c,item);
}
}
m_Controls->m_DiffusionImageLabel->setText("<font color='red'>mandatory</font>");
m_Controls->m_InputData->setTitle("Please Select Input Data");
}
}
void QmitkPreprocessingView::Activated()
{
QmitkFunctionality::Activated();
}
void QmitkPreprocessingView::Deactivated()
{
QmitkFunctionality::Deactivated();
}
void QmitkPreprocessingView::DoHalfSphereGradientDirections()
{
MitkDwiType::Pointer newDwi = m_DiffusionImage->Clone();
GradientDirectionContainerType::Pointer gradientContainer = newDwi->GetDirections();
for (unsigned int j=0; j<gradientContainer->Size(); j++)
if (gradientContainer->at(j)[0]<0)
gradientContainer->at(j) = -gradientContainer->at(j);
newDwi->SetDirections(gradientContainer);
mitk::DataNode::Pointer imageNode = mitk::DataNode::New();
imageNode->SetData( newDwi );
QString name = m_SelectedDiffusionNodes.back()->GetName().c_str();
imageNode->SetName((name+"_halfsphere").toStdString().c_str());
GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back());
}
void QmitkPreprocessingView::DoApplyMesurementFrame()
{
if (m_DiffusionImage.IsNull())
return;
vnl_matrix_fixed< double, 3, 3 > mf;
for (int r=0; r<3; r++)
for (int c=0; c<3; c++)
{
QTableWidgetItem* item = m_Controls->m_MeasurementFrameTable->item(r,c);
if (!item)
return;
mf[r][c] = item->text().toDouble();
}
MitkDwiType::Pointer newDwi = m_DiffusionImage->Clone();
newDwi->SetMeasurementFrame(mf);
mitk::DataNode::Pointer imageNode = mitk::DataNode::New();
imageNode->SetData( newDwi );
QString name = m_SelectedDiffusionNodes.back()->GetName().c_str();
imageNode->SetName((name+"_new-MF").toStdString().c_str());
GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back());
}
void QmitkPreprocessingView::DoShowGradientDirections()
{
if (m_DiffusionImage.IsNull())
return;
int maxIndex = 0;
unsigned int maxSize = m_DiffusionImage->GetDimension(0);
if (maxSize<m_DiffusionImage->GetDimension(1))
{
maxSize = m_DiffusionImage->GetDimension(1);
maxIndex = 1;
}
if (maxSize<m_DiffusionImage->GetDimension(2))
{
maxSize = m_DiffusionImage->GetDimension(2);
maxIndex = 2;
}
mitk::Point3D origin = m_DiffusionImage->GetGeometry()->GetOrigin();
mitk::PointSet::Pointer originSet = mitk::PointSet::New();
typedef mitk::DiffusionImage<short>::BValueMap BValueMap;
typedef mitk::DiffusionImage<short>::BValueMap::iterator BValueMapIterator;
BValueMap bValMap = m_DiffusionImage->GetBValueMap();
GradientDirectionContainerType::Pointer gradientContainer = m_DiffusionImage->GetDirections();
mitk::BaseGeometry::Pointer geometry = m_DiffusionImage->GetGeometry();
int shellCount = 1;
for(BValueMapIterator it = bValMap.begin(); it!=bValMap.end(); ++it)
{
mitk::PointSet::Pointer pointset = mitk::PointSet::New();
for (unsigned int j=0; j<it->second.size(); j++)
{
mitk::Point3D ip;
vnl_vector_fixed< double, 3 > v = gradientContainer->at(it->second[j]);
if (v.magnitude()>mitk::eps)
{
ip[0] = v[0]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[0]-0.5*geometry->GetSpacing()[0] + geometry->GetSpacing()[0]*m_DiffusionImage->GetDimension(0)/2;
ip[1] = v[1]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[1]-0.5*geometry->GetSpacing()[1] + geometry->GetSpacing()[1]*m_DiffusionImage->GetDimension(1)/2;
ip[2] = v[2]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[2]-0.5*geometry->GetSpacing()[2] + geometry->GetSpacing()[2]*m_DiffusionImage->GetDimension(2)/2;
pointset->InsertPoint(j, ip);
}
else if (originSet->IsEmpty())
{
ip[0] = v[0]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[0]-0.5*geometry->GetSpacing()[0] + geometry->GetSpacing()[0]*m_DiffusionImage->GetDimension(0)/2;
ip[1] = v[1]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[1]-0.5*geometry->GetSpacing()[1] + geometry->GetSpacing()[1]*m_DiffusionImage->GetDimension(1)/2;
ip[2] = v[2]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[2]-0.5*geometry->GetSpacing()[2] + geometry->GetSpacing()[2]*m_DiffusionImage->GetDimension(2)/2;
originSet->InsertPoint(j, ip);
}
}
if (it->first<mitk::eps)
continue;
// add shell to datastorage
mitk::DataNode::Pointer node = mitk::DataNode::New();
node->SetData(pointset);
QString name = m_SelectedDiffusionNodes.front()->GetName().c_str();
name += "_Shell_";
name += QString::number(it->first);
node->SetName(name.toStdString().c_str());
node->SetProperty("pointsize", mitk::FloatProperty::New((float)maxSize/50));
int b0 = shellCount%2;
int b1 = 0;
int b2 = 0;
if (shellCount>4)
b2 = 1;
if (shellCount%4 >= 2)
b1 = 1;
node->SetProperty("color", mitk::ColorProperty::New(b2, b1, b0));
GetDefaultDataStorage()->Add(node, m_SelectedDiffusionNodes.front());
shellCount++;
}
// add origin to datastorage
mitk::DataNode::Pointer node = mitk::DataNode::New();
node->SetData(originSet);
QString name = m_SelectedDiffusionNodes.front()->GetName().c_str();
name += "_Origin";
node->SetName(name.toStdString().c_str());
node->SetProperty("pointsize", mitk::FloatProperty::New((float)maxSize/50));
node->SetProperty("color", mitk::ColorProperty::New(1,1,1));
GetDefaultDataStorage()->Add(node, m_SelectedDiffusionNodes.front());
}
void QmitkPreprocessingView::DoReduceGradientDirections()
{
if (m_DiffusionImage.IsNull())
return;
typedef mitk::DiffusionImage<DiffusionPixelType> DiffusionImageType;
typedef itk::ElectrostaticRepulsionDiffusionGradientReductionFilter<DiffusionPixelType, DiffusionPixelType> FilterType;
typedef DiffusionImageType::BValueMap BValueMap;
// GetShellSelection from GUI
BValueMap shellSlectionMap;
BValueMap originalShellMap = m_DiffusionImage->GetBValueMap();
std::vector<unsigned int> newNumGradientDirections;
int shellCounter = 0;
QString name = m_SelectedDiffusionNodes.front()->GetName().c_str();
for (int i=0; i<m_Controls->m_B_ValueMap_TableWidget->rowCount(); i++)
{
double BValue = m_Controls->m_B_ValueMap_TableWidget->item(i,0)->text().toDouble();
shellSlectionMap[BValue] = originalShellMap[BValue];
unsigned int num = m_Controls->m_B_ValueMap_TableWidget->item(i,1)->text().toUInt();
newNumGradientDirections.push_back(num);
name += "_";
name += QString::number(num);
shellCounter++;
}
if (newNumGradientDirections.empty())
return;
GradientDirectionContainerType::Pointer gradientContainer = m_DiffusionImage->GetDirections();
FilterType::Pointer filter = FilterType::New();
filter->SetInput(m_DiffusionImage->GetVectorImage());
filter->SetOriginalGradientDirections(gradientContainer);
filter->SetNumGradientDirections(newNumGradientDirections);
filter->SetOriginalBValueMap(originalShellMap);
filter->SetShellSelectionBValueMap(shellSlectionMap);
filter->Update();
DiffusionImageType::Pointer image = DiffusionImageType::New();
image->SetVectorImage( filter->GetOutput() );
image->SetReferenceBValue(m_DiffusionImage->GetReferenceBValue());
image->SetDirections(filter->GetGradientDirections());
image->SetMeasurementFrame(m_DiffusionImage->GetMeasurementFrame());
image->InitializeFromVectorImage();
mitk::DataNode::Pointer imageNode = mitk::DataNode::New();
imageNode->SetData( image );
imageNode->SetName(name.toStdString().c_str());
GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back());
}
void QmitkPreprocessingView::MergeDwis()
{
typedef mitk::DiffusionImage<DiffusionPixelType> DiffusionImageType;
typedef DiffusionImageType::GradientDirectionContainerType GradientContainerType;
if (m_SelectedDiffusionNodes.size()<2)
return;
typedef itk::VectorImage<DiffusionPixelType,3> DwiImageType;
typedef DwiImageType::PixelType DwiPixelType;
typedef DwiImageType::RegionType DwiRegionType;
typedef std::vector< DwiImageType::Pointer > DwiImageContainerType;
typedef std::vector< GradientContainerType::Pointer > GradientListContainerType;
DwiImageContainerType imageContainer;
GradientListContainerType gradientListContainer;
std::vector< double > bValueContainer;
QString name = m_SelectedDiffusionNodes.front()->GetName().c_str();
for (unsigned int i=0; i<m_SelectedDiffusionNodes.size(); i++)
{
DiffusionImageType::Pointer dwi = dynamic_cast< mitk::DiffusionImage<DiffusionPixelType>* >( m_SelectedDiffusionNodes.at(i)->GetData() );
if ( dwi.IsNotNull() )
{
imageContainer.push_back(dwi->GetVectorImage());
gradientListContainer.push_back(dwi->GetDirections());
bValueContainer.push_back(dwi->GetReferenceBValue());
if (i>0)
{
name += "+";
name += m_SelectedDiffusionNodes.at(i)->GetName().c_str();
}
}
}
typedef itk::MergeDiffusionImagesFilter<short> FilterType;
FilterType::Pointer filter = FilterType::New();
filter->SetImageVolumes(imageContainer);
filter->SetGradientLists(gradientListContainer);
filter->SetBValues(bValueContainer);
filter->Update();
vnl_matrix_fixed< double, 3, 3 > mf; mf.set_identity();
DiffusionImageType::Pointer image = DiffusionImageType::New();
image->SetVectorImage( filter->GetOutput() );
image->SetReferenceBValue(filter->GetB_Value());
image->SetDirections(filter->GetOutputGradients());
image->SetMeasurementFrame(mf);
image->InitializeFromVectorImage();
mitk::DataNode::Pointer imageNode = mitk::DataNode::New();
imageNode->SetData( image );
imageNode->SetName(name.toStdString().c_str());
GetDefaultDataStorage()->Add(imageNode);
}
void QmitkPreprocessingView::ExtractB0()
{
typedef mitk::DiffusionImage<DiffusionPixelType> DiffusionImageType;
typedef DiffusionImageType::GradientDirectionContainerType GradientContainerType;
int nrFiles = m_SelectedDiffusionNodes.size();
if (!nrFiles) return;
// call the extraction withou averaging if the check-box is checked
if( this->m_Controls->m_CheckExtractAll->isChecked() )
{
DoExtractBOWithoutAveraging();
return;
}
mitk::DataStorage::SetOfObjects::const_iterator itemiter( m_SelectedDiffusionNodes.begin() );
mitk::DataStorage::SetOfObjects::const_iterator itemiterend( m_SelectedDiffusionNodes.end() );
std::vector<mitk::DataNode::Pointer> nodes;
while ( itemiter != itemiterend ) // for all items
{
DiffusionImageType* vols =
static_cast<DiffusionImageType*>(
(*itemiter)->GetData());
std::string nodename;
(*itemiter)->GetStringProperty("name", nodename);
// Extract image using found index
typedef itk::B0ImageExtractionImageFilter<short, short> FilterType;
FilterType::Pointer filter = FilterType::New();
filter->SetInput(vols->GetVectorImage());
filter->SetDirections(vols->GetDirections());
filter->Update();
mitk::Image::Pointer mitkImage = mitk::Image::New();
mitkImage->InitializeByItk( filter->GetOutput() );
mitkImage->SetVolume( filter->GetOutput()->GetBufferPointer() );
mitk::DataNode::Pointer node=mitk::DataNode::New();
node->SetData( mitkImage );
node->SetProperty( "name", mitk::StringProperty::New(nodename + "_B0"));
GetDefaultDataStorage()->Add(node, (*itemiter));
++itemiter;
}
}
void QmitkPreprocessingView::DoExtractBOWithoutAveraging()
{
// typedefs
typedef mitk::DiffusionImage<DiffusionPixelType> DiffusionImageType;
typedef DiffusionImageType::GradientDirectionContainerType GradientContainerType;
typedef itk::B0ImageExtractionToSeparateImageFilter< short, short> FilterType;
// check number of selected objects, return if empty
int nrFiles = m_SelectedDiffusionNodes.size();
if (!nrFiles)
return;
mitk::DataStorage::SetOfObjects::const_iterator itemiter( m_SelectedDiffusionNodes.begin() );
mitk::DataStorage::SetOfObjects::const_iterator itemiterend( m_SelectedDiffusionNodes.end() );
while ( itemiter != itemiterend ) // for all items
{
DiffusionImageType* vols =
static_cast<DiffusionImageType*>(
(*itemiter)->GetData());
std::string nodename;
(*itemiter)->GetStringProperty("name", nodename);
// Extract image using found index
FilterType::Pointer filter = FilterType::New();
filter->SetInput(vols->GetVectorImage());
filter->SetDirections(vols->GetDirections());
filter->Update();
mitk::Image::Pointer mitkImage = mitk::Image::New();
mitkImage->InitializeByItk( filter->GetOutput() );
mitkImage->SetImportChannel( filter->GetOutput()->GetBufferPointer() );
mitk::DataNode::Pointer node=mitk::DataNode::New();
node->SetData( mitkImage );
node->SetProperty( "name", mitk::StringProperty::New(nodename + "_B0_ALL"));
GetDefaultDataStorage()->Add(node, (*itemiter));
/*A reinitialization is needed to access the time channels via the ImageNavigationController
The Global-Geometry can not recognize the time channel without a re-init.
(for a new selection in datamanger a automatically updated of the Global-Geometry should be done - if it contains the time channel)*/
mitk::RenderingManager::GetInstance()->InitializeViews(node->GetData()->GetTimeGeometry(),mitk::RenderingManager::REQUEST_UPDATE_ALL, true);
++itemiter;
}
}
void QmitkPreprocessingView::AverageGradients()
{
int nrFiles = m_SelectedDiffusionNodes.size();
if (!nrFiles) return;
mitk::DataStorage::SetOfObjects::const_iterator itemiter( m_SelectedDiffusionNodes.begin() );
mitk::DataStorage::SetOfObjects::const_iterator itemiterend( m_SelectedDiffusionNodes.end() );
while ( itemiter != itemiterend ) // for all items
{
mitk::DiffusionImage<DiffusionPixelType>* mitkDwi =
static_cast<mitk::DiffusionImage<DiffusionPixelType>*>(
(*itemiter)->GetData());
MitkDwiType::Pointer newDwi = mitkDwi->Clone();
newDwi->AverageRedundantGradients(m_Controls->m_Blur->value());
mitk::DataNode::Pointer imageNode = mitk::DataNode::New();
imageNode->SetData( newDwi );
QString name = (*itemiter)->GetName().c_str();
imageNode->SetName((name+"_averaged").toStdString().c_str());
GetDefaultDataStorage()->Add(imageNode, (*itemiter));
++itemiter;
}
}
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkQBallReconstructionView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkQBallReconstructionView.cpp
index e37c14e773..32e86ab070 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkQBallReconstructionView.cpp
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkQBallReconstructionView.cpp
@@ -1,1007 +1,1086 @@
/*===================================================================
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.
===================================================================*/
//#define MBILOG_ENABLE_DEBUG
#include "QmitkQBallReconstructionView.h"
#include "mitkDiffusionImagingConfigure.h"
// qt includes
#include <QMessageBox>
// itk includes
#include "itkTimeProbe.h"
// mitk includes
#include "mitkProgressBar.h"
#include "mitkStatusBar.h"
#include "mitkNodePredicateDataType.h"
#include "QmitkDataStorageComboBox.h"
#include "QmitkStdMultiWidget.h"
#include "itkDiffusionQballReconstructionImageFilter.h"
#include "itkAnalyticalDiffusionQballReconstructionImageFilter.h"
#include "itkDiffusionMultiShellQballReconstructionImageFilter.h"
#include "itkVectorContainer.h"
+#include "itkB0ImageExtractionImageFilter.h"
+#include <itkBinaryThresholdImageFilter.h>
#include "mitkQBallImage.h"
#include "mitkProperties.h"
#include "mitkVtkResliceInterpolationProperty.h"
#include "mitkLookupTable.h"
#include "mitkLookupTableProperty.h"
#include "mitkTransferFunction.h"
#include "mitkTransferFunctionProperty.h"
#include "mitkDataNodeObject.h"
#include "mitkOdfNormalizationMethodProperty.h"
#include "mitkOdfScaleByProperty.h"
#include "berryIStructuredSelection.h"
#include "berryIWorkbenchWindow.h"
#include "berryISelectionService.h"
#include <boost/version.hpp>
const std::string QmitkQBallReconstructionView::VIEW_ID = "org.mitk.views.qballreconstruction";
typedef float TTensorPixelType;
const int QmitkQBallReconstructionView::nrconvkernels = 252;
struct QbrShellSelection
{
QmitkQBallReconstructionView* m_View;
mitk::DataNode * m_Node;
std::string m_NodeName;
std::vector<QCheckBox *> m_CheckBoxes;
QLabel * m_Label;
mitk::DiffusionImage<DiffusionPixelType> * m_Image;
typedef mitk::DiffusionImage<DiffusionPixelType>::BValueMap BValueMap;
QbrShellSelection(QmitkQBallReconstructionView* view, mitk::DataNode * node)
: m_View(view),
m_Node(node),
m_NodeName(node->GetName())
{
m_Image = dynamic_cast<mitk::DiffusionImage<DiffusionPixelType> * > (node->GetData());
if(!m_Image){MITK_INFO << "QmitkQBallReconstructionView::QbrShellSelection : fail to initialize DiffusionImage "; return;}
GenerateCheckboxes();
}
void GenerateCheckboxes()
{
BValueMap origMap = m_Image->GetBValueMap();
BValueMap::iterator itStart = origMap.begin();
itStart++;
BValueMap::iterator itEnd = origMap.end();
m_Label = new QLabel(m_NodeName.c_str());
m_Label->setVisible(true);
m_View->m_Controls->m_QBallSelectionBox->layout()->addWidget(m_Label);
for(BValueMap::iterator it = itStart ; it!= itEnd; it++)
{
QCheckBox * box = new QCheckBox(QString::number(it->first));
m_View->m_Controls->m_QBallSelectionBox->layout()->addWidget(box);
box->setChecked(true);
box->setCheckable(true);
// box->setVisible(true);
m_CheckBoxes.push_back(box);
}
}
void SetVisible(bool vis)
{
foreach(QCheckBox * box, m_CheckBoxes)
{
box->setVisible(vis);
}
}
BValueMap GetBValueSelctionMap()
{
BValueMap inputMap = m_Image->GetBValueMap();
BValueMap outputMap;
unsigned int val = 0;
if(inputMap.find(0) == inputMap.end()){
MITK_INFO << "QbrShellSelection: return empty BValueMap from GUI Selection";
return outputMap;
}else{
outputMap[val] = inputMap[val];
MITK_INFO << val;
}
foreach(QCheckBox * box, m_CheckBoxes)
{
if(box->isChecked()){
val = box->text().toDouble();
outputMap[val] = inputMap[val];
MITK_INFO << val;
}
}
return outputMap;
}
~QbrShellSelection()
{
m_View->m_Controls->m_QBallSelectionBox->layout()->removeWidget(m_Label);
delete m_Label;
for(std::vector<QCheckBox *>::iterator it = m_CheckBoxes.begin() ; it!= m_CheckBoxes.end(); it++)
{
m_View->m_Controls->m_QBallSelectionBox->layout()->removeWidget((*it));
delete (*it);
}
m_CheckBoxes.clear();
}
};
using namespace berry;
struct QbrSelListener : ISelectionListener
{
berryObjectMacro(QbrSelListener);
QbrSelListener(QmitkQBallReconstructionView* view)
{
m_View = view;
}
void DoSelectionChanged(ISelection::ConstPointer selection)
{
// save current selection in member variable
m_View->m_CurrentSelection = selection.Cast<const IStructuredSelection>();
// do something with the selected items
if(m_View->m_CurrentSelection)
{
bool foundDwiVolume = false;
m_View->m_Controls->m_DiffusionImageLabel->setText("<font color='red'>mandatory</font>");
m_View->m_Controls->m_InputData->setTitle("Please Select Input Data");
QString selected_images = "";
mitk::DataStorage::SetOfObjects::Pointer set =
mitk::DataStorage::SetOfObjects::New();
int at = 0;
// iterate selection
for (IStructuredSelection::iterator i = m_View->m_CurrentSelection->Begin();
i != m_View->m_CurrentSelection->End(); ++i)
{
// extract datatree node
if (mitk::DataNodeObject::Pointer nodeObj = i->Cast<mitk::DataNodeObject>())
{
mitk::DataNode::Pointer node = nodeObj->GetDataNode();
mitk::DiffusionImage<DiffusionPixelType>* diffusionImage = dynamic_cast<mitk::DiffusionImage<DiffusionPixelType> * >(node->GetData());
// only look at interesting types
if(diffusionImage)
{
foundDwiVolume = true;
selected_images += QString(node->GetName().c_str());
if(i + 1 != m_View->m_CurrentSelection->End())
selected_images += "\n";
set->InsertElement(at++, node);
}
}
}
m_View->GenerateShellSelectionUI(set);
m_View->m_Controls->m_DiffusionImageLabel->setText(selected_images);
m_View->m_Controls->m_ButtonStandard->setEnabled(foundDwiVolume);
if (foundDwiVolume)
m_View->m_Controls->m_InputData->setTitle("Input Data");
else
m_View->m_Controls->m_DiffusionImageLabel->setText("<font color='red'>mandatory</font>");
}
}
void SelectionChanged(IWorkbenchPart::Pointer part, ISelection::ConstPointer selection)
{
// check, if selection comes from datamanager
if (part)
{
QString partname(part->GetPartName().c_str());
if(partname.compare("Data Manager")==0)
{
// apply selection
DoSelectionChanged(selection);
}
}
}
QmitkQBallReconstructionView* m_View;
};
// --------------- QmitkQBallReconstructionView----------------- //
QmitkQBallReconstructionView::QmitkQBallReconstructionView()
: QmitkFunctionality(),
m_Controls(NULL),
m_MultiWidget(NULL)
{
}
QmitkQBallReconstructionView::~QmitkQBallReconstructionView()
{
this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->RemovePostSelectionListener(/*"org.mitk.views.datamanager",*/ m_SelListener);
}
void QmitkQBallReconstructionView::CreateQtPartControl(QWidget *parent)
{
if (!m_Controls)
{
// create GUI widgets
m_Controls = new Ui::QmitkQBallReconstructionViewControls;
m_Controls->setupUi(parent);
this->CreateConnections();
m_Controls->m_DiffusionImageLabel->setText("<font color='red'>mandatory</font>");
QStringList items;
items << "2" << "4" << "6" << "8" << "10" << "12";
m_Controls->m_QBallReconstructionMaxLLevelComboBox->addItems(items);
m_Controls->m_QBallReconstructionMaxLLevelComboBox->setCurrentIndex(1);
MethodChoosen(m_Controls->m_QBallReconstructionMethodComboBox->currentIndex());
#ifndef DIFFUSION_IMAGING_EXTENDED
m_Controls->m_QBallReconstructionMethodComboBox->removeItem(3);
#endif
AdvancedCheckboxClicked();
}
m_SelListener = berry::ISelectionListener::Pointer(new QbrSelListener(this));
this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->AddPostSelectionListener(/*"org.mitk.views.datamanager",*/ m_SelListener);
berry::ISelection::ConstPointer sel(
this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.datamanager"));
m_CurrentSelection = sel.Cast<const IStructuredSelection>();
m_SelListener.Cast<QbrSelListener>()->DoSelectionChanged(sel);
}
void QmitkQBallReconstructionView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget)
{
m_MultiWidget = &stdMultiWidget;
}
void QmitkQBallReconstructionView::StdMultiWidgetNotAvailable()
{
m_MultiWidget = NULL;
}
void QmitkQBallReconstructionView::CreateConnections()
{
if ( m_Controls )
{
connect( (QObject*)(m_Controls->m_ButtonStandard), SIGNAL(clicked()), this, SLOT(ReconstructStandard()) );
connect( (QObject*)(m_Controls->m_AdvancedCheckbox), SIGNAL(clicked()), this, SLOT(AdvancedCheckboxClicked()) );
connect( (QObject*)(m_Controls->m_QBallReconstructionMethodComboBox), SIGNAL(currentIndexChanged(int)), this, SLOT(MethodChoosen(int)) );
-
+ connect( (QObject*)(m_Controls->m_QBallReconstructionThreasholdEdit), SIGNAL(valueChanged(int)), this, SLOT(PreviewThreshold(int)) );
}
}
void QmitkQBallReconstructionView::OnSelectionChanged( std::vector<mitk::DataNode*> )
{
}
void QmitkQBallReconstructionView::Activated()
{
QmitkFunctionality::Activated();
berry::ISelection::ConstPointer sel(
this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.datamanager"));
m_CurrentSelection = sel.Cast<const IStructuredSelection>();
m_SelListener.Cast<QbrSelListener>()->DoSelectionChanged(sel);
}
void QmitkQBallReconstructionView::Deactivated()
{
+
+ mitk::DataStorage::SetOfObjects::ConstPointer objects = this->GetDefaultDataStorage()->GetAll();
+ mitk::DataStorage::SetOfObjects::const_iterator itemiter( objects->begin() );
+ mitk::DataStorage::SetOfObjects::const_iterator itemiterend( objects->end() );
+ while ( itemiter != itemiterend ) // for all items
+ {
+ mitk::DataNode::Pointer node = *itemiter;
+ if (node.IsNull())
+ continue;
+
+ // only look at interesting types
+ if(dynamic_cast<mitk::DiffusionImage<short>*>(node->GetData()))
+ {
+ if (this->GetDefaultDataStorage()->GetNamedDerivedNode("ThresholdOverlay", *itemiter))
+ {
+ node = this->GetDefaultDataStorage()->GetNamedDerivedNode("ThresholdOverlay", *itemiter);
+ this->GetDefaultDataStorage()->Remove(node);
+ }
+ }
+ itemiter++;
+ }
+
+ mitk::RenderingManager::GetInstance()->RequestUpdateAll();
QmitkFunctionality::Deactivated();
}
void QmitkQBallReconstructionView::ReconstructStandard()
{
int index = m_Controls->m_QBallReconstructionMethodComboBox->currentIndex();
#ifndef DIFFUSION_IMAGING_EXTENDED
if(index>=3)
{
index = index + 1;
}
#endif
switch(index)
{
case 0:
{
// Numerical
Reconstruct(0,0);
break;
}
case 1:
{
// Standard
Reconstruct(1,0);
break;
}
case 2:
{
// Solid Angle
Reconstruct(1,6);
break;
}
case 3:
{
// Constrained Solid Angle
Reconstruct(1,7);
break;
}
case 4:
{
// ADC
Reconstruct(1,4);
break;
}
case 5:
{
// Raw Signal
Reconstruct(1,5);
break;
}
case 6:
{
// Q-Ball reconstruction
Reconstruct(2,0);
break;
}
}
}
void QmitkQBallReconstructionView::MethodChoosen(int method)
{
#ifndef DIFFUSION_IMAGING_EXTENDED
if(method>=3)
{
method = method + 1;
}
#endif
m_Controls->m_QBallSelectionBox->setHidden(true);
m_Controls->m_OutputCoeffsImage->setHidden(true);
if (method==0)
m_Controls->m_ShFrame->setVisible(false);
else
m_Controls->m_ShFrame->setVisible(true);
switch(method)
{
case 0:
m_Controls->m_Description->setText("Numerical recon. (Tuch 2004)");
break;
case 1:
m_Controls->m_Description->setText("Spherical harmonics recon. (Descoteaux 2007)");
m_Controls->m_OutputCoeffsImage->setHidden(false);
break;
case 2:
m_Controls->m_Description->setText("SH recon. with solid angle consideration (Aganj 2009)");
m_Controls->m_OutputCoeffsImage->setHidden(false);
break;
case 3:
m_Controls->m_Description->setText("SH solid angle with non-neg. constraint (Goh 2009)");
break;
case 4:
m_Controls->m_Description->setText("SH recon. of the plain ADC-profiles");
break;
case 5:
m_Controls->m_Description->setText("SH recon. of the raw diffusion signal");
break;
case 6:
m_Controls->m_Description->setText("SH recon. of the multi shell diffusion signal (Aganj 2010)");
m_Controls->m_QBallSelectionBox->setHidden(false);
m_Controls->m_OutputCoeffsImage->setHidden(false);
break;
}
}
void QmitkQBallReconstructionView::AdvancedCheckboxClicked()
{
bool check = m_Controls->m_AdvancedCheckbox->isChecked();
m_Controls->m_QBallReconstructionMaxLLevelTextLabel_2->setVisible(check);
m_Controls->m_QBallReconstructionMaxLLevelComboBox->setVisible(check);
m_Controls->m_QBallReconstructionLambdaTextLabel_2->setVisible(check);
m_Controls->m_QBallReconstructionLambdaLineEdit->setVisible(check);
m_Controls->m_QBallReconstructionThresholdLabel_2->setVisible(check);
m_Controls->m_QBallReconstructionThreasholdEdit->setVisible(check);
m_Controls->label_2->setVisible(check);
m_Controls->frame_2->setVisible(check);
}
void QmitkQBallReconstructionView::Reconstruct(int method, int normalization)
{
if (m_CurrentSelection)
{
mitk::DataStorage::SetOfObjects::Pointer set =
mitk::DataStorage::SetOfObjects::New();
int at = 0;
for (IStructuredSelection::iterator i = m_CurrentSelection->Begin();
i != m_CurrentSelection->End();
++i)
{
if (mitk::DataNodeObject::Pointer nodeObj = i->Cast<mitk::DataNodeObject>())
{
mitk::DataNode::Pointer node = nodeObj->GetDataNode();
if(QString("DiffusionImage").compare(node->GetData()->GetNameOfClass())==0)
{
set->InsertElement(at++, node);
}
}
}
if(method == 0)
{
NumericalQBallReconstruction(set, normalization);
}
else
{
#if BOOST_VERSION / 100000 > 0
#if BOOST_VERSION / 100 % 1000 > 34
if(method == 1)
{
AnalyticalQBallReconstruction(set, normalization);
}
if(method == 2)
{
MultiQBallReconstruction(set);
}
#else
std::cout << "ERROR: Boost 1.35 minimum required" << std::endl;
QMessageBox::warning(NULL,"ERROR","Boost 1.35 minimum required");
#endif
#else
std::cout << "ERROR: Boost 1.35 minimum required" << std::endl;
QMessageBox::warning(NULL,"ERROR","Boost 1.35 minimum required");
#endif
}
}
}
void QmitkQBallReconstructionView::NumericalQBallReconstruction
(mitk::DataStorage::SetOfObjects::Pointer inImages, int normalization)
{
try
{
itk::TimeProbe clock;
int nrFiles = inImages->size();
if (!nrFiles) return;
QString status;
mitk::ProgressBar::GetInstance()->AddStepsToDo(nrFiles);
mitk::DataStorage::SetOfObjects::const_iterator itemiter( inImages->begin() );
mitk::DataStorage::SetOfObjects::const_iterator itemiterend( inImages->end() );
while ( itemiter != itemiterend ) // for all items
{
mitk::DiffusionImage<DiffusionPixelType>* vols =
static_cast<mitk::DiffusionImage<DiffusionPixelType>*>(
(*itemiter)->GetData());
std::string nodename;
(*itemiter)->GetStringProperty("name", nodename);
// QBALL RECONSTRUCTION
clock.Start();
MITK_INFO << "QBall reconstruction ";
mitk::StatusBar::GetInstance()->DisplayText(status.sprintf(
- "QBall reconstruction for %s", nodename.c_str()).toAscii());
+ "QBall reconstruction for %s", nodename.c_str()).toLatin1());
typedef itk::DiffusionQballReconstructionImageFilter
<DiffusionPixelType, DiffusionPixelType, TTensorPixelType, QBALL_ODFSIZE>
QballReconstructionImageFilterType;
QballReconstructionImageFilterType::Pointer filter =
QballReconstructionImageFilterType::New();
filter->SetGradientImage( vols->GetDirections(), vols->GetVectorImage() );
filter->SetBValue(vols->GetReferenceBValue());
filter->SetThreshold( m_Controls->m_QBallReconstructionThreasholdEdit->value() );
std::string nodePostfix;
switch(normalization)
{
case 0:
{
filter->SetNormalizationMethod(QballReconstructionImageFilterType::QBR_STANDARD);
nodePostfix = "_Numerical_Qball";
break;
}
case 1:
{
filter->SetNormalizationMethod(QballReconstructionImageFilterType::QBR_B_ZERO_B_VALUE);
nodePostfix = "_Numerical_ZeroBvalueNormalization_Qball";
break;
}
case 2:
{
filter->SetNormalizationMethod(QballReconstructionImageFilterType::QBR_B_ZERO);
nodePostfix = "_NumericalQball_ZeroNormalization_Qball";
break;
}
case 3:
{
filter->SetNormalizationMethod(QballReconstructionImageFilterType::QBR_NONE);
nodePostfix = "_NumericalQball_NoNormalization_Qball";
break;
}
default:
{
filter->SetNormalizationMethod(QballReconstructionImageFilterType::QBR_STANDARD);
nodePostfix = "_NumericalQball_Qball";
}
}
filter->Update();
clock.Stop();
MITK_DEBUG << "took " << clock.GetMean() << "s." ;
// ODFs TO DATATREE
mitk::QBallImage::Pointer image = mitk::QBallImage::New();
image->InitializeByItk( filter->GetOutput() );
image->SetVolume( filter->GetOutput()->GetBufferPointer() );
mitk::DataNode::Pointer node=mitk::DataNode::New();
node->SetData( image );
SetDefaultNodeProperties(node, nodename+nodePostfix);
mitk::ProgressBar::GetInstance()->Progress();
GetDefaultDataStorage()->Add(node, *itemiter);
++itemiter;
}
- mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toAscii());
+ mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toLatin1());
m_MultiWidget->RequestUpdate();
}
catch (itk::ExceptionObject &ex)
{
MITK_INFO << ex ;
QMessageBox::information(0, "Reconstruction not possible:", ex.GetDescription());
return ;
}
}
void QmitkQBallReconstructionView::AnalyticalQBallReconstruction(
mitk::DataStorage::SetOfObjects::Pointer inImages,
int normalization)
{
try
{
itk::TimeProbe clock;
int nrFiles = inImages->size();
if (!nrFiles) return;
std::vector<float> lambdas;
float minLambda = m_Controls->m_QBallReconstructionLambdaLineEdit->value();
lambdas.push_back(minLambda);
int nLambdas = lambdas.size();
QString status;
mitk::ProgressBar::GetInstance()->AddStepsToDo(nrFiles*nLambdas);
mitk::DataStorage::SetOfObjects::const_iterator itemiter( inImages->begin() );
mitk::DataStorage::SetOfObjects::const_iterator itemiterend( inImages->end() );
std::vector<mitk::DataNode::Pointer>* nodes
= new std::vector<mitk::DataNode::Pointer>();
while ( itemiter != itemiterend ) // for all items
{
// QBALL RECONSTRUCTION
clock.Start();
MITK_INFO << "QBall reconstruction ";
- mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("QBall reconstruction for %s", (*itemiter)->GetName().c_str()).toAscii());
+ mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("QBall reconstruction for %s", (*itemiter)->GetName().c_str()).toLatin1());
for(int i=0; i<nLambdas; i++)
{
float currentLambda = lambdas[i];
switch(m_Controls->m_QBallReconstructionMaxLLevelComboBox->currentIndex())
{
case 0:
{
TemplatedAnalyticalQBallReconstruction<2>(*itemiter, currentLambda, normalization);
break;
}
case 1:
{
TemplatedAnalyticalQBallReconstruction<4>(*itemiter, currentLambda, normalization);
break;
}
case 2:
{
TemplatedAnalyticalQBallReconstruction<6>(*itemiter, currentLambda, normalization);
break;
}
case 3:
{
TemplatedAnalyticalQBallReconstruction<8>(*itemiter, currentLambda, normalization);
break;
}
case 4:
{
TemplatedAnalyticalQBallReconstruction<10>(*itemiter, currentLambda, normalization);
break;
}
case 5:
{
TemplatedAnalyticalQBallReconstruction<12>(*itemiter, currentLambda, normalization);
break;
}
}
clock.Stop();
MITK_DEBUG << "took " << clock.GetMean() << "s." ;
mitk::ProgressBar::GetInstance()->Progress();
itemiter++;
}
}
std::vector<mitk::DataNode::Pointer>::iterator nodeIt;
for(nodeIt = nodes->begin(); nodeIt != nodes->end(); ++nodeIt)
GetDefaultDataStorage()->Add(*nodeIt);
m_MultiWidget->RequestUpdate();
- mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toAscii());
+ mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toLatin1());
}
catch (itk::ExceptionObject &ex)
{
MITK_INFO << ex;
QMessageBox::information(0, "Reconstruction not possible:", ex.GetDescription());
return;
}
}
template<int L>
void QmitkQBallReconstructionView::TemplatedAnalyticalQBallReconstruction(mitk::DataNode* dataNodePointer, float lambda, int normalization)
{
typedef itk::AnalyticalDiffusionQballReconstructionImageFilter
<DiffusionPixelType,DiffusionPixelType,TTensorPixelType,L,QBALL_ODFSIZE> FilterType;
typename FilterType::Pointer filter = FilterType::New();
mitk::DiffusionImage<DiffusionPixelType>* vols = dynamic_cast<mitk::DiffusionImage<DiffusionPixelType>*>(dataNodePointer->GetData());
filter->SetGradientImage( vols->GetDirections(), vols->GetVectorImage() );
filter->SetBValue(vols->GetReferenceBValue());
filter->SetThreshold( m_Controls->m_QBallReconstructionThreasholdEdit->value() );
filter->SetLambda(lambda);
std::string nodePostfix;
switch(normalization)
{
case 0:
{
filter->SetNormalizationMethod(FilterType::QBAR_STANDARD);
nodePostfix = "_SphericalHarmonics_Qball";
break;
}
case 1:
{
filter->SetNormalizationMethod(FilterType::QBAR_B_ZERO_B_VALUE);
nodePostfix = "_SphericalHarmonics_1_Qball";
break;
}
case 2:
{
filter->SetNormalizationMethod(FilterType::QBAR_B_ZERO);
nodePostfix = "_SphericalHarmonics_2_Qball";
break;
}
case 3:
{
filter->SetNormalizationMethod(FilterType::QBAR_NONE);
nodePostfix = "_SphericalHarmonics_3_Qball";
break;
}
case 4:
{
filter->SetNormalizationMethod(FilterType::QBAR_ADC_ONLY);
nodePostfix = "_AdcProfile";
break;
}
case 5:
{
filter->SetNormalizationMethod(FilterType::QBAR_RAW_SIGNAL);
nodePostfix = "_RawSignal";
break;
}
case 6:
{
filter->SetNormalizationMethod(FilterType::QBAR_SOLID_ANGLE);
nodePostfix = "_SphericalHarmonics_CSA_Qball";
break;
}
case 7:
{
filter->SetNormalizationMethod(FilterType::QBAR_NONNEG_SOLID_ANGLE);
nodePostfix = "_SphericalHarmonics_NonNegCSA_Qball";
break;
}
default:
{
filter->SetNormalizationMethod(FilterType::QBAR_STANDARD);
}
}
filter->Update();
// ODFs TO DATATREE
mitk::QBallImage::Pointer image = mitk::QBallImage::New();
image->InitializeByItk( filter->GetOutput() );
image->SetVolume( filter->GetOutput()->GetBufferPointer() );
mitk::DataNode::Pointer node=mitk::DataNode::New();
node->SetData( image );
SetDefaultNodeProperties(node, dataNodePointer->GetName()+nodePostfix);
GetDefaultDataStorage()->Add(node, dataNodePointer);
if(m_Controls->m_OutputCoeffsImage->isChecked())
{
mitk::Image::Pointer coeffsImage = mitk::Image::New();
coeffsImage->InitializeByItk( filter->GetCoefficientImage().GetPointer() );
coeffsImage->SetVolume( filter->GetCoefficientImage()->GetBufferPointer() );
mitk::DataNode::Pointer coeffsNode=mitk::DataNode::New();
coeffsNode->SetData( coeffsImage );
coeffsNode->SetProperty( "name", mitk::StringProperty::New(dataNodePointer->GetName()+"_SH-Coeffs") );
coeffsNode->SetVisibility(false);
GetDefaultDataStorage()->Add(coeffsNode, node);
}
}
void QmitkQBallReconstructionView::MultiQBallReconstruction(mitk::DataStorage::SetOfObjects::Pointer inImages)
{
try
{
itk::TimeProbe clock;
int nrFiles = inImages->size();
if (!nrFiles) return;
std::vector<float> lambdas;
float minLambda = m_Controls->m_QBallReconstructionLambdaLineEdit->value();
lambdas.push_back(minLambda);
int nLambdas = lambdas.size();
QString status;
mitk::ProgressBar::GetInstance()->AddStepsToDo(nrFiles*nLambdas);
mitk::DataStorage::SetOfObjects::const_iterator itemiter( inImages->begin() );
mitk::DataStorage::SetOfObjects::const_iterator itemiterend( inImages->end() );
while ( itemiter != itemiterend ) // for all items
{
mitk::DataNode* nodePointer = (*itemiter).GetPointer();
std::string nodename;
(*itemiter)->GetStringProperty("name",nodename);
itemiter++;
// QBALL RECONSTRUCTION
clock.Start();
MITK_INFO << "QBall reconstruction ";
- mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("QBall reconstruction for %s", nodename.c_str()).toAscii());
+ mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("QBall reconstruction for %s", nodename.c_str()).toLatin1());
for(int i=0; i<nLambdas; i++)
{
float currentLambda = lambdas[i];
switch(m_Controls->m_QBallReconstructionMaxLLevelComboBox->currentIndex())
{
case 0:
{
TemplatedMultiQBallReconstruction<2>(currentLambda, nodePointer);
break;
}
case 1:
{
TemplatedMultiQBallReconstruction<4>(currentLambda, nodePointer);
break;
}
case 2:
{
TemplatedMultiQBallReconstruction<6>(currentLambda, nodePointer);
break;
}
case 3:
{
TemplatedMultiQBallReconstruction<8>(currentLambda, nodePointer);
break;
}
case 4:
{
TemplatedMultiQBallReconstruction<10>(currentLambda, nodePointer);
break;
}
case 5:
{
TemplatedMultiQBallReconstruction<12>(currentLambda, nodePointer);
break;
}
}
clock.Stop();
MITK_DEBUG << "took " << clock.GetMean() << "s." ;
mitk::ProgressBar::GetInstance()->Progress();
}
}
m_MultiWidget->RequestUpdate();
- mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toAscii());
+ mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toLatin1());
}
catch (itk::ExceptionObject &ex)
{
MITK_INFO << ex ;
QMessageBox::information(0, "Reconstruction not possible:", ex.GetDescription());
return ;
}
}
template<int L>
void QmitkQBallReconstructionView::TemplatedMultiQBallReconstruction(float lambda, mitk::DataNode* dataNodePointer)
{
typedef itk::DiffusionMultiShellQballReconstructionImageFilter
<DiffusionPixelType,DiffusionPixelType,TTensorPixelType,L,QBALL_ODFSIZE> FilterType;
typename FilterType::Pointer filter = FilterType::New();
std::string nodename;
dataNodePointer->GetStringProperty("name",nodename);
mitk::DiffusionImage<DiffusionPixelType>* dwi = dynamic_cast<mitk::DiffusionImage<DiffusionPixelType>*>(dataNodePointer->GetData());
mitk::DiffusionImage<short>::BValueMap currSelectionMap = m_ShellSelectorMap[dataNodePointer]->GetBValueSelctionMap();
if(currSelectionMap.size() != 4 && currSelectionMap.find(0) != currSelectionMap.end())
{
QMessageBox::information(0, "Reconstruction not possible:" ,QString("Only three shells in a equidistant configuration is supported. (ImageName: " + QString(nodename.c_str()) + ")"));
return;
}
mitk::DiffusionImage<short>::BValueMap::reverse_iterator it1 = currSelectionMap.rbegin();
mitk::DiffusionImage<short>::BValueMap::reverse_iterator it2 = currSelectionMap.rbegin();
++it2;
// Get average distance
int avdistance = 0;
for(; it2 != currSelectionMap.rend(); ++it1,++it2)
avdistance += (int)it1->first - (int)it2->first;
avdistance /= currSelectionMap.size()-1;
// Check if all shells are using the same averae distance
it1 = currSelectionMap.rbegin();
it2 = currSelectionMap.rbegin();
++it2;
for(; it2 != currSelectionMap.rend(); ++it1,++it2)
if(avdistance != (int)it1->first - (int)it2->first)
{
QMessageBox::information(0, "Reconstruction not possible:" ,QString("Selected Shells are not in a equidistant configuration. (ImageName: " + QString(nodename.c_str()) + ")"));
return;
}
filter->SetBValueMap(m_ShellSelectorMap[dataNodePointer]->GetBValueSelctionMap());
filter->SetGradientImage( dwi->GetDirections(), dwi->GetVectorImage(), dwi->GetReferenceBValue() );
filter->SetThreshold( m_Controls->m_QBallReconstructionThreasholdEdit->value() );
filter->SetLambda(lambda);
filter->Update();
// ODFs TO DATATREE
mitk::QBallImage::Pointer image = mitk::QBallImage::New();
image->InitializeByItk( filter->GetOutput() );
image->SetVolume( filter->GetOutput()->GetBufferPointer() );
mitk::DataNode::Pointer node=mitk::DataNode::New();
node->SetData( image );
SetDefaultNodeProperties(node, nodename+"_SphericalHarmonics_MultiShell_Qball");
GetDefaultDataStorage()->Add(node, dataNodePointer);
if(m_Controls->m_OutputCoeffsImage->isChecked())
{
mitk::Image::Pointer coeffsImage = mitk::Image::New();
coeffsImage->InitializeByItk( filter->GetCoefficientImage().GetPointer() );
coeffsImage->SetVolume( filter->GetCoefficientImage()->GetBufferPointer() );
mitk::DataNode::Pointer coeffsNode=mitk::DataNode::New();
coeffsNode->SetData( coeffsImage );
coeffsNode->SetProperty( "name", mitk::StringProperty::New(
QString(nodename.c_str()).append("_SH-Coefficients").toStdString()) );
coeffsNode->SetVisibility(false);
GetDefaultDataStorage()->Add(coeffsNode, node);
}
}
void QmitkQBallReconstructionView::SetDefaultNodeProperties(mitk::DataNode::Pointer node, std::string name)
{
node->SetProperty( "ShowMaxNumber", mitk::IntProperty::New( 500 ) );
node->SetProperty( "Scaling", mitk::FloatProperty::New( 1.0 ) );
node->SetProperty( "Normalization", mitk::OdfNormalizationMethodProperty::New());
node->SetProperty( "ScaleBy", mitk::OdfScaleByProperty::New());
node->SetProperty( "IndexParam1", mitk::FloatProperty::New(2));
node->SetProperty( "IndexParam2", mitk::FloatProperty::New(1));
node->SetProperty( "visible", mitk::BoolProperty::New( true ) );
node->SetProperty( "VisibleOdfs", mitk::BoolProperty::New( false ) );
node->SetProperty ("layer", mitk::IntProperty::New(100));
node->SetProperty( "DoRefresh", mitk::BoolProperty::New( true ) );
node->SetProperty( "name", mitk::StringProperty::New(name) );
}
void QmitkQBallReconstructionView::GenerateShellSelectionUI(mitk::DataStorage::SetOfObjects::Pointer set)
{
+ m_DiffusionImages = set;
std::map<const mitk::DataNode * , QbrShellSelection * > tempMap;
const mitk::DataStorage::SetOfObjects::iterator setEnd( set->end() );
mitk::DataStorage::SetOfObjects::iterator NodeIt( set->begin() );
while(NodeIt != setEnd)
{
if(m_ShellSelectorMap.find( (*NodeIt).GetPointer() ) != m_ShellSelectorMap.end())
{
tempMap[(*NodeIt).GetPointer()] = m_ShellSelectorMap[(*NodeIt).GetPointer()];
m_ShellSelectorMap.erase((*NodeIt).GetPointer());
}else
{
tempMap[(*NodeIt).GetPointer()] = new QbrShellSelection(this, (*NodeIt) );
tempMap[(*NodeIt).GetPointer()]->SetVisible(true);
}
NodeIt++;
}
for(std::map<const mitk::DataNode * , QbrShellSelection * >::iterator it = m_ShellSelectorMap.begin(); it != m_ShellSelectorMap.end();it ++)
{
delete it->second;
}
m_ShellSelectorMap.clear();
m_ShellSelectorMap = tempMap;
}
+
+
+
+void QmitkQBallReconstructionView::PreviewThreshold(int threshold)
+{
+ mitk::DataStorage::SetOfObjects::const_iterator itemiter( m_DiffusionImages->begin() );
+ mitk::DataStorage::SetOfObjects::const_iterator itemiterend( m_DiffusionImages->end() );
+ while ( itemiter != itemiterend ) // for all items
+ {
+ mitk::DiffusionImage<DiffusionPixelType>* vols =
+ static_cast<mitk::DiffusionImage<DiffusionPixelType>*>(
+ (*itemiter)->GetData());
+
+ // Extract b0 image
+ typedef itk::B0ImageExtractionImageFilter<short, short> FilterType;
+ FilterType::Pointer filterB0 = FilterType::New();
+ filterB0->SetInput(vols->GetVectorImage());
+ filterB0->SetDirections(vols->GetDirections());
+ filterB0->Update();
+
+ mitk::Image::Pointer mitkImage = mitk::Image::New();
+
+ typedef itk::Image<short, 3> ImageType;
+ typedef itk::Image<short, 3> SegmentationType;
+ typedef itk::BinaryThresholdImageFilter<ImageType, SegmentationType> ThresholdFilterType;
+ // apply threshold
+ ThresholdFilterType::Pointer filterThreshold = ThresholdFilterType::New();
+ filterThreshold->SetInput(filterB0->GetOutput());
+ filterThreshold->SetLowerThreshold(threshold);
+ filterThreshold->SetInsideValue(0);
+ filterThreshold->SetOutsideValue(1); // mark cut off values red
+ filterThreshold->Update();
+
+ mitkImage->InitializeByItk( filterThreshold->GetOutput() );
+ mitkImage->SetVolume( filterThreshold->GetOutput()->GetBufferPointer() );
+ mitk::DataNode::Pointer node;
+ if (this->GetDefaultDataStorage()->GetNamedDerivedNode("ThresholdOverlay", *itemiter))
+ {
+ node = this->GetDefaultDataStorage()->GetNamedDerivedNode("ThresholdOverlay", *itemiter);
+ }
+ else
+ {
+ // create a new node, to show thresholded values
+ node = mitk::DataNode::New();
+ GetDefaultDataStorage()->Add( node, *itemiter );
+ node->SetProperty( "name", mitk::StringProperty::New("ThresholdOverlay"));
+ node->SetBoolProperty("helper object", true);
+ }
+ node->SetData( mitkImage );
+ itemiter++;
+ mitk::RenderingManager::GetInstance()->RequestUpdateAll();
+ }
+}
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkQBallReconstructionView.h b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkQBallReconstructionView.h
index 429da04967..3ac068f4f9 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkQBallReconstructionView.h
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkQBallReconstructionView.h
@@ -1,123 +1,131 @@
/*===================================================================
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 _QMITKQBALLRECONSTRUCTIONVIEW_H_INCLUDED
#define _QMITKQBALLRECONSTRUCTIONVIEW_H_INCLUDED
#include <QmitkFunctionality.h>
#include <string>
#include "ui_QmitkQBallReconstructionViewControls.h"
#include "mitkDiffusionImage.h"
#include <berryIPartListener.h>
#include <berryISelectionListener.h>
#include <berryIStructuredSelection.h>
typedef short DiffusionPixelType;
struct QbrSelListener;
struct QbrShellSelection;
/*!
* \ingroup org_mitk_gui_qt_qballreconstruction_internal
*
* \brief QmitkQBallReconstructionView
*
* Document your class here.
*
* \sa QmitkFunctionality
*/
class QmitkQBallReconstructionView : public QmitkFunctionality
{
friend struct QbrSelListener;
friend struct QbrShellSelection;
// this is needed for all Qt objects that should have a MOC object (everything that derives from QObject)
Q_OBJECT
public:
static const std::string VIEW_ID;
QmitkQBallReconstructionView();
virtual ~QmitkQBallReconstructionView();
virtual void CreateQtPartControl(QWidget *parent);
/// \brief Creation of the connections of main and control widget
virtual void CreateConnections();
/// \brief Called when the functionality is activated
virtual void Activated();
virtual void Deactivated();
virtual void StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget);
virtual void StdMultiWidgetNotAvailable();
static const int nrconvkernels;
protected slots:
void ReconstructStandard();
void AdvancedCheckboxClicked();
void MethodChoosen(int method);
void Reconstruct(int method, int normalization);
void NumericalQBallReconstruction(mitk::DataStorage::SetOfObjects::Pointer inImages, int normalization);
void AnalyticalQBallReconstruction(mitk::DataStorage::SetOfObjects::Pointer inImages, int normalization);
void MultiQBallReconstruction(mitk::DataStorage::SetOfObjects::Pointer inImages);
+
+ /**
+ * @brief PreviewThreshold Generates a preview of the values that are cut off by the thresholds
+ * @param threshold
+ */
+ void PreviewThreshold(int threshold);
+
protected:
/// \brief called by QmitkFunctionality when DataManager's selection has changed
virtual void OnSelectionChanged( std::vector<mitk::DataNode*> nodes );
Ui::QmitkQBallReconstructionViewControls* m_Controls;
QmitkStdMultiWidget* m_MultiWidget;
template<int L>
void TemplatedAnalyticalQBallReconstruction(mitk::DataNode* dataNodePointer, float lambda, int normalization);
template<int L>
void TemplatedMultiQBallReconstruction(float lambda, mitk::DataNode*);
void SetDefaultNodeProperties(mitk::DataNode::Pointer node, std::string name);
//void Create
berry::ISelectionListener::Pointer m_SelListener;
berry::IStructuredSelection::ConstPointer m_CurrentSelection;
+ mitk::DataStorage::SetOfObjects::Pointer m_DiffusionImages;
private:
std::map< const mitk::DataNode *, QbrShellSelection * > m_ShellSelectorMap;
void GenerateShellSelectionUI(mitk::DataStorage::SetOfObjects::Pointer set);
};
#endif // _QMITKQBALLRECONSTRUCTIONVIEW_H_INCLUDED
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkTensorReconstructionView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkTensorReconstructionView.cpp
index 85cc46fe79..bc98ff91f9 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkTensorReconstructionView.cpp
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkTensorReconstructionView.cpp
@@ -1,965 +1,1054 @@
/*===================================================================
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 "QmitkTensorReconstructionView.h"
#include "mitkDiffusionImagingConfigure.h"
// qt includes
#include <QMessageBox>
#include <QImage>
#include <QGraphicsScene>
#include <QGraphicsPixmapItem>
#include <QGraphicsLinearLayout>
// itk includes
#include "itkTimeProbe.h"
//#include "itkTensor.h"
// mitk includes
#include "mitkProgressBar.h"
#include "mitkStatusBar.h"
#include "mitkNodePredicateDataType.h"
#include "QmitkDataStorageComboBox.h"
#include "QmitkStdMultiWidget.h"
#include "mitkTeemDiffusionTensor3DReconstructionImageFilter.h"
#include "itkDiffusionTensor3DReconstructionImageFilter.h"
#include "itkTensorImageToDiffusionImageFilter.h"
#include "itkPointShell.h"
#include "itkVector.h"
#include "itkB0ImageExtractionImageFilter.h"
#include "itkTensorReconstructionWithEigenvalueCorrectionFilter.h"
-//#include "itkFreeWaterEliminationFilter.h"
+
+#include "mitkImageCast.h"
+#include "mitkImageAccessByItk.h"
+#include <itkBinaryThresholdImageFilter.h>
+
#include "mitkProperties.h"
#include "mitkDataNodeObject.h"
#include "mitkOdfNormalizationMethodProperty.h"
#include "mitkOdfScaleByProperty.h"
#include "mitkDiffusionImageMapper.h"
#include "mitkLookupTableProperty.h"
#include "mitkLookupTable.h"
#include "mitkImageStatisticsHolder.h"
#include <itkTensorImageToQBallImageFilter.h>
#include <itkResidualImageFilter.h>
#include <berryIWorkbenchWindow.h>
#include <berryISelectionService.h>
const std::string QmitkTensorReconstructionView::VIEW_ID = "org.mitk.views.tensorreconstruction";
typedef float TTensorPixelType;
typedef itk::DiffusionTensor3D< TTensorPixelType > TensorPixelType;
typedef itk::Image< TensorPixelType, 3 > TensorImageType;
using namespace berry;
QmitkTensorReconstructionView::QmitkTensorReconstructionView()
: QmitkFunctionality(),
m_Controls(NULL),
m_MultiWidget(NULL)
{
m_DiffusionImages = mitk::DataStorage::SetOfObjects::New();
m_TensorImages = mitk::DataStorage::SetOfObjects::New();
}
QmitkTensorReconstructionView::~QmitkTensorReconstructionView()
{
}
void QmitkTensorReconstructionView::CreateQtPartControl(QWidget *parent)
{
if (!m_Controls)
{
// create GUI widgets
m_Controls = new Ui::QmitkTensorReconstructionViewControls;
m_Controls->setupUi(parent);
this->CreateConnections();
Advanced1CheckboxClicked();
}
}
void QmitkTensorReconstructionView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget)
{
m_MultiWidget = &stdMultiWidget;
}
void QmitkTensorReconstructionView::StdMultiWidgetNotAvailable()
{
m_MultiWidget = NULL;
}
void QmitkTensorReconstructionView::CreateConnections()
{
if ( m_Controls )
{
connect( (QObject*)(m_Controls->m_StartReconstruction), SIGNAL(clicked()), this, SLOT(Reconstruct()) );
connect( (QObject*)(m_Controls->m_Advanced1), SIGNAL(clicked()), this, SLOT(Advanced1CheckboxClicked()) );
connect( (QObject*)(m_Controls->m_TensorsToDWIButton), SIGNAL(clicked()), this, SLOT(TensorsToDWI()) );
connect( (QObject*)(m_Controls->m_TensorsToQbiButton), SIGNAL(clicked()), this, SLOT(TensorsToQbi()) );
connect( (QObject*)(m_Controls->m_ResidualButton), SIGNAL(clicked()), this, SLOT(ResidualCalculation()) );
connect( (QObject*)(m_Controls->m_PerSliceView), SIGNAL(pointSelected(int, int)), this, SLOT(ResidualClicked(int, int)) );
+ connect( (QObject*)(m_Controls->m_TensorReconstructionThreshold), SIGNAL(valueChanged(int)), this, SLOT(PreviewThreshold(int)) );
}
}
void QmitkTensorReconstructionView::ResidualClicked(int slice, int volume)
{
// Use image coord to reset crosshair
// Find currently selected diffusion image
// Update Label
// to do: This position should be modified in order to skip B0 volumes that are not taken into account
// when calculating residuals
// Find the diffusion image
mitk::DiffusionImage<DiffusionPixelType>* diffImage;
mitk::DataNode::Pointer correctNode;
mitk::BaseGeometry* geometry;
if (m_DiffusionImage.IsNotNull())
{
diffImage = static_cast<mitk::DiffusionImage<DiffusionPixelType>*>(m_DiffusionImage->GetData());
geometry = diffImage->GetGeometry();
// Remember the node whose display index must be updated
correctNode = mitk::DataNode::New();
correctNode = m_DiffusionImage;
}
if(diffImage != NULL)
{
typedef vnl_vector_fixed< double, 3 > GradientDirectionType;
typedef itk::VectorContainer< unsigned int,
GradientDirectionType > GradientDirectionContainerType;
GradientDirectionContainerType::Pointer dirs = diffImage->GetDirections();
for(unsigned int i=0; i<dirs->Size() && i<=volume; i++)
{
GradientDirectionType grad = dirs->ElementAt(i);
// check if image is b0 weighted
if(fabs(grad[0]) < 0.001 && fabs(grad[1]) < 0.001 && fabs(grad[2]) < 0.001)
{
volume++;
}
}
QString pos = "Volume: ";
pos.append(QString::number(volume));
pos.append(", Slice: ");
pos.append(QString::number(slice));
m_Controls->m_PositionLabel->setText(pos);
if(correctNode)
{
int oldDisplayVal;
correctNode->GetIntProperty("DisplayChannel", oldDisplayVal);
std::string oldVal = QString::number(oldDisplayVal).toStdString();
std::string newVal = QString::number(volume).toStdString();
correctNode->SetIntProperty("DisplayChannel",volume);
correctNode->SetSelected(true);
this->FirePropertyChanged("DisplayChannel", oldVal, newVal);
correctNode->UpdateOutputInformation();
mitk::Point3D p3 = m_MultiWidget->GetCrossPosition();
itk::Index<3> ix;
geometry->WorldToIndex(p3, ix);
// ix[2] = slice;
mitk::Vector3D vec;
vec[0] = ix[0];
vec[1] = ix[1];
vec[2] = slice;
mitk::Vector3D v3New;
geometry->IndexToWorld(vec, v3New);
mitk::Point3D origin = geometry->GetOrigin();
mitk::Point3D p3New;
p3New[0] = v3New[0] + origin[0];
p3New[1] = v3New[1] + origin[1];
p3New[2] = v3New[2] + origin[2];
m_MultiWidget->MoveCrossToPosition(p3New);
m_MultiWidget->RequestUpdate();
}
}
}
void QmitkTensorReconstructionView::Advanced1CheckboxClicked()
{
bool check = m_Controls->
m_Advanced1->isChecked();
m_Controls->frame->setVisible(check);
}
void QmitkTensorReconstructionView::Activated()
{
QmitkFunctionality::Activated();
}
void QmitkTensorReconstructionView::Deactivated()
{
+
+ // Get all current nodes
+
+ mitk::DataStorage::SetOfObjects::ConstPointer objects = this->GetDefaultDataStorage()->GetAll();
+ mitk::DataStorage::SetOfObjects::const_iterator itemiter( objects->begin() );
+ mitk::DataStorage::SetOfObjects::const_iterator itemiterend( objects->end() );
+ while ( itemiter != itemiterend ) // for all items
+ {
+ mitk::DataNode::Pointer node = *itemiter;
+ if (node.IsNull())
+ continue;
+
+ // only look at interesting types
+ if(dynamic_cast<mitk::DiffusionImage<short>*>(node->GetData()))
+ {
+ if (this->GetDefaultDataStorage()->GetNamedDerivedNode("ThresholdOverlay", *itemiter))
+ {
+ node = this->GetDefaultDataStorage()->GetNamedDerivedNode("ThresholdOverlay", *itemiter);
+ this->GetDefaultDataStorage()->Remove(node);
+ }
+ }
+ itemiter++;
+ }
+
+
+ mitk::RenderingManager::GetInstance()->RequestUpdateAll();
+
QmitkFunctionality::Deactivated();
}
void QmitkTensorReconstructionView::ResidualCalculation()
{
// Extract dwi and dti from current selection
// In case of multiple selections, take the first one, since taking all combinations is not meaningful
mitk::DataStorage::SetOfObjects::Pointer set =
mitk::DataStorage::SetOfObjects::New();
mitk::DiffusionImage<DiffusionPixelType>::Pointer diffImage
= mitk::DiffusionImage<DiffusionPixelType>::New();
TensorImageType::Pointer tensorImage;
std::string nodename;
if(m_DiffusionImage.IsNotNull())
{
diffImage = static_cast<mitk::DiffusionImage<DiffusionPixelType>*>(m_DiffusionImage->GetData());
}
else
return;
if(m_TensorImage.IsNotNull())
{
mitk::TensorImage* mitkVol;
mitkVol = static_cast<mitk::TensorImage*>(m_TensorImage->GetData());
mitk::CastToItkImage(mitkVol, tensorImage);
m_TensorImage->GetStringProperty("name", nodename);
}
else
return;
typedef itk::TensorImageToDiffusionImageFilter<
TTensorPixelType, DiffusionPixelType > FilterType;
mitk::DiffusionImage<DiffusionPixelType>::GradientDirectionContainerType* gradients
= diffImage->GetDirections();
// Find the min and the max values from a baseline image
mitk::ImageStatisticsHolder *stats = diffImage->GetStatistics();
//Initialize filter that calculates the modeled diffusion weighted signals
FilterType::Pointer filter = FilterType::New();
filter->SetInput( tensorImage );
filter->SetBValue(diffImage->GetReferenceBValue());
filter->SetGradientList(gradients);
filter->SetMin(stats->GetScalarValueMin());
filter->SetMax(stats->GetScalarValueMax());
filter->Update();
// TENSORS TO DATATREE
mitk::DiffusionImage<DiffusionPixelType>::Pointer image = mitk::DiffusionImage<DiffusionPixelType>::New();
image->SetVectorImage( filter->GetOutput() );
image->SetReferenceBValue(diffImage->GetReferenceBValue());
image->SetDirections(gradients);
image->InitializeFromVectorImage();
mitk::DataNode::Pointer node = mitk::DataNode::New();
node->SetData( image );
mitk::DiffusionImageMapper<short>::SetDefaultProperties(node);
node->SetName("Estimated DWI");
+ QString newname;
+ newname = newname.append(nodename.c_str());
+ newname = newname.append("_DWI");
+ node->SetName(newname.toLatin1());
+
GetDefaultDataStorage()->Add(node, m_TensorImage);
mitk::DiffusionImage<DiffusionPixelType>::BValueMap map =image->GetBValueMap();
mitk::DiffusionImage<DiffusionPixelType>::IndicesVector b0Indices = map[0];
typedef itk::ResidualImageFilter<DiffusionPixelType, float> ResidualImageFilterType;
ResidualImageFilterType::Pointer residualFilter = ResidualImageFilterType::New();
residualFilter->SetInput(diffImage->GetVectorImage());
residualFilter->SetSecondDiffusionImage(image->GetVectorImage());
residualFilter->SetGradients(gradients);
residualFilter->SetB0Index(b0Indices[0]);
residualFilter->SetB0Threshold(30);
residualFilter->Update();
itk::Image<float, 3>::Pointer residualImage = itk::Image<float, 3>::New();
residualImage = residualFilter->GetOutput();
mitk::Image::Pointer mitkResImg = mitk::Image::New();
mitk::CastToMitkImage(residualImage, mitkResImg);
stats = mitkResImg->GetStatistics();
float min = stats->GetScalarValueMin();
float max = stats->GetScalarValueMax();
mitk::LookupTableProperty::Pointer lutProp = mitk::LookupTableProperty::New();
mitk::LookupTable::Pointer lut = mitk::LookupTable::New();
vtkSmartPointer<vtkLookupTable> lookupTable =
vtkSmartPointer<vtkLookupTable>::New();
lookupTable->SetTableRange(min, max);
// If you don't want to use the whole color range, you can use
// SetValueRange, SetHueRange, and SetSaturationRange
lookupTable->Build();
vtkSmartPointer<vtkLookupTable> reversedlookupTable =
vtkSmartPointer<vtkLookupTable>::New();
reversedlookupTable->SetTableRange(min+1, max);
reversedlookupTable->Build();
for(int i=0; i<256; i++)
{
double* rgba = reversedlookupTable->GetTableValue(255-i);
lookupTable->SetTableValue(i, rgba[0], rgba[1], rgba[2], rgba[3]);
}
lut->SetVtkLookupTable(lookupTable);
lutProp->SetLookupTable(lut);
// Create lookuptable
mitk::DataNode::Pointer resNode=mitk::DataNode::New();
resNode->SetData( mitkResImg );
resNode->SetName("Residuals");
resNode->SetProperty("LookupTable", lutProp);
bool b;
resNode->GetBoolProperty("use color", b);
resNode->SetBoolProperty("use color", false);
GetDefaultDataStorage()->Add(resNode, m_TensorImage);
m_MultiWidget->RequestUpdate();
// Draw Graph
std::vector<double> means = residualFilter->GetMeans();
std::vector<double> q1s = residualFilter->GetQ1();
std::vector<double> q3s = residualFilter->GetQ3();
std::vector<double> percentagesOfOUtliers = residualFilter->GetPercentagesOfOutliers();
m_Controls->m_ResidualAnalysis->SetMeans(means);
m_Controls->m_ResidualAnalysis->SetQ1(q1s);
m_Controls->m_ResidualAnalysis->SetQ3(q3s);
m_Controls->m_ResidualAnalysis->SetPercentagesOfOutliers(percentagesOfOUtliers);
if(m_Controls->m_PercentagesOfOutliers->isChecked())
{
m_Controls->m_ResidualAnalysis->DrawPercentagesOfOutliers();
}
else
{
m_Controls->m_ResidualAnalysis->DrawMeans();
}
// Draw Graph for volumes per slice in the QGraphicsView
std::vector< std::vector<double> > outliersPerSlice = residualFilter->GetOutliersPerSlice();
int xSize = outliersPerSlice.size();
if(xSize == 0)
{
return;
}
int ySize = outliersPerSlice[0].size();
// Find maximum in outliersPerSlice
double maxOutlier= 0.0;
for(int i=0; i<xSize; i++)
{
for(int j=0; j<ySize; j++)
{
if(outliersPerSlice[i][j]>maxOutlier)
{
maxOutlier = outliersPerSlice[i][j];
}
}
}
// Create some QImage
QImage qImage(xSize, ySize, QImage::Format_RGB32);
QImage legend(1, 256, QImage::Format_RGB32);
QRgb value;
vtkSmartPointer<vtkLookupTable> lookup =
vtkSmartPointer<vtkLookupTable>::New();
lookup->SetTableRange(0.0, maxOutlier);
lookup->Build();
reversedlookupTable->SetTableRange(0, maxOutlier);
reversedlookupTable->Build();
for(int i=0; i<256; i++)
{
double* rgba = reversedlookupTable->GetTableValue(255-i);
lookup->SetTableValue(i, rgba[0], rgba[1], rgba[2], rgba[3]);
}
// Fill qImage
for(int i=0; i<xSize; i++)
{
for(int j=0; j<ySize; j++)
{
double out = outliersPerSlice[i][j];
unsigned char *_rgba = lookup->MapValue(out);
int r, g, b;
r = _rgba[0];
g = _rgba[1];
b = _rgba[2];
value = qRgb(r, g, b);
qImage.setPixel(i,j,value);
}
}
for(int i=0; i<256; i++)
{
double* rgba = lookup->GetTableValue(i);
int r, g, b;
r = rgba[0]*255;
g = rgba[1]*255;
b = rgba[2]*255;
value = qRgb(r, g, b);
legend.setPixel(0,255-i,value);
}
QString upper = QString::number(maxOutlier, 'g', 3);
upper.append(" %");
QString lower = QString::number(0.0);
lower.append(" %");
m_Controls->m_UpperLabel->setText(upper);
m_Controls->m_LowerLabel->setText(lower);
- QGraphicsScene* scene = new QGraphicsScene;
- QGraphicsScene* scene2 = new QGraphicsScene;
-
-
QPixmap pixmap(QPixmap::fromImage(qImage));
- QGraphicsPixmapItem *item = new QGraphicsPixmapItem( pixmap, 0, scene);
- item->scale(10.0, 3.0);
+ QGraphicsPixmapItem *item = new QGraphicsPixmapItem(pixmap);
+ item->setTransform(QTransform::fromScale(10.0, 3.0), true);
QPixmap pixmap2(QPixmap::fromImage(legend));
- QGraphicsPixmapItem *item2 = new QGraphicsPixmapItem( pixmap2, 0, scene2);
- item2->scale(20.0, 1.0);
+ QGraphicsPixmapItem *item2 = new QGraphicsPixmapItem(pixmap2);
+ item2->setTransform(QTransform::fromScale(20.0, 1.0), true);
m_Controls->m_PerSliceView->SetResidualPixmapItem(item);
+ QGraphicsScene* scene = new QGraphicsScene;
+ QGraphicsScene* scene2 = new QGraphicsScene;
+ scene->addItem(item);
+ scene2->addItem(item2);
m_Controls->m_PerSliceView->setScene(scene);
m_Controls->m_LegendView->setScene(scene2);
m_Controls->m_PerSliceView->show();
m_Controls->m_PerSliceView->repaint();
m_Controls->m_LegendView->setHorizontalScrollBarPolicy ( Qt::ScrollBarAlwaysOff );
m_Controls->m_LegendView->setVerticalScrollBarPolicy ( Qt::ScrollBarAlwaysOff );
m_Controls->m_LegendView->show();
m_Controls->m_LegendView->repaint();
}
void QmitkTensorReconstructionView::Reconstruct()
{
int method = m_Controls->m_ReconctructionMethodBox->currentIndex();
switch (method)
{
case 0:
ItkTensorReconstruction(m_DiffusionImages);
break;
case 1:
TensorReconstructionWithCorr(m_DiffusionImages);
break;
default:
ItkTensorReconstruction(m_DiffusionImages);
}
}
void QmitkTensorReconstructionView::TensorReconstructionWithCorr
(mitk::DataStorage::SetOfObjects::Pointer inImages)
{
try
{
int nrFiles = inImages->size();
if (!nrFiles) return;
QString status;
mitk::ProgressBar::GetInstance()->AddStepsToDo(nrFiles);
mitk::DataStorage::SetOfObjects::const_iterator itemiter( inImages->begin() );
mitk::DataStorage::SetOfObjects::const_iterator itemiterend( inImages->end() );
while ( itemiter != itemiterend ) // for all items
{
typedef mitk::DiffusionImage<DiffusionPixelType> DiffusionImageType;
typedef DiffusionImageType::GradientDirectionContainerType GradientDirectionContainerType;
DiffusionImageType* vols = static_cast<DiffusionImageType*>((*itemiter)->GetData());
std::string nodename;
(*itemiter)->GetStringProperty("name", nodename);
// TENSOR RECONSTRUCTION
MITK_INFO << "Tensor reconstruction with correction for negative eigenvalues";
- mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Tensor reconstruction for %s", nodename.c_str()).toAscii());
+ mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Tensor reconstruction for %s", nodename.c_str()).toLatin1());
typedef itk::TensorReconstructionWithEigenvalueCorrectionFilter< DiffusionPixelType, TTensorPixelType > ReconstructionFilter;
float b0Threshold = m_Controls->m_TensorReconstructionThreshold->value();
GradientDirectionContainerType::Pointer gradientContainerCopy = GradientDirectionContainerType::New();
for(GradientDirectionContainerType::ConstIterator it = vols->GetDirections()->Begin();
it != vols->GetDirections()->End(); it++)
{
gradientContainerCopy->push_back(it.Value());
}
ReconstructionFilter::Pointer reconFilter = ReconstructionFilter::New();
reconFilter->SetGradientImage( gradientContainerCopy, vols->GetVectorImage() );
reconFilter->SetBValue(vols->GetReferenceBValue());
reconFilter->SetB0Threshold(b0Threshold);
reconFilter->Update();
typedef itk::Image<itk::DiffusionTensor3D<TTensorPixelType>, 3> TensorImageType;
TensorImageType::Pointer outputTensorImg = reconFilter->GetOutput();
typedef itk::ImageRegionIterator<TensorImageType> TensorImageIteratorType;
TensorImageIteratorType tensorIt(outputTensorImg, outputTensorImg->GetRequestedRegion());
tensorIt.GoToBegin();
int negatives = 0;
while(!tensorIt.IsAtEnd())
{
typedef itk::DiffusionTensor3D<TTensorPixelType> TensorType;
TensorType tensor = tensorIt.Get();
TensorType::EigenValuesArrayType ev;
tensor.ComputeEigenValues(ev);
for(unsigned int i=0; i<ev.Size(); i++)
{
if(ev[i] < 0.0)
{
tensor.Fill(0.0);
tensorIt.Set(tensor);
negatives++;
break;
}
}
++tensorIt;
}
MITK_INFO << negatives << " tensors with negative eigenvalues" << std::endl;
mitk::TensorImage::Pointer image = mitk::TensorImage::New();
image->InitializeByItk( outputTensorImg.GetPointer() );
image->SetVolume( outputTensorImg->GetBufferPointer() );
mitk::DataNode::Pointer node=mitk::DataNode::New();
node->SetData( image );
SetDefaultNodeProperties(node, nodename+"_EigenvalueCorrected_DT");
GetDefaultDataStorage()->Add(node, *itemiter);
mitk::ProgressBar::GetInstance()->Progress();
++itemiter;
}
- mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toAscii());
+ mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toLatin1());
m_MultiWidget->RequestUpdate();
}
catch (itk::ExceptionObject &ex)
{
MITK_INFO << ex ;
QMessageBox::information(0, "Reconstruction not possible:", ex.GetDescription());
}
}
void QmitkTensorReconstructionView::ItkTensorReconstruction(mitk::DataStorage::SetOfObjects::Pointer inImages)
{
try
{
itk::TimeProbe clock;
int nrFiles = inImages->size();
if (!nrFiles) return;
QString status;
mitk::ProgressBar::GetInstance()->AddStepsToDo(nrFiles);
mitk::DataStorage::SetOfObjects::const_iterator itemiter( inImages->begin() );
mitk::DataStorage::SetOfObjects::const_iterator itemiterend( inImages->end() );
while ( itemiter != itemiterend ) // for all items
{
mitk::DiffusionImage<DiffusionPixelType>* vols =
static_cast<mitk::DiffusionImage<DiffusionPixelType>*>(
(*itemiter)->GetData());
std::string nodename;
(*itemiter)->GetStringProperty("name", nodename);
// TENSOR RECONSTRUCTION
clock.Start();
MITK_DEBUG << "Tensor reconstruction ";
- mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Tensor reconstruction for %s", nodename.c_str()).toAscii());
+ mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Tensor reconstruction for %s", nodename.c_str()).toLatin1());
typedef itk::DiffusionTensor3DReconstructionImageFilter<
DiffusionPixelType, DiffusionPixelType, TTensorPixelType > TensorReconstructionImageFilterType;
TensorReconstructionImageFilterType::Pointer tensorReconstructionFilter =
TensorReconstructionImageFilterType::New();
typedef mitk::DiffusionImage<DiffusionPixelType> DiffusionImageType;
typedef DiffusionImageType::GradientDirectionContainerType GradientDirectionContainerType;
GradientDirectionContainerType::Pointer gradientContainerCopy = GradientDirectionContainerType::New();
for(GradientDirectionContainerType::ConstIterator it = vols->GetDirections()->Begin();
it != vols->GetDirections()->End(); it++)
{
gradientContainerCopy->push_back(it.Value());
}
tensorReconstructionFilter->SetGradientImage( gradientContainerCopy, vols->GetVectorImage() );
tensorReconstructionFilter->SetBValue(vols->GetReferenceBValue());
tensorReconstructionFilter->SetThreshold( m_Controls->m_TensorReconstructionThreshold->value() );
tensorReconstructionFilter->Update();
clock.Stop();
MITK_DEBUG << "took " << clock.GetMean() << "s.";
// TENSORS TO DATATREE
mitk::TensorImage::Pointer image = mitk::TensorImage::New();
typedef itk::Image<itk::DiffusionTensor3D<TTensorPixelType>, 3> TensorImageType;
TensorImageType::Pointer tensorImage;
tensorImage = tensorReconstructionFilter->GetOutput();
// Check the tensor for negative eigenvalues
if(m_Controls->m_CheckNegativeEigenvalues->isChecked())
{
typedef itk::ImageRegionIterator<TensorImageType> TensorImageIteratorType;
TensorImageIteratorType tensorIt(tensorImage, tensorImage->GetRequestedRegion());
tensorIt.GoToBegin();
while(!tensorIt.IsAtEnd())
{
typedef itk::DiffusionTensor3D<TTensorPixelType> TensorType;
//typedef itk::Tensor<TTensorPixelType, 3> TensorType2;
TensorType tensor = tensorIt.Get();
TensorType::EigenValuesArrayType ev;
tensor.ComputeEigenValues(ev);
for(unsigned int i=0; i<ev.Size(); i++)
{
if(ev[i] < 0.0)
{
tensor.Fill(0.0);
tensorIt.Set(tensor);
break;
}
}
++tensorIt;
}
}
tensorImage->SetDirection( vols->GetVectorImage()->GetDirection() );
image->InitializeByItk( tensorImage.GetPointer() );
image->SetVolume( tensorReconstructionFilter->GetOutput()->GetBufferPointer() );
mitk::DataNode::Pointer node=mitk::DataNode::New();
node->SetData( image );
SetDefaultNodeProperties(node, nodename+"_LinearLeastSquares_DT");
GetDefaultDataStorage()->Add(node, *itemiter);
mitk::ProgressBar::GetInstance()->Progress();
++itemiter;
}
- mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toAscii());
+ mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toLatin1());
m_MultiWidget->RequestUpdate();
}
catch (itk::ExceptionObject &ex)
{
MITK_INFO << ex ;
QMessageBox::information(0, "Reconstruction not possible:", ex.GetDescription());
return;
}
}
void QmitkTensorReconstructionView::SetDefaultNodeProperties(mitk::DataNode::Pointer node, std::string name)
{
node->SetProperty( "ShowMaxNumber", mitk::IntProperty::New( 500 ) );
node->SetProperty( "Scaling", mitk::FloatProperty::New( 1.0 ) );
node->SetProperty( "Normalization", mitk::OdfNormalizationMethodProperty::New());
node->SetProperty( "ScaleBy", mitk::OdfScaleByProperty::New());
node->SetProperty( "IndexParam1", mitk::FloatProperty::New(2));
node->SetProperty( "IndexParam2", mitk::FloatProperty::New(1));
node->SetProperty( "visible", mitk::BoolProperty::New( true ) );
node->SetProperty( "VisibleOdfs", mitk::BoolProperty::New( false ) );
node->SetProperty ("layer", mitk::IntProperty::New(100));
node->SetProperty( "DoRefresh", mitk::BoolProperty::New( true ) );
node->SetProperty( "name", mitk::StringProperty::New(name) );
}
void QmitkTensorReconstructionView::TensorsToDWI()
{
DoTensorsToDWI(m_TensorImages);
}
void QmitkTensorReconstructionView::TensorsToQbi()
{
for (unsigned int i=0; i<m_TensorImages->size(); i++)
{
mitk::DataNode::Pointer tensorImageNode = m_TensorImages->at(i);
MITK_INFO << "starting Q-Ball estimation";
typedef float TTensorPixelType;
typedef itk::DiffusionTensor3D< TTensorPixelType > TensorPixelType;
typedef itk::Image< TensorPixelType, 3 > TensorImageType;
TensorImageType::Pointer itkvol = TensorImageType::New();
mitk::CastToItkImage(dynamic_cast<mitk::TensorImage*>(tensorImageNode->GetData()), itkvol);
typedef itk::TensorImageToQBallImageFilter< TTensorPixelType, TTensorPixelType > FilterType;
FilterType::Pointer filter = FilterType::New();
filter->SetInput( itkvol );
filter->Update();
typedef itk::Vector<TTensorPixelType,QBALL_ODFSIZE> OutputPixelType;
typedef itk::Image<OutputPixelType,3> OutputImageType;
mitk::QBallImage::Pointer image = mitk::QBallImage::New();
OutputImageType::Pointer outimg = filter->GetOutput();
image->InitializeByItk( outimg.GetPointer() );
image->SetVolume( outimg->GetBufferPointer() );
mitk::DataNode::Pointer node = mitk::DataNode::New();
node->SetData( image );
node->SetName(tensorImageNode->GetName()+"_Qball");
GetDefaultDataStorage()->Add(node, tensorImageNode);
}
}
void QmitkTensorReconstructionView::OnSelectionChanged( std::vector<mitk::DataNode*> nodes )
{
m_DiffusionImages = mitk::DataStorage::SetOfObjects::New();
m_TensorImages = mitk::DataStorage::SetOfObjects::New();
bool foundDwiVolume = false;
bool foundTensorVolume = false;
m_Controls->m_DiffusionImageLabel->setText("<font color='red'>mandatory</font>");
m_DiffusionImage = NULL;
m_TensorImage = NULL;
m_Controls->m_InputData->setTitle("Please Select Input Data");
// iterate selection
for( std::vector<mitk::DataNode*>::iterator it = nodes.begin(); it != nodes.end(); ++it )
{
mitk::DataNode::Pointer node = *it;
if (node.IsNull())
continue;
// only look at interesting types
- if(dynamic_cast<mitk::DiffusionImage<short>*>(node->GetData()))
+ if(dynamic_cast<mitk::DiffusionImage<DiffusionPixelType>*>(node->GetData()))
{
foundDwiVolume = true;
m_Controls->m_DiffusionImageLabel->setText(node->GetName().c_str());
m_DiffusionImages->push_back(node);
m_DiffusionImage = node;
}
else if(dynamic_cast<mitk::TensorImage*>(node->GetData()))
{
foundTensorVolume = true;
m_Controls->m_DiffusionImageLabel->setText(node->GetName().c_str());
m_TensorImages->push_back(node);
m_TensorImage = node;
}
}
m_Controls->m_StartReconstruction->setEnabled(foundDwiVolume);
m_Controls->m_TensorsToDWIButton->setEnabled(foundTensorVolume);
m_Controls->m_TensorsToQbiButton->setEnabled(foundTensorVolume);
if (foundDwiVolume || foundTensorVolume)
m_Controls->m_InputData->setTitle("Input Data");
m_Controls->m_ResidualButton->setEnabled(foundDwiVolume && foundTensorVolume);
m_Controls->m_PercentagesOfOutliers->setEnabled(foundDwiVolume && foundTensorVolume);
m_Controls->m_PerSliceView->setEnabled(foundDwiVolume && foundTensorVolume);
}
template<int ndirs>
itk::VectorContainer<unsigned int, vnl_vector_fixed<double, 3> >::Pointer
QmitkTensorReconstructionView::MakeGradientList()
{
itk::VectorContainer<unsigned int, vnl_vector_fixed<double,3> >::Pointer retval =
itk::VectorContainer<unsigned int, vnl_vector_fixed<double,3> >::New();
vnl_matrix_fixed<double, 3, ndirs>* U =
itk::PointShell<ndirs, vnl_matrix_fixed<double, 3, ndirs> >::DistributePointShell();
for(int i=0; i<ndirs;i++)
{
vnl_vector_fixed<double,3> v;
v[0] = U->get(0,i); v[1] = U->get(1,i); v[2] = U->get(2,i);
retval->push_back(v);
}
// Add 0 vector for B0
vnl_vector_fixed<double,3> v;
v.fill(0.0);
retval->push_back(v);
return retval;
}
void QmitkTensorReconstructionView::DoTensorsToDWI(mitk::DataStorage::SetOfObjects::Pointer inImages)
{
try
{
itk::TimeProbe clock;
int nrFiles = inImages->size();
if (!nrFiles) return;
QString status;
mitk::ProgressBar::GetInstance()->AddStepsToDo(nrFiles);
mitk::DataStorage::SetOfObjects::const_iterator itemiter( inImages->begin() );
mitk::DataStorage::SetOfObjects::const_iterator itemiterend( inImages->end() );
while ( itemiter != itemiterend ) // for all items
{
std::string nodename;
(*itemiter)->GetStringProperty("name", nodename);
mitk::TensorImage* vol =
static_cast<mitk::TensorImage*>((*itemiter)->GetData());
typedef float TTensorPixelType;
typedef itk::DiffusionTensor3D< TTensorPixelType > TensorPixelType;
typedef itk::Image< TensorPixelType, 3 > TensorImageType;
TensorImageType::Pointer itkvol = TensorImageType::New();
mitk::CastToItkImage(vol, itkvol);
typedef itk::TensorImageToDiffusionImageFilter<
TTensorPixelType, DiffusionPixelType > FilterType;
FilterType::GradientListPointerType gradientList = FilterType::GradientListType::New();
switch(m_Controls->m_TensorsToDWINumDirsSelect->currentIndex())
{
case 0:
gradientList = MakeGradientList<12>();
break;
case 1:
gradientList = MakeGradientList<42>();
break;
case 2:
gradientList = MakeGradientList<92>();
break;
case 3:
gradientList = MakeGradientList<162>();
break;
case 4:
gradientList = MakeGradientList<252>();
break;
case 5:
gradientList = MakeGradientList<362>();
break;
case 6:
gradientList = MakeGradientList<492>();
break;
case 7:
gradientList = MakeGradientList<642>();
break;
case 8:
gradientList = MakeGradientList<812>();
break;
case 9:
gradientList = MakeGradientList<1002>();
break;
default:
gradientList = MakeGradientList<92>();
}
double bVal = m_Controls->m_TensorsToDWIBValueEdit->text().toDouble();
// DWI ESTIMATION
clock.Start();
MBI_INFO << "DWI Estimation ";
mitk::StatusBar::GetInstance()->DisplayText(status.sprintf(
- "DWI Estimation for %s", nodename.c_str()).toAscii());
+ "DWI Estimation for %s", nodename.c_str()).toLatin1());
FilterType::Pointer filter = FilterType::New();
filter->SetInput( itkvol );
filter->SetBValue(bVal);
filter->SetGradientList(gradientList);
//filter->SetNumberOfThreads(1);
filter->Update();
clock.Stop();
MBI_DEBUG << "took " << clock.GetMean() << "s.";
// TENSORS TO DATATREE
mitk::DiffusionImage<DiffusionPixelType>::Pointer image = mitk::DiffusionImage<DiffusionPixelType>::New();
image->SetVectorImage( filter->GetOutput() );
image->SetReferenceBValue(bVal);
image->SetDirections(gradientList);
image->InitializeFromVectorImage();
mitk::DataNode::Pointer node=mitk::DataNode::New();
node->SetData( image );
mitk::DiffusionImageMapper<short>::SetDefaultProperties(node);
node->SetName(nodename+"_DWI");
GetDefaultDataStorage()->Add(node, *itemiter);
mitk::ProgressBar::GetInstance()->Progress();
++itemiter;
}
- mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toAscii());
+ mitk::StatusBar::GetInstance()->DisplayText(status.sprintf("Finished Processing %d Files", nrFiles).toLatin1());
m_MultiWidget->RequestUpdate();
}
catch (itk::ExceptionObject &ex)
{
MITK_INFO << ex ;
QMessageBox::information(0, "DWI estimation failed:", ex.GetDescription());
return ;
}
}
+
+
+void QmitkTensorReconstructionView::PreviewThreshold(int threshold)
+{
+ mitk::DataStorage::SetOfObjects::const_iterator itemiter( m_DiffusionImages->begin() );
+ mitk::DataStorage::SetOfObjects::const_iterator itemiterend( m_DiffusionImages->end() );
+ while ( itemiter != itemiterend ) // for all items
+ {
+ mitk::DiffusionImage<DiffusionPixelType>* vols =
+ static_cast<mitk::DiffusionImage<DiffusionPixelType>*>(
+ (*itemiter)->GetData());
+
+ // Extract b0 image
+ typedef itk::B0ImageExtractionImageFilter<short, short> FilterType;
+ FilterType::Pointer filterB0 = FilterType::New();
+ filterB0->SetInput(vols->GetVectorImage());
+ filterB0->SetDirections(vols->GetDirections());
+ filterB0->Update();
+
+ mitk::Image::Pointer mitkImage = mitk::Image::New();
+
+ typedef itk::Image<short, 3> ImageType;
+ typedef itk::Image<short, 3> SegmentationType;
+ typedef itk::BinaryThresholdImageFilter<ImageType, SegmentationType> ThresholdFilterType;
+ // apply threshold
+ ThresholdFilterType::Pointer filterThreshold = ThresholdFilterType::New();
+ filterThreshold->SetInput(filterB0->GetOutput());
+ filterThreshold->SetLowerThreshold(threshold);
+ filterThreshold->SetInsideValue(0);
+ filterThreshold->SetOutsideValue(1); // mark cut off values red
+ filterThreshold->Update();
+
+ mitkImage->InitializeByItk( filterThreshold->GetOutput() );
+ mitkImage->SetVolume( filterThreshold->GetOutput()->GetBufferPointer() );
+ mitk::DataNode::Pointer node;
+ if (this->GetDefaultDataStorage()->GetNamedDerivedNode("ThresholdOverlay", *itemiter))
+ {
+ node = this->GetDefaultDataStorage()->GetNamedDerivedNode("ThresholdOverlay", *itemiter);
+ }
+ else
+ {
+ // create a new node, to show thresholded values
+ node = mitk::DataNode::New();
+ GetDefaultDataStorage()->Add( node, *itemiter );
+ node->SetProperty( "name", mitk::StringProperty::New("ThresholdOverlay"));
+ node->SetBoolProperty("helper object", true);
+ }
+ node->SetData( mitkImage );
+ itemiter++;
+ mitk::RenderingManager::GetInstance()->RequestUpdateAll();
+ }
+}
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkTensorReconstructionView.h b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkTensorReconstructionView.h
index cd927b796a..4fc685b48c 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkTensorReconstructionView.h
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkTensorReconstructionView.h
@@ -1,112 +1,117 @@
/*===================================================================
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 _QMITKTENSORRECONSTRUCTIONVIEW_H_INCLUDED
#define _QMITKTENSORRECONSTRUCTIONVIEW_H_INCLUDED
#include <QmitkFunctionality.h>
#include <string>
#include "ui_QmitkTensorReconstructionViewControls.h"
#include <mitkDiffusionImage.h>
#include <mitkTensorImage.h>
typedef short DiffusionPixelType;
struct TrSelListener;
/*!
* \ingroup org_mitk_gui_qt_tensorreconstruction_internal
*
* \brief QmitkTensorReconstructionView
*
* Document your class here.
*
* \sa QmitkFunctionality
*/
class QmitkTensorReconstructionView : public QmitkFunctionality
{
friend struct TrSelListener;
// this is needed for all Qt objects that should have a MOC object (everything that derives from QObject)
Q_OBJECT
public:
static const std::string VIEW_ID;
QmitkTensorReconstructionView();
virtual ~QmitkTensorReconstructionView();
virtual void CreateQtPartControl(QWidget *parent);
/// \brief Creation of the connections of main and control widget
virtual void CreateConnections();
/// \brief Called when the functionality is activated
virtual void Activated();
virtual void Deactivated();
virtual void StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget);
virtual void StdMultiWidgetNotAvailable();
static const int nrconvkernels;
protected slots:
void TensorsToQbi();
void TensorsToDWI();
void DoTensorsToDWI(mitk::DataStorage::SetOfObjects::Pointer inImages);
void Advanced1CheckboxClicked();
void Reconstruct();
void ResidualCalculation();
void ResidualClicked(int slice, int volume);
+ /**
+ * @brief PreviewThreshold Generates a preview of the values that are cut off by the thresholds
+ * @param threshold
+ */
+ void PreviewThreshold(int threshold);
protected:
void ItkTensorReconstruction(mitk::DataStorage::SetOfObjects::Pointer inImages);
void TeemTensorReconstruction(mitk::DataStorage::SetOfObjects::Pointer inImages);
void TensorReconstructionWithCorr(mitk::DataStorage::SetOfObjects::Pointer inImages);
void OnSelectionChanged( std::vector<mitk::DataNode*> nodes );
Ui::QmitkTensorReconstructionViewControls* m_Controls;
QmitkStdMultiWidget* m_MultiWidget;
template<int ndirs> itk::VectorContainer<unsigned int, vnl_vector_fixed<double,3> >::Pointer MakeGradientList();
template<int L>
void TemplatedAnalyticalTensorReconstruction(mitk::DiffusionImage<DiffusionPixelType>* vols,
float lambda, std::string nodename, std::vector<mitk::DataNode::Pointer>* nodes, int normalization);
void SetDefaultNodeProperties(mitk::DataNode::Pointer node, std::string name);
mitk::DataNode::Pointer m_DiffusionImage;
mitk::DataNode::Pointer m_TensorImage;
mitk::DataStorage::SetOfObjects::Pointer m_DiffusionImages;
mitk::DataStorage::SetOfObjects::Pointer m_TensorImages;
};
#endif // _QMITKTENSORRECONSTRUCTIONVIEW_H_INCLUDED
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkTractbasedSpatialStatisticsView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkTractbasedSpatialStatisticsView.cpp
index 0f8e4ae59e..7de3c7fdef 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkTractbasedSpatialStatisticsView.cpp
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkTractbasedSpatialStatisticsView.cpp
@@ -1,1137 +1,1137 @@
/*===================================================================
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.
===================================================================*/
// Qmitk
#include "QmitkTractbasedSpatialStatisticsView.h"
#include "QmitkStdMultiWidget.h"
#include "mitkDataNodeObject.h"
#include <itkCastImageFilter.h>
// Qt
#include <QMessageBox>
#include <QInputDialog>
#include <QClipboard>
#include <qwt_plot_picker.h>
#include <mitkTractAnalyzer.h>
#include <mitkTbssImporter.h>
#include <mitkPlanarCircle.h>
#include <mitkPlanarFigureInteractor.h>
#include "vtkPoints.h"
#include <vtkCellArray.h>
#include <vtkPolyLine.h>
const std::string QmitkTractbasedSpatialStatisticsView::VIEW_ID = "org.mitk.views.tractbasedspatialstatistics";
using namespace berry;
QmitkTractbasedSpatialStatisticsView::QmitkTractbasedSpatialStatisticsView()
: QmitkFunctionality()
, m_Controls( 0 )
, m_MultiWidget( NULL )
{
}
QmitkTractbasedSpatialStatisticsView::~QmitkTractbasedSpatialStatisticsView()
{
}
void QmitkTractbasedSpatialStatisticsView::PerformChange()
{
m_Controls->m_RoiPlotWidget->ModifyPlot(m_Controls->m_Segments->value(), m_Controls->m_Average->isChecked());
}
void QmitkTractbasedSpatialStatisticsView::OnSelectionChanged(std::vector<mitk::DataNode*> nodes)
{
//datamanager selection changed
if (!this->IsActivated())
return;
// Check which datatypes are selected in the datamanager and enable/disable widgets accordingly
bool foundTbssRoi = false;
bool foundTbss = false;
bool found3dImage = false;
bool found4dImage = false;
bool foundFiberBundle = false;
bool foundStartRoi = false;
bool foundEndRoi = false;
mitk::TbssRoiImage* roiImage;
mitk::TbssImage* image;
mitk::Image* img;
mitk::FiberBundleX* fib;
mitk::PlanarFigure* start;
mitk::PlanarFigure* end;
m_CurrentStartRoi = NULL;
m_CurrentEndRoi = NULL;
for ( int i=0; i<nodes.size(); i++ )
{
// only look at interesting types
// check for valid data
mitk::BaseData* nodeData = nodes[i]->GetData();
if( nodeData )
{
if(QString("TbssRoiImage").compare(nodeData->GetNameOfClass())==0)
{
foundTbssRoi = true;
roiImage = static_cast<mitk::TbssRoiImage*>(nodeData);
}
else if (QString("TbssImage").compare(nodeData->GetNameOfClass())==0)
{
foundTbss = true;
image = static_cast<mitk::TbssImage*>(nodeData);
}
else if(QString("Image").compare(nodeData->GetNameOfClass())==0)
{
img = static_cast<mitk::Image*>(nodeData);
if(img->GetDimension() == 3)
{
found3dImage = true;
}
else if(img->GetDimension() == 4)
{
found4dImage = true;
}
}
else if (QString("FiberBundleX").compare(nodeData->GetNameOfClass())==0)
{
foundFiberBundle = true;
fib = static_cast<mitk::FiberBundleX*>(nodeData);
this->m_CurrentFiberNode = nodes[i];
}
if(QString("PlanarCircle").compare(nodeData->GetNameOfClass())==0)
{
if(!foundStartRoi)
{
start = dynamic_cast<mitk::PlanarFigure*>(nodeData);
this->m_CurrentStartRoi = nodes[i];
foundStartRoi = true;
}
else
{
end = dynamic_cast<mitk::PlanarFigure*>(nodeData);
this->m_CurrentEndRoi = nodes[i];
foundEndRoi = true;
}
}
}
}
this->m_Controls->m_CreateRoi->setEnabled(found3dImage);
this->m_Controls->m_ImportFsl->setEnabled(found4dImage);
if(foundTbss && foundTbssRoi)
{
this->Plot(image, roiImage);
}
else if(found3dImage && foundFiberBundle && foundStartRoi && foundEndRoi)
{
this->PlotFiberBundle(fib, img, start, end);
}
else if(found3dImage && foundFiberBundle)
{
this->PlotFiberBundle(fib, img);
}
else if(foundTbss && foundStartRoi && foundEndRoi && foundFiberBundle)
{
this->PlotFiber4D(image, fib, start, end);
}
if(found3dImage)
{
this->InitPointsets();
}
this->m_Controls->m_Cut->setEnabled(foundFiberBundle && foundStartRoi && foundEndRoi);
this->m_Controls->m_SegmentLabel->setEnabled(foundFiberBundle && foundStartRoi && foundEndRoi && (found3dImage || foundTbss));
this->m_Controls->m_Segments->setEnabled(foundFiberBundle && foundStartRoi && foundEndRoi && (found3dImage || foundTbss));
this->m_Controls->m_Average->setEnabled(foundFiberBundle && foundStartRoi && foundEndRoi && found3dImage);
}
void QmitkTractbasedSpatialStatisticsView::InitPointsets()
{
// Check if PointSetStart exsits, if not create it.
m_P1 = this->GetDefaultDataStorage()->GetNamedNode("PointSetNode");
if (m_PointSetNode)
{
//m_PointSetNode = dynamic_cast<mitk::PointSet*>(m_P1->GetData());
return;
}
if ((!m_P1) || (!m_PointSetNode))
{
// create new ones
m_PointSetNode = mitk::PointSet::New();
m_P1 = mitk::DataNode::New();
m_P1->SetData( m_PointSetNode );
m_P1->SetProperty( "name", mitk::StringProperty::New( "PointSet" ) );
m_P1->SetProperty( "opacity", mitk::FloatProperty::New( 1 ) );
m_P1->SetProperty( "helper object", mitk::BoolProperty::New(true) ); // CHANGE if wanted
m_P1->SetProperty( "pointsize", mitk::FloatProperty::New( 0.1 ) );
m_P1->SetColor( 1.0, 0.0, 0.0 );
this->GetDefaultDataStorage()->Add(m_P1);
m_Controls->m_PointWidget->SetPointSetNode(m_P1);
m_Controls->m_PointWidget->SetMultiWidget(GetActiveStdMultiWidget());
}
}
void QmitkTractbasedSpatialStatisticsView::CreateQtPartControl( QWidget *parent )
{
// build up qt view, unless already done
if ( !m_Controls )
{
// create GUI widgets from the Qt Designer's .ui file
m_Controls = new Ui::QmitkTractbasedSpatialStatisticsViewControls;
m_Controls->setupUi( parent );
this->CreateConnections();
}
// Table for the FSL TBSS import
m_GroupModel = new QmitkTbssTableModel();
m_Controls->m_GroupInfo->setModel(m_GroupModel);
}
void QmitkTractbasedSpatialStatisticsView::Activated()
{
QmitkFunctionality::Activated();
}
void QmitkTractbasedSpatialStatisticsView::Deactivated()
{
QmitkFunctionality::Deactivated();
}
void QmitkTractbasedSpatialStatisticsView::CreateConnections()
{
if ( m_Controls )
{
connect( (QObject*)(m_Controls->m_CreateRoi), SIGNAL(clicked()), this, SLOT(CreateRoi()) );
connect( (QObject*)(m_Controls->m_ImportFsl), SIGNAL(clicked()), this, SLOT(TbssImport()) );
connect( (QObject*)(m_Controls->m_AddGroup), SIGNAL(clicked()), this, SLOT(AddGroup()) );
connect( (QObject*)(m_Controls->m_RemoveGroup), SIGNAL(clicked()), this, SLOT(RemoveGroup()) );
connect( (QObject*)(m_Controls->m_Clipboard), SIGNAL(clicked()), this, SLOT(CopyToClipboard()) );
connect( m_Controls->m_RoiPlotWidget->m_PlotPicker, SIGNAL(selected(const QPointF&)), SLOT(Clicked(const QPointF&) ) );
connect( m_Controls->m_RoiPlotWidget->m_PlotPicker, SIGNAL(moved(const QPointF&)), SLOT(Clicked(const QPointF&) ) );
connect( (QObject*)(m_Controls->m_Cut), SIGNAL(clicked()), this, SLOT(Cut()) );
connect( (QObject*)(m_Controls->m_Average), SIGNAL(stateChanged(int)), this, SLOT(PerformChange()) );
connect( (QObject*)(m_Controls->m_Segments), SIGNAL(valueChanged(int)), this, SLOT(PerformChange()) );
}
}
void QmitkTractbasedSpatialStatisticsView::CopyToClipboard()
{
if(m_Controls->m_RoiPlotWidget->IsPlottingFiber())
{
// Working with fiber bundles
std::vector <std::vector<double> > profiles = m_Controls->m_RoiPlotWidget->GetIndividualProfiles();
QString clipboardText;
for (std::vector<std::vector<double> >::iterator it = profiles.begin(); it
!= profiles.end(); ++it)
{
for (std::vector<double>::iterator it2 = (*it).begin(); it2 !=
(*it).end(); ++it2)
{
clipboardText.append(QString("%1 \t").arg(*it2));
}
clipboardText.append(QString("\n"));
}
if(m_Controls->m_Average->isChecked())
{
std::vector<double> averages = m_Controls->m_RoiPlotWidget->GetAverageProfile();
clipboardText.append(QString("\nAverage\n"));
for (std::vector<double>::iterator it2 = averages.begin(); it2 !=
averages.end(); ++it2)
{
clipboardText.append(QString("%1 \t").arg(*it2));
}
}
QApplication::clipboard()->setText(clipboardText, QClipboard::Clipboard);
}
else{
// Working with TBSS Data
if(m_Controls->m_Average->isChecked())
{
std::vector<std::vector<double> > vals = m_Controls->m_RoiPlotWidget->GetVals();
QString clipboardText;
for (std::vector<std::vector<double> >::iterator it = vals.begin(); it
!= vals.end(); ++it)
{
for (std::vector<double>::iterator it2 = (*it).begin(); it2 !=
(*it).end(); ++it2)
{
clipboardText.append(QString("%1 \t").arg(*it2));
double d = *it2;
std::cout << d <<std::endl;
}
clipboardText.append(QString("\n"));
}
QApplication::clipboard()->setText(clipboardText, QClipboard::Clipboard);
}
else
{
std::vector<std::vector<double> > vals = m_Controls->m_RoiPlotWidget->GetIndividualProfiles();
QString clipboardText;
for (std::vector<std::vector<double> >::iterator it = vals.begin(); it
!= vals.end(); ++it)
{
for (std::vector<double>::iterator it2 = (*it).begin(); it2 !=
(*it).end(); ++it2)
{
clipboardText.append(QString("%1 \t").arg(*it2));
double d = *it2;
std::cout << d <<std::endl;
}
clipboardText.append(QString("\n"));
}
QApplication::clipboard()->setText(clipboardText, QClipboard::Clipboard);
}
}
}
void QmitkTractbasedSpatialStatisticsView::RemoveGroup()
{
QTableView *temp = static_cast<QTableView*>(m_Controls->m_GroupInfo);
QItemSelectionModel *selectionModel = temp->selectionModel();
QModelIndexList indices = selectionModel->selectedRows();
QModelIndex index;
foreach(index, indices)
{
int row = index.row();
m_GroupModel->removeRows(row, 1, QModelIndex());
}
}
void QmitkTractbasedSpatialStatisticsView::AddGroup()
{
QString group("Group");
int number = 0;
QPair<QString, int> pair(group, number);
QList< QPair<QString, int> >list = m_GroupModel->getList();
if(!list.contains(pair))
{
m_GroupModel->insertRows(0, 1, QModelIndex());
QModelIndex index = m_GroupModel->index(0, 0, QModelIndex());
m_GroupModel->setData(index, group, Qt::EditRole);
index = m_GroupModel->index(0, 1, QModelIndex());
m_GroupModel->setData(index, number, Qt::EditRole);
}
}
void QmitkTractbasedSpatialStatisticsView::TbssImport()
{
// Read groups from the interface
mitk::TbssImporter::Pointer importer = mitk::TbssImporter::New();
QList< QPair<QString, int> >list = m_GroupModel->getList();
if(list.size() == 0)
{
QMessageBox msgBox;
msgBox.setText("No study group information has been set yet.");
msgBox.exec();
return;
}
std::vector < std::pair<std::string, int> > groups;
for(int i=0; i<list.size(); i++)
{
QPair<QString, int> pair = list.at(i);
std::string s = pair.first.toStdString();
int n = pair.second;
std::pair<std::string, int> p;
p.first = s;
p.second = n;
groups.push_back(p);
}
importer->SetGroupInfo(groups);
std::string minfo = m_Controls->m_MeasurementInfo->text().toStdString();
importer->SetMeasurementInfo(minfo);
std::string name = "";
std::vector<mitk::DataNode*> nodes = this->GetDataManagerSelection();
for ( int i=0; i<nodes.size(); i++ )
{
if(QString("Image").compare(nodes[i]->GetData()->GetNameOfClass())==0)
{
mitk::Image* img = static_cast<mitk::Image*>(nodes[i]->GetData());
if(img->GetDimension() == 4)
{
importer->SetImportVolume(img);
name = nodes[i]->GetName();
}
}
}
mitk::TbssImage::Pointer tbssImage;
tbssImage = importer->Import();
name += "_tbss";
AddTbssToDataStorage(tbssImage, name);
}
void QmitkTractbasedSpatialStatisticsView::AddTbssToDataStorage(mitk::Image* image, std::string name)
{
mitk::LevelWindow levelwindow;
levelwindow.SetAuto( image );
mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New();
levWinProp->SetLevelWindow( levelwindow );
mitk::DataNode::Pointer result = mitk::DataNode::New();
result->SetProperty( "name", mitk::StringProperty::New(name) );
result->SetData( image );
result->SetProperty( "levelwindow", levWinProp );
// add new image to data storage and set as active to ease further processing
GetDefaultDataStorage()->Add( result );
// show the results
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkTractbasedSpatialStatisticsView::Clicked(const QPointF& pos)
{
int index = (int)pos.x();
if(m_Roi.size() > 0 && m_CurrentGeometry != NULL && !m_Controls->m_RoiPlotWidget->IsPlottingFiber() )
{
index = std::min( (int)m_Roi.size()-1, std::max(0, index) );
itk::Index<3> ix = m_Roi.at(index);
mitk::Vector3D i;
i[0] = ix[0];
i[1] = ix[1];
i[2] = ix[2];
mitk::Vector3D w;
m_CurrentGeometry->IndexToWorld(i, w);
mitk::Point3D origin = m_CurrentGeometry->GetOrigin();
mitk::Point3D p;
p[0] = w[0] + origin[0];
p[1] = w[1] + origin[1];
p[2] = w[2] + origin[2];
m_MultiWidget->MoveCrossToPosition(p);
m_Controls->m_RoiPlotWidget->drawBar(index);
}
else if(m_Controls->m_RoiPlotWidget->IsPlottingFiber() )
{
mitk::Point3D point = m_Controls->m_RoiPlotWidget->GetPositionInWorld(index);
m_MultiWidget->MoveCrossToPosition(point);
}
}
void QmitkTractbasedSpatialStatisticsView::Cut()
{
mitk::BaseData* fibData = m_CurrentFiberNode->GetData();
mitk::FiberBundleX* fib = static_cast<mitk::FiberBundleX*>(fibData);
mitk::BaseData* startData = m_CurrentStartRoi->GetData();
mitk::PlanarFigure* startRoi = static_cast<mitk::PlanarFigure*>(startData);
- mitk::PlaneGeometry* startGeometry2D = dynamic_cast<mitk::PlaneGeometry*>( const_cast<mitk::Geometry2D*>(startRoi->GetGeometry2D()) );
+ mitk::PlaneGeometry* startGeometry2D = const_cast<mitk::PlaneGeometry*>(startRoi->GetPlaneGeometry());
mitk::BaseData* endData = m_CurrentEndRoi->GetData();
mitk::PlanarFigure* endRoi = static_cast<mitk::PlanarFigure*>(endData);
- mitk::PlaneGeometry* endGeometry2D = dynamic_cast<mitk::PlaneGeometry*>( const_cast<mitk::Geometry2D*>(endRoi->GetGeometry2D()) );
+ mitk::PlaneGeometry* endGeometry2D = const_cast<mitk::PlaneGeometry*>(endRoi->GetPlaneGeometry());
mitk::Point3D startCenter = startRoi->GetWorldControlPoint(0); //center Point of start roi
mitk::Point3D endCenter = endRoi->GetWorldControlPoint(0); //center Point of end roi
mitk::FiberBundleX::Pointer inStart = fib->ExtractFiberSubset(startRoi);
mitk::FiberBundleX::Pointer inBoth = inStart->ExtractFiberSubset(endRoi);
int num = inBoth->GetNumFibers();
vtkSmartPointer<vtkPolyData> fiberPolyData = inBoth->GetFiberPolyData();
vtkCellArray* lines = fiberPolyData->GetLines();
lines->InitTraversal();
// initialize new vtk polydata
vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
vtkSmartPointer<vtkCellArray> cells = vtkSmartPointer<vtkCellArray>::New();
int pointIndex=0;
// find start and endpoint
for( int fiberID( 0 ); fiberID < num; fiberID++ )
{
vtkIdType numPointsInCell(0);
vtkIdType* pointsInCell(NULL);
lines->GetNextCell ( numPointsInCell, pointsInCell );
int startId = 0;
int endId = 0;
float minDistStart = std::numeric_limits<float>::max();
float minDistEnd = std::numeric_limits<float>::max();
vtkSmartPointer<vtkPolyLine> polyLine = vtkSmartPointer<vtkPolyLine>::New();
int lineIndex=0;
for( int pointInCellID( 0 ); pointInCellID < numPointsInCell ; pointInCellID++)
{
double *p = fiberPolyData->GetPoint( pointsInCell[ pointInCellID ] );
mitk::Point3D point;
point[0] = p[0];
point[1] = p[1];
point[2] = p[2];
float distanceToStart = point.EuclideanDistanceTo(startCenter);
float distanceToEnd = point.EuclideanDistanceTo(endCenter);
if(distanceToStart < minDistStart)
{
minDistStart = distanceToStart;
startId = pointInCellID;
}
if(distanceToEnd < minDistEnd)
{
minDistEnd = distanceToEnd;
endId = pointInCellID;
}
}
/* We found the start and end points of of the part that should be plottet for
the current fiber. now we need to plot them. If the endId is smaller than the startId the plot order
must be reversed*/
if(startId < endId)
{
double *p = fiberPolyData->GetPoint( pointsInCell[ startId ] );
mitk::Vector3D p0;
p0[0] = p[0];
p0[1] = p[1];
p0[2] = p[2];
p = fiberPolyData->GetPoint( pointsInCell[ startId+1 ] );
mitk::Vector3D p1;
p1[0] = p[0];
p1[1] = p[1];
p1[2] = p[2];
// Check if p and p2 are both on the same side of the plane
mitk::Vector3D normal = startGeometry2D->GetNormal();
mitk::Point3D pStart;
pStart[0] = p0[0];
pStart[1] = p0[1];
pStart[2] = p0[2];
bool startOnPositive = startGeometry2D->IsAbove(pStart);
mitk::Point3D pSecond;
pSecond[0] = p1[0];
pSecond[1] = p1[1];
pSecond[2] = p1[2];
bool secondOnPositive = startGeometry2D->IsAbove(pSecond);
// Calculate intersection with the plane
mitk::Vector3D onPlane;
onPlane[0] = startCenter[0];
onPlane[1] = startCenter[1];
onPlane[2] = startCenter[2];
if(! (secondOnPositive ^ startOnPositive) )
{
/* startId and startId+1 lie on the same side of the plane, so we need
need startId-1 to calculate the intersection with the planar figure*/
p = fiberPolyData->GetPoint( pointsInCell[ startId-1 ] );
p1[0] = p[0];
p1[1] = p[1];
p1[2] = p[2];
}
double d = ( (onPlane-p0)*normal) / ( (p0-p1) * normal );
mitk::Vector3D newPoint = (p0-p1);
newPoint[0] = d*newPoint[0] + p0[0];
newPoint[1] = d*newPoint[1] + p0[1];
newPoint[2] = d*newPoint[2] + p0[2];
double insertPoint[3];
insertPoint[0] = newPoint[0];
insertPoint[1] = newPoint[1];
insertPoint[2] = newPoint[2];
// First insert the intersection with the start roi
points->InsertNextPoint(insertPoint);
polyLine->GetPointIds()->InsertId(lineIndex,pointIndex);
lineIndex++;
pointIndex++;
if(! (secondOnPositive ^ startOnPositive) )
{
/* StartId and startId+1 lie on the same side of the plane
so startId is also part of the ROI*/
double *start = fiberPolyData->GetPoint( pointsInCell[startId] );
points->InsertNextPoint(start);
polyLine->GetPointIds()->InsertId(lineIndex,pointIndex);
lineIndex++;
pointIndex++;
}
// Insert the rest up and to including endId-1
for( int pointInCellID( startId+1 ); pointInCellID < endId ; pointInCellID++)
{
// create new polyline for new polydata
double *p = fiberPolyData->GetPoint( pointsInCell[ pointInCellID ] );
points->InsertNextPoint(p);
// add point to line
polyLine->GetPointIds()->InsertId(lineIndex,pointIndex);
lineIndex++;
pointIndex++;
}
/* endId must be included if endId and endId-1 lie on the same side of the
plane defined by endRoi*/
p = fiberPolyData->GetPoint( pointsInCell[ endId ] );
p0[0] = p[0]; p0[1] = p[1]; p0[2] = p[2];
p = fiberPolyData->GetPoint( pointsInCell[ endId-1 ] );
p1[0] = p[0]; p1[1] = p[1]; p1[2] = p[2];
mitk::Point3D pLast;
pLast[0] = p0[0]; pLast[1] = p0[1]; pLast[2] = p0[2];
mitk::Point3D pBeforeLast;
pBeforeLast[0] = p1[0]; pBeforeLast[1] = p1[1]; pBeforeLast[2] = p1[2];
bool lastOnPositive = endGeometry2D->IsAbove(pLast);
bool secondLastOnPositive = endGeometry2D->IsAbove(pBeforeLast);
normal = endGeometry2D->GetNormal();
onPlane[0] = endCenter[0];
onPlane[1] = endCenter[1];
onPlane[2] = endCenter[2];
if(! (lastOnPositive ^ secondLastOnPositive) )
{
/* endId and endId-1 lie on the same side of the plane, so we need
need endId+1 to calculate the intersection with the planar figure.
this should exist since we know that the fiber crosses the planar figure
endId is part of the roi so can also be included here*/
p = fiberPolyData->GetPoint( pointsInCell[ endId+1 ] );
p1[0] = p[0];
p1[1] = p[1];
p1[2] = p[2];
double *end = fiberPolyData->GetPoint( pointsInCell[endId] );
points->InsertNextPoint(end);
polyLine->GetPointIds()->InsertId(lineIndex,pointIndex);
lineIndex++;
pointIndex++;
}
d = ( (onPlane-p0)*normal) / ( (p0-p1) * normal );
newPoint = (p0-p1);
newPoint[0] = d*newPoint[0] + p0[0];
newPoint[1] = d*newPoint[1] + p0[1];
newPoint[2] = d*newPoint[2] + p0[2];
insertPoint[0] = newPoint[0];
insertPoint[1] = newPoint[1];
insertPoint[2] = newPoint[2];
//Insert the Last Point (intersection with the end roi)
points->InsertNextPoint(insertPoint);
polyLine->GetPointIds()->InsertId(lineIndex,pointIndex);
lineIndex++;
pointIndex++;
}
// Need to reverse walking order
else{
double *p = fiberPolyData->GetPoint( pointsInCell[ startId ] );
mitk::Vector3D p0;
p0[0] = p[0];
p0[1] = p[1];
p0[2] = p[2];
p = fiberPolyData->GetPoint( pointsInCell[ startId-1 ] );
mitk::Vector3D p1;
p1[0] = p[0];
p1[1] = p[1];
p1[2] = p[2];
// Check if p and p2 are both on the same side of the plane
mitk::Vector3D normal = startGeometry2D->GetNormal();
mitk::Point3D pStart;
pStart[0] = p0[0];
pStart[1] = p0[1];
pStart[2] = p0[2];
bool startOnPositive = startGeometry2D->IsAbove(pStart);
mitk::Point3D pSecond;
pSecond[0] = p1[0];
pSecond[1] = p1[1];
pSecond[2] = p1[2];
bool secondOnPositive = startGeometry2D->IsAbove(pSecond);
// Calculate intersection with the plane
mitk::Vector3D onPlane;
onPlane[0] = startCenter[0];
onPlane[1] = startCenter[1];
onPlane[2] = startCenter[2];
if(! (secondOnPositive ^ startOnPositive) )
{
/* startId and startId-1 lie on the same side of the plane, so we need
need startId+1 to calculate the intersection with the planar figure*/
p = fiberPolyData->GetPoint( pointsInCell[ startId+1 ] );
p1[0] = p[0];
p1[1] = p[1];
p1[2] = p[2];
}
double d = ( (onPlane-p0)*normal) / ( (p0-p1) * normal );
mitk::Vector3D newPoint = (p0-p1);
newPoint[0] = d*newPoint[0] + p0[0];
newPoint[1] = d*newPoint[1] + p0[1];
newPoint[2] = d*newPoint[2] + p0[2];
double insertPoint[3];
insertPoint[0] = newPoint[0];
insertPoint[1] = newPoint[1];
insertPoint[2] = newPoint[2];
// First insert the intersection with the start roi
points->InsertNextPoint(insertPoint);
polyLine->GetPointIds()->InsertId(lineIndex,pointIndex);
lineIndex++;
pointIndex++;
if(! (secondOnPositive ^ startOnPositive) )
{
/* startId and startId-1 lie on the same side of the plane
so endId is also part of the ROI*/
double *start = fiberPolyData->GetPoint( pointsInCell[startId] );
points->InsertNextPoint(start);
polyLine->GetPointIds()->InsertId(lineIndex,pointIndex);
lineIndex++;
pointIndex++;
}
// Insert the rest up and to including endId-1
for( int pointInCellID( startId-1 ); pointInCellID > endId ; pointInCellID--)
{
// create new polyline for new polydata
double *p = fiberPolyData->GetPoint( pointsInCell[ pointInCellID ] );
points->InsertNextPoint(p);
// add point to line
polyLine->GetPointIds()->InsertId(lineIndex,pointIndex);
lineIndex++;
pointIndex++;
}
/* startId must be included if startId and startId+ lie on the same side of the
plane defined by endRoi*/
p = fiberPolyData->GetPoint( pointsInCell[ endId ] );
p0[0] = p[0];
p0[1] = p[1];
p0[2] = p[2];
p = fiberPolyData->GetPoint( pointsInCell[ endId+1 ] );
p1[0] = p[0];
p1[1] = p[1];
p1[2] = p[2];
mitk::Point3D pLast;
pLast[0] = p0[0];
pLast[1] = p0[1];
pLast[2] = p0[2];
bool lastOnPositive = endGeometry2D->IsAbove(pLast);
mitk::Point3D pBeforeLast;
pBeforeLast[0] = p1[0];
pBeforeLast[1] = p1[1];
pBeforeLast[2] = p1[2];
bool secondLastOnPositive = endGeometry2D->IsAbove(pBeforeLast);
onPlane[0] = endCenter[0];
onPlane[1] = endCenter[1];
onPlane[2] = endCenter[2];
if(! (lastOnPositive ^ secondLastOnPositive) )
{
/* endId and endId+1 lie on the same side of the plane, so we need
need endId-1 to calculate the intersection with the planar figure.
this should exist since we know that the fiber crosses the planar figure*/
p = fiberPolyData->GetPoint( pointsInCell[ endId-1 ] );
p1[0] = p[0];
p1[1] = p[1];
p1[2] = p[2];
/* endId and endId+1 lie on the same side of the plane
so startId is also part of the ROI*/
double *end = fiberPolyData->GetPoint( pointsInCell[endId] );
points->InsertNextPoint(end);
polyLine->GetPointIds()->InsertId(lineIndex,pointIndex);
lineIndex++;
pointIndex++;
}
d = ( (onPlane-p0)*normal) / ( (p0-p1) * normal );
newPoint = (p0-p1);
newPoint[0] = d*newPoint[0] + p0[0];
newPoint[1] = d*newPoint[1] + p0[1];
newPoint[2] = d*newPoint[2] + p0[2];
insertPoint[0] = newPoint[0];
insertPoint[1] = newPoint[1];
insertPoint[2] = newPoint[2];
//Insert the Last Point (intersection with the end roi)
points->InsertNextPoint(insertPoint);
polyLine->GetPointIds()->InsertId(lineIndex,pointIndex);
lineIndex++;
pointIndex++;
}
// add polyline to vtk cell array
cells->InsertNextCell(polyLine);
}
// Add the points to the dataset
polyData->SetPoints(points);
// Add the lines to the dataset
polyData->SetLines(cells);
mitk::FiberBundleX::Pointer cutBundle = mitk::FiberBundleX::New(polyData);
mitk::DataNode::Pointer cutNode = mitk::DataNode::New();
cutNode->SetData(cutBundle);
std::string name = "fiberCut";
cutNode->SetName(name);
GetDataStorage()->Add(cutNode);
}
void QmitkTractbasedSpatialStatisticsView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget)
{
m_MultiWidget = &stdMultiWidget;
}
void QmitkTractbasedSpatialStatisticsView::StdMultiWidgetNotAvailable()
{
m_MultiWidget = NULL;
}
void QmitkTractbasedSpatialStatisticsView::CreateRoi()
{
bool ok;
double threshold = QInputDialog::getDouble(m_Controls->m_CreateRoi, tr("Set an FA threshold"),
tr("Threshold:"), 0.2, 0.0, 1.0, 2, &ok);
if(!ok)
return;
mitk::Image::Pointer image;
std::vector<mitk::DataNode*> nodes = this->GetDataManagerSelection();
for ( int i=0; i<nodes.size(); i++ )
{
if(QString("Image").compare(nodes[i]->GetData()->GetNameOfClass())==0)
{
mitk::Image* img = static_cast<mitk::Image*>(nodes[i]->GetData());
if(img->GetDimension() == 3)
{
image = img;
}
}
}
if(image.IsNull())
{
return;
}
mitk::TractAnalyzer analyzer;
analyzer.SetInputImage(image);
analyzer.SetThreshold(threshold);
m_PointSetNode = this->m_Controls->m_PointWidget->GetPointSet();
// Set Pointset to analyzer
analyzer.SetPointSet(m_PointSetNode);
// Run Analyzer
try
{
analyzer.MakeRoi();
}
catch (const mitk::Exception& e)
{
QMessageBox msgBox;
msgBox.setText(QString::fromStdString(e.what()));
msgBox.exec();
}
// Obtain tbss roi image from analyzer
mitk::TbssRoiImage::Pointer tbssRoi = analyzer.GetRoiImage();
tbssRoi->SetStructure(m_Controls->m_Structure->text().toStdString());
// get path description and set to interface
std::string pathDescription = analyzer.GetPathDescription();
m_Controls->m_PathTextEdit->setPlainText(QString(pathDescription.c_str()));
// Add roi image to datastorage
AddTbssToDataStorage(tbssRoi, m_Controls->m_RoiName->text().toStdString());
}
void QmitkTractbasedSpatialStatisticsView::PlotFiber4D(mitk::TbssImage* image,
mitk::FiberBundleX* fib,
mitk::PlanarFigure* startRoi,
mitk::PlanarFigure* endRoi)
{
if(m_Controls->m_TabWidget->currentWidget() == m_Controls->m_MeasureTAB)
{
m_CurrentGeometry = image->GetGeometry();
m_Controls->m_RoiPlotWidget->SetGroups(image->GetGroupInfo());
m_Controls->m_RoiPlotWidget->SetProjections(image->GetImage());
m_Controls->m_RoiPlotWidget->SetMeasure( image->GetMeasurementInfo() );
m_Controls->m_RoiPlotWidget->PlotFiber4D(image, fib, startRoi, endRoi, m_Controls->m_Segments->value());
}
}
void QmitkTractbasedSpatialStatisticsView:: PlotFiberBundle(mitk::FiberBundleX *fib, mitk::Image* img,
mitk::PlanarFigure* startRoi, mitk::PlanarFigure* endRoi)
{
bool avg = m_Controls->m_Average->isChecked();
int segments = m_Controls->m_Segments->value();
m_Controls->m_RoiPlotWidget->PlotFiberBetweenRois(fib, img, startRoi ,endRoi, avg, segments);
m_Controls->m_RoiPlotWidget->SetPlottingFiber(true);
mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll();
}
void QmitkTractbasedSpatialStatisticsView::Plot(mitk::TbssImage* image, mitk::TbssRoiImage* roiImage)
{
if(m_Controls->m_TabWidget->currentWidget() == m_Controls->m_MeasureTAB)
{
std::vector< itk::Index<3> > roi = roiImage->GetRoi();
m_Roi = roi;
m_CurrentGeometry = image->GetGeometry();
std::string structure = roiImage->GetStructure();
m_Controls->m_RoiPlotWidget->SetGroups(image->GetGroupInfo());
m_Controls->m_RoiPlotWidget->SetProjections(image->GetImage());
m_Controls->m_RoiPlotWidget->SetRoi(roi);
m_Controls->m_RoiPlotWidget->SetStructure(structure);
m_Controls->m_RoiPlotWidget->SetMeasure( image->GetMeasurementInfo() );
m_Controls->m_RoiPlotWidget->DrawProfiles();
}
m_Controls->m_RoiPlotWidget->SetPlottingFiber(false);
}
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/mitkPluginActivator.cpp
index 36f711d20d..fe487b9901 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/mitkPluginActivator.cpp
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/mitkPluginActivator.cpp
@@ -1,104 +1,106 @@
/*===================================================================
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 "mitkPluginActivator.h"
#include <QtPlugin>
#include "src/internal/Perspectives/QmitkDiffusionImagingAppPerspective.h"
#include "src/internal/Perspectives/QmitkDIAppIVIMPerspective.h"
#include "src/internal/Perspectives/QmitkDIAppSyntheticDataGenerationPerspective.h"
#include "src/internal/Perspectives/QmitkGibbsTractographyPerspective.h"
#include "src/internal/Perspectives/QmitkStreamlineTractographyPerspective.h"
#include "src/internal/Perspectives/QmitkProbabilisticTractographyPerspective.h"
#include "src/internal/Perspectives/QmitkFiberProcessingPerspective.h"
#include "src/internal/Perspectives/QmitkDiffusionDefaultPerspective.h"
#include "src/internal/QmitkQBallReconstructionView.h"
#include "src/internal/QmitkPreprocessingView.h"
#include "src/internal/QmitkDiffusionDicomImportView.h"
#include "src/internal/QmitkDiffusionQuantificationView.h"
#include "src/internal/QmitkTensorReconstructionView.h"
#include "src/internal/QmitkControlVisualizationPropertiesView.h"
#include "src/internal/QmitkODFDetailsView.h"
#include "src/internal/QmitkGibbsTrackingView.h"
#include "src/internal/QmitkStochasticFiberTrackingView.h"
#include "src/internal/QmitkFiberProcessingView.h"
#include "src/internal/QmitkPartialVolumeAnalysisView.h"
#include "src/internal/QmitkIVIMView.h"
#include "src/internal/QmitkTractbasedSpatialStatisticsView.h"
#include "src/internal/QmitkTbssSkeletonizationView.h"
#include "src/internal/QmitkStreamlineTrackingView.h"
#include "src/internal/Connectomics/QmitkConnectomicsDataView.h"
#include "src/internal/Connectomics/QmitkConnectomicsNetworkOperationsView.h"
#include "src/internal/Connectomics/QmitkConnectomicsStatisticsView.h"
#include "src/internal/Connectomics/QmitkRandomParcellationView.h"
#include "src/internal/QmitkOdfMaximaExtractionView.h"
#include "src/internal/QmitkFiberfoxView.h"
#include "src/internal/QmitkFiberExtractionView.h"
#include "src/internal/QmitkFieldmapGeneratorView.h"
#include "src/internal/QmitkDiffusionRegistrationView.h"
#include "src/internal/QmitkDenoisingView.h"
namespace mitk {
void PluginActivator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(QmitkDiffusionImagingAppPerspective, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkGibbsTractographyPerspective, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkStreamlineTractographyPerspective, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkProbabilisticTractographyPerspective, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkDIAppSyntheticDataGenerationPerspective, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkDIAppIVIMPerspective, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkFiberProcessingPerspective, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkDiffusionDefaultPerspective, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkQBallReconstructionView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkPreprocessingView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkDiffusionDicomImport, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkDiffusionQuantificationView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkTensorReconstructionView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkControlVisualizationPropertiesView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkODFDetailsView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkGibbsTrackingView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkStochasticFiberTrackingView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkFiberProcessingView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkPartialVolumeAnalysisView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkIVIMView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkTractbasedSpatialStatisticsView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkTbssSkeletonizationView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkConnectomicsDataView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkConnectomicsNetworkOperationsView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkConnectomicsStatisticsView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkStreamlineTrackingView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkOdfMaximaExtractionView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkFiberfoxView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkFiberExtractionView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkFieldmapGeneratorView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkDiffusionRegistrationView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkDenoisingView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkRandomParcellationView, context)
}
void PluginActivator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_diffusionimaging, mitk::PluginActivator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_diffusionimaging, mitk::PluginActivator)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/mitkPluginActivator.h
index 489bd853ca..c99ace3fa1 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/mitkPluginActivator.h
+++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/mitkPluginActivator.h
@@ -1,40 +1,43 @@
/*===================================================================
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 MITKPLUGINACTIVATOR_H
#define MITKPLUGINACTIVATOR_H
#include <ctkPluginActivator.h>
#include <mitkExportMacros.h>
namespace mitk {
class MITK_LOCAL PluginActivator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_diffusionimaging")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
}; // PluginActivator
}
#endif // MITKPLUGINACTIVATOR_H
diff --git a/Plugins/org.mitk.gui.qt.diffusionimagingapp/CMakeLists.txt b/Plugins/org.mitk.gui.qt.diffusionimagingapp/CMakeLists.txt
index d2a1d8b798..8884b6c47a 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimagingapp/CMakeLists.txt
+++ b/Plugins/org.mitk.gui.qt.diffusionimagingapp/CMakeLists.txt
@@ -1,14 +1,14 @@
# The project name must correspond to the directory name of your plug-in
# and must not contain periods.
project(org_mitk_gui_qt_diffusionimagingapp)
MACRO_CREATE_MITK_CTK_PLUGIN(
EXPORT_DIRECTIVE DIFFUSIONIMAGING_APP_EXPORT
EXPORTED_INCLUDE_SUFFIXES src
MODULE_DEPENDS MitkQtWidgets MitkSceneSerialization
- PACKAGE_DEPENDS Qt4|QtWebKit
+ PACKAGE_DEPENDS Qt4|QtWebKit Qt5|WebKitWidgets
)
if(QT_QTWEBKIT_FOUND)
add_definitions(-DQT_WEBKIT)
endif(QT_QTWEBKIT_FOUND)
diff --git a/Plugins/org.mitk.gui.qt.diffusionimagingapp/documentation/UserManual/QmitkDiffusionImagingAppUserManual.dox b/Plugins/org.mitk.gui.qt.diffusionimagingapp/documentation/UserManual/QmitkDiffusionImagingAppUserManual.dox
index 9f679c8296..dad1bdf580 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimagingapp/documentation/UserManual/QmitkDiffusionImagingAppUserManual.dox
+++ b/Plugins/org.mitk.gui.qt.diffusionimagingapp/documentation/UserManual/QmitkDiffusionImagingAppUserManual.dox
@@ -1,10 +1,10 @@
/**
\page org_mitk_gui_qt_diffusionimagingapp Using The Diffusion Imaging Application
\section QMitkDiffusionApplicationManualOverview What is the Diffusion Imaging Application
-The Diffusion Imaging Application contains selected views for the analysis of images of the human brain. These encompass the views developed by the <a href="http://www.dkfz.de/en/mbi/projects/neuroimaging.html">Neuroimaging Group</a> of the Division Medical and Biological Informatics as well as basic image processing views such as segmentation and volumevisualization.
+The Diffusion Imaging Application contains selected views for the analysis of images of the human brain. These encompass the views developed by the <a href="http://www.dkfz.de/en/mbi/research/MIC/index.html">Medical Image Computing Group</a> of the Division Medical and Biological Informatics as well as basic image processing views such as segmentation and volumevisualization.
For a basic guide to MITK see \ref MITKUserManualPage .
*/
diff --git a/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/internal/QmitkDiffusionApplicationPlugin.cpp b/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/internal/QmitkDiffusionApplicationPlugin.cpp
index d3dd44ef81..33906841dd 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/internal/QmitkDiffusionApplicationPlugin.cpp
+++ b/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/internal/QmitkDiffusionApplicationPlugin.cpp
@@ -1,88 +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 "QmitkDiffusionApplicationPlugin.h"
#include "src/QmitkDiffusionImagingAppApplication.h"
#include "src/internal/Perspectives/QmitkWelcomePerspective.h"
#include "src/internal/QmitkDiffusionImagingAppIntroPart.h"
#include <mitkVersion.h>
#include <mitkLogMacros.h>
#include <service/cm/ctkConfigurationAdmin.h>
#include <service/cm/ctkConfiguration.h>
#include <QFileInfo>
#include <QDateTime>
#include <QtPlugin>
QmitkDiffusionApplicationPlugin* QmitkDiffusionApplicationPlugin::inst = 0;
QmitkDiffusionApplicationPlugin::QmitkDiffusionApplicationPlugin()
{
inst = this;
}
QmitkDiffusionApplicationPlugin::~QmitkDiffusionApplicationPlugin()
{
}
QmitkDiffusionApplicationPlugin* QmitkDiffusionApplicationPlugin::GetDefault()
{
return inst;
}
void QmitkDiffusionApplicationPlugin::start(ctkPluginContext* context)
{
berry::AbstractUICTKPlugin::start(context);
this->context = context;
BERRY_REGISTER_EXTENSION_CLASS(QmitkDiffusionImagingAppApplication, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkDiffusionImagingAppIntroPart, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkWelcomePerspective, context)
ctkServiceReference cmRef = context->getServiceReference<ctkConfigurationAdmin>();
ctkConfigurationAdmin* configAdmin = 0;
if (cmRef)
{
configAdmin = context->getService<ctkConfigurationAdmin>(cmRef);
}
// Use the CTK Configuration Admin service to configure the BlueBerry help system
if (configAdmin)
{
ctkConfigurationPtr conf = configAdmin->getConfiguration("org.blueberry.services.help", QString());
ctkDictionary helpProps;
helpProps.insert("homePage", "qthelp://org.mitk.gui.qt.diffusionimagingapp/bundle/index.html");
conf->update(helpProps);
context->ungetService(cmRef);
}
else
{
MITK_WARN << "Configuration Admin service unavailable, cannot set home page url.";
}
}
ctkPluginContext* QmitkDiffusionApplicationPlugin::GetPluginContext() const
{
return context;
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_diffusionimagingapp, QmitkDiffusionApplicationPlugin)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_diffusionimagingapp, QmitkDiffusionApplicationPlugin)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/internal/QmitkDiffusionApplicationPlugin.h b/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/internal/QmitkDiffusionApplicationPlugin.h
index bd57933803..9b8e79ef15 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/internal/QmitkDiffusionApplicationPlugin.h
+++ b/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/internal/QmitkDiffusionApplicationPlugin.h
@@ -1,52 +1,55 @@
/*===================================================================
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 QMITKDIFFUSIONAPPLICATIONPLUGIN_H_
#define QMITKDIFFUSIONAPPLICATIONPLUGIN_H_
#include <berryAbstractUICTKPlugin.h>
#include <QString>
#include <berryQCHPluginListener.h>
class QmitkDiffusionApplicationPlugin : public QObject, public berry::AbstractUICTKPlugin
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_diffusionimagingapp")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
QmitkDiffusionApplicationPlugin();
~QmitkDiffusionApplicationPlugin();
static QmitkDiffusionApplicationPlugin* GetDefault();
ctkPluginContext* GetPluginContext() const;
void start(ctkPluginContext*);
QString GetQtHelpCollectionFile() const;
private:
static QmitkDiffusionApplicationPlugin* inst;
ctkPluginContext* context;
};
#endif /* QMITKDIFFUSIONAPPLICATIONPLUGIN_H_ */
diff --git a/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/internal/QmitkDiffusionImagingAppIntroPart.cpp b/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/internal/QmitkDiffusionImagingAppIntroPart.cpp
index 1e2a24b0bb..e4afa76043 100644
--- a/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/internal/QmitkDiffusionImagingAppIntroPart.cpp
+++ b/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/internal/QmitkDiffusionImagingAppIntroPart.cpp
@@ -1,204 +1,215 @@
/*===================================================================
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 "QmitkDiffusionImagingAppIntroPart.h"
#include "mitkNodePredicateDataType.h"
#include <berryIWorkbenchWindow.h>
#include <berryIWorkbench.h>
#include <berryIWorkbenchPage.h>
#include <berryIPerspectiveRegistry.h>
#include <berryWorkbenchPreferenceConstants.h>
#include <berryIPreferences.h>
#include <berryIEditorReference.h>
#include <berryIEditorInput.h>
#include <mitkIDataStorageService.h>
#include <mitkDataStorageEditorInput.h>
#include <mitkLogMacros.h>
#include <QLabel>
#include <QMessageBox>
#include <QtCore/qconfig.h>
#include <QWebView>
#include <QWebPage>
+#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
+# include <QUrlQuery>
+#endif
#include <QString>
#include <QStringList>
#include <QRegExp>
#include <QChar>
#include <QByteArray>
#include <QDesktopServices>
#include "QmitkDiffusionApplicationPlugin.h"
#include "mitkDataStorageEditorInput.h"
#include <string>
#include "mitkBaseDataIOFactory.h"
#include "mitkSceneIO.h"
#include "mitkProgressBar.h"
#include "mitkDataNodeFactory.h"
#include "mitkNodePredicateNot.h"
#include "mitkNodePredicateProperty.h"
QmitkDiffusionImagingAppIntroPart::QmitkDiffusionImagingAppIntroPart()
: m_Controls(NULL)
{
berry::IPreferences::Pointer workbenchPrefs = QmitkDiffusionApplicationPlugin::GetDefault()->GetPreferencesService()->GetSystemPreferences();
workbenchPrefs->PutBool(berry::WorkbenchPreferenceConstants::SHOW_INTRO, true);
workbenchPrefs->Flush();
}
QmitkDiffusionImagingAppIntroPart::~QmitkDiffusionImagingAppIntroPart()
{
// if the workbench is not closing (that means, welcome screen was closed explicitly), set "Show_intro" false
if (!this->GetIntroSite()->GetPage()->GetWorkbenchWindow()->GetWorkbench()->IsClosing())
{
berry::IPreferences::Pointer workbenchPrefs = QmitkDiffusionApplicationPlugin::GetDefault()->GetPreferencesService()->GetSystemPreferences();
workbenchPrefs->PutBool(berry::WorkbenchPreferenceConstants::SHOW_INTRO, false);
workbenchPrefs->Flush();
}
else
{
berry::IPreferences::Pointer workbenchPrefs = QmitkDiffusionApplicationPlugin::GetDefault()->GetPreferencesService()->GetSystemPreferences();
workbenchPrefs->PutBool(berry::WorkbenchPreferenceConstants::SHOW_INTRO, true);
workbenchPrefs->Flush();
}
// if workbench is not closing (Just welcome screen closing), open last used perspective
if (this->GetIntroSite()->GetPage()->GetPerspective()->GetId()
== "org.mitk.diffusionimagingapp.perspectives.welcome"
&& !this->GetIntroSite()->GetPage()->GetWorkbenchWindow()->GetWorkbench()->IsClosing())
{
berry::IPerspectiveDescriptor::Pointer perspective = this->GetIntroSite()->GetWorkbenchWindow()->GetWorkbench()->GetPerspectiveRegistry()->FindPerspectiveWithId("org.mitk.perspectives.diffusiondefault");
if (perspective)
{
this->GetIntroSite()->GetPage()->SetPerspective(perspective);
}
}
}
void QmitkDiffusionImagingAppIntroPart::CreateQtPartControl(QWidget* parent)
{
if (!m_Controls)
{
// create GUI widgets
m_Controls = new Ui::QmitkWelcomeScreenViewControls;
m_Controls->setupUi(parent);
// create a QWebView as well as a QWebPage and QWebFrame within the QWebview
m_view = new QWebView(parent);
m_view->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
QUrl urlQtResource(QString("qrc:/org.mitk.gui.qt.welcomescreen/mitkdiffusionimagingappwelcomeview.html"), QUrl::TolerantMode );
m_view->load( urlQtResource );
// adds the webview as a widget
parent->layout()->addWidget(m_view);
this->CreateConnections();
}
}
void QmitkDiffusionImagingAppIntroPart::CreateConnections()
{
if ( m_Controls )
{
connect( (QObject*)(m_view->page()), SIGNAL(linkClicked(const QUrl& )), this, SLOT(DelegateMeTo(const QUrl& )) );
}
}
void QmitkDiffusionImagingAppIntroPart::DelegateMeTo(const QUrl& showMeNext)
{
QString scheme = showMeNext.scheme();
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
QByteArray urlHostname = showMeNext.encodedHost();
QByteArray urlPath = showMeNext.encodedPath();
QByteArray dataset = showMeNext.encodedQueryItemValue("dataset");
QByteArray clear = showMeNext.encodedQueryItemValue("clear");
+#else
+ QByteArray urlHostname = QUrl::toAce(showMeNext.host());
+ QByteArray urlPath = showMeNext.path().toLatin1();
+ QUrlQuery query(showMeNext);
+ QByteArray dataset = query.queryItemValue("dataset").toLatin1();
+ QByteArray clear = query.queryItemValue("clear").toLatin1();//showMeNext.encodedQueryItemValue("clear");
+#endif
if (scheme.isEmpty()) MITK_INFO << " empty scheme of the to be delegated link" ;
// if the scheme is set to mitk, it is to be tested which action should be applied
if (scheme.contains(QString("mitk")) )
{
if(urlPath.isEmpty() ) MITK_INFO << " mitk path is empty " ;
// searching for the perspective keyword within the host name
if(urlHostname.contains(QByteArray("perspectives")) )
{
// the simplified method removes every whitespace
// ( whitespace means any character for which the standard C++ isspace() method returns true)
urlPath = urlPath.simplified();
QString tmpPerspectiveId(urlPath.data());
tmpPerspectiveId.replace(QString("/"), QString("") );
std::string perspectiveId = tmpPerspectiveId.toStdString();
// is working fine as long as the perspective id is valid, if not the application crashes
GetIntroSite()->GetWorkbenchWindow()->GetWorkbench()->ShowPerspective(perspectiveId, GetIntroSite()->GetWorkbenchWindow() );
// search the Workbench for opened StdMultiWidgets to ensure the focus does not stay on the welcome screen and is switched to
// an StdMultiWidget if one available
mitk::IDataStorageService::Pointer service =
berry::Platform::GetServiceRegistry().GetServiceById<mitk::IDataStorageService>(mitk::IDataStorageService::ID);
berry::IEditorInput::Pointer editorInput;
editorInput = new mitk::DataStorageEditorInput( service->GetActiveDataStorage() );
// the solution is not clean, but the dependency to the StdMultiWidget was removed in order to fix a crash problem
// as described in Bug #11715
// This is the correct way : use the static string ID variable
// berry::IEditorPart::Pointer editor = GetIntroSite()->GetPage()->FindEditors( editorInput, QmitkStdMultiWidgetEditor::EDITOR_ID );
// QuickFix: we use the same string for an local variable
const std::string stdEditorID = "org.mitk.editors.stdmultiwidget";
// search for opened StdMultiWidgetEditors
std::vector<berry::IEditorReference::Pointer> editorList = GetIntroSite()->GetPage()->FindEditors( editorInput, stdEditorID, 1 );
// if an StdMultiWidgetEditor open was found, give focus to it
if(editorList.size())
{
GetIntroSite()->GetPage()->Activate( editorList[0]->GetPart(true) );
}
}
}
// if the scheme is set to http, by default no action is performed, if an external webpage needs to be
// shown it should be implemented below
else if (scheme.contains(QString("http")) )
{
QDesktopServices::openUrl(showMeNext);
// m_view->load( ) ;
}
else if(scheme.contains("qrc"))
{
m_view->load(showMeNext);
}
}
void QmitkDiffusionImagingAppIntroPart::StandbyStateChanged(bool)
{
}
void QmitkDiffusionImagingAppIntroPart::SetFocus()
{
}
diff --git a/Plugins/org.mitk.gui.qt.dtiatlasapp/CMakeLists.txt b/Plugins/org.mitk.gui.qt.dtiatlasapp/CMakeLists.txt
index 1ae889096d..6a242b4c90 100644
--- a/Plugins/org.mitk.gui.qt.dtiatlasapp/CMakeLists.txt
+++ b/Plugins/org.mitk.gui.qt.dtiatlasapp/CMakeLists.txt
@@ -1,14 +1,14 @@
# The project name must correspond to the directory name of your plug-in
# and must not contain periods.
project(org_mitk_gui_qt_dtiatlasapp)
MACRO_CREATE_MITK_CTK_PLUGIN(
EXPORT_DIRECTIVE DTIATLAS_APP_EXPORT
EXPORTED_INCLUDE_SUFFIXES src
MODULE_DEPENDS MitkQtWidgets MitkSceneSerialization
- PACKAGE_DEPENDS Qt4|QtWebKit
+ PACKAGE_DEPENDS Qt4|QtWebKit Qt5|WebKitWidgets
)
if(QT_QTWEBKIT_FOUND)
add_definitions(-DQT_WEBKIT)
endif(QT_QTWEBKIT_FOUND)
diff --git a/Plugins/org.mitk.gui.qt.dtiatlasapp/src/QmitkDTIAtlasAppWorkbenchAdvisor.cpp b/Plugins/org.mitk.gui.qt.dtiatlasapp/src/QmitkDTIAtlasAppWorkbenchAdvisor.cpp
index 9c035fe194..c99aa6de75 100644
--- a/Plugins/org.mitk.gui.qt.dtiatlasapp/src/QmitkDTIAtlasAppWorkbenchAdvisor.cpp
+++ b/Plugins/org.mitk.gui.qt.dtiatlasapp/src/QmitkDTIAtlasAppWorkbenchAdvisor.cpp
@@ -1,111 +1,111 @@
/*===================================================================
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 "QmitkDTIAtlasAppWorkbenchAdvisor.h"
#include "internal/QmitkDTIAtlasAppApplicationPlugin.h"
#include <berryPlatform.h>
#include <berryIPreferencesService.h>
#include <berryWorkbenchPreferenceConstants.h>
#include <berryQtAssistantUtil.h>
#include <QmitkExtWorkbenchWindowAdvisor.h>
#include <QApplication>
const std::string QmitkDTIAtlasAppWorkbenchAdvisor::WELCOME_PERSPECTIVE_ID = "org.mitk.dtiatlasapp.perspectives.welcome";
void
QmitkDTIAtlasAppWorkbenchAdvisor::Initialize(berry::IWorkbenchConfigurer::Pointer configurer)
{
berry::QtWorkbenchAdvisor::Initialize(configurer);
configurer->SetSaveAndRestore(true);
// TODO This should go into the products plugin_customization.ini file (when
// the product and branding support is finished, see bug 2146).
// This will not work anymore, if bug 2822 is fixed.
berry::IPreferencesService::Pointer prefService = berry::Platform::GetServiceRegistry().GetServiceById<berry::IPreferencesService>(berry::IPreferencesService::ID);
prefService->GetSystemPreferences()->Put(berry::WorkbenchPreferenceConstants::PREFERRED_SASH_LAYOUT, berry::WorkbenchPreferenceConstants::RIGHT);
QString collectionFile = QmitkDTIAtlasAppApplicationPlugin::GetDefault()->GetQtHelpCollectionFile();
if (!collectionFile.isEmpty())
{
// berry::QtAssistantUtil::SetHelpCollectionFile(collectionFile);
// berry::QtAssistantUtil::SetDefaultHelpUrl("qthelp://org.mitk.gui.qt.dtiatlasapp/bundle/index.html");
typedef std::vector<berry::IBundle::Pointer> BundleContainer;
BundleContainer bundles = berry::Platform::GetBundles();
berry::QtAssistantUtil::RegisterQCHFiles(bundles);
}
}
berry::WorkbenchWindowAdvisor*
QmitkDTIAtlasAppWorkbenchAdvisor::CreateWorkbenchWindowAdvisor(
berry::IWorkbenchWindowConfigurer::Pointer configurer)
{
std::vector<std::string> perspExcludeList;
perspExcludeList.push_back( std::string("org.mitk.dtiatlasapp.perspectives.welcome") );
perspExcludeList.push_back( std::string("org.mitk.perspectives.diffusionimaginginternal") );
perspExcludeList.push_back( std::string("org.mitk.perspectives.publicdiffusionimaging") );
perspExcludeList.push_back( std::string("org.mitk.extapp.defaultperspective") );
perspExcludeList.push_back( std::string("org.mitk.coreapp.defaultperspective") );
std::vector<std::string> viewExcludeList;
viewExcludeList.push_back( std::string("org.mitk.views.partialvolumeanalysis") );
viewExcludeList.push_back( std::string("org.mitk.views.globalfibertracking") );
viewExcludeList.push_back( std::string("org.mitk.views.tractbasedspatialstatistics") );
viewExcludeList.push_back( std::string("org.mitk.views.fibertracking") );
viewExcludeList.push_back( std::string("org.mitk.views.ivim") );
viewExcludeList.push_back( std::string("org.mitk.views.qballreconstruction") );
viewExcludeList.push_back( std::string("org.mitk.views.diffusiondicomimport") );
viewExcludeList.push_back( std::string("org.mitk.views.diffusionpreprocessing") );
viewExcludeList.push_back( std::string("org.mitk.views.diffusionquantification") );
viewExcludeList.push_back( std::string("org.mitk.views.tensorreconstruction") );
viewExcludeList.push_back( std::string("org.mitk.views.perspectiveswitcher") );
viewExcludeList.push_back( std::string("org.mitk.views.basicimageprocessing") );
viewExcludeList.push_back( std::string("org.mitk.views.fiberbundleoperations") );
viewExcludeList.push_back( std::string("org.mitk.views.measurement") );
viewExcludeList.push_back( std::string("org.mitk.views.moviemaker") );
viewExcludeList.push_back( std::string("org.mitk.views.odfdetails") );
- viewExcludeList.push_back( std::string("org.mitk.views.propertylistview") );
+ viewExcludeList.push_back( std::string("org.mitk.views.properties") );
viewExcludeList.push_back( std::string("org.mitk.views.screenshotmaker") );
viewExcludeList.push_back( std::string("org.mitk.views.segmentation") );
viewExcludeList.push_back( std::string("org.mitk.views.imagestatistics") );
// viewExcludeList.push_back( std::string("org.mitk.views.controlvisualizationpropertiesview") );
viewExcludeList.push_back( std::string("org.mitk.views.volumevisualization") );
viewExcludeList.push_back( std::string("org.mitk.views.simplemeasurement") );
configurer->SetShowPerspectiveBar(false);
configurer->SetInitialSize(berry::Point(1000,770));
QmitkExtWorkbenchWindowAdvisor* advisor = new QmitkExtWorkbenchWindowAdvisor(this, configurer);
advisor->SetPerspectiveExcludeList(perspExcludeList);
advisor->SetViewExcludeList(viewExcludeList);
advisor->ShowViewToolbar(false);
advisor->ShowVersionInfo(false);
advisor->ShowMitkVersionInfo(false);
advisor->SetProductName("based on MITK Diffusion Imaging App");
advisor->SetWindowIcon(":/org.mitk.gui.qt.dtiatlasapp/app-icon.png");
return advisor;
}
std::string QmitkDTIAtlasAppWorkbenchAdvisor::GetInitialWindowPerspectiveId()
{
return WELCOME_PERSPECTIVE_ID;
}
diff --git a/Plugins/org.mitk.gui.qt.dtiatlasapp/src/internal/QmitkDTIAtlasAppApplicationPlugin.cpp b/Plugins/org.mitk.gui.qt.dtiatlasapp/src/internal/QmitkDTIAtlasAppApplicationPlugin.cpp
index 337ece002c..cbc6c6d0cc 100644
--- a/Plugins/org.mitk.gui.qt.dtiatlasapp/src/internal/QmitkDTIAtlasAppApplicationPlugin.cpp
+++ b/Plugins/org.mitk.gui.qt.dtiatlasapp/src/internal/QmitkDTIAtlasAppApplicationPlugin.cpp
@@ -1,121 +1,121 @@
/*===================================================================
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 "QmitkDTIAtlasAppApplicationPlugin.h"
#include <QtPlugin>
#include <mitkVersion.h>
#include <berryQtAssistantUtil.h>
#include "src/QmitkDTIAtlasAppApplication.h"
#include "src/internal/QmitkDTIAtlasAppIntroPart.h"
#include "src/internal/QmitkDTIAtlasAppPerspective.h"
#include "src/internal/QmitkWelcomePerspective.h"
#include <QFileInfo>
#include <QDateTime>
QmitkDTIAtlasAppApplicationPlugin* QmitkDTIAtlasAppApplicationPlugin::inst = 0;
QmitkDTIAtlasAppApplicationPlugin::QmitkDTIAtlasAppApplicationPlugin()
: pluginListener(0)
{
inst = this;
}
QmitkDTIAtlasAppApplicationPlugin::~QmitkDTIAtlasAppApplicationPlugin()
{
delete pluginListener;
}
QmitkDTIAtlasAppApplicationPlugin* QmitkDTIAtlasAppApplicationPlugin::GetDefault()
{
return inst;
}
void QmitkDTIAtlasAppApplicationPlugin::start(ctkPluginContext* context)
{
berry::AbstractUICTKPlugin::start(context);
this->context = context;
BERRY_REGISTER_EXTENSION_CLASS(QmitkDTIAtlasAppApplication, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkDTIAtlasAppIntroPart, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkDTIAtlasAppPerspective, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkWelcomePerspective, context)
// QString collectionFile = GetQtHelpCollectionFile();
// berry::QtAssistantUtil::SetHelpCollectionFile(collectionFile);
// berry::QtAssistantUtil::SetDefaultHelpUrl("qthelp://org.mitk.gui.qt.dtiatlasapp/bundle/index.html");
delete pluginListener;
pluginListener = new berry::QCHPluginListener(context);
context->connectPluginListener(pluginListener, SLOT(pluginChanged(ctkPluginEvent)), Qt::DirectConnection);
// register all QCH files from all the currently installed plugins
pluginListener->processPlugins();
}
QString QmitkDTIAtlasAppApplicationPlugin::GetQtHelpCollectionFile() const
{
if (!helpCollectionFile.isEmpty())
{
return helpCollectionFile;
}
QString collectionFilename;
QString na("n/a");
// if (na != MITK_REVISION)
// collectionFilename = "MitkDTIAtlasAppQtHelpCollection_" MITK_REVISION ".qhc";
// else
collectionFilename = "MitkDTIAtlasAppQtHelpCollection.qhc";
QFileInfo collectionFileInfo = context->getDataFile(collectionFilename);
QFileInfo pluginFileInfo = QFileInfo(QUrl(context->getPlugin()->getLocation()).toLocalFile());
if (!collectionFileInfo.exists() ||
pluginFileInfo.lastModified() > collectionFileInfo.lastModified())
{
// extract the qhc file from the plug-in
QByteArray content = context->getPlugin()->getResource(collectionFilename);
if (content.isEmpty())
{
BERRY_WARN << "Could not get plug-in resource: " << collectionFilename.toStdString();
}
else
{
QFile file(collectionFileInfo.absoluteFilePath());
file.open(QIODevice::WriteOnly);
file.write(content);
file.close();
}
}
if (QFile::exists(collectionFileInfo.absoluteFilePath()))
{
helpCollectionFile = collectionFileInfo.absoluteFilePath();
}
return helpCollectionFile;
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_dtiatlasapp, QmitkDTIAtlasAppApplicationPlugin)
-
-
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_dtiatlasapp, QmitkDTIAtlasAppApplicationPlugin)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.dtiatlasapp/src/internal/QmitkDTIAtlasAppApplicationPlugin.h b/Plugins/org.mitk.gui.qt.dtiatlasapp/src/internal/QmitkDTIAtlasAppApplicationPlugin.h
index 01b83066ba..c7b74966c2 100644
--- a/Plugins/org.mitk.gui.qt.dtiatlasapp/src/internal/QmitkDTIAtlasAppApplicationPlugin.h
+++ b/Plugins/org.mitk.gui.qt.dtiatlasapp/src/internal/QmitkDTIAtlasAppApplicationPlugin.h
@@ -1,57 +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 QMITKDTIATLASAPPAPPLICATIONPLUGIN_H_
#define QMITKDTIATLASAPPAPPLICATIONPLUGIN_H_
#include <QString>
#include <berryAbstractUICTKPlugin.h>
#include <berryIBundleContext.h>
#include <berryQCHPluginListener.h>
class QmitkDTIAtlasAppApplicationPlugin :
public QObject, public berry::AbstractUICTKPlugin
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_dtiatlasapp")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
QmitkDTIAtlasAppApplicationPlugin();
~QmitkDTIAtlasAppApplicationPlugin();
static QmitkDTIAtlasAppApplicationPlugin* GetDefault();
ctkPluginContext* GetPluginContext() const;
void start(ctkPluginContext*);
QString GetQtHelpCollectionFile() const;
private:
static QmitkDTIAtlasAppApplicationPlugin* inst;
ctkPluginContext* context;
berry::QCHPluginListener* pluginListener;
mutable QString helpCollectionFile;
}; // QmitkDTIAtlasAppApplicationPlugin
#endif // QMITKDTIATLASAPPAPPLICATIONPLUGIN_H_
diff --git a/Plugins/org.mitk.gui.qt.dtiatlasapp/src/internal/QmitkDTIAtlasAppIntroPart.cpp b/Plugins/org.mitk.gui.qt.dtiatlasapp/src/internal/QmitkDTIAtlasAppIntroPart.cpp
index f0b21f3a28..c4406ff44d 100644
--- a/Plugins/org.mitk.gui.qt.dtiatlasapp/src/internal/QmitkDTIAtlasAppIntroPart.cpp
+++ b/Plugins/org.mitk.gui.qt.dtiatlasapp/src/internal/QmitkDTIAtlasAppIntroPart.cpp
@@ -1,293 +1,304 @@
/*===================================================================
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 "QmitkDTIAtlasAppIntroPart.h"
#include "mitkNodePredicateDataType.h"
#include <berryIWorkbenchWindow.h>
#include <berryIWorkbench.h>
#include <berryIWorkbenchPage.h>
#include <berryIPerspectiveRegistry.h>
#include <berryWorkbenchPreferenceConstants.h>
#include <berryIPreferences.h>
#include <berryIEditorReference.h>
#include <mitkLogMacros.h>
#include <QLabel>
#include <QMessageBox>
#include <QtCore/qconfig.h>
#ifdef QT_WEBKIT
-#include <QWebView>
-#include <QWebPage>
+# include <QWebView>
+# include <QWebPage>
+# if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
+# include <QUrlQuery>
+# endif
#endif
#include <QString>
#include <QStringList>
#include <QRegExp>
#include <QChar>
#include <QByteArray>
#include <QDesktopServices>
#include "QmitkStdMultiWidget.h"
#include "QmitkStdMultiWidgetEditor.h"
#include "QmitkDTIAtlasAppApplicationPlugin.h"
#include "mitkDataStorageEditorInput.h"
#include "mitkBaseDataIOFactory.h"
#include "mitkSceneIO.h"
#include "mitkProgressBar.h"
#include "mitkDataNodeFactory.h"
#include "mitkNodePredicateNot.h"
#include "mitkNodePredicateProperty.h"
QmitkDTIAtlasAppIntroPart::QmitkDTIAtlasAppIntroPart()
: m_Controls(NULL)
{
berry::IPreferences::Pointer workbenchPrefs = QmitkDTIAtlasAppApplicationPlugin::GetDefault()->GetPreferencesService()->GetSystemPreferences();
workbenchPrefs->PutBool(berry::WorkbenchPreferenceConstants::SHOW_INTRO, true);
workbenchPrefs->Flush();
}
QmitkDTIAtlasAppIntroPart::~QmitkDTIAtlasAppIntroPart()
{
// if the workbench is not closing (that means, welcome screen was closed explicitly), set "Show_intro" false
if (!this->GetIntroSite()->GetPage()->GetWorkbenchWindow()->GetWorkbench()->IsClosing())
{
berry::IPreferences::Pointer workbenchPrefs = QmitkDTIAtlasAppApplicationPlugin::GetDefault()->GetPreferencesService()->GetSystemPreferences();
workbenchPrefs->PutBool(berry::WorkbenchPreferenceConstants::SHOW_INTRO, false);
workbenchPrefs->Flush();
}
else
{
berry::IPreferences::Pointer workbenchPrefs = QmitkDTIAtlasAppApplicationPlugin::GetDefault()->GetPreferencesService()->GetSystemPreferences();
workbenchPrefs->PutBool(berry::WorkbenchPreferenceConstants::SHOW_INTRO, true);
workbenchPrefs->Flush();
}
// if workbench is not closing (Just welcome screen closing), open last used perspective
if (this->GetIntroSite()->GetPage()->GetPerspective()->GetId()
== "org.mitk.dtiatlasapp.perspectives.welcome" && !this->GetIntroSite()->GetPage()->GetWorkbenchWindow()->GetWorkbench()->IsClosing())
{
berry::IPerspectiveDescriptor::Pointer perspective = this->GetIntroSite()->GetWorkbenchWindow()->GetWorkbench()->GetPerspectiveRegistry()->FindPerspectiveWithId("org.mitk.dtiatlasapp.perspectives.dtiatlasapp");
if (perspective)
{
this->GetIntroSite()->GetPage()->SetPerspective(perspective);
}
}
}
void QmitkDTIAtlasAppIntroPart::CreateQtPartControl(QWidget* parent)
{
if (!m_Controls)
{
// create GUI widgets
m_Controls = new Ui::QmitkWelcomeScreenViewControls;
m_Controls->setupUi(parent);
#ifdef QT_WEBKIT
// create a QWebView as well as a QWebPage and QWebFrame within the QWebview
m_view = new QWebView(parent);
m_view->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
QUrl urlQtResource(QString("qrc:/org.mitk.gui.qt.welcomescreen/mitkdtiatlasappwelcomeview.html"), QUrl::TolerantMode );
m_view->load( urlQtResource );
// adds the webview as a widget
parent->layout()->addWidget(m_view);
this->CreateConnections();
#else
parent->layout()->addWidget(new QLabel("<h1><center>Please install Qt with the WebKit option to see cool pictures!</center></h1>"));
#endif
}
}
#ifdef QT_WEBKIT
void QmitkDTIAtlasAppIntroPart::CreateConnections()
{
if ( m_Controls )
{
connect( (QObject*)(m_view->page()), SIGNAL(linkClicked(const QUrl& )), this, SLOT(DelegateMeTo(const QUrl& )) );
}
}
void QmitkDTIAtlasAppIntroPart::DelegateMeTo(const QUrl& showMeNext)
{
QString scheme = showMeNext.scheme();
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
QByteArray urlHostname = showMeNext.encodedHost();
QByteArray urlPath = showMeNext.encodedPath();
QByteArray dataset = showMeNext.encodedQueryItemValue("dataset");
QByteArray clear = showMeNext.encodedQueryItemValue("clear");
+#else
+ QByteArray urlHostname = QUrl::toAce(showMeNext.host());
+ QByteArray urlPath = showMeNext.path().toLatin1();
+ QUrlQuery query(showMeNext);
+ QByteArray dataset = query.queryItemValue("dataset").toLatin1();
+ QByteArray clear = query.queryItemValue("clear").toLatin1();//showMeNext.encodedQueryItemValue("clear");
+#endif
if (scheme.isEmpty()) MITK_INFO << " empty scheme of the to be delegated link" ;
// if the scheme is set to mitk, it is to be tested which action should be applied
if (scheme.contains(QString("mitk")) )
{
if(urlPath.isEmpty() ) MITK_INFO << " mitk path is empty " ;
// searching for the perspective keyword within the host name
if(urlHostname.contains(QByteArray("perspectives")) )
{
// the simplified method removes every whitespace
// ( whitespace means any character for which the standard C++ isspace() method returns true)
urlPath = urlPath.simplified();
QString tmpPerspectiveId(urlPath.data());
tmpPerspectiveId.replace(QString("/"), QString("") );
std::string perspectiveId = tmpPerspectiveId.toStdString();
// is working fine as long as the perspective id is valid, if not the application crashes
GetIntroSite()->GetWorkbenchWindow()->GetWorkbench()->ShowPerspective(perspectiveId, GetIntroSite()->GetWorkbenchWindow() );
mitk::DataStorageEditorInput::Pointer editorInput;
editorInput = new mitk::DataStorageEditorInput();
berry::IEditorPart::Pointer editor = GetIntroSite()->GetPage()->OpenEditor(editorInput, QmitkStdMultiWidgetEditor::EDITOR_ID);
QmitkStdMultiWidgetEditor::Pointer multiWidgetEditor;
mitk::DataStorage::Pointer dataStorage;
if (editor.Cast<QmitkStdMultiWidgetEditor>().IsNull())
{
editorInput = new mitk::DataStorageEditorInput();
dataStorage = editorInput->GetDataStorageReference()->GetDataStorage();
}
else
{
multiWidgetEditor = editor.Cast<QmitkStdMultiWidgetEditor>();
multiWidgetEditor->GetStdMultiWidget()->RequestUpdate();
dataStorage = multiWidgetEditor->GetEditorInput().Cast<mitk::DataStorageEditorInput>()->GetDataStorageReference()->GetDataStorage();
}
bool dsmodified = false;
QString *fileName = new QString(dataset.data());
if ( fileName->right(5) == ".mitk" )
{
mitk::SceneIO::Pointer sceneIO = mitk::SceneIO::New();
bool clearDataStorageFirst(false);
QString *sClear = new QString(clear.data());
if ( sClear->right(4) == "true" )
{
clearDataStorageFirst = true;
}
mitk::ProgressBar::GetInstance()->AddStepsToDo(2);
dataStorage = sceneIO->LoadScene( fileName->toLocal8Bit().constData(), dataStorage, clearDataStorageFirst );
dsmodified = true;
mitk::ProgressBar::GetInstance()->Progress(2);
}
else
{
mitk::DataNodeFactory::Pointer nodeReader = mitk::DataNodeFactory::New();
try
{
nodeReader->SetFileName(fileName->toLocal8Bit().data());
nodeReader->Update();
for ( unsigned int i = 0 ; i < nodeReader->GetNumberOfOutputs( ); ++i )
{
mitk::DataNode::Pointer node;
node = nodeReader->GetOutput(i);
if ( node->GetData() != NULL )
{
dataStorage->Add(node);
dsmodified = true;
}
}
}
catch(...)
{
MITK_INFO << "Could not open file!";
}
}
if(dataStorage.IsNotNull() && dsmodified)
{
// get all nodes that have not set "includeInBoundingBox" to false
mitk::NodePredicateNot::Pointer pred
= mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("includeInBoundingBox"
, mitk::BoolProperty::New(false)));
mitk::DataStorage::SetOfObjects::ConstPointer rs = dataStorage->GetSubset(pred);
if(rs->Size() > 0)
{
// calculate bounding geometry of these nodes
mitk::TimeGeometry::Pointer bounds = dataStorage->ComputeBoundingGeometry3D(rs);
// initialize the views to the bounding geometry
mitk::RenderingManager::GetInstance()->InitializeViews(bounds);
}
}
}
// searching for the load
if(urlHostname.contains(QByteArray("perspectives")) )
{
// the simplified method removes every whitespace
// ( whitespace means any character for which the standard C++ isspace() method returns true)
urlPath = urlPath.simplified();
QString tmpPerspectiveId(urlPath.data());
tmpPerspectiveId.replace(QString("/"), QString("") );
std::string perspectiveId = tmpPerspectiveId.toStdString();
// is working fine as long as the perspective id is valid, if not the application crashes
GetIntroSite()->GetWorkbenchWindow()->GetWorkbench()->ShowPerspective(perspectiveId, GetIntroSite()->GetWorkbenchWindow() );
mitk::DataStorageEditorInput::Pointer editorInput;
editorInput = new mitk::DataStorageEditorInput();
GetIntroSite()->GetPage()->OpenEditor(editorInput, QmitkStdMultiWidgetEditor::EDITOR_ID);
}
else
{
MITK_INFO << "Unkown mitk action keyword (see documentation for mitk links)" ;
}
}
// if the scheme is set to http, by default no action is performed, if an external webpage needs to be
// shown it should be implemented below
else if (scheme.contains(QString("http")) )
{
QDesktopServices::openUrl(showMeNext);
// m_view->load( ) ;
}
else if(scheme.contains("qrc"))
{
m_view->load(showMeNext);
}
}
#endif
void QmitkDTIAtlasAppIntroPart::StandbyStateChanged(bool standby)
{
}
void QmitkDTIAtlasAppIntroPart::SetFocus()
{
}
diff --git a/Plugins/org.mitk.gui.qt.eventrecorder/src/internal/org_mitk_gui_qt_eventrecorder_Activator.cpp b/Plugins/org.mitk.gui.qt.eventrecorder/src/internal/org_mitk_gui_qt_eventrecorder_Activator.cpp
index 3186d188e0..4dc0876202 100644
--- a/Plugins/org.mitk.gui.qt.eventrecorder/src/internal/org_mitk_gui_qt_eventrecorder_Activator.cpp
+++ b/Plugins/org.mitk.gui.qt.eventrecorder/src/internal/org_mitk_gui_qt_eventrecorder_Activator.cpp
@@ -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.
===================================================================*/
#include "org_mitk_gui_qt_eventrecorder_Activator.h"
#include <QtPlugin>
#include "InteractionEventRecorder.h"
namespace mitk {
void org_mitk_gui_qt_eventrecorder_Activator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(InteractionEventRecorder, context)
}
void org_mitk_gui_qt_eventrecorder_Activator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_eventrecorder, mitk::org_mitk_gui_qt_eventrecorder_Activator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_eventrecorder, mitk::org_mitk_gui_qt_eventrecorder_Activator)
+#endif
\ No newline at end of file
diff --git a/Plugins/org.mitk.gui.qt.eventrecorder/src/internal/org_mitk_gui_qt_eventrecorder_Activator.h b/Plugins/org.mitk.gui.qt.eventrecorder/src/internal/org_mitk_gui_qt_eventrecorder_Activator.h
index a64fa7fcf5..b715022ba6 100644
--- a/Plugins/org.mitk.gui.qt.eventrecorder/src/internal/org_mitk_gui_qt_eventrecorder_Activator.h
+++ b/Plugins/org.mitk.gui.qt.eventrecorder/src/internal/org_mitk_gui_qt_eventrecorder_Activator.h
@@ -1,40 +1,43 @@
/*===================================================================
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 org_mitk_gui_qt_eventrecorder_Activator_h
#define org_mitk_gui_qt_eventrecorder_Activator_h
#include <ctkPluginActivator.h>
namespace mitk {
class org_mitk_gui_qt_eventrecorder_Activator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_eventrecorder")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
}; // org_mitk_gui_qt_eventrecorder_Activator
}
#endif // org_mitk_gui_qt_eventrecorder_Activator_h
diff --git a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/index.theme b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/index.theme
index 4a3ff343c3..25c2b08bec 100644
--- a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/index.theme
+++ b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/index.theme
@@ -1,25 +1,46 @@
[Icon Theme]
Name=tango
Comment=An icon theme following the tango style guide
Directories=scalable/actions scalable/status scalable/places
[scalable/actions]
Size=48
Type=Scalable
MinSize=1
MaxSize=256
Context=Actions
+[scalable/categories]
+Size=48
+Type=Scalable
+MinSize=1
+MaxSize=256
+Context=Categories
+
+[scalable/devices]
+Size=48
+Type=Scalable
+MinSize=1
+MaxSize=256
+Context=Devices
+
+[scalable/mimetypes]
+Size=48
+Type=Scalable
+MinSize=1
+MaxSize=256
+Context=MimeTypes
+
[scalable/status]
Size=48
Type=Scalable
MinSize=1
MaxSize=256
Context=Status
[scalable/places]
Size=48
Type=Scalable
MinSize=1
MaxSize=256
Context=Places
diff --git a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/list-add.svg b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/list-add.svg
new file mode 100644
index 0000000000..6eaed44811
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/list-add.svg
@@ -0,0 +1,436 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="48px"
+ height="48px"
+ id="svg6431"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/actions"
+ sodipodi:docname="list-add.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <defs
+ id="defs6433">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 24 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="48 : 24 : 1"
+ inkscape:persp3d-origin="24 : 16 : 1"
+ id="perspective70" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient2091">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop2093" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop2095" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient7916">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop7918" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.34020618;"
+ offset="1.0000000"
+ id="stop7920" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient8662">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop8664" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop8666" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8662"
+ id="radialGradient1503"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,0.536723,-1.018989e-13,16.87306)"
+ cx="24.837126"
+ cy="36.421127"
+ fx="24.837126"
+ fy="36.421127"
+ r="15.644737" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient2847">
+ <stop
+ style="stop-color:#3465a4;stop-opacity:1;"
+ offset="0"
+ id="stop2849" />
+ <stop
+ style="stop-color:#3465a4;stop-opacity:0;"
+ offset="1"
+ id="stop2851" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2847"
+ id="linearGradient1488"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.000000,0.000000,0.000000,-1.000000,-1.242480,40.08170)"
+ x1="37.128052"
+ y1="29.729605"
+ x2="37.065414"
+ y2="26.194071" />
+ <linearGradient
+ id="linearGradient2831">
+ <stop
+ style="stop-color:#3465a4;stop-opacity:1;"
+ offset="0"
+ id="stop2833" />
+ <stop
+ id="stop2855"
+ offset="0.33333334"
+ style="stop-color:#5b86be;stop-opacity:1;" />
+ <stop
+ style="stop-color:#83a8d8;stop-opacity:0;"
+ offset="1"
+ id="stop2835" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2831"
+ id="linearGradient1486"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-48.30498,-6.043298)"
+ x1="13.478554"
+ y1="10.612206"
+ x2="15.419417"
+ y2="19.115122" />
+ <linearGradient
+ id="linearGradient2380">
+ <stop
+ style="stop-color:#b9cfe7;stop-opacity:1"
+ offset="0"
+ id="stop2382" />
+ <stop
+ style="stop-color:#729fcf;stop-opacity:1"
+ offset="1"
+ id="stop2384" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2682">
+ <stop
+ style="stop-color:#3977c3;stop-opacity:1;"
+ offset="0"
+ id="stop2684" />
+ <stop
+ style="stop-color:#89aedc;stop-opacity:0;"
+ offset="1"
+ id="stop2686" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2682"
+ id="linearGradient2688"
+ x1="36.713837"
+ y1="31.455952"
+ x2="37.124462"
+ y2="24.842253"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-48.77039,-5.765705)" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient2690">
+ <stop
+ style="stop-color:#c4d7eb;stop-opacity:1;"
+ offset="0"
+ id="stop2692" />
+ <stop
+ style="stop-color:#c4d7eb;stop-opacity:0;"
+ offset="1"
+ id="stop2694" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2690"
+ id="linearGradient2696"
+ x1="32.647972"
+ y1="30.748846"
+ x2="37.124462"
+ y2="24.842253"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-48.77039,-5.765705)" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient2871">
+ <stop
+ style="stop-color:#3465a4;stop-opacity:1;"
+ offset="0"
+ id="stop2873" />
+ <stop
+ style="stop-color:#3465a4;stop-opacity:1"
+ offset="1"
+ id="stop2875" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2402">
+ <stop
+ style="stop-color:#729fcf;stop-opacity:1;"
+ offset="0"
+ id="stop2404" />
+ <stop
+ style="stop-color:#528ac5;stop-opacity:1;"
+ offset="1"
+ id="stop2406" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2797"
+ id="linearGradient1493"
+ gradientUnits="userSpaceOnUse"
+ x1="5.9649176"
+ y1="26.048164"
+ x2="52.854097"
+ y2="26.048164" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient2797">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop2799" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop2801" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2797"
+ id="linearGradient1491"
+ gradientUnits="userSpaceOnUse"
+ x1="5.9649176"
+ y1="26.048164"
+ x2="52.854097"
+ y2="26.048164" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient7179">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop7181" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop7183" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2316">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop2318" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.65979379;"
+ offset="1"
+ id="stop2320" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1322">
+ <stop
+ id="stop1324"
+ offset="0.0000000"
+ style="stop-color:#729fcf" />
+ <stop
+ id="stop1326"
+ offset="1.0000000"
+ style="stop-color:#5187d6;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1322"
+ id="linearGradient4975"
+ x1="34.892849"
+ y1="36.422989"
+ x2="45.918697"
+ y2="48.547989"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-18.01785,-13.57119)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7179"
+ id="linearGradient7185"
+ x1="13.435029"
+ y1="13.604306"
+ x2="22.374878"
+ y2="23.554308"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7179"
+ id="linearGradient7189"
+ gradientUnits="userSpaceOnUse"
+ x1="13.435029"
+ y1="13.604306"
+ x2="22.374878"
+ y2="23.554308"
+ gradientTransform="matrix(-1.000000,0.000000,0.000000,-1.000000,47.93934,50.02474)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2380"
+ id="linearGradient7180"
+ gradientUnits="userSpaceOnUse"
+ x1="62.513836"
+ y1="36.061237"
+ x2="15.984863"
+ y2="20.60858" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2871"
+ id="linearGradient7182"
+ gradientUnits="userSpaceOnUse"
+ x1="46.834816"
+ y1="45.264122"
+ x2="45.380436"
+ y2="50.939667" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2402"
+ id="linearGradient7184"
+ gradientUnits="userSpaceOnUse"
+ x1="18.935766"
+ y1="23.667896"
+ x2="53.588622"
+ y2="26.649362" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2871"
+ id="linearGradient7186"
+ gradientUnits="userSpaceOnUse"
+ x1="46.834816"
+ y1="45.264122"
+ x2="45.380436"
+ y2="50.939667" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7916"
+ id="linearGradient7922"
+ x1="16.874998"
+ y1="22.851799"
+ x2="27.900846"
+ y2="34.976799"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2091"
+ id="radialGradient2097"
+ cx="23.070683"
+ cy="35.127438"
+ fx="23.070683"
+ fy="35.127438"
+ r="10.319340"
+ gradientTransform="matrix(0.914812,1.265023e-2,-8.21502e-3,0.213562,2.253914,27.18889)"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="0.15686275"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1"
+ inkscape:cx="-123.56934"
+ inkscape:cy="0.031886897"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:window-width="1280"
+ inkscape:window-height="818"
+ inkscape:window-x="0"
+ inkscape:window-y="30"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:showpageshadow="false" />
+ <metadata
+ id="metadata6436">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Add</dc:title>
+ <dc:date>2006-01-04</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Andreas Nilsson</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source>http://tango-project.org</dc:source>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>add</rdf:li>
+ <rdf:li>plus</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/publicdomain/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.10824742;fill:url(#radialGradient2097);fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path1361"
+ sodipodi:cx="22.958872"
+ sodipodi:cy="34.94062"
+ sodipodi:rx="10.31934"
+ sodipodi:ry="2.320194"
+ d="M 33.278212 34.94062 A 10.31934 2.320194 0 1 1 12.639532,34.94062 A 10.31934 2.320194 0 1 1 33.278212 34.94062 z"
+ transform="matrix(1.550487,0,0,1.978714,-12.4813,-32.49103)" />
+ <path
+ style="font-size:59.901077px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr-tb;text-anchor:start;fill:#75a1d0;fill-opacity:1.0000000;stroke:#3465a4;stroke-width:1.0000004px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans"
+ d="M 27.514356,37.542682 L 27.514356,28.515722 L 37.492820,28.475543 L 37.492820,21.480219 L 27.523285,21.480219 L 27.514356,11.520049 L 20.498082,11.531210 L 20.502546,21.462362 L 10.512920,21.536022 L 10.477206,28.504561 L 20.511475,28.475543 L 20.518171,37.515896 L 27.514356,37.542682 z "
+ id="text1314"
+ sodipodi:nodetypes="ccccccccccccc" />
+ <path
+ style="font-size:59.901077px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr-tb;text-anchor:start;opacity:0.40860215;fill:url(#linearGradient4975);fill-opacity:1.0000000;stroke:url(#linearGradient7922);stroke-width:1.0000006px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans"
+ d="M 26.498702,36.533920 L 26.498702,27.499738 L 36.501304,27.499738 L 36.494607,22.475309 L 26.507630,22.475309 L 26.507630,12.480335 L 21.512796,12.498193 L 21.521725,22.475309 L 11.495536,22.493166 L 11.468750,27.466256 L 21.533143,27.475185 L 21.519750,36.502670 L 26.498702,36.533920 z "
+ id="path7076"
+ sodipodi:nodetypes="ccccccccccccc" />
+ <path
+ style="fill:#ffffff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;opacity:0.31182796"
+ d="M 11.000000,25.000000 C 11.000000,26.937500 36.984375,24.031250 36.984375,24.968750 L 36.984375,21.968750 L 27.000000,22.000000 L 27.000000,12.034772 L 21.000000,12.034772 L 21.000000,22.000000 L 11.000000,22.000000 L 11.000000,25.000000 z "
+ id="path7914"
+ sodipodi:nodetypes="ccccccccc" />
+ </g>
+</svg>
diff --git a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/list-remove.svg b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/list-remove.svg
new file mode 100644
index 0000000000..5f109a05c3
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/list-remove.svg
@@ -0,0 +1,424 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="48px"
+ height="48px"
+ id="svg6431"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/actions"
+ sodipodi:docname="list-remove.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <defs
+ id="defs6433">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 24 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="48 : 24 : 1"
+ inkscape:persp3d-origin="24 : 16 : 1"
+ id="perspective69" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient2091">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop2093" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop2095" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2091"
+ id="radialGradient2097"
+ cx="23.070683"
+ cy="35.127438"
+ fx="23.070683"
+ fy="35.127438"
+ r="10.319340"
+ gradientTransform="matrix(0.914812,1.265023e-2,-8.21502e-3,0.213562,2.253914,27.18889)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient7916">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop7918" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.34020618;"
+ offset="1.0000000"
+ id="stop7920" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient8662">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop8664" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop8666" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8662"
+ id="radialGradient1503"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,0.536723,-1.018989e-13,16.87306)"
+ cx="24.837126"
+ cy="36.421127"
+ fx="24.837126"
+ fy="36.421127"
+ r="15.644737" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient2847">
+ <stop
+ style="stop-color:#3465a4;stop-opacity:1;"
+ offset="0"
+ id="stop2849" />
+ <stop
+ style="stop-color:#3465a4;stop-opacity:0;"
+ offset="1"
+ id="stop2851" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2847"
+ id="linearGradient1488"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1.000000,0.000000,0.000000,-1.000000,-1.242480,40.08170)"
+ x1="37.128052"
+ y1="29.729605"
+ x2="37.065414"
+ y2="26.194071" />
+ <linearGradient
+ id="linearGradient2831">
+ <stop
+ style="stop-color:#3465a4;stop-opacity:1;"
+ offset="0"
+ id="stop2833" />
+ <stop
+ id="stop2855"
+ offset="0.33333334"
+ style="stop-color:#5b86be;stop-opacity:1;" />
+ <stop
+ style="stop-color:#83a8d8;stop-opacity:0;"
+ offset="1"
+ id="stop2835" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2831"
+ id="linearGradient1486"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-48.30498,-6.043298)"
+ x1="13.478554"
+ y1="10.612206"
+ x2="15.419417"
+ y2="19.115122" />
+ <linearGradient
+ id="linearGradient2380">
+ <stop
+ style="stop-color:#b9cfe7;stop-opacity:1"
+ offset="0"
+ id="stop2382" />
+ <stop
+ style="stop-color:#729fcf;stop-opacity:1"
+ offset="1"
+ id="stop2384" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2682">
+ <stop
+ style="stop-color:#3977c3;stop-opacity:1;"
+ offset="0"
+ id="stop2684" />
+ <stop
+ style="stop-color:#89aedc;stop-opacity:0;"
+ offset="1"
+ id="stop2686" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2682"
+ id="linearGradient2688"
+ x1="36.713837"
+ y1="31.455952"
+ x2="37.124462"
+ y2="24.842253"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-48.77039,-5.765705)" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient2690">
+ <stop
+ style="stop-color:#c4d7eb;stop-opacity:1;"
+ offset="0"
+ id="stop2692" />
+ <stop
+ style="stop-color:#c4d7eb;stop-opacity:0;"
+ offset="1"
+ id="stop2694" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2690"
+ id="linearGradient2696"
+ x1="32.647972"
+ y1="30.748846"
+ x2="37.124462"
+ y2="24.842253"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-48.77039,-5.765705)" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient2871">
+ <stop
+ style="stop-color:#3465a4;stop-opacity:1;"
+ offset="0"
+ id="stop2873" />
+ <stop
+ style="stop-color:#3465a4;stop-opacity:1"
+ offset="1"
+ id="stop2875" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2402">
+ <stop
+ style="stop-color:#729fcf;stop-opacity:1;"
+ offset="0"
+ id="stop2404" />
+ <stop
+ style="stop-color:#528ac5;stop-opacity:1;"
+ offset="1"
+ id="stop2406" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2797"
+ id="linearGradient1493"
+ gradientUnits="userSpaceOnUse"
+ x1="5.9649176"
+ y1="26.048164"
+ x2="52.854097"
+ y2="26.048164" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient2797">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop2799" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop2801" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2797"
+ id="linearGradient1491"
+ gradientUnits="userSpaceOnUse"
+ x1="5.9649176"
+ y1="26.048164"
+ x2="52.854097"
+ y2="26.048164" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient7179">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop7181" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop7183" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2316">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop2318" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.65979379;"
+ offset="1"
+ id="stop2320" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient1322">
+ <stop
+ id="stop1324"
+ offset="0.0000000"
+ style="stop-color:#729fcf" />
+ <stop
+ id="stop1326"
+ offset="1.0000000"
+ style="stop-color:#5187d6;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1322"
+ id="linearGradient4975"
+ x1="34.892849"
+ y1="36.422989"
+ x2="45.918697"
+ y2="48.547989"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-18.01785,-13.57119)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7179"
+ id="linearGradient7185"
+ x1="13.435029"
+ y1="13.604306"
+ x2="22.374878"
+ y2="23.554308"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7179"
+ id="linearGradient7189"
+ gradientUnits="userSpaceOnUse"
+ x1="13.435029"
+ y1="13.604306"
+ x2="22.374878"
+ y2="23.554308"
+ gradientTransform="matrix(-1.000000,0.000000,0.000000,-1.000000,47.93934,50.02474)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2380"
+ id="linearGradient7180"
+ gradientUnits="userSpaceOnUse"
+ x1="62.513836"
+ y1="36.061237"
+ x2="15.984863"
+ y2="20.60858" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2871"
+ id="linearGradient7182"
+ gradientUnits="userSpaceOnUse"
+ x1="46.834816"
+ y1="45.264122"
+ x2="45.380436"
+ y2="50.939667" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2402"
+ id="linearGradient7184"
+ gradientUnits="userSpaceOnUse"
+ x1="18.935766"
+ y1="23.667896"
+ x2="53.588622"
+ y2="26.649362" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2871"
+ id="linearGradient7186"
+ gradientUnits="userSpaceOnUse"
+ x1="46.834816"
+ y1="45.264122"
+ x2="45.380436"
+ y2="50.939667" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7916"
+ id="linearGradient7922"
+ x1="16.874998"
+ y1="22.851799"
+ x2="27.900846"
+ y2="34.976799"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="0.10980392"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1"
+ inkscape:cx="-123.27226"
+ inkscape:cy="26.474252"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:window-width="1280"
+ inkscape:window-height="818"
+ inkscape:window-x="0"
+ inkscape:window-y="30"
+ inkscape:showpageshadow="false" />
+ <metadata
+ id="metadata6436">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Remove</dc:title>
+ <dc:date>2006-01-04</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Andreas Nilsson</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source>http://tango-project.org</dc:source>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>remove</rdf:li>
+ <rdf:li>delete</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/publicdomain/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <path
+ style="font-size:59.901077px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr-tb;text-anchor:start;fill:#75a1d0;fill-opacity:1.0000000;stroke:#3465a4;stroke-width:1.0000004px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans"
+ d="M 27.514356,28.359472 L 39.633445,28.475543 L 39.633445,21.480219 L 27.523285,21.480219 L 20.502546,21.462362 L 8.5441705,21.489147 L 8.5084565,28.457686 L 20.511475,28.475543 L 27.514356,28.359472 z "
+ id="text1314"
+ sodipodi:nodetypes="ccccccccc" />
+ <path
+ style="font-size:59.901077px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125.00000%;writing-mode:lr-tb;text-anchor:start;opacity:0.40860215;fill:url(#linearGradient4975);fill-opacity:1.0000000;stroke:url(#linearGradient7922);stroke-width:1.0000006px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;font-family:Bitstream Vera Sans"
+ d="M 38.579429,27.484113 L 38.588357,22.475309 L 9.5267863,22.493166 L 9.5000003,27.466256 L 38.579429,27.484113 z "
+ id="path7076"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="fill:#ffffff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;opacity:0.31182796"
+ d="M 9.0000000,25.000000 C 9.0000000,26.937500 39.125000,24.062500 39.125000,25.000000 L 39.125000,22.000000 L 9.0000000,22.000000 L 9.0000000,25.000000 z "
+ id="path7914"
+ sodipodi:nodetypes="ccccc" />
+ </g>
+</svg>
diff --git a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-playback-pause.svg b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-playback-pause.svg
new file mode 100644
index 0000000000..8a434cabb1
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-playback-pause.svg
@@ -0,0 +1,641 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="48px"
+ height="48px"
+ id="svg1307"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/actions"
+ sodipodi:docname="media-playback-pause.svg"
+ inkscape:export-filename="/home/lapo/Desktop/Grafica/Icone/media-actions-outlines.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <defs
+ id="defs1309">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 24 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="48 : 24 : 1"
+ inkscape:persp3d-origin="24 : 16 : 1"
+ id="perspective85" />
+ <linearGradient
+ id="linearGradient2817">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop2819" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.48453608;"
+ offset="1"
+ id="stop2821" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2584">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop2586" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop2588" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2697">
+ <stop
+ id="stop2699"
+ offset="0"
+ style="stop-color:#babdb6" />
+ <stop
+ id="stop2701"
+ offset="1"
+ style="stop-color:#555753" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2679"
+ inkscape:collect="always">
+ <stop
+ id="stop2681"
+ offset="0"
+ style="stop-color:#f7f7f7;stop-opacity:1" />
+ <stop
+ id="stop2683"
+ offset="1"
+ style="stop-color:#ccd0c7;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3081">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3083" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3085" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient8662">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop8664" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop8666" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient2112"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(3.562309e-6,-1.07205,1.992104,-1.250658e-6,-42.61165,283.7891)"
+ cx="169.77171"
+ cy="100.20107"
+ fx="169.77171"
+ fy="100.20107"
+ r="11" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2697"
+ id="linearGradient2122"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-12.00000,0.000000)"
+ x1="169"
+ y1="110.33805"
+ x2="169"
+ y2="93.204849" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3081"
+ id="linearGradient2124"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(133.0000,70.99999)"
+ x1="15.089521"
+ y1="15.291994"
+ x2="14"
+ y2="52.510574" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8662"
+ id="radialGradient2137"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,0.536723,4.473733e-13,16.87306)"
+ cx="24.837126"
+ cy="36.421127"
+ fx="24.837126"
+ fy="36.421127"
+ r="15.644737" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8662"
+ id="radialGradient2139"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,0.536723,-1.416456e-12,16.87306)"
+ cx="24.837126"
+ cy="36.421127"
+ fx="24.837126"
+ fy="36.421127"
+ r="15.644737" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8662"
+ id="radialGradient2725"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.536723,4.526469e-13,16.87306)"
+ cx="24.837126"
+ cy="36.421127"
+ fx="24.837126"
+ fy="36.421127"
+ r="15.644737" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8662"
+ id="radialGradient2727"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.536723,-1.432388e-12,16.87306)"
+ cx="24.837126"
+ cy="36.421127"
+ fx="24.837126"
+ fy="36.421127"
+ r="15.644737" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient2729"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(3.562309e-6,-1.07205,1.992104,-1.250658e-6,-42.61165,283.7891)"
+ cx="169.77171"
+ cy="100.20107"
+ fx="169.77171"
+ fy="100.20107"
+ r="11" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2697"
+ id="linearGradient2731"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-12,0)"
+ x1="169"
+ y1="110.33805"
+ x2="169"
+ y2="93.204849" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3081"
+ id="linearGradient2733"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(133,70.99999)"
+ x1="15.089521"
+ y1="15.291994"
+ x2="14"
+ y2="52.510574" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8662"
+ id="radialGradient2745"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.536723,4.579205e-13,16.87306)"
+ cx="24.837126"
+ cy="36.421127"
+ fx="24.837126"
+ fy="36.421127"
+ r="15.644737" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8662"
+ id="radialGradient2747"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.536723,-1.44832e-12,16.87306)"
+ cx="24.837126"
+ cy="36.421127"
+ fx="24.837126"
+ fy="36.421127"
+ r="15.644737" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient2749"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(3.562309e-6,-1.07205,1.992104,-1.250658e-6,-42.61165,283.7891)"
+ cx="169.77171"
+ cy="100.20107"
+ fx="169.77171"
+ fy="100.20107"
+ r="11" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2697"
+ id="linearGradient2751"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-12,0)"
+ x1="169"
+ y1="110.33805"
+ x2="169"
+ y2="93.204849" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3081"
+ id="linearGradient2753"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(133,70.99999)"
+ x1="15.089521"
+ y1="15.291994"
+ x2="14"
+ y2="52.510574" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient2791"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(3.562309e-6,-1.07205,1.992104,-1.250658e-6,-42.61165,283.7891)"
+ cx="169.77171"
+ cy="100.20107"
+ fx="169.77171"
+ fy="100.20107"
+ r="11" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2697"
+ id="linearGradient2793"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-12,0)"
+ x1="169"
+ y1="110.33805"
+ x2="169"
+ y2="93.204849" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2697"
+ id="linearGradient2795"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-12,0)"
+ x1="169"
+ y1="110.33805"
+ x2="169"
+ y2="93.204849" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3081"
+ id="linearGradient2797"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(133,70.99999)"
+ x1="15.089521"
+ y1="15.291994"
+ x2="14"
+ y2="52.510574" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3081"
+ id="linearGradient2800"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-4e-4,-9.426e-2)"
+ x1="15.089521"
+ y1="15.291994"
+ x2="14"
+ y2="52.510574" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2697"
+ id="linearGradient2803"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.004384,-145.0004,-71.4625)"
+ x1="169"
+ y1="110.33805"
+ x2="169"
+ y2="93.204849" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2697"
+ id="linearGradient2806"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-145.0004,-97.0943)"
+ x1="169"
+ y1="110.33805"
+ x2="169"
+ y2="93.204849" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient2809"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(3.562309e-6,-1.07205,1.992104,-1.250658e-6,-175.6121,212.6949)"
+ cx="169.77171"
+ cy="100.20107"
+ fx="169.77171"
+ fy="100.20107"
+ r="11" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2817"
+ id="linearGradient2823"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.103262,0,0,1.054917,-163.1228,-76.31138)"
+ x1="174.83363"
+ y1="84.263489"
+ x2="174.74524"
+ y2="105.49083" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3081"
+ id="linearGradient2825"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-4e-4,-26.09426)"
+ x1="15.089521"
+ y1="15.291994"
+ x2="14"
+ y2="52.510574" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient2831"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(3.562309e-6,-1.07205,1.992104,-1.250658e-6,-175.6121,186.6949)"
+ cx="169.77171"
+ cy="100.20107"
+ fx="169.77171"
+ fy="100.20107"
+ r="11" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2817"
+ id="linearGradient2858"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.103262,0,0,1.054917,-163.1228,-76.31138)"
+ x1="174.83363"
+ y1="84.263489"
+ x2="174.74524"
+ y2="105.49083" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient2860"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(3.562309e-6,-1.07205,1.992104,-1.250658e-6,-175.6121,212.6949)"
+ cx="169.77171"
+ cy="100.20107"
+ fx="169.77171"
+ fy="100.20107"
+ r="11" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2697"
+ id="linearGradient2862"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.004384,-145.0004,-71.4625)"
+ x1="169"
+ y1="110.33805"
+ x2="169"
+ y2="93.204849" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3081"
+ id="linearGradient2864"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-4e-4,-9.426e-2)"
+ x1="15.089521"
+ y1="15.291994"
+ x2="14"
+ y2="52.510574" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="0.19607843"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1"
+ inkscape:cx="-59.41743"
+ inkscape:cy="19.968635"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:grid-points="true"
+ fill="#fcaf3e"
+ showguides="false"
+ inkscape:guide-bbox="true"
+ guidetolerance="1px"
+ stroke="#729fcf"
+ inkscape:window-width="872"
+ inkscape:window-height="688"
+ inkscape:window-x="0"
+ inkscape:window-y="160"
+ showborder="true"
+ inkscape:showpageshadow="false">
+ <sodipodi:guide
+ orientation="horizontal"
+ position="38.996647"
+ id="guide2194" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="9.0140845"
+ id="guide2196" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="9.0140845"
+ id="guide2198" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="38.975184"
+ id="guide2200" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="22.988281"
+ id="guide2202" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="23.908786"
+ id="guide2204" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="157.99417"
+ id="guide4332" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-36.062446"
+ id="guide4334" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-58.02695"
+ id="guide4336" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="180.00287"
+ id="guide4338" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="107.92217"
+ id="guide4417" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="129.93087"
+ id="guide4419" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="19.996875"
+ id="guide5106" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="63.039674"
+ id="guide5119" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="49.066305"
+ id="guide5121" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-86.007168"
+ id="guide5307" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-108.09009"
+ id="guide5309" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-100.15429"
+ id="guide3111" />
+ <inkscape:grid
+ id="GridFromPre046Settings"
+ type="xygrid"
+ originx="0px"
+ originy="0px"
+ spacingx="0.5px"
+ spacingy="0.5px"
+ color="#0000ff"
+ empcolor="#0000ff"
+ opacity="0.2"
+ empopacity="0.4"
+ empspacing="2" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata1312">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Media Playback Pause</dc:title>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Lapo Calamandrei</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>media</rdf:li>
+ <rdf:li>pause</rdf:li>
+ <rdf:li>playback</rdf:li>
+ <rdf:li>video</rdf:li>
+ <rdf:li>music</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/publicdomain/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ style="display:inline">
+ <g
+ id="g2837">
+ <path
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ id="path2815"
+ d="M 26.086565,12.829103 L 26.086565,34.982359 L 34.912658,34.982359 L 34.912658,12.829103 L 26.086565,12.829103 z "
+ style="opacity:0.15;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2823);stroke-width:1.99999952;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <path
+ id="path2827"
+ d="M 26.4996,13.40575 L 26.4996,34.40575 L 34.4996,34.40575 L 34.4996,13.40575 L 26.4996,13.40575 z "
+ style="color:#000000;fill:url(#radialGradient2809);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <path
+ style="color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2803);stroke-width:1.00000012;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 26.4996,13.407946 L 26.4996,34.50001 L 34.4996,34.50001 L 34.4996,13.407946 L 26.4996,13.407946 z "
+ id="path2762"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true" />
+ <path
+ id="path2811"
+ d="M 27.4996,14.40575 L 27.4996,33.40575 L 33.4996,33.40575 L 33.4996,14.40575 L 27.4996,14.40575 z "
+ style="color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2800);stroke-width:0.9999997;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ id="path2479"
+ d="M 28.019106,14.942758 L 28.019106,23.328389 L 33.013048,22.70967 L 33.013048,14.85437 L 28.019106,14.942758 z "
+ style="opacity:0.5;color:#000000;fill:#f7f7f7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible" />
+ </g>
+ <g
+ id="use2844"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true"
+ transform="translate(-12.97229,0)">
+ <path
+ style="opacity:0.15;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2858);stroke-width:1.99999952;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 26.086565,12.829103 L 26.086565,34.982359 L 34.912658,34.982359 L 34.912658,12.829103 L 26.086565,12.829103 z "
+ id="path2848"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true" />
+ <path
+ style="color:#000000;fill:url(#radialGradient2860);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 26.4996,13.40575 L 26.4996,34.40575 L 34.4996,34.40575 L 34.4996,13.40575 L 26.4996,13.40575 z "
+ id="path2850"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true" />
+ <path
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ id="path2852"
+ d="M 26.4996,13.407946 L 26.4996,34.50001 L 34.4996,34.50001 L 34.4996,13.407946 L 26.4996,13.407946 z "
+ style="color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2862);stroke-width:1.00000012;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <path
+ style="color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2864);stroke-width:0.9999997;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 27.4996,14.40575 L 27.4996,33.40575 L 33.4996,33.40575 L 33.4996,14.40575 L 27.4996,14.40575 z "
+ id="path2854"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true" />
+ <path
+ style="opacity:0.5;color:#000000;fill:#f7f7f7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+ d="M 28.019106,14.942758 L 28.019106,25.007768 L 33.013048,24.389049 L 33.013048,14.85437 L 28.019106,14.942758 z "
+ id="path2856"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true"
+ sodipodi:nodetypes="ccccc" />
+ </g>
+ </g>
+</svg>
diff --git a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-playback-start.svg b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-playback-start.svg
new file mode 100644
index 0000000000..75616de46f
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-playback-start.svg
@@ -0,0 +1,319 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="48px"
+ height="48px"
+ id="svg1307"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/actions"
+ sodipodi:docname="media-playback-start.svg"
+ inkscape:export-filename="/home/lapo/Desktop/Grafica/Icone/media-actions-outlines.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <defs
+ id="defs1309">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 24 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="48 : 24 : 1"
+ inkscape:persp3d-origin="24 : 16 : 1"
+ id="perspective49" />
+ <linearGradient
+ id="linearGradient2684">
+ <stop
+ id="stop2686"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop2688"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2584">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop2586" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop2588" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5075">
+ <stop
+ style="stop-color:#adb0a8;stop-opacity:1;"
+ offset="0"
+ id="stop5077" />
+ <stop
+ style="stop-color:#464744;stop-opacity:1"
+ offset="1"
+ id="stop5079" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2691"
+ inkscape:collect="always">
+ <stop
+ id="stop2693"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ <stop
+ id="stop2695"
+ offset="1"
+ style="stop-color:#d3d7cf" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3340">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3342" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.62886596;"
+ offset="1"
+ id="stop3344" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5075"
+ id="linearGradient2306"
+ gradientUnits="userSpaceOnUse"
+ x1="71.288956"
+ y1="124.11652"
+ x2="70.826942"
+ y2="95"
+ gradientTransform="translate(-45.00042,-71.09425)" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2691"
+ id="radialGradient2314"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(5.324342e-2,-0.836238,2.019473,0.128568,-151.9195,108.0768)"
+ cx="107.5884"
+ cy="83.990814"
+ fx="107.5884"
+ fy="83.990814"
+ r="12.551644" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2684"
+ id="linearGradient2690"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.128181,0,0,1.128181,-53.99314,-83.36009)"
+ x1="70.913956"
+ y1="101.74152"
+ x2="70.951942"
+ y2="88.923729" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="0.19607843"
+ inkscape:pageopacity="0.0000000"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1"
+ inkscape:cx="-117.42449"
+ inkscape:cy="12.980288"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:grid-points="true"
+ fill="#555753"
+ showguides="false"
+ inkscape:guide-bbox="true"
+ guidetolerance="1px"
+ stroke="#555753"
+ inkscape:window-width="872"
+ inkscape:window-height="688"
+ inkscape:window-x="326"
+ inkscape:window-y="160"
+ showborder="true"
+ inkscape:showpageshadow="false">
+ <sodipodi:guide
+ orientation="horizontal"
+ position="38.996647"
+ id="guide2194" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="9.0140845"
+ id="guide2196" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="9.0140845"
+ id="guide2198" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="38.975184"
+ id="guide2200" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="22.988281"
+ id="guide2202" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="23.908786"
+ id="guide2204" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="157.99417"
+ id="guide4332" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-36.062446"
+ id="guide4334" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-58.02695"
+ id="guide4336" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="180.00287"
+ id="guide4338" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="107.92217"
+ id="guide4417" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="129.93087"
+ id="guide4419" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="19.996875"
+ id="guide5106" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="63.039674"
+ id="guide5119" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="49.066305"
+ id="guide5121" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-86.007168"
+ id="guide5307" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-108.09009"
+ id="guide5309" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-100.15429"
+ id="guide3111" />
+ <inkscape:grid
+ id="GridFromPre046Settings"
+ type="xygrid"
+ originx="0px"
+ originy="0px"
+ spacingx="0.5px"
+ spacingy="0.5px"
+ color="#0000ff"
+ empcolor="#0000ff"
+ opacity="0.2"
+ empopacity="0.4"
+ empspacing="2" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata1312">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Media Playback Start</dc:title>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Lapo Calamandrei</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>play</rdf:li>
+ <rdf:li>media</rdf:li>
+ <rdf:li>music</rdf:li>
+ <rdf:li>video</rdf:li>
+ <rdf:li>player</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/publicdomain/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:groupmode="layer"
+ id="layer4"
+ inkscape:label="contorno"
+ style="display:inline" />
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ style="display:inline">
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path2682"
+ d="M 12,39.5 L 12,9 L 38.06998,23.817079 L 12,39.5 z "
+ style="color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2690);stroke-width:1.99999833;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;opacity:0.15"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true" />
+ <path
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ style="color:#000000;fill:url(#radialGradient2314);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.00000036;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 12.49946,37.81149 L 12.49946,10.000005 L 36.602747,23.905748 L 12.49946,37.81149 z "
+ id="path3375"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ style="color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2306);stroke-width:1.00000036;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 12.49946,37.81149 L 12.49946,10.000005 L 36.602747,23.905748 L 12.49946,37.81149 z "
+ id="path2479"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 12.99946,10.87449 L 12.99946,36.93699 L 35.59321,23.90574 L 12.99946,10.87449 z M 13.99946,12.62449 L 33.56196,23.90574 L 13.99946,35.18699 L 13.99946,12.62449 z "
+ id="path2481"
+ sodipodi:nodetypes="cccccccc" />
+ <path
+ style="opacity:0.5;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+ d="M 13.9375,12.5625 L 13.9375,24.25 C 18.206698,24.205215 23.101656,23.904436 31,22.375 L 13.9375,12.5625 z "
+ id="path2339"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true"
+ sodipodi:nodetypes="cccc" />
+ </g>
+</svg>
diff --git a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-playback-stop.svg b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-playback-stop.svg
new file mode 100644
index 0000000000..24bbfb52e5
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-playback-stop.svg
@@ -0,0 +1,651 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="48"
+ height="48"
+ id="svg1307"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/actions"
+ sodipodi:docname="media-playback-stop.svg"
+ inkscape:export-filename="/home/lapo/Desktop/Grafica/Icone/media-actions-outlines.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ version="1.0"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <defs
+ id="defs1309">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 24 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="48 : 24 : 1"
+ inkscape:persp3d-origin="24 : 16 : 1"
+ id="perspective82" />
+ <linearGradient
+ id="linearGradient2817">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop2819" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.48453608;"
+ offset="1"
+ id="stop2821" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2584">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop2586" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop2588" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2697">
+ <stop
+ id="stop2699"
+ offset="0"
+ style="stop-color:#babdb6" />
+ <stop
+ id="stop2701"
+ offset="1"
+ style="stop-color:#555753" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2679"
+ inkscape:collect="always">
+ <stop
+ id="stop2681"
+ offset="0"
+ style="stop-color:#f7f7f7;stop-opacity:1" />
+ <stop
+ id="stop2683"
+ offset="1"
+ style="stop-color:#ccd0c7;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3081">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3083" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3085" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient8662">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop8664" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop8666" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient2112"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(3.562309e-6,-1.07205,1.992104,-1.250658e-6,-42.61165,283.7891)"
+ cx="169.77171"
+ cy="100.20107"
+ fx="169.77171"
+ fy="100.20107"
+ r="11" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2697"
+ id="linearGradient2122"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-12,0)"
+ x1="169"
+ y1="110.33805"
+ x2="169"
+ y2="93.204849" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3081"
+ id="linearGradient2124"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(133,70.99999)"
+ x1="15.089521"
+ y1="15.291994"
+ x2="14"
+ y2="52.510574" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8662"
+ id="radialGradient2137"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.536723,4.473733e-13,16.87306)"
+ cx="24.837126"
+ cy="36.421127"
+ fx="24.837126"
+ fy="36.421127"
+ r="15.644737" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8662"
+ id="radialGradient2139"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.536723,-1.416456e-12,16.87306)"
+ cx="24.837126"
+ cy="36.421127"
+ fx="24.837126"
+ fy="36.421127"
+ r="15.644737" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8662"
+ id="radialGradient2725"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.536723,4.526469e-13,16.87306)"
+ cx="24.837126"
+ cy="36.421127"
+ fx="24.837126"
+ fy="36.421127"
+ r="15.644737" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8662"
+ id="radialGradient2727"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.536723,-1.432388e-12,16.87306)"
+ cx="24.837126"
+ cy="36.421127"
+ fx="24.837126"
+ fy="36.421127"
+ r="15.644737" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient2729"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(3.562309e-6,-1.07205,1.992104,-1.250658e-6,-42.61165,283.7891)"
+ cx="169.77171"
+ cy="100.20107"
+ fx="169.77171"
+ fy="100.20107"
+ r="11" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2697"
+ id="linearGradient2731"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-12,0)"
+ x1="169"
+ y1="110.33805"
+ x2="169"
+ y2="93.204849" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3081"
+ id="linearGradient2733"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(133,70.99999)"
+ x1="15.089521"
+ y1="15.291994"
+ x2="14"
+ y2="52.510574" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8662"
+ id="radialGradient2745"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.536723,4.579205e-13,16.87306)"
+ cx="24.837126"
+ cy="36.421127"
+ fx="24.837126"
+ fy="36.421127"
+ r="15.644737" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8662"
+ id="radialGradient2747"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.536723,-1.44832e-12,16.87306)"
+ cx="24.837126"
+ cy="36.421127"
+ fx="24.837126"
+ fy="36.421127"
+ r="15.644737" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient2749"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(3.562309e-6,-1.07205,1.992104,-1.250658e-6,-42.61165,283.7891)"
+ cx="169.77171"
+ cy="100.20107"
+ fx="169.77171"
+ fy="100.20107"
+ r="11" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2697"
+ id="linearGradient2751"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-12,0)"
+ x1="169"
+ y1="110.33805"
+ x2="169"
+ y2="93.204849" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3081"
+ id="linearGradient2753"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(133,70.99999)"
+ x1="15.089521"
+ y1="15.291994"
+ x2="14"
+ y2="52.510574" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient2791"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(3.562309e-6,-1.07205,1.992104,-1.250658e-6,-42.61165,283.7891)"
+ cx="169.77171"
+ cy="100.20107"
+ fx="169.77171"
+ fy="100.20107"
+ r="11" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2697"
+ id="linearGradient2793"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-12,0)"
+ x1="169"
+ y1="110.33805"
+ x2="169"
+ y2="93.204849" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2697"
+ id="linearGradient2795"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-12,0)"
+ x1="169"
+ y1="110.33805"
+ x2="169"
+ y2="93.204849" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3081"
+ id="linearGradient2797"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(133,70.99999)"
+ x1="15.089521"
+ y1="15.291994"
+ x2="14"
+ y2="52.510574" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3081"
+ id="linearGradient2800"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-4e-4,-9.426e-2)"
+ x1="15.089521"
+ y1="15.291994"
+ x2="14"
+ y2="52.510574" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2697"
+ id="linearGradient2803"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.004384,-145.0004,-71.4625)"
+ x1="169"
+ y1="110.33805"
+ x2="169"
+ y2="93.204849" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2697"
+ id="linearGradient2806"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-145.0004,-97.0943)"
+ x1="169"
+ y1="110.33805"
+ x2="169"
+ y2="93.204849" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient2809"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(3.562309e-6,-1.07205,1.992104,-1.250658e-6,-175.6121,212.6949)"
+ cx="169.77171"
+ cy="100.20107"
+ fx="169.77171"
+ fy="100.20107"
+ r="11" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2817"
+ id="linearGradient2823"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.103262,0,0,1.054917,-163.1228,-76.31138)"
+ x1="174.83363"
+ y1="84.263489"
+ x2="174.74524"
+ y2="105.49083" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3081"
+ id="linearGradient2825"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-4e-4,-26.09426)"
+ x1="15.089521"
+ y1="15.291994"
+ x2="14"
+ y2="52.510574" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient2831"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(3.562309e-6,-1.07205,1.992104,-1.250658e-6,-175.6121,186.6949)"
+ cx="169.77171"
+ cy="100.20107"
+ fx="169.77171"
+ fy="100.20107"
+ r="11" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2817"
+ id="linearGradient2858"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.103262,0,0,1.054917,-163.1228,-76.31138)"
+ x1="174.83363"
+ y1="84.263489"
+ x2="174.74524"
+ y2="105.49083" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient2860"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(3.562309e-6,-1.07205,1.992104,-1.250658e-6,-175.6121,212.6949)"
+ cx="169.77171"
+ cy="100.20107"
+ fx="169.77171"
+ fy="100.20107"
+ r="11" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2697"
+ id="linearGradient2862"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.004384,-145.0004,-71.4625)"
+ x1="169"
+ y1="110.33805"
+ x2="169"
+ y2="93.204849" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3081"
+ id="linearGradient2864"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-4e-4,-9.426e-2)"
+ x1="15.089521"
+ y1="15.291994"
+ x2="14"
+ y2="52.510574" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3081"
+ id="linearGradient3421"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(3.000198,0,0,1,-67.006,-9.426e-2)"
+ x1="15.089521"
+ y1="15.291994"
+ x2="14"
+ y2="52.510574" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2697"
+ id="linearGradient3424"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.498884,0,0,1.004384,-414.0618,-71.4625)"
+ x1="169"
+ y1="110.33805"
+ x2="169"
+ y2="93.204849" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient3427"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(8.905772e-6,-1.07205,4.98026,-1.250658e-6,-490.7792,212.6949)"
+ cx="169.77171"
+ cy="100.20107"
+ fx="169.77171"
+ fy="100.20107"
+ r="11" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2817"
+ id="linearGradient3430"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.624525,0,0,1.054917,-436.1019,-76.31138)"
+ x1="174.83363"
+ y1="84.263489"
+ x2="174.74524"
+ y2="105.49083" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="0.19607843"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="4"
+ inkscape:cx="-0.153018"
+ inkscape:cy="25.719637"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:grid-points="true"
+ fill="#fcaf3e"
+ showguides="false"
+ inkscape:guide-bbox="true"
+ guidetolerance="1px"
+ stroke="#729fcf"
+ inkscape:window-width="872"
+ inkscape:window-height="688"
+ inkscape:window-x="0"
+ inkscape:window-y="160"
+ showborder="true"
+ inkscape:showpageshadow="false">
+ <sodipodi:guide
+ orientation="horizontal"
+ position="38.996647"
+ id="guide2194" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="9.0140845"
+ id="guide2196" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="9.0140845"
+ id="guide2198" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="38.975184"
+ id="guide2200" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="22.988281"
+ id="guide2202" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="23.908786"
+ id="guide2204" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="157.99417"
+ id="guide4332" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-36.062446"
+ id="guide4334" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-58.02695"
+ id="guide4336" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="180.00287"
+ id="guide4338" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="107.92217"
+ id="guide4417" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="129.93087"
+ id="guide4419" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="19.996875"
+ id="guide5106" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="63.039674"
+ id="guide5119" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="49.066305"
+ id="guide5121" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-86.007168"
+ id="guide5307" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-108.09009"
+ id="guide5309" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-100.15429"
+ id="guide3111" />
+ <inkscape:grid
+ id="GridFromPre046Settings"
+ type="xygrid"
+ originx="0px"
+ originy="0px"
+ spacingx="0.5px"
+ spacingy="0.5px"
+ color="#0000ff"
+ empcolor="#0000ff"
+ opacity="0.2"
+ empopacity="0.4"
+ empspacing="2" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata1312">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Media Playback Pause</dc:title>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Lapo Calamandrei</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>media</rdf:li>
+ <rdf:li>stop</rdf:li>
+ <rdf:li>playback</rdf:li>
+ <rdf:li>video</rdf:li>
+ <rdf:li>music</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/publicdomain/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ style="display:inline"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true">
+ <path
+ style="opacity:0.15;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient3430);stroke-width:1.99999952;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 14.00382,12.829103 L 14.00382,34.982359 L 35.000004,34.982359 L 35.000004,12.829103 L 14.00382,12.829103 z "
+ id="path2815"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true" />
+ <path
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ style="color:#000000;fill:url(#radialGradient3427);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 14.5,13.40575 L 14.5,34.40575 L 34.5,34.40575 L 34.5,13.40575 L 14.5,13.40575 z "
+ id="path2827" />
+ <path
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ id="path2762"
+ d="M 14.496737,13.407946 L 14.496737,34.50001 L 34.487808,34.50001 L 34.487808,13.407946 L 14.496737,13.407946 z "
+ style="color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient3424);stroke-width:0.99999952;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <path
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ style="color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient3421);stroke-width:0.99999976;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 15.499412,14.40575 L 15.499412,33.40575 L 33.500595,33.40575 L 33.500595,14.40575 L 15.499412,14.40575 z "
+ id="path2811" />
+ <path
+ style="opacity:0.5;color:#000000;fill:#f7f7f7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
+ d="M 16,14.942758 L 16,25.5 L 33,22.70967 L 33,14.85437 L 16,14.942758 z "
+ id="path2479"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true"
+ sodipodi:nodetypes="ccccc" />
+ </g>
+</svg>
diff --git a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-record.svg b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-record.svg
new file mode 100644
index 0000000000..85bbb98f6e
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-record.svg
@@ -0,0 +1,337 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="48px"
+ height="48px"
+ id="svg1307"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/actions"
+ sodipodi:docname="media-record.svg"
+ inkscape:export-filename="/home/lapo/Desktop/Grafica/Icone/media-actions-outlines.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <defs
+ id="defs1309">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 24 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="48 : 24 : 1"
+ inkscape:persp3d-origin="24 : 16 : 1"
+ id="perspective47" />
+ <linearGradient
+ id="linearGradient3837">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop3839" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.78350514;"
+ offset="1"
+ id="stop3841" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2257">
+ <stop
+ style="stop-color:#ef2929"
+ offset="0"
+ id="stop2259" />
+ <stop
+ style="stop-color:#cc0000"
+ offset="1"
+ id="stop2261" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3340">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3342" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3344" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient8662">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop8664" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop8666" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8662"
+ id="radialGradient2228"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.536723,-3.241652e-13,16.87306)"
+ cx="24.837126"
+ cy="36.421127"
+ fx="24.837126"
+ fy="36.421127"
+ r="15.644737" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3340"
+ id="radialGradient1368"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(3.658819,-3.13388e-16,1.719536e-16,2.080782,-62.4164,12.76204)"
+ cx="21.929186"
+ cy="-3.2182934"
+ fx="21.929186"
+ fy="-3.2182934"
+ r="13" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2257"
+ id="radialGradient2263"
+ cx="22.5"
+ cy="28.116049"
+ fx="22.5"
+ fy="28.116049"
+ r="14.537862"
+ gradientTransform="matrix(2.365562,-4.942242e-16,5.359766e-16,2.202845,-30.72517,-34.23996)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3837"
+ id="linearGradient3843"
+ x1="21.702389"
+ y1="8.9115314"
+ x2="21.816015"
+ y2="35.546108"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2257"
+ id="radialGradient3845"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.365562,-4.942242e-16,5.359766e-16,2.202845,-30.72517,-34.23996)"
+ cx="22.5"
+ cy="28.116049"
+ fx="22.5"
+ fy="28.116049"
+ r="14.537862" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="0.11372549"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1"
+ inkscape:cx="-125.50077"
+ inkscape:cy="34.59508"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:grid-points="true"
+ fill="#ef2929"
+ showguides="false"
+ inkscape:guide-bbox="true"
+ guidetolerance="1px"
+ stroke="#ef2929"
+ inkscape:window-width="872"
+ inkscape:window-height="688"
+ inkscape:window-x="494"
+ inkscape:window-y="160"
+ showborder="true"
+ inkscape:showpageshadow="false">
+ <sodipodi:guide
+ orientation="horizontal"
+ position="38.996647"
+ id="guide2194" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="9.0140845"
+ id="guide2196" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="9.0140845"
+ id="guide2198" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="38.975184"
+ id="guide2200" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="22.988281"
+ id="guide2202" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="23.908786"
+ id="guide2204" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="157.99417"
+ id="guide4332" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-36.062446"
+ id="guide4334" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-58.02695"
+ id="guide4336" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="180.00287"
+ id="guide4338" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="107.92217"
+ id="guide4417" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="129.93087"
+ id="guide4419" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="19.996875"
+ id="guide5106" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="63.039674"
+ id="guide5119" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="49.066305"
+ id="guide5121" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-86.007168"
+ id="guide5307" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-108.09009"
+ id="guide5309" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-100.15429"
+ id="guide3111" />
+ <inkscape:grid
+ id="GridFromPre046Settings"
+ type="xygrid"
+ originx="0px"
+ originy="0px"
+ spacingx="0.5px"
+ spacingy="0.5px"
+ color="#0000ff"
+ empcolor="#0000ff"
+ opacity="0.2"
+ empopacity="0.4"
+ empspacing="2" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata1312">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Media Record</dc:title>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Lapo Calamandrei</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>media</rdf:li>
+ <rdf:li>player</rdf:li>
+ <rdf:li>record</rdf:li>
+ <rdf:li>music</rdf:li>
+ <rdf:li>sound</rdf:li>
+ <rdf:li>video</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/publicdomain/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ style="display:inline">
+ <path
+ transform="matrix(0.920697,0,0,0.99358,3.679484,1.641236)"
+ d="M 36.5 22 A 14 13 0 1 1 8.5,22 A 14 13 0 1 1 36.5 22 z"
+ sodipodi:ry="13"
+ sodipodi:rx="14"
+ sodipodi:cy="22"
+ sodipodi:cx="22.5"
+ id="path3835"
+ style="opacity:0.15;color:#000000;fill:url(#radialGradient3845);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient3843);stroke-width:3.13661647;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true" />
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="/home/lapo/Desktop/Grafica/Icone/media-actions.png"
+ sodipodi:type="arc"
+ style="opacity:0.03999999;color:#000000;fill:url(#radialGradient2228);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="path2226"
+ sodipodi:cx="24.837126"
+ sodipodi:cy="36.421127"
+ sodipodi:rx="15.644737"
+ sodipodi:ry="8.3968935"
+ d="M 40.481863 36.421127 A 15.644737 8.3968935 0 1 1 9.1923885,36.421127 A 15.644737 8.3968935 0 1 1 40.481863 36.421127 z"
+ transform="matrix(1.150533,0,0,0.565685,-4.5765,16.55285)" />
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill:url(#radialGradient2263);fill-opacity:1.0;fill-rule:evenodd;stroke:#cc0000;stroke-width:1.0757246;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="path2525"
+ sodipodi:cx="22.5"
+ sodipodi:cy="22"
+ sodipodi:rx="14"
+ sodipodi:ry="13"
+ d="M 36.5 22 A 14 13 0 1 1 8.5,22 A 14 13 0 1 1 36.5 22 z"
+ transform="matrix(0.894862,0,0,0.9657,3.855776,2.660348)" />
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#f77d7d;stroke-width:1.21739173;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="path2527"
+ sodipodi:cx="24"
+ sodipodi:cy="24"
+ sodipodi:rx="14"
+ sodipodi:ry="14"
+ d="M 38 24 A 14 14 0 1 1 10,24 A 14 14 0 1 1 38 24 z"
+ transform="matrix(0.821429,0,0,0.821429,4.285117,4.191455)" />
+ <path
+ style="opacity:0.6;fill:url(#radialGradient1368);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.25pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="M 23.84315,11.90574 C 17.563618,11.985335 12.438727,16.897799 12.03065,23.09324 C 18.148473,25.61002 25.90107,21.642017 35.172655,19.711354 C 34.484245,16.962785 30.617935,11.90574 23.9994,11.90574 C 23.947693,11.90574 23.894703,11.905087 23.84315,11.90574 z "
+ id="path2529"
+ sodipodi:nodetypes="cccsc" />
+ </g>
+</svg>
diff --git a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-seek-backward.svg b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-seek-backward.svg
new file mode 100644
index 0000000000..75f49f1a82
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-seek-backward.svg
@@ -0,0 +1,374 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="48px"
+ height="48px"
+ id="svg1307"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/actions"
+ sodipodi:docname="media-seek-backward.svg"
+ inkscape:export-filename="/home/lapo/Desktop/Grafica/Icone/media-actions-outlines.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <defs
+ id="defs1309">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 24 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="48 : 24 : 1"
+ inkscape:persp3d-origin="24 : 16 : 1"
+ id="perspective58" />
+ <linearGradient
+ id="linearGradient2316">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop2318" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.65979379;"
+ offset="1"
+ id="stop2320" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2584">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop2586" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop2588" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5075">
+ <stop
+ style="stop-color:#adb0a8;stop-opacity:1;"
+ offset="0"
+ id="stop5077" />
+ <stop
+ style="stop-color:#464744;stop-opacity:1"
+ offset="1"
+ id="stop5079" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2679"
+ inkscape:collect="always">
+ <stop
+ id="stop2681"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ <stop
+ id="stop2683"
+ offset="1"
+ style="stop-color:#d3d7cf" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2591">
+ <stop
+ id="stop2593"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop2595"
+ offset="1"
+ style="stop-color:#eeeeec;stop-opacity:0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient8662">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop8664" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop8666" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8662"
+ id="radialGradient1932"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.536723,4.095103e-13,16.87306)"
+ cx="24.837126"
+ cy="36.421127"
+ fx="24.837126"
+ fy="36.421127"
+ r="15.644737" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5075"
+ id="linearGradient1401"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-47.9996,-121)"
+ x1="54.988514"
+ y1="156"
+ x2="54.896976"
+ y2="142.18799" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient1426"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-44.99051,-97.26213)"
+ x1="49.430401"
+ y1="112.94963"
+ x2="49.667324"
+ y2="115.13713" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient1436"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.222659,-0.996273,2.129992,0.476041,-290.946,20.8517)"
+ cx="64.227074"
+ cy="147.99352"
+ fx="64.227074"
+ fy="147.99352"
+ r="8.75" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient1439"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.222659,-0.996273,2.129992,0.476041,-308.946,20.8517)"
+ cx="64.227074"
+ cy="147.99352"
+ fx="64.227074"
+ fy="147.99352"
+ r="8.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2316"
+ id="linearGradient2322"
+ x1="24.476166"
+ y1="13.658564"
+ x2="23.750401"
+ y2="36"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="0.15294118"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="8"
+ inkscape:cx="44.949418"
+ inkscape:cy="17.655272"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:grid-points="true"
+ fill="#fcaf3e"
+ showguides="false"
+ inkscape:guide-bbox="true"
+ guidetolerance="1px"
+ stroke="#729fcf"
+ inkscape:window-width="1144"
+ inkscape:window-height="808"
+ inkscape:window-x="290"
+ inkscape:window-y="34"
+ showborder="true"
+ inkscape:showpageshadow="false"
+ borderlayer="top">
+ <sodipodi:guide
+ orientation="horizontal"
+ position="38.996647"
+ id="guide2194" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="9.0140845"
+ id="guide2196" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="9.0140845"
+ id="guide2198" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="38.975184"
+ id="guide2200" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="22.988281"
+ id="guide2202" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="23.908786"
+ id="guide2204" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="157.99417"
+ id="guide4332" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-36.062446"
+ id="guide4334" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-58.02695"
+ id="guide4336" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="180.00287"
+ id="guide4338" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="107.92217"
+ id="guide4417" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="129.93087"
+ id="guide4419" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="19.996875"
+ id="guide5106" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="63.039674"
+ id="guide5119" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="49.066305"
+ id="guide5121" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-87.043372"
+ id="guide5307" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-102.03286"
+ id="guide5309" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-100.04058"
+ id="guide3111" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-92.545841"
+ id="guide1879" />
+ <inkscape:grid
+ id="GridFromPre046Settings"
+ type="xygrid"
+ originx="0px"
+ originy="0px"
+ spacingx="0.5px"
+ spacingy="0.5px"
+ color="#0000ff"
+ empcolor="#0000ff"
+ opacity="0.2"
+ empopacity="0.4"
+ empspacing="2" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata1312">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Media Seek Backward</dc:title>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Lapo Calamandrei</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/publicdomain/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ style="display:inline">
+ <path
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ sodipodi:nodetypes="cccccccc"
+ id="path1441"
+ d="M 23.5004,13.5 L 6.0004,24 L 23.5004,34.5 L 23.5004,13.5 z M 41.5004,13.5 L 24.0004,24 L 41.5004,34.5 L 41.5004,13.5 z "
+ style="color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2322);stroke-width:3;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;opacity:0.15" />
+ <path
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="/home/lapo/Desktop/Grafica/Icone/media-actions.png"
+ sodipodi:nodetypes="cccc"
+ id="path5515"
+ d="M 23.5004,13.5 L 6.0004,24 L 23.5004,34.5 L 23.5004,13.5 z "
+ style="color:#000000;fill:url(#radialGradient1439);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.0000006;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <path
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ style="color:#000000;fill:url(#radialGradient1436);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.0000006;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 41.5004,13.5 L 24.0004,24 L 41.5004,34.5 L 41.5004,13.5 z "
+ id="use5517"
+ sodipodi:nodetypes="cccc"
+ inkscape:export-filename="/home/lapo/Desktop/Grafica/Icone/media-actions.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ sodipodi:nodetypes="ccccccccc"
+ style="opacity:0.07027025;color:#000000;fill:url(#linearGradient1426);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 41.5004,13.5 L 40.3129,14.21875 L 41.5004,14.09375 L 41.5004,13.5 z M 23.5004,13.75 L 23.03165,13.78125 L 19.0629,16.15625 L 23.5004,15.75 L 23.5004,13.75 z "
+ id="path2915" />
+ <path
+ style="color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient1401);stroke-width:1.0000006;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 23.5004,13.5 L 6.0004,24 L 23.5004,34.5 L 23.5004,13.5 z M 41.5004,13.5 L 24.0004,24 L 41.5004,34.5 L 41.5004,13.5 z "
+ id="path5521"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true" />
+ <path
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 23.0004,14.375 L 6.96915,24 L 23.0004,33.625 L 23.0004,14.375 z M 41.0004,14.375 L 24.96915,24 L 41.0004,33.625 L 41.0004,14.375 z M 22.0004,16.15625 L 22.0004,31.84375 L 8.90665,24 L 22.0004,16.15625 z M 40.0004,16.15625 L 40.0004,31.84375 L 26.90665,24 L 40.0004,16.15625 z "
+ id="path5525"
+ sodipodi:nodetypes="cccccccccccccccc"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true" />
+ <path
+ style="opacity:0.56111111;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 9.9375,23.375 L 21.9375,16.1875 L 21.9375,22.9375 L 9.9375,23.375 z "
+ id="path3197"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true" />
+ <path
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ id="path4072"
+ d="M 29.3125,22.5 L 40,16.1875 L 40,21.9375 L 29.3125,22.5 z "
+ style="opacity:0.56111109;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ sodipodi:nodetypes="cccc" />
+ </g>
+</svg>
diff --git a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-seek-forward.svg b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-seek-forward.svg
new file mode 100644
index 0000000000..b1b9fe950b
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-seek-forward.svg
@@ -0,0 +1,383 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="48px"
+ height="48px"
+ id="svg1307"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/actions"
+ sodipodi:docname="media-seek-forward.svg"
+ inkscape:export-filename="/home/lapo/Desktop/Grafica/Icone/media-actions-outlines.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <defs
+ id="defs1309">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 24 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="48 : 24 : 1"
+ inkscape:persp3d-origin="24 : 16 : 1"
+ id="perspective58" />
+ <linearGradient
+ id="linearGradient2316">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop2318" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.65979379;"
+ offset="1"
+ id="stop2320" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2584">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop2586" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop2588" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5075">
+ <stop
+ style="stop-color:#adb0a8;stop-opacity:1;"
+ offset="0"
+ id="stop5077" />
+ <stop
+ style="stop-color:#464744;stop-opacity:1"
+ offset="1"
+ id="stop5079" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2679"
+ inkscape:collect="always">
+ <stop
+ id="stop2681"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ <stop
+ id="stop2683"
+ offset="1"
+ style="stop-color:#d3d7cf" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2591">
+ <stop
+ id="stop2593"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop2595"
+ offset="1"
+ style="stop-color:#eeeeec;stop-opacity:0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient8662">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop8664" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop8666" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8662"
+ id="radialGradient1932"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.536723,4.094188e-13,16.87306)"
+ cx="24.837126"
+ cy="36.421127"
+ fx="24.837126"
+ fy="36.421127"
+ r="15.644737" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5075"
+ id="linearGradient1401"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,95.99994,-121)"
+ x1="53.499996"
+ y1="158.41438"
+ x2="53.499996"
+ y2="142.05258" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient1426"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,92.99085,-97.26213)"
+ x1="49.430401"
+ y1="112.94963"
+ x2="49.667324"
+ y2="115.13713" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient1436"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.222659,-0.996273,-2.129992,0.476041,338.9463,20.8517)"
+ cx="64.227074"
+ cy="147.99352"
+ fx="64.227074"
+ fy="147.99352"
+ r="8.75" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient1439"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.222659,-0.996273,-2.129992,0.476041,356.9463,20.8517)"
+ cx="64.227074"
+ cy="147.99352"
+ fx="64.227074"
+ fy="147.99352"
+ r="8.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2316"
+ id="linearGradient2322"
+ x1="24.476166"
+ y1="13.658564"
+ x2="23.750401"
+ y2="36"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,48.00034,0)" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="0.15294118"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="5.6568542"
+ inkscape:cx="46.567445"
+ inkscape:cy="3.7129274"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:grid-points="true"
+ fill="#fcaf3e"
+ showguides="false"
+ inkscape:guide-bbox="true"
+ guidetolerance="1px"
+ stroke="#729fcf"
+ inkscape:window-width="1144"
+ inkscape:window-height="808"
+ inkscape:window-x="290"
+ inkscape:window-y="40"
+ showborder="true"
+ inkscape:showpageshadow="false"
+ borderlayer="top">
+ <sodipodi:guide
+ orientation="horizontal"
+ position="38.996647"
+ id="guide2194" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="9.0140845"
+ id="guide2196" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="9.0140845"
+ id="guide2198" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="38.975184"
+ id="guide2200" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="22.988281"
+ id="guide2202" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="23.908786"
+ id="guide2204" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="157.99417"
+ id="guide4332" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-36.062446"
+ id="guide4334" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-58.02695"
+ id="guide4336" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="180.00287"
+ id="guide4338" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="107.92217"
+ id="guide4417" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="129.93087"
+ id="guide4419" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="19.996875"
+ id="guide5106" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="63.039674"
+ id="guide5119" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="49.066305"
+ id="guide5121" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-87.043372"
+ id="guide5307" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-102.03286"
+ id="guide5309" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-100.04058"
+ id="guide3111" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-92.545841"
+ id="guide1879" />
+ <inkscape:grid
+ id="GridFromPre046Settings"
+ type="xygrid"
+ originx="0px"
+ originy="0px"
+ spacingx="0.5px"
+ spacingy="0.5px"
+ color="#0000ff"
+ empcolor="#0000ff"
+ opacity="0.2"
+ empopacity="0.4"
+ empspacing="2"
+ visible="true"
+ enabled="true" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata1312">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Media Seek Forward</dc:title>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Lapo Calamandrei</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/publicdomain/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ style="display:inline">
+ <path
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ sodipodi:nodetypes="cccccccc"
+ id="path1441"
+ d="M 24.499943,13.5 L 41.999943,24 L 24.499943,34.5 L 24.499943,13.5 z M 6.4999427,13.5 L 23.999943,24 L 6.4999427,34.5 L 6.4999427,13.5 z "
+ style="opacity:0.15;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2322);stroke-width:3;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <path
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="/home/lapo/Desktop/Grafica/Icone/media-actions.png"
+ sodipodi:nodetypes="cccc"
+ id="path5515"
+ d="M 24.499943,13.5 L 41.999943,24 L 24.499943,34.5 L 24.499943,13.5 z "
+ style="color:#000000;fill:url(#radialGradient1439);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.0000006;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <path
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ style="color:#000000;fill:url(#radialGradient1436);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.0000006;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 6.4999427,13.5 L 23.999943,24 L 6.4999427,34.5 L 6.4999427,13.5 z "
+ id="use5517"
+ sodipodi:nodetypes="cccc"
+ inkscape:export-filename="/home/lapo/Desktop/Grafica/Icone/media-actions.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ sodipodi:nodetypes="ccccccccc"
+ style="opacity:0.07027025;color:#000000;fill:url(#linearGradient1426);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 6.4999427,13.5 L 7.6874427,14.21875 L 6.4999427,14.09375 L 6.4999427,13.5 z M 24.499943,13.75 L 24.968693,13.78125 L 28.937443,16.15625 L 24.499943,15.75 L 24.499943,13.75 z "
+ id="path2915" />
+ <path
+ style="color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient1401);stroke-width:1.0000006;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 24.499943,13.5 L 41.999943,24 L 24.499943,34.5 L 24.499943,13.5 z M 6.4999427,13.5 L 23.999943,24 L 6.4999427,34.5 L 6.4999427,13.5 z "
+ id="path5521"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true" />
+ <path
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 24.999943,14.375 L 41.031193,24 L 24.999943,33.625 L 24.999943,14.375 z M 6.9999427,14.375 L 23.031193,24 L 6.9999427,33.625 L 6.9999427,14.375 z M 25.999943,16.15625 L 25.999943,31.84375 L 39.093693,24 L 25.999943,16.15625 z M 7.9999427,16.15625 L 7.9999427,31.84375 L 21.093693,24 L 7.9999427,16.15625 z "
+ id="path5525"
+ sodipodi:nodetypes="cccccccccccccccc"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true" />
+ <path
+ style="opacity:0.56111109;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 35.587969,21.78401 L 26.062843,16.1875 L 26.062843,22.230393 L 35.587969,21.78401 z "
+ id="path3197"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ id="path4072"
+ d="M 20.278833,23.207107 L 8.0003427,16.1875 L 8.0003427,24.05882 L 20.278833,23.207107 z "
+ style="opacity:0.56111109;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ sodipodi:nodetypes="cccc" />
+ </g>
+</svg>
diff --git a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-skip-backward.svg b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-skip-backward.svg
new file mode 100644
index 0000000000..fccd7762cd
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-skip-backward.svg
@@ -0,0 +1,1025 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="48px"
+ height="48px"
+ id="svg1307"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/actions"
+ sodipodi:docname="media-skip-backward.svg"
+ inkscape:export-filename="/home/lapo/Desktop/Grafica/Icone/media-actions-outlines.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <defs
+ id="defs1309">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 24 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="48 : 24 : 1"
+ inkscape:persp3d-origin="24 : 16 : 1"
+ id="perspective127" />
+ <linearGradient
+ id="linearGradient2316">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop2318" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.65979379;"
+ offset="1"
+ id="stop2320" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2584">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop2586" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop2588" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5075">
+ <stop
+ style="stop-color:#adb0a8;stop-opacity:1;"
+ offset="0"
+ id="stop5077" />
+ <stop
+ style="stop-color:#464744;stop-opacity:1"
+ offset="1"
+ id="stop5079" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2679"
+ inkscape:collect="always">
+ <stop
+ id="stop2681"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ <stop
+ id="stop2683"
+ offset="1"
+ style="stop-color:#d3d7cf" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2591">
+ <stop
+ id="stop2593"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop2595"
+ offset="1"
+ style="stop-color:#eeeeec;stop-opacity:0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient8662">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop8664" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop8666" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8662"
+ id="radialGradient1932"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.536723,3.953052e-13,16.87306)"
+ cx="24.837126"
+ cy="36.421127"
+ fx="24.837126"
+ fy="36.421127"
+ r="15.644737" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5075"
+ id="linearGradient1401"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-45.99994,-121)"
+ x1="55.886486"
+ y1="157.70728"
+ x2="55.936192"
+ y2="142.93646" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient1426"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-42.99085,-97.26213)"
+ x1="49.430401"
+ y1="112.94963"
+ x2="49.667324"
+ y2="115.13713" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient1436"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.222659,-0.996273,2.129992,0.476041,-288.9463,20.8517)"
+ cx="64.227074"
+ cy="147.99352"
+ fx="64.227074"
+ fy="147.99352"
+ r="8.75" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient1439"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.222659,-0.996273,2.129992,0.476041,-306.9463,20.8517)"
+ cx="64.227074"
+ cy="147.99352"
+ fx="64.227074"
+ fy="147.99352"
+ r="8.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2316"
+ id="linearGradient2322"
+ x1="24.476166"
+ y1="13.658564"
+ x2="23.750401"
+ y2="36"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,46.00034,0)" />
+ <radialGradient
+ r="8.75"
+ fy="146.18817"
+ fx="64.214218"
+ cy="146.18817"
+ cx="64.214218"
+ gradientTransform="matrix(0.264218,-0.986066,-2.238896,-0.59991,468.602,298.4876)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient1535"
+ xlink:href="#linearGradient2679"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="142.03874"
+ x2="89.066872"
+ y1="155.00908"
+ x1="90"
+ gradientTransform="matrix(-1,4.681043e-17,-4.681043e-17,-1,326,290)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2331"
+ xlink:href="#linearGradient5075"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="140.03592"
+ x2="89"
+ y1="149.4554"
+ x1="89"
+ gradientTransform="matrix(-1,0,0,-1,326,290)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2329"
+ xlink:href="#linearGradient2591"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="142.00146"
+ x2="49"
+ y1="155"
+ x1="52.048431"
+ gradientTransform="translate(-326,-290)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2327"
+ xlink:href="#linearGradient2591"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="113.80963"
+ x2="56.941994"
+ y1="107.94752"
+ x1="55.934441"
+ gradientTransform="translate(146.4002,36.96061)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2325"
+ xlink:href="#linearGradient8662"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="106.38314"
+ x2="54.712406"
+ y1="102.97689"
+ x1="54.346024"
+ gradientTransform="translate(146.4002,36.96061)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2323"
+ xlink:href="#linearGradient2584"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="101.35189"
+ x2="53.201031"
+ y1="99.445641"
+ x1="53.017841"
+ gradientTransform="translate(146.4002,36.96061)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2321"
+ xlink:href="#linearGradient2584"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="122.29481"
+ x2="54.390476"
+ y1="116.38297"
+ x1="53.931114"
+ gradientTransform="translate(146.4002,36.96061)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2319"
+ xlink:href="#linearGradient2584"
+ inkscape:collect="always" />
+ <radialGradient
+ r="8.75"
+ fy="146.18817"
+ fx="64.214218"
+ cy="146.18817"
+ cx="64.214218"
+ gradientTransform="matrix(0.264218,-0.986066,-2.238896,-0.59991,486.602,298.4876)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2317"
+ xlink:href="#linearGradient2679"
+ inkscape:collect="always" />
+ <radialGradient
+ r="8.75"
+ fy="147.99352"
+ fx="64.227074"
+ cy="147.99352"
+ cx="64.227074"
+ gradientTransform="matrix(-0.222659,-0.996273,-2.129992,0.476041,604.946,141.8517)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2315"
+ xlink:href="#linearGradient2679"
+ inkscape:collect="always" />
+ <radialGradient
+ r="15.644737"
+ fy="36.421127"
+ fx="24.837126"
+ cy="36.421127"
+ cx="24.837126"
+ gradientTransform="matrix(1,0,0,0.536723,-1.836182e-12,16.87306)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2313"
+ xlink:href="#linearGradient8662"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient4219">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop4221" />
+ <stop
+ style="stop-color:#eeeeec;stop-opacity:0"
+ offset="1"
+ id="stop4223" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4207">
+ <stop
+ id="stop4209"
+ offset="0"
+ style="stop-color:#adb0a8;stop-opacity:1;" />
+ <stop
+ id="stop4211"
+ offset="1"
+ style="stop-color:#464744;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4201">
+ <stop
+ id="stop4203"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop4205"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8662"
+ id="radialGradient4276"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.536723,-1.893136e-12,16.87306)"
+ cx="24.837126"
+ cy="36.421127"
+ fx="24.837126"
+ fy="36.421127"
+ r="15.644737" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient4278"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.222659,-0.996273,-2.129992,0.476041,604.946,141.8517)"
+ cx="64.227074"
+ cy="147.99352"
+ fx="64.227074"
+ fy="147.99352"
+ r="8.75" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient4280"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.264218,-0.986066,-2.238896,-0.59991,486.602,298.4876)"
+ cx="64.214218"
+ cy="146.18817"
+ fx="64.214218"
+ fy="146.18817"
+ r="8.75" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient4282"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.264218,-0.986066,-2.238896,-0.59991,468.602,298.4876)"
+ cx="64.214218"
+ cy="146.18817"
+ fx="64.214218"
+ fy="146.18817"
+ r="8.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient4284"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.4002,36.96061)"
+ x1="53.931114"
+ y1="116.38297"
+ x2="54.390476"
+ y2="122.29481" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient4286"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.4002,36.96061)"
+ x1="53.017841"
+ y1="99.445641"
+ x2="53.201031"
+ y2="101.35189" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient4288"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.4002,36.96061)"
+ x1="54.346024"
+ y1="102.97689"
+ x2="54.712406"
+ y2="106.38314" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8662"
+ id="linearGradient4290"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.4002,36.96061)"
+ x1="55.934441"
+ y1="107.94752"
+ x2="56.941994"
+ y2="113.80963" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2591"
+ id="linearGradient4292"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-326,-290)"
+ x1="52.048431"
+ y1="155"
+ x2="49"
+ y2="142.00146" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2591"
+ id="linearGradient4294"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,326,290)"
+ x1="89"
+ y1="149.4554"
+ x2="89"
+ y2="140.03592" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5075"
+ id="linearGradient4296"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,4.681043e-17,-4.681043e-17,-1,326,290)"
+ x1="90"
+ y1="155.00908"
+ x2="89.066872"
+ y2="142.03874" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient4313"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.222659,-0.996273,-2.129992,0.476041,604.946,141.8517)"
+ cx="64.227074"
+ cy="147.99352"
+ fx="64.227074"
+ fy="147.99352"
+ r="8.75" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient4315"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.264218,-0.986066,-2.238896,-0.59991,486.602,298.4876)"
+ cx="64.214218"
+ cy="146.18817"
+ fx="64.214218"
+ fy="146.18817"
+ r="8.75" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient4317"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.264218,-0.986066,-2.238896,-0.59991,468.602,298.4876)"
+ cx="64.214218"
+ cy="146.18817"
+ fx="64.214218"
+ fy="146.18817"
+ r="8.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient4319"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.4002,36.96061)"
+ x1="53.931114"
+ y1="116.38297"
+ x2="54.390476"
+ y2="122.29481" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient4321"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.4002,36.96061)"
+ x1="53.017841"
+ y1="99.445641"
+ x2="53.201031"
+ y2="101.35189" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient4323"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.4002,36.96061)"
+ x1="54.346024"
+ y1="102.97689"
+ x2="54.712406"
+ y2="106.38314" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8662"
+ id="linearGradient4325"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.4002,36.96061)"
+ x1="55.934441"
+ y1="107.94752"
+ x2="56.941994"
+ y2="113.80963" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2591"
+ id="linearGradient4327"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-326,-290)"
+ x1="52.048431"
+ y1="155"
+ x2="49"
+ y2="142.00146" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2591"
+ id="linearGradient4329"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,326,290)"
+ x1="89"
+ y1="149.4554"
+ x2="89"
+ y2="140.03592" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5075"
+ id="linearGradient4331"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,4.681043e-17,-4.681043e-17,-1,326,290)"
+ x1="90"
+ y1="155.00908"
+ x2="89.066872"
+ y2="142.03874" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5075"
+ id="linearGradient4334"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,4.681043e-17,-4.681043e-17,-1,203.7502,196.75)"
+ x1="90"
+ y1="155.00908"
+ x2="89.066872"
+ y2="142.03874" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2591"
+ id="linearGradient4337"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,203.7502,196.75)"
+ x1="89"
+ y1="149.4554"
+ x2="89"
+ y2="140.03592" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient4352"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.222659,-0.996273,-2.129992,0.476041,604.946,141.8517)"
+ cx="64.227074"
+ cy="147.99352"
+ fx="64.227074"
+ fy="147.99352"
+ r="8.75" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient4354"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.264218,-0.986066,-2.238896,-0.59991,486.602,298.4876)"
+ cx="64.214218"
+ cy="146.18817"
+ fx="64.214218"
+ fy="146.18817"
+ r="8.75" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient4356"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.264218,-0.986066,-2.238896,-0.59991,468.602,298.4876)"
+ cx="64.214218"
+ cy="146.18817"
+ fx="64.214218"
+ fy="146.18817"
+ r="8.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient4358"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.4002,36.96061)"
+ x1="53.931114"
+ y1="116.38297"
+ x2="54.390476"
+ y2="122.29481" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient4360"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.4002,36.96061)"
+ x1="53.017841"
+ y1="99.445641"
+ x2="53.201031"
+ y2="101.35189" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient4362"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.4002,36.96061)"
+ x1="54.346024"
+ y1="102.97689"
+ x2="54.712406"
+ y2="106.38314" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8662"
+ id="linearGradient4364"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.4002,36.96061)"
+ x1="55.934441"
+ y1="107.94752"
+ x2="56.941994"
+ y2="113.80963" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient4375"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.222659,-0.996273,2.129992,0.476041,-323.9464,20.8517)"
+ cx="64.227074"
+ cy="147.99352"
+ fx="64.227074"
+ fy="147.99352"
+ r="8.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient4377"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.4002,36.96061)"
+ x1="53.931114"
+ y1="116.38297"
+ x2="54.390476"
+ y2="122.29481" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient4379"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.4002,36.96061)"
+ x1="53.017841"
+ y1="99.445641"
+ x2="53.201031"
+ y2="101.35189" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient4381"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.4002,36.96061)"
+ x1="54.346024"
+ y1="102.97689"
+ x2="54.712406"
+ y2="106.38314" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8662"
+ id="linearGradient4383"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.4002,36.96061)"
+ x1="55.934441"
+ y1="107.94752"
+ x2="56.941994"
+ y2="113.80963" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8662"
+ id="linearGradient4386"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(62.1504,-56.28938)"
+ x1="55.934441"
+ y1="107.94752"
+ x2="56.941994"
+ y2="113.80963" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient4389"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(62.1504,-56.28938)"
+ x1="54.346024"
+ y1="102.97689"
+ x2="54.712406"
+ y2="106.38314" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient4392"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(62.1504,-56.28938)"
+ x1="53.017841"
+ y1="99.445641"
+ x2="53.201031"
+ y2="101.35189" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient4395"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(62.1504,-56.28938)"
+ x1="53.931114"
+ y1="116.38297"
+ x2="54.390476"
+ y2="122.29481" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient4397"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.264218,-0.986066,-2.238896,-0.59991,486.602,298.4876)"
+ cx="64.214218"
+ cy="146.18817"
+ fx="64.214218"
+ fy="146.18817"
+ r="8.75" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient4399"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.264218,-0.986066,-2.238896,-0.59991,468.602,298.4876)"
+ cx="64.214218"
+ cy="146.18817"
+ fx="64.214218"
+ fy="146.18817"
+ r="8.75" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient4402"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.264218,-0.986066,-2.238896,-0.59991,431.3526,205.2376)"
+ cx="64.214218"
+ cy="146.18817"
+ fx="64.214218"
+ fy="146.18817"
+ r="8.75" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient4405"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.264218,-0.986066,-2.238896,-0.59991,449.3526,205.2376)"
+ cx="64.214218"
+ cy="146.18817"
+ fx="64.214218"
+ fy="146.18817"
+ r="8.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5075"
+ id="linearGradient4413"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,4.681043e-17,4.681043e-17,-1,-45.0004,169)"
+ x1="54"
+ y1="131.27296"
+ x2="54"
+ y2="145" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2316"
+ id="linearGradient5293"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(1.99966,0)"
+ x1="24.476166"
+ y1="13.658564"
+ x2="23.750401"
+ y2="36" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="0.15294118"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1"
+ inkscape:cx="-122.45446"
+ inkscape:cy="17.377251"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:grid-points="true"
+ fill="#fcaf3e"
+ showguides="false"
+ inkscape:guide-bbox="true"
+ guidetolerance="1px"
+ stroke="#729fcf"
+ inkscape:window-width="1144"
+ inkscape:window-height="808"
+ inkscape:window-x="290"
+ inkscape:window-y="40"
+ showborder="true"
+ inkscape:showpageshadow="false"
+ borderlayer="top">
+ <sodipodi:guide
+ orientation="horizontal"
+ position="38.996647"
+ id="guide2194" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="9.0140845"
+ id="guide2196" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="9.0140845"
+ id="guide2198" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="38.975184"
+ id="guide2200" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="22.988281"
+ id="guide2202" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="23.908786"
+ id="guide2204" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="157.99417"
+ id="guide4332" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-36.062446"
+ id="guide4334" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-58.02695"
+ id="guide4336" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="180.00287"
+ id="guide4338" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="107.92217"
+ id="guide4417" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="129.93087"
+ id="guide4419" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="19.996875"
+ id="guide5106" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="63.039674"
+ id="guide5119" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="49.066305"
+ id="guide5121" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-87.043372"
+ id="guide5307" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-102.03286"
+ id="guide5309" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-100.04058"
+ id="guide3111" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-92.545841"
+ id="guide1879" />
+ <inkscape:grid
+ id="GridFromPre046Settings"
+ type="xygrid"
+ originx="0px"
+ originy="0px"
+ spacingx="0.5px"
+ spacingy="0.5px"
+ color="#0000ff"
+ empcolor="#0000ff"
+ opacity="0.2"
+ empopacity="0.4"
+ empspacing="2" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata1312">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Media Skip Backward</dc:title>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Lapo Calamandrei</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/publicdomain/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ style="display:inline">
+ <path
+ style="opacity:0.15;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient5293);stroke-width:3;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 43.5,13.5 L 43.5,34.5 L 26,24 L 43.5,13.5 z M 25.5,13.5 L 25.5,34.5 L 8.5,24.3125 L 8.5,34.5 L 3.5,34.5 L 3.5,13.5 L 8.5,13.5 L 8.5,23.6875 L 25.5,13.5 z "
+ id="path5288"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true" />
+ <path
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="/home/lapo/Desktop/Grafica/Icone/media-actions.png"
+ sodipodi:nodetypes="cccc"
+ id="path5515"
+ d="M 25.500057,13.5 L 8.000057,24 L 25.500057,34.5 L 25.500057,13.5 z "
+ style="color:#000000;fill:url(#radialGradient1439);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.0000006;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <path
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ style="color:#000000;fill:url(#radialGradient1436);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.0000006;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 43.500057,13.5 L 26.000057,24 L 43.500057,34.5 L 43.500057,13.5 z "
+ id="use5517"
+ sodipodi:nodetypes="cccc"
+ inkscape:export-filename="/home/lapo/Desktop/Grafica/Icone/media-actions.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ sodipodi:nodetypes="ccccccccc"
+ style="opacity:0.07027025;color:#000000;fill:url(#linearGradient1426);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 43.500057,13.5 L 42.312557,14.21875 L 43.500057,14.09375 L 43.500057,13.5 z M 25.500057,13.75 L 25.031307,13.78125 L 21.062557,16.15625 L 25.500057,15.75 L 25.500057,13.75 z "
+ id="path2915" />
+ <path
+ style="color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient1401);stroke-width:1.0000006;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 25.500057,13.5 L 8.000057,24 L 25.500057,34.5 L 25.500057,13.5 z M 43.500057,13.5 L 26.000057,24 L 43.500057,34.5 L 43.500057,13.5 z "
+ id="path5521"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true" />
+ <path
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 25.000057,14.375 L 8.968807,24 L 25.000057,33.625 L 25.000057,14.375 z M 43.000057,14.375 L 26.968807,24 L 43.000057,33.625 L 43.000057,14.375 z M 24.000057,16.15625 L 24.000057,31.84375 L 10.906307,24 L 24.000057,16.15625 z M 42.000057,16.15625 L 42.000057,31.84375 L 28.906307,24 L 42.000057,16.15625 z "
+ id="path5525"
+ sodipodi:nodetypes="cccccccccccccccc"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true" />
+ <path
+ style="opacity:0.56111109;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 12.412031,23.15901 L 23.999657,16.1875 L 23.999657,22.230393 L 12.412031,23.15901 z "
+ id="path3197"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ id="path4072"
+ d="M 31.971167,22.144607 L 41.999657,16.1875 L 41.999657,21.74632 L 31.971167,22.144607 z "
+ style="opacity:0.56111109;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ sodipodi:nodetypes="cccc" />
+ <path
+ style="color:#000000;fill:url(#radialGradient4375);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.0000006;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 8.5,13.499999 L 3.5,13.499999 L 3.5,34.499999 L 8.5,34.499999 L 8.5,13.499999 z "
+ id="path3110"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="/home/lapo/Desktop/Grafica/Icone/media-actions.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true" />
+ <rect
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ transform="scale(1,-1)"
+ style="color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="rect1923"
+ width="3"
+ height="19"
+ x="4.4996033"
+ y="-33.5" />
+ <path
+ style="color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4413);stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 3.4996,34.499999 L 3.4996,13.499999 L 8.4996,13.499999 L 8.4996,34.499999 L 3.4996,34.499999 z "
+ id="path1935"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true" />
+ <path
+ style="opacity:0.56111109;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 7,24.3125 L 5.043263,24.649549 L 5.043263,15.031146 L 7.076195,15.031146 L 7,24.3125 z "
+ id="path5291"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true"
+ sodipodi:nodetypes="ccccc" />
+ </g>
+</svg>
diff --git a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-skip-forward.svg b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-skip-forward.svg
new file mode 100644
index 0000000000..7c4d40054b
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/actions/media-skip-forward.svg
@@ -0,0 +1,1013 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="48px"
+ height="48px"
+ id="svg1307"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/actions"
+ sodipodi:docname="media-skip-forward.svg"
+ inkscape:export-filename="/home/lapo/Desktop/Grafica/Icone/media-actions-outlines.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <defs
+ id="defs1309">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 24 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="48 : 24 : 1"
+ inkscape:persp3d-origin="24 : 16 : 1"
+ id="perspective126" />
+ <linearGradient
+ id="linearGradient2316">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop2318" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.65979379;"
+ offset="1"
+ id="stop2320" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2584">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop2586" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop2588" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5075">
+ <stop
+ style="stop-color:#adb0a8;stop-opacity:1;"
+ offset="0"
+ id="stop5077" />
+ <stop
+ style="stop-color:#464744;stop-opacity:1"
+ offset="1"
+ id="stop5079" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2679"
+ inkscape:collect="always">
+ <stop
+ id="stop2681"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ <stop
+ id="stop2683"
+ offset="1"
+ style="stop-color:#d3d7cf" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2591">
+ <stop
+ id="stop2593"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop2595"
+ offset="1"
+ style="stop-color:#eeeeec;stop-opacity:0" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient8662">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop8664" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop8666" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8662"
+ id="radialGradient1932"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.536723,3.953052e-13,16.87306)"
+ cx="24.837126"
+ cy="36.421127"
+ fx="24.837126"
+ fy="36.421127"
+ r="15.644737" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5075"
+ id="linearGradient1401"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,93.99994,-121)"
+ x1="55.613514"
+ y1="157.56604"
+ x2="55.771976"
+ y2="140.31299" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient1426"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,90.99085,-97.26213)"
+ x1="49.430401"
+ y1="112.94963"
+ x2="49.667324"
+ y2="115.13713" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient1436"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.222659,-0.996273,-2.129992,0.476041,336.9463,20.8517)"
+ cx="64.227074"
+ cy="147.99352"
+ fx="64.227074"
+ fy="147.99352"
+ r="8.75" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient1439"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.222659,-0.996273,-2.129992,0.476041,354.9463,20.8517)"
+ cx="64.227074"
+ cy="147.99352"
+ fx="64.227074"
+ fy="147.99352"
+ r="8.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2316"
+ id="linearGradient2322"
+ x1="24.476166"
+ y1="13.658564"
+ x2="23.750401"
+ y2="36"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,46.00034,0)" />
+ <radialGradient
+ r="8.75"
+ fy="146.18817"
+ fx="64.214218"
+ cy="146.18817"
+ cx="64.214218"
+ gradientTransform="matrix(0.264218,-0.986066,-2.238896,-0.59991,468.602,298.4876)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient1535"
+ xlink:href="#linearGradient2679"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="142.03874"
+ x2="89.066872"
+ y1="155.00908"
+ x1="90"
+ gradientTransform="matrix(-1,4.681043e-17,-4.681043e-17,-1,326,290)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2331"
+ xlink:href="#linearGradient5075"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="140.03592"
+ x2="89"
+ y1="149.4554"
+ x1="89"
+ gradientTransform="matrix(-1,0,0,-1,326,290)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2329"
+ xlink:href="#linearGradient2591"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="142.00146"
+ x2="49"
+ y1="155"
+ x1="52.048431"
+ gradientTransform="translate(-326,-290)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2327"
+ xlink:href="#linearGradient2591"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="113.80963"
+ x2="56.941994"
+ y1="107.94752"
+ x1="55.934441"
+ gradientTransform="translate(146.4002,36.96061)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2325"
+ xlink:href="#linearGradient8662"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="106.38314"
+ x2="54.712406"
+ y1="102.97689"
+ x1="54.346024"
+ gradientTransform="translate(146.4002,36.96061)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2323"
+ xlink:href="#linearGradient2584"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="101.35189"
+ x2="53.201031"
+ y1="99.445641"
+ x1="53.017841"
+ gradientTransform="translate(146.4002,36.96061)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2321"
+ xlink:href="#linearGradient2584"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="122.29481"
+ x2="54.390476"
+ y1="116.38297"
+ x1="53.931114"
+ gradientTransform="translate(146.4002,36.96061)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2319"
+ xlink:href="#linearGradient2584"
+ inkscape:collect="always" />
+ <radialGradient
+ r="8.75"
+ fy="146.18817"
+ fx="64.214218"
+ cy="146.18817"
+ cx="64.214218"
+ gradientTransform="matrix(0.264218,-0.986066,-2.238896,-0.59991,486.602,298.4876)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2317"
+ xlink:href="#linearGradient2679"
+ inkscape:collect="always" />
+ <radialGradient
+ r="8.75"
+ fy="147.99352"
+ fx="64.227074"
+ cy="147.99352"
+ cx="64.227074"
+ gradientTransform="matrix(-0.222659,-0.996273,-2.129992,0.476041,604.946,141.8517)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2315"
+ xlink:href="#linearGradient2679"
+ inkscape:collect="always" />
+ <radialGradient
+ r="15.644737"
+ fy="36.421127"
+ fx="24.837126"
+ cy="36.421127"
+ cx="24.837126"
+ gradientTransform="matrix(1,0,0,0.536723,-1.836182e-12,16.87306)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2313"
+ xlink:href="#linearGradient8662"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient4219">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop4221" />
+ <stop
+ style="stop-color:#eeeeec;stop-opacity:0"
+ offset="1"
+ id="stop4223" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4207">
+ <stop
+ id="stop4209"
+ offset="0"
+ style="stop-color:#adb0a8;stop-opacity:1;" />
+ <stop
+ id="stop4211"
+ offset="1"
+ style="stop-color:#464744;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4201">
+ <stop
+ id="stop4203"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop4205"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8662"
+ id="radialGradient4276"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.536723,-1.893136e-12,16.87306)"
+ cx="24.837126"
+ cy="36.421127"
+ fx="24.837126"
+ fy="36.421127"
+ r="15.644737" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient4278"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.222659,-0.996273,-2.129992,0.476041,604.946,141.8517)"
+ cx="64.227074"
+ cy="147.99352"
+ fx="64.227074"
+ fy="147.99352"
+ r="8.75" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient4280"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.264218,-0.986066,-2.238896,-0.59991,486.602,298.4876)"
+ cx="64.214218"
+ cy="146.18817"
+ fx="64.214218"
+ fy="146.18817"
+ r="8.75" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient4282"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.264218,-0.986066,-2.238896,-0.59991,468.602,298.4876)"
+ cx="64.214218"
+ cy="146.18817"
+ fx="64.214218"
+ fy="146.18817"
+ r="8.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient4284"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.4002,36.96061)"
+ x1="53.931114"
+ y1="116.38297"
+ x2="54.390476"
+ y2="122.29481" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient4286"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.4002,36.96061)"
+ x1="53.017841"
+ y1="99.445641"
+ x2="53.201031"
+ y2="101.35189" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient4288"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.4002,36.96061)"
+ x1="54.346024"
+ y1="102.97689"
+ x2="54.712406"
+ y2="106.38314" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8662"
+ id="linearGradient4290"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.4002,36.96061)"
+ x1="55.934441"
+ y1="107.94752"
+ x2="56.941994"
+ y2="113.80963" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2591"
+ id="linearGradient4292"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-326,-290)"
+ x1="52.048431"
+ y1="155"
+ x2="49"
+ y2="142.00146" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2591"
+ id="linearGradient4294"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,326,290)"
+ x1="89"
+ y1="149.4554"
+ x2="89"
+ y2="140.03592" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5075"
+ id="linearGradient4296"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,4.681043e-17,-4.681043e-17,-1,326,290)"
+ x1="90"
+ y1="155.00908"
+ x2="89.066872"
+ y2="142.03874" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient4313"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.222659,-0.996273,-2.129992,0.476041,604.946,141.8517)"
+ cx="64.227074"
+ cy="147.99352"
+ fx="64.227074"
+ fy="147.99352"
+ r="8.75" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient4315"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.264218,-0.986066,-2.238896,-0.59991,486.602,298.4876)"
+ cx="64.214218"
+ cy="146.18817"
+ fx="64.214218"
+ fy="146.18817"
+ r="8.75" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient4317"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.264218,-0.986066,-2.238896,-0.59991,468.602,298.4876)"
+ cx="64.214218"
+ cy="146.18817"
+ fx="64.214218"
+ fy="146.18817"
+ r="8.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient4319"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.4002,36.96061)"
+ x1="53.931114"
+ y1="116.38297"
+ x2="54.390476"
+ y2="122.29481" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient4321"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.4002,36.96061)"
+ x1="53.017841"
+ y1="99.445641"
+ x2="53.201031"
+ y2="101.35189" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient4323"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.4002,36.96061)"
+ x1="54.346024"
+ y1="102.97689"
+ x2="54.712406"
+ y2="106.38314" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8662"
+ id="linearGradient4325"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.4002,36.96061)"
+ x1="55.934441"
+ y1="107.94752"
+ x2="56.941994"
+ y2="113.80963" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2591"
+ id="linearGradient4327"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-326,-290)"
+ x1="52.048431"
+ y1="155"
+ x2="49"
+ y2="142.00146" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2591"
+ id="linearGradient4329"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,326,290)"
+ x1="89"
+ y1="149.4554"
+ x2="89"
+ y2="140.03592" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5075"
+ id="linearGradient4331"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,4.681043e-17,-4.681043e-17,-1,326,290)"
+ x1="90"
+ y1="155.00908"
+ x2="89.066872"
+ y2="142.03874" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5075"
+ id="linearGradient4334"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,4.681043e-17,-4.681043e-17,-1,203.7502,196.75)"
+ x1="90"
+ y1="155.00908"
+ x2="89.066872"
+ y2="142.03874" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2591"
+ id="linearGradient4337"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,-1,203.7502,196.75)"
+ x1="89"
+ y1="149.4554"
+ x2="89"
+ y2="140.03592" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient4352"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.222659,-0.996273,-2.129992,0.476041,604.946,141.8517)"
+ cx="64.227074"
+ cy="147.99352"
+ fx="64.227074"
+ fy="147.99352"
+ r="8.75" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient4354"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.264218,-0.986066,-2.238896,-0.59991,486.602,298.4876)"
+ cx="64.214218"
+ cy="146.18817"
+ fx="64.214218"
+ fy="146.18817"
+ r="8.75" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient4356"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.264218,-0.986066,-2.238896,-0.59991,468.602,298.4876)"
+ cx="64.214218"
+ cy="146.18817"
+ fx="64.214218"
+ fy="146.18817"
+ r="8.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient4358"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.4002,36.96061)"
+ x1="53.931114"
+ y1="116.38297"
+ x2="54.390476"
+ y2="122.29481" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient4360"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.4002,36.96061)"
+ x1="53.017841"
+ y1="99.445641"
+ x2="53.201031"
+ y2="101.35189" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient4362"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.4002,36.96061)"
+ x1="54.346024"
+ y1="102.97689"
+ x2="54.712406"
+ y2="106.38314" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8662"
+ id="linearGradient4364"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.4002,36.96061)"
+ x1="55.934441"
+ y1="107.94752"
+ x2="56.941994"
+ y2="113.80963" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient4375"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.222659,-0.996273,-2.129992,0.476041,371.9464,20.8517)"
+ cx="64.227074"
+ cy="147.99352"
+ fx="64.227074"
+ fy="147.99352"
+ r="8.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient4377"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.4002,36.96061)"
+ x1="53.931114"
+ y1="116.38297"
+ x2="54.390476"
+ y2="122.29481" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient4379"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.4002,36.96061)"
+ x1="53.017841"
+ y1="99.445641"
+ x2="53.201031"
+ y2="101.35189" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient4381"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.4002,36.96061)"
+ x1="54.346024"
+ y1="102.97689"
+ x2="54.712406"
+ y2="106.38314" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8662"
+ id="linearGradient4383"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(146.4002,36.96061)"
+ x1="55.934441"
+ y1="107.94752"
+ x2="56.941994"
+ y2="113.80963" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8662"
+ id="linearGradient4386"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(62.1504,-56.28938)"
+ x1="55.934441"
+ y1="107.94752"
+ x2="56.941994"
+ y2="113.80963" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient4389"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(62.1504,-56.28938)"
+ x1="54.346024"
+ y1="102.97689"
+ x2="54.712406"
+ y2="106.38314" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient4392"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(62.1504,-56.28938)"
+ x1="53.017841"
+ y1="99.445641"
+ x2="53.201031"
+ y2="101.35189" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2584"
+ id="linearGradient4395"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(62.1504,-56.28938)"
+ x1="53.931114"
+ y1="116.38297"
+ x2="54.390476"
+ y2="122.29481" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient4397"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.264218,-0.986066,-2.238896,-0.59991,486.602,298.4876)"
+ cx="64.214218"
+ cy="146.18817"
+ fx="64.214218"
+ fy="146.18817"
+ r="8.75" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient4399"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.264218,-0.986066,-2.238896,-0.59991,468.602,298.4876)"
+ cx="64.214218"
+ cy="146.18817"
+ fx="64.214218"
+ fy="146.18817"
+ r="8.75" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient4402"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.264218,-0.986066,-2.238896,-0.59991,431.3526,205.2376)"
+ cx="64.214218"
+ cy="146.18817"
+ fx="64.214218"
+ fy="146.18817"
+ r="8.75" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2679"
+ id="radialGradient4405"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.264218,-0.986066,-2.238896,-0.59991,449.3526,205.2376)"
+ cx="64.214218"
+ cy="146.18817"
+ fx="64.214218"
+ fy="146.18817"
+ r="8.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5075"
+ id="linearGradient4413"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,4.681043e-17,-4.681043e-17,-1,93.0004,169)"
+ x1="54"
+ y1="132.5"
+ x2="54"
+ y2="145" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="0.15294118"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="4"
+ inkscape:cx="15.624329"
+ inkscape:cy="31.787027"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:grid-points="true"
+ fill="#fcaf3e"
+ showguides="false"
+ inkscape:guide-bbox="true"
+ guidetolerance="1px"
+ stroke="#729fcf"
+ inkscape:window-width="1144"
+ inkscape:window-height="808"
+ inkscape:window-x="290"
+ inkscape:window-y="40"
+ showborder="true"
+ inkscape:showpageshadow="false"
+ borderlayer="top">
+ <sodipodi:guide
+ orientation="horizontal"
+ position="38.996647"
+ id="guide2194" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="9.0140845"
+ id="guide2196" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="9.0140845"
+ id="guide2198" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="38.975184"
+ id="guide2200" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="22.988281"
+ id="guide2202" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="23.908786"
+ id="guide2204" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="157.99417"
+ id="guide4332" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-36.062446"
+ id="guide4334" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-58.02695"
+ id="guide4336" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="180.00287"
+ id="guide4338" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="107.92217"
+ id="guide4417" />
+ <sodipodi:guide
+ orientation="vertical"
+ position="129.93087"
+ id="guide4419" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="19.996875"
+ id="guide5106" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="63.039674"
+ id="guide5119" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="49.066305"
+ id="guide5121" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-87.043372"
+ id="guide5307" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-102.03286"
+ id="guide5309" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-100.04058"
+ id="guide3111" />
+ <sodipodi:guide
+ orientation="horizontal"
+ position="-92.545841"
+ id="guide1879" />
+ <inkscape:grid
+ id="GridFromPre046Settings"
+ type="xygrid"
+ originx="0px"
+ originy="0px"
+ spacingx="0.5px"
+ spacingy="0.5px"
+ color="#0000ff"
+ empcolor="#0000ff"
+ opacity="0.2"
+ empopacity="0.4"
+ empspacing="2" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata1312">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Media Skip Forward</dc:title>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Lapo Calamandrei</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/publicdomain/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ style="display:inline">
+ <path
+ style="color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2322);stroke-width:3;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;opacity:0.15"
+ d="M 4.5 13.5 L 4.5 34.5 L 22 24 L 4.5 13.5 z M 22.5 13.5 L 22.5 34.5 L 39.5 24.3125 L 39.5 34.5 L 44.5 34.5 L 44.5 13.5 L 39.5 13.5 L 39.5 23.6875 L 22.5 13.5 z "
+ id="path5288" />
+ <path
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="/home/lapo/Desktop/Grafica/Icone/media-actions.png"
+ sodipodi:nodetypes="cccc"
+ id="path5515"
+ d="M 22.499943,13.5 L 39.999943,24 L 22.499943,34.5 L 22.499943,13.5 z "
+ style="color:#000000;fill:url(#radialGradient1439);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.0000006;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <path
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ style="color:#000000;fill:url(#radialGradient1436);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.0000006;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 4.4999427,13.5 L 21.999943,24 L 4.4999427,34.5 L 4.4999427,13.5 z "
+ id="use5517"
+ sodipodi:nodetypes="cccc"
+ inkscape:export-filename="/home/lapo/Desktop/Grafica/Icone/media-actions.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90" />
+ <path
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ sodipodi:nodetypes="ccccccccc"
+ style="opacity:0.07027025;color:#000000;fill:url(#linearGradient1426);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 4.4999427,13.5 L 5.6874427,14.21875 L 4.4999427,14.09375 L 4.4999427,13.5 z M 22.499943,13.75 L 22.968693,13.78125 L 26.937443,16.15625 L 22.499943,15.75 L 22.499943,13.75 z "
+ id="path2915" />
+ <path
+ style="color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient1401);stroke-width:1.0000006;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 22.499943,13.5 L 39.999943,24 L 22.499943,34.5 L 22.499943,13.5 z M 4.4999427,13.5 L 21.999943,24 L 4.4999427,34.5 L 4.4999427,13.5 z "
+ id="path5521"
+ sodipodi:nodetypes="cccccccc"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true" />
+ <path
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 22.999943,14.375 L 39.031193,24 L 22.999943,33.625 L 22.999943,14.375 z M 4.9999427,14.375 L 21.031193,24 L 4.9999427,33.625 L 4.9999427,14.375 z M 23.999943,16.15625 L 23.999943,31.84375 L 37.093693,24 L 23.999943,16.15625 z M 5.9999427,16.15625 L 5.9999427,31.84375 L 19.093693,24 L 5.9999427,16.15625 z "
+ id="path5525"
+ sodipodi:nodetypes="cccccccccccccccc"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true" />
+ <path
+ style="opacity:0.56111109;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 33.587969,21.78401 L 24.062843,16.1875 L 24.062843,22.230393 L 33.587969,21.78401 z "
+ id="path3197"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ id="path4072"
+ d="M 18.278833,23.207107 L 6.0003427,16.1875 L 6.0003427,24.05882 L 18.278833,23.207107 z "
+ style="opacity:0.56111109;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ sodipodi:nodetypes="cccc" />
+ <path
+ style="color:#000000;fill:url(#radialGradient4375);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.0000006;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 39.5,13.499999 L 44.5,13.499999 L 44.5,34.499999 L 39.5,34.499999 L 39.5,13.499999 z "
+ id="path3110"
+ sodipodi:nodetypes="ccccc"
+ inkscape:export-filename="/home/lapo/Desktop/Grafica/Icone/media-actions.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true" />
+ <rect
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ transform="scale(-1,-1)"
+ style="color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="rect1923"
+ width="3"
+ height="19"
+ x="-43.500397"
+ y="-33.5" />
+ <path
+ style="color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4413);stroke-width:1;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 44.5004,34.499999 L 44.5004,13.499999 L 39.5004,13.499999 L 39.5004,34.499999 L 44.5004,34.499999 z "
+ id="path1935"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true" />
+ <path
+ style="opacity:0.56111109;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 41,22 L 42.956737,21.837049 L 42.956737,15.031146 L 40.923805,15.031146 L 41,22 z "
+ id="path5291"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true"
+ sodipodi:nodetypes="ccccc" />
+ </g>
+</svg>
diff --git a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/categories/applications-multimedia.svg b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/categories/applications-multimedia.svg
new file mode 100644
index 0000000000..6844e8db1a
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/categories/applications-multimedia.svg
@@ -0,0 +1,498 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ sodipodi:docname="applications-multimedia.svg"
+ sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/categories"
+ inkscape:version="0.46"
+ sodipodi:version="0.32"
+ id="svg1430"
+ height="48px"
+ width="48px"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <defs
+ id="defs3">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 24 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="48 : 24 : 1"
+ inkscape:persp3d-origin="24 : 16 : 1"
+ id="perspective78" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="radialGradient6719"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
+ cx="605.71429"
+ cy="486.64789"
+ fx="605.71429"
+ fy="486.64789"
+ r="117.14286" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient5060">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop5062" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop5064" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="radialGradient6717"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
+ cx="605.71429"
+ cy="486.64789"
+ fx="605.71429"
+ fy="486.64789"
+ r="117.14286" />
+ <linearGradient
+ id="linearGradient5048">
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="0"
+ id="stop5050" />
+ <stop
+ id="stop5056"
+ offset="0.5"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop5052" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5048"
+ id="linearGradient6715"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
+ x1="302.85715"
+ y1="366.64789"
+ x2="302.85715"
+ y2="609.50507" />
+ <linearGradient
+ id="linearGradient3593">
+ <stop
+ id="stop3595"
+ offset="0"
+ style="stop-color:#939393;stop-opacity:1;" />
+ <stop
+ id="stop3597"
+ offset="1.0000000"
+ style="stop-color:#d9d9d9;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3575"
+ inkscape:collect="always">
+ <stop
+ id="stop3577"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop3579"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2613"
+ inkscape:collect="always">
+ <stop
+ id="stop2615"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop2617"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2601">
+ <stop
+ id="stop2603"
+ offset="0.0000000"
+ style="stop-color:#5d5d5d;stop-opacity:1.0000000;" />
+ <stop
+ id="stop2605"
+ offset="1.0000000"
+ style="stop-color:#444444;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2502">
+ <stop
+ id="stop2504"
+ offset="0"
+ style="stop-color:#fdfdfd;stop-opacity:1;" />
+ <stop
+ id="stop2506"
+ offset="1.0000000"
+ style="stop-color:#d4d4d4;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.883137,5.542409e-23,8.493709e-23,2.136047,-64.96822,-52.48586)"
+ r="19.571430"
+ fy="35.673447"
+ fx="27.216267"
+ cy="35.673447"
+ cx="27.216267"
+ id="radialGradient2607"
+ xlink:href="#linearGradient2601"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ y2="49.142849"
+ x2="21.536488"
+ y1="13.142847"
+ x1="5.4635010"
+ id="linearGradient2619"
+ xlink:href="#linearGradient2613"
+ inkscape:collect="always" />
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,0.207120,0.000000,35.11327)"
+ r="22.071428"
+ fy="44.285713"
+ fx="24.642857"
+ cy="44.285713"
+ cx="24.642857"
+ id="radialGradient3581"
+ xlink:href="#linearGradient3575"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ y2="11.107142"
+ x2="7.9285712"
+ y1="15.928572"
+ x1="10.678571"
+ id="linearGradient3599"
+ xlink:href="#linearGradient3593"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="18.693317"
+ x2="18.772917"
+ y1="6.1102505"
+ x1="2.7612331"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4385"
+ xlink:href="#linearGradient2502"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientTransform="translate(-0.599666,-0.578168)"
+ y2="18.693317"
+ x2="18.772917"
+ y1="6.1102505"
+ x1="2.7612331"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4387"
+ xlink:href="#linearGradient2502"
+ inkscape:collect="always" />
+ </defs>
+ <sodipodi:namedview
+ inkscape:showpageshadow="false"
+ inkscape:window-y="160"
+ inkscape:window-x="483"
+ inkscape:window-height="688"
+ inkscape:window-width="872"
+ inkscape:document-units="px"
+ inkscape:grid-bbox="true"
+ showgrid="false"
+ inkscape:current-layer="layer1"
+ inkscape:cy="25.564139"
+ inkscape:cx="23.940203"
+ inkscape:zoom="1"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ borderopacity="0.14117647"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Multimedia Category</dc:title>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source>http://jimmac.musichall.cz</dc:source>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>video</rdf:li>
+ <rdf:li>multimedia</rdf:li>
+ <rdf:li>category</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title />
+ </cc:Agent>
+ </dc:contributor>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/publicdomain/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:groupmode="layer"
+ inkscape:label="Layer 1"
+ id="layer1">
+ <g
+ transform="matrix(2.33489e-2,0,0,2.086758e-2,45.33878,41.86789)"
+ id="g6707">
+ <rect
+ style="opacity:0.40206185;color:black;fill:url(#linearGradient6715);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="rect6709"
+ width="1339.6335"
+ height="478.35718"
+ x="-1559.2523"
+ y="-150.69685" />
+ <path
+ style="opacity:0.40206185;color:black;fill:url(#radialGradient6717);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z "
+ id="path6711"
+ sodipodi:nodetypes="cccc" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path6713"
+ d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z "
+ style="opacity:0.40206185;color:black;fill:url(#radialGradient6719);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ </g>
+ <rect
+ ry="1.1428572"
+ rx="1.1428572"
+ y="16.571430"
+ x="5.4285707"
+ height="27.999996"
+ width="38.142860"
+ id="rect1440"
+ style="opacity:1.0000000;color:#000000;fill:url(#radialGradient2607);fill-opacity:1.0;fill-rule:nonzero;stroke:#1b1b1b;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block" />
+ <rect
+ style="opacity:0.31155780;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:nonzero;stroke:url(#linearGradient2619);stroke-width:0.99999964;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block"
+ id="rect2609"
+ width="36.072987"
+ height="26.060221"
+ x="6.3920727"
+ y="17.489294"
+ rx="0.27372196"
+ ry="0.27372196" />
+ <g
+ transform="matrix(-0.972710,0.232023,0.232023,0.972710,45.78579,5.110631)"
+ id="g4376">
+ <rect
+ transform="matrix(0.974407,-0.224790,0.224790,0.974407,0.000000,0.000000)"
+ ry="1.1428572"
+ rx="1.1428572"
+ y="10.353170"
+ x="1.7052064"
+ height="6.5087900"
+ width="39.805996"
+ id="rect4362"
+ style="opacity:1.0000000;color:#000000;fill:url(#linearGradient4385);fill-opacity:1.0000000;fill-rule:nonzero;stroke:#2b2b2b;stroke-width:1.0000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path4364"
+ d="M 9.1896391,8.9691823 L 6.7610675,15.540611 L 11.475352,14.254897 L 13.903923,7.9691824 L 9.1896391,8.9691823 z "
+ style="fill:#000000;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
+ <path
+ style="fill:#000000;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ d="M 18.332496,6.8977538 L 16.046781,13.397754 L 20.761067,12.254897 L 23.046781,5.8977539 L 18.332496,6.8977538 z "
+ id="path4366"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path4368"
+ d="M 27.903923,4.6834682 L 25.618208,11.112040 L 30.332494,9.9691828 L 32.618208,3.6834683 L 27.903923,4.6834682 z "
+ style="fill:#000000;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path4370"
+ d="M 39.412852,2.0182896 C 39.641926,2.1743435 39.814094,2.3819105 39.881602,2.6745396 L 40.613745,5.7504324 L 39.890531,7.7504324 L 35.203031,8.8352538 L 37.484281,2.4781110 L 39.412852,2.0182896 z "
+ style="opacity:1.0000000;color:#000000;fill:#000000;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block" />
+ <rect
+ style="opacity:1.0000000;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:nonzero;stroke:#ffffff;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:0.57512951;visibility:visible;display:block"
+ id="rect4372"
+ width="37.842842"
+ height="4.6068902"
+ x="2.6716552"
+ y="11.327118"
+ rx="0.26506385"
+ ry="0.26506385"
+ transform="matrix(0.974407,-0.224790,0.224790,0.974407,0.000000,0.000000)" />
+ </g>
+ <rect
+ transform="matrix(0.974407,-0.224790,0.224790,0.974407,0.000000,0.000000)"
+ ry="1.1428553"
+ rx="1.1428553"
+ y="9.6851511"
+ x="0.67043102"
+ height="6.9415727"
+ width="40.077335"
+ id="rect2200"
+ style="opacity:1.0000000;color:#000000;fill:url(#linearGradient4387);fill-opacity:1.0000000;fill-rule:nonzero;stroke:#2e2e2e;stroke-width:0.99999833;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path2202"
+ d="M 10.142858,8.1428571 L 7.7142859,14.714286 L 12.428572,13.428572 L 14.857143,7.1428572 L 10.142858,8.1428571 z "
+ style="fill:#000000;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
+ <path
+ style="fill:#000000;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ d="M 19.428573,5.7857143 L 16.785715,12.785715 L 21.500001,11.642858 L 24.142858,4.7857144 L 19.428573,5.7857143 z "
+ id="path2204"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path2206"
+ d="M 29.071429,3.6428573 L 26.499999,10.785715 L 31.214285,9.6428576 L 33.785714,2.6428574 L 29.071429,3.6428573 z "
+ style="fill:#000000;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="rect2210"
+ d="M 41.294643,0.97767869 C 41.523717,1.1337326 41.695885,1.3412996 41.763393,1.6339287 L 42.424107,4.2812501 L 41.343751,7.0669644 L 36.227680,8.2946429 L 38.580358,1.5803572 L 41.294643,0.97767869 z "
+ style="opacity:1.0000000;color:#000000;fill:#000000;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block" />
+ <rect
+ style="opacity:1.0000000;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.99999809;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:0.57512951;visibility:visible;display:block"
+ id="rect2510"
+ width="38.199306"
+ height="4.9147058"
+ x="1.6368761"
+ y="10.659099"
+ rx="0.26506338"
+ ry="0.26506338"
+ transform="matrix(0.974407,-0.224790,0.224790,0.974407,0.000000,0.000000)" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path3583"
+ d="M 6.5357143,10.892862 L 6.5357143,18.678576 C 6.5357143,19.142862 6.9285714,19.571434 7.3928571,19.607148 L 15.285713,19.607148 C 16.149377,19.607148 16.559575,18.345296 15.892855,17.678576 L 9.6785715,10.392862 C 8.7142857,9.0000049 6.5357143,9.6785764 6.5357143,10.892862 z "
+ style="fill:url(#linearGradient3599);fill-opacity:1.0;fill-rule:evenodd;stroke:#1b1b1b;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000;stroke-dasharray:none;stroke-miterlimit:4.0000000" />
+ <path
+ transform="translate(-7.142886e-2,-4.964285)"
+ d="M 9.0357146 17.196428 A 0.48214287 0.48214287 0 1 1 8.0714288,17.196428 A 0.48214287 0.48214287 0 1 1 9.0357146 17.196428 z"
+ sodipodi:ry="0.48214287"
+ sodipodi:rx="0.48214287"
+ sodipodi:cy="17.196428"
+ sodipodi:cx="8.5535717"
+ id="path3587"
+ style="opacity:1.0000000;color:#000000;fill:#ffffff;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1.0000000;color:#000000;fill:#ffffff;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block"
+ id="path3589"
+ sodipodi:cx="8.5535717"
+ sodipodi:cy="17.196428"
+ sodipodi:rx="0.48214287"
+ sodipodi:ry="0.48214287"
+ d="M 9.0357146 17.196428 A 0.48214287 0.48214287 0 1 1 8.0714288,17.196428 A 0.48214287 0.48214287 0 1 1 9.0357146 17.196428 z"
+ transform="translate(-7.142884e-2,0.321429)" />
+ <path
+ transform="translate(4.964285,0.321429)"
+ d="M 9.0357146 17.196428 A 0.48214287 0.48214287 0 1 1 8.0714288,17.196428 A 0.48214287 0.48214287 0 1 1 9.0357146 17.196428 z"
+ sodipodi:ry="0.48214287"
+ sodipodi:rx="0.48214287"
+ sodipodi:cy="17.196428"
+ sodipodi:cx="8.5535717"
+ id="path3591"
+ style="opacity:1.0000000;color:#000000;fill:#ffffff;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block"
+ sodipodi:type="arc" />
+ <g
+ transform="translate(0.000000,4.000000)"
+ style="opacity:0.26130649"
+ id="g3629">
+ <path
+ style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+ d="M 10.000000,28.428571 L 38.000000,28.428571"
+ id="path3601" />
+ <path
+ style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+ d="M 10.000000,32.571424 L 38.000000,32.571424"
+ id="path3603" />
+ <path
+ style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+ d="M 32.500000,28.000000 L 32.500000,24.000000"
+ id="path3607" />
+ <path
+ style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+ d="M 10.000000,32.571424 L 38.000000,32.571424"
+ id="path3605" />
+ <path
+ style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000"
+ d="M 22.500000,28.000000 L 22.500000,24.000000"
+ id="path3611" />
+ <path
+ id="path3615"
+ d="M 9.7429344,36.571424 L 23.042766,36.571424"
+ style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.99999970;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000" />
+ </g>
+ <g
+ transform="matrix(0.688056,0.000000,0.000000,0.688056,11.98189,14.73331)"
+ style="fill:#ffffff;fill-opacity:1.0000000"
+ id="g3680">
+ <path
+ style="fill:#ffffff;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ id="path3674"
+ d="M 13.817087,27.838710 C 13.930688,28.803867 14.061948,29.766424 14.212013,30.726635 L 12.104297,31.841956 C 11.971325,30.898587 11.859805,29.948673 11.653276,29.018190 L 13.817087,27.838710 z " />
+ <path
+ style="fill:#ffffff;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ id="path3676"
+ d="M 17.665061,28.673198 C 17.640890,30.752445 18.343061,29.865981 15.754098,31.262303 C 16.569510,29.958741 17.945730,28.643937 19.302723,29.817297 C 21.893912,30.238969 17.868875,32.299286 19.657894,30.131624 C 22.257907,27.861759 21.880200,29.134103 24.062213,29.263059 C 25.842435,29.693266 25.858407,29.319392 23.491960,30.679722 C 23.523989,30.651797 23.556018,30.623873 23.588047,30.595949 L 25.826668,29.648988 C 25.801378,29.687677 25.776087,29.726367 25.750797,29.765056 C 22.939448,31.442531 24.082399,30.948809 22.103508,30.691366 C 20.237158,30.363681 19.228118,30.138071 21.882669,29.206652 C 20.743226,30.500571 18.901454,32.506543 17.264071,31.089587 C 15.675562,29.919042 19.396606,28.676254 18.028684,30.358607 C 15.346131,31.837218 15.628223,31.910467 15.467942,29.792686 L 17.665061,28.673198 z " />
+ <path
+ style="fill:#ffffff;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ id="path3678"
+ d="M 29.174994,26.230789 C 29.320924,27.738745 29.400780,29.250331 29.580136,30.755472 C 31.003608,32.606218 27.753159,35.389440 28.232911,32.564306 C 28.574992,29.320495 28.883230,28.720136 31.761658,27.684322 C 32.309347,28.667665 32.609389,29.822268 33.465682,30.412281 C 28.625607,32.963952 35.159427,28.931066 35.886628,28.544940 C 36.351549,28.435797 36.826481,28.379615 37.298915,28.314189 L 35.378159,29.751503 C 34.913315,29.819571 34.443102,29.870403 33.993175,30.012668 C 36.991756,28.101100 33.424771,30.854559 31.487156,31.830219 C 30.563410,31.105995 30.343692,29.935794 29.703924,28.949905 C 32.849914,26.731101 30.336554,28.808674 30.341827,31.527237 C 30.058287,33.877330 27.021653,35.077122 27.526846,31.833696 C 27.354082,30.351890 27.276842,28.851328 26.996747,27.386363 L 29.174994,26.230789 z " />
+ </g>
+ <g
+ transform="matrix(1.013963,0.000000,0.000000,1.013963,1.878556,5.469083)"
+ id="g3755">
+ <path
+ style="fill:#ffffff;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ id="path3693"
+ d="M 11.316278,22.373912 C 13.137134,21.040704 12.443447,22.092821 12.444714,23.520770 C 12.430049,24.807118 12.620598,26.077651 12.907135,27.327364 L 11.644224,28.009509 C 11.357063,26.749616 11.164834,25.469172 11.168897,24.173075 C 11.149082,22.620294 10.880245,22.220438 12.516062,21.502217 L 11.316278,22.373912 z " />
+ <path
+ style="fill:#ffffff;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ id="path3695"
+ d="M 15.610946,22.413179 C 15.586578,23.203483 15.586964,23.994452 15.583955,24.785079 C 15.582875,25.117013 15.582924,25.448948 15.582616,25.780883 L 14.317899,26.425288 C 14.317592,26.093808 14.317641,25.762328 14.316561,25.430849 C 14.313575,24.649394 14.314193,23.867574 14.289570,23.086454 L 15.610946,22.413179 z " />
+ <path
+ style="fill:#ffffff;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ id="path3697"
+ d="M 17.833281,21.200996 C 17.932050,21.997348 17.950388,22.856151 17.978429,23.673827 C 17.986396,23.914997 17.991625,24.156243 17.998223,24.397452 L 16.740672,25.042643 C 16.732850,24.802516 16.727470,24.562310 16.717206,24.322263 C 16.681420,23.507155 16.675481,22.674054 16.511905,21.874271 L 17.833281,21.200996 z " />
+ <path
+ style="fill:#ffffff;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ id="path3699"
+ d="M 20.257647,20.594904 C 20.061483,21.277118 19.988799,21.990783 19.919991,22.698525 C 19.852596,23.459764 19.822368,24.223412 19.791333,24.986754 L 18.534220,25.621448 C 18.564177,24.858063 18.593786,24.094534 18.649765,23.332489 C 18.705131,22.644365 18.732760,21.926923 18.936271,21.268179 L 20.257647,20.594904 z " />
+ <path
+ style="fill:#ffffff;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ id="path3701"
+ d="M 9.8969255,22.310339 C 10.803649,22.501267 11.723703,22.658903 12.639116,22.814076 C 14.789061,23.146228 16.945692,23.441011 19.107211,23.687690 C 20.011149,23.780203 20.914437,23.877970 21.816810,23.984418 L 20.648790,24.810816 C 19.754597,24.700327 18.859587,24.597014 17.963955,24.498588 C 15.801624,24.238152 13.642863,23.943889 11.488982,23.621430 C 10.560864,23.472229 9.6271038,23.290017 8.6971411,23.182034 L 9.8969255,22.310339 z " />
+ </g>
+ </g>
+</svg>
diff --git a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/devices/camera-photo.svg b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/devices/camera-photo.svg
new file mode 100644
index 0000000000..4911410136
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/devices/camera-photo.svg
@@ -0,0 +1,681 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ sodipodi:docname="camera-photo.svg"
+ sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/devices"
+ inkscape:version="0.46"
+ sodipodi:version="0.32"
+ id="svg7631"
+ height="48px"
+ width="48px"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <defs
+ id="defs3">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 24 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="48 : 24 : 1"
+ inkscape:persp3d-origin="24 : 16 : 1"
+ id="perspective102" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="radialGradient6719"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
+ cx="605.71429"
+ cy="486.64789"
+ fx="605.71429"
+ fy="486.64789"
+ r="117.14286" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient5060">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop5062" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop5064" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="radialGradient6717"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
+ cx="605.71429"
+ cy="486.64789"
+ fx="605.71429"
+ fy="486.64789"
+ r="117.14286" />
+ <linearGradient
+ id="linearGradient5048">
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="0"
+ id="stop5050" />
+ <stop
+ id="stop5056"
+ offset="0.5"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop5052" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5048"
+ id="linearGradient6715"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
+ x1="302.85715"
+ y1="366.64789"
+ x2="302.85715"
+ y2="609.50507" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient2818">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop2820" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop2822" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2690"
+ inkscape:collect="always">
+ <stop
+ id="stop2692"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop2694"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2673">
+ <stop
+ id="stop2675"
+ offset="0.0000000"
+ style="stop-color:#8b8b8b;stop-opacity:1.0000000;" />
+ <stop
+ style="stop-color:#d3d9da;stop-opacity:1.0000000;"
+ offset="0.50000000"
+ id="stop2681" />
+ <stop
+ id="stop2677"
+ offset="1.0000000"
+ style="stop-color:#828282;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2656"
+ inkscape:collect="always">
+ <stop
+ id="stop2658"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop2660"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2631">
+ <stop
+ id="stop2633"
+ offset="0.0000000"
+ style="stop-color:#010101;stop-opacity:1.0000000;" />
+ <stop
+ id="stop2635"
+ offset="1.0000000"
+ style="stop-color:#959595;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2615">
+ <stop
+ id="stop2617"
+ offset="0.0000000"
+ style="stop-color:#363d40;stop-opacity:1.0000000;" />
+ <stop
+ style="stop-color:#818f95;stop-opacity:1.0000000;"
+ offset="0.50000000"
+ id="stop2623" />
+ <stop
+ id="stop2619"
+ offset="1.0000000"
+ style="stop-color:#31383b;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2304">
+ <stop
+ id="stop2306"
+ offset="0.0000000"
+ style="stop-color:#353633;stop-opacity:1.0000000;" />
+ <stop
+ id="stop2308"
+ offset="1.0000000"
+ style="stop-color:#676964;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2290">
+ <stop
+ id="stop2292"
+ offset="0"
+ style="stop-color:#555753;stop-opacity:1;" />
+ <stop
+ id="stop2294"
+ offset="1.0000000"
+ style="stop-color:#313330;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2268">
+ <stop
+ id="stop2270"
+ offset="0"
+ style="stop-color:#555753;stop-opacity:1;" />
+ <stop
+ id="stop2272"
+ offset="1.0000000"
+ style="stop-opacity:1.0000000;stop-color:#141514" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2230">
+ <stop
+ style="stop-color:#eeeeee;stop-opacity:1;"
+ offset="0"
+ id="stop2232" />
+ <stop
+ style="stop-color:#a2a2a2;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop2234" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3301">
+ <stop
+ id="stop3303"
+ offset="0.0000000"
+ style="stop-color:#ffffff;stop-opacity:1.0000000;" />
+ <stop
+ id="stop3305"
+ offset="1.0000000"
+ style="stop-color:#cbcbcb;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2591">
+ <stop
+ style="stop-color:#7a7a7a;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop2593" />
+ <stop
+ style="stop-color:#000000;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop2595" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2656"
+ id="radialGradient1415"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,0.453571,-8.417747e-16,20.11540)"
+ cx="25.375000"
+ cy="36.812500"
+ fx="25.375000"
+ fy="36.812500"
+ r="17.500000" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2656"
+ id="radialGradient1417"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,0.453571,-1.856804e-15,20.11540)"
+ cx="25.375000"
+ cy="36.812500"
+ fx="25.375000"
+ fy="36.812500"
+ r="17.500000" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2615"
+ id="linearGradient1423"
+ gradientUnits="userSpaceOnUse"
+ x1="22.549892"
+ y1="39.051506"
+ x2="38.416191"
+ y2="30.566227" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2673"
+ id="linearGradient1425"
+ gradientUnits="userSpaceOnUse"
+ x1="23.660564"
+ y1="35.302856"
+ x2="33.904015"
+ y2="30.916578" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2591"
+ id="radialGradient1431"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,1.013514,-4.816024e-16,-0.304899)"
+ cx="16.875000"
+ cy="23.672499"
+ fx="16.875000"
+ fy="23.672499"
+ r="4.6250000" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2631"
+ id="linearGradient1433"
+ gradientUnits="userSpaceOnUse"
+ x1="12.835793"
+ y1="18.849401"
+ x2="18.422049"
+ y2="27.072878" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3301"
+ id="linearGradient1451"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.655244,0.000000,0.000000,1.898477,14.94194,-35.55180)"
+ x1="6.5595827"
+ y1="29.373810"
+ x2="6.5595827"
+ y2="30.191154" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3301"
+ id="linearGradient1456"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.477785,0.000000,0.000000,1.982181,18.56747,-51.60768)"
+ x1="6.5595827"
+ y1="29.373810"
+ x2="6.5595827"
+ y2="30.191154" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2230"
+ id="linearGradient1458"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.318423,0.000000,0.000000,0.773191,18.70736,-14.22023)"
+ x1="7.9151335"
+ y1="30.816841"
+ x2="7.9151335"
+ y2="24.700985" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2268"
+ id="linearGradient1461"
+ gradientUnits="userSpaceOnUse"
+ x1="29.395439"
+ y1="9.4121714"
+ x2="29.395439"
+ y2="12.846690" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2690"
+ id="linearGradient1469"
+ gradientUnits="userSpaceOnUse"
+ x1="16.666620"
+ y1="16.124990"
+ x2="35.888493"
+ y2="57.124992" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2290"
+ id="linearGradient1475"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.024993,0.000000,0.000000,1.000000,-6.795098e-2,0.000000)"
+ x1="7.8705277"
+ y1="29.718750"
+ x2="14.843750"
+ y2="29.718750" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2304"
+ id="linearGradient1482"
+ gradientUnits="userSpaceOnUse"
+ x1="16.353432"
+ y1="26.093410"
+ x2="30.130077"
+ y2="26.093410" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2290"
+ id="linearGradient1485"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.035758,0.000000,0.000000,1.000000,-0.162473,0.202030)"
+ x1="7.8705277"
+ y1="29.718750"
+ x2="14.843750"
+ y2="29.718750" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2818"
+ id="radialGradient2824"
+ cx="14.75"
+ cy="22.6875"
+ fx="14.75"
+ fy="22.6875"
+ r="1.75"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,1.035714,0.000000,-0.810268)"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <sodipodi:namedview
+ inkscape:guide-bbox="true"
+ showguides="true"
+ fill="#555753"
+ inkscape:window-y="117"
+ inkscape:window-x="326"
+ inkscape:window-height="731"
+ inkscape:window-width="872"
+ inkscape:showpageshadow="false"
+ inkscape:document-units="px"
+ inkscape:grid-bbox="true"
+ showgrid="false"
+ inkscape:current-layer="layer1"
+ inkscape:cy="16.629155"
+ inkscape:cx="10.439293"
+ inkscape:zoom="1"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ borderopacity="0.20392157"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source>http://jimmac.musichall.cz</dc:source>
+ <dc:title>Photo Camera</dc:title>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>camera</rdf:li>
+ <rdf:li>photo</rdf:li>
+ <rdf:li>SLR</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/publicdomain/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:groupmode="layer"
+ inkscape:label="Layer 1"
+ id="layer1">
+ <g
+ transform="matrix(2.45274e-2,0,0,2.086758e-2,45.15006,37.31476)"
+ id="g6707">
+ <rect
+ style="opacity:0.40206185;color:black;fill:url(#linearGradient6715);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="rect6709"
+ width="1339.6335"
+ height="478.35718"
+ x="-1559.2523"
+ y="-150.69685" />
+ <path
+ style="opacity:0.40206185;color:black;fill:url(#radialGradient6717);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z "
+ id="path6711"
+ sodipodi:nodetypes="cccc" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path6713"
+ d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z "
+ style="opacity:0.40206185;color:black;fill:url(#radialGradient6719);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ </g>
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.39873418;color:#000000;fill:url(#radialGradient1415);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block;overflow:visible"
+ id="path2664"
+ sodipodi:cx="25.375000"
+ sodipodi:cy="36.812500"
+ sodipodi:rx="17.500000"
+ sodipodi:ry="7.9375000"
+ d="M 42.875000 36.812500 A 17.500000 7.9375000 0 1 1 7.8750000,36.812500 A 17.500000 7.9375000 0 1 1 42.875000 36.812500 z"
+ transform="matrix(0.693194,0.000000,0.000000,0.811023,13.91019,9.956690)" />
+ <path
+ style="opacity:1.0000000;color:#000000;fill:url(#linearGradient1485);fill-opacity:1.0000000;fill-rule:nonzero;stroke:#282828;stroke-width:2.0000002;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block;overflow:visible"
+ d="M 8.9327762,18.920780 C 5.4615071,18.920780 2.6534933,20.040780 2.6534933,21.420780 C 2.6534933,21.577572 2.8105028,21.709462 2.8800654,21.858280 C 2.8698789,21.907712 2.7829631,21.899460 2.7829631,21.952030 C 2.7829631,21.952030 2.6534933,38.263988 2.6534933,38.420780 C 2.6534933,39.800780 5.4615071,40.920780 8.9327762,40.920780 C 12.404046,40.920780 15.212059,39.800780 15.212059,38.420780 L 15.082590,21.952030 C 15.082590,21.899460 14.995674,21.907712 14.985487,21.858280 C 15.055050,21.709462 15.212059,21.577572 15.212059,21.420780 C 15.212059,20.040780 12.404046,18.920780 8.9327762,18.920780 z "
+ id="path2608"
+ sodipodi:nodetypes="csscssscssc" />
+ <path
+ sodipodi:nodetypes="ccccccccczcc"
+ id="path8417"
+ d="M 2.1428571,38.647933 L 42.285714,38.647933 C 43.396882,38.748948 44.505076,37.497897 44.505076,36.790790 L 44.505076,19.142857 C 44.404061,18.031689 40.536106,16.719102 39.626969,16.618087 L 37.194851,16.618087 L 34.271326,13.533125 L 23.714286,13.533125 L 20.278818,16.564532 C 20.278818,16.564532 13.552003,16.776186 8.3377087,17.731617 C 3.1234141,18.687048 2.0000000,20.318891 2.0000000,21.531074 L 2.1428571,38.647933 z "
+ style="opacity:1.0000000;color:#000000;fill:url(#linearGradient1482);fill-opacity:1.0000000;fill-rule:nonzero;stroke:#282828;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block;overflow:visible" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path2300"
+ d="M 33.890618,13.907352 L 35.254324,17.695424 L 37.123106,17.240855 L 33.890618,13.907352 z "
+ style="opacity:1.0000000;color:#000000;fill:#3f413e;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block;overflow:visible" />
+ <path
+ transform="matrix(1.256914,0.000000,0.000000,1.256914,-11.68675,-10.02479)"
+ d="M 43.133513 33.908371 A 1.9697975 1.9697975 0 1 1 39.193918,33.908371 A 1.9697975 1.9697975 0 1 1 43.133513 33.908371 z"
+ sodipodi:ry="1.9697975"
+ sodipodi:rx="1.9697975"
+ sodipodi:cy="33.908371"
+ sodipodi:cx="41.163715"
+ id="path2302"
+ style="opacity:1.0000000;color:#000000;fill:#585b57;fill-opacity:1.0000000;fill-rule:nonzero;stroke:#a7a7a7;stroke-width:0.79559946;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block;overflow:visible"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(1.082923,0.000000,0.000000,1.082923,-3.320501,-4.385684)"
+ d="M 40.714286 33.571430 A 10.142858 10.142858 0 1 1 20.428571,33.571430 A 10.142858 10.142858 0 1 1 40.714286 33.571430 z"
+ sodipodi:ry="10.142858"
+ sodipodi:rx="10.142858"
+ sodipodi:cy="33.571430"
+ sodipodi:cx="30.571428"
+ id="path2280"
+ style="opacity:1.0000000;color:#000000;fill:url(#linearGradient1423);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block;overflow:visible"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1.0000000;color:#000000;fill:url(#linearGradient1425);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block;overflow:visible"
+ id="path2278"
+ sodipodi:cx="30.571428"
+ sodipodi:cy="33.571430"
+ sodipodi:rx="10.142858"
+ sodipodi:ry="10.142858"
+ d="M 40.714286 33.571430 A 10.142858 10.142858 0 1 1 20.428571,33.571430 A 10.142858 10.142858 0 1 1 40.714286 33.571430 z"
+ transform="matrix(1.082923,0.000000,0.000000,1.082923,-3.155039,-2.495930)" />
+ <path
+ sodipodi:nodetypes="csscssscssc"
+ id="path7949"
+ d="M 8.9327729,18.718750 C 5.4975804,18.718750 2.7187500,19.838750 2.7187500,21.218750 C 2.7187500,21.375542 2.8741277,21.507432 2.9429673,21.656250 C 2.9328867,21.705682 2.8468742,21.697430 2.8468742,21.750000 C 2.8468742,21.750000 2.7187500,38.061958 2.7187500,38.218750 C 2.7187500,39.598750 5.4975804,40.718750 8.9327729,40.718750 C 12.367966,40.718750 15.146796,39.598750 15.146796,38.218750 L 15.018672,21.750000 C 15.018672,21.697430 14.932659,21.705682 14.922578,21.656250 C 14.991418,21.507432 15.146796,21.375542 15.146796,21.218750 C 15.146796,19.838750 12.367966,18.718750 8.9327729,18.718750 z "
+ style="opacity:1.0000000;color:#000000;fill:url(#linearGradient1475);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block;overflow:visible" />
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path2298"
+ d="M 24.243661,14.159890 L 23.486047,17.796439 L 23.132493,19.008622 L 20.354573,16.937809 L 24.243661,14.159890 z "
+ style="opacity:1.0000000;color:#000000;fill:#7b7e79;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block;overflow:visible" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path2276"
+ d="M 19.030081,27.995300 L 23.940615,19.412683 L 35.153309,19.412683 L 39.991888,26.528041 L 35.254324,17.796439 L 23.435539,17.796439 L 19.030081,27.995300 z "
+ style="opacity:1.0000000;color:#000000;fill:#a7aba7;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block;overflow:visible" />
+ <path
+ sodipodi:nodetypes="cssssccc"
+ id="path7953"
+ d="M 20.312500,16.875000 C 20.312500,16.875000 8.1666040,17.513063 4.1562500,19.625000 C 3.3042101,20.073702 2.6682424,20.465607 2.6682424,21.067227 C 2.6682424,22.447227 5.4923214,24.093750 8.8437500,24.093750 C 12.195179,24.093750 14.843750,22.598750 14.843750,21.218750 C 14.843750,20.904411 14.663819,20.589696 14.406250,20.312500 L 23.031250,18.500000 L 20.312500,16.875000 z "
+ style="color:#000000;fill:#888a85;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block;overflow:visible" />
+ <path
+ sodipodi:nodetypes="ccsccscccccccc"
+ id="path2683"
+ d="M 24.553211,14.482118 L 20.635909,17.275103 C 20.635909,17.275104 14.191167,17.710137 9.3867322,18.590468 C 4.5822970,19.470800 3.1666200,20.423893 3.0416200,21.603294 L 3.2677390,38.194718 C 3.5637007,39.355800 6.4977958,40.267861 9.4963120,40.267861 C 12.494828,40.267861 14.997700,38.668300 15.293662,37.507218 L 41.781643,37.632218 C 43.242971,37.662792 43.513492,36.931125 43.513492,36.279599 L 43.513492,19.602477 C 43.513492,18.890493 40.671858,17.738265 39.834182,17.645190 L 36.900777,17.707690 L 33.660467,14.482118 L 24.553211,14.482118 z "
+ style="opacity:0.41772148;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:nonzero;stroke:url(#linearGradient1469);stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block;overflow:visible" />
+ <path
+ transform="matrix(1.082923,0.000000,0.000000,1.082923,-3.050891,-1.568850)"
+ d="M 40.714286 33.571430 A 10.142858 10.142858 0 1 1 20.428571,33.571430 A 10.142858 10.142858 0 1 1 40.714286 33.571430 z"
+ sodipodi:ry="10.142858"
+ sodipodi:rx="10.142858"
+ sodipodi:cy="33.571430"
+ sodipodi:cx="30.571428"
+ id="path8415"
+ style="opacity:1.0000000;color:#000000;fill:#2e3436;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block;overflow:visible"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill:url(#radialGradient1431);fill-opacity:1.0000000;fill-rule:nonzero;stroke:url(#linearGradient1433);stroke-width:0.59630877;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ id="path2589"
+ sodipodi:cx="15.750000"
+ sodipodi:cy="22.562500"
+ sodipodi:rx="4.1250000"
+ sodipodi:ry="4.1875000"
+ d="M 19.875000 22.562500 A 4.1250000 4.1875000 0 1 1 11.625000,22.562500 A 4.1250000 4.1875000 0 1 1 19.875000 22.562500 z"
+ transform="matrix(1.676984,0.000000,0.000000,1.676984,3.488419,-3.050526)" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.60759497;color:#000000;fill:#ffffff;fill-opacity:0.52866244;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ id="path2599"
+ sodipodi:cx="14.750000"
+ sodipodi:cy="22.687500"
+ sodipodi:rx="1.7500000"
+ sodipodi:ry="1.8125000"
+ d="M 16.500000 22.687500 A 1.7500000 1.8125000 0 1 1 13.000000,22.687500 A 1.7500000 1.8125000 0 1 1 16.500000 22.687500 z"
+ transform="matrix(1.676984,0.000000,0.000000,1.676984,5.499948,-3.195174)" />
+ <path
+ transform="matrix(1.673245,0.000000,0.000000,1.673245,3.333940,-5.000547)"
+ d="M 16.500000 22.687500 A 1.7500000 1.8125000 0 1 1 13.000000,22.687500 A 1.7500000 1.8125000 0 1 1 16.500000 22.687500 z"
+ sodipodi:ry="1.8125000"
+ sodipodi:rx="1.7500000"
+ sodipodi:cy="22.687500"
+ sodipodi:cx="14.750000"
+ id="path2601"
+ style="opacity:0.37341771;color:#000000;fill:#ffffff;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1.0000000;color:#000000;fill:url(#radialGradient2824);fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ id="path8405"
+ sodipodi:cx="14.750000"
+ sodipodi:cy="22.687500"
+ sodipodi:rx="1.7500000"
+ sodipodi:ry="1.8125000"
+ d="M 16.500000 22.687500 A 1.7500000 1.8125000 0 1 1 13.000000,22.687500 A 1.7500000 1.8125000 0 1 1 16.500000 22.687500 z"
+ transform="matrix(0.412730,0.000000,0.000000,0.412730,27.45136,28.98197)" />
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path1507"
+ d="M 22.223356,15.574103 L 25.152798,13.452783 L 26.061935,11.028417 L 32.425896,11.028417 L 33.739095,13.957860 L 36.567522,16.382225 L 34.042141,5.4725778 L 24.142646,5.4725778 L 22.223356,15.574103 z "
+ style="opacity:1.0000000;color:#000000;fill:url(#linearGradient1461);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block;overflow:visible" />
+ <rect
+ ry="1.5035454"
+ rx="1.5035444"
+ y="4.6366777"
+ x="24.478594"
+ height="4.5837932"
+ width="9.3285160"
+ id="rect3297"
+ style="color:#000000;fill:url(#linearGradient1456);fill-opacity:1.0000000;fill-rule:nonzero;stroke:url(#linearGradient1458);stroke-width:1.0000004;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans" />
+ <path
+ transform="matrix(0.359444,0.000000,0.000000,0.554344,7.698551,7.305544e-2)"
+ sodipodi:type="arc"
+ style="opacity:1.0000000;color:#000000;fill:#2f302e;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block;overflow:visible"
+ id="path2288"
+ sodipodi:cx="8.7857141"
+ sodipodi:cy="38.214287"
+ sodipodi:rx="6.0714288"
+ sodipodi:ry="2.5000000"
+ d="M 14.857143 38.214287 A 6.0714288 2.5000000 0 1 1 2.7142854,38.214287 A 6.0714288 2.5000000 0 1 1 14.857143 38.214287 z" />
+ <path
+ sodipodi:nodetypes="czcccsc"
+ id="path2312"
+ d="M 2.7034271,21.250564 C 2.5678753,23.036228 5.1472726,25.130768 8.8987966,25.132037 C 12.712821,25.133306 14.748227,22.948217 14.950257,21.028927 L 19.495944,19.311668 L 14.344166,20.321820 C 14.445182,22.241110 12.642329,24.152278 8.9038729,24.092824 C 4.8175065,24.026843 3.3284271,22.438064 2.7034271,21.250564 z "
+ style="opacity:1.0000000;color:#000000;fill:#c4c6c3;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block;overflow:visible" />
+ <rect
+ style="color:#000000;fill:url(#linearGradient1451);fill-opacity:1.0000000;fill-rule:nonzero;stroke:#464646;stroke-width:0.99999970;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ id="rect2282"
+ width="4.1362314"
+ height="4.3902278"
+ x="17.562916"
+ y="18.317474"
+ rx="0.69542336"
+ ry="0.69542354" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.43037972;color:#000000;fill:#ffffff;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ id="path2612"
+ sodipodi:cx="14.750000"
+ sodipodi:cy="22.687500"
+ sodipodi:rx="1.7500000"
+ sodipodi:ry="1.8125000"
+ d="M 16.500000 22.687500 A 1.7500000 1.8125000 0 1 1 13.000000,22.687500 A 1.7500000 1.8125000 0 1 1 16.500000 22.687500 z"
+ transform="matrix(0.389835,0.000000,0.000000,0.389835,4.452477,12.38659)" />
+ <path
+ transform="matrix(0.456110,0.000000,0.000000,0.456110,20.30269,21.39326)"
+ d="M 16.500000 22.687500 A 1.7500000 1.8125000 0 1 1 13.000000,22.687500 A 1.7500000 1.8125000 0 1 1 16.500000 22.687500 z"
+ sodipodi:ry="1.8125000"
+ sodipodi:rx="1.7500000"
+ sodipodi:cy="22.687500"
+ sodipodi:cx="14.750000"
+ id="path2629"
+ style="opacity:1.0000000;color:#000000;fill:#ffffff;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1.0000000;color:#000000;fill:#c5c5c5;fill-opacity:0.52866244;fill-rule:nonzero;stroke:none;stroke-width:2.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block;overflow:visible"
+ id="path2641"
+ sodipodi:cx="40.625000"
+ sodipodi:cy="20.562500"
+ sodipodi:rx="1.6250000"
+ sodipodi:ry="0.68750000"
+ d="M 42.250000 20.562500 A 1.6250000 0.68750000 0 1 1 39.000000,20.562500 A 1.6250000 0.68750000 0 1 1 42.250000 20.562500 z"
+ transform="matrix(1.038462,0.000000,0.000000,1.636364,-1.187500,-12.71023)" />
+ <path
+ transform="matrix(1.038462,0.000000,0.000000,1.636364,-1.125000,-12.33523)"
+ d="M 42.250000 20.562500 A 1.6250000 0.68750000 0 1 1 39.000000,20.562500 A 1.6250000 0.68750000 0 1 1 42.250000 20.562500 z"
+ sodipodi:ry="0.68750000"
+ sodipodi:rx="1.6250000"
+ sodipodi:cy="20.562500"
+ sodipodi:cx="40.625000"
+ id="path2639"
+ style="opacity:1.0000000;color:#000000;fill:#565656;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:2.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block;overflow:visible"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:nodetypes="cs"
+ id="path2650"
+ d="M 23.271357,28.422173 C 25.874096,25.054531 32.027018,24.229460 35.546276,27.380934"
+ style="opacity:1.0000000;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:nonzero;stroke:#777777;stroke-width:1.0000007;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block;overflow:visible" />
+ <path
+ id="path2668"
+ d="M 30.219981,31.818049 C 28.600014,31.818049 27.309626,33.185948 27.309626,34.863771 C 27.309626,35.247616 27.556343,35.506933 27.681881,35.845170 C 27.808561,35.862524 27.889059,35.980535 28.020294,35.980535 C 29.636648,35.980535 30.930649,34.642736 30.930649,32.968655 C 30.930649,32.575045 30.656499,32.298592 30.524554,31.953415 C 30.409594,31.939221 30.338611,31.818049 30.219981,31.818049 z "
+ style="opacity:0.67088610;color:#000000;fill:#ffffff;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans" />
+ </g>
+</svg>
diff --git a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/devices/camera-video.svg b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/devices/camera-video.svg
new file mode 100644
index 0000000000..e24713457f
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/devices/camera-video.svg
@@ -0,0 +1,1257 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ sodipodi:docname="camera-video.svg"
+ sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/devices"
+ inkscape:version="0.46"
+ sodipodi:version="0.32"
+ id="svg1260"
+ height="48px"
+ width="48px"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <defs
+ id="defs3">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 24 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="48 : 24 : 1"
+ inkscape:persp3d-origin="24 : 16 : 1"
+ id="perspective177" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="radialGradient6719"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
+ cx="605.71429"
+ cy="486.64789"
+ fx="605.71429"
+ fy="486.64789"
+ r="117.14286" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient5060">
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop5062" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop5064" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="radialGradient6717"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
+ cx="605.71429"
+ cy="486.64789"
+ fx="605.71429"
+ fy="486.64789"
+ r="117.14286" />
+ <linearGradient
+ id="linearGradient5048">
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="0"
+ id="stop5050" />
+ <stop
+ id="stop5056"
+ offset="0.5"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop5052" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5048"
+ id="linearGradient6715"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
+ x1="302.85715"
+ y1="366.64789"
+ x2="302.85715"
+ y2="609.50507" />
+ <linearGradient
+ id="linearGradient2244"
+ inkscape:collect="always">
+ <stop
+ id="stop2246"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop2248"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2230">
+ <stop
+ id="stop2232"
+ offset="0"
+ style="stop-color:#eeeeee;stop-opacity:1;" />
+ <stop
+ id="stop2234"
+ offset="1.0000000"
+ style="stop-color:#a2a2a2;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3301">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop3303" />
+ <stop
+ style="stop-color:#cbcbcb;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop3305" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3287"
+ inkscape:collect="always">
+ <stop
+ id="stop3289"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop3291"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3279">
+ <stop
+ id="stop3281"
+ offset="0.0000000"
+ style="stop-color:#bebebe;stop-opacity:0.0000000;" />
+ <stop
+ id="stop3283"
+ offset="1.0000000"
+ style="stop-color:#717171;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3265"
+ inkscape:collect="always">
+ <stop
+ id="stop3267"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop3269"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3250">
+ <stop
+ id="stop3252"
+ offset="0"
+ style="stop-color:#174992;stop-opacity:1;" />
+ <stop
+ id="stop3254"
+ offset="1.0000000"
+ style="stop-color:#233247;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3238">
+ <stop
+ id="stop3240"
+ offset="0.0000000"
+ style="stop-color:#000000;stop-opacity:0.27835050;" />
+ <stop
+ id="stop3242"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3180">
+ <stop
+ id="stop3182"
+ offset="0.0000000"
+ style="stop-color:#c8c8c8;stop-opacity:1.0000000;" />
+ <stop
+ id="stop3184"
+ offset="1.0000000"
+ style="stop-color:#545454;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3170">
+ <stop
+ style="stop-color:#919191;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop3172" />
+ <stop
+ style="stop-color:#545454;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop3174" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3116"
+ inkscape:collect="always">
+ <stop
+ id="stop3118"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop3120"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3016">
+ <stop
+ id="stop3018"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop3020"
+ offset="1.0000000"
+ style="stop-color:#747474;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2854">
+ <stop
+ id="stop2856"
+ offset="0.0000000"
+ style="stop-color:#dddddd;stop-opacity:1.0000000;" />
+ <stop
+ id="stop2858"
+ offset="1.0000000"
+ style="stop-color:#a0a0a0;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2801">
+ <stop
+ style="stop-color:#d7d7d7;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop2803" />
+ <stop
+ style="stop-color:#9a9a9a;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop2805" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2659">
+ <stop
+ id="stop2661"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop2663"
+ offset="1.0000000"
+ style="stop-color:#b6b6b6;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2591">
+ <stop
+ id="stop2593"
+ offset="0.0000000"
+ style="stop-color:#d3d3d3;stop-opacity:1.0000000;" />
+ <stop
+ id="stop2595"
+ offset="1.0000000"
+ style="stop-color:#000000;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2261">
+ <stop
+ id="stop2263"
+ offset="0.0000000"
+ style="stop-color:#b6b6b6;stop-opacity:1.0000000;" />
+ <stop
+ id="stop2265"
+ offset="1.0000000"
+ style="stop-color:#a0a0a0;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ gradientTransform="matrix(1.192333,0.000000,0.000000,1.000000,-11.96891,-0.625000)"
+ y2="26.625000"
+ x2="39.532253"
+ y1="3.2500000"
+ x1="39.814648"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3186"
+ xlink:href="#linearGradient3180"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="35.537243"
+ x2="31.554640"
+ y1="23.074486"
+ x1="31.289474"
+ gradientTransform="matrix(0.920341,0.000000,0.000000,1.000000,5.113065,-0.618717)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1605"
+ xlink:href="#linearGradient2261"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.686241"
+ x2="34.443943"
+ y1="24.311874"
+ x1="32.372795"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1607"
+ xlink:href="#linearGradient3250"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="23.500000"
+ x2="21.375000"
+ y1="33.218750"
+ x1="40.593750"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1609"
+ xlink:href="#linearGradient3116"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="35.071529"
+ x2="33.984650"
+ y1="20.222286"
+ x1="28.798098"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1611"
+ xlink:href="#linearGradient3265"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="28.125509"
+ x2="13.114621"
+ y1="26.012749"
+ x1="16.489622"
+ gradientTransform="matrix(1.030948,0.000000,0.000000,1.030948,-0.405869,-2.837538)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1618"
+ xlink:href="#linearGradient3238"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="27.727798"
+ x2="16.638567"
+ y1="23.396770"
+ x1="30.661369"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1629"
+ xlink:href="#linearGradient2244"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="27.409931"
+ x2="7.1562500"
+ y1="32.006123"
+ x1="8.6845827"
+ gradientTransform="matrix(0.633663,0.000000,0.000000,1.297297,10.46536,-8.810810)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1633"
+ xlink:href="#linearGradient3016"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="27.891649"
+ x2="26.604893"
+ y1="15.296312"
+ x1="26.980543"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1676"
+ xlink:href="#linearGradient3279"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="32.090096"
+ x2="23.864855"
+ y1="24.665476"
+ x1="18.694136"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1679"
+ xlink:href="#linearGradient2801"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="30.191154"
+ x2="6.5595827"
+ y1="29.373810"
+ x1="6.5595827"
+ gradientTransform="matrix(1.120873,0.000000,0.000000,2.563637,-0.106115,-48.35474)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1682"
+ xlink:href="#linearGradient3301"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="24.700985"
+ x2="7.9151335"
+ y1="30.816841"
+ x1="7.9151335"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1684"
+ xlink:href="#linearGradient2230"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="35.138027"
+ x2="11.343681"
+ y1="16.013027"
+ x1="9.5126343"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1687"
+ xlink:href="#linearGradient3287"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.841251"
+ x2="12.523165"
+ y1="29.706160"
+ x1="12.586802"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1690"
+ xlink:href="#linearGradient2854"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.841251"
+ x2="12.523165"
+ y1="24.643660"
+ x1="12.649302"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1693"
+ xlink:href="#linearGradient2854"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.841251"
+ x2="12.523165"
+ y1="24.643660"
+ x1="12.649302"
+ gradientTransform="translate(-1.125000,-0.125000)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1696"
+ xlink:href="#linearGradient3170"
+ inkscape:collect="always" />
+ <radialGradient
+ r="4.6250000"
+ fy="23.672499"
+ fx="16.875000"
+ cy="23.672499"
+ cx="16.875000"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,1.013514,0.000000,-0.304899)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient1699"
+ xlink:href="#linearGradient2591"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="30.812494"
+ x2="12.257777"
+ y1="42.484329"
+ x1="12.187341"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1701"
+ xlink:href="#linearGradient2659"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="30.812517"
+ x2="7.7578020"
+ y1="42.484352"
+ x1="7.6873660"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1703"
+ xlink:href="#linearGradient2659"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="30.812494"
+ x2="3.2578177"
+ y1="42.484329"
+ x1="3.1873815"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1705"
+ xlink:href="#linearGradient2659"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="30.812494"
+ x2="-1.2421666"
+ y1="42.484329"
+ x1="-1.3126028"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1707"
+ xlink:href="#linearGradient2659"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="28.562525"
+ x2="1.0078188"
+ y1="40.234360"
+ x1="0.93738264"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1709"
+ xlink:href="#linearGradient2659"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="28.562502"
+ x2="5.5078030"
+ y1="40.234337"
+ x1="5.4373670"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1711"
+ xlink:href="#linearGradient2659"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="28.562502"
+ x2="10.007788"
+ y1="40.234337"
+ x1="9.9373512"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1713"
+ xlink:href="#linearGradient2659"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="26.312532"
+ x2="12.257786"
+ y1="37.984367"
+ x1="12.187350"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1715"
+ xlink:href="#linearGradient2659"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="26.312510"
+ x2="7.7578020"
+ y1="37.984344"
+ x1="7.6873660"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1717"
+ xlink:href="#linearGradient2659"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="26.312510"
+ x2="3.2578177"
+ y1="37.984344"
+ x1="3.1873815"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1719"
+ xlink:href="#linearGradient2659"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="26.312510"
+ x2="-1.2421666"
+ y1="37.984344"
+ x1="-1.3126028"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1721"
+ xlink:href="#linearGradient2659"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="24.062519"
+ x2="1.0078188"
+ y1="35.734352"
+ x1="0.93738264"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1723"
+ xlink:href="#linearGradient2659"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="21.812548"
+ x2="-1.2421666"
+ y1="33.484383"
+ x1="-1.3126028"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1725"
+ xlink:href="#linearGradient2659"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="21.812548"
+ x2="3.2578108"
+ y1="33.484383"
+ x1="3.1873748"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1727"
+ xlink:href="#linearGradient2659"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="24.062519"
+ x2="5.5078030"
+ y1="35.734352"
+ x1="5.4373670"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1729"
+ xlink:href="#linearGradient2659"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="21.812548"
+ x2="7.7578020"
+ y1="33.484383"
+ x1="7.6873660"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1731"
+ xlink:href="#linearGradient2659"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="24.062519"
+ x2="10.007794"
+ y1="35.734352"
+ x1="9.9373579"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1733"
+ xlink:href="#linearGradient2659"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5048"
+ id="linearGradient12782"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
+ x1="302.85715"
+ y1="366.64789"
+ x2="302.85715"
+ y2="609.50507" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="radialGradient12784"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
+ cx="605.71429"
+ cy="486.64789"
+ fx="605.71429"
+ fy="486.64789"
+ r="117.14286" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="radialGradient12786"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
+ cx="605.71429"
+ cy="486.64789"
+ fx="605.71429"
+ fy="486.64789"
+ r="117.14286" />
+ </defs>
+ <sodipodi:namedview
+ inkscape:window-y="70"
+ inkscape:window-x="429"
+ inkscape:window-height="778"
+ inkscape:window-width="977"
+ inkscape:document-units="px"
+ inkscape:grid-bbox="true"
+ showgrid="false"
+ inkscape:current-layer="layer1"
+ inkscape:cy="7.4612846"
+ inkscape:cx="18.089653"
+ inkscape:zoom="1"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ borderopacity="0.26666667"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base"
+ inkscape:showpageshadow="false" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Camera / Video</dc:title>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source>http://jimmac.musichall.cz/</dc:source>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>camera</rdf:li>
+ <rdf:li>camcorder</rdf:li>
+ <rdf:li>video</rdf:li>
+ <rdf:li>cam</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/publicdomain/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:groupmode="layer"
+ inkscape:label="Layer 1"
+ id="layer1">
+ <path
+ sodipodi:nodetypes="czssssccc"
+ id="path3178"
+ d="M 30.806057,10.750000 C 30.806057,10.750000 30.973729,9.5937500 32.370995,9.6250000 C 32.370995,9.6250000 40.568288,9.6250000 40.568288,9.6250000 C 42.095965,9.6250000 42.636240,10.578125 42.580350,11.687500 C 42.580350,11.687500 42.580350,16.812500 42.580350,16.812500 C 42.561720,17.843750 41.741991,18.484375 40.717329,18.562500 C 40.717329,18.562500 31.178661,18.625000 31.178661,18.625000 L 30.731536,16.000000 L 30.806057,10.750000 z "
+ style="color:#000000;fill:url(#linearGradient3186);fill-opacity:1.0000000;fill-rule:nonzero;stroke:#6c6c6c;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans" />
+ <g
+ transform="matrix(1.98486e-2,0,0,2.086758e-2,38.77905,35.9036)"
+ id="g6707">
+ <rect
+ style="opacity:0.40206185;color:black;fill:url(#linearGradient6715);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="rect6709"
+ width="1339.6335"
+ height="478.35718"
+ x="-1559.2523"
+ y="-150.69685" />
+ <path
+ style="opacity:0.40206185;color:black;fill:url(#radialGradient6717);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z "
+ id="path6711"
+ sodipodi:nodetypes="cccc" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path6713"
+ d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z "
+ style="opacity:0.40206185;color:black;fill:url(#radialGradient6719);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ </g>
+ <g
+ transform="matrix(1.194071e-2,0,0,1.272548e-2,44.30799,39.99902)"
+ id="g12774"
+ style="opacity:0.32989691">
+ <rect
+ style="opacity:0.40206185;color:black;fill:url(#linearGradient12782);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="rect12776"
+ width="1339.6335"
+ height="478.35718"
+ x="-1559.2523"
+ y="-150.69685" />
+ <path
+ style="opacity:0.40206185;color:black;fill:url(#radialGradient12784);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z "
+ id="path12778"
+ sodipodi:nodetypes="cccc" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path12780"
+ d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z "
+ style="opacity:0.40206185;color:black;fill:url(#radialGradient12786);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ </g>
+ </g>
+ <g
+ inkscape:label="vectors"
+ id="layer2"
+ inkscape:groupmode="layer">
+ <path
+ sodipodi:nodetypes="ccccc"
+ id="path3188"
+ d="M 39.875000,12.375000 L 31.687500,14.875000 L 26.062500,14.625000 L 34.187500,12.375000 L 39.875000,12.375000 z "
+ style="color:#000000;fill:#c6c6c6;fill-opacity:1.0000000;fill-rule:nonzero;stroke:#c4c4c4;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans" />
+ <path
+ id="path3168"
+ d="M 39.875000,12.437500 L 31.500000,14.875000 L 31.500000,19.375000 L 39.875000,16.500000 L 39.875000,12.437500 z "
+ style="color:#000000;fill:url(#linearGradient1696);fill-opacity:1.0000000;fill-rule:nonzero;stroke:#7a7a7a;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans" />
+ <path
+ style="opacity:1.0000000;color:#000000;fill:url(#linearGradient1693);fill-opacity:1.0000000;fill-rule:nonzero;stroke:#6c6c6c;stroke-width:2.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ d="M 30.946541,13.125000 L 16.187500,13.045653 C 10.985425,13.045653 8.6250000,16.568903 8.6250000,19.639403 C 8.6250000,22.527377 10.778028,24.585851 12.250000,25.108153 L 12.250000,32.250000 C 12.250000,35.720857 14.502357,38.705357 17.687500,38.562500 L 32.531250,38.718750 C 34.430679,38.718750 37.437500,36.805677 37.437500,34.906250 L 37.437500,18.712849 C 37.437500,15.232909 35.210688,13.125000 30.946541,13.125000 z "
+ id="path3024"
+ sodipodi:nodetypes="cccccccccc" />
+ <path
+ sodipodi:nodetypes="cccccccss"
+ id="rect2100"
+ d="M 7.0590545,14.475766 C 7.0590545,14.475766 22.648340,14.118623 22.648340,14.118623 C 24.547769,14.118623 26.076912,15.647766 26.076912,17.547195 L 26.076912,34.404338 C 26.076912,36.303766 24.547769,39.113239 22.648340,39.113239 L 7.8090545,38.970382 C 4.6239115,39.113239 2.3804825,35.732338 2.3804825,32.261481 C 2.3804825,32.261481 2.3804825,20.029338 2.3804825,20.029338 C 2.2224267,17.549131 3.3232635,14.778342 7.0590545,14.475766 z "
+ style="fill:url(#linearGradient1690);fill-opacity:1.0000000;stroke:#6c6c6c;stroke-width:1.0000000;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ style="fill:none;fill-opacity:1.0000000;stroke:url(#linearGradient1687);stroke-width:0.93053865;stroke-miterlimit:4.0000000;stroke-opacity:0.75141245"
+ d="M 7.5565619,15.382160 C 7.5565619,15.382160 22.460743,15.100358 22.460743,15.100358 C 24.228235,15.100358 25.253413,14.479091 25.253413,16.246583 L 25.253413,33.793883 C 25.253413,35.561375 23.830487,38.175698 22.062995,38.175698 L 8.2544659,38.042764 C 5.2905672,38.175698 3.2913581,35.029639 3.2913581,31.799872 C 3.2913581,31.799872 3.2913581,20.417390 3.2913581,20.417390 C 3.2768635,18.551404 3.3731571,15.752106 7.5565619,15.382160 z "
+ id="path3026"
+ sodipodi:nodetypes="cccccccss" />
+ <rect
+ style="color:#000000;fill:url(#linearGradient1682);fill-opacity:1.0000000;fill-rule:nonzero;stroke:url(#linearGradient1684);stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ id="rect3297"
+ width="7.0755110"
+ height="5.9284096"
+ x="4.3773780"
+ y="24.388432"
+ rx="1.5035444"
+ ry="1.5035446" />
+ <path
+ sodipodi:nodetypes="cccccssccc"
+ id="path2295"
+ d="M 30.183978,13.125000 L 16.187500,13.023129 C 11.329175,13.054379 8.6250000,16.546379 8.6250000,19.616879 C 8.6250000,22.504853 10.778028,24.563327 12.250000,25.085629 L 12.250000,32.250000 C 12.250000,35.720857 11.688952,38.429890 17.687500,38.562500 C 17.687500,38.562500 32.531250,38.718750 32.531250,38.718750 C 34.532654,38.780384 37.437500,36.805677 37.437500,34.906250 L 37.437500,19.066403 C 37.437500,15.101007 35.022034,13.020526 30.183978,13.125000 z "
+ style="fill:url(#linearGradient1679);fill-opacity:1.0000000;stroke:none;stroke-width:1.0000000;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cscsccss"
+ id="path3277"
+ d="M 17.633475,37.570175 C 18.163805,37.487311 18.858379,37.179533 18.854339,36.475415 L 18.782524,23.958369 C 20.123514,22.351295 21.088204,20.192061 20.167708,17.633240 C 20.167708,17.633240 36.327611,17.594408 36.327611,17.594408 L 36.106640,33.946253 C 36.106640,33.946253 34.950120,37.671777 32.394329,37.702757 C 32.394329,37.702757 17.633475,37.570175 17.633475,37.570175 z "
+ style="opacity:0.65573770;color:#000000;fill:url(#linearGradient1676);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans" />
+ <path
+ transform="translate(-1.375000,-2.890164)"
+ d="M 19.875000 22.562500 A 4.1250000 4.1875000 0 1 1 11.625000,22.562500 A 4.1250000 4.1875000 0 1 1 19.875000 22.562500 z"
+ sodipodi:ry="4.1875000"
+ sodipodi:rx="4.1250000"
+ sodipodi:cy="22.562500"
+ sodipodi:cx="15.750000"
+ id="path2589"
+ style="color:#000000;fill:url(#radialGradient1699);fill-opacity:1.0000000;fill-rule:nonzero;stroke:#6c6c6c;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ sodipodi:type="arc" />
+ <path
+ transform="translate(0.562500,-2.515164)"
+ d="M 16.500000 22.687500 A 1.7500000 1.8125000 0 1 1 13.000000,22.687500 A 1.7500000 1.8125000 0 1 1 16.500000 22.687500 z"
+ sodipodi:ry="1.8125000"
+ sodipodi:rx="1.7500000"
+ sodipodi:cy="22.687500"
+ sodipodi:cx="14.750000"
+ id="path2599"
+ style="color:#000000;fill:#ffffff;fill-opacity:0.45762709;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill:#ffffff;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ id="path2601"
+ sodipodi:cx="14.750000"
+ sodipodi:cy="22.687500"
+ sodipodi:rx="1.7500000"
+ sodipodi:ry="1.8125000"
+ d="M 16.500000 22.687500 A 1.7500000 1.8125000 0 1 1 13.000000,22.687500 A 1.7500000 1.8125000 0 1 1 16.500000 22.687500 z"
+ transform="matrix(0.840316,0.000000,0.000000,0.840316,0.855340,-0.480722)" />
+ <g
+ transform="translate(1.000003,7.000000e-6)"
+ id="g3032">
+ <g
+ id="g2874"
+ transform="translate(0.176777,0.176777)"
+ style="fill:#ffffff;fill-opacity:1.0000000">
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ id="path2876"
+ sodipodi:cx="3.7500000"
+ sodipodi:cy="32.500000"
+ sodipodi:rx="1.1250000"
+ sodipodi:ry="1.1250000"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,2.833330,18.05551)" />
+ <path
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,4.833326,18.05550)"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ sodipodi:ry="1.1250000"
+ sodipodi:rx="1.1250000"
+ sodipodi:cy="32.500000"
+ sodipodi:cx="3.7500000"
+ id="path2878"
+ style="color:#000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ id="path2880"
+ sodipodi:cx="3.7500000"
+ sodipodi:cy="32.500000"
+ sodipodi:rx="1.1250000"
+ sodipodi:ry="1.1250000"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,6.833326,18.05551)" />
+ <path
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,8.833326,18.05551)"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ sodipodi:ry="1.1250000"
+ sodipodi:rx="1.1250000"
+ sodipodi:cy="32.500000"
+ sodipodi:cx="3.7500000"
+ id="path2882"
+ style="color:#000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ id="path2884"
+ sodipodi:cx="3.7500000"
+ sodipodi:cy="32.500000"
+ sodipodi:rx="1.1250000"
+ sodipodi:ry="1.1250000"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,7.833329,19.05550)" />
+ <path
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,5.833329,19.05551)"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ sodipodi:ry="1.1250000"
+ sodipodi:rx="1.1250000"
+ sodipodi:cy="32.500000"
+ sodipodi:cx="3.7500000"
+ id="path2886"
+ style="color:#000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ id="path2888"
+ sodipodi:cx="3.7500000"
+ sodipodi:cy="32.500000"
+ sodipodi:rx="1.1250000"
+ sodipodi:ry="1.1250000"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,3.833329,19.05551)" />
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ id="path2890"
+ sodipodi:cx="3.7500000"
+ sodipodi:cy="32.500000"
+ sodipodi:rx="1.1250000"
+ sodipodi:ry="1.1250000"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,2.833326,20.05550)" />
+ <path
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,4.833326,20.05551)"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ sodipodi:ry="1.1250000"
+ sodipodi:rx="1.1250000"
+ sodipodi:cy="32.500000"
+ sodipodi:cx="3.7500000"
+ id="path2892"
+ style="color:#000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ id="path2894"
+ sodipodi:cx="3.7500000"
+ sodipodi:cy="32.500000"
+ sodipodi:rx="1.1250000"
+ sodipodi:ry="1.1250000"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,6.833326,20.05551)" />
+ <path
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,8.833326,20.05551)"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ sodipodi:ry="1.1250000"
+ sodipodi:rx="1.1250000"
+ sodipodi:cy="32.500000"
+ sodipodi:cx="3.7500000"
+ id="path2896"
+ style="color:#000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ id="path2898"
+ sodipodi:cx="3.7500000"
+ sodipodi:cy="32.500000"
+ sodipodi:rx="1.1250000"
+ sodipodi:ry="1.1250000"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,7.833329,21.05551)" />
+ <path
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,8.833326,22.05550)"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ sodipodi:ry="1.1250000"
+ sodipodi:rx="1.1250000"
+ sodipodi:cy="32.500000"
+ sodipodi:cx="3.7500000"
+ id="path2900"
+ style="color:#000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ id="path2902"
+ sodipodi:cx="3.7500000"
+ sodipodi:cy="32.500000"
+ sodipodi:rx="1.1250000"
+ sodipodi:ry="1.1250000"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,6.833329,22.05550)" />
+ <path
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,5.833329,21.05551)"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ sodipodi:ry="1.1250000"
+ sodipodi:rx="1.1250000"
+ sodipodi:cy="32.500000"
+ sodipodi:cx="3.7500000"
+ id="path2904"
+ style="color:#000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ id="path2906"
+ sodipodi:cx="3.7500000"
+ sodipodi:cy="32.500000"
+ sodipodi:rx="1.1250000"
+ sodipodi:ry="1.1250000"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,4.833326,22.05550)" />
+ <path
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,3.833326,21.05551)"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ sodipodi:ry="1.1250000"
+ sodipodi:rx="1.1250000"
+ sodipodi:cy="32.500000"
+ sodipodi:cx="3.7500000"
+ id="path2908"
+ style="color:#000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ sodipodi:type="arc" />
+ </g>
+ <g
+ id="g2995">
+ <path
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,2.833330,18.05551)"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ sodipodi:ry="1.1250000"
+ sodipodi:rx="1.1250000"
+ sodipodi:cy="32.500000"
+ sodipodi:cx="3.7500000"
+ id="path2603"
+ style="color:#000000;fill:url(#linearGradient1701);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill:url(#linearGradient1703);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ id="path2605"
+ sodipodi:cx="3.7500000"
+ sodipodi:cy="32.500000"
+ sodipodi:rx="1.1250000"
+ sodipodi:ry="1.1250000"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,4.833326,18.05550)" />
+ <path
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,6.833326,18.05551)"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ sodipodi:ry="1.1250000"
+ sodipodi:rx="1.1250000"
+ sodipodi:cy="32.500000"
+ sodipodi:cx="3.7500000"
+ id="path2607"
+ style="color:#000000;fill:url(#linearGradient1705);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill:url(#linearGradient1707);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ id="path2609"
+ sodipodi:cx="3.7500000"
+ sodipodi:cy="32.500000"
+ sodipodi:rx="1.1250000"
+ sodipodi:ry="1.1250000"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,8.833326,18.05551)" />
+ <path
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,7.833329,19.05550)"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ sodipodi:ry="1.1250000"
+ sodipodi:rx="1.1250000"
+ sodipodi:cy="32.500000"
+ sodipodi:cx="3.7500000"
+ id="path2611"
+ style="color:#000000;fill:url(#linearGradient1709);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill:url(#linearGradient1711);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ id="path2613"
+ sodipodi:cx="3.7500000"
+ sodipodi:cy="32.500000"
+ sodipodi:rx="1.1250000"
+ sodipodi:ry="1.1250000"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,5.833329,19.05551)" />
+ <path
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,3.833329,19.05551)"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ sodipodi:ry="1.1250000"
+ sodipodi:rx="1.1250000"
+ sodipodi:cy="32.500000"
+ sodipodi:cx="3.7500000"
+ id="path2615"
+ style="color:#000000;fill:url(#linearGradient1713);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,2.833326,20.05550)"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ sodipodi:ry="1.1250000"
+ sodipodi:rx="1.1250000"
+ sodipodi:cy="32.500000"
+ sodipodi:cx="3.7500000"
+ id="path2619"
+ style="color:#000000;fill:url(#linearGradient1715);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill:url(#linearGradient1717);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ id="path2621"
+ sodipodi:cx="3.7500000"
+ sodipodi:cy="32.500000"
+ sodipodi:rx="1.1250000"
+ sodipodi:ry="1.1250000"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,4.833326,20.05551)" />
+ <path
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,6.833326,20.05551)"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ sodipodi:ry="1.1250000"
+ sodipodi:rx="1.1250000"
+ sodipodi:cy="32.500000"
+ sodipodi:cx="3.7500000"
+ id="path2623"
+ style="color:#000000;fill:url(#linearGradient1719);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill:url(#linearGradient1721);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ id="path2625"
+ sodipodi:cx="3.7500000"
+ sodipodi:cy="32.500000"
+ sodipodi:rx="1.1250000"
+ sodipodi:ry="1.1250000"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,8.833326,20.05551)" />
+ <path
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,7.833329,21.05551)"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ sodipodi:ry="1.1250000"
+ sodipodi:rx="1.1250000"
+ sodipodi:cy="32.500000"
+ sodipodi:cx="3.7500000"
+ id="path2627"
+ style="color:#000000;fill:url(#linearGradient1723);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill:url(#linearGradient1725);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ id="path2629"
+ sodipodi:cx="3.7500000"
+ sodipodi:cy="32.500000"
+ sodipodi:rx="1.1250000"
+ sodipodi:ry="1.1250000"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,8.833326,22.05550)" />
+ <path
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,6.833329,22.05550)"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ sodipodi:ry="1.1250000"
+ sodipodi:rx="1.1250000"
+ sodipodi:cy="32.500000"
+ sodipodi:cx="3.7500000"
+ id="path2631"
+ style="color:#000000;fill:url(#linearGradient1727);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill:url(#linearGradient1729);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ id="path2633"
+ sodipodi:cx="3.7500000"
+ sodipodi:cy="32.500000"
+ sodipodi:rx="1.1250000"
+ sodipodi:ry="1.1250000"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,5.833329,21.05551)" />
+ <path
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,4.833326,22.05550)"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ sodipodi:ry="1.1250000"
+ sodipodi:rx="1.1250000"
+ sodipodi:cy="32.500000"
+ sodipodi:cx="3.7500000"
+ id="path2635"
+ style="color:#000000;fill:url(#linearGradient1731);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill:url(#linearGradient1733);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ id="path2637"
+ sodipodi:cx="3.7500000"
+ sodipodi:cy="32.500000"
+ sodipodi:rx="1.1250000"
+ sodipodi:ry="1.1250000"
+ d="M 4.8750000 32.500000 A 1.1250000 1.1250000 0 1 1 2.6250000,32.500000 A 1.1250000 1.1250000 0 1 1 4.8750000 32.500000 z"
+ transform="matrix(0.444446,0.000000,0.000000,0.444446,3.833326,21.05551)" />
+ </g>
+ </g>
+ <rect
+ ry="0.50354433"
+ rx="0.50354433"
+ y="28.000000"
+ x="13.000000"
+ height="3.0000000"
+ width="4.0000000"
+ id="rect3014"
+ style="color:#000000;fill:url(#linearGradient1633);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:2.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans" />
+ <path
+ style="fill:#000000;fill-opacity:0.10734458;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
+ d="M 19.234835,37.206242 C 19.234835,37.206242 19.234835,24.346407 19.234835,24.346407 C 20.002531,23.540621 20.421274,22.863407 20.827064,21.623261 C 20.827064,21.623261 34.327665,21.623261 34.327665,21.623261 C 34.327665,21.623261 21.452665,22.337524 21.452665,22.337524 C 21.114277,23.122324 20.552237,24.008019 20.003141,24.622296 C 20.003141,24.622296 19.234835,37.206242 19.234835,37.206242 z "
+ id="path1466"
+ sodipodi:nodetypes="csscssc" />
+ <path
+ style="opacity:0.63387978;fill:none;fill-opacity:1.0000000;stroke:url(#linearGradient1629);stroke-width:1.0000000;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ d="M 30.852943,13.627626 L 16.564140,13.509265 C 11.973189,13.538795 9.4178354,17.059587 9.4178354,19.961104 C 9.4178354,22.690141 11.452373,24.635329 12.843337,25.128887 L 12.843337,31.898973 C 12.843337,35.178814 12.313166,37.915535 17.981589,38.040847 C 17.981589,38.040847 32.008426,38.188498 32.008426,38.188498 C 34.253237,38.202546 36.954024,36.778456 36.909830,34.409038 L 36.909830,18.857858 C 36.909830,15.791277 34.919019,13.627626 30.852943,13.627626 z "
+ id="path2240"
+ sodipodi:nodetypes="cccccssccc" />
+ <g
+ transform="matrix(1.000000,0.000000,-6.156892e-2,1.000000,1.776540,0.000000)"
+ id="g3216">
+ <rect
+ style="color:#000000;fill:#e0e0e0;fill-opacity:1.0000000;fill-rule:nonzero;stroke:#6c6c6c;stroke-width:0.88373333;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ id="rect2108"
+ width="5.0357141"
+ height="7.0985928"
+ x="20.828430"
+ y="25.444061"
+ rx="0.28571433"
+ ry="0.28517434" />
+ <rect
+ style="color:#000000;fill:url(#linearGradient1605);fill-opacity:1.0000000;fill-rule:nonzero;stroke:#6c6c6c;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ id="rect2096"
+ width="21.545832"
+ height="16.267857"
+ x="23.799280"
+ y="20.720566"
+ rx="1.2857143"
+ ry="1.2832843" />
+ <rect
+ style="fill:url(#linearGradient1607);fill-opacity:1.0000000;stroke:none;stroke-width:1.0000000;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
+ id="rect2098"
+ width="16.053572"
+ height="12.053572"
+ x="25.938265"
+ y="22.881281"
+ rx="0.27234393"
+ ry="0.27182922" />
+ <rect
+ style="color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:nonzero;stroke:url(#linearGradient1609);stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ id="rect3030"
+ width="18.296387"
+ height="14.230534"
+ x="24.837126"
+ y="21.748661"
+ rx="0.0071788891"
+ ry="0.0071653211" />
+ <g
+ id="g3201"
+ transform="translate(-0.707105,0.000000)" />
+ <path
+ id="rect3258"
+ transform="matrix(1.000000,0.000000,6.156892e-2,1.000000,-1.776540,0.000000)"
+ d="M 27.375000,23.500000 C 27.224121,23.500000 27.071771,23.630656 27.062500,23.781250 L 26.500000,33.031250 C 33.815243,31.681306 33.857480,27.120605 41.343750,26.000000 L 41.468750,23.781250 C 41.478022,23.630657 41.369630,23.500000 41.218750,23.500000 L 27.375000,23.500000 z "
+ style="opacity:0.15300544;fill:url(#linearGradient1611);fill-opacity:1.0000000;stroke:none;stroke-width:1.0000000;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000" />
+ </g>
+ <path
+ sodipodi:nodetypes="ccccccccc"
+ id="path3234"
+ d="M 20.948038,32.973981 L 22.936776,35.183690 L 23.113552,32.929787 L 20.948038,32.973981 z M 24.571961,37.481787 L 25.102290,38.630835 C 25.102290,38.630835 32.438523,38.719223 32.438523,38.719223 C 34.252705,38.802710 35.818267,37.481787 35.818267,37.481787 L 24.571961,37.481787 z "
+ style="fill:#000000;fill-opacity:0.25988701;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path3236"
+ d="M 13.114621,25.495849 C 16.303953,25.586974 18.149209,24.983280 19.003494,23.593641 C 17.773323,26.190668 13.114621,26.532383 13.114621,26.532383 L 13.114621,25.495849 z "
+ style="fill:url(#linearGradient1618);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000" />
+ <path
+ sodipodi:nodetypes="cc"
+ id="path3246"
+ d="M 21.214039,15.323636 L 32.784719,15.323636"
+ style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.0000005px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:0.62711865" />
+ <path
+ transform="matrix(1.321444,0.000000,0.000000,1.321444,-6.515399,-9.039650)"
+ d="M 20.064156 18.345709 A 0.83968931 0.83968931 0 1 1 18.384777,18.345709 A 0.83968931 0.83968931 0 1 1 20.064156 18.345709 z"
+ sodipodi:ry="0.83968931"
+ sodipodi:rx="0.83968931"
+ sodipodi:cy="18.345709"
+ sodipodi:cx="19.224466"
+ id="path3248"
+ style="color:#000000;fill:#ffffff;fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:0.62711865;visibility:visible;display:inline;overflow:visible;font-family:Bitstream Vera Sans"
+ sodipodi:type="arc" />
+ </g>
+</svg>
diff --git a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/mimetypes/image-x-generic.svg b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/mimetypes/image-x-generic.svg
new file mode 100644
index 0000000000..45dd641ae7
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/mimetypes/image-x-generic.svg
@@ -0,0 +1,581 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 9.0, SVG Export Plug-In -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="48.000000px"
+ height="48.000000px"
+ xml:space="preserve"
+ id="svg16168"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docname="image-x-generic.svg"
+ sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/mimetypes"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"><metadata
+ id="metadata16236">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+
+
+
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+
+
+
+ <dc:title>Genric Image</dc:title>
+<dc:creator>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+</dc:creator>
+<dc:subject>
+ <rdf:Bag><rdf:li>image</rdf:li><rdf:li>picture</rdf:li><rdf:li>snapshot</rdf:li><rdf:li>photo</rdf:li></rdf:Bag>
+</dc:subject>
+<cc:license
+ rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
+</cc:Work>
+
+
+
+
+<cc:License
+ rdf:about="http://creativecommons.org/licenses/publicdomain/"><cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" /><cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" /><cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /></cc:License></rdf:RDF>
+
+
+
+</metadata>
+
+
+
+<defs
+ id="defs16234"><inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 24 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="48 : 24 : 1"
+ inkscape:persp3d-origin="24 : 16 : 1"
+ id="perspective80" /><radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="radialGradient6719"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
+ cx="605.71429"
+ cy="486.64789"
+ fx="605.71429"
+ fy="486.64789"
+ r="117.14286" /><linearGradient
+ inkscape:collect="always"
+ id="linearGradient5060"><stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0"
+ id="stop5062" /><stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop5064" /></linearGradient><radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="radialGradient6717"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
+ cx="605.71429"
+ cy="486.64789"
+ fx="605.71429"
+ fy="486.64789"
+ r="117.14286" /><linearGradient
+ id="linearGradient5048"><stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="0"
+ id="stop5050" /><stop
+ id="stop5056"
+ offset="0.5"
+ style="stop-color:black;stop-opacity:1;" /><stop
+ style="stop-color:black;stop-opacity:0;"
+ offset="1"
+ id="stop5052" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5048"
+ id="linearGradient6715"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
+ x1="302.85715"
+ y1="366.64789"
+ x2="302.85715"
+ y2="609.50507" /><linearGradient
+ id="linearGradient8171"><stop
+ style="stop-color:#bbbdba;stop-opacity:1;"
+ offset="0"
+ id="stop8173" /><stop
+ style="stop-color:#70746e;stop-opacity:1;"
+ offset="1"
+ id="stop8175" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ id="linearGradient8155"><stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop8157" /><stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop8159" /></linearGradient><linearGradient
+ id="linearGradient2224"><stop
+ style="stop-color:#7c7c7c;stop-opacity:1;"
+ offset="0"
+ id="stop2226" /><stop
+ style="stop-color:#b8b8b8;stop-opacity:1;"
+ offset="1"
+ id="stop2228" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ id="linearGradient2251"><stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop2253" /><stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop2255" /></linearGradient><linearGradient
+ id="linearGradient7648"
+ gradientUnits="userSpaceOnUse"
+ x1="21.9326"
+ y1="24.6274"
+ x2="21.9326"
+ y2="7.1091"
+ style="stroke-dasharray:none;stroke-miterlimit:4.0000000;stroke-width:1.2166667">
+ <stop
+ offset="0"
+ style="stop-color:#8595bc;stop-opacity:1;"
+ id="stop7650" />
+
+
+
+
+ <stop
+ offset="1"
+ style="stop-color:#041a3b;stop-opacity:1;"
+ id="stop7652" />
+
+
+
+
+ </linearGradient><linearGradient
+ id="linearGradient2392"><stop
+ id="stop2394"
+ offset="0.0000000"
+ style="stop-color:#715b26;stop-opacity:1.0000000;" /><stop
+ id="stop2396"
+ offset="1.0000000"
+ style="stop-color:#312710;stop-opacity:1.0000000;" /></linearGradient><linearGradient
+ inkscape:collect="always"
+ id="linearGradient12129"><stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop12131" /><stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop12133" /></linearGradient>
+
+ <linearGradient
+ style="stroke-dasharray:none;stroke-miterlimit:4.0000000;stroke-width:1.2166667"
+ y2="36.0328"
+ x2="31.0813"
+ y1="3.7319"
+ x1="12.4873"
+ gradientUnits="userSpaceOnUse"
+ id="aigrd1">
+ <stop
+ id="stop16177"
+ style="stop-color:#D2D2D2;stroke-dasharray:none;stroke-miterlimit:4.0000000;stroke-width:1.2166667"
+ offset="0" />
+
+
+
+
+ <stop
+ id="stop16179"
+ style="stop-color:#EDEDED;stroke-dasharray:none;stroke-miterlimit:4.0000000;stroke-width:1.2166667"
+ offset="1" />
+
+
+
+
+ </linearGradient>
+
+
+
+
+
+ <linearGradient
+ style="stroke-dasharray:none;stroke-miterlimit:4.0000000;stroke-width:1.2166667"
+ y2="22.5769"
+ x2="21.9168"
+ y1="30.3413"
+ x1="21.877"
+ gradientUnits="userSpaceOnUse"
+ id="aigrd2">
+ <stop
+ id="stop16184"
+ style="stop-color:#5e4f07;stop-opacity:1.0000000;"
+ offset="0.0000000" />
+
+
+
+
+ <stop
+ id="stop16186"
+ style="stop-color:#348a31;stop-opacity:1.0000000;"
+ offset="1.0000000" />
+
+
+
+
+ </linearGradient>
+
+
+
+
+
+
+
+
+
+ <linearGradient
+ style="stroke-dasharray:none;stroke-miterlimit:4.0000000;stroke-width:1.2166667"
+ y2="7.1091"
+ x2="21.9326"
+ y1="24.6274"
+ x1="21.9326"
+ gradientUnits="userSpaceOnUse"
+ id="aigrd3">
+ <stop
+ id="stop16199"
+ style="stop-color:#D0D6E5;stroke-dasharray:none;stroke-miterlimit:4.0000000;stroke-width:1.2166667"
+ offset="0" />
+
+
+
+
+ <stop
+ id="stop16201"
+ style="stop-color:#093A80;stroke-dasharray:none;stroke-miterlimit:4.0000000;stroke-width:1.2166667"
+ offset="1" />
+
+
+
+
+ </linearGradient>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient12129"
+ id="radialGradient12135"
+ cx="24.218407"
+ cy="41.636040"
+ fx="24.218407"
+ fy="41.636040"
+ r="22.097088"
+ gradientTransform="matrix(1.000000,0.000000,0.000000,0.184000,0.000000,33.97501)"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7648"
+ id="linearGradient7671"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.098989,0.000000,0.000000,-0.797757,-1.953865,37.32400)"
+ x1="21.9326"
+ y1="24.627399"
+ x2="21.9326"
+ y2="7.1090999" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#aigrd3"
+ id="linearGradient7673"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.098989,0.000000,0.000000,1.106697,-1.953865,-4.922453)"
+ x1="21.9326"
+ y1="24.6274"
+ x2="21.9326"
+ y2="7.1091" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#aigrd1"
+ id="linearGradient8148"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.434003,0.000000,0.000000,0.990087,52.32167,2.838918)"
+ x1="12.4873"
+ y1="3.7319"
+ x2="31.0813"
+ y2="36.0328" /><radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8155"
+ id="radialGradient8161"
+ cx="12.700491"
+ cy="10.404876"
+ fx="12.700491"
+ fy="10.404876"
+ r="19.96875"
+ gradientTransform="matrix(1.710531,-5.396358e-24,2.470345e-24,1.124849,-11.56833,1.802582)"
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2251"
+ id="linearGradient8166"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(5.147570,-3.409792)"
+ x1="33.396004"
+ y1="36.921333"
+ x2="34.170048"
+ y2="38.070381" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2224"
+ id="linearGradient8169"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(5.147570,-3.034792)"
+ x1="35.996582"
+ y1="40.458221"
+ x2="33.664921"
+ y2="37.770721" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8171"
+ id="linearGradient8177"
+ x1="42.1875"
+ y1="31"
+ x2="45"
+ y2="39.984692"
+ gradientUnits="userSpaceOnUse" /></defs>
+
+
+
+<sodipodi:namedview
+ inkscape:window-height="818"
+ inkscape:window-width="1238"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ borderopacity="0.07058824"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base"
+ inkscape:zoom="1"
+ inkscape:cx="49.378608"
+ inkscape:cy="-24.095483"
+ inkscape:window-x="0"
+ inkscape:window-y="30"
+ inkscape:current-layer="svg16168"
+ showgrid="false"
+ inkscape:showpageshadow="false" />
+
+
+
+
+
+ <g
+ style="display:inline"
+ transform="matrix(2.175112e-2,0,0,2.493263e-2,42.41049,33.81117)"
+ id="g6707"><rect
+ style="opacity:0.40206185;color:black;fill:url(#linearGradient6715);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="rect6709"
+ width="1339.6335"
+ height="478.35718"
+ x="-1559.2523"
+ y="-150.69685" /><path
+ style="opacity:0.40206185;color:black;fill:url(#radialGradient6717);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z "
+ id="path6711"
+ sodipodi:nodetypes="cccc" /><path
+ sodipodi:nodetypes="cccc"
+ id="path6713"
+ d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z "
+ style="opacity:0.40206185;color:black;fill:url(#radialGradient6719);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" /></g><path
+ style="color:#000000;fill:url(#linearGradient8148);fill-opacity:1;fill-rule:nonzero;stroke:#bbbfbb;stroke-width:0.99999994;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 2.7177715,6.4547749 L 43.379544,6.4547749 C 44.002793,6.4547749 44.504543,6.9565247 44.504543,7.5797745 L 44.504543,31.480581 C 44.504543,32.103831 36.047842,39.499872 35.424593,39.499872 L 2.7177715,39.499872 C 2.0945221,39.499872 1.5927727,38.998122 1.5927727,38.374872 L 1.5927727,7.5797745 C 1.5927727,6.9565247 2.0945221,6.4547749 2.7177715,6.4547749 z "
+ id="rect7603"
+ sodipodi:nodetypes="ccccccccc" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<g
+ id="g7654"
+ transform="matrix(1.054774,0.000000,0.000000,1.049989,-0.814647,4.485012)"><path
+ id="path7644"
+ d="M 5.512695,30 L 39.643234,30 L 39.643234,19.627375 L 5.512695,19.627375 L 5.512695,30 z "
+ style="fill:url(#linearGradient7671);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.2166667;stroke-miterlimit:4" /><path
+ style="fill:url(#linearGradient7673);fill-rule:nonzero;stroke:none;stroke-width:1.2166667;stroke-miterlimit:4"
+ d="M 5.512695,5.237844 L 39.643234,5.237844 L 39.643234,19.627375 L 5.512695,19.627375 L 5.512695,5.237844 z "
+ id="path16203" /><g
+ id="g16205"
+ style="fill-rule:nonzero;stroke:#000000;stroke-width:1.15611064;stroke-miterlimit:4"
+ transform="matrix(1.189217,0.000000,0.000000,1.189217,-3.525355,-6.535408)">
+ <g
+ id="g16207">
+ <path
+ style="opacity:0.04999994;fill:#e8f52f;stroke:none"
+ d="M 18.4,15.4 C 18.4,17.6 16.6,19.5 14.3,19.5 C 12.1,19.5 10.2,17.7 10.2,15.4 C 10.2,13.2 12,11.3 14.3,11.3 C 16.5,11.3 18.4,13.1 18.4,15.4 z "
+ id="path16209" />
+
+
+
+
+ <path
+ style="opacity:0.20829994;fill:#ecf751;stroke:none"
+ d="M 18,15.4 C 18,17.4 16.4,19.1 14.3,19.1 C 12.3,19.1 10.6,17.5 10.6,15.4 C 10.6,13.4 12.2,11.7 14.3,11.7 C 16.3,11.7 18,13.3 18,15.4 L 18,15.4 z "
+ id="path16211" />
+
+
+
+
+ <path
+ style="opacity:0.36669994;fill:#f0f972;stroke:none"
+ d="M 17.6,15.4 C 17.6,17.2 16.1,18.7 14.3,18.7 C 12.5,18.7 11,17.2 11,15.4 C 11,13.6 12.5,12.1 14.3,12.1 C 16.1,12.1 17.6,13.6 17.6,15.4 L 17.6,15.4 z "
+ id="path16213" />
+
+
+
+
+ <path
+ style="opacity:0.525;fill:#f4fa95;stroke:none"
+ d="M 17.2,15.4 C 17.2,17 15.9,18.3 14.3,18.3 C 12.7,18.3 11.4,17 11.4,15.4 C 11.4,13.8 12.7,12.5 14.3,12.5 C 15.9,12.5 17.2,13.8 17.2,15.4 z "
+ id="path16215" />
+
+
+
+
+ <path
+ style="opacity:0.6833;fill:#f7fcb7;stroke:none"
+ d="M 16.8,15.4 C 16.8,16.8 15.7,17.9 14.3,17.9 C 12.9,17.9 11.8,16.8 11.8,15.4 C 11.8,14 12.9,12.9 14.3,12.9 C 15.7,12.9 16.8,14 16.8,15.4 L 16.8,15.4 z "
+ id="path16217" />
+
+
+
+
+ <path
+ style="opacity:0.8417;fill:#fbfddb;stroke:none"
+ d="M 16.4,15.4 C 16.4,16.6 15.4,17.5 14.3,17.5 C 13.2,17.5 12.2,16.5 12.2,15.4 C 12.2,14.3 13.2,13.3 14.3,13.3 C 15.4,13.3 16.4,14.3 16.4,15.4 z "
+ id="path16219" />
+
+
+
+
+ <path
+ style="fill:#ffffff;stroke:none"
+ d="M 16,15.4 C 16,16.4 15.2,17.2 14.2,17.2 C 13.2,17.2 12.4,16.4 12.4,15.4 C 12.4,14.4 13.2,13.6 14.2,13.6 C 15.2,13.6 16,14.4 16,15.4 L 16,15.4 z "
+ id="path16221" />
+
+
+
+
+ </g>
+
+
+
+
+ </g><path
+ style="opacity:0.3;fill-rule:nonzero;stroke:none;stroke-width:1.2166667;stroke-miterlimit:4"
+ d="M 25.015859,21.649044 L 33.697148,21.649044 L 35.362052,22.124732 L 32.507931,22.124732 C 32.507931,22.124732 35.362052,22.362574 36.789115,24.146401 C 38.216174,25.811305 35.12421,27.832976 35.12421,27.832976 C 35.12421,27.832976 35.12421,27.832976 35.12421,27.832976 C 35.005288,27.47621 34.291756,24.622087 32.864696,23.43287 C 31.794399,22.481496 30.605182,22.243652 30.605182,22.243652 L 25.015859,22.243652 L 25.015859,21.767966 L 25.015859,21.649044 z "
+ id="path16223" /><path
+ style="opacity:0.3;fill-rule:nonzero;stroke:none;stroke-width:1.2166667;stroke-miterlimit:4"
+ d="M 30.724106,22.362574 L 25.729391,22.362574 L 35.005288,27.595131 L 30.724106,22.362574 L 30.724106,22.362574 z "
+ id="path16225" /><path
+ style="fill:#515151;fill-rule:nonzero;stroke:none;stroke-width:1.2166667;stroke-miterlimit:4"
+ d="M 25.015859,21.767966 L 33.697148,21.767966 L 35.005288,20.935513 L 32.151167,20.935513 C 32.151167,20.935513 34.767443,20.459827 35.12421,17.486782 C 35.480973,14.513739 31.080869,11.183931 31.080869,11.183931 C 31.080869,11.183931 31.080869,11.183931 31.080869,11.302853 C 31.19979,12.016383 32.389007,17.011096 31.556557,18.913846 C 31.19979,20.578747 30.129495,20.935513 30.129495,20.935513 L 24.659094,20.935513 L 24.896938,21.767966 L 25.015859,21.767966 z "
+ id="path16227" /><path
+ style="fill:#515151;fill-rule:nonzero;stroke:none;stroke-width:1.2166667;stroke-miterlimit:4"
+ d="M 30.248418,20.459827 L 25.253704,20.459827 L 31.19979,11.421773 L 30.248418,20.459827 z "
+ id="path16229" /></g><path
+ style="color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.99999976;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 2.8042317,7.4528585 L 43.233985,7.4528585 C 43.384366,7.4528585 43.505431,7.5739234 43.505431,7.7243045 L 43.505431,31.422651 C 43.505431,32.368527 36.401687,38.5 36.251306,38.5 L 2.8042317,38.5 C 2.6538507,38.5 2.5327858,38.378935 2.5327858,38.228554 L 2.5327858,7.7243045 C 2.5327858,7.5739234 2.6538507,7.4528585 2.8042317,7.4528585 z "
+ id="rect7675"
+ sodipodi:nodetypes="ccccccccc" /><rect
+ style="opacity:0.84659095;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#4f4f4f;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="rect8163"
+ width="35.0625"
+ height="25.0625"
+ x="5.5"
+ y="10.5" /><path
+ style="color:#000000;fill:url(#linearGradient8169);fill-opacity:1.0;fill-rule:evenodd;stroke:url(#linearGradient8177);stroke-width:1.00000024;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 35.206652,39.468763 C 37.23707,39.798661 44.795445,34.938834 44.491063,30.970919 C 42.927801,33.394016 39.732541,32.257657 35.623783,32.416667 C 35.623783,32.416667 36.019152,38.968763 35.206652,39.468763 z "
+ id="path2210"
+ sodipodi:nodetypes="cccc" /><path
+ sodipodi:nodetypes="cccc"
+ id="path2247"
+ d="M 36.657089,37.277261 C 38.026868,36.593432 41.085338,35.130796 42.384719,33.249792 C 40.788625,33.929847 39.436909,33.459288 36.682385,33.440197 C 36.682385,33.440197 36.844707,36.502291 36.657089,37.277261 z "
+ style="opacity:0.36931817;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient8166);stroke-width:0.99999982;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" /><path
+ style="opacity:0.30113636;color:#000000;fill:url(#radialGradient8161);fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 3.0625,8 L 3.0625,30.0625 C 25.388579,30.950861 27.884634,17 43,17 L 43,8 L 3.0625,8 z "
+ id="rect8150"
+ sodipodi:nodetypes="ccccc" /></svg>
\ No newline at end of file
diff --git a/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/mimetypes/video-x-generic.svg b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/mimetypes/video-x-generic.svg
new file mode 100644
index 0000000000..1f3a8b95a8
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.ext/resources/icons/tango/scalable/mimetypes/video-x-generic.svg
@@ -0,0 +1,319 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ inkscape:export-ydpi="90.000000"
+ inkscape:export-xdpi="90.000000"
+ inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png"
+ width="48px"
+ height="48px"
+ id="svg11300"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docbase="/home/jimmac/Desktop"
+ sodipodi:docname="video-x-generic.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape">
+ <defs
+ id="defs3">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 24 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="48 : 24 : 1"
+ inkscape:persp3d-origin="24 : 16 : 1"
+ id="perspective40" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient7138">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop7140" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop7142" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient7087">
+ <stop
+ style="stop-color:#888a85;stop-opacity:1;"
+ offset="0"
+ id="stop7089" />
+ <stop
+ style="stop-color:#b8b9b6;stop-opacity:1;"
+ offset="1"
+ id="stop7091" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient7079">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop7081" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop7083" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient7069">
+ <stop
+ style="stop-color:#888a85;stop-opacity:1;"
+ offset="0"
+ id="stop7071" />
+ <stop
+ style="stop-color:#888a85;stop-opacity:0;"
+ offset="1"
+ id="stop7073" />
+ </linearGradient>
+ <radialGradient
+ id="aigrd4"
+ cx="9.3418"
+ cy="22.6138"
+ r="14.1515"
+ fx="9.3418"
+ fy="22.6138"
+ gradientUnits="userSpaceOnUse">
+ <stop
+ offset="0"
+ style="stop-color:#767676"
+ id="stop6452" />
+ <stop
+ offset="1"
+ style="stop-color:#484848"
+ id="stop6454" />
+ </radialGradient>
+ <radialGradient
+ r="14.1515"
+ fy="24.735121"
+ fx="20.655508"
+ cy="24.735121"
+ cx="20.655508"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient6540"
+ xlink:href="#aigrd4"
+ inkscape:collect="always"
+ gradientTransform="translate(1.971678,9.220141)" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient7054">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop7056" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop7058" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7054"
+ id="linearGradient7060"
+ x1="21.03167"
+ y1="31.867859"
+ x2="21.107563"
+ y2="-4.5986342"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7069"
+ id="linearGradient7075"
+ x1="46.54464"
+ y1="35.24506"
+ x2="40.820396"
+ y2="34.140205"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.884878,0,0,0.884878,5.318113,5.943159)" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7079"
+ id="radialGradient7085"
+ cx="23.157747"
+ cy="26.963573"
+ fx="23.157747"
+ fy="26.963573"
+ r="21.566757"
+ gradientTransform="matrix(1,0,0,0.663934,0,9.061528)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7087"
+ id="linearGradient7093"
+ x1="23.816254"
+ y1="12.75"
+ x2="29.049412"
+ y2="25.772396"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7138"
+ id="linearGradient7144"
+ x1="43.6875"
+ y1="32.133045"
+ x2="26.625"
+ y2="32.133045"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,2)" />
+ </defs>
+ <sodipodi:namedview
+ stroke="#ef2929"
+ fill="#eeeeec"
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="0.25490196"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1"
+ inkscape:cx="16.18058"
+ inkscape:cy="40.223164"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:showpageshadow="false"
+ inkscape:window-width="872"
+ inkscape:window-height="688"
+ inkscape:window-x="477"
+ inkscape:window-y="160" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source>http://jimmac.musichall.cz</dc:source>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
+ <dc:title>Generic Video</dc:title>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>video</rdf:li>
+ <rdf:li>audio</rdf:li>
+ <rdf:li>multimedia</rdf:li>
+ <rdf:li>movie</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/publicdomain/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <path
+ sodipodi:type="arc"
+ style="opacity:0.70329674;color:#000000;fill:url(#radialGradient7085);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="path7077"
+ sodipodi:cx="23.157747"
+ sodipodi:cy="26.963573"
+ sodipodi:rx="21.566757"
+ sodipodi:ry="14.318913"
+ d="M 44.724504 26.963573 A 21.566757 14.318913 0 1 1 1.5909901,26.963573 A 21.566757 14.318913 0 1 1 44.724504 26.963573 z"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true"
+ transform="translate(1.237437,0.762563)" />
+ <path
+ transform="matrix(1.254237,0,0,1.541926,-9.79661,-6.279528)"
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ d="M 40.5 21 A 14.75 8.25 0 1 1 11,21 A 14.75 8.25 0 1 1 40.5 21 z"
+ sodipodi:ry="8.25"
+ sodipodi:rx="14.75"
+ sodipodi:cy="21"
+ sodipodi:cx="25.75"
+ id="path7028"
+ style="opacity:1;color:#000000;fill:#a1a39f;fill-opacity:1;fill-rule:evenodd;stroke:#6d6f6a;stroke-width:0.7190817;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;color:#000000;fill:#555753;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.11522388;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="path7042"
+ sodipodi:cx="25.75"
+ sodipodi:cy="21"
+ sodipodi:rx="14.75"
+ sodipodi:ry="8.25"
+ d="M 40.5 21 A 14.75 8.25 0 1 1 11,21 A 14.75 8.25 0 1 1 40.5 21 z"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true"
+ transform="matrix(0.764011,0,0,1.001814,2.310475,2.543083)" />
+ <path
+ style="fill:url(#radialGradient6540);fill-rule:nonzero;stroke:#3b3d39;stroke-miterlimit:4;stroke-opacity:1"
+ d="M 46.025804,41.226233 C 46.025804,41.226233 37.701909,37.489226 32.369805,37.959515 C 26.686793,38.460754 17.193028,38.796952 13.471708,32.920175 C 29.269805,37.684641 36.558698,29.774427 47.251087,34.22969 C 47.251087,34.22969 46.025804,41.226233 46.025804,41.226233 z "
+ id="path6456"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true"
+ sodipodi:nodetypes="czccc" />
+ <path
+ transform="matrix(0.760969,0,0,0.986663,2.905048,0.584267)"
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ d="M 40.5 21 A 14.75 8.25 0 1 1 11,21 A 14.75 8.25 0 1 1 40.5 21 z"
+ sodipodi:ry="8.25"
+ sodipodi:rx="14.75"
+ sodipodi:cy="21"
+ sodipodi:cx="25.75"
+ id="path7026"
+ style="opacity:1;color:#000000;fill:url(#linearGradient7093);fill-opacity:1;fill-rule:evenodd;stroke:#757972;stroke-width:1.23408842;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc" />
+ <path
+ style="opacity:1;color:#000000;fill:#d3d7cf;fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 21.09375,7.71875 C 11.536229,8.2444238 4.0000001,14.13337 4,21.25 C 4,28.711046 12.288003,34.781251 22.5,34.78125 C 32.711998,34.78125 41,28.711045 41,21.25 C 41,13.788954 32.711998,7.71875 22.5,7.71875 C 22.460109,7.71875 22.414832,7.7185655 22.375,7.71875 C 22.136944,7.7198528 21.892094,7.7111092 21.65625,7.71875 C 21.541092,7.7224809 21.4271,7.7134779 21.3125,7.71875 C 21.236995,7.7222235 21.169006,7.7146108 21.09375,7.71875 z M 19.71875,9.90625 C 19.782003,9.9011431 19.842341,9.9097202 19.90625,9.90625 C 20.040354,9.8989684 20.175794,9.90625 20.3125,9.90625 C 23.228892,9.9062502 25.59375,11.608453 25.59375,13.6875 C 25.59375,15.766547 23.228891,17.4375 20.3125,17.4375 C 17.396109,17.4375 15.03125,15.766547 15.03125,13.6875 C 15.03125,11.752352 17.083204,10.119037 19.71875,9.90625 z M 31.21875,14.5 C 31.285397,14.494037 31.338935,14.504252 31.40625,14.5 C 31.523002,14.492625 31.631386,14.502149 31.75,14.5 C 31.798199,14.499127 31.826509,14.5 31.875,14.5 C 34.978453,14.5 37.5,16.314203 37.5,18.53125 C 37.5,20.748296 34.978454,22.53125 31.875,22.53125 C 28.771546,22.531251 26.25,20.748297 26.25,18.53125 C 26.249999,16.483247 28.441783,14.748443 31.21875,14.5 z M 12,17.65625 C 12.217826,17.638427 12.463035,17.65625 12.6875,17.65625 C 15.879889,17.65625 18.46875,19.498598 18.46875,21.78125 C 18.46875,24.063902 15.879889,25.90625 12.6875,25.90625 C 9.4951118,25.90625 6.90625,24.063902 6.90625,21.78125 C 6.90625,19.659098 9.1198541,17.891914 12,17.65625 z M 23.53125,22.78125 C 23.555225,22.778464 23.56969,22.783841 23.59375,22.78125 C 23.596499,22.781133 23.622453,22.781217 23.625,22.78125 C 23.627553,22.781295 23.653493,22.781349 23.65625,22.78125 C 23.662492,22.781356 23.684306,22.781365 23.6875,22.78125 C 23.713653,22.781429 23.755011,22.780867 23.78125,22.78125 C 23.78446,22.781173 23.806268,22.781167 23.8125,22.78125 C 24.053476,22.761472 24.28293,22.78125 24.53125,22.78125 C 28.062916,22.78125 30.9375,24.810811 30.9375,27.34375 C 30.9375,29.87669 28.062916,31.9375 24.53125,31.9375 C 20.999584,31.9375 18.125,29.876689 18.125,27.34375 C 18.125,25.061781 20.486444,23.135039 23.53125,22.78125 z "
+ id="path7012"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true" />
+ <path
+ sodipodi:type="arc"
+ style="opacity:1;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient7060);stroke-width:1.05932879;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ id="path7044"
+ sodipodi:cx="22.185474"
+ sodipodi:cy="19.008621"
+ sodipodi:rx="18.473166"
+ sodipodi:ry="13.435029"
+ d="M 40.65864 19.008621 A 18.473166 13.435029 0 1 1 3.7123089,19.008621 A 18.473166 13.435029 0 1 1 40.65864 19.008621 z"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true"
+ transform="matrix(0.950533,0,0,0.9375,1.450995,3.320621)" />
+ <path
+ style="opacity:1;color:#000000;fill:url(#linearGradient7075);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 46.875,34.493906 L 45.793438,40.543896 C 43.18442,39.668459 41.611389,38.97574 38.722272,38.287036 L 39.054101,33.374389 C 40.952632,33.173083 43.91738,33.516123 46.875,34.493906 z "
+ id="path7067"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="opacity:0.70329674;color:#000000;fill:url(#linearGradient7144);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ d="M 46.875,34.3125 L 46.6875,35.1875 C 38.582601,32.158614 31.121435,34.960781 23.3125,35.1875 C 33.923553,34.304921 37.402743,31.471843 46.875,34.3125 z "
+ id="path7136"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true"
+ sodipodi:nodetypes="cccc" />
+ </g>
+</svg>
diff --git a/Plugins/org.mitk.gui.qt.ext/resources/org_mitk_icons.qrc b/Plugins/org.mitk.gui.qt.ext/resources/org_mitk_icons.qrc
index 56315b325f..08f6548161 100644
--- a/Plugins/org.mitk.gui.qt.ext/resources/org_mitk_icons.qrc
+++ b/Plugins/org.mitk.gui.qt.ext/resources/org_mitk_icons.qrc
@@ -1,51 +1,67 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource prefix="/org_mitk_icons">
<file>icons/awesome/index.theme</file>
<file>icons/awesome/scalable/actions/document-open.svg</file>
<file>icons/awesome/scalable/actions/document-print.svg</file>
<file>icons/awesome/scalable/actions/document-save.svg</file>
<file>icons/awesome/scalable/actions/edit-delete.svg</file>
<file>icons/awesome/scalable/actions/edit-redo.svg</file>
<file>icons/awesome/scalable/actions/edit-undo.svg</file>
<file>icons/awesome/scalable/actions/go-down.svg</file>
<file>icons/awesome/scalable/actions/go-home.svg</file>
<file>icons/awesome/scalable/actions/go-next.svg</file>
<file>icons/awesome/scalable/actions/go-previous.svg</file>
<file>icons/awesome/scalable/actions/go-up.svg</file>
<file>icons/awesome/scalable/actions/system-log-out.svg</file>
<file>icons/awesome/scalable/actions/view-list-details.svg</file>
<file>icons/awesome/scalable/actions/view-list-icons.svg</file>
<file>icons/awesome/scalable/actions/view-refresh.svg</file>
<file>icons/awesome/scalable/places/folder.svg</file>
<file>icons/awesome/scalable/status/dialog-error.svg</file>
<file>icons/awesome/scalable/status/dialog-information.svg</file>
<file>icons/awesome/scalable/status/dialog-question.svg</file>
<file>icons/awesome/scalable/status/dialog-warning.svg</file>
<file>icons/tango/index.theme</file>
<file>icons/tango/scalable/actions/document-open.svg</file>
<file>icons/tango/scalable/actions/document-print.svg</file>
<file>icons/tango/scalable/actions/document-save.svg</file>
<file>icons/tango/scalable/actions/edit-delete.svg</file>
<file>icons/tango/scalable/actions/edit-redo.svg</file>
<file>icons/tango/scalable/actions/edit-undo.svg</file>
<file>icons/tango/scalable/actions/go-bottom.svg</file>
<file>icons/tango/scalable/actions/go-down.svg</file>
<file>icons/tango/scalable/actions/go-first.svg</file>
<file>icons/tango/scalable/actions/go-home.svg</file>
<file>icons/tango/scalable/actions/go-last.svg</file>
<file>icons/tango/scalable/actions/go-next.svg</file>
<file>icons/tango/scalable/actions/go-previous.svg</file>
<file>icons/tango/scalable/actions/go-top.svg</file>
<file>icons/tango/scalable/actions/go-up.svg</file>
<file>icons/tango/scalable/actions/system-log-out.svg</file>
<file>icons/tango/scalable/actions/view-list-details.svg</file>
<file>icons/tango/scalable/actions/view-list-icons.svg</file>
<file>icons/tango/scalable/actions/view-refresh.svg</file>
+ <file>icons/tango/scalable/actions/list-add.svg</file>
+ <file>icons/tango/scalable/actions/list-remove.svg</file>
+ <file>icons/tango/scalable/actions/media-playback-pause.svg</file>
+ <file>icons/tango/scalable/actions/media-playback-start.svg</file>
+ <file>icons/tango/scalable/actions/media-playback-stop.svg</file>
+ <file>icons/tango/scalable/actions/media-record.svg</file>
+ <file>icons/tango/scalable/actions/media-seek-backward.svg</file>
+ <file>icons/tango/scalable/actions/media-seek-forward.svg</file>
+ <file>icons/tango/scalable/actions/media-skip-backward.svg</file>
+ <file>icons/tango/scalable/actions/media-skip-forward.svg</file>
+ <file>icons/tango/scalable/actions/system-log-out.svg</file>
+ <file>icons/tango/scalable/categories/applications-multimedia.svg</file>
+ <file>icons/tango/scalable/devices/camera-photo.svg</file>
+ <file>icons/tango/scalable/devices/camera-video.svg</file>
+ <file>icons/tango/scalable/mimetypes/image-x-generic.svg</file>
+ <file>icons/tango/scalable/mimetypes/video-x-generic.svg</file>
<file>icons/tango/scalable/places/folder.svg</file>
<file>icons/tango/scalable/places/folder-remote.svg</file>
<file>icons/tango/scalable/status/dialog-error.svg</file>
<file>icons/tango/scalable/status/dialog-information.svg</file>
<file>icons/tango/scalable/status/dialog-question.svg</file>
<file>icons/tango/scalable/status/dialog-warning.svg</file>
</qresource>
</RCC>
diff --git a/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkCommonExtPlugin.cpp b/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkCommonExtPlugin.cpp
index d013f6b1cf..3b2af41b96 100644
--- a/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkCommonExtPlugin.cpp
+++ b/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkCommonExtPlugin.cpp
@@ -1,258 +1,260 @@
/*===================================================================
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 "QmitkCommonExtPlugin.h"
#include <QtWidgetsExtRegisterClasses.h>
#include "QmitkAppInstancesPreferencePage.h"
#include "QmitkExternalProgramsPreferencePage.h"
#include "QmitkInputDevicesPrefPage.h"
#include "QmitkModuleView.h"
#include <mitkIDataStorageService.h>
#include <mitkSceneIO.h>
#include <mitkProgressBar.h>
#include <mitkRenderingManager.h>
#include <mitkIOUtil.h>
#include <berryPlatformUI.h>
#include <berryIPreferencesService.h>
#include <Poco/Util/OptionProcessor.h>
#include <QProcess>
#include <QMainWindow>
#include <QtPlugin>
#include <berryIPreferencesService.h>
#include "berryPlatform.h"
#include <QMessageBox>
ctkPluginContext* QmitkCommonExtPlugin::_context = 0;
void QmitkCommonExtPlugin::start(ctkPluginContext* context)
{
this->_context = context;
QtWidgetsExtRegisterClasses();
BERRY_REGISTER_EXTENSION_CLASS(QmitkAppInstancesPreferencePage, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkExternalProgramsPreferencePage, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkInputDevicesPrefPage, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkModuleView, context)
if (qApp->metaObject()->indexOfSignal("messageReceived(QByteArray)") > -1)
{
connect(qApp, SIGNAL(messageReceived(QByteArray)), this, SLOT(handleIPCMessage(QByteArray)));
}
std::vector<std::string> args = berry::Platform::GetApplicationArgs();
QStringList qargs;
for (std::vector<std::string>::const_iterator it = args.begin(); it != args.end(); ++it)
{
qargs << QString::fromStdString(*it);
}
// This is a potentially long running operation.
loadDataFromDisk(qargs, true);
}
void QmitkCommonExtPlugin::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
this->_context = 0;
}
ctkPluginContext* QmitkCommonExtPlugin::getContext()
{
return _context;
}
void QmitkCommonExtPlugin::loadDataFromDisk(const QStringList &arguments, bool globalReinit)
{
if (!arguments.empty())
{
ctkServiceReference serviceRef = _context->getServiceReference<mitk::IDataStorageService>();
if (serviceRef)
{
mitk::IDataStorageService* dataStorageService = _context->getService<mitk::IDataStorageService>(serviceRef);
mitk::DataStorage::Pointer dataStorage = dataStorageService->GetDefaultDataStorage()->GetDataStorage();
int argumentsAdded = 0;
for (int i = 0; i < arguments.size(); ++i)
{
if (arguments[i].right(5) == ".mitk")
{
mitk::SceneIO::Pointer sceneIO = mitk::SceneIO::New();
bool clearDataStorageFirst(false);
mitk::ProgressBar::GetInstance()->AddStepsToDo(2);
dataStorage = sceneIO->LoadScene( arguments[i].toLocal8Bit().constData(), dataStorage, clearDataStorageFirst );
mitk::ProgressBar::GetInstance()->Progress(2);
argumentsAdded++;
}
else
{
try
{
std::vector<mitk::BaseData::Pointer> baseDataVector = mitk::IOUtil::Load(arguments[i].toStdString());
Q_FOREACH(const mitk::BaseData::Pointer& baseData, baseDataVector)
{
if (baseData.IsNotNull())
{
mitk::DataNode::Pointer dataNode = mitk::DataNode::New();
dataNode->SetData(baseData);
dataStorage->Add(dataNode);
++argumentsAdded;
}
}
}
catch (...)
{
MITK_WARN << "Failed to load command line argument: " << arguments[i].toStdString();
}
}
} // end for each command line argument
if (argumentsAdded > 0 && globalReinit)
{
// calculate bounding geometry
mitk::RenderingManager::GetInstance()->InitializeViews(dataStorage->ComputeBoundingGeometry3D());
}
}
else
{
MITK_ERROR << "A service reference for mitk::IDataStorageService does not exist";
}
}
}
void QmitkCommonExtPlugin::startNewInstance(const QStringList &args, const QStringList& files)
{
QStringList newArgs(args);
#ifdef Q_OS_UNIX
newArgs << QString("--") + QString::fromStdString(berry::Platform::ARG_NEWINSTANCE);
#else
newArgs << QString("/") + QString::fromStdString(berry::Platform::ARG_NEWINSTANCE);
#endif
newArgs << files;
QProcess::startDetached(qApp->applicationFilePath(), newArgs);
}
void QmitkCommonExtPlugin::handleIPCMessage(const QByteArray& msg)
{
QDataStream ds(msg);
QString msgType;
ds >> msgType;
// we only handle messages containing command line arguments
if (msgType != "$cmdLineArgs") return;
// activate the current workbench window
berry::IWorkbenchWindow::Pointer window =
berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow();
QMainWindow* mainWindow =
static_cast<QMainWindow*> (window->GetShell()->GetControl());
mainWindow->setWindowState(mainWindow->windowState() & ~Qt::WindowMinimized);
mainWindow->raise();
mainWindow->activateWindow();
// Get the preferences for the instantiation behavior
berry::IPreferencesService::Pointer prefService
= berry::Platform::GetServiceRegistry()
.GetServiceById<berry::IPreferencesService>(berry::IPreferencesService::ID);
berry::IPreferences::Pointer prefs = prefService->GetSystemPreferences()->Node("/General");
bool newInstanceAlways = prefs->GetBool("newInstance.always", false);
bool newInstanceScene = prefs->GetBool("newInstance.scene", true);
QStringList args;
ds >> args;
QStringList fileArgs;
QStringList sceneArgs;
Poco::Util::OptionSet os;
berry::Platform::GetOptionSet(os);
Poco::Util::OptionProcessor processor(os);
#if !defined(POCO_OS_FAMILY_UNIX)
processor.setUnixStyle(false);
#endif
args.pop_front();
QStringList::Iterator it = args.begin();
while (it != args.end())
{
std::string name;
std::string value;
if (processor.process(it->toStdString(), name, value))
{
++it;
}
else
{
if (it->endsWith(".mitk"))
{
sceneArgs << *it;
}
else
{
fileArgs << *it;
}
it = args.erase(it);
}
}
if (newInstanceAlways)
{
if (newInstanceScene)
{
startNewInstance(args, fileArgs);
foreach(QString sceneFile, sceneArgs)
{
startNewInstance(args, QStringList(sceneFile));
}
}
else
{
fileArgs.append(sceneArgs);
startNewInstance(args, fileArgs);
}
}
else
{
loadDataFromDisk(fileArgs, false);
if (newInstanceScene)
{
foreach(QString sceneFile, sceneArgs)
{
startNewInstance(args, QStringList(sceneFile));
}
}
else
{
loadDataFromDisk(sceneArgs, false);
}
}
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_ext, QmitkCommonExtPlugin)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_ext, QmitkCommonExtPlugin)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkCommonExtPlugin.h b/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkCommonExtPlugin.h
index 82a93125a5..54835551cd 100644
--- a/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkCommonExtPlugin.h
+++ b/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkCommonExtPlugin.h
@@ -1,50 +1,53 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef QMITKCOMMONEXTPLUGIN_H_
#define QMITKCOMMONEXTPLUGIN_H_
#include <ctkPluginActivator.h>
class QmitkCommonExtPlugin : public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_ext")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
static ctkPluginContext* getContext();
private:
void loadDataFromDisk(const QStringList& args, bool globalReinit);
void startNewInstance(const QStringList& args, const QStringList &files);
private Q_SLOTS:
void handleIPCMessage(const QByteArray &msg);
private:
static ctkPluginContext* _context;
};
#endif /* QMITKCOMMONEXTPLUGIN_H_ */
diff --git a/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkExternalProgramsPreferencePage.cpp b/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkExternalProgramsPreferencePage.cpp
index af8e485885..6e1f622a3c 100644
--- a/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkExternalProgramsPreferencePage.cpp
+++ b/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkExternalProgramsPreferencePage.cpp
@@ -1,136 +1,190 @@
/*===================================================================
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 <berryIPreferencesService.h>
#include <berryPlatform.h>
#include <berryServiceRegistry.h>
#include <mitkExceptionMacro.h>
#include <QFileDialog>
#include <QProcess>
#include <QTextCodec>
#include <ui_QmitkExternalProgramsPreferencePage.h>
#include "QmitkExternalProgramsPreferencePage.h"
static berry::IPreferences::Pointer GetPreferences()
{
berry::IPreferencesService::Pointer preferencesService =
berry::Platform::GetServiceRegistry().GetServiceById<berry::IPreferencesService>(berry::IPreferencesService::ID);
if (preferencesService.IsNotNull())
{
berry::IPreferences::Pointer systemPreferences = preferencesService->GetSystemPreferences();
if (systemPreferences.IsNotNull())
return systemPreferences->Node("/org.mitk.gui.qt.ext.externalprograms");
}
mitkThrow();
}
QmitkExternalProgramsPreferencePage::QmitkExternalProgramsPreferencePage()
: m_Preferences(GetPreferences()),
m_Ui(new Ui::QmitkExternalProgramsPreferencePage),
m_Control(NULL),
+ m_FFmpegProcess(NULL),
m_GnuplotProcess(NULL)
{
}
QmitkExternalProgramsPreferencePage::~QmitkExternalProgramsPreferencePage()
{
}
void QmitkExternalProgramsPreferencePage::CreateQtControl(QWidget* parent)
{
m_Control = new QWidget(parent);
+ m_FFmpegProcess = new QProcess(m_Control);
m_GnuplotProcess = new QProcess(m_Control);
m_Ui->setupUi(m_Control);
+ connect(m_FFmpegProcess, SIGNAL(error(QProcess::ProcessError)), this, SLOT(OnFFmpegProcessError(QProcess::ProcessError)));
+ connect(m_FFmpegProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(OnFFmpegProcessFinished(int, QProcess::ExitStatus)));
+ connect(m_Ui->ffmpegButton, SIGNAL(clicked()), this, SLOT(OnFFmpegButtonClicked()));
+
connect(m_GnuplotProcess, SIGNAL(error(QProcess::ProcessError)), this, SLOT(OnGnuplotProcessError(QProcess::ProcessError)));
connect(m_GnuplotProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(OnGnuplotProcessFinished(int, QProcess::ExitStatus)));
connect(m_Ui->gnuplotButton, SIGNAL(clicked()), this, SLOT(OnGnuplotButtonClicked()));
this->Update();
}
+void QmitkExternalProgramsPreferencePage::OnFFmpegButtonClicked()
+{
+ QString filter = "ffmpeg/avconv executable ";
+
+#if defined(WIN32)
+ filter += "(ffmpeg.exe avconv.exe)";
+#else
+ filter += "(ffmpeg avconv)";
+#endif
+
+ QString ffmpegPath = QFileDialog::getOpenFileName(m_Control, "FFmpeg/Libav", "", filter);
+
+ if (!ffmpegPath.isEmpty())
+ {
+ m_FFmpegPath = ffmpegPath;
+ m_FFmpegProcess->start(ffmpegPath, QStringList() << "-version", QProcess::ReadOnly);
+ }
+}
+
+void QmitkExternalProgramsPreferencePage::OnFFmpegProcessError(QProcess::ProcessError)
+{
+ m_FFmpegPath.clear();
+ m_Ui->ffmpegLineEdit->clear();
+}
+
+void QmitkExternalProgramsPreferencePage::OnFFmpegProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
+{
+ if (exitStatus == QProcess::NormalExit && exitCode == 0)
+ {
+ QString output = QTextCodec::codecForName("UTF-8")->toUnicode(m_FFmpegProcess->readAllStandardOutput());
+
+ if (output.startsWith("ffmpeg") || output.startsWith("avconv"))
+ {
+ m_Ui->ffmpegLineEdit->setText(m_FFmpegPath);
+ return;
+ }
+ }
+
+ m_FFmpegPath.clear();
+ m_Ui->ffmpegLineEdit->clear();
+}
+
void QmitkExternalProgramsPreferencePage::OnGnuplotButtonClicked()
{
- QString filter = "Gnuplot executable ";
+ QString filter = "gnuplot executable ";
#if defined(WIN32)
filter += "(gnuplot.exe)";
#else
filter += "(gnuplot)";
#endif
QString gnuplotPath = QFileDialog::getOpenFileName(m_Control, "Gnuplot", "", filter);
if (!gnuplotPath.isEmpty())
{
m_GnuplotPath = gnuplotPath;
m_GnuplotProcess->start(gnuplotPath, QStringList() << "--version", QProcess::ReadOnly);
}
}
void QmitkExternalProgramsPreferencePage::OnGnuplotProcessError(QProcess::ProcessError)
{
m_GnuplotPath.clear();
m_Ui->gnuplotLineEdit->clear();
}
void QmitkExternalProgramsPreferencePage::OnGnuplotProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
if (exitStatus == QProcess::NormalExit && exitCode == 0)
{
- QString version = QTextCodec::codecForName("UTF-8")->toUnicode(m_GnuplotProcess->readAllStandardOutput()).trimmed();
+ QString output = QTextCodec::codecForName("UTF-8")->toUnicode(m_GnuplotProcess->readAllStandardOutput());
- if (version.startsWith("gnuplot"))
+ if (output.startsWith("gnuplot"))
{
- m_Ui->gnuplotLineEdit->setText(QString("%1 (%2)").arg(m_GnuplotPath).arg(version.trimmed()));
+ m_Ui->gnuplotLineEdit->setText(m_GnuplotPath);
return;
}
}
m_GnuplotPath.clear();
m_Ui->gnuplotLineEdit->clear();
}
QWidget* QmitkExternalProgramsPreferencePage::GetQtControl() const
{
return m_Control;
}
void QmitkExternalProgramsPreferencePage::Init(berry::IWorkbench::Pointer)
{
}
void QmitkExternalProgramsPreferencePage::PerformCancel()
{
}
bool QmitkExternalProgramsPreferencePage::PerformOk()
{
+ m_Preferences->Put("ffmpeg", m_FFmpegPath.toStdString());
m_Preferences->Put("gnuplot", m_GnuplotPath.toStdString());
return true;
}
void QmitkExternalProgramsPreferencePage::Update()
{
+ m_FFmpegPath = QString::fromStdString(m_Preferences->Get("ffmpeg", ""));
+
+ if (!m_FFmpegPath.isEmpty())
+ m_FFmpegProcess->start(m_FFmpegPath, QStringList() << "-version", QProcess::ReadOnly);
+
m_GnuplotPath = QString::fromStdString(m_Preferences->Get("gnuplot", ""));
if (!m_GnuplotPath.isEmpty())
m_GnuplotProcess->start(m_GnuplotPath, QStringList() << "--version", QProcess::ReadOnly);
}
diff --git a/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkExternalProgramsPreferencePage.h b/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkExternalProgramsPreferencePage.h
index e766b3b400..fb4da45609 100644
--- a/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkExternalProgramsPreferencePage.h
+++ b/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkExternalProgramsPreferencePage.h
@@ -1,59 +1,67 @@
/*===================================================================
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 QmitkExternalProgramsPreferencePage_h
#define QmitkExternalProgramsPreferencePage_h
#include <berryIPreferences.h>
#include <berryIQtPreferencePage.h>
#include <QProcess>
#include <QScopedPointer>
namespace Ui
{
class QmitkExternalProgramsPreferencePage;
}
class QmitkExternalProgramsPreferencePage : public QObject, public berry::IQtPreferencePage
{
Q_OBJECT
Q_INTERFACES(berry::IPreferencePage)
public:
QmitkExternalProgramsPreferencePage();
~QmitkExternalProgramsPreferencePage();
void CreateQtControl(QWidget* parent);
QWidget* GetQtControl() const;
void Init(berry::IWorkbench::Pointer);
void PerformCancel();
bool PerformOk();
void Update();
private slots:
+ void OnFFmpegButtonClicked();
+ void OnFFmpegProcessError(QProcess::ProcessError error);
+ void OnFFmpegProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
+
void OnGnuplotButtonClicked();
void OnGnuplotProcessError(QProcess::ProcessError error);
void OnGnuplotProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
private:
berry::IPreferences::Pointer m_Preferences;
QScopedPointer<Ui::QmitkExternalProgramsPreferencePage> m_Ui;
QWidget* m_Control;
+
+ QProcess* m_FFmpegProcess;
+ QString m_FFmpegPath;
+
QProcess* m_GnuplotProcess;
QString m_GnuplotPath;
};
#endif
diff --git a/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkExternalProgramsPreferencePage.ui b/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkExternalProgramsPreferencePage.ui
index ace9d303c8..428b27c526 100644
--- a/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkExternalProgramsPreferencePage.ui
+++ b/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkExternalProgramsPreferencePage.ui
@@ -1,65 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QmitkExternalProgramsPreferencePage</class>
<widget class="QWidget" name="QmitkExternalProgramsPreferencePage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>External Programs</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="ffmpegLabel">
+ <property name="text">
+ <string>FFmpeg/Libav:</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="buddy">
+ <cstring>gnuplotButton</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="ffmpegLineEdit">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QToolButton" name="ffmpegButton">
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
<widget class="QLabel" name="gnuplotLabel">
<property name="text">
- <string>Gnuplot &amp;executable:</string>
+ <string>gnuplot:</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="buddy">
<cstring>gnuplotButton</cstring>
</property>
</widget>
</item>
- <item>
+ <item row="1" column="1">
<widget class="QLineEdit" name="gnuplotLineEdit">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
- <item>
+ <item row="1" column="2">
<widget class="QToolButton" name="gnuplotButton">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>248</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
diff --git a/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkModuleView.cpp b/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkModuleView.cpp
index 05fbff3d5f..0e7b708225 100644
--- a/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkModuleView.cpp
+++ b/Plugins/org.mitk.gui.qt.ext/src/internal/QmitkModuleView.cpp
@@ -1,100 +1,105 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "QmitkModuleView.h"
#include <QmitkModuleTableModel.h>
#include <QTableView>
#include <QHBoxLayout>
#include <QHeaderView>
#include <QSortFilterProxyModel>
#include <QSettings>
QmitkModuleView::QmitkModuleView()
: tableView(0)
{
}
void QmitkModuleView::SetFocus()
{
//tableView->setFocus();
}
void QmitkModuleView::CreateQtPartControl(QWidget *parent)
{
QHBoxLayout* layout = new QHBoxLayout();
layout->setMargin(0);
parent->setLayout(layout);
tableView = new QTableView(parent);
QmitkModuleTableModel* tableModel = new QmitkModuleTableModel(tableView);
QSortFilterProxyModel* sortProxyModel = new QSortFilterProxyModel(tableView);
sortProxyModel->setSourceModel(tableModel);
sortProxyModel->setDynamicSortFilter(true);
tableView->setModel(sortProxyModel);
tableView->verticalHeader()->hide();
tableView->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
tableView->setSelectionMode(QAbstractItemView::ExtendedSelection);
tableView->setTextElideMode(Qt::ElideMiddle);
tableView->setSortingEnabled(true);
tableView->sortByColumn(0, Qt::AscendingOrder);
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
// Fixed size for "Id" column
tableView->horizontalHeader()->setResizeMode(0, QHeaderView::ResizeToContents);
// Fixed size for "Version" column
tableView->horizontalHeader()->setResizeMode(2, QHeaderView::ResizeToContents);
+#else
+ tableView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
+ tableView->horizontalHeader()->setSectionResizeMode(2, QHeaderView::ResizeToContents);
+#endif
tableView->horizontalHeader()->setStretchLastSection(true);
tableView->horizontalHeader()->setCascadingSectionResizes(true);
layout->addWidget(tableView);
if (viewState)
{
berry::IMemento::Pointer tableHeaderState = viewState->GetChild("tableHeader");
if (tableHeaderState)
{
std::string key;
tableHeaderState->GetString("qsettings-key", key);
if (!key.empty())
{
QSettings settings;
QByteArray ba = settings.value(QString::fromStdString(key)).toByteArray();
tableView->horizontalHeader()->restoreState(ba);
}
}
}
}
void QmitkModuleView::Init(berry::IViewSite::Pointer site, berry::IMemento::Pointer memento)
{
berry::QtViewPart::Init(site, memento);
viewState = memento;
}
void QmitkModuleView::SaveState(berry::IMemento::Pointer memento)
{
QString key = "QmitkModuleView_tableHeader";
QByteArray ba = tableView->horizontalHeader()->saveState();
QSettings settings;
settings.setValue(key, ba);
berry::IMemento::Pointer tableHeaderState = memento->CreateChild("tableHeader");
tableHeaderState->PutString("qsettings-key", key.toStdString());
}
diff --git a/Plugins/org.mitk.gui.qt.extapplication/CMakeLists.txt b/Plugins/org.mitk.gui.qt.extapplication/CMakeLists.txt
index 8ffe39bbf9..4f0146d128 100644
--- a/Plugins/org.mitk.gui.qt.extapplication/CMakeLists.txt
+++ b/Plugins/org.mitk.gui.qt.extapplication/CMakeLists.txt
@@ -1,11 +1,17 @@
project(org_mitk_gui_qt_extapplication)
MACRO_CREATE_MITK_CTK_PLUGIN(
EXPORT_DIRECTIVE MITK_QT_EXTAPP
EXPORTED_INCLUDE_SUFFIXES src
- PACKAGE_DEPENDS Qt4|QtWebKit
+ PACKAGE_DEPENDS Qt4|QtWebKit Qt5|WebKit
)
-if(QT_QTWEBKIT_FOUND)
- add_definitions(-DQT_WEBKIT)
-endif(QT_QTWEBKIT_FOUND)
+if (DESIRED_QT_VERSION MATCHES "5")
+ if (Qt5WebKit_DIR)
+ add_definitions(-DQT_WEBKIT)
+ endif()
+else()
+ if(QT_QTWEBKIT_FOUND)
+ add_definitions(-DQT_WEBKIT)
+ endif(QT_QTWEBKIT_FOUND)
+endif()
diff --git a/Plugins/org.mitk.gui.qt.extapplication/src/internal/QmitkExtApplicationPlugin.cpp b/Plugins/org.mitk.gui.qt.extapplication/src/internal/QmitkExtApplicationPlugin.cpp
index 55d66f1e9e..76a334ca60 100644
--- a/Plugins/org.mitk.gui.qt.extapplication/src/internal/QmitkExtApplicationPlugin.cpp
+++ b/Plugins/org.mitk.gui.qt.extapplication/src/internal/QmitkExtApplicationPlugin.cpp
@@ -1,90 +1,92 @@
/*===================================================================
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 "QmitkExtApplicationPlugin.h"
#include "perspectives/QmitkExtDefaultPerspective.h"
#include "perspectives/QmitkEditorPerspective.h"
#include "perspectives/QmitkVisualizationPerspective.h"
#include "QmitkMitkWorkbenchIntroPart.h"
#include "QmitkExtApplication.h"
#include <mitkVersion.h>
#include <mitkLogMacros.h>
#include <service/cm/ctkConfigurationAdmin.h>
#include <service/cm/ctkConfiguration.h>
#include <QFileInfo>
#include <QDateTime>
#include <QtPlugin>
QmitkExtApplicationPlugin* QmitkExtApplicationPlugin::inst = 0;
QmitkExtApplicationPlugin::QmitkExtApplicationPlugin()
{
inst = this;
}
QmitkExtApplicationPlugin::~QmitkExtApplicationPlugin()
{
}
QmitkExtApplicationPlugin* QmitkExtApplicationPlugin::GetDefault()
{
return inst;
}
void QmitkExtApplicationPlugin::start(ctkPluginContext* context)
{
berry::AbstractUICTKPlugin::start(context);
this->context = context;
BERRY_REGISTER_EXTENSION_CLASS(QmitkExtDefaultPerspective, context);
BERRY_REGISTER_EXTENSION_CLASS(QmitkEditorPerspective, context);
BERRY_REGISTER_EXTENSION_CLASS(QmitkMitkWorkbenchIntroPart, context);
BERRY_REGISTER_EXTENSION_CLASS(QmitkExtApplication, context);
BERRY_REGISTER_EXTENSION_CLASS(QmitkVisualizationPerspective, context);
ctkServiceReference cmRef = context->getServiceReference<ctkConfigurationAdmin>();
ctkConfigurationAdmin* configAdmin = 0;
if (cmRef)
{
configAdmin = context->getService<ctkConfigurationAdmin>(cmRef);
}
// Use the CTK Configuration Admin service to configure the BlueBerry help system
if (configAdmin)
{
ctkConfigurationPtr conf = configAdmin->getConfiguration("org.blueberry.services.help", QString());
ctkDictionary helpProps;
helpProps.insert("homePage", "qthelp://org.mitk.gui.qt.extapplication/bundle/index.html");
conf->update(helpProps);
context->ungetService(cmRef);
}
else
{
MITK_WARN << "Configuration Admin service unavailable, cannot set home page url.";
}
}
ctkPluginContext* QmitkExtApplicationPlugin::GetPluginContext() const
{
return context;
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_extapplication, QmitkExtApplicationPlugin)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_extapplication, QmitkExtApplicationPlugin)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.extapplication/src/internal/QmitkExtApplicationPlugin.h b/Plugins/org.mitk.gui.qt.extapplication/src/internal/QmitkExtApplicationPlugin.h
index 168124b30f..0387cc5af9 100644
--- a/Plugins/org.mitk.gui.qt.extapplication/src/internal/QmitkExtApplicationPlugin.h
+++ b/Plugins/org.mitk.gui.qt.extapplication/src/internal/QmitkExtApplicationPlugin.h
@@ -1,52 +1,55 @@
/*===================================================================
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 QMITKEXTAPPLICATIONPLUGIN_H_
#define QMITKEXTAPPLICATIONPLUGIN_H_
#include <berryAbstractUICTKPlugin.h>
#include <QString>
#include <berryQCHPluginListener.h>
class QmitkExtApplicationPlugin : public QObject, public berry::AbstractUICTKPlugin
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_extapplication")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
QmitkExtApplicationPlugin();
~QmitkExtApplicationPlugin();
static QmitkExtApplicationPlugin* GetDefault();
ctkPluginContext* GetPluginContext() const;
void start(ctkPluginContext*);
QString GetQtHelpCollectionFile() const;
private:
static QmitkExtApplicationPlugin* inst;
ctkPluginContext* context;
};
#endif /* QMITKEXTAPPLICATIONPLUGIN_H_ */
diff --git a/Plugins/org.mitk.gui.qt.extapplication/src/internal/QmitkMitkWorkbenchIntroPart.cpp b/Plugins/org.mitk.gui.qt.extapplication/src/internal/QmitkMitkWorkbenchIntroPart.cpp
index b415c12118..093d3dac13 100644
--- a/Plugins/org.mitk.gui.qt.extapplication/src/internal/QmitkMitkWorkbenchIntroPart.cpp
+++ b/Plugins/org.mitk.gui.qt.extapplication/src/internal/QmitkMitkWorkbenchIntroPart.cpp
@@ -1,203 +1,214 @@
/*===================================================================
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 "QmitkMitkWorkbenchIntroPart.h"
#include <berryIWorkbenchWindow.h>
#include <berryIWorkbench.h>
#include <berryIWorkbenchPage.h>
#include <berryIPerspectiveRegistry.h>
#include <berryWorkbenchPreferenceConstants.h>
#include <berryIPreferences.h>
#include <berryIEditorReference.h>
#include <berryIEditorInput.h>
#include <mitkIDataStorageService.h>
#include <mitkDataStorageEditorInput.h>
#include <mitkLogMacros.h>
#include <QLabel>
#include <QMessageBox>
#include <QtCore/qconfig.h>
#ifdef QT_WEBKIT
-#include <QWebView>
-#include <QWebPage>
+# include <QWebView>
+# include <QWebPage>
+# if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
+# include <QUrlQuery>
+# endif
#endif
#include <QString>
#include <QStringList>
#include <QRegExp>
#include <QChar>
#include <QByteArray>
#include <QDesktopServices>
#include "QmitkExtApplicationPlugin.h"
#include "mitkDataStorageEditorInput.h"
#include <string>
QmitkMitkWorkbenchIntroPart::QmitkMitkWorkbenchIntroPart()
: m_Controls(NULL)
{
berry::IPreferences::Pointer workbenchPrefs = QmitkExtApplicationPlugin::GetDefault()->GetPreferencesService()->GetSystemPreferences();
workbenchPrefs->PutBool(berry::WorkbenchPreferenceConstants::SHOW_INTRO, true);
workbenchPrefs->Flush();
}
QmitkMitkWorkbenchIntroPart::~QmitkMitkWorkbenchIntroPart()
{
// if the workbench is not closing (that means, welcome screen was closed explicitly), set "Show_intro" false
if (!this->GetIntroSite()->GetPage()->GetWorkbenchWindow()->GetWorkbench()->IsClosing())
{
berry::IPreferences::Pointer workbenchPrefs = QmitkExtApplicationPlugin::GetDefault()->GetPreferencesService()->GetSystemPreferences();
workbenchPrefs->PutBool(berry::WorkbenchPreferenceConstants::SHOW_INTRO, false);
workbenchPrefs->Flush();
}
else
{
berry::IPreferences::Pointer workbenchPrefs = QmitkExtApplicationPlugin::GetDefault()->GetPreferencesService()->GetSystemPreferences();
workbenchPrefs->PutBool(berry::WorkbenchPreferenceConstants::SHOW_INTRO, true);
workbenchPrefs->Flush();
}
// if workbench is not closing (Just welcome screen closing), open last used perspective
if (this->GetIntroSite()->GetPage()->GetPerspective()->GetId()
== "org.mitk.mitkworkbench.perspectives.editor" && !this->GetIntroSite()->GetPage()->GetWorkbenchWindow()->GetWorkbench()->IsClosing())
{
berry::IPerspectiveDescriptor::Pointer perspective = this->GetIntroSite()->GetWorkbenchWindow()->GetWorkbench()->GetPerspectiveRegistry()->FindPerspectiveWithId("org.mitk.mitkworkbench.perspectives.editor");
if (perspective)
{
this->GetIntroSite()->GetPage()->SetPerspective(perspective);
}
}
}
void QmitkMitkWorkbenchIntroPart::CreateQtPartControl(QWidget* parent)
{
if (!m_Controls)
{
// create GUI widgets
m_Controls = new Ui::QmitkWelcomeScreenViewControls;
m_Controls->setupUi(parent);
#ifdef QT_WEBKIT
// create a QWebView as well as a QWebPage and QWebFrame within the QWebview
m_view = new QWebView(parent);
m_view->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
QUrl urlQtResource(QString("qrc:/org.mitk.gui.qt.welcomescreen/mitkworkbenchwelcomeview.html"), QUrl::TolerantMode );
m_view->load( urlQtResource );
// adds the webview as a widget
parent->layout()->addWidget(m_view);
this->CreateConnections();
#else
parent->layout()->addWidget(new QLabel("<h1><center>Please install Qt with the WebKit option to see cool pictures!</center></h1>"));
#endif
}
}
#ifdef QT_WEBKIT
void QmitkMitkWorkbenchIntroPart::CreateConnections()
{
if ( m_Controls )
{
connect( (QObject*)(m_view->page()), SIGNAL(linkClicked(const QUrl& )), this, SLOT(DelegateMeTo(const QUrl& )) );
}
}
void QmitkMitkWorkbenchIntroPart::DelegateMeTo(const QUrl& showMeNext)
{
QString scheme = showMeNext.scheme();
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
QByteArray urlHostname = showMeNext.encodedHost();
QByteArray urlPath = showMeNext.encodedPath();
QByteArray dataset = showMeNext.encodedQueryItemValue("dataset");
QByteArray clear = showMeNext.encodedQueryItemValue("clear");
+#else
+ QByteArray urlHostname = QUrl::toAce(showMeNext.host());
+ QByteArray urlPath = showMeNext.path().toLatin1();
+ QUrlQuery query(showMeNext);
+ QByteArray dataset = query.queryItemValue("dataset").toLatin1();
+ QByteArray clear = query.queryItemValue("clear").toLatin1();//showMeNext.encodedQueryItemValue("clear");
+#endif
if (scheme.isEmpty()) MITK_INFO << " empty scheme of the to be delegated link" ;
// if the scheme is set to mitk, it is to be tested which action should be applied
if (scheme.contains(QString("mitk")) )
{
if(urlPath.isEmpty() ) MITK_INFO << " mitk path is empty " ;
// searching for the perspective keyword within the host name
if(urlHostname.contains(QByteArray("perspectives")) )
{
// the simplified method removes every whitespace
// ( whitespace means any character for which the standard C++ isspace() method returns true)
urlPath = urlPath.simplified();
QString tmpPerspectiveId(urlPath.data());
tmpPerspectiveId.replace(QString("/"), QString("") );
std::string perspectiveId = tmpPerspectiveId.toStdString();
// is working fine as long as the perspective id is valid, if not the application crashes
GetIntroSite()->GetWorkbenchWindow()->GetWorkbench()->ShowPerspective(perspectiveId, GetIntroSite()->GetWorkbenchWindow() );
// search the Workbench for opened StdMultiWidgets to ensure the focus does not stay on the welcome screen and is switched to
// an StdMultiWidget if one available
mitk::IDataStorageService::Pointer service =
berry::Platform::GetServiceRegistry().GetServiceById<mitk::IDataStorageService>(mitk::IDataStorageService::ID);
berry::IEditorInput::Pointer editorInput;
editorInput = new mitk::DataStorageEditorInput( service->GetActiveDataStorage() );
// the solution is not clean, but the dependency to the StdMultiWidget was removed in order to fix a crash problem
// as described in Bug #11715
// This is the correct way : use the static string ID variable
// berry::IEditorPart::Pointer editor = GetIntroSite()->GetPage()->FindEditors( editorInput, QmitkStdMultiWidgetEditor::EDITOR_ID );
// QuickFix: we use the same string for an local variable
const std::string stdEditorID = "org.mitk.editors.stdmultiwidget";
// search for opened StdMultiWidgetEditors
std::vector<berry::IEditorReference::Pointer> editorList = GetIntroSite()->GetPage()->FindEditors( editorInput, stdEditorID, 1 );
// if an StdMultiWidgetEditor open was found, give focus to it
if(editorList.size())
{
GetIntroSite()->GetPage()->Activate( editorList[0]->GetPart(true) );
}
}
}
// if the scheme is set to http, by default no action is performed, if an external webpage needs to be
// shown it should be implemented below
else if (scheme.contains(QString("http")) )
{
QDesktopServices::openUrl(showMeNext);
// m_view->load( ) ;
}
else if(scheme.contains("qrc"))
{
m_view->load(showMeNext);
}
}
#endif
void QmitkMitkWorkbenchIntroPart::StandbyStateChanged(bool standby)
{
}
void QmitkMitkWorkbenchIntroPart::SetFocus()
{
}
diff --git a/Plugins/org.mitk.gui.qt.extapplication/src/internal/perspectives/QmitkExtDefaultPerspective.cpp b/Plugins/org.mitk.gui.qt.extapplication/src/internal/perspectives/QmitkExtDefaultPerspective.cpp
index 1cdeee7b3f..eb62e48b85 100644
--- a/Plugins/org.mitk.gui.qt.extapplication/src/internal/perspectives/QmitkExtDefaultPerspective.cpp
+++ b/Plugins/org.mitk.gui.qt.extapplication/src/internal/perspectives/QmitkExtDefaultPerspective.cpp
@@ -1,40 +1,39 @@
/*===================================================================
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 "QmitkExtDefaultPerspective.h"
#include "berryIViewLayout.h"
QmitkExtDefaultPerspective::QmitkExtDefaultPerspective()
{
}
void QmitkExtDefaultPerspective::CreateInitialLayout(berry::IPageLayout::Pointer layout)
{
std::string editorArea = layout->GetEditorArea();
layout->AddView("org.mitk.views.datamanager", berry::IPageLayout::LEFT, 0.3f, editorArea);
berry::IViewLayout::Pointer lo = layout->GetViewLayout("org.mitk.views.datamanager");
lo->SetCloseable(false);
layout->AddView("org.mitk.views.imagenavigator",
berry::IPageLayout::BOTTOM, 0.5f, "org.mitk.views.datamanager");
berry::IPlaceholderFolderLayout::Pointer bottomFolder = layout->CreatePlaceholderFolder("bottom", berry::IPageLayout::BOTTOM, 0.7f, editorArea);
- bottomFolder->AddPlaceholder("org.mitk.views.propertylistview");
bottomFolder->AddPlaceholder("org.blueberry.views.logview");
bottomFolder->AddPlaceholder("org.mitk.views.modules");
}
diff --git a/Plugins/org.mitk.gui.qt.igtexamples/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.igtexamples/src/internal/mitkPluginActivator.cpp
index f81bd5e67b..1bcd8603be 100644
--- a/Plugins/org.mitk.gui.qt.igtexamples/src/internal/mitkPluginActivator.cpp
+++ b/Plugins/org.mitk.gui.qt.igtexamples/src/internal/mitkPluginActivator.cpp
@@ -1,37 +1,39 @@
/*===================================================================
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 "mitkPluginActivator.h"
#include "QmitkIGTTutorialView.h"
#include "QmitkIGTTrackingLabView.h"
#include <QtPlugin>
namespace mitk {
void PluginActivator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(QmitkIGTTutorialView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkIGTTrackingLabView, context)
}
void PluginActivator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_igtexamples, mitk::PluginActivator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_igtexamples, mitk::PluginActivator)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.igtexamples/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.igtexamples/src/internal/mitkPluginActivator.h
index 12053e09e3..e6e9d7b23e 100644
--- a/Plugins/org.mitk.gui.qt.igtexamples/src/internal/mitkPluginActivator.h
+++ b/Plugins/org.mitk.gui.qt.igtexamples/src/internal/mitkPluginActivator.h
@@ -1,39 +1,42 @@
/*===================================================================
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 MITKPLUGINACTIVATOR_H
#define MITKPLUGINACTIVATOR_H
#include <ctkPluginActivator.h>
#include <mitkExportMacros.h>
namespace mitk {
class MITK_LOCAL PluginActivator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_igtexamples")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
}; // PluginActivator
}
#endif // MITKPLUGINACTIVATOR_H
diff --git a/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkNavigationDataPlayerView.cpp b/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkNavigationDataPlayerView.cpp
index b39112e2bb..140d7cf497 100644
--- a/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkNavigationDataPlayerView.cpp
+++ b/Plugins/org.mitk.gui.qt.igttracking/src/internal/QmitkNavigationDataPlayerView.cpp
@@ -1,230 +1,233 @@
/*===================================================================
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.
===================================================================*/
// Qmitk
#include "QmitkNavigationDataPlayerView.h"
// QT
#include <QFileDialog>
#include <QMessageBox>
//mitk
#include <mitkNavigationDataSet.h>
#include <mitkNavigationDataReaderXML.h>
#include <mitkNavigationDataSequentialPlayer.h>
#include <mitkNavigationDataPlayer.h>
#include <mitkVirtualTrackingTool.h>
// VTK
#include <vtkSphereSource.h>
const std::string QmitkNavigationDataPlayerView::VIEW_ID = "org.mitk.views.navigationdataplayer";
QmitkNavigationDataPlayerView::QmitkNavigationDataPlayerView()
: m_Controls( 0 )
{
}
QmitkNavigationDataPlayerView::~QmitkNavigationDataPlayerView()
{
}
void QmitkNavigationDataPlayerView::CreateQtPartControl( QWidget *parent )
{
// build up qt view, unless already done
if ( !m_Controls )
{
// create GUI widgets from the Qt Designer's .ui file
m_Controls = new Ui::QmitkNavigationDataPlayerViewControls;
m_Controls->setupUi( parent );
this->CreateConnections();
// make deselected Player invisible
m_Controls->m_TimedWidget->setVisible(false);
}
}
void QmitkNavigationDataPlayerView::SetFocus()
{
if ( m_Controls )
{
m_Controls->m_grpbxControls->setFocus();
}
}
void QmitkNavigationDataPlayerView::CreateConnections()
{
connect( m_Controls->m_RdbSequential, SIGNAL(released()), this, SLOT(OnSelectPlayer()) );
connect( m_Controls->m_RdbTimeBased, SIGNAL(released()), this, SLOT(OnSelectPlayer()) );
connect( m_Controls->m_BtnOpenFile, SIGNAL(released()), this, SLOT(OnOpenFile()) );
connect( m_Controls->m_ChkDisplay, SIGNAL(released()), this, SLOT(OnSetDisplay()) );
connect( m_Controls->m_chkRepeat, SIGNAL(stateChanged(int)), this, SLOT(OnSetRepeat(int)) );
connect( m_Controls->m_ChkMicroservice, SIGNAL(released()), this, SLOT(OnSetMicroservice()) );
connect( m_Controls->m_SequentialWidget, SIGNAL(SignalUpdate()), this, SLOT(OnUpdate()) );
connect( m_Controls->m_TimedWidget, SIGNAL(SignalUpdate()), this, SLOT(OnUpdate()) );
this->SetInteractionComponentsEnabledState(false);
}
void QmitkNavigationDataPlayerView::OnOpenFile(){
mitk::NavigationDataReaderXML::Pointer reader = mitk::NavigationDataReaderXML::New();
// FIXME Filter for correct Files and use correct Reader
QString fileName = QFileDialog::getOpenFileName(NULL, "Open Navigation Data Set", "", "XML files (*.xml)"); //"XML files (*.xml);; Csv files (*.csv)" for additional csv files. Not supported yet.
if ( fileName.isNull() ) { return; } // user pressed cancel
try
{
m_Data = reader->Read(fileName.toStdString());
}
catch ( const mitk::Exception &e )
{
MITK_WARN("NavigationDataPlayerView") << "could not open file " << fileName.toStdString();
QMessageBox::critical(0, "Error Reading File", "The file '" + fileName
+"' could not be read.\n" + e.GetDescription() );
return;
}
// Update Labels
m_Controls->m_LblFilePath->setText(fileName);
m_Controls->m_LblFrames->setText(QString::number(m_Data->Size()));
m_Controls->m_LblTools->setText(QString::number(m_Data->GetNumberOfTools()));
// Initialize Widgets and create Player
this->OnSelectPlayer();
this->SetInteractionComponentsEnabledState(true);
}
void QmitkNavigationDataPlayerView::OnSelectPlayer()
{
if (m_Controls->m_RdbSequential->isChecked())
{
m_Controls->m_SequentialWidget->setVisible(true);
m_Controls->m_TimedWidget->setVisible(false);
mitk::NavigationDataSequentialPlayer::Pointer seqPlayer = mitk::NavigationDataSequentialPlayer::New();
seqPlayer->SetNavigationDataSet(m_Data);
m_Controls->m_SequentialWidget->SetPlayer(seqPlayer);
m_Player = seqPlayer;
} else {
m_Controls->m_SequentialWidget->setVisible(false);
m_Controls->m_TimedWidget->setVisible(true);
mitk::NavigationDataPlayer::Pointer timedPlayer = mitk::NavigationDataPlayer::New();
timedPlayer->SetNavigationDataSet(m_Data);
m_Controls->m_TimedWidget->SetPlayer(timedPlayer);
m_Player = timedPlayer;
}
this->ConfigurePlayer();
// SetupRenderingPipeline
this->OnSetDisplay();
}
void QmitkNavigationDataPlayerView::ConfigurePlayer()
{
// set repeat mode according to the checkbox
m_Player->SetRepeat( m_Controls->m_chkRepeat->isChecked() );
}
void QmitkNavigationDataPlayerView::OnSetRepeat(int checkState)
{
m_Player->SetRepeat(checkState != 0);
}
void QmitkNavigationDataPlayerView::OnSetMicroservice(){
if(m_Controls->m_ChkMicroservice->isChecked())
{
m_ToolStorage = mitk::NavigationToolStorage::New();
for (itk::ProcessObject::DataObjectPointerArraySizeType i = 0;
i < m_Player->GetNumberOfIndexedOutputs(); i++)
{
mitk::NavigationTool::Pointer currentDummyTool = mitk::NavigationTool::New();
mitk::VirtualTrackingTool::Pointer dummyTool = mitk::VirtualTrackingTool::New();
std::stringstream name;
name << "Virtual Tool " << i;
dummyTool->SetToolName(name.str());
currentDummyTool->SetTrackingTool(dummyTool.GetPointer());
currentDummyTool->SetDataNode(m_RenderingNodes.at(i));
currentDummyTool->SetIdentifier(name.str());
m_ToolStorage->AddTool(currentDummyTool);
}
m_Player->RegisterAsMicroservice();
m_ToolStorage->SetName("NavigationDataPlayer Tool Storage");
m_ToolStorage->RegisterAsMicroservice(m_Player->GetMicroserviceID());
} else {
if (m_ToolStorage.IsNotNull()) m_ToolStorage->UnRegisterMicroservice();
m_ToolStorage = NULL;
m_Player->UnRegisterMicroservice();
}
}
void QmitkNavigationDataPlayerView::OnUpdate(){
if (m_VisFilter.IsNotNull())
{
m_VisFilter->Update();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
}
void QmitkNavigationDataPlayerView::OnSetDisplay(){
DestroyPipeline();
if ( (m_Controls->m_ChkDisplay->isChecked()) && ( m_Player.IsNotNull() ))
{
CreatePipeline();
}
}
void QmitkNavigationDataPlayerView::CreatePipeline(){
m_VisFilter = mitk::NavigationDataObjectVisualizationFilter::New();
m_VisFilter->ConnectTo(m_Player);
for (unsigned int i = 0 ; i < m_Player->GetNumberOfIndexedOutputs(); i++ ) {
mitk::DataNode::Pointer node = mitk::DataNode::New();
QString name = "Recorded Tool " + QString::number(i + 1);
node->SetName(name.toStdString());
//create small sphere and use it as surface
mitk::Surface::Pointer mySphere = mitk::Surface::New();
vtkSphereSource *vtkData = vtkSphereSource::New();
vtkData->SetRadius(5.0f);
vtkData->SetCenter(0.0, 0.0, 0.0);
vtkData->Update();
mySphere->SetVtkPolyData(vtkData->GetOutput());
vtkData->Delete();
node->SetData(mySphere);
m_VisFilter->SetRepresentationObject(i, mySphere);
// Add Node to DataStorageand to local list of Nodes
GetDataStorage()->Add(node);
m_RenderingNodes.push_back(node);
}
m_VisFilter->Update();
+
+ mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects(GetDataStorage());
+ mitk::RenderingManager::GetInstance()->RequestUpdateAll();
}
void QmitkNavigationDataPlayerView::DestroyPipeline(){
m_VisFilter = NULL;
for (unsigned int i = 0; i < m_RenderingNodes.size(); i++){
this->GetDataStorage()->Remove(m_RenderingNodes[i]);
}
m_RenderingNodes.clear();
}
void QmitkNavigationDataPlayerView::SetInteractionComponentsEnabledState(bool isActive){
m_Controls->m_grpbxSettings->setEnabled(isActive);
m_Controls->m_grpbxControls->setEnabled(isActive);
-}
+}
\ No newline at end of file
diff --git a/Plugins/org.mitk.gui.qt.igttracking/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.igttracking/src/internal/mitkPluginActivator.cpp
index dac2744b3f..578dae18ac 100644
--- a/Plugins/org.mitk.gui.qt.igttracking/src/internal/mitkPluginActivator.cpp
+++ b/Plugins/org.mitk.gui.qt.igttracking/src/internal/mitkPluginActivator.cpp
@@ -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.
===================================================================*/
#include "mitkPluginActivator.h"
#include <QtPlugin>
#include "QmitkMITKIGTNavigationToolManagerView.h"
#include "QmitkMITKIGTTrackingToolboxView.h"
#include "QmitkNavigationDataPlayerView.h"
//#include <mitkPersistenceService.h> //Workaround for bug in persistence module (see bug 16643 for details)
//CAN BE REMOVED WHEN THE BUG IS FIXED
namespace mitk {
void PluginActivator::start(ctkPluginContext* context)
{
// mitk::PersistenceService::LoadModule(); //Workaround for bug in persistence module (see bug 16643 for details)
//CAN BE REMOVED WHEN THE BUG IS FIXED
BERRY_REGISTER_EXTENSION_CLASS(QmitkMITKIGTNavigationToolManagerView, context)
BERRY_REGISTER_EXTENSION_CLASS( QmitkMITKIGTTrackingToolboxView , context)
BERRY_REGISTER_EXTENSION_CLASS( QmitkNavigationDataPlayerView , context)
}
void PluginActivator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_igttracking, mitk::PluginActivator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_igttracking, mitk::PluginActivator)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.igttracking/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.igttracking/src/internal/mitkPluginActivator.h
index bcc0aed5a2..968e2aad26 100644
--- a/Plugins/org.mitk.gui.qt.igttracking/src/internal/mitkPluginActivator.h
+++ b/Plugins/org.mitk.gui.qt.igttracking/src/internal/mitkPluginActivator.h
@@ -1,40 +1,43 @@
/*===================================================================
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 MITKPLUGINACTIVATOR_H
#define MITKPLUGINACTIVATOR_H
#include <ctkPluginActivator.h>
namespace mitk {
class PluginActivator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_igttracking")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
}; // PluginActivator
}
#endif // MITKPLUGINACTIVATOR_H
diff --git a/Plugins/org.mitk.gui.qt.imagecropper/src/internal/mitkImageCropperPluginActivator.cpp b/Plugins/org.mitk.gui.qt.imagecropper/src/internal/mitkImageCropperPluginActivator.cpp
index c3f9c4dec9..874d543673 100644
--- a/Plugins/org.mitk.gui.qt.imagecropper/src/internal/mitkImageCropperPluginActivator.cpp
+++ b/Plugins/org.mitk.gui.qt.imagecropper/src/internal/mitkImageCropperPluginActivator.cpp
@@ -1,35 +1,37 @@
/*===================================================================
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 "mitkImageCropperPluginActivator.h"
#include "QmitkImageCropper.h"
#include <QtPlugin>
namespace mitk {
void ImageCropperPluginActivator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS( QmitkImageCropper, context )
}
void ImageCropperPluginActivator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_imagecropper, mitk::ImageCropperPluginActivator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_imagecropper, mitk::ImageCropperPluginActivator)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.imagecropper/src/internal/mitkImageCropperPluginActivator.h b/Plugins/org.mitk.gui.qt.imagecropper/src/internal/mitkImageCropperPluginActivator.h
index 395a280167..3d77c1ee15 100644
--- a/Plugins/org.mitk.gui.qt.imagecropper/src/internal/mitkImageCropperPluginActivator.h
+++ b/Plugins/org.mitk.gui.qt.imagecropper/src/internal/mitkImageCropperPluginActivator.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 MITKPLUGINACTIVATOR_H
#define MITKPLUGINACTIVATOR_H
#include <ctkPluginActivator.h>
namespace mitk {
class ImageCropperPluginActivator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_imagecropper")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
}; // PluginActivator
}
#endif // MITKPLUGINACTIVATOR_H
diff --git a/Plugins/org.mitk.gui.qt.imagenavigator/src/internal/mitkImageNavigatorPluginActivator.cpp b/Plugins/org.mitk.gui.qt.imagenavigator/src/internal/mitkImageNavigatorPluginActivator.cpp
index 5dafa9f935..c2312a81d2 100644
--- a/Plugins/org.mitk.gui.qt.imagenavigator/src/internal/mitkImageNavigatorPluginActivator.cpp
+++ b/Plugins/org.mitk.gui.qt.imagenavigator/src/internal/mitkImageNavigatorPluginActivator.cpp
@@ -1,36 +1,38 @@
/*===================================================================
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 "mitkImageNavigatorPluginActivator.h"
#include "QmitkImageNavigatorView.h"
#include <QtPlugin>
namespace mitk {
void ImageNavigatorPluginActivator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(QmitkImageNavigatorView, context)
}
void ImageNavigatorPluginActivator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_imagenavigator, mitk::ImageNavigatorPluginActivator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_imagenavigator, mitk::ImageNavigatorPluginActivator)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.imagenavigator/src/internal/mitkImageNavigatorPluginActivator.h b/Plugins/org.mitk.gui.qt.imagenavigator/src/internal/mitkImageNavigatorPluginActivator.h
index f01e093d00..27dabb9f00 100644
--- a/Plugins/org.mitk.gui.qt.imagenavigator/src/internal/mitkImageNavigatorPluginActivator.h
+++ b/Plugins/org.mitk.gui.qt.imagenavigator/src/internal/mitkImageNavigatorPluginActivator.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 MITKIMAGENAVIGATORPLUGINACTIVATOR_H
#define MITKIMAGENAVIGATORPLUGINACTIVATOR_H
#include <ctkPluginActivator.h>
namespace mitk {
class ImageNavigatorPluginActivator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
- Q_INTERFACES(ctkPluginActivator)
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_imagenavigator")
+#endif
+ Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
}; // ImageNavigatorPluginActivator
}
#endif // MITKIMAGENAVIGATORPLUGINACTIVATOR_H
diff --git a/Plugins/org.mitk.gui.qt.materialeditor/src/internal/mitkMaterialEditorPluginActivator.cpp b/Plugins/org.mitk.gui.qt.materialeditor/src/internal/mitkMaterialEditorPluginActivator.cpp
index b137a40f5c..2b93d4e8f6 100644
--- a/Plugins/org.mitk.gui.qt.materialeditor/src/internal/mitkMaterialEditorPluginActivator.cpp
+++ b/Plugins/org.mitk.gui.qt.materialeditor/src/internal/mitkMaterialEditorPluginActivator.cpp
@@ -1,36 +1,38 @@
/*===================================================================
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 "mitkMaterialEditorPluginActivator.h"
#include "QmitkMITKSurfaceMaterialEditorView.h"
#include <QtPlugin>
namespace mitk {
void MaterialEditorPluginActivator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(QmitkMITKSurfaceMaterialEditorView, context)
}
void MaterialEditorPluginActivator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_materialeditor, mitk::MaterialEditorPluginActivator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_materialeditor, mitk::MaterialEditorPluginActivator)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.materialeditor/src/internal/mitkMaterialEditorPluginActivator.h b/Plugins/org.mitk.gui.qt.materialeditor/src/internal/mitkMaterialEditorPluginActivator.h
index adbb283970..6151f14c5a 100644
--- a/Plugins/org.mitk.gui.qt.materialeditor/src/internal/mitkMaterialEditorPluginActivator.h
+++ b/Plugins/org.mitk.gui.qt.materialeditor/src/internal/mitkMaterialEditorPluginActivator.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 MITKMATERIALEDITORPLUGINACTIVATOR_H
#define MITKMATERIALEDITORPLUGINACTIVATOR_H
#include <ctkPluginActivator.h>
namespace mitk {
class MaterialEditorPluginActivator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
- Q_INTERFACES(ctkPluginActivator)
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_materialeditor")
+#endif
+ Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
}; // MaterialEditorPluginActivator
}
#endif // MITKMATERIALEDITORPLUGINACTIVATOR_H
diff --git a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.cpp b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.cpp
index 7624375be4..1c09429e5f 100644
--- a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.cpp
+++ b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkImageStatisticsView.cpp
@@ -1,992 +1,998 @@
/*===================================================================
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 "QmitkImageStatisticsView.h"
// Qt includes
#include <qclipboard.h>
#include <qscrollbar.h>
// berry includes
#include <berryIWorkbenchPage.h>
// mitk includes
#include "mitkNodePredicateDataType.h"
#include "mitkPlanarFigureInteractor.h"
// itk includes
#include "itksys/SystemTools.hxx"
#include <mitkILinkedRenderWindowPart.h>
#include <QmitkRenderWindow.h>
const std::string QmitkImageStatisticsView::VIEW_ID = "org.mitk.views.imagestatistics";
const int QmitkImageStatisticsView::STAT_TABLE_BASE_HEIGHT = 180;
QmitkImageStatisticsView::QmitkImageStatisticsView(QObject* /*parent*/, const char* /*name*/)
: m_Controls( NULL ),
m_TimeStepperAdapter( NULL ),
m_SelectedImage( NULL ),
m_SelectedImageMask( NULL ),
m_SelectedPlanarFigure( NULL ),
m_ImageObserverTag( -1 ),
m_ImageMaskObserverTag( -1 ),
m_PlanarFigureObserverTag( -1 ),
m_TimeObserverTag( -1 ),
m_CurrentStatisticsValid( false ),
m_StatisticsUpdatePending( false ),
m_DataNodeSelectionChanged ( false ),
m_Visible(false)
{
this->m_CalculationThread = new QmitkImageStatisticsCalculationThread;
}
QmitkImageStatisticsView::~QmitkImageStatisticsView()
{
if ( m_SelectedImage != NULL )
m_SelectedImage->RemoveObserver( m_ImageObserverTag );
if ( m_SelectedImageMask != NULL )
m_SelectedImageMask->RemoveObserver( m_ImageMaskObserverTag );
if ( m_SelectedPlanarFigure != NULL )
m_SelectedPlanarFigure->RemoveObserver( m_PlanarFigureObserverTag );
while(this->m_CalculationThread->isRunning()) // wait until thread has finished
{
itksys::SystemTools::Delay(100);
}
delete this->m_CalculationThread;
}
void QmitkImageStatisticsView::CreateQtPartControl(QWidget *parent)
{
if (m_Controls == NULL)
{
m_Controls = new Ui::QmitkImageStatisticsViewControls;
m_Controls->setupUi(parent);
CreateConnections();
m_Controls->m_ErrorMessageLabel->hide();
m_Controls->m_StatisticsWidgetStack->setCurrentIndex( 0 );
m_Controls->m_BinSizeFrame->setVisible(false);
}
}
void QmitkImageStatisticsView::CreateConnections()
{
if ( m_Controls )
{
connect( (QObject*)(this->m_Controls->m_ButtonCopyHistogramToClipboard), SIGNAL(clicked()),(QObject*) this, SLOT(OnClipboardHistogramButtonClicked()) );
connect( (QObject*)(this->m_Controls->m_ButtonCopyStatisticsToClipboard), SIGNAL(clicked()),(QObject*) this, SLOT(OnClipboardStatisticsButtonClicked()) );
connect( (QObject*)(this->m_Controls->m_IgnoreZerosCheckbox), SIGNAL(clicked()),(QObject*) this, SLOT(OnIgnoreZerosCheckboxClicked()) );
connect( (QObject*) this->m_CalculationThread, SIGNAL(finished()),this, SLOT( OnThreadedStatisticsCalculationEnds()),Qt::QueuedConnection);
connect( (QObject*) this, SIGNAL(StatisticsUpdate()),this, SLOT( RequestStatisticsUpdate()), Qt::QueuedConnection);
connect( (QObject*) this->m_Controls->m_StatisticsTable, SIGNAL(cellDoubleClicked(int,int)),this, SLOT( JumpToCoordinates(int,int)) );
connect( (QObject*) (this->m_Controls->m_barRadioButton), SIGNAL(clicked()), (QObject*) (this->m_Controls->m_JSHistogram), SLOT(OnBarRadioButtonSelected()));
connect( (QObject*) (this->m_Controls->m_lineRadioButton), SIGNAL(clicked()), (QObject*) (this->m_Controls->m_JSHistogram), SLOT(OnLineRadioButtonSelected()));
connect( (QObject*) (this->m_Controls->m_HistogramBinSizeSpinbox), SIGNAL(editingFinished()), this, SLOT(OnHistogramBinSizeBoxValueChanged()));
connect( (QObject*)(this->m_Controls->m_UseDefaultBinSizeBox), SIGNAL(clicked()),(QObject*) this, SLOT(OnDefaultBinSizeBoxChanged()) );
}
}
void QmitkImageStatisticsView::OnDefaultBinSizeBoxChanged()
{
if (m_CalculationThread!=NULL)
m_Controls->m_HistogramBinSizeSpinbox->setValue(m_CalculationThread->GetHistogramBinSize());
if (m_Controls->m_UseDefaultBinSizeBox->isChecked())
m_Controls->m_BinSizeFrame->setVisible(false);
else
m_Controls->m_BinSizeFrame->setVisible(true);
}
void QmitkImageStatisticsView::PartClosed( berry::IWorkbenchPartReference::Pointer )
{
}
void QmitkImageStatisticsView::OnTimeChanged(const itk::EventObject& e)
{
if (this->m_SelectedDataNodes.isEmpty() || this->m_SelectedImage == NULL)
return;
const mitk::SliceNavigationController::GeometryTimeEvent* timeEvent =
dynamic_cast<const mitk::SliceNavigationController::GeometryTimeEvent*>(&e);
assert(timeEvent != NULL);
unsigned int timestep = timeEvent->GetPos();
if (this->m_SelectedImage->GetTimeSteps() > 1)
{
for (unsigned int x = 0; x < this->m_Controls->m_StatisticsTable->columnCount(); x++)
{
for (unsigned int y = 0; y < this->m_Controls->m_StatisticsTable->rowCount(); y++)
{
QTableWidgetItem* item = this->m_Controls->m_StatisticsTable->item(y, x);
if (item == NULL)
break;
if (x == timestep)
{
item->setBackgroundColor(Qt::yellow);
}
else
{
if (y % 2 == 0)
item->setBackground(this->m_Controls->m_StatisticsTable->palette().base());
else
item->setBackground(this->m_Controls->m_StatisticsTable->palette().alternateBase());
}
}
}
this->m_Controls->m_StatisticsTable->viewport()->update();
}
if ((this->m_SelectedImage->GetTimeSteps() == 1 && timestep == 0) ||
this->m_SelectedImage->GetTimeSteps() > 1)
{
// display histogram for selected timestep
this->m_Controls->m_JSHistogram->ClearHistogram();
QmitkImageStatisticsCalculationThread::HistogramType::Pointer histogram =
this->m_CalculationThread->GetTimeStepHistogram(timestep);
if (histogram.IsNotNull())
{
this->m_Controls->m_JSHistogram->ComputeHistogram(histogram.GetPointer());
// this->m_Controls->m_JSHistogram->SignalGraphChanged();
// hacky way to make sure the protected SignalGraphChanged() is called
if (this->m_Controls->m_JSHistogram->GetUseLineGraph())
{
this->m_Controls->m_JSHistogram->OnBarRadioButtonSelected();
this->m_Controls->m_JSHistogram->OnLineRadioButtonSelected();
}
else
{
this->m_Controls->m_JSHistogram->OnLineRadioButtonSelected();
this->m_Controls->m_JSHistogram->OnBarRadioButtonSelected();
}
}
}
}
void QmitkImageStatisticsView::JumpToCoordinates(int row ,int col)
{
if(m_SelectedDataNodes.isEmpty())
{
MITK_WARN("QmitkImageStatisticsView") << "No data node selected for statistics calculation." ;
return;
}
mitk::Point3D world;
if (row==4 && !m_WorldMinList.empty())
world = m_WorldMinList[col];
else if (row==3 && !m_WorldMaxList.empty())
world = m_WorldMaxList[col];
else
return;
mitk::IRenderWindowPart* part = this->GetRenderWindowPart();
if (part)
{
part->GetQmitkRenderWindow("axial")->GetSliceNavigationController()->SelectSliceByPoint(world);
part->GetQmitkRenderWindow("sagittal")->GetSliceNavigationController()->SelectSliceByPoint(world);
part->GetQmitkRenderWindow("coronal")->GetSliceNavigationController()->SelectSliceByPoint(world);
mitk::SliceNavigationController::GeometryTimeEvent timeEvent(this->m_SelectedImage->GetTimeGeometry(), col);
part->GetQmitkRenderWindow("axial")->GetSliceNavigationController()->SetGeometryTime(timeEvent);
}
}
void QmitkImageStatisticsView::OnIgnoreZerosCheckboxClicked()
{
emit StatisticsUpdate();
}
void QmitkImageStatisticsView::OnClipboardHistogramButtonClicked()
{
if ( m_CurrentStatisticsValid )
{
const unsigned int t = this->GetRenderWindowPart()->GetTimeNavigationController()->GetTime()->GetPos();
typedef mitk::ImageStatisticsCalculator::HistogramType HistogramType;
const HistogramType *histogram = this->m_CalculationThread->GetTimeStepHistogram(t).GetPointer();
QString clipboard( "Measurement \t Frequency\n" );
for ( HistogramType::ConstIterator it = histogram->Begin();
it != histogram->End();
++it )
{
if( m_Controls->m_HistogramBinSizeSpinbox->value() == 1)
{
clipboard = clipboard.append( "%L1 \t %L2\n" )
.arg( it.GetMeasurementVector()[0], 0, 'f', 0 )
.arg( it.GetFrequency() );
}
else
{
clipboard = clipboard.append( "%L1 \t %L2\n" )
.arg( it.GetMeasurementVector()[0], 0, 'f', 2 )
.arg( it.GetFrequency() );
}
}
QApplication::clipboard()->setText(
clipboard, QClipboard::Clipboard );
}
else
{
QApplication::clipboard()->clear();
}
}
void QmitkImageStatisticsView::OnClipboardStatisticsButtonClicked()
{
QLocale tempLocal;
QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedStates));
if ( this->m_CurrentStatisticsValid )
{
const std::vector<mitk::ImageStatisticsCalculator::Statistics> &statistics =
this->m_CalculationThread->GetStatisticsData();
const unsigned int t = this->GetRenderWindowPart()->GetTimeNavigationController()->GetTime()->
GetPos();
// Copy statistics to clipboard ("%Ln" will use the default locale for
// number formatting)
QString clipboard( "Mean \t StdDev \t RMS \t Max \t Min \t N \t V (mm³)\n" );
clipboard = clipboard.append( "%L1 \t %L2 \t %L3 \t %L4 \t %L5 \t %L6 \t %L7" )
.arg( statistics[t].GetMean(), 0, 'f', 10 )
.arg( statistics[t].GetSigma(), 0, 'f', 10 )
.arg( statistics[t].GetRMS(), 0, 'f', 10 )
.arg( statistics[t].GetMax(), 0, 'f', 10 )
.arg( statistics[t].GetMin(), 0, 'f', 10 )
.arg( statistics[t].GetN() )
.arg( m_Controls->m_StatisticsTable->item( 0, 6 )->text().toDouble(), 0, 'f', 10 );
QApplication::clipboard()->setText(
clipboard, QClipboard::Clipboard );
}
else
{
QApplication::clipboard()->clear();
}
QLocale::setDefault(tempLocal);
}
void QmitkImageStatisticsView::OnSelectionChanged( berry::IWorkbenchPart::Pointer /*part*/,
const QList<mitk::DataNode::Pointer> &selectedNodes )
{
if (this->m_Visible)
{
this->SelectionChanged( selectedNodes );
}
else
{
this->m_DataNodeSelectionChanged = true;
}
}
void QmitkImageStatisticsView::SelectionChanged(const QList<mitk::DataNode::Pointer> &selectedNodes)
{
if( this->m_StatisticsUpdatePending )
{
this->m_DataNodeSelectionChanged = true;
return; // not ready for new data now!
}
if (selectedNodes.size() == this->m_SelectedDataNodes.size())
{
int i = 0;
for (; i < selectedNodes.size(); ++i)
{
if (selectedNodes.at(i) != this->m_SelectedDataNodes.at(i))
{
break;
}
}
// node selection did not change
if (i == selectedNodes.size()) return;
}
+ //reset the feature image and image mask field
+ m_Controls->m_SelectedFeatureImageLabel->setText("None");
+ m_Controls->m_SelectedMaskLabel->setText("None");
+
this->ReinitData();
if (selectedNodes.isEmpty())
{
m_Controls->m_JSHistogram->ClearHistogram();
m_Controls->m_lineRadioButton->setEnabled(true);
m_Controls->m_barRadioButton->setEnabled(true);
m_Controls->m_HistogramBinSizeSpinbox->setEnabled(true);
m_Controls->m_HistogramBinSizeCaptionLabel->setEnabled(true);
// m_Controls->m_HistogramBinSizeLabel->setEnabled(true);
m_Controls->m_InfoLabel->setText(QString(""));
// m_Controls->horizontalLayout_3->setEnabled(false);
m_Controls->groupBox->setEnabled(false);
m_Controls->groupBox_3->setEnabled(false);
}
else
{
// m_Controls->horizontalLayout_3->setEnabled(true);
m_Controls->groupBox->setEnabled(true);
m_Controls->groupBox_3->setEnabled(true);
}
if(selectedNodes.size() == 1 || selectedNodes.size() == 2)
{
bool isBinary = false;
selectedNodes.value(0)->GetBoolProperty("binary",isBinary);
if(isBinary)
{
m_Controls->m_JSHistogram->ClearHistogram();
m_Controls->m_lineRadioButton->setEnabled(true);
m_Controls->m_barRadioButton->setEnabled(true);
m_Controls->m_HistogramBinSizeSpinbox->setEnabled(true);
m_Controls->m_HistogramBinSizeCaptionLabel->setEnabled(true);
// m_Controls->m_HistogramBinSizeLabel->setEnabled(true);
m_Controls->m_InfoLabel->setText(QString(""));
}
for (int i= 0; i< selectedNodes.size(); ++i)
{
this->m_SelectedDataNodes.push_back(selectedNodes.at(i));
}
this->m_DataNodeSelectionChanged = false;
this->m_Controls->m_ErrorMessageLabel->setText( "" );
this->m_Controls->m_ErrorMessageLabel->hide();
emit StatisticsUpdate();
}
else
{
this->m_DataNodeSelectionChanged = false;
}
}
void QmitkImageStatisticsView::ReinitData()
{
while( this->m_CalculationThread->isRunning()) // wait until thread has finished
{
itksys::SystemTools::Delay(100);
}
if(this->m_SelectedImage != NULL)
{
this->m_SelectedImage->RemoveObserver( this->m_ImageObserverTag);
this->m_SelectedImage = NULL;
}
if(this->m_SelectedImageMask != NULL)
{
this->m_SelectedImageMask->RemoveObserver( this->m_ImageMaskObserverTag);
this->m_SelectedImageMask = NULL;
}
if(this->m_SelectedPlanarFigure != NULL)
{
this->m_SelectedPlanarFigure->RemoveObserver( this->m_PlanarFigureObserverTag);
this->m_SelectedPlanarFigure = NULL;
}
this->m_SelectedDataNodes.clear();
this->m_StatisticsUpdatePending = false;
m_Controls->m_ErrorMessageLabel->setText( "" );
m_Controls->m_ErrorMessageLabel->hide();
this->InvalidateStatisticsTableView();
m_Controls->m_JSHistogram->ClearHistogram();
m_Controls->m_StatisticsWidgetStack->setCurrentIndex( 0 );
}
void QmitkImageStatisticsView::OnThreadedStatisticsCalculationEnds()
{
std::stringstream message;
message << "";
m_Controls->m_ErrorMessageLabel->setText( message.str().c_str() );
m_Controls->m_ErrorMessageLabel->hide();
this->WriteStatisticsToGUI();
}
void QmitkImageStatisticsView::UpdateStatistics()
{
mitk::IRenderWindowPart* renderPart = this->GetRenderWindowPart();
if ( renderPart == NULL )
{
this->m_StatisticsUpdatePending = false;
return;
}
m_WorldMinList.clear();
m_WorldMaxList.clear();
// classify selected nodes
mitk::NodePredicateDataType::Pointer imagePredicate = mitk::NodePredicateDataType::New("Image");
std::string maskName = std::string();
std::string maskType = std::string();
std::string featureImageName = std::string();
unsigned int maskDimension = 0;
// reset data from last run
ITKCommandType::Pointer changeListener = ITKCommandType::New();
changeListener->SetCallbackFunction( this, &QmitkImageStatisticsView::SelectedDataModified );
mitk::DataNode::Pointer planarFigureNode;
for( int i= 0 ; i < this->m_SelectedDataNodes.size(); ++i)
{
mitk::PlanarFigure::Pointer planarFig = dynamic_cast<mitk::PlanarFigure*>(this->m_SelectedDataNodes.at(i)->GetData());
if( imagePredicate->CheckNode(this->m_SelectedDataNodes.at(i)) )
{
bool isMask = false;
this->m_SelectedDataNodes.at(i)->GetPropertyValue("binary", isMask);
if( this->m_SelectedImageMask == NULL && isMask)
{
this->m_SelectedImageMask = dynamic_cast<mitk::Image*>(this->m_SelectedDataNodes.at(i)->GetData());
this->m_ImageMaskObserverTag = this->m_SelectedImageMask->AddObserver(itk::ModifiedEvent(), changeListener);
maskName = this->m_SelectedDataNodes.at(i)->GetName();
maskType = m_SelectedImageMask->GetNameOfClass();
maskDimension = 3;
}
else if( !isMask )
{
if(this->m_SelectedImage == NULL)
{
this->m_SelectedImage = static_cast<mitk::Image*>(this->m_SelectedDataNodes.at(i)->GetData());
this->m_ImageObserverTag = this->m_SelectedImage->AddObserver(itk::ModifiedEvent(), changeListener);
}
featureImageName = this->m_SelectedDataNodes.at(i)->GetName();
}
}
else if (planarFig.IsNotNull())
{
if(this->m_SelectedPlanarFigure == NULL)
{
this->m_SelectedPlanarFigure = planarFig;
this->m_PlanarFigureObserverTag =
this->m_SelectedPlanarFigure->AddObserver(mitk::EndInteractionPlanarFigureEvent(), changeListener);
maskName = this->m_SelectedDataNodes.at(i)->GetName();
maskType = this->m_SelectedPlanarFigure->GetNameOfClass();
maskDimension = 2;
planarFigureNode = m_SelectedDataNodes.at(i);
}
}
else
{
std::stringstream message;
message << "<font color='red'>" << "Invalid data node type!" << "</font>";
m_Controls->m_ErrorMessageLabel->setText( message.str().c_str() );
m_Controls->m_ErrorMessageLabel->show();
}
}
if(maskName == "")
{
maskName = "None";
maskType = "";
maskDimension = 0;
}
if(featureImageName == "")
{
featureImageName = "None";
}
if (m_SelectedPlanarFigure != NULL && m_SelectedImage == NULL)
{
mitk::DataStorage::SetOfObjects::ConstPointer parentSet = this->GetDataStorage()->GetSources(planarFigureNode);
for (int i=0; i<parentSet->Size(); i++)
{
mitk::DataNode::Pointer node = parentSet->ElementAt(i);
if( imagePredicate->CheckNode(node) )
{
bool isMask = false;
node->GetPropertyValue("binary", isMask);
if( !isMask )
{
if(this->m_SelectedImage == NULL)
{
this->m_SelectedImage = static_cast<mitk::Image*>(node->GetData());
this->m_ImageObserverTag = this->m_SelectedImage->AddObserver(itk::ModifiedEvent(), changeListener);
}
}
}
}
}
unsigned int timeStep = renderPart->GetTimeNavigationController()->GetTime()->GetPos();
if ( m_SelectedImage != NULL && m_SelectedImage->IsInitialized())
{
// Check if a the selected image is a multi-channel image. If yes, statistics
// cannot be calculated currently.
if ( m_SelectedImage->GetPixelType().GetNumberOfComponents() > 1 )
{
std::stringstream message;
message << "<font color='red'>Multi-component images not supported.</font>";
m_Controls->m_ErrorMessageLabel->setText( message.str().c_str() );
m_Controls->m_ErrorMessageLabel->show();
this->InvalidateStatisticsTableView();
m_Controls->m_StatisticsWidgetStack->setCurrentIndex( 0 );
m_Controls->m_JSHistogram->ClearHistogram();
m_CurrentStatisticsValid = false;
this->m_StatisticsUpdatePending = false;
m_Controls->m_lineRadioButton->setEnabled(true);
m_Controls->m_barRadioButton->setEnabled(true);
m_Controls->m_HistogramBinSizeSpinbox->setEnabled(true);
m_Controls->m_HistogramBinSizeCaptionLabel->setEnabled(true);
// m_Controls->m_HistogramBinSizeLabel->setEnabled(true);
m_Controls->m_InfoLabel->setText(QString(""));
return;
}
std::stringstream maskLabel;
maskLabel << maskName;
if ( maskDimension > 0 )
{
maskLabel << " [" << maskDimension << "D " << maskType << "]";
}
m_Controls->m_SelectedMaskLabel->setText( maskLabel.str().c_str() );
m_Controls->m_SelectedFeatureImageLabel->setText(featureImageName.c_str());
// check time step validity
if(m_SelectedImage->GetDimension() <= 3 && timeStep > m_SelectedImage->GetDimension(3)-1)
{
timeStep = m_SelectedImage->GetDimension(3)-1;
}
// Add the used mask time step to the mask label so the user knows which mask time step was used
// if the image time step is bigger than the total number of mask time steps (see
// ImageStatisticsCalculator::ExtractImageAndMask)
if (m_SelectedImageMask != NULL)
{
unsigned int maskTimeStep = timeStep;
if (maskTimeStep >= m_SelectedImageMask->GetTimeSteps())
{
maskTimeStep = m_SelectedImageMask->GetTimeSteps() - 1;
}
m_Controls->m_SelectedMaskLabel->setText(m_Controls->m_SelectedMaskLabel->text() +
QString(" (t=") +
QString::number(maskTimeStep) +
QString(")"));
}
//// initialize thread and trigger it
this->m_CalculationThread->SetIgnoreZeroValueVoxel( m_Controls->m_IgnoreZerosCheckbox->isChecked() );
this->m_CalculationThread->Initialize( m_SelectedImage, m_SelectedImageMask, m_SelectedPlanarFigure );
this->m_CalculationThread->SetTimeStep( timeStep );
this->m_CalculationThread->SetHistogramBinSize(m_Controls->m_HistogramBinSizeSpinbox->value());
std::stringstream message;
message << "<font color='red'>Calculating statistics...</font>";
m_Controls->m_ErrorMessageLabel->setText( message.str().c_str() );
m_Controls->m_ErrorMessageLabel->show();
try
{
// Compute statistics
this->m_CalculationThread->SetUseDefaultBinSize(m_Controls->m_UseDefaultBinSizeBox->isChecked());
this->m_CalculationThread->start();
}
catch ( const mitk::Exception& e)
{
std::stringstream message;
message << "<font color='red'>" << e.GetDescription() << "</font>";
m_Controls->m_ErrorMessageLabel->setText( message.str().c_str() );
m_Controls->m_ErrorMessageLabel->show();
this->m_StatisticsUpdatePending = false;
}
catch ( const std::runtime_error &e )
{
// In case of exception, print error message on GUI
std::stringstream message;
message << "<font color='red'>" << e.what() << "</font>";
m_Controls->m_ErrorMessageLabel->setText( message.str().c_str() );
m_Controls->m_ErrorMessageLabel->show();
this->m_StatisticsUpdatePending = false;
}
catch ( const std::exception &e )
{
MITK_ERROR << "Caught exception: " << e.what();
// In case of exception, print error message on GUI
std::stringstream message;
message << "<font color='red'>Error! Unequal Dimensions of Image and Segmentation. No recompute possible </font>";
m_Controls->m_ErrorMessageLabel->setText( message.str().c_str() );
m_Controls->m_ErrorMessageLabel->show();
this->m_StatisticsUpdatePending = false;
}
}
else
{
this->m_StatisticsUpdatePending = false;
}
}
void QmitkImageStatisticsView::SelectedDataModified()
{
if( !m_StatisticsUpdatePending )
{
emit StatisticsUpdate();
}
}
void QmitkImageStatisticsView::NodeRemoved(const mitk::DataNode *node)
{
while(this->m_CalculationThread->isRunning()) // wait until thread has finished
{
itksys::SystemTools::Delay(100);
}
if (node->GetData() == m_SelectedImage)
{
m_SelectedImage = NULL;
}
}
void QmitkImageStatisticsView::RequestStatisticsUpdate()
{
if ( !m_StatisticsUpdatePending )
{
if(this->m_DataNodeSelectionChanged)
{
this->SelectionChanged(this->GetCurrentSelection());
}
else
{
this->m_StatisticsUpdatePending = true;
this->UpdateStatistics();
}
}
if (this->GetRenderWindowPart())
this->GetRenderWindowPart()->RequestUpdate();
}
void QmitkImageStatisticsView::OnHistogramBinSizeBoxValueChanged()
{
this->UpdateStatistics();
}
void QmitkImageStatisticsView::WriteStatisticsToGUI()
{
m_Controls->m_lineRadioButton->setEnabled(true);
m_Controls->m_barRadioButton->setEnabled(true);
m_Controls->m_HistogramBinSizeSpinbox->setEnabled(true);
m_Controls->m_HistogramBinSizeCaptionLabel->setEnabled(true);
// m_Controls->m_HistogramBinSizeLabel->setEnabled(true);
m_Controls->m_InfoLabel->setText(QString(""));
if(m_DataNodeSelectionChanged)
{
this->m_StatisticsUpdatePending = false;
this->RequestStatisticsUpdate();
return; // stop visualization of results and calculate statistics of new selection
}
if ( this->m_CalculationThread->GetStatisticsUpdateSuccessFlag())
{
if ( this->m_CalculationThread->GetStatisticsChangedFlag() )
{
// Do not show any error messages
m_Controls->m_ErrorMessageLabel->hide();
m_CurrentStatisticsValid = true;
}
if (m_Controls->m_barRadioButton->isChecked())
{
m_Controls->m_JSHistogram->OnBarRadioButtonSelected();
}
m_Controls->m_StatisticsWidgetStack->setCurrentIndex( 0 );
m_Controls->m_HistogramBinSizeSpinbox->setValue( this->m_CalculationThread->GetHistogramBinSize() );
//m_Controls->m_JSHistogram->ComputeHistogram( this->m_CalculationThread->GetTimeStepHistogram(this->m_CalculationThread->GetTimeStep()).GetPointer() );
this->FillStatisticsTableView( this->m_CalculationThread->GetStatisticsData(), this->m_CalculationThread->GetStatisticsImage());
}
else
{
m_Controls->m_SelectedMaskLabel->setText( "None" );
m_Controls->m_ErrorMessageLabel->setText( m_CalculationThread->GetLastErrorMessage().c_str() );
m_Controls->m_ErrorMessageLabel->show();
// Clear statistics and histogram
this->InvalidateStatisticsTableView();
m_Controls->m_StatisticsWidgetStack->setCurrentIndex( 0 );
//m_Controls->m_JSHistogram->clearHistogram();
m_CurrentStatisticsValid = false;
// If a (non-closed) PlanarFigure is selected, display a line profile widget
if ( m_SelectedPlanarFigure != NULL )
{
// Check if the (closed) planar figure is out of bounds and so no image mask could be calculated--> Intensity Profile can not be calculated
bool outOfBounds = false;
if ( m_SelectedPlanarFigure->IsClosed() && m_SelectedImageMask == NULL)
{
outOfBounds = true;
std::stringstream message;
message << "<font color='red'>Planar figure is on a rotated image plane or outside the image bounds.</font>";
m_Controls->m_InfoLabel->setText(message.str().c_str());
}
// check whether PlanarFigure is initialized
const mitk::PlaneGeometry *planarFigurePlaneGeometry = m_SelectedPlanarFigure->GetPlaneGeometry();
if ( planarFigurePlaneGeometry == NULL || outOfBounds)
{
// Clear statistics, histogram, and GUI
this->InvalidateStatisticsTableView();
m_Controls->m_StatisticsWidgetStack->setCurrentIndex( 0 );
m_Controls->m_JSHistogram->ClearHistogram();
m_CurrentStatisticsValid = false;
m_Controls->m_ErrorMessageLabel->hide();
m_Controls->m_SelectedMaskLabel->setText( "None" );
this->m_StatisticsUpdatePending = false;
m_Controls->m_lineRadioButton->setEnabled(true);
m_Controls->m_barRadioButton->setEnabled(true);
m_Controls->m_HistogramBinSizeSpinbox->setEnabled(true);
m_Controls->m_HistogramBinSizeCaptionLabel->setEnabled(true);
// m_Controls->m_HistogramBinSizeLabel->setEnabled(true);
if (!outOfBounds)
m_Controls->m_InfoLabel->setText(QString(""));
return;
}
unsigned int timeStep = this->GetRenderWindowPart()->GetTimeNavigationController()->GetTime()->GetPos();
m_Controls->m_JSHistogram->SetImage(this->m_CalculationThread->GetStatisticsImage());
m_Controls->m_JSHistogram->SetPlanarFigure(m_SelectedPlanarFigure);
m_Controls->m_JSHistogram->ComputeIntensityProfile(timeStep);
m_Controls->m_lineRadioButton->setEnabled(false);
m_Controls->m_barRadioButton->setEnabled(false);
m_Controls->m_HistogramBinSizeSpinbox->setEnabled(false);
m_Controls->m_HistogramBinSizeCaptionLabel->setEnabled(false);
// m_Controls->m_HistogramBinSizeLabel->setEnabled(false);
std::stringstream message;
message << "<font color='red'>Only linegraph available for an intesityprofile!</font>";
m_Controls->m_InfoLabel->setText(message.str().c_str());
}
}
this->m_StatisticsUpdatePending = false;
}
void QmitkImageStatisticsView::FillStatisticsTableView(
const std::vector<mitk::ImageStatisticsCalculator::Statistics> &s,
const mitk::Image *image )
{
this->m_Controls->m_StatisticsTable->setColumnCount(image->GetTimeSteps());
this->m_Controls->m_StatisticsTable->horizontalHeader()->setVisible(image->GetTimeSteps() > 1);
int decimals = 2;
mitk::PixelType doublePix = mitk::MakeScalarPixelType< double >();
mitk::PixelType floatPix = mitk::MakeScalarPixelType< float >();
if (image->GetPixelType()==doublePix || image->GetPixelType()==floatPix)
{
decimals = 5;
}
for (unsigned int t = 0; t < image->GetTimeSteps(); t++)
{
this->m_Controls->m_StatisticsTable->setHorizontalHeaderItem(t,
new QTableWidgetItem(QString::number(t)));
if (s[t].GetMaxIndex().size()==3)
{
mitk::Point3D index, max, min;
index[0] = s[t].GetMaxIndex()[0];
index[1] = s[t].GetMaxIndex()[1];
index[2] = s[t].GetMaxIndex()[2];
m_SelectedImage->GetGeometry()->IndexToWorld(index, max);
this->m_WorldMaxList.push_back(max);
index[0] = s[t].GetMinIndex()[0];
index[1] = s[t].GetMinIndex()[1];
index[2] = s[t].GetMinIndex()[2];
m_SelectedImage->GetGeometry()->IndexToWorld(index, min);
this->m_WorldMinList.push_back(min);
}
this->m_Controls->m_StatisticsTable->setItem( 0, t, new QTableWidgetItem(
QString("%1").arg(s[t].GetMean(), 0, 'f', decimals) ) );
this->m_Controls->m_StatisticsTable->setItem( 1, t, new QTableWidgetItem(
QString("%1").arg(s[t].GetSigma(), 0, 'f', decimals) ) );
this->m_Controls->m_StatisticsTable->setItem( 2, t, new QTableWidgetItem(
QString("%1").arg(s[t].GetRMS(), 0, 'f', decimals) ) );
QString max; max.append(QString("%1").arg(s[t].GetMax(), 0, 'f', decimals));
max += " (";
for (int i=0; i<s[t].GetMaxIndex().size(); i++)
{
max += QString::number(s[t].GetMaxIndex()[i]);
if (i<s[t].GetMaxIndex().size()-1)
max += ",";
}
max += ")";
this->m_Controls->m_StatisticsTable->setItem( 3, t, new QTableWidgetItem( max ) );
QString min; min.append(QString("%1").arg(s[t].GetMin(), 0, 'f', decimals));
min += " (";
for (int i=0; i<s[t].GetMinIndex().size(); i++)
{
min += QString::number(s[t].GetMinIndex()[i]);
if (i<s[t].GetMinIndex().size()-1)
min += ",";
}
min += ")";
this->m_Controls->m_StatisticsTable->setItem( 4, t, new QTableWidgetItem( min ) );
this->m_Controls->m_StatisticsTable->setItem( 5, t, new QTableWidgetItem(
QString("%1").arg(s[t].GetN()) ) );
const mitk::BaseGeometry *geometry = image->GetGeometry();
if ( geometry != NULL )
{
const mitk::Vector3D &spacing = image->GetGeometry()->GetSpacing();
double volume = spacing[0] * spacing[1] * spacing[2] * (double) s[t].GetN();
this->m_Controls->m_StatisticsTable->setItem( 6, t, new QTableWidgetItem(
QString("%1").arg(volume, 0, 'f', decimals) ) );
}
else
{
this->m_Controls->m_StatisticsTable->setItem( 6, t, new QTableWidgetItem(
"NA" ) );
}
}
this->m_Controls->m_StatisticsTable->resizeColumnsToContents();
int height = STAT_TABLE_BASE_HEIGHT;
if (this->m_Controls->m_StatisticsTable->horizontalHeader()->isVisible())
height += this->m_Controls->m_StatisticsTable->horizontalHeader()->height();
if (this->m_Controls->m_StatisticsTable->horizontalScrollBar()->isVisible())
height += this->m_Controls->m_StatisticsTable->horizontalScrollBar()->height();
this->m_Controls->m_StatisticsTable->setMinimumHeight(height);
// make sure the current timestep's column is highlighted (and the correct histogram is displayed)
unsigned int t = this->GetRenderWindowPart()->GetTimeNavigationController()->GetTime()->
GetPos();
mitk::SliceNavigationController::GeometryTimeEvent timeEvent(this->m_SelectedImage->GetTimeGeometry(),
t);
this->OnTimeChanged(timeEvent);
+ t = std::min(image->GetTimeSteps() - 1, t);
+
QString hotspotMean; hotspotMean.append(QString("%1").arg(s[t].GetHotspotStatistics().GetMean(), 0, 'f', decimals));
hotspotMean += " (";
for (int i=0; i<s[t].GetHotspotIndex().size(); i++)
{
hotspotMean += QString::number(s[t].GetHotspotIndex()[i]);
if (i<s[t].GetHotspotIndex().size()-1)
hotspotMean += ",";
}
hotspotMean += ")";
this->m_Controls->m_StatisticsTable->setItem( 7, t, new QTableWidgetItem( hotspotMean ) );
QString hotspotMax; hotspotMax.append(QString("%1").arg(s[t].GetHotspotStatistics().GetMax(), 0, 'f', decimals));
hotspotMax += " (";
for (int i=0; i<s[t].GetHotspotStatistics().GetMaxIndex().size(); i++)
{
hotspotMax += QString::number(s[t].GetHotspotStatistics().GetMaxIndex()[i]);
if (i<s[t].GetHotspotStatistics().GetMaxIndex().size()-1)
hotspotMax += ",";
}
hotspotMax += ")";
this->m_Controls->m_StatisticsTable->setItem( 8, t, new QTableWidgetItem( hotspotMax ) );
QString hotspotMin; hotspotMin.append(QString("%1").arg(s[t].GetHotspotStatistics().GetMin(), 0, 'f', decimals));
hotspotMin += " (";
for (int i=0; i<s[t].GetHotspotStatistics().GetMinIndex().size(); i++)
{
hotspotMin += QString::number(s[t].GetHotspotStatistics().GetMinIndex()[i]);
if (i<s[t].GetHotspotStatistics().GetMinIndex().size()-1)
hotspotMin += ",";
}
hotspotMin += ")";
this->m_Controls->m_StatisticsTable->setItem( 9, t, new QTableWidgetItem( hotspotMin ) );
}
void QmitkImageStatisticsView::InvalidateStatisticsTableView()
{
this->m_Controls->m_StatisticsTable->horizontalHeader()->setVisible(false);
this->m_Controls->m_StatisticsTable->setColumnCount(1);
for ( unsigned int i = 0; i < this->m_Controls->m_StatisticsTable->rowCount(); ++i )
{
{
this->m_Controls->m_StatisticsTable->setItem( i, 0, new QTableWidgetItem( "NA" ) );
}
}
this->m_Controls->m_StatisticsTable->setMinimumHeight(STAT_TABLE_BASE_HEIGHT);
}
void QmitkImageStatisticsView::Activated()
{
}
void QmitkImageStatisticsView::Deactivated()
{
}
void QmitkImageStatisticsView::Visible()
{
m_Visible = true;
mitk::IRenderWindowPart* renderWindow = GetRenderWindowPart();
if (renderWindow)
{
itk::ReceptorMemberCommand<QmitkImageStatisticsView>::Pointer cmdTimeEvent =
itk::ReceptorMemberCommand<QmitkImageStatisticsView>::New();
cmdTimeEvent->SetCallbackFunction(this, &QmitkImageStatisticsView::OnTimeChanged);
// It is sufficient to add the observer to the axial render window since the GeometryTimeEvent
// is always triggered by all views.
m_TimeObserverTag = renderWindow->GetQmitkRenderWindow("axial")->
GetSliceNavigationController()->
AddObserver(mitk::SliceNavigationController::GeometryTimeEvent(NULL, 0), cmdTimeEvent);
}
if (m_DataNodeSelectionChanged)
{
if (this->IsCurrentSelectionValid())
{
this->SelectionChanged(this->GetCurrentSelection());
}
else
{
this->SelectionChanged(this->GetDataManagerSelection());
}
m_DataNodeSelectionChanged = false;
}
}
void QmitkImageStatisticsView::Hidden()
{
m_Visible = false;
// The slice navigation controller observer is removed here instead of in the destructor.
// If it was called in the destructor, the application would freeze because the view's
// destructor gets called after the render windows have been destructed.
if ( m_TimeObserverTag != NULL )
{
mitk::IRenderWindowPart* renderWindow = GetRenderWindowPart();
if (renderWindow)
{
renderWindow->GetQmitkRenderWindow("axial")->GetSliceNavigationController()->
RemoveObserver( m_TimeObserverTag );
}
m_TimeObserverTag = NULL;
}
}
void QmitkImageStatisticsView::SetFocus()
{
}
diff --git a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkMeasurementView.cpp b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkMeasurementView.cpp
index 060183b87f..e7466fae1f 100644
--- a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkMeasurementView.cpp
+++ b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkMeasurementView.cpp
@@ -1,958 +1,967 @@
/*===================================================================
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.
===================================================================*/
#define MEASUREMENT_DEBUG MITK_DEBUG("QmitkMeasurementView") << __LINE__ << ": "
#include "QmitkMeasurementView.h"
-#include <QtGui>
+#include <QAction>
+#include <QApplication>
+#include <QClipboard>
+#include <QGridLayout>
+#include <QToolBar>
+#include <QTextBrowser>
#include <mitkIPropertyFilters.h>
#include <mitkPropertyFilter.h>
#include <mitkVtkLayerController.h>
#include <mitkWeakPointer.h>
#include <mitkPlanarCircle.h>
#include <mitkPlanarEllipse.h>
#include <mitkPlanarPolygon.h>
#include <mitkPlanarAngle.h>
#include <mitkPlanarRectangle.h>
#include <mitkPlanarLine.h>
#include <mitkPlanarCross.h>
#include <mitkPlanarFourPointAngle.h>
#include <mitkPlanarDoubleEllipse.h>
#include <mitkPlanarBezierCurve.h>
#include <mitkPlanarSubdivisionPolygon.h>
#include <mitkPlanarFigureInteractor.h>
#include <mitkPlaneGeometry.h>
#include <mitkGlobalInteraction.h>
#include <mitkILinkedRenderWindowPart.h>
#include <mitkNodePredicateDataType.h>
#include <mitkNodePredicateProperty.h>
#include <mitkNodePredicateAnd.h>
#include <mitkNodePredicateNot.h>
#include <QmitkRenderWindow.h>
#include <mitkImage.h>
#include "mitkPluginActivator.h"
#include "usModuleRegistry.h"
template <class T>
static T* GetService()
{
ctkPluginContext* context = mitk::PluginActivator::GetContext();
ctkServiceReference serviceRef = context->getServiceReference<T>();
return serviceRef
? context->getService<T>(serviceRef)
: NULL;
}
struct QmitkPlanarFigureData
{
QmitkPlanarFigureData()
: m_Figure(0), m_EndPlacementObserverTag(0), m_SelectObserverTag(0), m_StartInteractionObserverTag(0), m_EndInteractionObserverTag(0)
{
}
mitk::PlanarFigure* m_Figure;
unsigned int m_EndPlacementObserverTag;
unsigned int m_SelectObserverTag;
unsigned int m_StartInteractionObserverTag;
unsigned int m_EndInteractionObserverTag;
};
struct QmitkMeasurementViewData
{
QmitkMeasurementViewData()
: m_LineCounter(0), m_PathCounter(0), m_AngleCounter(0),
m_FourPointAngleCounter(0), m_CircleCounter(0), m_EllipseCounter(0),
m_DoubleEllipseCounter(0), m_RectangleCounter(0), m_PolygonCounter(0),
m_BezierCurveCounter(0), m_SubdivisionPolygonCounter(0), m_UnintializedPlanarFigure(false)
{
}
// internal vars
unsigned int m_LineCounter;
unsigned int m_PathCounter;
unsigned int m_AngleCounter;
unsigned int m_FourPointAngleCounter;
unsigned int m_CircleCounter;
unsigned int m_EllipseCounter;
unsigned int m_DoubleEllipseCounter;
unsigned int m_RectangleCounter;
unsigned int m_PolygonCounter;
unsigned int m_BezierCurveCounter;
unsigned int m_SubdivisionPolygonCounter;
QList<mitk::DataNode::Pointer> m_CurrentSelection;
std::map<mitk::DataNode*, QmitkPlanarFigureData> m_DataNodeToPlanarFigureData;
mitk::WeakPointer<mitk::DataNode> m_SelectedImageNode;
bool m_UnintializedPlanarFigure;
// WIDGETS
QWidget* m_Parent;
QLabel* m_SelectedImageLabel;
QAction* m_DrawLine;
QAction* m_DrawPath;
QAction* m_DrawAngle;
QAction* m_DrawFourPointAngle;
QAction* m_DrawRectangle;
QAction* m_DrawPolygon;
QAction* m_DrawCircle;
QAction* m_DrawEllipse;
QAction* m_DrawDoubleEllipse;
QAction* m_DrawBezierCurve;
QAction* m_DrawSubdivisionPolygon;
QToolBar* m_DrawActionsToolBar;
QActionGroup* m_DrawActionsGroup;
QTextBrowser* m_SelectedPlanarFiguresText;
QPushButton* m_CopyToClipboard;
QGridLayout* m_Layout;
};
const std::string QmitkMeasurementView::VIEW_ID = "org.mitk.views.measurement";
QmitkMeasurementView::QmitkMeasurementView()
: d( new QmitkMeasurementViewData )
{
}
QmitkMeasurementView::~QmitkMeasurementView()
{
this->RemoveAllInteractors();
delete d;
}
void QmitkMeasurementView::CreateQtPartControl(QWidget* parent)
{
d->m_Parent = parent;
// image label
QLabel* selectedImageLabel = new QLabel("Reference Image: ");
d->m_SelectedImageLabel = new QLabel;
d->m_SelectedImageLabel->setStyleSheet("font-weight: bold;");
d->m_DrawActionsToolBar = new QToolBar;
d->m_DrawActionsGroup = new QActionGroup(this);
d->m_DrawActionsGroup->setExclusive(true);
//# add actions
MEASUREMENT_DEBUG << "Draw Line";
QAction* currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/line.png"), "Draw Line");
currentAction->setCheckable(true);
d->m_DrawLine = currentAction;
d->m_DrawActionsToolBar->addAction(currentAction);
d->m_DrawActionsGroup->addAction(currentAction);
MEASUREMENT_DEBUG << "Draw Path";
currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/path.png"), "Draw Path");
currentAction->setCheckable(true);
d->m_DrawPath = currentAction;
d->m_DrawActionsToolBar->addAction(currentAction);
d->m_DrawActionsGroup->addAction(currentAction);
MEASUREMENT_DEBUG << "Draw Angle";
currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/angle.png"), "Draw Angle");
currentAction->setCheckable(true);
d->m_DrawAngle = currentAction;
d->m_DrawActionsToolBar->addAction(currentAction);
d->m_DrawActionsGroup->addAction(currentAction);
MEASUREMENT_DEBUG << "Draw Four Point Angle";
currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/four-point-angle.png"), "Draw Four Point Angle");
currentAction->setCheckable(true);
d->m_DrawFourPointAngle = currentAction;
d->m_DrawActionsToolBar->addAction(currentAction);
d->m_DrawActionsGroup->addAction(currentAction);
MEASUREMENT_DEBUG << "Draw Circle";
currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/circle.png"), "Draw Circle");
currentAction->setCheckable(true);
d->m_DrawCircle = currentAction;
d->m_DrawActionsToolBar->addAction(currentAction);
d->m_DrawActionsGroup->addAction(currentAction);
MEASUREMENT_DEBUG << "Draw Ellipse";
currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/ellipse.png"), "Draw Ellipse");
currentAction->setCheckable(true);
d->m_DrawEllipse = currentAction;
d->m_DrawActionsToolBar->addAction(currentAction);
d->m_DrawActionsGroup->addAction(currentAction);
MEASUREMENT_DEBUG << "Draw Double Ellipse";
currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/doubleellipse.png"), "Draw Double Ellipse");
currentAction->setCheckable(true);
d->m_DrawDoubleEllipse = currentAction;
d->m_DrawActionsToolBar->addAction(currentAction);
d->m_DrawActionsGroup->addAction(currentAction);
MEASUREMENT_DEBUG << "Draw Rectangle";
currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/rectangle.png"), "Draw Rectangle");
currentAction->setCheckable(true);
d->m_DrawRectangle = currentAction;
d->m_DrawActionsToolBar->addAction(currentAction);
d->m_DrawActionsGroup->addAction(currentAction);
MEASUREMENT_DEBUG << "Draw Polygon";
currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/polygon.png"), "Draw Polygon");
currentAction->setCheckable(true);
d->m_DrawPolygon = currentAction;
d->m_DrawActionsToolBar->addAction(currentAction);
d->m_DrawActionsGroup->addAction(currentAction);
MEASUREMENT_DEBUG << "Draw Bezier Curve";
currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/beziercurve.png"), "Draw Bezier Curve");
currentAction->setCheckable(true);
d->m_DrawBezierCurve = currentAction;
d->m_DrawActionsToolBar->addAction(currentAction);
d->m_DrawActionsGroup->addAction(currentAction);
MEASUREMENT_DEBUG << "Draw Subdivision Polygon";
currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/subdivisionpolygon.png"), "Draw Subdivision Polygon");
currentAction->setCheckable(true);
d->m_DrawSubdivisionPolygon = currentAction;
d->m_DrawActionsToolBar->addAction(currentAction);
d->m_DrawActionsGroup->addAction(currentAction);
// planar figure details text
d->m_SelectedPlanarFiguresText = new QTextBrowser;
// copy to clipboard button
d->m_CopyToClipboard = new QPushButton("Copy to Clipboard");
d->m_Layout = new QGridLayout;
d->m_Layout->addWidget(selectedImageLabel, 0, 0, 1, 1);
d->m_Layout->addWidget(d->m_SelectedImageLabel, 0, 1, 1, 1);
d->m_Layout->addWidget(d->m_DrawActionsToolBar, 1, 0, 1, 2);
d->m_Layout->addWidget(d->m_SelectedPlanarFiguresText, 2, 0, 1, 2);
d->m_Layout->addWidget(d->m_CopyToClipboard, 3, 0, 1, 2);
d->m_Parent->setLayout(d->m_Layout);
// create connections
this->CreateConnections();
// readd interactors and observers
this->AddAllInteractors();
}
void QmitkMeasurementView::CreateConnections()
{
QObject::connect( d->m_DrawLine, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawLineTriggered(bool) ) );
QObject::connect( d->m_DrawPath, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawPathTriggered(bool) ) );
QObject::connect( d->m_DrawAngle, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawAngleTriggered(bool) ) );
QObject::connect( d->m_DrawFourPointAngle, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawFourPointAngleTriggered(bool) ) );
QObject::connect( d->m_DrawCircle, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawCircleTriggered(bool) ) );
QObject::connect( d->m_DrawEllipse, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawEllipseTriggered(bool) ) );
QObject::connect( d->m_DrawDoubleEllipse, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawDoubleEllipseTriggered(bool) ) );
QObject::connect( d->m_DrawRectangle, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawRectangleTriggered(bool) ) );
QObject::connect( d->m_DrawPolygon, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawPolygonTriggered(bool) ) );
QObject::connect( d->m_DrawBezierCurve, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawBezierCurveTriggered(bool) ) );
QObject::connect( d->m_DrawSubdivisionPolygon, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawSubdivisionPolygonTriggered(bool) ) );
QObject::connect( d->m_CopyToClipboard, SIGNAL( clicked(bool) ), this, SLOT( CopyToClipboard(bool) ) );
}
void QmitkMeasurementView::NodeAdded( const mitk::DataNode* node )
{
// add observer for selection in renderwindow
mitk::PlanarFigure* figure = dynamic_cast<mitk::PlanarFigure*>(node->GetData());
bool isPositionMarker (false);
node->GetBoolProperty("isContourMarker", isPositionMarker);
if( figure && !isPositionMarker )
{
MEASUREMENT_DEBUG << "figure added. will add interactor if needed.";
mitk::PlanarFigureInteractor::Pointer figureInteractor
= dynamic_cast<mitk::PlanarFigureInteractor*>(node->GetDataInteractor().GetPointer() );
mitk::DataNode* nonConstNode = const_cast<mitk::DataNode*>( node );
if(figureInteractor.IsNull())
{
figureInteractor = mitk::PlanarFigureInteractor::New();
us::Module* planarFigureModule = us::ModuleRegistry::GetModule( "MitkPlanarFigure" );
figureInteractor->LoadStateMachine("PlanarFigureInteraction.xml", planarFigureModule );
figureInteractor->SetEventConfig( "PlanarFigureConfig.xml", planarFigureModule );
figureInteractor->SetDataNode( nonConstNode );
// nonConstNode->SetBoolProperty( "planarfigure.isextendable", true );
}
else
{
// just to be sure that the interactor is not added twice
// mitk::GlobalInteraction::GetInstance()->RemoveInteractor(figureInteractor);
}
MEASUREMENT_DEBUG << "adding interactor to globalinteraction";
// mitk::GlobalInteraction::GetInstance()->AddInteractor(figureInteractor);
MEASUREMENT_DEBUG << "will now add observers for planarfigure";
QmitkPlanarFigureData data;
data.m_Figure = figure;
// add observer for event when figure has been placed
typedef itk::SimpleMemberCommand< QmitkMeasurementView > SimpleCommandType;
SimpleCommandType::Pointer initializationCommand = SimpleCommandType::New();
initializationCommand->SetCallbackFunction( this, &QmitkMeasurementView::PlanarFigureInitialized );
data.m_EndPlacementObserverTag = figure->AddObserver( mitk::EndPlacementPlanarFigureEvent(), initializationCommand );
// add observer for event when figure is picked (selected)
typedef itk::MemberCommand< QmitkMeasurementView > MemberCommandType;
MemberCommandType::Pointer selectCommand = MemberCommandType::New();
selectCommand->SetCallbackFunction( this, &QmitkMeasurementView::PlanarFigureSelected );
data.m_SelectObserverTag = figure->AddObserver( mitk::SelectPlanarFigureEvent(), selectCommand );
// add observer for event when interaction with figure starts
SimpleCommandType::Pointer startInteractionCommand = SimpleCommandType::New();
startInteractionCommand->SetCallbackFunction( this, &QmitkMeasurementView::DisableCrosshairNavigation);
data.m_StartInteractionObserverTag = figure->AddObserver( mitk::StartInteractionPlanarFigureEvent(), startInteractionCommand );
// add observer for event when interaction with figure starts
SimpleCommandType::Pointer endInteractionCommand = SimpleCommandType::New();
endInteractionCommand->SetCallbackFunction( this, &QmitkMeasurementView::EnableCrosshairNavigation);
data.m_EndInteractionObserverTag = figure->AddObserver( mitk::EndInteractionPlanarFigureEvent(), endInteractionCommand );
// adding to the map of tracked planarfigures
d->m_DataNodeToPlanarFigureData[nonConstNode] = data;
}
this->CheckForTopMostVisibleImage();
}
void QmitkMeasurementView::NodeChanged(const mitk::DataNode* node)
{
// DETERMINE IF WE HAVE TO RENEW OUR DETAILS TEXT (ANY NODE CHANGED IN OUR SELECTION?)
bool renewText = false;
for( int i=0; i < d->m_CurrentSelection.size(); ++i )
{
if( node == d->m_CurrentSelection.at(i) )
{
renewText = true;
break;
}
}
if(renewText)
{
MEASUREMENT_DEBUG << "Selected nodes changed. Refreshing text.";
this->UpdateMeasurementText();
}
this->CheckForTopMostVisibleImage();
}
void QmitkMeasurementView::CheckForTopMostVisibleImage(mitk::DataNode* _NodeToNeglect)
{
d->m_SelectedImageNode = this->DetectTopMostVisibleImage().GetPointer();
if( d->m_SelectedImageNode.GetPointer() == _NodeToNeglect )
d->m_SelectedImageNode = 0;
if( d->m_SelectedImageNode.IsNotNull() && d->m_UnintializedPlanarFigure == false )
{
MEASUREMENT_DEBUG << "Reference image found";
d->m_SelectedImageLabel->setText( QString::fromStdString( d->m_SelectedImageNode->GetName() ) );
d->m_DrawActionsToolBar->setEnabled(true);
MEASUREMENT_DEBUG << "Updating Measurement text";
}
else
{
MEASUREMENT_DEBUG << "No reference image available. Will disable actions for creating new planarfigures";
if( d->m_UnintializedPlanarFigure == false )
d->m_SelectedImageLabel->setText( "No visible image available." );
d->m_DrawActionsToolBar->setEnabled(false);
}
}
void QmitkMeasurementView::NodeRemoved(const mitk::DataNode* node)
{
MEASUREMENT_DEBUG << "node removed from data storage";
mitk::DataNode* nonConstNode = const_cast<mitk::DataNode*>(node);
std::map<mitk::DataNode*, QmitkPlanarFigureData>::iterator it =
d->m_DataNodeToPlanarFigureData.find(nonConstNode);
bool isFigureFinished = false;
bool isPlaced = false;
if( it != d->m_DataNodeToPlanarFigureData.end() )
{
QmitkPlanarFigureData& data = it->second;
// remove observers
data.m_Figure->RemoveObserver( data.m_EndPlacementObserverTag );
data.m_Figure->RemoveObserver( data.m_SelectObserverTag );
data.m_Figure->RemoveObserver( data.m_StartInteractionObserverTag );
data.m_Figure->RemoveObserver( data.m_EndInteractionObserverTag );
MEASUREMENT_DEBUG << "removing from the list of tracked planar figures";
isFigureFinished = data.m_Figure->GetPropertyList()->GetBoolProperty("initiallyplaced",isPlaced);
if (!isFigureFinished) { // if the property does not yet exist or is false, drop the datanode
PlanarFigureInitialized(); // normally called when a figure is finished, to reset all buttons
}
d->m_DataNodeToPlanarFigureData.erase( it );
}
mitk::TNodePredicateDataType<mitk::PlanarFigure>::Pointer isPlanarFigure = mitk::TNodePredicateDataType<mitk::PlanarFigure>::New();
mitk::DataStorage::SetOfObjects::ConstPointer nodes =
GetDataStorage()->GetDerivations(node,isPlanarFigure);
for (unsigned int x = 0; x < nodes->size(); x++)
{
mitk::PlanarFigure* planarFigure = dynamic_cast<mitk::PlanarFigure*> (nodes->at(x)->GetData());
if (planarFigure != NULL) {
isFigureFinished = planarFigure->GetPropertyList()->GetBoolProperty("initiallyplaced",isPlaced);
if (!isFigureFinished) { // if the property does not yet exist or is false, drop the datanode
GetDataStorage()->Remove(nodes->at(x));
if( !d->m_DataNodeToPlanarFigureData.empty() )
{
std::map<mitk::DataNode*, QmitkPlanarFigureData>::iterator it2 =
d->m_DataNodeToPlanarFigureData.find(nodes->at(x));
//check if returned it2 valid
if( it2 != d->m_DataNodeToPlanarFigureData.end() )
{
d->m_DataNodeToPlanarFigureData.erase( it2 );// removing planar figure from tracked figure list
PlanarFigureInitialized(); // normally called when a figure is finished, to reset all buttons
EnableCrosshairNavigation();
}
}
}
}
}
this->CheckForTopMostVisibleImage(nonConstNode);
}
void QmitkMeasurementView::PlanarFigureSelected( itk::Object* object, const itk::EventObject& )
{
MEASUREMENT_DEBUG << "planar figure " << object << " selected";
std::map<mitk::DataNode*, QmitkPlanarFigureData>::iterator it =
d->m_DataNodeToPlanarFigureData.begin();
d->m_CurrentSelection.clear();
while( it != d->m_DataNodeToPlanarFigureData.end())
{
mitk::DataNode* node = it->first;
QmitkPlanarFigureData& data = it->second;
if( data.m_Figure == object )
{
MITK_DEBUG << "selected node found. enabling selection";
node->SetSelected(true);
d->m_CurrentSelection.push_back( node );
}
else
{
node->SetSelected(false);
}
++it;
}
this->UpdateMeasurementText();
this->RequestRenderWindowUpdate();
}
void QmitkMeasurementView::PlanarFigureInitialized()
{
MEASUREMENT_DEBUG << "planar figure initialized";
d->m_UnintializedPlanarFigure = false;
d->m_DrawActionsToolBar->setEnabled(true);
d->m_DrawLine->setChecked(false);
d->m_DrawPath->setChecked(false);
d->m_DrawAngle->setChecked(false);
d->m_DrawFourPointAngle->setChecked(false);
d->m_DrawCircle->setChecked(false);
d->m_DrawEllipse->setChecked(false);
d->m_DrawDoubleEllipse->setChecked(false);
d->m_DrawRectangle->setChecked(false);
d->m_DrawPolygon->setChecked(false);
d->m_DrawBezierCurve->setChecked(false);
d->m_DrawSubdivisionPolygon->setChecked(false);
}
void QmitkMeasurementView::SetFocus()
{
d->m_SelectedImageLabel->setFocus();
}
void QmitkMeasurementView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/,
const QList<mitk::DataNode::Pointer> &nodes)
{
MEASUREMENT_DEBUG << "Determine the top most visible image";
MEASUREMENT_DEBUG << "The PlanarFigure interactor will take the currently visible PlaneGeometry from the slice navigation controller";
this->CheckForTopMostVisibleImage();
MEASUREMENT_DEBUG << "refreshing selection and detailed text";
d->m_CurrentSelection = nodes;
this->UpdateMeasurementText();
// bug 16600: deselecting all planarfigures by clicking on datamanager when no node is selected
if(d->m_CurrentSelection.size() == 0)
{
+ // bug 18440: resetting the selected image label here because unselecting the
+ // current node did not reset the label
+ d->m_SelectedImageLabel->setText( "No visible image available." );
+
mitk::TNodePredicateDataType<mitk::PlanarFigure>::Pointer isPlanarFigure = mitk::TNodePredicateDataType<mitk::PlanarFigure>::New();
mitk::DataStorage::SetOfObjects::ConstPointer planarFigures = this->GetDataStorage()->GetSubset( isPlanarFigure );
// setting all planar figures which are not helper objects not selected
for(mitk::DataStorage::SetOfObjects::ConstIterator it=planarFigures->Begin(); it!=planarFigures->End(); it++)
{
mitk::DataNode* node = it.Value();
bool isHelperObject(false);
node->GetBoolProperty("helper object", isHelperObject);
if(!isHelperObject)
{
node->SetSelected(false);
}
}
}
for( int i=d->m_CurrentSelection.size()-1; i>= 0; --i)
{
mitk::DataNode* node = d->m_CurrentSelection.at(i);
mitk::PlanarFigure* _PlanarFigure = dynamic_cast<mitk::PlanarFigure*> (node->GetData());
// the last selected planar figure
if (_PlanarFigure && _PlanarFigure->GetPlaneGeometry())
{
QmitkRenderWindow* selectedRenderWindow = 0;
bool PlanarFigureInitializedWindow = false;
mitk::ILinkedRenderWindowPart* linkedRenderWindow = dynamic_cast<mitk::ILinkedRenderWindowPart*>(this->GetRenderWindowPart());
if(! linkedRenderWindow )
{
return;
}
QmitkRenderWindow* RenderWindow1 = linkedRenderWindow->GetQmitkRenderWindow( "axial") ;
QmitkRenderWindow* RenderWindow2 = linkedRenderWindow->GetQmitkRenderWindow( "sagittal") ;
QmitkRenderWindow* RenderWindow3 = linkedRenderWindow->GetQmitkRenderWindow( "coronal") ;
QmitkRenderWindow* RenderWindow4 = linkedRenderWindow->GetQmitkRenderWindow( "3d") ;
if (node->GetBoolProperty("PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow1->GetRenderer()))
{
selectedRenderWindow = RenderWindow1;
}
if (!selectedRenderWindow && node->GetBoolProperty("PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow2->GetRenderer()))
{
selectedRenderWindow = RenderWindow2;
}
if (!selectedRenderWindow && node->GetBoolProperty("PlanarFigureInitializedWindow", PlanarFigureInitializedWindow,RenderWindow3->GetRenderer()))
{
selectedRenderWindow = RenderWindow3;
}
if (!selectedRenderWindow && node->GetBoolProperty("PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow4->GetRenderer()))
{
selectedRenderWindow = RenderWindow4;
}
const mitk::PlaneGeometry* _PlaneGeometry = dynamic_cast<const mitk::PlaneGeometry*> (_PlanarFigure->GetPlaneGeometry());
mitk::VnlVector normal = _PlaneGeometry->GetNormalVnl();
mitk::PlaneGeometry::ConstPointer _Plane1 = RenderWindow1->GetRenderer()->GetCurrentWorldPlaneGeometry();
mitk::VnlVector normal1 = _Plane1->GetNormalVnl();
mitk::PlaneGeometry::ConstPointer _Plane2 = RenderWindow2->GetRenderer()->GetCurrentWorldPlaneGeometry();
mitk::VnlVector normal2 = _Plane2->GetNormalVnl();
mitk::PlaneGeometry::ConstPointer _Plane3 = RenderWindow3->GetRenderer()->GetCurrentWorldPlaneGeometry();
mitk::VnlVector normal3 = _Plane3->GetNormalVnl();
normal[0] = fabs(normal[0]); normal[1] = fabs(normal[1]); normal[2] = fabs(normal[2]);
normal1[0] = fabs(normal1[0]); normal1[1] = fabs(normal1[1]); normal1[2] = fabs(normal1[2]);
normal2[0] = fabs(normal2[0]); normal2[1] = fabs(normal2[1]); normal2[2] = fabs(normal2[2]);
normal3[0] = fabs(normal3[0]); normal3[1] = fabs(normal3[1]); normal3[2] = fabs(normal3[2]);
double ang1 = angle(normal, normal1);
double ang2 = angle(normal, normal2);
double ang3 = angle(normal, normal3);
if(ang1 < ang2 && ang1 < ang3)
{
selectedRenderWindow = RenderWindow1;
}
else
{
if(ang2 < ang3)
{
selectedRenderWindow = RenderWindow2;
}
else
{
selectedRenderWindow = RenderWindow3;
}
}
// re-orient view
if (selectedRenderWindow)
{
const mitk::Point3D& centerP = _PlaneGeometry->GetOrigin();
selectedRenderWindow->GetSliceNavigationController()->ReorientSlices(centerP, _PlaneGeometry->GetNormal());
}
}
break;
}
this->RequestRenderWindowUpdate();
}
void QmitkMeasurementView::ActionDrawLineTriggered(bool checked)
{
Q_UNUSED(checked)
mitk::PlanarLine::Pointer figure = mitk::PlanarLine::New();
QString qString = QString("Line%1").arg(++d->m_LineCounter);
this->AddFigureToDataStorage(figure, qString);
MEASUREMENT_DEBUG << "PlanarLine initialized...";
}
void QmitkMeasurementView::ActionDrawPathTriggered(bool checked)
{
Q_UNUSED(checked)
mitk::IPropertyFilters* propertyFilters = GetService<mitk::IPropertyFilters>();
if (propertyFilters != NULL)
{
mitk::PropertyFilter filter;
filter.AddEntry("ClosedPlanarPolygon", mitk::PropertyFilter::Blacklist);
propertyFilters->AddFilter(filter, "PlanarPolygon");
}
mitk::PlanarPolygon::Pointer figure = mitk::PlanarPolygon::New();
figure->ClosedOff();
QString qString = QString("Path%1").arg(++d->m_PathCounter);
mitk::DataNode::Pointer node = this->AddFigureToDataStorage(figure, qString);
mitk::BoolProperty::Pointer closedProperty = mitk::BoolProperty::New( false );
node->SetProperty("ClosedPlanarPolygon", closedProperty);
node->SetProperty("planarfigure.isextendable",mitk::BoolProperty::New(true));
MEASUREMENT_DEBUG << "PlanarPath initialized...";
}
void QmitkMeasurementView::ActionDrawAngleTriggered(bool checked)
{
Q_UNUSED(checked)
mitk::PlanarAngle::Pointer figure = mitk::PlanarAngle::New();
QString qString = QString("Angle%1").arg(++d->m_AngleCounter);
this->AddFigureToDataStorage(figure, qString);
MEASUREMENT_DEBUG << "PlanarAngle initialized...";
}
void QmitkMeasurementView::ActionDrawFourPointAngleTriggered(bool checked)
{
Q_UNUSED(checked)
mitk::PlanarFourPointAngle::Pointer figure =
mitk::PlanarFourPointAngle::New();
QString qString = QString("Four Point Angle%1").arg(++d->m_FourPointAngleCounter);
this->AddFigureToDataStorage(figure, qString);
MEASUREMENT_DEBUG << "PlanarFourPointAngle initialized...";
}
void QmitkMeasurementView::ActionDrawCircleTriggered(bool checked)
{
Q_UNUSED(checked)
mitk::PlanarCircle::Pointer figure = mitk::PlanarCircle::New();
QString qString = QString("Circle%1").arg(++d->m_CircleCounter);
this->AddFigureToDataStorage(figure, qString);
MEASUREMENT_DEBUG << "PlanarCircle initialized...";
}
void QmitkMeasurementView::ActionDrawEllipseTriggered(bool checked)
{
Q_UNUSED(checked)
mitk::PlanarEllipse::Pointer figure = mitk::PlanarEllipse::New();
QString qString = QString("Ellipse%1").arg(++d->m_EllipseCounter);
this->AddFigureToDataStorage(figure, qString);
MEASUREMENT_DEBUG << "PlanarEllipse initialized...";
}
void QmitkMeasurementView::ActionDrawDoubleEllipseTriggered(bool checked)
{
Q_UNUSED(checked)
mitk::PlanarDoubleEllipse::Pointer figure = mitk::PlanarDoubleEllipse::New();
QString qString = QString("DoubleEllipse%1").arg(++d->m_DoubleEllipseCounter);
this->AddFigureToDataStorage(figure, qString);
MEASUREMENT_DEBUG << "PlanarDoubleEllipse initialized...";
}
void QmitkMeasurementView::ActionDrawBezierCurveTriggered(bool checked)
{
Q_UNUSED(checked)
mitk::PlanarBezierCurve::Pointer figure = mitk::PlanarBezierCurve::New();
QString qString = QString("BezierCurve%1").arg(++d->m_BezierCurveCounter);
this->AddFigureToDataStorage(figure, qString);
MEASUREMENT_DEBUG << "PlanarBezierCurve initialized...";
}
void QmitkMeasurementView::ActionDrawSubdivisionPolygonTriggered(bool checked)
{
Q_UNUSED(checked)
mitk::PlanarSubdivisionPolygon::Pointer figure = mitk::PlanarSubdivisionPolygon::New();
QString qString = QString("SubdivisionPolygon%1").arg(++d->m_SubdivisionPolygonCounter);
this->AddFigureToDataStorage(figure, qString);
MEASUREMENT_DEBUG << "PlanarSubdivisionPolygon initialized...";
}
void QmitkMeasurementView::ActionDrawRectangleTriggered(bool checked)
{
Q_UNUSED(checked)
mitk::PlanarRectangle::Pointer figure = mitk::PlanarRectangle::New();
QString qString = QString("Rectangle%1").arg(++d->m_RectangleCounter);
this->AddFigureToDataStorage(figure, qString);
MEASUREMENT_DEBUG << "PlanarRectangle initialized...";
}
void QmitkMeasurementView::ActionDrawPolygonTriggered(bool checked)
{
Q_UNUSED(checked)
mitk::PlanarPolygon::Pointer figure = mitk::PlanarPolygon::New();
figure->ClosedOn();
QString qString = QString("Polygon%1").arg(++d->m_PolygonCounter);
mitk::DataNode::Pointer node = this->AddFigureToDataStorage(figure, qString);
node->SetProperty("planarfigure.isextendable",mitk::BoolProperty::New(true));
MEASUREMENT_DEBUG << "PlanarPolygon initialized...";
}
void QmitkMeasurementView::CopyToClipboard( bool checked )
{
Q_UNUSED(checked)
MEASUREMENT_DEBUG << "Copying current Text to clipboard...";
QString clipboardText = d->m_SelectedPlanarFiguresText->toPlainText();
QApplication::clipboard()->setText(clipboardText, QClipboard::Clipboard);
}
mitk::DataNode::Pointer QmitkMeasurementView::AddFigureToDataStorage(
mitk::PlanarFigure* figure, const QString& name)
{
// add as
MEASUREMENT_DEBUG << "Adding new figure to datastorage...";
if( d->m_SelectedImageNode.IsNull() )
{
MITK_ERROR << "No reference image available";
return 0;
}
mitk::DataNode::Pointer newNode = mitk::DataNode::New();
newNode->SetName(name.toStdString());
newNode->SetData(figure);
// set as selected
newNode->SetSelected( true );
this->GetDataStorage()->Add(newNode, d->m_SelectedImageNode);
// set all others in selection as deselected
for( int i=0; i<d->m_CurrentSelection.size(); ++i)
d->m_CurrentSelection.at(i)->SetSelected(false);
d->m_CurrentSelection.clear();
d->m_CurrentSelection.push_back( newNode );
this->UpdateMeasurementText();
this->DisableCrosshairNavigation();
d->m_DrawActionsToolBar->setEnabled(false);
d->m_UnintializedPlanarFigure = true;
return newNode;
}
void QmitkMeasurementView::UpdateMeasurementText()
{
d->m_SelectedPlanarFiguresText->clear();
QString infoText;
QString plainInfoText;
int j = 1;
mitk::PlanarFigure* _PlanarFigure = 0;
mitk::PlanarAngle* planarAngle = 0;
mitk::PlanarFourPointAngle* planarFourPointAngle = 0;
mitk::DataNode::Pointer node = 0;
for (int i=0; i<d->m_CurrentSelection.size(); ++i, ++j)
{
plainInfoText.clear();
node = d->m_CurrentSelection.at(i);
_PlanarFigure = dynamic_cast<mitk::PlanarFigure*> (node->GetData());
if( !_PlanarFigure )
continue;
if(j>1)
infoText.append("<br />");
infoText.append(QString("<b>%1</b><hr />").arg(QString::fromStdString(
node->GetName())));
plainInfoText.append(QString("%1").arg(QString::fromStdString(
node->GetName())));
planarAngle = dynamic_cast<mitk::PlanarAngle*> (_PlanarFigure);
if(!planarAngle)
{
planarFourPointAngle = dynamic_cast<mitk::PlanarFourPointAngle*> (_PlanarFigure);
}
double featureQuantity = 0.0;
for (unsigned int k = 0; k < _PlanarFigure->GetNumberOfFeatures(); ++k)
{
if ( !_PlanarFigure->IsFeatureActive( k ) ) continue;
featureQuantity = _PlanarFigure->GetQuantity(k);
if ((planarAngle && k == planarAngle->FEATURE_ID_ANGLE)
|| (planarFourPointAngle && k == planarFourPointAngle->FEATURE_ID_ANGLE))
featureQuantity = featureQuantity * 180 / vnl_math::pi;
infoText.append(
QString("<i>%1</i>: %2 %3") .arg(QString(
_PlanarFigure->GetFeatureName(k))) .arg(featureQuantity, 0, 'f',
2) .arg(QString(_PlanarFigure->GetFeatureUnit(k))));
plainInfoText.append(
QString("\n%1: %2 %3") .arg(QString(_PlanarFigure->GetFeatureName(k))) .arg(
featureQuantity, 0, 'f', 2) .arg(QString(
_PlanarFigure->GetFeatureUnit(k))));
if(k+1 != _PlanarFigure->GetNumberOfFeatures())
infoText.append("<br />");
}
if (j != d->m_CurrentSelection.size())
infoText.append("<br />");
}
d->m_SelectedPlanarFiguresText->setHtml(infoText);
}
void QmitkMeasurementView::AddAllInteractors()
{
MEASUREMENT_DEBUG << "Adding interactors and observers to all planar figures";
mitk::DataStorage::SetOfObjects::ConstPointer planarFigures = this->GetAllPlanarFigures();
for(mitk::DataStorage::SetOfObjects::ConstIterator it=planarFigures->Begin();
it!=planarFigures->End(); it++)
{
this->NodeAdded( it.Value() );
}
}
void QmitkMeasurementView::RemoveAllInteractors()
{
MEASUREMENT_DEBUG << "Removing interactors and observers from all planar figures";
mitk::DataStorage::SetOfObjects::ConstPointer planarFigures = this->GetAllPlanarFigures();
for(mitk::DataStorage::SetOfObjects::ConstIterator it=planarFigures->Begin();
it!=planarFigures->End(); it++)
{
this->NodeRemoved( it.Value() );
}
}
mitk::DataNode::Pointer QmitkMeasurementView::DetectTopMostVisibleImage()
{
// get all images from the data storage which are not a segmentation
mitk::TNodePredicateDataType<mitk::Image>::Pointer isImage = mitk::TNodePredicateDataType<mitk::Image>::New();
mitk::NodePredicateProperty::Pointer isBinary = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true));
mitk::NodePredicateNot::Pointer isNotBinary = mitk::NodePredicateNot::New( isBinary );
mitk::NodePredicateAnd::Pointer isNormalImage = mitk::NodePredicateAnd::New( isImage, isNotBinary );
mitk::DataStorage::SetOfObjects::ConstPointer Images
= this->GetDataStorage()->GetSubset( isNormalImage );
mitk::DataNode::Pointer currentNode;
int maxLayer = itk::NumericTraits<int>::min();
// iterate over selection
for (mitk::DataStorage::SetOfObjects::ConstIterator sofIt = Images->Begin(); sofIt != Images->End(); ++sofIt)
{
mitk::DataNode::Pointer node = sofIt->Value();
if ( node.IsNull() )
continue;
if (node->IsVisible(NULL) == false)
continue;
// we also do not want to assign planar figures to helper objects ( even if they are of type image )
if (node->GetProperty("helper object"))
continue;
int layer = 0;
node->GetIntProperty("layer", layer);
if ( layer < maxLayer )
{
continue;
}
else
{
maxLayer = layer;
currentNode = node;
}
}
return currentNode;
}
void QmitkMeasurementView::EnableCrosshairNavigation()
{
MEASUREMENT_DEBUG << "EnableCrosshairNavigation";
// enable the crosshair navigation
if (mitk::ILinkedRenderWindowPart* linkedRenderWindow =
dynamic_cast<mitk::ILinkedRenderWindowPart*>(this->GetRenderWindowPart()))
{
MEASUREMENT_DEBUG << "enabling linked navigation";
linkedRenderWindow->EnableLinkedNavigation(true);
linkedRenderWindow->EnableSlicingPlanes(true);
}
}
void QmitkMeasurementView::DisableCrosshairNavigation()
{
MEASUREMENT_DEBUG << "DisableCrosshairNavigation";
// disable the crosshair navigation during the drawing
if (mitk::ILinkedRenderWindowPart* linkedRenderWindow =
dynamic_cast<mitk::ILinkedRenderWindowPart*>(this->GetRenderWindowPart()))
{
MEASUREMENT_DEBUG << "disabling linked navigation";
linkedRenderWindow->EnableLinkedNavigation(false);
linkedRenderWindow->EnableSlicingPlanes(false);
}
}
mitk::DataStorage::SetOfObjects::ConstPointer QmitkMeasurementView::GetAllPlanarFigures() const
{
mitk::TNodePredicateDataType<mitk::PlanarFigure>::Pointer isPlanarFigure = mitk::TNodePredicateDataType<mitk::PlanarFigure>::New();
mitk::NodePredicateProperty::Pointer isNotHelperObject = mitk::NodePredicateProperty::New("helper object", mitk::BoolProperty::New(false));
mitk::NodePredicateAnd::Pointer isNotHelperButPlanarFigure = mitk::NodePredicateAnd::New( isPlanarFigure, isNotHelperObject );
return this->GetDataStorage()->GetSubset( isPlanarFigure );
}
diff --git a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/mitkPluginActivator.cpp
index a471351f45..aa05373988 100644
--- a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/mitkPluginActivator.cpp
+++ b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/mitkPluginActivator.cpp
@@ -1,42 +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 "mitkPluginActivator.h"
#include "QmitkMeasurementView.h"
#include "QmitkImageStatisticsView.h"
#include <QtPlugin>
ctkPluginContext* mitk::PluginActivator::m_Context = NULL;
ctkPluginContext* mitk::PluginActivator::GetContext()
{
return m_Context;
}
void mitk::PluginActivator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(QmitkMeasurementView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkImageStatisticsView, context)
m_Context = context;
}
void mitk::PluginActivator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
m_Context = NULL;
}
-Q_EXPORT_PLUGIN2(org.mitk.gui.qt.measurementtoolbox, mitk::PluginActivator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org.mitk.gui.qt.measurementtoolbox, mitk::PluginActivator)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/mitkPluginActivator.h
index 46e55e4329..789098ce7d 100644
--- a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/mitkPluginActivator.h
+++ b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/mitkPluginActivator.h
@@ -1,40 +1,43 @@
/*===================================================================
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 MITKPLUGINACTIVATOR_H
#define MITKPLUGINACTIVATOR_H
#include <ctkPluginActivator.h>
#include <mitkExportMacros.h>
namespace mitk
{
class PluginActivator : public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org.mitk.gui.qt.measurementtoolbox")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
static ctkPluginContext* GetContext();
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
private:
static ctkPluginContext* m_Context;
};
}
#endif
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker.dox b/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker.dox
index 878627bddb..fb341641ed 100644
--- a/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker.dox
+++ b/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker.dox
@@ -1,44 +1,65 @@
/**
+\page org_mitk_gui_qt_moviemaker The Movie Maker Plugin
-\page org_mitk_views_moviemaker The Movie Maker View
+\imageMacro{QmitkMovieMaker_Icon.png,"Icon of the Movie Maker Plugin.",2.00}
-\imageMacro{QmitkMovieMaker_Icon.png,"Icon of the Movie Maker View",2.00}
+\tableofcontents
-Available sections:
- - \ref QmitkMovieMakerUserManualOverview
- - \ref QmitkMovieMakerUserManualFeatures
- - \ref QmitkMovieMakerUserManualUsage
+\section org_mitk_gui_qt_moviemakerOverview Overview
-\section QmitkMovieMakerUserManualOverview Overview
+The Movie Maker View allows you to create basic animations of your scene and to record them to video files.
+Individual animations are arranged in a timeline and can be played back sequential or in parallel.
-MovieMaker is a functionality for easily creating fancy movies from scenes displayed in MITK widgets.
-It is also possible to slide through your data, automatically rotate 3D scenes and take screenshots of widgets.
+The Movie Maker View uses external FFmpeg/Libav command line utilities to write compressed video files.
-\section QmitkMovieMakerUserManualFeatures Features
+<b>You have to manually install either FFmpeg or Libav and set the corresponding path in "External Programs" in the MITK Workbench Preferences (Ctrl+P) in order to record your movies to video files.</b>
- The Movie Maker allows you to create movies and screenshots from within MITK. It can automatically scroll thorugh timesteps and slices while recording a movie. This way, you can record visualizations like a beating heart or a rotating skull.
+\imageMacro{QmitkMovieMaker_Preferences.png,"The External Programs preferences page.",12.00}
-\section QmitkMovieMakerUserManualUsage Usage
+\section org_mitk_gui_qt_moviemakerUsage Usage
-\imageMacro{QmitkMovieMaker_ControlArea.png,"A view of the command area of QmitkMovieMaker",9.84}
+\imageMacro{QmitkMovieMaker_MovieMakerView.png,"The Movie Maker View.",16.00}
-\subsection QmitkMovieMakerUserManualWindowSelection Window selection
-With the first two drop down boxes, you can choose which window you want to step through and which window you want to record in. Left clicking inside a window will set both drop down boxes to that window, but you can choose different windows for stepping and recording.
+To create a movie you have to add an animation to the timeline by clicking the "Add animation" button.
+You can choose between the available types of animations, e.g., Orbit or Slice.
-The first drop down box defines the window along which slices will be stepped through if stepping is set to spatial (see below). The second denotes the window from which the content will be recorded.
+The timeline surrounding bottons allow you to arrange, remove, or add further animations to your movie.
-\subsection QmitkMovieMakerUserManualRecordingOptions Recording Options
+Each animation can be set to either begin with the previous animation, i.e., run in parallel, or to start after the previous animation, i.e., run sequential.
+In combination with delays, rather complex animation arrangements are possible.
-The slider can be used to step through the slices manually while not recording. Start and stop control a preview of what a video would look like.
+To set animation specific parameters, select the corresponding animation in the timeline first.
-The buttons in the bottom part of this section can be used to create movies (windows only) or screenshots. Clicking opens a file %dialog where a name can be selected. After confirmation, a screenshot or movie is created according to the playing options.
+You can play back, pause and stop your movie with the according controls at the bottom of the Movie Maker View.
+Click the "Record" button to finally record your movie to a video file with the specified number of frames per second.
+You have to choose the render window which you want to record.
-\subsection QmitkMovieMakerUserManualPlayingOptions Playing Options
+\subsection org_mitk_gui_qt_moviemakerOrbitUsage Orbit Animation
-The first section controls whether the movie steps through slices (if a 2D view is selected), rotate the shown scene (if a 3D view is selected), or step through time steps (if set to temporal and a time resolved dataset is selected). If set to combined, a combination of both above options is used, with their speed relation set via the S/T Relation Spinbox.
+The Orbit animation rotates the camera in the 3D window around the scene.
+Align the camera directly in the 3D window and enter the number of degrees for the orbitting.
+You usually do not need to adjust the "Start angle" setting - leave it at 180 degrees.
+If you are planning to have a specific view in the middle of your movie you can play the movie and pause it at the specific frame of interest.
+Adjust the camera in the 3D window and restart the animation.
-In the second section the direction of stepping can be set. Options are: Forward, backward and Ping-Pong, which is back-and-forth.The stepping speed can be set via the spinbox(total time in seconds).
+\imageMacro{QmitkMovieMaker_Orbit.png,"The Orbit animation.",12.00}
-Although stepping speed is a total time in sec., this can not always be achieved. As a minimal frame rate of 25 fps is assumed to provide smooth movies, a dataset with only 25 slices will always be stepped through in 1 sec or faster.
+\subsection org_mitk_gui_qt_moviemakerSliceUsage Slice Animation
+
+The Slice animation slices through an image.
+You can choose the image plane (axial, sagittal, or coronal), as well as the start and end points of the slicing.
+Use the image navigator in the bottom left of the Workbench to get an idea of the desired values.
+Check "Reverse" in order to slice from the higher slice number to the lower slice number.
+
+\imageMacro{QmitkMovieMaker_Slice.png,"The Slice animation.",12.00}
+
+\subsection org_mitk_gui_qt_moviemakerTimeUsage Time Animation
+
+The Time animation steps through the individual time steps of the current scene.
+You can specify the range of the animated time steps.
+Use the image navigator in the bottom left of the Workbench to get an idea of the desired values.
+Check "Reverse" in order to step from later time steps to previous time steps.
+
+\imageMacro{QmitkMovieMaker_Time.gif,"The Time animation.",12.00}
*/
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_ControlArea.png b/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_ControlArea.png
deleted file mode 100644
index ec8c0b8dca..0000000000
Binary files a/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_ControlArea.png and /dev/null differ
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_Icon.png b/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_Icon.png
index 92c8276a2a..d9d484927f 100644
Binary files a/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_Icon.png and b/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_Icon.png differ
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_MovieMakerView.png b/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_MovieMakerView.png
new file mode 100644
index 0000000000..8b5eac9c8e
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_MovieMakerView.png differ
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_Orbit.png b/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_Orbit.png
new file mode 100644
index 0000000000..107e752a15
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_Orbit.png differ
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_Preferences.png b/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_Preferences.png
new file mode 100644
index 0000000000..c26c59a63c
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_Preferences.png differ
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_ScreenshotMakerInterface.png b/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_ScreenshotMakerInterface.png
deleted file mode 100644
index 085dcbdea6..0000000000
Binary files a/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_ScreenshotMakerInterface.png and /dev/null differ
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_Slice.png b/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_Slice.png
new file mode 100644
index 0000000000..dcd2321025
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_Slice.png differ
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_Time.gif b/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_Time.gif
new file mode 100644
index 0000000000..0b78372955
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkMovieMaker_Time.gif differ
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkScreenshotMaker.dox b/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkScreenshotMaker.dox
deleted file mode 100644
index 05b657bdeb..0000000000
--- a/Plugins/org.mitk.gui.qt.moviemaker/documentation/UserManual/QmitkScreenshotMaker.dox
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
-\page org_mitk_views_screenshotmaker The Screenshot Maker
-
-This view provides the functionality to create and save screenshots of the data.
-
-Available sections:
- - \ref QmitkScreenshotMakerUserManualUse
-
-\imageMacro{QmitkMovieMaker_ScreenshotMakerInterface.png,"The Screenshot Maker User Interface",7.09}
-
-\section QmitkScreenshotMakerUserManualUse Usage
-
-The first section offers the option of creating a screenshot of the last activated render window (thus the one, which was last clicked into). Upon clicking the button, the Screenshot Maker asks for a filename in which the screenshot is to be stored. The multiplanar Screenshot button asks for a folder, where screenshots of the three 2D views will be stored with default names.
-
-The high resolution screenshot section works the same as the simple screenshot section, aside from the fact, that the user can choose a magnification factor.
-
-In the option section one can rotate the camera in the 3D view by using the buttons. Furthermore one can choose the background colour for the screenshots, default is black.
-
-*/
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/files.cmake b/Plugins/org.mitk.gui.qt.moviemaker/files.cmake
index c4e28db992..184872f9d9 100644
--- a/Plugins/org.mitk.gui.qt.moviemaker/files.cmake
+++ b/Plugins/org.mitk.gui.qt.moviemaker/files.cmake
@@ -1,46 +1,57 @@
set(SRC_CPP_FILES
-
)
set(INTERNAL_CPP_FILES
- QmitkMovieMaker.cpp
+ QmitkAnimationItem.cpp
+ QmitkAnimationItemDelegate.cpp
+ QmitkAnimationWidget.cpp
+ QmitkFFmpegWriter.cpp
+ QmitkMovieMakerView.cpp
+ QmitkOrbitAnimationItem.cpp
+ QmitkOrbitAnimationWidget.cpp
+ QmitkSliceAnimationItem.cpp
+ QmitkSliceAnimationWidget.cpp
+ QmitkTimeSliceAnimationItem.cpp
+ QmitkTimeSliceAnimationWidget.cpp
mitkMovieMakerPluginActivator.cpp
QmitkScreenshotMaker.cpp
-
)
set(UI_FILES
- src/internal/QmitkMovieMakerControls.ui
+ src/internal/QmitkMovieMakerView.ui
+ src/internal/QmitkOrbitAnimationWidget.ui
+ src/internal/QmitkSliceAnimationWidget.ui
+ src/internal/QmitkTimeSliceAnimationWidget.ui
src/internal/QmitkScreenshotMakerControls.ui
)
set(MOC_H_FILES
src/internal/mitkMovieMakerPluginActivator.h
- src/internal/QmitkMovieMaker.h
+ src/internal/QmitkAnimationItemDelegate.h
+ src/internal/QmitkAnimationWidget.h
+ src/internal/QmitkFFmpegWriter.h
+ src/internal/QmitkMovieMakerView.h
+ src/internal/QmitkOrbitAnimationWidget.h
+ src/internal/QmitkSliceAnimationWidget.h
+ src/internal/QmitkTimeSliceAnimationWidget.h
src/internal/QmitkScreenshotMaker.h
)
set(CACHED_RESOURCE_FILES
- resources/icon.xpm
- plugin.xml
- resources/play.xpm
- resources/stop.xpm
- resources/pause.xpm
+ resources/camera-video.png
resources/screenshot_maker.png
+ plugin.xml
)
-set(RES_FILES
+set(QRC_FILES
resources/QmitkMovieMaker.qrc
- resources/play.xpm
- resources/stop.xpm
- resources/pause.xpm
)
foreach(file ${SRC_CPP_FILES})
set(CPP_FILES ${CPP_FILES} src/${file})
endforeach(file ${SRC_CPP_FILES})
foreach(file ${INTERNAL_CPP_FILES})
set(CPP_FILES ${CPP_FILES} src/internal/${file})
endforeach(file ${INTERNAL_CPP_FILES})
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.moviemaker/manifest_headers.cmake
index 33c96b326e..0273e2802e 100644
--- a/Plugins/org.mitk.gui.qt.moviemaker/manifest_headers.cmake
+++ b/Plugins/org.mitk.gui.qt.moviemaker/manifest_headers.cmake
@@ -1,5 +1,5 @@
set(Plugin-Name "MITK Movie Maker")
set(Plugin-Version "0.9")
set(Plugin-Vendor "DKFZ, Medical and Biological Informatics")
set(Plugin-ContactAddress "http://www.mitk.org")
-set(Require-Plugin org.mitk.gui.qt.common.legacy)
\ No newline at end of file
+set(Require-Plugin org.mitk.gui.qt.common org.mitk.gui.qt.common.legacy org.mitk.gui.qt.ext)
\ No newline at end of file
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/plugin.xml b/Plugins/org.mitk.gui.qt.moviemaker/plugin.xml
index 32c792be7d..d3fe235aa5 100644
--- a/Plugins/org.mitk.gui.qt.moviemaker/plugin.xml
+++ b/Plugins/org.mitk.gui.qt.moviemaker/plugin.xml
@@ -1,35 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<?BlueBerry version="0.1"?>
<plugin>
<extension point="org.blueberry.ui.views">
<view id="org.mitk.views.moviemaker"
name="Movie Maker"
- class="QmitkMovieMaker"
- icon="resources/icon.xpm" >
+ class="QmitkMovieMakerView"
+ icon="resources/camera-video.png" >
<description>Take movies of your data</description>
<keywordReference id="org.mitk.views.moviemaker.Keyword"/>
</view>
</extension>
<extension point="org.blueberry.ui.views">
<view id="org.mitk.views.screenshotmaker"
name="Screenshot Maker"
class="QmitkScreenshotMaker"
icon="resources/screenshot_maker.png" >
<description>Take screenshots of your data</description>
<keywordReference id="org.mitk.views.screenshotmaker.Keyword"/>
</view>
</extension>
<extension point="org.blueberry.ui.keywords">
<keyword label="image" id="org.mitk.views.screenshotmaker.Keyword"/>
<keyword label="picture" id="org.mitk.views.screenshotmaker.Keyword"/>
<keyword label="screenshot" id="org.mitk.views.screenshotmaker.Keyword"/>
<keyword label="movie" id="org.mitk.views.moviemaker.Keyword"/>
<keyword label="clip" id="org.mitk.views.moviemaker.Keyword"/>
</extension>
</plugin>
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/resources/QmitkMovieMaker.qrc b/Plugins/org.mitk.gui.qt.moviemaker/resources/QmitkMovieMaker.qrc
index 8bdb515e34..61ad433b67 100644
--- a/Plugins/org.mitk.gui.qt.moviemaker/resources/QmitkMovieMaker.qrc
+++ b/Plugins/org.mitk.gui.qt.moviemaker/resources/QmitkMovieMaker.qrc
@@ -1,10 +1,6 @@
<RCC>
<qresource prefix="/QmitkMovieMakerView" >
- <file>QmitkMovieMakerClasses.png</file>
- <file>QmitkMovieMakerGUI.png</file>
- <file>icon.xpm</file>
- <file>pause.xpm</file>
- <file>play.xpm</file>
- <file>stop.xpm</file>
+ <file>delay.svg</file>
+ <file>duration.svg</file>
</qresource>
</RCC>
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/resources/QmitkMovieMakerClasses.png b/Plugins/org.mitk.gui.qt.moviemaker/resources/QmitkMovieMakerClasses.png
deleted file mode 100644
index 9c26381a09..0000000000
Binary files a/Plugins/org.mitk.gui.qt.moviemaker/resources/QmitkMovieMakerClasses.png and /dev/null differ
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/resources/QmitkMovieMakerGUI.png b/Plugins/org.mitk.gui.qt.moviemaker/resources/QmitkMovieMakerGUI.png
deleted file mode 100644
index 02af724a9e..0000000000
Binary files a/Plugins/org.mitk.gui.qt.moviemaker/resources/QmitkMovieMakerGUI.png and /dev/null differ
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/resources/camera-video.png b/Plugins/org.mitk.gui.qt.moviemaker/resources/camera-video.png
new file mode 100644
index 0000000000..d9d484927f
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.moviemaker/resources/camera-video.png differ
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/resources/delay.svg b/Plugins/org.mitk.gui.qt.moviemaker/resources/delay.svg
new file mode 100644
index 0000000000..75e2310861
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.moviemaker/resources/delay.svg
@@ -0,0 +1,404 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ inkscape:export-ydpi="90.000000"
+ inkscape:export-xdpi="90.000000"
+ inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png"
+ width="48px"
+ height="48px"
+ id="svg11300"
+ sodipodi:version="0.32"
+ inkscape:version="0.48.4 r9939"
+ sodipodi:docname="appointment-new.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ version="1.1">
+ <defs
+ id="defs3">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 24 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="48 : 24 : 1"
+ inkscape:persp3d-origin="24 : 16 : 1"
+ id="perspective59" />
+ <linearGradient
+ id="linearGradient5204">
+ <stop
+ style="stop-color:#c40000;stop-opacity:1;"
+ offset="0"
+ id="stop5206" />
+ <stop
+ style="stop-color:#c40000;stop-opacity:0;"
+ offset="1"
+ id="stop5208" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5196">
+ <stop
+ style="stop-color:#c40000;stop-opacity:1;"
+ offset="0"
+ id="stop5198" />
+ <stop
+ style="stop-color:#c40000;stop-opacity:0;"
+ offset="1"
+ id="stop5200" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient12512">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop12513" />
+ <stop
+ style="stop-color:#fff520;stop-opacity:0.89108908;"
+ offset="0.50000000"
+ id="stop12517" />
+ <stop
+ style="stop-color:#fff300;stop-opacity:0.0000000;"
+ offset="1.0000000"
+ id="stop12514" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10653">
+ <stop
+ style="stop-color:#f3f4ff;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop10655" />
+ <stop
+ style="stop-color:#9193af;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop10657" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient42174">
+ <stop
+ style="stop-color:#a0a0a0;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop42176" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop42178" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2145">
+ <stop
+ style="stop-color:#fffffd;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop2147" />
+ <stop
+ style="stop-color:#cbcbc9;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop2149" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37935">
+ <stop
+ id="stop37937"
+ offset="0.0000000"
+ style="stop-color:#9497b3;stop-opacity:1.0000000;" />
+ <stop
+ id="stop37939"
+ offset="1.0000000"
+ style="stop-color:#4c4059;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2152">
+ <stop
+ id="stop2154"
+ offset="0.0000000"
+ style="stop-color:#9aa29a;stop-opacity:1.0000000;" />
+ <stop
+ id="stop2156"
+ offset="1.0000000"
+ style="stop-color:#b5beb5;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3816">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop3818" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop3820" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3816"
+ id="radialGradient3822"
+ cx="31.112698"
+ cy="19.008621"
+ fx="31.112698"
+ fy="19.008621"
+ r="8.6620579"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2152"
+ id="linearGradient4307"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(3.123841,0.000000,0.000000,0.969691,-31.88758,-19.59492)"
+ x1="8.9156475"
+ y1="37.197018"
+ x2="9.8855033"
+ y2="52.090678" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10653"
+ id="radialGradient4309"
+ gradientUnits="userSpaceOnUse"
+ cx="11.329200"
+ cy="10.583970"
+ fx="11.329200"
+ fy="10.583970"
+ r="15.532059" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2145"
+ id="radialGradient4311"
+ gradientUnits="userSpaceOnUse"
+ cx="11.901996"
+ cy="10.045444"
+ fx="11.901996"
+ fy="10.045444"
+ r="29.292715" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient42174"
+ id="linearGradient4313"
+ gradientUnits="userSpaceOnUse"
+ x1="6.3422160"
+ y1="7.7893324"
+ x2="22.218424"
+ y2="25.884274" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5196"
+ id="radialGradient5202"
+ cx="23.375"
+ cy="10.972863"
+ fx="23.375"
+ fy="10.972863"
+ r="3.3478092"
+ gradientTransform="matrix(3.63042,0,0,3.742066,-61.48607,-29.18618)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5204"
+ id="linearGradient5210"
+ x1="19.667364"
+ y1="4.2570662"
+ x2="20.329933"
+ y2="5.2845874"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37935"
+ id="radialGradient5212"
+ gradientUnits="userSpaceOnUse"
+ cx="8.7468252"
+ cy="6.8283234"
+ fx="8.7468252"
+ fy="6.8283234"
+ r="29.889715" />
+ </defs>
+ <sodipodi:namedview
+ stroke="#c4a000"
+ fill="#babdb6"
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="0.25490196"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="11.313708"
+ inkscape:cx="25.583496"
+ inkscape:cy="29.939851"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:showpageshadow="false"
+ inkscape:window-width="1920"
+ inkscape:window-height="1018"
+ inkscape:window-x="-8"
+ inkscape:window-y="-8"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source>http://jimmac.musichall.cz</dc:source>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
+ <dc:title></dc:title>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>appointment</rdf:li>
+ <rdf:li>new</rdf:li>
+ <rdf:li>meeting</rdf:li>
+ <rdf:li>rvsp</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/publicdomain/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <path
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.45064,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z"
+ sodipodi:ry="8.6620579"
+ sodipodi:rx="8.6620579"
+ sodipodi:cy="19.008621"
+ sodipodi:cx="31.112698"
+ id="path4318"
+ style="opacity:1;color:#000000;fill:url(#radialGradient3822);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc"
+ transform="matrix(2.563158,0.000000,0.000000,1.219602,-55.98414,14.04144)" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path14341"
+ d="M 18.587591,1.403729 L 4.226755,18.096665 L 5.4854717,19.339844 L 18.587591,1.403729 z "
+ style="color:#000000;fill:url(#linearGradient4307);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path18921"
+ d="M 18.467176,1.3138035 L 5.6605716,19.072612 L 7.4900985,20.687913 L 18.467176,1.3138035 z "
+ style="fill:#fefefe;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1" />
+ <path
+ transform="matrix(1.431529,0.000000,0.000000,1.431529,0.569459,-1.654618)"
+ d="M 31.160714 16.910715 A 14.910714 14.910714 0 1 1 1.3392859,16.910715 A 14.910714 14.910714 0 1 1 31.160714 16.910715 z"
+ sodipodi:ry="14.910714"
+ sodipodi:rx="14.910714"
+ sodipodi:cy="16.910715"
+ sodipodi:cx="16.25"
+ id="path27786"
+ style="fill:url(#radialGradient5212);fill-opacity:1;fill-rule:evenodd;stroke:#605773;stroke-width:0.69855404;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(1.163838,0.000000,0.000000,1.163838,4.824801,2.777556)"
+ d="M 31.160714 16.910715 A 14.910714 14.910714 0 1 1 1.3392859,16.910715 A 14.910714 14.910714 0 1 1 31.160714 16.910715 z"
+ sodipodi:ry="14.910714"
+ sodipodi:rx="14.910714"
+ sodipodi:cy="16.910715"
+ sodipodi:cx="16.25"
+ id="path35549"
+ style="fill:url(#radialGradient4311);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4313);stroke-width:0.71139598;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="color:#000000;fill:url(#radialGradient5202);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient5210);stroke-width:0.56498736;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+ id="path4120"
+ sodipodi:cx="23.375"
+ sodipodi:cy="11.875"
+ sodipodi:rx="8.5"
+ sodipodi:ry="8.5"
+ d="M 16.679382,6.6387137 A 8.5,8.5 0 0 1 23.332691,3.3751053 L 23.375,11.875 z"
+ transform="matrix(-1.7699457,-0.00432917,-0.00432917,1.7699457,65.147988,2.66958)"
+ sodipodi:start="3.8052902"
+ sodipodi:end="4.7074114" />
+ <path
+ transform="matrix(2.073295,0,0,2.073295,-7.8102239,-12.94932)"
+ d="m 16.40625,17.28125 a 1.21875,1.21875 0 1 1 -2.4375,0 1.21875,1.21875 0 1 1 2.4375,0 z"
+ sodipodi:ry="1.21875"
+ sodipodi:rx="1.21875"
+ sodipodi:cy="17.28125"
+ sodipodi:cx="15.1875"
+ id="path34778"
+ style="fill:#f3f3f3;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.48232403;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc" />
+ <path
+ id="path35561"
+ d="M 29.894247,28.564063 25.771479,25.106582"
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(2.749493,0.000000,0.000000,2.749493,-22.30073,-12.40939)"
+ d="M 17.324117 7.6932044 A 0.61871845 0.61871845 0 1 1 16.08668,7.6932044 A 0.61871845 0.61871845 0 1 1 17.324117 7.6932044 z"
+ sodipodi:ry="0.61871845"
+ sodipodi:rx="0.61871845"
+ sodipodi:cy="7.6932044"
+ sodipodi:cx="16.705399"
+ id="path35563"
+ style="fill:#b6b9b1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.36871839;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;opacity:1"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(2.749493,0.000000,0.000000,2.749493,-22.30073,14.80922)"
+ d="M 17.324117 7.6932044 A 0.61871845 0.61871845 0 1 1 16.08668,7.6932044 A 0.61871845 0.61871845 0 1 1 17.324117 7.6932044 z"
+ sodipodi:ry="0.61871845"
+ sodipodi:rx="0.61871845"
+ sodipodi:cy="7.6932044"
+ sodipodi:cx="16.705399"
+ id="path35565"
+ style="fill:#b6b9b1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.36871839;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;opacity:1"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(2.749493,0.000000,0.000000,2.749493,-35.91004,1.199890)"
+ d="M 17.324117 7.6932044 A 0.61871845 0.61871845 0 1 1 16.08668,7.6932044 A 0.61871845 0.61871845 0 1 1 17.324117 7.6932044 z"
+ sodipodi:ry="0.61871845"
+ sodipodi:rx="0.61871845"
+ sodipodi:cy="7.6932044"
+ sodipodi:cx="16.705399"
+ id="path35567"
+ style="fill:#b6b9b1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.36871839;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;opacity:1"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(2.749493,0.000000,0.000000,2.749493,-8.691448,1.199890)"
+ d="M 17.324117 7.6932044 A 0.61871845 0.61871845 0 1 1 16.08668,7.6932044 A 0.61871845 0.61871845 0 1 1 17.324117 7.6932044 z"
+ sodipodi:ry="0.61871845"
+ sodipodi:rx="0.61871845"
+ sodipodi:cy="7.6932044"
+ sodipodi:cx="16.705399"
+ id="path35569"
+ style="fill:#b6b9b1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.36871839;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;opacity:1"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#radialGradient4309);stroke-width:0.73656511;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
+ id="path10651"
+ sodipodi:cx="16.25"
+ sodipodi:cy="16.910715"
+ sodipodi:rx="14.910714"
+ sodipodi:ry="14.910714"
+ d="M 31.160714 16.910715 A 14.910714 14.910714 0 1 1 1.3392859,16.910715 A 14.910714 14.910714 0 1 1 31.160714 16.910715 z"
+ transform="matrix(1.357654,0.000000,0.000000,1.357654,1.769896,-0.493735)" />
+ <path
+ id="path35559"
+ d="m 26.451233,21.541106 9.304986,-7.226072"
+ style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+</svg>
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/resources/duration.svg b/Plugins/org.mitk.gui.qt.moviemaker/resources/duration.svg
new file mode 100644
index 0000000000..01b1d129bd
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.moviemaker/resources/duration.svg
@@ -0,0 +1,392 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ inkscape:export-ydpi="90.000000"
+ inkscape:export-xdpi="90.000000"
+ inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png"
+ width="48px"
+ height="48px"
+ id="svg11300"
+ sodipodi:version="0.32"
+ inkscape:version="0.48.4 r9939"
+ sodipodi:docname="delay.svg"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ version="1.1">
+ <defs
+ id="defs3">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 24 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="48 : 24 : 1"
+ inkscape:persp3d-origin="24 : 16 : 1"
+ id="perspective59" />
+ <linearGradient
+ id="linearGradient5204">
+ <stop
+ style="stop-color:#c40000;stop-opacity:1;"
+ offset="0"
+ id="stop5206" />
+ <stop
+ style="stop-color:#c40000;stop-opacity:0;"
+ offset="1"
+ id="stop5208" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5196">
+ <stop
+ style="stop-color:#c40000;stop-opacity:1;"
+ offset="0"
+ id="stop5198" />
+ <stop
+ style="stop-color:#c40000;stop-opacity:0;"
+ offset="1"
+ id="stop5200" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient12512">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop12513" />
+ <stop
+ style="stop-color:#fff520;stop-opacity:0.89108908;"
+ offset="0.50000000"
+ id="stop12517" />
+ <stop
+ style="stop-color:#fff300;stop-opacity:0.0000000;"
+ offset="1.0000000"
+ id="stop12514" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient10653">
+ <stop
+ style="stop-color:#f3f4ff;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop10655" />
+ <stop
+ style="stop-color:#9193af;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop10657" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient42174">
+ <stop
+ style="stop-color:#a0a0a0;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop42176" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop42178" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2145">
+ <stop
+ style="stop-color:#fffffd;stop-opacity:1.0000000;"
+ offset="0.0000000"
+ id="stop2147" />
+ <stop
+ style="stop-color:#cbcbc9;stop-opacity:1.0000000;"
+ offset="1.0000000"
+ id="stop2149" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient37935">
+ <stop
+ id="stop37937"
+ offset="0.0000000"
+ style="stop-color:#9497b3;stop-opacity:1.0000000;" />
+ <stop
+ id="stop37939"
+ offset="1.0000000"
+ style="stop-color:#4c4059;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2152">
+ <stop
+ id="stop2154"
+ offset="0.0000000"
+ style="stop-color:#9aa29a;stop-opacity:1.0000000;" />
+ <stop
+ id="stop2156"
+ offset="1.0000000"
+ style="stop-color:#b5beb5;stop-opacity:1.0000000;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3816">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop3818" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop3820" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3816"
+ id="radialGradient3822"
+ cx="31.112698"
+ cy="19.008621"
+ fx="31.112698"
+ fy="19.008621"
+ r="8.6620579"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2152"
+ id="linearGradient4307"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(3.123841,0.000000,0.000000,0.969691,-31.88758,-19.59492)"
+ x1="8.9156475"
+ y1="37.197018"
+ x2="9.8855033"
+ y2="52.090678" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient10653"
+ id="radialGradient4309"
+ gradientUnits="userSpaceOnUse"
+ cx="11.329200"
+ cy="10.583970"
+ fx="11.329200"
+ fy="10.583970"
+ r="15.532059" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2145"
+ id="radialGradient4311"
+ gradientUnits="userSpaceOnUse"
+ cx="11.901996"
+ cy="10.045444"
+ fx="11.901996"
+ fy="10.045444"
+ r="29.292715" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient42174"
+ id="linearGradient4313"
+ gradientUnits="userSpaceOnUse"
+ x1="6.3422160"
+ y1="7.7893324"
+ x2="22.218424"
+ y2="25.884274" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5196"
+ id="radialGradient5202"
+ cx="23.375"
+ cy="10.972863"
+ fx="23.375"
+ fy="10.972863"
+ r="3.3478092"
+ gradientTransform="matrix(3.63042,0,0,3.742066,-61.48607,-29.18618)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5204"
+ id="linearGradient5210"
+ x1="19.667364"
+ y1="4.2570662"
+ x2="20.329933"
+ y2="5.2845874"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient37935"
+ id="radialGradient5212"
+ gradientUnits="userSpaceOnUse"
+ cx="8.7468252"
+ cy="6.8283234"
+ fx="8.7468252"
+ fy="6.8283234"
+ r="29.889715" />
+ </defs>
+ <sodipodi:namedview
+ stroke="#c4a000"
+ fill="#babdb6"
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="0.25490196"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="11.313708"
+ inkscape:cx="25.583496"
+ inkscape:cy="29.939851"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:grid-bbox="true"
+ inkscape:document-units="px"
+ inkscape:showpageshadow="false"
+ inkscape:window-width="1920"
+ inkscape:window-height="1018"
+ inkscape:window-x="-8"
+ inkscape:window-y="-8"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source>http://jimmac.musichall.cz</dc:source>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
+ <dc:title></dc:title>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>appointment</rdf:li>
+ <rdf:li>new</rdf:li>
+ <rdf:li>meeting</rdf:li>
+ <rdf:li>rvsp</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/publicdomain/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer">
+ <path
+ d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.45064,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z"
+ sodipodi:ry="8.6620579"
+ sodipodi:rx="8.6620579"
+ sodipodi:cy="19.008621"
+ sodipodi:cx="31.112698"
+ id="path4318"
+ style="opacity:1;color:#000000;fill:url(#radialGradient3822);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+ sodipodi:type="arc"
+ transform="matrix(2.563158,0.000000,0.000000,1.219602,-55.98414,14.04144)" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path14341"
+ d="M 18.587591,1.403729 L 4.226755,18.096665 L 5.4854717,19.339844 L 18.587591,1.403729 z "
+ style="color:#000000;fill:url(#linearGradient4307);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path18921"
+ d="M 18.467176,1.3138035 L 5.6605716,19.072612 L 7.4900985,20.687913 L 18.467176,1.3138035 z "
+ style="fill:#fefefe;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1" />
+ <path
+ transform="matrix(1.431529,0.000000,0.000000,1.431529,0.569459,-1.654618)"
+ d="M 31.160714 16.910715 A 14.910714 14.910714 0 1 1 1.3392859,16.910715 A 14.910714 14.910714 0 1 1 31.160714 16.910715 z"
+ sodipodi:ry="14.910714"
+ sodipodi:rx="14.910714"
+ sodipodi:cy="16.910715"
+ sodipodi:cx="16.25"
+ id="path27786"
+ style="fill:url(#radialGradient5212);fill-opacity:1;fill-rule:evenodd;stroke:#605773;stroke-width:0.69855404;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(1.163838,0.000000,0.000000,1.163838,4.824801,2.777556)"
+ d="M 31.160714 16.910715 A 14.910714 14.910714 0 1 1 1.3392859,16.910715 A 14.910714 14.910714 0 1 1 31.160714 16.910715 z"
+ sodipodi:ry="14.910714"
+ sodipodi:rx="14.910714"
+ sodipodi:cy="16.910715"
+ sodipodi:cx="16.25"
+ id="path35549"
+ style="fill:url(#radialGradient4311);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4313);stroke-width:0.71139598;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(2.073295,0,0,2.073295,-7.8102239,-12.94932)"
+ d="m 16.40625,17.28125 a 1.21875,1.21875 0 1 1 -2.4375,0 1.21875,1.21875 0 1 1 2.4375,0 z"
+ sodipodi:ry="1.21875"
+ sodipodi:rx="1.21875"
+ sodipodi:cy="17.28125"
+ sodipodi:cx="15.1875"
+ id="path34778"
+ style="fill:#f3f3f3;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.48232403;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ sodipodi:type="arc" />
+ <path
+ id="path35561"
+ d="M 29.894247,28.564063 25.771479,25.106582"
+ style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(2.749493,0.000000,0.000000,2.749493,-22.30073,-12.40939)"
+ d="M 17.324117 7.6932044 A 0.61871845 0.61871845 0 1 1 16.08668,7.6932044 A 0.61871845 0.61871845 0 1 1 17.324117 7.6932044 z"
+ sodipodi:ry="0.61871845"
+ sodipodi:rx="0.61871845"
+ sodipodi:cy="7.6932044"
+ sodipodi:cx="16.705399"
+ id="path35563"
+ style="fill:#b6b9b1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.36871839;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;opacity:1"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(2.749493,0.000000,0.000000,2.749493,-22.30073,14.80922)"
+ d="M 17.324117 7.6932044 A 0.61871845 0.61871845 0 1 1 16.08668,7.6932044 A 0.61871845 0.61871845 0 1 1 17.324117 7.6932044 z"
+ sodipodi:ry="0.61871845"
+ sodipodi:rx="0.61871845"
+ sodipodi:cy="7.6932044"
+ sodipodi:cx="16.705399"
+ id="path35565"
+ style="fill:#b6b9b1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.36871839;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;opacity:1"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(2.749493,0.000000,0.000000,2.749493,-35.91004,1.199890)"
+ d="M 17.324117 7.6932044 A 0.61871845 0.61871845 0 1 1 16.08668,7.6932044 A 0.61871845 0.61871845 0 1 1 17.324117 7.6932044 z"
+ sodipodi:ry="0.61871845"
+ sodipodi:rx="0.61871845"
+ sodipodi:cy="7.6932044"
+ sodipodi:cx="16.705399"
+ id="path35567"
+ style="fill:#b6b9b1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.36871839;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;opacity:1"
+ sodipodi:type="arc" />
+ <path
+ transform="matrix(2.749493,0.000000,0.000000,2.749493,-8.691448,1.199890)"
+ d="M 17.324117 7.6932044 A 0.61871845 0.61871845 0 1 1 16.08668,7.6932044 A 0.61871845 0.61871845 0 1 1 17.324117 7.6932044 z"
+ sodipodi:ry="0.61871845"
+ sodipodi:rx="0.61871845"
+ sodipodi:cy="7.6932044"
+ sodipodi:cx="16.705399"
+ id="path35569"
+ style="fill:#b6b9b1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.36871839;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;opacity:1"
+ sodipodi:type="arc" />
+ <path
+ sodipodi:type="arc"
+ style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#radialGradient4309);stroke-width:0.73656511;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
+ id="path10651"
+ sodipodi:cx="16.25"
+ sodipodi:cy="16.910715"
+ sodipodi:rx="14.910714"
+ sodipodi:ry="14.910714"
+ d="M 31.160714 16.910715 A 14.910714 14.910714 0 1 1 1.3392859,16.910715 A 14.910714 14.910714 0 1 1 31.160714 16.910715 z"
+ transform="matrix(1.357654,0.000000,0.000000,1.357654,1.769896,-0.493735)" />
+ <path
+ id="path35559"
+ d="M 23.601935,20.194702 23.667885,8.4135938"
+ style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ </g>
+</svg>
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/resources/icon.png b/Plugins/org.mitk.gui.qt.moviemaker/resources/icon.png
deleted file mode 100644
index 6ad519ea65..0000000000
Binary files a/Plugins/org.mitk.gui.qt.moviemaker/resources/icon.png and /dev/null differ
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/resources/icon.xpm b/Plugins/org.mitk.gui.qt.moviemaker/resources/icon.xpm
deleted file mode 100644
index 103ebf4b01..0000000000
--- a/Plugins/org.mitk.gui.qt.moviemaker/resources/icon.xpm
+++ /dev/null
@@ -1,47 +0,0 @@
-/* XPM */
-static const char * icon_xpm[] = {
-"28 28 16 1",
-" c None",
-". c #000000",
-"+ c #555555",
-"@ c #222222",
-"# c #777777",
-"$ c #444444",
-"% c #BBBBBB",
-"& c #DDDDDD",
-"* c #AAAAAA",
-"= c #FFFFFF",
-"- c #888888",
-"; c #993366",
-"> c #CC6666",
-", c #663300",
-"' c #440000",
-") c #FFFF00",
-" ... ",
-" ..+@@. ",
-" ..++@+@.. ",
-" ..+++##@@.. ",
-" ..+++##@@@@.. ",
-" ..+++##@@@$$.. ",
-" ..#++##@@@$...$ ",
-" ..##++#@@@%&&.$ ",
-" ...*@@+#@@%&&==&. ",
-" ...*++++@@%&&==&&@@. ",
-" ..$$==+#-%&&==&&@@$$@. ",
-" .+##..=-&&==&&@@@$$+@. ",
-" .##---*.=%=&&@@@@$$++@. ",
-" .===%**%%$=*@@@@@$$+++@. ",
-".=-@+=&%&&.&-@@@@$$++++@. ",
-".&.;.+=&%%.%#@@@$$+++++@. ",
-".&.>,.=&**.*+@$$====++@. ",
-".&.,,.&&--.*+=$$&&&&====... ",
-".&+.'.&%##.-=&$+%%%%&&&&===.",
-".&%+.*&*++$=&$======%%%%&&&.",
-" .&&&&&-++&**$&&&+++%===%%%.",
-" .&==&*+++&*--.%%@))++++===.",
-" .&**&*+++&-+@@@*+@@)))@&&&.",
-" .@&&&*+++@@@@..----@@@+%%%.",
-" .+@@$*+@@@@.. .....----***.",
-" .+++$@@@.. ....---.",
-" ..@+$@.. ... ",
-" .... "};
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/resources/pause.xpm b/Plugins/org.mitk.gui.qt.moviemaker/resources/pause.xpm
deleted file mode 100644
index 0ad2e7421c..0000000000
--- a/Plugins/org.mitk.gui.qt.moviemaker/resources/pause.xpm
+++ /dev/null
@@ -1,57 +0,0 @@
-/* XPM */
-static const char * pause_xpm[] = {
-"24 24 30 1",
-" c None",
-". c #000000",
-"+ c #FFFFFF",
-"@ c #737372",
-"# c #848483",
-"$ c #888887",
-"% c #7E7E7D",
-"& c #A8A7A6",
-"* c #A4A4A3",
-"= c #A6A5A4",
-"- c #B5B4B3",
-"; c #858483",
-"> c #AAA9A7",
-", c #C0BFBE",
-"' c #91908E",
-") c #AFAEAC",
-"! c #CACAC8",
-"~ c #A6A5A2",
-"{ c #BBBAB7",
-"] c #D4D3D2",
-"^ c #AEADA9",
-"/ c #BFBDBA",
-"( c #D7D5D3",
-"_ c #B2B0AD",
-": c #C3C1BE",
-"< c #D9D8D6",
-"[ c #B5B3B0",
-"} c #D1CFCC",
-"| c #DEDDDB",
-"1 c #F3F3F3",
-" ",
-" ",
-" ",
-" ",
-" ",
-" .....+.....+ ",
-" .@#$.+.@#$.+ ",
-" .%&*.+.%&*.+ ",
-" .%=-.+.%=-.+ ",
-" .;>,.+.;>,.+ ",
-" .')!.+.')!.+ ",
-" .')!.+.')!.+ ",
-" .')!.+.')!.+ ",
-" .~{].+.~{].+ ",
-" .~{].+.~{].+ ",
-" .^/(.+.^/(.+ ",
-" ._:<.+._:<.+ ",
-" .[}|.+.[}|.+ ",
-" .....+.....+ ",
-" +++++1++++++ ",
-" ",
-" ",
-" ",
-" "};
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/resources/play.xpm b/Plugins/org.mitk.gui.qt.moviemaker/resources/play.xpm
deleted file mode 100644
index 0bcda4f454..0000000000
--- a/Plugins/org.mitk.gui.qt.moviemaker/resources/play.xpm
+++ /dev/null
@@ -1,64 +0,0 @@
-/* XPM */
-static const char * play_xpm[] = {
-"24 24 37 1",
-" c None",
-". c #000000",
-"+ c #727170",
-"@ c #7B7B7A",
-"# c #6C6B6A",
-"$ c #7F7E7D",
-"% c #999996",
-"& c #7D7C7B",
-"* c #828180",
-"= c #9D9C9A",
-"- c #B0AFAC",
-"; c #908F8D",
-"> c #868583",
-", c #A1A09E",
-"' c #B4B3B1",
-") c #B6B4B2",
-"! c #A5A4A1",
-"~ c #898886",
-"{ c #B9B7B4",
-"] c #BAB9B6",
-"^ c #BCBAB7",
-"/ c #C3C2BF",
-"( c #FFFFFF",
-"_ c #8C8B89",
-": c #A9A8A5",
-"< c #BDBCB9",
-"[ c #C5C3C0",
-"} c #D0CECC",
-"| c #8F8E8C",
-"1 c #B5B3B1",
-"2 c #C7C6C3",
-"3 c #D2D1CE",
-"4 c #B9B6B4",
-"5 c #D8D7D5",
-"6 c #A19F9D",
-"7 c #C7C6C4",
-"8 c #A7A6A3",
-" ",
-" ",
-" ",
-" ",
-" . ",
-" .. ",
-" .+. ",
-" .@#. ",
-" .$%&. ",
-" .*=-;. ",
-" .>,')!. ",
-" .~!{]^/.( ",
-" ._:<[}.( ",
-" .|123.( ",
-" .=45.( ",
-" .67.( ",
-" .8.( ",
-" ..( ",
-" .( ",
-" ( ",
-" ",
-" ",
-" ",
-" "};
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/resources/stop.xpm b/Plugins/org.mitk.gui.qt.moviemaker/resources/stop.xpm
deleted file mode 100644
index 3b76b26157..0000000000
--- a/Plugins/org.mitk.gui.qt.moviemaker/resources/stop.xpm
+++ /dev/null
@@ -1,56 +0,0 @@
-/* XPM */
-static const char * stop_xpm[] = {
-"24 24 29 1",
-" c None",
-". c #000000",
-"+ c #FFFFFF",
-"@ c #737372",
-"# c #848483",
-"$ c #888887",
-"% c #7E7E7D",
-"& c #A8A7A6",
-"* c #A4A4A3",
-"= c #A6A5A4",
-"- c #B5B4B3",
-"; c #858483",
-"> c #AAA9A7",
-", c #C0BFBE",
-"' c #91908E",
-") c #AFAEAC",
-"! c #CACAC8",
-"~ c #A6A5A2",
-"{ c #BBBAB7",
-"] c #D4D3D2",
-"^ c #AEADA9",
-"/ c #BFBDBA",
-"( c #D7D5D3",
-"_ c #B2B0AD",
-": c #C3C1BE",
-"< c #D9D8D6",
-"[ c #B5B3B0",
-"} c #D1CFCC",
-"| c #DEDDDB",
-" ",
-" ",
-" ",
-" ",
-" ",
-" .............+ ",
-" .@#$$$$$$$$$.+ ",
-" .%&*********.+ ",
-" .%=---------.+ ",
-" .;>,,,,,,,,,.+ ",
-" .')!!!!!!!!!.+ ",
-" .')!!!!!!!!!.+ ",
-" .~{]]]]]]]]].+ ",
-" .~{]]]]]]]]].+ ",
-" .^/(((((((((.+ ",
-" ._:<<<<<<<<<.+ ",
-" .[}|||||||||.+ ",
-" .............+ ",
-" ++++++++++++++ ",
-" ",
-" ",
-" ",
-" ",
-" "};
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationItem.cpp b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationItem.cpp
new file mode 100644
index 0000000000..c55bb0808a
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationItem.cpp
@@ -0,0 +1,71 @@
+/*===================================================================
+
+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 "QmitkAnimationItem.h"
+
+QmitkAnimationItem::QmitkAnimationItem(const QString& widgetKey, double duration, double delay, bool startWithPrevious)
+{
+ this->SetWidgetKey(widgetKey);
+ this->SetDuration(duration);
+ this->SetDelay(delay);
+ this->SetStartWithPrevious(startWithPrevious);
+
+ this->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+}
+
+QmitkAnimationItem::~QmitkAnimationItem()
+{
+}
+
+QString QmitkAnimationItem::GetWidgetKey() const
+{
+ return this->data(WidgetKeyRole).toString();
+}
+
+void QmitkAnimationItem::SetWidgetKey(const QString& widgetKey)
+{
+ this->setData(widgetKey, WidgetKeyRole);
+}
+
+double QmitkAnimationItem::GetDuration() const
+{
+ return this->data(DurationRole).toDouble();
+}
+
+void QmitkAnimationItem::SetDuration(double duration)
+{
+ this->setData(duration, DurationRole);
+}
+
+double QmitkAnimationItem::GetDelay() const
+{
+ return this->data(DelayRole).toDouble();
+}
+
+void QmitkAnimationItem::SetDelay(double delay)
+{
+ this->setData(delay, DelayRole);
+}
+
+bool QmitkAnimationItem::GetStartWithPrevious() const
+{
+ return this->data(StartWithPreviousRole).toBool();
+}
+
+void QmitkAnimationItem::SetStartWithPrevious(bool startWithPrevious)
+{
+ this->setData(startWithPrevious, StartWithPreviousRole);
+}
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationItem.h b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationItem.h
new file mode 100644
index 0000000000..9e7fcec130
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationItem.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 QmitkAnimationItem_h
+#define QmitkAnimationItem_h
+
+#include <QStandardItem>
+
+class QmitkAnimationItem : public QStandardItem
+{
+public:
+ enum AnimationItemDataRole
+ {
+ WidgetKeyRole = Qt::UserRole + 2,
+ DurationRole,
+ DelayRole,
+ StartWithPreviousRole,
+ RenderWindowRole,
+ FromRole,
+ ToRole,
+ ReverseRole,
+ StartAngleRole,
+ OrbitRole
+ };
+
+ explicit QmitkAnimationItem(const QString& widgetKey, double duration = 2.0, double delay = 0.0, bool startWithPrevious = false);
+ virtual ~QmitkAnimationItem();
+
+ QString GetWidgetKey() const;
+ void SetWidgetKey(const QString& widgetKey);
+
+ double GetDuration() const;
+ void SetDuration(double duration);
+
+ double GetDelay() const;
+ void SetDelay(double delay);
+
+ bool GetStartWithPrevious() const;
+ void SetStartWithPrevious(bool startWithPrevious);
+
+ virtual void Animate(double s) = 0;
+};
+
+#endif
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationItemDelegate.cpp b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationItemDelegate.cpp
new file mode 100644
index 0000000000..781aeb37af
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationItemDelegate.cpp
@@ -0,0 +1,123 @@
+/*===================================================================
+
+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 "QmitkAnimationItem.h"
+#include "QmitkAnimationItemDelegate.h"
+#include <QApplication>
+#include <QPainter>
+#include <QStandardItemModel>
+#include <limits>
+
+QmitkAnimationItemDelegate::QmitkAnimationItemDelegate(QObject* parent)
+ : QStyledItemDelegate(parent)
+{
+}
+
+QmitkAnimationItemDelegate::~QmitkAnimationItemDelegate()
+{
+}
+
+void QmitkAnimationItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
+{
+ painter->save();
+
+ if (option.state & QStyle::State_Selected)
+ painter->fillRect(option.rect, option.palette.highlight());
+
+ if (index.column() == 0)
+ {
+ QStyleOptionViewItem opt = option;
+ this->initStyleOption(&opt, index);
+
+ QRect rect = QRect(opt.rect.x() + 3, opt.rect.y(), opt.rect.width() - 6, opt.rect.height());
+ QString text = option.fontMetrics.elidedText(index.data().toString(), Qt::ElideRight, rect.width());
+ QPalette::ColorRole colorRole = (option.state & QStyle::State_Selected)
+ ? QPalette::HighlightedText
+ : QPalette::Text;
+
+ QApplication::style()->drawItemText(painter, rect, 0, option.palette, true, text, colorRole);
+ }
+ else if (index.column() == 1)
+ {
+ const QStandardItemModel* model = dynamic_cast<const QStandardItemModel*>(index.model());
+ const QmitkAnimationItem* thisItem = dynamic_cast<QmitkAnimationItem*>(model->item(index.row(), 1));
+ QList<const QmitkAnimationItem*> items;
+
+ const int rowCount = model->rowCount();
+
+ for (int i = 0; i < rowCount; ++i)
+ items << dynamic_cast<QmitkAnimationItem*>(model->item(i, 1));
+
+ double totalDuration = 0.0;
+ double previousStart = 0.0;
+ double thisStart = 0.0;
+
+ Q_FOREACH(const QmitkAnimationItem* item, items)
+ {
+ if (item->GetStartWithPrevious())
+ {
+ totalDuration = std::max(totalDuration, previousStart + item->GetDelay() + item->GetDuration());
+ }
+ else
+ {
+ previousStart = totalDuration;
+ totalDuration += item->GetDelay() + item->GetDuration();
+ }
+
+ if (item == thisItem)
+ thisStart = previousStart;
+ }
+
+ const QRect& rect = option.rect;
+ const double widthPerSecond = rect.width() / totalDuration;
+
+ QColor color = thisItem->GetStartWithPrevious()
+ ? QColor("DarkGray")
+ : QColor("DimGray");
+
+ painter->setBrush(color);
+ painter->setPen(Qt::NoPen);
+
+ painter->drawRect(
+ rect.x() + static_cast<int>(widthPerSecond * (thisStart + thisItem->GetDelay())),
+ rect.y() + 1,
+ static_cast<int>(widthPerSecond * thisItem->GetDuration()),
+ rect.height() - 2);
+
+ if (thisItem->GetDelay() > std::numeric_limits<double>::min())
+ {
+ QPen pen(color);
+ painter->setPen(pen);
+
+ painter->drawLine(
+ rect.x() + static_cast<int>(widthPerSecond * thisStart),
+ rect.y() + 1,
+ rect.x() + static_cast<int>(widthPerSecond * thisStart),
+ rect.y() + rect.height() - 2);
+
+ pen.setStyle(Qt::DashLine);
+ painter->setPen(pen);
+
+ painter->drawLine(
+ rect.x() + static_cast<int>(widthPerSecond * thisStart),
+ rect.y() + rect.height() / 2,
+ rect.x() + static_cast<int>(widthPerSecond * (thisStart + thisItem->GetDelay())) - 1,
+ rect.y() + rect.height() / 2);
+ }
+ }
+
+ painter->restore();
+}
diff --git a/Plugins/org.mitk.gui.qt.igttracking/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationItemDelegate.h
similarity index 58%
copy from Plugins/org.mitk.gui.qt.igttracking/src/internal/mitkPluginActivator.h
copy to Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationItemDelegate.h
index bcc0aed5a2..b1ad53c99a 100644
--- a/Plugins/org.mitk.gui.qt.igttracking/src/internal/mitkPluginActivator.h
+++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationItemDelegate.h
@@ -1,40 +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 QmitkAnimationItemDelegate_h
+#define QmitkAnimationItemDelegate_h
-#ifndef MITKPLUGINACTIVATOR_H
-#define MITKPLUGINACTIVATOR_H
+#include <QStyledItemDelegate>
-#include <ctkPluginActivator.h>
-
-namespace mitk {
-
-class PluginActivator :
- public QObject, public ctkPluginActivator
+class QmitkAnimationItemDelegate : public QStyledItemDelegate
{
Q_OBJECT
- Q_INTERFACES(ctkPluginActivator)
public:
+ explicit QmitkAnimationItemDelegate(QObject* parent = NULL);
+ ~QmitkAnimationItemDelegate();
- void start(ctkPluginContext* context);
- void stop(ctkPluginContext* context);
-
-}; // PluginActivator
-
-}
+ void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
+};
-#endif // MITKPLUGINACTIVATOR_H
+#endif
diff --git a/Modules/DiffusionImaging/MiniApps/mitkDiffusionMiniApps.cpp b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationWidget.cpp
old mode 100755
new mode 100644
similarity index 75%
rename from Modules/DiffusionImaging/MiniApps/mitkDiffusionMiniApps.cpp
rename to Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationWidget.cpp
index c7d6ac601a..45c861d9ab
--- a/Modules/DiffusionImaging/MiniApps/mitkDiffusionMiniApps.cpp
+++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationWidget.cpp
@@ -1,22 +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.
===================================================================*/
-#include <MiniAppManager.h>
+#include "QmitkAnimationWidget.h"
-int main(int argc, char* argv[])
+QmitkAnimationWidget::QmitkAnimationWidget(QWidget* parent)
+ : QWidget(parent)
+{
+}
+
+QmitkAnimationWidget::~QmitkAnimationWidget()
{
- return MiniAppManager::GetInstance()->RunMiniApp(argc, argv);
}
diff --git a/Plugins/org.mitk.gui.qt.igttracking/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationWidget.h
similarity index 59%
copy from Plugins/org.mitk.gui.qt.igttracking/src/internal/mitkPluginActivator.h
copy to Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationWidget.h
index bcc0aed5a2..103a7b5f6e 100644
--- a/Plugins/org.mitk.gui.qt.igttracking/src/internal/mitkPluginActivator.h
+++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkAnimationWidget.h
@@ -1,40 +1,35 @@
/*===================================================================
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 QmitkAnimationWidget_h
+#define QmitkAnimationWidget_h
-#ifndef MITKPLUGINACTIVATOR_H
-#define MITKPLUGINACTIVATOR_H
+#include <QWidget>
-#include <ctkPluginActivator.h>
+class QmitkAnimationItem;
-namespace mitk {
-
-class PluginActivator :
- public QObject, public ctkPluginActivator
+class QmitkAnimationWidget : public QWidget
{
Q_OBJECT
- Q_INTERFACES(ctkPluginActivator)
public:
+ explicit QmitkAnimationWidget(QWidget* parent = NULL);
+ virtual ~QmitkAnimationWidget();
- void start(ctkPluginContext* context);
- void stop(ctkPluginContext* context);
-
-}; // PluginActivator
-
-}
+ virtual void SetAnimationItem(QmitkAnimationItem* animationItem) = 0;
+};
-#endif // MITKPLUGINACTIVATOR_H
+#endif
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkFFmpegWriter.cpp b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkFFmpegWriter.cpp
new file mode 100644
index 0000000000..ae332ba296
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkFFmpegWriter.cpp
@@ -0,0 +1,176 @@
+/*===================================================================
+
+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 "QmitkFFmpegWriter.h"
+#include <QMessageBox>
+#include <mitkLogMacros.h>
+#include <mitkExceptionMacro.h>
+
+QmitkFFmpegWriter::QmitkFFmpegWriter(QObject* parent)
+ : QObject(parent),
+ m_Process(new QProcess(this)),
+ m_Framerate(0),
+ m_IsRunning(false)
+{
+ this->connect(m_Process, SIGNAL(error(QProcess::ProcessError)),
+ this, SLOT(OnProcessError(QProcess::ProcessError)));
+
+ this->connect(m_Process, SIGNAL(finished(int, QProcess::ExitStatus)),
+ this, SLOT(OnProcessFinished(int, QProcess::ExitStatus)));
+}
+
+QmitkFFmpegWriter::~QmitkFFmpegWriter()
+{
+}
+
+QString QmitkFFmpegWriter::GetFFmpegPath() const
+{
+ return m_FFmpegPath;
+}
+
+void QmitkFFmpegWriter::SetFFmpegPath(const QString& path)
+{
+ m_FFmpegPath = path;
+}
+
+QSize QmitkFFmpegWriter::GetSize() const
+{
+ return m_Size;
+}
+
+void QmitkFFmpegWriter::SetSize(const QSize& size)
+{
+ m_Size = size;
+}
+
+void QmitkFFmpegWriter::SetSize(int width, int height)
+{
+ m_Size = QSize(width, height);
+}
+
+int QmitkFFmpegWriter::GetFramerate() const
+{
+ return m_Framerate;
+}
+
+void QmitkFFmpegWriter::SetFramerate(int framerate)
+{
+ m_Framerate = framerate;
+}
+
+QString QmitkFFmpegWriter::GetOutputPath() const
+{
+ return m_OutputPath;
+}
+
+void QmitkFFmpegWriter::SetOutputPath(const QString& path)
+{
+ m_OutputPath = path;
+}
+
+void QmitkFFmpegWriter::Start()
+{
+ if (m_FFmpegPath.isEmpty())
+ mitkThrow() << "FFmpeg/Libav path is empty!";
+
+ if (m_Size.isNull())
+ mitkThrow() << "Invalid video frame size!";
+
+ if (m_Framerate <= 0)
+ mitkThrow() << "Invalid framerate!";
+
+ if (m_OutputPath.isEmpty())
+ mitkThrow() << "Output path is empty!";
+
+ m_Process->start(m_FFmpegPath, QStringList()
+ << "-y"
+ << "-f" << "rawvideo"
+ << "-pix_fmt" << "rgb24"
+ << "-s" << QString("%1x%2").arg(m_Size.width()).arg(m_Size.height())
+ << "-r" << QString("%1").arg(m_Framerate)
+ << "-i" << "-"
+ << "-vf" << "vflip"
+ << "-pix_fmt" << "yuv420p"
+ << "-crf" << "18"
+ << m_OutputPath);
+
+ m_Process->waitForStarted();
+ m_IsRunning = true;
+}
+
+bool QmitkFFmpegWriter::IsRunning() const
+{
+ return m_IsRunning;
+}
+
+void QmitkFFmpegWriter::WriteFrame(const unsigned char* frame)
+{
+ if (frame == NULL || !m_Process->isOpen())
+ return;
+
+ m_Process->write(reinterpret_cast<const char*>(frame), m_Size.width() * m_Size.height() * 3);
+ m_Process->waitForBytesWritten();
+}
+
+void QmitkFFmpegWriter::Stop()
+{
+ m_IsRunning = false;
+ m_Process->closeWriteChannel();
+}
+
+void QmitkFFmpegWriter::OnProcessError(QProcess::ProcessError error)
+{
+ m_IsRunning = false;
+
+ MITK_ERROR << QString::fromLatin1(m_Process->readAllStandardError()).toStdString();
+
+ switch (error)
+ {
+ case QProcess::FailedToStart:
+ mitkThrow() << "FFmpeg/Libav failed to start!";
+
+ case QProcess::Crashed:
+ mitkThrow() << "FFmpeg/Libav crashed!";
+
+ case QProcess::Timedout:
+ mitkThrow() << "FFmpeg/Libav timed out!";
+
+ case QProcess::WriteError:
+ mitkThrow() << "Could not write to FFmpeg/Libav!";
+
+ case QProcess::ReadError:
+ mitkThrow() << "Could not read from FFmpeg/Libav!";
+
+ default:
+ mitkThrow() << "An unknown error occurred!";
+ }
+}
+
+void QmitkFFmpegWriter::OnProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
+{
+ m_IsRunning = false;
+
+ if (exitStatus != QProcess::CrashExit)
+ {
+ if (exitCode != 0)
+ {
+ m_Process->close();
+ mitkThrow() << QString("FFmpeg/Libav exit code: %1").arg(exitCode).toStdString().c_str();
+ }
+ }
+
+ m_Process->close();
+}
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkFFmpegWriter.h b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkFFmpegWriter.h
new file mode 100644
index 0000000000..5527edb538
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkFFmpegWriter.h
@@ -0,0 +1,62 @@
+/*===================================================================
+
+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 QmitkFFmpegWriter_h
+#define QmitkFFmpegWriter_h
+
+#include <QProcess>
+#include <QSize>
+
+class QmitkFFmpegWriter : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit QmitkFFmpegWriter(QObject* parent = NULL);
+ ~QmitkFFmpegWriter();
+
+ QString GetFFmpegPath() const;
+ void SetFFmpegPath(const QString& path);
+
+ QSize GetSize() const;
+ void SetSize(const QSize& size);
+ void SetSize(int width, int height);
+
+ int GetFramerate() const;
+ void SetFramerate(int framerate);
+
+ QString GetOutputPath() const;
+ void SetOutputPath(const QString& path);
+
+ void Start();
+ bool IsRunning() const;
+ void WriteFrame(const unsigned char* frame);
+ void Stop();
+
+private slots:
+ void OnProcessError(QProcess::ProcessError error);
+ void OnProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
+
+private:
+ QProcess* m_Process;
+ QString m_FFmpegPath;
+ QSize m_Size;
+ int m_Framerate;
+ QString m_OutputPath;
+ bool m_IsRunning;
+};
+
+#endif
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMaker.cpp b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMaker.cpp
deleted file mode 100644
index 0d78c15e3c..0000000000
--- a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMaker.cpp
+++ /dev/null
@@ -1,769 +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 "QmitkMovieMaker.h"
-//#include "QmitkMovieMakerControls.h"
-#include "QmitkStepperAdapter.h"
-#include "QmitkStdMultiWidget.h"
-#include "QmitkMovieMaker.h"
-//#include "QmitkMovieMakerControls.h"
-#include "QmitkStepperAdapter.h"
-#include "QmitkStdMultiWidget.h"
-
-#include "mitkVtkPropRenderer.h"
-#include "mitkGlobalInteraction.h"
-
-#include <iostream>
-
-#include <vtkRenderer.h>
-#include <vtkCamera.h>
-
-#include <qaction.h>
-#include <qfiledialog.h>
-#include <qtimer.h>
-#include <qdatetime.h>
-#include <qspinbox.h>
-#include <qcombobox.h>
-
-#include "qapplication.h"
-
-#include "vtkImageWriter.h"
-#include "vtkJPEGWriter.h"
-#include "vtkPNGWriter.h"
-#include "vtkRenderLargeImage.h"
-#include "vtkRenderWindowInteractor.h"
-#include "vtkRenderer.h"
-#include "vtkTestUtilities.h"
-
-#include <vtkActor.h>
-#include "vtkMitkRenderProp.h"
-
-#include <vtkRenderer.h>
-#include <vtkRenderWindow.h>
-#include "vtkRenderWindowInteractor.h"
-#include <qradiobutton.h>
-
-QmitkMovieMaker::QmitkMovieMaker(QObject *parent, const char * /*name*/)
-
-:
- QmitkFunctionality(), m_Controls(NULL),
- m_StepperAdapter(NULL),
- m_FocusManagerCallback(0), m_Looping(true), m_Direction(0), m_Aspect(0)
-{
-
- parentWidget = parent;
-
- m_Timer = new QTimer(this);
- m_Time = new QTime();
-
- m_FocusManagerCallback = MemberCommand::New();
- m_FocusManagerCallback->SetCallbackFunction(this, &QmitkMovieMaker::FocusChange);
-
- m_movieGenerator = mitk::MovieGenerator::New();
-
- if (m_movieGenerator.IsNull())
- {
- MITK_ERROR << "Either mitk::MovieGenerator is not implemented for your";
- MITK_ERROR << " platform or an error occurred during";
- MITK_ERROR << " mitk::MovieGenerator::New()" ;
- }
-
-}
-
-QmitkMovieMaker::~QmitkMovieMaker()
-{
- delete m_StepperAdapter;
- delete m_Timer;
- delete m_Time;
- //delete m_RecordingRenderer;
-
-}
-
-mitk::BaseController* QmitkMovieMaker::GetSpatialController()
-{
- mitk::BaseRenderer* focusedRenderer = mitk::GlobalInteraction::GetInstance()->GetFocus();
-
- if (mitk::BaseRenderer::GetInstance(GetActiveStdMultiWidget()->mitkWidget1->GetRenderWindow())
- == focusedRenderer)
- {
- return GetActiveStdMultiWidget()->mitkWidget1->GetController();
- }
- else if (mitk::BaseRenderer::GetInstance(
- GetActiveStdMultiWidget()->mitkWidget2->GetRenderWindow()) == focusedRenderer)
- {
- return GetActiveStdMultiWidget()->mitkWidget2->GetController();
- }
- else if (mitk::BaseRenderer::GetInstance(
- GetActiveStdMultiWidget()->mitkWidget3->GetRenderWindow()) == focusedRenderer)
- {
- return GetActiveStdMultiWidget()->mitkWidget3->GetController();
- }
- else if (mitk::BaseRenderer::GetInstance(
- GetActiveStdMultiWidget()->mitkWidget4->GetRenderWindow()) == focusedRenderer)
- {
- return GetActiveStdMultiWidget()->mitkWidget4->GetController();
- }
-
- return GetActiveStdMultiWidget()->mitkWidget4->GetController();
-}
-
-mitk::BaseController* QmitkMovieMaker::GetTemporalController()
-{
- return GetActiveStdMultiWidget()->GetTimeNavigationController();
-}
-
-void QmitkMovieMaker::CreateConnections()
-{
- if (m_Controls)
- {
- // start / pause / stop playing
- connect((QObject*) m_Controls->btnPlay, SIGNAL(clicked()), (QObject*) this,
- SLOT(StartPlaying()));
- connect((QObject*) m_Controls->btnPause, SIGNAL(clicked()), this, SLOT(PausePlaying()));
- connect((QObject*) m_Controls->btnStop, SIGNAL(clicked()), this, SLOT(StopPlaying()));
-
- connect((QObject*) m_Controls->rbtnForward, SIGNAL(clicked()), this, SLOT(RBTNForward()));
- connect((QObject*) m_Controls->rbtnBackward, SIGNAL(clicked()), this, SLOT(RBTNBackward()));
- connect((QObject*) m_Controls->rbtnPingPong, SIGNAL(clicked()), this, SLOT(RBTNPingPong()));
-
- // radio button group: forward, backward, ping-pong
- connect( this, SIGNAL(SwitchDirection(int)), this, SLOT(SetDirection(int)) );
-
- // radio button group: spatial, temporal
- connect((QObject*) m_Controls->rbtnSpatial, SIGNAL(clicked()), this, SLOT(RBTNSpatial()));
- connect((QObject*) m_Controls->rbtnTemporal, SIGNAL(clicked()), this, SLOT(RBTNTemporal()));
- connect((QObject*) m_Controls->rbtnCombined, SIGNAL(clicked()), this, SLOT(RBTNCombined()));
- connect( this, SIGNAL(SwitchAspect(int)), this, SLOT(SetAspect(int)) );
-
- // stepper window selection
- connect((QObject*) (m_Controls->cmbSelectedStepperWindow), SIGNAL ( activated ( int) ), (QObject*) this, SLOT ( SetStepperWindow (int) ) );
-
- // recording window selection
- connect((QObject*) (m_Controls->cmbSelectedRecordingWindow), SIGNAL ( activated ( int) ), (QObject*) this, SLOT ( SetRecordingWindow (int) ) );
-
- // advance the animation
- // every timer tick
- connect((QObject*) m_Timer, SIGNAL(timeout()), this, SLOT(AdvanceAnimation()));
-
- // movie generation
- // when the movie button is clicked
- connect((QObject*) m_Controls->btnMovie, SIGNAL(clicked()), this, SLOT(GenerateMovie()));
-
- connect((QObject*) m_Controls->btnScreenshot, SIGNAL(clicked()), this, SLOT(
- GenerateScreenshot()));
- connect((QObject*) m_Controls->m_HRScreenshot, SIGNAL(clicked()), this, SLOT(
- GenerateHR3DScreenshot()));
-
- // blocking of ui elements during movie generation
- connect((QObject*) this, SIGNAL(StartBlockControls()), (QObject*) this, SLOT(BlockControls()));
-
- connect((QObject*) this, SIGNAL(EndBlockControls()), (QObject*) this, SLOT(UnBlockControls()));
-
- connect((QObject*) this, SIGNAL(EndBlockControlsMovieDeactive()), (QObject*) this, SLOT(
- UnBlockControlsMovieDeactive()));
-
- // allow for change of spatialtime relation
- connect((QObject*) m_Controls->spatialTimeRelation, SIGNAL(valueChanged ( int ) ), this, SLOT( DeleteMStepper() ) );
-
-
- m_Controls->btnScreenshot->setVisible(false);
- m_Controls->m_HRScreenshot->setVisible(false);
- }
-}
-
-void QmitkMovieMaker::Activated()
-{
- QmitkFunctionality::Activated();
-
- // create a member command that will be executed from the observer
- itk::SimpleMemberCommand<QmitkMovieMaker>::Pointer stepperChangedCommand;
- stepperChangedCommand = itk::SimpleMemberCommand<QmitkMovieMaker>::New();
- // set the callback function of the member command
- stepperChangedCommand->SetCallbackFunction(this, &QmitkMovieMaker::UpdateGUI);
- // add an observer to the data tree node pointer connected to the above member command
- MITK_INFO << "Add observer on insertion point node in NavigationPathController::AddObservers";
- m_StepperObserverTag = this->GetTemporalController()->GetTime()->AddObserver(
- itk::ModifiedEvent(), stepperChangedCommand);
-
- m_FocusManagerObserverTag
- = mitk::GlobalInteraction::GetInstance()->GetFocusManager()->AddObserver(mitk::FocusEvent(),
- m_FocusManagerCallback);
- this->UpdateGUI();
- // Initialize steppers etc.
- this->FocusChange();
-}
-
-void QmitkMovieMaker::Deactivated()
-{
- QmitkFunctionality::Deactivated();
- this->GetTemporalController()->GetTime()->RemoveObserver(m_StepperObserverTag);
- mitk::GlobalInteraction::GetInstance()->GetFocusManager()->RemoveObserver(
- m_FocusManagerObserverTag); // remove (if tag is invalid, nothing is removed)
-}
-
-void QmitkMovieMaker::FocusChange()
-{
- mitk::Stepper *stepper = this->GetAspectStepper();
- m_StepperAdapter->SetStepper(stepper);
-
- // Make the stepper movement non-inverted
- stepper->InverseDirectionOff();
-
- // Set stepping direction and aspect (spatial / temporal) for new stepper
- this->UpdateLooping();
- this->UpdateDirection();
-
- // Set newly focused window as active in "Selected Window" combo box
- const mitk::RenderingManager::RenderWindowVector rwv =
- mitk::RenderingManager::GetInstance()->GetAllRegisteredRenderWindows();
-
- int i;
- mitk::RenderingManager::RenderWindowVector::const_iterator iter;
- for (iter = rwv.begin(), i = 0; iter != rwv.end(); ++iter, ++i)
- {
- mitk::BaseRenderer* focusedRenderer =
- mitk::GlobalInteraction::GetInstance()->GetFocusManager()->GetFocused();
-
- if (focusedRenderer == mitk::BaseRenderer::GetInstance((*iter)))
- {
- m_Controls->cmbSelectedStepperWindow->setCurrentIndex(i);
- // this->cmbSelectedStepperWindow_activated(i);
- this->SetStepperWindow(i);
- m_Controls->cmbSelectedRecordingWindow->setCurrentIndex(i);
- // this->cmbSelectedRecordWindow_activated(i);
- this->SetRecordingWindow(i);
- break;
- }
- }
-}
-
-void QmitkMovieMaker::AdvanceAnimation()
-{
- // This method is called when a timer timeout occurs. It increases the
- // stepper value according to the elapsed time and the stepper interval.
- // Note that a screen refresh is not forced, but merely requested, and may
- // occur only after more calls to AdvanceAnimation().
-
- mitk::Stepper* stepper = this->GetAspectStepper();
-
- m_StepperAdapter->SetStepper(stepper);
-
- int elapsedTime = m_Time->elapsed();
- m_Time->restart();
-
- static double increment = 0.0;
- increment = increment - static_cast<int> (increment);
- increment += elapsedTime * stepper->GetSteps() / (m_Controls->spnDuration->value() * 1000.0);
-
- int i, n = static_cast<int> (increment);
- for (i = 0; i < n; ++i)
- {
- stepper->Next();
- }
-}
-
-void QmitkMovieMaker::RenderSlot()
-{
- int *i = widget->GetRenderWindow()->GetSize();
- m_PropRenderer->Resize(i[0], i[1]);
-
- widget->GetRenderWindow()->Render();
-}
-
-void QmitkMovieMaker::PausePlaying()
-{
-
- m_Controls->slidAngle->setDisabled(false);
- m_Controls->btnMovie->setEnabled(true);
- m_Controls->btnPlay->setEnabled(true);
- m_Controls->btnScreenshot->setEnabled(true);
-
- m_Timer->stop();
-
- m_Controls->btnPlay->setHidden(false);
- m_Controls->btnPause->setHidden(true);
- if (m_movieGenerator.IsNull())
- m_Controls->btnMovie->setEnabled(false);
-}
-
-void QmitkMovieMaker::StopPlaying()
-{
- m_Controls->slidAngle->setDisabled(false);
- m_Controls->btnMovie->setEnabled(true);
- m_Controls->btnPlay->setEnabled(true);
- m_Controls->btnScreenshot->setEnabled(true);
-
- m_Controls->btnPlay->setHidden(false);
- m_Controls->btnPause->setHidden(true);
-
- m_Timer->stop();
- switch (m_Direction)
- {
- case 0:
- case 2:
- this->GetAspectStepper()->First();
- break;
-
- case 1:
- this->GetAspectStepper()->Last();
- break;
- }
-
- // Reposition slider GUI element
- m_StepperAdapter->SetStepper(this->GetAspectStepper());
-
- if (m_movieGenerator.IsNull())
- m_Controls->btnMovie->setEnabled(false);
-
-}
-
-void QmitkMovieMaker::SetLooping(bool looping)
-{
- m_Looping = looping;
- this->UpdateLooping();
-}
-
-void QmitkMovieMaker::SetDirection(int direction)
-{
- m_Direction = direction;
- this->UpdateDirection();
-}
-
-void QmitkMovieMaker::SetAspect(int aspect)
-{
- m_Aspect = aspect;
-
- m_StepperAdapter->SetStepper(this->GetAspectStepper());
- this->UpdateLooping();
- this->UpdateDirection();
-}
-
-void QmitkMovieMaker::SetStepperWindow(int window)
-{
- // Set newly selected window / renderer as focused
- const mitk::RenderingManager::RenderWindowVector rwv =
- mitk::RenderingManager::GetInstance()->GetAllRegisteredRenderWindows();
-
- //Delete MultiStepper
- DeleteMStepper();
-
- int i;
- mitk::RenderingManager::RenderWindowVector::const_iterator iter;
- for (iter = rwv.begin(), i = 0; iter != rwv.end(); ++iter, ++i)
- {
- if (i == window)
- {
- mitk::GlobalInteraction::GetInstance()->GetFocusManager() ->SetFocused(
- mitk::BaseRenderer::GetInstance((*iter)));
- break;
- }
- }
-}
-
-void QmitkMovieMaker::SetRecordingWindow(int window)
-{
- // Set newly selected window for recording
- const mitk::RenderingManager::RenderWindowVector rwv =
- mitk::RenderingManager::GetInstance()->GetAllRegisteredRenderWindows();
-
- //Delete MultiStepper
- DeleteMStepper();
-
- int i;
- mitk::RenderingManager::RenderWindowVector::const_iterator iter;
- for (iter = rwv.begin(), i = 0; iter != rwv.end(); ++iter, ++i)
- {
- if (i == window)
- {
- m_RecordingRenderer = mitk::BaseRenderer::GetInstance((*iter));
- break;
- }
- }
-}
-
-void QmitkMovieMaker::UpdateLooping()
-{
- this->GetAspectStepper()->SetAutoRepeat(m_Looping);
-}
-
-void QmitkMovieMaker::UpdateDirection()
-{
- mitk::Stepper* stepper = this->GetAspectStepper();
-
- switch (m_Direction)
- {
- case 0:
- stepper->InverseDirectionOff();
- stepper->PingPongOff();
- break;
-
- case 1:
- stepper->InverseDirectionOn();
- stepper->PingPongOff();
- break;
-
- case 2:
- stepper->PingPongOn();
- break;
- }
-}
-
-mitk::Stepper* QmitkMovieMaker::GetAspectStepper()
-{
- if (m_Aspect == 0)
- {
- m_Stepper = NULL;
- return this->GetSpatialController()->GetSlice();
- }
- else if (m_Aspect == 1)
- {
- m_Stepper = NULL;
- return this->GetTemporalController()->GetTime();
- }
- else if (m_Aspect == 2)
- {
- if (m_Stepper.IsNull())
- {
- int rel = m_Controls->spatialTimeRelation->value();
- int timeRepeat = 1;
- int sliceRepeat = 1;
- if (rel < 0)
- {
- sliceRepeat = -rel;
- }
- else if (rel > 0)
- {
- timeRepeat = rel;
- }
- m_Stepper = mitk::MultiStepper::New();
- m_Stepper->AddStepper(this->GetSpatialController()->GetSlice(), sliceRepeat);
- m_Stepper->AddStepper(this->GetTemporalController()->GetTime(), timeRepeat);
- }
-
- return m_Stepper.GetPointer();
- }
- else
- {
- // should never get here
- return 0;
- }
-}
-
-void QmitkMovieMaker::GenerateMovie()
-{
- emit StartBlockControls();
-
- // provide the movie generator with the stepper and rotate the camera each step
- if (m_movieGenerator.IsNotNull())
- {
- m_movieGenerator->SetStepper(this->GetAspectStepper());
- m_movieGenerator->SetRenderer(m_RecordingRenderer);
- m_movieGenerator->SetFrameRate(static_cast<unsigned int> (360
- / (m_Controls->spnDuration->value())));
-
- // QString movieFileName = QFileDialog::getSaveFileName( QString::null, "Movie (*.avi)", 0, "movie file dialog", "Choose a file name" );
-
- QString movieFileName = QFileDialog::getSaveFileName(0, "Choose a file name", QString::null,
- "Movie (*.avi)", 0, 0);
-
- if (movieFileName.isEmpty() == false)
- {
- mitk::RenderingManager::GetInstance()->RequestUpdateAll();
- m_movieGenerator->SetFileName(movieFileName.toAscii());
- m_movieGenerator->WriteMovie();
- }
-
- emit EndBlockControls();
- }
- else
- {
- MITK_ERROR << "Either mitk::MovieGenerator is not implemented for your";
- MITK_ERROR << " platform or an error occurred during";
- MITK_ERROR << " mitk::MovieGenerator::New()";
-
- emit EndBlockControlsMovieDeactive();
- }
-}
-
-void QmitkMovieMaker::GenerateScreenshot()
-{
- emit StartBlockControls();
-
- QString fileName = QFileDialog::getSaveFileName(NULL, "Save screenshot to...", QDir::currentPath(), "JPEG file (*.jpg);;PNG file (*.png)");
-
- vtkRenderer* renderer = mitk::GlobalInteraction::GetInstance()->GetFocus()->GetVtkRenderer();
- if (renderer == NULL)
- return;
- this->TakeScreenshot(renderer, 1, fileName);
-
- if (m_movieGenerator.IsNotNull())
- emit EndBlockControls();
- else
- emit EndBlockControlsMovieDeactive();
-}
-
-void QmitkMovieMaker::GenerateHR3DScreenshot()
-{
- emit StartBlockControls();
-
- QString fileName = QFileDialog::getSaveFileName(NULL, "Save screenshot to...", QDir::currentPath(), "JPEG file (*.jpg);;PNG file (*.png)");
-
- // only works correctly for 3D RenderWindow
- vtkRenderer* renderer = m_MultiWidget->mitkWidget4->GetRenderer()->GetVtkRenderer();
- if (renderer == NULL)
- return;
- this->TakeScreenshot(renderer, 4, fileName);
-
- if (m_movieGenerator.IsNotNull())
- emit EndBlockControls();
- else
- emit EndBlockControlsMovieDeactive();
-}
-
-void QmitkMovieMaker::UpdateGUI()
-{
- int bla = this->GetTemporalController()->GetTime()->GetSteps();
- if (bla < 2)
- {
- m_Controls->rbtnTemporal->setEnabled(false);
- m_Controls->rbtnCombined->setEnabled(false);
- m_Controls->spatialTimeRelation->setEnabled(false);
- }
- else
- {
- m_Controls->rbtnTemporal->setEnabled(true);
- m_Controls->rbtnCombined->setEnabled(true);
- m_Controls->spatialTimeRelation->setEnabled(true);
- }
-
-}
-
-void QmitkMovieMaker::DataStorageChanged()
-{
- // UpdateGUI();
-}
-
-void QmitkMovieMaker::CreateQtPartControl(QWidget *parent)
-{
- if (!m_Controls)
- {
- m_Controls = new Ui::QmitkMovieMakerControls;
- m_Controls->setupUi(parent);
-
- m_StepperAdapter = new QmitkStepperAdapter((QObject*) m_Controls->slidAngle,
- this->GetSpatialController()->GetSlice(), "AngleStepperToMovieMakerFunctionality");
-
- // Initialize "Selected Window" combo box
- const mitk::RenderingManager::RenderWindowVector rwv =
- mitk::RenderingManager::GetInstance()->GetAllRegisteredRenderWindows();
-
- mitk::RenderingManager::RenderWindowVector::const_iterator iter;
- unsigned int i = 0;
- for (iter = rwv.begin(); iter != rwv.end(); ++iter)
- {
- QString name(mitk::BaseRenderer::GetInstance((*iter))->GetName());
- if (name=="stdmulti.widget1")
- {
- m_Controls->cmbSelectedStepperWindow->insertItem(i, "Axial");
- m_Controls->cmbSelectedRecordingWindow->insertItem(i++, "Axial");
- }
- else if (name=="stdmulti.widget2")
- {
- m_Controls->cmbSelectedStepperWindow->insertItem(i, "Sagittal");
- m_Controls->cmbSelectedRecordingWindow->insertItem(i++, "Sagittal");
- }
- else if (name=="stdmulti.widget3")
- {
- m_Controls->cmbSelectedStepperWindow->insertItem(i, "Coronal");
- m_Controls->cmbSelectedRecordingWindow->insertItem(i++, "Coronal");
- }
- else if (name=="stdmulti.widget4")
- {
- m_Controls->cmbSelectedStepperWindow->insertItem(i, "3D Window");
- m_Controls->cmbSelectedRecordingWindow->insertItem(i++, "3D Window");
- }
- else
- {
- m_Controls->cmbSelectedStepperWindow->insertItem(i, name);
- m_Controls->cmbSelectedRecordingWindow->insertItem(i++, name);
- }
- }
-
- m_Controls->btnPause->setHidden(true);
- if (m_movieGenerator.IsNull())
- m_Controls->btnMovie->setEnabled(false);
- }
-
- this->CreateConnections();
-
-}
-
-void QmitkMovieMaker::StartPlaying()
-{
- m_Controls->slidAngle->setDisabled(true);
- m_Controls->btnMovie->setEnabled(false);
- m_Controls->btnPlay->setEnabled(false);
- m_Controls->btnScreenshot->setEnabled(false);
-
- // Restart timer with 5 msec interval - this should be fine-grained enough
- // even for high display refresh frequencies
- m_Timer->start(5);
-
- m_Time->restart();
-
- m_Controls->btnPlay->setHidden(true);
- m_Controls->btnPause->setHidden(false);
- if (m_movieGenerator.IsNull())
- m_Controls->btnMovie->setEnabled(false);
-
-}
-
-void QmitkMovieMaker::RBTNForward()
-{
- emit SwitchDirection(0);
-}
-
-void QmitkMovieMaker::RBTNBackward()
-{
- emit SwitchDirection(1);
-}
-
-void QmitkMovieMaker::RBTNPingPong()
-{
- emit SwitchDirection(2);
-}
-
-void QmitkMovieMaker::RBTNSpatial()
-{
- emit SwitchAspect(0);
-}
-
-void QmitkMovieMaker::RBTNTemporal()
-{
- emit SwitchAspect(1);
-}
-
-void QmitkMovieMaker::RBTNCombined()
-{
- emit SwitchAspect(2);
-}
-
-void QmitkMovieMaker::BlockControls()
-{
- BlockControls(true);
-}
-
-void QmitkMovieMaker::UnBlockControls()
-{
- BlockControls(false);
-}
-
-void QmitkMovieMaker::UnBlockControlsMovieDeactive()
-{
- BlockControls(false);
-
- m_Controls->btnMovie->setEnabled(false);
-}
-
-void QmitkMovieMaker::BlockControls(bool blocked)
-{
- m_Controls->slidAngle->setDisabled(blocked);
- m_Controls->spnDuration->setEnabled(!blocked);
- m_Controls->btnPlay->setEnabled(!blocked);
- m_Controls->btnMovie->setEnabled(!blocked);
- m_Controls->btnScreenshot->setEnabled(!blocked);
-}
-
-void QmitkMovieMaker::StdMultiWidgetAvailable(QmitkStdMultiWidget& stdMultiWidget)
-{
- m_MultiWidget = &stdMultiWidget;
- m_Parent->setEnabled(true);
-}
-
-void QmitkMovieMaker::StdMultiWidgetNotAvailable()
-{
- m_MultiWidget = NULL;
- m_Parent->setEnabled(false);
-}
-
-void QmitkMovieMaker::TakeScreenshot(vtkRenderer* renderer, unsigned int magnificationFactor, QString fileName)
-{
- if ((renderer == NULL) ||(magnificationFactor < 1) || fileName.isEmpty())
- return;
-
- bool doubleBuffering( renderer->GetRenderWindow()->GetDoubleBuffer() );
- renderer->GetRenderWindow()->DoubleBufferOff();
-
- vtkImageWriter* fileWriter;
-
- QFileInfo fi(fileName);
- QString suffix = fi.suffix();
- if (suffix.compare("png", Qt::CaseInsensitive) == 0)
- {
- fileWriter = vtkPNGWriter::New();
- }
- else // default is jpeg
- {
- vtkJPEGWriter* w = vtkJPEGWriter::New();
- w->SetQuality(100);
- w->ProgressiveOff();
- fileWriter = w;
- }
- vtkRenderLargeImage* magnifier = vtkRenderLargeImage::New();
- magnifier->SetInput(renderer);
- magnifier->SetMagnification(magnificationFactor);
- //magnifier->Update();
- fileWriter->SetInputConnection(magnifier->GetOutputPort());
- fileWriter->SetFileName(fileName.toLatin1());
-
- // vtkRenderLargeImage has problems with different layers, therefore we have to
- // temporarily deactivate all other layers.
- // we set the background to white, because it is nicer than black...
- double oldBackground[3];
- renderer->GetBackground(oldBackground);
- double white[] = {1.0, 1.0, 1.0};
- renderer->SetBackground(white);
- m_MultiWidget->DisableColoredRectangles();
- m_MultiWidget->DisableDepartmentLogo();
- m_MultiWidget->DisableGradientBackground();
-
- m_MultiWidget->mitkWidget1->ActivateMenuWidget( false );
- m_MultiWidget->mitkWidget2->ActivateMenuWidget( false );
- m_MultiWidget->mitkWidget3->ActivateMenuWidget( false );
- m_MultiWidget->mitkWidget4->ActivateMenuWidget( false );
-
- fileWriter->Write();
- fileWriter->Delete();
-
- m_MultiWidget->mitkWidget1->ActivateMenuWidget( true );
- m_MultiWidget->mitkWidget2->ActivateMenuWidget( true );
- m_MultiWidget->mitkWidget3->ActivateMenuWidget( true );
- m_MultiWidget->mitkWidget4->ActivateMenuWidget( true );
-
- m_MultiWidget->EnableColoredRectangles();
- m_MultiWidget->EnableDepartmentLogo();
- m_MultiWidget->EnableGradientBackground();
- renderer->SetBackground(oldBackground);
-
- renderer->GetRenderWindow()->SetDoubleBuffer(doubleBuffering);
-}
-
-void QmitkMovieMaker::DeleteMStepper()
-{
- m_Stepper = NULL;
- UpdateLooping();
-}
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMaker.h b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMaker.h
deleted file mode 100644
index ea91684197..0000000000
--- a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMaker.h
+++ /dev/null
@@ -1,300 +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.
-
-===================================================================*/
-
-#if !defined(QMITK_MOVIEMAKER_H__INCLUDED)
-#define QMITK_MOVIEMAKER_H__INCLUDED
-
-#include "QmitkFunctionality.h"
-#include "mitkCameraRotationController.h"
-#include "mitkStepper.h"
-#include "mitkMultiStepper.h"
-#include "mitkMovieGenerator.h"
-#include "itkCommand.h"
-
-#include "QVTKWidget.h"
-#include "vtkEventQtSlotConnect.h"
-#include "vtkRenderWindow.h"
-#include "mitkVtkPropRenderer.h"
-
-#include "ui_QmitkMovieMakerControls.h"
-//#include "../MovieMakerDll.h"
-
-//class QmitkStdMultiWidget;
-//class QmitkMovieMakerControls;
-class QmitkStepperAdapter;
-class vtkCamera;
-class QTimer;
-class QTime;
-
-/**
- * \brief Functionality for creating movies (AVIs)
- * \ingroup Functionalities
- *
- *
- * - \ref QmitkMovieMakerOverview
- * - \ref QmitkMovieMakerImplementation
- * - \ref QmitkMovieMakerTodo
- *
- * \section QmitkMovieMakerOverview Overview
- *
- * The MovieMaker functionality extends existing modes of data visualization
- * with animation capabilities. The animation aspect determines which
- * aspect of a visualization gets animated. This aspect can be spatial
- * (i.e. the camera position and orientation in a 3D view, or the selected
- * slice in a 2D view), temporal (the time step in a time-based dataset), or
- * something more sophisticated (for example, volume rendering transfer
- * functions might be changed dynamically as part of an animation to produce
- * interesting effects). Currently, the following animation modes are
- * supported:
- *
- * - Rotation of the camera around the dataset (3D views)
- * - Stepping through the dataset slice by slice (2D views)
- * - Stepping through a time-based dataset (2D and 3D views)
- *
- * As can be seen in the screenshot below, the functionality provides cine
- * controls to start, pause and stop the animation. The direction of the
- * animation can be selected (forward, backward or ping-pong). The animation
- * can be set to either the spatial or the temporal aspect, or to both
- * aspects combined. The cycle time determines the duration of one animation
- * loop.
- *
- * In a multi-view scenario, the animation is applied to the currently
- * focussed view. Other views which display the same data may be affected as
- * well.
- *
- * Animations can be written on disk; the corresponding button creates an
- * animation consisting of one single loop and writes every animation frame
- * into an AVI file.
- *
- * \image html QmitkMovieMakerGUI.png
- *
- * \section QmitkMovieMakerImplementation Implementation
- *
- * The following diagram provides an overview over the classes collaborating
- * with QmitkMovieMaker.
- *
- * \image html QmitkMovieMakerClasses.png
- *
- * The respective roles of these classes are:
- * - QmitkMovieMaker
- * - Provides a class interface for configuring and controlling the
- * animation
- * - Is associated with the user interface
- * - As a Functionality, controls initialization and maintainance of the
- * involved components
- * - mitk::BaseController
- * - Controls an animation aspect (slice selection, camera angle, ...)
- * - Subclass mitk::SliceNavigationController: Transfers the animation
- * requests to the associated Renderer for selecting a slice in a 3D
- * dataset
- * - Subclass mitk::CameraRotationController: Modifies the camera angle
- * - mitk::Stepper
- * - Link between MovieMaker and Controller
- * - Holds the current step position of the associated animation aspect
- * (e.g. the camera rotation angle, or the slice number)
- * - mitk::FocusManager
- * - Determines which of the available RenderWindows (and thereby which
- * Renderers) the animation shall be applied to
- * - mitk::BaseRenderer
- * - Controls the rendering of a dataset
- * - Target class of the animation
- * - mitk::MovieGenerator
- * - Writes an AVI file
- *
- *
- * \section QmitkMovieMakerTodo Future plans
- *
- * The basic animation capabilities of this functionality could be extended
- * to allow the creation of more sophisticated animations. Potentially useful
- * features include:
- *
- * - <em>Camera paths</em>: Allow the definition of complex camera paths along
- * which the camera can then be moved during an animation. This might be
- * done by defining camera keyframes between which camera movements are
- * interpolated (as in standard 3D animation applications). Paths derived
- * from anatomical features (e.g. vessel graphs) could also serve as a
- * basis for camera movements.
- * - <em>Color / transfer function animation</em>: Choosing suitable color
- * and transfer functions is critical to the quality and benefit of volume
- * rendering. Dynamically changing transfer functions could visually enrich
- * an animation. One way of achieving this could be to define transfer
- * function keyframes between which an animation interpolates.
- *
- */
-class QmitkMovieMaker: public QmitkFunctionality
-{
- Q_OBJECT
-
-public:
- /** \brief Constructor. */
- QmitkMovieMaker(QObject *parent=0, const char *name=0);
-
- /** \brief Destructor. */
- virtual ~QmitkMovieMaker();
-
- /** \brief Method for creating the widget containing the application
- * controls, like sliders, buttons etc.
- */
- void CreateQtPartControl(QWidget *parent);
- // virtual QWidget * CreateControlWidget(QWidget *parent);
-
- /** \brief Method for creating the connections of main and control widget.
- */
- virtual void CreateConnections();
-
- /** \brief Method for creating an QAction object, i.e. button & menu entry.
- * @param parent the parent QWidget
- */
- // virtual QAction * CreateAction(QActionGroup *parent);
-
- virtual void Activated();
-
- virtual void Deactivated();
-
- /** \brief Called when another window receives the focus. */
- void FocusChange();
-
- virtual void DataStorageChanged();
-
- ///
- /// Called when a StdMultiWidget is available.
- ///
- virtual void StdMultiWidgetAvailable(QmitkStdMultiWidget& stdMultiWidget);
- ///
- /// Called when no StdMultiWidget is available.
- ///
- virtual void StdMultiWidgetNotAvailable();
-
- signals:
- void StartBlockControls();
- void EndBlockControls();
- void EndBlockControlsMovieDeactive();
-
-public slots:
-
- /** \brief Start playing the animation by restarting the timer. */
- void StartPlaying();
-
- /** \brief Pauses playing the animation by stopping the timer. */
- void PausePlaying();
-
- /** \brief Stops playing the animation and resets the stepper. */
- void StopPlaying();
-
- /** \brief Sets animation looping ON/OFF. */
- void SetLooping(bool looping);
-
- /** \brief Sets the direction: 0 = forward, 1 = backward, 2 = pingpong. */
- void SetDirection(int direction);
-
- /** \brief Sets the animation aspect:
- * 0 = spatial, 1 = temporal, 2 = combined.
- */
- void SetAspect(int aspect);
-
- /** \brief Sets a specified stepper window, which is moving. */
- void SetStepperWindow(int window);
-
- /** \brief Sets a specified recording window, from which the movie is generated. */
- void SetRecordingWindow(int window);
-
- /** \brief Advances the animation by one frame.
- * Exactly how much the stepper advances depends on the time elapsed since
- * the last call to this function.
- */
- void AdvanceAnimation();
-
-protected slots:
-
- void RenderSlot();
- void GenerateMovie();
-
- void GenerateScreenshot();
- void GenerateHR3DScreenshot();
- void RBTNForward();
- void RBTNBackward();
- void RBTNPingPong();
- void RBTNSpatial();
- void RBTNTemporal();
- void RBTNCombined();
- void BlockControls();
- void UnBlockControls();
- void UnBlockControlsMovieDeactive();
- void BlockControls(bool blocked);
-
- void DeleteMStepper();
-
- signals:
-
- void SwitchDirection(int);
- void SwitchAspect(int);
- void SwitchSelectedStepperWindow(int);
- void SwitchSelectedRecordingWindow(int);
-
-protected:
-
- QObject *parentWidget;
- QVTKWidget * widget;
- QmitkStdMultiWidget* m_MultiWidget;
- vtkEventQtSlotConnect * connections;
- vtkRenderWindow * renderWindow;
- mitk::VtkPropRenderer::Pointer m_PropRenderer;
-
- Ui::QmitkMovieMakerControls* m_Controls;
-
-private:
- mitk::BaseController* GetSpatialController();
-
- mitk::BaseController* GetTemporalController();
-
- void UpdateLooping();
-
- void UpdateDirection();
-
- void UpdateGUI();
-
- mitk::Stepper* GetAspectStepper();
-
- /*!
- \brief taking a screenshot "from" the specified renderer
- \param magnificationFactor specifying the quality of the screenshot (the magnification of the actual RenderWindow size)
- \param fileName file location and name where the screenshot should be saved
- */
- void TakeScreenshot(vtkRenderer* renderer, unsigned int magnificationFactor, QString fileName);
-
- QmitkStepperAdapter* m_StepperAdapter;
-
- typedef itk::SimpleMemberCommand<QmitkMovieMaker> MemberCommand;
- MemberCommand::Pointer m_FocusManagerCallback;
-
- QTimer* m_Timer;
-
- QTime* m_Time;
-
- bool m_Looping;
- int m_Direction;
-
- int m_Aspect;
- mitk::MultiStepper::Pointer m_Stepper;
- mitk::BaseRenderer * m_RecordingRenderer;
-
- mitk::MovieGenerator::Pointer m_movieGenerator;
-
- unsigned long m_FocusManagerObserverTag;
- unsigned long m_StepperObserverTag;
-
-};
-#endif // !defined(QMITK_MOVIEMAKER_H__INCLUDED)
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMakerControls.ui b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMakerControls.ui
deleted file mode 100644
index 68dd4a6fa2..0000000000
--- a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMakerControls.ui
+++ /dev/null
@@ -1,454 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>QmitkMovieMakerControls</class>
- <widget class="QWidget" name="QmitkMovieMakerControls">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>423</width>
- <height>665</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>MovieMaker</string>
- </property>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="0" column="0">
- <widget class="QLabel" name="textLabel3">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="font">
- <font>
- <weight>75</weight>
- <bold>true</bold>
- </font>
- </property>
- <property name="text">
- <string>Window for stepping</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="0" colspan="2">
- <widget class="QComboBox" name="cmbSelectedStepperWindow">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="textLabel3_2">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="font">
- <font>
- <weight>75</weight>
- <bold>true</bold>
- </font>
- </property>
- <property name="text">
- <string>Window for recording</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="3" column="0" colspan="2">
- <widget class="QComboBox" name="cmbSelectedRecordingWindow">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- <item row="4" column="0" colspan="2">
- <widget class="QGroupBox" name="groupBox">
- <property name="font">
- <font>
- <weight>75</weight>
- <bold>true</bold>
- </font>
- </property>
- <property name="title">
- <string>Recording options</string>
- </property>
- <layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0" colspan="2">
- <layout class="QHBoxLayout">
- <item>
- <widget class="QLabel" name="textLabel1">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="font">
- <font/>
- </property>
- <property name="text">
- <string>Step</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QmitkSliderNavigatorWidget" name="slidAngle" native="true"/>
- </item>
- </layout>
- </item>
- <item row="1" column="0" colspan="2">
- <layout class="QHBoxLayout">
- <item>
- <widget class="QToolButton" name="btnPlay">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="font">
- <font/>
- </property>
- <property name="toolTip">
- <string>Start stepper</string>
- </property>
- <property name="text">
- <string/>
- </property>
- <property name="icon">
- <iconset resource="../../../../../../../mitkBinaryCTK/MITK-superbuild/MITK-build/Modules/Bundles/org.mitk.gui.qt.moviemaker/org_mitk_gui_qt_moviemaker_cached.qrc">
- <normaloff>:/org.mitk.gui.qt.moviemaker/resources/play.xpm</normaloff>:/org.mitk.gui.qt.moviemaker/resources/play.xpm</iconset>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QToolButton" name="btnPause">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="font">
- <font/>
- </property>
- <property name="toolTip">
- <string>Pause stepper</string>
- </property>
- <property name="text">
- <string/>
- </property>
- <property name="icon">
- <iconset resource="../../../../../../../mitkBinaryCTK/MITK-superbuild/MITK-build/Modules/Bundles/org.mitk.gui.qt.moviemaker/org_mitk_gui_qt_moviemaker_cached.qrc">
- <normaloff>:/org.mitk.gui.qt.moviemaker/resources/pause.xpm</normaloff>:/org.mitk.gui.qt.moviemaker/resources/pause.xpm</iconset>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QToolButton" name="btnStop">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="font">
- <font/>
- </property>
- <property name="toolTip">
- <string>Stop stepper</string>
- </property>
- <property name="text">
- <string/>
- </property>
- <property name="icon">
- <iconset resource="../../../../../../../mitkBinaryCTK/MITK-superbuild/MITK-build/Modules/Bundles/org.mitk.gui.qt.moviemaker/org_mitk_gui_qt_moviemaker_cached.qrc">
- <normaloff>:/org.mitk.gui.qt.moviemaker/resources/stop.xpm</normaloff>:/org.mitk.gui.qt.moviemaker/resources/stop.xpm</iconset>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="2" column="0" colspan="2">
- <widget class="QToolButton" name="btnMovie">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="font">
- <font/>
- </property>
- <property name="text">
- <string>Write Movie (MS Windows only) ...</string>
- </property>
- </widget>
- </item>
- <item row="3" column="0">
- <widget class="QToolButton" name="btnScreenshot">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="font">
- <font/>
- </property>
- <property name="toolTip">
- <string>Writes a screenshot of the selected window.</string>
- </property>
- <property name="text">
- <string>Write Screenshot</string>
- </property>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="QToolButton" name="m_HRScreenshot">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="font">
- <font/>
- </property>
- <property name="toolTip">
- <string>Writes a screenshot of the selected window.</string>
- </property>
- <property name="text">
- <string>Write high resolution 3D Screenshot</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="5" column="0" colspan="2">
- <widget class="QGroupBox" name="groupBox_2">
- <property name="font">
- <font>
- <weight>75</weight>
- <bold>true</bold>
- </font>
- </property>
- <property name="title">
- <string>Playing options</string>
- </property>
- <layout class="QVBoxLayout">
- <item>
- <widget class="QWidget" name="buttonGroup1" native="true">
- <layout class="QVBoxLayout">
- <item>
- <widget class="QRadioButton" name="rbtnSpatial">
- <property name="font">
- <font/>
- </property>
- <property name="text">
- <string>Spatial</string>
- </property>
- <property name="checked">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QRadioButton" name="rbtnTemporal">
- <property name="font">
- <font/>
- </property>
- <property name="text">
- <string>Temporal</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QRadioButton" name="rbtnCombined">
- <property name="font">
- <font/>
- </property>
- <property name="text">
- <string>Combined</string>
- </property>
- </widget>
- </item>
- <item>
- <layout class="QHBoxLayout">
- <item>
- <widget class="QLabel" name="textLabel2_2">
- <property name="font">
- <font/>
- </property>
- <property name="text">
- <string>S/T Relation</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="spatialTimeRelation">
- <property name="font">
- <font/>
- </property>
- <property name="minimum">
- <number>-10</number>
- </property>
- <property name="maximum">
- <number>10</number>
- </property>
- <property name="value">
- <number>0</number>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="Line" name="line2">
- <property name="frameShape">
- <enum>QFrame::HLine</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Sunken</enum>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QWidget" name="buttonGroup2" native="true">
- <layout class="QVBoxLayout">
- <item>
- <widget class="QRadioButton" name="rbtnForward">
- <property name="font">
- <font/>
- </property>
- <property name="text">
- <string>Forward</string>
- </property>
- <property name="checked">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QRadioButton" name="rbtnBackward">
- <property name="font">
- <font/>
- </property>
- <property name="text">
- <string>Backward</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QRadioButton" name="rbtnPingPong">
- <property name="font">
- <font/>
- </property>
- <property name="text">
- <string>Ping-Pong</string>
- </property>
- </widget>
- </item>
- <item>
- <layout class="QHBoxLayout">
- <item>
- <widget class="QLabel" name="textLabel2">
- <property name="font">
- <font/>
- </property>
- <property name="text">
- <string>Cycle (sec)</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="spnDuration">
- <property name="font">
- <font/>
- </property>
- <property name="minimum">
- <number>1</number>
- </property>
- <property name="maximum">
- <number>200</number>
- </property>
- <property name="value">
- <number>5</number>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="6" column="1">
- <spacer>
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>31</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- <layoutdefault spacing="6" margin="11"/>
- <customwidgets>
- <customwidget>
- <class>QmitkSliderNavigatorWidget</class>
- <extends>QWidget</extends>
- <header>QmitkSliderNavigatorWidget.h</header>
- <container>1</container>
- </customwidget>
- </customwidgets>
- <tabstops>
- <tabstop>rbtnForward</tabstop>
- <tabstop>rbtnBackward</tabstop>
- <tabstop>rbtnPingPong</tabstop>
- <tabstop>rbtnSpatial</tabstop>
- <tabstop>rbtnTemporal</tabstop>
- <tabstop>cmbSelectedStepperWindow</tabstop>
- </tabstops>
- <resources>
- <include location="../../../../../../../mitkBinaryCTK/MITK-superbuild/MITK-build/Modules/Bundles/org.mitk.gui.qt.moviemaker/org_mitk_gui_qt_moviemaker_cached.qrc"/>
- </resources>
- <connections/>
-</ui>
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMakerView.cpp b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMakerView.cpp
new file mode 100644
index 0000000000..e03aea6d7c
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMakerView.cpp
@@ -0,0 +1,690 @@
+/*===================================================================
+
+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 "QmitkAnimationItemDelegate.h"
+#include "QmitkFFmpegWriter.h"
+#include "QmitkMovieMakerView.h"
+#include "QmitkOrbitAnimationItem.h"
+#include "QmitkOrbitAnimationWidget.h"
+#include "QmitkSliceAnimationItem.h"
+#include "QmitkSliceAnimationWidget.h"
+#include "QmitkTimeSliceAnimationWidget.h"
+#include "QmitkTimeSliceAnimationItem.h"
+#include <ui_QmitkMovieMakerView.h>
+#include <QFileDialog>
+#include <QMenu>
+#include <QMessageBox>
+#include <QStandardItemModel>
+#include <QTimer>
+#include <mitkBaseRenderer.h>
+#include <mitkGL.h>
+
+static QmitkAnimationItem* CreateDefaultAnimation(const QString& widgetKey)
+{
+ if (widgetKey == "Orbit")
+ return new QmitkOrbitAnimationItem;
+
+ if (widgetKey == "Slice")
+ return new QmitkSliceAnimationItem;
+
+ if (widgetKey == "Time")
+ return new QmitkTimeSliceAnimationItem;
+
+ return NULL;
+}
+
+static QString GetFFmpegPath()
+{
+ berry::IPreferencesService::Pointer preferencesService =
+ berry::Platform::GetServiceRegistry().GetServiceById<berry::IPreferencesService>(berry::IPreferencesService::ID);
+
+ berry::IPreferences::Pointer preferences = preferencesService->GetSystemPreferences()->Node("/org.mitk.gui.qt.ext.externalprograms");
+
+ return QString::fromStdString(preferences->Get("ffmpeg", ""));
+}
+
+static unsigned char* ReadPixels(vtkRenderWindow* renderWindow, int x, int y, int width, int height)
+{
+ if (renderWindow == NULL)
+ return NULL;
+
+ unsigned char* frame = new unsigned char[width * height * 3];
+
+ renderWindow->MakeCurrent();
+ glReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, frame);
+
+ return frame;
+}
+
+const std::string QmitkMovieMakerView::VIEW_ID = "org.mitk.views.moviemaker";
+
+QmitkMovieMakerView::QmitkMovieMakerView()
+ : m_FFmpegWriter(NULL),
+ m_Ui(new Ui::QmitkMovieMakerView),
+ m_AnimationModel(NULL),
+ m_AddAnimationMenu(NULL),
+ m_RecordMenu(NULL),
+ m_Timer(NULL),
+ m_TotalDuration(0.0),
+ m_NumFrames(0),
+ m_CurrentFrame(0)
+{
+}
+
+QmitkMovieMakerView::~QmitkMovieMakerView()
+{
+}
+
+void QmitkMovieMakerView::CreateQtPartControl(QWidget* parent)
+{
+ m_FFmpegWriter = new QmitkFFmpegWriter(parent);
+
+ m_Ui->setupUi(parent);
+
+ this->InitializeAnimationWidgets();
+ this->InitializeAnimationTreeViewWidgets();
+ this->InitializePlaybackAndRecordWidgets();
+ this->InitializeTimer(parent);
+
+ m_Ui->animationWidgetGroupBox->setVisible(false);
+}
+
+void QmitkMovieMakerView::InitializeAnimationWidgets()
+{
+ m_AnimationWidgets["Orbit"] = new QmitkOrbitAnimationWidget;
+ m_AnimationWidgets["Slice"] = new QmitkSliceAnimationWidget;
+ m_AnimationWidgets["Time"] = new QmitkTimeSliceAnimationWidget;
+
+ Q_FOREACH(QWidget* widget, m_AnimationWidgets.values())
+ {
+ if (widget != NULL)
+ {
+ widget->setVisible(false);
+ m_Ui->animationWidgetGroupBoxLayout->addWidget(widget);
+ }
+ }
+
+ this->ConnectAnimationWidgets();
+}
+
+void QmitkMovieMakerView::InitializeAnimationTreeViewWidgets()
+{
+ this->InitializeAnimationModel();
+ this->InitializeAddAnimationMenu();
+ this->ConnectAnimationTreeViewWidgets();
+}
+
+void QmitkMovieMakerView::InitializePlaybackAndRecordWidgets()
+{
+ this->InitializeRecordMenu();
+ this->ConnectPlaybackAndRecordWidgets();
+}
+
+void QmitkMovieMakerView::InitializeAnimationModel()
+{
+ m_AnimationModel = new QStandardItemModel(m_Ui->animationTreeView);
+ m_AnimationModel->setHorizontalHeaderLabels(QStringList() << "Animation" << "Timeline");
+ m_Ui->animationTreeView->setModel(m_AnimationModel);
+
+ m_Ui->animationTreeView->setItemDelegate(new QmitkAnimationItemDelegate(m_Ui->animationTreeView));
+}
+
+void QmitkMovieMakerView::InitializeAddAnimationMenu()
+{
+ m_AddAnimationMenu = new QMenu(m_Ui->addAnimationButton);
+
+ Q_FOREACH(const QString& key, m_AnimationWidgets.keys())
+ {
+ m_AddAnimationMenu->addAction(key);
+ }
+}
+
+void QmitkMovieMakerView::InitializeRecordMenu()
+{
+ typedef QPair<QString, QString> PairOfStrings;
+
+ m_RecordMenu = new QMenu(m_Ui->recordButton);
+
+ QVector<PairOfStrings> renderWindows;
+ renderWindows.push_back(qMakePair(QString("Axial"), QString("stdmulti.widget1")));
+ renderWindows.push_back(qMakePair(QString("Sagittal"), QString("stdmulti.widget2")));
+ renderWindows.push_back(qMakePair(QString("Coronal"), QString("stdmulti.widget3")));
+ renderWindows.push_back(qMakePair(QString("3D"), QString("stdmulti.widget4")));
+
+ Q_FOREACH(const PairOfStrings& renderWindow, renderWindows)
+ {
+ QAction* action = new QAction(m_RecordMenu);
+ action->setText(renderWindow.first);
+ action->setData(renderWindow.second);
+
+ m_RecordMenu->addAction(action);
+ }
+}
+
+void QmitkMovieMakerView::InitializeTimer(QWidget* parent)
+{
+ m_Timer = new QTimer(parent);
+
+ this->OnFPSSpinBoxValueChanged(m_Ui->fpsSpinBox->value());
+ this->ConnectTimer();
+}
+
+void QmitkMovieMakerView::ConnectAnimationTreeViewWidgets()
+{
+ this->connect(m_AnimationModel, SIGNAL(rowsInserted(const QModelIndex&, int, int)),
+ this, SLOT(OnAnimationTreeViewRowsInserted(const QModelIndex&, int, int)));
+
+ this->connect(m_AnimationModel, SIGNAL(rowsRemoved(const QModelIndex&, int, int)),
+ this, SLOT(OnAnimationTreeViewRowsRemoved(const QModelIndex&, int, int)));
+
+ this->connect(m_Ui->animationTreeView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&, const QItemSelection&)),
+ this, SLOT(OnAnimationTreeViewSelectionChanged(const QItemSelection&, const QItemSelection&)));
+
+ this->connect(m_Ui->moveAnimationUpButton, SIGNAL(clicked()),
+ this, SLOT(OnMoveAnimationUpButtonClicked()));
+
+ this->connect(m_Ui->moveAnimationDownButton, SIGNAL(clicked()),
+ this, SLOT(OnMoveAnimationDownButtonClicked()));
+
+ this->connect(m_Ui->addAnimationButton, SIGNAL(clicked()),
+ this, SLOT(OnAddAnimationButtonClicked()));
+
+ this->connect(m_Ui->removeAnimationButton, SIGNAL(clicked()),
+ this, SLOT(OnRemoveAnimationButtonClicked()));
+}
+
+void QmitkMovieMakerView::ConnectAnimationWidgets()
+{
+ this->connect(m_Ui->startComboBox, SIGNAL(currentIndexChanged(int)),
+ this, SLOT(OnStartComboBoxCurrentIndexChanged(int)));
+
+ this->connect(m_Ui->durationSpinBox, SIGNAL(valueChanged(double)),
+ this, SLOT(OnDurationSpinBoxValueChanged(double)));
+
+ this->connect(m_Ui->delaySpinBox, SIGNAL(valueChanged(double)),
+ this, SLOT(OnDelaySpinBoxValueChanged(double)));
+}
+
+void QmitkMovieMakerView::ConnectPlaybackAndRecordWidgets()
+{
+ this->connect(m_Ui->playButton, SIGNAL(toggled(bool)),
+ this, SLOT(OnPlayButtonToggled(bool)));
+
+ this->connect(m_Ui->stopButton, SIGNAL(clicked()),
+ this, SLOT(OnStopButtonClicked()));
+
+ this->connect(m_Ui->recordButton, SIGNAL(clicked()),
+ this, SLOT(OnRecordButtonClicked()));
+
+ this->connect(m_Ui->fpsSpinBox, SIGNAL(valueChanged(int)),
+ this, SLOT(OnFPSSpinBoxValueChanged(int)));
+}
+
+void QmitkMovieMakerView::ConnectTimer()
+{
+ this->connect(m_Timer, SIGNAL(timeout()),
+ this, SLOT(OnTimerTimeout()));
+}
+
+void QmitkMovieMakerView::SetFocus()
+{
+ m_Ui->addAnimationButton->setFocus();
+}
+
+void QmitkMovieMakerView::OnMoveAnimationUpButtonClicked()
+{
+ const QItemSelection selection = m_Ui->animationTreeView->selectionModel()->selection();
+
+ if (!selection.isEmpty())
+ {
+ const int selectedRow = selection[0].top();
+
+ if (selectedRow > 0)
+ m_AnimationModel->insertRow(selectedRow - 1, m_AnimationModel->takeRow(selectedRow));
+ }
+
+ this->CalculateTotalDuration();
+}
+
+void QmitkMovieMakerView::OnMoveAnimationDownButtonClicked()
+{
+ const QItemSelection selection = m_Ui->animationTreeView->selectionModel()->selection();
+
+ if (!selection.isEmpty())
+ {
+ const int rowCount = m_AnimationModel->rowCount();
+ const int selectedRow = selection[0].top();
+
+ if (selectedRow < rowCount - 1)
+ m_AnimationModel->insertRow(selectedRow + 1, m_AnimationModel->takeRow(selectedRow));
+ }
+
+ this->CalculateTotalDuration();
+}
+
+void QmitkMovieMakerView::OnAddAnimationButtonClicked()
+{
+ QAction* action = m_AddAnimationMenu->exec(QCursor::pos());
+
+ if (action != NULL)
+ {
+ const QString widgetKey = action->text();
+
+ m_AnimationModel->appendRow(QList<QStandardItem*>()
+ << new QStandardItem(widgetKey)
+ << CreateDefaultAnimation(widgetKey));
+
+ m_Ui->playbackAndRecordingGroupBox->setEnabled(true);
+ }
+}
+
+void QmitkMovieMakerView::OnPlayButtonToggled(bool checked)
+{
+ if (checked)
+ {
+ m_Ui->playButton->setIcon(QIcon(":/org_mitk_icons/icons/tango/scalable/actions/media-playback-pause.svg"));
+ m_Ui->playButton->repaint();
+
+ m_Timer->start(static_cast<int>(1000.0 / m_Ui->fpsSpinBox->value()));
+ }
+ else
+ {
+ m_Timer->stop();
+
+ m_Ui->playButton->setIcon(QIcon(":/org_mitk_icons/icons/tango/scalable/actions/media-playback-start.svg"));
+ m_Ui->playButton->repaint();
+ }
+}
+
+void QmitkMovieMakerView::OnStopButtonClicked()
+{
+ m_Ui->playButton->setChecked(false);
+ m_Ui->stopButton->setEnabled(false);
+
+ m_CurrentFrame = 0;
+ this->RenderCurrentFrame();
+}
+
+void QmitkMovieMakerView::OnRecordButtonClicked() // TODO: Refactor
+{
+ const QString ffmpegPath = GetFFmpegPath();
+
+ if (ffmpegPath.isEmpty())
+ {
+ QMessageBox::information(NULL, "Movie Maker",
+ "<p>Set path to FFmpeg<sup>1</sup> or Libav<sup>2</sup> (avconv) in preferences (Window -> Preferences... (Ctrl+P) -> External Programs) to be able to record your movies to video files.</p>"
+ "<p>If you are using Linux, chances are good that either FFmpeg or Libav is included in the official package repositories.</p>"
+ "<p>[1] <a href=\"https://www.ffmpeg.org/download.html\">Download FFmpeg from ffmpeg.org</a><br/>"
+ "[2] <a href=\"https://libav.org/download.html\">Download Libav from libav.org</a></p>");
+ return;
+ }
+
+ m_FFmpegWriter->SetFFmpegPath(GetFFmpegPath());
+
+ QAction* action = m_RecordMenu->exec(QCursor::pos());
+
+ if (action == NULL)
+ return;
+
+ vtkRenderWindow* renderWindow = mitk::BaseRenderer::GetRenderWindowByName(action->data().toString().toStdString());
+
+ if (renderWindow == NULL)
+ return;
+
+ const int border = 3;
+ const int x = border;
+ const int y = border;
+ int width = renderWindow->GetSize()[0] - border * 2;
+ int height = renderWindow->GetSize()[1] - border * 2;
+
+ if (width & 1)
+ --width;
+
+ if (height & 1)
+ --height;
+
+ if (width < 16 || height < 16)
+ return;
+
+ m_FFmpegWriter->SetSize(width, height);
+ m_FFmpegWriter->SetFramerate(m_Ui->fpsSpinBox->value());
+
+ QString saveFileName = QFileDialog::getSaveFileName(NULL, "Specify a filename", "", "Movie (*.mp4)");
+
+ if (saveFileName.isEmpty())
+ return;
+
+ if(!saveFileName.endsWith(".mp4"))
+ saveFileName += ".mp4";
+
+ m_FFmpegWriter->SetOutputPath(saveFileName);
+
+ try
+ {
+ m_FFmpegWriter->Start();
+
+ for (m_CurrentFrame = 0; m_CurrentFrame < m_NumFrames; ++m_CurrentFrame)
+ {
+ this->RenderCurrentFrame();
+
+ renderWindow->MakeCurrent();
+ unsigned char* frame = ReadPixels(renderWindow, x, y, width, height);
+ m_FFmpegWriter->WriteFrame(frame);
+ delete[] frame;
+ }
+
+ m_FFmpegWriter->Stop();
+
+ m_CurrentFrame = 0;
+ this->RenderCurrentFrame();
+ }
+ catch (const mitk::Exception& exception)
+ {
+ m_CurrentFrame = 0;
+ this->RenderCurrentFrame();
+
+ QMessageBox::critical(NULL, "Movie Maker", exception.GetDescription());
+ }
+}
+
+void QmitkMovieMakerView::OnRemoveAnimationButtonClicked()
+{
+ const QItemSelection selection = m_Ui->animationTreeView->selectionModel()->selection();
+
+ if (!selection.isEmpty())
+ m_AnimationModel->removeRow(selection[0].top());
+}
+
+void QmitkMovieMakerView::OnAnimationTreeViewRowsInserted(const QModelIndex& parent, int start, int)
+{
+ this->CalculateTotalDuration();
+
+ m_Ui->animationTreeView->selectionModel()->select(
+ m_AnimationModel->index(start, 0, parent),
+ QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
+}
+
+void QmitkMovieMakerView::OnAnimationTreeViewRowsRemoved(const QModelIndex&, int, int)
+{
+ this->CalculateTotalDuration();
+ this->UpdateWidgets();
+}
+
+void QmitkMovieMakerView::OnAnimationTreeViewSelectionChanged(const QItemSelection&, const QItemSelection&)
+{
+ this->UpdateWidgets();
+}
+
+void QmitkMovieMakerView::OnStartComboBoxCurrentIndexChanged(int index)
+{
+ QmitkAnimationItem* item = this->GetSelectedAnimationItem();
+
+ if (item != NULL)
+ {
+ item->SetStartWithPrevious(index);
+ this->RedrawTimeline();
+ this->CalculateTotalDuration();
+ }
+}
+
+void QmitkMovieMakerView::OnDurationSpinBoxValueChanged(double value)
+{
+ QmitkAnimationItem* item = this->GetSelectedAnimationItem();
+
+ if (item != NULL)
+ {
+ item->SetDuration(value);
+ this->RedrawTimeline();
+ this->CalculateTotalDuration();
+ }
+}
+
+void QmitkMovieMakerView::OnDelaySpinBoxValueChanged(double value)
+{
+ QmitkAnimationItem* item = this->GetSelectedAnimationItem();
+
+ if (item != NULL)
+ {
+ item->SetDelay(value);
+ this->RedrawTimeline();
+ this->CalculateTotalDuration();
+ }
+}
+
+void QmitkMovieMakerView::OnFPSSpinBoxValueChanged(int value)
+{
+ this->CalculateTotalDuration();
+ m_Timer->setInterval(static_cast<int>(1000.0 / value));
+}
+
+void QmitkMovieMakerView::OnTimerTimeout()
+{
+ this->RenderCurrentFrame();
+
+ m_CurrentFrame = std::min(m_NumFrames, m_CurrentFrame + 1);
+
+ if (m_CurrentFrame >= m_NumFrames)
+ {
+ m_Ui->playButton->setChecked(false);
+
+ m_CurrentFrame = 0;
+ this->RenderCurrentFrame();
+ }
+
+ m_Ui->stopButton->setEnabled(m_CurrentFrame != 0);
+}
+
+void QmitkMovieMakerView::RenderCurrentFrame()
+{
+ typedef QPair<QmitkAnimationItem*, double> AnimationInterpolationFactorPair;
+
+ const double deltaT = m_TotalDuration / (m_NumFrames - 1);
+ const QVector<AnimationInterpolationFactorPair> activeAnimations = this->GetActiveAnimations(m_CurrentFrame * deltaT);
+
+ Q_FOREACH(const AnimationInterpolationFactorPair& animation, activeAnimations)
+ {
+ const QVector<AnimationInterpolationFactorPair> nextActiveAnimations = this->GetActiveAnimations((m_CurrentFrame + 1) * deltaT);
+ bool lastFrameForAnimation = true;
+
+ Q_FOREACH(const AnimationInterpolationFactorPair& nextAnimation, nextActiveAnimations)
+ {
+ if (nextAnimation.first == animation.first)
+ {
+ lastFrameForAnimation = false;
+ break;
+ }
+ }
+
+ animation.first->Animate(!lastFrameForAnimation
+ ? animation.second
+ : 1.0);
+ }
+
+ mitk::RenderingManager::GetInstance()->ForceImmediateUpdateAll();
+}
+
+void QmitkMovieMakerView::UpdateWidgets()
+{
+ const QItemSelection selection = m_Ui->animationTreeView->selectionModel()->selection();
+
+ if (selection.isEmpty())
+ {
+ m_Ui->moveAnimationUpButton->setEnabled(false);
+ m_Ui->moveAnimationDownButton->setEnabled(false);
+ m_Ui->removeAnimationButton->setEnabled(false);
+ m_Ui->playbackAndRecordingGroupBox->setEnabled(false);
+
+ this->HideCurrentAnimationWidget();
+ }
+ else
+ {
+ const int rowCount = m_AnimationModel->rowCount();
+ const int selectedRow = selection[0].top();
+
+ m_Ui->moveAnimationUpButton->setEnabled(rowCount > 1 && selectedRow != 0);
+ m_Ui->moveAnimationDownButton->setEnabled(rowCount > 1 && selectedRow < rowCount - 1);
+ m_Ui->removeAnimationButton->setEnabled(true);
+ m_Ui->playbackAndRecordingGroupBox->setEnabled(true);
+
+ this->ShowAnimationWidget(dynamic_cast<QmitkAnimationItem*>(m_AnimationModel->item(selectedRow, 1)));
+ }
+
+ this->UpdateAnimationWidgets();
+}
+
+void QmitkMovieMakerView::UpdateAnimationWidgets()
+{
+ QmitkAnimationItem* item = this->GetSelectedAnimationItem();
+
+ if (item != NULL)
+ {
+ m_Ui->startComboBox->setCurrentIndex(item->GetStartWithPrevious());
+ m_Ui->durationSpinBox->setValue(item->GetDuration());
+ m_Ui->delaySpinBox->setValue(item->GetDelay());
+
+ m_Ui->animationGroupBox->setEnabled(true);
+ }
+ else
+ {
+ m_Ui->animationGroupBox->setEnabled(false);
+ }
+}
+
+void QmitkMovieMakerView::HideCurrentAnimationWidget()
+{
+ if (m_Ui->animationWidgetGroupBox->isVisible())
+ {
+ m_Ui->animationWidgetGroupBox->setVisible(false);
+
+ int numWidgets = m_Ui->animationWidgetGroupBoxLayout->count();
+
+ for (int i = 0; i < numWidgets; ++i)
+ m_Ui->animationWidgetGroupBoxLayout->itemAt(i)->widget()->setVisible(false);
+ }
+}
+
+void QmitkMovieMakerView::ShowAnimationWidget(QmitkAnimationItem* animationItem)
+{
+ this->HideCurrentAnimationWidget();
+
+ if (animationItem == NULL)
+ return;
+
+ const QString widgetKey = animationItem->GetWidgetKey();
+ QmitkAnimationWidget* animationWidget = NULL;
+
+ if (m_AnimationWidgets.contains(widgetKey))
+ {
+ animationWidget = m_AnimationWidgets[widgetKey];
+
+ if (animationWidget != NULL)
+ {
+ m_Ui->animationWidgetGroupBox->setTitle(widgetKey);
+ animationWidget->SetAnimationItem(animationItem);
+ animationWidget->setVisible(true);
+ }
+ }
+
+ m_Ui->animationWidgetGroupBox->setVisible(animationWidget != NULL);
+}
+
+void QmitkMovieMakerView::RedrawTimeline()
+{
+ if (m_AnimationModel->rowCount() > 1)
+ {
+ m_Ui->animationTreeView->dataChanged(
+ m_AnimationModel->index(0, 1),
+ m_AnimationModel->index(m_AnimationModel->rowCount() - 1, 1));
+ }
+}
+
+QmitkAnimationItem* QmitkMovieMakerView::GetSelectedAnimationItem() const
+{
+ const QItemSelection selection = m_Ui->animationTreeView->selectionModel()->selection();
+
+ return !selection.isEmpty()
+ ? dynamic_cast<QmitkAnimationItem*>(m_AnimationModel->item(selection[0].top(), 1))
+ : NULL;
+}
+
+void QmitkMovieMakerView::CalculateTotalDuration()
+{
+ const int rowCount = m_AnimationModel->rowCount();
+
+ double totalDuration = 0.0;
+ double previousStart = 0.0;
+
+ for (int i = 0; i < rowCount; ++i)
+ {
+ QmitkAnimationItem* item = dynamic_cast<QmitkAnimationItem*>(m_AnimationModel->item(i, 1));
+
+ if (item == NULL)
+ continue;
+
+ if (item->GetStartWithPrevious())
+ {
+ totalDuration = std::max(totalDuration, previousStart + item->GetDelay() + item->GetDuration());
+ }
+ else
+ {
+ previousStart = totalDuration;
+ totalDuration += item->GetDelay() + item->GetDuration();
+ }
+ }
+
+ m_TotalDuration = totalDuration; // TODO totalDuration == 0
+ m_NumFrames = static_cast<int>(totalDuration * m_Ui->fpsSpinBox->value()); // TODO numFrames < 2
+}
+
+QVector<QPair<QmitkAnimationItem*, double> > QmitkMovieMakerView::GetActiveAnimations(double t) const
+{
+ const int rowCount = m_AnimationModel->rowCount();
+
+ QVector<QPair<QmitkAnimationItem*, double> > activeAnimations;
+
+ double totalDuration = 0.0;
+ double previousStart = 0.0;
+
+ for (int i = 0; i < rowCount; ++i)
+ {
+ QmitkAnimationItem* item = dynamic_cast<QmitkAnimationItem*>(m_AnimationModel->item(i, 1));
+
+ if (item == NULL)
+ continue;
+
+ if (item->GetDuration() > 0.0)
+ {
+ double start = item->GetStartWithPrevious()
+ ? previousStart + item->GetDelay()
+ : totalDuration + item->GetDelay();
+
+ if (start <= t && t <= start + item->GetDuration())
+ activeAnimations.push_back(qMakePair(item, (t - start) / item->GetDuration()));
+ }
+
+ if (item->GetStartWithPrevious())
+ {
+ totalDuration = std::max(totalDuration, previousStart + item->GetDelay() + item->GetDuration());
+ }
+ else
+ {
+ previousStart = totalDuration;
+ totalDuration += item->GetDelay() + item->GetDuration();
+ }
+ }
+
+ return activeAnimations;
+}
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMakerView.h b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMakerView.h
new file mode 100644
index 0000000000..f686ba79b9
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMakerView.h
@@ -0,0 +1,98 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#ifndef QmitkMovieMakerView_h
+#define QmitkMovieMakerView_h
+
+#include <QmitkAbstractView.h>
+
+class QmitkAnimationItem;
+class QmitkAnimationWidget;
+class QmitkFFmpegWriter;
+class QMenu;
+class QStandardItemModel;
+class QTimer;
+
+namespace Ui
+{
+ class QmitkMovieMakerView;
+}
+
+class QmitkMovieMakerView : public QmitkAbstractView
+{
+ Q_OBJECT
+
+public:
+ static const std::string VIEW_ID;
+
+ QmitkMovieMakerView();
+ ~QmitkMovieMakerView();
+
+ void CreateQtPartControl(QWidget* parent);
+ void SetFocus();
+
+private slots:
+ void OnMoveAnimationUpButtonClicked();
+ void OnMoveAnimationDownButtonClicked();
+ void OnAddAnimationButtonClicked();
+ void OnRemoveAnimationButtonClicked();
+ void OnAnimationTreeViewRowsInserted(const QModelIndex& parent, int start, int end);
+ void OnAnimationTreeViewRowsRemoved(const QModelIndex& parent, int start, int end);
+ void OnAnimationTreeViewSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
+ void OnStartComboBoxCurrentIndexChanged(int index);
+ void OnDurationSpinBoxValueChanged(double value);
+ void OnDelaySpinBoxValueChanged(double value);
+ void OnPlayButtonToggled(bool checked);
+ void OnStopButtonClicked();
+ void OnRecordButtonClicked();
+ void OnFPSSpinBoxValueChanged(int value);
+ void OnTimerTimeout();
+
+private:
+ void InitializeAnimationWidgets();
+ void InitializeAnimationTreeViewWidgets();
+ void InitializeAnimationModel();
+ void InitializeAddAnimationMenu();
+ void InitializePlaybackAndRecordWidgets();
+ void InitializeRecordMenu();
+ void InitializeTimer(QWidget* parent);
+ void ConnectAnimationTreeViewWidgets();
+ void ConnectAnimationWidgets();
+ void ConnectPlaybackAndRecordWidgets();
+ void ConnectTimer();
+ void RenderCurrentFrame();
+ void UpdateWidgets();
+ void UpdateAnimationWidgets();
+ void HideCurrentAnimationWidget();
+ void ShowAnimationWidget(QmitkAnimationItem* animationItem);
+ void RedrawTimeline();
+ void CalculateTotalDuration();
+ QmitkAnimationItem* GetSelectedAnimationItem() const;
+ QVector<QPair<QmitkAnimationItem*, double> > GetActiveAnimations(double t) const;
+
+ QmitkFFmpegWriter* m_FFmpegWriter;
+ Ui::QmitkMovieMakerView* m_Ui;
+ QStandardItemModel* m_AnimationModel;
+ QMap<QString, QmitkAnimationWidget*> m_AnimationWidgets;
+ QMenu* m_AddAnimationMenu;
+ QMenu* m_RecordMenu;
+ QTimer* m_Timer;
+ double m_TotalDuration;
+ int m_NumFrames;
+ int m_CurrentFrame;
+};
+
+#endif
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMakerView.ui b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMakerView.ui
new file mode 100644
index 0000000000..ccbd70bb83
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkMovieMakerView.ui
@@ -0,0 +1,507 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>QmitkMovieMakerView</class>
+ <widget class="QWidget" name="QmitkMovieMakerView">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>320</width>
+ <height>640</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Movie Maker</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <layout class="QGridLayout" name="animationTreeViewLayout">
+ <item row="0" column="3">
+ <widget class="QToolButton" name="moveAnimationUpButton">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip">
+ <string>Move animation up</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../../../org.mitk.gui.qt.ext/resources/org_mitk_icons.qrc">
+ <normaloff>:/org_mitk_icons/icons/tango/scalable/actions/go-up.svg</normaloff>:/org_mitk_icons/icons/tango/scalable/actions/go-up.svg</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>24</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3">
+ <widget class="QToolButton" name="moveAnimationDownButton">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip">
+ <string>Move animation down</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../../../org.mitk.gui.qt.ext/resources/org_mitk_icons.qrc">
+ <normaloff>:/org_mitk_icons/icons/tango/scalable/actions/go-down.svg</normaloff>:/org_mitk_icons/icons/tango/scalable/actions/go-down.svg</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>24</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QToolButton" name="addAnimationButton">
+ <property name="toolTip">
+ <string>Add animation</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../../../org.mitk.gui.qt.ext/resources/org_mitk_icons.qrc">
+ <normaloff>:/org_mitk_icons/icons/tango/scalable/actions/list-add.svg</normaloff>:/org_mitk_icons/icons/tango/scalable/actions/list-add.svg</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>24</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QToolButton" name="removeAnimationButton">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip">
+ <string>Remove animation</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../../../org.mitk.gui.qt.ext/resources/org_mitk_icons.qrc">
+ <normaloff>:/org_mitk_icons/icons/tango/scalable/actions/list-remove.svg</normaloff>:/org_mitk_icons/icons/tango/scalable/actions/list-remove.svg</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>24</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" rowspan="3" colspan="3">
+ <widget class="QTreeView" name="animationTreeView">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>100</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>100</height>
+ </size>
+ </property>
+ <property name="rootIsDecorated">
+ <bool>false</bool>
+ </property>
+ <property name="uniformRowHeights">
+ <bool>true</bool>
+ </property>
+ <attribute name="headerDefaultSectionSize">
+ <number>80</number>
+ </attribute>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="animationGroupBox">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="title">
+ <string>Animation</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="startIconLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>24</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>24</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="pixmap">
+ <pixmap resource="../../../org.mitk.gui.qt.ext/resources/org_mitk_icons.qrc">:/org_mitk_icons/icons/tango/scalable/actions/media-playback-start.svg</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="startLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Start:</string>
+ </property>
+ <property name="buddy">
+ <cstring>startComboBox</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2" colspan="2">
+ <widget class="QComboBox" name="startComboBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <item>
+ <property name="text">
+ <string>After previous</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>With previous</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="durationIconLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>24</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>24</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="pixmap">
+ <pixmap resource="../../resources/QmitkMovieMaker.qrc">:/QmitkMovieMakerView/duration.svg</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="durationLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Duration:</string>
+ </property>
+ <property name="buddy">
+ <cstring>durationSpinBox</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QDoubleSpinBox" name="durationSpinBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="suffix">
+ <string> s</string>
+ </property>
+ <property name="maximum">
+ <double>100.000000000000000</double>
+ </property>
+ <property name="singleStep">
+ <double>0.500000000000000</double>
+ </property>
+ <property name="value">
+ <double>2.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="delayIconLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>24</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>24</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="pixmap">
+ <pixmap resource="../../resources/QmitkMovieMaker.qrc">:/QmitkMovieMakerView/delay.svg</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLabel" name="delaylabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Delay:</string>
+ </property>
+ <property name="buddy">
+ <cstring>delaySpinBox</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QDoubleSpinBox" name="delaySpinBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="suffix">
+ <string> s</string>
+ </property>
+ <property name="maximum">
+ <double>100.000000000000000</double>
+ </property>
+ <property name="singleStep">
+ <double>0.500000000000000</double>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="animationWidgetGroupBox">
+ <layout class="QVBoxLayout" name="animationWidgetGroupBoxLayout"/>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="playbackAndRecordingGroupBox">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="title">
+ <string>Playback &amp;&amp; Recording</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QToolButton" name="playButton">
+ <property name="toolTip">
+ <string>Play</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../../../org.mitk.gui.qt.ext/resources/org_mitk_icons.qrc">
+ <normaloff>:/org_mitk_icons/icons/tango/scalable/actions/media-playback-start.svg</normaloff>:/org_mitk_icons/icons/tango/scalable/actions/media-playback-start.svg</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>24</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="stopButton">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip">
+ <string>Stop</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../../../org.mitk.gui.qt.ext/resources/org_mitk_icons.qrc">
+ <normaloff>:/org_mitk_icons/icons/tango/scalable/actions/media-playback-stop.svg</normaloff>:/org_mitk_icons/icons/tango/scalable/actions/media-playback-stop.svg</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>24</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QToolButton" name="recordButton">
+ <property name="toolTip">
+ <string>Record</string>
+ </property>
+ <property name="icon">
+ <iconset resource="../../../org.mitk.gui.qt.ext/resources/org_mitk_icons.qrc">
+ <normaloff>:/org_mitk_icons/icons/tango/scalable/actions/media-record.svg</normaloff>:/org_mitk_icons/icons/tango/scalable/actions/media-record.svg</iconset>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>24</width>
+ <height>24</height>
+ </size>
+ </property>
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="fpsSpinBox">
+ <property name="toolTip">
+ <string>Frames per second</string>
+ </property>
+ <property name="suffix">
+ <string> FPS</string>
+ </property>
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>120</number>
+ </property>
+ <property name="value">
+ <number>30</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>227</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>animationTreeView</tabstop>
+ <tabstop>moveAnimationUpButton</tabstop>
+ <tabstop>moveAnimationDownButton</tabstop>
+ <tabstop>addAnimationButton</tabstop>
+ <tabstop>removeAnimationButton</tabstop>
+ <tabstop>startComboBox</tabstop>
+ <tabstop>durationSpinBox</tabstop>
+ <tabstop>delaySpinBox</tabstop>
+ <tabstop>playButton</tabstop>
+ <tabstop>stopButton</tabstop>
+ <tabstop>recordButton</tabstop>
+ <tabstop>fpsSpinBox</tabstop>
+ </tabstops>
+ <resources>
+ <include location="../../../org.mitk.gui.qt.ext/resources/org_mitk_icons.qrc"/>
+ <include location="../../resources/QmitkMovieMaker.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkOrbitAnimationItem.cpp b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkOrbitAnimationItem.cpp
new file mode 100644
index 0000000000..a65c898f31
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkOrbitAnimationItem.cpp
@@ -0,0 +1,85 @@
+/*===================================================================
+
+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 "QmitkOrbitAnimationItem.h"
+#include <mitkBaseRenderer.h>
+
+QmitkOrbitAnimationItem::QmitkOrbitAnimationItem(int startAngle, int orbit, bool reverse, double duration, double delay, bool startWithPrevious)
+ : QmitkAnimationItem("Orbit", duration, delay, startWithPrevious)
+{
+ this->SetStartAngle(startAngle);
+ this->SetOrbit(orbit);
+ this->SetReverse(reverse);
+}
+
+QmitkOrbitAnimationItem::~QmitkOrbitAnimationItem()
+{
+}
+
+int QmitkOrbitAnimationItem::GetStartAngle() const
+{
+ return this->data(StartAngleRole).toInt();
+}
+
+void QmitkOrbitAnimationItem::SetStartAngle(int angle)
+{
+ this->setData(angle, StartAngleRole);
+}
+
+int QmitkOrbitAnimationItem::GetOrbit() const
+{
+ return this->data(OrbitRole).toInt();
+}
+
+void QmitkOrbitAnimationItem::SetOrbit(int angle)
+{
+ this->setData(angle, OrbitRole);
+}
+
+bool QmitkOrbitAnimationItem::GetReverse() const
+{
+ return this->data(ReverseRole).toBool();
+}
+
+void QmitkOrbitAnimationItem::SetReverse(bool reverse)
+{
+ this->setData(reverse, ReverseRole);
+}
+
+void QmitkOrbitAnimationItem::Animate(double s)
+{
+ vtkRenderWindow* renderWindow = mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget4");
+
+ if (renderWindow == NULL)
+ return;
+
+ mitk::Stepper* stepper = mitk::BaseRenderer::GetInstance(renderWindow)->GetCameraRotationController()->GetSlice();
+
+ if (stepper == NULL)
+ return;
+
+ int newPos = this->GetReverse()
+ ? this->GetStartAngle() - this->GetOrbit() * s
+ : this->GetStartAngle() + this->GetOrbit() * s;
+
+ while (newPos < 0)
+ newPos += 360;
+
+ while (newPos > 360)
+ newPos -= 360;
+
+ stepper->SetPos(static_cast<unsigned int>(newPos));
+}
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkOrbitAnimationItem.h b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkOrbitAnimationItem.h
new file mode 100644
index 0000000000..4198afba73
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkOrbitAnimationItem.h
@@ -0,0 +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 QmitkOrbitAnimationItem_h
+#define QmitkOrbitAnimationItem_h
+
+#include "QmitkAnimationItem.h"
+
+class QmitkOrbitAnimationItem : public QmitkAnimationItem
+{
+public:
+ explicit QmitkOrbitAnimationItem(int startAngle = 180, int orbit = 360, bool reverse = false, double duration = 2.0, double delay = 0.0, bool startWithPrevious = false);
+ virtual ~QmitkOrbitAnimationItem();
+
+ int GetStartAngle() const;
+ void SetStartAngle(int angle);
+
+ int GetOrbit() const;
+ void SetOrbit(int angle);
+
+ bool GetReverse() const;
+ void SetReverse(bool reverse);
+
+ void Animate(double s);
+};
+
+#endif
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkOrbitAnimationWidget.cpp b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkOrbitAnimationWidget.cpp
new file mode 100644
index 0000000000..0daae05426
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkOrbitAnimationWidget.cpp
@@ -0,0 +1,89 @@
+/*===================================================================
+
+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 "QmitkOrbitAnimationItem.h"
+#include "QmitkOrbitAnimationWidget.h"
+#include <limits>
+#include <ui_QmitkOrbitAnimationWidget.h>
+
+QmitkOrbitAnimationWidget::QmitkOrbitAnimationWidget(QWidget* parent)
+ : QmitkAnimationWidget(parent),
+ m_Ui(new Ui::QmitkOrbitAnimationWidget)
+{
+ m_Ui->setupUi(this);
+
+ m_Ui->orbitLineEdit->setValidator(new QIntValidator(0, std::numeric_limits<int>::max(), this));
+
+ this->connect(m_Ui->startAngleSlider, SIGNAL(valueChanged(int)),
+ m_Ui->startAngleSpinBox, SLOT(setValue(int)));
+
+ this->connect(m_Ui->startAngleSpinBox, SIGNAL(valueChanged(int)),
+ m_Ui->startAngleSlider, SLOT(setValue(int)));
+
+ this->connect(m_Ui->startAngleSpinBox, SIGNAL(valueChanged(int)),
+ this, SLOT(OnStartAngleChanged(int)));
+
+ this->connect(m_Ui->orbitLineEdit, SIGNAL(editingFinished()),
+ this, SLOT(OnOrbitEditingFinished()));
+
+ this->connect(m_Ui->reverseCheckBox, SIGNAL(clicked(bool)),
+ this, SLOT(OnReverseChanged(bool)));
+}
+
+QmitkOrbitAnimationWidget::~QmitkOrbitAnimationWidget()
+{
+}
+
+void QmitkOrbitAnimationWidget::SetAnimationItem(QmitkAnimationItem* orbitAnimationItem)
+{
+ m_AnimationItem = dynamic_cast<QmitkOrbitAnimationItem*>(orbitAnimationItem);
+
+ if (m_AnimationItem == NULL)
+ return;
+
+ m_Ui->startAngleSlider->setValue(m_AnimationItem->GetStartAngle());
+ m_Ui->orbitLineEdit->setText(QString("%1").arg(m_AnimationItem->GetOrbit()));
+ m_Ui->reverseCheckBox->setChecked(m_AnimationItem->GetReverse());
+}
+
+void QmitkOrbitAnimationWidget::OnStartAngleChanged(int angle)
+{
+ if (m_AnimationItem == NULL)
+ return;
+
+ if (m_AnimationItem->GetStartAngle() != angle)
+ m_AnimationItem->SetStartAngle(angle);
+}
+
+void QmitkOrbitAnimationWidget::OnOrbitEditingFinished()
+{
+ if (m_AnimationItem == NULL)
+ return;
+
+ int angle = m_Ui->orbitLineEdit->text().toInt();
+
+ if (m_AnimationItem->GetOrbit() != angle)
+ m_AnimationItem->SetOrbit(angle);
+}
+
+void QmitkOrbitAnimationWidget::OnReverseChanged(bool reverse)
+{
+ if (m_AnimationItem == NULL)
+ return;
+
+ if (m_AnimationItem->GetReverse() != reverse)
+ m_AnimationItem->SetReverse(reverse);
+}
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkOrbitAnimationWidget.h b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkOrbitAnimationWidget.h
new file mode 100644
index 0000000000..e343cfd47f
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkOrbitAnimationWidget.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 QmitkOrbitAnimationWidget_h
+#define QmitkOrbitAnimationWidget_h
+
+#include "QmitkAnimationWidget.h"
+
+class QmitkOrbitAnimationItem;
+
+namespace Ui
+{
+ class QmitkOrbitAnimationWidget;
+}
+
+class QmitkOrbitAnimationWidget : public QmitkAnimationWidget
+{
+ Q_OBJECT
+
+public:
+ explicit QmitkOrbitAnimationWidget(QWidget* parent = NULL);
+ ~QmitkOrbitAnimationWidget();
+
+ void SetAnimationItem(QmitkAnimationItem* orbitAnimationItem);
+
+private slots:
+ void OnStartAngleChanged(int angle);
+ void OnOrbitEditingFinished();
+ void OnReverseChanged(bool reverse);
+
+private:
+ Ui::QmitkOrbitAnimationWidget* m_Ui;
+ QmitkOrbitAnimationItem* m_AnimationItem;
+};
+
+#endif
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkOrbitAnimationWidget.ui b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkOrbitAnimationWidget.ui
new file mode 100644
index 0000000000..d07661f51c
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkOrbitAnimationWidget.ui
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>QmitkOrbitAnimationWidget</class>
+ <widget class="QWidget" name="QmitkOrbitAnimationWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>192</width>
+ <height>87</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>QmitkOrbitAnimationWidget</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="startAngleLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Start angle:</string>
+ </property>
+ <property name="buddy">
+ <cstring>startAngleSlider</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QSlider" name="startAngleSlider">
+ <property name="maximum">
+ <number>360</number>
+ </property>
+ <property name="value">
+ <number>180</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QSpinBox" name="startAngleSpinBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximum">
+ <number>360</number>
+ </property>
+ <property name="value">
+ <number>180</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="orbitLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Orbit:</string>
+ </property>
+ <property name="buddy">
+ <cstring>startAngleSlider</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" colspan="2">
+ <widget class="QLineEdit" name="orbitLineEdit">
+ <property name="text">
+ <string>360</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QCheckBox" name="reverseCheckBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Reverse</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>startAngleSlider</tabstop>
+ <tabstop>startAngleSpinBox</tabstop>
+ <tabstop>reverseCheckBox</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkSliceAnimationItem.cpp b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkSliceAnimationItem.cpp
new file mode 100644
index 0000000000..624512a7ec
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkSliceAnimationItem.cpp
@@ -0,0 +1,91 @@
+/*===================================================================
+
+The Medical Imaging Interaction Toolkit (MITK)
+
+Copyright (c) German Cancer Research Center,
+Division of Medical and Biological Informatics.
+All rights reserved.
+
+This software is distributed WITHOUT ANY WARRANTY; without
+even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE.
+
+See LICENSE.txt or http://www.mitk.org for details.
+
+===================================================================*/
+
+#include "QmitkSliceAnimationItem.h"
+#include <mitkBaseRenderer.h>
+
+QmitkSliceAnimationItem::QmitkSliceAnimationItem(int renderWindow, int from, int to, bool reverse, double duration, double delay, bool startWithPrevious)
+ : QmitkAnimationItem("Slice", duration, delay, startWithPrevious)
+{
+ this->SetRenderWindow(renderWindow);
+ this->SetFrom(from);
+ this->SetTo(to);
+ this->SetReverse(reverse);
+}
+
+QmitkSliceAnimationItem::~QmitkSliceAnimationItem()
+{
+}
+
+int QmitkSliceAnimationItem::GetRenderWindow() const
+{
+ return this->data(RenderWindowRole).toInt();
+}
+
+void QmitkSliceAnimationItem::SetRenderWindow(int renderWindow)
+{
+ this->setData(renderWindow, RenderWindowRole);
+}
+
+int QmitkSliceAnimationItem::GetFrom() const
+{
+ return this->data(FromRole).toInt();
+}
+
+void QmitkSliceAnimationItem::SetFrom(int from)
+{
+ this->setData(from, FromRole);
+}
+
+int QmitkSliceAnimationItem::GetTo() const
+{
+ return this->data(ToRole).toInt();
+}
+
+void QmitkSliceAnimationItem::SetTo(int to)
+{
+ this->setData(to, ToRole);
+}
+
+bool QmitkSliceAnimationItem::GetReverse() const
+{
+ return this->data(ReverseRole).toBool();
+}
+
+void QmitkSliceAnimationItem::SetReverse(bool reverse)
+{
+ this->setData(reverse, ReverseRole);
+}
+
+void QmitkSliceAnimationItem::Animate(double s)
+{
+ const QString renderWindowName = QString("stdmulti.widget%1").arg(this->GetRenderWindow() + 1);
+ vtkRenderWindow* renderWindow = mitk::BaseRenderer::GetRenderWindowByName(renderWindowName.toStdString());
+
+ if (renderWindow == NULL)
+ return;
+
+ mitk::Stepper* stepper = mitk::BaseRenderer::GetInstance(renderWindow)->GetSliceNavigationController()->GetSlice();
+
+ if (stepper == NULL)
+ return;
+
+ int newPos = this->GetReverse()
+ ? this->GetTo() - static_cast<int>((this->GetTo() - this->GetFrom()) * s)
+ : this->GetFrom() + static_cast<int>((this->GetTo() - this->GetFrom()) * s);
+
+ stepper->SetPos(static_cast<unsigned int>(newPos));
+}
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkSliceAnimationItem.h b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkSliceAnimationItem.h
new file mode 100644
index 0000000000..2626740387
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkSliceAnimationItem.h
@@ -0,0 +1,43 @@
+/*===================================================================
+
+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 QmitkSliceAnimationItem_h
+#define QmitkSliceAnimationItem_h
+
+#include "QmitkAnimationItem.h"
+
+class QmitkSliceAnimationItem : public QmitkAnimationItem
+{
+public:
+ explicit QmitkSliceAnimationItem(int renderWindow = 0, int from = 0, int to = 0, bool reverse = false, double duration = 2.0, double delay = 0.0, bool startWithPrevious = false);
+ virtual ~QmitkSliceAnimationItem();
+
+ int GetRenderWindow() const;
+ void SetRenderWindow(int renderWindow);
+
+ int GetFrom() const;
+ void SetFrom(int from);
+
+ int GetTo() const;
+ void SetTo(int to);
+
+ bool GetReverse() const;
+ void SetReverse(bool reverse);
+
+ void Animate(double s);
+};
+
+#endif
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkSliceAnimationWidget.cpp b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkSliceAnimationWidget.cpp
new file mode 100644
index 0000000000..b6aef991c1
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkSliceAnimationWidget.cpp
@@ -0,0 +1,131 @@
+/*===================================================================
+
+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 "QmitkSliceAnimationItem.h"
+#include "QmitkSliceAnimationWidget.h"
+#include <mitkBaseRenderer.h>
+#include <ui_QmitkSliceAnimationWidget.h>
+
+static int GetNumberOfSlices(int renderWindow)
+{
+ const QString renderWindowName = QString("stdmulti.widget%1").arg(renderWindow + 1);
+ vtkRenderWindow* theRenderWindow = mitk::BaseRenderer::GetRenderWindowByName(renderWindowName.toStdString());
+
+ if (theRenderWindow != NULL)
+ {
+ mitk::Stepper* stepper = mitk::BaseRenderer::GetInstance(theRenderWindow)->GetSliceNavigationController()->GetSlice();
+
+ if (stepper != NULL)
+ return std::max(1, static_cast<int>(stepper->GetSteps()));
+ }
+
+ return 1;
+}
+
+QmitkSliceAnimationWidget::QmitkSliceAnimationWidget(QWidget* parent)
+ : QmitkAnimationWidget(parent),
+ m_Ui(new Ui::QmitkSliceAnimationWidget)
+{
+ m_Ui->setupUi(this);
+
+ this->connect(m_Ui->windowComboBox, SIGNAL(currentIndexChanged(int)),
+ this, SLOT(OnRenderWindowChanged(int)));
+
+ this->connect(m_Ui->sliceRangeWidget, SIGNAL(minimumValueChanged(double)),
+ this, SLOT(OnFromChanged(double)));
+
+ this->connect(m_Ui->sliceRangeWidget, SIGNAL(maximumValueChanged(double)),
+ this, SLOT(OnToChanged(double)));
+
+ this->connect(m_Ui->reverseCheckBox, SIGNAL(clicked(bool)),
+ this, SLOT(OnReverseChanged(bool)));
+}
+
+QmitkSliceAnimationWidget::~QmitkSliceAnimationWidget()
+{
+}
+
+void QmitkSliceAnimationWidget::SetAnimationItem(QmitkAnimationItem* sliceAnimationItem)
+{
+ m_AnimationItem = dynamic_cast<QmitkSliceAnimationItem*>(sliceAnimationItem);
+
+ if (m_AnimationItem == NULL)
+ return;
+
+ m_Ui->windowComboBox->setCurrentIndex(m_AnimationItem->GetRenderWindow());
+
+ const int maximum = GetNumberOfSlices(m_AnimationItem->GetRenderWindow()) - 1;
+ const int from = std::min(m_AnimationItem->GetFrom(), maximum);
+ const int to = std::min(m_AnimationItem->GetTo(), maximum);
+
+ m_AnimationItem->SetFrom(from);
+ m_AnimationItem->SetTo(to);
+
+ m_Ui->sliceRangeWidget->setMaximum(maximum);
+ m_Ui->sliceRangeWidget->setValues(from, to);
+ m_Ui->reverseCheckBox->setChecked(m_AnimationItem->GetReverse());
+}
+
+void QmitkSliceAnimationWidget::OnRenderWindowChanged(int renderWindow)
+{
+ if (m_AnimationItem == NULL)
+ return;
+
+ const int lastSlice = static_cast<int>(GetNumberOfSlices(renderWindow) - 1);
+
+ if (lastSlice < m_AnimationItem->GetFrom())
+ m_AnimationItem->SetFrom(lastSlice);
+
+ if (lastSlice < m_AnimationItem->GetTo())
+ m_AnimationItem->SetTo(lastSlice);
+
+ m_Ui->sliceRangeWidget->setMaximum(lastSlice);
+ m_Ui->sliceRangeWidget->setValues(m_AnimationItem->GetFrom(), m_AnimationItem->GetTo());
+
+ if (m_AnimationItem->GetRenderWindow() != renderWindow)
+ m_AnimationItem->SetRenderWindow(renderWindow);
+}
+
+void QmitkSliceAnimationWidget::OnFromChanged(double from)
+{
+ if (m_AnimationItem == NULL)
+ return;
+
+ int intFrom = static_cast<int>(from);
+
+ if (m_AnimationItem->GetFrom() != intFrom)
+ m_AnimationItem->SetFrom(intFrom);
+}
+
+void QmitkSliceAnimationWidget::OnToChanged(double to)
+{
+ if (m_AnimationItem == NULL)
+ return;
+
+ int intTo = static_cast<int>(to);
+
+ if (m_AnimationItem->GetTo() != intTo)
+ m_AnimationItem->SetTo(intTo);
+}
+
+void QmitkSliceAnimationWidget::OnReverseChanged(bool reverse)
+{
+ if (m_AnimationItem == NULL)
+ return;
+
+ if (m_AnimationItem->GetReverse() != reverse)
+ m_AnimationItem->SetReverse(reverse);
+}
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkSliceAnimationWidget.h b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkSliceAnimationWidget.h
new file mode 100644
index 0000000000..a12de9ed58
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkSliceAnimationWidget.h
@@ -0,0 +1,50 @@
+/*===================================================================
+
+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 QmitkSliceAnimationWidget_h
+#define QmitkSliceAnimationWidget_h
+
+#include "QmitkAnimationWidget.h"
+
+class QmitkSliceAnimationItem;
+
+namespace Ui
+{
+ class QmitkSliceAnimationWidget;
+}
+
+class QmitkSliceAnimationWidget : public QmitkAnimationWidget
+{
+ Q_OBJECT
+
+public:
+ explicit QmitkSliceAnimationWidget(QWidget* parent = NULL);
+ ~QmitkSliceAnimationWidget();
+
+ void SetAnimationItem(QmitkAnimationItem* sliceAnimationItem);
+
+private slots:
+ void OnRenderWindowChanged(int renderWindow);
+ void OnFromChanged(double from);
+ void OnToChanged(double to);
+ void OnReverseChanged(bool reverse);
+
+private:
+ Ui::QmitkSliceAnimationWidget* m_Ui;
+ QmitkSliceAnimationItem* m_AnimationItem;
+};
+
+#endif
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkSliceAnimationWidget.ui b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkSliceAnimationWidget.ui
new file mode 100644
index 0000000000..86f72fc9d9
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkSliceAnimationWidget.ui
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>QmitkSliceAnimationWidget</class>
+ <widget class="QWidget" name="QmitkSliceAnimationWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>304</width>
+ <height>96</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>QmitkSliceAnimationWidget</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="windowLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Window:</string>
+ </property>
+ <property name="buddy">
+ <cstring>windowComboBox</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="2">
+ <widget class="QComboBox" name="windowComboBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <item>
+ <property name="text">
+ <string>Axial</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Sagittal</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Coronal</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="sliceRangeLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Slice range:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" colspan="2">
+ <widget class="ctkRangeWidget" name="sliceRangeWidget">
+ <property name="decimals">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <double>999.000000000000000</double>
+ </property>
+ <property name="maximumValue">
+ <double>999.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QCheckBox" name="reverseCheckBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Reverse</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>ctkRangeWidget</class>
+ <extends>QWidget</extends>
+ <header>ctkRangeWidget.h</header>
+ </customwidget>
+ </customwidgets>
+ <tabstops>
+ <tabstop>windowComboBox</tabstop>
+ <tabstop>reverseCheckBox</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkTimeSliceAnimationItem.cpp b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkTimeSliceAnimationItem.cpp
new file mode 100644
index 0000000000..8c84cc8fca
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkTimeSliceAnimationItem.cpp
@@ -0,0 +1,74 @@
+/*===================================================================
+
+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 "QmitkTimeSliceAnimationItem.h"
+#include <mitkBaseRenderer.h>
+
+QmitkTimeSliceAnimationItem::QmitkTimeSliceAnimationItem(int from, int to, bool reverse, double duration, double delay, bool startWithPrevious)
+ : QmitkAnimationItem("Time", duration, delay, startWithPrevious)
+{
+ this->SetFrom(from);
+ this->SetTo(to);
+ this->SetReverse(reverse);
+}
+
+QmitkTimeSliceAnimationItem::~QmitkTimeSliceAnimationItem()
+{
+}
+
+int QmitkTimeSliceAnimationItem::GetFrom() const
+{
+ return this->data(FromRole).toInt();
+}
+
+void QmitkTimeSliceAnimationItem::SetFrom(int from)
+{
+ this->setData(from, FromRole);
+}
+
+int QmitkTimeSliceAnimationItem::GetTo() const
+{
+ return this->data(ToRole).toInt();
+}
+
+void QmitkTimeSliceAnimationItem::SetTo(int to)
+{
+ this->setData(to, ToRole);
+}
+
+bool QmitkTimeSliceAnimationItem::GetReverse() const
+{
+ return this->data(ReverseRole).toBool();
+}
+
+void QmitkTimeSliceAnimationItem::SetReverse(bool reverse)
+{
+ this->setData(reverse, ReverseRole);
+}
+
+void QmitkTimeSliceAnimationItem::Animate(double s)
+{
+ mitk::Stepper* stepper = mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetTime();
+
+ if (stepper == NULL)
+ return;
+
+ int newPos = this->GetReverse()
+ ? this->GetTo() - static_cast<int>((this->GetTo() - this->GetFrom()) * s)
+ : this->GetFrom() + static_cast<int>((this->GetTo() - this->GetFrom()) * s);
+
+ stepper->SetPos(static_cast<unsigned int>(newPos));
+}
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkTimeSliceAnimationItem.h b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkTimeSliceAnimationItem.h
new file mode 100644
index 0000000000..916f74ae20
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkTimeSliceAnimationItem.h
@@ -0,0 +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 QmitkTimeSliceAnimationItem_h
+#define QmitkTimeSliceAnimationItem_h
+
+#include "QmitkAnimationItem.h"
+
+class QmitkTimeSliceAnimationItem : public QmitkAnimationItem
+{
+public:
+ explicit QmitkTimeSliceAnimationItem(int from = 0, int to = 0, bool reverse = false, double duration = 2.0, double delay = 0.0, bool startWithPrevious = false);
+ virtual ~QmitkTimeSliceAnimationItem();
+
+ int GetFrom() const;
+ void SetFrom(int from);
+
+ int GetTo() const;
+ void SetTo(int to);
+
+ bool GetReverse() const;
+ void SetReverse(bool reverse);
+
+ void Animate(double s);
+};
+
+#endif
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkTimeSliceAnimationWidget.cpp b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkTimeSliceAnimationWidget.cpp
new file mode 100644
index 0000000000..189f4eda95
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkTimeSliceAnimationWidget.cpp
@@ -0,0 +1,102 @@
+/*===================================================================
+
+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 "QmitkTimeSliceAnimationItem.h"
+#include "QmitkTimeSliceAnimationWidget.h"
+#include <mitkRenderingManager.h>
+#include <mitkSliceNavigationController.h>
+#include <mitkStepper.h>
+#include <ui_QmitkTimeSliceAnimationWidget.h>
+
+static int GetNumberOfSlices()
+{
+ mitk::Stepper* stepper = mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetTime();
+
+ if (stepper != NULL)
+ return std::max(1, static_cast<int>(stepper->GetSteps()));
+
+ return 1;
+}
+
+QmitkTimeSliceAnimationWidget::QmitkTimeSliceAnimationWidget(QWidget* parent)
+ : QmitkAnimationWidget(parent),
+ m_Ui(new Ui::QmitkTimeSliceAnimationWidget)
+{
+ m_Ui->setupUi(this);
+
+ this->connect(m_Ui->sliceRangeWidget, SIGNAL(minimumValueChanged(double)),
+ this, SLOT(OnFromChanged(double)));
+
+ this->connect(m_Ui->sliceRangeWidget, SIGNAL(maximumValueChanged(double)),
+ this, SLOT(OnToChanged(double)));
+
+ this->connect(m_Ui->reverseCheckBox, SIGNAL(clicked(bool)),
+ this, SLOT(OnReverseChanged(bool)));
+}
+
+QmitkTimeSliceAnimationWidget::~QmitkTimeSliceAnimationWidget()
+{
+}
+
+void QmitkTimeSliceAnimationWidget::SetAnimationItem(QmitkAnimationItem* sliceAnimationItem)
+{
+ m_AnimationItem = dynamic_cast<QmitkTimeSliceAnimationItem*>(sliceAnimationItem);
+
+ if (m_AnimationItem == NULL)
+ return;
+
+ const int maximum = GetNumberOfSlices() - 1;
+ const int from = std::min(m_AnimationItem->GetFrom(), maximum);
+ const int to = std::min(m_AnimationItem->GetTo(), maximum);
+
+ m_AnimationItem->SetFrom(from);
+ m_AnimationItem->SetTo(to);
+
+ m_Ui->sliceRangeWidget->setMaximum(maximum);
+ m_Ui->sliceRangeWidget->setValues(from, to);
+ m_Ui->reverseCheckBox->setChecked(m_AnimationItem->GetReverse());
+}
+
+void QmitkTimeSliceAnimationWidget::OnFromChanged(double from)
+{
+ if (m_AnimationItem == NULL)
+ return;
+
+ int intFrom = static_cast<int>(from);
+
+ if (m_AnimationItem->GetFrom() != intFrom)
+ m_AnimationItem->SetFrom(intFrom);
+}
+
+void QmitkTimeSliceAnimationWidget::OnToChanged(double to)
+{
+ if (m_AnimationItem == NULL)
+ return;
+
+ int intTo = static_cast<int>(to);
+
+ if (m_AnimationItem->GetTo() != intTo)
+ m_AnimationItem->SetTo(intTo);
+}
+
+void QmitkTimeSliceAnimationWidget::OnReverseChanged(bool reverse)
+{
+ if (m_AnimationItem == NULL)
+ return;
+
+ if (m_AnimationItem->GetReverse() != reverse)
+ m_AnimationItem->SetReverse(reverse);
+}
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkTimeSliceAnimationWidget.h b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkTimeSliceAnimationWidget.h
new file mode 100644
index 0000000000..bed8155dc0
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkTimeSliceAnimationWidget.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 QmitkTimeSliceAnimationWidget_h
+#define QmitkTimeSliceAnimationWidget_h
+
+#include "QmitkAnimationWidget.h"
+
+class QmitkTimeSliceAnimationItem;
+
+namespace Ui
+{
+ class QmitkTimeSliceAnimationWidget;
+}
+
+class QmitkTimeSliceAnimationWidget : public QmitkAnimationWidget
+{
+ Q_OBJECT
+
+public:
+ explicit QmitkTimeSliceAnimationWidget(QWidget* parent = NULL);
+ ~QmitkTimeSliceAnimationWidget();
+
+ void SetAnimationItem(QmitkAnimationItem* sliceAnimationItem);
+
+private slots:
+ void OnFromChanged(double from);
+ void OnToChanged(double to);
+ void OnReverseChanged(bool reverse);
+
+private:
+ Ui::QmitkTimeSliceAnimationWidget* m_Ui;
+ QmitkTimeSliceAnimationItem* m_AnimationItem;
+};
+
+#endif
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkTimeSliceAnimationWidget.ui b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkTimeSliceAnimationWidget.ui
new file mode 100644
index 0000000000..a74fa2a150
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/QmitkTimeSliceAnimationWidget.ui
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>QmitkTimeSliceAnimationWidget</class>
+ <widget class="QWidget" name="QmitkTimeSliceAnimationWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>304</width>
+ <height>71</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>QmitkTimeSliceAnimationWidget</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="sliceRangeLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Slice range:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QCheckBox" name="reverseCheckBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Reverse</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="2">
+ <widget class="ctkRangeWidget" name="sliceRangeWidget" native="true">
+ <property name="decimals" stdset="0">
+ <number>0</number>
+ </property>
+ <property name="maximum" stdset="0">
+ <double>999.000000000000000</double>
+ </property>
+ <property name="maximumValue" stdset="0">
+ <double>999.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>ctkRangeWidget</class>
+ <extends>QWidget</extends>
+ <header>ctkRangeWidget.h</header>
+ </customwidget>
+ </customwidgets>
+ <tabstops>
+ <tabstop>reverseCheckBox</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/mitkMovieMakerPluginActivator.cpp b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/mitkMovieMakerPluginActivator.cpp
index 6becf27540..81f7742a7b 100644
--- a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/mitkMovieMakerPluginActivator.cpp
+++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/mitkMovieMakerPluginActivator.cpp
@@ -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.
===================================================================*/
#include "mitkMovieMakerPluginActivator.h"
-#include "QmitkMovieMaker.h"
+#include "QmitkMovieMakerView.h"
#include "QmitkScreenshotMaker.h"
#include <QtPlugin>
namespace mitk {
void MovieMakerPluginActivator::start(ctkPluginContext* context)
{
- BERRY_REGISTER_EXTENSION_CLASS(QmitkMovieMaker, context)
+ BERRY_REGISTER_EXTENSION_CLASS(QmitkMovieMakerView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkScreenshotMaker, context)
}
void MovieMakerPluginActivator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_moviemaker, mitk::MovieMakerPluginActivator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_moviemaker, mitk::MovieMakerPluginActivator)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/mitkMovieMakerPluginActivator.h b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/mitkMovieMakerPluginActivator.h
index 380e629689..be23ecec69 100644
--- a/Plugins/org.mitk.gui.qt.moviemaker/src/internal/mitkMovieMakerPluginActivator.h
+++ b/Plugins/org.mitk.gui.qt.moviemaker/src/internal/mitkMovieMakerPluginActivator.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 MITKMOVIEMAKERPLUGINACTIVATOR_H
#define MITKMOVIEMAKERPLUGINACTIVATOR_H
#include <ctkPluginActivator.h>
namespace mitk {
class MovieMakerPluginActivator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
- Q_INTERFACES(ctkPluginActivator)
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_moviemaker")
+#endif
+ Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
}; // MovieMakerPluginActivator
}
#endif // MITKMOVIEMAKERPLUGINACTIVATOR_H
diff --git a/Plugins/org.mitk.gui.qt.pointsetinteraction/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.pointsetinteraction/src/internal/mitkPluginActivator.cpp
index 05cadbea0a..69cab01fdb 100644
--- a/Plugins/org.mitk.gui.qt.pointsetinteraction/src/internal/mitkPluginActivator.cpp
+++ b/Plugins/org.mitk.gui.qt.pointsetinteraction/src/internal/mitkPluginActivator.cpp
@@ -1,36 +1,38 @@
/*===================================================================
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 "mitkPluginActivator.h"
#include "QmitkPointSetInteractionView.h"
#include <QtPlugin>
namespace mitk {
void PluginActivator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(QmitkPointSetInteractionView, context)
}
void PluginActivator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_pointsetinteraction, mitk::PluginActivator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_pointsetinteraction, mitk::PluginActivator)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.pointsetinteraction/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.pointsetinteraction/src/internal/mitkPluginActivator.h
index 28a2aa0fdc..030dad599d 100644
--- a/Plugins/org.mitk.gui.qt.pointsetinteraction/src/internal/mitkPluginActivator.h
+++ b/Plugins/org.mitk.gui.qt.pointsetinteraction/src/internal/mitkPluginActivator.h
@@ -1,39 +1,42 @@
/*===================================================================
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 MITKPLUGINACTIVATOR_H
#define MITKPLUGINACTIVATOR_H
#include <ctkPluginActivator.h>
#include <mitkExportMacros.h>
namespace mitk {
class MITK_LOCAL PluginActivator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
- Q_INTERFACES(ctkPluginActivator)
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_pointsetinteraction")
+#endif
+ Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
}; // PluginActivator
}
#endif // MITKPLUGINACTIVATOR_H
diff --git a/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkAddNewPropertyDialog.cpp b/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkAddNewPropertyDialog.cpp
index 55e6f2c830..31846956ed 100644
--- a/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkAddNewPropertyDialog.cpp
+++ b/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkAddNewPropertyDialog.cpp
@@ -1,172 +1,172 @@
/*===================================================================
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 "QmitkAddNewPropertyDialog.h"
#include <mitkProperties.h>
#include <QMessageBox>
#include <cassert>
QmitkAddNewPropertyDialog::QmitkAddNewPropertyDialog(mitk::DataNode::Pointer dataNode, mitk::BaseRenderer::Pointer renderer, QWidget* parent)
: QDialog(parent),
m_DataNode(dataNode),
m_Renderer(renderer)
{
m_Controls.setupUi(this);
QStringList types;
types << "bool" << "double" << "float" << "int" << "string";
m_Controls.typeComboBox->addItems(types);
connect(m_Controls.typeComboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(ShowAdequateValueWidget(const QString&)));
connect(m_Controls.addButton, SIGNAL(clicked()), this, SLOT(AddNewProperty()));
connect(m_Controls.cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
this->ShowAdequateValueWidget(types[0]);
}
QmitkAddNewPropertyDialog::~QmitkAddNewPropertyDialog()
{
}
void QmitkAddNewPropertyDialog::AddNewProperty()
{
if (m_Controls.nameLineEdit->text().isEmpty())
{
QMessageBox::critical(this, "No name specified", "Enter a property name.");
return;
}
if (!this->ValidateValue())
{
QMessageBox::critical(this, "Invalid value", "Enter a valid " + m_Controls.typeComboBox->currentText() + " value.");
return;
}
- m_DataNode->SetProperty(m_Controls.nameLineEdit->text().toAscii(), this->CreateProperty(), m_Renderer);
+ m_DataNode->SetProperty(m_Controls.nameLineEdit->text().toLatin1(), this->CreateProperty(), m_Renderer);
this->accept();
}
mitk::BaseProperty::Pointer QmitkAddNewPropertyDialog::CreateProperty() const
{
QString type = m_Controls.typeComboBox->currentText();
if (type == "bool")
{
return mitk::BoolProperty::New(m_Controls.valueCheckBox->isChecked()).GetPointer();
}
else if (type == "double")
{
return mitk::DoubleProperty::New(m_Controls.valueLineEdit->text().toDouble()).GetPointer();
}
else if (type == "float")
{
return mitk::FloatProperty::New(m_Controls.valueLineEdit->text().toFloat()).GetPointer();
}
else if (type == "int")
{
return mitk::IntProperty::New(m_Controls.valueLineEdit->text().toInt()).GetPointer();
}
else if (type == "string")
{
return mitk::StringProperty::New(m_Controls.valueLineEdit->text().toStdString()).GetPointer();
}
else
{
assert(false && "Property creation for selected type not implemented!");
}
return NULL;
}
bool QmitkAddNewPropertyDialog::ValidateValue()
{
QString type = m_Controls.typeComboBox->currentText();
if (type == "bool")
{
return true;
}
else if (type == "double")
{
bool ok = false;
m_Controls.valueLineEdit->text().toDouble(&ok);
return ok;
}
else if (type == "float")
{
bool ok = false;
m_Controls.valueLineEdit->text().toFloat(&ok);
return ok;
}
else if (type == "int")
{
bool ok = false;
m_Controls.valueLineEdit->text().toInt(&ok);
return ok;
}
else if (type == "string")
{
return true;
}
else
{
assert(false && "Value validation for selected type not implemented!");
}
return false;
}
void QmitkAddNewPropertyDialog::ShowAdequateValueWidget(const QString& type)
{
m_Controls.valueLineEdit->clear();
m_Controls.valueLineEdit->hide();
m_Controls.valueCheckBox->setChecked(false);
m_Controls.valueCheckBox->hide();
if (type == "bool")
{
m_Controls.valueCheckBox->show();
}
else if (type == "double")
{
m_Controls.valueLineEdit->setText("0");
m_Controls.valueLineEdit->show();
}
else if (type == "float")
{
m_Controls.valueLineEdit->setText("0");
m_Controls.valueLineEdit->show();
}
else if (type == "int")
{
m_Controls.valueLineEdit->setText("0");
m_Controls.valueLineEdit->show();
}
else if (type == "string")
{
m_Controls.valueLineEdit->show();
}
else
{
assert(false && "No adequate value widget specified for selected type!");
}
}
\ No newline at end of file
diff --git a/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyItemModel.cpp b/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyItemModel.cpp
index f57e188d6a..d792bfea83 100644
--- a/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyItemModel.cpp
+++ b/Plugins/org.mitk.gui.qt.properties/src/internal/QmitkPropertyItemModel.cpp
@@ -1,520 +1,521 @@
/*===================================================================
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 "mitkGetPropertyService.h"
#include "QmitkPropertiesPreferencePage.h"
#include "QmitkPropertyItem.h"
#include "QmitkPropertyItemModel.h"
#include <berryIBerryPreferences.h>
#include <mitkColorProperty.h>
#include <mitkEnumerationProperty.h>
#include <mitkProperties.h>
#include <mitkIPropertyAliases.h>
#include <mitkIPropertyFilters.h>
#include <mitkRenderingManager.h>
#include <mitkStringProperty.h>
static QColor MitkToQt(const mitk::Color &color)
{
return QColor(color.GetRed() * 255, color.GetGreen() * 255, color.GetBlue() * 255);
}
static mitk::BaseProperty* GetBaseProperty(const QVariant& data)
{
return data.isValid()
? reinterpret_cast<mitk::BaseProperty*>(data.value<void*>())
: NULL;
}
static mitk::Color QtToMitk(const QColor &color)
{
mitk::Color mitkColor;
mitkColor.SetRed(color.red() / 255.0f);
mitkColor.SetGreen(color.green() / 255.0f);
mitkColor.SetBlue(color.blue() / 255.0f);
return mitkColor;
}
class PropertyEqualTo
{
public:
PropertyEqualTo(const mitk::BaseProperty* property)
: m_Property(property)
{
}
bool operator()(const mitk::PropertyList::PropertyMapElementType& pair) const
{
return pair.second.GetPointer() == m_Property;
}
private:
const mitk::BaseProperty* m_Property;
};
QmitkPropertyItemModel::QmitkPropertyItemModel(QObject* parent)
: QAbstractItemModel(parent),
m_PropertyAliases(NULL),
m_PropertyFilters(NULL)
{
this->CreateRootItem();
}
QmitkPropertyItemModel::~QmitkPropertyItemModel()
{
this->SetNewPropertyList(NULL);
}
int QmitkPropertyItemModel::columnCount(const QModelIndex& parent) const
{
if (parent.isValid())
return static_cast<QmitkPropertyItem*>(parent.internalPointer())->GetColumnCount();
else
return m_RootItem->GetColumnCount();
}
void QmitkPropertyItemModel::CreateRootItem()
{
QList<QVariant> rootData;
rootData << "Property" << "Value";
m_RootItem.reset(new QmitkPropertyItem(rootData));
- this->reset();
+ this->beginResetModel();
+ this->endResetModel();
}
QVariant QmitkPropertyItemModel::data(const QModelIndex& index, int role) const
{
if(!index.isValid())
return QVariant();
mitk::BaseProperty* property = index.column() == 1
? GetBaseProperty(static_cast<QmitkPropertyItem*>(index.internalPointer())->GetData(1))
: NULL;
if (role == Qt::DisplayRole)
{
if (index.column() == 0)
{
return static_cast<QmitkPropertyItem*>(index.internalPointer())->GetData(0);
}
else if (index.column() == 1 && property != NULL)
{
if (mitk::ColorProperty* colorProperty = dynamic_cast<mitk::ColorProperty*>(property))
return MitkToQt(colorProperty->GetValue());
else if (dynamic_cast<mitk::BoolProperty*>(property) == NULL)
return QString::fromStdString(property->GetValueAsString());
}
}
else if (index.column() == 1 && property != NULL)
{
if (role == Qt::CheckStateRole)
{
if (mitk::BoolProperty* boolProperty = dynamic_cast<mitk::BoolProperty*>(property))
return boolProperty->GetValue() ? Qt::Checked : Qt::Unchecked;
}
else if (role == Qt::EditRole)
{
if (dynamic_cast<mitk::StringProperty*>(property) != NULL)
{
return QString::fromStdString(property->GetValueAsString());
}
else if (mitk::IntProperty* intProperty = dynamic_cast<mitk::IntProperty*>(property))
{
return intProperty->GetValue();
}
else if (mitk::FloatProperty* floatProperty = dynamic_cast<mitk::FloatProperty*>(property))
{
return floatProperty->GetValue();
}
else if (mitk::DoubleProperty* doubleProperty = dynamic_cast<mitk::DoubleProperty*>(property))
{
return doubleProperty->GetValue();
}
else if (mitk::EnumerationProperty* enumProperty = dynamic_cast<mitk::EnumerationProperty*>(property))
{
QStringList values;
for (mitk::EnumerationProperty::EnumConstIterator it = enumProperty->Begin(); it != enumProperty->End(); it++)
values << QString::fromStdString(it->second);
return values;
}
else if (mitk::ColorProperty* colorProperty = dynamic_cast<mitk::ColorProperty*>(property))
{
return MitkToQt(colorProperty->GetValue());
}
}
else if (role == mitk::PropertyRole)
{
return QVariant::fromValue<void*>(property);
}
}
return QVariant();
}
QModelIndex QmitkPropertyItemModel::FindProperty(const mitk::BaseProperty* property)
{
if (property == NULL)
return QModelIndex();
typedef mitk::PropertyList::PropertyMap PropertyMap;
const PropertyMap* propertyMap = m_PropertyList->GetMap();
PropertyMap::const_iterator it = std::find_if(propertyMap->begin(), propertyMap->end(), PropertyEqualTo(property));
if (it == propertyMap->end())
return QModelIndex();
QString name = QString::fromStdString(it->first);
if (!name.contains('.'))
{
QModelIndexList item = this->match(index(0, 0), Qt::DisplayRole, name, 1, Qt::MatchExactly);
if (!item.empty())
return item[0];
}
else
{
QStringList names = name.split('.');
QModelIndexList items = this->match(index(0, 0), Qt::DisplayRole, names.last(), -1, Qt::MatchRecursive | Qt::MatchExactly);
foreach(QModelIndex item, items)
{
QModelIndex candidate = item;
for (int i = names.length() - 1; i != 0; --i)
{
QModelIndex parent = item.parent();
if (parent.parent() == QModelIndex())
{
if (parent.data() != names.first())
break;
return candidate;
}
if (parent.data() != names[i - 1])
break;
item = parent;
}
}
}
return QModelIndex();
}
Qt::ItemFlags QmitkPropertyItemModel::flags(const QModelIndex& index) const
{
Qt::ItemFlags flags = QAbstractItemModel::flags(index);
if (index.column() == 1)
{
if (index.data(Qt::EditRole).isValid())
flags |= Qt::ItemIsEditable;
if (index.data(Qt::CheckStateRole).isValid())
flags |= Qt::ItemIsUserCheckable;
}
return flags;
}
mitk::PropertyList* QmitkPropertyItemModel::GetPropertyList() const
{
return m_PropertyList.GetPointer();
}
QVariant QmitkPropertyItemModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
return m_RootItem->GetData(section);
return QVariant();
}
QModelIndex QmitkPropertyItemModel::index(int row, int column, const QModelIndex& parent) const
{
if (!this->hasIndex(row, column, parent))
return QModelIndex();
QmitkPropertyItem* parentItem = parent.isValid()
? static_cast<QmitkPropertyItem*>(parent.internalPointer())
: m_RootItem.get();
QmitkPropertyItem* childItem = parentItem->GetChild(row);
return childItem != NULL
? this->createIndex(row, column, childItem)
: QModelIndex();
}
void QmitkPropertyItemModel::OnPreferencesChanged(const berry::IBerryPreferences* preferences)
{
bool showAliases = preferences->GetBool(QmitkPropertiesPreferencePage::SHOW_ALIASES, true);
bool filterProperties = preferences->GetBool(QmitkPropertiesPreferencePage::FILTER_PROPERTIES, true);
bool updateAliases = showAliases != (m_PropertyAliases != NULL);
bool updateFilters = filterProperties != (m_PropertyFilters != NULL);
bool resetPropertyList = false;
if (updateAliases)
{
m_PropertyAliases = showAliases
? mitk::GetPropertyService<mitk::IPropertyAliases>()
: NULL;
resetPropertyList = m_PropertyList.IsNotNull();
}
if (updateFilters)
{
m_PropertyFilters = filterProperties
? mitk::GetPropertyService<mitk::IPropertyFilters>()
: NULL;
if (!resetPropertyList)
resetPropertyList = m_PropertyList.IsNotNull();
}
if (resetPropertyList)
this->SetNewPropertyList(m_PropertyList.GetPointer());
}
void QmitkPropertyItemModel::OnPropertyDeleted(const itk::Object* property, const itk::EventObject&)
{
/*QModelIndex index = this->FindProperty(static_cast<const mitk::BaseProperty*>(property));
if (index != QModelIndex())
this->reset();*/
}
void QmitkPropertyItemModel::OnPropertyListDeleted(const itk::Object*)
{
this->CreateRootItem();
}
void QmitkPropertyItemModel::OnPropertyModified(const itk::Object* property, const itk::EventObject&)
{
QModelIndex index = this->FindProperty(static_cast<const mitk::BaseProperty*>(property));
if (index != QModelIndex())
emit dataChanged(index, index);
}
QModelIndex QmitkPropertyItemModel::parent(const QModelIndex& child) const
{
if (!child.isValid())
return QModelIndex();
QmitkPropertyItem* parentItem = static_cast<QmitkPropertyItem*>(child.internalPointer())->GetParent();
if (parentItem == m_RootItem.get())
return QModelIndex();
return this->createIndex(parentItem->GetRow(), 0, parentItem);
}
int QmitkPropertyItemModel::rowCount(const QModelIndex& parent) const
{
if (parent.column() > 0)
return 0;
QmitkPropertyItem *parentItem = parent.isValid()
? static_cast<QmitkPropertyItem*>(parent.internalPointer())
: m_RootItem.get();
return parentItem->GetChildCount();
}
bool QmitkPropertyItemModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
if (!index.isValid() || index.column() != 1 || (role != Qt::EditRole && role != Qt::CheckStateRole))
return false;
mitk::BaseProperty* property = GetBaseProperty(static_cast<QmitkPropertyItem*>(index.internalPointer())->GetData(1));
if (property == NULL)
return false;
if (mitk::BoolProperty* boolProperty = dynamic_cast<mitk::BoolProperty*>(property))
{
boolProperty->SetValue(value.toInt() == Qt::Checked ? true : false);
}
else if (mitk::StringProperty* stringProperty = dynamic_cast<mitk::StringProperty*>(property))
{
stringProperty->SetValue(value.toString().toStdString());
}
else if (mitk::IntProperty* intProperty = dynamic_cast<mitk::IntProperty*>(property))
{
intProperty->SetValue(value.toInt());
}
else if (mitk::FloatProperty* floatProperty = dynamic_cast<mitk::FloatProperty*>(property))
{
floatProperty->SetValue(value.toFloat());
}
else if (mitk::DoubleProperty* doubleProperty = dynamic_cast<mitk::DoubleProperty*>(property))
{
doubleProperty->SetValue(value.toDouble());
}
else if (mitk::EnumerationProperty* enumProperty = dynamic_cast<mitk::EnumerationProperty*>(property))
{
std::string selection = value.toString().toStdString();
if (selection != enumProperty->GetValueAsString() && enumProperty->IsValidEnumerationValue(selection))
enumProperty->SetValue(selection);
}
else if (mitk::ColorProperty* colorProperty = dynamic_cast<mitk::ColorProperty*>(property))
{
colorProperty->SetValue(QtToMitk(value.value<QColor>()));
}
m_PropertyList->InvokeEvent(itk::ModifiedEvent());
m_PropertyList->Modified();
mitk::RenderingManager::GetInstance()->RequestUpdateAll();
return true;
}
void QmitkPropertyItemModel::SetNewPropertyList(mitk::PropertyList* propertyList)
{
typedef mitk::PropertyList::PropertyMap PropertyMap;
this->beginResetModel();
if (m_PropertyList.IsNotNull())
{
mitk::MessageDelegate1<QmitkPropertyItemModel, const itk::Object*> delegate(this, &QmitkPropertyItemModel::OnPropertyListDeleted);
m_PropertyList.ObjectDelete.RemoveListener(delegate);
const PropertyMap* propertyMap = m_PropertyList->GetMap();
for (PropertyMap::const_iterator propertyIt = propertyMap->begin(); propertyIt != propertyMap->end(); ++propertyIt)
{
std::map<std::string, unsigned long>::const_iterator tagIt = m_PropertyModifiedTags.find(propertyIt->first);
if (tagIt != m_PropertyModifiedTags.end())
propertyIt->second->RemoveObserver(tagIt->second);
tagIt = m_PropertyDeletedTags.find(propertyIt->first);
if (tagIt != m_PropertyDeletedTags.end())
propertyIt->second->RemoveObserver(tagIt->second);
}
m_PropertyModifiedTags.clear();
}
m_PropertyList = propertyList;
if (m_PropertyList.IsNotNull())
{
mitk::MessageDelegate1<QmitkPropertyItemModel, const itk::Object*> delegate(this, &QmitkPropertyItemModel::OnPropertyListDeleted);
m_PropertyList.ObjectDelete.AddListener(delegate);
mitk::MessageDelegate2<QmitkPropertyItemModel, const itk::Object*, const itk::EventObject&> propertyDelegate(this, &QmitkPropertyItemModel::OnPropertyModified);
itk::MemberCommand<QmitkPropertyItemModel>::Pointer modifiedCommand = itk::MemberCommand<QmitkPropertyItemModel>::New();
modifiedCommand->SetCallbackFunction(this, &QmitkPropertyItemModel::OnPropertyModified);
const PropertyMap* propertyMap = m_PropertyList->GetMap();
for (PropertyMap::const_iterator it = propertyMap->begin(); it != propertyMap->end(); ++it)
m_PropertyModifiedTags.insert(std::make_pair(it->first, it->second->AddObserver(itk::ModifiedEvent(), modifiedCommand)));
itk::MemberCommand<QmitkPropertyItemModel>::Pointer deletedCommand = itk::MemberCommand<QmitkPropertyItemModel>::New();
deletedCommand->SetCallbackFunction(this, &QmitkPropertyItemModel::OnPropertyDeleted);
for (PropertyMap::const_iterator it = propertyMap->begin(); it != propertyMap->end(); ++it)
m_PropertyDeletedTags.insert(std::make_pair(it->first, it->second->AddObserver(itk::DeleteEvent(), deletedCommand)));
}
this->CreateRootItem();
if (m_PropertyList != NULL && !m_PropertyList->IsEmpty())
{
mitk::PropertyList::PropertyMap filteredProperties;
bool filterProperties = false;
if (m_PropertyFilters != NULL && (m_PropertyFilters->HasFilter() || m_PropertyFilters->HasFilter(m_ClassName.toStdString())))
{
filteredProperties = m_PropertyFilters->ApplyFilter(*m_PropertyList->GetMap(), m_ClassName.toStdString());
filterProperties = true;
}
const mitk::PropertyList::PropertyMap* propertyMap = !filterProperties
? m_PropertyList->GetMap()
: &filteredProperties;
mitk::PropertyList::PropertyMap::const_iterator end = propertyMap->end();
for (mitk::PropertyList::PropertyMap::const_iterator iter = propertyMap->begin(); iter != end; ++iter)
{
std::vector<std::string> aliases;
if (m_PropertyAliases != NULL)
{
aliases = m_PropertyAliases->GetAliases(iter->first, m_ClassName.toStdString());
if (aliases.empty() && !m_ClassName.isEmpty())
aliases = m_PropertyAliases->GetAliases(iter->first);
}
if (aliases.empty())
{
QList<QVariant> data;
data << QString::fromStdString(iter->first) << QVariant::fromValue((reinterpret_cast<void *>(iter->second.GetPointer())));
m_RootItem->AppendChild(new QmitkPropertyItem(data));
}
else
{
std::vector<std::string>::const_iterator end = aliases.end();
for (std::vector<std::string>::const_iterator aliasIter = aliases.begin(); aliasIter != end; ++aliasIter)
{
QList<QVariant> data;
data << QString::fromStdString(*aliasIter) << QVariant::fromValue((reinterpret_cast<void *>(iter->second.GetPointer())));
m_RootItem->AppendChild(new QmitkPropertyItem(data));
}
}
}
}
this->endResetModel();
}
void QmitkPropertyItemModel::SetPropertyList(mitk::PropertyList* propertyList, const QString& className)
{
if (m_PropertyList.GetPointer() != propertyList)
{
m_ClassName = className;
this->SetNewPropertyList(propertyList);
}
}
void QmitkPropertyItemModel::Update()
{
this->SetNewPropertyList(m_PropertyList);
}
diff --git a/Plugins/org.mitk.gui.qt.properties/src/internal/org_mitk_gui_qt_properties_Activator.cpp b/Plugins/org.mitk.gui.qt.properties/src/internal/org_mitk_gui_qt_properties_Activator.cpp
index 16112dd4f4..7c0a926d07 100644
--- a/Plugins/org.mitk.gui.qt.properties/src/internal/org_mitk_gui_qt_properties_Activator.cpp
+++ b/Plugins/org.mitk.gui.qt.properties/src/internal/org_mitk_gui_qt_properties_Activator.cpp
@@ -1,41 +1,43 @@
/*===================================================================
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_properties_Activator.h"
#include "QmitkPropertiesPreferencePage.h"
#include "QmitkPropertyTreeView.h"
#include <QtPlugin>
ctkPluginContext* mitk::org_mitk_gui_qt_properties_Activator::m_Context = NULL;
ctkPluginContext* mitk::org_mitk_gui_qt_properties_Activator::GetContext()
{
return m_Context;
}
void mitk::org_mitk_gui_qt_properties_Activator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(QmitkPropertiesPreferencePage, context);
BERRY_REGISTER_EXTENSION_CLASS(QmitkPropertyTreeView, context);
m_Context = context;
}
void mitk::org_mitk_gui_qt_properties_Activator::stop(ctkPluginContext*)
{
m_Context = NULL;
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_properties, mitk::org_mitk_gui_qt_properties_Activator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_properties, mitk::org_mitk_gui_qt_properties_Activator)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.properties/src/internal/org_mitk_gui_qt_properties_Activator.h b/Plugins/org.mitk.gui.qt.properties/src/internal/org_mitk_gui_qt_properties_Activator.h
index 331a0bebd8..cf54d060c8 100644
--- a/Plugins/org.mitk.gui.qt.properties/src/internal/org_mitk_gui_qt_properties_Activator.h
+++ b/Plugins/org.mitk.gui.qt.properties/src/internal/org_mitk_gui_qt_properties_Activator.h
@@ -1,40 +1,43 @@
/*===================================================================
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 org_mitk_gui_qt_properties_Activator_h
#define org_mitk_gui_qt_properties_Activator_h
#include <ctkPluginActivator.h>
namespace mitk
{
class org_mitk_gui_qt_properties_Activator : public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_properties")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
static ctkPluginContext* GetContext();
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
private:
static ctkPluginContext* m_Context;
};
}
#endif
diff --git a/Plugins/org.mitk.gui.qt.python/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.python/src/internal/mitkPluginActivator.cpp
index e59a8e8108..eca9c442f4 100644
--- a/Plugins/org.mitk.gui.qt.python/src/internal/mitkPluginActivator.cpp
+++ b/Plugins/org.mitk.gui.qt.python/src/internal/mitkPluginActivator.cpp
@@ -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.
===================================================================*/
#include "mitkPluginActivator.h"
#include <QtPlugin>
#include "QmitkPythonView.h"
namespace mitk
{
QString PluginActivator::m_XmlFilePath;
void PluginActivator::start(ctkPluginContext* context)
{
m_XmlFilePath = context->getDataFile("PythonSnippets.xml").absoluteFilePath();
BERRY_REGISTER_EXTENSION_CLASS(QmitkPythonView, context)
}
void PluginActivator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_python, mitk::PluginActivator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_python, mitk::PluginActivator)
+#endif
+
diff --git a/Plugins/org.mitk.gui.qt.python/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.python/src/internal/mitkPluginActivator.h
index 9a32e11e62..7c46ee5ea2 100644
--- a/Plugins/org.mitk.gui.qt.python/src/internal/mitkPluginActivator.h
+++ b/Plugins/org.mitk.gui.qt.python/src/internal/mitkPluginActivator.h
@@ -1,39 +1,42 @@
/*===================================================================
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 MITKPLUGINACTIVATOR_H
#define MITKPLUGINACTIVATOR_H
#include <ctkPluginActivator.h>
#include <mitkExportMacros.h>
namespace mitk {
class MITK_LOCAL PluginActivator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_python")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
static QString m_XmlFilePath;
}; // PluginActivator
}
#endif // MITKPLUGINACTIVATOR_H
diff --git a/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkLoadPresetDialog.cpp b/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkLoadPresetDialog.cpp
index bbec4bf094..09e7863c4a 100644
--- a/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkLoadPresetDialog.cpp
+++ b/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkLoadPresetDialog.cpp
@@ -1,91 +1,91 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#include "QmitkLoadPresetDialog.h"
#include <qlineedit.h>
#include <qpushbutton.h>
#include <qlayout.h>
#include <qlabel.h>
QmitkLoadPresetDialog::QmitkLoadPresetDialog(QWidget* parent, Qt::WindowFlags f, const char* name, std::list<std::string> presets)
:QDialog(parent, f)
{
QDialog::setMinimumSize(250, 300);
this->setObjectName(name);
QBoxLayout * verticalLayout = new QVBoxLayout( this );
verticalLayout->setMargin(5);
verticalLayout->setSpacing(5);
// list of all presets
lblPrompt = new QLabel( "Which preset do you want to load?", this );
verticalLayout->addWidget( lblPrompt );
lstPresets = new QListWidget( this );
verticalLayout->addWidget( lstPresets );
std::list<std::string>::iterator iter;
for( iter = presets.begin(); iter != presets.end(); iter++ )
{
std::string preset = *iter;
new QListWidgetItem(preset.c_str(), lstPresets);
}
lstPresets->setCurrentItem(0); // select first Item by default (might turn out to be a stupid descision)
connect( lstPresets, SIGNAL(itemDoubleClicked (QListWidgetItem *)), this, SLOT(onPresetImmediatelySelected(QListWidgetItem *)) );
// buttons for closing the dialog
btnOk = new QPushButton( tr("Ok"), this);
btnOk->setObjectName("btnOk" );
btnOk->setDefault(true);
connect( btnOk, SIGNAL(clicked()), this, SLOT(accept()) );
QPushButton* btnCancel = new QPushButton( tr("Cancel"), this);
btnCancel->setObjectName("btnCancel" );
connect( btnCancel, SIGNAL(clicked()), this, SLOT(reject()) );
QWidget* buttonWidget = new QWidget(this);
QBoxLayout * horizontalLayout = new QHBoxLayout( buttonWidget );
horizontalLayout->setSpacing(5);
horizontalLayout->addStretch();
horizontalLayout->addWidget( btnOk );
horizontalLayout->addWidget( btnCancel );
verticalLayout->addWidget(buttonWidget);
}
QmitkLoadPresetDialog::~QmitkLoadPresetDialog()
{
}
std::string QmitkLoadPresetDialog::GetPresetName()
{
- std::string presetName = std::string(lstPresets->currentItem()->text().toAscii());
+ std::string presetName = std::string(lstPresets->currentItem()->text().toLatin1());
return presetName;
}
void QmitkLoadPresetDialog::onPresetImmediatelySelected(QListWidgetItem * )
{
if ( (signed)(lstPresets->row(lstPresets->currentItem())) != (signed)(lstPresets->count()-1) )
{
accept(); // close
}
else
{
// dont close
}
}
diff --git a/Plugins/org.mitk.gui.qt.registration/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.registration/src/internal/mitkPluginActivator.cpp
index 681063590a..4925593fb2 100644
--- a/Plugins/org.mitk.gui.qt.registration/src/internal/mitkPluginActivator.cpp
+++ b/Plugins/org.mitk.gui.qt.registration/src/internal/mitkPluginActivator.cpp
@@ -1,41 +1,43 @@
/*===================================================================
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 "mitkPluginActivator.h"
#include "src/internal/QmitkDeformableRegistrationView.h"
#include "src/internal/QmitkPointBasedRegistrationView.h"
#include "src/internal/QmitkRigidRegistrationView.h"
#include <QtPlugin>
namespace mitk {
void PluginActivator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(QmitkDeformableRegistrationView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkPointBasedRegistrationView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkRigidRegistrationView, context)
//Q_UNUSED(context)
}
void PluginActivator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_registration, mitk::PluginActivator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_registration, mitk::PluginActivator)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.registration/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.registration/src/internal/mitkPluginActivator.h
index 12053e09e3..30da5fdaa1 100644
--- a/Plugins/org.mitk.gui.qt.registration/src/internal/mitkPluginActivator.h
+++ b/Plugins/org.mitk.gui.qt.registration/src/internal/mitkPluginActivator.h
@@ -1,39 +1,42 @@
/*===================================================================
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 MITKPLUGINACTIVATOR_H
#define MITKPLUGINACTIVATOR_H
#include <ctkPluginActivator.h>
#include <mitkExportMacros.h>
namespace mitk {
class MITK_LOCAL PluginActivator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_registration")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
}; // PluginActivator
}
#endif // MITKPLUGINACTIVATOR_H
diff --git a/Plugins/org.mitk.gui.qt.remeshing/CMakeLists.txt b/Plugins/org.mitk.gui.qt.remeshing/CMakeLists.txt
index 34efdc8fe3..fdc8add159 100644
--- a/Plugins/org.mitk.gui.qt.remeshing/CMakeLists.txt
+++ b/Plugins/org.mitk.gui.qt.remeshing/CMakeLists.txt
@@ -1,9 +1,10 @@
project(org_mitk_gui_qt_remeshing)
include_directories(${CTK_INCLUDE_DIRS})
MACRO_CREATE_MITK_CTK_PLUGIN(
EXPORT_DIRECTIVE REMESHING_EXPORT
EXPORTED_INCLUDE_SUFFIXES src
MODULE_DEPENDS MitkQtWidgets MitkRemeshing
+ PACKAGE_DEPENDS Qt4|QtCore Qt5|OpenGL+Xml
)
diff --git a/Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemashing.dox b/Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemeshing.dox
similarity index 86%
rename from Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemashing.dox
rename to Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemeshing.dox
index 479aca2342..72588e7834 100644
--- a/Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemashing.dox
+++ b/Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemeshing.dox
@@ -1,71 +1,71 @@
/**
\page org_mitk_gui_qt_remeshing The Remeshing Plugin
-\imageMacro{QmitkRemashing_Icon.png,"Icon of the Remeshing Plugin.",2.00}
+\imageMacro{QmitkRemeshing_Icon.png,"Icon of the Remeshing Plugin.",2.00}
\tableofcontents
\section org_mitk_gui_qt_remeshingOverview Overview
The Remeshing View allows you to remesh surfaces.
If done right, remeshing can dramatically increase the quality of your surface mesh.
However, you might lose precision if you reduce your surface mesh too strong.
Even when you keep the detail of your mesh there might be a tiny distance between your original surface and the remeshed surface.
Hence, be careful when using remeshed surfaces for evaluation purposes and always keep the original versions.
\section org_mitk_gui_qt_remeshingUsage Usage
-\imageMacro{QmitkRemashing_RemeshingView.png,"Basic and advanced mode of the Remeshing View.",13.29}
+\imageMacro{QmitkRemeshing_RemeshingView.png,"Basic and advanced mode of the Remeshing View.",13.29}
There are two basic and about a handful of advanced settings that influence remeshing.
Most of the time you should be able to gain satisfying results by adjusting only the two basic settings or even without changing any of the default parameters.
In the following the effects of all settings are described in more detail. Image examples are based on the following surface:
-\imageMacro{QmitkRemashing_OriginalMesh.png,"The surface from which all examples below originate from.",10.08}
+\imageMacro{QmitkRemeshing_OriginalMesh.png,"The surface from which all examples below originate from.",10.08}
\subsection org_mitk_gui_qt_remeshingBasicSettings Basic Settings
The <b>Vertices</b> setting is the number of vertices the remeshed surface will consist of.
This is exact as long as <b>Boundary fixing</b> is turned off (default).
The maximum number of vertices is limited to the number of vertices of the input surface, however, you can increase this limit by adjusting the <b>Max. # of vertices</b> setting.
The <b>Gradation</b> setting controls the distribution of vertices in the remeshed surface.
If set to zero the vertices are distributed equally all over the remeshed surface.
You can push more vertices towards surface regions with high curvature, i.e., more detailed regions, by increasing this setting.
-\imageMacro{QmitkRemashing_Gradation10Percent.png,"Vertex count reduced to 10 percent\, gradation 0 vs. 1.",16.00}
+\imageMacro{QmitkRemeshing_Gradation10Percent.png,"Vertex count reduced to 10 percent\, gradation 0 vs. 1.",16.00}
\subsection org_mitk_gui_qt_remeshingAdvancedSettings Advanced Settings
You can arbirarily increase the maximum adjustable number of vertices by changing the <b>Max. # of vertices</b> setting.
<b>Edge splitting</b> is disabled by default and might take a long time during remeshing when enabled.
This setting represents a number by which the average edge length of the input surface is multiplied to serve as a threshold which regulates edge splitting.
Long edges are split recursively until all edges satisfy the threshold.
Edge splitting is useful for surfaces that contain thin and long polygons.
-\imageMacro{QmitkRemashing_Cylinder.png,"A surface that contains extremely long polygons.",16.00}
+\imageMacro{QmitkRemeshing_Cylinder.png,"A surface that contains extremely long polygons.",16.00}
<br>
-\imageMacro{QmitkRemashing_CylinderBad.png,"A remeshing attempt without edge splitting.",16.00}
+\imageMacro{QmitkRemeshing_CylinderBad.png,"A remeshing attempt without edge splitting.",16.00}
<br>
-\imageMacro{QmitkRemashing_CylinderGood.png,"Increased max. # of vertices\, enabled edge splitting\, followed by a second remeshing run without edge splitting.",16.00}
+\imageMacro{QmitkRemeshing_CylinderGood.png,"Increased max. # of vertices\, enabled edge splitting\, followed by a second remeshing run without edge splitting.",16.00}
The <b>Subsampling</b> setting has direct impact on the quality of the remeshed surface.
The input surface is recursively subdivided until the total number of vertices exceeds its initial vertex count times this setting.
-\imageMacro{QmitkRemashing_Subsampling20Percent.png,"Vertex count reduced to 20 percent\, subsampling 10 vs. 500.",16.00}
+\imageMacro{QmitkRemeshing_Subsampling20Percent.png,"Vertex count reduced to 20 percent\, subsampling 10 vs. 500.",16.00}
You usually leave the <b>Optimization level</b> set to its default value 1.
When disabled, the remeshed surface has usually a slightly smaller volume than the original surface.
The optimization process minimizes the distance between the two surfaces but values higher than 1 introduce degenerated triangles to the remeshed surface.
If your surface is open, i.e., it has holes in it, boundaries tend to shrink irregularly during remeshing.
If the position and smoothness of your surface boundaries are important, you should activate the <b>Boundary fixing</b> setting.
This results in additional vertices that make up extra polygons at the remeshed boundaries to keep the original boundaries.
-\imageMacro{QmitkRemashing_NoBoundaryFixing10Percent.png,"Vertex count reduced to 10 percent\, no boundary fixing.",10.08}
+\imageMacro{QmitkRemeshing_NoBoundaryFixing10Percent.png,"Vertex count reduced to 10 percent\, no boundary fixing.",10.08}
*/
diff --git a/Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemashing_CylinderBad.png b/Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemeshing_CylinderBad.png
similarity index 100%
rename from Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemashing_CylinderBad.png
rename to Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemeshing_CylinderBad.png
diff --git a/Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemashing_CylinderGood.png b/Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemeshing_CylinderGood.png
similarity index 100%
rename from Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemashing_CylinderGood.png
rename to Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemeshing_CylinderGood.png
diff --git a/Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemashing_Gradation10Percent.png b/Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemeshing_Gradation10Percent.png
similarity index 100%
rename from Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemashing_Gradation10Percent.png
rename to Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemeshing_Gradation10Percent.png
diff --git a/Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemashing_Icon.png b/Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemeshing_Icon.png
similarity index 100%
rename from Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemashing_Icon.png
rename to Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemeshing_Icon.png
diff --git a/Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemashing_NoBoundaryFixing10Percent.png b/Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemeshing_NoBoundaryFixing10Percent.png
similarity index 100%
rename from Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemashing_NoBoundaryFixing10Percent.png
rename to Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemeshing_NoBoundaryFixing10Percent.png
diff --git a/Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemashing_OriginalMesh.png b/Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemeshing_OriginalMesh.png
similarity index 100%
rename from Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemashing_OriginalMesh.png
rename to Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemeshing_OriginalMesh.png
diff --git a/Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemashing_RemeshingView.png b/Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemeshing_RemeshingView.png
similarity index 100%
rename from Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemashing_RemeshingView.png
rename to Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemeshing_RemeshingView.png
diff --git a/Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemashing_Subsampling20percent.png b/Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemeshing_Subsampling20percent.png
similarity index 100%
rename from Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemashing_Subsampling20percent.png
rename to Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemeshing_Subsampling20percent.png
diff --git a/Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemashing_cylinder.png b/Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemeshing_cylinder.png
similarity index 100%
rename from Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemashing_cylinder.png
rename to Plugins/org.mitk.gui.qt.remeshing/documentation/UserManual/QmitkRemeshing_cylinder.png
diff --git a/Plugins/org.mitk.gui.qt.remeshing/src/internal/org_mitk_gui_qt_remeshing_Activator.cpp b/Plugins/org.mitk.gui.qt.remeshing/src/internal/org_mitk_gui_qt_remeshing_Activator.cpp
index 2fe6042c78..1f552fe402 100644
--- a/Plugins/org.mitk.gui.qt.remeshing/src/internal/org_mitk_gui_qt_remeshing_Activator.cpp
+++ b/Plugins/org.mitk.gui.qt.remeshing/src/internal/org_mitk_gui_qt_remeshing_Activator.cpp
@@ -1,30 +1,32 @@
/*===================================================================
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_remeshing_Activator.h"
#include "QmitkRemeshingView.h"
#include <QtPlugin>
void mitk::org_mitk_gui_qt_remeshing_Activator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(QmitkRemeshingView, context);
}
void mitk::org_mitk_gui_qt_remeshing_Activator::stop(ctkPluginContext*)
{
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_remeshing, mitk::org_mitk_gui_qt_remeshing_Activator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_remeshing, mitk::org_mitk_gui_qt_remeshing_Activator)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.remeshing/src/internal/org_mitk_gui_qt_remeshing_Activator.h b/Plugins/org.mitk.gui.qt.remeshing/src/internal/org_mitk_gui_qt_remeshing_Activator.h
index 3ecd3b77b8..efce73c069 100644
--- a/Plugins/org.mitk.gui.qt.remeshing/src/internal/org_mitk_gui_qt_remeshing_Activator.h
+++ b/Plugins/org.mitk.gui.qt.remeshing/src/internal/org_mitk_gui_qt_remeshing_Activator.h
@@ -1,35 +1,38 @@
/*===================================================================
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 org_mitk_gui_qt_remeshing_Activator_h
#define org_mitk_gui_qt_remeshing_Activator_h
#include <ctkPluginActivator.h>
namespace mitk
{
class org_mitk_gui_qt_remeshing_Activator : public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_remeshing")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
};
}
#endif
diff --git a/Plugins/org.mitk.gui.qt.segmentation/CMakeLists.txt b/Plugins/org.mitk.gui.qt.segmentation/CMakeLists.txt
index 93cb1256d8..5e6125d475 100644
--- a/Plugins/org.mitk.gui.qt.segmentation/CMakeLists.txt
+++ b/Plugins/org.mitk.gui.qt.segmentation/CMakeLists.txt
@@ -1,9 +1,10 @@
project(org_mitk_gui_qt_segmentation)
include_directories(${CTK_INCLUDE_DIRS})
MACRO_CREATE_MITK_CTK_PLUGIN(
EXPORT_DIRECTIVE MITK_QT_SEGMENTATION
EXPORTED_INCLUDE_SUFFIXES src
MODULE_DEPENDS MitkQtWidgetsExt MitkSegmentationUI
+ PACKAGE_DEPENDS Qt4|QtCore Qt5|OpenGL
)
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkClippingPlane.dox b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkClippingPlane.dox
index 27e63aa45e..2c98b29a58 100644
--- a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkClippingPlane.dox
+++ b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkClippingPlane.dox
@@ -1,71 +1,71 @@
/**
\page org_mitk_views_deformableclippingplane The Clipping Plane
\imageMacro{QmitkClippingPlane_Icon.png,"Icon of the Clipping Plane Plugin",5.00}
+\imageMacro{QmitkClippingPlane_Overview2.png,"Clipping Plane view",16.00}
\tableofcontents
\section org_mitk_views_clippingPlaneManualOverview Overview
The <b>Clipping Plane view</b> allows you to create clipping planes and calculate the volumina of the devided parts.
-\imageMacro{QmitkClippingPlane_Overview.png,"Clipping Plane view with segmentation and two clipping planes",16.00}
\section org_mitk_views_clippingPlaneTechnicalIssue Technical Issue
To use the Update Volumina function your image should be binary.
\section org_mitk_views_clippingPlaneManualImageSelection Image Selection
The Clipping Plane view makes use of the Data Manager view to give you an overview of all images, segmentations and clipping planes.
\imageMacro{QmitkClippingPlane_DataManager.png,"Data Manager is used for selecting the current clipping plane. The reference plane is selected in the drop down box of the control area.",8.00}
To select the reference plane use the drop down box in the control area of the Clipping Plane view or the Data Manager. The clipping plane selected in the Data Manager is displayed below the drop down box. If no clipping plane exists or none is selected create a new clipping plane by using the "Create new clipping plane" button.
Some items of the graphical user interface might be disabled when no plane is selected.
In any case, the application will give you hints if a selection is needed.
\section org_mitk_views_clippingPlaneCreating Creating New Clipping Plane
If you want to create a new clipping plane select an image from the Data Manager and press the button "Create new clipping plane". Optionally you can enable the "...with surface model" option.
\section org_mitk_views_clippingPlaneInteraction Interaction with the planes
\imageMacro{QmitkClippingPlane_Interaction.png,"The interaction buttons",5.00}
You have different options to interact with the clipping planes:
\subsection org_mitk_views_clippingPlaneTranslation Translation
In Translation mode you can change the position of the clipping plane.
- Click the Translation Button
- Move mouse over the selected clipping plane (the plane changes its color from blue to green)
- Hold mouse-left button and move the mouse orthogonally to the plane
\subsection org_mitk_views_clippingPlaneRotation Rotation
In Rotation mode you can change the angle of the clipping plane.
- Click the Rotation Button
- Move mouse over the selected clipping plane (the plane changes its color from blue to green)
- Hold mouse-left button and move the mouse in the direction it should be rotated
\subsection org_mitk_views_clippingPlaneDeformation Deformation
In Deformation mode you can change the surface of the clipping plane.
- Click the Deformation Button
- Move mouse over the selected clipping plane (the plane changes its color from blue to green). The deformation area is highlighted in red and yellow.
- On mouse-scrolling you can change the size of the deformation area (Scroll-Down = smaller / Scroll-Up = bigger).
- Hold mouse-left button and move the mouse orthogonally to the plane to deformate the plane
\section org_mitk_views_clippingPlaneUpdateVolumina Update Volumina
\imageMacro{QmitkClippingPlane_UpdateVolumina.png,"The 'Update Volumina' button",5.00}
Calculating the volumina of the segmentation parts, which are devided by the clipping plane(s).
- Create a segmentation (see Segmentation-Manual)
- Create one or more clipping plane(s)
- Use the interaction buttons (Translation, Rotation, Deformation) to adjust the clipping plane for intersecting the segmentation
- (You can decide which planes shouldnt be included for the calculation by changing their visibility to invisible)
- Click button "Update Volumina" button
- The intersected parts are displayed in different colors and their volumina are shown beneath the "Update Volumina" button
**/
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkClippingPlane_Icon.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkClippingPlane_Icon.png
index 28c5fb54e8..35dc639aed 100644
Binary files a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkClippingPlane_Icon.png and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkClippingPlane_Icon.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkClippingPlane_Overview2.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkClippingPlane_Overview2.png
new file mode 100644
index 0000000000..efc7f4f086
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkClippingPlane_Overview2.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation.dox b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation.dox
index 6c4e8fd64b..7a787b0a4b 100644
--- a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation.dox
+++ b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation.dox
@@ -1,292 +1,315 @@
/**
\page org_mitk_views_segmentation The Segmentation Plugin
\imageMacro{QmitkSegmentation_Icon.png,"Icon of the Segmentation Plugin",2.00}
<i>Some of the features described below are closed source additions to the open source toolkit MITK and are not available in every application.</i>
\tableofcontents
\section org_mitk_gui_qt_segmentationUserManualOverview Overview
-The <b>Segmentation perspective</b> allows you to create segmentations of anatomical and pathological structures in medical images of the human body.
-The perspective groups a number of tools which can be used for:
+The <b>Segmentation plugin</b> allows you to create segmentations of anatomical and pathological structures in medical images of the human body.
+The plugin consists of a number of view which can be used for:
<ul>
- <li> (semi-)automatic segmentation of organs on CT or MR image volumes
- <li> semi-automatic segmentation of lesions such as enlarged lymph nodes or tumors
- <li> manual segmentation of any structures you might want to delineate
+ <li> manual and (semi-)automatic segmentation of organs on CT or MR image volumes via the <b>Segmentation View</b>
+ <li> segmentation postprocessing via the \subpage org_mitk_views_segmentationutilities
+ <li> clipping of existing segmentations using a resection plane via the \subpage org_mitk_views_deformableclippingplane
</ul>
-For more detailed information on the clipping plane view see \subpage org_mitk_views_deformableclippingplane.
+\imageMacro{QmitkSegmentation_IMGApplication.png,"Segmentation Plugin consisting of the Segmentation View the Segmentation Utilities View and the Clipping Plane View", 16.00}
-\imageMacro{QmitkSegmentation_IMGApplication.png,"Segmentation perspective consisting of the Data Manager view and the Segmentation view",16.00}
+The segmentation plugin offers a number of preferences which can be set via the MITK Workbench application preference dialog:
+
+\imageMacro{QmitkSegmentation_IMGPreferences.png,"Segmentation Plugin consisting of the Segmentation View the Segmentation Utilities View and the Clipping Plane View", 10.00}
+
+The following preferences can be set:
+<ul>
+ <li> <b>Slim view:</b> Allows you to show or hide the tool button description of the Segmentation View
+ <li> <b>2D display:</b> Specify whether the segmentation is drawn as outline or as a transparent overlay
+ <li> <b>3D display:</b> Activate 3D volume rendering for your segmentation
+ <li> <b>Data node selection mode:</b> If activated the segmentation image combo box is always sychronized with the data manager selection.
+ <li> <b>Smoothed surface creation:</b> Set certain smoothing parameters for surface creation
+</ul>
If you wonder what segmentations are good for, we shortly revisit the concept of a segmentation here.
A CT or MR image is made up of volume of physical measurements (volume elements are called voxels).
In CT images, for example, the gray value of each voxel corresponds to the mass absorbtion coefficient for X-rays in this voxel, which is similar in many %parts of the human body.
The gray value does not contain any further information, so the computer does not know whether a given voxel is part of the body or the background, nor can it tell a brain from a liver.
However, the distinction between a foreground and a background structure is required when:
<ul>
<li>you want to know the volume of a given organ (the computer needs to know which %parts of the image belong to this organ)
<li>you want to create 3D polygon visualizations (the computer needs to know the surfaces of structures that should be drawn)
<li>as a necessary pre-processing step for therapy planning, therapy support, and therapy monitoring
</ul>
Creating this distinction between foreground and background is called <i>segmentation</i>.
The Segmentation perspective of the MITK Workbench uses a voxel based approach to segmentation, i.e. each voxel of an image must be completely assigned to either foreground or background.
This is in contrast to some other applications which might use an approach based on contours, where the border of a structure might cut a voxel into two %parts.
The remainder of this document will summarize the features of the Segmentation perspective and how they are used.
\section org_mitk_gui_qt_segmentationUserManualTechnical Technical Issues
The Segmentation perspective makes a number of assumptions. To know what this view can be used for, it will help you to know that:
<ul>
<li> Images must be 2D, 3D, or 3D+t
<li> Images must be single-values, i.e. CT, MRI or "normal" ultrasound. Images from color doppler or photographic (RGB) images are not supported
<li> Segmentations are handled as binary images of the same extent as the original image
</ul>
\section org_mitk_gui_qt_segmentationUserManualImageSelection Image Selection
The Segmentation perspective makes use of the Data Manager view to give you an overview of all images and segmentations.
\imageMacro{QmitkSegmentation_IMGSelection.png,"Data Manager is used for selecting the current segmentation. The reference image is selected in the drop down box of the control area.",5.50}
-To select the reference image (e.g. the original CT/MR image) use the drop down box in the control area of the Segmentation view. The segmentation image selected in the Data Manager is displayed below the drop down box. If no segmentation image exists or none is selected create a new segmentation image by using the "New segmentation" button.
-Some items of the graphical user interface might be disabled when no image is selected.
+To select the reference image (e.g. the original CT/MR image) use the patient image drop down box in the control area of the Segmentation view. The segmentation image selected in the Data Manager is displayed below in the segmentation drop down box.
+By default the auto selection mode is enabled, which always keeps the selection of the segmentation drop down box in synch with the selection in the data manager.
+If you disable the auto selection mode the selection of the right segmentation image has to be done via the drop down box.
+If no segmentation image exists or none is selected create a new segmentation image by using the "New segmentation" button on the right of the Segmentation drop down box.
+Some items of the graphical user interface might be disabled when no image is selected or the selected image does not fit to the patient image's geoemtry.
In any case, the application will give you hints if a selection is needed.
+\section org_mitk_gui_qt_segmentationUserManualToolOverview Tool overview
+
+MITK comes with a comprehensive set of segmentation tools. These tools can be differenciated between manual slice-based 2D segmentation tools and (semi-)automated 3D tools.
+The manual 2D tools require a big amount of user interaction and can only be applied to a single image slice whereas the 3D tools operate on the hole image. The 3D tools usually
+require a small amount of interaction like placin seedpoints of setting some parameters.
+You can switch between the different toolsets by switching the 2D/3D tab in the segmentation view.
+
+\imageMacro{QmitkSegmentation_ToolOverview.png,"An overview of the existing tools in MITK. There are interactive 2D tools as well as (semi-)automated 3D tools",5.50}
+
\section org_mitk_gui_qt_segmentationUserManualManualKringeling Manual Contouring
With manual contouring you define which voxels are part of the segmentation and which are not.
This allows you to create segmentations of any structeres that you may find in an image, even if they are not part of the human body.
You might also use manual contouring to correct segmentations that result from sub-optimal automatic methods.
The drawback of manual contouring is that you might need to define contours on many 2D slices.
However, this is moderated by the interpolation feature, which will make suggestions for a segmentation.
\subsection org_mitk_gui_qt_segmentationUserManualManualKringeling1 Creating New Segmentations
Unless you want to edit existing segmentations, you have to create a new, empty segmentation before you can edit it.
To do so, click the "New manual segmentation" button.
Input fields will appear where you can choose a name for the new segmentation and a color for its display.
Click the checkmark button to confirm or the X button to cancel the new segmentation.
Notice that the input field suggests names once you %start typing and that it also suggests colors for known organ names.
If you use names that are not yet known to the application, it will automatically remember these names and consider them the next time you create a new segmentation.
Once you created a new segmentation, you can notice a new item with the "binary mask" icon in the Data Manager tree view.
This item is automatically selected for you, allowing you to %start editing the new segmentation right away.
\subsection org_mitk_gui_qt_segmentationUserManualManualKringeling2 Selecting Segmentations for Editing
As you might want to have segmentations of multiple structures in a single patient image, the application needs to know which of them to use for editing.
You select a segmenation by clicking it in the tree view of Data Manager. Note that segmentations are usually displayed as sub-items of "their" patient image.
In the rare case, where you need to edit a segmentation that is not displayed as a a sub-item, you can click both the original image AND the segmentation while holding down CTRL or for Mac OS X the CMD on the keyboard.
When a selection is made, the Segmentation View will hide all but the selected segmentation and the corresponding original image.
When there are multiple segmentations, the unselected ones will remain in the Data Manager, you can make them visible at any time by selecting them.
\subsection org_mitk_gui_qt_segmentationUserManualManualKringeling3 Selecting Editing Tools
If you are familiar with the MITK Workbench, you know that clicking and moving the mouse in any of the 2D render windows will move around the crosshair that defines what part of the image is displayed.
This behavior is disabled while any of the manual segmentation tools are active -- otherwise you might have a hard time concentrating on the contour you are drawing.
To %start using one of the editing tools, click its button the the displayed toolbox.
The selected editing tool will be active and its corresponding button will stay pressed until you click the button again.
Selecting a different tool also deactivates the previous one.
If you have to delineate a lot of images, you should try using shortcuts to switch tools. Just hit the first letter of each tool to activate it (A for Add, S for Subtract, etc.).
\subsection org_mitk_gui_qt_segmentationUserManualManualKringeling4 Using Editing Tools
All of the editing tools work by the same principle: you use the mouse (left button) to click anywhere in a 2D window (any of the orientations axial, sagittal, or frontal), move the mouse while holding the mouse button and release to finish the editing action.
Multi-step undo and redo is fully supported by all editing tools. Use the application-wide undo button in the toolbar to revert erroneous %actions.
\imageMacro{QmitkSegmentation_IMGIconAddSubtract.png,"Add and Subtract Tools",7.70}
Use the left mouse button to draw a closed contour. When releasing the mouse button, the contour will be added (Add tool) to or removed from (Subtract tool) the current segmentation.
Hold down the CTRL / CMD key to invert the operation (this will switch tools temporarily to allow for quick corrections).
\imageMacro{QmitkSegmentation_IMGIconPaintWipe.png,"Paint and Wipe Tools",7.68}
Use the slider below the toolbox to change the radius of these round paintbrush tools. Move the mouse in any 2D window and press the left button to draw or erase pixels.
As the Add/Subtract tools, holding CTRL / CMD while drawing will invert the current tool's behavior.
\imageMacro{QmitkSegmentation_IMGIconRegionGrowing.png,"Region Growing Tool",3.81}
Click at one point in a 2D slice widget to add an image region to the segmentation with the region growing tool. Moving up the cursor while holding the left mouse button widens the range for the included grey values; moving it down narrows it.
When working on an image with a high range of grey values, the selection range can be influenced more strongly by moving the cursor at higher velocity.
Region Growing selects all pixels around the mouse cursor that have a similar gray value as the pixel below the mouse cursor.
This enables you to quickly create segmentations of structures that have a good contrast to surrounding tissue, e.g. the lungs.
The tool will select more or less pixels (corresponding to a changing gray value interval width) when you move the mouse up or down while holding down the left mouse button.
A common issue with region growing is the so called "leakage" which happens when the structure of interest is connected to other pixels, of similar gray values, through a narrow "bridge" at the border of the structure.
The Region Growing tool comes with a "leakage detection/removal" feature. If leakage happens, you can left-click into the leakage region and the tool will try to automatically remove this region (see illustration below).
\imageMacro{QmitkSegmentation_IMGLeakage.png,"Leakage correction feature of the Region Growing tool",11.28}
<br>
\imageMacro{QmitkSegmentation_IMGIconCorrection.png,"Correction Tool",3.77}
You do not have to draw a closed contour to use the Correction tool and do not need to switch between the Add and Substract tool to perform
small corrective changes. The following figure shows the usage of this tool:
<ul>
<li> if the user draws a line which %starts and ends outside the segmenation AND it intersects no other segmentation the endpoints of the line are connected and the resulting contour is filled
<li> if the user draws a line which %starts and ends outside the segmenation a part of it is cut off (left image)
<li> if the line is drawn fully inside the segmentation the marked region is added to the segmentation (right image)
</ul>
\imageMacro{QmitkSegmentation_IMGCorrectionActions.png,"%Actions of the Correction tool illustrated.",13.50}
<br>
\imageMacro{QmitkSegmentation_IMGIconFill.png,"Fill Tool",3.81}
Left-click inside a segmentation with holes to completely fill all holes.
\imageMacro{QmitkSegmentation_IMGIconErase.png,"Erase Tool",3.79}
This tool removes a connected part of pixels that form a segmentation. You may use it to remove so called islands (see picture) or to clear a whole slice at once (hold CTRL while clicking).
\imageMacro{QmitkSegmentation_IMGIconLiveWire.png,"LiveWire Tool",3.01}
The LiveWire Tool acts as a magnetic lasso with a contour snapping to edges of objects.
\imageMacro{QmitkSegmentation_IMGLiveWireUsage.png,"Steps for using LiveWire Tool",16.00}
<ul>
<li>(1) To start the Tool you have to double click near the edge of the object you want to segment. The initial anchor point will snap to the edge within a 3x3 region.
<li>(2) Move the mouse. You don't have trace the edge of the object. The contour will automatically snap to it.
<li>(3) To fix a segment you can set anchor points by single left mouse button click.
<li>(4) Go on with moving the mouse and setting anchor points.
<li>(5) To close the contour double click on the initial anchor point.
<li>(6) After closing the contour can be edited by moving, inserting and deleting anchor points.
</ul>
The contour will be transfered to its binary image representation by deactivating the tool.
+\imageMacro{QmitkSegmentation_IMG2DFastMarchingUsage.png,"2D Fast Marching Tool",3.01}
+
+Provides a fast marching based 2D interaction segmentation tool. You start with setting seedpoints in an image slice. Via several sliders you can
+adapt parameters and see the fast marching result instantly.
+
\subsection org_mitk_gui_qt_segmentationUserManualManualKringeling5 Interpolation
Creating segmentations for modern CT volumes is very time-consuming, because structures of interest can easily cover a range of 50 or more slices.
The Manual Segmentation View offers two helpful features for these cases:
<ul>
<li> <b>3D Interpolation</b>
<li> <b>2D Interpolation</b>
</ul>
<br>
<b>The 3D interpolation</b> is activated by default when using the manual segmentation tools. That means if you start contouring, from the second contour onwards, the surface of the segmented area will be interpolated based on the given contour information.
The interpolation works with all available manual tools. Please note that this is currently a pure mathematical interpolation, i.e. image intensity information is not taken into account. With each further contour the interpolation result will be improved,
but the more contours you provide the longer the recalculation will take. To achieve an optimal interpolation result and in this way a most accurate segmentation you should try to describe the surface with sparse contours by segmenting in arbitrary
oriented planes. The 3D interpolation is not meant to be used for parallel slice-wise segmentation.
\imageMacro{QmitkSegmentation_3DInterpolationWrongRight.png,"3D Interpolation HowTo",16.00}
You can accept the interpolation result by clicking the "Accept" - button below the tool buttons.
In this case the 3D interpolation will be deactivated automatically so that the result can be postprocessed without any interpolation running in background. During recalculation the interpolated surface is blinking yellow/white. When the interpolation
has finished the surface is shown yellow with a small opacity. Additional to the surface, black contours are shown in the 3D render window. They mark the positions of all the drawn contours which were used for the interpolation.
You can navigate between the drawn contours by clicking on the „Position“ - Nodes in the datamanager which are located below the selected segmentation. If you don't want to see these nodes just unckeck the „Show Position Nodes“ Checkbox and these nodes will be hidden.
If you want to delete a drawn contour we recommend to use the Erase-Tool since Redo/Undo is not yet working for 3D interpolation.
+The current state of the 3D interpolation can be saved accross application restart. Therefor just click on save project during the interpolation is active. After restarting the application and load your project you can click on "Reinit Interpolation" within the 3D interpolation GUI area.
<br>
<b>The 2D Interpolation</b> creates suggestions for a segmentation whenever you have a slice that
<ul>
<li> has got neighboring slices with segmentations (these do not need to be direct neighbors but could also be a couple of slices away) AND
<li> is completely clear of a manual segmentation -- i.e. there will be no suggestion if there is even only a single pixel of segmentation in the current slice.
</ul>
Interpolated suggestions are displayed in a different way than manual segmentations are, until you "accept" them as part of the segmentation.
To accept single slices, click the "Accept" button below the toolbox.
If you have segmented a whole organ in every-x-slice, you may also review the interpolations and then accept all of them at once by clicking "... all slices".
-\section org_mitk_gui_qt_segmentationUserManualOrganSegmentation Organ Segmentation
+\section org_mitk_gui_qt_segmentationUserManual3DSegmentationTools 3D Segmenation tools
-\note This feature is only available in our 3M3 Demo Application (http://www.mint-medical.de/productssolutions/mitk3m3/mitk3m3/#downloads) but not in the open source part of MITK
+The 3D tools operate on the hole image and require usually a small amount of interaction like placing seed-points or specifying certain parameters. All 3D tools provide
+an immediate segmentation feedback, which is displayed as a transparent green overlay. For accepting a preview you have to press the "Comfirm" button of the selected tool.
+The following 3D tools are at your disposal:
-The manual contouring described above is a fallback option that will work for any kind of images and structures of interest.
-However, manual contouring is very time-consuming and tedious.
-This is why a major part of image analysis research is working towards automatic segmentation methods.
-The Segmentation View comprises a number of easy-to-use tools for segmentation of CT images (Liver) and MR image (left ventricle and wall, left and right lung).
+\subsection org_mitk_gui_qt_segmentationUserManual3DThresholdTool 3D Threshold tool
-\subsection org_mitk_gui_qt_segmentationUserManualOrganSegmentation1 Liver on CT Images
+The Thresholding tool simply applies a 3D threshold to the patient image. All pixels with values equal or above the selected threshold are labeled.
+You can change the threshold by either moving the slider of setting a certain value in the spinbox.
-On CT image volumes, preferrably with a contrast agent in the portal venous phase, the Liver tool will fully automatically analyze and segment the image.
-All you have to do is to load and select the image, then click the "Liver" button.
-During the process, which takes a minute or two, you will get visual progress feedback by means of a contour that moves closer and closer to the real liver boundaries.
+\imageMacro{QmitkSegmentation_3DThresholdTool.png,"3D Threshold tool",10.00}
-\subsection org_mitk_gui_qt_segmentationUserManualOrganSegmentation2 Heart, Lung, and Hippocampus on MRI
+\subsection org_mitk_gui_qt_segmentationUserManual3DULTool 3D Upper/Lower Threshold tool
-While liver segmentation is performed fully automatic, the following tools for segmentation of the heart, the lungs, and the hippocampus need a minimum amount of guidance.
-Click one of the buttons on the "Organ segmentation" page to add an average %model of the respective organ to the image.
-This %model can be dragged to the right position by using the left mouse button while holding down the CTRL key.
-You can also use CTRL + middle mouse button to rotate or CTRL + right mouse button to scale the %model.
+The Upper/Lower Thresholding tool works similar to the simple 3D threshold tool but allows you to define an upper and lower threshold. All pixels with
+values within this threshold intervall will be labeled
-Before starting the automatic segmentation process by clicking the "Start segmentation" button, try placing the %model closely to the organ in the MR image
-(in most cases, you do not need to rotate or scale the %model).
-During the segmentation process, a green contour that moves closer and closer to the real liver boundaries will provide you with visual feedback of the segmentation progress.
+\imageMacro{QmitkSegmentation_3DULThresholdTool.png,"3D Upper/Lower Threshold tool",10.00}
-The algorithms used for segmentation of the heart and lung are method which need training by a number of example images.
-They will not work well with other kind of images, so here is a list of the image types that were used for training:
-<ul>
-<li> Hippocampus segmentation: T1-weighted MR images, 1.5 Tesla scanner (Magnetom Vision, Siemens Medical Solutions), 1.0 mm isotropic resolution
-<li> Heart: Left ventricle inner segmentation (LV Model): MRI; velocity encoded cine (VEC-cine) MRI sequence; trained on systole and diastole
-<li> Heart: Left ventricular wall segmentation (LV Inner Wall, LV Outer Wall): 4D MRI; short axis 12 slice spin lock sequence(SA_12_sl); trained on whole heart cycle
-<li> Lung segmentation: 3D and 4D MRI; works best on FLASH3D and TWIST4D sequences
-</ul>
+\subsection org_mitk_gui_qt_segmentationUserManual3DOtsuTool 3D Otsu tool
+
+The 3D Otsu tool provides a more sophisticated thresholding algorithm. It allows you to define a number of regions. Based on the image histogram the pixels will
+then divided into different regions. There more regions you define the longer will the calculation take.
+
+\imageMacro{QmitkSegmentation_3DOtsuTool.png,"3D Otsu tool",10.00}
+
+\subsection org_mitk_gui_qt_segmentationUserManual3DFMTool 3D Fast Marching tool
+
+The 3D Fast Marching tools works similar to the 2D pendant but on the hole image. Depending on you image's size the calculation will take some time.
+You can interactive set the parameters of the algorithm via the tool GUI.
+
+\imageMacro{QmitkSegmentation_3DFMTool.png,"3D Fast Marching tool",10.00}
+
+\subsection org_mitk_gui_qt_segmentationUserManual3DRGTool 3D Region Growing tool
-\subsection org_mitk_gui_qt_segmentationUserManualOrganSegmentation99 Other Organs
+The 3D Region Growing tool works similar to the 2D pendant. At the beginning you have to place a seedpoint and define a threshold intervall. If you press
+"Run segmentation" a preview is calculated, if the "3D preview" box is checked you will also see the result in 3D. By moving the "Adapt region growing slider"
+you can interactively adapt the result to you image.
-As mentioned in the Heart/Lung section, most of the underlying methods are based on "training".
-The basic algorithm is versatile and can be applied on all kinds of segmentation problems where the structure of interest is topologically like a sphere (and not like a torus etc.).
-If you are interested in other organs than those offered by the current version of the Segmentation view,
-please contact our research team.
+\imageMacro{QmitkSegmentation_3DRGTool.png,"3D Region Growing tool",10.00}
-\section org_mitk_gui_qt_segmentationUserManualLesionSegmentation Lesion Segmentation
++\subsection org_mitk_gui_qt_segmentationUserManual3DWatershedTool 3D Watershed tool
-\note This feature is only available in our 3M3 Demo Application (http://www.mint-medical.de/productssolutions/mitk3m3/mitk3m3/#downloads) but not in the open source part of MITK
+This tool provides a watershed based segmentation algorithm.
-Lesion segmentation is a little different from organ segmentation. Since lesions are not part of the healthy body, they sometimes have a diffused border,
-and are often found in varying places all over the body.
-The tools in this section offer efficient ways to create 3D segmentations of such lesions.
+\imageMacro{QmitkSegmentation_3DWatershedTool.png,"3D Watershed tool",10.00}
-The Segmentation View currently offers supoprt for enlarged lymph nodes.
+\subsection org_mitk_gui_qt_segmentationUserManualPickingTool Picking tool
-To segment an enlarged lymph node, find a more or less central slice of it, activate the "Lymph Node" tool and draw a rough contour on the inside of the lymph node.
-When releaseing the mouse button, a segmentation algorithm is started in a background task. The result will become visible after a couple of seconds, but you do not have to wait for it.
-If you need to segment several lymph nodes, you can continue to inspect the image right after closing the drawn contour.
+The Picking tool allows you to select islands within your segmentation. This is especially usefull if e.g. a thresholding delivered your several areas within
+your image but you are just interested in one special region.
-If the lymph node segmentation is not to your content, you can select the "Lymph Node Correction" tool and drag %parts of the lymph node surface towards the right position (works in 3D, not slice-by-slice).
-This kind of correction helps in many cases.
-If nothing else helps, you can still use the pure manual tools as a fallback.
+\imageMacro{QmitkSegmentation_PickingTool.png,"Picking tool",10.00}
\section org_mitk_gui_qt_segmentationUserManualPostprocessing Things you can do with segmentations
As mentioned in the introduction, segmentations are never an end in themselves.
Consequently, the Segmentation view adds a couple of "post-processing" %actions to the Data Manager.
These %actions are accessible through the context-menu of segmentations in Data Manager's list view
\imageMacro{QmitkSegmentation_IMGDataManagerContextMenu.png,"Context menu items for segmentations.",10.58}
<ul>
<li> <b>Create polygon %model</b> applies the marching cubes algorithms to the segmentation. This polygon %model can be used for visualization in 3D or other things such as stereolithography (3D printing).
<li> <b>Create smoothed polygon %model</b> uses smoothing in addition to the marching cubes algorithms, which creates models that do not follow the exact outlines of the segmentation, but look smoother.
-<li> <b>Statistics</b> goes through all the voxels in the patient image that are part of the segmentation and calculates some statistical measures (minumum, maximum, median, histogram, etc.). Note that the statistics are ALWAYS calculated for the parent element of the segmentation as shown in Data Manager.
<li> <b>Autocrop</b> can save memory. Manual segmentations have the same extent as the patient image, even if the segmentation comprises only a small sub-volume. This invisible and meaningless margin is removed by autocropping.
</ul>
\section QmitkSegmentation_UserManualSurfaceMasking Surface Masking
You can use the surface masking tool to create binary images from a surface which
is used used as a mask on an image. This task is demonstrated below:
\imageMacro{QmitkSegmentation_FromSurfaceBefore.png,"Load an image and a surface.",16.00}
Select the image and the surface in the corresponding drop-down boxes (both are selected automatically if there is just one image and one surface)
\imageMacro{QmitkSegmentation_FromSurfaceAfter.png,"Create segmentation from surface",16.00}
After clicking "Create segmentation from surface" the newly created binary image is inserted in the DataManager and can be used for further processing
\section org_mitk_gui_qt_segmentationUserManualTechnicalDetail Technical Information for Developers
For technical specifications see \subpage QmitkSegmentationTechnicalPage and for information on the extensions of the tools system \subpage toolextensions .
*/
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentationPreferences.tiff b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentationPreferences.tiff
new file mode 100644
index 0000000000..7659e33ad7
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentationPreferences.tiff differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentationUtilities.dox b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentationUtilities.dox
new file mode 100644
index 0000000000..b60a39db80
--- /dev/null
+++ b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentationUtilities.dox
@@ -0,0 +1,62 @@
+/**
+\page org_mitk_views_segmentationutilities The Segmentation Utilities View
+
+\imageMacro{SegmentationUtilities.png,"Icon of the Segmentation Utilities View",5.00}
+
+\imageMacro{QmitkSegmentationUtilities_Overview.png,"The Segmentation Utilities view",16.00}
+
+\tableofcontents
+
+\section org_mitk_views_segmentationUtilitiesManualOverview Overview
+
+The <b>Segmentation Utilities View</b> allows you to postprocess existing segmentations
+
+
+\section org_mitk_views_segmentationUtilitiesImageSelection Image Selection
+
+Usually the data selection in the Segmentation Utilities View is done via drop down box which let you just select the appropriate data.
+
+\section org_mitk_views_segmentationUtilitiesBooleanOperations Boolean Operations
+
+Boolean operations allow you to create the
+
+<ul>
+<li> <b>Union:</b> Combines two existing segmentations
+<li> <b>Intersection:</b> Keeps just the overlapping areas of two existing segmentations
+<li> <b>Difference:</b> Subtracts one segmentation from the other
+</ul>
+
+of two segmentations. The selected segmentations must have the same geometry (size, spacing, ...)
+
+\imageMacro{QmitkSegmentationUtilities_IMGBooleanOperations.png,"Boolean operations of the SegmentationUtlitiesView",6.00}
+
+\section org_mitk_views_segmentationUtilitiesImageMasking Image masking
+
+You can mask your grey value image with either an existing segmentation or a surface. The result will be an image containing only
+the pixels that are cover by the respective mask.
+
+\imageMacro{QmitkSegmentationUtilities_IMGImageMasking.png,"Image masking widget of the Segmentation Utilities View",6.00}
+
+\section org_mitk_views_segmentationUtilitiesMorphologicalOperators Morphological Operators
+
+The morphological operators are applied to a single segmentation image. Based on a given structuring element the underlying segmentation will be modfied.
+MITK provides a <b>ball</b> and a <b>cross</b> as structuring elements. The follow operators are at your disposal:
+
+<ul>
+<li> <b>Dilation:</b> Each labeled pixel within the segmentation will be dilated based on the selected structuring element
+<li> <b>Erosion:</b> Each labeled pixel within the segmentation will be eroded based on the selected structuring element
+<li> <b>Opening:</b> A dilation followed by an erosion, used for smoothing edges or eliminating small objects
+<li> <b>Closing</b> An erosion followed by an dilation, used for filling small holes
+<li> <b>Fill Holes</b> Fills bigger holes within a segmentation
+</ul>
+
+\imageMacro{QmitkSegmentationUtilities_IMGMorphologicalOperators.png,"Morphological operators widget of the Segmentation Utilities View",6.00}
+
+\section org_mitk_views_segmentationUtilitiesSurfaceToImage Surface to binary image
+
+This widget lets you fill you meshes into an empty binary image. It is required that a reference grey value image is present.
+The created binary image will have the same geometrical properties like the reference image
+
+\imageMacro{QmitkSegmentationUtilities_IMGSurfaceToImage.png,"Surface to image widget of the Segmentation Utilities View",6.00}
+
+**/
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentationUtilities_IMGBooleanOperations.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentationUtilities_IMGBooleanOperations.png
new file mode 100644
index 0000000000..c3d5ef1cc1
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentationUtilities_IMGBooleanOperations.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentationUtilities_IMGImageMasking.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentationUtilities_IMGImageMasking.png
new file mode 100644
index 0000000000..f632f2b765
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentationUtilities_IMGImageMasking.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentationUtilities_IMGMorphologicalOperators.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentationUtilities_IMGMorphologicalOperators.png
new file mode 100644
index 0000000000..4adf520577
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentationUtilities_IMGMorphologicalOperators.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentationUtilities_IMGSurfaceToImage.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentationUtilities_IMGSurfaceToImage.png
new file mode 100644
index 0000000000..4c5e6273b2
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentationUtilities_IMGSurfaceToImage.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentationUtilities_Overview.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentationUtilities_Overview.png
new file mode 100644
index 0000000000..d992e36112
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentationUtilities_Overview.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_3DFMTool.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_3DFMTool.png
new file mode 100644
index 0000000000..99f0ef415d
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_3DFMTool.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_3DOtsuTool.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_3DOtsuTool.png
new file mode 100644
index 0000000000..c8694ce654
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_3DOtsuTool.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_3DRGTool.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_3DRGTool.png
new file mode 100644
index 0000000000..13c632cd88
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_3DRGTool.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_3DThresholdTool.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_3DThresholdTool.png
new file mode 100644
index 0000000000..5ff7139996
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_3DThresholdTool.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_3DTools.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_3DTools.png
new file mode 100644
index 0000000000..b31bdc4022
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_3DTools.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_3DULThresholdTool.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_3DULThresholdTool.png
new file mode 100644
index 0000000000..07a297bb06
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_3DULThresholdTool.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_3DWatershedTool.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_3DWatershedTool.png
new file mode 100644
index 0000000000..633163d943
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_3DWatershedTool.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMG2DFastMarchingUsage.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMG2DFastMarchingUsage.png
new file mode 100644
index 0000000000..ccd13bde62
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMG2DFastMarchingUsage.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGApplication.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGApplication.png
index 2902b91db9..81c903ae29 100644
Binary files a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGApplication.png and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGApplication.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGDataManagerContextMenu.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGDataManagerContextMenu.png
index a69d3b8dd2..ae303a7361 100644
Binary files a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGDataManagerContextMenu.png and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGDataManagerContextMenu.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGIconAddSubtract.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGIconAddSubtract.png
index 9e9aaf4c68..35efdd7797 100644
Binary files a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGIconAddSubtract.png and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGIconAddSubtract.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGIconCorrection.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGIconCorrection.png
index 41f21628e6..b8c31e4feb 100644
Binary files a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGIconCorrection.png and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGIconCorrection.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGIconErase.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGIconErase.png
index fafede4885..e4d95e6889 100644
Binary files a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGIconErase.png and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGIconErase.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGIconFill.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGIconFill.png
index 33b9498598..d3f2135306 100644
Binary files a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGIconFill.png and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGIconFill.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGIconLiveWire.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGIconLiveWire.png
index befc1f39bd..98344cb6e9 100644
Binary files a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGIconLiveWire.png and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGIconLiveWire.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGIconPaintWipe.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGIconPaintWipe.png
index c034048640..6a3ef5775f 100644
Binary files a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGIconPaintWipe.png and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGIconPaintWipe.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGIconRegionGrowing.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGIconRegionGrowing.png
index ec2ce1bb6b..dd54ad0fd0 100644
Binary files a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGIconRegionGrowing.png and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGIconRegionGrowing.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGPreferences.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGPreferences.png
new file mode 100644
index 0000000000..c8f4b0ff75
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGPreferences.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGSelection.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGSelection.png
index 25db6192cb..6364255e65 100644
Binary files a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGSelection.png and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_IMGSelection.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_PickingTool.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_PickingTool.png
new file mode 100644
index 0000000000..fa7be1a716
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_PickingTool.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_ToolOverview.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_ToolOverview.png
new file mode 100644
index 0000000000..d0d1025e84
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/QmitkSegmentation_ToolOverview.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/SegmentationUtilities.png b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/SegmentationUtilities.png
new file mode 100644
index 0000000000..2f6f7fd125
Binary files /dev/null and b/Plugins/org.mitk.gui.qt.segmentation/documentation/UserManual/SegmentationUtilities.png differ
diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/ImageMasking/QmitkImageMaskingWidget.cpp b/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/ImageMasking/QmitkImageMaskingWidget.cpp
index e64379cf1c..ceaa877fc7 100644
--- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/ImageMasking/QmitkImageMaskingWidget.cpp
+++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/ImageMasking/QmitkImageMaskingWidget.cpp
@@ -1,302 +1,302 @@
/*===================================================================
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 "QmitkImageMaskingWidget.h"
#include "mitkImage.h"
#include "../../Common/QmitkDataSelectionWidget.h"
#include <mitkException.h>
#include <mitkExceptionMacro.h>
#include <mitkImageStatisticsHolder.h>
#include <mitkMaskImageFilter.h>
#include <mitkProgressBar.h>
#include <mitkSliceNavigationController.h>
#include <mitkSurfaceToImageFilter.h>
#include <qmessagebox.h>
static const char* const HelpText = "Select a regular image and a binary image";
QmitkImageMaskingWidget::QmitkImageMaskingWidget(mitk::SliceNavigationController* timeNavigationController, QWidget* parent)
: QmitkSegmentationUtilityWidget(timeNavigationController, parent)
{
m_Controls.setupUi(this);
m_Controls.dataSelectionWidget->AddDataStorageComboBox(QmitkDataSelectionWidget::ImagePredicate);
m_Controls.dataSelectionWidget->AddDataStorageComboBox(QmitkDataSelectionWidget::SegmentationPredicate);
m_Controls.dataSelectionWidget->SetHelpText(HelpText);
this->EnableButtons(false);
connect (m_Controls.rbMaskImage, SIGNAL(toggled(bool)), this, SLOT(OnImageMaskingToggled(bool)));
connect (m_Controls.rbMaskSurface, SIGNAL(toggled(bool)), this, SLOT(OnSurfaceMaskingToggled(bool)));
connect (m_Controls.btnMaskImage, SIGNAL(clicked()), this, SLOT(OnMaskImagePressed()));
connect(m_Controls.dataSelectionWidget, SIGNAL(SelectionChanged(unsigned int, const mitk::DataNode*)),
this, SLOT(OnSelectionChanged(unsigned int, const mitk::DataNode*)));
if( m_Controls.dataSelectionWidget->GetSelection(0).IsNotNull() &&
m_Controls.dataSelectionWidget->GetSelection(1).IsNotNull() )
{
this->OnSelectionChanged( 0, m_Controls.dataSelectionWidget->GetSelection(0));
}
}
QmitkImageMaskingWidget::~QmitkImageMaskingWidget()
{
}
void QmitkImageMaskingWidget::OnSelectionChanged(unsigned int index, const mitk::DataNode* selection)
{
QmitkDataSelectionWidget* dataSelectionWidget = m_Controls.dataSelectionWidget;
mitk::DataNode::Pointer node0 = dataSelectionWidget->GetSelection(0);
mitk::DataNode::Pointer node1 = dataSelectionWidget->GetSelection(1);
if (node0.IsNull() || node1.IsNull() )
{
if( m_Controls.rbMaskImage->isChecked() )
{
dataSelectionWidget->SetHelpText(HelpText);
}
else
{
dataSelectionWidget->SetHelpText("Select a regular image and a surface");
}
this->EnableButtons(false);
}
else
{
this->SelectionControl(index, selection);
}
}
void QmitkImageMaskingWidget::SelectionControl(unsigned int index, const mitk::DataNode* selection)
{
QmitkDataSelectionWidget* dataSelectionWidget = m_Controls.dataSelectionWidget;
mitk::DataNode::Pointer node = dataSelectionWidget->GetSelection(index);
//if Image-Masking is enabled, check if image-dimension of reference and binary image is identical
if( m_Controls.rbMaskImage->isChecked() )
{
if( dataSelectionWidget->GetSelection(0) == dataSelectionWidget->GetSelection(1) )
{
dataSelectionWidget->SetHelpText("Select two different images above");
this->EnableButtons(false);
return;
}
else if( node.IsNotNull() && selection )
{
mitk::Image::Pointer referenceImage = dynamic_cast<mitk::Image*> ( dataSelectionWidget->GetSelection(0)->GetData() );
mitk::Image::Pointer maskImage = dynamic_cast<mitk::Image*> ( dataSelectionWidget->GetSelection(1)->GetData() );
- if( referenceImage->GetLargestPossibleRegion().GetSize() != maskImage->GetLargestPossibleRegion().GetSize() )
+ if( maskImage.IsNull() || referenceImage->GetLargestPossibleRegion().GetSize() != maskImage->GetLargestPossibleRegion().GetSize() )
{
dataSelectionWidget->SetHelpText("Different image sizes cannot be masked");
this->EnableButtons(false);
return;
}
}
else
{
dataSelectionWidget->SetHelpText(HelpText);
return;
}
}
dataSelectionWidget->SetHelpText("");
this->EnableButtons();
}
void QmitkImageMaskingWidget::EnableButtons(bool enable)
{
m_Controls.btnMaskImage->setEnabled(enable);
}
void QmitkImageMaskingWidget::OnImageMaskingToggled(bool status)
{
if (status)
{
m_Controls.dataSelectionWidget->SetHelpText("Select a regular image and a binary image");
m_Controls.dataSelectionWidget->SetPredicate(1, QmitkDataSelectionWidget::SegmentationPredicate);
}
}
void QmitkImageMaskingWidget::OnSurfaceMaskingToggled(bool status)
{
if (status)
{
m_Controls.dataSelectionWidget->SetHelpText("Select a regular image and a surface");
m_Controls.dataSelectionWidget->SetPredicate(1, QmitkDataSelectionWidget::SurfacePredicate);
}
}
void QmitkImageMaskingWidget::OnMaskImagePressed()
{
//Disable Buttons during calculation and initialize Progressbar
this->EnableButtons(false);
mitk::ProgressBar::GetInstance()->AddStepsToDo(4);
mitk::ProgressBar::GetInstance()->Progress();
QmitkDataSelectionWidget* dataSelectionWidget = m_Controls.dataSelectionWidget;
//create result image, get mask node and reference image
mitk::Image::Pointer resultImage(0);
mitk::DataNode::Pointer maskingNode = dataSelectionWidget->GetSelection(1);
mitk::Image::Pointer referenceImage = static_cast<mitk::Image*>(dataSelectionWidget->GetSelection(0)->GetData());
if(referenceImage.IsNull() || maskingNode.IsNull() )
{
MITK_ERROR << "Selection does not contain an image";
QMessageBox::information( this, "Image and Surface Masking", "Selection does not contain an image", QMessageBox::Ok );
m_Controls.btnMaskImage->setEnabled(true);
return;
}
//Do Image-Masking
if (m_Controls.rbMaskImage->isChecked())
{
mitk::ProgressBar::GetInstance()->Progress();
mitk::Image::Pointer maskImage = dynamic_cast<mitk::Image*> ( maskingNode->GetData() );
if(maskImage.IsNull() )
{
MITK_ERROR << "Selection does not contain a binary image";
QMessageBox::information( this, "Image and Surface Masking", "Selection does not contain a binary image", QMessageBox::Ok );
this->EnableButtons();
return;
}
if( referenceImage->GetLargestPossibleRegion().GetSize() == maskImage->GetLargestPossibleRegion().GetSize() )
{
resultImage = this->MaskImage( referenceImage, maskImage );
}
}
//Do Surface-Masking
else
{
mitk::ProgressBar::GetInstance()->Progress();
//1. convert surface to image
mitk::Surface::Pointer surface = dynamic_cast<mitk::Surface*> ( maskingNode->GetData() );
//TODO Get 3D Surface of current time step
if(surface.IsNull())
{
MITK_ERROR << "Selection does not contain a surface";
QMessageBox::information( this, "Image and Surface Masking", "Selection does not contain a surface", QMessageBox::Ok );
this->EnableButtons();
return;
}
mitk::Image::Pointer maskImage = this->ConvertSurfaceToImage( referenceImage, surface );
//2. mask reference image with mask image
if(maskImage.IsNotNull() &&
referenceImage->GetLargestPossibleRegion().GetSize() == maskImage->GetLargestPossibleRegion().GetSize() )
{
resultImage = this->MaskImage( referenceImage, maskImage );
}
}
mitk::ProgressBar::GetInstance()->Progress();
if( resultImage.IsNull() )
{
MITK_ERROR << "Masking failed";
QMessageBox::information( this, "Image and Surface Masking", "Masking failed. For more information please see logging window.", QMessageBox::Ok );
this->EnableButtons();
mitk::ProgressBar::GetInstance()->Progress(4);
return;
}
//Add result to data storage
this->AddToDataStorage(
dataSelectionWidget->GetDataStorage(),
resultImage,
dataSelectionWidget->GetSelection(0)->GetName() + "_" + dataSelectionWidget->GetSelection(1)->GetName(),
dataSelectionWidget->GetSelection(0));
this->EnableButtons();
mitk::ProgressBar::GetInstance()->Progress();
}
mitk::Image::Pointer QmitkImageMaskingWidget::MaskImage(mitk::Image::Pointer referenceImage, mitk::Image::Pointer maskImage )
{
mitk::Image::Pointer resultImage(0);
mitk::MaskImageFilter::Pointer maskFilter = mitk::MaskImageFilter::New();
maskFilter->SetInput( referenceImage );
maskFilter->SetMask( maskImage );
maskFilter->OverrideOutsideValueOn();
maskFilter->SetOutsideValue( referenceImage->GetStatistics()->GetScalarValueMin() );
try
{
maskFilter->Update();
}
catch(itk::ExceptionObject& excpt)
{
MITK_ERROR << excpt.GetDescription();
return 0;
}
resultImage = maskFilter->GetOutput();
return resultImage;
}
mitk::Image::Pointer QmitkImageMaskingWidget::ConvertSurfaceToImage( mitk::Image::Pointer image, mitk::Surface::Pointer surface )
{
mitk::ProgressBar::GetInstance()->AddStepsToDo(2);
mitk::ProgressBar::GetInstance()->Progress();
mitk::SurfaceToImageFilter::Pointer surfaceToImageFilter = mitk::SurfaceToImageFilter::New();
surfaceToImageFilter->MakeOutputBinaryOn();
surfaceToImageFilter->SetInput(surface);
surfaceToImageFilter->SetImage(image);
try
{
surfaceToImageFilter->Update();
}
catch(itk::ExceptionObject& excpt)
{
MITK_ERROR << excpt.GetDescription();
return 0;
}
mitk::ProgressBar::GetInstance()->Progress();
mitk::Image::Pointer resultImage = mitk::Image::New();
resultImage = surfaceToImageFilter->GetOutput();
return resultImage;
}
void QmitkImageMaskingWidget::AddToDataStorage(mitk::DataStorage::Pointer dataStorage, mitk::Image::Pointer segmentation, const std::string& name, mitk::DataNode::Pointer parent )
{
mitk::DataNode::Pointer dataNode = mitk::DataNode::New();
dataNode->SetName(name);
dataNode->SetData(segmentation);
dataStorage->Add(dataNode, parent);
}
diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.segmentation/src/internal/mitkPluginActivator.cpp
index 6500500440..d1609d5dd2 100644
--- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/mitkPluginActivator.cpp
+++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/mitkPluginActivator.cpp
@@ -1,53 +1,55 @@
/*===================================================================
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 "mitkPluginActivator.h"
#include "QmitkSegmentationView.h"
#include "QmitkThresholdAction.h"
#include "QmitkCreatePolygonModelAction.h"
#include "QmitkAutocropAction.h"
#include "QmitkSegmentationPreferencePage.h"
#include "QmitkDeformableClippingPlaneView.h"
#include "SegmentationUtilities/QmitkSegmentationUtilitiesView.h"
using namespace mitk;
ctkPluginContext* PluginActivator::m_context = NULL;
void PluginActivator::start(ctkPluginContext *context)
{
BERRY_REGISTER_EXTENSION_CLASS(QmitkSegmentationView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkThresholdAction, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkCreatePolygonModelAction, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkAutocropAction, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkSegmentationPreferencePage, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkDeformableClippingPlaneView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkSegmentationUtilitiesView, context)
this->m_context = context;
}
void PluginActivator::stop(ctkPluginContext *)
{
this->m_context = NULL;
}
ctkPluginContext*PluginActivator::getContext()
{
return m_context;
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_segmentation, mitk::PluginActivator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_segmentation, mitk::PluginActivator)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.segmentation/src/internal/mitkPluginActivator.h
index d0c6e5f9e2..6f030a44c9 100644
--- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/mitkPluginActivator.h
+++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/mitkPluginActivator.h
@@ -1,43 +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 MITKPLUGINACTIVATOR_H
#define MITKPLUGINACTIVATOR_H
// Parent classes
#include <QObject>
#include <ctkPluginActivator.h>
#include <mitkExportMacros.h>
namespace mitk
{
class MITK_LOCAL PluginActivator : public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_segmentation")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext *context);
void stop(ctkPluginContext *context);
static ctkPluginContext* getContext();
private:
static ctkPluginContext* m_context;
};
}
#endif
diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseItemDelegate.h b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseItemDelegate.h
index 01a009a16d..73500b789e 100644
--- a/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseItemDelegate.h
+++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/QmitkBaseItemDelegate.h
@@ -1,49 +1,39 @@
/*===================================================================
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 <QStyledItemDelegate>
-
-namespace sofa
-{
- namespace core
- {
- namespace objectmodel
- {
- class BaseData;
- }
- }
-}
+#include <sofa/core/objectmodel/BaseData.h>
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/org_mitk_gui_qt_simulation_Activator.cpp b/Plugins/org.mitk.gui.qt.simulation/src/internal/org_mitk_gui_qt_simulation_Activator.cpp
index 90369e11b2..60f0d28cb2 100644
--- a/Plugins/org.mitk.gui.qt.simulation/src/internal/org_mitk_gui_qt_simulation_Activator.cpp
+++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/org_mitk_gui_qt_simulation_Activator.cpp
@@ -1,41 +1,43 @@
/*===================================================================
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 "QmitkSimulationPreferencePage.h"
#include "QmitkSimulationView.h"
#include <QtPlugin>
ctkPluginContext* mitk::org_mitk_gui_qt_simulation_Activator::Context = NULL;
ctkPluginContext* mitk::org_mitk_gui_qt_simulation_Activator::GetContext()
{
return Context;
}
void mitk::org_mitk_gui_qt_simulation_Activator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(QmitkSimulationPreferencePage, context);
BERRY_REGISTER_EXTENSION_CLASS(QmitkSimulationView, context);
Context = context;
}
void mitk::org_mitk_gui_qt_simulation_Activator::stop(ctkPluginContext*)
{
Context = NULL;
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_simulation, mitk::org_mitk_gui_qt_simulation_Activator);
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_simulation, mitk::org_mitk_gui_qt_simulation_Activator)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.simulation/src/internal/org_mitk_gui_qt_simulation_Activator.h b/Plugins/org.mitk.gui.qt.simulation/src/internal/org_mitk_gui_qt_simulation_Activator.h
index 65e96a3771..c299e30a7b 100644
--- a/Plugins/org.mitk.gui.qt.simulation/src/internal/org_mitk_gui_qt_simulation_Activator.h
+++ b/Plugins/org.mitk.gui.qt.simulation/src/internal/org_mitk_gui_qt_simulation_Activator.h
@@ -1,40 +1,43 @@
/*===================================================================
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 org_mitk_gui_qt_simulation_Activator_h
#define org_mitk_gui_qt_simulation_Activator_h
#include <ctkPluginActivator.h>
namespace mitk
{
class org_mitk_gui_qt_simulation_Activator : public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_simulation")
+#endif
Q_INTERFACES(ctkPluginActivator);
public:
static ctkPluginContext* GetContext();
void start(ctkPluginContext* context);
void stop(ctkPluginContext*);
private:
static ctkPluginContext* Context;
};
}
#endif
diff --git a/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/org_mitk_gui_qt_stdmultiwidgeteditor_Activator.cpp b/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/org_mitk_gui_qt_stdmultiwidgeteditor_Activator.cpp
index 1d5eb961dc..3aaf7b6c86 100644
--- a/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/org_mitk_gui_qt_stdmultiwidgeteditor_Activator.cpp
+++ b/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/org_mitk_gui_qt_stdmultiwidgeteditor_Activator.cpp
@@ -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.
===================================================================*/
#include "org_mitk_gui_qt_stdmultiwidgeteditor_Activator.h"
#include "../QmitkStdMultiWidgetEditor.h"
#include "QmitkStdMultiWidgetEditorPreferencePage.h"
void
org_mitk_gui_qt_stdmultiwidgeteditor_Activator::start(ctkPluginContext* context)
{
Q_UNUSED(context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkStdMultiWidgetEditor, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkStdMultiWidgetEditorPreferencePage, context)
}
void
org_mitk_gui_qt_stdmultiwidgeteditor_Activator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_stdmultiwidgeteditor, org_mitk_gui_qt_stdmultiwidgeteditor_Activator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_stdmultiwidgeteditor, org_mitk_gui_qt_stdmultiwidgeteditor_Activator)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/org_mitk_gui_qt_stdmultiwidgeteditor_Activator.h b/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/org_mitk_gui_qt_stdmultiwidgeteditor_Activator.h
index aa8c4f44f9..6ef85778a0 100644
--- a/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/org_mitk_gui_qt_stdmultiwidgeteditor_Activator.h
+++ b/Plugins/org.mitk.gui.qt.stdmultiwidgeteditor/src/internal/org_mitk_gui_qt_stdmultiwidgeteditor_Activator.h
@@ -1,39 +1,42 @@
/*===================================================================
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 org_mitk_gui_qt_stdmultiwidgeteditor_Activator_H_
#define org_mitk_gui_qt_stdmultiwidgeteditor_Activator_H_
#include <ctkPluginActivator.h>
/**
* \ingroup org_mitk_gui_qt_stdmultiwidgeteditor
*/
class org_mitk_gui_qt_stdmultiwidgeteditor_Activator : public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_stdmultiwidgeteditor")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
};
#endif /* org_mitk_gui_qt_stdmultiwidgeteditor_Activator_H_ */
diff --git a/Plugins/org.mitk.gui.qt.toftutorial/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.toftutorial/src/internal/mitkPluginActivator.cpp
index d6162b8a10..a0f199e44d 100644
--- a/Plugins/org.mitk.gui.qt.toftutorial/src/internal/mitkPluginActivator.cpp
+++ b/Plugins/org.mitk.gui.qt.toftutorial/src/internal/mitkPluginActivator.cpp
@@ -1,35 +1,37 @@
/*===================================================================
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 "mitkPluginActivator.h"
#include <QtPlugin>
#include "QmitkToFTutorialView.h"
namespace mitk {
void PluginActivator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(QmitkToFTutorialView, context)
}
void PluginActivator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_toftutorial, mitk::PluginActivator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_toftutorial, mitk::PluginActivator)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.toftutorial/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.toftutorial/src/internal/mitkPluginActivator.h
index 489bd853ca..03aa373134 100644
--- a/Plugins/org.mitk.gui.qt.toftutorial/src/internal/mitkPluginActivator.h
+++ b/Plugins/org.mitk.gui.qt.toftutorial/src/internal/mitkPluginActivator.h
@@ -1,40 +1,43 @@
/*===================================================================
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 MITKPLUGINACTIVATOR_H
#define MITKPLUGINACTIVATOR_H
#include <ctkPluginActivator.h>
#include <mitkExportMacros.h>
namespace mitk {
class MITK_LOCAL PluginActivator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_toftutorial")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
}; // PluginActivator
}
#endif // MITKPLUGINACTIVATOR_H
diff --git a/Plugins/org.mitk.gui.qt.tofutil/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.tofutil/src/internal/mitkPluginActivator.cpp
index 5a4c6d5d7e..547829cbea 100644
--- a/Plugins/org.mitk.gui.qt.tofutil/src/internal/mitkPluginActivator.cpp
+++ b/Plugins/org.mitk.gui.qt.tofutil/src/internal/mitkPluginActivator.cpp
@@ -1,37 +1,39 @@
/*===================================================================
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 "mitkPluginActivator.h"
#include <QtPlugin>
#include "QmitkToFUtilView.h"
#include "QmitkToFDeviceGeneration.h"
namespace mitk {
void PluginActivator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(QmitkToFUtilView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkToFDeviceGeneration, context)
}
void PluginActivator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_tofutil, mitk::PluginActivator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_tofutil, mitk::PluginActivator)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.tofutil/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.tofutil/src/internal/mitkPluginActivator.h
index 489bd853ca..c1daf6b9f3 100644
--- a/Plugins/org.mitk.gui.qt.tofutil/src/internal/mitkPluginActivator.h
+++ b/Plugins/org.mitk.gui.qt.tofutil/src/internal/mitkPluginActivator.h
@@ -1,40 +1,43 @@
/*===================================================================
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 MITKPLUGINACTIVATOR_H
#define MITKPLUGINACTIVATOR_H
#include <ctkPluginActivator.h>
#include <mitkExportMacros.h>
namespace mitk {
class MITK_LOCAL PluginActivator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_tofutil")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
}; // PluginActivator
}
#endif // MITKPLUGINACTIVATOR_H
diff --git a/Plugins/org.mitk.gui.qt.ugvisualization/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.ugvisualization/src/internal/mitkPluginActivator.cpp
index 763d7135fc..a0ede4b27a 100644
--- a/Plugins/org.mitk.gui.qt.ugvisualization/src/internal/mitkPluginActivator.cpp
+++ b/Plugins/org.mitk.gui.qt.ugvisualization/src/internal/mitkPluginActivator.cpp
@@ -1,36 +1,38 @@
/*===================================================================
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 "mitkPluginActivator.h"
#include <QtPlugin>
#include "QmitkUGVisualizationView.h"
namespace mitk {
void PluginActivator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(QmitkUGVisualizationView, context)
}
void PluginActivator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_ugvisualization, mitk::PluginActivator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_ugvisualization, mitk::PluginActivator)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.ugvisualization/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.ugvisualization/src/internal/mitkPluginActivator.h
index 489bd853ca..4761cacfa1 100644
--- a/Plugins/org.mitk.gui.qt.ugvisualization/src/internal/mitkPluginActivator.h
+++ b/Plugins/org.mitk.gui.qt.ugvisualization/src/internal/mitkPluginActivator.h
@@ -1,40 +1,43 @@
/*===================================================================
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 MITKPLUGINACTIVATOR_H
#define MITKPLUGINACTIVATOR_H
#include <ctkPluginActivator.h>
#include <mitkExportMacros.h>
namespace mitk {
class MITK_LOCAL PluginActivator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_ugvisualization")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
}; // PluginActivator
}
#endif // MITKPLUGINACTIVATOR_H
diff --git a/Plugins/org.mitk.gui.qt.ultrasound/src/internal/org_mitk_gui_qt_ultrasound_Activator.cpp b/Plugins/org.mitk.gui.qt.ultrasound/src/internal/org_mitk_gui_qt_ultrasound_Activator.cpp
index ef25db43db..04b614a8aa 100644
--- a/Plugins/org.mitk.gui.qt.ultrasound/src/internal/org_mitk_gui_qt_ultrasound_Activator.cpp
+++ b/Plugins/org.mitk.gui.qt.ultrasound/src/internal/org_mitk_gui_qt_ultrasound_Activator.cpp
@@ -1,49 +1,51 @@
/*===================================================================
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_ultrasound_Activator.h"
#include <QtPlugin>
#include "UltrasoundSupport.h"
namespace mitk {
ctkPluginContext* org_mitk_gui_qt_ultrasound_Activator::m_Context = 0;
void org_mitk_gui_qt_ultrasound_Activator::start(ctkPluginContext* context)
{
m_Context = context;
BERRY_REGISTER_EXTENSION_CLASS(UltrasoundSupport, context)
}
void org_mitk_gui_qt_ultrasound_Activator::stop(ctkPluginContext* context)
{
m_Context = 0;
Q_UNUSED(context)
}
ctkPluginContext *org_mitk_gui_qt_ultrasound_Activator::GetContext()
{
return m_Context;
}
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_ultrasound, mitk::org_mitk_gui_qt_ultrasound_Activator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_ultrasound, mitk::org_mitk_gui_qt_ultrasound_Activator)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.ultrasound/src/internal/org_mitk_gui_qt_ultrasound_Activator.h b/Plugins/org.mitk.gui.qt.ultrasound/src/internal/org_mitk_gui_qt_ultrasound_Activator.h
index c34cbc0eda..54e46694f6 100644
--- a/Plugins/org.mitk.gui.qt.ultrasound/src/internal/org_mitk_gui_qt_ultrasound_Activator.h
+++ b/Plugins/org.mitk.gui.qt.ultrasound/src/internal/org_mitk_gui_qt_ultrasound_Activator.h
@@ -1,47 +1,50 @@
/*===================================================================
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 org_mitk_gui_qt_ultrasound_Activator_h
#define org_mitk_gui_qt_ultrasound_Activator_h
#include <ctkPluginActivator.h>
namespace mitk {
class org_mitk_gui_qt_ultrasound_Activator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_ultrasound")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
static ctkPluginContext* GetContext();
private:
static ctkPluginContext* m_Context;
}; // org_mitk_gui_qt_ultrasound_Activator
typedef org_mitk_gui_qt_ultrasound_Activator PluginActivator;
}
#endif // org_mitk_gui_qt_ultrasound_Activator_h
diff --git a/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewNavigatorWidget.cpp b/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewNavigatorWidget.cpp
index d58235cb44..731d5a9fc4 100644
--- a/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewNavigatorWidget.cpp
+++ b/Plugins/org.mitk.gui.qt.viewnavigator/src/QmitkViewNavigatorWidget.cpp
@@ -1,783 +1,791 @@
/*===================================================================
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.
===================================================================*/
//Qmitk headers
#include "QmitkViewNavigatorWidget.h"
// Blueberry
#include <berryISelectionService.h>
#include <berryIWorkbenchWindow.h>
#include <berryIPerspectiveRegistry.h>
#include <berryPlatformUI.h>
#include <berryIWorkbenchPage.h>
#include <berryIExtensionPointService.h>
// Qt
#include <QMessageBox>
#include <QTreeView>
#include <QStandardItem>
#include <QSortFilterProxyModel>
class KeywordRegistry
{
public:
KeywordRegistry()
{
berry::IExtensionPointService::Pointer extensionPointService = berry::Platform::GetExtensionPointService();
berry::IConfigurationElement::vector keywordExts(extensionPointService->GetConfigurationElementsFor("org.blueberry.ui.keywords"));
std::string keywordId;
std::string keywordLabels;
berry::IConfigurationElement::vector::iterator keywordExtsIt;
for (keywordExtsIt = keywordExts.begin(); keywordExtsIt != keywordExts.end(); ++keywordExtsIt)
{
(*keywordExtsIt)->GetAttribute("id", keywordId);
(*keywordExtsIt)->GetAttribute("label", keywordLabels);
if (m_Keywords.find(keywordId) == m_Keywords.end())
{
m_Keywords[keywordId] = std::vector<QString>();
}
m_Keywords[keywordId].push_back(QString::fromStdString(keywordLabels));
}
}
std::vector<QString> GetKeywords(const std::string& id)
{
return m_Keywords[id];
}
std::vector<QString> GetKeywords(const std::vector<std::string>& ids)
{
std::vector<QString> result;
for (unsigned int i = 0; i < ids.size(); ++i)
{
std::vector< QString > tmpResult;
tmpResult = this->GetKeywords(ids[i]);
result.insert(result.end(), tmpResult.begin(), tmpResult.end());
}
return result;
}
private:
std::map<std::string, std::vector<QString> > m_Keywords;
};
class ClassFilterProxyModel : public QSortFilterProxyModel
{
private :
bool hasToBeDisplayed(const QModelIndex index) const;
bool displayElement(const QModelIndex index) const;
public:
ClassFilterProxyModel(QObject *parent = NULL);
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
};
ClassFilterProxyModel::ClassFilterProxyModel(QObject *parent):
QSortFilterProxyModel(parent)
{
}
bool ClassFilterProxyModel::filterAcceptsRow(int sourceRow,
const QModelIndex &sourceParent) const
{
QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
return hasToBeDisplayed(index);
}
bool ClassFilterProxyModel::displayElement(const QModelIndex index) const
{
bool result = false;
QString type = sourceModel()->data(index, Qt::DisplayRole).toString();
QStandardItem * item = dynamic_cast<QStandardItemModel*>(sourceModel())->itemFromIndex(index);
if (type.contains(filterRegExp()))
{
return true;
}
{
mitk::QtViewItem* viewItem = dynamic_cast<mitk::QtViewItem*>(item);
if (viewItem)
{
for (unsigned int i = 0; i < viewItem->m_Tags.size(); ++i)
{
if (viewItem->m_Tags[i].contains(filterRegExp()))
{
return true;
}
}
if (viewItem->m_Description.contains(filterRegExp()))
{
return true;
}
}
}
{
mitk::QtPerspectiveItem* viewItem = dynamic_cast<mitk::QtPerspectiveItem*>(item);
if (viewItem)
{
for (unsigned int i = 0; i < viewItem->m_Tags.size(); ++i)
{
if (viewItem->m_Tags[i].contains(filterRegExp()))
{
return true;
}
}
if (viewItem->m_Description.contains(filterRegExp()))
{
return true;
}
}
}
return result;
}
bool ClassFilterProxyModel::hasToBeDisplayed(const QModelIndex index) const
{
bool result = false;
if ( sourceModel()->rowCount(index) > 0 )
{
for( int ii = 0; ii < sourceModel()->rowCount(index); ii++)
{
QModelIndex childIndex = sourceModel()->index(ii,0,index);
if ( ! childIndex.isValid() )
break;
result = hasToBeDisplayed(childIndex);
result |= displayElement(index);
if (result)
{
break;
}
}
}
else
{
result = displayElement(index);
}
return result;
}
class ViewNavigatorPerspectiveListener: public berry::IPerspectiveListener
{
public:
ViewNavigatorPerspectiveListener(QmitkViewNavigatorWidget* p) :
parentWidget(p)
{
}
Events::Types GetPerspectiveEventTypes() const
{
return Events::ACTIVATED | Events::SAVED_AS | Events::DEACTIVATED
// remove the following line when command framework is finished
| Events::CLOSED | Events::OPENED | Events::PART_CHANGED;
}
void PerspectiveActivated(berry::IWorkbenchPage::Pointer /*page*/,
berry::IPerspectiveDescriptor::Pointer /*perspective*/)
{
parentWidget->UpdateTreeList();
}
void PerspectiveSavedAs(berry::IWorkbenchPage::Pointer /*page*/,
berry::IPerspectiveDescriptor::Pointer /*oldPerspective*/,
berry::IPerspectiveDescriptor::Pointer /*newPerspective*/)
{
}
void PerspectiveDeactivated(berry::IWorkbenchPage::Pointer /*page*/,
berry::IPerspectiveDescriptor::Pointer /*perspective*/)
{
parentWidget->UpdateTreeList();
}
void PerspectiveOpened(berry::IWorkbenchPage::Pointer /*page*/,
berry::IPerspectiveDescriptor::Pointer /*perspective*/)
{
parentWidget->UpdateTreeList();
}
void PerspectiveClosed(berry::IWorkbenchPage::Pointer /*page*/,
berry::IPerspectiveDescriptor::Pointer /*perspective*/)
{
parentWidget->UpdateTreeList();
}
void PerspectiveChanged(berry::IWorkbenchPage::Pointer,
berry::IPerspectiveDescriptor::Pointer,
berry::IWorkbenchPartReference::Pointer partRef, const std::string& changeId)
{
if (changeId=="viewHide" && partRef->GetId()=="org.mitk.views.viewnavigatorview")
berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->RemovePerspectiveListener(parentWidget->m_PerspectiveListener);
else
parentWidget->UpdateTreeList(NULL, partRef.GetPointer(), changeId);
}
private:
QmitkViewNavigatorWidget* parentWidget;
};
struct ViewNavigatorWindowListener : public berry::IWindowListener
{
ViewNavigatorWindowListener(QmitkViewNavigatorWidget* switcher)
: switcher(switcher)
, m_Done(false)
{}
virtual void WindowOpened(berry::IWorkbenchWindow::Pointer window)
{
if (m_Done)
return;
if ( switcher->FillTreeList() )
{
m_Done = true;
switcher->m_PerspectiveListener = ViewNavigatorPerspectiveListener::Pointer(new ViewNavigatorPerspectiveListener(switcher));
window->AddPerspectiveListener(switcher->m_PerspectiveListener);
}
}
virtual void WindowActivated(berry::IWorkbenchWindow::Pointer window)
{
if (m_Done)
return;
if ( switcher->FillTreeList() )
{
m_Done = true;
switcher->m_PerspectiveListener = ViewNavigatorPerspectiveListener::Pointer(new ViewNavigatorPerspectiveListener(switcher));
window->AddPerspectiveListener(switcher->m_PerspectiveListener);
}
}
private:
QmitkViewNavigatorWidget* switcher;
bool m_Done;
};
bool compareViews(berry::IViewDescriptor::Pointer a, berry::IViewDescriptor::Pointer b)
{
if (a.IsNull() || b.IsNull())
return false;
return a->GetLabel().compare(b->GetLabel()) < 0;
}
bool comparePerspectives(berry::IPerspectiveDescriptor::Pointer a, berry::IPerspectiveDescriptor::Pointer b)
{
if (a.IsNull() || b.IsNull())
return false;
return a->GetLabel().compare(b->GetLabel()) < 0;
}
bool compareQStandardItems(QStandardItem* a, QStandardItem* b)
{
if (a==NULL || b==NULL)
return false;
return a->text().compare(b->text()) < 0;
}
QmitkViewNavigatorWidget::QmitkViewNavigatorWidget( QWidget * parent, Qt::WindowFlags )
: QWidget(parent)
{
m_Generated = false;
this->CreateQtPartControl(this);
}
QmitkViewNavigatorWidget::~QmitkViewNavigatorWidget()
{
}
void QmitkViewNavigatorWidget::setFocus()
{
m_Controls.lineEdit->setFocus();
}
void QmitkViewNavigatorWidget::CreateQtPartControl( QWidget *parent )
{
// create GUI widgets from the Qt Designer's .ui file
if (berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow().IsNotNull())
{
m_PerspectiveListener = ViewNavigatorPerspectiveListener::Pointer(new ViewNavigatorPerspectiveListener(this));
berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->AddPerspectiveListener(m_PerspectiveListener);
}
else
{
m_WindowListener = ViewNavigatorWindowListener::Pointer(new ViewNavigatorWindowListener(this));
berry::PlatformUI::GetWorkbench()->AddWindowListener(m_WindowListener);
}
m_Parent = parent;
m_Controls.setupUi( parent );
connect( m_Controls.m_PluginTreeView, SIGNAL(customContextMenuRequested(QPoint)), SLOT(CustomMenuRequested(QPoint)));
connect( m_Controls.m_PluginTreeView, SIGNAL(doubleClicked(const QModelIndex&)), SLOT(ItemClicked(const QModelIndex&)));
connect( m_Controls.lineEdit, SIGNAL(textChanged(QString)), SLOT(FilterChanged()));
m_ContextMenu = new QMenu(m_Controls.m_PluginTreeView);
m_Controls.m_PluginTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
// Create a new TreeModel for the data
m_TreeModel = new QStandardItemModel();
m_FilterProxyModel = new ClassFilterProxyModel(this);
m_FilterProxyModel->setSourceModel(m_TreeModel);
//proxyModel->setFilterFixedString("Diff");
m_Controls.m_PluginTreeView->setModel(m_FilterProxyModel);
}
void QmitkViewNavigatorWidget::UpdateTreeList(QStandardItem* root, berry::IWorkbenchPartReference *partRef, const std::string &changeId)
{
berry::IWorkbenchPage::Pointer page = berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage();
if (page.IsNull())
return;
if( !m_Generated )
{
m_Generated = FillTreeList();
}
if (root==NULL)
root = m_TreeModel->invisibleRootItem();
for (int i=0; i<root->rowCount(); i++)
{
QStandardItem* item = root->child(i);
QFont font;
if (dynamic_cast<mitk::QtPerspectiveItem*>(item))
{
mitk::QtPerspectiveItem* pItem = dynamic_cast<mitk::QtPerspectiveItem*>(item);
berry::IPerspectiveDescriptor::Pointer currentPersp = page->GetPerspective();
if (currentPersp.IsNotNull() && currentPersp->GetId()==pItem->m_Perspective->GetId())
font.setBold(true);
pItem->setFont(font);
}
mitk::QtViewItem* vItem = dynamic_cast<mitk::QtViewItem*>(item);
if (vItem)
{
std::vector<berry::IViewPart::Pointer> viewParts(page->GetViews());
for (unsigned int i=0; i<viewParts.size(); i++)
if(viewParts[i]->GetPartName()==vItem->m_View->GetLabel())
{
font.setBold(true);
break;
}
if( partRef!=NULL && partRef->GetId()==vItem->m_View->GetId() && changeId=="viewHide")
font.setBold(false);
vItem->setFont(font);
}
UpdateTreeList(item, partRef, changeId);
}
}
bool QmitkViewNavigatorWidget::FillTreeList()
{
// active workbench window available?
if (berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow().IsNull())
return false;
// active page available?
berry::IWorkbenchPage::Pointer page = berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage();
if (page.IsNull())
return false;
// everything is fine and we can remove the window listener
if (m_WindowListener.IsNotNull())
berry::PlatformUI::GetWorkbench()->RemoveWindowListener(m_WindowListener);
// initialize tree model
m_TreeModel->clear();
QStandardItem *treeRootItem = m_TreeModel->invisibleRootItem();
// get all available perspectives
berry::IPerspectiveRegistry* perspRegistry = berry::PlatformUI::GetWorkbench()->GetPerspectiveRegistry();
std::vector<berry::IPerspectiveDescriptor::Pointer> perspectiveDescriptors(perspRegistry->GetPerspectives());
std::sort(perspectiveDescriptors.begin(), perspectiveDescriptors.end(), comparePerspectives);
// get all Keywords
KeywordRegistry keywordRegistry;
berry::IPerspectiveDescriptor::Pointer currentPersp = page->GetPerspective();
std::vector<std::string> perspectiveExcludeList = berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetPerspectiveExcludeList();
std::vector< QStandardItem* > categoryItems;
QStandardItem *perspectiveRootItem = new QStandardItem("Workflows");
perspectiveRootItem->setEditable(false);
+ perspectiveRootItem->setFont(QFont("", 12, QFont::Normal));
treeRootItem->appendRow(perspectiveRootItem);
+
for (unsigned int i=0; i<perspectiveDescriptors.size(); i++)
{
berry::IPerspectiveDescriptor::Pointer p = perspectiveDescriptors.at(i);
bool skipPerspective = false;
for(unsigned int e=0; e<perspectiveExcludeList.size(); e++)
if(perspectiveExcludeList.at(e)==p->GetId())
{
skipPerspective = true;
break;
}
if (skipPerspective)
continue;
//QIcon* pIcon = static_cast<QIcon*>(p->GetImageDescriptor()->CreateImage());
mitk::QtPerspectiveItem* pItem = new mitk::QtPerspectiveItem(QString::fromStdString(p->GetLabel()));
pItem->m_Perspective = p;
pItem->m_Description = QString::fromStdString(p->GetDescription());
std::vector<std::string> keylist = p->GetKeywordReferences();
pItem->m_Tags = keywordRegistry.GetKeywords(keylist);
pItem->setEditable(false);
QFont font; font.setBold(true);
if (currentPersp.IsNotNull() && currentPersp->GetId()==p->GetId())
pItem->setFont(font);
std::vector<std::string> catPath = p->GetCategoryPath();
if (catPath.empty())
{
perspectiveRootItem->appendRow(pItem);
}
else
{
QStandardItem* categoryItem = NULL;
for (unsigned int c=0; c<categoryItems.size(); c++)
if (categoryItems.at(c)->text().toStdString() == catPath.front())
{
categoryItem = categoryItems.at(c);
break;
}
if (categoryItem==NULL)
{
categoryItem = new QStandardItem(QIcon(),catPath.front().c_str());
categoryItems.push_back(categoryItem);
}
categoryItem->setEditable(false);
categoryItem->appendRow(pItem);
+ categoryItem->setFont(QFont("", 12, QFont::Normal));
}
}
std::sort(categoryItems.begin(), categoryItems.end(), compareQStandardItems);
for (unsigned int i=0; i<categoryItems.size(); i++)
perspectiveRootItem->appendRow(categoryItems.at(i));
// get all available views
berry::IViewRegistry* viewRegistry = berry::PlatformUI::GetWorkbench()->GetViewRegistry();
std::vector<berry::IViewDescriptor::Pointer> viewDescriptors(viewRegistry->GetViews());
std::vector<berry::IViewPart::Pointer> viewParts(page->GetViews());
std::sort(viewDescriptors.begin(), viewDescriptors.end(), compareViews);
-
+ QStandardItem* emptyItem = new QStandardItem();
+ emptyItem->setFlags(Qt::ItemIsEnabled);
+ treeRootItem->appendRow(emptyItem);
std::vector<std::string> viewExcludeList = berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetViewExcludeList();
QStandardItem* viewRootItem = new QStandardItem(QIcon(),"Views");
+ viewRootItem->setFont(QFont("", 12, QFont::Normal));
viewRootItem->setEditable(false);
treeRootItem->appendRow(viewRootItem);
categoryItems.clear();
QStandardItem* noCategoryItem = new QStandardItem(QIcon(),"Miscellaneous");
noCategoryItem->setEditable(false);
+ noCategoryItem->setFont(QFont("", 12, QFont::Normal));
for (unsigned int i = 0; i < viewDescriptors.size(); ++i)
{
berry::IViewDescriptor::Pointer v = viewDescriptors[i];
bool skipView = false;
for(unsigned int e=0; e<viewExcludeList.size(); e++)
if(viewExcludeList.at(e)==v->GetId())
{
skipView = true;
break;
}
if (skipView)
continue;
std::vector<std::string> catPath = v->GetCategoryPath();
QIcon* icon = static_cast<QIcon*>(v->GetImageDescriptor()->CreateImage());
mitk::QtViewItem* vItem = new mitk::QtViewItem(*icon, QString::fromStdString(v->GetLabel()));
vItem->m_View = v;
vItem->setToolTip(v->GetDescription().c_str());
vItem->m_Description = QString::fromStdString(v->GetDescription());
std::vector<std::string> keylist = v->GetKeywordReferences();
vItem->m_Tags = keywordRegistry.GetKeywords(keylist);
vItem->setEditable(false);
for (unsigned int i=0; i<viewParts.size(); i++)
if(viewParts[i]->GetPartName()==v->GetLabel())
{
QFont font; font.setBold(true);
vItem->setFont(font);
break;
}
if (catPath.empty())
noCategoryItem->appendRow(vItem);
else
{
QStandardItem* categoryItem = NULL;
for (unsigned int c=0; c<categoryItems.size(); c++)
if (categoryItems.at(c)->text().toStdString() == catPath.front())
{
categoryItem = categoryItems.at(c);
break;
}
if (categoryItem==NULL)
{
categoryItem = new QStandardItem(QIcon(),catPath.front().c_str());
categoryItems.push_back(categoryItem);
}
categoryItem->setEditable(false);
categoryItem->appendRow(vItem);
+ categoryItem->setFont(QFont("", 12, QFont::Normal));
}
}
std::sort(categoryItems.begin(), categoryItems.end(), compareQStandardItems);
for (unsigned int i=0; i<categoryItems.size(); i++)
viewRootItem->appendRow(categoryItems.at(i));
if (noCategoryItem->hasChildren())
viewRootItem->appendRow(noCategoryItem);
m_Controls.m_PluginTreeView->expandAll();
return true;
}
void QmitkViewNavigatorWidget::FilterChanged()
{
QString filterString = m_Controls.lineEdit->text();
// if (filterString.size() > 0 )
m_Controls.m_PluginTreeView->expandAll();
// else
// m_Controls.m_PluginTreeView->collapseAll();
// QRegExp::PatternSyntax syntax = QRegExp::RegExp;
Qt::CaseSensitivity caseSensitivity = Qt::CaseInsensitive;
QString strPattern = "^*" + filterString;
QRegExp regExp(strPattern, caseSensitivity);
m_FilterProxyModel->setFilterRegExp(regExp);
}
void QmitkViewNavigatorWidget::ItemClicked(const QModelIndex &index)
{
QStandardItem* item = m_TreeModel->itemFromIndex(m_FilterProxyModel->mapToSource(index));
if ( dynamic_cast< mitk::QtPerspectiveItem* >(item) )
{
try
{
mitk::QtPerspectiveItem* pItem = dynamic_cast< mitk::QtPerspectiveItem* >(item);
berry::PlatformUI::GetWorkbench()->ShowPerspective( pItem->m_Perspective->GetId(), berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow() );
}
catch (...)
{
QMessageBox::critical(0, "Opening Perspective Failed", QString("The requested perspective could not be opened.\nSee the log for details."));
}
}
else if ( dynamic_cast< mitk::QtViewItem* >(item) )
{
berry::IWorkbenchPage::Pointer page = berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage();
if (page.IsNotNull())
{
try
{
mitk::QtViewItem* vItem = dynamic_cast< mitk::QtViewItem* >(item);
page->ShowView(vItem->m_View->GetId());
}
catch (berry::PartInitException e)
{
BERRY_ERROR << "Error: " << e.displayText() << std::endl;
}
}
}
}
void QmitkViewNavigatorWidget::AddPerspective()
{
QmitkNewPerspectiveDialog* dialog = new QmitkNewPerspectiveDialog( m_Parent );
int dialogReturnValue = dialog->exec();
if ( dialogReturnValue == QDialog::Rejected )
return;
berry::IPerspectiveRegistry* perspRegistry = berry::PlatformUI::GetWorkbench()->GetPerspectiveRegistry();
try
{
berry::IPerspectiveDescriptor::Pointer perspDesc;
perspDesc = perspRegistry->CreatePerspective(dialog->GetPerspectiveName().toStdString(), perspRegistry->FindPerspectiveWithId(perspRegistry->GetDefaultPerspective()));
berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->SetPerspective(perspDesc);
}
catch(...)
{
QMessageBox::warning(m_Parent, "Error", "Duplication of selected perspective failed. Please make sure the specified perspective name is not already in use!");
}
FillTreeList();
}
void QmitkViewNavigatorWidget::ClonePerspective()
{
if (m_RegisteredPerspective.IsNotNull())
{
QmitkNewPerspectiveDialog* dialog = new QmitkNewPerspectiveDialog( m_Parent );
QString defaultName(m_RegisteredPerspective->GetLabel().c_str());
defaultName.append(" Copy");
dialog->SetPerspectiveName(defaultName);
int dialogReturnValue = dialog->exec();
if ( dialogReturnValue == QDialog::Rejected )
return;
berry::IPerspectiveRegistry* perspRegistry = berry::PlatformUI::GetWorkbench()->GetPerspectiveRegistry();
try
{
berry::IPerspectiveDescriptor::Pointer perspDesc = perspRegistry->ClonePerspective(dialog->GetPerspectiveName().toStdString(), dialog->GetPerspectiveName().toStdString(), m_RegisteredPerspective);
berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->SetPerspective(perspDesc);
}
catch(...)
{
QMessageBox::warning(m_Parent, "Error", "Duplication of selected perspective failed. Please make sure the specified perspective name is not already in use!");
}
FillTreeList();
}
}
void QmitkViewNavigatorWidget::ResetPerspective()
{
if (QMessageBox::Yes == QMessageBox(QMessageBox::Question, "Please confirm", "Do you really want to reset the current perspective?", QMessageBox::Yes|QMessageBox::No).exec())
berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->ResetPerspective();
}
void QmitkViewNavigatorWidget::DeletePerspective()
{
if (m_RegisteredPerspective.IsNotNull())
{
QString question = "Do you really want to remove the perspective '";
question.append(m_RegisteredPerspective->GetLabel().c_str());
question.append("'?");
if (QMessageBox::Yes == QMessageBox(QMessageBox::Question, "Please confirm", question, QMessageBox::Yes|QMessageBox::No).exec())
{
if( m_RegisteredPerspective == berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->GetPerspective() )
{
berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->CloseCurrentPerspective(true, true);
}
berry::IPerspectiveRegistry* perspRegistry = berry::PlatformUI::GetWorkbench()->GetPerspectiveRegistry();
perspRegistry->DeletePerspective(m_RegisteredPerspective);
berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->RemovePerspective(m_RegisteredPerspective);
FillTreeList();
if (! berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->GetPerspective())
{
berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage()->Close();
}
}
}
}
void QmitkViewNavigatorWidget::ClosePerspective()
{
if (QMessageBox::Yes == QMessageBox(QMessageBox::Question, "Please confirm", "Do you really want to close the current perspective?", QMessageBox::Yes|QMessageBox::No).exec())
{
berry::IWorkbenchPage::Pointer page = berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage();
page->CloseCurrentPerspective(true, true);
// if ( page->GetPerspective().IsNull() )
// {
// berry::IPerspectiveRegistry* perspRegistry = berry::PlatformUI::GetWorkbench()->GetPerspectiveRegistry();
// berry::PlatformUI::GetWorkbench()->ShowPerspective( perspRegistry->GetDefaultPerspective(), berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow() );
// }
}
}
void QmitkViewNavigatorWidget::CloseAllPerspectives()
{
if (QMessageBox::Yes == QMessageBox(QMessageBox::Question, "Please confirm", "Do you really want to close all perspectives?", QMessageBox::Yes|QMessageBox::No).exec())
{
berry::IWorkbenchPage::Pointer page = berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow()->GetActivePage();
page->CloseAllPerspectives(true, true);
// berry::IPerspectiveRegistry* perspRegistry = berry::PlatformUI::GetWorkbench()->GetPerspectiveRegistry();
// berry::PlatformUI::GetWorkbench()->ShowPerspective( perspRegistry->GetDefaultPerspective(), berry::PlatformUI::GetWorkbench()->GetActiveWorkbenchWindow() );
}
}
void QmitkViewNavigatorWidget::ExpandAll()
{
m_Controls.m_PluginTreeView->expandAll();
}
void QmitkViewNavigatorWidget::CollapseAll()
{
m_Controls.m_PluginTreeView->collapseAll();
}
void QmitkViewNavigatorWidget::CustomMenuRequested(QPoint pos)
{
QModelIndex index = m_Controls.m_PluginTreeView->indexAt(pos);
QStandardItem* item = m_TreeModel->itemFromIndex(m_FilterProxyModel->mapToSource(index));
if (m_ContextMenu==NULL)
return;
m_ContextMenu->clear();
m_RegisteredPerspective = NULL;
QAction* expandAction = new QAction("Expand tree", this);
m_ContextMenu->addAction(expandAction);
connect(expandAction, SIGNAL(triggered()), SLOT(ExpandAll()));
QAction* collapseAction = new QAction("Collapse tree", this);
m_ContextMenu->addAction(collapseAction);
connect(collapseAction, SIGNAL(triggered()), SLOT(CollapseAll()));
m_ContextMenu->addSeparator();
if ( item!=NULL && dynamic_cast< mitk::QtPerspectiveItem* >(item) )
{
m_RegisteredPerspective = dynamic_cast< mitk::QtPerspectiveItem* >(item)->m_Perspective;
//m_ContextMenu->addSeparator();
QAction* cloneAction = new QAction("Duplicate perspective", this);
m_ContextMenu->addAction(cloneAction);
connect(cloneAction, SIGNAL(triggered()), SLOT(ClonePerspective()));
if (!m_RegisteredPerspective->IsPredefined())
{
QAction* deleteAction = new QAction("Remove perspective", this);
m_ContextMenu->addAction(deleteAction);
connect(deleteAction, SIGNAL(triggered()), SLOT(DeletePerspective()));
}
m_ContextMenu->addSeparator();
}
QAction* resetAction = new QAction("Reset current perspective", this);
m_ContextMenu->addAction(resetAction);
connect(resetAction, SIGNAL(triggered()), SLOT(ResetPerspective()));
QAction* closeAction = new QAction("Close current perspective", this);
m_ContextMenu->addAction(closeAction);
connect(closeAction, SIGNAL(triggered()), SLOT(ClosePerspective()));
m_ContextMenu->addSeparator();
QAction* closeAllAction = new QAction("Close all perspectives", this);
m_ContextMenu->addAction(closeAllAction);
connect(closeAllAction, SIGNAL(triggered()), SLOT(CloseAllPerspectives()));
m_ContextMenu->popup(m_Controls.m_PluginTreeView->viewport()->mapToGlobal(pos));
}
diff --git a/Plugins/org.mitk.gui.qt.viewnavigator/src/internal/org_mitk_gui_qt_viewnavigator_Activator.cpp b/Plugins/org.mitk.gui.qt.viewnavigator/src/internal/org_mitk_gui_qt_viewnavigator_Activator.cpp
index 50a638f6f0..d4dfcaa33e 100644
--- a/Plugins/org.mitk.gui.qt.viewnavigator/src/internal/org_mitk_gui_qt_viewnavigator_Activator.cpp
+++ b/Plugins/org.mitk.gui.qt.viewnavigator/src/internal/org_mitk_gui_qt_viewnavigator_Activator.cpp
@@ -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.
===================================================================*/
#include "org_mitk_gui_qt_viewnavigator_Activator.h"
#include <QtPlugin>
#include "ViewNavigatorView.h"
namespace mitk {
void org_mitk_gui_qt_viewnavigator_Activator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(ViewNavigatorView, context)
}
void org_mitk_gui_qt_viewnavigator_Activator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_viewnavigator, mitk::org_mitk_gui_qt_viewnavigator_Activator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_viewnavigator, mitk::org_mitk_gui_qt_viewnavigator_Activator)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.viewnavigator/src/internal/org_mitk_gui_qt_viewnavigator_Activator.h b/Plugins/org.mitk.gui.qt.viewnavigator/src/internal/org_mitk_gui_qt_viewnavigator_Activator.h
index 67ebc8166a..8f0d1acc9a 100644
--- a/Plugins/org.mitk.gui.qt.viewnavigator/src/internal/org_mitk_gui_qt_viewnavigator_Activator.h
+++ b/Plugins/org.mitk.gui.qt.viewnavigator/src/internal/org_mitk_gui_qt_viewnavigator_Activator.h
@@ -1,40 +1,43 @@
/*===================================================================
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 org_mitk_gui_qt_viewnavigator_Activator_h
#define org_mitk_gui_qt_viewnavigator_Activator_h
#include <ctkPluginActivator.h>
namespace mitk {
class org_mitk_gui_qt_viewnavigator_Activator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_viewnavigator")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
}; // org_mitk_gui_qt_viewnavigator_Activator
}
#endif // org_mitk_gui_qt_viewnavigator_Activator_h
diff --git a/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/QmitkVolumeVisualizationView.cpp b/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/QmitkVolumeVisualizationView.cpp
index 3fd2a7b691..e7ae864f41 100755
--- a/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/QmitkVolumeVisualizationView.cpp
+++ b/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/QmitkVolumeVisualizationView.cpp
@@ -1,351 +1,348 @@
/*===================================================================
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 "QmitkVolumeVisualizationView.h"
#include <QComboBox>
#include <berryISelectionProvider.h>
#include <berryISelectionService.h>
#include <berryIWorkbenchWindow.h>
//#include <berryISelectionService.h>
#include <mitkDataNodeObject.h>
#include <mitkProperties.h>
#include <mitkNodePredicateDataType.h>
#include <mitkTransferFunction.h>
#include <mitkTransferFunctionProperty.h>
#include <mitkTransferFunctionInitializer.h>
#include "mitkHistogramGenerator.h"
#include "QmitkPiecewiseFunctionCanvas.h"
#include "QmitkColorTransferFunctionCanvas.h"
#include "mitkBaseRenderer.h"
#include "mitkVtkVolumeRenderingProperty.h"
#include <mitkIRenderingManager.h>
#include <QToolTip>
-#include <qxtspanslider.h>
const std::string QmitkVolumeVisualizationView::VIEW_ID =
"org.mitk.views.volumevisualization";
enum RenderMode
{
RM_CPU_COMPOSITE_RAYCAST = 0,
RM_CPU_MIP_RAYCAST = 1,
RM_GPU_COMPOSITE_SLICING = 2,
RM_GPU_COMPOSITE_RAYCAST = 3,
RM_GPU_MIP_RAYCAST = 4
};
QmitkVolumeVisualizationView::QmitkVolumeVisualizationView()
: QmitkAbstractView(),
m_Controls(NULL)
{
}
QmitkVolumeVisualizationView::~QmitkVolumeVisualizationView()
{
}
void QmitkVolumeVisualizationView::CreateQtPartControl(QWidget* parent)
{
if (!m_Controls)
{
m_Controls = new Ui::QmitkVolumeVisualizationViewControls;
m_Controls->setupUi(parent);
- m_Controls->m_TransferFunctionWidget->SetIntegerMode(true);
-
// Fill the tf presets in the generator widget
std::vector<std::string> names;
mitk::TransferFunctionInitializer::GetPresetNames(names);
for (std::vector<std::string>::const_iterator it = names.begin();
it != names.end(); ++it)
{
m_Controls->m_TransferFunctionGeneratorWidget->AddPreset(QString::fromStdString(*it));
}
m_Controls->m_RenderMode->addItem("CPU raycast");
m_Controls->m_RenderMode->addItem("CPU MIP raycast");
m_Controls->m_RenderMode->addItem("GPU slicing");
// Only with VTK 5.6 or above
#if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) ))
m_Controls->m_RenderMode->addItem("GPU raycast");
m_Controls->m_RenderMode->addItem("GPU MIP raycast");
#endif
connect( m_Controls->m_EnableRenderingCB, SIGNAL( toggled(bool) ),this, SLOT( OnEnableRendering(bool) ));
connect( m_Controls->m_EnableLOD, SIGNAL( toggled(bool) ),this, SLOT( OnEnableLOD(bool) ));
connect( m_Controls->m_RenderMode, SIGNAL( activated(int) ),this, SLOT( OnRenderMode(int) ));
connect( m_Controls->m_TransferFunctionGeneratorWidget, SIGNAL( SignalUpdateCanvas( ) ), m_Controls->m_TransferFunctionWidget, SLOT( OnUpdateCanvas( ) ) );
connect( m_Controls->m_TransferFunctionGeneratorWidget, SIGNAL(SignalTransferFunctionModeChanged(int)), SLOT(OnMitkInternalPreset(int)));
m_Controls->m_EnableRenderingCB->setEnabled(false);
m_Controls->m_EnableLOD->setEnabled(false);
m_Controls->m_RenderMode->setEnabled(false);
m_Controls->m_TransferFunctionWidget->setEnabled(false);
m_Controls->m_TransferFunctionGeneratorWidget->setEnabled(false);
m_Controls->m_SelectedImageLabel->hide();
m_Controls->m_ErrorImageLabel->hide();
}
}
void QmitkVolumeVisualizationView::OnMitkInternalPreset( int mode )
{
if (m_SelectedNode.IsNull()) return;
mitk::DataNode::Pointer node(m_SelectedNode.GetPointer());
mitk::TransferFunctionProperty::Pointer transferFuncProp;
if (node->GetProperty(transferFuncProp, "TransferFunction"))
{
//first item is only information
if( --mode == -1 )
return;
// -- Creat new TransferFunction
mitk::TransferFunctionInitializer::Pointer tfInit = mitk::TransferFunctionInitializer::New(transferFuncProp->GetValue());
tfInit->SetTransferFunctionMode(mode);
this->GetRenderWindowPart()->GetRenderingManager()->RequestUpdateAll();
m_Controls->m_TransferFunctionWidget->OnUpdateCanvas();
}
}
void QmitkVolumeVisualizationView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/, const QList<mitk::DataNode::Pointer>& nodes)
{
bool weHadAnImageButItsNotThreeDeeOrFourDee = false;
mitk::DataNode::Pointer node;
foreach (mitk::DataNode::Pointer currentNode, nodes)
{
if( currentNode.IsNotNull() && dynamic_cast<mitk::Image*>(currentNode->GetData()) )
{
if( dynamic_cast<mitk::Image*>(currentNode->GetData())->GetDimension()>=3 )
{
if (node.IsNull())
{
node = currentNode;
}
}
else
{
weHadAnImageButItsNotThreeDeeOrFourDee = true;
}
}
}
if( node.IsNotNull() )
{
m_Controls->m_NoSelectedImageLabel->hide();
m_Controls->m_ErrorImageLabel->hide();
m_Controls->m_SelectedImageLabel->show();
std::string infoText;
if (node->GetName().empty())
infoText = std::string("Selected Image: [currently selected image has no name]");
else
infoText = std::string("Selected Image: ") + node->GetName();
m_Controls->m_SelectedImageLabel->setText( QString( infoText.c_str() ) );
m_SelectedNode = node;
}
else
{
if(weHadAnImageButItsNotThreeDeeOrFourDee)
{
m_Controls->m_NoSelectedImageLabel->hide();
m_Controls->m_ErrorImageLabel->show();
std::string infoText;
infoText = std::string("only 3D or 4D images are supported");
m_Controls->m_ErrorImageLabel->setText( QString( infoText.c_str() ) );
}
else
{
m_Controls->m_SelectedImageLabel->hide();
m_Controls->m_ErrorImageLabel->hide();
m_Controls->m_NoSelectedImageLabel->show();
}
m_SelectedNode = 0;
}
UpdateInterface();
}
void QmitkVolumeVisualizationView::UpdateInterface()
{
if(m_SelectedNode.IsNull())
{
// turnoff all
m_Controls->m_EnableRenderingCB->setChecked(false);
m_Controls->m_EnableRenderingCB->setEnabled(false);
m_Controls->m_EnableLOD->setChecked(false);
m_Controls->m_EnableLOD->setEnabled(false);
m_Controls->m_RenderMode->setCurrentIndex(0);
m_Controls->m_RenderMode->setEnabled(false);
m_Controls->m_TransferFunctionWidget->SetDataNode(0);
m_Controls->m_TransferFunctionWidget->setEnabled(false);
m_Controls->m_TransferFunctionGeneratorWidget->SetDataNode(0);
m_Controls->m_TransferFunctionGeneratorWidget->setEnabled(false);
return;
}
bool enabled = false;
m_SelectedNode->GetBoolProperty("volumerendering",enabled);
m_Controls->m_EnableRenderingCB->setEnabled(true);
m_Controls->m_EnableRenderingCB->setChecked(enabled);
if(!enabled)
{
// turnoff all except volumerendering checkbox
m_Controls->m_EnableLOD->setChecked(false);
m_Controls->m_EnableLOD->setEnabled(false);
m_Controls->m_RenderMode->setCurrentIndex(0);
m_Controls->m_RenderMode->setEnabled(false);
m_Controls->m_TransferFunctionWidget->SetDataNode(0);
m_Controls->m_TransferFunctionWidget->setEnabled(false);
m_Controls->m_TransferFunctionGeneratorWidget->SetDataNode(0);
m_Controls->m_TransferFunctionGeneratorWidget->setEnabled(false);
return;
}
// otherwise we can activate em all
enabled = false;
m_SelectedNode->GetBoolProperty("volumerendering.uselod",enabled);
m_Controls->m_EnableLOD->setEnabled(true);
m_Controls->m_EnableLOD->setChecked(enabled);
m_Controls->m_RenderMode->setEnabled(true);
// Determine Combo Box mode
{
bool usegpu=false;
bool useray=false;
bool usemip=false;
m_SelectedNode->GetBoolProperty("volumerendering.usegpu",usegpu);
// Only with VTK 5.6 or above
#if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) ))
m_SelectedNode->GetBoolProperty("volumerendering.useray",useray);
#endif
m_SelectedNode->GetBoolProperty("volumerendering.usemip",usemip);
int mode = 0;
if(useray)
{
if(usemip)
mode=RM_GPU_MIP_RAYCAST;
else
mode=RM_GPU_COMPOSITE_RAYCAST;
}
else if(usegpu)
mode=RM_GPU_COMPOSITE_SLICING;
else
{
if(usemip)
mode=RM_CPU_MIP_RAYCAST;
else
mode=RM_CPU_COMPOSITE_RAYCAST;
}
m_Controls->m_RenderMode->setCurrentIndex(mode);
}
m_Controls->m_TransferFunctionWidget->SetDataNode(m_SelectedNode);
m_Controls->m_TransferFunctionWidget->setEnabled(true);
m_Controls->m_TransferFunctionGeneratorWidget->SetDataNode(m_SelectedNode);
m_Controls->m_TransferFunctionGeneratorWidget->setEnabled(true);
}
void QmitkVolumeVisualizationView::OnEnableRendering(bool state)
{
if(m_SelectedNode.IsNull())
return;
m_SelectedNode->SetProperty("volumerendering",mitk::BoolProperty::New(state));
UpdateInterface();
this->GetRenderWindowPart()->GetRenderingManager()->RequestUpdateAll();
}
void QmitkVolumeVisualizationView::OnEnableLOD(bool state)
{
if(m_SelectedNode.IsNull())
return;
m_SelectedNode->SetProperty("volumerendering.uselod",mitk::BoolProperty::New(state));
this->GetRenderWindowPart()->GetRenderingManager()->RequestUpdateAll();
}
void QmitkVolumeVisualizationView::OnRenderMode(int mode)
{
if(m_SelectedNode.IsNull())
return;
bool usegpu=mode==RM_GPU_COMPOSITE_SLICING;
// Only with VTK 5.6 or above
#if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) ))
bool useray=(mode==RM_GPU_COMPOSITE_RAYCAST)||(mode==RM_GPU_MIP_RAYCAST);
#endif
bool usemip=(mode==RM_GPU_MIP_RAYCAST)||(mode==RM_CPU_MIP_RAYCAST);
m_SelectedNode->SetProperty("volumerendering.usegpu",mitk::BoolProperty::New(usegpu));
// Only with VTK 5.6 or above
#if ((VTK_MAJOR_VERSION > 5) || ((VTK_MAJOR_VERSION==5) && (VTK_MINOR_VERSION>=6) ))
m_SelectedNode->SetProperty("volumerendering.useray",mitk::BoolProperty::New(useray));
#endif
m_SelectedNode->SetProperty("volumerendering.usemip",mitk::BoolProperty::New(usemip));
this->GetRenderWindowPart()->GetRenderingManager()->RequestUpdateAll();
}
void QmitkVolumeVisualizationView::SetFocus()
{
}
void QmitkVolumeVisualizationView::NodeRemoved(const mitk::DataNode* node)
{
if(m_SelectedNode == node)
{
m_SelectedNode=0;
m_Controls->m_SelectedImageLabel->hide();
m_Controls->m_ErrorImageLabel->hide();
m_Controls->m_NoSelectedImageLabel->show();
UpdateInterface();
}
}
diff --git a/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/QmitkVolumeVisualizationViewControls.ui b/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/QmitkVolumeVisualizationViewControls.ui
index 5251781bd9..982bc0f0a9 100644
--- a/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/QmitkVolumeVisualizationViewControls.ui
+++ b/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/QmitkVolumeVisualizationViewControls.ui
@@ -1,331 +1,334 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QmitkVolumeVisualizationViewControls</class>
<widget class="QWidget" name="QmitkVolumeVisualizationViewControls">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
- <width>323</width>
+ <width>324</width>
<height>679</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="windowTitle">
<string>QmitkTemplate</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="m_ErrorImageLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="palette">
<palette>
<active>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>191</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Text">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>191</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="ButtonText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>191</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>191</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Text">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>191</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="ButtonText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>191</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>120</red>
<green>120</green>
<blue>120</blue>
</color>
</brush>
</colorrole>
<colorrole role="Text">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>120</red>
<green>120</green>
<blue>120</blue>
</color>
</brush>
</colorrole>
<colorrole role="ButtonText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>120</red>
<green>120</green>
<blue>120</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="m_NoSelectedImageLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="palette">
<palette>
<active>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>197</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Text">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>191</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="ButtonText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>189</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>197</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Text">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>191</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="ButtonText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>189</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>120</red>
<green>120</green>
<blue>120</blue>
</color>
</brush>
</colorrole>
<colorrole role="Text">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>120</red>
<green>120</green>
<blue>120</blue>
</color>
</brush>
</colorrole>
<colorrole role="ButtonText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>120</red>
<green>120</green>
<blue>120</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="text">
<string>Please select a volume image!</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="m_SelectedImageLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QCheckBox" name="m_EnableRenderingCB">
<property name="toolTip">
<string>Click this checkbox to enable volumerendering in the 3D view of the selected image.</string>
</property>
<property name="text">
<string>Volumerendering</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="m_EnableLOD">
<property name="toolTip">
<string>Level of detail (LOD) enables a fast but lower quality preview rendering to increase interactivity.</string>
</property>
<property name="text">
<string>LOD</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="m_RenderMode">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
+ <property name="toolTip">
+ <string>Select render mode</string>
+ </property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QmitkTransferFunctionGeneratorWidget" name="m_TransferFunctionGeneratorWidget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QmitkTransferFunctionWidget" name="m_TransferFunctionWidget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>QmitkTransferFunctionWidget</class>
<extends>QWidget</extends>
<header location="global">QmitkTransferFunctionWidget.h</header>
</customwidget>
<customwidget>
<class>QmitkTransferFunctionGeneratorWidget</class>
<extends>QWidget</extends>
<header location="global">QmitkTransferFunctionGeneratorWidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<includes>
<include location="local">QmitkDataStorageComboBox.h</include>
</includes>
<resources/>
<connections/>
</ui>
diff --git a/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/mitkPluginActivator.cpp b/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/mitkPluginActivator.cpp
index 4849b6a992..e7f3775b4d 100644
--- a/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/mitkPluginActivator.cpp
+++ b/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/mitkPluginActivator.cpp
@@ -1,36 +1,38 @@
/*===================================================================
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 "mitkPluginActivator.h"
#include <QtPlugin>
#include "QmitkVolumeVisualizationView.h"
namespace mitk {
void PluginActivator::start(ctkPluginContext* context)
{
BERRY_REGISTER_EXTENSION_CLASS(QmitkVolumeVisualizationView, context)
}
void PluginActivator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
}
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_volumevisualization, mitk::PluginActivator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_volumevisualization, mitk::PluginActivator)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/mitkPluginActivator.h b/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/mitkPluginActivator.h
index 12053e09e3..624ff6e49e 100644
--- a/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/mitkPluginActivator.h
+++ b/Plugins/org.mitk.gui.qt.volumevisualization/src/internal/mitkPluginActivator.h
@@ -1,39 +1,42 @@
/*===================================================================
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 MITKPLUGINACTIVATOR_H
#define MITKPLUGINACTIVATOR_H
#include <ctkPluginActivator.h>
#include <mitkExportMacros.h>
namespace mitk {
class MITK_LOCAL PluginActivator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_volumevisualization")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
}; // PluginActivator
}
#endif // MITKPLUGINACTIVATOR_H
diff --git a/Plugins/org.mitk.gui.qt.xnat/src/internal/org_mitk_gui_qt_xnatinterface_Activator.cpp b/Plugins/org.mitk.gui.qt.xnat/src/internal/org_mitk_gui_qt_xnatinterface_Activator.cpp
index 8996a9fa3e..989e9a3bf6 100644
--- a/Plugins/org.mitk.gui.qt.xnat/src/internal/org_mitk_gui_qt_xnatinterface_Activator.cpp
+++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/org_mitk_gui_qt_xnatinterface_Activator.cpp
@@ -1,71 +1,73 @@
/*===================================================================
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_xnatinterface_Activator.h"
#include <QtPlugin>
#include "QmitkXnatEditor.h"
#include "QmitkXnatTreeBrowserView.h"
#include "QmitkXnatConnectionPreferencePage.h"
#include <usGetModuleContext.h>
#include <usModuleInitialization.h>
US_INITIALIZE_MODULE
namespace mitk {
ctkPluginContext* org_mitk_gui_qt_xnatinterface_Activator::m_Context = 0;
us::ModuleContext* org_mitk_gui_qt_xnatinterface_Activator::m_ModuleContext = 0;
QmitkXnatSessionManager* org_mitk_gui_qt_xnatinterface_Activator::GetXnatSessionManager()
{
static QmitkXnatSessionManager manager;
return &manager;
}
ctkPluginContext* org_mitk_gui_qt_xnatinterface_Activator::GetContext()
{
return m_Context;
}
us::ModuleContext* org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()
{
return m_ModuleContext;
}
void org_mitk_gui_qt_xnatinterface_Activator::start(ctkPluginContext* context)
{
this->m_Context = context;
this->m_ModuleContext = us::GetModuleContext();
BERRY_REGISTER_EXTENSION_CLASS(QmitkXnatEditor, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkXnatTreeBrowserView, context)
BERRY_REGISTER_EXTENSION_CLASS(QmitkXnatConnectionPreferencePage, context)
}
void org_mitk_gui_qt_xnatinterface_Activator::stop(ctkPluginContext* context)
{
Q_UNUSED(context)
Q_UNUSED(us::GetModuleContext())
this->m_Context = 0;
this->m_ModuleContext = 0;
}
}
-Q_EXPORT_PLUGIN2(org_mitk_gui_qt_xnatinterface, mitk::org_mitk_gui_qt_xnatinterface_Activator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_gui_qt_xnatinterface, mitk::org_mitk_gui_qt_xnatinterface_Activator)
+#endif
diff --git a/Plugins/org.mitk.gui.qt.xnat/src/internal/org_mitk_gui_qt_xnatinterface_Activator.h b/Plugins/org.mitk.gui.qt.xnat/src/internal/org_mitk_gui_qt_xnatinterface_Activator.h
index 29b284430c..3e8a712cbe 100644
--- a/Plugins/org.mitk.gui.qt.xnat/src/internal/org_mitk_gui_qt_xnatinterface_Activator.h
+++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/org_mitk_gui_qt_xnatinterface_Activator.h
@@ -1,50 +1,53 @@
/*===================================================================
The Medical Imaging Interaction Toolkit (MITK)
Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.
This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.
See LICENSE.txt or http://www.mitk.org for details.
===================================================================*/
#ifndef org_mitk_gui_qt_xnatinterface_Activator_h
#define org_mitk_gui_qt_xnatinterface_Activator_h
#include <ctkPluginActivator.h>
#include "QmitkXnatSessionManager.h"
namespace mitk {
class org_mitk_gui_qt_xnatinterface_Activator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_gui_qt_xnatinterface")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
static QmitkXnatSessionManager* GetXnatSessionManager();
static ctkPluginContext* GetContext();
static us::ModuleContext* GetXnatModuleContext();
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
private:
static ctkPluginContext* m_Context;
static us::ModuleContext* m_ModuleContext;
}; // org_mitk_gui_qt_xnatinterface_Activator
}
#endif // org_mitk_gui_qt_xnatinterface_Activator_h
diff --git a/Plugins/org.mitk.planarfigure/src/internal/mitkPlanarFigureActivator.cpp b/Plugins/org.mitk.planarfigure/src/internal/mitkPlanarFigureActivator.cpp
index 5cb9e6022d..10486ec012 100644
--- a/Plugins/org.mitk.planarfigure/src/internal/mitkPlanarFigureActivator.cpp
+++ b/Plugins/org.mitk.planarfigure/src/internal/mitkPlanarFigureActivator.cpp
@@ -1,83 +1,85 @@
/*===================================================================
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 "mitkPlanarFigureActivator.h"
#include "mitkPlanarFigureObjectFactory.h"
#include "QmitkNodeDescriptorManager.h"
#include "mitkNodePredicateDataType.h"
#include "mitkNodePredicateProperty.h"
#include "mitkNodePredicateAnd.h"
#include <QtPlugin>
void
mitk::PlanarFigureActivator::start(ctkPluginContext* /*context*/)
{
QmitkNodeDescriptorManager* descriptorManager = QmitkNodeDescriptorManager::GetInstance();
// Adding "PlanarLine"
mitk::NodePredicateDataType::Pointer isPlanarLine = mitk::NodePredicateDataType::New("PlanarLine");
descriptorManager->AddDescriptor(new QmitkNodeDescriptor(QObject::tr("PlanarLine"), QString(":/QtWidgetsExt/PlanarLine_48.png"), isPlanarLine, descriptorManager));
// Adding "PlanarCircle"
mitk::NodePredicateDataType::Pointer isPlanarCircle = mitk::NodePredicateDataType::New("PlanarCircle");
descriptorManager->AddDescriptor(new QmitkNodeDescriptor(QObject::tr("PlanarCircle"), QString(":/QtWidgetsExt/PlanarCircle_48.png"), isPlanarCircle, descriptorManager));
// Adding "PlanarEllipse"
mitk::NodePredicateDataType::Pointer isPlanarEllipse = mitk::NodePredicateDataType::New("PlanarEllipse");
descriptorManager->AddDescriptor(new QmitkNodeDescriptor(QObject::tr("PlanarEllipse"), QString(":/QtWidgetsExt/PlanarEllipse_48.png"), isPlanarEllipse, descriptorManager));
// Adding "PlanarAngle"
mitk::NodePredicateDataType::Pointer isPlanarAngle = mitk::NodePredicateDataType::New("PlanarAngle");
descriptorManager->AddDescriptor(new QmitkNodeDescriptor(QObject::tr("PlanarAngle"), QString(":/QtWidgetsExt/PlanarAngle_48.png"), isPlanarAngle, descriptorManager));
// Adding "PlanarFourPointAngle"
mitk::NodePredicateDataType::Pointer isPlanarFourPointAngle = mitk::NodePredicateDataType::New("PlanarFourPointAngle");
descriptorManager->AddDescriptor(new QmitkNodeDescriptor(QObject::tr("PlanarFourPointAngle"), QString(":/QtWidgetsExt/PlanarFourPointAngle_48.png"), isPlanarFourPointAngle, descriptorManager));
// Adding "PlanarRectangle"
mitk::NodePredicateDataType::Pointer isPlanarRectangle = mitk::NodePredicateDataType::New("PlanarRectangle");
descriptorManager->AddDescriptor(new QmitkNodeDescriptor(QObject::tr("PlanarRectangle"), QString(":/QtWidgetsExt/PlanarRectangle_48.png"), isPlanarRectangle, descriptorManager));
// Adding "PlanarPolygon"
mitk::NodePredicateDataType::Pointer isPlanarPolygon = mitk::NodePredicateDataType::New("PlanarPolygon");
descriptorManager->AddDescriptor(new QmitkNodeDescriptor(QObject::tr("PlanarPolygon"), QString(":/QtWidgetsExt/PlanarPolygon_48.png"), isPlanarPolygon, descriptorManager));
// Adding "PlanarPath"
mitk::NodePredicateProperty::Pointer isNotClosedPolygon = mitk::NodePredicateProperty::New("ClosedPlanarPolygon", mitk::BoolProperty::New(false));
mitk::NodePredicateAnd::Pointer isPlanarPath = mitk::NodePredicateAnd::New(isNotClosedPolygon, isPlanarPolygon);
descriptorManager->AddDescriptor(new QmitkNodeDescriptor(QObject::tr("PlanarPath"), QString(":/QtWidgetsExt/PlanarPath_48.png"), isPlanarPath, descriptorManager));
// Adding "PlanarDoubleEllipse"
mitk::NodePredicateDataType::Pointer isPlanarDoubleEllipse = mitk::NodePredicateDataType::New("PlanarDoubleEllipse");
descriptorManager->AddDescriptor(new QmitkNodeDescriptor("PlanarDoubleEllipse", ":/QtWidgetsExt/PlanarDoubleEllipse_48.png", isPlanarDoubleEllipse, descriptorManager));
// Adding "PlanarBezierCurve"
mitk::NodePredicateDataType::Pointer isPlanarBezierCurve = mitk::NodePredicateDataType::New("PlanarBezierCurve");
descriptorManager->AddDescriptor(new QmitkNodeDescriptor("PlanarBezierCurve", ":/QtWidgetsExt/PlanarBezierCurve_48.png", isPlanarBezierCurve, descriptorManager));
// Adding "PlanarSubdivisionPolygon"
mitk::NodePredicateDataType::Pointer isPlanarSubdivisionPolygon = mitk::NodePredicateDataType::New("PlanarSubdivisionPolygon");
descriptorManager->AddDescriptor(new QmitkNodeDescriptor("PlanarSubdivisionPolygon", ":/QtWidgetsExt/PlanarSubdivisionPolygon_48.png", isPlanarSubdivisionPolygon, descriptorManager));
}
void
mitk::PlanarFigureActivator::stop(ctkPluginContext* /*context*/)
{
}
-Q_EXPORT_PLUGIN2(org_mitk_planarfigure, mitk::PlanarFigureActivator)
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_planarfigure, mitk::PlanarFigureActivator)
+#endif
diff --git a/Plugins/org.mitk.planarfigure/src/internal/mitkPlanarFigureActivator.h b/Plugins/org.mitk.planarfigure/src/internal/mitkPlanarFigureActivator.h
index c45556bf3c..49605698e8 100644
--- a/Plugins/org.mitk.planarfigure/src/internal/mitkPlanarFigureActivator.h
+++ b/Plugins/org.mitk.planarfigure/src/internal/mitkPlanarFigureActivator.h
@@ -1,52 +1,55 @@
/*===================================================================
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 MITKPLANARFIGUREACTIVATOR_H_
#define MITKPLANARFIGUREACTIVATOR_H_
#include <ctkPluginActivator.h>
namespace mitk
{
/**
* \ingroup org_mitk_planarfigure_internal
*
* \brief The plug-in activator for the planar figure module
*
* When the plug-in is started by the framework, it initialzes planar figure specific things.
*/
class PlanarFigureActivator :
public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_planarfigure")
+#endif
Q_INTERFACES(ctkPluginActivator)
public:
/**
* Registers sandbox core object factories.
*/
void start(ctkPluginContext* context);
void stop(ctkPluginContext* context);
};
}
#endif /* MITKPLANARFIGUREACTIVATOR_H_ */
diff --git a/Plugins/org.mitk.simulation/src/internal/org_mitk_simulation_Activator.cpp b/Plugins/org.mitk.simulation/src/internal/org_mitk_simulation_Activator.cpp
index 90895d08ff..1d74aa9eaa 100644
--- a/Plugins/org.mitk.simulation/src/internal/org_mitk_simulation_Activator.cpp
+++ b/Plugins/org.mitk.simulation/src/internal/org_mitk_simulation_Activator.cpp
@@ -1,107 +1,109 @@
/*===================================================================
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_simulation_Activator.h"
#include <mitkGetSimulationPreferences.h>
#include <mitkIPropertyFilters.h>
#include <mitkMeshMitkLoader.h>
#include <mitkNodePredicateDataType.h>
#include <mitkPropertyFilter.h>
#include <mitkSimulationObjectFactory.h>
#include <QmitkNodeDescriptorManager.h>
#include <QtPlugin>
#include <sofa/core/ObjectFactory.h>
#include <sofa/helper/system/PluginManager.h>
static void RegisterSofaClasses()
{
int MeshMitkLoaderClass = sofa::core::RegisterObject("").add<mitk::MeshMitkLoader>();
}
static void LoadSofaPlugins()
{
berry::IPreferences::Pointer preferences = mitk::GetSimulationPreferences();
if (preferences.IsNull())
return;
QString plugins = preferences->GetByteArray("plugins", "").c_str();
if (plugins.isEmpty())
return;
QStringList pluginList = plugins.split(';', QString::SkipEmptyParts);
QStringListIterator it(pluginList);
typedef sofa::helper::system::PluginManager PluginManager;
PluginManager& pluginManager = PluginManager::getInstance();
while (it.hasNext())
{
std::string plugin = it.next().toStdString();
std::ostringstream errlog;
pluginManager.loadPlugin(plugin, &errlog);
if (errlog.str().empty())
pluginManager.getPluginMap()[plugin].initExternalModule();
}
}
static void AddPropertyFilters()
{
mitk::IPropertyFilters* filters = mitk::org_mitk_simulation_Activator::GetService<mitk::IPropertyFilters>();
if (filters == NULL)
return;
mitk::PropertyFilter filter;
filter.AddEntry("layer", mitk::PropertyFilter::Blacklist);
filter.AddEntry("name", mitk::PropertyFilter::Blacklist);
filter.AddEntry("path", mitk::PropertyFilter::Blacklist);
filter.AddEntry("selected", mitk::PropertyFilter::Blacklist);
filter.AddEntry("visible", mitk::PropertyFilter::Blacklist);
filters->AddFilter(filter, "Simulation");
}
ctkPluginContext* mitk::org_mitk_simulation_Activator::Context = NULL;
void mitk::org_mitk_simulation_Activator::start(ctkPluginContext* context)
{
Context = context;
RegisterSimulationObjectFactory();
RegisterSofaClasses();
LoadSofaPlugins();
AddPropertyFilters();
QmitkNodeDescriptorManager* nodeDescriptorManager = QmitkNodeDescriptorManager::GetInstance();
if (nodeDescriptorManager != NULL)
{
mitk::NodePredicateDataType::Pointer simulationPredicate = mitk::NodePredicateDataType::New("Simulation");
nodeDescriptorManager->AddDescriptor(new QmitkNodeDescriptor("Simulation", ":/Simulation/SOFAIcon.png", simulationPredicate, nodeDescriptorManager));
}
}
void mitk::org_mitk_simulation_Activator::stop(ctkPluginContext*)
{
Context = NULL;
}
-Q_EXPORT_PLUGIN2(org_mitk_simulation, mitk::org_mitk_simulation_Activator);
+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
+ Q_EXPORT_PLUGIN2(org_mitk_simulation, mitk::org_mitk_simulation_Activator)
+#endif
diff --git a/Plugins/org.mitk.simulation/src/internal/org_mitk_simulation_Activator.h b/Plugins/org.mitk.simulation/src/internal/org_mitk_simulation_Activator.h
index dd1d1ef36c..723654d737 100644
--- a/Plugins/org.mitk.simulation/src/internal/org_mitk_simulation_Activator.h
+++ b/Plugins/org.mitk.simulation/src/internal/org_mitk_simulation_Activator.h
@@ -1,51 +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 org_mitk_simulation_Activator_h
#define org_mitk_simulation_Activator_h
#include <ctkPluginActivator.h>
namespace mitk
{
class org_mitk_simulation_Activator : public QObject, public ctkPluginActivator
{
Q_OBJECT
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ Q_PLUGIN_METADATA(IID "org_mitk_simulation")
+#endif
Q_INTERFACES(ctkPluginActivator);
public:
template <class T>
static T* GetService()
{
if (Context == NULL)
return NULL;
ctkServiceReference serviceReference = Context->getServiceReference<T>();
return serviceReference
? Context->getService<T>(serviceReference)
: NULL;
}
void start(ctkPluginContext* context);
void stop(ctkPluginContext*);
private:
static ctkPluginContext* Context;
};
}
#endif
diff --git a/SuperBuild.cmake b/SuperBuild.cmake
index 35829cba9e..ae6252490d 100644
--- a/SuperBuild.cmake
+++ b/SuperBuild.cmake
@@ -1,489 +1,487 @@
#-----------------------------------------------------------------------------
# Convenient macro allowing to download a file
#-----------------------------------------------------------------------------
macro(downloadFile url dest)
file(DOWNLOAD ${url} ${dest} STATUS status)
list(GET status 0 error_code)
list(GET status 1 error_msg)
if(error_code)
message(FATAL_ERROR "error: Failed to download ${url} - ${error_msg}")
endif()
endmacro()
#-----------------------------------------------------------------------------
# MITK Prerequisites
#-----------------------------------------------------------------------------
if(UNIX AND NOT APPLE)
include(mitkFunctionCheckPackageHeader)
# Check for libxt-dev
mitkFunctionCheckPackageHeader(StringDefs.h libxt-dev /usr/include/X11/)
# Check for libtiff4-dev
mitkFunctionCheckPackageHeader(tiff.h libtiff4-dev)
# Check for libwrap0-dev
mitkFunctionCheckPackageHeader(tcpd.h libwrap0-dev)
endif()
#-----------------------------------------------------------------------------
# Qt options for external projects and MITK
#-----------------------------------------------------------------------------
if(MITK_USE_QT)
set(qt_project_args -DDESIRED_QT_VERSION:STRING=${DESIRED_QT_VERSION})
else()
set(qt_project_args )
endif()
if(MITK_USE_Qt4)
list(APPEND qt_project_args
-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE} )
endif()
#-----------------------------------------------------------------------------
# ExternalProjects
#-----------------------------------------------------------------------------
set(external_projects
ZLIB
Python
Numpy
tinyxml
GLUT
ANN
CppUnit
GLEW
VTK
ACVD
GDCM
OpenCV
Poco
ITK
Boost
DCMTK
CTK
SOFA
MITKData
Qwt
PCRE
Swig
SimpleITK
Eigen
)
-# Qxt supports Qt5. We need to also support it in QxtCMakeLists.txt
-#if(MITK_USE_Qt4)
- list(APPEND external_projects Qxt)
-#endif()
-
# These are "hard" dependencies and always set to ON
set(MITK_USE_tinyxml 1)
set(MITK_USE_ANN 1)
set(MITK_USE_Eigen 1)
set(MITK_USE_GLEW 1)
set(MITK_USE_GDCM 1)
set(MITK_USE_ITK 1)
set(MITK_USE_VTK 1)
# Semi-hard dependencies, enabled by user-controlled variables
if(MITK_USE_QT)
set(MITK_USE_Qwt 1)
- #if(MITK_USE_Qt4)
- set(MITK_USE_Qxt 1) #TODO: Check how Qxt builds with Qt 5
- #endif()
endif()
if(MITK_USE_SOFA)
set(MITK_USE_GLUT 1)
endif()
if(NOT MITK_USE_SYSTEM_PYTHON)
set(MITK_USE_ZLIB 1)
endif()
if(MITK_USE_SimpleITK OR MITK_USE_Python)
set(MITK_USE_SWIG 1)
if(UNIX)
set(MITK_USE_PCRE 1)
endif()
endif()
# A list of "nice" external projects, playing well together with CMake
set(nice_external_projects ${external_projects})
list(REMOVE_ITEM nice_external_projects Boost)
foreach(proj ${nice_external_projects})
if(MITK_USE_${proj})
set(EXTERNAL_${proj}_DIR "${${proj}_DIR}" CACHE PATH "Path to ${proj} build directory")
mark_as_advanced(EXTERNAL_${proj}_DIR)
if(EXTERNAL_${proj}_DIR)
set(${proj}_DIR ${EXTERNAL_${proj}_DIR})
endif()
endif()
endforeach()
if(MITK_USE_Boost)
set(EXTERNAL_BOOST_ROOT "${BOOST_ROOT}" CACHE PATH "Path to Boost directory")
mark_as_advanced(EXTERNAL_BOOST_ROOT)
if(EXTERNAL_BOOST_ROOT)
set(BOOST_ROOT ${EXTERNAL_BOOST_ROOT})
endif()
endif()
# Setup file for setting custom ctest vars
configure_file(
CMake/SuperbuildCTestCustom.cmake.in
${MITK_BINARY_DIR}/CTestCustom.cmake
@ONLY
)
if(BUILD_TESTING)
set(EXTERNAL_MITK_DATA_DIR "${MITK_DATA_DIR}" CACHE PATH "Path to the MITK data directory")
mark_as_advanced(EXTERNAL_MITK_DATA_DIR)
if(EXTERNAL_MITK_DATA_DIR)
set(MITK_DATA_DIR ${EXTERNAL_MITK_DATA_DIR})
endif()
endif()
# Look for git early on, if needed
if((BUILD_TESTING AND NOT EXTERNAL_MITK_DATA_DIR) OR
(MITK_USE_CTK AND NOT EXTERNAL_CTK_DIR))
find_package(Git REQUIRED)
endif()
#-----------------------------------------------------------------------------
# External project settings
#-----------------------------------------------------------------------------
include(ExternalProject)
set(ep_base "${CMAKE_BINARY_DIR}/CMakeExternals")
set_property(DIRECTORY PROPERTY EP_BASE ${ep_base})
set(ep_install_dir ${ep_base}/Install)
#set(ep_build_dir ${ep_base}/Build)
set(ep_source_dir ${ep_base}/Source)
#set(ep_parallelism_level)
set(ep_build_shared_libs ON)
set(ep_build_testing OFF)
if(NOT MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL)
set(MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL http://mitk.org/download/thirdparty)
endif()
# Compute -G arg for configuring external projects with the same CMake generator:
if(CMAKE_EXTRA_GENERATOR)
set(gen "${CMAKE_EXTRA_GENERATOR} - ${CMAKE_GENERATOR}")
else()
set(gen "${CMAKE_GENERATOR}")
endif()
# Use this value where semi-colons are needed in ep_add args:
set(sep "^^")
##
if(MSVC_VERSION)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /bigobj /MP")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj /MP")
endif()
set(ep_common_args
-DBUILD_TESTING:BOOL=${ep_build_testing}
-DCMAKE_INSTALL_PREFIX:PATH=${ep_install_dir}
-DCMAKE_PREFIX_PATH:PATH=${CMAKE_PREFIX_PATH}
-DBUILD_SHARED_LIBS:BOOL=ON
-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
-DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER}
-DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER}
-DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS}
-DCMAKE_CXX_FLAGS:STRING=${CMAKE_CXX_FLAGS}
#debug flags
-DCMAKE_CXX_FLAGS_DEBUG:STRING=${CMAKE_CXX_FLAGS_DEBUG}
-DCMAKE_C_FLAGS_DEBUG:STRING=${CMAKE_C_FLAGS_DEBUG}
#release flags
-DCMAKE_CXX_FLAGS_RELEASE:STRING=${CMAKE_CXX_FLAGS_RELEASE}
-DCMAKE_C_FLAGS_RELEASE:STRING=${CMAKE_C_FLAGS_RELEASE}
#relwithdebinfo
-DCMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=${CMAKE_CXX_FLAGS_RELWITHDEBINFO}
-DCMAKE_C_FLAGS_RELWITHDEBINFO:STRING=${CMAKE_C_FLAGS_RELWITHDEBINFO}
#link flags
-DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_EXE_LINKER_FLAGS}
-DCMAKE_SHARED_LINKER_FLAGS:STRING=${CMAKE_SHARED_LINKER_FLAGS}
-DCMAKE_MODULE_LINKER_FLAGS:STRING=${CMAKE_MODULE_LINKER_FLAGS}
)
# Pass the CMAKE_OSX variables to external projects
if(APPLE)
set(MAC_OSX_ARCHITECTURE_ARGS
-DCMAKE_OSX_ARCHITECTURES:PATH=${CMAKE_OSX_ARCHITECTURES}
-DCMAKE_OSX_DEPLOYMENT_TARGET:PATH=${CMAKE_OSX_DEPLOYMENT_TARGET}
-DCMAKE_OSX_SYSROOT:PATH=${CMAKE_OSX_SYSROOT}
)
set(ep_common_args
${MAC_OSX_ARCHITECTURE_ARGS}
${ep_common_args}
)
endif()
# Include external projects
foreach(p ${external_projects})
include(CMakeExternals/${p}.cmake)
endforeach()
#-----------------------------------------------------------------------------
# Set superbuild boolean args
#-----------------------------------------------------------------------------
set(mitk_cmake_boolean_args
BUILD_SHARED_LIBS
WITH_COVERAGE
BUILD_TESTING
MITK_USE_QT
MITK_BUILD_ALL_PLUGINS
MITK_BUILD_ALL_APPS
MITK_BUILD_TUTORIAL # Deprecated. Use MITK_BUILD_EXAMPLES instead
MITK_BUILD_EXAMPLES
MITK_USE_ACVD
MITK_USE_CppUnit
MITK_USE_GLEW
MITK_USE_Boost
MITK_USE_SYSTEM_Boost
MITK_USE_BLUEBERRY
MITK_USE_CTK
MITK_USE_DCMTK
MITK_USE_OpenCV
MITK_USE_Poco
MITK_USE_SOFA
MITK_USE_Python
MITK_USE_OpenCL
MITK_ENABLE_PIC_READER
)
#-----------------------------------------------------------------------------
# Create the final variable containing superbuild boolean args
#-----------------------------------------------------------------------------
set(mitk_superbuild_boolean_args)
foreach(mitk_cmake_arg ${mitk_cmake_boolean_args})
list(APPEND mitk_superbuild_boolean_args -D${mitk_cmake_arg}:BOOL=${${mitk_cmake_arg}})
endforeach()
if(MITK_BUILD_ALL_PLUGINS)
list(APPEND mitk_superbuild_boolean_args -DBLUEBERRY_BUILD_ALL_PLUGINS:BOOL=ON)
endif()
#-----------------------------------------------------------------------------
# MITK Utilities
#-----------------------------------------------------------------------------
set(proj MITK-Utilities)
ExternalProject_Add(${proj}
DOWNLOAD_COMMAND ""
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
DEPENDS
# Mandatory dependencies
${tinyxml_DEPENDS}
${ANN_DEPENDS}
${VTK_DEPENDS}
${ITK_DEPENDS}
# Optionnal dependencies
${ACVD_DEPENDS}
${CppUnit_DEPENDS}
${Eigen_DEPENDS}
${GLUT_DEPENDS}
${GLEW_DEPENDS}
${Boost_DEPENDS}
${CTK_DEPENDS}
${DCMTK_DEPENDS}
${OpenCV_DEPENDS}
${Poco_DEPENDS}
${SOFA_DEPENDS}
${MITK-Data_DEPENDS}
${Qwt_DEPENDS}
- ${Qxt_DEPENDS}
${ZLIB_DEPENDS}
${SimpleITK_DEPENDS}
${Numpy_DEPENDS}
)
#-----------------------------------------------------------------------------
# Additional MITK CXX/C Flags
#-----------------------------------------------------------------------------
set(MITK_ADDITIONAL_C_FLAGS "" CACHE STRING "Additional C Flags for MITK")
set(MITK_ADDITIONAL_C_FLAGS_RELEASE "" CACHE STRING "Additional Release C Flags for MITK")
set(MITK_ADDITIONAL_C_FLAGS_DEBUG "" CACHE STRING "Additional Debug C Flags for MITK")
mark_as_advanced(MITK_ADDITIONAL_C_FLAGS MITK_ADDITIONAL_C_FLAGS_DEBUG MITK_ADDITIONAL_C_FLAGS_RELEASE)
set(MITK_ADDITIONAL_CXX_FLAGS "" CACHE STRING "Additional CXX Flags for MITK")
set(MITK_ADDITIONAL_CXX_FLAGS_RELEASE "" CACHE STRING "Additional Release CXX Flags for MITK")
set(MITK_ADDITIONAL_CXX_FLAGS_DEBUG "" CACHE STRING "Additional Debug CXX Flags for MITK")
mark_as_advanced(MITK_ADDITIONAL_CXX_FLAGS MITK_ADDITIONAL_CXX_FLAGS_DEBUG MITK_ADDITIONAL_CXX_FLAGS_RELEASE)
set(MITK_ADDITIONAL_EXE_LINKER_FLAGS "" CACHE STRING "Additional exe linker flags for MITK")
set(MITK_ADDITIONAL_SHARED_LINKER_FLAGS "" CACHE STRING "Additional shared linker flags for MITK")
set(MITK_ADDITIONAL_MODULE_LINKER_FLAGS "" CACHE STRING "Additional module linker flags for MITK")
mark_as_advanced(MITK_ADDITIONAL_EXE_LINKER_FLAGS MITK_ADDITIONAL_SHARED_LINKER_FLAGS MITK_ADDITIONAL_MODULE_LINKER_FLAGS)
#-----------------------------------------------------------------------------
# MITK Configure
#-----------------------------------------------------------------------------
if(MITK_INITIAL_CACHE_FILE)
set(mitk_initial_cache_arg -C "${MITK_INITIAL_CACHE_FILE}")
endif()
set(mitk_optional_cache_args )
foreach(type RUNTIME ARCHIVE LIBRARY)
if(DEFINED CTK_PLUGIN_${type}_OUTPUT_DIRECTORY)
list(APPEND mitk_optional_cache_args -DCTK_PLUGIN_${type}_OUTPUT_DIRECTORY:PATH=${CTK_PLUGIN_${type}_OUTPUT_DIRECTORY})
endif()
endforeach()
# Optional python variables
if(MITK_USE_Python)
list(APPEND mitk_optional_cache_args
-DPYTHON_EXECUTABLE:FILEPATH=${PYTHON_EXECUTABLE}
-DPYTHON_INCLUDE_DIR:PATH=${PYTHON_INCLUDE_DIR}
-DPYTHON_LIBRARY:FILEPATH=${PYTHON_LIBRARY}
-DPYTHON_INCLUDE_DIR2:PATH=${PYTHON_INCLUDE_DIR2}
-DMITK_USE_SYSTEM_PYTHON:BOOL=${MITK_USE_SYSTEM_PYTHON}
-DMITK_BUILD_org.mitk.gui.qt.python:BOOL=ON
)
if( NOT MITK_USE_SYSTEM_PYTHON )
list(APPEND mitk_optional_cache_args
# Folders are needed to create an installer
-DPython_DIR:PATH=${Python_DIR}
-DNumpy_DIR:PATH=${Numpy_DIR}
)
endif()
endif()
+if(MITK_USE_QT)
+ if(DESIRED_QT_VERSION MATCHES "5")
+ list(APPEND mitk_optional_cache_args
+ -DQT5_INSTALL_PREFIX:PATH=${QT5_INSTALL_PREFIX}
+ )
+ endif()
+endif()
+
set(proj MITK-Configure)
ExternalProject_Add(${proj}
LIST_SEPARATOR ^^
DOWNLOAD_COMMAND ""
CMAKE_GENERATOR ${gen}
CMAKE_CACHE_ARGS
# --------------- Build options ----------------
-DBUILD_TESTING:BOOL=${ep_build_testing}
-DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_BINARY_DIR}/MITK-build/install
-DBUILD_SHARED_LIBS:BOOL=ON
-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
# --------------- Compile options ----------------
-DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER}
-DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER}
"-DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS} ${MITK_ADDITIONAL_C_FLAGS}"
"-DCMAKE_CXX_FLAGS:STRING=${CMAKE_CXX_FLAGS} ${MITK_ADDITIONAL_CXX_FLAGS}"
# debug flags
"-DCMAKE_CXX_FLAGS_DEBUG:STRING=${CMAKE_CXX_FLAGS_DEBUG} ${MITK_ADDITIONAL_CXX_FLAGS_DEBUG}"
"-DCMAKE_C_FLAGS_DEBUG:STRING=${CMAKE_C_FLAGS_DEBUG} ${MITK_ADDITIONAL_C_FLAGS_DEBUG}"
# release flags
"-DCMAKE_CXX_FLAGS_RELEASE:STRING=${CMAKE_CXX_FLAGS_RELEASE} ${MITK_ADDITIONAL_CXX_FLAGS_RELEASE}"
"-DCMAKE_C_FLAGS_RELEASE:STRING=${CMAKE_C_FLAGS_RELEASE} ${MITK_ADDITIONAL_C_FLAGS_RELEASE}"
# relwithdebinfo
-DCMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=${CMAKE_CXX_FLAGS_RELWITHDEBINFO}
-DCMAKE_C_FLAGS_RELWITHDEBINFO:STRING=${CMAKE_C_FLAGS_RELWITHDEBINFO}
# link flags
"-DCMAKE_EXE_LINKER_FLAGS:STRING=${CMAKE_EXE_LINKER_FLAGS} ${MITK_ADDITIONAL_EXE_LINKER_FLAGS}"
"-DCMAKE_SHARED_LINKER_FLAGS:STRING=${CMAKE_SHARED_LINKER_FLAGS} ${MITK_ADDITIONAL_SHARED_LINKER_FLAGS}"
"-DCMAKE_MODULE_LINKER_FLAGS:STRING=${CMAKE_MODULE_LINKER_FLAGS} ${MITK_ADDITIONAL_MODULE_LINKER_FLAGS}"
# Output directories
-DMITK_CMAKE_LIBRARY_OUTPUT_DIRECTORY:PATH=${MITK_CMAKE_LIBRARY_OUTPUT_DIRECTORY}
-DMITK_CMAKE_RUNTIME_OUTPUT_DIRECTORY:PATH=${MITK_CMAKE_RUNTIME_OUTPUT_DIRECTORY}
-DMITK_CMAKE_ARCHIVE_OUTPUT_DIRECTORY:PATH=${MITK_CMAKE_ARCHIVE_OUTPUT_DIRECTORY}
# ------------- Boolean build options --------------
${mitk_superbuild_boolean_args}
${mitk_optional_cache_args}
-DMITK_USE_SUPERBUILD:BOOL=OFF
-DMITK_BUILD_CONFIGURATION:STRING=${MITK_BUILD_CONFIGURATION}
-DCTEST_USE_LAUNCHERS:BOOL=${CTEST_USE_LAUNCHERS}
# ----------------- Miscellaneous ---------------
-DMITK_CTEST_SCRIPT_MODE:STRING=${MITK_CTEST_SCRIPT_MODE}
-DMITK_SUPERBUILD_BINARY_DIR:PATH=${MITK_BINARY_DIR}
-DMITK_MODULES_TO_BUILD:INTERNAL=${MITK_MODULES_TO_BUILD}
${qt_project_args}
-DMITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES:STRING=${MITK_ACCESSBYITK_INTEGRAL_PIXEL_TYPES}
-DMITK_ACCESSBYITK_FLOATING_PIXEL_TYPES:STRING=${MITK_ACCESSBYITK_FLOATING_PIXEL_TYPES}
-DMITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES:STRING=${MITK_ACCESSBYITK_COMPOSITE_PIXEL_TYPES}
-DMITK_ACCESSBYITK_VECTOR_PIXEL_TYPES:STRING=${MITK_ACCESSBYITK_VECTOR_PIXEL_TYPES}
-DMITK_ACCESSBYITK_DIMENSIONS:STRING=${MITK_ACCESSBYITK_DIMENSIONS}
# --------------- External project dirs ---------------
-DCppMicroServices_DIR:PATH=${CppMicroServices_DIR}
-DMITK_KWSTYLE_EXECUTABLE:FILEPATH=${MITK_KWSTYLE_EXECUTABLE}
-DCTK_DIR:PATH=${CTK_DIR}
-DDCMTK_DIR:PATH=${DCMTK_DIR}
-DEigen_DIR:PATH=${Eigen_DIR}
-Dtinyxml_DIR:PATH=${tinyxml_DIR}
-DGLUT_DIR:PATH=${GLUT_DIR}
-DGLEW_DIR:PATH=${GLEW_DIR}
-DANN_DIR:PATH=${ANN_DIR}
-DCppUnit_DIR:PATH=${CppUnit_DIR}
-DVTK_DIR:PATH=${VTK_DIR} # FindVTK expects VTK_DIR
-DITK_DIR:PATH=${ITK_DIR} # FindITK expects ITK_DIR
-DACVD_DIR:PATH=${ACVD_DIR}
-DOpenCV_DIR:PATH=${OpenCV_DIR}
-DPoco_DIR:PATH=${Poco_DIR}
-DSOFA_DIR:PATH=${SOFA_DIR}
-DGDCM_DIR:PATH=${GDCM_DIR}
-DBOOST_ROOT:PATH=${BOOST_ROOT}
-DMITK_USE_Boost_LIBRARIES:STRING=${MITK_USE_Boost_LIBRARIES}
-DMITK_DATA_DIR:PATH=${MITK_DATA_DIR}
-DQwt_DIR:PATH=${Qwt_DIR}
- -DQxt_DIR:PATH=${Qxt_DIR}
-DSimpleITK_DIR:PATH=${SimpleITK_DIR}
-DNumpy_DIR:PATH=${Numpy_DIR}
CMAKE_ARGS
${mitk_initial_cache_arg}
${MAC_OSX_ARCHITECTURE_ARGS}
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}
BINARY_DIR ${CMAKE_BINARY_DIR}/MITK-build
BUILD_COMMAND ""
INSTALL_COMMAND ""
DEPENDS
MITK-Utilities
)
#-----------------------------------------------------------------------------
# MITK
#-----------------------------------------------------------------------------
if(CMAKE_GENERATOR MATCHES ".*Makefiles.*")
set(mitk_build_cmd "$(MAKE)")
else()
set(mitk_build_cmd ${CMAKE_COMMAND} --build ${CMAKE_CURRENT_BINARY_DIR}/MITK-build --config ${CMAKE_CFG_INTDIR})
endif()
if(NOT DEFINED SUPERBUILD_EXCLUDE_MITKBUILD_TARGET OR NOT SUPERBUILD_EXCLUDE_MITKBUILD_TARGET)
set(MITKBUILD_TARGET_ALL_OPTION "ALL")
else()
set(MITKBUILD_TARGET_ALL_OPTION "")
endif()
add_custom_target(MITK-build ${MITKBUILD_TARGET_ALL_OPTION}
COMMAND ${mitk_build_cmd}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/MITK-build
DEPENDS MITK-Configure
)
#-----------------------------------------------------------------------------
# Custom target allowing to drive the build of the MITK project itself
#-----------------------------------------------------------------------------
add_custom_target(MITK
COMMAND ${mitk_build_cmd}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/MITK-build
)

File Metadata

Mime Type
application/octet-stream
Expires
Tue, May 21, 11:09 AM (1 d, 23 h)
Storage Engine
chunks
Storage Format
Chunks
Storage Handle
oXJ51mSDr.Ov
Default Alt Text
(4 MB)

Event Timeline