--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
+
+## ========================
+## == Project definition ==
+## ========================
+
+SET(prj_NAME FrontAlgorithms)
+SET(prj_MAJOR_VERSION 0)
+SET(prj_MINOR_VERSION 1)
+SET(prj_RELEASE_VERSION 0)
+
+## ==========================
+## == Some useful policies ==
+## ==========================
+
+SET(_policies CMP0015 CMP0020 CMP0042)
+FOREACH(_p ${_policies})
+ IF(POLICY ${_p})
+ CMAKE_POLICY(SET ${_p} NEW)
+ ENDIF(POLICY ${_p})
+ENDFOREACH(_p)
+
+## ===========================
+## == Project configuration ==
+## ===========================
+
+PROJECT(${prj_NAME})
+SET(
+ prj_VERSION
+ "${prj_MAJOR_VERSION}.${prj_MINOR_VERSION}.${prj_RELEASE_VERSION}"
+ )
+SET(prj_SHORT_VERSION "${prj_MAJOR_VERSION}")
+
+## =====================================
+## == Functions, packages and options ==
+## =====================================
+
+INCLUDE(cmake/DetectOS.cmake)
+INCLUDE(cmake/Restrictions.cmake)
+INCLUDE(cmake/Functions.cmake)
+INCLUDE(cmake/KitwareTools.cmake)
+INCLUDE(cmake/Options.cmake)
+
+## ===========================
+## == Use all valid subdirs ==
+## ===========================
+
+SET(
+ _include_dirs
+ .
+ lib
+ )
+IF(USE_cpPlugins)
+ LIST(APPEND _include_dirs lib/Instances)
+ENDIF(USE_cpPlugins)
+FOREACH(_dir ${_include_dirs})
+ INCLUDE_DIRECTORIES(
+ ${PROJECT_SOURCE_DIR}/${_dir}
+ ${PROJECT_BINARY_DIR}/${_dir}
+ )
+ENDFOREACH(_dir)
+
+## ========================
+## == Manage source code ==
+## ========================
+
+SUBDIRS(lib)
+IF(USE_cpPlugins)
+ SUBDIRS(plugins)
+ENDIF(USE_cpPlugins)
+
+## eof - $RCSfile$
--- /dev/null
+## =====================
+## == OS-based values ==
+## =====================
+
+SET(prj_NAME_OS "${prj_NAME}_OS_${CMAKE_SYSTEM_NAME}")
+IF("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
+ SET(prj_NAME_LIB_PREFIX "lib")
+ SET(prj_NAME_LIB_EXT ".so")
+ SET(prj_NAME_ENV_SEPARATOR ":")
+ SET(prj_NAME_PATH_SEPARATOR "/")
+ELSEIF("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
+ SET(prj_NAME_LIB_PREFIX "lib")
+ SET(prj_NAME_LIB_EXT ".dylib")
+ SET(prj_NAME_ENV_SEPARATOR ":")
+ SET(prj_NAME_PATH_SEPARATOR "/")
+ELSEIF("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
+ SET(prj_NAME_LIB_PREFIX "")
+ SET(prj_NAME_LIB_EXT ".dll")
+ SET(prj_NAME_ENV_SEPARATOR ";")
+ SET(prj_NAME_PATH_SEPARATOR "\\")
+ENDIF("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
+
+## eof - $RCSfile$
--- /dev/null
+## -------------------------------------------------------------------------
+FUNCTION(NormPaths output_files)
+SET(_out)
+FOREACH(_f ${ARGN})
+ SET(_d)
+ FILE(TO_CMAKE_PATH ${_f} _d)
+ LIST(APPEND _out ${_d})
+ENDFOREACH(_f)
+SET(${output_files} "${_out}" PARENT_SCOPE)
+ENDFUNCTION()
+
+## -------------------------------------------------------------------------
+FUNCTION(Wrap_Qt_CPP output_files)
+SET(_out)
+FOREACH(_f ${ARGN})
+ IF(EXISTS ${_f})
+ FILE(READ ${_f} _txt)
+ STRING(FIND "${_txt}" "Q_OBJECT" _pos)
+ IF(NOT ${_pos} EQUAL -1)
+ SET(_s)
+ QT4_WRAP_CPP(_s ${_f})
+ SET(_out ${_out} ${_s})
+ ENDIF(NOT ${_pos} EQUAL -1)
+ ENDIF(EXISTS ${_f})
+ENDFOREACH(_f)
+SET(${output_files} "${_out}" PARENT_SCOPE)
+ENDFUNCTION()
+
+## -------------------------------------------------------------------------
+FUNCTION(Wrap_Qt_UI output_files)
+NormPaths(_source_dir ${PROJECT_SOURCE_DIR})
+NormPaths(_binary_dir ${PROJECT_BINARY_DIR})
+SET(_out)
+FOREACH(_f ${ARGN})
+ IF(EXISTS ${_f})
+ GET_FILENAME_COMPONENT(_name ${_f} NAME_WE)
+ GET_FILENAME_COMPONENT(_dir ${_f} DIRECTORY)
+ SET(_base_dir ${_source_dir})
+ STRING(FIND "${_dir}" "${_base_dir}" _pos)
+ IF(${_pos} EQUAL -1)
+ SET(_base_dir ${_binary_dir})
+ STRING(FIND "${_dir}" "${_base_dir}" _pos)
+ ENDIF(${_pos} EQUAL -1)
+ IF(NOT ${_pos} EQUAL -1)
+ STRING(REPLACE "${_base_dir}/" "" _dir ${_dir})
+ SET(_out_f ${_binary_dir}/${_dir}/ui_${_name}.h)
+ LIST(APPEND _out ${_out_f})
+ ADD_CUSTOM_COMMAND(
+ OUTPUT ${_out_f}
+ COMMAND Qt4::uic
+ ARGS -o ${_out_f} ${_f}
+ MAIN_DEPENDENCY ${_f} VERBATIM
+ )
+ ENDIF(NOT ${_pos} EQUAL -1)
+ ENDIF(EXISTS ${_f})
+ENDFOREACH(_f)
+SET(${output_files} "${_out}" PARENT_SCOPE)
+ENDFUNCTION()
+
+## -------------------------------------------------------------------------
+FUNCTION(
+ CreateLib
+ lib_name
+ lib_type
+ lib_source_files
+ lib_header_files
+ lib_qt_ui_files
+ lib_version
+ lib_short_version
+ )
+## -- Configure inputs to be cmake-path compatible
+NormPaths(_sources ${lib_source_files})
+NormPaths(_headers ${lib_header_files})
+NormPaths(_qt_uis ${lib_qt_ui_files})
+
+# -- Prepare Qt4-based code
+IF(Qt4_FOUND)
+ ## -- Guess what headers sould be qt-moc'ed
+ Wrap_Qt_CPP(_qt_moc_sources ${_headers})
+ IF(_qt_moc_sources)
+ SET(_sources ${_sources} ${_qt_moc_sources})
+ ENDIF(_qt_moc_sources)
+
+ ## -- Guess what qt-ui's sould be qt-uic'ed
+ ## -- Wrap qt-ui headers: this is equivalent to QT4_WRAP_UI except to change
+ ## -- the output file
+ Wrap_Qt_UI(_qt_ui_headers ${_qt_uis})
+ IF(_qt_ui_headers)
+ SET(_headers ${_headers} ${_qt_ui_headers})
+ SET(_sources ${_sources} ${_qt_ui_headers})
+ ENDIF(_qt_ui_headers)
+ENDIF(Qt4_FOUND)
+
+## -- Ok, compile library
+IF(_sources)
+ NormPaths(_cur_binary_dir ${CMAKE_CURRENT_BINARY_DIR})
+ ADD_LIBRARY(${lib_name} SHARED ${_sources} ${_headers})
+ SET_TARGET_PROPERTIES(
+ ${lib_name}
+ PROPERTIES
+ VERSION "${lib_version}"
+ SOVERSION "${lib_short_version}"
+ )
+ GENERATE_EXPORT_HEADER(
+ ${lib_name}
+ BASE_NAME ${lib_name}
+ EXPORT_MACRO_NAME ${lib_name}_EXPORT
+ EXPORT_FILE_NAME ${lib_name}_Export.h
+ STATIC_DEFINE ${lib_name}_BUILT_AS_STATIC
+ )
+ SET(${lib_name}_LIB ${lib_name} CACHE INTERNAL "Library ${lib_name}")
+ENDIF(_sources)
+
+ENDFUNCTION()
+
+## -------------------------------------------------------------------------
+FUNCTION(
+ LibFromDir
+ lib_name
+ lib_type
+ lib_source_dir
+ lib_version
+ lib_short_version
+ )
+
+## -- Configure inputs to be cmake-path compatible
+NormPaths(_global_source_dir ${PROJECT_SOURCE_DIR})
+NormPaths(_global_binary_dir ${PROJECT_BINARY_DIR})
+NormPaths(_source_dir ${lib_source_dir})
+STRING(REPLACE "${_global_source_dir}" "" _local_source_dir ${_source_dir})
+SET(_binary_dir ${_global_binary_dir}${_local_source_dir})
+
+## -- Some useful variables
+SET(_sources_extensions .c .cpp .cxx)
+SET(_headers_extensions .h .hpp .hxx)
+SET(_qt_ui_extensions .ui)
+SET(_dirs ${_source_dir} ${_binary_dir})
+SET(_sources)
+SET(_headers)
+SET(_qt_uis)
+
+## -- Glob source code
+FOREACH(_d ${_dirs})
+ FOREACH(_e ${_sources_extensions})
+ FILE(GLOB_RECURSE _f "${_d}/*${_e}")
+ SET(_sources ${_sources} ${_f})
+ ENDFOREACH(_e)
+ FOREACH(_e ${_headers_extensions})
+ FILE(GLOB_RECURSE _f "${_d}/*${_e}")
+ SET(_headers ${_headers} ${_f})
+ ENDFOREACH(_e)
+ FOREACH(_e ${_qt_ui_extensions})
+ FILE(GLOB_RECURSE _f "${_d}/*${_e}")
+ SET(_qt_uis ${_qt_uis} ${_f})
+ ENDFOREACH(_e)
+ENDFOREACH(_d)
+
+## -- Configure some files
+FILE(GLOB_RECURSE _configs "${_source_dir}/*.in")
+FOREACH(_c ${_configs})
+
+ ## -- Build input and output names
+ NormPaths(_input_file ${_c})
+ GET_FILENAME_COMPONENT(_input_name ${_input_file} NAME)
+ GET_FILENAME_COMPONENT(_input_dir ${_input_file} DIRECTORY)
+ STRING(REPLACE ".in" "" _output_name ${_input_name})
+ STRING(REPLACE "${_global_source_dir}" "" _output_dir ${_input_dir})
+ SET(_output_file "${_global_binary_dir}${_output_dir}/${_output_name}")
+
+ ## -- Configure file
+ CONFIGURE_FILE(${_input_file} ${_output_file} @ONLY)
+
+ ## -- Add it to the correct list
+ GET_FILENAME_COMPONENT(_output_ext ${_output_name} EXT)
+ IF(
+ "${_output_ext}" STREQUAL ".h"
+ OR
+ "${_output_ext}" STREQUAL ".hpp"
+ OR
+ "${_output_ext}" STREQUAL ".hxx"
+ )
+ SET(_headers ${_headers})
+ ENDIF()
+ IF(
+ "${_output_ext}" STREQUAL ".c"
+ OR
+ "${_output_ext}" STREQUAL ".cpp"
+ OR
+ "${_output_ext}" STREQUAL ".cxx"
+ )
+ SET(_sources ${_sources})
+ ENDIF()
+ IF("${_output_ext}" STREQUAL ".ui")
+ SET(_qt_uis ${_qt_uis})
+ ENDIF()
+ENDFOREACH(_c)
+IF(ARGN)
+ LIST(APPEND _sources ${ARGN})
+ENDIF(ARGN)
+
+## -- Create library
+CreateLib(
+ ${lib_name} ${lib_type}
+ "${_sources}" "${_headers}" "${_qt_uis}"
+ "${lib_version}" "${lib_short_version}"
+ )
+
+ENDFUNCTION()
+
+## -------------------------------------------------------------------------
+FUNCTION(
+ CompileInstances
+ out_lib_name
+ def_file
+ number_of_files
+ prefix
+ version
+ short_version
+ )
+## -- Configure inputs to be cmake-path compatible
+NormPaths(_def_file ${def_file})
+GET_FILENAME_COMPONENT(_def_name ${_def_file} NAME_WE)
+GET_FILENAME_COMPONENT(_def_dir ${_def_file} DIRECTORY)
+NormPaths(_global_source_dir ${PROJECT_SOURCE_DIR})
+NormPaths(_global_binary_dir ${PROJECT_BINARY_DIR})
+STRING(REPLACE "${_global_source_dir}" "" _out_dir ${_def_dir})
+SET(_out_base "${_global_binary_dir}${_out_dir}")
+SET(_out_header "${_out_base}/${_def_name}.h")
+SET(_lib_name "${prefix}${_def_name}")
+SET(_input_extra_code "${_global_source_dir}${_out_dir}/${_def_name}_extra.cxx")
+
+## -- Infere source code filenames
+MATH(EXPR _last_range "${number_of_files}-1")
+SET(_out_code)
+FOREACH(_n RANGE 0 ${_last_range})
+ LIST(APPEND _out_code ${_out_base}/${_def_name}_${_n}.cxx)
+ENDFOREACH(_n)
+
+## -- Add extra code, if any
+SET(_all_out_code ${_out_code})
+IF(EXISTS ${_input_extra_code})
+ LIST(APPEND _all_out_code ${_input_extra_code})
+ENDIF(EXISTS ${_input_extra_code})
+
+## -- Command to write source code
+ADD_CUSTOM_COMMAND(
+ OUTPUT ${_out_header} ${_out_code}
+ DEPENDS ${cpPlugins_bash_BuildInstances_APP} ${_def_file}
+ COMMAND ${cpPlugins_bash_BuildInstances_APP} ${_def_file} ${_lib_name} ${_out_base}/${_def_name} ${number_of_files}
+ )
+
+## -- Create library
+CreateLib(
+ "${_lib_name}" SHARED
+ "${_all_out_code}" "${_out_header}" ""
+ "${version}" "${short_version}"
+ )
+
+## -- Return value
+SET(${out_lib_name} ${_lib_name} PARENT_SCOPE)
+
+ENDFUNCTION()
+
+## -------------------------------------------------------------------------
+FUNCTION(Wrap_cpPlugins output_lib source_dir version short_version prefix)
+
+## -- Configure inputs to be cmake-path compatible
+NormPaths(_source_dir ${source_dir})
+NormPaths(_global_source_dir ${PROJECT_SOURCE_DIR})
+NormPaths(_global_binary_dir ${PROJECT_BINARY_DIR})
+STRING(REPLACE "${_global_source_dir}" "" _out_dir ${_source_dir})
+SET(_out_dir "${_global_binary_dir}${_out_dir}")
+FILE(MAKE_DIRECTORY ${_out_dir})
+GET_FILENAME_COMPONENT(_lib_name ${_source_dir} NAME_WE)
+SET(_lib_name ${prefix}${_lib_name})
+
+## -- Get source code
+FILE(GLOB_RECURSE _hdr_h "${_source_dir}/*.h")
+FILE(GLOB_RECURSE _hdr_hxx "${_source_dir}/*.hxx")
+FILE(GLOB_RECURSE _hdr_hpp "${_source_dir}/*.hpp")
+FILE(GLOB_RECURSE _src_c "${_source_dir}/*.c")
+FILE(GLOB_RECURSE _src_cxx "${_source_dir}/*.cxx")
+FILE(GLOB_RECURSE _src_cpp "${_source_dir}/*.cpp")
+FILE(GLOB_RECURSE _qt_ui "${_source_dir}/*.ui")
+
+## -- Identify sources to wrap
+SET(_hdr_to_wrap)
+FOREACH(_h ${_hdr_h})
+ FILE(READ ${_h} _txt)
+ STRING(FIND "${_txt}" "cpPluginsObject" _res)
+ IF(NOT ${_res} EQUAL -1)
+ LIST(APPEND _hdr_to_wrap ${_h})
+ ENDIF(NOT ${_res} EQUAL -1)
+ENDFOREACH(_h)
+
+## -- Integrate all source files
+SET(_all_src ${_src_c} ${_src_cpp} ${_src_cxx})
+SET(_all_hdr ${_hdr_h} ${_hdr_hpp} ${_hdr_hxx})
+
+## -- Wrap plugins
+IF(_hdr_to_wrap)
+ SET(_host ${_out_dir}/${_lib_name}_host.cxx)
+ ADD_CUSTOM_COMMAND(
+ OUTPUT ${_host}
+ DEPENDS ${cpPlugins_bash_HostCreator_APP} ${_hdr_to_wrap}
+ COMMAND ${cpPlugins_bash_HostCreator_APP} ${_lib_name} ${_host} ${_hdr_to_wrap}
+ )
+ SET(_all_src ${_all_src} ${_host})
+ENDIF(_hdr_to_wrap)
+
+## -- Ok, build library
+IF(_all_src)
+ CreateLib(
+ ${_lib_name} SHARED
+ "${_all_src}" "${_all_hdr}" "${_qt_ui}"
+ "${version}" "${short_version}"
+ ${ARGN}
+ )
+ SET(${output_lib} ${_lib_name} PARENT_SCOPE)
+ELSE(_all_src)
+ MESSAGE(FATAL_ERROR "No source code found to build \"${_lib_name}\"")
+ENDIF(_all_src)
+ENDFUNCTION()
+
+## -------------------------------------------------------------------------
+FUNCTION(AppFromDir output_app source_dir)
+
+## -- Configure inputs to be cmake-path compatible
+NormPaths(_global_source_dir ${PROJECT_SOURCE_DIR})
+NormPaths(_global_binary_dir ${PROJECT_BINARY_DIR})
+NormPaths(_source_dir ${source_dir})
+STRING(REPLACE "${_global_source_dir}" "" _local_source_dir ${_source_dir})
+SET(_binary_dir ${_global_binary_dir}${_local_source_dir})
+IF(${output_app})
+ SET(_app_name ${${output_app}})
+ELSE(${output_app})
+ GET_FILENAME_COMPONENT(_app_name ${_source_dir} NAME_WE)
+ENDIF(${output_app})
+SET(_app_name_option OFF)
+IF(ARGN)
+ LIST(GET ARGN 0 _app_name_option)
+ENDIF(ARGN)
+OPTION(
+ BUILD_${_app_name}
+ "Build \"${_app_name}\" application"
+ ${_app_name_option}
+ )
+
+## -- Real build commands
+IF(BUILD_${_app_name})
+ ## -- Some useful variables
+ SET(_sources_extensions .c .cpp .cxx)
+ SET(_headers_extensions .h .hpp .hxx)
+ SET(_qt_ui_extensions .ui)
+ SET(_dirs ${_source_dir} ${_binary_dir})
+ SET(_sources)
+ SET(_headers)
+ SET(_qt_uis)
+
+ ## -- Glob source code
+ FOREACH(_d ${_dirs})
+ FOREACH(_e ${_sources_extensions})
+ FILE(GLOB_RECURSE _f "${_d}/*${_e}")
+ SET(_sources ${_sources} ${_f})
+ ENDFOREACH(_e)
+ FOREACH(_e ${_headers_extensions})
+ FILE(GLOB_RECURSE _f "${_d}/*${_e}")
+ SET(_headers ${_headers} ${_f})
+ ENDFOREACH(_e)
+ FOREACH(_e ${_qt_ui_extensions})
+ FILE(GLOB_RECURSE _f "${_d}/*${_e}")
+ SET(_qt_uis ${_qt_uis} ${_f})
+ ENDFOREACH(_e)
+ ENDFOREACH(_d)
+
+ ## -- Configure some files
+ FILE(GLOB_RECURSE _configs "${_source_dir}/*.in")
+ FOREACH(_c ${_configs})
+
+ ## -- Build input and output names
+ NormPaths(_input_file ${_c})
+ GET_FILENAME_COMPONENT(_input_name ${_input_file} NAME)
+ GET_FILENAME_COMPONENT(_input_dir ${_input_file} DIRECTORY)
+ STRING(REPLACE ".in" "" _output_name ${_input_name})
+ STRING(REPLACE "${_global_source_dir}" "" _output_dir ${_input_dir})
+ SET(_output_file "${_global_binary_dir}${_output_dir}/${_output_name}")
+
+ ## -- Configure file
+ CONFIGURE_FILE(${_input_file} ${_output_file} @ONLY)
+
+ ## -- Add it to the correct list
+ GET_FILENAME_COMPONENT(_output_ext ${_output_name} EXT)
+ IF(
+ "${_output_ext}" STREQUAL ".h"
+ OR
+ "${_output_ext}" STREQUAL ".hpp"
+ OR
+ "${_output_ext}" STREQUAL ".hxx"
+ )
+ SET(_headers ${_headers})
+ ENDIF()
+ IF(
+ "${_output_ext}" STREQUAL ".c"
+ OR
+ "${_output_ext}" STREQUAL ".cpp"
+ OR
+ "${_output_ext}" STREQUAL ".cxx"
+ )
+ SET(_sources ${_sources})
+ ENDIF()
+ IF("${_output_ext}" STREQUAL ".ui")
+ SET(_qt_uis ${_qt_uis})
+ ENDIF()
+ ENDFOREACH(_c)
+
+ # -- Prepare Qt4-based code
+ IF(Qt4_FOUND)
+
+ ## -- Guess what headers sould be qt-moc'ed
+ Wrap_Qt_CPP(_qt_moc_sources ${_headers})
+ IF(_qt_moc_sources)
+ SET(_sources ${_sources} ${_qt_moc_sources})
+ ENDIF(_qt_moc_sources)
+ ## -- Guess what qt-ui's sould be qt-uic'ed
+ ## -- Wrap qt-ui headers: this is equivalent to QT4_WRAP_UI except to
+ ## -- change the output file
+ Wrap_Qt_UI(_qt_ui_headers ${_qt_uis})
+ IF(_qt_ui_headers)
+ SET(_headers ${_headers} ${_qt_ui_headers})
+ SET(_sources ${_sources} ${_qt_ui_headers})
+ ENDIF(_qt_ui_headers)
+ ENDIF(Qt4_FOUND)
+
+ ## -- Ok, compile application
+ IF(_sources)
+ SET(_gui_type "")
+ IF(WIN32)
+ SET(_gui_type WIN32)
+ ENDIF(WIN32)
+ IF(APPLE)
+ SET(_gui_type MACOSX_BUNDLE)
+ ENDIF(APPLE)
+ ADD_EXECUTABLE(${_app_name} ${_gui_type} ${_sources})
+ SET(${output_app} ${_app_name} PARENT_SCOPE)
+ ELSE(_sources)
+ SET(${output_app} "" PARENT_SCOPE)
+ MESSAGE(FATAL_ERROR "No source code found to build \"${_app_name}\"")
+ ENDIF(_sources)
+ENDIF(BUILD_${_app_name})
+
+ENDFUNCTION()
+
+## eof - $RCSfile$
--- /dev/null
+# ======================
+# == Find ITK and VTK ==
+# ======================
+
+FIND_PACKAGE(ITK REQUIRED)
+INCLUDE(${ITK_USE_FILE})
+
+FIND_PACKAGE(VTK REQUIRED)
+INCLUDE(${VTK_USE_FILE})
+
+# ===================================================
+# == Do not use itk-vtk glue --> problems ahead!!! ==
+# ===================================================
+
+IF(ITKVtkGlue_LOADED)
+ MESSAGE(FATAL_ERROR "ITKVtkGlue module is available. Please re-compile your ITK without it. It could lead to nasty compilation problems... Just waiting for Kitware to solve it.")
+ENDIF(ITKVtkGlue_LOADED)
+
+## eof - $RCSfile$
--- /dev/null
+## ===============================
+## == Some configurable options ==
+## ===============================
+
+OPTION(USE_cpPlugins "Build cpPlugins-based code" OFF)
+IF(USE_cpPlugins)
+ FIND_PACKAGE(cpPlugins REQUIRED)
+ IF(USE_QT4)
+ INCLUDE(cmake/Qt4Tools.cmake)
+ ENDIF(USE_QT4)
+ENDIF(USE_cpPlugins)
+
+## eof - $RCSfile$
--- /dev/null
+## ==================================================
+## == Find Qt4 and check if it was well configured ==
+## ==================================================
+
+SET(QT4_FOUND "0")
+IF(USE_QT4)
+ FIND_PACKAGE(Qt4 REQUIRED)
+ INCLUDE(${QT_USE_FILE})
+ SET(QT4_FOUND "1")
+ENDIF(USE_QT4)
+
+## eof - $RCSfile$
--- /dev/null
+## =======================================================================
+## == Force c++11 language version ==
+## == NOTE: It seems that by default on Visual Studio Compiler supports ==
+## == c++11, so it only need to be tested on other OS. ==
+## =======================================================================
+
+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$
--- /dev/null
+
+## =========================================
+## == Manage every directory as a library ==
+## =========================================
+
+LibFromDir(
+ fpa
+ SHARED
+ ${CMAKE_CURRENT_SOURCE_DIR}/fpa
+ "${prj_VERSION}" "${prj_SHORT_VERSION}"
+ )
+
+## ==================================
+## == Compile cpPlugins-based code ==
+## ==================================
+
+IF(USE_cpPlugins)
+
+ ## =======================
+ ## == Compile instances ==
+ ## =======================
+
+ SUBDIRS(Instances)
+
+ ## ===================================
+ ## == Libraries to dynamically load ==
+ ## ===================================
+
+ SET(
+ fpa_DynLibs
+ local@fpa
+ )
+ FOREACH(_lib ${fpa_Instances})
+ LIST(APPEND fpa_DynLibs local@${_lib})
+ ENDFOREACH(_lib)
+ FILE(WRITE ${PROJECT_BINARY_DIR}/cpPlugins_Libraries.config "")
+ FOREACH(_lib ${fpa_DynLibs})
+ FILE(APPEND ${PROJECT_BINARY_DIR}/cpPlugins_Libraries.config "${_lib}\n")
+ ENDFOREACH(_lib)
+
+ENDIF(USE_cpPlugins)
+
+## eof - $RCSfile$
--- /dev/null
+SET(_pfx "")
+SET(_all_instances)
+
+## ===========================
+## == Compile each instance ==
+## ===========================
+FILE(GLOB _instances "${CMAKE_CURRENT_SOURCE_DIR}/*.i")
+
+FOREACH(_instance ${_instances})
+ CompileInstances(
+ _lib_name
+ ${_instance} ${cpPlugins_NUMBER_OF_FILES}
+ "${_pfx}" "${prj_VERSION}" "${prj_SHORT_VERSION}"
+ )
+ LIST(APPEND _all_instances ${_lib_name})
+ENDFOREACH(_instance)
+SET(
+ fpa_Instances ${_all_instances}
+ CACHE INTERNAL "All valid instances." FORCE
+ )
+
+## ====================
+## == Link libraries ==
+## ====================
+
+TARGET_LINK_LIBRARIES(
+ ${_pfx}fpa_MinimumSpanningTree
+ ${ITK_LIBRARIES} ${VTK_LIBRARIES} ${cpPlugins_Instances}
+ )
+
+## eof - $RCSfile$
--- /dev/null
+
+i itkIndex.h
+t fpa/Base/MinimumSpanningTree
+t itkSimpleDataObjectDecorator
+
+c fpa::Base::MinimumSpanningTree< itk::Index< #process_dims# >, #reals#, itk::Functor::IndexLexicographicCompare< #process_dims# > >
+
+** eof - $RCSfile$
--- /dev/null
+#ifndef __FPA__BASE__ALGORITHM__H__
+#define __FPA__BASE__ALGORITHM__H__
+
+#include <functional>
+#include <set>
+#include <utility>
+#include <vector>
+#include <fpa/Config.h>
+#include <fpa/Base/Events.h>
+
+namespace fpa
+{
+ namespace Base
+ {
+ /**
+ * Base front propagation algorithm. From a series of start seeds with
+ * costs, a priority queue is filled and emptied updating costs. Each
+ * vertex could be marked as "visited", "in the front", "not yet there"
+ * or "freezed".
+ *
+ * @param _TVertex Vertex type.
+ * @param _TScalar Scalar (real computations) type.
+ * @param _TFilter Base class for this algorithm. It should be any
+ * itk-based filter (itk::ProcessObject).
+ * @param _TVertexCompare Vertex lexicographical compare.
+ *
+ */
+ template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare = std::less< _TVertex > >
+ class Algorithm
+ : public _TFilter
+ {
+ public:
+ typedef Algorithm Self;
+ typedef _TFilter Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ // Template arguments
+ typedef _TVertex TVertex;
+ typedef _TScalar TScalar;
+ typedef _TFilter TFilter;
+ typedef _TVertexCompare TVertexCompare;
+
+ // Some useful types
+ typedef unsigned long TFrontId;
+
+ // Minigraph to represent collisions
+ typedef std::pair< TVertex, bool > TCollision;
+ typedef std::vector< TCollision > TCollisionsRow;
+ typedef std::vector< TCollisionsRow > TCollisions;
+
+ enum TNodeLabel
+ {
+ FarLabel = 0,
+ FrontLabel,
+ AliveLabel
+ };
+
+ /**
+ * WARNING: std::set< T > objects are immutable
+ */
+ struct TNode
+ {
+ static const TVertexCompare VertexCompare;
+ TVertex Vertex;
+ mutable TVertex Parent;
+ mutable TScalar Result;
+ mutable TFrontId FrontId;
+ mutable TNodeLabel Label;
+ bool operator<( const TNode& other ) const
+ { return( VertexCompare( this->Vertex, other.Vertex ) ); }
+ };
+ typedef std::set< TNode > TNodes;
+ typedef std::vector< TVertex > TVertices;
+
+ public:
+ itkTypeMacro( Algorithm, _TFilter );
+
+ itkBooleanMacro( StopAtOneFront );
+ itkGetConstMacro( StopAtOneFront, bool );
+ itkSetMacro( StopAtOneFront, bool );
+
+ itkBooleanMacro( ThrowEvents );
+ itkGetConstMacro( ThrowEvents, bool );
+ itkSetMacro( ThrowEvents, bool );
+
+ fpa_Base_NewEvent( TStartEvent );
+ fpa_Base_NewEvent( TStartLoopEvent );
+ fpa_Base_NewEvent( TStartBacktrackingEvent );
+ fpa_Base_NewEvent( TEndEvent );
+ fpa_Base_NewEvent( TEndLoopEvent );
+ fpa_Base_NewEvent( TEndBacktrackingEvent );
+ fpa_Base_NewEventWithVertex( TCollisionEvent, TVertex );
+ fpa_Base_NewEventWithVertex( TAliveEvent, TVertex );
+ fpa_Base_NewEventWithVertex( TFrontEvent, TVertex );
+ fpa_Base_NewEventWithVertex( TFreezeEvent, TVertex );
+ fpa_Base_NewEventWithVertex( TBacktrackingEvent, TVertex );
+
+ public:
+ virtual void InvokeEvent( const itk::EventObject& e );
+ virtual void InvokeEvent( const itk::EventObject& e ) const;
+
+ unsigned long GetNumberOfSeeds( ) const;
+ void AddSeed( const TVertex& s, const TScalar& v = TScalar( 0 ) );
+ void AddSeed( const TNode& n );
+ void RemoveSeed( const TVertex& s );
+ void RemoveAllSeeds( );
+
+ protected:
+ // Methods to extend itk-based architecture
+ Algorithm( );
+ virtual ~Algorithm( );
+ virtual void GenerateData( ) fpa_OVERRIDE;
+
+ // Front propagation generic methods
+ virtual void _Loop( );
+
+ // Front propagation methods to be overloaded
+ virtual void _BeforeGenerateData( );
+ virtual void _AfterGenerateData( );
+ virtual void _BeforeLoop( );
+ virtual void _AfterLoop( );
+
+ virtual void _InitMarks( ) = 0;
+ virtual void _InitResults( ) = 0;
+ virtual void _DeallocateAuxiliary( ) = 0;
+
+ virtual TFrontId _GetMark( const TVertex& v ) = 0;
+ virtual TFrontId _GetMark( const TNode& v );
+
+ virtual void _Visit( const TNode& n ) = 0;
+ virtual bool _NeedToStop( );
+
+ virtual TVertices _GetNeighborhood( const TVertex& v ) const = 0;
+ virtual TVertices _GetNeighborhood( const TNode& n ) const;
+
+ virtual bool _Result( TNode& node, const TNode& parent ) = 0;
+
+ virtual void _QueueClear( ) = 0;
+ virtual void _QueuePush( const TNode& node ) = 0;
+ virtual TNode _QueuePop( ) = 0;
+ virtual bool _IsQueueEmpty( ) const = 0;
+
+ virtual bool _UpdateCollisions( const TVertex& a, const TVertex& b );
+
+ private:
+ // Purposely not implemented
+ Algorithm( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+ TNodes m_Seeds;
+ TCollisions m_Collisions;
+ bool m_StopAtOneFront;
+ bool m_ThrowEvents;
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Base/Algorithm.hxx>
+#endif
+
+#endif // __FPA__BASE__ALGORITHM__H__
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __FPA__BASE__ALGORITHM__HXX__
+#define __FPA__BASE__ALGORITHM__HXX__
+
+#include <queue>
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
+const _TVertexCompare fpa::Base::
+Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
+TNode::VertexCompare = _TVertexCompare( );
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
+void fpa::Base::
+Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
+InvokeEvent( const itk::EventObject& e )
+{
+ if( this->m_ThrowEvents )
+ this->Superclass::InvokeEvent( e );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
+void fpa::Base::
+Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
+InvokeEvent( const itk::EventObject& e ) const
+{
+ if( this->m_ThrowEvents )
+ this->Superclass::InvokeEvent( e );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
+unsigned long fpa::Base::
+Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
+GetNumberOfSeeds( ) const
+{
+ return( this->m_Seeds.size( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
+void fpa::Base::
+Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
+AddSeed( const TVertex& s, const TScalar& v )
+{
+ TNode n;
+ n.Vertex = s;
+ n.Parent = s;
+ n.Result = v;
+ n.Label = Self::FrontLabel;
+ this->AddSeed( n );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
+void fpa::Base::
+Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
+AddSeed( const TNode& n )
+{
+ this->m_Seeds.insert( n );
+ this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
+void fpa::Base::
+Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
+RemoveSeed( const TVertex& s )
+{
+ TNode n;
+ n.Vertex = s;
+ typename TNodes::iterator i = this->m_Seeds.find( n );
+ if( i != this->m_Seeds.end( ) )
+ {
+ this->m_Seeds.erase( i );
+ this->Modified( );
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
+void fpa::Base::
+Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
+RemoveAllSeeds( )
+{
+ this->m_Seeds.clear( );
+ this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
+fpa::Base::
+Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
+Algorithm( )
+ : Superclass( ),
+ m_StopAtOneFront( false ),
+ m_ThrowEvents( false )
+{
+}
+
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
+fpa::Base::
+Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
+~Algorithm( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
+void fpa::Base::
+Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
+GenerateData( )
+{
+ this->InvokeEvent( TStartEvent( ) );
+ this->_BeforeGenerateData( );
+
+ unsigned int N = this->m_Seeds.size( );
+ if( N > 0 )
+ {
+ // Enumerate seeds
+ typename TNodes::iterator nIt = this->m_Seeds.begin( );
+ for( unsigned long i = 1; nIt != this->m_Seeds.end( ); ++nIt, ++i )
+ nIt->FrontId = i;
+
+ // Prepare collisions
+ TCollision coll( TVertex( ), false );
+ TCollisionsRow row( N, coll );
+ this->m_Collisions.clear( );
+ this->m_Collisions.resize( N, row );
+
+ // Put seeds on queue
+ this->_QueueClear( );
+ for( nIt = this->m_Seeds.begin( ); nIt != this->m_Seeds.end( ); ++nIt )
+ this->_QueuePush( *nIt );
+
+ // Init marks and results
+ this->_InitMarks( );
+ this->_InitResults( );
+
+ // Main loop
+ this->_BeforeLoop( );
+ this->_Loop( );
+ this->_AfterLoop( );
+
+ // Deallocate any memory
+ this->_DeallocateAuxiliary( );
+
+ } // fi
+
+ this->_AfterGenerateData( );
+ this->InvokeEvent( TEndEvent( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
+void fpa::Base::
+Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
+_Loop( )
+{
+ this->InvokeEvent( TStartLoopEvent( ) );
+ this->_BeforeLoop( );
+
+ while( !( this->_IsQueueEmpty( ) ) )
+ {
+ // Extract next candidate
+ TNode node = this->_QueuePop( );
+
+ // Check if it has been visited
+ if( this->_GetMark( node ) > 0 )
+ continue;
+
+ // Mark it as visited
+ this->_Visit( node );
+ this->InvokeEvent( TAliveEvent( node.Vertex, node.FrontId ) );
+
+ // Check if there is an external stop condition
+ if( this->_NeedToStop( ) )
+ {
+ this->_QueueClear( );
+ continue;
+
+ } // fi
+
+ // Get neighborhood
+ TVertices neighborhood = this->_GetNeighborhood( node );
+
+ // Update neighborhood
+ auto neighIt = neighborhood.begin( );
+ bool stop = false;
+ for( ; neighIt != neighborhood.end( ); ++neighIt )
+ {
+ if( this->_GetMark( *neighIt ) == 0 )
+ {
+ TNode neigh;
+ neigh.Vertex = *neighIt;
+ neigh.Parent = node.Vertex;
+ neigh.FrontId = node.FrontId;
+ if( this->_Result( neigh, node ) )
+ {
+ this->_QueuePush( neigh );
+ this->InvokeEvent( TFrontEvent( *neighIt, node.FrontId ) );
+
+ } // fi
+ }
+ else
+ stop |= this->_UpdateCollisions( node.Vertex, *neighIt );
+
+ } // rof
+
+ if( stop )
+ this->_QueueClear( );
+
+ } // elihw
+
+ this->_AfterLoop( );
+ this->InvokeEvent( TEndLoopEvent( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
+void fpa::Base::
+Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
+_BeforeGenerateData( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
+void fpa::Base::
+Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
+_AfterGenerateData( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
+void fpa::Base::
+Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
+_BeforeLoop( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
+void fpa::Base::
+Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
+_AfterLoop( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
+typename fpa::Base::
+Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
+TFrontId fpa::Base::
+Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
+_GetMark( const TNode& v )
+{
+ return( this->_GetMark( v.Vertex ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
+bool fpa::Base::
+Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
+_NeedToStop( )
+{
+ return( false );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
+typename fpa::Base::
+Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
+TVertices fpa::Base::
+Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
+_GetNeighborhood( const TNode& n ) const
+{
+ return( this->_GetNeighborhood( n.Vertex ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TScalar, class _TFilter, class _TVertexCompare >
+bool fpa::Base::
+Algorithm< _TVertex, _TScalar, _TFilter, _TVertexCompare >::
+_UpdateCollisions( const TVertex& a, const TVertex& b )
+{
+ auto ma = this->_GetMark( a );
+ auto mb = this->_GetMark( b );
+ if( ma == mb || ma == 0 || mb == 0 )
+ return( false );
+ ma--;
+ mb--;
+
+ // Mark collision, if it is new
+ bool ret = false;
+ bool exists = this->m_Collisions[ ma ][ mb ].second;
+ exists &= this->m_Collisions[ mb ][ ma ].second;
+ if( !exists )
+ {
+ this->m_Collisions[ ma ][ mb ].first = a;
+ this->m_Collisions[ ma ][ mb ].second = true;
+ this->m_Collisions[ mb ][ ma ].first = b;
+ this->m_Collisions[ mb ][ ma ].second = true;
+
+ // Stop if one front is desired
+ if( this->m_StopAtOneFront )
+ {
+ // Perform a depth-first iteration on front graph
+ unsigned long N = this->GetNumberOfSeeds( );
+ unsigned long count = 0;
+ std::vector< bool > m( N, false );
+ std::queue< unsigned long > q;
+ q.push( 0 );
+ while( !q.empty( ) )
+ {
+ unsigned long f = q.front( );
+ q.pop( );
+
+ if( m[ f ] )
+ continue;
+ m[ f ] = true;
+ count++;
+
+ for( unsigned int n = 0; n < N; ++n )
+ if( this->m_Collisions[ f ][ n ].second && !m[ n ] )
+ q.push( n );
+
+ } // elihw
+ ret = ( count == N );
+ this->InvokeEvent( TCollisionEvent( a, ma + 1 ) );
+ this->InvokeEvent( TCollisionEvent( b, mb + 1 ) );
+
+ } // fi
+
+ } // fi
+ return( ret );
+}
+
+#endif // __FPA__BASE__ALGORITHM__HXX__
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __FPA__BASE__DIJKSTRA__H__
+#define __FPA__BASE__DIJKSTRA__H__
+
+#include <vector>
+#include <itkFunctionBase.h>
+#include <fpa/Base/Algorithm.h>
+#include <fpa/Base/MinimumSpanningTree.h>
+
+namespace fpa
+{
+ namespace Base
+ {
+ /**
+ */
+ template< class _TSuperclass >
+ class Dijkstra
+ : public _TSuperclass
+ {
+ public:
+ typedef Dijkstra Self;
+ typedef _TSuperclass Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ // Template arguments
+ typedef typename Superclass::TVertex TVertex;
+ typedef typename Superclass::TScalar TScalar;
+ typedef typename Superclass::TFilter TFilter;
+ typedef typename Superclass::TVertexCompare TVertexCompare;
+ typedef typename Superclass::TFrontId TFrontId;
+ typedef typename Superclass::TCollision TCollision;
+ typedef typename Superclass::TCollisionsRow TCollisionsRow;
+ typedef typename Superclass::TCollisions TCollisions;
+ typedef typename Superclass::TNodeLabel TNodeLabel;
+ typedef typename Superclass::TNode TNode;
+ typedef typename Superclass::TNodes TNodes;
+ typedef typename Superclass::TVertices TVertices;
+
+ typedef itk::FunctionBase< TScalar, TScalar > TCostConversionFunction;
+
+ typedef
+ fpa::Base::MinimumSpanningTree< TVertex, TScalar, TVertexCompare >
+ TMinimumSpanningTree;
+
+ struct TDijkstraCmp
+ {
+ bool operator()( const TNode& a, const TNode& b )
+ { return( b.Result < a.Result ); }
+ };
+ static const TDijkstraCmp DijkstraCmp;
+
+ public:
+ itkTypeMacro( Dijkstra, Algorithm );
+
+ itkGetObjectMacro( CostConversionFunction, TCostConversionFunction );
+ itkSetObjectMacro( CostConversionFunction, TCostConversionFunction );
+
+ public:
+ TMinimumSpanningTree* GetMinimumSpanningTree( );
+ const TMinimumSpanningTree* GetMinimumSpanningTree( ) const;
+ void GraftMinimumSpanningTree( itk::DataObject* obj );
+
+ protected:
+ // Methods to extend itk-based architecture
+ Dijkstra( );
+ virtual ~Dijkstra( );
+
+ // Front propagation methods to be overloaded
+ virtual void _AfterGenerateData( ) fpa_OVERRIDE;
+ virtual void _Visit( const TNode& n ) fpa_OVERRIDE;
+ virtual bool _Result( TNode& node, const TNode& parent ) fpa_OVERRIDE;
+ virtual void _QueueClear( ) fpa_OVERRIDE;
+ virtual void _QueuePush( const TNode& node ) fpa_OVERRIDE;
+ virtual TNode _QueuePop( ) fpa_OVERRIDE;
+ virtual bool _IsQueueEmpty( ) const fpa_OVERRIDE;
+
+ // Dijkstra methods to be overloaded
+ virtual TScalar _Cost( const TVertex& a, const TVertex& b ) const = 0;
+
+ private:
+ // Purposely not implemented
+ Dijkstra( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+ unsigned int m_MSTIdx;
+ std::vector< TNode > m_Queue;
+ typename TCostConversionFunction::Pointer m_CostConversionFunction;
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Base/Dijkstra.hxx>
+#endif
+
+#endif // __FPA__BASE__DIJKSTRA__H__
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __FPA__BASE__DIJKSTRA__HXX__
+#define __FPA__BASE__DIJKSTRA__HXX__
+
+#include <algorithm>
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass >
+const typename fpa::Base::Dijkstra< _TSuperclass >::TDijkstraCmp
+fpa::Base::Dijkstra< _TSuperclass >::DijkstraCmp =
+fpa::Base::Dijkstra< _TSuperclass >::TDijkstraCmp( );
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass >
+typename fpa::Base::Dijkstra< _TSuperclass >::
+TMinimumSpanningTree* fpa::Base::Dijkstra< _TSuperclass >::
+GetMinimumSpanningTree( )
+{
+ return(
+ dynamic_cast< TMinimumSpanningTree* >(
+ this->itk::ProcessObject::GetOutput( this->m_MSTIdx )
+ )
+ );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass >
+const typename fpa::Base::Dijkstra< _TSuperclass >::
+TMinimumSpanningTree* fpa::Base::Dijkstra< _TSuperclass >::
+GetMinimumSpanningTree( ) const
+{
+ return(
+ dynamic_cast< const TMinimumSpanningTree* >(
+ this->itk::ProcessObject::GetOutput( this->m_MSTIdx )
+ )
+ );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass >
+void fpa::Base::Dijkstra< _TSuperclass >::
+GraftMinimumSpanningTree( itk::DataObject* obj )
+{
+ TMinimumSpanningTree* mst = dynamic_cast< TMinimumSpanningTree* >( obj );
+ if( mst != NULL )
+ this->GraftNthOutput( this->m_MSTIdx, mst );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass >
+fpa::Base::Dijkstra< _TSuperclass >::
+Dijkstra( )
+ : Superclass( ),
+ m_CostConversionFunction( NULL )
+{
+ this->m_MSTIdx = this->GetNumberOfRequiredOutputs( );
+ this->SetNumberOfRequiredOutputs( this->m_MSTIdx + 1 );
+ typename TMinimumSpanningTree::Pointer mst = TMinimumSpanningTree::New( );
+ this->itk::ProcessObject::SetNthOutput( this->m_MSTIdx, mst );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass >
+fpa::Base::Dijkstra< _TSuperclass >::
+~Dijkstra( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass >
+void fpa::Base::Dijkstra< _TSuperclass >::
+_AfterGenerateData( )
+{
+ this->Superclass::_AfterGenerateData( );
+ this->GetMinimumSpanningTree( )->SetCollisions( this->m_Collisions );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass >
+void fpa::Base::Dijkstra< _TSuperclass >::
+_Visit( const TNode& n )
+{
+ this->Superclass::_Visit( n );
+ this->GetMinimumSpanningTree( )->SetNode(
+ n.Vertex, n.Parent, n.FrontId, n.Result
+ );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass >
+bool fpa::Base::Dijkstra< _TSuperclass >::
+_Result( TNode& node, const TNode& parent )
+{
+ node.Result = this->_Cost( node.Vertex, parent.Vertex );
+ if( node.Result >= TScalar( 0 ) )
+ {
+ if( this->m_CostConversionFunction.IsNotNull( ) )
+ node.Result = this->m_CostConversionFunction->Evaluate( node.Result );
+ node.Result += parent.Result;
+ return( true );
+ }
+ else
+ return( false );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass >
+void fpa::Base::Dijkstra< _TSuperclass >::
+_QueueClear( )
+{
+ this->m_Queue.clear( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass >
+void fpa::Base::Dijkstra< _TSuperclass >::
+_QueuePush( const TNode& node )
+{
+ this->m_Queue.push_back( node );
+ std::push_heap( this->m_Queue.begin( ), this->m_Queue.end( ), DijkstraCmp );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass >
+typename fpa::Base::Dijkstra< _TSuperclass >::
+TNode fpa::Base::Dijkstra< _TSuperclass >::
+_QueuePop( )
+{
+ std::pop_heap( this->m_Queue.begin( ), this->m_Queue.end( ), DijkstraCmp );
+ TNode n = this->m_Queue.back( );
+ this->m_Queue.pop_back( );
+ return( n );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass >
+bool fpa::Base::Dijkstra< _TSuperclass >::
+_IsQueueEmpty( ) const
+{
+ return( this->m_Queue.size( ) == 0 );
+}
+
+#endif // __FPA__BASE__DIJKSTRA__HXX__
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __FPA__BASE__EVENTS__H__
+#define __FPA__BASE__EVENTS__H__
+
+#include <vector>
+#include <itkProcessObject.h>
+
+// -------------------------------------------------------------------------
+#define fpa_Base_NewEvent( name ) \
+ class name \
+ : public BaseEvent \
+ { \
+ public: \
+ name( ) : BaseEvent( ) { } \
+ virtual ~name( ) { } \
+ const char* GetEventName( ) const \
+ { return( "fpa::Base::##name" ); } \
+ bool CheckEvent( const itk::EventObject* e ) const \
+ { return( dynamic_cast< const name* >( e ) != NULL ); } \
+ itk::EventObject* MakeObject( ) const \
+ { return( new name( ) ); } \
+ };
+
+// -------------------------------------------------------------------------
+#define fpa_Base_NewEventWithVertex( name, type ) \
+ class name \
+ : public BaseEventWithVertex< type > \
+ { \
+ public: \
+ name( ) : BaseEventWithVertex< type >( ) { } \
+ name( const type& v, long fid ) \
+ : BaseEventWithVertex< type >( v, fid ) { } \
+ virtual ~name( ) { } \
+ const char* GetEventName( ) const \
+ { return( "fpa::Base::##name" ); } \
+ bool CheckEvent( const itk::EventObject* e ) const \
+ { return( dynamic_cast< const name* >( e ) != NULL ); } \
+ itk::EventObject* MakeObject( ) const \
+ { return( new name( ) ); } \
+ };
+
+namespace fpa
+{
+ namespace Base
+ {
+ /**
+ */
+ class BaseEvent
+ : public itk::AnyEvent
+ {
+ public:
+ BaseEvent( )
+ : itk::AnyEvent( )
+ { }
+ virtual ~BaseEvent( )
+ { }
+ const char* GetEventName( ) const
+ { return( "fpa::Base::BaseEvent" ); }
+ bool CheckEvent( const itk::EventObject* e ) const
+ { return( dynamic_cast< const BaseEvent* >( e ) != NULL ); }
+ itk::EventObject* MakeObject( ) const
+ { return( new BaseEvent( ) ); }
+ };
+
+ /**
+ */
+ template< class V >
+ class BaseEventWithVertex
+ : public BaseEvent
+ {
+ public:
+ BaseEventWithVertex( )
+ : BaseEvent( )
+ { }
+ BaseEventWithVertex( const V& v, long fid )
+ : BaseEvent( ),
+ Vertex( v ),
+ FrontId( fid )
+ { }
+ virtual ~BaseEventWithVertex( )
+ { }
+ const char* GetEventName( ) const
+ { return( "fpa::Base::BaseEventWithVertex" ); }
+ bool CheckEvent( const itk::EventObject* e ) const
+ {
+ return(
+ dynamic_cast< const BaseEventWithVertex< V >* >( e ) != NULL
+ );
+ }
+ itk::EventObject* MakeObject( ) const
+ { return( new BaseEventWithVertex< V >( ) ); }
+
+ public:
+ V Vertex;
+ long FrontId;
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#endif // __FPA__BASE__EVENTS__H__
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __FPA__BASE__FUNCTORS__GAUSSIANCOST__H__
+#define __FPA__BASE__FUNCTORS__GAUSSIANCOST__H__
+
+#include <fpa/Config.h>
+#include <itkFunctionBase.h>
+#include <cpExtensions/Algorithms/IterativeGaussianModelEstimator.h>
+
+namespace fpa
+{
+ namespace Base
+ {
+ namespace Functors
+ {
+ /**
+ */
+ template< class _TResult >
+ class GaussianCost
+ : public itk::FunctionBase< _TResult, _TResult >
+ {
+ public:
+ typedef GaussianCost Self;
+ typedef itk::FunctionBase< _TResult, _TResult > Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ // Template arguments
+ typedef _TResult TResult;
+ typedef
+ cpExtensions::Algorithms::IterativeGaussianModelEstimator< TResult, 1 >
+ TModel;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro( GaussianCost, Algorithm );
+
+ itkGetConstMacro( SupportSize, unsigned int );
+ itkGetConstMacro( MinimumCost, _TResult );
+ itkGetObjectMacro( Model, TModel );
+ itkGetConstObjectMacro( Model, TModel );
+ itkSetMacro( SupportSize, unsigned int );
+ itkSetMacro( MinimumCost, _TResult );
+
+ public:
+ virtual _TResult Evaluate( const _TResult& x ) const fpa_OVERRIDE;
+
+ protected:
+ // Methods to extend itk-based architecture
+ GaussianCost( );
+ virtual ~GaussianCost( );
+
+ private:
+ // Purposely not implemented
+ GaussianCost( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+ unsigned int m_SupportSize;
+ _TResult m_MinimumCost;
+ typename TModel::Pointer m_Model;
+ };
+
+ } // ecapseman
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Base/Functors/GaussianCost.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __FPA__BASE__FUNCTORS__GAUSSIANCOST__H__
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __FPA__BASE__FUNCTORS__GAUSSIANCOST__HXX__
+#define __FPA__BASE__FUNCTORS__GAUSSIANCOST__HXX__
+
+// -------------------------------------------------------------------------
+template< class _TResult >
+_TResult fpa::Base::Functors::GaussianCost< _TResult >::
+Evaluate( const _TResult& x ) const
+{
+ _TResult r = _TResult( 0 );
+ if( this->m_Model->GetNumberOfSamples( ) > this->m_SupportSize )
+ {
+ r = this->m_Model->SquaredMahalanobis( x );
+ if( r <= _TResult( 1 ) )
+ this->m_Model->AddSample( x );
+ }
+ else
+ {
+ this->m_Model->AddSample( x );
+ if( this->m_Model->GetNumberOfSamples( ) > 2 )
+ r = this->m_Model->SquaredMahalanobis( x );
+
+ } // fi
+ if( r < this->m_MinimumCost )
+ return( this->m_MinimumCost );
+ else
+ return( r );
+}
+
+// -------------------------------------------------------------------------
+template< class _TResult >
+fpa::Base::Functors::GaussianCost< _TResult >::
+GaussianCost( )
+ : Superclass( ),
+ m_SupportSize( 30 ),
+ m_MinimumCost( _TResult( 1e-10 ) )
+{
+ this->m_Model = TModel::New( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TResult >
+fpa::Base::Functors::GaussianCost< _TResult >::
+~GaussianCost( )
+{
+}
+
+#endif // __FPA__BASE__FUNCTORS__GAUSSIANCOST__HXX__
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __FPA__BASE__FUNCTORS__INVERTCOST__H__
+#define __FPA__BASE__FUNCTORS__INVERTCOST__H__
+
+#include <fpa/Config.h>
+#include <itkFunctionBase.h>
+
+namespace fpa
+{
+ namespace Base
+ {
+ namespace Functors
+ {
+ /**
+ */
+ template< class _TResult >
+ class InvertCost
+ : public itk::FunctionBase< _TResult, _TResult >
+ {
+ public:
+ typedef InvertCost Self;
+ typedef itk::FunctionBase< _TResult, _TResult > Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ // Template arguments
+ typedef _TResult TResult;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro( InvertCost, Algorithm );
+
+ public:
+ virtual _TResult Evaluate( const _TResult& x ) const fpa_OVERRIDE;
+
+ protected:
+ // Methods to extend itk-based architecture
+ InvertCost( );
+ virtual ~InvertCost( );
+
+ private:
+ // Purposely not implemented
+ InvertCost( const Self& other );
+ Self& operator=( const Self& other );
+ };
+
+ } // ecapseman
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Base/Functors/InvertCost.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __FPA__BASE__FUNCTORS__INVERTCOST__H__
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __FPA__BASE__FUNCTORS__INVERTCOST__HXX__
+#define __FPA__BASE__FUNCTORS__INVERTCOST__HXX__
+
+// -------------------------------------------------------------------------
+template< class _TResult >
+_TResult fpa::Base::Functors::InvertCost< _TResult >::
+Evaluate( const _TResult& x ) const
+{
+ return( _TResult( 1 ) / ( _TResult( 1 ) + x ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TResult >
+fpa::Base::Functors::InvertCost< _TResult >::
+InvertCost( )
+ : Superclass( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TResult >
+fpa::Base::Functors::InvertCost< _TResult >::
+~InvertCost( )
+{
+}
+
+#endif // __FPA__BASE__FUNCTORS__INVERTCOST__HXX__
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __FPA__BASE__MINIMUMSPANNINGTREE__H__
+#define __FPA__BASE__MINIMUMSPANNINGTREE__H__
+
+#include <functional>
+#include <map>
+#include <utility>
+#include <vector>
+#include <itkSimpleDataObjectDecorator.h>
+
+namespace fpa
+{
+ namespace Base
+ {
+ /**
+ */
+ template< class _TVertex, class _TScalar, class _TVertexCompare = std::less< _TVertex > >
+ class MinimumSpanningTree
+ : public itk::SimpleDataObjectDecorator< std::map< _TVertex, std::pair< _TVertex, std::pair< _TScalar, long > >, _TVertexCompare > >
+ {
+ public:
+ typedef std::pair< _TScalar, long > TData;
+ typedef std::pair< _TVertex, TData > TParent;
+ typedef std::map< _TVertex, TParent, _TVertexCompare > TContainer;
+ typedef itk::SimpleDataObjectDecorator< TContainer > Superclass;
+ typedef MinimumSpanningTree Self;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ typedef _TVertex TVertex;
+ typedef _TScalar TScalar;
+ typedef _TVertexCompare TVertexCompare;
+
+ typedef std::vector< TVertex > TVertices;
+ typedef std::pair< TVertex, bool > TCollision;
+ typedef std::vector< TCollision > TCollisionsRow;
+ typedef std::vector< TCollisionsRow > TCollisions;
+
+ typedef std::multimap< double, _TVertex > TNodeQueue;
+
+ protected:
+ typedef std::vector< unsigned long > _TRow;
+ typedef std::vector< _TRow > _TMatrix;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro( MinimumSpanningTree, itk::SimpleDataObjectDecorator );
+
+ itkBooleanMacro( FillNodeQueue );
+
+ itkGetConstReferenceMacro( Collisions, TCollisions );
+ itkGetConstReferenceMacro( NodeQueue, TNodeQueue );
+ itkGetConstMacro( FillNodeQueue, bool );
+
+ itkSetMacro( FillNodeQueue, bool );
+
+ public:
+ void SetCollisions( const TCollisions& collisions );
+ TVertices GetPath( const _TVertex& a ) const;
+ TVertices GetPath( const _TVertex& a, const _TVertex& b ) const;
+
+ virtual void SetNode(
+ const _TVertex& vertex,
+ const _TVertex& parent,
+ const long& fid = -1,
+ const _TScalar& result = _TScalar( 0 )
+ );
+ virtual void Clear( );
+
+ protected:
+ MinimumSpanningTree( );
+ virtual ~MinimumSpanningTree( );
+
+ virtual bool _HasVertex( const _TVertex& a ) const;
+ virtual long _FrontId( const _TVertex& a ) const;
+ virtual void _Path( TVertices& path, const _TVertex& a ) const;
+
+ private:
+ // Purposely not implemented
+ MinimumSpanningTree( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+ TCollisions m_Collisions;
+ _TMatrix m_FrontPaths;
+ TNodeQueue m_NodeQueue;
+ bool m_FillNodeQueue;
+
+ static const unsigned long INF_VALUE;
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Base/MinimumSpanningTree.hxx>
+#endif
+
+#endif // __FPA__BASE__MINIMUMSPANNINGTREE__H__
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __FPA__BASE__MINIMUMSPANNINGTREE__HXX__
+#define __FPA__BASE__MINIMUMSPANNINGTREE__HXX__
+
+#include <limits>
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TScalar, class _TVertexCompare >
+const unsigned long fpa::Base::
+MinimumSpanningTree< _TVertex, _TScalar, _TVertexCompare >::INF_VALUE =
+ std::numeric_limits< unsigned long >::max( );
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TScalar, class _TVertexCompare >
+void fpa::Base::MinimumSpanningTree< _TVertex, _TScalar, _TVertexCompare >::
+SetCollisions( const TCollisions& collisions )
+{
+ // Prepare a front graph
+ this->m_Collisions = collisions;
+ unsigned long nSeeds = this->m_Collisions.size( );
+ _TMatrix dist( nSeeds, _TRow( nSeeds, Self::INF_VALUE ) );
+ this->m_FrontPaths = dist;
+ for( unsigned long i = 0; i < nSeeds; ++i )
+ {
+ for( unsigned long j = 0; j < nSeeds; ++j )
+ {
+ if( this->m_Collisions[ i ][ j ].second )
+ {
+ dist[ i ][ j ] = 1;
+ dist[ j ][ i ] = 1;
+ this->m_FrontPaths[ i ][ j ] = j;
+ this->m_FrontPaths[ j ][ i ] = i;
+
+ } // fi
+
+ } // rof
+ dist[ i ][ i ] = 0;
+ this->m_FrontPaths[ i ][ i ] = i;
+
+ } // rof
+
+ // Use Floyd-Warshall to compute all possible paths between fronts
+ for( unsigned long k = 0; k < nSeeds; ++k )
+ {
+ for( unsigned long i = 0; i < nSeeds; ++i )
+ {
+ for( unsigned long j = 0; j < nSeeds; ++j )
+ {
+ // WARNING: you don't want a numeric overflow!!!
+ unsigned long dik = dist[ i ][ k ];
+ unsigned long dkj = dist[ k ][ j ];
+ unsigned long sum = Self::INF_VALUE;
+ if( dik < Self::INF_VALUE && dkj < Self::INF_VALUE )
+ sum = dik + dkj;
+
+ // Ok, continue Floyd-Warshall
+ if( sum < dist[ i ][ j ] )
+ {
+ dist[ i ][ j ] = sum;
+ this->m_FrontPaths[ i ][ j ] = this->m_FrontPaths[ i ][ k ];
+
+ } // fi
+
+ } // rof
+
+ } // rof
+
+ } // rof
+ this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TScalar, class _TVertexCompare >
+typename
+fpa::Base::MinimumSpanningTree< _TVertex, _TScalar, _TVertexCompare >::
+TVertices
+fpa::Base::MinimumSpanningTree< _TVertex, _TScalar, _TVertexCompare >::
+GetPath( const _TVertex& a ) const
+{
+ TVertices path;
+ if( this->_HasVertex( a ) )
+ this->_Path( path, a );
+ return( path );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TScalar, class _TVertexCompare >
+typename
+fpa::Base::MinimumSpanningTree< _TVertex, _TScalar, _TVertexCompare >::
+TVertices
+fpa::Base::MinimumSpanningTree< _TVertex, _TScalar, _TVertexCompare >::
+GetPath( const _TVertex& a, const _TVertex& b ) const
+{
+ TVertices path;
+
+ // Check existence
+ if( !this->_HasVertex( a ) || !this->_HasVertex( b ) )
+ return( path );
+
+ // Get front ids
+ long fa = this->_FrontId( a ) - 1;
+ long fb = this->_FrontId( b ) - 1;
+
+ if( fa == fb )
+ {
+ // Get paths
+ TVertices ap, bp;
+ this->_Path( ap, a );
+ this->_Path( bp, b );
+
+ // Ignore common part: find common ancestor
+ auto raIt = ap.rbegin( );
+ auto rbIt = bp.rbegin( );
+ while( *raIt == *rbIt && raIt != ap.rend( ) && rbIt != bp.rend( ) )
+ {
+ ++raIt;
+ ++rbIt;
+
+ } // elihw
+ if( raIt != ap.rbegin( ) ) --raIt;
+ if( rbIt != bp.rbegin( ) ) --rbIt;
+
+ // Add part from a
+ for( auto iaIt = ap.begin( ); iaIt != ap.end( ) && *iaIt != *raIt; ++iaIt )
+ path.push_back( *iaIt );
+
+ // Add part from b
+ for( ; rbIt != bp.rend( ); ++rbIt )
+ path.push_back( *rbIt );
+ }
+ else
+ {
+ // Use this->m_FrontPaths from Floyd-Warshall
+ if( this->m_FrontPaths[ fa ][ fb ] < Self::INF_VALUE )
+ {
+ // Compute front path
+ std::vector< long > fpath;
+ fpath.push_back( fa );
+ while( fa != fb )
+ {
+ fa = this->m_FrontPaths[ fa ][ fb ];
+ fpath.push_back( fa );
+
+ } // elihw
+
+ // Continue only if both fronts are connected
+ unsigned int N = fpath.size( );
+ if( N > 0 )
+ {
+ // First path: from start vertex to first collision
+ path = this->GetPath(
+ a, this->m_Collisions[ fpath[ 0 ] ][ fpath[ 1 ] ].first
+ );
+
+ // Intermediary paths
+ for( unsigned int i = 1; i < N - 1; ++i )
+ {
+ TVertices ipath =
+ this->GetPath(
+ this->m_Collisions[ fpath[ i ] ][ fpath[ i - 1 ] ].first,
+ this->m_Collisions[ fpath[ i ] ][ fpath[ i + 1 ] ].first
+ );
+ path.insert( path.end( ), ipath.begin( ), ipath.end( ) );
+
+ } // rof
+
+ // Final path: from last collision to end point
+ TVertices lpath =
+ this->GetPath(
+ this->m_Collisions[ fpath[ N - 1 ] ][ fpath[ N - 2 ] ].first, b
+ );
+ path.insert( path.end( ), lpath.begin( ), lpath.end( ) );
+
+ // Remove repeated vertices
+ auto p = path.begin( );
+ auto q = p;
+ q++;
+ while( q != path.end( ) )
+ {
+ if( *q == *p )
+ {
+ p = path.erase( p );
+ q = p;
+ }
+ else
+ ++p;
+ ++q;
+
+ } // elihw
+
+ } // fi
+
+ } // fi
+
+ } // fi
+ return( path );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TScalar, class _TVertexCompare >
+void fpa::Base::MinimumSpanningTree< _TVertex, _TScalar, _TVertexCompare >::
+SetNode(
+ const _TVertex& vertex, const _TVertex& parent,
+ const long& fid, const _TScalar& result
+ )
+{
+ this->Get( )[ vertex ] = TParent( parent, TData( result, fid ) );
+ this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TScalar, class _TVertexCompare >
+void fpa::Base::MinimumSpanningTree< _TVertex, _TScalar, _TVertexCompare >::
+Clear( )
+{
+ this->Get( ).clear( );
+ this->m_NodeQueue.clear( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TScalar, class _TVertexCompare >
+fpa::Base::MinimumSpanningTree< _TVertex, _TScalar, _TVertexCompare >::
+MinimumSpanningTree( )
+ : Superclass( ),
+ m_FillNodeQueue( false )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TScalar, class _TVertexCompare >
+fpa::Base::MinimumSpanningTree< _TVertex, _TScalar, _TVertexCompare >::
+~MinimumSpanningTree( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TScalar, class _TVertexCompare >
+bool fpa::Base::MinimumSpanningTree< _TVertex, _TScalar, _TVertexCompare >::
+_HasVertex( const _TVertex& a ) const
+{
+ return( this->Get( ).find( a ) != this->Get( ).end( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TScalar, class _TVertexCompare >
+long fpa::Base::MinimumSpanningTree< _TVertex, _TScalar, _TVertexCompare >::
+_FrontId( const _TVertex& a ) const
+{
+ static const long MAX_ID = std::numeric_limits< long >::max( );
+ auto i = this->Get( ).find( a );
+ if( i != this->Get( ).end( ) )
+ return( i->second.second.second );
+ else
+ return( MAX_ID );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TScalar, class _TVertexCompare >
+void fpa::Base::MinimumSpanningTree< _TVertex, _TScalar, _TVertexCompare >::
+_Path( TVertices& path, const _TVertex& a ) const
+{
+ auto& m = this->Get( );
+ auto it = m.find( a );
+ if( it != m.end( ) )
+ {
+ do
+ {
+ path.push_back( it->first );
+ it = m.find( it->second.first );
+
+ } while( it->first != it->second.first );
+ path.push_back( it->first );
+
+ } // fi
+}
+
+#endif // __FPA__BASE__MINIMUMSPANNINGTREE__HXX__
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __FPA__BASE__REGIONGROW__H__
+#define __FPA__BASE__REGIONGROW__H__
+
+#include <deque>
+#include <itkFunctionBase.h>
+#include <fpa/Base/Algorithm.h>
+
+namespace fpa
+{
+ namespace Base
+ {
+ /**
+ */
+ template< class _TSuperclass >
+ class RegionGrow
+ : public _TSuperclass
+ {
+ public:
+ typedef RegionGrow Self;
+ typedef _TSuperclass Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ // Template arguments
+ typedef typename Superclass::TVertex TVertex;
+ typedef typename Superclass::TScalar TScalar;
+ typedef typename Superclass::TFilter TFilter;
+ typedef typename Superclass::TVertexCompare TVertexCompare;
+ typedef typename Superclass::TFrontId TFrontId;
+ typedef typename Superclass::TCollision TCollision;
+ typedef typename Superclass::TCollisionsRow TCollisionsRow;
+ typedef typename Superclass::TCollisions TCollisions;
+ typedef typename Superclass::TNodeLabel TNodeLabel;
+ typedef typename Superclass::TNode TNode;
+ typedef typename Superclass::TNodes TNodes;
+ typedef typename Superclass::TVertices TVertices;
+
+ typedef itk::FunctionBase< TVertex, bool > TRegionGrowFunction;
+
+ public:
+ itkTypeMacro( RegionGrow, Algorithm );
+
+ itkGetObjectMacro( RegionGrowFunction, TRegionGrowFunction );
+ itkGetConstMacro( InsideValue, TScalar );
+ itkGetConstMacro( OutsideValue, TScalar );
+
+ itkSetObjectMacro( RegionGrowFunction, TRegionGrowFunction );
+ itkSetMacro( InsideValue, TScalar );
+ itkSetMacro( OutsideValue, TScalar );
+
+ protected:
+ // Methods to extend itk-based architecture
+ RegionGrow( );
+ virtual ~RegionGrow( );
+
+ // Front propagation methods to be overloaded
+ virtual bool _Result( TNode& node, const TNode& parent ) fpa_OVERRIDE;
+ virtual void _QueueClear( ) fpa_OVERRIDE;
+ virtual void _QueuePush( const TNode& node ) fpa_OVERRIDE;
+ virtual TNode _QueuePop( ) fpa_OVERRIDE;
+ virtual bool _IsQueueEmpty( ) const fpa_OVERRIDE;
+
+ private:
+ // Purposely not implemented
+ RegionGrow( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+ std::deque< TNode > m_Queue;
+ typename TRegionGrowFunction::Pointer m_RegionGrowFunction;
+ TScalar m_InsideValue;
+ TScalar m_OutsideValue;
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Base/RegionGrow.hxx>
+#endif
+
+#endif // __FPA__BASE__REGIONGROW__H__
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __FPA__BASE__REGIONGROW__HXX__
+#define __FPA__BASE__REGIONGROW__HXX__
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass >
+fpa::Base::RegionGrow< _TSuperclass >::
+RegionGrow( )
+ : Superclass( ),
+ m_RegionGrowFunction( NULL ),
+ m_InsideValue( TScalar( 1 ) ),
+ m_OutsideValue( TScalar( 0 ) )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass >
+fpa::Base::RegionGrow< _TSuperclass >::
+~RegionGrow( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass >
+bool fpa::Base::RegionGrow< _TSuperclass >::
+_Result( TNode& node, const TNode& parent )
+{
+ if( this->m_RegionGrowFunction.IsNotNull( ) )
+ {
+ bool res = this->m_RegionGrowFunction->Evaluate( node.Vertex );
+ node.Result = ( res )? this->m_InsideValue: this->m_OutsideValue;
+ return( res );
+ }
+ else
+ {
+ node.Result = this->m_OutsideValue;
+ return( false );
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass >
+void fpa::Base::RegionGrow< _TSuperclass >::
+_QueueClear( )
+{
+ this->m_Queue.clear( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass >
+void fpa::Base::RegionGrow< _TSuperclass >::
+_QueuePush( const TNode& node )
+{
+ this->m_Queue.push_back( node );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass >
+typename fpa::Base::RegionGrow< _TSuperclass >::
+TNode fpa::Base::RegionGrow< _TSuperclass >::
+_QueuePop( )
+{
+ TNode n = this->m_Queue.front( );
+ this->m_Queue.pop_front( );
+ return( n );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass >
+bool fpa::Base::RegionGrow< _TSuperclass >::
+_IsQueueEmpty( ) const
+{
+ return( this->m_Queue.size( ) == 0 );
+}
+
+#endif // __FPA__BASE__REGIONGROW__HXX__
+
+// eof - $RCSfile$
--- /dev/null
+#include <fpa/Config.h>
+#include <string>
+
+// -------------------------------------------------------------------------
+std::string fpa_EXPORT GetVersion( )
+{
+ return( fpa_VERSION );
+}
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __fpa__h__
+#define __fpa__h__
+
+#include <fpa_Export.h>
+
+/*
+ * =========================================================================
+ * Version numbers and strings
+ * =========================================================================
+ */
+#define fpa_MAJOR_VERSION @prj_MAJ_VER@
+#define fpa_MINOR_VERSION @prj_MIN_VER@
+#define fpa_RELEASE_VERSION @prj_REL_VER@
+#define fpa_VERSION "@prj_VERSION@"
+#define fpa_SHORT_VERSION "@prj_SHORT_VERSION@"
+
+/*
+ * =========================================================================
+ * Language related macros
+ * =========================================================================
+ */
+
+#if __cplusplus >= 201103L
+# define fpa_OVERRIDE override
+# define fpa_DELETE_FUNCTION =delete
+# define fpa_NULLPTR nullptr
+# define fpa_NOEXCEPT noexcept
+# define fpa_HAS_CXX11_STATIC_ASSERT
+# define fpa_HAS_CXX11_RVREF
+#else
+# define fpa_OVERRIDE
+# define fpa_DELETE_FUNCTION
+# define fpa_NULLPTR NULL
+# define fpa_NOEXCEPT throw()
+#endif
+
+#endif // __fpa__h__
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __FPA__IMAGE__ALGORITHM__H__
+#define __FPA__IMAGE__ALGORITHM__H__
+
+#include <fpa/Base/Algorithm.h>
+#include <itkImage.h>
+#include <itkImageToImageFilter.h>
+
+namespace fpa
+{
+ namespace Image
+ {
+ /**
+ */
+ template< class _TInputImage, class _TOutputImage >
+ class Algorithm
+ : public fpa::Base::Algorithm< typename _TInputImage::IndexType, typename _TOutputImage::PixelType, itk::ImageToImageFilter< _TInputImage, _TOutputImage >, typename _TInputImage::IndexType::LexicographicCompare >
+ {
+ public:
+ typedef fpa::Base::Algorithm< typename _TInputImage::IndexType, typename _TOutputImage::PixelType, itk::ImageToImageFilter< _TInputImage, _TOutputImage >, typename _TInputImage::IndexType::LexicographicCompare > Superclass;
+ typedef Algorithm Self;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ // Input types
+ typedef _TInputImage TInputImage;
+ typedef _TOutputImage TOutputImage;
+ itkConceptMacro(
+ ImagesSameDimension,
+ (
+ itk::Concept::
+ SameDimension<
+ TInputImage::ImageDimension,
+ TOutputImage::ImageDimension
+ >
+ )
+ );
+
+ // Template arguments
+ typedef typename Superclass::TVertex TVertex;
+ typedef typename Superclass::TScalar TScalar;
+ typedef typename Superclass::TFilter TFilter;
+ typedef typename Superclass::TVertexCompare TVertexCompare;
+ typedef typename Superclass::TFrontId TFrontId;
+ typedef typename Superclass::TCollision TCollision;
+ typedef typename Superclass::TCollisionsRow TCollisionsRow;
+ typedef typename Superclass::TCollisions TCollisions;
+ typedef typename Superclass::TNodeLabel TNodeLabel;
+ typedef typename Superclass::TNode TNode;
+ typedef typename Superclass::TNodes TNodes;
+ typedef typename Superclass::TVertices TVertices;
+
+ typedef itk::Image< TFrontId, TInputImage::ImageDimension > TMarkImage;
+
+ public:
+ itkTypeMacro( Algorithm, _TFilter );
+
+ itkGetConstMacro( NeighborhoodOrder, unsigned short );
+ itkSetMacro( NeighborhoodOrder, unsigned short );
+
+ protected:
+ // Methods to extend itk-imaged architecture
+ Algorithm( );
+ virtual ~Algorithm( );
+
+ // Front propagation methods to be overloaded
+ virtual void _BeforeGenerateData( ) fpa_OVERRIDE;
+ virtual void _InitMarks( ) fpa_OVERRIDE;
+ virtual void _InitResults( ) fpa_OVERRIDE;
+ virtual void _DeallocateAuxiliary( ) fpa_OVERRIDE;
+ virtual TFrontId _GetMark( const TVertex& v ) fpa_OVERRIDE;
+ virtual void _Visit( const TNode& n ) fpa_OVERRIDE;
+ virtual TVertices _GetNeighborhood(
+ const TVertex& v
+ ) const fpa_OVERRIDE;
+
+ private:
+ // Purposely not implemented
+ Algorithm( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+ unsigned short m_NeighborhoodOrder;
+ typename TMarkImage::Pointer m_Marks;
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Image/Algorithm.hxx>
+#endif
+
+#endif // __FPA__IMAGE__ALGORITHM__H__
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __FPA__IMAGE__ALGORITHM__HXX__
+#define __FPA__IMAGE__ALGORITHM__HXX__
+
+#include <itkConstNeighborhoodIterator.h>
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+fpa::Image::Algorithm< _TInputImage, _TOutputImage >::
+Algorithm( )
+ : Superclass( ),
+ m_NeighborhoodOrder( 1 )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+fpa::Image::Algorithm< _TInputImage, _TOutputImage >::
+~Algorithm( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+void fpa::Image::Algorithm< _TInputImage, _TOutputImage >::
+_BeforeGenerateData( )
+{
+ this->Superclass::_BeforeGenerateData( );
+ this->AllocateOutputs( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+void fpa::Image::Algorithm< _TInputImage, _TOutputImage >::
+_InitMarks( )
+{
+ TOutputImage* out = this->GetOutput( );
+ this->m_Marks = TMarkImage::New( );
+ this->m_Marks->CopyInformation( out );
+ this->m_Marks->SetRequestedRegion( out->GetRequestedRegion( ) );
+ this->m_Marks->SetBufferedRegion( out->GetBufferedRegion( ) );
+ this->m_Marks->Allocate( );
+ this->m_Marks->FillBuffer( 0 );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+void fpa::Image::Algorithm< _TInputImage, _TOutputImage >::
+_InitResults( )
+{
+ this->GetOutput( )->FillBuffer( TScalar( 0 ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+void fpa::Image::Algorithm< _TInputImage, _TOutputImage >::
+_DeallocateAuxiliary( )
+{
+ this->m_Marks = NULL;
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+typename fpa::Image::Algorithm< _TInputImage, _TOutputImage >::
+TFrontId fpa::Image::Algorithm< _TInputImage, _TOutputImage >::
+_GetMark( const TVertex& v )
+{
+ if( this->m_Marks->GetRequestedRegion( ).IsInside( v ) )
+ return( this->m_Marks->GetPixel( v ) );
+ else
+ return( 0 );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+void fpa::Image::Algorithm< _TInputImage, _TOutputImage >::
+_Visit( const TNode& n )
+{
+ if( this->m_Marks->GetRequestedRegion( ).IsInside( n.Vertex ) )
+ {
+ this->m_Marks->SetPixel( n.Vertex, n.FrontId );
+ this->GetOutput( )->SetPixel( n.Vertex, n.Result );
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+typename fpa::Image::Algorithm< _TInputImage, _TOutputImage >::
+TVertices fpa::Image::Algorithm< _TInputImage, _TOutputImage >::
+_GetNeighborhood( const TVertex& v ) const
+{
+ TVertices neighs;
+ auto reg = this->GetInput( )->GetRequestedRegion( );
+ if( this->m_NeighborhoodOrder == 1 )
+ {
+ for( unsigned int d = 0; d < _TInputImage::ImageDimension; d++ )
+ {
+ for( int i = -1; i <= 1; i += 2 )
+ {
+ TVertex n = v;
+ n[ d ] += i;
+ if( reg.IsInside( n ) )
+ neighs.push_back( n );
+
+ } // rof
+
+ } // rof
+ }
+ else
+ {
+ typedef itk::ConstNeighborhoodIterator< _TInputImage > _TNeighIt;
+ typename _TInputImage::SizeType nSize;
+ nSize.Fill( 1 );
+
+ _TNeighIt nIt( nSize, this->GetInput( ), reg );
+ nIt.SetLocation( v );
+ for( unsigned int i = 0; i < nIt.Size( ); i++ )
+ {
+ TVertex n = nIt.GetIndex( i );
+ if( n == v )
+ continue;
+ if( reg.IsInside( n ) )
+ neighs.push_back( n );
+
+ } // rof
+
+ } // fi
+ return( neighs );
+}
+
+#endif // __FPA__IMAGE__ALGORITHM__HXX__
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __FPA__IMAGE__DIJKSTRA__H__
+#define __FPA__IMAGE__DIJKSTRA__H__
+
+#include <fpa/Base/Dijkstra.h>
+#include <fpa/Image/Algorithm.h>
+
+namespace fpa
+{
+ namespace Image
+ {
+ /**
+ */
+ template< class _TInputImage, class _TOutputImage = _TInputImage >
+ class Dijkstra
+ : public fpa::Base::Dijkstra< fpa::Image::Algorithm< _TInputImage, _TOutputImage > >
+ {
+ public:
+ typedef fpa::Base::Dijkstra< fpa::Image::Algorithm< _TInputImage, _TOutputImage > > Superclass;
+ typedef Dijkstra Self;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ // Template arguments
+ typedef typename Superclass::TVertex TVertex;
+ typedef typename Superclass::TScalar TScalar;
+ typedef typename Superclass::TFilter TFilter;
+ typedef typename Superclass::TVertexCompare TVertexCompare;
+ typedef typename Superclass::TFrontId TFrontId;
+ typedef typename Superclass::TCollision TCollision;
+ typedef typename Superclass::TCollisionsRow TCollisionsRow;
+ typedef typename Superclass::TCollisions TCollisions;
+ typedef typename Superclass::TNodeLabel TNodeLabel;
+ typedef typename Superclass::TNode TNode;
+ typedef typename Superclass::TNodes TNodes;
+ typedef typename Superclass::TVertices TVertices;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro( Dijkstra, fpa::Base::Dijkstra );
+
+ itkBooleanMacro( UseImageSpacing );
+ itkGetConstMacro( UseImageSpacing, bool );
+ itkSetMacro( UseImageSpacing, bool );
+
+ protected:
+ Dijkstra( );
+ virtual ~Dijkstra( );
+
+ // Dijkstra methods to be overloaded
+ virtual TScalar _Cost(
+ const TVertex& a, const TVertex& b
+ ) const fpa_OVERRIDE;
+
+ private:
+ // Purposely not implemented
+ Dijkstra( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+ bool m_UseImageSpacing;
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Image/Dijkstra.hxx>
+#endif
+
+#endif // __FPA__IMAGE__DIJKSTRA__H__
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __FPA__IMAGE__DIJKSTRA__HXX__
+#define __FPA__IMAGE__DIJKSTRA__HXX__
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+fpa::Image::Dijkstra< _TInputImage, _TOutputImage >::
+Dijkstra( )
+ : Superclass( ),
+ m_UseImageSpacing( false )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+fpa::Image::Dijkstra< _TInputImage, _TOutputImage >::
+~Dijkstra( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+typename fpa::Image::Dijkstra< _TInputImage, _TOutputImage >::
+TScalar fpa::Image::Dijkstra< _TInputImage, _TOutputImage >::
+_Cost( const TVertex& a, const TVertex& b ) const
+{
+ auto input = this->GetInput( );
+ TScalar coeff = TScalar( 1 );
+ if( this->m_UseImageSpacing )
+ {
+ typename _TInputImage::PointType pa, pb;
+ input->TransformIndexToPhysicalPoint( a, pa );
+ input->TransformIndexToPhysicalPoint( b, pb );
+ coeff = TScalar( pa.EuclideanDistanceTo( pb ) );
+
+ } // fi
+ TScalar va = TScalar( input->GetPixel( a ) );
+ return( va * coeff );
+}
+
+#endif // __FPA__IMAGE__DIJKSTRA__HXX__
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __fpa__Image__MultiplyImageAndDistanceMap__h__
+#define __fpa__Image__MultiplyImageAndDistanceMap__h__
+
+#include <itkImageToImageFilter.h>
+
+namespace fpa
+{
+ namespace Image
+ {
+ /**
+ */
+ template< class _TInput, class _TDistanceMap >
+ class MultiplyImageAndDistanceMap
+ : public itk::ImageToImageFilter< _TInput, _TInput >
+ {
+ public:
+ typedef MultiplyImageAndDistanceMap Self;
+ typedef itk::ImageToImageFilter< _TInput, _TInput > Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ typedef _TInput TInput;
+ typedef _TDistanceMap TDistanceMap;
+
+ typedef typename TInput::RegionType TRegion;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro( MultiplyImageAndDistanceMap, itkImageToImageFilter );
+
+ public:
+ _TDistanceMap* GetDistanceMap( );
+ const _TDistanceMap* GetDistanceMap( ) const;
+ void SetDistanceMap( _TDistanceMap* dmap );
+
+ protected:
+ MultiplyImageAndDistanceMap( );
+ virtual ~MultiplyImageAndDistanceMap( );
+
+ virtual void ThreadedGenerateData(
+ const TRegion& region,
+ itk::ThreadIdType threadId
+ ) fpa_OVERRIDE;
+
+ private:
+ // Purposely not implemented.
+ MultiplyImageAndDistanceMap( const Self& );
+ void operator=( const Self& );
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Image/MultiplyImageAndDistanceMap.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Image__MultiplyImageAndDistanceMap__h__
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __fpa__Image__MultiplyImageAndDistanceMap__hxx__
+#define __fpa__Image__MultiplyImageAndDistanceMap__hxx__
+
+#include <itkImageRegionConstIteratorWithIndex.h>
+#include <itkImageRegionIteratorWithIndex.h>
+#include <itkProgressReporter.h>
+
+// -------------------------------------------------------------------------
+template< class _TInput, class _TDistanceMap >
+_TDistanceMap*
+fpa::Image::MultiplyImageAndDistanceMap< _TInput, _TDistanceMap >::
+GetDistanceMap( )
+{
+ return(
+ dynamic_cast< _TDistanceMap* >(
+ this->itk::ProcessObject::GetInput( 1 )
+ )
+ );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInput, class _TDistanceMap >
+const _TDistanceMap*
+fpa::Image::MultiplyImageAndDistanceMap< _TInput, _TDistanceMap >::
+GetDistanceMap( ) const
+{
+ return(
+ dynamic_cast< const _TDistanceMap* >(
+ this->itk::ProcessObject::GetInput( 1 )
+ )
+ );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInput, class _TDistanceMap >
+void fpa::Image::MultiplyImageAndDistanceMap< _TInput, _TDistanceMap >::
+SetDistanceMap( _TDistanceMap* dmap )
+{
+ this->itk::ProcessObject::SetNthInput( 1, dmap );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInput, class _TDistanceMap >
+fpa::Image::MultiplyImageAndDistanceMap< _TInput, _TDistanceMap >::
+MultiplyImageAndDistanceMap( )
+ : Superclass( )
+{
+ this->SetNumberOfRequiredInputs( 2 );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInput, class _TDistanceMap >
+fpa::Image::MultiplyImageAndDistanceMap< _TInput, _TDistanceMap >::
+~MultiplyImageAndDistanceMap( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TInput, class _TDistanceMap >
+void fpa::Image::MultiplyImageAndDistanceMap< _TInput, _TDistanceMap >::
+ThreadedGenerateData( const TRegion& region, itk::ThreadIdType threadId )
+{
+ typedef typename _TInput::PixelType _TPixel;
+ const typename TRegion::SizeType& regionSize = region.GetSize( );
+ if( regionSize[ 0 ] == 0 )
+ return;
+ const _TInput* input = this->GetInput( );
+ const _TDistanceMap* dmap = this->GetDistanceMap( );
+ _TInput* output = this->GetOutput( );
+ itk::ProgressReporter pr( this, threadId, region.GetNumberOfPixels( ) );
+
+ // Prepare iterators
+ itk::ImageRegionConstIteratorWithIndex< _TInput > iIt( input, region );
+ itk::ImageRegionConstIteratorWithIndex< _TDistanceMap > dIt( dmap, region );
+ itk::ImageRegionIteratorWithIndex< _TInput > oIt( output, region );
+ iIt.GoToBegin( );
+ dIt.GoToBegin( );
+ oIt.GoToBegin( );
+ for(
+ ; !iIt.IsAtEnd( ) && !dIt.IsAtEnd( ) && !oIt.IsAtEnd( );
+ ++iIt, ++dIt, ++oIt
+ )
+ {
+ double d = double( dIt.Get( ) );
+ if( !( d >= double( 0 ) ) )
+ {
+ /* TODO
+ double v = double( iIt.Get( ) );
+ if( v >= 0 )
+ oIt.Set( _TPixel( v / std::fabs( d ) ) );
+ else
+ oIt.Set( _TPixel( v * std::fabs( d ) ) );
+ */
+ oIt.Set( _TPixel( 0 ) );
+ }
+ else
+ oIt.Set( iIt.Get( ) );
+ pr.CompletedPixel( );
+
+ } // rof
+}
+
+#endif // __fpa__Image__MultiplyImageAndDistanceMap__hxx__
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __FPA__IMAGE__REGIONGROW__H__
+#define __FPA__IMAGE__REGIONGROW__H__
+
+#include <fpa/Base/RegionGrow.h>
+#include <fpa/Image/Algorithm.h>
+
+namespace fpa
+{
+ namespace Image
+ {
+ /**
+ */
+ template< class _TInputImage, class _TOutputImage = _TInputImage >
+ class RegionGrow
+ : public fpa::Base::RegionGrow< fpa::Image::Algorithm< _TInputImage, _TOutputImage > >
+ {
+ public:
+ typedef fpa::Base::RegionGrow< fpa::Image::Algorithm< _TInputImage, _TOutputImage > > Superclass;
+ typedef RegionGrow Self;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro( RegionGrow, fpa::Base::RegionGrow );
+
+ protected:
+ RegionGrow( );
+ virtual ~RegionGrow( );
+
+ private:
+ // Purposely not implemented
+ RegionGrow( const Self& other );
+ Self& operator=( const Self& other );
+ };
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/Image/RegionGrow.hxx>
+#endif
+
+#endif // __FPA__IMAGE__REGIONGROW__H__
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __FPA__IMAGE__REGIONGROW__HXX__
+#define __FPA__IMAGE__REGIONGROW__HXX__
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+fpa::Image::RegionGrow< _TInputImage, _TOutputImage >::
+RegionGrow( )
+ : Superclass( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+fpa::Image::RegionGrow< _TInputImage, _TOutputImage >::
+~RegionGrow( )
+{
+}
+
+#endif // __FPA__IMAGE__REGIONGROW__HXX__
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __FPA__VTK__IMAGE__OBSERVER2D__H__
+#define __FPA__VTK__IMAGE__OBSERVER2D__H__
+
+#include <set>
+#include <itkCommand.h>
+#include <vtkActor.h>
+#include <vtkImageActor.h>
+#include <vtkImageData.h>
+#include <vtkPolyData.h>
+#include <vtkSmartPointer.h>
+
+namespace fpa
+{
+ namespace VTK
+ {
+ namespace Image
+ {
+ /**
+ */
+ template< class _TFilter, class _TRenderWindow >
+ class Observer2D
+ : public itk::Command
+ {
+ public:
+ typedef Observer2D Self;
+ typedef itk::Command Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ typedef _TFilter TFilter;
+ typedef _TRenderWindow TRenderWindow;
+ typedef typename TFilter::TInputImage TImage;
+ typedef typename TFilter::TVertex TVertex;
+
+ typedef std::set< TVertex > TVertices;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro( Observer2D, itkCommand );
+
+ itkGetConstMacro( RenderPercentage, double );
+ itkSetMacro( RenderPercentage, double );
+
+ public:
+ void SetRenderWindow( _TRenderWindow* rw );
+ void SetPixel(
+ typename TImage::IndexType idx,
+ unsigned char red,
+ unsigned char green,
+ unsigned char blue,
+ unsigned char alpha
+ );
+ void Render( );
+ void Execute( itk::Object* c, const itk::EventObject& e ) fpa_OVERRIDE
+ { this->Execute( ( const itk::Object* )( c ), e ); }
+ void Execute( const itk::Object* c, const itk::EventObject& e ) fpa_OVERRIDE;
+
+ protected:
+ Observer2D( );
+ virtual ~Observer2D( );
+
+ private:
+ // Purposely not implemented
+ Observer2D( const Self& );
+ void operator=( const Self& );
+
+ protected:
+ vtkSmartPointer< vtkImageData > m_Stencil;
+ vtkSmartPointer< vtkImageActor > m_StencilActor;
+
+ _TRenderWindow* m_RenderWindow;
+ unsigned long m_Count;
+ unsigned long m_RenderCount;
+ double m_RenderPercentage;
+ };
+
+ } // ecapseman
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/VTK/Image/Observer2D.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __FPA__VTK__IMAGE__OBSERVER2D__H__
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __FPA__VTK__IMAGE__OBSERVER2D__HXX__
+#define __FPA__VTK__IMAGE__OBSERVER2D__HXX__
+
+#include <vtkCellArray.h>
+#include <vtkPolyDataMapper.h>
+#include <vtkPoints.h>
+#include <vtkPointData.h>
+#include <vtkProperty.h>
+#include <vtkRenderer.h>
+#include <vtkRendererCollection.h>
+
+// -------------------------------------------------------------------------
+template< class _TFilter, class _TRenderWindow >
+void fpa::VTK::Image::Observer2D< _TFilter, _TRenderWindow >::
+SetRenderWindow( _TRenderWindow* rw )
+{
+ this->m_RenderWindow = rw;
+}
+
+// -------------------------------------------------------------------------
+template< class _TFilter, class _TRenderWindow >
+void fpa::VTK::Image::Observer2D< _TFilter, _TRenderWindow >::
+SetPixel(
+ typename TImage::IndexType idx,
+ unsigned char red,
+ unsigned char green,
+ unsigned char blue,
+ unsigned char alpha
+ )
+{
+ this->m_Stencil->SetScalarComponentFromDouble
+ ( idx[ 0 ], idx[ 1 ], 0, 0, red );
+ this->m_Stencil->SetScalarComponentFromDouble
+ ( idx[ 0 ], idx[ 1 ], 0, 1, green );
+ this->m_Stencil->SetScalarComponentFromDouble
+ ( idx[ 0 ], idx[ 1 ], 0, 2, blue );
+ this->m_Stencil->SetScalarComponentFromDouble
+ ( idx[ 0 ], idx[ 1 ], 0, 3, alpha );
+ this->m_Stencil->Modified( );
+ this->m_StencilActor->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TFilter, class _TRenderWindow >
+void fpa::VTK::Image::Observer2D< _TFilter, _TRenderWindow >::
+Render( )
+{
+ if( this->m_RenderWindow != NULL )
+ this->m_RenderWindow->Render( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TFilter, class _TRenderWindow >
+void fpa::VTK::Image::Observer2D< _TFilter, _TRenderWindow >::
+Execute( const itk::Object* c, const itk::EventObject& e )
+{
+ typedef typename _TFilter::TStartEvent _TStartEvent;
+ typedef typename _TFilter::TStartLoopEvent _TStartLoopEvent;
+ typedef typename _TFilter::TEndEvent _TEndEvent;
+ typedef typename _TFilter::TEndLoopEvent _TEndLoopEvent;
+ typedef typename _TFilter::TAliveEvent _TAliveEvent;
+ typedef typename _TFilter::TFrontEvent _TFrontEvent;
+ typedef typename _TFilter::TFreezeEvent _TFreezeEvent;
+
+ typedef typename _TFilter::TStartBacktrackingEvent _TStartBacktrackingEvent;
+ typedef typename _TFilter::TEndBacktrackingEvent _TEndBacktrackingEvent;
+ typedef typename _TFilter::TBacktrackingEvent _TBacktrackingEvent;
+
+ static unsigned char Colors[][4] =
+ {
+ { 0, 0, 127, 127 },
+ { 0, 127, 127, 127 },
+ { 127, 0, 127, 127 },
+ { 127, 127, 0, 127 },
+ { 0, 0, 63, 127 },
+ { 0, 63, 63, 127 },
+ { 63, 0, 63, 127 },
+ { 63, 63, 0, 127 },
+ { 63, 63, 127, 127 },
+ { 63, 127, 127, 127 },
+ { 127, 63, 127, 127 },
+ { 127, 127, 63, 127 },
+ { 127, 127, 63, 127 },
+ { 127, 63, 63, 127 },
+ { 63, 127, 63, 127 },
+ { 63, 63, 127, 127 }
+ };
+
+ auto filter = dynamic_cast< const _TFilter* >( c );
+ if( this->m_RenderWindow == NULL || filter == NULL )
+ return;
+
+ const _TStartEvent* startEvt = dynamic_cast< const _TStartEvent* >( &e );
+ const _TStartBacktrackingEvent* startBackEvt =
+ dynamic_cast< const _TStartBacktrackingEvent* >( &e );
+ if( startEvt != NULL || startBackEvt != NULL )
+ {
+ const TImage* img = filter->GetInput( );
+ unsigned int minD = TImage::ImageDimension;
+ minD = ( minD < 3 )? minD: 3;
+
+ int e[ 6 ] = { 0 };
+ typename TImage::RegionType reg = img->GetRequestedRegion( );
+ for( unsigned int i = 0; i < minD; i++ )
+ {
+ e[ ( i << 1 ) + 0 ] = reg.GetIndex( )[ i ];
+ e[ ( i << 1 ) + 1 ] = reg.GetIndex( )[ i ] + reg.GetSize( )[ i ] - 1;
+
+ } // rof
+
+ typename TImage::SpacingType spac = img->GetSpacing( );
+ double s[ 3 ] = { 1, 1, 1 };
+ for( unsigned int i = 0; i < minD; i++ )
+ s[ i ] = double( spac[ i ] );
+
+ typename TImage::PointType orig = img->GetOrigin( );
+ double o[ 3 ] = { 0 };
+ for( unsigned int i = 0; i < minD; i++ )
+ o[ i ] = double( orig[ i ] );
+
+ this->m_Stencil->SetExtent( e );
+ this->m_Stencil->SetSpacing( s );
+ this->m_Stencil->SetOrigin( o );
+ this->m_Stencil->AllocateScalars( VTK_UNSIGNED_CHAR, 4 );
+ for( unsigned int i = 0; i < 3; i++ )
+ this->m_Stencil->GetPointData( )->
+ GetScalars( )->FillComponent( i, 255 );
+ this->m_Stencil->GetPointData( )->GetScalars( )->FillComponent( 3, 0 );
+
+ this->m_StencilActor->SetInputData( this->m_Stencil );
+ this->m_StencilActor->InterpolateOff( );
+
+ this->m_Count = 0;
+ this->m_RenderCount = reg.GetNumberOfPixels( );
+
+ vtkRenderer* ren =
+ this->m_RenderWindow->GetRenderers( )->GetFirstRenderer( );
+ ren->AddActor( this->m_StencilActor );
+ return;
+
+ } // fi
+
+ const _TAliveEvent* aliveEvt = dynamic_cast< const _TAliveEvent* >( &e );
+ const _TFrontEvent* frontEvt = dynamic_cast< const _TFrontEvent* >( &e );
+ if( aliveEvt != NULL || frontEvt != NULL )
+ {
+ if( aliveEvt != NULL )
+ this->SetPixel(
+ aliveEvt->Vertex,
+ Colors[ aliveEvt->FrontId ][ 0 ],
+ Colors[ aliveEvt->FrontId ][ 1 ],
+ Colors[ aliveEvt->FrontId ][ 2 ],
+ Colors[ aliveEvt->FrontId ][ 3 ]
+ );
+ else if( frontEvt != NULL )
+ this->SetPixel( frontEvt->Vertex, 255, 0, 0, 255 );
+ this->m_Count++;
+
+ // Render visual debug
+ double per = double( this->m_RenderCount ) * this->m_RenderPercentage;
+ if( double( this->m_Count ) >= per )
+ this->Render( );
+ if( double( this->m_Count ) >= per )
+ this->m_Count = 0;
+
+ return;
+
+ } // fi
+
+ const _TEndEvent* endEvt = dynamic_cast< const _TEndEvent* >( &e );
+ if( endEvt != NULL )
+ {
+ vtkRenderer* ren =
+ this->m_RenderWindow->GetRenderers( )->GetFirstRenderer( );
+ ren->RemoveActor( this->m_StencilActor );
+ this->Render( );
+ return;
+
+ } // fi
+
+ const _TBacktrackingEvent* backEvt =
+ dynamic_cast< const _TBacktrackingEvent* >( &e );
+ const _TEndBacktrackingEvent* endBackEvt =
+ dynamic_cast< const _TEndBacktrackingEvent* >( &e );
+ if( backEvt != NULL )
+ {
+ this->SetPixel( backEvt->Vertex, 0, 0, 255, 255 );
+ return;
+
+ } // fi
+
+ if( endBackEvt != NULL )
+ {
+ this->m_RenderWindow->Render( );
+ /* TODO: DEBUG
+ std::cout << "Press enter: " << std::ends;
+ int aux;
+ std::cin >> aux;
+ */
+ return;
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TFilter, class _TRenderWindow >
+fpa::VTK::Image::Observer2D< _TFilter, _TRenderWindow >::
+Observer2D( )
+ : Superclass( ),
+ m_RenderWindow( NULL ),
+ m_RenderPercentage( double( 0.01 ) )
+{
+ this->m_Stencil = vtkSmartPointer< vtkImageData >::New( );
+ this->m_StencilActor = vtkSmartPointer< vtkImageActor >::New( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TFilter, class _TRenderWindow >
+fpa::VTK::Image::Observer2D< _TFilter, _TRenderWindow >::
+~Observer2D( )
+{
+}
+
+#endif // __FPA__VTK__IMAGE__OBSERVER2D__HXX__
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __FPA__VTK__IMAGE__OBSERVER3D__H__
+#define __FPA__VTK__IMAGE__OBSERVER3D__H__
+
+#include <map>
+
+#include <itkCommand.h>
+
+#include <vtkActor.h>
+#include <vtkPolyData.h>
+#include <vtkPolyDataMapper.h>
+#include <vtkSmartPointer.h>
+
+namespace fpa
+{
+ namespace VTK
+ {
+ namespace Image
+ {
+ /**
+ */
+ template< class _TFilter, class _TRenderWindow >
+ class Observer3D
+ : public itk::Command
+ {
+ public:
+ typedef Observer3D Self;
+ typedef itk::Command Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ typedef _TFilter TFilter;
+ typedef _TRenderWindow TRenderWindow;
+ typedef typename TFilter::TInputImage TImage;
+ typedef typename TFilter::TVertex TVertex;
+ typedef typename TFilter::TVertexCompare TVertexCompare;
+
+ typedef std::set< TVertex > TVertices;
+
+ public:
+ itkNewMacro( Self );
+ itkTypeMacro( Observer3D, itkCommand );
+
+ itkGetConstMacro( RenderPercentage, double );
+ itkSetMacro( RenderPercentage, double );
+
+ public:
+ void SetRenderWindow( _TRenderWindow* rw );
+ void Render( );
+ void Execute( itk::Object* c, const itk::EventObject& e ) fpa_OVERRIDE
+ { this->Execute( ( const itk::Object* )( c ), e ); }
+ void Execute( const itk::Object* c, const itk::EventObject& e ) fpa_OVERRIDE;
+
+ protected:
+ Observer3D( );
+ virtual ~Observer3D( );
+
+ private:
+ Observer3D( const Self& ); // Not impl.
+ void operator=( const Self& ); // Not impl.
+
+ protected:
+ vtkSmartPointer< vtkPolyData > m_PolyData;
+ vtkSmartPointer< vtkPolyDataMapper > m_PolyDataMapper;
+ vtkSmartPointer< vtkActor > m_PolyDataActor;
+ std::map< TVertex, unsigned long, TVertexCompare > m_PointsToReplace;
+ std::map< TVertex, unsigned long, TVertexCompare > m_PointsInFront;
+
+ _TRenderWindow* m_RenderWindow;
+ unsigned long m_Count;
+ unsigned long m_RenderCount;
+ double m_RenderPercentage;
+ };
+
+ } // ecapseman
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/VTK/Observer3D.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __FPA__VTK__IMAGE__OBSERVER3D__H__
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __FPA__VTK__IMAGE__OBSERVER3D__HXX__
+#define __FPA__VTK__IMAGE__OBSERVER3D__HXX__
+
+#include <vtkCellArray.h>
+#include <vtkPolyDataMapper.h>
+#include <vtkPoints.h>
+#include <vtkPointData.h>
+#include <vtkProperty.h>
+#include <vtkRenderer.h>
+#include <vtkRendererCollection.h>
+
+// -------------------------------------------------------------------------
+template< class _TFilter, class _TRenderWindow >
+void fpa::VTK::Image::Observer3D< _TFilter, _TRenderWindow >::
+SetRenderWindow( _TRenderWindow* rw )
+{
+ this->m_RenderWindow = rw;
+}
+
+// -------------------------------------------------------------------------
+template< class _TFilter, class _TRenderWindow >
+void fpa::VTK::Image::Observer3D< _TFilter, _TRenderWindow >::
+Render( )
+{
+ if( this->m_RenderWindow != NULL )
+ this->m_RenderWindow->Render( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TFilter, class _TRenderWindow >
+void fpa::VTK::Image::Observer3D< _TFilter, _TRenderWindow >::
+Execute( const itk::Object* c, const itk::EventObject& e )
+{
+ typedef typename _TFilter::TStartEvent _TStartEvent;
+ typedef typename _TFilter::TStartLoopEvent _TStartLoopEvent;
+ typedef typename _TFilter::TEndEvent _TEndEvent;
+ typedef typename _TFilter::TEndLoopEvent _TEndLoopEvent;
+ typedef typename _TFilter::TAliveEvent _TAliveEvent;
+ typedef typename _TFilter::TFrontEvent _TFrontEvent;
+ typedef typename _TFilter::TFreezeEvent _TFreezeEvent;
+
+ typedef typename _TFilter::TStartBacktrackingEvent _TStartBacktrackingEvent;
+ typedef typename _TFilter::TEndBacktrackingEvent _TEndBacktrackingEvent;
+ typedef typename _TFilter::TBacktrackingEvent _TBacktrackingEvent;
+
+ static unsigned char Colors[][4] =
+ {
+ { 0, 0, 127, 127 },
+ { 0, 127, 127, 127 },
+ { 127, 0, 127, 127 },
+ { 127, 127, 0, 127 },
+ { 0, 0, 63, 127 },
+ { 0, 63, 63, 127 },
+ { 63, 0, 63, 127 },
+ { 63, 63, 0, 127 },
+ { 63, 63, 127, 127 },
+ { 63, 127, 127, 127 },
+ { 127, 63, 127, 127 },
+ { 127, 127, 63, 127 },
+ { 127, 127, 63, 127 },
+ { 127, 63, 63, 127 },
+ { 63, 127, 63, 127 },
+ { 63, 63, 127, 127 }
+ };
+
+ auto filter = dynamic_cast< const _TFilter* >( c );
+ if( this->m_RenderWindow == NULL || filter == NULL )
+ return;
+ auto image = filter->GetInput( );
+ if( image == NULL )
+ return;
+
+ const _TStartEvent* startEvt = dynamic_cast< const _TStartEvent* >( &e );
+ const _TStartBacktrackingEvent* startBackEvt =
+ dynamic_cast< const _TStartBacktrackingEvent* >( &e );
+ if( startEvt != NULL || startBackEvt != NULL )
+ {
+ this->m_Count = 0;
+ this->m_RenderCount =
+ image->GetLargestPossibleRegion( ).GetNumberOfPixels( );
+ this->m_PointsToReplace.clear( );
+ this->m_PointsInFront.clear( );
+
+ vtkRenderer* ren =
+ this->m_RenderWindow->GetRenderers( )->GetFirstRenderer( );
+ ren->AddActor( this->m_PolyDataActor );
+ return;
+
+ } // fi
+
+ const _TFrontEvent* frontEvt = dynamic_cast< const _TFrontEvent* >( &e );
+ if( frontEvt != NULL )
+ {
+ typename TImage::PointType pnt;
+ image->TransformIndexToPhysicalPoint( frontEvt->Vertex, pnt );
+ if( this->m_PointsToReplace.empty( ) )
+ {
+ unsigned long nPoints = this->m_PolyData->GetNumberOfPoints( );
+ this->m_PolyData->GetPoints( )->
+ InsertNextPoint( pnt[ 0 ], pnt[ 1 ], pnt[ 2 ] );
+ this->m_PolyData->GetVerts( )->InsertNextCell( 1 );
+ this->m_PolyData->GetVerts( )->InsertCellPoint( nPoints );
+ this->m_PointsInFront[ frontEvt->Vertex ] = nPoints;
+ }
+ else
+ {
+ auto pIt = this->m_PointsToReplace.begin( );
+ this->m_PolyData->GetPoints( )->
+ SetPoint( pIt->second, pnt[ 0 ], pnt[ 1 ], pnt[ 2 ] );
+ this->m_PointsToReplace.erase( pIt );
+
+ } // fi
+ this->m_PolyData->Modified( );
+ this->m_PolyDataMapper->Modified( );
+ this->m_PolyDataActor->Modified( );
+
+ // Render visual debug
+ this->m_Count++;
+ double per = double( this->m_RenderCount ) * this->m_RenderPercentage;
+ if( double( this->m_Count ) >= per )
+ this->Render( );
+ if( double( this->m_Count ) >= per )
+ this->m_Count = 0;
+
+ return;
+
+ } // fi
+
+ const _TAliveEvent* aliveEvt = dynamic_cast< const _TAliveEvent* >( &e );
+ if( aliveEvt != NULL )
+ {
+ auto pIt = this->m_PointsInFront.find( aliveEvt->Vertex );
+ if( pIt != this->m_PointsInFront.end( ) )
+ {
+ this->m_PointsToReplace[ pIt->first ] = pIt->second;
+ this->m_PointsInFront.erase( pIt );
+
+ } // fi
+ return;
+
+ } // fi
+
+ const _TEndEvent* endEvt = dynamic_cast< const _TEndEvent* >( &e );
+ if( endEvt != NULL )
+ {
+ vtkRenderer* ren =
+ this->m_RenderWindow->GetRenderers( )->GetFirstRenderer( );
+ ren->RemoveActor( this->m_PolyDataActor );
+ this->Render( );
+ return;
+
+ } // fi
+
+ const _TBacktrackingEvent* backEvt =
+ dynamic_cast< const _TBacktrackingEvent* >( &e );
+ const _TEndBacktrackingEvent* endBackEvt =
+ dynamic_cast< const _TEndBacktrackingEvent* >( &e );
+ if( backEvt != NULL )
+ {
+ // TODO:
+ return;
+
+ } // fi
+
+ if( endBackEvt != NULL )
+ {
+ this->m_RenderWindow->Render( );
+
+ /* TODO: DEBUG
+ std::cout << "Press enter: " << std::ends;
+ int aux;
+ std::cin >> aux;
+ */
+ return;
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TFilter, class _TRenderWindow >
+fpa::VTK::Image::Observer3D< _TFilter, _TRenderWindow >::
+Observer3D( )
+ : Superclass( ),
+ m_RenderWindow( NULL ),
+ m_RenderPercentage( double( 0.000001 ) )
+{
+ this->m_PolyData = vtkSmartPointer< vtkPolyData >::New( );
+ this->m_PolyDataMapper = vtkSmartPointer< vtkPolyDataMapper >::New( );
+ this->m_PolyDataActor =vtkSmartPointer< vtkActor >::New( );
+
+ vtkSmartPointer< vtkPoints > points =
+ vtkSmartPointer< vtkPoints >::New( );
+ vtkSmartPointer< vtkCellArray > verts =
+ vtkSmartPointer< vtkCellArray >::New( );
+ this->m_PolyData->SetPoints( points );
+ this->m_PolyData->SetVerts( verts );
+ this->m_PolyDataMapper->SetInputData( this->m_PolyData );
+ this->m_PolyDataActor->SetMapper( this->m_PolyDataMapper );
+ this->m_PolyDataActor->GetProperty( )->SetColor( 0, 1, 0 );
+}
+
+// -------------------------------------------------------------------------
+template< class _TFilter, class _TRenderWindow >
+fpa::VTK::Image::Observer3D< _TFilter, _TRenderWindow >::
+~Observer3D( )
+{
+}
+
+#endif // __FPA__VTK__IMAGE__OBSERVER3D__HXX__
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __FPA__VTK__IMAGE__PATHTOPOLYDATAFILTER__H__
+#define __FPA__VTK__IMAGE__PATHTOPOLYDATAFILTER__H__
+
+#include <itkImageBase.h>
+#include <vtkPolyDataAlgorithm.h>
+
+namespace fpa
+{
+ namespace VTK
+ {
+ namespace Image
+ {
+ /**
+ */
+ template< class _TMinimumSpanningTree >
+ class PathToPolyDataFilter
+ : public vtkPolyDataAlgorithm
+ {
+ public:
+ typedef PathToPolyDataFilter Self;
+ typedef _TMinimumSpanningTree TMinimumSpanningTree;
+ typedef typename TMinimumSpanningTree::TVertex TVertex;
+ typedef itk::ImageBase< TVertex::Dimension > TImage;
+
+ public:
+ vtkTypeMacro( PathToPolyDataFilter, vtkPolyDataAlgorithm );
+
+ vtkGetMacro( Seed0, TVertex );
+ vtkGetMacro( Seed1, TVertex );
+
+ vtkSetMacro( Seed0, TVertex );
+ vtkSetMacro( Seed1, TVertex );
+
+ public:
+ static Self* New( );
+
+ const TMinimumSpanningTree* GetMinimumSpanningTree( ) const;
+ const TImage* GetImage( ) const;
+ void SetMinimumSpanningTree( const TMinimumSpanningTree* mst );
+ void SetImage( const TImage* image );
+
+ protected:
+ PathToPolyDataFilter( );
+ virtual ~PathToPolyDataFilter( );
+
+ int RequestData(
+ vtkInformation* information,
+ vtkInformationVector** input,
+ vtkInformationVector* output
+ );
+ int RequestInformation(
+ vtkInformation* information,
+ vtkInformationVector** input,
+ vtkInformationVector* output
+ );
+
+ virtual void _PrepareOutput( vtkPolyData* out );
+
+ private:
+ // Purposely not implemented
+ PathToPolyDataFilter( const Self& );
+ void operator=( const Self& );
+
+ protected:
+ const TMinimumSpanningTree* m_MST;
+ const TImage* m_Image;
+ TVertex Seed0;
+ TVertex Seed1;
+ };
+
+ } // ecapseman
+
+ } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+# include <fpa/VTK/Image/PathToPolyDataFilter.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __FPA__VTK__IMAGE__PATHTOPOLYDATAFILTER__H__
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __FPA__VTK__IMAGE__PATHTOPOLYDATAFILTER__HXX__
+#define __FPA__VTK__IMAGE__PATHTOPOLYDATAFILTER__HXX__
+
+#include <vtkCellArray.h>
+#include <vtkInformation.h>
+#include <vtkInformationVector.h>
+#include <vtkPointData.h>
+#include <vtkPoints.h>
+#include <vtkSmartPointer.h>
+#include <vtkStreamingDemandDrivenPipeline.h>
+
+// -------------------------------------------------------------------------
+template< class _TMinimumSpanningTree >
+typename fpa::VTK::Image::PathToPolyDataFilter< _TMinimumSpanningTree >::
+Self* fpa::VTK::Image::PathToPolyDataFilter< _TMinimumSpanningTree >::
+New( )
+{
+ return( new Self( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TMinimumSpanningTree >
+const typename fpa::VTK::Image::PathToPolyDataFilter< _TMinimumSpanningTree >::
+TMinimumSpanningTree*
+fpa::VTK::Image::PathToPolyDataFilter< _TMinimumSpanningTree >::
+GetMinimumSpanningTree( ) const
+{
+ return( this->m_MST );
+}
+
+// -------------------------------------------------------------------------
+template< class _TMinimumSpanningTree >
+const typename fpa::VTK::Image::PathToPolyDataFilter< _TMinimumSpanningTree >::
+TImage* fpa::VTK::Image::PathToPolyDataFilter< _TMinimumSpanningTree >::
+GetImage( ) const
+{
+ return( this->m_Image );
+}
+
+// -------------------------------------------------------------------------
+template< class _TMinimumSpanningTree >
+void fpa::VTK::Image::PathToPolyDataFilter< _TMinimumSpanningTree >::
+SetMinimumSpanningTree( const TMinimumSpanningTree* mst )
+{
+ if( this->m_MST != mst )
+ {
+ this->m_MST = mst;
+ this->Modified( );
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TMinimumSpanningTree >
+void fpa::VTK::Image::PathToPolyDataFilter< _TMinimumSpanningTree >::
+SetImage( const TImage* image )
+{
+ if( this->m_Image != image )
+ {
+ this->m_Image = image;
+ this->Modified( );
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TMinimumSpanningTree >
+fpa::VTK::Image::PathToPolyDataFilter< _TMinimumSpanningTree >::
+PathToPolyDataFilter( )
+ : vtkPolyDataAlgorithm( ),
+ m_MST( NULL ),
+ m_Image( NULL )
+{
+ this->SetNumberOfInputPorts( 0 );
+}
+
+// -------------------------------------------------------------------------
+template< class _TMinimumSpanningTree >
+fpa::VTK::Image::PathToPolyDataFilter< _TMinimumSpanningTree >::
+~PathToPolyDataFilter( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TMinimumSpanningTree >
+int fpa::VTK::Image::PathToPolyDataFilter< _TMinimumSpanningTree >::
+RequestData(
+ vtkInformation* information,
+ vtkInformationVector** input,
+ vtkInformationVector* output
+ )
+{
+ if( this->m_MST == NULL || this->m_Image == NULL )
+ return( 0 );
+ auto path = this->m_MST->GetPath( this->Seed0, this->Seed1 );
+ if( path.size( ) == 0 )
+ return( 0 );
+
+ // Prepare output
+ vtkInformation* info = output->GetInformationObject( 0 );
+ vtkPolyData* out = vtkPolyData::SafeDownCast(
+ info->Get( vtkDataObject::DATA_OBJECT( ) )
+ );
+ this->_PrepareOutput( out );
+ vtkPoints* points = out->GetPoints( );
+ vtkCellArray* lines = out->GetLines( );
+
+ unsigned int i = 0;
+ for( auto pIt = path.begin( ); pIt != path.end( ); ++pIt, ++i )
+ {
+ typename TImage::PointType p;
+ this->m_Image->TransformIndexToPhysicalPoint( *pIt, p );
+ if( TImage::ImageDimension == 1 )
+ points->InsertNextPoint( double( p[ 0 ] ), double( 0 ), double( 0 ) );
+ else if( TImage::ImageDimension == 2 )
+ points->InsertNextPoint( double( p[ 0 ] ), double( p[ 1 ] ), double( 0 ) );
+ else if( TImage::ImageDimension > 2 )
+ points->InsertNextPoint( double( p[ 0 ] ), double( p[ 1 ] ), double( p[ 2 ] ) );
+
+ if( i > 0 )
+ {
+ lines->InsertNextCell( 2 );
+ lines->InsertCellPoint( i - 1 );
+ lines->InsertCellPoint( i );
+
+ } // fi
+
+ } // rof
+ out->Modified( );
+ return( 1 );
+}
+
+// -------------------------------------------------------------------------
+template< class _TMinimumSpanningTree >
+int fpa::VTK::Image::PathToPolyDataFilter< _TMinimumSpanningTree >::
+RequestInformation(
+ vtkInformation* information,
+ vtkInformationVector** input,
+ vtkInformationVector* output
+ )
+{
+ vtkInformation* out = output->GetInformationObject( 0 );
+ out->Set( CAN_HANDLE_PIECE_REQUEST( ), 1 );
+ return( 1 );
+}
+
+// -------------------------------------------------------------------------
+template< class _TMinimumSpanningTree >
+void fpa::VTK::Image::PathToPolyDataFilter< _TMinimumSpanningTree >::
+_PrepareOutput( vtkPolyData* out )
+{
+ // Prepare points
+ vtkPoints* points = out->GetPoints( );
+ if( points == NULL )
+ {
+ points = vtkPoints::New( );
+ out->SetPoints( points );
+ points->Delete( );
+
+ } // fi
+
+ // Prepare points
+ vtkCellArray* lines = out->GetLines( );
+ if( lines == NULL )
+ {
+ lines = vtkCellArray::New( );
+ out->SetLines( lines );
+ out->SetVerts( vtkCellArray::New( ) );
+ out->SetPolys( vtkCellArray::New( ) );
+ out->SetStrips( vtkCellArray::New( ) );
+ lines->Delete( );
+
+ } // fi
+}
+
+#endif // __FPA__VTK__IMAGE__PATHTOPOLYDATAFILTER__HXX__
+
+// eof - $RCSfile$
--- /dev/null
+## ==========================
+## == Build plugin library ==
+## ==========================
+Wrap_cpPlugins(
+ _plugin
+ ${CMAKE_CURRENT_SOURCE_DIR}/Plugins
+ ${prj_VERSION} ${prj_SHORT_VERSION}
+ fpa
+ )
+TARGET_LINK_LIBRARIES(${_plugin} ${cpPlugins_LIB} ${fpa_Instances})
+
+## eof - $RCSfile$
--- /dev/null
+#include "BaseImageFilter.h"
+#include <cpPlugins/DataObjects/Image.h>
+
+// -------------------------------------------------------------------------
+bool fpaPlugins::BaseImageFilter::
+IsInteractive( )
+{
+ return( true );
+}
+
+// -------------------------------------------------------------------------
+/* TODO
+ void fpaPlugins::BaseImageFilter::
+ SetInteractionObjects( const std::vector< void* >& objs )
+ {
+ if( objs.size( ) > 0 )
+ this->m_SingleInteractor =
+ reinterpret_cast< vtkRenderWindowInteractor* >( objs[ 0 ] );
+ if( objs.size( ) > 1 )
+ this->m_MPRViewer = reinterpret_cast< TMPRWidget* >( objs[ 1 ] );
+ }
+*/
+
+// -------------------------------------------------------------------------
+fpaPlugins::BaseImageFilter::
+BaseImageFilter( )
+ : Superclass( )
+{
+ this->_ConfigureInput< cpPlugins::DataObjects::Image >( "Input", true, false );
+ this->_ConfigureInput< cpPlugins::BaseObjects::DataObject >( "Seeds", true, false );
+ this->_ConfigureOutput< cpPlugins::DataObjects::Image >( "Output" );
+
+ this->m_Parameters.ConfigureAsBool( "VisualDebug" );
+ this->m_Parameters.ConfigureAsBool( "StopAtOneFront" );
+ this->m_Parameters.SetBool( "VisualDebug", false );
+ this->m_Parameters.SetBool( "StopAtOneFront", false );
+
+ std::vector< std::string > orders;
+ orders.push_back( "1" );
+ orders.push_back( "2" );
+ this->m_Parameters.ConfigureAsChoices( "NeighborhoodOrder", orders );
+ this->m_Parameters.SetSelectedChoice( "NeighborhoodOrder", "1" );
+}
+
+// -------------------------------------------------------------------------
+fpaPlugins::BaseImageFilter::
+~BaseImageFilter( )
+{
+}
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __FPAPLUGINS__BASEIMAGEFILTER__H__
+#define __FPAPLUGINS__BASEIMAGEFILTER__H__
+
+#include <fpa/Config.h>
+#include <plugins/fpaPlugins_Export.h>
+#include <cpPlugins/BaseObjects/ProcessObject.h>
+
+#include <cpExtensions/QT/SimpleMPRWidget.h>
+#include <vtkRenderWindowInteractor.h>
+
+namespace fpaPlugins
+{
+ /**
+ */
+ class fpaPlugins_EXPORT BaseImageFilter
+ : public cpPlugins::BaseObjects::ProcessObject
+ {
+ public:
+ typedef BaseImageFilter Self;
+ typedef cpPlugins::BaseObjects::ProcessObject Superclass;
+ typedef itk::SmartPointer< Self > Pointer;
+ typedef itk::SmartPointer< const Self > ConstPointer;
+
+ typedef cpExtensions::QT::SimpleMPRWidget TMPRWidget;
+
+ public:
+ itkTypeMacro( BaseImageFilter, cpPlugins::BaseObjects::ProcessObject );
+ cpPlugins_Id_Macro( BaseImageFilter, fpaImageAlgorithm );
+
+ public:
+ virtual bool IsInteractive( ) fpa_OVERRIDE;
+ /* TODO
+ virtual void SetInteractionObjects(
+ const std::vector< void* >& objs
+ ) override;
+ */
+
+ protected:
+ BaseImageFilter( );
+ virtual ~BaseImageFilter( );
+
+ template< class _TFilter >
+ inline _TFilter* _ConfigureFilter( );
+
+ template< class _TFilter >
+ inline void _ExecuteFilter( _TFilter* filter );
+
+ template< class _TFilter >
+ inline void _ConfigureDebugger( _TFilter* filter );
+
+ template< class _TFilter >
+ inline void _DeconfigureDebugger( _TFilter* filter );
+
+ private:
+ // Purposely not implemented.
+ BaseImageFilter( const Self& other );
+ Self& operator=( const Self& other );
+
+ protected:
+ std::set< unsigned long > m_Observers;
+ };
+
+} // ecapseman
+
+#include "BaseImageFilter.hxx"
+
+#endif // __FPAPLUGINS__BASEIMAGEFILTER__H__
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __FPAPLUGINS__BASEIMAGEFILTER__HXX__
+#define __FPAPLUGINS__BASEIMAGEFILTER__HXX__
+
+#include <vtkPolyData.h>
+
+/* TODO
+ #include <fpa/VTK/Image/Observer2D.h>
+ #include <fpa/VTK/Image/Observer2D.hxx>
+*/
+#include <fpa/VTK/Image/Observer3D.h>
+#include <fpa/VTK/Image/Observer3D.hxx>
+
+// -------------------------------------------------------------------------
+template< class _TFilter >
+_TFilter* fpaPlugins::BaseImageFilter::
+_ConfigureFilter( )
+{
+ typedef typename _TFilter::TInputImage _TImage;
+ static const unsigned int Dim = _TImage::ImageDimension;
+
+ auto image = this->GetInputData< _TImage >( "Input" );
+ if( image == NULL )
+ return( NULL );
+ auto seeds = this->GetInputData< vtkPolyData >( "Seeds" )->GetPoints( );
+
+ // Create filter and connect input
+ auto filter = this->_CreateITK< _TFilter >( );
+ filter->SetInput( image );
+
+ // Set numeric parameters
+ filter->SetNeighborhoodOrder(
+ this->m_Parameters.GetSelectedChoice( "NeighborhoodOrder" )[ 0 ] - '0'
+ );
+ filter->SetStopAtOneFront( this->m_Parameters.GetBool( "StopAtOneFront" ) );
+
+ // Assign seeds
+ filter->RemoveAllSeeds( );
+ if( seeds != NULL )
+ {
+ typename _TImage::PointType pnt;
+ typename _TImage::IndexType idx;
+ unsigned int dim =
+ ( _TImage::ImageDimension < 3 )? _TImage::ImageDimension: 3;
+ for( unsigned int i = 0; i < seeds->GetNumberOfPoints( ); ++i )
+ {
+ double buf[ 3 ];
+ seeds->GetPoint( i, buf );
+ pnt.Fill( 0 );
+ for( unsigned int d = 0; d < dim; ++d )
+ pnt[ d ] = buf[ d ];
+
+ if( image->TransformPhysicalPointToIndex( pnt, idx ) )
+ filter->AddSeed( idx, 0 );
+
+ } // rof
+
+ } // fi
+
+ // Ok!
+ return( filter );
+}
+
+// -------------------------------------------------------------------------
+template< class _TFilter >
+void fpaPlugins::BaseImageFilter::
+_ExecuteFilter( _TFilter* filter )
+{
+ // Go!!!
+ this->_ConfigureDebugger( filter );
+ filter->Update( );
+ this->_DeconfigureDebugger( filter );
+
+ // Connect output
+ this->GetOutput( "Output" )->SetITK( filter->GetOutput( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TFilter >
+void fpaPlugins::BaseImageFilter::
+_ConfigureDebugger( _TFilter* filter )
+{
+ typedef typename _TFilter::TInputImage _TImage;
+ typedef fpa::VTK::Image::Observer3D< _TFilter, vtkRenderWindow > _3D;
+
+ /* TODO
+ typedef fpa::VTK::Image::Observer2D< _TFilter, vtkRenderWindow > _2D;
+ */
+
+ this->m_Observers.clear( );
+ if( this->m_Parameters.GetBool( "VisualDebug" ) )
+ {
+ if( _TImage::ImageDimension == 2 )
+ {
+ }
+ else if( _TImage::ImageDimension == 3 )
+ {
+ /* TODO
+ auto iren = this->m_MPRViewer->GetInteractor( 3 );
+ if( iren != NULL )
+ {
+ typename _3D::Pointer debugger = _3D::New( );
+ debugger->SetRenderWindow( iren->GetRenderWindow( ) );
+ debugger->SetRenderPercentage( 0.001 );
+ this->m_Observers.insert(
+ filter->AddObserver( itk::AnyEvent( ), debugger )
+ );
+ filter->ThrowEventsOn( );
+
+ } // fi
+ */
+
+ } // fi
+
+ /* TODO
+ if( this->m_SingleInteractor != NULL )
+ {
+ if( _TImage::ImageDimension == 2 )
+ {
+ }
+ else if( _TImage::ImageDimension == 3 )
+ {
+ } // fi
+
+ } // fi
+
+ */
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class F >
+void fpaPlugins::BaseImageFilter::
+_DeconfigureDebugger( F* filter )
+{
+ /* TODO
+ if( filter != NULL )
+ {
+ auto oIt = this->m_Observers.begin( );
+ for( ; oIt != this->m_Observers.end( ); ++oIt )
+ filter->RemoveObserver( *oIt );
+
+ } // fi
+ this->m_Observers.clear( );
+ */
+}
+
+#endif // __FPAPLUGINS__BASEIMAGEFILTER__HXX__
+
+// eof - $RCSfile$
--- /dev/null
+#include "GaussianCostFunctor.h"
+
+#include <fpa/Base/Functors/GaussianCost.h>
+#include <fpa/Base/Functors/GaussianCost.hxx>
+
+// -------------------------------------------------------------------------
+fpaPlugins::GaussianCostFunctor::
+GaussianCostFunctor( )
+ : Superclass( )
+{
+ this->_ConfigureOutput< cpPlugins::BaseObjects::DataObject >( "Output" );
+ this->_ConfigureOutput< cpPlugins::BaseObjects::DataObject >( "Estimator" );
+ std::vector< std::string > choices;
+ choices.push_back( "float" );
+ choices.push_back( "double" );
+ this->m_Parameters.ConfigureAsChoices( "ResultType", choices );
+ this->m_Parameters.SetSelectedChoice( "ResultType", "float" );
+ this->m_Parameters.ConfigureAsUint( "SupportSize" );
+ this->m_Parameters.ConfigureAsReal( "MinimumCost" );
+ this->m_Parameters.SetUint( "SupportSize", 30 );
+ this->m_Parameters.SetReal( "MinimumCost", 1e-5 );
+}
+
+// -------------------------------------------------------------------------
+fpaPlugins::GaussianCostFunctor::
+~GaussianCostFunctor( )
+{
+}
+
+// -------------------------------------------------------------------------
+void fpaPlugins::GaussianCostFunctor::
+_GenerateData( )
+{
+ auto rtype = this->m_Parameters.GetSelectedChoice( "ResultType" );
+ if ( rtype == "float" ) this->_GD0< float >( );
+ else if( rtype == "double" ) this->_GD0< double >( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TResult >
+void fpaPlugins::GaussianCostFunctor::
+_GD0( )
+{
+ typedef fpa::Base::Functors::GaussianCost< _TResult > _TFunctor;
+ auto out = this->GetOutput( "Output" );
+ auto f = out->GetITK< _TFunctor >( );
+ if( f == NULL )
+ {
+ typename _TFunctor::Pointer ptr_f = _TFunctor::New( );
+ f = ptr_f.GetPointer( );
+ out->SetITK( f );
+
+ } // fi
+ f->SetSupportSize( this->m_Parameters.GetUint( "SupportSize" ) );
+ f->SetMinimumCost( this->m_Parameters.GetReal( "MinimumCost" ) );
+ this->GetOutput( "Estimator" )->SetITK( f->GetModel( ) );
+}
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __FPAPLUGINS__GAUSSIANCOSTFUNCTOR__H__
+#define __FPAPLUGINS__GAUSSIANCOSTFUNCTOR__H__
+
+#include <plugins/fpaPlugins_Export.h>
+#include <cpPlugins/BaseObjects/ProcessObject.h>
+
+namespace fpaPlugins
+{
+ /**
+ */
+ class fpaPlugins_EXPORT GaussianCostFunctor
+ : public cpPlugins::BaseObjects::ProcessObject
+ {
+ cpPluginsObject(
+ GaussianCostFunctor,
+ cpPlugins::BaseObjects::ProcessObject,
+ fpaFunctors
+ );
+
+ protected:
+ template< class _TResult >
+ inline void _GD0( );
+ };
+
+} // ecapseman
+
+#endif // __FPAPLUGINS__GAUSSIANCOSTFUNCTOR__H__
+
+// eof - $RCSfile$
--- /dev/null
+#include "ImageDijkstra.h"
+// TODO: #include "MinimumSpanningTree.h"
+
+#include <cpPlugins/DataObjects/Image.h>
+#include <fpa/Image/Dijkstra.h>
+
+#include <fpa/Base/Algorithm.hxx>
+#include <fpa/Base/Dijkstra.hxx>
+#include <fpa/Image/Algorithm.hxx>
+#include <fpa/Image/Dijkstra.hxx>
+
+// -------------------------------------------------------------------------
+fpaPlugins::ImageDijkstra::
+ImageDijkstra( )
+ : Superclass( )
+{
+ this->_ConfigureInput< cpPlugins::BaseObjects::DataObject >( "CostFunctor", false, false );
+ this->_ConfigureOutput< cpPlugins::BaseObjects::DataObject >( "MST" );
+ std::vector< std::string > choices;
+ choices.push_back( "float" );
+ choices.push_back( "double" );
+ this->m_Parameters.ConfigureAsChoices( "ResultType", choices );
+ this->m_Parameters.SetSelectedChoice( "ResultType", "float" );
+ this->m_Parameters.ConfigureAsBool( "FillNodeQueue" );
+ this->m_Parameters.SetBool( "FillNodeQueue", false );
+}
+
+// -------------------------------------------------------------------------
+fpaPlugins::ImageDijkstra::
+~ImageDijkstra( )
+{
+}
+
+// -------------------------------------------------------------------------
+void fpaPlugins::ImageDijkstra::
+_GenerateData( )
+{
+ auto o = this->GetInputData( "Input" );
+ cpPlugins_Demangle_ImageScalars_Dims( o, _GD0 );
+ else this->_Error( "Invalid input image." );
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage >
+void fpaPlugins::ImageDijkstra::
+_GD0( _TImage* image )
+{
+ auto rtype = this->m_Parameters.GetSelectedChoice( "ResultType" );
+ if( rtype == "float" ) this->_GD1< _TImage, float >( image );
+ else if( rtype == "double" ) this->_GD1< _TImage, double >( image );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutput >
+void fpaPlugins::ImageDijkstra::
+_GD1( _TInputImage* input )
+{
+ typedef itk::Image< _TOutput, _TInputImage::ImageDimension > _TOutputImage;
+ typedef fpa::Image::Dijkstra< _TInputImage, _TOutputImage > _TFilter;
+ typedef typename _TFilter::TCostConversionFunction _TCostFunctor;
+
+ // Get functor
+ auto base_functor =
+ this->GetInputData< itk::LightObject >( "CostFunctor" );
+ _TCostFunctor* functor = NULL;
+ if( base_functor != NULL )
+ {
+ functor = dynamic_cast< _TCostFunctor* >( base_functor );
+ if( functor == NULL )
+ this->_Error( "Given cost functor is invalid." );
+
+ } // fi
+
+ // Create filter
+ _TFilter* filter = this->_ConfigureFilter< _TFilter >( );
+ // TODO: filter->SetFillNodeQueue( this->m_Parameters.GetBool( "FillNodeQueue" ) );
+ filter->SetCostConversionFunction( functor );
+
+ // Go!!!
+ this->_ExecuteFilter( filter );
+
+ // Connect remaining output
+ this->GetOutput( "MST" )->SetITK( filter->GetMinimumSpanningTree( ) );
+}
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __FPAPLUGINS__IMAGEDIJKSTRA__H__
+#define __FPAPLUGINS__IMAGEDIJKSTRA__H__
+
+#include "BaseImageFilter.h"
+
+namespace fpaPlugins
+{
+ /**
+ */
+ class fpaPlugins_EXPORT ImageDijkstra
+ : public BaseImageFilter
+ {
+ cpPluginsObject( ImageDijkstra, BaseImageFilter, fpa );
+
+ protected:
+ template< class _TImage >
+ inline void _GD0( _TImage* image );
+
+ template< class _TInputImage, class _TOutput >
+ inline void _GD1( _TInputImage* input );
+ };
+
+} // ecapseman
+
+#endif // __FPAPLUGINS__IMAGEDIJKSTRA__H__
+
+// eof - $RCSfile$
--- /dev/null
+#include "ImagePathToPolyDataFilter.h"
+#include <cpPlugins/DataObjects/Image.h>
+#include <cpPlugins/DataObjects/Mesh.h>
+#include <fpa/Base/MinimumSpanningTree.h>
+#include <fpa/VTK/Image/PathToPolyDataFilter.h>
+#include <fpa/VTK/Image/PathToPolyDataFilter.hxx>
+
+// -------------------------------------------------------------------------
+fpaPlugins::ImagePathToPolyDataFilter::
+ImagePathToPolyDataFilter( )
+ : Superclass( )
+{
+ this->_ConfigureInput< cpPlugins::BaseObjects::DataObject >( "MST", true, false );
+ this->_ConfigureInput< cpPlugins::DataObjects::Image >( "Image", true, false );
+ this->_ConfigureInput< cpPlugins::BaseObjects::DataObject >( "Seeds", true, false );
+ this->_ConfigureOutput< cpPlugins::DataObjects::Mesh >( "Output" );
+
+ this->m_Parameters.ConfigureAsUint( "Seed0" );
+ this->m_Parameters.ConfigureAsUint( "Seed1" );
+ this->m_Parameters.SetUint( "Seed0", 0 );
+ this->m_Parameters.SetUint( "Seed1", 1 );
+}
+
+// -------------------------------------------------------------------------
+fpaPlugins::ImagePathToPolyDataFilter::
+~ImagePathToPolyDataFilter( )
+{
+}
+
+// -------------------------------------------------------------------------
+void fpaPlugins::ImagePathToPolyDataFilter::
+_GenerateData( )
+{
+ auto i2 = this->GetInputData< itk::ImageBase< 2 > >( "Image" );
+ auto i3 = this->GetInputData< itk::ImageBase< 3 > >( "Image" );
+ if( i2 != NULL )
+ this->_GD0( i2 );
+ else if( i3 != NULL )
+ this->_GD0( i3 );
+ else
+ this->_Error( "No valid input image." );
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage >
+void fpaPlugins::ImagePathToPolyDataFilter::
+_GD0( _TImage* image )
+{
+ typedef typename _TImage::IndexType _TIndex;
+ typedef typename _TIndex::LexicographicCompare _TComp;
+ typedef fpa::Base::MinimumSpanningTree< _TIndex, float, _TComp > _TFloat;
+ typedef fpa::Base::MinimumSpanningTree< _TIndex, double, _TComp > _TDouble;
+
+ auto mf = this->GetInputData< _TFloat >( "MST" );
+ auto md = this->GetInputData< _TDouble >( "MST" );
+ if( mf != NULL )
+ this->_GD1( image, mf );
+ else if( md != NULL )
+ this->_GD1( image, md );
+ else
+ this->_Error( "No valid input minimum spanning tree." );
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage, class _TMST >
+void fpaPlugins::ImagePathToPolyDataFilter::
+_GD1( _TImage* image, _TMST* mst )
+{
+ typedef fpa::VTK::Image::PathToPolyDataFilter< _TMST > _TFilter;
+ auto seeds = this->GetInputData< vtkPolyData >( "Seeds" )->GetPoints( );
+ if( seeds->GetNumberOfPoints( ) < 2 )
+ this->_Error( "Not enough seeds." );
+
+ auto filter = this->_CreateVTK< _TFilter >( );
+ filter->SetImage( image );
+ filter->SetMinimumSpanningTree( mst );
+
+ typename _TImage::PointType pnt;
+ typename _TImage::IndexType idx;
+ unsigned int dim =
+ ( _TImage::ImageDimension < 3 )? _TImage::ImageDimension: 3;
+ double buf[ 3 ];
+ seeds->GetPoint( this->m_Parameters.GetUint( "Seed0" ), buf );
+ pnt.Fill( 0 );
+ for( unsigned int d = 0; d < dim; ++d )
+ pnt[ d ] = buf[ d ];
+ if( image->TransformPhysicalPointToIndex( pnt, idx ) )
+ filter->SetSeed0( idx );
+ seeds->GetPoint( this->m_Parameters.GetUint( "Seed1" ), buf );
+ pnt.Fill( 0 );
+ for( unsigned int d = 0; d < dim; ++d )
+ pnt[ d ] = buf[ d ];
+ if( image->TransformPhysicalPointToIndex( pnt, idx ) )
+ filter->SetSeed1( idx );
+ filter->Update( );
+ this->GetOutput( "Output" )->SetVTK( filter->GetOutput( ) );
+}
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __FPAPLUGINS__IMAGEPATHTOPOLYDATAFILTER__H__
+#define __FPAPLUGINS__IMAGEPATHTOPOLYDATAFILTER__H__
+
+#include <plugins/fpaPlugins_Export.h>
+#include <cpPlugins/BaseObjects/ProcessObject.h>
+
+namespace fpaPlugins
+{
+ /**
+ */
+ class fpaPlugins_EXPORT ImagePathToPolyDataFilter
+ : public cpPlugins::BaseObjects::ProcessObject
+ {
+ cpPluginsObject(
+ ImagePathToPolyDataFilter,
+ cpPlugins::BaseObjects::ProcessObject,
+ fpaImageAlgorithm
+ );
+
+ protected:
+ template< class _TImage >
+ inline void _GD0( _TImage* image );
+
+ template< class _TImage, class _TMST >
+ inline void _GD1( _TImage* image, _TMST* mst );
+ };
+
+} // ecapseman
+
+#endif // __FPAPLUGINS__IMAGEPATHTOPOLYDATAFILTER__H__
+
+// eof - $RCSfile$
--- /dev/null
+#include "InvertCostFunctor.h"
+
+#include <fpa/Base/Functors/InvertCost.h>
+#include <fpa/Base/Functors/InvertCost.hxx>
+
+// -------------------------------------------------------------------------
+fpaPlugins::InvertCostFunctor::
+InvertCostFunctor( )
+ : Superclass( )
+{
+ this->_ConfigureOutput< cpPlugins::BaseObjects::DataObject >( "Output" );
+ std::vector< std::string > choices;
+ choices.push_back( "float" );
+ choices.push_back( "double" );
+ this->m_Parameters.ConfigureAsChoices( "ResultType", choices );
+ this->m_Parameters.SetSelectedChoice( "ResultType", "float" );
+}
+
+// -------------------------------------------------------------------------
+fpaPlugins::InvertCostFunctor::
+~InvertCostFunctor( )
+{
+}
+
+// -------------------------------------------------------------------------
+void fpaPlugins::InvertCostFunctor::
+_GenerateData( )
+{
+ auto rtype = this->m_Parameters.GetSelectedChoice( "ResultType" );
+ if ( rtype == "float" ) this->_GD0< float >( );
+ else if( rtype == "double" ) this->_GD0< double >( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TResult >
+void fpaPlugins::InvertCostFunctor::
+_GD0( )
+{
+ typedef fpa::Base::Functors::InvertCost< _TResult > _TFunctor;
+ auto out = this->GetOutput( "Output" );
+ auto f = out->GetITK< _TFunctor >( );
+ if( f == NULL )
+ {
+ typename _TFunctor::Pointer ptr_f = _TFunctor::New( );
+ f = ptr_f.GetPointer( );
+ out->SetITK( f );
+
+ } // fi
+}
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __FPAPLUGINS__INVERTCOSTFUNCTOR__H__
+#define __FPAPLUGINS__INVERTCOSTFUNCTOR__H__
+
+#include <plugins/fpaPlugins_Export.h>
+#include <cpPlugins/BaseObjects/ProcessObject.h>
+
+namespace fpaPlugins
+{
+ /**
+ */
+ class fpaPlugins_EXPORT InvertCostFunctor
+ : public cpPlugins::BaseObjects::ProcessObject
+ {
+ cpPluginsObject(
+ InvertCostFunctor,
+ cpPlugins::BaseObjects::ProcessObject,
+ fpaFunctors
+ );
+
+ protected:
+ template< class _TResult >
+ inline void _GD0( );
+ };
+
+} // ecapseman
+
+#endif // __FPAPLUGINS__INVERTCOSTFUNCTOR__H__
+
+// eof - $RCSfile$
--- /dev/null
+#include "MultiplyImageAndDistanceMap.h"
+#include <cpPlugins/DataObjects/Image.h>
+
+#include <fpa/Image/MultiplyImageAndDistanceMap.h>
+#include <fpa/Image/MultiplyImageAndDistanceMap.hxx>
+
+/* TODO
+ #include <fpa/Image/Dijkstra.h>
+ #include <fpa/Base/Algorithm.hxx>
+ #include <fpa/Base/Dijkstra.hxx>
+ #include <fpa/Image/Algorithm.hxx>
+ #include <fpa/Image/Dijkstra.hxx>
+*/
+
+// -------------------------------------------------------------------------
+fpaPlugins::MultiplyImageAndDistanceMap::
+MultiplyImageAndDistanceMap( )
+ : Superclass( )
+{
+ typedef cpPlugins::DataObjects::Image _TImage;
+ this->_ConfigureInput< _TImage >( "Input", true, false );
+ this->_ConfigureInput< _TImage >( "DistanceMap", true, false );
+ this->_ConfigureOutput< _TImage >( "Output" );
+
+ /* TODO
+ this->_ConfigureOutput< cpPlugins::BaseObjects::DataObject >( "MST" );
+ std::vector< std::string > choices;
+ choices.push_back( "float" );
+ choices.push_back( "double" );
+ this->m_Parameters.ConfigureAsChoices( "ResultType", choices );
+ this->m_Parameters.SetSelectedChoice( "ResultType", "float" );
+ this->m_Parameters.ConfigureAsBool( "FillNodeQueue" );
+ this->m_Parameters.SetBool( "FillNodeQueue", false );
+ */
+}
+
+// -------------------------------------------------------------------------
+fpaPlugins::MultiplyImageAndDistanceMap::
+~MultiplyImageAndDistanceMap( )
+{
+}
+
+// -------------------------------------------------------------------------
+void fpaPlugins::MultiplyImageAndDistanceMap::
+_GenerateData( )
+{
+ auto o = this->GetInputData( "Input" );
+ cpPlugins_Demangle_ImageScalars_Dims( o, _GD0 );
+ else this->_Error( "Invalid input image." );
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage >
+void fpaPlugins::MultiplyImageAndDistanceMap::
+_GD0( _TImage* image )
+{
+ typedef itk::Image< float, _TImage::ImageDimension > _TFloat;
+ typedef itk::Image< double, _TImage::ImageDimension > _TDouble;
+
+ auto f = this->GetInputData< _TFloat >( "DistanceMap" );
+ auto d = this->GetInputData< _TDouble >( "DistanceMap" );
+ if ( f != NULL ) this->_GD1( image, f );
+ else if( d != NULL ) this->_GD1( image, d );
+ else this->_Error( "Invalid distance map." );
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage, class _TDistanceMap >
+ void fpaPlugins::MultiplyImageAndDistanceMap::
+_GD1( _TImage* input, _TDistanceMap* dmap )
+{
+ typedef fpa::Image::MultiplyImageAndDistanceMap< _TImage, _TDistanceMap > _TFilter;
+
+ auto filter = this->_CreateITK< _TFilter >( );
+ filter->SetInput( input );
+ filter->SetDistanceMap( dmap );
+ filter->Update( );
+ this->GetOutput( "Output" )->SetITK( filter->GetOutput( ) );
+}
+
+// eof - $RCSfile$
--- /dev/null
+#ifndef __fpaPlugins__MultiplyImageAndDistanceMap__h__
+#define __fpaPlugins__MultiplyImageAndDistanceMap__h__
+
+#include <fpa/Config.h>
+#include <plugins/fpaPlugins_Export.h>
+#include <cpPlugins/BaseObjects/ProcessObject.h>
+
+namespace fpaPlugins
+{
+ /**
+ */
+ class fpaPlugins_EXPORT MultiplyImageAndDistanceMap
+ : public cpPlugins::BaseObjects::ProcessObject
+ {
+ cpPluginsObject(
+ MultiplyImageAndDistanceMap, cpPlugins::BaseObjects::ProcessObject, fpa
+ );
+
+ protected:
+ template< class _TImage >
+ inline void _GD0( _TImage* image );
+
+ template< class _TImage, class _TDistanceMap >
+ inline void _GD1( _TImage* input, _TDistanceMap* dmap );
+ };
+
+} // ecapseman
+
+#endif // __fpaPlugins__MultiplyImageAndDistanceMap__h__
+
+// eof - $RCSfile$