]> Creatis software - cpPlugins.git/commitdiff
...
authorLeonardo Flórez-Valencia <florez-l@javeriana.edu.co>
Tue, 26 Sep 2017 20:47:04 +0000 (15:47 -0500)
committerLeonardo Flórez-Valencia <florez-l@javeriana.edu.co>
Tue, 26 Sep 2017 20:47:04 +0000 (15:47 -0500)
82 files changed:
CMakeLists.txt [new file with mode: 0644]
cmake/Definitions.cmake [new file with mode: 0644]
cmake/Functions.cmake [new file with mode: 0644]
cmake/InstallCommands.cmake [new file with mode: 0644]
cmake/cpPluginsConfig.cmake.in [new file with mode: 0644]
lib/CMakeLists.txt [new file with mode: 0644]
lib/cpPlugins/CMakeLists.txt [new file with mode: 0644]
lib/cpPlugins/Config.h.in [new file with mode: 0644]
lib/cpPlugins/Interface/ComponentInterface.cxx [new file with mode: 0644]
lib/cpPlugins/Interface/ComponentInterface.h [new file with mode: 0644]
lib/cpPlugins/Interface/GarbageCollector.h [new file with mode: 0644]
lib/cpPlugins/Interface/GarbageCollector.hxx [new file with mode: 0644]
lib/cpPlugins/Interface/Manager.cxx [new file with mode: 0644]
lib/cpPlugins/Interface/Manager.h [new file with mode: 0644]
lib/cpPlugins/Pipeline/Object.cxx [new file with mode: 0644]
lib/cpPlugins/Pipeline/Object.h [new file with mode: 0644]
lib/cpPlugins/Pipeline/Parameters.cxx [new file with mode: 0644]
lib/cpPlugins/Pipeline/Parameters.h [new file with mode: 0644]
lib/cpPlugins/Pipeline/ProcessObject.h [new file with mode: 0644]
lib/cpPlugins/Utils/ExpandTemplates.cxx [new file with mode: 0644]
lib/cpPlugins/Utils/ExpandTemplates.h [new file with mode: 0644]
lib/cpPlugins/Version.cxx.in [new file with mode: 0644]
lib/ivq/CMakeLists.txt [new file with mode: 0644]
lib/ivq/Config.h.in [new file with mode: 0644]
lib/ivq/ITK/BooleanMapSaliencyFunction.h [new file with mode: 0644]
lib/ivq/ITK/BooleanMapSaliencyFunction.hxx [new file with mode: 0644]
lib/ivq/ITK/CPRImageFilter.h [new file with mode: 0644]
lib/ivq/ITK/CPRImageFilter.hxx [new file with mode: 0644]
lib/ivq/ITK/ExtractLabelFunction.h [new file with mode: 0644]
lib/ivq/ITK/ExtractLabelFunction.hxx [new file with mode: 0644]
lib/ivq/ITK/ImageROIFromFunction.h [new file with mode: 0644]
lib/ivq/ITK/ImageROIFromFunction.hxx [new file with mode: 0644]
lib/ivq/ITK/ImageStatisticsFromSeeds.h [new file with mode: 0644]
lib/ivq/ITK/ImageStatisticsFromSeeds.hxx [new file with mode: 0644]
lib/ivq/ITK/ImageUnaryFunctionFilter.h [new file with mode: 0644]
lib/ivq/ITK/ImageUnaryFunctionFilter.hxx [new file with mode: 0644]
lib/ivq/ITK/IncrementalMeanAndVariance.cxx [new file with mode: 0644]
lib/ivq/ITK/IncrementalMeanAndVariance.h [new file with mode: 0644]
lib/ivq/ITK/IsoImageSlicer.h [new file with mode: 0644]
lib/ivq/ITK/IsoImageSlicer.hxx [new file with mode: 0644]
lib/ivq/ITK/PeakDetector.cxx [new file with mode: 0644]
lib/ivq/ITK/PeakDetector.h [new file with mode: 0644]
lib/ivq/ITK/RasterContourFilter.h [new file with mode: 0644]
lib/ivq/ITK/RasterContourFilter.hxx [new file with mode: 0644]
lib/ivq/ITK/Simple3DCurve.cxx [new file with mode: 0644]
lib/ivq/ITK/Simple3DCurve.h [new file with mode: 0644]
lib/ivq/ITK/ThresholdFunction.h [new file with mode: 0644]
lib/ivq/ITK/ThresholdFunction.hxx [new file with mode: 0644]
lib/ivq/Qt/DicomSeriesSelectorDialog.cxx [new file with mode: 0644]
lib/ivq/Qt/DicomSeriesSelectorDialog.h [new file with mode: 0644]
lib/ivq/Qt/DicomSeriesSelectorDialog.ui [new file with mode: 0644]
lib/ivq/Qt/DicomSeriesSelectorWidget.cxx [new file with mode: 0644]
lib/ivq/Qt/DicomSeriesSelectorWidget.h [new file with mode: 0644]
lib/ivq/Qt/DicomSeriesSelectorWidget.ui [new file with mode: 0644]
lib/ivq/Qt/ImageViewerWidget.cxx [new file with mode: 0644]
lib/ivq/Qt/ImageViewerWidget.h [new file with mode: 0644]
lib/ivq/Qt/MPRViewersWidget.cxx [new file with mode: 0644]
lib/ivq/Qt/MPRViewersWidget.h [new file with mode: 0644]
lib/ivq/Qt/MPRViewersWidget.ui [new file with mode: 0644]
lib/ivq/Qt/RendererWidget.cxx [new file with mode: 0644]
lib/ivq/Qt/RendererWidget.h [new file with mode: 0644]
lib/ivq/VTK/BrushWidget.cxx [new file with mode: 0644]
lib/ivq/VTK/BrushWidget.h [new file with mode: 0644]
lib/ivq/VTK/ImageActor.cxx [new file with mode: 0644]
lib/ivq/VTK/ImageActor.h [new file with mode: 0644]
lib/ivq/VTK/ImageSlicePointPlacer.cxx [new file with mode: 0644]
lib/ivq/VTK/ImageSlicePointPlacer.h [new file with mode: 0644]
lib/ivq/VTK/ImageViewer.cxx [new file with mode: 0644]
lib/ivq/VTK/ImageViewer.h [new file with mode: 0644]
lib/ivq/VTK/InteractorStyleImage.cxx [new file with mode: 0644]
lib/ivq/VTK/InteractorStyleImage.h [new file with mode: 0644]
lib/ivq/VTK/MPRViewers.cxx [new file with mode: 0644]
lib/ivq/VTK/MPRViewers.h [new file with mode: 0644]
lib/ivq/VTK/PolyDataActor.cxx [new file with mode: 0644]
lib/ivq/VTK/PolyDataActor.h [new file with mode: 0644]
lib/ivq/VTK/SeedWidget.cxx [new file with mode: 0644]
lib/ivq/VTK/SeedWidget.h [new file with mode: 0644]
lib/ivq/VTK/SeedWidgetOverImageActor.cxx [new file with mode: 0644]
lib/ivq/VTK/SeedWidgetOverImageActor.h [new file with mode: 0644]
lib/ivq/VTK/Simple3DCurveToPolyData.cxx [new file with mode: 0644]
lib/ivq/VTK/Simple3DCurveToPolyData.h [new file with mode: 0644]
lib/ivq/Version.cxx.in [new file with mode: 0644]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..335f9e9
--- /dev/null
@@ -0,0 +1,57 @@
+## =========================================================================
+## @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+## =========================================================================
+
+cmake_minimum_required(VERSION 3.0)
+
+## == Basic project configuration
+set(prj_NAME cpPlugins)
+set(prj_MAJ 1)
+set(prj_MIN 0)
+set(prj_REL 0)
+
+## == Project definition
+project(${prj_NAME} VERSION "${prj_MAJ}.${prj_MIN}.${prj_REL}")
+
+## == Project policies
+set(_policies CMP0015 CMP0020 CMP0042 CMP0053)
+foreach(_p ${_policies})
+  if(POLICY ${_p})
+    cmake_policy(SET ${_p} NEW)
+  endif(POLICY ${_p})
+endforeach(_p)
+
+## == Some general configuration
+include(cmake/Definitions.cmake)
+include(cmake/Functions.cmake)
+
+## == Find ITK
+find_package(ITK CONFIG REQUIRED)
+include(${ITK_USE_FILE})
+
+## == Find VTK, only if linked against ITK
+set(cpPlugins_USE_VTK 0)
+if(ITKVtkGlue_LOADED)
+  find_package(VTK CONFIG REQUIRED)
+  include(${VTK_USE_FILE})
+  set(cpPlugins_USE_VTK 1)
+endif(ITKVtkGlue_LOADED)
+
+## == Find Qt5, only if linked against VTK
+set(cpPlugins_USE_Qt5 0)
+if(VTK_FOUND)
+  if(Qt5_DIR)
+    find_package(Qt5 CONFIG REQUIRED COMPONENTS Widgets)
+    set(CMAKE_INCLUDE_CURRENT_DIR ON)
+    set(CMAKE_AUTOMOC ON)
+    set(cpPlugins_USE_Qt5 1)
+  endif(Qt5_DIR)
+endif(VTK_FOUND)
+
+## == Build packages
+subdirs(lib)
+
+## == Installation commands
+include(cmake/InstallCommands.cmake)
+
+## eof - $RCSfile$
diff --git a/cmake/Definitions.cmake b/cmake/Definitions.cmake
new file mode 100644 (file)
index 0000000..46fb5cf
--- /dev/null
@@ -0,0 +1,53 @@
+## =========================================================================
+## @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+## =========================================================================
+
+## == If working on a MacOSX, activate the use of RPATH's
+## == Furthermore: prepare the type of executables
+set(EXECUTABLE_TYPE "" CACHE STRING "Executable linking." FORCE)
+if(APPLE)
+  set(EXECUTABLE_TYPE "MACOSX_BUNDLE" CACHE STRING "Executable linking." FORCE)
+  set(CMAKE_MACOSX_RPATH true CACHE BOOL "Use RPATH's on MacOSX." FORCE)
+  mark_as_advanced(CMAKE_MACOSX_RPATH)
+elseif(WIN32)
+  set(EXECUTABLE_TYPE "WIN32" CACHE STRING "Executable linking." FORCE)
+endif(APPLE)
+mark_as_advanced(EXECUTABLE_TYPE)
+
+## == Force c++11
+if(NOT MSVC)
+  include(CheckCXXCompilerFlag)
+  check_cxx_compiler_flag("-std=c++11" COMPILER_SUPPORTS_CXX11)
+  if(COMPILER_SUPPORTS_CXX11)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+  else(COMPILER_SUPPORTS_CXX11)
+    check_cxx_compiler_flag("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
+    if(COMPILER_SUPPORTS_CXX0X)
+      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
+    else(COMPILER_SUPPORTS_CXX0X)
+      message(
+        FATAL_ERROR
+        "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support."
+        )
+    endif(COMPILER_SUPPORTS_CXX0X)
+  endif(COMPILER_SUPPORTS_CXX11)
+endif(NOT MSVC)
+
+## == Prepare header generator to build shared libs
+include(GenerateExportHeader)
+
+## == Do not allow to build inside the source tree
+if(PROJECT_BINARY_DIR STREQUAL ${PROJECT_SOURCE_DIR})
+  message(FATAL_ERROR "Building in the source tree is not allowed.")
+endif(PROJECT_BINARY_DIR STREQUAL ${PROJECT_SOURCE_DIR})
+
+## == Where to put targets (executables and libs)
+set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR})
+set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR})
+mark_as_advanced(
+  CMAKE_BACKWARDS_COMPATIBILITY
+  EXECUTABLE_OUTPUT_PATH
+  LIBRARY_OUTPUT_PATH
+  )
+
+## eof - $RCSfile$
diff --git a/cmake/Functions.cmake b/cmake/Functions.cmake
new file mode 100644 (file)
index 0000000..8ca0f15
--- /dev/null
@@ -0,0 +1,141 @@
+## =========================================================================
+## @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+## =========================================================================
+
+## -------------------------------------------------------------------------
+function(BuildLibrary lib typ src maj min rel)
+
+## -- Get sources
+set(_files)
+foreach(_s ${src})
+
+  ## -- Canonicalize path
+  get_filename_component(_p "${_s}" ABSOLUTE)
+
+  ## -- Check type of input
+  if(IS_DIRECTORY ${_p})
+    file(GLOB _f "${_p}/*")
+    foreach(_x ${_f})
+      if(NOT IS_DIRECTORY ${_x})
+        list(APPEND _files ${_x})
+      endif(NOT IS_DIRECTORY ${_x})
+    endforeach(_x)
+  else(IS_DIRECTORY ${_p})
+    list(APPEND _files ${_p})
+  endif(IS_DIRECTORY ${_p})
+
+endforeach(_s)
+
+## -- Process sources
+set(_cpp)
+set(_hpp)
+set(_qui)
+foreach(_f ${_files})
+
+  ## -- Separate filename from extension
+  string(REGEX REPLACE "\\.[^.]*$" "" _name ${_f})
+  string(REPLACE ${_name} "" _ext ${_f})
+  set(_out_name ${_name})
+  set(_out_ext ${_ext})
+
+  ## -- Process .in files
+  string(COMPARE EQUAL "${_ext}" ".in" _in_cmp)
+  if(_in_cmp)
+    string(REPLACE ${PROJECT_SOURCE_DIR} ${PROJECT_BINARY_DIR} _out ${_name})
+    configure_file(${_f} ${_out} @ONLY)
+    string(REGEX REPLACE "\\.[^.]*$" "" _out_name ${_out})
+    string(REPLACE ${_out_name} "" _out_ext ${_out})
+  endif(_in_cmp)
+
+  ## -- Now, get real extension
+  string(SUBSTRING ${_out_ext} 0 2 _ext_cmp)
+
+  ## -- Process .c?? files
+  string(COMPARE EQUAL "${_ext_cmp}" ".c" _c_cmp)
+  if(_c_cmp)
+    list(APPEND _cpp ${_out_name}${_out_ext})
+  endif(_c_cmp)
+
+  ## -- Process .h?? files
+  string(COMPARE EQUAL "${_ext_cmp}" ".h" _h_cmp)
+  if(_h_cmp)
+    list(APPEND _hpp ${_out_name}${_out_ext})
+  endif(_h_cmp)
+
+  ## -- Process .ui files
+  string(COMPARE EQUAL "${_out_ext}" ".ui" _u_cmp)
+  if(_u_cmp)
+    list(APPEND _qui ${_out_name}${_out_ext})
+  endif(_u_cmp)
+
+endforeach(_f)
+
+## -- Process Qt ui files
+list(LENGTH _qui _qui_len)
+if(${_qui_len} GREATER 0)
+  qt5_wrap_ui(_qui_hpp ${_qui})
+endif(${_qui_len} GREATER 0)
+
+## -- Real build
+add_library(${lib} ${typ} ${_cpp} ${_hpp} ${_qui_hpp})
+
+## -- Header creation
+generate_export_header(${lib})
+set_property(TARGET ${lib} PROPERTY VERSION "${maj}.${min}.${rel}")
+set_property(TARGET ${lib} PROPERTY SOVERSION ${maj})
+set_property(TARGET ${lib} PROPERTY INTERFACE_${lib}_MAJOR_VERSION ${maj})
+set_property(TARGET ${lib} APPEND PROPERTY COMPATIBLE_INTERFACE_STRING ${maj})
+
+## -- Link library
+target_link_libraries(${lib} PUBLIC ${ARGN})
+
+## -- Installation rules
+option(${lib}_INSTALL_DEVEL "Install development files for ${lib}" OFF)
+string(COMPARE EQUAL "${type}" "SHARED" _cmp)
+if(_cmp OR ${lib}_INSTALL_DEVEL)
+  install(
+    TARGETS ${lib}
+    EXPORT "${targets_export_name}"
+    LIBRARY DESTINATION "lib"
+    ARCHIVE DESTINATION "lib"
+    RUNTIME DESTINATION "bin"
+    INCLUDES DESTINATION "${include_install_dir}"
+    )
+endif(_cmp OR ${lib}_INSTALL_DEVEL)
+if(${lib}_INSTALL_DEVEL)
+  string(TOLOWER ${lib} _lower_lib)
+  set(
+    _install_hdr
+    ${_hpp}
+    ${CMAKE_CURRENT_BINARY_DIR}/${_lower_lib}_export.h
+    )
+  set(_install_dirs)
+  foreach(_h ${_install_hdr})
+    string(REPLACE ${CMAKE_CURRENT_SOURCE_DIR} "" _h_name ${_h})
+    string(COMPARE EQUAL "${_h_name}" "${_h}" _h_cmp)
+    if(_h_cmp)
+      string(REPLACE ${CMAKE_CURRENT_BINARY_DIR} "" _h_name ${_h})
+    endif(_h_cmp)
+    set(_h_out ${include_install_dir}/${lib}${_h_name})
+    get_filename_component(_h_dir ${_h_out} DIRECTORY)
+    install(
+      FILES "${_h}"
+      DESTINATION "${_h_dir}"
+      )
+  endforeach(_h)
+endif(${lib}_INSTALL_DEVEL)
+
+endfunction()
+
+## -------------------------------------------------------------------------
+function(BuildLibraryRecursive lib typ dir maj min rel)
+
+## -- Globbing directory
+file(GLOB_RECURSE _files "${dir}/*")
+
+## -- Build library
+BuildLibrary(${lib} ${typ} "${_files}" ${maj} ${min} ${rel} ${ARGN})
+
+endfunction()
+
+## eof - $RCSfile$
diff --git a/cmake/InstallCommands.cmake b/cmake/InstallCommands.cmake
new file mode 100644 (file)
index 0000000..97500ae
--- /dev/null
@@ -0,0 +1,40 @@
+## =========================================================================
+## @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+## =========================================================================
+
+## =========================
+## == Installation values ==
+## =========================
+
+set(config_install_dir "lib/cmake/${PROJECT_NAME}")
+set(include_install_dir "include")
+set(generated_dir "${PROJECT_BINARY_DIR}/generated")
+set(version_config "${generated_dir}/${PROJECT_NAME}ConfigVersion.cmake")
+set(project_config "${generated_dir}/${PROJECT_NAME}Config.cmake")
+set(targets_export_name "${PROJECT_NAME}Targets")
+set(namespace "${PROJECT_NAME}::")
+
+## ===============================
+## == Global installation rules ==
+## ===============================
+
+include(CMakePackageConfigHelpers)
+write_basic_package_version_file(
+  "${version_config}" COMPATIBILITY SameMajorVersion
+  )
+configure_package_config_file(
+  "cmake/${PROJECT_NAME}Config.cmake.in"
+  "${project_config}"
+  INSTALL_DESTINATION "${config_install_dir}"
+  )
+install(
+  EXPORT "${targets_export_name}"
+  NAMESPACE "${namespace}"
+  DESTINATION "${config_install_dir}"
+  )
+install(
+  FILES "${project_config}"
+  DESTINATION "${config_install_dir}"
+  )
+
+## eof - $RCSfile$
diff --git a/cmake/cpPluginsConfig.cmake.in b/cmake/cpPluginsConfig.cmake.in
new file mode 100644 (file)
index 0000000..891261c
--- /dev/null
@@ -0,0 +1,26 @@
+@PACKAGE_INIT@
+
+include("${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake")
+check_required_components("@PROJECT_NAME@")
+
+## ===========================================
+## == Find needed packages and dependencies ==
+## ===========================================
+
+set(ITK_DIR "@ITK_DIR@")
+set(VTK_DIR "@VTK_DIR@")
+set(Qt5_DIR "@Qt5_DIR@")
+
+find_package(ITK CONFIG REQUIRED)
+include(${ITK_USE_FILE})
+if(NOT "${VTK_DIR}" STREQUAL "")
+  find_package(VTK CONFIG REQUIRED)
+  include(${VTK_USE_FILE})
+endif(NOT "${VTK_DIR}" STREQUAL "")
+if(NOT "${Qt5_DIR}" STREQUAL "")
+  find_package(Qt5 CONFIG REQUIRED COMPONENTS Widgets)
+  set(CMAKE_INCLUDE_CURRENT_DIR ON)
+  set(CMAKE_AUTOMOC ON)
+endif(NOT "${Qt5_DIR}" STREQUAL "")
+
+## eof - $RCSfile$
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
new file mode 100644 (file)
index 0000000..64b550f
--- /dev/null
@@ -0,0 +1,12 @@
+## =========================================================================
+## @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+## =========================================================================
+
+## == Build libraries
+include_directories(
+  ${CMAKE_CURRENT_SOURCE_DIR}
+  ${CMAKE_CURRENT_BINARY_DIR}
+  )
+subdirs(ivq cpPlugins)
+
+## eof - $RCSfile$
diff --git a/lib/cpPlugins/CMakeLists.txt b/lib/cpPlugins/CMakeLists.txt
new file mode 100644 (file)
index 0000000..b663bc1
--- /dev/null
@@ -0,0 +1,11 @@
+## =========================================================================
+## @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+## =========================================================================
+
+BuildLibraryRecursive(
+  cpPlugins SHARED .
+  ${prj_MAJ} ${prj_MIN} ${prj_REL}
+  ${ITK_LIBRARIES} ${VTK_LIBRARIES} 
+  )
+
+## eof - $RCSfile$
diff --git a/lib/cpPlugins/Config.h.in b/lib/cpPlugins/Config.h.in
new file mode 100644 (file)
index 0000000..b6117ce
--- /dev/null
@@ -0,0 +1,43 @@
+/* =========================================================================
+ * @author ??? (???@javeriana.edu.co)
+ * @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+ * =========================================================================
+ */
+#ifndef __cpPlugins__Config__h__
+#define __cpPlugins__Config__h__
+
+#include <cpPlugins/cpplugins_export.h>
+
+/* =========================================================================
+ * Identify OS
+ * =========================================================================
+ */
+#define cpPlugins_OS_@CMAKE_SYSTEM_NAME@
+#ifdef cpPlugins_OS_Windows
+#  define cpPlugins_LIB_PREFIX     ""
+#  define cpPlugins_ENV_SEPARATOR  ";"
+#  define cpPlugins_PATH_SEPARATOR '\\'
+#  define cpPlugins_LIB_EXT        ".dll"
+#else // cpPlugins_OS_Windows
+#  define cpPlugins_LIB_PREFIX     "lib"
+#  define cpPlugins_ENV_SEPARATOR  ":"
+#  define cpPlugins_PATH_SEPARATOR '/'
+#  ifdef cpPlugins_OS_Linux
+#    define cpPlugins_LIB_EXT ".so"
+#  else // cpPlugins_OS_Linux
+#    define cpPlugins_LIB_EXT ".dylib"
+#  endif // cpPlugins_OS_Linux
+#endif // cpPlugins_OS_Windows
+
+#ifdef cpPlugins_OS_Windows
+#  ifndef WIN32_LEAN_AND_MEAN
+#    define WIN32_LEAN_AND_MEAN
+#  endif // WIN32_LEAN_AND_MEAN
+#  define NOMINMAX
+#  include <windows.h>
+#  include <tchar.h>
+#endif // cpPlugins_OS_Windows
+
+#endif // __cpPlugins__Config__h__
+
+// eof - $RCSfile$
diff --git a/lib/cpPlugins/Interface/ComponentInterface.cxx b/lib/cpPlugins/Interface/ComponentInterface.cxx
new file mode 100644 (file)
index 0000000..46a63ad
--- /dev/null
@@ -0,0 +1,64 @@
+/* TODO
+   #include <cpPlugins/ComponentInterface.h>
+
+   cpPlugins::ComponentInterface::ComponentInterface(void* lib_handle, void* component_reference, std::string component_name,
+   std::string lib_name) {
+   this->component_reference = component_reference;
+   this->component_name      = component_name;
+   this->lib_name            = lib_name;
+   this->destructor          = (component_destructor)dlsym(lib_handle, "destroy_component");
+   this->updater             = (component_updater)dlsym(lib_handle, "update_component");
+   this->getOutput           = (component_getOutput)dlsym(lib_handle, "getOutput_component");
+   this->setInput            = (component_setInput)dlsym(lib_handle, "setInput_component");
+   }
+
+   cpPlugins::ComponentInterface::~ComponentInterface() {
+   // Destroy component reference
+   (this->destructor)(const_cast<char*>((this->component_name).c_str()), this->component_reference);
+   }
+
+   void cpPlugins::ComponentInterface::Update() {
+   (this->updater)(const_cast<char*>((this->component_name).c_str()), this->component_reference);
+   }
+
+   void cpPlugins::ComponentInterface::SetInput(void* input) {
+   (this->setInput)(const_cast<char*>((this->component_name).c_str()), this->component_reference, input);
+   }
+
+   void* cpPlugins::ComponentInterface::GetOutput() {
+   return  (this->getOutput)(const_cast<char*>((this->component_name).c_str()), this->component_reference);
+   }
+
+   void* cpPlugins::ComponentInterface::GetComponent() {
+   return this->component_reference;
+   }
+
+   void cpPlugins::ComponentInterface::SetComponent(void* component_reference) {
+   this->component_reference = component_reference;
+   }
+
+   std::string cpPlugins::ComponentInterface::GetLibraryName() {
+   return this->lib_name;
+   }
+
+   void cpPlugins::ComponentInterface::SetLibraryName(std::string lib_name) {
+   this->lib_name = lib_name;
+   }
+
+   std::string cpPlugins::ComponentInterface::GetComponentName() {
+   return this->component_name;
+   }
+
+   void cpPlugins::ComponentInterface::SetComponentName(std::string component_reference) {
+   this->component_name = component_name;
+   }
+
+   void cpPlugins::ComponentInterface::SetComponentDestructor(void* lib_handle) {
+   this->destructor = (component_destructor)dlsym(lib_handle, "destroy_component");;
+   }
+
+   void cpPlugins::ComponentInterface::SetComponentUpdater(void* lib_handle) {
+   this->updater = (component_updater)dlsym(lib_handle, "update_component");
+   }
+
+*/
diff --git a/lib/cpPlugins/Interface/ComponentInterface.h b/lib/cpPlugins/Interface/ComponentInterface.h
new file mode 100644 (file)
index 0000000..7e96515
--- /dev/null
@@ -0,0 +1,66 @@
+/* =========================================================================
+ * @author ??? (???@javeriana.edu.co)
+ * @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+ * =========================================================================
+ */
+#ifndef __cpPlugins__Interface__ComponentInterface__h__
+#define __cpPlugins__Interface__ComponentInterface__h__
+
+/* TODO
+   #include <memory>
+   #include <string>
+   #include <dlfcn.h>
+   #include <cpPlugins/cpplugins_export.h>
+
+   namespace cpPlugins
+   {
+   namespace Interface
+   {
+   class CPPLUGINS_EXPORT ComponentInterface
+   : public std::enable_shared_from_this< ComponentInterface >
+   {
+   public:
+   typedef ComponentInterface Self;
+   typedef std::enable_shared_from_this< ComponentInterface > Superclass;
+
+   typedef void(*TDestructor)(char*, void*);
+   typedef void(*TUpdater)(char*, void*);
+   typedef void*(*TOutput)(char*, void*);
+   typedef void(*TInput)(char*, void*, void*);
+
+   // Variable definition
+   private:
+   TDestructor destructor;
+   TUpdater    updater;
+   TOutput  getOutput;
+   TInput   setInput;
+   std::string          lib_name;
+   std::string          component_name;
+   void*                component_reference;
+
+   // Method definition
+   public:
+   ComponentInterface(void* lib_handle, void* component_reference,
+   std::string component_name, std::string lib_name);
+   virtual ~ComponentInterface();
+   void        Update();
+   void        SetInput(void* input);
+   void*       GetOutput();
+   void*       GetComponent();
+   void        SetComponent(void* reference);
+   std::string GetLibraryName();
+   void        SetLibraryName(std::string lib_name);
+   std::string GetComponentName();
+   void        SetComponentName(std::string component_name);
+   void        SetComponentDestructor(void* lib_handle);
+   void        SetComponentUpdater(void* lib_handle);
+   };
+
+   } // ecapseman
+
+   } // ecapseman
+*/
+
+#endif // __cpPlugins__Interface__ComponentInterface__h__
+
+// eof - $RCSfile$
diff --git a/lib/cpPlugins/Interface/GarbageCollector.h b/lib/cpPlugins/Interface/GarbageCollector.h
new file mode 100644 (file)
index 0000000..95b3311
--- /dev/null
@@ -0,0 +1,50 @@
+/* =========================================================================
+ * @author ??? (???@javeriana.edu.co)
+ * @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+ * =========================================================================
+ */
+#ifndef __cpPlugins__Interface__GarbageCollector__h__
+#define __cpPlugins__Interface__GarbageCollector__h__
+
+/* TODO
+   #include <iostream>
+   #include <cstdint>
+   #include <memory>
+   #include <map>
+*/
+
+namespace cpPlugins
+{
+  namespace Interface
+  {
+    /**
+     */
+    template< class _TComponent >
+    class GarbageCollector
+    {
+    public:
+      typedef GarbageCollector              Self;
+      typedef _TComponent                   TComponent;
+      typedef uintptr_t                     TKey;
+      typedef std::shared_ptr< TComponent > TResource;
+      typedef std::weak_ptr< TComponent >   TReference;
+      typedef std::map< TKey, TReference >  THandler;
+
+    public:
+      GarbageCollector( );
+      virtual ~GarbageCollector( );
+      TResource CreateManager( TComponent* component_object );
+      TReference GetReference( TComponent* component_object );
+
+    private:
+      THandler m_Handler;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#include <cpPlugins/Interface/GarbageCollector.hxx>
+#endif // __cpPlugins__Interface__GarbageCollector__h__
+
+// eof - $RCSfile$
diff --git a/lib/cpPlugins/Interface/GarbageCollector.hxx b/lib/cpPlugins/Interface/GarbageCollector.hxx
new file mode 100644 (file)
index 0000000..6d0089c
--- /dev/null
@@ -0,0 +1,65 @@
+/* =========================================================================
+ * @author ??? (???@javeriana.edu.co)
+ * @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+ * =========================================================================
+ */
+#ifndef __cpPlugins__Interface__GarbageCollector__hxx__
+#define __cpPlugins__Interface__GarbageCollector__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TComponent >
+cpPlugins::Interface::GarbageCollector< _TComponent >::
+GarbageCollector( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TComponent >
+cpPlugins::Interface::GarbageCollector< _TComponent >::
+~GarbageCollector( )
+{
+  /* TODO
+     std::cout << "Deleting garbage collector..." << std :: endl;
+  */
+}
+
+// -------------------------------------------------------------------------
+template< class _TComponent >
+typename cpPlugins::Interface::GarbageCollector< _TComponent >::TResource
+cpPlugins::Interface::GarbageCollector< _TComponent >::
+CreateManager( TComponent* component_object )
+{
+  TKey new_key = reinterpret_cast< TKey >( component_object );
+  TResource new_obj =
+    std::shared_ptr< TComponent >(
+      component_object,
+      [&]( TComponent* component_object )
+      { // begin
+        /* TODO
+           std::cout << "Component " << component_object->GetComponentName( ) << "( " << component_object << " ) is going out of scope, deleting..." << std::endl;
+        */
+        this->m_Handler.erase( reinterpret_cast< TKey >( component_object ) );
+        delete component_object;
+      } // end
+      );
+  this->m_Handler[ new_key ] = new_obj;
+  return( component_object->shared_from_this( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TComponent >
+typename cpPlugins::Interface::GarbageCollector< _TComponent >::TReference
+cpPlugins::Interface::GarbageCollector< _TComponent >::
+GetReference( TComponent* pointer )
+{
+  TKey key = reinterpret_cast< TKey >( pointer );
+  THandler::const_iterator it = this->m_Handler.find( key );
+  if( it != this->m_Handler.end( ) )
+    return( it->second );
+  else
+    return( TReference( NULL ) );
+}
+
+#endif // __cpPlugins__Interface__GarbageCollector__hxx__
+
+// eof - $RCSfile$
diff --git a/lib/cpPlugins/Interface/Manager.cxx b/lib/cpPlugins/Interface/Manager.cxx
new file mode 100644 (file)
index 0000000..d4c08c4
--- /dev/null
@@ -0,0 +1,225 @@
+/* =========================================================================
+ * @author ??? (???@javeriana.edu.co)
+ * @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+ * =========================================================================
+ */
+#include <cpPlugins/Interface/Manager.h>
+
+// -------------------------------------------------------------------------
+cpPlugins::Interface::Manager::
+Manager( )
+{
+}
+
+// -------------------------------------------------------------------------
+cpPlugins::Interface::Manager::
+~Manager( )
+{
+}
+
+// -------------------------------------------------------------------------
+/* TODO
+   std::set< std::string > cpPlugins::Manager::
+   GetContents( )
+   {
+   // If there are no libraries loaded, throw empty handler exception
+   if( this->m_Libraries.empty( ) )
+   throw std::runtime_error( "There are no libraries loaded in the system" );
+
+   std::set< std::string > libraries_components;
+
+   // Iterate through map
+   std::map< std::string, void* >::iterator it;
+   for( it = this->m_Libraries.begin( ); it != this->m_Libraries.end( ); ++it )
+   {
+   // Pointer to function names, adquire names
+   char**( *get_library_components )( );
+   get_library_components = ( char**( * )( ) )dlsym( it->second, "get_library_components" );
+   char** library_components = get_library_components( );
+   char** iterator = library_components;
+   while( *iterator )
+   {
+   // Insert "library_name::component_name"
+   libraries_components.insert(
+   it->first + std::string( "::" ) + std::string( *iterator )
+   );
+
+   // Free memory
+   free( *iterator );
+   iterator++;
+
+   } // elihw
+   free( library_components );
+
+   } // rof
+   return( libraries_components );
+   }
+
+// -------------------------------------------------------------------------
+void cpPlugins::Manager::
+LoadLibrary( const std::string& lib_name )
+{
+void* lib = dlopen( lib_name, RTLD_LAZY );
+
+if( lib == NULL )
+throw std::runtime_error(
+"Unable to load " + std::string( lib_name ) +
+std::string( " library: " ) + std::string( dlerror( ) ) + "\n"
+);
+
+// Get constructor function from lib
+dispatcher component_dispatcher =
+( dispatcher )dlsym( lib, "dispatch_component" );
+
+if( component_dispatcher == NULL )
+throw std::runtime_error(
+"Unable to load dispatcher method from dynamic library: " +
+std::string( dlerror( ) ) + std::string( "\n" )
+);
+
+
+// Get destructor function from lib
+destructor component_destructor = ( destructor )dlsym( lib, "destroy_component" );
+
+if( component_destructor == NULL )
+throw std::runtime_error(
+"Unable to load destructor method from dynamic library: " +
+std::string( dlerror( ) ) + std::string( "\n" )
+);
+
+// Get updater function from lib
+updater component_updater = ( updater )dlsym( lib, "update_component" );
+
+if( component_updater == NULL )
+throw std::runtime_error(
+"Unable to load updater method from dynamic library: " +
+std::string( dlerror( ) ) + std::string( "\n" )
+);
+
+
+// Register into library handler
+this->m_Libraries[ lib_name ] = lib;
+
+// Register garbage collector
+GarbageCollector<ComponentInterface>* garbage_collector =
+new GarbageCollector<ComponentInterface>( );
+
+this->m_Collector.
+insert( std::pair<std::string, GarbageCollector<ComponentInterface>* >
+(
+std::string( lib_name ), garbage_collector
+)
+);
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Manager::
+UnloadLibrary( const std::string& lib_name )
+{
+// Validate library existence
+void* lib;
+if( !this->m_Libraries.empty( ) )
+{
+try
+{
+lib = this->m_Libraries.at( lib_name );
+}
+catch( const std::exception& err )
+{
+throw std::runtime_error(
+"The requested library has not been loaded into the system"
+);
+
+} // yrt
+}
+else
+throw std::runtime_error( "There are no libraries loaded in the system" );
+
+// Close library handle
+dlclose( lib );
+
+// Erase register from handler
+this->m_Libraries.erase( lib_name );
+
+// Erase register from garbage collector
+delete this->m_Collector.at( lib_name );
+this->m_Collector.erase( lib_name );
+}
+
+// -------------------------------------------------------------------------
+std::shared_ptr< cpPlugins::Manager::TComponent > cpPlugins::Manager::
+CreateComponent(
+const std::string& lib_name, const std::string& component_name
+)
+{
+// Validate library existence
+void* lib;
+if( !this->m_Libraries.empty( ) )
+{
+try
+{
+lib = this->m_Libraries.at( lib_name );
+}
+catch( const std::exception& oor )
+{
+throw std::runtime_error(
+"The requested library has not been loaded into the system"
+);
+
+} // yrt
+}
+else
+throw "There are no libraries loaded in the system";
+
+// Validate component existence
+component_validator component_exists =
+( component_validator )dlsym( lib, "component_exists" );
+
+if( !component_exists( component_name ) )
+throw std::runtime_error(
+"The requested component ( " + std::string( component_name ) +
+" ) doesn't exists in the library context\n"
+);
+
+// Get constructor function from lib
+dispatcher component_dispatcher =
+( dispatcher )dlsym( lib, "dispatch_component" );
+
+if( component_dispatcher == NULL )
+throw std::runtime_error(
+"Unable to load dispatcher method from dynamic library: " +
+std::string( dlerror( ) ) + std::string( "\n" )
+);
+
+// Get destructor function from lib
+destructor component_destructor = ( destructor )dlsym( lib, "destroy_component" );
+
+if( component_destructor == NULL )
+throw std::runtime_error(
+"Unable to load destructor method from dynamic library: " +
+std::string( dlerror( ) ) + std::string( "\n" )
+);
+
+// Get updater function from lib
+updater component_updater = ( updater )dlsym( lib, "update_component" );
+
+if( component_updater == NULL )
+throw std::runtime_error(
+"Unable to load updater method from dynamic library: " +
+std::string( dlerror( ) ) + std::string( "\n" )
+);
+
+// Dispatch requested component
+void* component_reference = component_dispatcher( component_name );
+
+// Create interface
+ComponentInterface* component_interface =
+new ComponentInterface( lib, component_reference,
+std::string( component_name ), std::string( lib_name ) );
+
+// Register into garbage collector and return smart_ptr
+return( this->m_Collector.at( lib_name )->create_manager( component_interface ) );
+}
+*/
+
+// eof - $RCSfile$
diff --git a/lib/cpPlugins/Interface/Manager.h b/lib/cpPlugins/Interface/Manager.h
new file mode 100644 (file)
index 0000000..385ff22
--- /dev/null
@@ -0,0 +1,71 @@
+/* =========================================================================
+ * @author ??? (???@javeriana.edu.co)
+ * @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+ * =========================================================================
+ */
+#ifndef __cpPlugins__Interface__Manager__h__
+#define __cpPlugins__Interface__Manager__h__
+
+#include <map>
+#include <set>
+#include <string>
+#include <cpPlugins/Config.h>
+/* TODO
+   #include <cpPlugins/Interface/GarbageCollector.h>
+   #include <cpPlugins/Interface/ComponentInterface.h>
+*/
+
+/* TODO
+   #include <cstdlib>
+   #include <dlfcn.h>
+
+   typedef void*(*dispatcher)(char*);
+   typedef void(*destructor)(char*, void*);
+   typedef void(*updater)(char*, void*);
+   typedef bool(*component_validator)(char*);
+*/
+
+namespace cpPlugins
+{
+  namespace Interface
+  {
+    /**
+     */
+    class CPPLUGINS_EXPORT Manager
+    {
+    public:
+      typedef Manager Self;
+
+      /* TODO
+         typedef cpPlugins::Interface::ComponentInterface TComponent;
+         typedef cpPlugins::Interface::GarbageCollector< TComponent > TCollector;
+      */
+
+    public:
+      Manager( );
+      virtual ~Manager( );
+
+      /* TODO
+         std::set< std::string > GetContents( );
+         void LoadLibrary( const std::string& lib_name );
+         void UnloadLibrary( const std::string& lib_name );
+         std::shared_ptr< TComponent > CreateComponent(
+         const std::string& lib_name, const std::string& component_name
+         );
+      */
+
+      /* TODO
+         private:
+         std::map< std::string, TCollector >              m_Collectors;
+         std::map< std::string, void* >                   m_Libraries;
+         std::map< std::string, std::set< std::string > > m_Components;
+      */
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#endif // __cpPlugins__Interface__Manager__h__
+
+// eof - $RCSfile$
diff --git a/lib/cpPlugins/Pipeline/Object.cxx b/lib/cpPlugins/Pipeline/Object.cxx
new file mode 100644 (file)
index 0000000..62468bf
--- /dev/null
@@ -0,0 +1,207 @@
+/* =========================================================================
+ * @author ??? (???@javeriana.edu.co)
+ * @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+ * =========================================================================
+ */
+#include <cpPlugins/Pipeline/Object.h>
+#include <itkLightObject.h>
+#include <itkObject.h>
+#include <vtkObject.h>
+#include <vtkObjectBase.h>
+#include <vtkSmartPointer.h>
+
+// -------------------------------------------------------------------------
+cpPlugins::Pipeline::Object::
+Object( const std::string& category )
+  : m_Name( "" ),
+    m_Category( category ),
+    m_Object( NULL ),
+    m_Type( Self::NeitherType )
+{
+}
+
+// -------------------------------------------------------------------------
+cpPlugins::Pipeline::Object::
+~Object( )
+{
+  this->_DeleteObject( );
+}
+
+// -------------------------------------------------------------------------
+void* cpPlugins::Pipeline::Object::
+GetObject( )
+{
+  return( this->m_Object );
+}
+
+// -------------------------------------------------------------------------
+const void* cpPlugins::Pipeline::Object::
+GetObject( ) const
+{
+  return( this->m_Object );
+}
+
+// -------------------------------------------------------------------------
+itk::LightObject* cpPlugins::Pipeline::Object::
+GetObjectAsITK( )
+{
+  if( this->m_Object != NULL && this->m_Type == Self::ITKType )
+  {
+    itk::LightObject::Pointer* o =
+      reinterpret_cast< itk::LightObject::Pointer* >( this->m_Object );
+    return( o->GetPointer( ) );
+  }
+  else
+    return( NULL );
+}
+
+// -------------------------------------------------------------------------
+const itk::LightObject* cpPlugins::Pipeline::Object::
+GetObjectAsITK( ) const
+{
+  if( this->m_Object != NULL && this->m_Type == Self::ITKType )
+  {
+    const itk::LightObject::Pointer* o =
+      reinterpret_cast< const itk::LightObject::Pointer* >( this->m_Object );
+    return( o->GetPointer( ) );
+  }
+  else
+    return( NULL );
+}
+
+// -------------------------------------------------------------------------
+vtkObjectBase* cpPlugins::Pipeline::Object::
+GetObjectAsVTK( )
+{
+  if( this->m_Object != NULL && this->m_Type == Self::VTKType )
+  {
+    vtkSmartPointer< vtkObjectBase >* o =
+      reinterpret_cast< vtkSmartPointer< vtkObjectBase >* >( this->m_Object );
+    return( o->GetPointer( ) );
+  }
+  else
+    return( NULL );
+}
+
+// -------------------------------------------------------------------------
+const vtkObjectBase* cpPlugins::Pipeline::Object::
+GetObjectAsVTK( ) const
+{
+  if( this->m_Object != NULL && this->m_Type == Self::VTKType )
+  {
+    const vtkSmartPointer< vtkObjectBase >* o =
+      reinterpret_cast< const vtkSmartPointer< vtkObjectBase >* >(
+        this->m_Object
+        );
+    return( o->GetPointer( ) );
+  }
+  else
+    return( NULL );
+}
+
+// -------------------------------------------------------------------------
+const char* cpPlugins::Pipeline::Object::
+GetClassName( ) const
+{
+  return( this->m_Name.c_str( ) );
+}
+
+// -------------------------------------------------------------------------
+const char* cpPlugins::Pipeline::Object::
+GetClassCategory( ) const
+{
+  return( this->m_Category.c_str( ) );
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Pipeline::Object::
+SetClassName( const std::string& name )
+{
+  this->m_Name = name;
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Pipeline::Object::
+Modified( )
+{
+  const itk::Object* i =
+    dynamic_cast< const itk::Object* >( this->GetObjectAsITK( ) );
+  vtkObject* v =
+    dynamic_cast< vtkObject* >( this->GetObjectAsVTK( ) );
+  if( i != NULL ) i->Modified( );
+  if( v != NULL ) v->Modified( );
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Pipeline::Object::
+_DeleteObject( )
+{
+  typedef itk::LightObject::Pointer _TIPtr;
+  typedef vtkSmartPointer< vtkObjectBase > _TVPtr;
+  if( this->m_Object != NULL )
+  {
+    if( this->m_Type == Self::ITKType )
+    {
+      _TIPtr* o = reinterpret_cast< _TIPtr* >( this->m_Object );
+      delete o;
+    }
+    else if( this->m_Type == Self::VTKType )
+    {
+      _TVPtr* o = reinterpret_cast< _TVPtr* >( this->m_Object );
+      delete o;
+
+    } // fi
+    this->m_Object = NULL;
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Pipeline::Object::
+_SetObject( itk::LightObject* obj )
+{
+  if( obj != NULL )
+  {
+    itk::LightObject::Pointer* p = new itk::LightObject::Pointer( obj );
+    this->m_Object = p;
+    this->m_Type = Self::ITKType;
+  }
+  else
+  {
+    this->_DeleteObject( );
+    this->m_Type = Self::NeitherType;
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Pipeline::Object::
+_SetObject( vtkObjectBase* obj )
+{
+  if( obj != NULL )
+  {
+    vtkSmartPointer< vtkObjectBase >* p =
+      new vtkSmartPointer< vtkObjectBase >( obj );
+    this->m_Object = p;
+    this->m_Type = Self::VTKType;
+  }
+  else
+  {
+    this->_DeleteObject( );
+    this->m_Type = Self::NeitherType;
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Pipeline::Object::
+_SetObject( void* obj )
+{
+  if( obj != NULL )
+    this->m_Object = obj;
+  else
+    this->_DeleteObject( );
+  this->m_Type = Self::NeitherType;
+}
+
+// eof - $RCSfile$
diff --git a/lib/cpPlugins/Pipeline/Object.h b/lib/cpPlugins/Pipeline/Object.h
new file mode 100644 (file)
index 0000000..ec1bc94
--- /dev/null
@@ -0,0 +1,79 @@
+/* =========================================================================
+ * @author ??? (???@javeriana.edu.co)
+ * @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+ * =========================================================================
+ */
+#ifndef __cpPlugins__Pipeline__Object__h__
+#define __cpPlugins__Pipeline__Object__h__
+
+#include <cpPlugins/Config.h>
+#include <string>
+
+// Some forward declarations
+namespace itk { class LightObject; }
+class vtkObjectBase;
+
+namespace cpPlugins
+{
+  namespace Pipeline
+  {
+    /**
+     */
+    class CPPLUGINS_EXPORT Object
+    {
+    public:
+      typedef Object Self;
+
+      enum TType
+      {
+        NeitherType = 0,
+        ITKType,
+        VTKType
+      };
+
+    public:
+      Object( const std::string& category = "" );
+      virtual ~Object( );
+
+      virtual void* GetObject( );
+      virtual const void* GetObject( ) const;
+
+      virtual itk::LightObject* GetObjectAsITK( );
+      virtual const itk::LightObject* GetObjectAsITK( ) const;
+
+      virtual vtkObjectBase* GetObjectAsVTK( );
+      virtual const vtkObjectBase* GetObjectAsVTK( ) const;
+
+      const char* GetClassName( ) const;
+      const char* GetClassCategory( ) const;
+      void SetClassName( const std::string& name );
+
+      virtual void Modified( );
+
+      virtual Self* CreateAnother( ) const = 0;
+
+    protected:
+      void _DeleteObject( );
+      void _SetObject( itk::LightObject* obj );
+      void _SetObject( vtkObjectBase* obj );
+      void _SetObject( void* obj );
+
+    private:
+      // Purposely not implemented
+      Object( const Self& );
+      Self& operator=( const Self& );
+
+    protected:
+      std::string m_Name;
+      std::string m_Category;
+      void*       m_Object;
+      TType       m_Type;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#endif // __cpPlugins__Pipeline__Object__h__
+
+// eof - $RCSfile$
diff --git a/lib/cpPlugins/Pipeline/Parameters.cxx b/lib/cpPlugins/Pipeline/Parameters.cxx
new file mode 100644 (file)
index 0000000..93b5261
--- /dev/null
@@ -0,0 +1,705 @@
+/* =========================================================================
+ * @author ??? (???@javeriana.edu.co)
+ * @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+ * =========================================================================
+ */
+#include <cpPlugins/Pipeline/Parameters.h>
+#include <sstream>
+#include <typeinfo>
+
+/* TODO
+   #include <cpPlugins/Pipeline/ProcessObject.h>
+   #include <cpPlugins/OS/String.h>
+   #include <cpPlugins/tinyxml2/tinyxml2.h>
+*/
+
+// -------------------------------------------------------------------------
+cpPlugins::Pipeline::Parameters::
+Parameters( )
+  : m_ProcessObject( NULL )
+{
+  this->Clear( );
+}
+
+// -------------------------------------------------------------------------
+cpPlugins::Pipeline::Parameters::
+~Parameters( )
+{
+}
+
+// -------------------------------------------------------------------------
+cpPlugins::Pipeline::ProcessObject* cpPlugins::Pipeline::Parameters::
+GetProcessObject( )
+{
+  return( this->m_ProcessObject );
+}
+
+// -------------------------------------------------------------------------
+const cpPlugins::Pipeline::ProcessObject* cpPlugins::Pipeline::Parameters::
+GetProcessObject( ) const
+{
+  return( this->m_ProcessObject );
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Pipeline::Parameters::
+SetProcessObject( cpPlugins::Pipeline::ProcessObject* po )
+{
+  this->m_ProcessObject = po;
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Pipeline::Parameters::
+Modified( ) const
+{
+  /* TODO
+     if( this->m_ProcessObject != NULL )
+     this->m_ProcessObject->Modified( );
+  */
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Pipeline::Parameters::
+Clear( )
+{
+  this->m_Parameters.clear( );
+  this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Pipeline::Parameters::
+GetNames( std::vector< std::string >& container ) const
+{
+  container.clear( );
+  TParameters::const_iterator i = this->m_Parameters.begin( );
+  for( ; i != this->m_Parameters.end( ); ++i )
+    container.push_back( i->first );
+}
+
+// -------------------------------------------------------------------------
+cpPlugins::Pipeline::Parameters::
+Type cpPlugins::Pipeline::Parameters::
+GetType( const std::string& name ) const
+{
+  TParameters::const_iterator i = this->m_Parameters.find( name );
+  if( i != this->m_Parameters.end( ) )
+    return( i->second.first );
+  else
+    return( Self::NoType );
+}
+
+// -------------------------------------------------------------------------
+#define cpPlugins_Pipeline_Parameters_TypeAsString( Y )         \
+  if( i->second.first == Self::Y )                              \
+    return( #Y )
+
+std::string cpPlugins::Pipeline::Parameters::
+GetTypeAsString( const std::string& name ) const
+{
+  TParameters::const_iterator i = this->m_Parameters.find( name );
+  cpPlugins_Pipeline_Parameters_TypeAsString( String );
+  else cpPlugins_Pipeline_Parameters_TypeAsString( Bool );
+  else cpPlugins_Pipeline_Parameters_TypeAsString( Int );
+  else cpPlugins_Pipeline_Parameters_TypeAsString( Uint );
+  else cpPlugins_Pipeline_Parameters_TypeAsString( Real );
+  else cpPlugins_Pipeline_Parameters_TypeAsString( OpenFileName );
+  else cpPlugins_Pipeline_Parameters_TypeAsString( SaveFileName );
+  else cpPlugins_Pipeline_Parameters_TypeAsString( PathName );
+  else cpPlugins_Pipeline_Parameters_TypeAsString( StringList );
+  else cpPlugins_Pipeline_Parameters_TypeAsString( BoolList );
+  else cpPlugins_Pipeline_Parameters_TypeAsString( IntList );
+  else cpPlugins_Pipeline_Parameters_TypeAsString( UintList );
+  else cpPlugins_Pipeline_Parameters_TypeAsString( RealList );
+  else cpPlugins_Pipeline_Parameters_TypeAsString( OpenFileNameList );
+  else cpPlugins_Pipeline_Parameters_TypeAsString( SaveFileNameList );
+  else cpPlugins_Pipeline_Parameters_TypeAsString( PathNameList );
+  else cpPlugins_Pipeline_Parameters_TypeAsString( Choices );
+  else return( "NoType" );
+}
+
+// -------------------------------------------------------------------------
+#define cpPlugins_Pipeline_Parameters_TypeFromString( Y, str )      \
+  if( str == std::string( #Y ) )                                    \
+    return( Self::Y )
+
+cpPlugins::Pipeline::Parameters::
+Type cpPlugins::Pipeline::Parameters::
+GetTypeFromString( const std::string& t )
+{
+  cpPlugins_Pipeline_Parameters_TypeFromString( String, t );
+  else cpPlugins_Pipeline_Parameters_TypeFromString( Bool, t );
+  else cpPlugins_Pipeline_Parameters_TypeFromString( Int, t );
+  else cpPlugins_Pipeline_Parameters_TypeFromString( Uint, t );
+  else cpPlugins_Pipeline_Parameters_TypeFromString( Real, t );
+  else cpPlugins_Pipeline_Parameters_TypeFromString( OpenFileName, t );
+  else cpPlugins_Pipeline_Parameters_TypeFromString( SaveFileName, t );
+  else cpPlugins_Pipeline_Parameters_TypeFromString( PathName, t );
+  else cpPlugins_Pipeline_Parameters_TypeFromString( StringList, t );
+  else cpPlugins_Pipeline_Parameters_TypeFromString( BoolList, t );
+  else cpPlugins_Pipeline_Parameters_TypeFromString( IntList, t );
+  else cpPlugins_Pipeline_Parameters_TypeFromString( UintList, t );
+  else cpPlugins_Pipeline_Parameters_TypeFromString( RealList, t );
+  else cpPlugins_Pipeline_Parameters_TypeFromString( OpenFileNameList, t );
+  else cpPlugins_Pipeline_Parameters_TypeFromString( SaveFileNameList, t );
+  else cpPlugins_Pipeline_Parameters_TypeFromString( PathNameList, t );
+  else cpPlugins_Pipeline_Parameters_TypeFromString( Choices, t );
+  else return( Self::NoType );
+}
+
+// -------------------------------------------------------------------------
+std::string cpPlugins::Pipeline::Parameters::
+GetString( const std::string& name, bool force ) const
+{
+  TParameters::const_iterator i = this->m_Parameters.find( name );
+  if( i != this->m_Parameters.end( ) )
+  {
+    if( i->second.first == Self::String || force )
+      return( i->second.second );
+    else
+      return( "" );
+  }
+  else
+    return( "" );
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Pipeline::Parameters::
+SetString( const std::string& name, const std::string& v, bool force )
+{
+  TParameters::iterator i = this->m_Parameters.find( name );
+  if( i != this->m_Parameters.end( ) )
+  {
+    if( i->second.first == Self::String || force )
+    {
+      if( i->second.second != v )
+      {
+        i->second.second = v;
+        this->Modified( );
+
+      } // fi
+
+    } // fi
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Pipeline::Parameters::
+ConfigureAsChoices(
+  const std::string& name, const std::vector< std::string >& choices
+  )
+{
+  // It is invalid not to give choices when configuring
+  if( choices.size( ) == 0 )
+    return;
+
+  std::stringstream str_choices;
+  str_choices << choices[ 0 ];
+  for( unsigned int i = 1; i < choices.size( ); ++i )
+    str_choices << "#" << choices[ i ];
+  str_choices << "@";
+  this->m_Parameters[ name ] =
+    TParameter( Self::Choices, str_choices.str( ) );
+  this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Pipeline::Parameters::
+ConfigureAsRealTypesChoices( const std::string& name )
+{
+  std::vector< std::string > choices;
+  choices.push_back( "float" );
+  choices.push_back( "double" );
+  this->ConfigureAsChoices( name, choices );
+  this->SetSelectedChoice( name, "float" );
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Pipeline::Parameters::
+ConfigureAsIntTypesChoices( const std::string& name )
+{
+  std::vector< std::string > choices;
+  choices.push_back( "char" );
+  choices.push_back( "uchar" );
+  choices.push_back( "short" );
+  choices.push_back( "ushort" );
+  choices.push_back( "int" );
+  choices.push_back( "uint" );
+  choices.push_back( "long" );
+  choices.push_back( "ulong" );
+  this->ConfigureAsChoices( name, choices );
+  this->SetSelectedChoice( name, "char" );
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Pipeline::Parameters::
+ConfigureAsScalarTypesChoices( const std::string& name )
+{
+  std::vector< std::string > choices;
+  choices.push_back( "char" );
+  choices.push_back( "uchar" );
+  choices.push_back( "short" );
+  choices.push_back( "ushort" );
+  choices.push_back( "int" );
+  choices.push_back( "uint" );
+  choices.push_back( "long" );
+  choices.push_back( "ulong" );
+  choices.push_back( "float" );
+  choices.push_back( "double" );
+  this->ConfigureAsChoices( name, choices );
+  this->SetSelectedChoice( name, "char" );
+}
+
+// -------------------------------------------------------------------------
+std::vector< std::string > cpPlugins::Pipeline::Parameters::
+GetChoices( const std::string& name ) const
+{
+  std::vector< std::string > choices;
+
+  TParameters::const_iterator i = this->m_Parameters.find( name );
+  if( i != this->m_Parameters.end( ) )
+  {
+    if( i->second.first == Self::Choices )
+    {
+      std::istringstream str_choices( i->second.second );
+      std::string real_choices;
+      std::getline( str_choices, real_choices, '@' );
+      std::istringstream str( real_choices );
+      std::string token;
+      while( std::getline( str, token, '#' ) )
+        choices.push_back( token );
+
+    } // fi
+
+  } // fi
+  return( choices );
+}
+
+// -------------------------------------------------------------------------
+std::string cpPlugins::Pipeline::Parameters::
+GetSelectedChoice( const std::string& name ) const
+{
+  TParameters::const_iterator i = this->m_Parameters.find( name );
+  if( i != this->m_Parameters.end( ) )
+  {
+    if( i->second.first == Self::Choices )
+    {
+      std::istringstream str_choices( i->second.second );
+      std::string real_choice;
+      std::getline( str_choices, real_choice, '@' );
+      std::getline( str_choices, real_choice, '@' );
+      return( real_choice );
+    }
+    else
+      return( "" );
+  }
+  else
+    return( "" );
+}
+
+// -------------------------------------------------------------------------
+bool cpPlugins::Pipeline::Parameters::
+SetSelectedChoice( const std::string& name, const std::string& choice )
+{
+  TParameters::iterator i = this->m_Parameters.find( name );
+  if( i != this->m_Parameters.end( ) )
+  {
+    if( i->second.first == Self::Choices )
+    {
+      std::istringstream str_choices( i->second.second );
+      std::string choices;
+      std::getline( str_choices, choices, '@' );
+      if( choices.find( choice ) != std::string::npos )
+      {
+        std::stringstream new_choices;
+        new_choices << choices << "@" << choice;
+        i->second.second = new_choices.str( );
+        this->Modified( );
+        return( true );
+      }
+      else
+        return( false );
+    }
+    else
+      return( false );
+  }
+  else
+    return( false );
+}
+
+// -------------------------------------------------------------------------
+std::string cpPlugins::Pipeline::Parameters::
+GetAcceptedFileExtensions( const std::string& name ) const
+{
+  std::map< std::string, std::string >::const_iterator i =
+    this->m_AcceptedFileExtensions.find( name );
+  if( i != this->m_AcceptedFileExtensions.end( ) )
+    return( i->second );
+  else
+    return( "" );
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Pipeline::Parameters::
+SetAcceptedFileExtensions(
+  const std::string& name, const std::string& extensions
+  )
+{
+  TParameters::iterator i = this->m_Parameters.find( name );
+  if( i != this->m_Parameters.end( ) )
+  {
+    bool is_valid = ( i->second.first == Self::OpenFileName );
+    is_valid     |= ( i->second.first == Self::SaveFileName );
+    is_valid     |= ( i->second.first == Self::OpenFileNameList );
+    is_valid     |= ( i->second.first == Self::SaveFileNameList );
+    if( is_valid )
+      this->m_AcceptedFileExtensions[ name ] = extensions;
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+cpPlugins::Pipeline::Parameters::
+TParameters& cpPlugins::Pipeline::Parameters::
+GetRawParameters( )
+{
+  return( this->m_Parameters );
+}
+
+// -------------------------------------------------------------------------
+const cpPlugins::Pipeline::Parameters::
+TParameters& cpPlugins::Pipeline::Parameters::
+GetRawParameters( ) const
+{
+  return( this->m_Parameters );
+}
+
+// -------------------------------------------------------------------------
+#define cpPlugins_Pipeline_Parameters_Configure_Code( Y )               \
+  void cpPlugins::Pipeline::Parameters::                                \
+  ConfigureAs##Y( const std::string& name, const T##Y& init )           \
+  {                                                                     \
+    this->_Configure< Y >( name );                                      \
+    this->Set##Y( name, init );                                         \
+  }                                                                     \
+  bool cpPlugins::Pipeline::Parameters::                                \
+  Has##Y( const std::string& name ) const                               \
+  { return( this->_Has< Y >( name ) ); }
+
+// -------------------------------------------------------------------------
+#define cpPlugins_Pipeline_Parameters_ConfigureList_Code( Y )           \
+  void cpPlugins::Pipeline::Parameters::                                \
+  ConfigureAs##Y##List( const std::string& name )                       \
+  { this->_Configure< Y##List >( name ); }                              \
+  bool cpPlugins::Pipeline::Parameters::                                \
+  Has##Y##List( const std::string& name ) const                         \
+  { return( this->_Has< Y##List >( name ) ); }
+
+// -------------------------------------------------------------------------
+#define cpPlugins_Pipeline_Parameters_GetSet_Code( Y )                  \
+  cpPlugins::Pipeline::Parameters::T##Y                                 \
+  cpPlugins::Pipeline::Parameters::                                     \
+  Get##Y( const std::string& name ) const                               \
+  { return( this->_Get< T##Y, Y >( name ) ); }                          \
+  void cpPlugins::Pipeline::Parameters::Set##Y(                         \
+    const std::string& name, const T##Y& v                              \
+    )                                                                   \
+  { this->_Set< T##Y, Y >( name, v ); }
+
+// -------------------------------------------------------------------------
+#define cpPlugins_Pipeline_Parameters_GetSetList_Code( Y )              \
+  std::vector< cpPlugins::Pipeline::Parameters::T##Y >                  \
+  cpPlugins::Pipeline::Parameters::                                     \
+  Get##Y##List( const std::string& name ) const                         \
+  { return( this->_GetList< T##Y, Y##List >( name ) ); }                \
+  void cpPlugins::Pipeline::Parameters::AddTo##Y##List(                 \
+    const std::string& name,                                            \
+    const cpPlugins::Pipeline::Parameters::T##Y& v                      \
+    )                                                                   \
+  { this->_AddToList< T##Y, Y##List >( name, v ); }                     \
+  void cpPlugins::Pipeline::Parameters::                                \
+  Clear##Y##List( const std::string& name )                             \
+  { this->_ClearList< Y##List >( name ); }
+
+// -------------------------------------------------------------------------
+cpPlugins_Pipeline_Parameters_Configure_Code( String );
+cpPlugins_Pipeline_Parameters_Configure_Code( Bool );
+cpPlugins_Pipeline_Parameters_Configure_Code( Int );
+cpPlugins_Pipeline_Parameters_Configure_Code( Uint );
+cpPlugins_Pipeline_Parameters_Configure_Code( Real );
+cpPlugins_Pipeline_Parameters_Configure_Code( OpenFileName );
+cpPlugins_Pipeline_Parameters_Configure_Code( SaveFileName );
+cpPlugins_Pipeline_Parameters_Configure_Code( PathName );
+
+cpPlugins_Pipeline_Parameters_ConfigureList_Code( String );
+cpPlugins_Pipeline_Parameters_ConfigureList_Code( Bool );
+cpPlugins_Pipeline_Parameters_ConfigureList_Code( Int );
+cpPlugins_Pipeline_Parameters_ConfigureList_Code( Uint );
+cpPlugins_Pipeline_Parameters_ConfigureList_Code( Real );
+cpPlugins_Pipeline_Parameters_ConfigureList_Code( OpenFileName );
+cpPlugins_Pipeline_Parameters_ConfigureList_Code( SaveFileName );
+cpPlugins_Pipeline_Parameters_ConfigureList_Code( PathName );
+
+cpPlugins_Pipeline_Parameters_GetSet_Code( Bool );
+cpPlugins_Pipeline_Parameters_GetSet_Code( Int );
+cpPlugins_Pipeline_Parameters_GetSet_Code( Uint );
+cpPlugins_Pipeline_Parameters_GetSet_Code( Real );
+cpPlugins_Pipeline_Parameters_GetSet_Code( OpenFileName );
+cpPlugins_Pipeline_Parameters_GetSet_Code( SaveFileName );
+cpPlugins_Pipeline_Parameters_GetSet_Code( PathName );
+
+cpPlugins_Pipeline_Parameters_GetSetList_Code( String );
+cpPlugins_Pipeline_Parameters_GetSetList_Code( Bool );
+cpPlugins_Pipeline_Parameters_GetSetList_Code( Int );
+cpPlugins_Pipeline_Parameters_GetSetList_Code( Uint );
+cpPlugins_Pipeline_Parameters_GetSetList_Code( Real );
+cpPlugins_Pipeline_Parameters_GetSetList_Code( PathName );
+
+// -------------------------------------------------------------------------
+std::vector< cpPlugins::Pipeline::Parameters::TOpenFileName >
+cpPlugins::Pipeline::Parameters::
+GetOpenFileNameList( const std::string& name ) const
+{
+  return( this->_GetList< TOpenFileName, OpenFileNameList >( name ) );
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Pipeline::Parameters::
+AddToOpenFileNameList(
+  const std::string& name,
+  const cpPlugins::Pipeline::Parameters::TOpenFileName& v
+  )
+{
+  TParameters::iterator i = this->m_Parameters.find( name );
+  if( i != this->m_Parameters.end( ) )
+  {
+    if( i->second.first == OpenFileNameList )
+    {
+      size_t pos = v.find_last_of( "/\\" );
+      if( i->second.second == "" )
+        i->second.second = v.substr( 0, pos );
+      i->second.second += std::string( "#" );
+      i->second.second += v.substr( pos + 1 );
+      this->Modified( );
+
+    } // fi
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Pipeline::Parameters::
+ClearOpenFileNameList( const std::string& name )
+{
+  this->_ClearList< OpenFileNameList >( name );
+}
+
+// -------------------------------------------------------------------------
+std::vector< cpPlugins::Pipeline::Parameters::TSaveFileName >
+cpPlugins::Pipeline::Parameters::
+GetSaveFileNameList( const std::string& name ) const
+{
+  return( this->_GetList< TSaveFileName, SaveFileNameList >( name ) );
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Pipeline::Parameters::
+AddToSaveFileNameList(
+  const std::string& name,
+  const cpPlugins::Pipeline::Parameters::TSaveFileName& v
+  )
+{
+  TParameters::iterator i = this->m_Parameters.find( name );
+  if( i != this->m_Parameters.end( ) )
+  {
+    if( i->second.first == SaveFileNameList )
+    {
+      size_t pos = v.find_last_of( "/\\" );
+      if( i->second.second == "" )
+        i->second.second = v.substr( 0, pos );
+      i->second.second += std::string( "#" );
+      i->second.second += v.substr( pos + 1 );
+      this->Modified( );
+
+    } // fi
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Pipeline::Parameters::
+ClearSaveFileNameList( const std::string& name )
+{
+  this->_ClearList< SaveFileNameList >( name );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _Enum >
+void cpPlugins::Pipeline::Parameters::
+_Configure( const std::string& name )
+{
+  this->m_Parameters[ name ] = TParameter( ( Self::Type )( _Enum ), "" );
+  this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _Enum >
+bool cpPlugins::Pipeline::Parameters::
+_Has( const std::string& name ) const
+{
+  TParameters::const_iterator i = this->m_Parameters.find( name );
+  if( i != this->m_Parameters.end( ) )
+    return( i->second.first == ( Self::Type )( _Enum ) );
+  else
+    return( false );
+}
+
+// -------------------------------------------------------------------------
+template< class _Type, unsigned int _Enum >
+_Type cpPlugins::Pipeline::Parameters::
+_Get( const std::string& name ) const
+{
+  TParameters::const_iterator i = this->m_Parameters.find( name );
+  if( i != this->m_Parameters.end( ) )
+  {
+    if( i->second.first == ( Self::Type )( _Enum ) )
+    {
+      if( typeid( _Type ) != typeid( std::string ) )
+      {
+        std::istringstream tok_str( i->second.second );
+        _Type v;
+        tok_str >> v;
+        return( v );
+      }
+      else
+      {
+        const _Type* ptr =
+          reinterpret_cast< const _Type* >( &( i->second.second ) );
+        return( *ptr );
+
+      } // fi
+
+    } // fi
+
+  } // fi
+  return( _Type( 0 ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _Type, unsigned int _Enum >
+void cpPlugins::Pipeline::Parameters::
+_Set( const std::string& name, const _Type& v )
+{
+  TParameters::iterator i = this->m_Parameters.find( name );
+  if( i != this->m_Parameters.end( ) )
+  {
+    if( i->second.first == ( Self::Type )( _Enum ) )
+    {
+      if( typeid( _Type ) != typeid( std::string ) )
+      {
+        std::stringstream str;
+        str << v;
+        if( i->second.second != str.str( ) )
+        {
+          i->second.second = str.str( );
+          this->Modified( );
+
+        } // fi
+      }
+      else
+      {
+        const std::string* str = reinterpret_cast< const std::string* >( &v );
+        if( i->second.second != *str )
+        {
+          i->second.second = *str;
+          this->Modified( );
+
+        } // fi
+
+      } // fi
+
+    } // fi
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _Type, unsigned int _Enum >
+std::vector< _Type > cpPlugins::Pipeline::Parameters::
+_GetList( const std::string& name ) const
+{
+  std::vector< _Type > lst;
+  std::vector< std::string >* slst =
+    reinterpret_cast< std::vector< std::string >* >( &lst );
+  TParameters::const_iterator i = this->m_Parameters.find( name );
+  if( i != this->m_Parameters.end( ) )
+  {
+    if( i->second.first == ( Self::Type )( _Enum ) )
+    {
+      std::istringstream tokens( i->second.second );
+      std::string t;
+      while( std::getline( tokens, t, '#' ) )
+      {
+        if( typeid( _Type ) != typeid( std::string ) )
+        {
+          std::istringstream tok_str( t );
+          _Type v;
+          tok_str >> v;
+          lst.push_back( v );
+        }
+        else
+          slst->push_back( t );
+
+      } // elihw
+
+    } // fi
+
+  } // fi
+  return( lst );
+}
+
+// -------------------------------------------------------------------------
+template< class _Type, unsigned int _Enum >
+void cpPlugins::Pipeline::Parameters::
+_AddToList( const std::string& name, const _Type& v )
+{
+  TParameters::iterator i = this->m_Parameters.find( name );
+  if( i != this->m_Parameters.end( ) )
+  {
+    if( i->second.first == ( Self::Type )( _Enum ) )
+    {
+      std::stringstream str;
+      if( i->second.second != "" )
+        str << i->second.second << "#";
+      str << v;
+      i->second.second = str.str( );
+      this->Modified( );
+
+    } // fi
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _Enum >
+void cpPlugins::Pipeline::Parameters::
+_ClearList( const std::string& name )
+{
+  TParameters::iterator i = this->m_Parameters.find( name );
+  if( i != this->m_Parameters.end( ) )
+  {
+    if( i->second.first == ( Self::Type )( _Enum ) )
+    {
+      if( i->second.second != "" )
+      {
+        i->second.second = "";
+        this->Modified( );
+
+      } // fi
+
+    } // fi
+
+  } // fi
+}
+
+// eof - $RCSfile$
diff --git a/lib/cpPlugins/Pipeline/Parameters.h b/lib/cpPlugins/Pipeline/Parameters.h
new file mode 100644 (file)
index 0000000..0d90f48
--- /dev/null
@@ -0,0 +1,207 @@
+/* =========================================================================
+ * @author ??? (???@javeriana.edu.co)
+ * @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+ * =========================================================================
+ */
+#ifndef __cpPlugins__Pipeline__Parameters__h__
+#define __cpPlugins__Pipeline__Parameters__h__
+
+#include <cpPlugins/Config.h>
+
+#include <map>
+#include <ostream>
+#include <vector>
+
+// -------------------------------------------------------------------------
+#define cpPlugins_Pipeline_Parameters_Configure( Y )                    \
+  void ConfigureAs##Y( const std::string& name, const T##Y& init );     \
+  bool Has##Y( const std::string& name ) const
+
+// -------------------------------------------------------------------------
+#define cpPlugins_Pipeline_Parameters_ConfigureList( Y )                \
+  void ConfigureAs##Y##List( const std::string& name );                 \
+  bool Has##Y##List( const std::string& name ) const
+
+// -------------------------------------------------------------------------
+#define cpPlugins_Pipeline_Parameters_GetSet( Y )       \
+  T##Y Get##Y( const std::string& name ) const;         \
+  void Set##Y( const std::string& name, const T##Y& v )
+
+// -------------------------------------------------------------------------
+#define cpPlugins_Pipeline_Parameters_GetSetList( Y )                   \
+  std::vector< T##Y > Get##Y##List( const std::string& name ) const;    \
+  void AddTo##Y##List( const std::string& name, const T##Y& v );        \
+  void Clear##Y##List( const std::string& name )
+
+// -------------------------------------------------------------------------
+namespace cpPlugins
+{
+  namespace Pipeline
+  {
+    class ProcessObject;
+
+    /**
+     */
+    class CPPLUGINS_EXPORT Parameters
+    {
+      friend std::ostream& operator<<( std::ostream& o, const Parameters& p )
+        {
+          for(
+            auto i = p.m_Parameters.begin( );
+            i != p.m_Parameters.end( );
+            ++i
+            )
+            o << i->first << ": ("
+              << i->second.first << " | "
+              << i->second.second << ")"
+              << std::endl;
+          return( o );
+        }
+
+    public:
+      typedef Parameters Self;
+
+      enum Type
+      {
+        String       , Bool             , Int              ,
+        Uint         , Real             , OpenFileName     ,
+        SaveFileName , PathName         , StringList       ,
+        BoolList     , IntList          , UintList         ,
+        RealList     , OpenFileNameList , SaveFileNameList ,
+        PathNameList , Choices          , NoType
+      };
+
+      typedef bool          TBool;
+      typedef long          TInt;
+      typedef unsigned long TUint;
+      typedef double        TReal;
+      typedef std::string   TString;
+      typedef std::string   TOpenFileName;
+      typedef std::string   TSaveFileName;
+      typedef std::string   TPathName;
+
+      typedef std::pair< Self::Type, std::string > TParameter;
+      typedef std::map< std::string, TParameter >  TParameters;
+
+    public:
+      cpPlugins_Pipeline_Parameters_Configure( String );
+      cpPlugins_Pipeline_Parameters_Configure( Bool );
+      cpPlugins_Pipeline_Parameters_Configure( Int );
+      cpPlugins_Pipeline_Parameters_Configure( Uint );
+      cpPlugins_Pipeline_Parameters_Configure( Real );
+      cpPlugins_Pipeline_Parameters_Configure( OpenFileName );
+      cpPlugins_Pipeline_Parameters_Configure( SaveFileName );
+      cpPlugins_Pipeline_Parameters_Configure( PathName );
+
+      cpPlugins_Pipeline_Parameters_ConfigureList( String );
+      cpPlugins_Pipeline_Parameters_ConfigureList( Bool );
+      cpPlugins_Pipeline_Parameters_ConfigureList( Int );
+      cpPlugins_Pipeline_Parameters_ConfigureList( Uint );
+      cpPlugins_Pipeline_Parameters_ConfigureList( Real );
+      cpPlugins_Pipeline_Parameters_ConfigureList( OpenFileName );
+      cpPlugins_Pipeline_Parameters_ConfigureList( SaveFileName );
+      cpPlugins_Pipeline_Parameters_ConfigureList( PathName );
+
+      cpPlugins_Pipeline_Parameters_GetSet( Bool );
+      cpPlugins_Pipeline_Parameters_GetSet( Int );
+      cpPlugins_Pipeline_Parameters_GetSet( Uint );
+      cpPlugins_Pipeline_Parameters_GetSet( Real );
+      cpPlugins_Pipeline_Parameters_GetSet( OpenFileName );
+      cpPlugins_Pipeline_Parameters_GetSet( SaveFileName );
+      cpPlugins_Pipeline_Parameters_GetSet( PathName );
+
+      cpPlugins_Pipeline_Parameters_GetSetList( String );
+      cpPlugins_Pipeline_Parameters_GetSetList( Bool );
+      cpPlugins_Pipeline_Parameters_GetSetList( Int );
+      cpPlugins_Pipeline_Parameters_GetSetList( Uint );
+      cpPlugins_Pipeline_Parameters_GetSetList( Real );
+      cpPlugins_Pipeline_Parameters_GetSetList( OpenFileName );
+      cpPlugins_Pipeline_Parameters_GetSetList( SaveFileName );
+      cpPlugins_Pipeline_Parameters_GetSetList( PathName );
+
+    public:
+      Parameters( );
+      virtual ~Parameters( );
+
+      ProcessObject* GetProcessObject( );
+      const ProcessObject* GetProcessObject( ) const;
+      void SetProcessObject( ProcessObject* po );
+      virtual void Modified( ) const;
+
+      // Parameters container configuration
+      void Clear( );
+
+      // Get methods
+      void GetNames( std::vector< std::string >& container ) const;
+      Type GetType( const std::string& name ) const;
+      std::string GetTypeAsString( const std::string& name ) const;
+      static Type GetTypeFromString( const std::string& t );
+
+      // Base string methods
+      std::string GetString(
+        const std::string& name, bool force = true
+        ) const;
+      void SetString(
+        const std::string& name, const std::string& v, bool force = true
+        );
+
+      void ConfigureAsChoices(
+        const std::string& name, const std::vector< std::string >& choices
+        );
+      void ConfigureAsRealTypesChoices( const std::string& name );
+      void ConfigureAsIntTypesChoices( const std::string& name );
+      void ConfigureAsScalarTypesChoices( const std::string& name );
+      std::vector< std::string > GetChoices( const std::string& name ) const;
+      std::string GetSelectedChoice( const std::string& name ) const;
+      bool SetSelectedChoice(
+        const std::string& name, const std::string& choice
+        );
+
+      std::string GetAcceptedFileExtensions( const std::string& name ) const;
+      void SetAcceptedFileExtensions(
+        const std::string& name, const std::string& extensions
+        );
+
+    protected:
+      TParameters& GetRawParameters( );
+      const TParameters& GetRawParameters( ) const;
+
+      template< unsigned int _Enum >
+      inline void _Configure( const std::string& name );
+
+      template< unsigned int _Enum >
+      inline bool _Has( const std::string& name ) const;
+
+      template< class _Type, unsigned int _Enum >
+      inline _Type _Get( const std::string& name ) const;
+
+      template< class _Type, unsigned int _Enum >
+      inline void _Set( const std::string& name, const _Type& v );
+
+      template< class _Type, unsigned int _Enum >
+      inline std::vector< _Type > _GetList( const std::string& name ) const;
+
+      template< class _Type, unsigned int _Enum >
+      inline void _AddToList( const std::string& name, const _Type& v );
+
+      template< unsigned int _Enum >
+      inline void _ClearList( const std::string& name );
+
+    private:
+      // Purposely not implemented
+      Parameters( const Self& other );
+      Self& operator=( const Self& other );
+
+    protected:
+      ProcessObject*                       m_ProcessObject;
+      TParameters                          m_Parameters;
+      std::map< std::string, std::string > m_AcceptedFileExtensions;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#endif // __cpPlugins__Pipeline__Parameters__h__
+
+// eof - $RCSfile$
diff --git a/lib/cpPlugins/Pipeline/ProcessObject.h b/lib/cpPlugins/Pipeline/ProcessObject.h
new file mode 100644 (file)
index 0000000..da90921
--- /dev/null
@@ -0,0 +1,46 @@
+/* =========================================================================
+ * @author ??? (???@javeriana.edu.co)
+ * @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+ * =========================================================================
+ */
+#ifndef __cpPlugins__Pipeline__ProcessObject__h__
+#define __cpPlugins__Pipeline__ProcessObject__h__
+
+#include <cpPlugins/Pipeline/Object.h>
+
+namespace cpPlugins
+{
+  namespace Pipeline
+  {
+    /**
+     */
+    class ProcessObject
+      : public cpPlugins::Pipeline::Object< void* >
+    {
+    public:
+      typedef Object Self;
+      typedef cpPlugins::Pipeline::Object< void* > Superclass;
+      typedef Superclass::TDecorated TDecorated;
+
+    public:
+      ProcessObject( );
+      virtual ~ProcessObject( );
+
+      virtual void Modified( ) const = 0;
+
+    private:
+      // Purposely not implemented
+      Object( const Self& );
+      Self& operator=( const Self& );
+
+    protected:
+      bool m_IsVTK;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#endif // __cpPlugins__Pipeline__ProcessObject__h__
+
+// eof - $RCSfile$
diff --git a/lib/cpPlugins/Utils/ExpandTemplates.cxx b/lib/cpPlugins/Utils/ExpandTemplates.cxx
new file mode 100644 (file)
index 0000000..37442b6
--- /dev/null
@@ -0,0 +1,178 @@
+/* =========================================================================
+ * @author Ricardo Montano-Barrera  (@javeriana.edu.co)
+ * @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+ * =========================================================================
+ */
+#include <cpPlugins/Utils/ExpandTemplates.h>
+#include <fstream>
+#include <sstream>
+#include <stdexcept>
+
+// -------------------------------------------------------------------------
+cpPlugins::Utils::ExpandTemplates::
+ExpandTemplates( )
+{
+}
+
+// -------------------------------------------------------------------------
+cpPlugins::Utils::ExpandTemplates::
+~ExpandTemplates( )
+{
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Utils::ExpandTemplates::
+Parse( const std::string& filename )
+{
+  // Load file in a string buffer
+  std::ifstream input( filename.c_str( ) );
+  if( !input )
+    throw std::runtime_error( "Unable to parse file \"" + filename + "\"" );
+  typedef std::istreambuf_iterator< char > _TIt;
+  std::istringstream buffer( std::string( ( _TIt( input ) ), _TIt( ) ) );
+  input.close( );
+
+  // Read line by line
+  TStringsMapQueue patterns;
+  TStrings lines;
+  Self::_ReadLines( &buffer, patterns, lines );
+
+  // Parse patterns
+  Self::_ParsePatterns( patterns, this->m_Patterns );
+
+  // Expand lines
+  this->m_Lines.clear( );
+  for( std::string line: lines )
+    Self::_Expand( this->m_Lines, line, this->m_Patterns );
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Utils::ExpandTemplates::
+Save( const std::string& filename )
+{
+  // Fill buffer
+  std::stringstream buffer;
+  for( std::string line: this->m_Lines )
+    buffer << line << std::endl;
+
+  // Save buffer to file
+  std::ofstream output( filename.c_str( ) );
+  if( !output )
+    throw std::runtime_error( "Unable to save file \"" + filename + "\"" );
+  output << buffer.str( );
+  output.close( );
+}
+
+// -------------------------------------------------------------------------
+std::string cpPlugins::Utils::ExpandTemplates::
+_Replace( const std::string& s, const std::string& f, const std::string& t )
+{
+  std::string r = s;
+  size_t p = r.find( f );
+  while( p != std::string::npos )
+  {
+    r.replace( p, f.length( ), t );
+    p = r.find( f );
+
+  } // elihw
+  return( r );
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Utils::ExpandTemplates::
+_ReadLines( std::istream* str, TStringsMapQueue& patterns, TStrings& lines )
+{
+  std::string line;
+  while( std::getline( *str, line ) )
+  {
+    std::size_t f = line.find_first_not_of( " \t\r\n" );
+    if( f != std::string::npos )
+    {
+      if( line[ f ] == '@' )
+      {
+        // New injection mark
+        std::string mark;
+        std::size_t s = line.find( "=" );
+        mark = line.substr( f, s ) + "@";
+        TStringsMapValue m( mark, TStrings( ) );
+        std::istringstream v( line.substr( s + 1 ) );
+        std::string t;
+        while( std::getline( v, t, ';' ) )
+          m.second.push_back( t );
+        patterns.push( m );
+      }
+      else
+        lines.push_back( line );
+    }
+    else
+      lines.push_back( line );
+
+  } // elihw
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Utils::ExpandTemplates::
+_ParsePatterns( TStringsMapQueue& q, TStringsMap& patterns )
+{
+  patterns.clear( );
+  while( q.size( ) > 0 )
+  {
+    TStringsMapValue p = q.front( );
+    q.pop( );
+
+    bool requeue = false;
+    TStrings new_v;
+    for( std::string v: p.second )
+    {
+      size_t s = v.find( "@" );
+      if( s != std::string::npos )
+      {
+        size_t e = v.find( "@", s + 1 );
+        if( e == std::string::npos )
+          throw std::runtime_error( "Invalid syntax: " + v );
+        std::string m = v.substr( s, e - s + 1 );
+        TStringsMap::const_iterator pIt = patterns.find( m );
+        if( pIt != patterns.end( ) )
+          for( std::string w: pIt->second )
+            new_v.push_back( Self::_Replace( v, m, w ) );
+        requeue = true;
+
+      } // fi
+
+    } // rof
+    if( requeue )
+    {
+      if( new_v.size( ) > 0 )
+        p.second = new_v;
+      q.push( p );
+    }
+    else
+      patterns.insert( p );
+
+  } // elihw
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Utils::ExpandTemplates::
+_Expand(
+  TStrings& expands, const std::string& line, const TStringsMap& patterns
+  )
+{
+  size_t s = line.find( "@" );
+  if( s != std::string::npos )
+  {
+    size_t e = line.find( "@", s + 1 );
+    if( e == std::string::npos )
+      throw std::runtime_error( "Invalid syntax: " + line );
+    std::string mark = line.substr( s, e - s + 1 );
+    TStringsMap::const_iterator pIt = patterns.find( mark );
+    if( pIt == patterns.end( ) )
+      throw std::runtime_error( "Unknown mark: " + mark );
+    for( std::string value: pIt->second )
+      Self::_Expand( expands, Self::_Replace( line, mark, value ), patterns );
+  }
+  else
+    expands.push_back( line );
+}
+
+// eof - $RCSfile$
diff --git a/lib/cpPlugins/Utils/ExpandTemplates.h b/lib/cpPlugins/Utils/ExpandTemplates.h
new file mode 100644 (file)
index 0000000..ee98713
--- /dev/null
@@ -0,0 +1,61 @@
+/* =========================================================================
+ * @author Ricardo Montano-Barrera  (@javeriana.edu.co)
+ * @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+ * =========================================================================
+ */
+#ifndef __cpPlugins__Utils__ExpandTemplates__h__
+#define __cpPlugins__Utils__ExpandTemplates__h__
+
+#include <map>
+#include <queue>
+#include <string>
+#include <vector>
+#include <cpPlugins/cpplugins_export.h>
+
+namespace cpPlugins
+{
+  namespace Utils
+  {
+    /**
+     */
+    class CPPLUGINS_EXPORT ExpandTemplates
+    {
+    private:
+      typedef ExpandTemplates                   Self;
+      typedef std::vector< std::string >        TStrings;
+      typedef std::map< std::string, TStrings > TStringsMap;
+      typedef TStringsMap::value_type           TStringsMapValue;
+      typedef std::queue< TStringsMapValue >    TStringsMapQueue;
+
+    public:
+      ExpandTemplates( );
+      virtual ~ExpandTemplates( );
+
+      void Parse( const std::string& filename );
+      void Save( const std::string& filename );
+
+    protected:
+      static std::string _Replace(
+        const std::string& s, const std::string& f, const std::string& t
+        );
+      static void _ReadLines(
+        std::istream* str, TStringsMapQueue& patterns, TStrings& lines
+        );
+      static void _ParsePatterns( TStringsMapQueue& q, TStringsMap& patterns );
+      static void _Expand(
+        TStrings& expands,
+        const std::string& line, const TStringsMap& patterns
+        );
+
+    private:
+      TStringsMap m_Patterns;
+      TStrings    m_Lines;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#endif // __cpPlugins__Utils__ExpandTemplates__h__
+
+// eof - $RCSfile$
diff --git a/lib/cpPlugins/Version.cxx.in b/lib/cpPlugins/Version.cxx.in
new file mode 100644 (file)
index 0000000..ea3c9ad
--- /dev/null
@@ -0,0 +1,7 @@
+
+#include <cpPlugins/cpplugins_export.h>
+#include <string>
+
+std::string CPPLUGINS_EXPORT version( ) { return( "@prj_VER@" ); }
+
+// eof - $RCSfile$
diff --git a/lib/ivq/CMakeLists.txt b/lib/ivq/CMakeLists.txt
new file mode 100644 (file)
index 0000000..1a55abc
--- /dev/null
@@ -0,0 +1,25 @@
+## =========================================================================
+## @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+## =========================================================================
+
+option(BUILD_ivq "Build ITK/VTK/Qt extensions." OFF)
+if(BUILD_ivq)
+
+  ## -- Set directories
+  set(_dirs . ITK)
+  if(${cpPlugins_USE_VTK} EQUAL 1)
+    list(APPEND _dirs VTK)
+  endif(${cpPlugins_USE_VTK} EQUAL 1)
+  if(${cpPlugins_USE_Qt5} EQUAL 1)
+    list(APPEND _dirs Qt)
+  endif(${cpPlugins_USE_Qt5} EQUAL 1)
+
+  ## -- Build
+  BuildLibrary(
+    ivq SHARED "${_dirs}"
+    ${prj_MAJ} ${prj_MIN} ${prj_REL}
+    ${ITK_LIBRARIES} ${VTK_LIBRARIES}
+    )
+endif(BUILD_ivq)
+
+## eof - $RCSfile$
diff --git a/lib/ivq/Config.h.in b/lib/ivq/Config.h.in
new file mode 100644 (file)
index 0000000..46a0144
--- /dev/null
@@ -0,0 +1,20 @@
+/* =========================================================================
+ * @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+ * =========================================================================
+ */
+#ifndef __ivq__Config__h__
+#define __ivq__Config__h__
+
+#include <ivq/ivq_export.h>
+
+#if @cpPlugins_USE_VTK@ == 1
+#  define ivq_USE_VTK
+#endif // @cpPlugins_USE_VTK@ == 1
+
+#if @cpPlugins_USE_Qt5@ == 1
+#  define ivq_USE_Qt5
+#endif // @cpPlugins_USE_Qt5@ == 1
+
+#endif // __ivq__Config__h__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/BooleanMapSaliencyFunction.h b/lib/ivq/ITK/BooleanMapSaliencyFunction.h
new file mode 100644 (file)
index 0000000..ce39ede
--- /dev/null
@@ -0,0 +1,81 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__ITK__BooleanMapSaliencyFunction__h__
+#define __ivq__ITK__BooleanMapSaliencyFunction__h__
+
+#include <set>
+
+#include <itkConceptChecking.h>
+#include <itkFunctionBase.h>
+
+namespace ivq
+{
+  namespace ITK
+  {
+    /**
+     */
+    template< class _TIn, class _TOut >
+    class BooleanMapSaliencyFunction
+      : public itk::FunctionBase< _TIn, _TOut >
+    {
+    public:
+      typedef BooleanMapSaliencyFunction       Self;
+      typedef itk::FunctionBase< _TIn, _TOut > Superclass;
+      typedef itk::SmartPointer< Self >        Pointer;
+      typedef itk::SmartPointer< const Self >  ConstPointer;
+
+      typedef typename Superclass::InputType  TInput;
+      typedef typename Superclass::OutputType TOutput;
+
+    public:
+      itkNewMacro( Self );
+      itkTypeMacro( ivq::ITK::BooleanMapSaliencyFunction, itk::FunctionBase );
+
+      itkBooleanMacro( UseBoundedThresholds );
+      itkGetConstMacro( UseBoundedThresholds, bool );
+      itkSetMacro( UseBoundedThresholds, bool );
+
+      // Concepts
+      itkConceptMacro( Concept0, ( itk::Concept::IsFloatingPoint< _TOut > ) );
+
+    public:
+      virtual _TOut Evaluate( const _TIn& in ) const override;
+
+      unsigned int GetNumberOfThresholds( ) const;
+      void ClearThresholds( );
+      void AddThreshold( const _TIn& v );
+      void AddThresholds(
+        const _TIn& v_min,
+        const _TIn& v_max,
+        const _TIn& v_delta
+        );
+
+    protected:
+      BooleanMapSaliencyFunction( );
+      virtual ~BooleanMapSaliencyFunction( );
+
+    private:
+      // Purposely not implemented
+      BooleanMapSaliencyFunction( const Self& other );
+      Self& operator=( const Self& other );
+
+    protected:
+      std::set< _TIn > m_Thresholds;
+      bool m_UseBoundedThresholds;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#  include <ivq/ITK/BooleanMapSaliencyFunction.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __ivq__ITK__BooleanMapSaliencyFunction__h__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/BooleanMapSaliencyFunction.hxx b/lib/ivq/ITK/BooleanMapSaliencyFunction.hxx
new file mode 100644 (file)
index 0000000..8084ac1
--- /dev/null
@@ -0,0 +1,92 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__ITK__BooleanMapSaliencyFilter__hxx__
+#define __ivq__ITK__BooleanMapSaliencyFilter__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TIn, class _TOut >
+_TOut ivq::ITK::BooleanMapSaliencyFunction< _TIn, _TOut >::
+Evaluate( const _TIn& in ) const
+{
+  bool stop = false;
+  unsigned long count = 0;
+  if( this->m_UseBoundedThresholds )
+  {
+    _TIn lower = *( this->m_Thresholds.begin( ) );
+    _TIn upper = *( this->m_Thresholds.rbegin( ) );
+    stop = ( in < lower || in > upper );
+
+  } // fi
+  typename std::set< _TIn >::const_iterator i = this->m_Thresholds.begin( );
+  while( i != this->m_Thresholds.end( ) && !stop )
+  {
+    stop = ( in < *i );
+    count += ( !stop )? 1: 0;
+    ++i;
+
+  } // elihw
+  return( _TOut( double( count ) / double( this->m_Thresholds.size( ) ) ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TIn, class _TOut >
+unsigned int ivq::ITK::BooleanMapSaliencyFunction< _TIn, _TOut >::
+GetNumberOfThresholds( ) const
+{
+  return( this->m_Thresholds.size( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TIn, class _TOut >
+void ivq::ITK::BooleanMapSaliencyFunction< _TIn, _TOut >::
+ClearThresholds( )
+{
+  if( this->m_Thresholds.size( ) > 0 )
+  {
+    this->m_Thresholds.clear( );
+    this->Modified( );
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TIn, class _TOut >
+void ivq::ITK::BooleanMapSaliencyFunction< _TIn, _TOut >::
+AddThreshold( const _TIn& v )
+{
+  if( this->m_Thresholds.insert( v ).second )
+    this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TIn, class _TOut >
+void ivq::ITK::BooleanMapSaliencyFunction< _TIn, _TOut >::
+AddThresholds( const _TIn& v_min, const _TIn& v_max, const _TIn& v_delta )
+{
+  for( _TIn v = v_min; v <= v_max; v += v_delta )
+    this->AddThreshold( v );
+}
+
+// -------------------------------------------------------------------------
+template< class _TIn, class _TOut >
+ivq::ITK::BooleanMapSaliencyFunction< _TIn, _TOut >::
+BooleanMapSaliencyFunction( )
+  : Superclass( ),
+    m_UseBoundedThresholds( false )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TIn, class _TOut >
+ivq::ITK::BooleanMapSaliencyFunction< _TIn, _TOut >::
+~BooleanMapSaliencyFunction( )
+{
+}
+
+#endif // __ivq__ITK__BooleanMapSaliencyFilter__hxx__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/CPRImageFilter.h b/lib/ivq/ITK/CPRImageFilter.h
new file mode 100644 (file)
index 0000000..6d42fa0
--- /dev/null
@@ -0,0 +1,84 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__ITK__CPRImageFilter__h__
+#define __ivq__ITK__CPRImageFilter__h__
+
+#include <vector>
+
+#include <itkImageToImageFilter.h>
+#include <itkJoinSeriesImageFilter.h>
+
+#include <ivq/ITK/IsoImageSlicer.h>
+
+namespace ivq
+{
+  namespace ITK
+  {
+    /**
+     */
+    template< class _TImage, class _TCurve >
+    class CPRImageFilter
+      : public itk::ImageToImageFilter< _TImage, _TImage >
+    {
+    public:
+      typedef CPRImageFilter                              Self;
+      typedef itk::ImageToImageFilter< _TImage, _TImage > Superclass;
+      typedef itk::SmartPointer< Self >                   Pointer;
+      typedef itk::SmartPointer< const Self >             ConstPointer;
+
+      typedef _TImage TImage;
+      typedef _TCurve TCurve;
+      typedef typename TCurve::TScalar TScalar;
+
+      typedef ivq::ITK::IsoImageSlicer< TImage, TScalar > TSlicer;
+      typedef typename TSlicer::TInterpolateFunction      TInterpolateFunction;
+      typedef typename TSlicer::TSliceImage               TSliceImage;
+
+      typedef itk::JoinSeriesImageFilter< TSliceImage, TImage > TJoinFilter;
+
+    public:
+      itkNewMacro( Self );
+      itkTypeMacro( CPRImageFilter, itk::ImageToImageFilter );
+
+      itkGetConstMacro( SliceRadius, double );
+      itkGetObjectMacro( Interpolator, TInterpolateFunction );
+
+      itkSetMacro( SliceRadius, double );
+      itkSetObjectMacro( Interpolator, TInterpolateFunction );
+
+    public:
+      _TCurve* GetCurve( );
+      const _TCurve* GetCurve( ) const;
+      void SetCurve( _TCurve* curve );
+
+    protected:
+      CPRImageFilter( );
+      virtual ~CPRImageFilter( );
+
+      virtual void GenerateOutputInformation( ) override;
+      virtual void GenerateInputRequestedRegion( ) override;
+      virtual void GenerateData( ) override;
+
+    protected:
+      double m_SliceRadius;
+      typename TInterpolateFunction::Pointer m_Interpolator;
+
+      std::vector< typename TSlicer::Pointer > m_Slicers;
+      typename TJoinFilter::Pointer            m_Join;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#  include <ivq/ITK/CPRImageFilter.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __ivq__ITK__CPRImageFilter__h__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/CPRImageFilter.hxx b/lib/ivq/ITK/CPRImageFilter.hxx
new file mode 100644 (file)
index 0000000..346cc0a
--- /dev/null
@@ -0,0 +1,133 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__ITK__CPRImageFilter__hxx__
+#define __ivq__ITK__CPRImageFilter__hxx__
+
+#include <itkMinimumMaximumImageCalculator.h>
+
+// -------------------------------------------------------------------------
+template< class _TImage, class _TCurve >
+_TCurve* ivq::ITK::CPRImageFilter< _TImage, _TCurve >::
+GetCurve( )
+{
+  return(
+    dynamic_cast< _TCurve* >( this->itk::ProcessObject::GetInput( 1 ) )
+    );
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage, class _TCurve >
+const _TCurve* ivq::ITK::CPRImageFilter< _TImage, _TCurve >::
+GetCurve( ) const
+{
+  return(
+    dynamic_cast< const _TCurve* >( this->itk::ProcessObject::GetInput( 1 ) )
+    );
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage, class _TCurve >
+void ivq::ITK::CPRImageFilter< _TImage, _TCurve >::
+SetCurve( _TCurve* curve )
+{
+  this->itk::ProcessObject::SetNthInput( 1, curve );
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage, class _TCurve >
+ivq::ITK::CPRImageFilter< _TImage, _TCurve >::
+CPRImageFilter( )
+  : Superclass( ),
+    m_SliceRadius( 0 )
+{
+  this->Superclass::SetNumberOfRequiredInputs( 2 );
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage, class _TCurve >
+ivq::ITK::CPRImageFilter< _TImage, _TCurve >::
+~CPRImageFilter( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage, class _TCurve >
+void ivq::ITK::CPRImageFilter< _TImage, _TCurve >::
+GenerateOutputInformation( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage, class _TCurve >
+void ivq::ITK::CPRImageFilter< _TImage, _TCurve >::
+GenerateInputRequestedRegion( )
+{
+  TImage* input = const_cast< TImage* >( this->GetInput( ) );
+  if( input != NULL )
+    input->SetRequestedRegionToLargestPossibleRegion( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage, class _TCurve >
+void ivq::ITK::CPRImageFilter< _TImage, _TCurve >::
+GenerateData( )
+{
+  typedef itk::MinimumMaximumImageCalculator< _TImage > _TMinMax;
+
+  const _TImage* input = this->GetInput( );
+  const _TCurve* curve = this->GetCurve( );
+  _TImage* output = this->GetOutput( );
+
+  // Compute image intensity range
+  typename _TMinMax::Pointer minmax = _TMinMax::New( );
+  minmax->SetImage( input );
+  minmax->Compute( );
+
+  // Main loop
+  this->m_Join = TJoinFilter::New( );
+  this->m_Slicers.clear( );
+  unsigned long N = curve->GetNumberOfPoints( );
+  double len = 0;
+  typename _TCurve::TPoint p, q;
+  for( unsigned long n = 0; n < N; ++n )
+  {
+    p = curve->GetPoint( n );
+    if( n > 0 )
+      len += p.EuclideanDistanceTo( q );
+    q = p;
+
+    // Prepare slicer
+    typename TSlicer::Pointer slicer = TSlicer::New( );
+    slicer->SetInput( input );
+    slicer->SetDefaultValue( minmax->GetMinimum( ) );
+    slicer->SpacingFromMinimumOn( );
+    if( this->m_Interpolator.IsNotNull( ) )
+      slicer->SetInterpolator( this->m_Interpolator );
+    slicer->SizeFromMaximumOff( );
+    if( this->m_SliceRadius > double( 0 ) )
+    {
+      slicer->SizeFromMinimumOff( );
+      slicer->SetSize( this->m_SliceRadius );
+    }
+    else
+      slicer->SizeFromMinimumOn( );
+    slicer->SetTranslation( p );
+    slicer->SetRotation( curve->GetFrame( n ) );
+    slicer->Update( );
+
+    this->m_Join->SetInput( n, slicer->GetOutput( ) );
+    this->m_Slicers.push_back( slicer );
+
+  } // rof
+  this->m_Join->SetSpacing( len / double( N ) );
+  this->m_Join->Update( );
+  this->GetOutput( )->Graft( this->m_Join->GetOutput( ) );
+}
+
+#endif // __ivq__ITK__CPRImageFilter__hxx__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/ExtractLabelFunction.h b/lib/ivq/ITK/ExtractLabelFunction.h
new file mode 100644 (file)
index 0000000..bd9f70b
--- /dev/null
@@ -0,0 +1,73 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__ITK__ExtractLabelFunction__h__
+#define __ivq__ITK__ExtractLabelFunction__h__
+
+#include <set>
+
+#include <itkFunctionBase.h>
+
+namespace ivq
+{
+  namespace ITK
+  {
+    /**
+     */
+    template< class _TIn, class _TOut >
+    class ExtractLabelFunction
+      : public itk::FunctionBase< _TIn, _TOut >
+    {
+    public:
+      typedef ExtractLabelFunction             Self;
+      typedef itk::FunctionBase< _TIn, _TOut > Superclass;
+      typedef itk::SmartPointer< Self >        Pointer;
+      typedef itk::SmartPointer< const Self >  ConstPointer;
+
+      typedef typename Superclass::InputType  TInput;
+      typedef typename Superclass::OutputType TOutput;
+
+    public:
+      itkNewMacro( Self );
+      itkTypeMacro( ivq::ITK::ExtractLabelFunction, itk::FunctionBase );
+
+      itkGetConstMacro( Label, _TIn );
+      itkGetConstMacro( InsideValue, _TOut );
+      itkGetConstMacro( OutsideValue, _TOut );
+
+      itkSetMacro( Label, _TIn );
+      itkSetMacro( InsideValue, _TOut );
+      itkSetMacro( OutsideValue, _TOut );
+
+    public:
+      virtual _TOut Evaluate( const _TIn& in ) const override;
+
+    protected:
+      ExtractLabelFunction( );
+      virtual ~ExtractLabelFunction( );
+
+    private:
+      // Purposely not implemented
+      ExtractLabelFunction( const Self& other );
+      Self& operator=( const Self& other );
+
+    protected:
+      _TIn  m_Label;
+      _TOut m_InsideValue;
+      _TOut m_OutsideValue;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#  include <ivq/ITK/ExtractLabelFunction.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __ivq__ITK__ExtractLabelFunction__h__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/ExtractLabelFunction.hxx b/lib/ivq/ITK/ExtractLabelFunction.hxx
new file mode 100644 (file)
index 0000000..1f009cf
--- /dev/null
@@ -0,0 +1,40 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__ITK__ExtractLabelFunction__hxx__
+#define __ivq__ITK__ExtractLabelFunction__hxx__
+
+#include <limits>
+
+// -------------------------------------------------------------------------
+template< class _TIn, class _TOut >
+_TOut ivq::ITK::ExtractLabelFunction< _TIn, _TOut >::
+Evaluate( const _TIn& in ) const
+{
+  return( ( in == this->m_Label )? this->m_InsideValue: this->m_OutsideValue );
+}
+
+// -------------------------------------------------------------------------
+template< class _TIn, class _TOut >
+ivq::ITK::ExtractLabelFunction< _TIn, _TOut >::
+ExtractLabelFunction( )
+  : Superclass( ),
+    m_Label( _TIn( 0 ) ),
+    m_InsideValue( std::numeric_limits< _TOut >::max( ) ),
+    m_OutsideValue( _TOut( 0 ) )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TIn, class _TOut >
+ivq::ITK::ExtractLabelFunction< _TIn, _TOut >::
+~ExtractLabelFunction( )
+{
+}
+
+#endif // __ivq__ITK__ExtractLabelFunction__hxx__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/ImageROIFromFunction.h b/lib/ivq/ITK/ImageROIFromFunction.h
new file mode 100644 (file)
index 0000000..6aef0f9
--- /dev/null
@@ -0,0 +1,83 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__ITK__ImageROIFromFunction__h__
+#define __ivq__ITK__ImageROIFromFunction__h__
+
+#include <itkFunctionBase.h>
+#include <itkObject.h>
+
+namespace ivq
+{
+  namespace ITK
+  {
+    /**
+     */
+    template< class _TImage >
+    class ImageROIFromFunction
+      : public itk::Object
+    {
+    public:
+      typedef ImageROIFromFunction            Self;
+      typedef itk::Object                     Superclass;
+      typedef itk::SmartPointer< Self >       Pointer;
+      typedef itk::SmartPointer< const Self > ConstPointer;
+
+      typedef _TImage TImage;
+      typedef typename TImage::IndexType  TIndex;
+      typedef typename TImage::PixelType  TPixel;
+      typedef typename TImage::RegionType TRegion;
+
+      typedef itk::FunctionBase< TPixel, bool > TFunction;
+
+    public:
+      itkNewMacro( Self );
+      itkTypeMacro( ivq::ITK::ImageROIFromFunction, itk::Object );
+
+      itkGetConstObjectMacro( Image, TImage );
+      itkSetConstObjectMacro( Image, TImage );
+
+      itkGetObjectMacro( Function, TFunction );
+      itkGetConstObjectMacro( Function, TFunction );
+      itkSetObjectMacro( Function, TFunction );
+
+      itkGetConstMacro( Padding, unsigned int );
+      itkSetMacro( Padding, unsigned int );
+
+      itkGetConstReferenceMacro( ROI, TRegion );
+
+    public:
+      virtual void Modified( ) const override;
+      virtual void Compute( );
+
+    protected:
+      ImageROIFromFunction( );
+      virtual ~ImageROIFromFunction( );
+
+    private:
+      // Purposely not implemented
+      ImageROIFromFunction( Self& other );
+      Self& operator=( Self& other );
+
+    protected:
+      typename TImage::ConstPointer m_Image;
+      typename TFunction::Pointer   m_Function;
+      unsigned int m_Padding;
+      TRegion      m_ROI;
+      mutable bool m_ROIUpdated;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#  include <ivq/ITK/ImageROIFromFunction.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __ivq__ITK__ImageROIFromFunction__h__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/ImageROIFromFunction.hxx b/lib/ivq/ITK/ImageROIFromFunction.hxx
new file mode 100644 (file)
index 0000000..d7ba4e3
--- /dev/null
@@ -0,0 +1,99 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__ITK__ImageROIFromFunction__hxx__
+#define __ivq__ITK__ImageROIFromFunction__hxx__
+
+#include <itkImageRegionConstIteratorWithIndex.h>
+
+// -------------------------------------------------------------------------
+template< class _TImage >
+void ivq::ITK::ImageROIFromFunction< _TImage >::
+Modified( ) const
+{
+  this->Superclass::Modified( );
+  this->m_ROIUpdated = false;
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage >
+void ivq::ITK::ImageROIFromFunction< _TImage >::
+Compute( )
+{
+  if( this->m_ROIUpdated || this->m_Image.IsNull( ) )
+    return;
+  if( this->m_Function.IsNotNull( ) )
+  {
+    // Initialize bounds
+    TRegion in_region = this->m_Image->GetRequestedRegion( );
+    TIndex iMin = in_region.GetIndex( );
+    TIndex iMax = iMin + in_region.GetSize( );
+    for( unsigned int d = 0; d < TImage::ImageDimension; ++d )
+      iMax[ d ] -= 1;
+
+    // Compute bounds
+    typedef itk::ImageRegionConstIteratorWithIndex< TImage > _TIt;
+    _TIt it( this->m_Image, in_region );
+    TIndex i0 = iMax;
+    TIndex i1 = iMin;
+    for( it.GoToBegin( ); !it.IsAtEnd( ); ++it )
+    {
+      if( this->m_Function->Evaluate( it.Get( ) ) )
+      {
+        TIndex i = it.GetIndex( );
+        for( unsigned int d = 0; d < TImage::ImageDimension; ++d )
+        {
+          i0[ d ] = ( i[ d ] < i0[ d ] )? i[ d ]: i0[ d ];
+          i1[ d ] = ( i1[ d ] < i[ d ] )? i[ d ]: i1[ d ];
+
+        } // rof
+
+      } // fi
+
+    } // rof
+
+    // Apply padding
+    for( unsigned int d = 0; d < TImage::ImageDimension; ++d )
+    {
+      i0[ d ] -= this->m_Padding;
+      i1[ d ] += this->m_Padding;
+      i0[ d ] = ( i0[ d ] < iMin[ d ] )? iMin[ d ]: i0[ d ];
+      i1[ d ] = ( iMax[ d ] < i1[ d ] )? iMax[ d ]: i1[ d ];
+
+    } // rof
+
+    // Create new ROI
+    typename TImage::SizeType roi_size;
+    for( unsigned int d = 0; d < TImage::ImageDimension; ++d )
+      roi_size[ d ] = i1[ d ] - i0[ d ] + 1;
+    this->m_ROI.SetIndex( i0 );
+    this->m_ROI.SetSize( roi_size );
+  }
+  else
+    this->m_ROI = this->m_Image->GetRequestedRegion( );
+  this->m_ROIUpdated = true;
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage >
+ivq::ITK::ImageROIFromFunction< _TImage >::
+ImageROIFromFunction( )
+  : Superclass( ),
+    m_Padding( 0 ),
+    m_ROIUpdated( false )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage >
+ivq::ITK::ImageROIFromFunction< _TImage >::
+~ImageROIFromFunction( )
+{
+}
+
+#endif // __ivq__ITK__ImageROIFromFunction__hxx__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/ImageStatisticsFromSeeds.h b/lib/ivq/ITK/ImageStatisticsFromSeeds.h
new file mode 100644 (file)
index 0000000..c9c24f1
--- /dev/null
@@ -0,0 +1,82 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__ITK__ImageStatisticsFromSeeds__h__
+#define __ivq__ITK__ImageStatisticsFromSeeds__h__
+
+#include <set>
+#include <itkObject.h>
+
+namespace ivq
+{
+  namespace ITK
+  {
+    /**
+     */
+    template< class _TImage >
+    class ImageStatisticsFromSeeds
+      : public itk::Object
+    {
+    public:
+      typedef itk::Object                     Superclass;
+      typedef ImageStatisticsFromSeeds        Self;
+      typedef itk::SmartPointer< Self >       Pointer;
+      typedef itk::SmartPointer< const Self > ConstPointer;
+
+      typedef _TImage TImage;
+      typedef typename TImage::IndexType TIndex;
+
+      typedef typename TIndex::LexicographicCompare TIndexCompare;
+      typedef std::set< TIndex, TIndexCompare > TIndices;
+
+    public:
+      itkNewMacro( Self );
+      itkTypeMacro( ivq::ITK::ImageStatisticsFromSeeds, itk::Object );
+
+      itkGetConstObjectMacro( Image, TImage );
+      itkGetConstMacro( Indices, TIndices );
+      itkGetConstMacro( Mean, double );
+      itkGetConstMacro( Deviation, double );
+      itkGetConstMacro( Radius, unsigned int );
+
+      itkSetConstObjectMacro( Image, TImage );
+      itkSetMacro( Radius, unsigned int );
+
+    public:
+      unsigned int GetNumberOfIndices( ) const;
+      void ClearIndices( );
+      void AddIndex( const TIndex& i );
+      void RemoveIndex( const TIndex& i );
+      void Compute( );
+
+    protected:
+      ImageStatisticsFromSeeds( );
+      virtual ~ImageStatisticsFromSeeds( );
+
+    private:
+      // Purposely not implemented
+      ImageStatisticsFromSeeds( Self& other );
+      Self& operator=( Self& other );
+
+    protected:
+      typename TImage::ConstPointer m_Image;
+      TIndices     m_Indices;
+      double       m_Mean;
+      double       m_Deviation;
+      unsigned int m_Radius;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#  include <ivq/ITK/ImageStatisticsFromSeeds.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __ivq__ITK__ImageStatisticsFromSeeds__h__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/ImageStatisticsFromSeeds.hxx b/lib/ivq/ITK/ImageStatisticsFromSeeds.hxx
new file mode 100644 (file)
index 0000000..2bf9a10
--- /dev/null
@@ -0,0 +1,125 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__ITK__ImageStatisticsFromSeeds__hxx__
+#define __ivq__ITK__ImageStatisticsFromSeeds__hxx__
+
+#include <cmath>
+#include <itkConstNeighborhoodIterator.h>
+
+// -------------------------------------------------------------------------
+template< class _TImage >
+unsigned int ivq::ITK::ImageStatisticsFromSeeds< _TImage >::
+GetNumberOfIndices( ) const
+{
+  return( this->m_Indices.size( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage >
+void ivq::ITK::ImageStatisticsFromSeeds< _TImage >::
+ClearIndices( )
+{
+  this->m_Indices.clear( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage >
+void ivq::ITK::ImageStatisticsFromSeeds< _TImage >::
+AddIndex( const TIndex& i )
+{
+  this->m_Indices.insert( i );
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage >
+void ivq::ITK::ImageStatisticsFromSeeds< _TImage >::
+RemoveIndex( const TIndex& i )
+{
+  typename TIndices::iterator it = this->m_Indices.find( i );
+  if( it != this->m_Indices.end( ) )
+    this->m_Indices.erase( it );
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage >
+void ivq::ITK::ImageStatisticsFromSeeds< _TImage >::
+Compute( )
+{
+  // Some values
+  const TImage* img = this->m_Image;
+  typename TImage::RegionType reg = img->GetRequestedRegion( );
+
+  // Prepare iterator
+  typedef itk::ConstNeighborhoodIterator< TImage > _TIt;
+  typename TImage::SizeType rad;
+  rad.Fill( this->m_Radius );
+  _TIt nIt( rad, img, reg );
+  unsigned long nSize = 1;
+  for( unsigned int d = 0; d < TImage::ImageDimension; ++d )
+    nSize *= nIt.GetSize( d );
+
+  // Fill values
+  double s1 = double( 0 );
+  double s2 = double( 0 );
+  unsigned long N = 0;
+  typename TIndices::const_iterator idxIt = this->m_Indices.begin( );
+  for( ; idxIt != this->m_Indices.end( ); ++idxIt )
+  {
+    TIndex idx = *idxIt;
+    if( reg.IsInside( idx ) )
+    {
+      nIt.SetLocation( idx );
+      for( unsigned long i = 0; i < nSize; ++i )
+      {
+        double v = double( nIt.GetPixel( i ) );
+        s1 += v;
+        s2 += v * v;
+        N++;
+
+      } // rof
+
+    } // fi
+
+  } // rof
+
+  // Final computations
+  if( N > 0 )
+  {
+    double n = double( N );
+    this->m_Mean = s1 / n;
+    this->m_Deviation = std::sqrt( ( ( n * s2 ) - ( s1 * s1 ) ) / ( n * n ) );
+  }
+  else
+  {
+    this->m_Mean = double( 0 );
+    this->m_Deviation = double( 0 );
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage >
+ivq::ITK::ImageStatisticsFromSeeds< _TImage >::
+ImageStatisticsFromSeeds( )
+  : Superclass( ),
+    m_Image( NULL ),
+    m_Mean( double( 0 ) ),
+    m_Deviation( double( 0 ) ),
+    m_Radius( 0 )
+{
+}
+      
+// -------------------------------------------------------------------------
+template< class _TImage >
+ivq::ITK::ImageStatisticsFromSeeds< _TImage >::
+~ImageStatisticsFromSeeds( )
+{
+}
+
+#endif // __ivq__ITK__ImageStatisticsFromSeeds__hxx__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/ImageUnaryFunctionFilter.h b/lib/ivq/ITK/ImageUnaryFunctionFilter.h
new file mode 100644 (file)
index 0000000..2be71e6
--- /dev/null
@@ -0,0 +1,72 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__ITK__ImageUnaryFunctionFilter__h__
+#define __ivq__ITK__ImageUnaryFunctionFilter__h__
+
+#include <itkFunctionBase.h>
+#include <itkImageToImageFilter.h>
+
+namespace ivq
+{
+  namespace ITK
+  {
+    /**
+     */
+    template< class _TInImage, class _TOutImage >
+    class ImageUnaryFunctionFilter
+      : public itk::ImageToImageFilter< _TInImage, _TOutImage >
+    {
+    public:
+      typedef itk::ImageToImageFilter< _TInImage, _TOutImage > Superclass;
+      typedef ImageUnaryFunctionFilter                         Self;
+      typedef itk::SmartPointer< Self >                        Pointer;
+      typedef itk::SmartPointer< const Self >                  ConstPointer;
+
+      typedef _TInImage  TInImage;
+      typedef _TOutImage TOutImage;
+      typedef typename TInImage::PixelType   TInPixel;
+      typedef typename TOutImage::PixelType  TOutPixel;
+      typedef typename TOutImage::RegionType TRegion;
+
+      typedef itk::FunctionBase< TInPixel, TOutPixel > TFunction;
+
+    public:
+      itkNewMacro( Self );
+      itkTypeMacro(
+        ivq::ITK::ImageUnaryFunctionFilter, itk::ImageToImageFilter
+        );
+
+      itkGetObjectMacro( Function, TFunction );
+      itkGetConstObjectMacro( Function, TFunction );
+      itkSetObjectMacro( Function, TFunction );
+
+    protected:
+      ImageUnaryFunctionFilter( );
+      virtual ~ImageUnaryFunctionFilter( );
+
+      virtual void ThreadedGenerateData( const TRegion& region, itk::ThreadIdType threadId ) override;
+      
+    private:
+      // Purposely not implemented
+      ImageUnaryFunctionFilter( Self& other );
+      Self& operator=( Self& other );
+
+    protected:
+      typename TFunction::Pointer m_Function;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#  include <ivq/ITK/ImageUnaryFunctionFilter.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __ivq__ITK__ImageUnaryFunctionFilter__h__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/ImageUnaryFunctionFilter.hxx b/lib/ivq/ITK/ImageUnaryFunctionFilter.hxx
new file mode 100644 (file)
index 0000000..b90f73e
--- /dev/null
@@ -0,0 +1,67 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__ITK__ImageUnaryFunctionFilter__hxx__
+#define __ivq__ITK__ImageUnaryFunctionFilter__hxx__
+
+#include <itkImageScanlineConstIterator.h>
+#include <itkImageScanlineIterator.h>
+#include <itkProgressReporter.h>
+
+// -------------------------------------------------------------------------
+template< class _TInImage, class _TOutImage >
+ivq::ITK::ImageUnaryFunctionFilter< _TInImage, _TOutImage >::
+ImageUnaryFunctionFilter( )
+  : Superclass( )
+{
+}
+
+
+// -------------------------------------------------------------------------
+template< class _TInImage, class _TOutImage >
+ivq::ITK::ImageUnaryFunctionFilter< _TInImage, _TOutImage >::
+~ImageUnaryFunctionFilter( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TInImage, class _TOutImage >
+void ivq::ITK::ImageUnaryFunctionFilter< _TInImage, _TOutImage >::
+ThreadedGenerateData( const TRegion& region, itk::ThreadIdType threadId )
+{
+  // Configure data for this thread
+  const typename TRegion::SizeType& regionSize = region.GetSize( );
+  if( regionSize[ 0 ] == 0 )
+    return;
+  const TInImage* in = this->GetInput( );
+  TOutImage* out = this->GetOutput( 0 );
+  const size_t nLines = region.GetNumberOfPixels( ) / regionSize[ 0 ];
+  itk::ProgressReporter progress( this, threadId, nLines );
+
+  // Iterate over this region
+  itk::ImageScanlineConstIterator< _TInImage > iIt( in, region );
+  itk::ImageScanlineIterator< _TOutImage > oIt( out, region );
+  iIt.GoToBegin( );
+  oIt.GoToBegin( );
+  while( !iIt.IsAtEnd( ) )
+  {
+    while( !iIt.IsAtEndOfLine( ) )
+    {
+      oIt.Set( this->m_Function->Evaluate( iIt.Get( ) ) );
+      ++iIt;
+      ++oIt;
+
+    } // elihw
+    iIt.NextLine( );
+    oIt.NextLine( );
+    progress.CompletedPixel( );
+
+  } // elihw
+}
+
+#endif // __ivq__ITK__ImageUnaryFunctionFilter__hxx__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/IncrementalMeanAndVariance.cxx b/lib/ivq/ITK/IncrementalMeanAndVariance.cxx
new file mode 100644 (file)
index 0000000..eab1d28
--- /dev/null
@@ -0,0 +1,75 @@
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#include <ivq/ITK/IncrementalMeanAndVariance.h>
+#include <cmath>
+
+// -------------------------------------------------------------------------
+ivq::ITK::IncrementalMeanAndVariance::
+IncrementalMeanAndVariance( )
+{
+  this->Clear( );
+}
+
+// -------------------------------------------------------------------------
+ivq::ITK::IncrementalMeanAndVariance::
+~IncrementalMeanAndVariance( )
+{
+}
+
+// -------------------------------------------------------------------------
+double ivq::ITK::IncrementalMeanAndVariance::
+GetMean( ) const
+{
+  return( this->m_M );
+}
+
+// -------------------------------------------------------------------------
+double ivq::ITK::IncrementalMeanAndVariance::
+GetVariance( ) const
+{
+  return( this->m_V );
+}
+
+// -------------------------------------------------------------------------
+double ivq::ITK::IncrementalMeanAndVariance::
+GetDeviation( ) const
+{
+  return( std::sqrt( this->m_V ) );
+}
+
+// -------------------------------------------------------------------------
+unsigned long ivq::ITK::IncrementalMeanAndVariance::
+GetNumberOfSamples( ) const
+{
+  return( ( unsigned long )( this->m_N ) );
+}
+
+// -------------------------------------------------------------------------
+void ivq::ITK::IncrementalMeanAndVariance::
+Clear( )
+{
+  this->m_M = double( 0 );
+  this->m_V = double( 0 );
+  this->m_N = double( 0 );
+}
+
+// -------------------------------------------------------------------------
+void ivq::ITK::IncrementalMeanAndVariance::
+AddValue( double v )
+{
+  this->m_N += double( 1 );
+  double d = v - this->m_M;
+  if( this->m_N > double( 1 ) )
+  {
+    double o = ( this->m_N - double( 2 ) ) / ( this->m_N - double( 1 ) );
+    this->m_V = ( o * this->m_V ) + ( ( d * d ) / this->m_N );
+  }
+  else
+    this->m_V = double( 0 );
+  this->m_M += d / this->m_N;
+}
+
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/IncrementalMeanAndVariance.h b/lib/ivq/ITK/IncrementalMeanAndVariance.h
new file mode 100644 (file)
index 0000000..39e6c2e
--- /dev/null
@@ -0,0 +1,46 @@
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __ivq__ITK__IncrementalMeanAndVariance__h__
+#define __ivq__ITK__IncrementalMeanAndVariance__h__
+
+#include <ivq/ivq_export.h>
+
+namespace ivq
+{
+  namespace ITK
+  {
+    /**
+     */
+    class IVQ_EXPORT IncrementalMeanAndVariance
+    {
+    public:
+      typedef IncrementalMeanAndVariance Self;
+
+    public:
+      IncrementalMeanAndVariance( );
+      virtual ~IncrementalMeanAndVariance( );
+
+      double GetMean( ) const;
+      double GetVariance( ) const;
+      double GetDeviation( ) const;
+      unsigned long GetNumberOfSamples( ) const;
+
+      void Clear( );
+      void AddValue( double v );
+
+    protected:
+      double m_M;
+      double m_V;
+      double m_N;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#endif // __ivq__ITK__IncrementalMeanAndVariance__h__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/IsoImageSlicer.h b/lib/ivq/ITK/IsoImageSlicer.h
new file mode 100644 (file)
index 0000000..22b4526
--- /dev/null
@@ -0,0 +1,214 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__ITK__IsoImageSlicer__h__
+#define __ivq__ITK__IsoImageSlicer__h__
+
+#include <itkAffineTransform.h>
+#include <itkExtractImageFilter.h>
+#include <itkImage.h>
+#include <itkImageToImageFilter.h>
+#include <itkInterpolateImageFunction.h>
+#include <itkResampleImageFilter.h>
+#include <itkVectorResampleImageFilter.h>
+#include <itkVectorInterpolateImageFunction.h>
+
+namespace ivq
+{
+  namespace ITK
+  {
+    /**
+     */
+    template< class _TSlicer, class _TInterpolateFunction >
+    class BaseImageSlicer
+      : public itk::ImageToImageFilter< typename _TSlicer::InputImageType, itk::Image< typename _TSlicer::InputImageType::PixelType, _TSlicer::ImageDimension - 1 > >
+    {
+    public:
+      // Basic types
+      typedef BaseImageSlicer                                Self;
+      typedef _TSlicer                                    TSlicer;
+      typedef _TInterpolateFunction          TInterpolateFunction;
+      typedef typename TSlicer::InputImageType             TImage;
+      typedef typename TInterpolateFunction::CoordRepType TScalar;
+      typedef typename TImage::PixelType                   TPixel;
+      enum
+      {
+        Dim      = TImage::ImageDimension,
+        SliceDim = TImage::ImageDimension - 1
+      };
+      typedef itk::Image< TPixel, Self::SliceDim > TSliceImage;
+
+      // itk types
+      typedef itk::ImageToImageFilter< TImage, TSliceImage > Superclass;
+      typedef itk::SmartPointer< Self >                      Pointer;
+      typedef itk::SmartPointer< const Self >                ConstPointer;
+
+      // Internal filters
+      typedef itk::ExtractImageFilter< TImage, TSliceImage > TCollapsor;
+
+      // Various types
+      typedef typename TImage::IndexType   TIndex;
+      typedef typename TImage::RegionType  TRegion;
+      typedef typename TImage::SizeType    TSize;
+      typedef typename TImage::SpacingType TSpacing;
+      typedef typename TSpacing::ValueType TSpacingValue;
+
+      typedef itk::AffineTransform< TScalar, Self::Dim > TTransform;
+      typedef typename TTransform::MatrixType            TMatrix;
+      typedef typename TTransform::OffsetType            TVector;
+
+    public:
+      itkNewMacro( Self );
+      itkTypeMacro( BaseImageSlicer, itkImageToImageFilter );
+
+      itkBooleanMacro( SizeFromMaximum );
+      itkBooleanMacro( SizeFromMinimum );
+      itkBooleanMacro( SpacingFromMaximum );
+      itkBooleanMacro( SpacingFromMinimum );
+
+      itkGetConstObjectMacro( Transform, TTransform );
+      itkGetConstMacro( DefaultValue, TPixel );
+      itkGetConstMacro( Size, TVector );
+      itkGetConstMacro( SizeFromMaximum, bool );
+      itkGetConstMacro( SizeFromMinimum, bool );
+      itkGetConstMacro( Spacing, TSpacingValue );
+      itkGetConstMacro( SpacingFromMaximum, bool );
+      itkGetConstMacro( SpacingFromMinimum, bool );
+
+      itkSetObjectMacro( Transform, TTransform );
+      itkSetMacro( Size, TVector );
+      itkSetMacro( DefaultValue, TPixel );
+      itkSetMacro( SizeFromMaximum, bool );
+      itkSetMacro( SizeFromMinimum, bool );
+      itkSetMacro( Spacing, TSpacingValue );
+      itkSetMacro( SpacingFromMaximum, bool );
+      itkSetMacro( SpacingFromMinimum, bool );
+
+    public:
+      virtual unsigned long GetMTime( ) const override;
+
+      const TInterpolateFunction* GetInterpolator( ) const;
+      const TMatrix& GetRotation( ) const;
+      const TVector& GetTranslation( ) const;
+
+      void SetInterpolator( TInterpolateFunction* f );
+
+      template< class _TOtherMatrix >
+      void SetRotation( const _TOtherMatrix& r );
+
+      template< class _TOtherVector >
+      void SetTranslation( const _TOtherVector& t );
+
+      void SetSize( TScalar s );
+
+    protected:
+      BaseImageSlicer( );
+      virtual ~BaseImageSlicer( );
+
+      virtual void GenerateOutputInformation( ) override; // TODO { }
+      virtual void GenerateInputRequestedRegion( ) override;
+      virtual void GenerateData( ) override;
+
+    private:
+      // Purposely not implemented
+      BaseImageSlicer( const Self& );
+      void operator=( const Self& );
+
+    protected:
+      typename TSlicer::Pointer    m_Slicer;
+      typename TCollapsor::Pointer m_Collapsor;
+      typename TTransform::Pointer m_Transform;
+
+      TPixel m_DefaultValue;
+
+      TVector m_Size;
+      bool    m_SizeFromMaximum;
+      bool    m_SizeFromMinimum;
+
+      TSpacingValue m_Spacing;
+      bool          m_SpacingFromMaximum;
+      bool          m_SpacingFromMinimum;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+// -------------------------------------------------------------------------
+#define ivq_ITK_DefineIsoImageSlicer( name, R, F )                      \
+  template< class _TImage, class _TScalar = double >                    \
+  class name                                                            \
+    : public ivq::ITK::BaseImageSlicer< R< _TImage, _TImage, _TScalar >, F< _TImage, _TScalar > > \
+  {                                                                     \
+  public:                                                               \
+    typedef ivq::ITK::BaseImageSlicer< R< _TImage, _TImage, _TScalar >, F< _TImage, _TScalar > > Superclass; \
+    typedef name                                       Self;            \
+    typedef itk::SmartPointer< Self >                  Pointer;         \
+    typedef itk::SmartPointer< const Self >            ConstPointer;    \
+  public:                                                               \
+    itkNewMacro( Self );                                                \
+    itkTypeMacro( ivq::ITK::name, ivq::ITK::BaseSlicer );               \
+  protected:                                                            \
+    name( ) : Superclass( ) { }                                         \
+    virtual ~name( ) { }                                                \
+  private:                                                              \
+    name( const Self& );                                                \
+    void operator=( const Self& );                                      \
+  };
+
+namespace ivq
+{
+  namespace ITK
+  {
+    ivq_ITK_DefineIsoImageSlicer(
+      IsoImageSlicer,
+      itk::ResampleImageFilter,
+      itk::InterpolateImageFunction
+      );
+    ivq_ITK_DefineIsoImageSlicer(
+      VectorIsoImageSlicer,
+      itk::VectorResampleImageFilter,
+      itk::VectorInterpolateImageFunction
+      );
+
+  } // ecapseman
+
+} // ecapseman
+
+// -------------------------------------------------------------------------
+template< class _TSlicer, class _TInterpolateFunction >
+template< class _TOtherMatrix >
+void ivq::ITK::BaseImageSlicer< _TSlicer, _TInterpolateFunction >::
+SetRotation( const _TOtherMatrix& r )
+{
+  TMatrix rotation;
+  for( unsigned int i = 0; i < Self::Dim; ++i )
+    for( unsigned int j = 0; j < Self::Dim; ++j )
+      rotation[ i ][ j ] = r[ i ][ j ];
+  this->m_Transform->SetMatrix( rotation );
+  this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSlicer, class _TInterpolateFunction >
+template< class _TOtherVector >
+void ivq::ITK::BaseImageSlicer< _TSlicer, _TInterpolateFunction >::
+SetTranslation( const _TOtherVector& t )
+{
+  TVector off;
+  for( unsigned int i = 0; i < Self::Dim; ++i )
+    off[ i ] = t[ i ];
+  this->m_Transform->SetOffset( off );
+  this->Modified( );
+}
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#  include <ivq/ITK/IsoImageSlicer.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __ivq__ITK__IsoImageSlicer__h__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/IsoImageSlicer.hxx b/lib/ivq/ITK/IsoImageSlicer.hxx
new file mode 100644 (file)
index 0000000..cfcfc5e
--- /dev/null
@@ -0,0 +1,209 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__ITK__IsoImageSlicer__hxx__
+#define __ivq__ITK__IsoImageSlicer__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TSlicer, class _TInterpolateFunction >
+unsigned long ivq::ITK::BaseImageSlicer< _TSlicer, _TInterpolateFunction >::
+GetMTime( ) const
+{
+  unsigned long t = this->Superclass::GetMTime( );
+  unsigned long sT = this->m_Slicer->GetMTime( );
+  unsigned long cT = this->m_Collapsor->GetMTime( );
+  unsigned long tT = this->m_Transform->GetMTime( );
+  t = ( sT > t )? sT: t;
+  t = ( cT > t )? cT: t;
+  t = ( tT > t )? tT: t;
+  return( t );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSlicer, class _TInterpolateFunction >
+const typename ivq::ITK::BaseImageSlicer< _TSlicer, _TInterpolateFunction >::
+TInterpolateFunction*
+ivq::ITK::BaseImageSlicer< _TSlicer, _TInterpolateFunction >::
+GetInterpolator( ) const
+{
+  return( this->m_Slicer->GetInterpolator( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSlicer, class _TInterpolateFunction >
+const typename ivq::ITK::BaseImageSlicer< _TSlicer, _TInterpolateFunction >::
+TMatrix& ivq::ITK::BaseImageSlicer< _TSlicer, _TInterpolateFunction >::
+GetRotation( ) const
+{
+  return( this->m_Transform->GetMatrix( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSlicer, class _TInterpolateFunction >
+const typename ivq::ITK::BaseImageSlicer< _TSlicer, _TInterpolateFunction >::
+TVector& ivq::ITK::BaseImageSlicer< _TSlicer, _TInterpolateFunction >::
+GetTranslation( ) const
+{
+  return( this->m_Transform->GetOffset( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSlicer, class _TInterpolateFunction >
+void ivq::ITK::BaseImageSlicer< _TSlicer, _TInterpolateFunction >::
+SetInterpolator( TInterpolateFunction* f )
+{
+  this->m_Slicer->SetInterpolator( f );
+  this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSlicer, class _TInterpolateFunction >
+void ivq::ITK::BaseImageSlicer< _TSlicer, _TInterpolateFunction >::
+SetSize( TScalar s )
+{
+  this->m_Size.Fill( s );
+  this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSlicer, class _TInterpolateFunction >
+ivq::ITK::BaseImageSlicer< _TSlicer, _TInterpolateFunction >::
+BaseImageSlicer( )
+  : Superclass( ),
+    m_SizeFromMaximum( false ),
+    m_SizeFromMinimum( false ),
+    m_Spacing( TSpacingValue( 1 ) ),
+    m_SpacingFromMaximum( false ),
+    m_SpacingFromMinimum( false )
+{
+  this->m_Size.Fill( TScalar( 1 ) );
+
+  // Slicer
+  this->m_Slicer = TSlicer::New( );
+
+  TIndex idx;
+  idx.Fill( 0 );
+  this->m_Slicer->SetOutputStartIndex( idx );
+
+  // Dimension collapsor
+  this->m_Collapsor = TCollapsor::New( );
+  this->m_Collapsor->SetInput( this->m_Slicer->GetOutput( ) );
+  this->m_Collapsor->SetDirectionCollapseToIdentity( );
+
+  this->m_Transform = TTransform::New( );
+  this->m_Transform->SetIdentity( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSlicer, class _TInterpolateFunction >
+ivq::ITK::BaseImageSlicer< _TSlicer, _TInterpolateFunction >::
+~BaseImageSlicer( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TSlicer, class _TInterpolateFunction >
+void ivq::ITK::BaseImageSlicer< _TSlicer, _TInterpolateFunction >::
+GenerateOutputInformation( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TSlicer, class _TInterpolateFunction >
+void ivq::ITK::BaseImageSlicer< _TSlicer, _TInterpolateFunction >::
+GenerateInputRequestedRegion( )
+{
+  TImage* input = const_cast< TImage* >( this->GetInput( ) );
+  if( input != NULL )
+    input->SetRequestedRegionToLargestPossibleRegion( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSlicer, class _TInterpolateFunction >
+void ivq::ITK::BaseImageSlicer< _TSlicer, _TInterpolateFunction >::
+GenerateData( )
+{
+  const TImage* input = this->GetInput( );
+
+  // Spacing
+  TSpacing spac;
+  if( this->m_SpacingFromMaximum || this->m_SpacingFromMinimum )
+  {
+    spac = input->GetSpacing( );
+    TSpacingValue minIso = spac[ 0 ];
+    TSpacingValue maxIso = spac[ 0 ];
+    for( unsigned int i = 1; i < Self::Dim; i++ )
+    {
+      minIso = ( spac[ i ] < minIso )? spac[ i ]: minIso;
+      maxIso = ( spac[ i ] > maxIso )? spac[ i ]: maxIso;
+
+    } // rof
+    this->m_Spacing = ( this->m_SpacingFromMinimum )? minIso: maxIso;
+
+  } // fi
+  spac.Fill( this->m_Spacing );
+
+  // Size and origin
+  if( this->m_SizeFromMaximum || this->m_SizeFromMinimum )
+  {
+    TSize iSize = input->GetRequestedRegion( ).GetSize( );
+    TSpacing iSpac = input->GetSpacing( );
+    TScalar minSize = TScalar( iSize[ 0 ] ) * TScalar( iSpac[ 0 ] );
+    TScalar maxSize = minSize;
+    for( unsigned int i = 1; i < Self::Dim; i++ )
+    {
+      TScalar v = TScalar( iSize[ i ] ) * TScalar( iSpac[ i ] );
+      minSize = ( v < minSize )? v: minSize;
+      maxSize = ( v > maxSize )? v: maxSize;
+
+    } // rof
+    if( this->m_SizeFromMaximum )
+      this->m_Size.Fill( maxSize );
+    else
+      this->m_Size.Fill( minSize );
+
+  } // fi
+
+  TSize size;
+  typename TSlicer::OriginPointType origin;
+  size[ 0 ] = 1;
+  origin[ 0 ] = 0;
+  for( unsigned int i = 1; i < Self::Dim; i++ )
+  {
+    double s = double( this->m_Size[ i ] ) / double( spac[ i ] );
+    size[ i ] = ( unsigned int )( s );
+    origin[ i ] = -( 0.5 * this->m_Size[ i ] );
+
+  } // rof
+
+  // Prepare slicer
+  this->m_Slicer->SetInput( input );
+  this->m_Slicer->SetTransform( this->m_Transform );
+  this->m_Slicer->SetOutputSpacing( spac );
+  this->m_Slicer->SetOutputOrigin( origin );
+  this->m_Slicer->SetSize( size );
+  this->m_Slicer->SetDefaultPixelValue( this->m_DefaultValue );
+
+  // Slice!
+  // Note: UpdateLargestPossibleRegion( ) is used since we need the
+  // output regions to be updated at each filter call.
+  this->m_Slicer->UpdateLargestPossibleRegion( );
+
+  // Collapse result
+  TRegion region = this->m_Slicer->GetOutput( )->GetRequestedRegion( );
+  TSize regionSize = region.GetSize( );
+  regionSize[ 0 ] = 0;
+  region.SetSize( regionSize );
+  this->m_Collapsor->SetExtractionRegion( region );
+
+  this->m_Collapsor->GraftOutput( this->GetOutput( ) );
+  this->m_Collapsor->UpdateLargestPossibleRegion( );
+  this->GraftOutput( this->m_Collapsor->GetOutput( ) );
+}
+
+#endif // __ivq__ITK__IsoImageSlicer__hxx__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/PeakDetector.cxx b/lib/ivq/ITK/PeakDetector.cxx
new file mode 100644 (file)
index 0000000..2151313
--- /dev/null
@@ -0,0 +1,188 @@
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#include <ivq/ITK/PeakDetector.h>
+#include <cmath>
+
+// -------------------------------------------------------------------------
+ivq::ITK::PeakDetector::
+PeakDetector( )
+  : m_K( 3 ),
+    m_T( 3.5 ),
+    m_I( 0.5 )
+{
+}
+
+// -------------------------------------------------------------------------
+ivq::ITK::PeakDetector::
+~PeakDetector( )
+{
+}
+
+// -------------------------------------------------------------------------
+unsigned long ivq::ITK::PeakDetector::
+GetKernelSize( ) const
+{
+  return( this->m_K );
+}
+
+// -------------------------------------------------------------------------
+double ivq::ITK::PeakDetector::
+GetThreshold( ) const
+{
+  return( this->m_T );
+}
+
+// -------------------------------------------------------------------------
+double ivq::ITK::PeakDetector::
+GetInfluence( ) const
+{
+  return( this->m_I );
+}
+
+// -------------------------------------------------------------------------
+void ivq::ITK::PeakDetector::
+SetKernelSize( unsigned long k )
+{
+  this->m_K = k;
+  this->Clear( );
+}
+
+// -------------------------------------------------------------------------
+void ivq::ITK::PeakDetector::
+SetThreshold( double t )
+{
+  this->m_T = t;
+  this->Clear( );
+}
+
+// -------------------------------------------------------------------------
+void ivq::ITK::PeakDetector::
+SetInfluence( double i )
+{
+  this->m_I = i;
+  this->Clear( );
+}
+
+// -------------------------------------------------------------------------
+void ivq::ITK::PeakDetector::
+Clear( )
+{
+  this->m_X.clear( );
+  this->m_Y.clear( );
+  this->m_YF.clear( );
+  this->m_Avg.clear( );
+  this->m_STD.clear( );
+  this->m_Peaks.clear( );
+  this->m_MeanAndVar.Clear( );
+}
+
+// -------------------------------------------------------------------------
+const std::vector< double >& ivq::ITK::PeakDetector::
+GetXValues( ) const
+{
+  return( this->m_X );
+}
+
+// -------------------------------------------------------------------------
+const std::vector< double >& ivq::ITK::PeakDetector::
+GetYValues( ) const
+{
+  return( this->m_Y );
+}
+
+// -------------------------------------------------------------------------
+const std::vector< double >& ivq::ITK::PeakDetector::
+GetFilteredYValues( ) const
+{
+  return( this->m_YF );
+}
+
+// -------------------------------------------------------------------------
+const std::vector< double >& ivq::ITK::PeakDetector::
+GetAverages( ) const
+{
+  return( this->m_Avg );
+}
+
+// -------------------------------------------------------------------------
+const std::vector< double >& ivq::ITK::PeakDetector::
+GetDeviations( ) const
+{
+  return( this->m_STD );
+}
+
+// -------------------------------------------------------------------------
+const std::vector< ivq::ITK::PeakDetector::TPeak >& ivq::ITK::
+PeakDetector::GetPeaks( ) const
+{
+  return( this->m_Peaks );
+}
+
+// -------------------------------------------------------------------------
+unsigned long ivq::ITK::PeakDetector::
+GetNumberOfSamples( ) const
+{
+  return( this->m_X.size( ) );
+}
+
+// -------------------------------------------------------------------------
+ivq::ITK::PeakDetector::
+TPeak ivq::ITK::PeakDetector::
+AddValue( double x, double y )
+{
+  this->m_X.push_back( x );
+  this->m_Y.push_back( y );
+
+  if( this->m_YF.size( ) < this->m_K )
+  {
+    this->m_YF.push_back( y );
+    this->m_Avg.push_back( double( 0 ) );
+    this->m_STD.push_back( double( 0 ) );
+    this->m_Peaks.push_back( Self::NoPeak );
+
+    this->m_MeanAndVar.AddValue( y );
+    if( this->m_YF.size( ) == this->m_K )
+    {
+      this->m_Avg.push_back( this->m_MeanAndVar.GetMean( ) );
+      this->m_STD.push_back( this->m_MeanAndVar.GetDeviation( ) );
+
+    } // fi
+  }
+  else
+  {
+    unsigned long i = this->m_X.size( ) - 1;
+    if(
+      ( std::fabs( y - this->m_Avg[ i - 1 ] ) ) >
+      ( this->m_T * this->m_STD[ i - 1 ] )
+      )
+    {
+      this->m_Peaks.push_back(
+        ( y > this->m_Avg[ i - 1 ] )? Self::PosPeak: Self::NegPeak
+        );
+      this->m_YF.push_back(
+        ( this->m_I * y ) +
+        ( ( double( 1 ) - this->m_I ) * this->m_YF[ i - 1 ] )
+        );
+    }
+    else
+    {
+      this->m_Peaks.push_back( Self::NoPeak );
+      this->m_YF.push_back( y );
+
+    } // fi
+
+    this->m_MeanAndVar.Clear( );
+    unsigned long k = 0;
+    for( unsigned long j = i - this->m_K; j <= i; ++j, ++k )
+      this->m_MeanAndVar.AddValue( this->m_YF[ j ] );
+    this->m_Avg.push_back( this->m_MeanAndVar.GetMean( ) );
+    this->m_STD.push_back( this->m_MeanAndVar.GetDeviation( ) );
+
+  } // fi
+  return( this->m_Peaks.back( ) );
+}
+
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/PeakDetector.h b/lib/ivq/ITK/PeakDetector.h
new file mode 100644 (file)
index 0000000..0dfa494
--- /dev/null
@@ -0,0 +1,76 @@
+// =========================================================================
+// @author Leonardo Florez Valencia
+// @email florez-l@javeriana.edu.co
+// =========================================================================
+
+#ifndef __ivq__ITK__PeakDetector__h__
+#define __ivq__ITK__PeakDetector__h__
+
+#include <ivq/ivq_export.h>
+
+#include <vector>
+#include <ivq/ITK/IncrementalMeanAndVariance.h>
+
+namespace ivq
+{
+  namespace ITK
+  {
+    /**
+     * https://stackoverflow.com/questions/22583391/peak-signal-detection-in-realtime-timeseries-data
+     */
+    class IVQ_EXPORT PeakDetector
+    {
+    public:
+      typedef PeakDetector Self;
+
+      enum TPeak
+      {
+        NoPeak = 0,
+        PosPeak,
+        NegPeak
+      };
+
+    public:
+      PeakDetector( );
+      virtual ~PeakDetector( );
+
+      unsigned long GetKernelSize( ) const;
+      double GetThreshold( ) const;
+      double GetInfluence( ) const;
+
+      void SetKernelSize( unsigned long k );
+      void SetThreshold( double t );
+      void SetInfluence( double i );
+
+      const std::vector< double >& GetXValues( ) const;
+      const std::vector< double >& GetYValues( ) const;
+      const std::vector< double >& GetFilteredYValues( ) const;
+      const std::vector< double >& GetAverages( ) const;
+      const std::vector< double >& GetDeviations( ) const;
+      const std::vector< TPeak >& GetPeaks( ) const;
+
+      void Clear( );
+      unsigned long GetNumberOfSamples( ) const;
+      TPeak AddValue( double x, double y );
+
+    protected:
+      unsigned long m_K;
+      double m_T;
+      double m_I;
+
+      std::vector< double > m_X;
+      std::vector< double > m_Y;
+      std::vector< double > m_YF;
+      std::vector< double > m_Avg;
+      std::vector< double > m_STD;
+      std::vector< TPeak >  m_Peaks;
+      ivq::ITK::IncrementalMeanAndVariance m_MeanAndVar;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#endif // __ivq__ITK__PeakDetector__h__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/RasterContourFilter.h b/lib/ivq/ITK/RasterContourFilter.h
new file mode 100644 (file)
index 0000000..2bec6f5
--- /dev/null
@@ -0,0 +1,108 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__ITK__RasterContourFilter__h__
+#define __ivq__ITK__RasterContourFilter__h__
+
+#include <deque>
+#include <itkImageSource.h>
+
+// -------------------------------------------------------------------------
+namespace ivq
+{
+  namespace ITK
+  {
+    /**
+     */
+    template< class _TImage >
+    class RasterContourFilter
+      : public itk::ImageSource< _TImage >
+    {
+    public:
+      // Basic types
+      typedef RasterContourFilter             Self;
+      typedef itk::ImageSource< _TImage >     Superclass;
+      typedef itk::SmartPointer< Self >       Pointer;
+      typedef itk::SmartPointer< const Self > ConstPointer;
+
+      typedef _TImage TImage;
+      typedef typename _TImage::IndexType  TIndex;
+      typedef typename _TImage::PixelType  TPixel;
+      typedef typename _TImage::PointType  TPoint;
+      typedef typename _TImage::RegionType TRegion;
+      typedef itk::ImageBase< 2 > TImageBase;
+
+    public:
+      itkNewMacro( Self );
+      itkTypeMacro( ivq::ITK::RasterContourFilter, itk::ImageSource );
+
+      itkGetConstObjectMacro( Template, TImageBase );
+      itkGetConstMacro( InsideValue, TPixel );
+      itkGetConstMacro( OutsideValue, TPixel );
+
+      itkSetConstObjectMacro( Template, TImageBase );
+      itkSetMacro( InsideValue, TPixel );
+      itkSetMacro( OutsideValue, TPixel );
+
+    public:
+      void AddPoint( double x, double y );
+      void AddPoint( double p[ 2 ] );
+
+      template< class _TPoint >
+      inline void AddPoint( const _TPoint& p );
+
+      void ClearPoints( );
+
+    protected:
+      RasterContourFilter( );
+      virtual ~RasterContourFilter( );
+
+      virtual void AllocateOutputs( ) override;
+      virtual void BeforeThreadedGenerateData( ) override;
+      virtual void AfterThreadedGenerateData( ) override;
+      virtual void ThreadedGenerateData(
+        const TRegion& region, itk::ThreadIdType id
+        ) override;
+
+    private:
+      // Purposely not implemented
+      RasterContourFilter( const Self& );
+      void operator=( const Self& );
+
+    protected:
+      std::deque< TPoint > m_Contour;
+      std::deque< TIndex > m_Polygon;
+      TRegion m_ROI;
+      typename TImageBase::ConstPointer m_Template;
+      TPixel m_InsideValue;
+      TPixel m_OutsideValue;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+// -------------------------------------------------------------------------
+template< class _TImage >
+template< class _TPoint >
+void ivq::ITK::RasterContourFilter< _TImage >::
+AddPoint( const _TPoint& p )
+{
+  TPoint pnt;
+  pnt[ 0 ] = p[ 0 ];
+  pnt[ 1 ] = p[ 2 ];
+  this->m_Contour.push_back( pnt );
+  this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+#ifndef ITK_MANUAL_INSTANTIATION
+#  include <ivq/ITK/RasterContourFilter.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __ivq__ITK__RasterContourFilter__h__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/RasterContourFilter.hxx b/lib/ivq/ITK/RasterContourFilter.hxx
new file mode 100644 (file)
index 0000000..83eda54
--- /dev/null
@@ -0,0 +1,175 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+// Inclusion test taken from:
+// https://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
+
+#ifndef __ivq__ITK__RasterContourFilter__hxx__
+#define __ivq__ITK__RasterContourFilter__hxx__
+
+#include <itkImageRegionIteratorWithIndex.h>
+#include <vtkPolygon.h>
+
+// -------------------------------------------------------------------------
+template< class _TImage >
+void ivq::ITK::RasterContourFilter< _TImage >::
+AddPoint( double x, double y )
+{
+  TPoint pnt;
+  pnt[ 0 ] = x;
+  pnt[ 1 ] = y;
+  this->m_Contour.push_back( pnt );
+  this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage >
+void ivq::ITK::RasterContourFilter< _TImage >::
+AddPoint( double p[ 2 ] )
+{
+  TPoint pnt;
+  pnt[ 0 ] = p[ 0 ];
+  pnt[ 1 ] = p[ 1 ];
+  this->m_Contour.push_back( pnt );
+  this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage >
+void ivq::ITK::RasterContourFilter< _TImage >::
+ClearPoints( )
+{
+  this->m_Contour.clear( );
+  this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage >
+ivq::ITK::RasterContourFilter< _TImage >::
+RasterContourFilter( )
+  : Superclass( ),
+    m_InsideValue( TPixel( 1 ) ),
+    m_OutsideValue( TPixel( 0 ) )
+{
+  this->ClearPoints( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage >
+ivq::ITK::RasterContourFilter< _TImage >::
+~RasterContourFilter( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage >
+void ivq::ITK::RasterContourFilter< _TImage >::
+AllocateOutputs( )
+{
+  _TImage* out = this->GetOutput( 0 );
+  out->SetSpacing( this->m_Template->GetSpacing( ) );
+  out->SetRegions( this->m_Template->GetRequestedRegion( ) );
+  out->SetOrigin( this->m_Template->GetOrigin( ) );
+  out->SetDirection( this->m_Template->GetDirection( ) );
+  out->Allocate( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage >
+void ivq::ITK::RasterContourFilter< _TImage >::
+BeforeThreadedGenerateData( )
+{
+  // Keep just indices, not points
+  this->m_Polygon.clear( );
+  _TImage* out = this->GetOutput( 0 );
+  TIndex minIdx, maxIdx;
+  std::deque< TPoint >::const_iterator c = this->m_Contour.begin( );
+  for( ; c != this->m_Contour.end( ); ++c )
+  {
+    TIndex idx;
+    out->TransformPhysicalPointToIndex( *c, idx );
+    bool added = true;
+    if( this->m_Polygon.size( ) > 0 )
+    {
+      if( this->m_Polygon.back( ) != idx )
+      {
+        this->m_Polygon.push_back( idx );
+        minIdx[ 0 ] = ( idx[ 0 ] < minIdx[ 0 ] )? idx[ 0 ]: minIdx[ 0 ];
+        minIdx[ 1 ] = ( idx[ 1 ] < minIdx[ 1 ] )? idx[ 1 ]: minIdx[ 1 ];
+        maxIdx[ 0 ] = ( idx[ 0 ] > maxIdx[ 0 ] )? idx[ 0 ]: maxIdx[ 0 ];
+        maxIdx[ 1 ] = ( idx[ 1 ] > maxIdx[ 1 ] )? idx[ 1 ]: maxIdx[ 1 ];
+
+      } // fi
+    }
+    else
+    {
+      this->m_Polygon.push_back( idx );
+      minIdx = maxIdx = idx;
+
+    } // fi
+
+  } // rof
+
+  // Set ROI
+  typename _TImage::SizeType size;
+  size[ 0 ] = maxIdx[ 0 ] - minIdx[ 0 ] + 1;
+  size[ 1 ] = maxIdx[ 1 ] - minIdx[ 1 ] + 1;
+  this->m_ROI.SetIndex( minIdx );
+  this->m_ROI.SetSize( size );
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage >
+void ivq::ITK::RasterContourFilter< _TImage >::
+AfterThreadedGenerateData( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage >
+void ivq::ITK::RasterContourFilter< _TImage >::
+ThreadedGenerateData( const TRegion& region, itk::ThreadIdType id )
+{
+  long nVerts = this->m_Polygon.size( );
+  _TImage* out = this->GetOutput( );
+  itk::ImageRegionIteratorWithIndex< _TImage > iIt( out, region );
+  for( iIt.GoToBegin( ); !iIt.IsAtEnd( ); ++iIt )
+  {
+    TIndex p = iIt.GetIndex( );
+    bool inside = false;
+    if( this->m_ROI.IsInside( p ) )
+    {
+      long i, j;
+      for( i = 0, j = nVerts - 1; i < nVerts; j = i++ )
+      {
+        TIndex pi = this->m_Polygon[ i ];
+        TIndex pj = this->m_Polygon[ j ];
+        double pi0 = double( pi[ 0 ] );
+        double pi1 = double( pi[ 1 ] );
+        double pj0 = double( pj[ 0 ] );
+        double pj1 = double( pj[ 1 ] );
+        double p0 = double( p[ 0 ] );
+        double p1 = double( p[ 1 ] );
+        double ji0 = pj0 - pi0;
+        double ji1 = pj1 - pi1;
+        double i1 = p1 - pi1;
+        if(
+          ( ( pi1 > p1 ) != ( pj1 > p1 ) ) &&
+          ( p0 < ( ( ji0 * i1 ) / ji1 ) + pi0 )
+          )
+          inside = !inside;
+
+      } // rof
+
+    } // fi
+    iIt.Set( ( inside )? this->m_InsideValue: this->m_OutsideValue );
+
+  } // rof
+}
+
+#endif // __ivq__ITK__RasterContourFilter__hxx__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/Simple3DCurve.cxx b/lib/ivq/ITK/Simple3DCurve.cxx
new file mode 100644 (file)
index 0000000..e5649d5
--- /dev/null
@@ -0,0 +1,177 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#include <ivq/ITK/Simple3DCurve.h>
+
+// -------------------------------------------------------------------------
+template< class _TScalar >
+void ivq::ITK::Simple3DCurve< _TScalar >::
+Modified( ) const
+{
+  this->Superclass::Modified( );
+  this->m_FramesUpdated = false;
+}
+
+// -------------------------------------------------------------------------
+template< class _TScalar >
+void ivq::ITK::Simple3DCurve< _TScalar >::
+Clear( )
+{
+  this->m_Points.clear( );
+  this->m_Frames.clear( );
+  this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TScalar >
+void ivq::ITK::Simple3DCurve< _TScalar >::
+Smooth( const unsigned int& kernel_size )
+{
+  std::vector< TPoint > new_points;
+
+  TPoint p;
+  int k = int( kernel_size );
+  unsigned int nPoints = this->m_Points.size( );
+  for( unsigned int i = 0; i < nPoints; ++i )
+  {
+    typename TPoint::VectorType v( TScalar( 0 ) );
+    for( int j = -k; j <= k; ++j )
+    {
+      int l = int( i ) + j;
+      if     ( l < 0        ) p = this->m_Points[ 0 ];
+      else if( l >= nPoints ) p = this->m_Points[ nPoints - 1 ];
+      else                    p = this->m_Points[ l ];
+      v += p.GetVectorFromOrigin( );
+
+    } // rof
+    v /= _TScalar( ( k << 1 ) + 1 );
+
+    p.Fill( 0 );
+    p += v;
+    new_points.push_back( p );
+
+  } // rof
+  this->m_Points = new_points;
+  this->m_Frames.clear( );
+  this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TScalar >
+unsigned long ivq::ITK::Simple3DCurve< _TScalar >::
+GetNumberOfPoints( ) const
+{
+  return( this->m_Points.size( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TScalar >
+const typename ivq::ITK::Simple3DCurve< _TScalar >::
+TMatrix& ivq::ITK::Simple3DCurve< _TScalar >::
+GetFrame( unsigned int id ) const
+{
+  if( !( this->m_FramesUpdated ) )
+  {
+    unsigned long N = this->m_Points.size( );
+
+    std::vector< TVector > tg( N );
+    tg[ 0 ] = this->m_Points[ 1 ] - this->m_Points[ 0 ];
+    tg[ N - 1 ] = this->m_Points[ N - 1 ] - this->m_Points[ N - 2 ];
+    for( unsigned int i = 1; i < N - 1; ++i )
+      tg[ i ] = this->m_Points[ i + 1 ] - this->m_Points[ i - 1 ];
+
+    std::vector< TVector > no( N );
+    std::vector< TVector > bn( N );
+    TVector prev_tg( _TScalar( 0 ) ), prev_no( _TScalar( 0 ) );
+    prev_tg[ 0 ] = _TScalar( 1 );
+    prev_no[ 1 ] = _TScalar( 1 );
+    for( unsigned int i = 0; i < N; ++i )
+    {
+      auto ntg = tg[ i ].GetNorm( );
+      if( double( ntg ) > double( 0 ) )
+        tg[ i ] /= ntg;
+
+      _TScalar ct = prev_tg * tg[ i ];
+      TVector a = itk::CrossProduct( prev_tg, tg[ i ] );
+      _TScalar st = a.GetNorm( );
+      if( st > _TScalar( 0 ) )
+        a /= st;
+
+      no[ i ] =
+        ( prev_no * ct ) +
+        ( itk::CrossProduct( a, prev_no ) * st ) +
+        ( a * ( ( a * prev_no ) * ( _TScalar( 1 ) - ct ) ) );
+      auto nno = no[ i ].GetNorm( );
+      if( double( nno ) > double( 0 ) )
+        no[ i ] /= nno;
+
+      bn[ i ] = itk::CrossProduct( tg[ i ], no[ i ] );
+
+      prev_tg = tg[ i ];
+      prev_no = no[ i ];
+
+    } // rof
+
+    this->m_Frames.clear( );
+    for( unsigned int i = 0; i < N; ++i )
+    {
+      TMatrix m;
+      for( unsigned int d = 0; d < 3; ++d )
+      {
+        m[ d ][ 0 ] = tg[ i ][ d ];
+        m[ d ][ 1 ] = no[ i ][ d ];
+        m[ d ][ 2 ] = bn[ i ][ d ];
+
+      } // rof
+      this->m_Frames.push_back( m );
+
+    } // rof
+
+    this->m_FramesUpdated = true;
+
+  } // fi
+  return( this->m_Frames[ id ] );
+}
+
+// -------------------------------------------------------------------------
+template< class _TScalar >
+const typename ivq::ITK::Simple3DCurve< _TScalar >::
+TPoint& ivq::ITK::Simple3DCurve< _TScalar >::
+GetPoint( unsigned int id ) const
+{
+  return( this->m_Points[ id ] );
+}
+
+// -------------------------------------------------------------------------
+template< class _TScalar >
+typename ivq::ITK::Simple3DCurve< _TScalar >::
+TVector ivq::ITK::Simple3DCurve< _TScalar >::
+GetVector( unsigned int id ) const
+{
+  return( this->m_Points[ id ].GetVectorFromOrigin( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TScalar >
+ivq::ITK::Simple3DCurve< _TScalar >::
+Simple3DCurve( )
+  : Superclass( ),
+    m_FramesUpdated( false )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TScalar >
+ivq::ITK::Simple3DCurve< _TScalar >::
+~Simple3DCurve( )
+{
+}
+
+// -------------------------------------------------------------------------
+template class ivq::ITK::Simple3DCurve< float >;
+template class ivq::ITK::Simple3DCurve< double >;
+
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/Simple3DCurve.h b/lib/ivq/ITK/Simple3DCurve.h
new file mode 100644 (file)
index 0000000..c01abb9
--- /dev/null
@@ -0,0 +1,83 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__ITK__Simple3DCurve__h__
+#define __ivq__ITK__Simple3DCurve__h__
+
+#include <ivq/ivq_export.h>
+
+#include <itkDataObject.h>
+#include <itkObjectFactory.h>
+#include <itkMatrix.h>
+#include <itkPoint.h>
+
+namespace ivq
+{
+  namespace ITK
+  {
+    /**
+     */
+    template< class _TScalar >
+    class IVQ_EXPORT Simple3DCurve
+      : public itk::DataObject
+    {
+    public:
+      typedef Simple3DCurve                   Self;
+      typedef itk::DataObject                 Superclass;
+      typedef itk::SmartPointer< Self >       Pointer;
+      typedef itk::SmartPointer< const Self > ConstPointer;
+
+      typedef _TScalar TScalar;
+      typedef itk::Matrix< TScalar, 3, 3 > TMatrix;
+      typedef itk::Point< TScalar, 3 >     TPoint;
+      typedef typename TPoint::VectorType  TVector;
+
+    public:
+      itkNewMacro( Self );
+      itkTypeMacro( ivq::ITK::Simple3DCurve, itk::DataObject );
+
+    public:
+      template< class _TVector >
+      inline void AddPoint( const _TVector& v )
+        {
+          TPoint p;
+          p[ 0 ] = v[ 0 ];
+          p[ 1 ] = v[ 1 ];
+          p[ 2 ] = v[ 2 ];
+          this->m_Points.push_back( p );
+          this->Modified( );
+        }
+
+      virtual void Modified( ) const override;
+      void Clear( );
+      void Smooth( const unsigned int& kernel_size = 1 );
+      unsigned long GetNumberOfPoints( ) const;
+      const TMatrix& GetFrame( unsigned int id ) const;
+      const TPoint& GetPoint( unsigned int id ) const;
+      TVector GetVector( unsigned int id ) const;
+
+    protected:
+      Simple3DCurve( );
+      virtual ~Simple3DCurve( );
+
+    private:
+      // Purposely not implemented
+      Simple3DCurve( const Self& other );
+      Self& operator=( const Self& other );
+
+    protected:
+      std::vector< TPoint > m_Points;
+      mutable std::vector< TMatrix > m_Frames;
+      mutable bool m_FramesUpdated;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#endif // __ivq__ITK__Simple3DCurve__h__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/ThresholdFunction.h b/lib/ivq/ITK/ThresholdFunction.h
new file mode 100644 (file)
index 0000000..690043c
--- /dev/null
@@ -0,0 +1,89 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__ITK__ThresholdFunction__h__
+#define __ivq__ITK__ThresholdFunction__h__
+
+#include <set>
+
+#include <itkFunctionBase.h>
+
+namespace ivq
+{
+  namespace ITK
+  {
+    /**
+     */
+    template< class _TIn, class _TOut >
+    class ThresholdFunction
+      : public itk::FunctionBase< _TIn, _TOut >
+    {
+    public:
+      typedef ThresholdFunction                Self;
+      typedef itk::FunctionBase< _TIn, _TOut > Superclass;
+      typedef itk::SmartPointer< Self >        Pointer;
+      typedef itk::SmartPointer< const Self >  ConstPointer;
+
+      typedef typename Superclass::InputType  TInput;
+      typedef typename Superclass::OutputType TOutput;
+
+    public:
+      itkNewMacro( Self );
+      itkTypeMacro( ivq::ITK::ThresholdFunction, itk::FunctionBase );
+
+      itkBooleanMacro( Strict );
+      itkBooleanMacro( Binary );
+
+      itkGetConstMacro( LowerThreshold, _TIn );
+      itkGetConstMacro( UpperThreshold, _TIn );
+      itkGetConstMacro( Strict, bool );
+      itkGetConstMacro( Binary, bool );
+      itkGetConstMacro( InsideValue, _TOut );
+      itkGetConstMacro( OutsideValue, _TOut );
+
+      itkSetMacro( LowerThreshold, _TIn );
+      itkSetMacro( UpperThreshold, _TIn );
+      itkSetMacro( Strict, bool );
+      itkSetMacro( Binary, bool );
+      itkSetMacro( InsideValue, _TOut );
+      itkSetMacro( OutsideValue, _TOut );
+
+    public:
+      void SetBetween( const _TIn& lower, const _TIn& upper );
+      void SetBelow( const _TIn& value );
+      void SetAbove( const _TIn& value );
+
+      virtual _TOut Evaluate( const _TIn& in ) const override;
+
+    protected:
+      ThresholdFunction( );
+      virtual ~ThresholdFunction( );
+
+    private:
+      // Purposely not implemented
+      ThresholdFunction( const Self& other );
+      Self& operator=( const Self& other );
+
+    protected:
+      _TIn  m_LowerThreshold;
+      _TIn  m_UpperThreshold;
+      bool  m_Strict;
+      bool  m_Binary;
+      _TOut m_InsideValue;
+      _TOut m_OutsideValue;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#  include <ivq/ITK/ThresholdFunction.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __ivq__ITK__ThresholdFunction__h__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/ITK/ThresholdFunction.hxx b/lib/ivq/ITK/ThresholdFunction.hxx
new file mode 100644 (file)
index 0000000..090b278
--- /dev/null
@@ -0,0 +1,98 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__ITK__ThresholdFunction__hxx__
+#define __ivq__ITK__ThresholdFunction__hxx__
+
+#include <limits>
+
+// -------------------------------------------------------------------------
+template< class _TIn, class _TOut >
+void ivq::ITK::ThresholdFunction< _TIn, _TOut >::
+SetBetween( const _TIn& lower, const _TIn& upper )
+{
+  this->SetLowerThreshold( lower );
+  this->SetUpperThreshold( upper );
+}
+
+// -------------------------------------------------------------------------
+template< class _TIn, class _TOut >
+void ivq::ITK::ThresholdFunction< _TIn, _TOut >::
+SetBelow( const _TIn& value )
+{
+  typedef std::numeric_limits< _TIn > _TTraits;
+  if( _TTraits::is_signed )
+    this->SetLowerThreshold( -_TTraits::max( ) );
+  else
+    this->SetLowerThreshold( _TIn( 0 ) );
+  this->SetUpperThreshold( value );
+}
+
+// -------------------------------------------------------------------------
+template< class _TIn, class _TOut >
+void ivq::ITK::ThresholdFunction< _TIn, _TOut >::
+SetAbove( const _TIn& value )
+{
+  typedef std::numeric_limits< _TIn > _TTraits;
+  this->SetLowerThreshold( value );
+  this->SetUpperThreshold( _TTraits::max( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TIn, class _TOut >
+_TOut ivq::ITK::ThresholdFunction< _TIn, _TOut >::
+Evaluate( const _TIn& in ) const
+{
+  // Check threshold
+  bool inside = false;
+  if( this->m_Strict )
+  {
+    inside  = ( this->m_LowerThreshold < in );
+    inside &= ( in < this->m_UpperThreshold );
+  }
+  else
+  {
+    inside  = ( this->m_LowerThreshold <= in );
+    inside &= ( in <= this->m_UpperThreshold );
+
+  } // fi
+
+  // Return value
+  if( inside )
+  {
+    if( this->m_Binary )
+      return( this->m_InsideValue );
+    else
+      return( _TOut( in ) );
+  }
+  else
+    return( this->m_OutsideValue );
+}
+
+// -------------------------------------------------------------------------
+template< class _TIn, class _TOut >
+ivq::ITK::ThresholdFunction< _TIn, _TOut >::
+ThresholdFunction( )
+  : Superclass( ),
+    m_LowerThreshold( _TIn( 0 ) ),
+    m_UpperThreshold( std::numeric_limits< _TIn >::max( ) ),
+    m_Strict( false ),
+    m_Binary( false ),
+    m_InsideValue( std::numeric_limits< _TOut >::max( ) ),
+    m_OutsideValue( _TOut( 0 ) )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TIn, class _TOut >
+ivq::ITK::ThresholdFunction< _TIn, _TOut >::
+~ThresholdFunction( )
+{
+}
+
+#endif // __ivq__ITK__ThresholdFunction__hxx__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/Qt/DicomSeriesSelectorDialog.cxx b/lib/ivq/Qt/DicomSeriesSelectorDialog.cxx
new file mode 100644 (file)
index 0000000..6e39f34
--- /dev/null
@@ -0,0 +1,34 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#include <ivq/Qt/DicomSeriesSelectorDialog.h>
+#include <ivq/ui_DicomSeriesSelectorDialog.h>
+
+// -------------------------------------------------------------------------
+ivq::Qt::DicomSeriesSelectorDialog::
+DicomSeriesSelectorDialog( QWidget* parent )
+  : QDialog( parent ),
+    m_UI( new Ui::DicomSeriesSelectorDialog )
+{
+  this->m_UI->setupUi( this );
+  this->setWindowTitle( "Choose DICOM series" );
+}
+
+// -------------------------------------------------------------------------
+ivq::Qt::DicomSeriesSelectorDialog::
+~DicomSeriesSelectorDialog( )
+{
+  delete this->m_UI;
+}
+
+// -------------------------------------------------------------------------
+std::vector< std::string >* ivq::Qt::DicomSeriesSelectorDialog::
+selectedFilenames( )
+{
+  return( this->m_UI->Selector->selectedFilenames( ) );
+}
+
+// eof - $RCSfile$
diff --git a/lib/ivq/Qt/DicomSeriesSelectorDialog.h b/lib/ivq/Qt/DicomSeriesSelectorDialog.h
new file mode 100644 (file)
index 0000000..973dbcc
--- /dev/null
@@ -0,0 +1,46 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__Qt__DicomSeriesSelectorDialog__h__
+#define __ivq__Qt__DicomSeriesSelectorDialog__h__
+
+#include <ivq/ivq_export.h>
+
+#include <QDialog>
+#include <gdcmSerieHelper.h>
+
+namespace Ui {  class DicomSeriesSelectorDialog; }
+
+namespace ivq
+{
+  namespace Qt
+  {
+    /**
+     */
+    class IVQ_EXPORT DicomSeriesSelectorDialog
+      : public QDialog
+    {
+      Q_OBJECT;
+    public:
+      typedef DicomSeriesSelectorDialog Self;
+
+    public:
+      explicit DicomSeriesSelectorDialog( QWidget* parent = 0 );
+      virtual ~DicomSeriesSelectorDialog( );
+
+      std::vector< std::string >* selectedFilenames( );
+
+    protected:
+      Ui::DicomSeriesSelectorDialog* m_UI;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#endif // __ivq__Qt__DicomSeriesSelectorDialog__h__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/Qt/DicomSeriesSelectorDialog.ui b/lib/ivq/Qt/DicomSeriesSelectorDialog.ui
new file mode 100644 (file)
index 0000000..ee12b34
--- /dev/null
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DicomSeriesSelectorDialog</class>
+ <widget class="QDialog" name="DicomSeriesSelectorDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>511</width>
+    <height>335</height>
+   </rect>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>511</width>
+    <height>335</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="0" column="0">
+    <widget class="ivq::Qt::DicomSeriesSelectorWidget" name="Selector" native="true"/>
+   </item>
+   <item row="1" column="0">
+    <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>
+ <customwidgets>
+  <customwidget>
+   <class>ivq::Qt::DicomSeriesSelectorWidget</class>
+   <extends>QWidget</extends>
+   <header location="global">ivq/Qt/DicomSeriesSelectorWidget.h</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>ButtonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>DicomSeriesSelectorDialog</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>DicomSeriesSelectorDialog</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>
+ </connections>
+</ui>
diff --git a/lib/ivq/Qt/DicomSeriesSelectorWidget.cxx b/lib/ivq/Qt/DicomSeriesSelectorWidget.cxx
new file mode 100644 (file)
index 0000000..a98ac75
--- /dev/null
@@ -0,0 +1,187 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#include <ivq/Qt/DicomSeriesSelectorWidget.h>
+#include <ivq/ui_DicomSeriesSelectorWidget.h>
+
+#include <queue>
+#include <string>
+#include <QFileDialog>
+
+// -------------------------------------------------------------------------
+ivq::Qt::DicomSeriesSelectorWidget::
+DicomSeriesSelectorWidget( QWidget* parent )
+  : QWidget( parent ),
+    m_UI( new Ui::DicomSeriesSelectorWidget )
+{
+  this->m_UI->setupUi( this );
+  this->setStartDir( ".", false );
+  this->connect(
+    this->m_UI->ChooseButton, SIGNAL( clicked( ) ),
+    this, SLOT( _Choose( ) )
+    );
+}
+
+// -------------------------------------------------------------------------
+ivq::Qt::DicomSeriesSelectorWidget::
+~DicomSeriesSelectorWidget( )
+{
+  delete this->m_UI;
+}
+
+// -------------------------------------------------------------------------
+QString ivq::Qt::DicomSeriesSelectorWidget::
+startDir( ) const
+{
+  return( this->m_UI->Directory->text( ) );
+}
+
+// -------------------------------------------------------------------------
+void ivq::Qt::DicomSeriesSelectorWidget::
+setStartDir( const QString& dir, bool build )
+{
+  this->m_Series.clear( );
+
+  this->m_UI->Directory->setText( dir );
+  if( !build )
+    return;
+  
+  // Process subdirs
+  QApplication::setOverrideCursor( ::Qt::WaitCursor );
+
+  this->m_UI->Series->clear( );
+  this->m_UI->Series->setColumnCount( 3 );
+  QStringList labels;
+  labels << "Images count" << "Series UID" << "Series path";
+  this->m_UI->Series->setHorizontalHeaderLabels( labels );
+
+  std::string main_dir_name = dir.toStdString( );
+  std::queue< std::string > q;
+  q.push( main_dir_name );
+  while( !( q.empty( ) ) )
+  {
+    std::string dir_name = q.front( );
+    q.pop( );
+
+    // Update queue
+    QDir dir( dir_name.c_str( ) );
+    QFileInfoList contents = dir.entryInfoList( );
+    QFileInfoList::const_iterator i = contents.begin( );
+    std::set< std::string > files;
+    for( ; i != contents.end( ); ++i )
+    {
+      if( i->isDir( ) )
+      {
+        std::string new_dir_name = i->absoluteFilePath( ).toStdString( );
+        if( new_dir_name.size( ) > dir_name.size( ) )
+          q.push( new_dir_name );
+      }
+      else
+        files.insert( i->absoluteFilePath( ).toStdString( ) );
+
+    } // rof
+
+    if( files.size( ) > 0 )
+    {
+      this->m_GDCMHelper.Clear( );
+      this->m_GDCMHelper.SetUseSeriesDetails( true );
+      this->m_GDCMHelper.SetLoadMode( 0 );
+      this->m_GDCMHelper.AddRestriction( "0008|0021" );
+      this->m_GDCMHelper.SetFileNames( files.begin( ), files.end( ) );
+
+      gdcm::FileList* flist =
+        this->m_GDCMHelper.GetFirstSingleSerieUIDFileSet( );
+      while( flist != NULL )
+      {
+        if( flist->size( ) > 0 )
+        {
+          this->m_GDCMHelper.OrderFileList( flist );
+          gdcm::File* file = ( *flist )[ 0 ];
+          std::string id =
+            this->m_GDCMHelper.CreateUniqueSeriesIdentifier( file ).c_str( );
+
+          gdcm::FileList::iterator it;
+          for( it = flist->begin( ); it != flist->end( ); ++it )
+            if( *it != NULL )
+              this->m_Series[ id ].push_back( ( *it )->filename );
+
+        } // fi
+        flist = this->m_GDCMHelper.GetNextSingleSerieUIDFileSet( );
+
+      } // elihw
+
+    } // fi
+
+  } // elihw
+
+  // Show series
+  std::map< std::string, std::vector< std::string > >::const_iterator sIt =
+    this->m_Series.begin( );
+  for( ; sIt != this->m_Series.end( ); ++sIt )
+  {
+    if( sIt->second.size( ) > 0 )
+    {
+      QFileInfo fdir( sIt->second[ 0 ].c_str( ) );
+
+      unsigned long rows = this->m_UI->Series->rowCount( );
+      this->m_UI->Series->insertRow( rows );
+      std::stringstream str_count;
+      str_count << sIt->second.size( );
+      QTableWidgetItem* count_item =
+        new QTableWidgetItem( str_count.str( ).c_str( ) );
+      QTableWidgetItem* uid_item =
+        new QTableWidgetItem( sIt->first.c_str( ) );
+      QTableWidgetItem* dir_item =
+        new QTableWidgetItem( fdir.dir( ).canonicalPath( ) );
+      count_item->setFlags( count_item->flags( ) & ~::Qt::ItemIsEditable );
+      uid_item->setFlags( uid_item->flags( ) & ~::Qt::ItemIsEditable );
+      dir_item->setFlags( dir_item->flags( ) & ~::Qt::ItemIsEditable );
+      this->m_UI->Series->setItem( rows, 0, count_item );
+      this->m_UI->Series->setItem( rows, 1, uid_item );
+      this->m_UI->Series->setItem( rows, 2, dir_item );
+
+    } // fi
+
+  } // rof
+
+  // Restore cursor
+  QApplication::restoreOverrideCursor( );
+}
+
+// -------------------------------------------------------------------------
+std::vector< std::string >* ivq::Qt::DicomSeriesSelectorWidget::
+selectedFilenames( )
+{
+  QList< QTableWidgetItem* > items = this->m_UI->Series->selectedItems( );
+  if( items.size( ) > 0 )
+  {
+    std::string uid =
+      this->m_UI->Series->
+      item( items[ 0 ]->row( ), 1 )->text( ).toStdString( );
+    std::map< std::string, std::vector< std::string > >::iterator sIt =
+      this->m_Series.find( uid );
+    if( sIt != this->m_Series.end( ) )
+      return( &( sIt->second ) );
+
+  } // fi
+  return( NULL );
+}
+
+// -------------------------------------------------------------------------
+void ivq::Qt::DicomSeriesSelectorWidget::
+_Choose( )
+{
+  QString qdir =
+    QFileDialog::getExistingDirectory(
+      this, tr( "Open Directory" ),
+      this->startDir( ),
+      QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks
+      );
+  if( qdir.toStdString( ) != "" )
+    this->setStartDir( qdir );
+}
+
+// eof - $RCSfile$
diff --git a/lib/ivq/Qt/DicomSeriesSelectorWidget.h b/lib/ivq/Qt/DicomSeriesSelectorWidget.h
new file mode 100644 (file)
index 0000000..6642803
--- /dev/null
@@ -0,0 +1,75 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__Qt__DicomSeriesSelectorWidget__h__
+#define __ivq__Qt__DicomSeriesSelectorWidget__h__
+
+#include <ivq/ivq_export.h>
+
+#include <QWidget>
+#include <gdcmSerieHelper.h>
+
+namespace Ui {  class DicomSeriesSelectorWidget; }
+
+namespace ivq
+{
+  namespace Qt
+  {
+    /**
+     */
+    class IVQ_EXPORT DicomSeriesSelectorWidget
+      : public QWidget
+    {
+      Q_OBJECT;
+    public:
+      typedef DicomSeriesSelectorWidget Self;
+
+    protected:
+      /**
+       */
+      class _GDCMSerieHelper
+        : public gdcm::SerieHelper
+      {
+      public:
+        _GDCMSerieHelper( )
+          {
+          }
+        virtual ~_GDCMSerieHelper( )
+          {
+          }
+        template< class _TIt >
+        void SetFileNames( _TIt b, _TIt e )
+          {
+            for( _TIt i = b; i != e; ++i )
+              this->AddFileName( *i );
+          }
+      };
+
+    public:
+      explicit DicomSeriesSelectorWidget( QWidget* parent = 0 );
+      virtual ~DicomSeriesSelectorWidget( );
+
+      QString startDir( ) const;
+      void setStartDir( const QString& dir, bool build = true );
+
+      std::vector< std::string >* selectedFilenames( );
+
+    protected slots:
+      void _Choose( );
+
+    protected:
+      Ui::DicomSeriesSelectorWidget* m_UI;
+      _GDCMSerieHelper m_GDCMHelper;
+      std::map< std::string, std::vector< std::string > > m_Series;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#endif // __ivq__Qt__DicomSeriesSelectorWidget__h__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/Qt/DicomSeriesSelectorWidget.ui b/lib/ivq/Qt/DicomSeriesSelectorWidget.ui
new file mode 100644 (file)
index 0000000..d3b648f
--- /dev/null
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>DicomSeriesSelectorWidget</class>
+ <widget class="QWidget" name="DicomSeriesSelectorWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>358</width>
+    <height>299</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <property name="margin">
+    <number>1</number>
+   </property>
+   <property name="spacing">
+    <number>1</number>
+   </property>
+   <item row="0" column="0">
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QLabel" name="label">
+       <property name="minimumSize">
+        <size>
+         <width>101</width>
+         <height>14</height>
+        </size>
+       </property>
+       <property name="maximumSize">
+        <size>
+         <width>101</width>
+         <height>14</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>DICOM directory:</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QLineEdit" name="Directory">
+       <property name="enabled">
+        <bool>true</bool>
+       </property>
+       <property name="readOnly">
+        <bool>true</bool>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="ChooseButton">
+       <property name="minimumSize">
+        <size>
+         <width>25</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="maximumSize">
+        <size>
+         <width>25</width>
+         <height>25</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>...</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item row="1" column="0">
+    <widget class="QTableWidget" name="Series">
+     <property name="selectionMode">
+      <enum>QAbstractItemView::SingleSelection</enum>
+     </property>
+     <property name="selectionBehavior">
+      <enum>QAbstractItemView::SelectRows</enum>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
\ No newline at end of file
diff --git a/lib/ivq/Qt/ImageViewerWidget.cxx b/lib/ivq/Qt/ImageViewerWidget.cxx
new file mode 100644 (file)
index 0000000..4e3d64e
--- /dev/null
@@ -0,0 +1,33 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#include <ivq/Qt/ImageViewerWidget.h>
+#include <ivq/VTK/ImageViewer.h>
+#include <vtkRenderWindow.h>
+
+// -------------------------------------------------------------------------
+ivq::Qt::ImageViewerWidget::
+ImageViewerWidget( QWidget* parent, ::Qt::WindowFlags f )
+  : QVTKWidget( parent, f )
+{
+  this->Viewer = vtkSmartPointer< ivq::VTK::ImageViewer >::New( );
+  this->Viewer->SetRenderWindow( this->GetRenderWindow( ) );
+}
+
+// -------------------------------------------------------------------------
+ivq::Qt::ImageViewerWidget::
+~ImageViewerWidget( )
+{
+}
+
+// -------------------------------------------------------------------------
+ivq::VTK::ImageViewer* ivq::Qt::ImageViewerWidget::
+GetViewer( )
+{
+  return( this->Viewer.GetPointer( ) );
+}
+
+// eof - $RCSfile$
diff --git a/lib/ivq/Qt/ImageViewerWidget.h b/lib/ivq/Qt/ImageViewerWidget.h
new file mode 100644 (file)
index 0000000..1fd67bd
--- /dev/null
@@ -0,0 +1,48 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__Qt__ImageViewerWidget__h__
+#define __ivq__Qt__ImageViewerWidget__h__
+
+#include <ivq/ivq_export.h>
+
+#include <vtkSmartPointer.h>
+#include <QVTKWidget.h>
+
+namespace ivq
+{
+  namespace VTK
+  {
+    class ImageViewer;
+
+  } // ecapseman
+
+  namespace Qt
+  {
+    /**
+     */
+    class IVQ_EXPORT ImageViewerWidget
+      : public QVTKWidget
+    {
+      Q_OBJECT;
+
+    public:
+      ImageViewerWidget( QWidget* parent = NULL, ::Qt::WindowFlags f = 0 );
+      virtual ~ImageViewerWidget( );
+
+      ivq::VTK::ImageViewer* GetViewer( );
+
+    protected:
+      vtkSmartPointer< ivq::VTK::ImageViewer > Viewer;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#endif // __ivq__Qt__ImageViewerWidget__h__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/Qt/MPRViewersWidget.cxx b/lib/ivq/Qt/MPRViewersWidget.cxx
new file mode 100644 (file)
index 0000000..87b0812
--- /dev/null
@@ -0,0 +1,70 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#include <ivq/Qt/MPRViewersWidget.h>
+#include <ivq/ui_MPRViewersWidget.h>
+
+#include <ivq/VTK/MPRViewers.h>
+
+// -------------------------------------------------------------------------
+ivq::Qt::MPRViewersWidget::
+MPRViewersWidget( QWidget* parent, ::Qt::WindowFlags f )
+  : QWidget( parent, f ),
+    UI( new Ui::MPRViewersWidget )
+{
+  this->UI->setupUi( this );
+  this->Viewers = vtkSmartPointer< ivq::VTK::MPRViewers >::New( );
+  this->Viewers->SetView( 0, this->UI->V1->GetViewer( ) );
+  this->Viewers->SetView( 1, this->UI->V2->GetViewer( ) );
+  this->Viewers->SetView( 2, this->UI->V3->GetViewer( ) );
+
+  // Connect slots
+  this->connect(
+    this->UI->Splitter12, SIGNAL( splitterMoved( int, int ) ),
+    this, SLOT( _Sync34( int, int ) )
+    );
+  this->connect(
+    this->UI->Splitter34, SIGNAL( splitterMoved( int, int ) ),
+    this, SLOT( _Sync12( int, int ) )
+    );
+}
+
+// -------------------------------------------------------------------------
+ivq::Qt::MPRViewersWidget::
+~MPRViewersWidget( )
+{
+  delete this->UI;
+}
+
+// -------------------------------------------------------------------------
+ivq::VTK::MPRViewers* ivq::Qt::MPRViewersWidget::
+GetViewers( )
+{
+  return( this->Viewers );
+}
+
+// -------------------------------------------------------------------------
+ivq::Qt::RendererWidget* ivq::Qt::MPRViewersWidget::
+GetRendererWidget( )
+{
+  return( this->UI->V4 );
+}
+
+// -------------------------------------------------------------------------
+void ivq::Qt::MPRViewersWidget::
+_Sync34( int a, int b )
+{
+  this->UI->Splitter34->setSizes( this->UI->Splitter12->sizes( ) );
+}
+
+// -------------------------------------------------------------------------
+void ivq::Qt::MPRViewersWidget::
+_Sync12( int a, int b )
+{
+  this->UI->Splitter12->setSizes( this->UI->Splitter34->sizes( ) );
+}
+
+// eof - $RCSfile$
diff --git a/lib/ivq/Qt/MPRViewersWidget.h b/lib/ivq/Qt/MPRViewersWidget.h
new file mode 100644 (file)
index 0000000..6d82e57
--- /dev/null
@@ -0,0 +1,53 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__Qt__MPRViewersWidget__h__
+#define __ivq__Qt__MPRViewersWidget__h__
+
+#include <ivq/ivq_export.h>
+
+#include <vtkSmartPointer.h>
+#include <QWidget>
+
+namespace Ui { class MPRViewersWidget; }
+
+namespace ivq
+{
+  namespace VTK { class MPRViewers; }
+  namespace Qt
+  {
+    class RendererWidget;
+
+    /**
+     */
+    class IVQ_EXPORT MPRViewersWidget
+      : public QWidget
+    {
+      Q_OBJECT;
+
+    public:
+      MPRViewersWidget( QWidget* parent = NULL, ::Qt::WindowFlags f = 0 );
+      virtual ~MPRViewersWidget( );
+
+      ivq::VTK::MPRViewers* GetViewers( );
+      ivq::Qt::RendererWidget* GetRendererWidget( );
+
+    private slots:
+      void _Sync34( int a, int b );
+      void _Sync12( int a, int b );
+
+    protected:
+      Ui::MPRViewersWidget* UI;
+      vtkSmartPointer< ivq::VTK::MPRViewers > Viewers;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#endif // __ivq__Qt__MPRViewersWidget__h__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/Qt/MPRViewersWidget.ui b/lib/ivq/Qt/MPRViewersWidget.ui
new file mode 100644 (file)
index 0000000..139b16f
--- /dev/null
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MPRViewersWidget</class>
+ <widget class="QWidget" name="MPRViewersWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>300</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </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="spacing">
+    <number>0</number>
+   </property>
+   <item row="0" column="0">
+    <widget class="QSplitter" name="Splitter1234">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <widget class="QSplitter" name="Splitter12">
+      <property name="orientation">
+       <enum>Qt::Horizontal</enum>
+      </property>
+      <widget class="ivq::Qt::ImageViewerWidget" name="V2" native="true"/>
+      <widget class="ivq::Qt::ImageViewerWidget" name="V1" native="true"/>
+     </widget>
+     <widget class="QSplitter" name="Splitter34">
+      <property name="orientation">
+       <enum>Qt::Horizontal</enum>
+      </property>
+      <widget class="ivq::Qt::ImageViewerWidget" name="V3" native="true"/>
+      <widget class="ivq::Qt::RendererWidget" name="V4" native="true"/>
+     </widget>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>ivq::Qt::ImageViewerWidget</class>
+   <extends>QWidget</extends>
+   <header location="global">ivq/Qt/ImageViewerWidget.h</header>
+   <container>1</container>
+  </customwidget>
+  <customwidget>
+   <class>ivq::Qt::RendererWidget</class>
+   <extends>QWidget</extends>
+   <header location="global">ivq/Qt/RendererWidget.h</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/lib/ivq/Qt/RendererWidget.cxx b/lib/ivq/Qt/RendererWidget.cxx
new file mode 100644 (file)
index 0000000..f0d54ec
--- /dev/null
@@ -0,0 +1,34 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#include <ivq/Qt/RendererWidget.h>
+
+#include <vtkRenderer.h>
+#include <vtkRenderWindow.h>
+
+// -------------------------------------------------------------------------
+ivq::Qt::RendererWidget::
+RendererWidget( QWidget* parent, ::Qt::WindowFlags f )
+  : QVTKWidget( parent, f )
+{
+  this->Renderer = vtkSmartPointer< vtkRenderer >::New( );
+  this->GetRenderWindow( )->AddRenderer( this->Renderer );
+}
+
+// -------------------------------------------------------------------------
+ivq::Qt::RendererWidget::
+~RendererWidget( )
+{
+}
+
+// -------------------------------------------------------------------------
+vtkRenderer* ivq::Qt::RendererWidget::
+GetRenderer( )
+{
+  return( this->Renderer.GetPointer( ) );
+}
+
+// eof - $RCSfile$
diff --git a/lib/ivq/Qt/RendererWidget.h b/lib/ivq/Qt/RendererWidget.h
new file mode 100644 (file)
index 0000000..362c8cc
--- /dev/null
@@ -0,0 +1,44 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__Qt__RendererWidget__h__
+#define __ivq__Qt__RendererWidget__h__
+
+#include <ivq/ivq_export.h>
+
+#include <vtkSmartPointer.h>
+#include <QVTKWidget.h>
+
+class vtkRenderer;
+
+namespace ivq
+{
+  namespace Qt
+  {
+    /**
+     */
+    class IVQ_EXPORT RendererWidget
+      : public QVTKWidget
+    {
+      Q_OBJECT;
+
+    public:
+      RendererWidget( QWidget* parent = NULL, ::Qt::WindowFlags f = 0 );
+      virtual ~RendererWidget( );
+
+      vtkRenderer* GetRenderer( );
+
+    protected:
+      vtkSmartPointer< vtkRenderer > Renderer;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#endif // __ivq__Qt__RendererWidget__h__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/VTK/BrushWidget.cxx b/lib/ivq/VTK/BrushWidget.cxx
new file mode 100644 (file)
index 0000000..1d42a4a
--- /dev/null
@@ -0,0 +1,639 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#include <ivq/VTK/BrushWidget.h>
+
+#include <cmath>
+#include <cstring>
+
+#include <vtkCallbackCommand.h>
+#include <vtkCellArray.h>
+#include <vtkImageData.h>
+#include <vtkImageMapToColors.h>
+#include <vtkLookupTable.h>
+#include <vtkPoints.h>
+#include <vtkPolyData.h>
+#include <vtkProperty.h>
+#include <vtkPropPicker.h>
+#include <vtkRenderer.h>
+#include <vtkRenderWindowInteractor.h>
+
+#include <ivq/VTK/ImageActor.h>
+#include <ivq/VTK/PolyDataActor.h>
+
+// -------------------------------------------------------------------------
+ivq::VTK::BrushWidget::
+Self* ivq::VTK::BrushWidget::
+New( )
+{
+  return( new Self );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::BrushWidget::
+SetEnabled( int enabling )
+{
+  if( this->Interactor == NULL )
+  {
+    vtkErrorMacro(
+      << "The interactor must be set prior to enabling/disabling widget"
+      );
+    return;
+
+  } // fi
+  if( this->Actor.GetPointer( ) == NULL )
+  {
+    vtkErrorMacro(
+      << "The external prop must be set prior to enabling/disabling widget"
+      );
+    return;
+
+  } // fi
+
+  if( enabling != 0 )
+  {
+    if( this->Enabled != 0 )
+      return;
+    if( this->CurrentRenderer == NULL )
+    {
+      this->SetCurrentRenderer(
+        this->Interactor->FindPokedRenderer(
+          this->Interactor->GetLastEventPosition( )[ 0 ],
+          this->Interactor->GetLastEventPosition( )[ 1 ]
+          )
+        );
+      if( this->CurrentRenderer == NULL )
+        return;
+
+    } // fi
+    this->Enabled = 1;
+    this->Brushing = false;
+    this->Filling = false;
+    this->ActualColor = 1;
+    this->_AddObservers( );
+
+    this->CircleActor->GetProperty( )->
+      SetColor( this->CanvasLUT->GetTableValue( this->ActualColor ) );
+    this->CurrentRenderer->AddViewProp( this->CircleActor->GetActor( ) );
+    this->CurrentRenderer->AddViewProp( this->CanvasActor );
+    this->CircleActor->GetActor( )->VisibilityOff( );
+
+    // Turn on the handles
+    /* TODO
+       for ( int i = 0; i < this->NumberOfHandles; ++i )
+       {
+       this->CurrentRenderer->AddViewProp(this->Handle[i]);
+       this->Handle[i]->SetProperty(this->HandleProperty);
+       this->Handle[i]->PickableOff();
+       }
+
+       this->SizeHandles();
+
+       this->CurrentRenderer->AddViewProp(this->LineActor);
+       this->LineActor->SetProperty(this->LineProperty);
+       this->LineActor->PickableOff();
+    */
+    this->InvokeEvent(vtkCommand::EnableEvent,NULL);
+  }
+  else
+  {
+    vtkDebugMacro( << "Disabling tracer widget" );
+    if( this->Enabled == 0 )
+      return;
+
+    // If disabling occurs without finishing an activity, cleanup states
+    /* TODO
+       if ( this->State == vtkImageTracerWidget::Tracing )
+       {
+       this->OnLeftButtonUp();
+       }
+       else if ( this->State == vtkImageTracerWidget::Snapping )
+       {
+       this->Interactor->SetControlKey( 1 );
+       this->OnMiddleButtonUp();
+       }
+    */
+    this->Enabled = 0;
+    this->Brushing = false;
+    this->Filling = false;
+    this->Interactor->RemoveObserver( this->EventCallbackCommand );
+    this->CurrentRenderer->RemoveViewProp( this->CircleActor->GetActor( ) );
+    this->CurrentRenderer->RemoveViewProp( this->CanvasActor );
+
+    // Turn off the handles
+    /* TODO
+       for( int i = 0; i < this->NumberOfHandles; ++i )
+       {
+       this->CurrentRenderer->RemoveViewProp(this->Handle[i]);
+       }
+
+       this->CurrentRenderer->RemoveViewProp(this->LineActor);
+
+       this->CurrentHandle = NULL;
+    */
+
+    this->InvokeEvent( vtkCommand::DisableEvent, NULL );
+    this->SetCurrentRenderer( NULL );
+
+  } // fi
+  this->Interactor->Render( );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::BrushWidget::
+PlaceWidget( double bounds[ 6 ] )
+{
+  double bds[ 6 ], ctr[ 3 ];
+  this->AdjustBounds( bounds, bds, ctr );
+  for( int i = 0; i < 6; ++i )
+    this->InitialBounds[ i ] = bds[ i ];
+  this->InitialLength = std::sqrt(
+    ( bds[ 1 ] - bds[ 0 ] ) * ( bds[ 1 ] - bds[ 0 ] ) +
+    ( bds[ 3 ] - bds[ 2 ] ) * ( bds[ 3 ] - bds[ 2 ] ) +
+    ( bds[ 5 ] - bds[ 4 ] ) * ( bds[ 5 ] - bds[ 4 ] )
+    );
+  this->SizeHandles( );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::BrushWidget::
+PlaceWidget( )
+{
+  this->Superclass::PlaceWidget( );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::BrushWidget::
+PlaceWidget(
+  double xmin, double xmax,
+  double ymin, double ymax,
+  double zmin, double zmax
+  )
+{
+  this->Superclass::PlaceWidget( xmin, xmax, ymin, ymax, zmin, zmax );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::BrushWidget::
+SetImageActor( ivq::VTK::ImageActor* actor )
+{
+  if( this->Actor != actor )
+  {
+    this->Actor = actor;
+    this->PropPicker->InitializePickList( );
+    if( this->Actor.GetPointer( ) != NULL )
+    {
+      this->PropPicker->AddPickList( this->Actor );
+
+      vtkImageData* image = this->Actor->GetInput( );
+      int ext[ 6 ];
+      double ori[ 3 ], spa[ 3 ];
+      image->GetExtent( ext );
+      image->GetOrigin( ori );
+      image->GetSpacing( spa );
+
+      this->Spacing = spa[ 0 ];
+      this->Spacing = ( spa[ 1 ] < this->Spacing )? spa[ 1 ]: this->Spacing;
+      this->Spacing = ( spa[ 2 ] < this->Spacing )? spa[ 2 ]: this->Spacing;
+      this->Radius = this->Spacing;
+      this->CircleActor->GetActor( )->SetScale( this->Radius );
+
+      unsigned long canvas_size = ext[ 1 ] - ext[ 0 ] + 1;
+      canvas_size              *= ext[ 3 ] - ext[ 2 ] + 1;
+      canvas_size              *= ext[ 5 ] - ext[ 4 ] + 1;
+
+      this->Canvas = vtkSmartPointer< vtkImageData >::New( );
+      this->Canvas->SetExtent( ext );
+      this->Canvas->SetOrigin( ori );
+      this->Canvas->SetSpacing( spa );
+      this->Canvas->AllocateScalars( VTK_UNSIGNED_CHAR, 1 );
+      std::memset(
+        this->Canvas->GetScalarPointer( ), 0,
+        canvas_size
+        );
+
+      this->CanvasLUT = vtkSmartPointer< vtkLookupTable >::New( );
+      this->CanvasLUT->SetNumberOfColors( 7 );
+      this->CanvasLUT->SetNumberOfTableValues( 7 );
+      this->CanvasLUT->SetTableRange( 0, 6 );
+      this->CanvasLUT->Build( );
+      this->CanvasLUT->SetTableValue( 0, 0.0, 0.0, 0.0, 0.0 );
+      this->CanvasLUT->SetTableValue( 1, 1.0, 0.0, 0.0, 0.6 );
+      this->CanvasLUT->SetTableValue( 2, 0.0, 1.0, 0.0, 0.6 );
+      this->CanvasLUT->SetTableValue( 3, 0.0, 0.0, 1.0, 0.6 );
+      this->CanvasLUT->SetTableValue( 4, 0.0, 1.0, 1.0, 0.6 );
+      this->CanvasLUT->SetTableValue( 5, 1.0, 0.0, 1.0, 0.6 );
+      this->CanvasLUT->SetTableValue( 6, 1.0, 1.0, 0.0, 0.6 );
+
+      this->CanvasVisualization =
+        vtkSmartPointer< vtkImageMapToColors >::New( );
+      this->CanvasVisualization->SetInputData( this->Canvas );
+      this->CanvasVisualization->SetLookupTable( this->CanvasLUT );
+      this->CanvasVisualization->Update( );
+
+      this->CanvasActor = vtkSmartPointer< ivq::VTK::ImageActor >::New( );
+      this->CanvasActor->
+        SetInputConnection( this->CanvasVisualization->GetOutputPort( ) );
+      this->CanvasActor->Update( );
+
+    } // fi
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+vtkImageData* ivq::VTK::BrushWidget::
+GetCanvas( ) const
+{
+  return( this->Canvas.GetPointer( ) );
+}
+
+// -------------------------------------------------------------------------
+ivq::VTK::BrushWidget::
+BrushWidget( )
+  : Superclass( ),
+    Brushing( false ),
+    Filling( false )
+{
+  this->PropPicker = vtkSmartPointer< vtkPropPicker >::New( );
+  this->PropPicker->PickFromListOn( );
+  this->EventCallbackCommand->SetCallback( Self::ProcessEvents );
+
+  double _2pi = double( 6.28318530718 );
+  unsigned int circle_samples = 50;
+  double _off = _2pi / double( circle_samples );
+  vtkSmartPointer< vtkPoints > circle_points =
+    vtkSmartPointer< vtkPoints >::New( );
+  vtkSmartPointer< vtkCellArray > circle_lines =
+    vtkSmartPointer< vtkCellArray >::New( );
+  circle_lines->InsertNextCell( circle_samples + 1 );
+  for( unsigned int i = 0; i < circle_samples; ++i )
+  {
+    double w = _off * double( i );
+    circle_points->InsertNextPoint(
+      std::cos( w ), std::sin( w ), double( 0 )
+      );
+    circle_lines->InsertCellPoint( i );
+
+  } // rof
+  circle_lines->InsertCellPoint( 0 );
+
+  this->Circle = vtkSmartPointer< vtkPolyData >::New( );
+  this->Circle->SetPoints( circle_points );
+  this->Circle->SetLines( circle_lines );
+
+  this->CircleActor = vtkSmartPointer< ivq::VTK::PolyDataActor >::New( );
+  this->CircleActor->SetInputData( this->Circle );
+  this->CircleActor->GetProperty( )->SetLineWidth( 2 );
+}
+
+// -------------------------------------------------------------------------
+ivq::VTK::BrushWidget::
+~BrushWidget( )
+{
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::BrushWidget::
+_AddObservers( )
+{
+  vtkRenderWindowInteractor* i = this->Interactor;
+  if( i == NULL )
+    return;
+
+  i->AddObserver(
+    vtkCommand::KeyPressEvent,
+    this->EventCallbackCommand,
+    this->Priority
+    );
+  i->AddObserver(
+    vtkCommand::KeyReleaseEvent,
+    this->EventCallbackCommand,
+    this->Priority
+    );
+  i->AddObserver(
+    vtkCommand::MouseWheelBackwardEvent,
+    this->EventCallbackCommand,
+    this->Priority
+    );
+  i->AddObserver(
+    vtkCommand::MouseWheelForwardEvent,
+    this->EventCallbackCommand,
+    this->Priority
+    );
+  i->AddObserver(
+    vtkCommand::MouseMoveEvent,
+    this->EventCallbackCommand,
+    this->Priority
+    );
+  i->AddObserver(
+    vtkCommand::LeftButtonPressEvent,
+    this->EventCallbackCommand,
+    this->Priority
+    );
+  i->AddObserver(
+    vtkCommand::LeftButtonReleaseEvent,
+    this->EventCallbackCommand,
+    this->Priority
+    );
+  i->AddObserver(
+    vtkCommand::MiddleButtonPressEvent,
+    this->EventCallbackCommand,
+    this->Priority
+    );
+  i->AddObserver(
+    vtkCommand::MiddleButtonReleaseEvent,
+    this->EventCallbackCommand,
+    this->Priority
+    );
+  i->AddObserver(
+    vtkCommand::RightButtonPressEvent,
+    this->EventCallbackCommand,
+    this->Priority
+    );
+  i->AddObserver(
+    vtkCommand::RightButtonReleaseEvent,
+    this->EventCallbackCommand,
+    this->Priority
+    );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::BrushWidget::
+ProcessEvents(
+  vtkObject* object, unsigned long event, void* clientdata, void* calldata
+  )
+{
+  Self* self = reinterpret_cast< Self* >( clientdata );
+  switch( event )
+  {
+  case vtkCommand::KeyPressEvent:
+    self->OnKeyPress( );
+    break;
+  case vtkCommand::KeyReleaseEvent:
+    self->OnKeyRelease( );
+    break;
+  case vtkCommand::MouseWheelBackwardEvent:
+    self->OnMouseWheelBackward( );
+    break;
+  case vtkCommand::MouseWheelForwardEvent:
+    self->OnMouseWheelForward( );
+    break;
+  case vtkCommand::LeftButtonPressEvent:
+    self->OnLeftButtonDown( );
+    break;
+  case vtkCommand::LeftButtonReleaseEvent:
+    self->OnLeftButtonUp( );
+    break;
+  case vtkCommand::MiddleButtonPressEvent:
+    self->OnMiddleButtonDown( );
+    break;
+  case vtkCommand::MiddleButtonReleaseEvent:
+    self->OnMiddleButtonUp( );
+    break;
+  case vtkCommand::RightButtonPressEvent:
+    self->OnRightButtonDown( );
+    break;
+  case vtkCommand::RightButtonReleaseEvent:
+    self->OnRightButtonUp( );
+    break;
+  case vtkCommand::MouseMoveEvent:
+    self->OnMouseMove( );
+    break;
+  } // hctiws
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::BrushWidget::
+OnKeyPress( )
+{
+  if(
+    this->Interactor->GetKeyCode( ) == 'b' ||
+    this->Interactor->GetKeyCode( ) == 'B'
+    )
+  {
+    this->Brushing = true;
+    this->CircleActor->GetActor( )->VisibilityOn( );
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::BrushWidget::
+OnKeyRelease( )
+{
+  if(
+    this->Interactor->GetKeyCode( ) == 'b' ||
+    this->Interactor->GetKeyCode( ) == 'B'
+    )
+  {
+    this->Brushing = false;
+    this->CircleActor->GetActor( )->VisibilityOff( );
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::BrushWidget::
+OnMouseWheelBackward( )
+{
+  if( this->Brushing )
+  {
+    this->Radius -= this->Spacing;
+    if( this->Radius < this->Spacing )
+      this->Radius = this->Spacing;
+    this->CircleActor->GetActor( )->SetScale( this->Radius );
+
+    // Interact, if desired
+    this->EventCallbackCommand->SetAbortFlag( 1 );
+    this->InvokeEvent( vtkCommand::InteractionEvent, NULL );
+    this->Interactor->Render( );
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::BrushWidget::
+OnMouseWheelForward( )
+{
+  if( this->Brushing )
+  {
+    this->Radius += this->Spacing;
+    this->CircleActor->GetActor( )->SetScale( this->Radius );
+
+    // Interact, if desired
+    this->EventCallbackCommand->SetAbortFlag( 1 );
+    this->InvokeEvent( vtkCommand::InteractionEvent, NULL );
+    this->Interactor->Render( );
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::BrushWidget::
+OnLeftButtonDown( )
+{
+  if( this->Brushing )
+  {
+    this->Filling = true;
+
+    // Interact, if desired
+    this->EventCallbackCommand->SetAbortFlag( 1 );
+    this->InvokeEvent( vtkCommand::InteractionEvent, NULL );
+    this->Interactor->Render( );
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::BrushWidget::
+OnLeftButtonUp( )
+{
+  if( this->Brushing )
+  {
+    this->Filling = false;
+
+    // Interact, if desired
+    this->EventCallbackCommand->SetAbortFlag( 1 );
+    this->InvokeEvent( vtkCommand::InteractionEvent, NULL );
+    this->Interactor->Render( );
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::BrushWidget::
+OnMiddleButtonDown( )
+{
+  if( this->Brushing )
+  {
+    // Interact, if desired
+    this->EventCallbackCommand->SetAbortFlag( 1 );
+    this->InvokeEvent( vtkCommand::InteractionEvent, NULL );
+    this->Interactor->Render( );
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::BrushWidget::
+OnMiddleButtonUp( )
+{
+  if( this->Brushing )
+  {
+    // Interact, if desired
+    this->EventCallbackCommand->SetAbortFlag( 1 );
+    this->InvokeEvent( vtkCommand::InteractionEvent, NULL );
+    this->Interactor->Render( );
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::BrushWidget::
+OnRightButtonDown( )
+{
+  if( this->Brushing )
+  {
+    // Interact, if desired
+    this->EventCallbackCommand->SetAbortFlag( 1 );
+    this->InvokeEvent( vtkCommand::InteractionEvent, NULL );
+    this->Interactor->Render( );
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::BrushWidget::
+OnRightButtonUp( )
+{
+  if( this->Brushing )
+  {
+    this->ActualColor = this->ActualColor + 1;
+    if( this->ActualColor >= this->CanvasLUT->GetNumberOfTableValues( ) )
+      this->ActualColor = 1;
+    this->CircleActor->GetProperty( )->
+      SetColor( this->CanvasLUT->GetTableValue( this->ActualColor ) );
+
+    // Interact, if desired
+    this->EventCallbackCommand->SetAbortFlag( 1 );
+    this->InvokeEvent( vtkCommand::InteractionEvent, NULL );
+    this->Interactor->Render( );
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::BrushWidget::
+OnMouseMove( )
+{
+  if( this->Brushing )
+  {
+    int X = this->Interactor->GetEventPosition( )[ 0 ];
+    int Y = this->Interactor->GetEventPosition( )[ 1 ];
+    int p = this->PropPicker->PickProp( X, Y, this->CurrentRenderer );
+    if( p == 0 )
+      return;
+    double pos[ 3 ];
+    this->PropPicker->GetPickPosition( pos );
+    this->CircleActor->GetActor( )->SetPosition( pos );
+
+    if( this->Filling )
+    {
+      double x[ 3 ], y[ 3 ], pcoords[ 3 ], spac[ 3 ];
+      int ijk[ 3 ], ext[ 6 ];
+      this->CircleActor->GetActor( )->GetPosition( x );
+      this->Canvas->ComputeStructuredCoordinates( x, ijk, pcoords );
+      this->Canvas->GetSpacing( spac );
+      this->Canvas->GetExtent( ext );
+
+      int min_h, max_h, min_v, max_v;
+      min_h = int( ( x[ 0 ] - this->Radius ) / spac[ 0 ] );
+      max_h = int( ( x[ 0 ] + this->Radius ) / spac[ 0 ] );
+      min_v = int( ( x[ 1 ] - this->Radius ) / spac[ 1 ] );
+      max_v = int( ( x[ 1 ] + this->Radius ) / spac[ 1 ] );
+      for( int h = min_h; h <= max_h; ++h )
+      {
+        if( ext[ 0 ] <= h && h <= ext[ 1 ] )
+        {
+          for( int v = min_v; v <= max_v; ++v )
+          {
+            if( ext[ 2 ] <= v && v <= ext[ 3 ] )
+            {
+              /* TODO
+                 ijk[ 0 ] = h;
+                 ijk[ 1 ] = v;
+                 this->Canvas->GetPoint( this->Canvas->ComputePointId( ijk ), y );
+                 double d = ( y[ 0 ] - x[ 0 ] ) * ( y[ 0 ] - x[ 0 ] );
+                 d       += ( y[ 1 ] - x[ 1 ] ) * ( y[ 1 ] - x[ 1 ] );
+                 d       += ( y[ 2 ] - x[ 2 ] ) * ( y[ 2 ] - x[ 2 ] );
+                 std::cout << d << " " << this->Radius << std::endl;
+                 if( std::sqrt( d ) <= this->Radius )
+              */
+              this->Canvas->
+                SetScalarComponentFromFloat( h, v, 0, 0, this->ActualColor );
+
+            } // fi
+
+          } // rof
+
+        } // fi
+
+      } // rof
+      this->Canvas->Modified( );
+      this->CanvasActor->Modified( );
+
+    } // fi
+
+    // Interact, if desired
+    this->EventCallbackCommand->SetAbortFlag( 1 );
+    this->InvokeEvent( vtkCommand::InteractionEvent, NULL );
+    this->Interactor->Render( );
+
+  } // fi
+}
+
+// eof - $RCSfile$
diff --git a/lib/ivq/VTK/BrushWidget.h b/lib/ivq/VTK/BrushWidget.h
new file mode 100644 (file)
index 0000000..78f9beb
--- /dev/null
@@ -0,0 +1,112 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__VTK__BrushWidget__h__
+#define __ivq__VTK__BrushWidget__h__
+
+#include <ivq/ivq_export.h>
+
+#include <vtkSmartPointer.h>
+#include <vtk3DWidget.h>
+
+class vtkImageData;
+class vtkImageMapToColors;
+class vtkLookupTable;
+class vtkPolyData;
+class vtkPropPicker;
+
+namespace ivq
+{
+  namespace VTK
+  {
+    class ImageActor;
+    class PolyDataActor;
+
+    /**
+     */
+    class IVQ_EXPORT BrushWidget
+      : public vtk3DWidget
+    {
+    public:
+      typedef BrushWidget Self;
+
+    public:
+      vtkTypeMacro( BrushWidget, vtk3DWidget );
+
+    public:
+      static Self* New( );
+
+      virtual void SetEnabled( int enabling ) override;
+      virtual void PlaceWidget( double bounds[ 6 ] ) override;
+      virtual void PlaceWidget( ) override;
+      virtual void PlaceWidget(
+        double xmin, double xmax,
+        double ymin, double ymax,
+        double zmin, double zmax
+        ) override;
+
+      virtual void SetImageActor( ivq::VTK::ImageActor* actor );
+
+      vtkImageData* GetCanvas( ) const;
+
+    protected:
+      BrushWidget( );
+      virtual ~BrushWidget( );
+
+      void _AddObservers( );
+
+      //handles the events
+      static void ProcessEvents(
+        vtkObject* object,
+        unsigned long event,
+        void* clientdata,
+        void* calldata
+        );
+
+      // ProcessEvents() dispatches to these methods.
+      virtual void OnKeyPress( );
+      virtual void OnKeyRelease( );
+      virtual void OnMouseWheelBackward( );
+      virtual void OnMouseWheelForward( );
+      virtual void OnLeftButtonDown( );
+      virtual void OnLeftButtonUp( );
+      virtual void OnMiddleButtonDown( );
+      virtual void OnMiddleButtonUp( );
+      virtual void OnRightButtonDown( );
+      virtual void OnRightButtonUp( );
+      virtual void OnMouseMove( );
+
+    private:
+      // Purposely not implemented
+      BrushWidget( const Self& );
+      Self& operator=( const Self& );
+
+    protected:
+      vtkSmartPointer< ivq::VTK::ImageActor > Actor;
+      vtkSmartPointer< vtkPropPicker >        PropPicker;
+
+      vtkSmartPointer< vtkImageData >         Canvas;
+      vtkSmartPointer< vtkLookupTable >       CanvasLUT;
+      vtkSmartPointer< vtkImageMapToColors >  CanvasVisualization;
+      vtkSmartPointer< ivq::VTK::ImageActor > CanvasActor;
+
+      vtkSmartPointer< vtkPolyData >             Circle;
+      vtkSmartPointer< ivq::VTK::PolyDataActor > CircleActor;
+
+      bool Brushing;
+      bool Filling;
+      double Radius;
+      double Spacing;
+      unsigned int ActualColor;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#endif // __ivq__VTK__BrushWidget__h__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/VTK/ImageActor.cxx b/lib/ivq/VTK/ImageActor.cxx
new file mode 100644 (file)
index 0000000..b9a4f85
--- /dev/null
@@ -0,0 +1,217 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#include <ivq/VTK/ImageActor.h>
+
+#include <vtkCommand.h>
+#include <vtkImageData.h>
+#include <vtkImageProperty.h>
+#include <vtkImageSliceMapper.h>
+#include <vtkPlane.h>
+
+// -------------------------------------------------------------------------
+ivq::VTK::ImageActor::
+Self* ivq::VTK::ImageActor::
+New( )
+{
+  return( new Self( ) );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageActor::
+Modified( )
+{
+  if( this->Mapper != NULL )
+  {
+    if( this->Mapper->GetNumberOfInputConnections( 0 ) > 0 )
+    {
+      this->Mapper->Modified( );
+      this->Mapper->Update( );
+      this->Superclass::Modified( );
+
+    } // fi
+  }
+  else
+    this->Superclass::Modified( );
+}
+
+// -------------------------------------------------------------------------
+vtkImageData* ivq::VTK::ImageActor::
+GetInput( )
+{
+  return( this->Mapper->GetInput( ) );
+}
+
+// -------------------------------------------------------------------------
+vtkAlgorithm* ivq::VTK::ImageActor::
+GetInputAlgorithm( )
+{
+  return( this->Mapper->GetInputAlgorithm( ) );
+}
+
+// -------------------------------------------------------------------------
+vtkInformation* ivq::VTK::ImageActor::
+GetInputInformation( )
+{
+  return( this->Mapper->GetInputInformation( ) );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageActor::
+SetInputData( vtkImageData* input )
+{
+  this->Mapper->SetInputData( input );
+  this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageActor::
+SetInputConnection( vtkAlgorithmOutput* aout )
+{
+  this->Mapper->SetInputConnection( aout );
+  this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+int ivq::VTK::ImageActor::
+GetOrientation( ) const
+{
+  return( this->Mapper->GetOrientation( ) );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageActor::
+SetOrientation( int orientation )
+{
+  this->Mapper->SetOrientation( ( orientation < 3 )? orientation: 2 );
+  this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+int ivq::VTK::ImageActor::
+GetSliceNumber( ) const
+{
+  return( this->Mapper->GetSliceNumber( ) );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageActor::
+SetSliceNumber( int slice )
+{
+  static int s = 0;
+  vtkImageData* image = this->Mapper->GetInput( );
+  if( image != NULL )
+  {
+    // Update slice
+    s = slice;
+    if( s < this->Mapper->GetSliceNumberMinValue( ) )
+      s = this->Mapper->GetSliceNumberMinValue( );
+    if( s > this->Mapper->GetSliceNumberMaxValue( ) )
+      s = this->Mapper->GetSliceNumberMaxValue( );
+    this->Mapper->SetSliceNumber( s );
+
+    // Propagate modifications
+    this->InvokeEvent( vtkCommand::InteractionEvent );
+    this->Modified( );
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+vtkPlane* ivq::VTK::ImageActor::
+GetSlicePlane( )
+{
+  return( this->Mapper->GetSlicePlane( ) );
+}
+
+// -------------------------------------------------------------------------
+const vtkPlane* ivq::VTK::ImageActor::
+GetSlicePlane( ) const
+{
+  return( this->Mapper->GetSlicePlane( ) );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageActor::
+GetActorBounds( double bounds[ 6 ] )
+{
+  double origin[ 3 ];
+  this->GetInput( )->GetBounds( bounds );
+  this->GetSlicePlane( )->GetOrigin( origin );
+  int orientation = this->GetOrientation( );
+  bounds[ ( orientation << 1 ) ] =
+    bounds[ ( orientation << 1 ) + 1 ] = origin[ orientation ];
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageActor::
+GetActorCenter( double center[ 3 ] )
+{
+  this->GetSlicePlane( )->GetOrigin( center );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageActor::
+ResetWindowLevel( )
+{
+  double r[ 2 ];
+  this->GetInput( )->GetScalarRange( r );
+  this->GetProperty( )->SetColorWindow( r[ 1 ] - r[ 0 ] );
+  this->GetProperty( )->SetColorLevel( ( r[ 1 ] + r[ 0 ] ) * 0.5 );
+  this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+double ivq::VTK::ImageActor::
+GetColorWindow( )
+{
+  return( this->GetProperty( )->GetColorWindow( ) );
+}
+
+// -------------------------------------------------------------------------
+double ivq::VTK::ImageActor::
+GetColorLevel( )
+{
+  return( this->GetProperty( )->GetColorLevel( ) );
+}
+
+// -------------------------------------------------------------------------
+void  ivq::VTK::ImageActor::
+SetColorWindow( const double& w )
+{
+  this->GetProperty( )->SetColorWindow( w );
+  this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+void  ivq::VTK::ImageActor::
+SetColorLevel( const double& l )
+{
+  this->GetProperty( )->SetColorLevel( l );
+  this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+ivq::VTK::ImageActor::
+ImageActor( )
+  : Superclass( )
+{
+  this->Mapper = vtkImageSliceMapper::New( );
+  this->SetMapper( this->Mapper );
+  this->GetProperty( )->SetInterpolationTypeToNearest( );
+}
+
+// -------------------------------------------------------------------------
+ivq::VTK::ImageActor::
+~ImageActor( )
+{
+  if( this->Mapper != NULL )
+    this->Mapper->Delete( );
+  this->Mapper = NULL;
+  this->SetMapper( NULL );
+}
+
+// eof - $RCSfile$
diff --git a/lib/ivq/VTK/ImageActor.h b/lib/ivq/VTK/ImageActor.h
new file mode 100644 (file)
index 0000000..e0e3ebb
--- /dev/null
@@ -0,0 +1,82 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__VTK__ImageActor__h__
+#define __ivq__VTK__ImageActor__h__
+
+#include <ivq/ivq_export.h>
+
+#include <vtkImageSlice.h>
+
+class vtkAlgorithm;
+class vtkAlgorithmOutput;
+class vtkImageData;
+class vtkImageSliceMapper;
+class vtkPlane;
+
+namespace ivq
+{
+  namespace VTK
+  {
+    /**
+     */
+    class IVQ_EXPORT ImageActor
+      : public vtkImageSlice
+    {
+    public:
+      typedef ImageActor Self;
+
+    public:
+      vtkTypeMacro( ImageActor, vtkImageSlice );
+
+    public:
+      static Self* New( );
+
+      virtual void Modified( ) override;
+
+      vtkImageData* GetInput( );
+      vtkAlgorithm* GetInputAlgorithm( );
+      vtkInformation* GetInputInformation( );
+      void SetInputData( vtkImageData* input );
+      void SetInputConnection( vtkAlgorithmOutput* aout );
+
+      int GetOrientation( ) const;
+      void SetOrientation( int orientation );
+
+      int GetSliceNumber( ) const;
+      void SetSliceNumber( int slice );
+
+      vtkPlane* GetSlicePlane( );
+      const vtkPlane* GetSlicePlane( ) const;
+      void GetActorBounds( double bounds[ 6 ] );
+      void GetActorCenter( double center[ 3 ] );
+
+      void ResetWindowLevel( );
+      double GetColorWindow( );
+      double GetColorLevel( );
+      void  SetColorWindow( const double& w );
+      void  SetColorLevel( const double& l );
+
+    protected:
+      ImageActor( );
+      virtual ~ImageActor( );
+
+    private:
+      // Purposely not implemented
+      ImageActor( const Self& );
+      Self& operator=( const Self& );
+
+    protected:
+      vtkImageSliceMapper* Mapper;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#endif // __ivq__VTK__ImageActor__h__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/VTK/ImageSlicePointPlacer.cxx b/lib/ivq/VTK/ImageSlicePointPlacer.cxx
new file mode 100644 (file)
index 0000000..b209f4a
--- /dev/null
@@ -0,0 +1,280 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#include <ivq/VTK/ImageSlicePointPlacer.h>
+
+#include <vtkBoundedPlanePointPlacer.h>
+#include <vtkImageData.h>
+#include <vtkImageMapper3D.h>
+#include <vtkImageSlice.h>
+#include <vtkImageSliceMapper.h>
+#include <vtkPlane.h>
+
+// -------------------------------------------------------------------------
+vtkCxxSetObjectMacro(
+  ivq::VTK::ImageSlicePointPlacer, ImageSlice, vtkImageSlice
+  );
+
+// -------------------------------------------------------------------------
+ivq::VTK::ImageSlicePointPlacer::
+Self* ivq::VTK::ImageSlicePointPlacer::
+New( )
+{
+  return( new Self( ) );
+}
+
+// -------------------------------------------------------------------------
+int ivq::VTK::ImageSlicePointPlacer::
+ComputeWorldPosition(
+  vtkRenderer* ren,
+  double displayPos[ 2 ],
+  double worldPos[ 3 ],
+  double worldOrient[ 9 ]
+  )
+{
+  if( !this->UpdateInternalState( ) )
+    return( 0 );
+  return(
+    this->Placer->ComputeWorldPosition(
+      ren, displayPos, worldPos, worldOrient
+      )
+    );
+}
+
+// -------------------------------------------------------------------------
+int ivq::VTK::ImageSlicePointPlacer::
+ComputeWorldPosition(
+  vtkRenderer* ren,
+  double displayPos[ 2 ],
+  double refWorldPos[ 2 ],
+  double worldPos[ 3 ],
+  double worldOrient[ 9 ]
+  )
+{
+  if( !this->UpdateInternalState( ) )
+    return( 0 );
+  return(
+    this->Placer->ComputeWorldPosition(
+      ren, displayPos, refWorldPos, worldPos, worldOrient
+      )
+    );
+}
+
+// -------------------------------------------------------------------------
+int ivq::VTK::ImageSlicePointPlacer::
+ValidateWorldPosition( double worldPos[ 3 ] )
+{
+  if( !this->UpdateInternalState( ) )
+    return( 0 );
+  return( this->Placer->ValidateWorldPosition( worldPos ) );
+}
+
+// -------------------------------------------------------------------------
+int ivq::VTK::ImageSlicePointPlacer::
+ValidateWorldPosition( double worldPos[ 3 ], double worldOrient[ 9 ] )
+{
+  if( !this->UpdateInternalState( ) )
+    return( 0 );
+  return( this->Placer->ValidateWorldPosition( worldPos, worldOrient ) );
+}
+
+// -------------------------------------------------------------------------
+int ivq::VTK::ImageSlicePointPlacer::
+UpdateWorldPosition(
+  vtkRenderer* ren, double worldPos[ 3 ], double worldOrient[ 9 ]
+  )
+{
+  if( !this->UpdateInternalState( ) )
+    return( 0 );
+  return( this->Placer->UpdateWorldPosition( ren, worldPos, worldOrient ) );
+}
+
+// -------------------------------------------------------------------------
+int ivq::VTK::ImageSlicePointPlacer::
+UpdateInternalState( )
+{
+  if( !this->ImageSlice )
+    return( 0 );
+
+  vtkImageData* input = this->ImageSlice->GetMapper( )->GetInput( );
+  if( !input )
+    return( 0 );
+
+  double spacing[ 3 ];
+  input->GetSpacing( spacing );
+
+  double origin[ 3 ];
+  input->GetOrigin( origin );
+
+  double b[ 6 ];
+  this->ImageSlice->GetBounds( b );
+  if( this->Bounds[ 0 ] != VTK_DOUBLE_MAX)
+  {
+    b[ 0 ] = ( b[ 0 ] < this->Bounds[ 0 ] )? this->Bounds[ 0 ] : b[ 0 ];
+    b[ 1 ] = ( b[ 1 ] > this->Bounds[ 1 ] )? this->Bounds[ 1 ] : b[ 1 ];
+    b[ 2 ] = ( b[ 2 ] < this->Bounds[ 2 ] )? this->Bounds[ 2 ] : b[ 2 ];
+    b[ 3 ] = ( b[ 3 ] > this->Bounds[ 3 ] )? this->Bounds[ 3 ] : b[ 3 ];
+    b[ 4 ] = ( b[ 4 ] < this->Bounds[ 4 ] )? this->Bounds[ 4 ] : b[ 4 ];
+    b[ 5 ] = ( b[ 5 ] > this->Bounds[ 5 ] )? this->Bounds[ 5 ] : b[ 5 ];
+
+  } // fi
+
+  int displayExtent[ 6 ] = { 0, 1, 0, 1, 0, 1 };
+  input->GetExtent( displayExtent );
+  vtkImageSliceMapper* mapper =
+    vtkImageSliceMapper::SafeDownCast( this->ImageSlice->GetMapper( ) );
+  if( mapper != NULL )
+  {
+    int ori = mapper->GetOrientation( );
+    displayExtent[ ( ori << 1 ) + 1 ] =
+      displayExtent[ ori << 1 ] =
+      mapper->GetSliceNumber( );
+
+  } // fi
+
+  int axis;
+  double position;
+  if( displayExtent[ 0 ] == displayExtent[ 1 ] )
+  {
+    axis = vtkBoundedPlanePointPlacer::XAxis;
+    position = origin[ 0 ] + displayExtent[ 0 ] * spacing[ 0 ];
+  }
+  else if( displayExtent[ 2 ] == displayExtent[ 3 ] )
+  {
+    axis = vtkBoundedPlanePointPlacer::YAxis;
+    position = origin[ 1 ] + displayExtent[ 2 ] * spacing[ 1 ];
+  }
+  else if( displayExtent[ 4 ] == displayExtent[ 5 ] )
+  {
+    axis = vtkBoundedPlanePointPlacer::ZAxis;
+    position = origin[ 2 ] + displayExtent[ 4 ] * spacing[ 2 ];
+  }
+  else
+  {
+    vtkErrorMacro( "Incorrect display extent in Image Slice" );
+    return( 0 );
+
+  } // fi
+
+  if(
+    axis != this->Placer->GetProjectionNormal( ) ||
+    position != this->Placer->GetProjectionPosition( ) ||
+    b[ 0 ] != this->SavedBounds[ 0 ] ||
+    b[ 1 ] != this->SavedBounds[ 1 ] ||
+    b[ 2 ] != this->SavedBounds[ 2 ] ||
+    b[ 3 ] != this->SavedBounds[ 3 ] ||
+    b[ 4 ] != this->SavedBounds[ 4 ] ||
+    b[ 5 ] != this->SavedBounds[ 5 ]
+    )
+  {
+    this->SavedBounds[ 0 ] = b[ 0 ];
+    this->SavedBounds[ 1 ] = b[ 1 ];
+    this->SavedBounds[ 2 ] = b[ 2 ];
+    this->SavedBounds[ 3 ] = b[ 3 ];
+    this->SavedBounds[ 4 ] = b[ 4 ];
+    this->SavedBounds[ 5 ] = b[ 5 ];
+
+    this->Placer->SetProjectionNormal( axis );
+    this->Placer->SetProjectionPosition( position );
+
+    this->Placer->RemoveAllBoundingPlanes( );
+
+    vtkPlane* plane;
+    if( axis != vtkBoundedPlanePointPlacer::XAxis )
+    {
+      plane = vtkPlane::New( );
+      plane->SetOrigin( b[ 0 ], b[ 2 ], b[ 4 ] );
+      plane->SetNormal( 1.0, 0.0, 0.0 );
+      this->Placer->AddBoundingPlane( plane );
+      plane->Delete( );
+
+      plane = vtkPlane::New();
+      plane->SetOrigin( b[ 1 ], b[ 3 ], b[ 5 ] );
+      plane->SetNormal( -1.0, 0.0, 0.0 );
+      this->Placer->AddBoundingPlane( plane );
+      plane->Delete( );
+
+    } // fi
+
+    if( axis != vtkBoundedPlanePointPlacer::YAxis )
+    {
+      plane = vtkPlane::New( );
+      plane->SetOrigin( b[ 0 ], b[ 2 ], b[ 4 ] );
+      plane->SetNormal( 0.0, 1.0, 0.0 );
+      this->Placer->AddBoundingPlane( plane );
+      plane->Delete( );
+
+      plane = vtkPlane::New( );
+      plane->SetOrigin( b[ 1 ], b[ 3 ], b[ 5 ] );
+      plane->SetNormal( 0.0, -1.0, 0.0 );
+      this->Placer->AddBoundingPlane( plane );
+      plane->Delete( );
+
+    } // fi
+
+    if( axis != vtkBoundedPlanePointPlacer::ZAxis )
+    {
+      plane = vtkPlane::New( );
+      plane->SetOrigin( b[ 0 ], b[ 2 ], b[ 4 ] );
+      plane->SetNormal( 0.0, 0.0, 1.0 );
+      this->Placer->AddBoundingPlane( plane );
+      plane->Delete( );
+
+      plane = vtkPlane::New( );
+      plane->SetOrigin( b[ 1 ], b[ 3 ], b[ 5 ] );
+      plane->SetNormal( 0.0, 0.0, -1.0 );
+      this->Placer->AddBoundingPlane( plane );
+      plane->Delete( );
+
+    } // fi
+
+    this->Modified( );
+
+  } // fi
+  return( 1 );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageSlicePointPlacer::
+SetWorldTolerance( double tol )
+{
+  double t =
+    ( tol < 0.0 )? 0.0: ( ( tol > VTK_DOUBLE_MAX )? VTK_DOUBLE_MAX: tol );
+  if( this->WorldTolerance != t )
+  {
+    this->WorldTolerance = t;
+    this->Placer->SetWorldTolerance( tol );
+    this->Modified( );
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+ivq::VTK::ImageSlicePointPlacer::
+ImageSlicePointPlacer( )
+  : Superclass( )
+{
+  this->Placer = vtkBoundedPlanePointPlacer::New( );
+  this->ImageSlice = NULL;
+  this->SavedBounds[ 0 ] = 0.0;
+  this->SavedBounds[ 1 ] = 0.0;
+  this->SavedBounds[ 2 ] = 0.0;
+  this->SavedBounds[ 3 ] = 0.0;
+  this->SavedBounds[ 4 ] = 0.0;
+  this->SavedBounds[ 5 ] = 0.0;
+  this->Bounds[ 0 ] = this->Bounds[ 2 ] = this->Bounds[ 4 ] = VTK_DOUBLE_MAX;
+  this->Bounds[ 1 ] = this->Bounds[ 3 ] = this->Bounds[ 5 ] = VTK_DOUBLE_MIN;
+}
+
+// -------------------------------------------------------------------------
+ivq::VTK::ImageSlicePointPlacer::
+~ImageSlicePointPlacer( )
+{
+  this->Placer->Delete( );
+  this->SetImageSlice( NULL );
+}
+
+// eof - $RCSfile$
diff --git a/lib/ivq/VTK/ImageSlicePointPlacer.h b/lib/ivq/VTK/ImageSlicePointPlacer.h
new file mode 100644 (file)
index 0000000..3ea5376
--- /dev/null
@@ -0,0 +1,87 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__VTK__ImageSlicePointPlacer__h__
+#define __ivq__VTK__ImageSlicePointPlacer__h__
+
+#include <ivq/ivq_export.h>
+
+#include <vtkPointPlacer.h>
+
+class vtkBoundedPlanePointPlacer;
+class vtkImageSlice;
+class vtkRenderer;
+
+namespace ivq
+{
+  namespace VTK
+  {
+    /**
+     */
+    class IVQ_EXPORT ImageSlicePointPlacer
+      : public vtkPointPlacer
+    {
+    public:
+      typedef ImageSlicePointPlacer Self;
+
+    public:
+      vtkTypeMacro( ImageSlicePointPlacer, vtkPointPlacer );
+
+      vtkGetObjectMacro( ImageSlice, vtkImageSlice );
+      vtkSetVector6Macro( Bounds, double );
+      vtkGetVector6Macro( Bounds, double );
+
+    public:
+      static Self* New( );
+
+      int ComputeWorldPosition(
+        vtkRenderer* ren,
+        double displayPos[ 2 ],
+        double worldPos[ 3 ],
+        double worldOrient[ 9 ]
+        );
+      int ComputeWorldPosition(
+        vtkRenderer* ren,
+        double displayPos[ 2 ],
+        double refWorldPos[ 2 ],
+        double worldPos[ 3 ],
+        double worldOrient[ 9 ]
+        );
+      int ValidateWorldPosition( double worldPos[ 3 ] );
+      int ValidateWorldPosition(
+        double worldPos[ 3 ], double worldOrient[ 9 ]
+        );
+      int UpdateWorldPosition(
+        vtkRenderer* ren, double worldPos[ 3 ], double worldOrient[ 9 ]
+        );
+      int UpdateInternalState( );
+
+      void SetImageSlice( vtkImageSlice* slice );
+      virtual void SetWorldTolerance( double tol );
+
+    protected:
+      ImageSlicePointPlacer( );
+      virtual ~ImageSlicePointPlacer( );
+
+    private:
+      // Purposely not implemented
+      ImageSlicePointPlacer( const Self& );
+      Self& operator=( const Self& );
+
+    protected:
+      vtkImageSlice* ImageSlice;
+      vtkBoundedPlanePointPlacer* Placer;
+      double SavedBounds[ 6 ];
+      double Bounds[ 6 ];
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#endif // __ivq__VTK__ImageSlicePointPlacer__h__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/VTK/ImageViewer.cxx b/lib/ivq/VTK/ImageViewer.cxx
new file mode 100644 (file)
index 0000000..564f74c
--- /dev/null
@@ -0,0 +1,913 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#include <ivq/VTK/ImageViewer.h>
+
+#include <sstream>
+
+#include <vtkAlgorithm.h>
+#include <vtkCamera.h>
+#include <vtkCommand.h>
+#include <vtkCornerAnnotation.h>
+#include <vtkCursor3D.h>
+#include <vtkImageData.h>
+#include <vtkImageProperty.h>
+#include <vtkImageSliceMapper.h>
+#include <vtkInformation.h>
+#include <vtkPropPicker.h>
+#include <vtkProperty.h>
+#include <vtkRenderer.h>
+#include <vtkRenderWindow.h>
+#include <vtkRenderWindowInteractor.h>
+#include <vtkStreamingDemandDrivenPipeline.h>
+#include <vtkTextProperty.h>
+
+#include <ivq/VTK/ImageActor.h>
+#include <ivq/VTK/InteractorStyleImage.h>
+#include <ivq/VTK/PolyDataActor.h>
+
+// -------------------------------------------------------------------------
+const double ivq::VTK::ImageViewer::CursorColors[ 3 ][ 3 ] =
+{
+  { 0, 0, 1 },
+  { 0, 1, 0 },
+  { 1, 0, 0 }
+};
+
+// -------------------------------------------------------------------------
+template< typename T >
+void ivq_VTK_ImageViewer_MessageTemplate(
+  vtkImageData* img, int* pos, std::stringstream& msg
+  )
+{
+  T* tuple = ( T* )( img->GetScalarPointer( pos ) );
+  if( tuple != NULL )
+  {
+    int n = img->GetNumberOfScalarComponents( );
+    for( int c = 0; c < n; ++c )
+    {
+      msg << long( tuple[ c ] );
+      if( c != ( n - 1 ) )
+        msg << ", ";
+
+    } // rof
+    msg << " )";
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+namespace ivq
+{
+  namespace VTK
+  {
+    /**
+     */
+    class ImageViewerCallback
+      : public vtkCommand
+    {
+    public:
+      static ImageViewerCallback* New( )
+        {
+          return( new ImageViewerCallback( ) );
+        }
+      virtual void Execute(
+        vtkObject* caller, unsigned long eId, void* data
+        ) override
+        {
+          if( this->Viewer == NULL )
+            return;
+
+          if( eId == vtkCommand::MouseMoveEvent )
+          {
+            vtkRenderWindowInteractor* iren = this->Viewer->Interactor;
+            vtkRenderer* ren = this->Viewer->Renderer;
+            ivq::VTK::ImageActor* actor = this->Viewer->ImageActor;
+            vtkImageData* image = actor->GetInput( );
+            vtkInteractorStyle* style =
+              vtkInteractorStyle::SafeDownCast( iren->GetInteractorStyle( ) );
+            vtkPropPicker* picker = this->Viewer->PropPicker;
+            vtkCornerAnnotation* annotation = this->Viewer->CornerAnnotation;
+            vtkCursor3D* cursor = this->Viewer->CursorSource;
+
+            // Pick
+            double pos[ 3 ];
+            int ijk[ 3 ];
+            bool validPick =
+              (
+                picker->Pick(
+                  iren->GetEventPosition( )[ 0 ],
+                  iren->GetEventPosition( )[ 1 ],
+                  0.0, ren
+                  ) != 0
+                );
+            if( validPick )
+            {
+              picker->GetPickPosition( pos );
+              vtkProp* pprop =
+                ivq::VTK::ImageActor::SafeDownCast( picker->GetViewProp( ) );
+              validPick = ( pprop == actor );
+
+            } // fi
+            if( validPick )
+            {
+              int ext[ 6 ];
+              double pcoords[ 3 ];
+              image->ComputeStructuredCoordinates( pos, ijk, pcoords );
+              ijk[ this->Viewer->GetSliceOrientation( ) ] =
+                actor->GetSliceNumber( );
+              image->GetExtent( ext );
+              validPick =
+                ( ext[ 0 ] <= ijk[ 0 ] && ijk[ 0 ] <= ext[ 1 ] ) &&
+                ( ext[ 2 ] <= ijk[ 1 ] && ijk[ 1 ] <= ext[ 3 ] ) &&
+                ( ext[ 4 ] <= ijk[ 2 ] && ijk[ 2 ] <= ext[ 5 ] );
+
+            } // fi
+
+            if( validPick )
+            {
+              // Build message
+              std::stringstream message;
+              message
+                << std::fixed << std::setprecision( 2 )
+                << "Point: [ "
+                << pos[ 0 ] << ", " << pos[ 1 ] << ", " << pos[ 2 ]
+                << " ]" << std::endl
+                << "Index: ( "
+                << ijk[ 0 ] << ", " << ijk[ 1 ] << ", " << ijk[ 2 ]
+                << " )" << std::endl
+                << "Value: ( ";
+              switch( image->GetScalarType( ) )
+              {
+                vtkTemplateMacro(
+                  (
+                    ivq_VTK_ImageViewer_MessageTemplate< VTK_TT >(
+                      image, ijk, message
+                      )
+                    )
+                  );
+              default:
+                return;
+              } // hctiws
+              annotation->SetText( 2, message.str( ).c_str( ) );
+              cursor->SetFocalPoint( pos );
+            }
+            else
+            {
+              double bounds[ 6 ];
+              actor->GetActorBounds( bounds );
+              annotation->SetText( 2, "Off image" );
+              cursor->SetFocalPoint(
+                bounds[ 0 ], bounds[ 2 ], bounds[ 4 ]
+                );
+
+            } // fi
+            std::stringstream wl;
+            wl
+              << "W/L : <"
+              << actor->GetProperty( )->GetColorWindow( ) << ", "
+              << actor->GetProperty( )->GetColorLevel( ) << ">";
+            annotation->SetText( 3, wl.str( ).c_str( ) );
+            iren->Render( );
+            style->OnMouseMove( );
+
+          } // fi
+        }
+
+    protected:
+      ImageViewerCallback( )
+        : vtkCommand( ),
+          Viewer( NULL )
+        {
+        }
+      virtual ~ImageViewerCallback( )
+        {
+        }
+
+    private:
+      // Purposely not implemented
+      ImageViewerCallback( const ImageViewerCallback& other );
+      ImageViewerCallback& operator=( const ImageViewerCallback& other );
+
+    public:
+      ivq::VTK::ImageViewer* Viewer;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+// -------------------------------------------------------------------------
+ivq::VTK::ImageViewer::
+Self* ivq::VTK::ImageViewer::
+New( )
+{
+  return( new Self( ) );
+}
+
+// -------------------------------------------------------------------------
+vtkRenderWindow* ivq::VTK::ImageViewer::
+GetRenderWindow( )
+{
+  return( this->RenderWindow );
+}
+
+// -------------------------------------------------------------------------
+vtkRenderer* ivq::VTK::ImageViewer::
+GetRenderer( )
+{
+  return( this->Renderer );
+}
+
+// -------------------------------------------------------------------------
+ivq::VTK::ImageActor* ivq::VTK::ImageViewer::
+GetImageActor( )
+{
+  return( this->ImageActor );
+}
+
+// -------------------------------------------------------------------------
+ivq::VTK::InteractorStyleImage* ivq::VTK::ImageViewer::
+GetInteractorStyle( )
+{
+  return( this->InteractorStyle );
+}
+
+// -------------------------------------------------------------------------
+const char* ivq::VTK::ImageViewer::
+GetWindowName( )
+{
+  return( this->RenderWindow->GetWindowName( ) );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageViewer::
+Render( )
+{
+  if( this->FirstRender )
+  {
+    vtkAlgorithm* input = this->_GetInputAlgorithm( );
+    if( input != NULL )
+    {
+      input->UpdateInformation( );
+      int* w_ext = this->_GetInputInformation( )->Get(
+        vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT( )
+        );
+      int xs = 0, ys = 0;
+      switch( this->SliceOrientation )
+      {
+      case Self::SLICE_ORIENTATION_XY:
+      default:
+      {
+        xs = w_ext[ 1 ] - w_ext[ 0 ] + 1;
+        ys = w_ext[ 3 ] - w_ext[ 2 ] + 1;
+      }
+      break;
+      case Self::SLICE_ORIENTATION_XZ:
+      {
+        xs = w_ext[ 1 ] - w_ext[ 0 ] + 1;
+        ys = w_ext[ 5 ] - w_ext[ 4 ] + 1;
+      }
+      break;
+      case Self::SLICE_ORIENTATION_YZ:
+      {
+        xs = w_ext[ 3 ] - w_ext[ 2 ] + 1;
+        ys = w_ext[ 5 ] - w_ext[ 4 ] + 1;
+      }
+      break;
+      } // hctiws
+
+      if( this->RenderWindow->GetSize( )[ 0 ] == 0 )
+        this->RenderWindow->SetSize(
+          ( xs < 150 )? 150: xs,
+          ( ys < 100 )? 100: ys
+          );
+
+      if( this->Renderer )
+      {
+        this->Renderer->ResetCamera( );
+        this->Renderer->GetActiveCamera( )->SetParallelScale(
+          ( xs < 150 )? 75: ( ( xs - 1 ) / 2.0 )
+          );
+
+      } // fi
+      this->FirstRender = 0;
+
+    } // fi
+
+  } // fi
+
+  if( this->GetInput( ) != NULL )
+    this->RenderWindow->Render( );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageViewer::
+SetInputData( vtkImageData* in )
+{
+  this->ImageActor = vtkSmartPointer< ivq::VTK::ImageActor >::New( );
+  this->_UnInstallPipeline( );
+  this->_InstallPipeline( );
+  this->SetupInteractor( );
+  this->ImageActor->SetInputData( in );
+  this->UpdateDisplayExtent( );
+}
+
+// -------------------------------------------------------------------------
+vtkImageData* ivq::VTK::ImageViewer::
+GetInput( )
+{
+  return( vtkImageData::SafeDownCast( this->ImageActor->GetInput( ) ) );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageViewer::
+SetInputConnection( vtkAlgorithmOutput* input )
+{
+  this->ImageActor = vtkSmartPointer< ivq::VTK::ImageActor >::New( );
+  this->_UnInstallPipeline( );
+  this->_InstallPipeline( );
+  this->SetupInteractor( );
+  this->ImageActor->SetInputConnection( input );
+  this->UpdateDisplayExtent( );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageViewer::
+SetSliceOrientation( int orientation )
+{
+  if(
+    orientation < Self::SLICE_ORIENTATION_YZ ||
+    orientation > Self::SLICE_ORIENTATION_XY
+    )
+  {
+    vtkErrorMacro( "Error - invalid slice orientation " << orientation );
+    return;
+
+  } // fi
+  if( this->SliceOrientation == orientation )
+    return;
+  this->SliceOrientation = orientation;
+  this->ImageActor->SetOrientation( this->SliceOrientation );
+  this->FirstRender = 1;
+
+  // Update the viewer
+  int* range = this->GetSliceRange( );
+  if( range != NULL )
+    this->Slice = static_cast< int >( ( range[ 0 ] + range[ 1 ] ) * 0.5 );
+  this->_UpdateOrientation( );
+  this->UpdateDisplayExtent( );
+  if( this->Renderer != NULL && this->GetInput( ) != NULL )
+  {
+    double scale = this->Renderer->GetActiveCamera( )->GetParallelScale( );
+    this->Renderer->ResetCamera( );
+    this->Renderer->GetActiveCamera( )->SetParallelScale( scale );
+
+  } // fi
+  this->Render( );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageViewer::
+SetSliceOrientationToXY( )
+{
+  this->SetSliceOrientation( ImageViewer::SLICE_ORIENTATION_XY );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageViewer::
+SetSliceOrientationToYZ( )
+{
+  this->SetSliceOrientation( ImageViewer::SLICE_ORIENTATION_YZ );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageViewer::
+SetSliceOrientationToXZ( )
+{
+  this->SetSliceOrientation( ImageViewer::SLICE_ORIENTATION_XZ );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageViewer::
+SetSlice( int s )
+{
+  int* range = this->GetSliceRange( );
+  if( range != NULL )
+  {
+    if( s < range[ 0 ] )
+      s = range[ 0 ];
+    else if( s > range[ 1 ] )
+      s = range[ 1 ];
+
+  } // fi
+  if( this->Slice == s )
+    return;
+  this->Slice = s;
+  this->ImageActor->SetSliceNumber( this->Slice );
+  this->ImageActor->Update( );
+  double bounds[ 6 ], center[ 3 ], focus[ 3 ];
+  this->ImageActor->GetActorBounds( bounds );
+  this->ImageActor->GetActorCenter( center );
+  this->CursorSource->GetFocalPoint( focus );
+  focus[ this->SliceOrientation ] = center[ this->SliceOrientation ];
+  this->CursorSource->SetModelBounds( bounds );
+  this->CursorSource->SetFocalPoint( focus );
+  this->CursorActor->Modified( );
+  this->Render( );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageViewer::
+UpdateDisplayExtent( )
+{
+  vtkAlgorithm* input = this->_GetInputAlgorithm( );
+  if( !input || !this->ImageActor )
+    return;
+  input->UpdateInformation( );
+  vtkInformation* outInfo = input->GetOutputInformation( 0 );
+
+  int* slice_range = this->GetSliceRange( );
+  this->Slice = ( slice_range[ 0 ] + slice_range[ 1 ] ) >> 1;
+  this->ImageActor->SetSliceNumber( this->Slice );
+
+  // Reset window level
+  vtkImageData* image = this->ImageActor->GetInput( );
+  double range[ 2 ];
+  image->GetScalarRange( range );
+  double color_window = range[ 1 ] - range[ 0 ];
+  double color_level = ( range[ 1 ] + range[ 0 ] ) * 0.5;
+  this->ImageActor->GetProperty( )->SetColorWindow( color_window );
+  this->ImageActor->GetProperty( )->SetColorLevel( color_level );
+
+  // Figure out the correct clipping range
+  if( this->Renderer != NULL )
+  {
+    this->Renderer->RemoveAllViewProps( );
+    this->Renderer->AddViewProp( this->ImageActor );
+    if(
+      this->InteractorStyle == NULL ||
+      !( this->InteractorStyle->GetAutoAdjustCameraClippingRange( ) )
+      )
+    {
+      vtkCamera* cam = this->Renderer->GetActiveCamera( );
+      if( cam )
+      {
+        double bounds[ 6 ];
+        this->ImageActor->GetActorBounds( bounds );
+        double spos = bounds[ this->SliceOrientation << 1 ];
+        double cpos = cam->GetPosition( )[ this->SliceOrientation ];
+        double range = std::fabs( spos - cpos );
+        double* spacing = outInfo->Get( vtkDataObject::SPACING( ) );
+        double avg_spacing = spacing[ 0 ] + spacing[ 1 ] + spacing[ 2 ];
+        cam->SetClippingRange( range - avg_spacing, range + avg_spacing );
+
+      } // fi
+    }
+    else
+      this->Renderer->ResetCameraClippingRange( );
+
+    // Prepare picker
+    this->PropPicker = vtkSmartPointer< vtkPropPicker >::New( );
+    this->PropPicker->PickFromListOn( );
+    this->PropPicker->AddPickList( this->ImageActor );
+
+    // Cursor
+    this->CursorSource = vtkSmartPointer< vtkCursor3D >::New( );
+    this->CursorActor = vtkSmartPointer< ivq::VTK::PolyDataActor >::New( );
+
+    double bounds[ 6 ], center[ 3 ];
+    this->ImageActor->GetActorBounds( bounds );
+    this->ImageActor->GetActorCenter( center );
+
+    this->CursorSource->SetModelBounds( bounds );
+    this->CursorSource->SetFocalPoint( center );
+    this->CursorSource->AllOn( );
+    this->CursorActor->
+      SetInputConnection( this->CursorSource->GetOutputPort( ) );
+    this->CursorActor->GetProperty( )->SetColor(
+      Self::CursorColors[ this->SliceOrientation ][ 0 ],
+      Self::CursorColors[ this->SliceOrientation ][ 1 ],
+      Self::CursorColors[ this->SliceOrientation ][ 2 ]
+      );
+    this->Renderer->AddViewProp( this->CursorActor->GetActor( ) );
+
+    // Annotations
+    this->CornerAnnotation = vtkSmartPointer< vtkCornerAnnotation >::New( );
+    this->CornerAnnotation->SetLinearFontScaleFactor( 2 );
+    this->CornerAnnotation->SetNonlinearFontScaleFactor( 1 );
+    this->CornerAnnotation->SetMaximumFontSize( 20 );
+    this->CornerAnnotation->SetText( 2, "Off image" );
+    std::stringstream wl;
+    wl
+      << "W/L : <"
+      << this->ImageActor->GetProperty( )->GetColorWindow( ) << ", "
+      << this->ImageActor->GetProperty( )->GetColorLevel( ) << ">";
+    this->CornerAnnotation->SetText( 3, wl.str( ).c_str( ) );
+    this->CornerAnnotation->GetTextProperty( )->SetColor( 1, 1, 0 );
+    this->CornerAnnotation->GetTextProperty( )->SetFontFamilyToCourier( );
+    this->CornerAnnotation->GetTextProperty( )->BoldOn( );
+    this->Renderer->AddViewProp( this->CornerAnnotation );
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+int ivq::VTK::ImageViewer::
+GetSliceMin( )
+{
+  int* range = this->GetSliceRange( );
+  if( range != NULL )
+    return( range[ 0 ] );
+  else
+    return( 0 );
+}
+
+// -------------------------------------------------------------------------
+int ivq::VTK::ImageViewer::
+GetSliceMax( )
+{
+  int* range = this->GetSliceRange( );
+  if( range != NULL )
+    return( range[ 1 ] );
+  else
+    return( 0 );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageViewer::
+GetSliceRange( int range[ 2 ] )
+{
+  this->GetSliceRange( range[ 0 ], range[ 1 ] );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageViewer::
+GetSliceRange( int& min, int& max )
+{
+  vtkAlgorithm* input = this->_GetInputAlgorithm( );
+  if( input != NULL )
+  {
+    input->UpdateInformation( );
+    int* w_ext = input->GetOutputInformation( 0 )->Get(
+      vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT( )
+      );
+    min = w_ext[ this->SliceOrientation << 1 ];
+    max = w_ext[ ( this->SliceOrientation << 1 ) + 1 ];
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+int* ivq::VTK::ImageViewer::
+GetSliceRange( )
+{
+  vtkAlgorithm *input = this->_GetInputAlgorithm( );
+  if( input != NULL )
+  {
+    input->UpdateInformation( );
+    return(
+      input->GetOutputInformation( 0 )->Get(
+        vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT( )
+        ) + this->SliceOrientation * 2
+      );
+  }
+  else
+    return( NULL );
+}
+
+// -------------------------------------------------------------------------
+double ivq::VTK::ImageViewer::
+GetColorWindow( )
+{
+  return( this->ImageActor->GetProperty( )->GetColorWindow( ) );
+}
+
+// -------------------------------------------------------------------------
+double ivq::VTK::ImageViewer::
+GetColorLevel( )
+{
+  return( this->ImageActor->GetProperty( )->GetColorLevel( ) );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageViewer::
+SetColorWindow( double s )
+{
+  this->ImageActor->GetProperty( )->SetColorWindow( s );
+  this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageViewer::
+SetColorLevel( double s )
+{
+  this->ImageActor->GetProperty( )->SetColorLevel( s );
+  this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageViewer::
+SetDisplayId( void* a )
+{
+  this->RenderWindow->SetDisplayId( a );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageViewer::
+SetWindowId( void* a )
+{
+  this->RenderWindow->SetWindowId( a );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageViewer::
+SetParentId( void* a )
+{
+  this->RenderWindow->SetParentId( a );
+}
+
+// -------------------------------------------------------------------------
+int* ivq::VTK::ImageViewer::
+GetPosition( )
+{
+  return( this->RenderWindow->GetPosition( ) );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageViewer::
+SetPosition( int a, int b )
+{
+  this->RenderWindow->SetPosition( a, b );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageViewer::
+SetPosition( int a[ 2 ] )
+{
+  this->SetPosition( a[ 0 ], a[ 1 ] );
+}
+
+// -------------------------------------------------------------------------
+int* ivq::VTK::ImageViewer::
+GetSize( )
+{
+  return( this->RenderWindow->GetSize( ) );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageViewer::
+SetSize( int a, int b )
+{
+  this->RenderWindow->SetSize( a, b );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageViewer::
+SetSize( int a[ 2 ] )
+{
+  this->SetSize( a[ 0 ], a[ 1 ] );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageViewer::
+SetRenderWindow( vtkRenderWindow* win )
+{
+  if( this->RenderWindow == win )
+    return;
+  this->_UnInstallPipeline( );
+  if( this->RenderWindow != NULL )
+    this->RenderWindow->UnRegister( this );
+  this->RenderWindow = win;
+  if( this->RenderWindow != NULL )
+    this->RenderWindow->Register( this );
+  this->_InstallPipeline( );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageViewer::
+SetRenderer( vtkRenderer* ren )
+{
+  if( this->Renderer == ren )
+    return;
+  this->_UnInstallPipeline( );
+  if( this->Renderer != NULL )
+    this->Renderer->UnRegister( this );
+  this->Renderer = ren;
+  if( this->Renderer )
+    this->Renderer->Register( this );
+  this->_InstallPipeline( );
+  this->_UpdateOrientation( );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageViewer::
+SetupInteractor( )
+{
+  if( this->Interactor == NULL )
+  {
+    vtkRenderWindowInteractor* rwi = this->RenderWindow->GetInteractor( );
+    if( rwi == NULL )
+    {
+      rwi = vtkRenderWindowInteractor::New( );
+      this->SetupInteractor( rwi );
+      rwi->Delete( );
+    }
+    else
+      this->SetupInteractor( rwi );
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageViewer::
+SetupInteractor( vtkRenderWindowInteractor* rwi )
+{
+  if( this->Interactor == rwi )
+    return;
+  this->_UnInstallPipeline( );
+  if( this->Interactor != NULL )
+    this->Interactor->UnRegister( this );
+  this->Interactor = rwi;
+  if( this->Interactor != NULL )
+    this->Interactor->Register( this );
+  this->_InstallPipeline( );
+  if( this->Renderer != NULL )
+    this->Renderer->GetActiveCamera( )->ParallelProjectionOn( );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageViewer::
+SetOffScreenRendering( int v )
+{
+  this->RenderWindow->SetOffScreenRendering( v );
+}
+
+// -------------------------------------------------------------------------
+int ivq::VTK::ImageViewer::
+GetOffScreenRendering( )
+{
+  return( this->RenderWindow->GetOffScreenRendering( ) );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageViewer::
+ResetCamera( )
+{
+  if( this->Renderer != NULL )
+    this->Renderer->ResetCamera( );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageViewer::
+Initialize( )
+{
+  if( this->Interactor != NULL )
+    this->Interactor->Initialize( );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageViewer::
+Start( )
+{
+  if( this->Interactor != NULL )
+    this->Interactor->Start( );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageViewer::
+GetFocalPoint( double point[ 3 ], int ijk[ 3 ] )
+{
+  this->CursorSource->GetFocalPoint( point );
+
+  double pcoords[ 3 ];
+  vtkImageData* image = this->GetInput( );
+  image->ComputeStructuredCoordinates( point, ijk, pcoords );
+  ijk[ this->SliceOrientation ] = this->ImageActor->GetSliceNumber( );
+}
+
+// -------------------------------------------------------------------------
+ivq::VTK::ImageViewer::
+ImageViewer( )
+  : Superclass( )
+{
+  this->Slice = 0;
+  this->FirstRender = 1;
+  this->SliceOrientation = Self::SLICE_ORIENTATION_XY;
+
+  // Setup the pipeline
+  vtkRenderWindow* renwin = vtkRenderWindow::New( );
+  this->SetRenderWindow( renwin );
+  renwin->Delete( );
+
+  vtkRenderer* ren = vtkRenderer::New( );
+  this->SetRenderer( ren );
+  ren->Delete( );
+
+  this->_InstallPipeline( );
+}
+
+// -------------------------------------------------------------------------
+ivq::VTK::ImageViewer::
+~ImageViewer( )
+{
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageViewer::
+_InstallPipeline( )
+{
+  if( this->RenderWindow != NULL && this->Renderer != NULL )
+    this->RenderWindow->AddRenderer( this->Renderer );
+  if( this->Interactor != NULL )
+  {
+    if( this->InteractorStyle == NULL )
+    {
+      this->InteractorStyle =
+        vtkSmartPointer< ivq::VTK::InteractorStyleImage >::New( );
+      this->InteractorStyle->SetViewer( this );
+      ImageViewerCallback* cbk = ImageViewerCallback::New( );
+      cbk->Viewer = this;
+      this->InteractorStyle->AddObserver( vtkCommand::MouseMoveEvent, cbk );
+      cbk->Delete( );
+
+    } // fi
+    this->Interactor->SetInteractorStyle( this->InteractorStyle );
+    this->Interactor->SetRenderWindow( this->RenderWindow );
+
+  } // fi
+  if( this->Renderer != NULL && this->ImageActor != NULL )
+    this->Renderer->AddViewProp( this->ImageActor );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageViewer::
+_UnInstallPipeline( )
+{
+  if( this->ImageActor != NULL )
+    this->ImageActor->SetInputConnection( NULL );
+  if( this->Renderer != NULL && this->ImageActor != NULL )
+    this->Renderer->RemoveViewProp( this->ImageActor );
+  if( this->RenderWindow != NULL && this->Renderer != NULL )
+    this->RenderWindow->RemoveRenderer( this->Renderer );
+
+  if( this->Interactor != NULL )
+  {
+    this->Interactor->SetInteractorStyle( NULL );
+    this->Interactor->SetRenderWindow( NULL );
+  }
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::ImageViewer::
+_UpdateOrientation( )
+{
+  if( this->Renderer == NULL )
+    return;
+  vtkCamera* cam = this->Renderer->GetActiveCamera( );
+  if( cam == NULL )
+    return;
+  switch( this->SliceOrientation )
+  {
+  case Self::SLICE_ORIENTATION_XY:
+  {
+    cam->SetFocalPoint( 0, 0, 0 );
+    cam->SetPosition( 0, 0, 1 ); // -1 if medical ?
+    cam->SetViewUp( 0, 1, 0 );
+  }
+  break;
+  case Self::SLICE_ORIENTATION_XZ:
+  {
+    cam->SetFocalPoint( 0, 0, 0 );
+    cam->SetPosition( 0, -1, 0 ); // 1 if medical ?
+    cam->SetViewUp( 0, 0, 1 );
+  }
+  break;
+  case Self::SLICE_ORIENTATION_YZ:
+  {
+    cam->SetFocalPoint( 0, 0, 0 );
+    cam->SetPosition( 1, 0, 0 ); // -1 if medical ?
+    cam->SetViewUp( 0, 0, 1 );
+  }
+  break;
+  } // hctiws
+}
+
+// -------------------------------------------------------------------------
+vtkAlgorithm* ivq::VTK::ImageViewer::
+_GetInputAlgorithm( )
+{
+  return( this->ImageActor->GetInputAlgorithm( ) );
+}
+
+// -------------------------------------------------------------------------
+vtkInformation* ivq::VTK::ImageViewer::
+_GetInputInformation( )
+{
+  return( this->ImageActor->GetInputInformation( ) );
+}
+
+// eof - $RCSfile$
diff --git a/lib/ivq/VTK/ImageViewer.h b/lib/ivq/VTK/ImageViewer.h
new file mode 100644 (file)
index 0000000..cd6c33f
--- /dev/null
@@ -0,0 +1,160 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__VTK__ImageViewer__h__
+#define __ivq__VTK__ImageViewer__h__
+
+#include <ivq/ivq_export.h>
+
+#include <vtkSmartPointer.h>
+#include <vtkObject.h>
+
+class vtkAlgorithm;
+class vtkAlgorithmOutput;
+class vtkCornerAnnotation;
+class vtkCursor3D;
+class vtkImageData;
+class vtkInformation;
+class vtkPropPicker;
+class vtkRenderer;
+class vtkRenderWindow;
+class vtkRenderWindowInteractor;
+
+namespace ivq
+{
+  namespace VTK
+  {
+    class ImageActor;
+    class InteractorStyleImage;
+    class PolyDataActor;
+
+    /**
+     */
+    class IVQ_EXPORT ImageViewer
+      : public vtkObject
+    {
+    public:
+      typedef ImageViewer Self;
+
+    public:
+      vtkTypeMacro( ImageViewer, vtkObject );
+
+      vtkGetMacro( SliceOrientation, int );
+      vtkGetMacro( Slice, int );
+      vtkBooleanMacro( OffScreenRendering, int );
+
+    public:
+      static Self* New( );
+
+      virtual vtkRenderWindow* GetRenderWindow( );
+      virtual vtkRenderer* GetRenderer( );
+      virtual ivq::VTK::ImageActor* GetImageActor( );
+      virtual ivq::VTK::InteractorStyleImage* GetInteractorStyle( );
+
+      virtual const char* GetWindowName( );
+      virtual void Render( );
+
+      virtual void SetInputData( vtkImageData* in );
+      virtual vtkImageData* GetInput( );
+      virtual void SetInputConnection( vtkAlgorithmOutput* input );
+
+      enum
+      {
+        SLICE_ORIENTATION_YZ = 0,
+        SLICE_ORIENTATION_XZ = 1,
+        SLICE_ORIENTATION_XY = 2
+      };
+      virtual void SetSliceOrientation( int orientation );
+      virtual void SetSliceOrientationToXY( );
+      virtual void SetSliceOrientationToYZ( );
+      virtual void SetSliceOrientationToXZ( );
+
+      virtual void SetSlice( int s );
+
+      virtual void UpdateDisplayExtent( );
+
+      virtual int GetSliceMin( );
+      virtual int GetSliceMax( );
+      virtual void GetSliceRange( int range[ 2 ] );
+      virtual void GetSliceRange( int& min, int& max );
+      virtual int* GetSliceRange( );
+
+      virtual double GetColorWindow( );
+      virtual double GetColorLevel( );
+      virtual void SetColorWindow( double s );
+      virtual void SetColorLevel( double s );
+
+      virtual void SetDisplayId( void* a );
+      virtual void SetWindowId( void* a );
+      virtual void SetParentId( void* a );
+
+      virtual int* GetPosition( );
+      virtual void SetPosition( int a, int b );
+      virtual void SetPosition( int a[ 2 ] );
+
+      virtual int* GetSize( );
+      virtual void SetSize( int a, int b );
+      virtual void SetSize( int a[ 2 ] );
+
+      virtual void SetRenderWindow( vtkRenderWindow* win );
+      virtual void SetRenderer( vtkRenderer* ren );
+      virtual void SetupInteractor( );
+      virtual void SetupInteractor( vtkRenderWindowInteractor* rwi );
+
+      virtual void SetOffScreenRendering( int v );
+      virtual int GetOffScreenRendering( );
+
+      virtual void ResetCamera( );
+      virtual void Initialize( );
+      virtual void Start( );
+
+      virtual void GetFocalPoint( double point[ 3 ], int ijk[ 3 ] );
+
+    protected:
+      ImageViewer( );
+      virtual ~ImageViewer( );
+
+      virtual void _InstallPipeline( );
+      virtual void _UnInstallPipeline( );
+      virtual void _UpdateOrientation( );
+
+      vtkAlgorithm* _GetInputAlgorithm( );
+      vtkInformation* _GetInputInformation( );
+
+    private:
+      // Purposely not implemented.
+      ImageViewer( const ImageViewer& other );
+      void operator=( const ImageViewer& other );
+
+    protected:
+      vtkSmartPointer< vtkRenderWindow >                RenderWindow;
+      vtkSmartPointer< vtkRenderer >                    Renderer;
+      vtkSmartPointer< ivq::VTK::ImageActor >           ImageActor;
+      vtkSmartPointer< vtkRenderWindowInteractor >      Interactor;
+      vtkSmartPointer< ivq::VTK::InteractorStyleImage > InteractorStyle;
+      
+      int SliceOrientation;
+      int FirstRender;
+      int Slice;
+
+      vtkSmartPointer< vtkPropPicker >       PropPicker;
+      vtkSmartPointer< vtkCornerAnnotation > CornerAnnotation;
+
+      vtkSmartPointer< vtkCursor3D >             CursorSource;
+      vtkSmartPointer< ivq::VTK::PolyDataActor > CursorActor;
+
+      static const double CursorColors[ 3 ][ 3 ];
+
+      friend class ImageViewerCallback;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#endif // __ivq__VTK__ImageViewer__h__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/VTK/InteractorStyleImage.cxx b/lib/ivq/VTK/InteractorStyleImage.cxx
new file mode 100644 (file)
index 0000000..4239bc5
--- /dev/null
@@ -0,0 +1,275 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#include <ivq/VTK/InteractorStyleImage.h>
+
+#include <vtkAssemblyPath.h>
+#include <vtkImageData.h>
+#include <vtkPropCollection.h>
+#include <vtkRenderer.h>
+#include <vtkRenderWindowInteractor.h>
+
+#include <ivq/VTK/ImageActor.h>
+#include <ivq/VTK/ImageViewer.h>
+
+// -------------------------------------------------------------------------
+ivq::VTK::InteractorStyleImage::
+Self* ivq::VTK::InteractorStyleImage::
+New( )
+{
+  return( new Self( ) );
+}
+
+// -------------------------------------------------------------------------
+ivq::VTK::ImageViewer* ivq::VTK::InteractorStyleImage::
+GetViewer( )
+{
+  return( this->Viewer );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::InteractorStyleImage::
+SetViewer( ivq::VTK::ImageViewer* v )
+{
+  this->Viewer = v;
+  this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::InteractorStyleImage::
+AddOtherViewer( ivq::VTK::ImageViewer* v )
+{
+  if( this->Viewer != NULL )
+    this->OtherViewers.insert( v );
+  else
+    this->Viewer = v;
+  this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::InteractorStyleImage::
+OnMouseMove( )
+{
+  if( this->PressedButton == 1 && this->Viewer != NULL )
+  {
+    if(
+      !this->Interactor->GetAltKey( ) &&
+      !this->Interactor->GetShiftKey( ) &&
+      !this->Interactor->GetControlKey( )
+      )
+    {
+      double dx = double( this->Interactor->GetEventPosition( )[ 0 ] );
+      double dy = double( this->Interactor->GetEventPosition( )[ 1 ] );
+      dx -= this->StartClick[ 0 ];
+      dy -= this->StartClick[ 1 ];
+      double sx = double( this->Interactor->GetSize( )[ 0 ] >> 1 );
+      double sy = double( this->Interactor->GetSize( )[ 1 ] >> 1 );
+      dx /= sx;
+      dy /= sy;
+      double off = double( 1 );
+      double w = this->StartWL[ 0 ] * ( off + dx );
+      double l = this->StartWL[ 1 ] * ( off + dy );
+      this->Viewer->GetImageActor( )->SetColorWindow( w );
+      this->Viewer->GetImageActor( )->SetColorLevel( l );
+      this->Interactor->Render( );
+
+      std::set< ivq::VTK::ImageViewer* >::iterator vIt =
+        this->OtherViewers.begin( );
+      for( ; vIt != this->OtherViewers.end( ); ++vIt )
+      {
+        ivq::VTK::ImageViewer* v = *vIt;
+        v->GetImageActor( )->SetColorWindow( w );
+        v->GetImageActor( )->SetColorLevel( l );
+        v->Render( );
+
+      } // rof
+    }
+    else if(
+      !this->Interactor->GetAltKey( ) &&
+      !this->Interactor->GetShiftKey( ) &&
+      this->Interactor->GetControlKey( )
+      )
+    {
+      double pos[ 3 ];
+      int ijk[ 3 ];
+      this->Viewer->GetFocalPoint( pos, ijk );
+      std::set< ivq::VTK::ImageViewer* >::iterator vIt =
+        this->OtherViewers.begin( );
+      for( ; vIt != this->OtherViewers.end( ); ++vIt )
+      {
+        ivq::VTK::ImageViewer* v = *vIt;
+        v->SetSlice( ijk[ v->GetSliceOrientation( ) ] );
+        v->Render( );
+
+      } // rof
+
+    } // fi
+
+  } // fi
+  this->vtkInteractorStyleTrackballCamera::OnMouseMove( );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::InteractorStyleImage::
+OnLeftButtonDown( )
+{
+  if( this->Viewer != NULL )
+  {
+    this->StartClick[ 0 ] = this->Interactor->GetEventPosition( )[ 0 ];
+    this->StartClick[ 1 ] = this->Interactor->GetEventPosition( )[ 1 ];
+    this->StartWL[ 0 ] = this->Viewer->GetImageActor( )->GetColorWindow( );
+    this->StartWL[ 1 ] = this->Viewer->GetImageActor( )->GetColorLevel( );
+    this->PressedButton = 1;
+
+  } // fi
+  this->vtkInteractorStyleTrackballCamera::OnLeftButtonDown( );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::InteractorStyleImage::
+OnLeftButtonUp( )
+{
+  if( this->Viewer != NULL )
+    this->PressedButton = 0;
+  this->vtkInteractorStyleTrackballCamera::OnLeftButtonUp( );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::InteractorStyleImage::
+OnMiddleButtonDown( )
+{
+  if( this->Viewer != NULL )
+  {
+    this->StartClick[ 0 ] = this->Interactor->GetEventPosition( )[ 0 ];
+    this->StartClick[ 1 ] = this->Interactor->GetEventPosition( )[ 1 ];
+    this->PressedButton = 2;
+
+  } // fi
+  this->vtkInteractorStyleTrackballCamera::OnMiddleButtonDown( );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::InteractorStyleImage::
+OnMiddleButtonUp( )
+{
+  if( this->Viewer != NULL )
+    this->PressedButton = 0;
+  this->vtkInteractorStyleTrackballCamera::OnMiddleButtonUp( );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::InteractorStyleImage::
+OnRightButtonDown( )
+{
+  if( this->Viewer != NULL )
+  {
+    this->StartClick[ 0 ] = this->Interactor->GetEventPosition( )[ 0 ];
+    this->StartClick[ 1 ] = this->Interactor->GetEventPosition( )[ 1 ];
+    this->PressedButton = 3;
+
+  } // fi
+  this->vtkInteractorStyleTrackballCamera::OnRightButtonDown( );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::InteractorStyleImage::
+OnRightButtonUp( )
+{
+  if( this->Viewer != NULL )
+    this->PressedButton = 0;
+  this->vtkInteractorStyleTrackballCamera::OnRightButtonUp( );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::InteractorStyleImage::
+OnMouseWheelForward( )
+{
+  if( this->Viewer != NULL )
+  {
+    int off = ( this->Interactor->GetShiftKey( ) )? 10: 1;
+    int s = this->Viewer->GetSlice( );
+    this->Viewer->SetSlice( s + off );
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::InteractorStyleImage::
+OnMouseWheelBackward( )
+{
+  if( this->Viewer != NULL )
+  {
+    int off = ( this->Interactor->GetShiftKey( ) )? 10: 1;
+    int s = this->Viewer->GetSlice( );
+    this->Viewer->SetSlice( s - off );
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::InteractorStyleImage::
+OnChar( )
+{
+  if( this->Viewer == NULL )
+    return;
+  switch( this->Interactor->GetKeyCode( ) )
+  {
+  case 'r': case 'R':
+  {
+    this->CurrentRenderer->ResetCamera( );
+    this->Interactor->Render( );
+  }
+  break;
+  case 'v': case 'V':
+  {
+    this->Viewer->GetImageActor( )->ResetWindowLevel( );
+    this->Interactor->Render( );
+    std::set< ivq::VTK::ImageViewer* >::iterator vIt =
+      this->OtherViewers.begin( );
+    for( ; vIt != this->OtherViewers.end( ); ++vIt )
+    {
+      ivq::VTK::ImageViewer* v = *vIt;
+      v->GetImageActor( )->ResetWindowLevel( );
+      v->Render( );
+
+    } // rof
+  }
+  break;
+  default:
+    break;
+
+  } // hctiws
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::InteractorStyleImage::
+Rotate( )
+{
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::InteractorStyleImage::
+Spin( )
+{
+}
+
+// -------------------------------------------------------------------------
+ivq::VTK::InteractorStyleImage::
+InteractorStyleImage( )
+  : Superclass( ),
+    Viewer( NULL ),
+    PressedButton( 0 )
+{
+  this->SetInteractionModeToImage2D( );
+}
+
+// -------------------------------------------------------------------------
+ivq::VTK::InteractorStyleImage::
+~InteractorStyleImage( )
+{
+}
+
+// eof - $RCSfile$
diff --git a/lib/ivq/VTK/InteractorStyleImage.h b/lib/ivq/VTK/InteractorStyleImage.h
new file mode 100644 (file)
index 0000000..af83511
--- /dev/null
@@ -0,0 +1,76 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__VTK__InteractorStyleImage__h__
+#define __ivq__VTK__InteractorStyleImage__h__
+
+#include <ivq/ivq_export.h>
+
+#include <set>
+#include <vtkInteractorStyleImage.h>
+
+namespace ivq
+{
+  namespace VTK
+  {
+    class ImageViewer;
+
+    /**
+     */
+    class IVQ_EXPORT InteractorStyleImage
+      : public vtkInteractorStyleImage
+    {
+    public:
+      typedef InteractorStyleImage Self;
+
+    public:
+      vtkTypeMacro( InteractorStyleImage, vtkInteractorStyleImage );
+
+    public:
+      static Self* New( );
+
+      ivq::VTK::ImageViewer* GetViewer( );
+      void SetViewer( ivq::VTK::ImageViewer* v );
+      void AddOtherViewer( ivq::VTK::ImageViewer* v );
+
+      virtual void OnMouseMove( ) override;
+      virtual void OnLeftButtonDown( ) override;
+      virtual void OnLeftButtonUp( ) override;
+      virtual void OnMiddleButtonDown( ) override;
+      virtual void OnMiddleButtonUp( ) override;
+      virtual void OnRightButtonDown( ) override;
+      virtual void OnRightButtonUp( ) override;
+      virtual void OnMouseWheelForward( ) override;
+      virtual void OnMouseWheelBackward( ) override;
+      virtual void OnChar( ) override;
+
+      virtual void Rotate( ) override;
+      virtual void Spin( ) override;
+
+    protected:
+      InteractorStyleImage( );
+      virtual ~InteractorStyleImage( );
+
+    private:
+      // Purposely not implemented.
+      InteractorStyleImage( const InteractorStyleImage& other );
+      void operator=( const InteractorStyleImage& other );
+
+    protected:
+      ivq::VTK::ImageViewer* Viewer;
+      std::set< ivq::VTK::ImageViewer* > OtherViewers;
+      double StartClick[ 2 ];
+      double StartWL[ 2 ];
+      unsigned char PressedButton;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#endif // __ivq__VTK__InteractorStyleImage__h__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/VTK/MPRViewers.cxx b/lib/ivq/VTK/MPRViewers.cxx
new file mode 100644 (file)
index 0000000..8a15026
--- /dev/null
@@ -0,0 +1,197 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#include <ivq/VTK/MPRViewers.h>
+
+#include <ivq/VTK/InteractorStyleImage.h>
+#include <ivq/VTK/ImageViewer.h>
+
+// -------------------------------------------------------------------------
+ivq::VTK::MPRViewers::
+Self* ivq::VTK::MPRViewers::
+New( )
+{
+  return( new Self( ) );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::MPRViewers::
+Render( )
+{
+  for( unsigned int i = 0; i < 3; ++i )
+    if( this->Viewers[ i ].GetPointer( ) != NULL )
+      this->Viewers[ i ]->Render( );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::MPRViewers::
+SetInputData( vtkImageData* in )
+{
+  bool need_to_configure = false;
+  for( unsigned int i = 0; i < 3; ++i )
+    need_to_configure |= ( this->Viewers[ i ].GetPointer( ) == NULL );
+  if( need_to_configure )
+    this->_ConfigureViews( );
+  for( unsigned int i = 0; i < 3; ++i )
+  {
+    this->Viewers[ i ]->SetInputData( in );
+    this->Viewers[ i ]->SetSliceOrientation( i );
+
+  } // rof
+  for( unsigned int i = 0; i < 3; ++i )
+    for( unsigned int j = 0; j < 3; ++j )
+      if( i != j )
+        this->Viewers[ i ]->GetInteractorStyle( )->
+          AddOtherViewer( this->Viewers[ j ] );
+}
+
+// -------------------------------------------------------------------------
+vtkImageData* ivq::VTK::MPRViewers::
+GetInput( )
+{
+  if( this->Viewers[ 0 ].GetPointer( ) != NULL )
+    return( this->Viewers[ 0 ]->GetInput( ) );
+  else
+    return( NULL );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::MPRViewers::
+SetInputConnection( vtkAlgorithmOutput* input )
+{
+  bool need_to_configure = false;
+  for( unsigned int i = 0; i < 3; ++i )
+    need_to_configure |= ( this->Viewers[ i ].GetPointer( ) == NULL );
+  if( need_to_configure )
+    this->_ConfigureViews( );
+  for( unsigned int i = 0; i < 3; ++i )
+  {
+    this->Viewers[ i ]->SetInputConnection( input );
+    this->Viewers[ i ]->SetSliceOrientation( i );
+
+  } // rof
+  for( unsigned int i = 0; i < 3; ++i )
+    for( unsigned int j = 0; j < 3; ++j )
+      if( i != j )
+        this->Viewers[ i ]->GetInteractorStyle( )->
+          AddOtherViewer( this->Viewers[ j ] );
+}
+
+// -------------------------------------------------------------------------
+ivq::VTK::ImageViewer* ivq::VTK::MPRViewers::
+GetView( int o )
+{
+  if( o < 3 )
+    return( this->Viewers[ o ].GetPointer( ) );
+  else
+    return( NULL );
+}
+
+// -------------------------------------------------------------------------
+const ivq::VTK::ImageViewer* ivq::VTK::MPRViewers::
+GetView( int o ) const
+{
+  if( o < 3 )
+    return( this->Viewers[ o ].GetPointer( ) );
+  else
+    return( NULL );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::MPRViewers::
+SetView( int o, ivq::VTK::ImageViewer* v )
+{
+  if( o < 3 )
+    this->Viewers[ o ] = v;
+}
+
+// -------------------------------------------------------------------------
+double ivq::VTK::MPRViewers::
+GetColorWindow( )
+{
+  if( this->Viewers[ 0 ].GetPointer( ) != NULL )
+    return( this->Viewers[ 0 ]->GetColorWindow( ) );
+  else
+    return( 0 );
+}
+
+// -------------------------------------------------------------------------
+double ivq::VTK::MPRViewers::
+GetColorLevel( )
+{
+  if( this->Viewers[ 0 ].GetPointer( ) != NULL )
+    return( this->Viewers[ 0 ]->GetColorLevel( ) );
+  else
+    return( 0 );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::MPRViewers::
+SetColorWindow( double s )
+{
+  for( unsigned int i = 0; i < 3; ++i )
+    if( this->Viewers[ i ].GetPointer( ) != NULL )
+      this->Viewers[ i ]->SetColorWindow( s );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::MPRViewers::
+SetColorLevel( double s )
+{
+  for( unsigned int i = 0; i < 3; ++i )
+    if( this->Viewers[ i ].GetPointer( ) != NULL )
+      this->Viewers[ i ]->SetColorLevel( s );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::MPRViewers::
+ResetCameras( )
+{
+  for( unsigned int i = 0; i < 3; ++i )
+    if( this->Viewers[ i ].GetPointer( ) != NULL )
+      this->Viewers[ i ]->ResetCamera( );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::MPRViewers::
+Initialize( )
+{
+  for( unsigned int i = 0; i < 3; ++i )
+    if( this->Viewers[ i ].GetPointer( ) != NULL )
+      this->Viewers[ i ]->Initialize( );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::MPRViewers::
+Start( )
+{
+  for( unsigned int i = 0; i < 3; ++i )
+    if( this->Viewers[ i ].GetPointer( ) != NULL )
+      this->Viewers[ i ]->Start( );
+}
+
+// -------------------------------------------------------------------------
+ivq::VTK::MPRViewers::
+MPRViewers( )
+  : Superclass( )
+{
+}
+
+// -------------------------------------------------------------------------
+ivq::VTK::MPRViewers::
+~MPRViewers( )
+{
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::MPRViewers::
+_ConfigureViews( )
+{
+  for( unsigned int i = 0; i < 3; ++i )
+    this->Viewers[ i ] = vtkSmartPointer< ivq::VTK::ImageViewer >::New( );
+}
+
+// eof - $RCSfile$
diff --git a/lib/ivq/VTK/MPRViewers.h b/lib/ivq/VTK/MPRViewers.h
new file mode 100644 (file)
index 0000000..b259b23
--- /dev/null
@@ -0,0 +1,78 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__VTK__MPRViewers__h__
+#define __ivq__VTK__MPRViewers__h__
+
+#include <ivq/ivq_export.h>
+
+#include <vtkSmartPointer.h>
+#include <vtkObject.h>
+
+class vtkAlgorithmOutput;
+class vtkImageData;
+
+namespace ivq
+{
+  namespace VTK
+  {
+    class ImageViewer;
+
+    /**
+     */
+    class IVQ_EXPORT MPRViewers
+      : public vtkObject
+    {
+    public:
+      typedef MPRViewers Self;
+
+    public:
+      vtkTypeMacro( MPRViewers, vtkObject );
+
+    public:
+      static Self* New( );
+
+      virtual void Render( );
+
+      virtual void SetInputData( vtkImageData* in );
+      virtual vtkImageData* GetInput( );
+      virtual void SetInputConnection( vtkAlgorithmOutput* input );
+
+      ivq::VTK::ImageViewer* GetView( int o );
+      const ivq::VTK::ImageViewer* GetView( int o ) const;
+      void SetView( int o, ivq::VTK::ImageViewer* v );
+
+      virtual double GetColorWindow( );
+      virtual double GetColorLevel( );
+      virtual void SetColorWindow( double s );
+      virtual void SetColorLevel( double s );
+
+      virtual void ResetCameras( );
+      virtual void Initialize( );
+      virtual void Start( );
+
+    protected:
+      MPRViewers( );
+      virtual ~MPRViewers( );
+
+      void _ConfigureViews( );
+
+    private:
+      // Purposely not implemented.
+      MPRViewers( const MPRViewers& other );
+      void operator=( const MPRViewers& other );
+
+    protected:
+      vtkSmartPointer< ivq::VTK::ImageViewer > Viewers[ 3 ];
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#endif // __ivq__VTK__MPRViewers__h__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/VTK/PolyDataActor.cxx b/lib/ivq/VTK/PolyDataActor.cxx
new file mode 100644 (file)
index 0000000..50022be
--- /dev/null
@@ -0,0 +1,129 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#include <ivq/VTK/PolyDataActor.h>
+
+#include <vtkActor.h>
+#include <vtkPolyDataMapper.h>
+
+// -------------------------------------------------------------------------
+ivq::VTK::PolyDataActor::
+Self* ivq::VTK::PolyDataActor::
+New( )
+{
+  return( new Self( ) );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::PolyDataActor::
+Modified( )
+{
+  this->Mapper->Modified( );
+  this->Actor->Modified( );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::PolyDataActor::
+Update( )
+{
+  this->Mapper->Update( );
+  this->Actor->Modified( );
+}
+
+// -------------------------------------------------------------------------
+vtkPolyData* ivq::VTK::PolyDataActor::
+GetInput( )
+{
+  return( this->Mapper->GetInput( ) );
+}
+
+// -------------------------------------------------------------------------
+vtkAlgorithm* ivq::VTK::PolyDataActor::
+GetInputAlgorithm( )
+{
+  return( this->Mapper->GetInputAlgorithm( ) );
+}
+
+// -------------------------------------------------------------------------
+vtkInformation* ivq::VTK::PolyDataActor::
+GetInputInformation( )
+{
+  return( this->Mapper->GetInputInformation( ) );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::PolyDataActor::
+SetInputData( vtkPolyData* input )
+{
+  this->Mapper->SetInputData( input );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::PolyDataActor::
+SetInputConnection( vtkAlgorithmOutput* aout )
+{
+  this->Mapper->SetInputConnection( aout );
+}
+
+// -------------------------------------------------------------------------
+vtkPolyDataMapper* ivq::VTK::PolyDataActor::
+GetMapper( )
+{
+  return( this->Mapper.GetPointer( ) );
+}
+
+// -------------------------------------------------------------------------
+const vtkPolyDataMapper* ivq::VTK::PolyDataActor::
+GetMapper( ) const
+{
+  return( this->Mapper.GetPointer( ) );
+}
+
+// -------------------------------------------------------------------------
+vtkActor* ivq::VTK::PolyDataActor::
+GetActor( )
+{
+  return( this->Actor.GetPointer( ) );
+}
+
+// -------------------------------------------------------------------------
+const vtkActor* ivq::VTK::PolyDataActor::
+GetActor( ) const
+{
+  return( this->Actor.GetPointer( ) );
+}
+
+// -------------------------------------------------------------------------
+vtkProperty* ivq::VTK::PolyDataActor::
+GetProperty( )
+{
+  return( this->Actor->GetProperty( ) );
+}
+
+// -------------------------------------------------------------------------
+const vtkProperty* ivq::VTK::PolyDataActor::
+GetProperty( ) const
+{
+  return( this->Actor->GetProperty( ) );
+}
+
+// -------------------------------------------------------------------------
+ivq::VTK::PolyDataActor::
+PolyDataActor( )
+  : Superclass( )
+{
+  this->Mapper = vtkSmartPointer< vtkPolyDataMapper >::New( );
+  this->Actor = vtkSmartPointer< vtkActor >::New( );
+  this->Actor->SetMapper( this->Mapper );
+}
+
+// -------------------------------------------------------------------------
+ivq::VTK::PolyDataActor::
+~PolyDataActor( )
+{
+}
+
+// eof - $RCSfile$
diff --git a/lib/ivq/VTK/PolyDataActor.h b/lib/ivq/VTK/PolyDataActor.h
new file mode 100644 (file)
index 0000000..21be872
--- /dev/null
@@ -0,0 +1,80 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__VTK__PolyDataActor__h__
+#define __ivq__VTK__PolyDataActor__h__
+
+#include <ivq/ivq_export.h>
+
+#include <vtkObject.h>
+
+#include <vtkSmartPointer.h>
+
+class vtkActor;
+class vtkAlgorithm;
+class vtkAlgorithmOutput;
+class vtkInformation;
+class vtkPolyData;
+class vtkPolyDataMapper;
+class vtkProperty;
+
+namespace ivq
+{
+  namespace VTK
+  {
+    /**
+     */
+    class IVQ_EXPORT PolyDataActor
+      : public vtkObject
+    {
+    public:
+      typedef PolyDataActor Self;
+
+    public:
+      vtkTypeMacro( PolyDataActor, vtkObject );
+
+    public:
+      static Self* New( );
+
+      virtual void Modified( ) override;
+      virtual void Update( );
+
+      vtkPolyData* GetInput( );
+      vtkAlgorithm* GetInputAlgorithm( );
+      vtkInformation* GetInputInformation( );
+      void SetInputData( vtkPolyData* input );
+      void SetInputConnection( vtkAlgorithmOutput* aout );
+
+      vtkPolyDataMapper* GetMapper( );
+      const vtkPolyDataMapper* GetMapper( ) const;
+
+      vtkActor* GetActor( );
+      const vtkActor* GetActor( ) const;
+
+      vtkProperty* GetProperty( );
+      const vtkProperty* GetProperty( ) const;
+
+    protected:
+      PolyDataActor( );
+      virtual ~PolyDataActor( );
+
+    private:
+      // Purposely not implemented
+      PolyDataActor( const Self& );
+      Self& operator=( const Self& );
+
+    protected:
+      vtkSmartPointer< vtkPolyDataMapper > Mapper;
+      vtkSmartPointer< vtkActor >          Actor;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#endif // __ivq__VTK__PolyDataActor__h__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/VTK/SeedWidget.cxx b/lib/ivq/VTK/SeedWidget.cxx
new file mode 100644 (file)
index 0000000..be43205
--- /dev/null
@@ -0,0 +1,109 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#include <ivq/VTK/SeedWidget.h>
+
+#include <vtkEvent.h>
+#include <vtkRenderWindowInteractor.h>
+#include <vtkWidgetCallbackMapper.h>
+#include <vtkWidgetEvent.h>
+
+// -------------------------------------------------------------------------
+ivq::VTK::SeedWidget::
+Self* ivq::VTK::SeedWidget::
+New( )
+{
+  return( new Self );
+}
+
+// -------------------------------------------------------------------------
+ivq::VTK::SeedWidget::
+SeedWidget( )
+  : Superclass( )
+{
+  // These are the event callbacks supported by this widget
+  this->CallbackMapper->SetCallbackMethod(
+    vtkCommand::LeftButtonPressEvent,
+    vtkWidgetEvent::AddPoint,
+    this, Self::_AddPointAction
+    );
+  this->CallbackMapper->SetCallbackMethod(
+    vtkCommand::RightButtonPressEvent,
+    vtkWidgetEvent::Completed,
+    this, Self::_CompletedAction
+    );
+  this->CallbackMapper->SetCallbackMethod(
+    vtkCommand::MouseMoveEvent,
+    vtkWidgetEvent::Move,
+    this, Self::_MoveAction
+    );
+  this->CallbackMapper->SetCallbackMethod(
+    vtkCommand::LeftButtonReleaseEvent,
+    vtkWidgetEvent::EndSelect,
+    this, Self::_EndSelectAction
+    );
+  this->CallbackMapper->SetCallbackMethod(
+    vtkCommand::KeyPressEvent,
+    vtkEvent::NoModifier, 127, 1, "Delete",
+    vtkWidgetEvent::Delete,
+    this, Self::_DeleteAction
+    );
+}
+
+// -------------------------------------------------------------------------
+ivq::VTK::SeedWidget::
+~SeedWidget( )
+{
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::SeedWidget::
+_AddPointAction( vtkAbstractWidget* wdg )
+{
+  Self* self = dynamic_cast< Self* >( wdg );
+  if( self == NULL )
+    return;
+  vtkRenderWindowInteractor* iren = self->GetInteractor( );
+  if( iren == NULL )
+    return;
+  int shift = iren->GetShiftKey( );
+  if( shift == 1 )
+    Self::AddPointAction( wdg );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::SeedWidget::
+_CompletedAction( vtkAbstractWidget* wdg )
+{
+  // Do nothing
+  Self::CompletedAction( wdg );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::SeedWidget::
+_MoveAction( vtkAbstractWidget* wdg )
+{
+  // Do nothing
+  Self::MoveAction( wdg );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::SeedWidget::
+_EndSelectAction( vtkAbstractWidget* wdg )
+{
+  // Do nothing
+  Self::EndSelectAction( wdg );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::SeedWidget::
+_DeleteAction( vtkAbstractWidget* wdg )
+{
+  // Do nothing
+  Self::DeleteAction( wdg );
+}
+
+// eof - $RCSfile$
diff --git a/lib/ivq/VTK/SeedWidget.h b/lib/ivq/VTK/SeedWidget.h
new file mode 100644 (file)
index 0000000..49bff82
--- /dev/null
@@ -0,0 +1,54 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__VTK__SeedWidget__h__
+#define __ivq__VTK__SeedWidget__h__
+
+#include <ivq/ivq_export.h>
+
+#include <vtkSeedWidget.h>
+
+namespace ivq
+{
+  namespace VTK
+  {
+    /**
+     */
+    class IVQ_EXPORT SeedWidget
+      : public vtkSeedWidget
+    {
+    public:
+      typedef SeedWidget Self;
+
+    public:
+      vtkTypeMacro( SeedWidget, vtkSeedWidget );
+
+    public:
+      static Self* New( );
+
+    protected:
+      SeedWidget( );
+      virtual ~SeedWidget( );
+
+      static void _AddPointAction( vtkAbstractWidget* wdg );
+      static void _CompletedAction( vtkAbstractWidget* wdg );
+      static void _MoveAction( vtkAbstractWidget* wdg );
+      static void _EndSelectAction( vtkAbstractWidget* wdg );
+      static void _DeleteAction( vtkAbstractWidget* wdg );
+
+    private:
+      // Purposely not implemented
+      SeedWidget( const Self& );
+      Self& operator=( const Self& );
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#endif // __ivq__VTK__SeedWidget__h__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/VTK/SeedWidgetOverImageActor.cxx b/lib/ivq/VTK/SeedWidgetOverImageActor.cxx
new file mode 100644 (file)
index 0000000..dbd90ca
--- /dev/null
@@ -0,0 +1,224 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#include <ivq/VTK/SeedWidgetOverImageActor.h>
+
+#include <ivq/VTK/ImageActor.h>
+#include <ivq/VTK/ImageSlicePointPlacer.h>
+
+#include <vtkCommand.h>
+#include <vtkHandleWidget.h>
+#include <vtkPointHandleRepresentation3D.h>
+#include <vtkProperty.h>
+#include <vtkRenderWindowInteractor.h>
+#include <vtkSeedRepresentation.h>
+
+// -------------------------------------------------------------------------
+namespace ivq
+{
+  namespace VTK
+  {
+    /**
+     */
+    class SeedWidgetOverImageActorCallback
+      : public vtkCommand
+    {
+    public:
+      static SeedWidgetOverImageActorCallback* New( )
+        {
+          return( new SeedWidgetOverImageActorCallback( ) );
+        }
+      virtual void Execute(
+        vtkObject* caller, unsigned long eId, void* data
+        ) override
+        {
+          ivq::VTK::ImageActor* actor =
+            ivq::VTK::ImageActor::SafeDownCast( caller );
+          ivq::VTK::SeedWidgetOverImageActor* widget =
+            ivq::VTK::SeedWidgetOverImageActor::SafeDownCast( caller );
+          if( actor != NULL && this->Widget != NULL )
+          {
+            if( eId == vtkCommand::InteractionEvent )
+            {
+              widget = this->Widget;
+              if( widget->GetEnabled( ) != 0 )
+              {
+                widget->CompleteInteraction( );
+                widget->EnabledOff( );
+                unsigned long nSeeds =
+                  widget->Representation->GetNumberOfSeeds( );
+                for( unsigned long i = 0; i < nSeeds; ++i )
+                {
+                  widget->Representation->RemoveLastHandle( );
+                  widget->DeleteSeed(
+                    widget->Representation->GetNumberOfSeeds( )
+                    );
+
+                } // rof
+
+                unsigned long slice = widget->Actor->GetSliceNumber( );
+                std::map< unsigned long, std::vector< double > >::iterator
+                  sIt = widget->Points.find( slice );
+                if( sIt != widget->Points.end( ) )
+                {
+                  widget->Representation->BuildRepresentation( );
+                  vtkRenderer* ren =
+                    widget->GetInteractor( )->FindPokedRenderer(
+                      widget->GetInteractor( )->GetEventPosition( )[ 0 ],
+                      widget->GetInteractor( )->GetEventPosition( )[ 1 ]
+                      );
+                  unsigned int nCoords = sIt->second.size( );
+                  for( unsigned int c = 0; c < nCoords; c += 3 )
+                  {
+                    double x[ 3 ];
+                    widget->ComputeWorldToDisplay(
+                      ren,
+                      sIt->second[ c ],
+                      sIt->second[ c + 1 ],
+                      sIt->second[ c + 2 ],
+                      x
+                      );
+                    x[ 2 ] = double( 0 );
+                    int s = widget->Representation->CreateHandle( x );
+                    vtkHandleWidget* curr_hnd = widget->CreateNewHandle( );
+                    widget->Representation->SetSeedDisplayPosition( s, x );
+                    curr_hnd->SetEnabled( 1 );
+
+                  } // rof
+
+                } // fi
+                widget->RestartInteraction( );
+                widget->EnabledOn( );
+                widget->Render( );
+
+              } // fi
+
+            } // fi
+          }
+          else if( widget != NULL )
+          {
+             if( eId == vtkCommand::InteractionEvent )
+             {
+               unsigned long sId = *( static_cast< int* >( data ) );
+               double pos[ 3 ];
+               widget->Representation->GetSeedWorldPosition( sId, pos );
+               unsigned long slice = widget->Actor->GetSliceNumber( );
+               widget->Points[ slice ][ ( sId * 3 ) + 0 ] = pos[ 0 ];
+               widget->Points[ slice ][ ( sId * 3 ) + 1 ] = pos[ 1 ];
+               widget->Points[ slice ][ ( sId * 3 ) + 2 ] = pos[ 2 ];
+             }
+             else if( eId == vtkCommand::PlacePointEvent )
+             {
+               unsigned long sId =
+                 widget->Representation->GetNumberOfSeeds( ) - 1;
+               double pos[ 3 ];
+               widget->Representation->GetSeedWorldPosition( sId, pos );
+               unsigned long slice = widget->Actor->GetSliceNumber( );
+               widget->Points[ slice ].push_back( pos[ 0 ] );
+               widget->Points[ slice ].push_back( pos[ 1 ] );
+               widget->Points[ slice ].push_back( pos[ 2 ] );
+
+             } // fi
+
+          } // fi
+        }
+
+    protected:
+      SeedWidgetOverImageActorCallback( )
+        : vtkCommand( ),
+          Widget( NULL )
+        {
+        }
+      virtual ~SeedWidgetOverImageActorCallback( )
+        {
+        }
+
+    private:
+      // Purposely not implemented
+      SeedWidgetOverImageActorCallback(
+        const SeedWidgetOverImageActorCallback& other
+        );
+      SeedWidgetOverImageActorCallback& operator=(
+        const SeedWidgetOverImageActorCallback& other
+        );
+
+    public:
+      ivq::VTK::SeedWidgetOverImageActor* Widget;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+// -------------------------------------------------------------------------
+ivq::VTK::SeedWidgetOverImageActor::
+Self* ivq::VTK::SeedWidgetOverImageActor::
+New( )
+{
+  return( new Self( ) );
+}
+
+// -------------------------------------------------------------------------
+ivq::VTK::ImageActor* ivq::VTK::SeedWidgetOverImageActor::
+GetActor( )
+{
+  return( this->Actor.GetPointer( ) );
+}
+
+// -------------------------------------------------------------------------
+void ivq::VTK::SeedWidgetOverImageActor::
+SetActor( ivq::VTK::ImageActor* actor )
+{
+  if( this->Actor.GetPointer( ) != actor )
+  {
+    this->Points.clear( );
+    this->Actor = actor;
+    this->Placer = vtkSmartPointer< ivq::VTK::ImageSlicePointPlacer >::New( );
+    this->Handles = vtkSmartPointer< vtkPointHandleRepresentation3D >::New( );
+    this->Representation = vtkSmartPointer< vtkSeedRepresentation >::New( );
+
+    this->Placer->SetImageSlice( this->Actor );
+    this->Handles->GetProperty( )->SetColor( 1, 0, 0 );
+    this->Handles->SetPointPlacer( this->Placer );
+    this->Representation->SetHandleRepresentation( this->Handles );
+    this->SetRepresentation( this->Representation );
+    this->Modified( );
+
+    vtkSmartPointer< SeedWidgetOverImageActorCallback > cbk =
+      vtkSmartPointer< SeedWidgetOverImageActorCallback >::New( );
+    cbk->Widget = this;
+    this->ObserverId =
+      this->Actor->AddObserver( vtkCommand::InteractionEvent, cbk );
+    this->AddObserver( vtkCommand::PlacePointEvent, cbk );
+    this->AddObserver( vtkCommand::InteractionEvent, cbk );
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+const ivq::VTK::SeedWidgetOverImageActor::
+TSeeds& ivq::VTK::SeedWidgetOverImageActor::
+GetSeeds( ) const
+{
+  return( this->Points );
+}
+
+// -------------------------------------------------------------------------
+ivq::VTK::SeedWidgetOverImageActor::
+SeedWidgetOverImageActor( )
+  : Superclass( )
+{
+}
+
+// -------------------------------------------------------------------------
+ivq::VTK::SeedWidgetOverImageActor::
+~SeedWidgetOverImageActor( )
+{
+  if( this->Actor.GetPointer( ) != NULL )
+    this->Actor->RemoveObserver( this->ObserverId );
+}
+
+// eof - $RCSfile$
diff --git a/lib/ivq/VTK/SeedWidgetOverImageActor.h b/lib/ivq/VTK/SeedWidgetOverImageActor.h
new file mode 100644 (file)
index 0000000..81f05c9
--- /dev/null
@@ -0,0 +1,78 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__VTK__SeedWidgetOverImageActor__h__
+#define __ivq__VTK__SeedWidgetOverImageActor__h__
+
+#include <ivq/ivq_export.h>
+
+#include <map>
+#include <vector>
+
+#include <ivq/VTK/SeedWidget.h>
+
+#include <vtkSmartPointer.h>
+
+class vtkPointHandleRepresentation3D;
+class vtkSeedRepresentation;
+
+namespace ivq
+{
+  namespace VTK
+  {
+    class ImageActor;
+    class ImageSlicePointPlacer;
+
+    /**
+     */
+    class IVQ_EXPORT SeedWidgetOverImageActor
+      : public ivq::VTK::SeedWidget
+    {
+    public:
+      typedef SeedWidgetOverImageActor Self;
+
+      typedef std::map< unsigned long, std::vector< double > > TSeeds;
+
+    public:
+      vtkTypeMacro( SeedWidgetOverImageActor, ivq::VTK::SeedWidget );
+
+    public:
+      static Self* New( );
+
+      ivq::VTK::ImageActor* GetActor( );
+      void SetActor( ivq::VTK::ImageActor* actor );
+
+      const TSeeds& GetSeeds( ) const;
+
+    protected:
+      SeedWidgetOverImageActor( );
+      virtual ~SeedWidgetOverImageActor( );
+
+    private:
+      // Purposely not implemented
+      SeedWidgetOverImageActor( const Self& );
+      Self& operator=( const Self& );
+
+    protected:
+      vtkSmartPointer< ivq::VTK::ImageActor >            Actor;
+      vtkSmartPointer< ivq::VTK::ImageSlicePointPlacer > Placer;
+      vtkSmartPointer< vtkPointHandleRepresentation3D >  Handles;
+      vtkSmartPointer< vtkSeedRepresentation >           Representation;
+
+      unsigned long ObserverId;
+
+      std::map< unsigned long, std::vector< double > > Points;
+
+      friend class SeedWidgetOverImageActorCallback;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#endif // __ivq__VTK__SeedWidgetOverImageActor__h__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/VTK/Simple3DCurveToPolyData.cxx b/lib/ivq/VTK/Simple3DCurveToPolyData.cxx
new file mode 100644 (file)
index 0000000..8b7e279
--- /dev/null
@@ -0,0 +1,119 @@
+#include <ivq/VTK/Simple3DCurveToPolyData.h>
+
+#include <vtkCellArray.h>
+#include <vtkInformation.h>
+#include <vtkInformationVector.h>
+#include <vtkSmartPointer.h>
+
+// -------------------------------------------------------------------------
+template< class _TCurve >
+typename ivq::VTK::Simple3DCurveToPolyData< _TCurve >::
+Self* ivq::VTK::Simple3DCurveToPolyData< _TCurve >::
+New( )
+{
+  return( new Self( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TCurve >
+const typename ivq::VTK::Simple3DCurveToPolyData< _TCurve >::
+TCurve* ivq::VTK::Simple3DCurveToPolyData< _TCurve >::
+GetInput( ) const
+{
+  return( this->m_Curve );
+}
+
+// -------------------------------------------------------------------------
+template< class _TCurve >
+void
+ivq::VTK::Simple3DCurveToPolyData< _TCurve >::
+SetInput( const TCurve* c )
+{
+  if( this->m_Curve != c )
+  {
+    this->m_Curve = c;
+    this->Modified( );
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TCurve >
+ivq::VTK::Simple3DCurveToPolyData< _TCurve >::
+Simple3DCurveToPolyData( )
+  : vtkPolyDataAlgorithm( ),
+    m_Curve( NULL )
+{
+  this->SetNumberOfInputPorts( 0 );
+}
+
+// -------------------------------------------------------------------------
+template< class _TCurve >
+ivq::VTK::Simple3DCurveToPolyData< _TCurve >::
+~Simple3DCurveToPolyData( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TCurve >
+int ivq::VTK::Simple3DCurveToPolyData< _TCurve >::
+RequestData(
+  vtkInformation* information,
+  vtkInformationVector** input,
+  vtkInformationVector* output
+  )
+{
+  if( this->m_Curve == NULL )
+    return( 0 );
+
+  // Get output
+  vtkInformation* info = output->GetInformationObject( 0 );
+  vtkPolyData* out = vtkPolyData::SafeDownCast(
+    info->Get( vtkDataObject::DATA_OBJECT( ) )
+    );
+
+  // Prepare data
+  out->SetPoints( vtkSmartPointer< vtkPoints >::New( ) );
+  out->SetVerts( vtkSmartPointer< vtkCellArray >::New( ) );
+  out->SetLines( vtkSmartPointer< vtkCellArray >::New( ) );
+  out->SetPolys( vtkSmartPointer< vtkCellArray >::New( ) );
+  out->SetStrips( vtkSmartPointer< vtkCellArray >::New( ) );
+  vtkPoints* points = out->GetPoints( );
+  vtkCellArray* lines = out->GetLines( );
+
+  // Get data
+  for( unsigned long i = 0; i < this->m_Curve->GetNumberOfPoints( ); ++i )
+  {
+    typename _TCurve::TPoint pnt = this->m_Curve->GetPoint( i );
+    points->InsertNextPoint( pnt[ 0 ], pnt[ 1 ], pnt[ 2 ] );
+    if( i > 0 )
+    {
+      lines->InsertNextCell( 2 );
+      lines->InsertCellPoint( i - 1 );
+      lines->InsertCellPoint( i );
+
+    } // fi
+
+  } // rof
+  return( 1 );
+}
+
+// -------------------------------------------------------------------------
+template< class _TCurve >
+int ivq::VTK::Simple3DCurveToPolyData< _TCurve >::
+RequestInformation(
+  vtkInformation* information,
+  vtkInformationVector** input,
+  vtkInformationVector* output
+  )
+{
+  return( 1 );
+}
+
+// -------------------------------------------------------------------------
+#include <ivq/ITK/Simple3DCurve.h>
+
+template class ivq::VTK::Simple3DCurveToPolyData< ivq::ITK::Simple3DCurve< float > >;
+template class ivq::VTK::Simple3DCurveToPolyData< ivq::ITK::Simple3DCurve< double > >;
+
+// eof - $RCSfile$
diff --git a/lib/ivq/VTK/Simple3DCurveToPolyData.h b/lib/ivq/VTK/Simple3DCurveToPolyData.h
new file mode 100644 (file)
index 0000000..e7d38f9
--- /dev/null
@@ -0,0 +1,66 @@
+/* =======================================================================
+ * @author: Leonardo Florez-Valencia
+ * @email: florez-l@javeriana.edu.co
+ * =======================================================================
+ */
+
+#ifndef __ivq__VTK__Simple3DCurveToPolyData__h__
+#define __ivq__VTK__Simple3DCurveToPolyData__h__
+
+#include <ivq/ivq_export.h>
+#include <vtkPolyDataAlgorithm.h>
+
+namespace ivq
+{
+  namespace VTK
+  {
+    /**
+     */
+    template< class _TCurve >
+    class IVQ_EXPORT Simple3DCurveToPolyData
+      : public vtkPolyDataAlgorithm
+    {
+    public:
+      typedef Simple3DCurveToPolyData Self;
+      typedef _TCurve TCurve;
+
+    public:
+      vtkTypeMacro( Simple3DCurveToPolyData, vtkPolyDataAlgorithm );
+
+    public:
+      static Self* New( );
+
+      const TCurve* GetInput( ) const;
+      void SetInput( const TCurve* c );
+
+    protected:
+      Simple3DCurveToPolyData( );
+      virtual ~Simple3DCurveToPolyData( );
+
+      int RequestData(
+        vtkInformation* information,
+        vtkInformationVector** input,
+        vtkInformationVector* output
+        );
+      int RequestInformation(
+        vtkInformation* information,
+        vtkInformationVector** input,
+        vtkInformationVector* output
+        );
+
+    private:
+      // Purposely not implemented
+      Simple3DCurveToPolyData( const Self& );
+      void operator=( const Self& );
+
+    protected:
+      const TCurve* m_Curve;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#endif // __ivq__VTK__Simple3DCurveToPolyData__h__
+
+// eof - $RCSfile$
diff --git a/lib/ivq/Version.cxx.in b/lib/ivq/Version.cxx.in
new file mode 100644 (file)
index 0000000..1ecb84a
--- /dev/null
@@ -0,0 +1,15 @@
+/* =========================================================================
+ * @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+ * =========================================================================
+ */
+
+#include <ivq/Config.h>
+#include <string>
+
+// -------------------------------------------------------------------------
+std::string IVQ_EXPORT version( )
+{
+  return( "@prj_MAJ@.@prj_MIN@.@prj_REL@" );
+}
+
+// eof - $RCSfile$