]> Creatis software - FrontAlgorithms.git/commitdiff
...
authorLeonardo Flórez-Valencia <florez-l@javeriana.edu.co>
Tue, 4 Oct 2016 13:11:09 +0000 (08:11 -0500)
committerLeonardo Flórez-Valencia <florez-l@javeriana.edu.co>
Tue, 4 Oct 2016 13:11:09 +0000 (08:11 -0500)
54 files changed:
CMakeLists.txt [new file with mode: 0644]
appli/CMakeLists.txt [new file with mode: 0644]
appli/examples/CMakeLists.txt [new file with mode: 0644]
appli/examples/ImageDijkstra.cxx [new file with mode: 0644]
cmake/DetectOS.cmake [new file with mode: 0644]
cmake/Functions.cmake [new file with mode: 0644]
cmake/KitwareTools.cmake [new file with mode: 0644]
cmake/Options.cmake [new file with mode: 0644]
cmake/Qt4Tools.cmake [new file with mode: 0644]
cmake/Restrictions.cmake [new file with mode: 0644]
lib/CMakeLists.txt [new file with mode: 0644]
lib/Instances/CMakeLists.txt [new file with mode: 0644]
lib/Instances/fpa_DataObjects.i [new file with mode: 0644]
lib/Instances/fpa_Filters.i [new file with mode: 0644]
lib/fpa/Base/Algorithm.h [new file with mode: 0644]
lib/fpa/Base/Algorithm.hxx [new file with mode: 0644]
lib/fpa/Base/Dijkstra.h [new file with mode: 0644]
lib/fpa/Base/Dijkstra.hxx [new file with mode: 0644]
lib/fpa/Base/DijkstraCostFunctionBase.h [new file with mode: 0644]
lib/fpa/Base/Events.h [new file with mode: 0644]
lib/fpa/Base/Functors/GaussianModel.h [new file with mode: 0644]
lib/fpa/Base/Functors/GaussianModel.hxx [new file with mode: 0644]
lib/fpa/Base/Functors/Inverse.h [new file with mode: 0644]
lib/fpa/Base/Functors/Inverse.hxx [new file with mode: 0644]
lib/fpa/Base/MinimumSpanningTree.h [new file with mode: 0644]
lib/fpa/Base/MinimumSpanningTree.hxx [new file with mode: 0644]
lib/fpa/Config.cxx [new file with mode: 0644]
lib/fpa/Config.h.in [new file with mode: 0644]
lib/fpa/Image/Algorithm.h [new file with mode: 0644]
lib/fpa/Image/Algorithm.hxx [new file with mode: 0644]
lib/fpa/Image/Dijkstra.h [new file with mode: 0644]
lib/fpa/Image/Dijkstra.hxx [new file with mode: 0644]
lib/fpa/Image/Functors/Base.h [new file with mode: 0644]
lib/fpa/Image/Functors/SimpleDijkstraCost.h [new file with mode: 0644]
lib/fpa/Image/Functors/SimpleDijkstraCost.hxx [new file with mode: 0644]
lib/fpa/Image/Functors/SimpleNeighborhood.h [new file with mode: 0644]
lib/fpa/Image/Functors/SimpleNeighborhood.hxx [new file with mode: 0644]
lib/fpa/Image/MinimumSpanningTree.h [new file with mode: 0644]
lib/fpa/Image/MinimumSpanningTree.hxx [new file with mode: 0644]
plugins/CMakeLists.txt [new file with mode: 0644]
plugins/Plugins/BaseImageFilter.cxx [new file with mode: 0644]
plugins/Plugins/BaseImageFilter.h [new file with mode: 0644]
plugins/Plugins/ExtractPathFromMinimumSpanningTree.cxx [new file with mode: 0644]
plugins/Plugins/ExtractPathFromMinimumSpanningTree.h [new file with mode: 0644]
plugins/Plugins/GaussianModelCost.cxx [new file with mode: 0644]
plugins/Plugins/GaussianModelCost.h [new file with mode: 0644]
plugins/Plugins/ImageDijkstra.cxx [new file with mode: 0644]
plugins/Plugins/ImageDijkstra.h [new file with mode: 0644]
plugins/Plugins/InvertCost.cxx [new file with mode: 0644]
plugins/Plugins/InvertCost.h [new file with mode: 0644]
plugins/Plugins/SimpleImageDijkstraCost.cxx [new file with mode: 0644]
plugins/Plugins/SimpleImageDijkstraCost.h [new file with mode: 0644]
plugins/Plugins/SimpleImageNeighborhood.cxx [new file with mode: 0644]
plugins/Plugins/SimpleImageNeighborhood.h [new file with mode: 0644]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..0d6fd70
--- /dev/null
@@ -0,0 +1,69 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 3.0)
+
+## ========================
+## == 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 plugins appli)
+
+## eof - $RCSfile$
diff --git a/appli/CMakeLists.txt b/appli/CMakeLists.txt
new file mode 100644 (file)
index 0000000..a5a2028
--- /dev/null
@@ -0,0 +1,6 @@
+OPTION(BUILD_EXAMPLES "Build simple examples" OFF)
+IF(BUILD_EXAMPLES)
+  SUBDIRS(examples)
+ENDIF(BUILD_EXAMPLES)
+
+## eof - $RCSfile$
diff --git a/appli/examples/CMakeLists.txt b/appli/examples/CMakeLists.txt
new file mode 100644 (file)
index 0000000..861b670
--- /dev/null
@@ -0,0 +1,4 @@
+ADD_EXECUTABLE(fpa_examples_ImageDijkstra ImageDijkstra.cxx)
+TARGET_LINK_LIBRARIES(fpa_examples_ImageDijkstra ${ITK_LIBRARIES})
+
+## eof - $RCSfile$
diff --git a/appli/examples/ImageDijkstra.cxx b/appli/examples/ImageDijkstra.cxx
new file mode 100644 (file)
index 0000000..1b56263
--- /dev/null
@@ -0,0 +1,69 @@
+#include <itkImage.h>
+#include <itkRandomImageSource.h>
+#include <itkImageFileWriter.h>
+
+#include <fpa/Image/Functors/SimpleNeighborhood.h>
+#include <fpa/Image/Functors/SimpleDijkstraCost.h>
+#include <fpa/Base/Functors/Inverse.h>
+#include <fpa/Image/Dijkstra.h>
+
+// -------------------------------------------------------------------------
+static const unsigned int VDim = 2;
+typedef float TScalar;
+typedef itk::Image< unsigned char, VDim > TInputImage;
+typedef itk::Image< TScalar, VDim > TOutputImage;
+
+typedef itk::RandomImageSource< TInputImage > TImageSource;
+typedef itk::ImageFileWriter< TOutputImage >  TImageWriter;
+
+typedef fpa::Image::Functors::SimpleNeighborhood< TInputImage > TNeighFunction;
+typedef fpa::Image::Functors::SimpleDijkstraCost< TInputImage, TScalar > TCostFunction;
+typedef fpa::Base::Functors::Inverse< TScalar, TScalar > TCostConversionFunction;
+
+typedef fpa::Image::Dijkstra< TInputImage, TOutputImage > TFilter;
+
+// -------------------------------------------------------------------------
+int main( int argc, char* argv[] )
+{
+  static const unsigned long SIZE = 100;
+  unsigned long size[] = { SIZE, SIZE };
+
+  unsigned int neigh_order = 1;
+  TInputImage::IndexType seed0, seed1;
+
+  seed0.Fill( 0 );
+  seed1.Fill( SIZE - 1 );
+
+  TImageSource::Pointer source = TImageSource::New( );
+  source->SetSize( size );
+  source->SetSpacing( 1 );
+  source->Update( );
+  TInputImage::Pointer input = source->GetOutput( );
+
+  TNeighFunction::Pointer neigh_function = TNeighFunction::New( );
+  neigh_function->SetOrder( neigh_order );
+
+  TCostFunction::Pointer cost_function = TCostFunction::New( );
+
+  TCostConversionFunction::Pointer cost_conversion_function =
+    TCostConversionFunction::New( );
+
+  TFilter::Pointer filter = TFilter::New( );
+  filter->SetInput( input );
+  filter->SetNeighborhoodFunction( neigh_function );
+  filter->SetCostFunction( cost_function );
+  filter->SetCostConversionFunction( cost_conversion_function );
+  filter->AddSeed( seed0, 0 );
+  filter->AddSeed( seed1, 0 );
+  filter->StopAtOneFrontOn( );
+  filter->Update( );
+
+  TImageWriter::Pointer writer = TImageWriter::New( );
+  writer->SetInput( filter->GetOutput( ) );
+  writer->SetFileName( "dijkstra.mhd" );
+  writer->Update( );
+
+  return( 0 );
+}
+
+// eof - $RCSfile$
diff --git a/cmake/DetectOS.cmake b/cmake/DetectOS.cmake
new file mode 100644 (file)
index 0000000..bba8346
--- /dev/null
@@ -0,0 +1,23 @@
+## =====================
+## == 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$
diff --git a/cmake/Functions.cmake b/cmake/Functions.cmake
new file mode 100644 (file)
index 0000000..f5a90f3
--- /dev/null
@@ -0,0 +1,453 @@
+## -------------------------------------------------------------------------
+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$
diff --git a/cmake/KitwareTools.cmake b/cmake/KitwareTools.cmake
new file mode 100644 (file)
index 0000000..a120bb2
--- /dev/null
@@ -0,0 +1,19 @@
+# ======================
+# == 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$
diff --git a/cmake/Options.cmake b/cmake/Options.cmake
new file mode 100644 (file)
index 0000000..63990d9
--- /dev/null
@@ -0,0 +1,13 @@
+## ===============================
+## == 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$
diff --git a/cmake/Qt4Tools.cmake b/cmake/Qt4Tools.cmake
new file mode 100644 (file)
index 0000000..16a0103
--- /dev/null
@@ -0,0 +1,12 @@
+## ==================================================
+## == 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$
diff --git a/cmake/Restrictions.cmake b/cmake/Restrictions.cmake
new file mode 100644 (file)
index 0000000..d177604
--- /dev/null
@@ -0,0 +1,51 @@
+## =======================================================================
+## == 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$
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
new file mode 100644 (file)
index 0000000..f2f2463
--- /dev/null
@@ -0,0 +1,20 @@
+## ======================================
+## == Build a library from a directory ==
+## ======================================
+
+LibFromDir(
+  fpa
+  SHARED
+  ${CMAKE_CURRENT_SOURCE_DIR}/fpa
+  "${prj_VERSION}" "${prj_SHORT_VERSION}"
+  )
+
+## ===================================
+## == Build instances for cpPlugins ==
+## ===================================
+
+IF(USE_cpPlugins)
+  SUBDIRS(Instances)
+ENDIF(USE_cpPlugins)
+
+## eof - $RCSfile$
diff --git a/lib/Instances/CMakeLists.txt b/lib/Instances/CMakeLists.txt
new file mode 100644 (file)
index 0000000..be886cb
--- /dev/null
@@ -0,0 +1,40 @@
+## ===========================
+## == Compile each instance ==
+## ===========================
+
+FILE(GLOB _instances "${CMAKE_CURRENT_SOURCE_DIR}/*.i")
+SET(_all_instances)
+FOREACH(_instance ${_instances})
+  CompileInstances(
+    _lib_name
+    ${_instance} ${cpPlugins_NUMBER_OF_FILES}
+    "" "${prj_VERSION}" "${prj_SHORT_VERSION}"
+    )
+  LIST(APPEND _all_instances ${_lib_name})
+ENDFOREACH(_instance)
+SET(
+  fpa_Instances ${_all_instances}
+  CACHE INTERNAL "All valid instances." FORCE
+  )
+
+## ===========
+## == Links ==
+## ===========
+
+TARGET_LINK_LIBRARIES(fpa_DataObjects ${cpPlugins_Images_LIB})
+TARGET_LINK_LIBRARIES(fpa_Filters fpa_DataObjects ${cpPlugins_ImageFilters_LIB})
+
+## ===================================
+## == Libraries to dynamically load ==
+## ===================================
+
+SET(fpa_DynLibs)
+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)
+
+## eof - $RCSfile$
diff --git a/lib/Instances/fpa_DataObjects.i b/lib/Instances/fpa_DataObjects.i
new file mode 100644 (file)
index 0000000..aee14d6
--- /dev/null
@@ -0,0 +1,8 @@
+
+t fpa/Image/MinimumSpanningTree
+t fpa/Base/MinimumSpanningTree
+
+c fpa::Base::MinimumSpanningTree< itk::Index< #process_dims# >, itk::Image< itk::Offset< #process_dims# >, #process_dims# > >
+c fpa::Image::MinimumSpanningTree< #process_dims# >
+
+** eof - $RCSfile$
\ No newline at end of file
diff --git a/lib/Instances/fpa_Filters.i b/lib/Instances/fpa_Filters.i
new file mode 100644 (file)
index 0000000..70dc94d
--- /dev/null
@@ -0,0 +1,12 @@
+
+d i_pixels=#pixels#
+d o_pixels=#pixels#
+
+i cpPlugins_Images.h
+t fpa/Base/Algorithm
+t fpa/Image/Algorithm
+
+c fpa::Base::Algorithm< itk::ImageToImageFilter< itk::Image< #i_pixels#, #process_dims# >, itk::Image< #o_pixels#, #process_dims# > >, itk::Index< #process_dims# >, #o_pixels# >
+c fpa::Image::Algorithm< itk::Image< #i_pixels#, #process_dims# >, itk::Image< #o_pixels#, #process_dims# > >
+
+** eof - $RCSfile$
\ No newline at end of file
diff --git a/lib/fpa/Base/Algorithm.h b/lib/fpa/Base/Algorithm.h
new file mode 100644 (file)
index 0000000..662bdf1
--- /dev/null
@@ -0,0 +1,128 @@
+#ifndef __fpa__Base__Algorithm__h__
+#define __fpa__Base__Algorithm__h__
+
+#include <vector>
+#include <itkFunctionBase.h>
+#include <fpa/Config.h>
+#include <fpa/Base/Events.h>
+
+namespace fpa
+{
+  namespace Base
+  {
+    /**
+     */
+    template< class _TFilter, class _TVertex, class _TOutput >
+    class Algorithm
+      : public _TFilter
+    {
+    public:
+      typedef Algorithm                       Self;
+      typedef _TFilter                        Superclass;
+      typedef itk::SmartPointer< Self >       Pointer;
+      typedef itk::SmartPointer< const Self > ConstPointer;
+
+      typedef _TVertex      TVertex;
+      typedef _TOutput      TOutput;
+      typedef unsigned long TFrontId;
+
+      // Different functions
+      typedef std::vector< TVertex >                      TNeighborhood;
+      typedef itk::FunctionBase< TVertex, TNeighborhood > TNeighborhoodFunction;
+
+      // Minigraph to represent collisions
+      typedef std::pair< _TVertex, bool >   TCollision;
+      typedef std::vector< TCollision >     TCollisionsRow;
+      typedef std::vector< TCollisionsRow > TCollisions;
+
+    protected:
+      struct _TQueueNode
+      {
+        TVertex  Vertex;
+        TVertex  Parent;
+        TOutput  Result;
+        TFrontId FrontId;
+        _TQueueNode( );
+        _TQueueNode( const TVertex& v );
+        _TQueueNode( const TVertex& v, const _TQueueNode& n );
+      };
+
+    public:
+      itkTypeMacro( Self, _TFilter );
+
+      fpa_Base_NewEvent( TStartEvent );
+      fpa_Base_NewEvent( TEndEvent );
+      fpa_Base_NewEvent( TStartLoopEvent );
+      fpa_Base_NewEvent( TEndLoopEvent );
+      fpa_Base_NewEventWithVertex( TPushEvent, TVertex );
+      fpa_Base_NewEventWithVertex( TPopEvent, TVertex );
+      fpa_Base_NewEventWithVertex( TMarkEvent, TVertex );
+
+      itkGetConstMacro( InitResult, _TOutput );
+      itkSetMacro( InitResult, _TOutput );
+
+      itkBooleanMacro( StopAtOneFront );
+      itkGetConstMacro( StopAtOneFront, bool );
+      itkSetMacro( StopAtOneFront, bool );
+
+      itkGetObjectMacro( NeighborhoodFunction, TNeighborhoodFunction );
+      itkSetObjectMacro( NeighborhoodFunction, TNeighborhoodFunction );
+
+    public:
+      void AddSeed( const TVertex& seed, const TOutput& value );
+
+    protected:
+      Algorithm( );
+      virtual ~Algorithm( );
+
+      virtual void GenerateData( ) fpa_OVERRIDE;
+
+      // Particular methods
+      virtual void _Loop( );
+
+      virtual void _BeforeGenerateData( );
+      virtual void _AfterGenerateData( );
+      virtual void _BeforeLoop( );
+      virtual void _AfterLoop( );
+
+      virtual bool _ValidLoop( ) const;
+      virtual void _UpdateCollisions( const TVertex& a, const TVertex& b );
+
+      virtual void _InitMarks( ) = 0;
+      virtual void _InitResults( const TOutput& init_value ) = 0;
+      virtual bool _IsMarked( const _TVertex& v ) const = 0;
+      virtual void _Mark( const _TQueueNode& n ) = 0;
+      virtual TFrontId _GetMark( const _TVertex& v ) const = 0;
+      virtual void _UpdateResult( const _TQueueNode& n ) = 0;
+
+      virtual bool _UpdateValue( _TQueueNode& v, const _TQueueNode& p ) = 0;
+      virtual unsigned long _QueueSize( ) const = 0;
+      virtual void _QueueClear( ) = 0;
+      virtual void _QueuePush( const _TQueueNode& node ) = 0;
+      virtual _TQueueNode _QueuePop( ) = 0;
+
+    private:
+      // Purposely not implemented.
+      Algorithm( const Self& other );
+      Self& operator=( const Self& other );
+
+    protected:
+      _TOutput m_InitResult;
+      bool m_StopAtOneFront;
+      typename TNeighborhoodFunction::Pointer m_NeighborhoodFunction;
+      std::vector< _TQueueNode > m_Seeds;
+      TCollisions m_Collisions;
+      unsigned int m_NumberOfFronts;
+    };
+
+  } // ecaseman
+
+} // ecaseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#  include <fpa/Base/Algorithm.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Base__Algorithm__h__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/Base/Algorithm.hxx b/lib/fpa/Base/Algorithm.hxx
new file mode 100644 (file)
index 0000000..4ad828c
--- /dev/null
@@ -0,0 +1,237 @@
+#ifndef __fpa__Base__Algorithm__hxx__
+#define __fpa__Base__Algorithm__hxx__
+
+#include <queue>
+
+// -------------------------------------------------------------------------
+template < class _TFilter, class _TVertex, class _TOutput >
+fpa::Base::Algorithm< _TFilter, _TVertex, _TOutput >::_TQueueNode::
+_TQueueNode( )
+{
+  this->Vertex.Fill( 0 );
+  this->Parent.Fill( 0 );
+  this->Result = _TOutput( 0 );
+  this->FrontId = 0;
+}
+
+// -------------------------------------------------------------------------
+template < class _TFilter, class _TVertex, class _TOutput >
+fpa::Base::Algorithm< _TFilter, _TVertex, _TOutput >::_TQueueNode::
+_TQueueNode( const _TVertex& v )
+{
+  this->Vertex = v;
+  this->Parent = v;
+  this->Result = _TOutput( 0 );
+  this->FrontId = 0;
+}
+
+// -------------------------------------------------------------------------
+template < class _TFilter, class _TVertex, class _TOutput >
+fpa::Base::Algorithm< _TFilter, _TVertex, _TOutput >::_TQueueNode::
+_TQueueNode( const _TVertex& v, const _TQueueNode& n )
+{
+  this->Vertex = v;
+  this->Parent = n.Vertex;
+  this->Result = n.Result;
+  this->FrontId = n.FrontId;
+}
+
+// -------------------------------------------------------------------------
+template < class _TFilter, class _TVertex, class _TOutput >
+void fpa::Base::Algorithm< _TFilter, _TVertex, _TOutput >::
+AddSeed( const _TVertex& seed, const TOutput& value )
+{
+  _TQueueNode node( seed );
+  node.FrontId = this->m_Seeds.size( ) + 1;
+  node.Result = value;
+  this->m_Seeds.push_back( node );
+  this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template < class _TFilter, class _TVertex, class _TOutput >
+fpa::Base::Algorithm< _TFilter, _TVertex, _TOutput >::
+Algorithm( )
+  : Superclass( ),
+    m_InitResult( _TOutput( 0 ) ),
+    m_StopAtOneFront( false )
+{
+}
+
+// -------------------------------------------------------------------------
+template < class _TFilter, class _TVertex, class _TOutput >
+fpa::Base::Algorithm< _TFilter, _TVertex, _TOutput >::
+~Algorithm( )
+{
+}
+
+// -------------------------------------------------------------------------
+template < class _TFilter, class _TVertex, class _TOutput >
+void fpa::Base::Algorithm< _TFilter, _TVertex, _TOutput >::
+GenerateData( )
+{
+  this->InvokeEvent( TStartEvent( ) );
+  this->_BeforeGenerateData( );
+  this->m_NumberOfFronts = this->m_Seeds.size( );
+  if( this->m_NumberOfFronts > 0 )
+  {
+    // Prepare collisions
+    TCollision coll( TVertex( ), false );
+    TCollisionsRow row( this->m_NumberOfFronts, coll );
+    this->m_Collisions.clear( );
+    this->m_Collisions.resize( this->m_NumberOfFronts, row );
+
+    // Put seeds on queue
+    this->_QueueClear( );
+    for(
+      auto nIt = this->m_Seeds.begin( );
+      nIt != this->m_Seeds.end( );
+      ++nIt
+      )
+      this->_QueuePush( *nIt );
+
+    // Init marks and results
+    this->_InitMarks( );
+    this->_InitResults( this->m_InitResult );
+
+    // Main loop
+    this->_Loop( );
+
+  } // fi
+  this->_AfterGenerateData( );
+  this->InvokeEvent( TEndEvent( ) );
+}
+
+// -------------------------------------------------------------------------
+template < class _TFilter, class _TVertex, class _TOutput >
+void fpa::Base::Algorithm< _TFilter, _TVertex, _TOutput >::
+_Loop( )
+{
+  this->InvokeEvent( TStartLoopEvent( ) );
+  this->_BeforeLoop( );
+  while( this->_ValidLoop( ) )
+  {
+    _TQueueNode node = this->_QueuePop( );
+    this->InvokeEvent( TPopEvent( node.Vertex, node.FrontId ) );
+
+    // Process actual vertex
+    if( this->_IsMarked( node.Vertex ) )
+      continue;
+    this->_Mark( node );
+    this->_UpdateResult( node );
+    this->InvokeEvent( TMarkEvent( node.Vertex, node.FrontId ) );
+
+    // Add neighbors to queue
+    TNeighborhood neighs = this->m_NeighborhoodFunction->Evaluate( node.Vertex );
+    for( auto it = neighs.begin( ); it != neighs.end( ); ++it )
+    {
+      if( !( this->_IsMarked( *it ) ) )
+      {
+        _TQueueNode neigh( *it, node );
+        if( this->_UpdateValue( neigh, node ) )
+        {
+          this->_QueuePush( neigh );
+          this->InvokeEvent( TPushEvent( node.Vertex, node.FrontId ) );
+
+        } // fi
+      }
+      else
+        this->_UpdateCollisions( node.Vertex, *it );
+
+    } // rof
+
+  } // elihw
+  this->_AfterLoop( );
+  this->InvokeEvent( TEndLoopEvent( ) );
+}
+
+// -------------------------------------------------------------------------
+template < class _TFilter, class _TVertex, class _TOutput >
+void fpa::Base::Algorithm< _TFilter, _TVertex, _TOutput >::
+_BeforeGenerateData( )
+{
+}
+
+// -------------------------------------------------------------------------
+template < class _TFilter, class _TVertex, class _TOutput >
+void fpa::Base::Algorithm< _TFilter, _TVertex, _TOutput >::
+_AfterGenerateData( )
+{
+}
+
+// -------------------------------------------------------------------------
+template < class _TFilter, class _TVertex, class _TOutput >
+void fpa::Base::Algorithm< _TFilter, _TVertex, _TOutput >::
+_BeforeLoop( )
+{
+}
+
+// -------------------------------------------------------------------------
+template < class _TFilter, class _TVertex, class _TOutput >
+void fpa::Base::Algorithm< _TFilter, _TVertex, _TOutput >::
+_AfterLoop( )
+{
+}
+
+// -------------------------------------------------------------------------
+template < class _TFilter, class _TVertex, class _TOutput >
+bool fpa::Base::Algorithm< _TFilter, _TVertex, _TOutput >::
+_ValidLoop( ) const
+{
+  bool r = ( this->_QueueSize( ) > 0 );
+  if( this->m_StopAtOneFront )
+    r &= ( this->m_NumberOfFronts > 0 );
+  return( r );
+}
+
+// -------------------------------------------------------------------------
+template < class _TFilter, class _TVertex, class _TOutput >
+void fpa::Base::Algorithm< _TFilter, _TVertex, _TOutput >::
+_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;
+
+  // Mark collision, if it is new
+  ma--; mb--;
+  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;
+
+    // Update number of fronts
+    unsigned long N = this->m_Seeds.size( );
+    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
+    this->m_NumberOfFronts = N - count;
+
+  } // fi
+}
+
+#endif // __fpa__Base__Algorithm__hxx__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/Base/Dijkstra.h b/lib/fpa/Base/Dijkstra.h
new file mode 100644 (file)
index 0000000..5633f22
--- /dev/null
@@ -0,0 +1,93 @@
+#ifndef __fpa__Base__Dijkstra__h__
+#define __fpa__Base__Dijkstra__h__
+
+#include <vector>
+#include <fpa/Config.h>
+#include <itkFunctionBase.h>
+#include <fpa/Base/DijkstraCostFunctionBase.h>
+
+namespace fpa
+{
+  namespace Base
+  {
+    /**
+     */
+    template< class _TSuperclass, class _TMST >
+    class Dijkstra
+      : public _TSuperclass
+    {
+    public:
+      typedef Dijkstra                        Self;
+      typedef _TSuperclass                    Superclass;
+      typedef itk::SmartPointer< Self >       Pointer;
+      typedef itk::SmartPointer< const Self > ConstPointer;
+
+      typedef _TMST TMST;
+      typedef typename Superclass::TOutput TOutput;
+      typedef typename Superclass::TVertex TVertex;
+
+      typedef itk::FunctionBase< TOutput, TOutput > TCostConversionFunction;
+      typedef DijkstraCostFunctionBase< TVertex, TOutput > TCostFunction;
+
+    protected:
+      typedef typename Superclass::_TQueueNode _TQueueNode;
+      struct _TQueueNodeCompare
+      {
+        bool operator( )( const _TQueueNode& a, const _TQueueNode& b )
+          {
+            return( b.Result < a.Result );
+          }
+      };
+      typedef std::vector< _TQueueNode > _TQueue;
+
+    public:
+      itkTypeMacro( Dijkstra, Algorithm );
+
+      itkGetObjectMacro( CostFunction, TCostFunction );
+      itkGetObjectMacro( CostConversionFunction, TCostConversionFunction );
+      itkSetObjectMacro( CostFunction, TCostFunction );
+      itkSetObjectMacro( CostConversionFunction, TCostConversionFunction );
+
+    public:
+      _TMST* GetMinimumSpanningTree( );
+      const _TMST* GetMinimumSpanningTree( ) const;
+
+    protected:
+      Dijkstra( );
+      virtual ~Dijkstra( );
+
+      virtual void _AfterGenerateData( ) fpa_OVERRIDE;
+
+      virtual void _UpdateResult( const _TQueueNode& n ) fpa_OVERRIDE;
+      virtual bool _UpdateValue(
+        _TQueueNode& v, const _TQueueNode& p
+        ) fpa_OVERRIDE;
+      virtual unsigned long _QueueSize( ) const fpa_OVERRIDE;
+      virtual void _QueueClear( ) fpa_OVERRIDE;
+      virtual void _QueuePush( const _TQueueNode& node ) fpa_OVERRIDE;
+      virtual _TQueueNode _QueuePop( ) fpa_OVERRIDE;
+
+    private:
+      // Purposely not defined
+      Dijkstra( const Self& other );
+      Self& operator=( const Self& other );
+
+    protected:
+      _TQueue m_Queue;
+      typename TCostFunction::Pointer m_CostFunction;
+      typename TCostConversionFunction::Pointer m_CostConversionFunction;
+
+      unsigned long m_MSTIndex;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#  include <fpa/Base/Dijkstra.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Base__Dijkstra__h__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/Base/Dijkstra.hxx b/lib/fpa/Base/Dijkstra.hxx
new file mode 100644 (file)
index 0000000..849ff6c
--- /dev/null
@@ -0,0 +1,135 @@
+#ifndef __fpa__Base__Dijkstra__hxx__
+#define __fpa__Base__Dijkstra__hxx__
+
+#include <algorithm>
+#include <limits>
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass, class _TMST >
+_TMST* fpa::Base::Dijkstra< _TSuperclass, _TMST >::
+GetMinimumSpanningTree( )
+{
+  return(
+    dynamic_cast< _TMST* >(
+      this->itk::ProcessObject::GetOutput( this->m_MSTIndex )
+      )
+    );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass, class _TMST >
+const _TMST* fpa::Base::Dijkstra< _TSuperclass, _TMST >::
+GetMinimumSpanningTree( ) const
+{
+  return(
+    dynamic_cast< const _TMST* >(
+      this->itk::ProcessObject::GetOutput( this->m_MSTIndex )
+      )
+    );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass, class _TMST >
+fpa::Base::Dijkstra< _TSuperclass, _TMST >::
+Dijkstra( )
+  : Superclass( )
+{
+  this->m_InitResult = TOutput( 0 );
+  this->m_MSTIndex = this->GetNumberOfRequiredOutputs( );
+  this->SetNumberOfRequiredOutputs( this->m_MSTIndex + 1 );
+  this->itk::ProcessObject::SetNthOutput( this->m_MSTIndex, _TMST::New( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass, class _TMST >
+fpa::Base::Dijkstra< _TSuperclass, _TMST >::
+~Dijkstra( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass, class _TMST >
+void fpa::Base::Dijkstra< _TSuperclass, _TMST >::
+_AfterGenerateData( )
+{
+  this->Superclass::_AfterGenerateData( );
+
+  auto mst = this->GetMinimumSpanningTree( );
+  mst->ClearSeeds( );
+  for( auto s = this->m_Seeds.begin( ); s != this->m_Seeds.end( ); ++s )
+    mst->AddSeed( s->Vertex );
+  mst->SetCollisions( this->m_Collisions );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass, class _TMST >
+void fpa::Base::Dijkstra< _TSuperclass, _TMST >::
+_UpdateResult( const _TQueueNode& n )
+{
+  this->Superclass::_UpdateResult( n );
+  this->GetMinimumSpanningTree( )->SetParent( n.Vertex, n.Parent );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass, class _TMST >
+bool fpa::Base::Dijkstra< _TSuperclass, _TMST >::
+_UpdateValue( _TQueueNode& v, const _TQueueNode& p )
+{
+  v.Result = this->m_CostFunction->Evaluate( p.Vertex, v.Vertex );
+  if( this->m_CostConversionFunction.IsNotNull( ) )
+    v.Result = this->m_CostConversionFunction->Evaluate( v.Result );
+  if( v.Result >= TOutput( 0 ) )
+  {
+    v.Result += p.Result;
+    return( true );
+  }
+  else
+  {
+    v.Result = this->m_InitResult;
+    return( false );
+
+  } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass, class _TMST >
+unsigned long fpa::Base::Dijkstra< _TSuperclass, _TMST >::
+_QueueSize( ) const
+{
+  return( this->m_Queue.size( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass, class _TMST >
+void fpa::Base::Dijkstra< _TSuperclass, _TMST >::
+_QueueClear( )
+{
+  this->m_Queue.clear( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass, class _TMST >
+void fpa::Base::Dijkstra< _TSuperclass, _TMST >::
+_QueuePush( const _TQueueNode& node )
+{
+  static _TQueueNodeCompare cmp;
+  this->m_Queue.push_back( node );
+  std::push_heap( this->m_Queue.begin( ), this->m_Queue.end( ), cmp );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSuperclass, class _TMST >
+typename fpa::Base::Dijkstra< _TSuperclass, _TMST >::
+_TQueueNode fpa::Base::Dijkstra< _TSuperclass, _TMST >::
+_QueuePop( )
+{
+  static _TQueueNodeCompare cmp;
+  std::pop_heap( this->m_Queue.begin( ), this->m_Queue.end( ), cmp );
+  _TQueueNode f = this->m_Queue.back( );
+  this->m_Queue.pop_back( );
+  return( f );
+}
+
+#endif // __fpa__Base__Dijkstra__hxx__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/Base/DijkstraCostFunctionBase.h b/lib/fpa/Base/DijkstraCostFunctionBase.h
new file mode 100644 (file)
index 0000000..d3a86b2
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef __fpa__Base__DijkstraCostFunctionBase__h__
+#define __fpa__Base__DijkstraCostFunctionBase__h__
+
+#include <itkObject.h>
+#include <itkObjectFactory.h>
+
+namespace fpa
+{
+  namespace Base
+  {
+    /**
+     */
+    template< class _TVertex, class _TOutput >
+    class DijkstraCostFunctionBase
+      : public itk::Object
+    {
+    public:
+      typedef DijkstraCostFunctionBase        Self;
+      typedef itk::Object                     Superclass;
+      typedef itk::SmartPointer< Self >       Pointer;
+      typedef itk::SmartPointer< const Self > ConstPointer;
+
+      typedef _TVertex TVertex;
+      typedef _TOutput TOutput;
+
+    public:
+      itkTypeMacro( DijkstraCostFunctionBase, itk::Object );
+
+    public:
+      virtual TOutput Evaluate( const TVertex& a, const TVertex& b ) const = 0;
+
+    protected:
+      DijkstraCostFunctionBase( )
+        : Superclass( )
+        { }
+      virtual ~DijkstraCostFunctionBase( )
+        { }
+
+    private:
+      // Purposely not defined
+      DijkstraCostFunctionBase( const Self& other );
+      Self& operator=( const Self& other );
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#endif // __fpa__Base__DijkstraCostFunctionBase__h__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/Base/Events.h b/lib/fpa/Base/Events.h
new file mode 100644 (file)
index 0000000..17c5564
--- /dev/null
@@ -0,0 +1,100 @@
+#ifndef __fpa__Base__Events__h__
+#define __fpa__Base__Events__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 _TVertex >
+    class BaseEventWithVertex
+      : public BaseEvent
+    {
+    public:
+      BaseEventWithVertex( )
+        : BaseEvent( )
+        { }
+      BaseEventWithVertex( const _TVertex& 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< _TVertex >* >( e ) != NULL
+            );
+        }
+      itk::EventObject* MakeObject( ) const
+        { return( new BaseEventWithVertex< _TVertex >( ) ); }
+
+    public:
+      _TVertex Vertex;
+      long     FrontId;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#endif // __fpa__Base__Events__h__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/Base/Functors/GaussianModel.h b/lib/fpa/Base/Functors/GaussianModel.h
new file mode 100644 (file)
index 0000000..f147b26
--- /dev/null
@@ -0,0 +1,75 @@
+#ifndef __fpa__Base__Functors__GaussianModel__h__
+#define __fpa__Base__Functors__GaussianModel__h__
+
+#include <fpa/Config.h>
+#include <itkFunctionBase.h>
+#include <cpExtensions/Algorithms/IterativeGaussianModelEstimator.h>
+
+namespace fpa
+{
+  namespace Base
+  {
+    namespace Functors
+    {
+      /**
+       */
+      template< class _TInput, class _TOutput >
+      class GaussianModel
+        : public itk::FunctionBase< _TInput, _TOutput >
+      {
+      public:
+        typedef GaussianModel                                Self;
+        typedef itk::FunctionBase< _TInput, _TOutput > Superclass;
+        typedef itk::SmartPointer< Self >              Pointer;
+        typedef itk::SmartPointer< const Self >        ConstPointer;
+
+        typedef _TInput  TInput;
+        typedef _TOutput TOutput;
+
+        // Model estimator
+        typedef
+        cpExtensions::Algorithms::IterativeGaussianModelEstimator< TOutput, 1 >
+        TModel;
+
+      public:
+        itkNewMacro( Self );
+        itkTypeMacro( GaussianModel, itk::FunctionBase );
+
+        itkGetConstMacro( SupportSize, unsigned int );
+        itkGetConstMacro( MinimumCost, TOutput );
+        itkGetObjectMacro( Model, TModel );
+        itkGetConstObjectMacro( Model, TModel );
+        itkSetMacro( SupportSize, unsigned int );
+        itkSetMacro( MinimumCost, TOutput );
+
+      public:
+        virtual TOutput Evaluate( const TInput& x ) const fpa_OVERRIDE;
+
+      protected:
+        GaussianModel( );
+        virtual ~GaussianModel( );
+
+      private:
+        // Purposely not implemented
+        GaussianModel( const Self& other );
+        Self& operator=( const Self& other );
+
+      protected:
+        unsigned int m_SupportSize;
+        TOutput m_MinimumCost;
+        typename TModel::Pointer m_Model;
+      };
+
+    } // ecapseman
+
+  } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#  include <fpa/Base/Functors/GaussianModel.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Base__Functors__GaussianModel__h__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/Base/Functors/GaussianModel.hxx b/lib/fpa/Base/Functors/GaussianModel.hxx
new file mode 100644 (file)
index 0000000..49db8b0
--- /dev/null
@@ -0,0 +1,50 @@
+#ifndef __fpa__Base__Functors__GaussianModel__hxx__
+#define __fpa__Base__Functors__GaussianModel__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TInput, class _TOutput >
+typename fpa::Base::Functors::GaussianModel< _TInput, _TOutput >::
+TOutput fpa::Base::Functors::GaussianModel< _TInput, _TOutput >::
+Evaluate( const TInput& x ) const
+{
+  TOutput r = TOutput( 0 );
+  if( this->m_Model->GetNumberOfSamples( ) > this->m_SupportSize )
+  {
+    r = this->m_Model->SquaredMahalanobis( TOutput( x ) );
+    if( r <= TOutput( 1 ) )
+      this->m_Model->AddSample( TOutput( x ) );
+  }
+  else
+  {
+    this->m_Model->AddSample( TOutput( x ) );
+    if( this->m_Model->GetNumberOfSamples( ) > 2 )
+      r = this->m_Model->SquaredMahalanobis( TOutput( x ) );
+
+  } // fi
+  if( r < this->m_MinimumCost )
+    return( this->m_MinimumCost );
+  else
+    return( r );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInput, class _TOutput >
+fpa::Base::Functors::GaussianModel< _TInput, _TOutput >::
+GaussianModel( )
+  : Superclass( ),
+    m_SupportSize( 30 ),
+    m_MinimumCost( TOutput( 1e-10 ) )
+{
+  this->m_Model = TModel::New( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInput, class _TOutput >
+fpa::Base::Functors::GaussianModel< _TInput, _TOutput >::
+~GaussianModel( )
+{
+}
+
+#endif // __fpa__Base__Functors__GaussianModel__hxx__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/Base/Functors/Inverse.h b/lib/fpa/Base/Functors/Inverse.h
new file mode 100644 (file)
index 0000000..0bd1a04
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef __fpa__Base__Functors__Inverse__h__
+#define __fpa__Base__Functors__Inverse__h__
+
+#include <fpa/Config.h>
+#include <itkFunctionBase.h>
+
+namespace fpa
+{
+  namespace Base
+  {
+    namespace Functors
+    {
+      /**
+       */
+      template< class _TInput, class _TOutput >
+      class Inverse
+        : public itk::FunctionBase< _TInput, _TOutput >
+      {
+      public:
+        typedef Inverse                                Self;
+        typedef itk::FunctionBase< _TInput, _TOutput > Superclass;
+        typedef itk::SmartPointer< Self >              Pointer;
+        typedef itk::SmartPointer< const Self >        ConstPointer;
+
+        typedef _TInput  TInput;
+        typedef _TOutput TOutput;
+
+      public:
+        itkNewMacro( Self );
+        itkTypeMacro( Inverse, itk::FunctionBase );
+
+      public:
+        virtual TOutput Evaluate( const TInput& x ) const fpa_OVERRIDE;
+
+      protected:
+        Inverse( );
+        virtual ~Inverse( );
+
+      private:
+        // Purposely not implemented
+        Inverse( const Self& other );
+        Self& operator=( const Self& other );
+      };
+
+    } // ecapseman
+
+  } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#  include <fpa/Base/Functors/Inverse.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Base__Functors__Inverse__h__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/Base/Functors/Inverse.hxx b/lib/fpa/Base/Functors/Inverse.hxx
new file mode 100644 (file)
index 0000000..e2ad9f0
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef __fpa__Base__Functors__Inverse__hxx__
+#define __fpa__Base__Functors__Inverse__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TInput, class _TOutput >
+typename fpa::Base::Functors::Inverse< _TInput, _TOutput >::
+TOutput fpa::Base::Functors::Inverse< _TInput, _TOutput >::
+Evaluate( const TInput& x ) const
+{
+  TInput sign = TInput( ( x < TInput( 0 ) )? -1: 1 );
+  TOutput y = TOutput( 1 ) / ( TOutput( 1 ) + TOutput( x * sign ) );
+  return( y * TOutput( sign ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInput, class _TOutput >
+fpa::Base::Functors::Inverse< _TInput, _TOutput >::
+Inverse( )
+  : Superclass( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TInput, class _TOutput >
+fpa::Base::Functors::Inverse< _TInput, _TOutput >::
+~Inverse( )
+{
+}
+
+#endif // __fpa__Base__Functors__Inverse__hxx__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/Base/MinimumSpanningTree.h b/lib/fpa/Base/MinimumSpanningTree.h
new file mode 100644 (file)
index 0000000..de22019
--- /dev/null
@@ -0,0 +1,77 @@
+#ifndef __fpa__Base__MinimumSpanningTree__h__
+#define __fpa__Base__MinimumSpanningTree__h__
+
+#include <fpa/Config.h>
+#include <deque>
+#include <vector>
+#include <utility>
+#include <itkObject.h>
+
+namespace fpa
+{
+  namespace Base
+  {
+    /**
+     */
+    template< class _TVertex, class _TSuperclass >
+    class MinimumSpanningTree
+      : public _TSuperclass
+    {
+    public:
+      typedef MinimumSpanningTree             Self;
+      typedef _TSuperclass                    Superclass;
+      typedef itk::SmartPointer< Self >       Pointer;
+      typedef itk::SmartPointer< const Self > ConstPointer;
+
+      typedef _TVertex                      TVertex;
+      typedef std::deque< _TVertex >        TVertices;
+      typedef std::pair< _TVertex, bool >   TCollision;
+      typedef std::vector< TCollision >     TCollisionsRow;
+      typedef std::vector< TCollisionsRow > TCollisions;
+
+    protected:
+      typedef std::vector< unsigned long > _TRow;
+      typedef std::vector< _TRow >         _TMatrix;
+
+    public:
+      itkTypeMacro( MinimumSpanningTree, _TSuperclass );
+
+    public:
+      const TCollisions& GetCollisions( ) const;
+      void SetCollisions( const TCollisions& collisions );
+
+      void ClearSeeds( );
+      void AddSeed( const _TVertex& seed );
+
+      virtual _TVertex GetParent( const _TVertex& v ) const = 0;
+      virtual void SetParent( const _TVertex& v, const _TVertex& p ) = 0;
+
+      virtual TVertices GetPath( const _TVertex& a ) const;
+      virtual TVertices GetPath( const _TVertex& a, const _TVertex& b ) const;
+
+    protected:
+      MinimumSpanningTree( );
+      virtual ~MinimumSpanningTree( );
+
+    private:
+      // Purposely not defined
+      MinimumSpanningTree( const Self& other );
+      Self& operator=( const Self& other );
+
+    protected:
+      TCollisions m_Collisions;
+      _TMatrix    m_FrontPaths;
+      TVertices   m_Seeds;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#  include <fpa/Base/MinimumSpanningTree.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Base__MinimumSpanningTree__h__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/Base/MinimumSpanningTree.hxx b/lib/fpa/Base/MinimumSpanningTree.hxx
new file mode 100644 (file)
index 0000000..8746005
--- /dev/null
@@ -0,0 +1,232 @@
+#ifndef __fpa__Base__MinimumSpanningTree__hxx__
+#define __fpa__Base__MinimumSpanningTree__hxx__
+
+#include <limits>
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TSuperclass >
+const typename fpa::Base::MinimumSpanningTree< _TVertex, _TSuperclass >::
+TCollisions& fpa::Base::MinimumSpanningTree< _TVertex, _TSuperclass >::
+GetCollisions( ) const
+{
+  return( this->m_Collisions );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TSuperclass >
+void fpa::Base::MinimumSpanningTree< _TVertex, _TSuperclass >::
+SetCollisions( const TCollisions& collisions )
+{
+  static const unsigned long _inf =
+    std::numeric_limits< unsigned long >::max( );
+  if( this->m_Collisions == collisions )
+    return;
+
+  this->m_Collisions = collisions;
+
+  // Prepare a front graph
+  unsigned long N = this->m_Collisions.size( );
+  _TMatrix dist( N, _TRow( N, _inf ) );
+  this->m_FrontPaths = dist;
+  for( unsigned long i = 0; i < N; ++i )
+  {
+    for( unsigned long j = 0; j < N; ++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 < N; ++k )
+  {
+    for( unsigned long i = 0; i < N; ++i )
+    {
+      for( unsigned long j = 0; j < N; ++j )
+      {
+        // WARNING: you don't want a numeric overflow!!!
+        unsigned long dik = dist[ i ][ k ];
+        unsigned long dkj = dist[ k ][ j ];
+        unsigned long sum = _inf;
+        if( dik < _inf && dkj < _inf )
+          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 _TSuperclass >
+void fpa::Base::MinimumSpanningTree< _TVertex, _TSuperclass >::
+ClearSeeds( )
+{
+  this->m_Seeds.clear( );
+  this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TSuperclass >
+void fpa::Base::MinimumSpanningTree< _TVertex, _TSuperclass >::
+AddSeed( const _TVertex& seed )
+{
+  this->m_Seeds.push_back( seed );
+  this->Modified( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TSuperclass >
+typename fpa::Base::MinimumSpanningTree< _TVertex, _TSuperclass >::
+TVertices fpa::Base::MinimumSpanningTree< _TVertex, _TSuperclass >::
+GetPath( const _TVertex& a ) const
+{
+  TVertices path;
+  _TVertex it = a;
+  _TVertex p = this->GetParent( it );
+  while( it != p )
+  {
+    path.push_front( it );
+    it = p;
+    p = this->GetParent( it );
+
+  } // elihw
+  path.push_front( it );
+  return( path );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TSuperclass >
+typename fpa::Base::MinimumSpanningTree< _TVertex, _TSuperclass >::
+TVertices fpa::Base::MinimumSpanningTree< _TVertex, _TSuperclass >::
+GetPath( const _TVertex& a, const _TVertex& b ) const
+{
+  static const unsigned long _inf =
+    std::numeric_limits< unsigned long >::max( );
+
+  TVertices path;
+  TVertices pa = this->GetPath( a );
+  TVertices pb = this->GetPath( b );
+  if( pa.size( ) > 0 && pb.size( ) > 0 )
+  {
+    // Find front identifiers
+    unsigned long ia = _inf, ib = _inf;
+    unsigned long N = this->m_Seeds.size( );
+    for( unsigned long i = 0; i < N; ++i )
+    {
+      if( this->m_Seeds[ i ] == pa.front( ) )
+        ia = i;
+      if( this->m_Seeds[ i ] == pb.front( ) )
+        ib = i;
+
+    } // rof
+
+    if( ia != ib )
+    {
+      // Use this->m_FrontPaths from Floyd-Warshall
+      if( this->m_FrontPaths[ ia ][ ib ] < _inf )
+      {
+        // Compute front path
+        std::vector< long > fpath;
+        fpath.push_back( ia );
+        while( ia != ib )
+        {
+          ia = this->m_FrontPaths[ ia ][ ib ];
+          fpath.push_back( ia );
+
+        } // 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( ) );
+
+        } // fi
+
+      } // fi
+    }
+    else
+    {
+      // Ignore common part: find common ancestor
+      auto aIt = pa.begin( );
+      auto bIt = pb.begin( );
+      while( *aIt == *bIt && aIt != pa.end( ) && bIt != pb.end( ) )
+      {
+        ++aIt;
+        ++bIt;
+
+      } // elihw
+
+      // Glue both parts
+      for( --aIt; aIt != pa.end( ); ++aIt )
+        path.push_front( *aIt );
+      for( ; bIt != pb.end( ); ++bIt )
+        path.push_back( *bIt );
+
+    } // fi
+
+  } // fi
+  return( path );
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TSuperclass >
+fpa::Base::MinimumSpanningTree< _TVertex, _TSuperclass >::
+MinimumSpanningTree( )
+  : Superclass( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TVertex, class _TSuperclass >
+fpa::Base::MinimumSpanningTree< _TVertex, _TSuperclass >::
+~MinimumSpanningTree( )
+{
+}
+
+#endif // __fpa__Base__MinimumSpanningTree__hxx__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/Config.cxx b/lib/fpa/Config.cxx
new file mode 100644 (file)
index 0000000..d881ac9
--- /dev/null
@@ -0,0 +1 @@
+// eof - $RCSfile$
diff --git a/lib/fpa/Config.h.in b/lib/fpa/Config.h.in
new file mode 100644 (file)
index 0000000..1050a24
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef __fpa__Config__h__
+#define __fpa__Config__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__Config__h__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/Image/Algorithm.h b/lib/fpa/Image/Algorithm.h
new file mode 100644 (file)
index 0000000..70a87a6
--- /dev/null
@@ -0,0 +1,70 @@
+#ifndef __fpa__Image__Algorithm__h__
+#define __fpa__Image__Algorithm__h__
+
+#include <itkFunctionBase.h>
+#include <itkImageToImageFilter.h>
+#include <fpa/Base/Algorithm.h>
+#include <fpa/Image/Functors/Base.h>
+
+namespace fpa
+{
+  namespace Image
+  {
+    /**
+     */
+    template< class _TInputImage, class _TOutputImage >
+    class Algorithm
+      : public fpa::Base::Algorithm< itk::ImageToImageFilter< _TInputImage, _TOutputImage >, typename _TInputImage::IndexType, typename _TOutputImage::PixelType >
+    {
+    public:
+      typedef itk::ImageToImageFilter< _TInputImage, _TOutputImage > TFilter;
+      typedef typename _TInputImage::IndexType                       TVertex;
+      typedef typename _TOutputImage::PixelType                      TOutput;
+
+      typedef Algorithm                                         Self;
+      typedef fpa::Base::Algorithm< TFilter, TVertex, TOutput > Superclass;
+      typedef itk::SmartPointer< Self >                         Pointer;
+      typedef itk::SmartPointer< const Self >                   ConstPointer;
+
+      typedef typename Superclass::TFrontId      TFrontId;
+      typedef typename Superclass::TNeighborhood TNeighborhood;
+      typedef fpa::Image::Functors::Base< itk::ImageBase< _TInputImage::ImageDimension >, itk::FunctionBase< TVertex, TNeighborhood > > TNeighborhoodFunction;
+
+    protected:
+      typedef typename Superclass::_TQueueNode _TQueueNode;
+
+    public:
+      itkTypeMacro( fpa::Image::Algorithm, fpa::Base::Algorithm );
+
+    protected:
+      Algorithm( );
+      virtual ~Algorithm( );
+
+      virtual void _BeforeGenerateData( ) fpa_OVERRIDE;
+      virtual void _InitMarks( ) fpa_OVERRIDE;
+      virtual void _InitResults( const TOutput& init_value ) fpa_OVERRIDE;
+      virtual bool _IsMarked( const TVertex& v ) const fpa_OVERRIDE;
+      virtual void _Mark( const _TQueueNode& n ) fpa_OVERRIDE;
+      virtual TFrontId _GetMark( const TVertex& v ) const fpa_OVERRIDE;
+      virtual void _UpdateResult( const _TQueueNode& n ) fpa_OVERRIDE;
+
+    private:
+      // Purposely not defined
+      Algorithm( const Self& other );
+      Self& operator=( const Self& other );
+
+    protected:
+      unsigned int m_MarksIdx;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#  include <fpa/Image/Algorithm.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Image__Algorithm__h__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/Image/Algorithm.hxx b/lib/fpa/Image/Algorithm.hxx
new file mode 100644 (file)
index 0000000..9eb2640
--- /dev/null
@@ -0,0 +1,114 @@
+#ifndef __fpa__Image__Algorithm__hxx__
+#define __fpa__Image__Algorithm__hxx__
+
+// Send Piotr's code to Anna
+
+#include <itkImage.h>
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+fpa::Image::Algorithm< _TInputImage, _TOutputImage >::
+Algorithm( )
+  : Superclass( )
+{
+  typedef itk::Image< TFrontId, _TInputImage::ImageDimension > _TMarks;
+  this->m_MarksIdx = this->GetNumberOfRequiredOutputs( );
+  this->itk::ProcessObject::SetNumberOfRequiredOutputs( this->m_MarksIdx + 1 );
+  typename _TMarks::Pointer marks = _TMarks::New( );
+  this->SetNthOutput( this->m_MarksIdx, marks );
+}
+
+// -------------------------------------------------------------------------
+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( );
+
+  TNeighborhoodFunction* neighFunc =
+    dynamic_cast< TNeighborhoodFunction* >( this->GetNeighborhoodFunction( ) );
+  if( neighFunc == NULL )
+    itkExceptionMacro( << "NeighborhoodFunction not well defined." );
+  neighFunc->SetImage( this->GetInput( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+void fpa::Image::Algorithm< _TInputImage, _TOutputImage >::
+_InitMarks( )
+{
+  typedef itk::Image< TFrontId, _TInputImage::ImageDimension > _TMarks;
+  _TMarks* marks =
+    dynamic_cast< _TMarks* >(
+      this->itk::ProcessObject::GetOutput( this->m_MarksIdx )
+      );
+  marks->FillBuffer( 0 );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+void fpa::Image::Algorithm< _TInputImage, _TOutputImage >::
+_InitResults( const TOutput& init_value )
+{
+  this->GetOutput( )->FillBuffer( init_value );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+bool fpa::Image::Algorithm< _TInputImage, _TOutputImage >::
+_IsMarked( const TVertex& v ) const
+{
+  typedef itk::Image< TFrontId, _TInputImage::ImageDimension > _TMarks;
+  const _TMarks* marks =
+    dynamic_cast< const _TMarks* >(
+      this->itk::ProcessObject::GetOutput( this->m_MarksIdx )
+      );
+  return( marks->GetPixel( v ) != 0 );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+void fpa::Image::Algorithm< _TInputImage, _TOutputImage >::
+_Mark( const _TQueueNode& n )
+{
+  typedef itk::Image< TFrontId, _TInputImage::ImageDimension > _TMarks;
+  _TMarks* marks =
+    dynamic_cast< _TMarks* >(
+      this->itk::ProcessObject::GetOutput( this->m_MarksIdx )
+      );
+  marks->SetPixel( n.Vertex, n.FrontId );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+typename fpa::Image::Algorithm< _TInputImage, _TOutputImage >::
+TFrontId fpa::Image::Algorithm< _TInputImage, _TOutputImage >::
+_GetMark( const TVertex& v ) const
+{
+  typedef itk::Image< TFrontId, _TInputImage::ImageDimension > _TMarks;
+  const _TMarks* marks =
+    dynamic_cast< const _TMarks* >(
+      this->itk::ProcessObject::GetOutput( this->m_MarksIdx )
+      );
+  return( marks->GetPixel( v ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+void fpa::Image::Algorithm< _TInputImage, _TOutputImage >::
+_UpdateResult( const _TQueueNode& n )
+{
+  this->GetOutput( )->SetPixel( n.Vertex, n.Result );
+}
+
+#endif // __fpa__Image__Algorithm__hxx__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/Image/Dijkstra.h b/lib/fpa/Image/Dijkstra.h
new file mode 100644 (file)
index 0000000..37c28e8
--- /dev/null
@@ -0,0 +1,61 @@
+#ifndef __fpa__Image__Dijkstra__h__
+#define __fpa__Image__Dijkstra__h__
+
+#include <fpa/Base/Dijkstra.h>
+#include <fpa/Image/Algorithm.h>
+#include <fpa/Image/MinimumSpanningTree.h>
+#include <fpa/Image/Functors/Base.h>
+
+namespace fpa
+{
+  namespace Image
+  {
+    /**
+     */
+    template< class _TInputImage, class _TOutputImage >
+    class Dijkstra
+      : public fpa::Base::Dijkstra< fpa::Image::Algorithm< _TInputImage, _TOutputImage >, fpa::Image::MinimumSpanningTree< _TInputImage::ImageDimension > >
+    {
+    public:
+      typedef Dijkstra                                             Self;
+      typedef fpa::Image::Algorithm< _TInputImage, _TOutputImage > TAlgorithm;
+      typedef fpa::Image::MinimumSpanningTree< _TInputImage::ImageDimension > TMST;
+      typedef fpa::Base::Dijkstra< TAlgorithm, TMST > Superclass;
+      typedef itk::SmartPointer< Self >               Pointer;
+      typedef itk::SmartPointer< const Self >         ConstPointer;
+
+      typedef typename Superclass::TOutput TOutput;
+      typedef typename Superclass::TVertex TVertex;
+
+      typedef fpa::Image::Functors::Base< _TInputImage, fpa::Base::DijkstraCostFunctionBase< TVertex, TOutput > > TCostFunction;
+
+    protected:
+      typedef typename Superclass::_TQueueNode _TQueueNode;
+
+    public:
+      itkNewMacro( Self );
+      itkTypeMacro( fpa::Image::Dijkstra, fpa::Base::Dijkstra );
+
+    protected:
+      Dijkstra( );
+      virtual ~Dijkstra( );
+
+      virtual void _BeforeGenerateData( ) fpa_OVERRIDE;
+
+    private:
+      // Purposely not defined
+      Dijkstra( const Self& other );
+      Self& operator=( const Self& other );
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#  include <fpa/Image/Dijkstra.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Image__Dijkstra__h__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/Image/Dijkstra.hxx b/lib/fpa/Image/Dijkstra.hxx
new file mode 100644 (file)
index 0000000..2831159
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef __fpa__Image__Dijkstra__hxx__
+#define __fpa__Image__Dijkstra__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+fpa::Image::Dijkstra< _TInputImage, _TOutputImage >::
+Dijkstra( )
+  : Superclass( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+fpa::Image::Dijkstra< _TInputImage, _TOutputImage >::
+~Dijkstra( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+void fpa::Image::Dijkstra< _TInputImage, _TOutputImage >::
+_BeforeGenerateData( )
+{
+  this->Superclass::_BeforeGenerateData( );
+
+  TCostFunction* cost =
+    dynamic_cast< TCostFunction* >( this->GetCostFunction( ) );
+  if( cost == NULL )
+    itkExceptionMacro( << "CostFunction not well defined." );
+  cost->SetImage( this->GetInput( ) );
+}
+
+#endif // __fpa__Image__Dijkstra__hxx__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/Image/Functors/Base.h b/lib/fpa/Image/Functors/Base.h
new file mode 100644 (file)
index 0000000..607b7c3
--- /dev/null
@@ -0,0 +1,55 @@
+#ifndef __fpa__Image__Functors__Base__h__
+#define __fpa__Image__Functors__Base__h__
+
+#include <fpa/Config.h>
+#include <itkFunctionBase.h>
+
+namespace fpa
+{
+  namespace Image
+  {
+    namespace Functors
+    {
+      /**
+       */
+      template< class _TImage, class _TSuperclass >
+      class Base
+        : public _TSuperclass
+      {
+      public:
+        typedef Base                            Self;
+        typedef _TSuperclass                    Superclass;
+        typedef itk::SmartPointer< Self >       Pointer;
+        typedef itk::SmartPointer< const Self > ConstPointer;
+
+        typedef _TImage TImage;
+        typedef itk::ImageBase< TImage::ImageDimension > TImageBase;
+
+      public:
+        itkTypeMacro( Base, itk::FunctionBase );
+
+        itkGetConstObjectMacro( Image, TImageBase );
+        itkSetConstObjectMacro( Image, TImageBase );
+
+      protected:
+        Base( ) : Superclass( ) { }
+        virtual ~Base( )        { }
+
+      private:
+        // Purposely not implemented
+        Base( const Self& other );
+        Self& operator=( const Self& other );
+
+      protected:
+        typename TImageBase::ConstPointer m_Image;
+      };
+
+    } // ecapseman
+
+  } // ecapseman
+
+} // ecapseman
+
+#endif // __fpa__Image__Functors__Base__h__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/Image/Functors/SimpleDijkstraCost.h b/lib/fpa/Image/Functors/SimpleDijkstraCost.h
new file mode 100644 (file)
index 0000000..d9a0405
--- /dev/null
@@ -0,0 +1,68 @@
+#ifndef __fpa__Image__Functors__SimpleDijkstraCost__h__
+#define __fpa__Image__Functors__SimpleDijkstraCost__h__
+
+#include <fpa/Image/Functors/Base.h>
+#include <fpa/Base/DijkstraCostFunctionBase.h>
+
+namespace fpa
+{
+  namespace Image
+  {
+    namespace Functors
+    {
+      /**
+       */
+      template< class _TImage, class _TOutput >
+      class SimpleDijkstraCost
+        : public fpa::Image::Functors::Base< _TImage, fpa::Base::DijkstraCostFunctionBase< typename _TImage::IndexType, _TOutput > >
+      {
+      public:
+        typedef _TImage                    TImage;
+        typedef typename TImage::IndexType TIndex;
+        typedef _TOutput                   TOutput;
+
+        typedef fpa::Base::DijkstraCostFunctionBase< TIndex, TOutput > TBaseFunctor;
+        typedef fpa::Image::Functors::Base< TImage, TBaseFunctor > Superclass;
+        typedef SimpleDijkstraCost              Self;
+        typedef itk::SmartPointer< Self >       Pointer;
+        typedef itk::SmartPointer< const Self > ConstPointer;
+
+      public:
+        itkNewMacro( Self );
+        itkTypeMacro( SimpleDijkstraCost, Base );
+
+        itkBooleanMacro( UseImageSpacing );
+        itkGetConstMacro( UseImageSpacing, bool );
+        itkSetMacro( UseImageSpacing, bool );
+
+      public:
+        virtual TOutput Evaluate(
+          const TIndex& a, const TIndex& b
+          ) const fpa_OVERRIDE;
+
+      protected:
+        SimpleDijkstraCost( );
+        virtual ~SimpleDijkstraCost( );
+
+      private:
+        // Purposely not implemented
+        SimpleDijkstraCost( const Self& other );
+        Self& operator=( const Self& other );
+
+      protected:
+        bool m_UseImageSpacing;
+      };
+
+    } // ecapseman
+
+  } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#  include <fpa/Image/Functors/SimpleDijkstraCost.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Image__Functors__SimpleDijkstraCost__h__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/Image/Functors/SimpleDijkstraCost.hxx b/lib/fpa/Image/Functors/SimpleDijkstraCost.hxx
new file mode 100644 (file)
index 0000000..25b8ff4
--- /dev/null
@@ -0,0 +1,42 @@
+#ifndef __fpa__Image__Functors__SimpleDijkstraCost__hxx__
+#define __fpa__Image__Functors__SimpleDijkstraCost__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TImage, class _TOutput >
+typename fpa::Image::Functors::SimpleDijkstraCost< _TImage, _TOutput >::
+TOutput fpa::Image::Functors::SimpleDijkstraCost< _TImage, _TOutput >::
+Evaluate( const TIndex& a, const TIndex& b ) const
+{
+  const _TImage* im =
+    dynamic_cast< const _TImage* >( this->m_Image.GetPointer( ) );
+  TOutput coeff = TOutput( 1 );
+  if( this->m_UseImageSpacing )
+  {
+    typename _TImage::PointType pa, pb;
+    im->TransformIndexToPhysicalPoint( a, pa );
+    im->TransformIndexToPhysicalPoint( b, pb );
+    coeff = TOutput( pa.EuclideanDistanceTo( pb ) );
+
+  } // fi
+  return( TOutput( im->GetPixel( a ) ) * coeff );
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage, class _TOutput >
+fpa::Image::Functors::SimpleDijkstraCost< _TImage, _TOutput >::
+SimpleDijkstraCost( )
+  : Superclass( ),
+    m_UseImageSpacing( false )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage, class _TOutput >
+fpa::Image::Functors::SimpleDijkstraCost< _TImage, _TOutput >::
+~SimpleDijkstraCost( )
+{
+}
+
+#endif // __fpa__Image__Functors__SimpleDijkstraCost__hxx__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/Image/Functors/SimpleNeighborhood.h b/lib/fpa/Image/Functors/SimpleNeighborhood.h
new file mode 100644 (file)
index 0000000..3074599
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef __fpa__Image__Functors__SimpleNeighborhood__h__
+#define __fpa__Image__Functors__SimpleNeighborhood__h__
+
+#include <vector>
+#include <fpa/Image/Functors/Base.h>
+#include <itkFunctionBase.h>
+
+namespace fpa
+{
+  namespace Image
+  {
+    namespace Functors
+    {
+      /**
+       */
+      template< class _TImage >
+      class SimpleNeighborhood
+        : public fpa::Image::Functors::Base< _TImage, itk::FunctionBase< typename _TImage::IndexType, std::vector< typename _TImage::IndexType > > >
+      {
+      public:
+        typedef _TImage                         TImage;
+        typedef typename TImage::IndexType      TIndex;
+        typedef std::vector< TIndex >           TOutput;
+        typedef itk::FunctionBase< TIndex, TOutput > TBaseFunctor;
+        typedef fpa::Image::Functors::Base< TImage, TBaseFunctor > Superclass;
+        typedef SimpleNeighborhood              Self;
+        typedef itk::SmartPointer< Self >       Pointer;
+        typedef itk::SmartPointer< const Self > ConstPointer;
+
+      public:
+        itkNewMacro( Self );
+        itkTypeMacro( SimpleNeighborhood, Base );
+
+        itkGetConstMacro( Order, unsigned int );
+        itkSetMacro( Order, unsigned int );
+
+      public:
+        virtual TOutput Evaluate( const TIndex& center ) const fpa_OVERRIDE;
+
+      protected:
+        SimpleNeighborhood( );
+        virtual ~SimpleNeighborhood( );
+
+      private:
+        // Purposely not implemented
+        SimpleNeighborhood( const Self& other );
+        Self& operator=( const Self& other );
+
+      protected:
+        unsigned int m_Order;
+      };
+
+    } // ecapseman
+
+  } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#  include <fpa/Image/Functors/SimpleNeighborhood.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Image__Functors__SimpleNeighborhood__h__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/Image/Functors/SimpleNeighborhood.hxx b/lib/fpa/Image/Functors/SimpleNeighborhood.hxx
new file mode 100644 (file)
index 0000000..ce5fcc5
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef __fpa__Image__Functors__SimpleNeighborhood__hxx__
+#define __fpa__Image__Functors__SimpleNeighborhood__hxx__
+
+// -------------------------------------------------------------------------
+template< class _TImage >
+typename fpa::Image::Functors::SimpleNeighborhood< _TImage >::
+TOutput fpa::Image::Functors::SimpleNeighborhood< _TImage >::
+Evaluate( const TIndex& center ) const
+{
+  TOutput res;
+  typename _TImage::RegionType reg = this->m_Image->GetRequestedRegion( );
+  if( this->m_Order == 1 )
+  {
+    for( unsigned int d = 0; d < _TImage::ImageDimension; ++d )
+    {
+      for( int o = -1; o <= 1; o += 2 )
+      {
+        TIndex idx = center;
+        idx[ d ] += o;
+        if( reg.IsInside( idx ) )
+          res.push_back( idx );
+
+      } // rof
+
+    } // rof
+  }
+  else
+  {
+    // TODO!!!
+
+  } // fi
+  return( res );
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage >
+fpa::Image::Functors::SimpleNeighborhood< _TImage >::
+SimpleNeighborhood( )
+  : Superclass( ),
+    m_Order( 1 )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage >
+ fpa::Image::Functors::SimpleNeighborhood< _TImage >::
+~SimpleNeighborhood( )
+{
+}
+
+#endif // __fpa__Image__Functors__SimpleNeighborhood__hxx__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/Image/MinimumSpanningTree.h b/lib/fpa/Image/MinimumSpanningTree.h
new file mode 100644 (file)
index 0000000..371664c
--- /dev/null
@@ -0,0 +1,63 @@
+#ifndef __fpa__Image__MinimumSpanningTree__h__
+#define __fpa__Image__MinimumSpanningTree__h__
+
+#include <fpa/Base/MinimumSpanningTree.h>
+#include <itkImage.h>
+
+namespace fpa
+{
+  namespace Image
+  {
+    /**
+     */
+    template< unsigned int _VDim >
+    class MinimumSpanningTree
+      : public fpa::Base::MinimumSpanningTree< itk::Index< _VDim >, itk::Image< itk::Offset< _VDim >, _VDim > >
+    {
+    public:
+      typedef itk::Index< _VDim >                               TVertex;
+      typedef itk::Offset< _VDim >                              TOffset;
+      typedef itk::Image< TOffset, _VDim >                      TImage;
+      typedef fpa::Base::MinimumSpanningTree< TVertex, TImage > Superclass;
+      typedef MinimumSpanningTree                               Self;
+      typedef itk::SmartPointer< Self >                         Pointer;
+      typedef itk::SmartPointer< const Self >                   ConstPointer;
+
+      typedef typename Superclass::TVertices TVertices;
+      typedef typename TImage::PointType TPoint;
+      typedef std::deque< TPoint > TPoints;
+
+    public:
+      itkNewMacro( Self );
+      itkTypeMacro(
+        fpa::Image::MinimumSpanningTree, fpa::Base::MinimumSpanningTree
+        );
+
+    public:
+      virtual TVertex GetParent( const TVertex& v ) const fpa_OVERRIDE;
+      virtual void SetParent( const TVertex& v, const TVertex& p ) fpa_OVERRIDE;
+
+      TPoints GetEuclideanPath( const TVertex& a ) const;
+      TPoints GetEuclideanPath( const TVertex& a, const TVertex& b ) const;
+
+    protected:
+      MinimumSpanningTree( );
+      virtual ~MinimumSpanningTree( );
+
+    private:
+      // Purposely not defined
+      MinimumSpanningTree( const Self& other );
+      Self& operator=( const Self& other );
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#  include <fpa/Image/MinimumSpanningTree.hxx>
+#endif // ITK_MANUAL_INSTANTIATION
+
+#endif // __fpa__Image__MinimumSpanningTree__h__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/Image/MinimumSpanningTree.hxx b/lib/fpa/Image/MinimumSpanningTree.hxx
new file mode 100644 (file)
index 0000000..01c642d
--- /dev/null
@@ -0,0 +1,75 @@
+#ifndef __fpa__Image__MinimumSpanningTree__hxx__
+#define __fpa__Image__MinimumSpanningTree__hxx__
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+typename fpa::Image::MinimumSpanningTree< _VDim >::
+TVertex fpa::Image::MinimumSpanningTree< _VDim >::
+GetParent( const TVertex& v ) const
+{
+  TVertex p = v + this->GetPixel( v );
+  return( p );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+void fpa::Image::MinimumSpanningTree< _VDim >::
+SetParent( const TVertex& v, const TVertex& p )
+{
+  this->SetPixel( v, p - v );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+typename fpa::Image::MinimumSpanningTree< _VDim >::
+TPoints fpa::Image::MinimumSpanningTree< _VDim >::
+GetEuclideanPath( const TVertex& a ) const
+{
+  TVertices path = this->GetPath( a );
+  TPoints points;
+  for( auto v = path.begin( ); v != path.end( ); ++v )
+  {
+    TPoint p;
+    this->TransformIndexToPhysicalPoint( *v, p );
+    points.push_back( p );
+
+  } // rof
+  return( points );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+typename fpa::Image::MinimumSpanningTree< _VDim >::
+TPoints fpa::Image::MinimumSpanningTree< _VDim >::
+GetEuclideanPath( const TVertex& a, const TVertex& b ) const
+{
+  TVertices path = this->GetPath( a, b );
+  TPoints points;
+  for( auto v = path.begin( ); v != path.end( ); ++v )
+  {
+    TPoint p;
+    this->TransformIndexToPhysicalPoint( *v, p );
+    points.push_back( p );
+
+  } // rof
+  return( points );
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+fpa::Image::MinimumSpanningTree< _VDim >::
+MinimumSpanningTree( )
+  : Superclass( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< unsigned int _VDim >
+fpa::Image::MinimumSpanningTree< _VDim >::
+~MinimumSpanningTree( )
+{
+}
+
+#endif // __fpa__Image__MinimumSpanningTree__hxx__
+
+// eof - $RCSfile$
diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt
new file mode 100644 (file)
index 0000000..09f152b
--- /dev/null
@@ -0,0 +1,15 @@
+## ==========================
+## == Build plugin library ==
+## ==========================
+
+IF(USE_cpPlugins)
+  Wrap_cpPlugins(
+    _plugin
+    ${CMAKE_CURRENT_SOURCE_DIR}/Plugins
+    ${prj_VERSION} ${prj_SHORT_VERSION}
+    fpa
+    )
+  TARGET_LINK_LIBRARIES(${_plugin} ${cpPlugins_LIB} ${fpa_Instances})
+ENDIF(USE_cpPlugins)
+
+## eof - $RCSfile$
\ No newline at end of file
diff --git a/plugins/Plugins/BaseImageFilter.cxx b/plugins/Plugins/BaseImageFilter.cxx
new file mode 100644 (file)
index 0000000..cb3f433
--- /dev/null
@@ -0,0 +1,29 @@
+#include <plugins/Plugins/BaseImageFilter.h>
+#include <cpPlugins/DataObjects/Image.h>
+
+// -------------------------------------------------------------------------
+fpaPlugins::BaseImageFilter::
+BaseImageFilter( )
+  : Superclass( )
+{
+  typedef cpPlugins::BaseObjects::DataObject _TData;
+  typedef cpPlugins::DataObjects::Image _TImage;
+
+  this->_ConfigureInput< _TImage >( "Input", true, false );
+  this->_ConfigureInput< _TData >( "Seeds", true, false );
+  this->_ConfigureInput< _TData >( "Neighborhood", false, false );
+  this->_ConfigureOutput< _TImage >( "Output" );
+
+  this->m_Parameters.ConfigureAsBool( "VisualDebug" );
+  this->m_Parameters.ConfigureAsBool( "StopAtOneFront" );
+  this->m_Parameters.SetBool( "VisualDebug", false );
+  this->m_Parameters.SetBool( "StopAtOneFront", false );
+}
+
+// -------------------------------------------------------------------------
+fpaPlugins::BaseImageFilter::
+~BaseImageFilter( )
+{
+}
+
+// eof - $RCSfile$
diff --git a/plugins/Plugins/BaseImageFilter.h b/plugins/Plugins/BaseImageFilter.h
new file mode 100644 (file)
index 0000000..30cb7d1
--- /dev/null
@@ -0,0 +1,52 @@
+#ifndef __fpa__Plugins__BaseImageFilter__h__
+#define __fpa__Plugins__BaseImageFilter__h__
+
+#include <plugins/fpaPlugins_Export.h>
+#include <cpPlugins/BaseObjects/ProcessObject.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;
+
+  public:
+    itkTypeMacro( BaseImageFilter, cpPlugins::BaseObjects::ProcessObject );
+    cpPlugins_Id_Macro( BaseImageFilter, fpaImageAlgorithm );
+
+  protected:
+    BaseImageFilter( );
+    virtual ~BaseImageFilter( );
+
+    /* TODO
+       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 );
+  };
+
+} // ecapseman
+
+#endif // __fpa__Plugins__BaseImageFilter__h__
+
+// eof - $RCSfile$
diff --git a/plugins/Plugins/ExtractPathFromMinimumSpanningTree.cxx b/plugins/Plugins/ExtractPathFromMinimumSpanningTree.cxx
new file mode 100644 (file)
index 0000000..f6b69d1
--- /dev/null
@@ -0,0 +1,124 @@
+#include <plugins/Plugins/ExtractPathFromMinimumSpanningTree.h>
+#include <cpPlugins/DataObjects/Image.h>
+#include <cpPlugins/DataObjects/Mesh.h>
+#include <fpa_DataObjects.h>
+
+/* TODO
+   #include <vtkFloatArray.h>
+   #include <vtkPointData.h>
+*/
+
+// -------------------------------------------------------------------------
+fpaPlugins::ExtractPathFromMinimumSpanningTree::
+ExtractPathFromMinimumSpanningTree( )
+  : Superclass( )
+{
+  typedef cpPlugins::BaseObjects::DataObject _TData;
+  typedef cpPlugins::DataObjects::Image _TMST;
+  typedef cpPlugins::DataObjects::Mesh  _TMesh;
+
+  this->_ConfigureInput< _TMST >( "MST", true, false );
+  this->_ConfigureInput< _TData >( "Seeds", true, false );
+  this->_ConfigureOutput< _TMesh >( "Paths" );
+
+  this->m_Parameters.ConfigureAsUintList( "Indices" );
+}
+
+// -------------------------------------------------------------------------
+fpaPlugins::ExtractPathFromMinimumSpanningTree::
+~ExtractPathFromMinimumSpanningTree( )
+{
+}
+
+// -------------------------------------------------------------------------
+void fpaPlugins::ExtractPathFromMinimumSpanningTree::
+_GenerateData( )
+{
+  typedef fpa::Image::MinimumSpanningTree< 2 > _TMST2;
+  typedef fpa::Image::MinimumSpanningTree< 3 > _TMST3;
+
+  auto mst2 = this->GetInputData< _TMST2 >( "MST" );
+  auto mst3 = this->GetInputData< _TMST3 >( "MST" );
+  if     ( mst2 != NULL ) this->_GD0( mst2 );
+  else if( mst3 != NULL ) this->_GD0( mst3 );
+  else this->_Error( "Invalid input spanning tree." );
+}
+
+// -------------------------------------------------------------------------
+template< class _TMST >
+void fpaPlugins::ExtractPathFromMinimumSpanningTree::
+_GD0( _TMST* mst )
+{
+  typedef typename _TMST::IndexType _TIndex;
+
+  // Get seeds
+  std::vector< _TIndex > seeds;
+  auto points = this->GetInputData< vtkPolyData >( "Seeds" );
+  if( points != NULL )
+  {
+    typename _TMST::PointType pnt;
+    typename _TMST::IndexType idx;
+    unsigned int dim =
+      ( _TMST::ImageDimension < 3 )? _TMST::ImageDimension: 3;
+    for( unsigned int i = 0; i < points->GetNumberOfPoints( ); ++i )
+    {
+      double buf[ 3 ];
+      points->GetPoint( i, buf );
+      pnt.Fill( 0 );
+      for( unsigned int d = 0; d < dim; ++d )
+        pnt[ d ] = buf[ d ];
+      if( mst->TransformPhysicalPointToIndex( pnt, idx ) )
+        seeds.push_back( idx );
+
+    } // rof
+
+  } // fi
+
+  // Prepare result
+  auto mesh = this->_CreateVTK< vtkPolyData >( );
+  mesh->SetPoints( vtkSmartPointer< vtkPoints >::New( ) );
+  mesh->SetVerts( vtkSmartPointer< vtkCellArray >::New( ) );
+  mesh->SetLines( vtkSmartPointer< vtkCellArray >::New( ) );
+  mesh->SetPolys( vtkSmartPointer< vtkCellArray >::New( ) );
+  mesh->SetStrips( vtkSmartPointer< vtkCellArray >::New( ) );
+  /* TODO
+     vtkSmartPointer< vtkFloatArray > data =
+     vtkSmartPointer< vtkFloatArray >::New( );
+     data->SetNumberOfComponents( 1 );
+     mesh->GetPointData( )->SetScalars( data );
+  */
+
+  // Compute
+  auto indices = this->m_Parameters.GetUintList( "Indices" );
+  for( unsigned int i = 0; i < indices.size( ); i += 2 )
+  {
+    if( i < indices.size( ) - 1 )
+    {
+      _TIndex a = seeds[ indices[ i ] ];
+      _TIndex b = seeds[ indices[ i + 1 ] ];
+
+      auto path = mst->GetEuclideanPath( a, b );
+      for( unsigned long j = 0; j < path.size( ); ++j )
+      {
+        auto p = path[ j ];
+        if( _TMST::ImageDimension == 2 )
+          mesh->GetPoints( )->InsertNextPoint( p[ 0 ], p[ 1 ], 0 );
+        else if( _TMST::ImageDimension == 3 )
+          mesh->GetPoints( )->InsertNextPoint( p[ 0 ], p[ 1 ], p[ 2 ] );
+        if( j > 0 )
+        {
+          mesh->GetLines( )->InsertNextCell( 2 );
+          mesh->GetLines( )->InsertCellPoint( j - 1 );
+          mesh->GetLines( )->InsertCellPoint( j );
+
+        } // fi
+
+      } // rof
+
+    } // fi
+
+  } // rof
+  this->GetOutput( "Paths" )->SetVTK( mesh );
+}
+
+// eof - $RCSfile$
diff --git a/plugins/Plugins/ExtractPathFromMinimumSpanningTree.h b/plugins/Plugins/ExtractPathFromMinimumSpanningTree.h
new file mode 100644 (file)
index 0000000..c3f8496
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef __fpa__Plugins__ExtractPathFromMinimumSpanningTree__h__
+#define __fpa__Plugins__ExtractPathFromMinimumSpanningTree__h__
+
+#include <plugins/fpaPlugins_Export.h>
+#include <cpPlugins/BaseObjects/ProcessObject.h>
+
+namespace fpaPlugins
+{
+  /**
+   */
+  class fpaPlugins_EXPORT ExtractPathFromMinimumSpanningTree
+    : public cpPlugins::BaseObjects::ProcessObject
+  {
+    cpPluginsObject(
+      ExtractPathFromMinimumSpanningTree,
+      cpPlugins::BaseObjects::ProcessObject,
+      fpa
+      );
+
+  protected:
+    template< class _TMST >
+    inline void _GD0( _TMST* mst );
+  };
+
+} // ecapseman
+
+#endif // __fpa__Plugins__ExtractPathFromMinimumSpanningTree__h__
+
+// eof - $RCSfile$
diff --git a/plugins/Plugins/GaussianModelCost.cxx b/plugins/Plugins/GaussianModelCost.cxx
new file mode 100644 (file)
index 0000000..c6b962b
--- /dev/null
@@ -0,0 +1,55 @@
+#include <plugins/Plugins/GaussianModelCost.h>
+#include <cpPlugins/DataObjects/Image.h>
+
+#include <fpa/Base/Functors/GaussianModel.h>
+#include <fpa/Base/Functors/GaussianModel.hxx>
+
+// -------------------------------------------------------------------------
+fpaPlugins::GaussianModelCost::
+GaussianModelCost( )
+  : Superclass( )
+{
+  typedef cpPlugins::BaseObjects::DataObject _TData;
+  this->_ConfigureOutput< _TData >( "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::GaussianModelCost::
+~GaussianModelCost( )
+{
+}
+
+// -------------------------------------------------------------------------
+void fpaPlugins::GaussianModelCost::
+_GenerateData( )
+{
+  auto rtype = this->m_Parameters.GetSelectedChoice( "ResultType" );
+  if     ( rtype == "float"  ) this->_GD0< float >( );
+  else if( rtype == "double" ) this->_GD0< double >( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TOutput >
+void fpaPlugins::GaussianModelCost::
+_GD0( )
+{
+  typedef fpa::Base::Functors::GaussianModel< _TOutput, _TOutput > _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$
diff --git a/plugins/Plugins/GaussianModelCost.h b/plugins/Plugins/GaussianModelCost.h
new file mode 100644 (file)
index 0000000..845f57f
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef __fpa__Plugins__GaussianModelCost__h__
+#define __fpa__Plugins__GaussianModelCost__h__
+
+#include <plugins/fpaPlugins_Export.h>
+#include <cpPlugins/BaseObjects/ProcessObject.h>
+
+namespace fpaPlugins
+{
+  /**
+   */
+  class fpaPlugins_EXPORT GaussianModelCost
+    : public cpPlugins::BaseObjects::ProcessObject
+  {
+    cpPluginsObject(
+      GaussianModelCost,
+      cpPlugins::BaseObjects::ProcessObject,
+      fpaFunctors
+      );
+
+  protected:
+    template< class _TOutput >
+    inline void _GD0( );
+  };
+
+} // ecapseman
+
+#endif // __fpa__Plugins__GaussianModelCost__h__
+
+// eof - $RCSfile$
diff --git a/plugins/Plugins/ImageDijkstra.cxx b/plugins/Plugins/ImageDijkstra.cxx
new file mode 100644 (file)
index 0000000..c5d34a4
--- /dev/null
@@ -0,0 +1,108 @@
+#include <plugins/Plugins/ImageDijkstra.h>
+#include <cpPlugins/DataObjects/Image.h>
+#include <vtkPolyData.h>
+
+#include <fpa/Image/Dijkstra.h>
+#include <fpa/Base/Dijkstra.hxx>
+#include <fpa/Image/Dijkstra.hxx>
+
+// -------------------------------------------------------------------------
+fpaPlugins::ImageDijkstra::
+ImageDijkstra( )
+  : Superclass( )
+{
+  typedef cpPlugins::BaseObjects::DataObject _TData;
+  typedef cpPlugins::DataObjects::Image      _TMST;
+
+  this->_ConfigureInput< _TData >( "Cost", false, false );
+  this->_ConfigureInput< _TData >( "CostConversion", false, false );
+  this->_ConfigureOutput< _TMST >( "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" );
+}
+
+// -------------------------------------------------------------------------
+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 )
+{
+  typedef itk::Image< float, _TImage::ImageDimension >  _TFloat;
+  typedef itk::Image< double, _TImage::ImageDimension > _TDouble;
+
+  auto rtype = this->m_Parameters.GetSelectedChoice( "ResultType" );
+  if     ( rtype == "float"  ) this->_GD1< _TImage, _TFloat >( image );
+  else if( rtype == "double" ) this->_GD1< _TImage, _TDouble >( image );
+}
+
+// -------------------------------------------------------------------------
+template< class _TInputImage, class _TOutputImage >
+void fpaPlugins::ImageDijkstra::
+_GD1( _TInputImage* image )
+{
+  typedef fpa::Image::Dijkstra< _TInputImage, _TOutputImage > _TFilter;
+  typedef typename _TFilter::TCostConversionFunction _TCostConversion;
+  typedef typename _TFilter::TCostFunction           _TCost;
+  typedef typename _TFilter::TNeighborhoodFunction   _TNeighborhood;
+
+  // Get functors
+  auto neig = this->GetInputData< _TNeighborhood >( "Neighborhood" );
+  auto cost = this->GetInputData< _TCost >( "Cost" );
+  auto conv = this->GetInputData< _TCostConversion >( "CostConversion" );
+
+  // Configure filter
+  auto filter = this->_CreateITK< _TFilter >( );
+  filter->SetInput( image );
+  filter->SetNeighborhoodFunction( neig );
+  filter->SetCostFunction( cost );
+  filter->SetCostConversionFunction( conv );
+  filter->SetStopAtOneFront( this->m_Parameters.GetBool( "StopAtOneFront" ) );
+
+  // Assign seeds
+  auto seeds = this->GetInputData< vtkPolyData >( "Seeds" );
+  if( seeds != NULL )
+  {
+    typename _TInputImage::PointType pnt;
+    typename _TInputImage::IndexType idx;
+    unsigned int dim =
+      ( _TInputImage::ImageDimension < 3 )? _TInputImage::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
+
+  // Assign outputs
+  filter->Update( );
+  this->GetOutput( "Output" )->SetITK( filter->GetOutput( ) );
+  this->GetOutput( "MST" )->SetITK( filter->GetMinimumSpanningTree( ) );
+}
+
+// eof - $RCSfile$
diff --git a/plugins/Plugins/ImageDijkstra.h b/plugins/Plugins/ImageDijkstra.h
new file mode 100644 (file)
index 0000000..74198c3
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef __fpa__Plugins__ImageDijkstra__h__
+#define __fpa__Plugins__ImageDijkstra__h__
+
+#include <plugins/Plugins/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 _TOutputImage >
+    inline void _GD1( _TInputImage* image );
+  };
+
+} // ecapseman
+
+#endif // __fpa__Plugins__ImageDijkstra__h__
+
+// eof - $RCSfile$
diff --git a/plugins/Plugins/InvertCost.cxx b/plugins/Plugins/InvertCost.cxx
new file mode 100644 (file)
index 0000000..fe77e0f
--- /dev/null
@@ -0,0 +1,55 @@
+#include <plugins/Plugins/InvertCost.h>
+#include <cpPlugins/DataObjects/Image.h>
+
+#include <fpa/Base/Functors/Inverse.h>
+#include <fpa/Base/Functors/Inverse.hxx>
+
+// -------------------------------------------------------------------------
+fpaPlugins::InvertCost::
+InvertCost( )
+  : Superclass( )
+{
+  typedef cpPlugins::BaseObjects::DataObject _TData;
+  this->_ConfigureOutput< _TData >( "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::InvertCost::
+~InvertCost( )
+{
+}
+
+// -------------------------------------------------------------------------
+void fpaPlugins::InvertCost::
+_GenerateData( )
+{
+  auto rtype = this->m_Parameters.GetSelectedChoice( "ResultType" );
+  if     ( rtype == "float"  ) this->_GD0< float >( );
+  else if( rtype == "double" ) this->_GD0< double >( );
+}
+
+// -------------------------------------------------------------------------
+template< class _TOutput >
+void fpaPlugins::InvertCost::
+_GD0( )
+{
+  typedef fpa::Base::Functors::Inverse< _TOutput, _TOutput > _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$
diff --git a/plugins/Plugins/InvertCost.h b/plugins/Plugins/InvertCost.h
new file mode 100644 (file)
index 0000000..f113068
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef __fpa__Plugins__InvertCost__h__
+#define __fpa__Plugins__InvertCost__h__
+
+#include <plugins/fpaPlugins_Export.h>
+#include <cpPlugins/BaseObjects/ProcessObject.h>
+
+namespace fpaPlugins
+{
+  /**
+   */
+  class fpaPlugins_EXPORT InvertCost
+    : public cpPlugins::BaseObjects::ProcessObject
+  {
+    cpPluginsObject(
+      InvertCost,
+      cpPlugins::BaseObjects::ProcessObject,
+      fpaFunctors
+      );
+
+  protected:
+    template< class _TOutput >
+    inline void _GD0( );
+  };
+
+} // ecapseman
+
+#endif // __fpa__Plugins__InvertCost__h__
+
+// eof - $RCSfile$
diff --git a/plugins/Plugins/SimpleImageDijkstraCost.cxx b/plugins/Plugins/SimpleImageDijkstraCost.cxx
new file mode 100644 (file)
index 0000000..6557a7f
--- /dev/null
@@ -0,0 +1,73 @@
+#include <plugins/Plugins/SimpleImageDijkstraCost.h>
+#include <cpPlugins/DataObjects/Image.h>
+
+#include <fpa/Image/Functors/SimpleDijkstraCost.h>
+#include <fpa/Image/Functors/SimpleDijkstraCost.hxx>
+
+// -------------------------------------------------------------------------
+fpaPlugins::SimpleImageDijkstraCost::
+SimpleImageDijkstraCost( )
+  : Superclass( )
+{
+  typedef cpPlugins::BaseObjects::DataObject _TData;
+  typedef cpPlugins::DataObjects::Image _TImage;
+
+  this->_ConfigureInput< _TImage >( "Input", true, false );
+  this->_ConfigureOutput< _TData >( "Output" );
+
+  std::vector< std::string > choices;
+  choices.push_back( "float" );
+  choices.push_back( "double" );
+  this->m_Parameters.ConfigureAsChoices( "ResultType", choices );
+  this->m_Parameters.ConfigureAsBool( "UseImageSpacing" );
+
+  this->m_Parameters.SetSelectedChoice( "ResultType", "float" );
+  this->m_Parameters.SetBool( "UseImageSpacing", false );
+}
+
+// -------------------------------------------------------------------------
+fpaPlugins::SimpleImageDijkstraCost::
+~SimpleImageDijkstraCost( )
+{
+}
+
+// -------------------------------------------------------------------------
+void fpaPlugins::SimpleImageDijkstraCost::
+_GenerateData( )
+{
+  auto o = this->GetInputData( "Input" );
+  cpPlugins_Demangle_ImageScalars_Dims( o, _GD0 );
+  else this->_Error( "Invalid input image." );
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage >
+void fpaPlugins::SimpleImageDijkstraCost::
+_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 _TImage, class _TOutput >
+void fpaPlugins::SimpleImageDijkstraCost::
+_GD1( _TImage* image )
+{
+  typedef
+    fpa::Image::Functors::SimpleDijkstraCost< _TImage, _TOutput >
+    _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->SetUseImageSpacing( this->m_Parameters.GetBool( "UseImageSpacing" ) );
+}
+
+// eof - $RCSfile$
diff --git a/plugins/Plugins/SimpleImageDijkstraCost.h b/plugins/Plugins/SimpleImageDijkstraCost.h
new file mode 100644 (file)
index 0000000..80ae8f9
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef __fpa__Plugins__SimpleImageDijkstraCost__h__
+#define __fpa__Plugins__SimpleImageDijkstraCost__h__
+
+#include <plugins/fpaPlugins_Export.h>
+#include <cpPlugins/BaseObjects/ProcessObject.h>
+
+namespace fpaPlugins
+{
+  /**
+   */
+  class fpaPlugins_EXPORT SimpleImageDijkstraCost
+    : public cpPlugins::BaseObjects::ProcessObject
+  {
+    cpPluginsObject(
+      SimpleImageDijkstraCost,
+      cpPlugins::BaseObjects::ProcessObject,
+      fpaFunctors
+      );
+
+  protected:
+    template< class _TImage >
+    inline void _GD0( _TImage* image );
+
+    template< class _TImage, class _TOutput >
+    inline void _GD1( _TImage* image );
+  };
+
+} // ecapseman
+
+#endif // __fpa__Plugins__SimpleImageDijkstraCost__h__
+
+// eof - $RCSfile$
diff --git a/plugins/Plugins/SimpleImageNeighborhood.cxx b/plugins/Plugins/SimpleImageNeighborhood.cxx
new file mode 100644 (file)
index 0000000..0fc9837
--- /dev/null
@@ -0,0 +1,55 @@
+#include <plugins/Plugins/SimpleImageNeighborhood.h>
+#include <cpPlugins/DataObjects/Image.h>
+
+#include <fpa/Image/Functors/SimpleNeighborhood.h>
+#include <fpa/Image/Functors/SimpleNeighborhood.hxx>
+
+// -------------------------------------------------------------------------
+fpaPlugins::SimpleImageNeighborhood::
+SimpleImageNeighborhood( )
+  : Superclass( )
+{
+  typedef cpPlugins::BaseObjects::DataObject _TData;
+  typedef cpPlugins::DataObjects::Image _TImage;
+
+  this->_ConfigureInput< _TImage >( "Input", true, false );
+  this->_ConfigureOutput< _TData >( "Output" );
+
+  this->m_Parameters.ConfigureAsUint( "Order" );
+  this->m_Parameters.SetUint( "Order", 1 );
+}
+
+// -------------------------------------------------------------------------
+fpaPlugins::SimpleImageNeighborhood::
+~SimpleImageNeighborhood( )
+{
+}
+
+// -------------------------------------------------------------------------
+void fpaPlugins::SimpleImageNeighborhood::
+_GenerateData( )
+{
+  auto o = this->GetInputData( "Input" );
+  cpPlugins_Demangle_ImageProcessDims( o, _GD0 );
+  else this->_Error( "Invalid input image." );
+}
+
+// -------------------------------------------------------------------------
+template< class _TImage >
+void fpaPlugins::SimpleImageNeighborhood::
+_GD0( _TImage* image )
+{
+  typedef fpa::Image::Functors::SimpleNeighborhood< _TImage > _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->SetOrder( this->m_Parameters.GetUint( "Order" ) );
+}
+
+// eof - $RCSfile$
diff --git a/plugins/Plugins/SimpleImageNeighborhood.h b/plugins/Plugins/SimpleImageNeighborhood.h
new file mode 100644 (file)
index 0000000..e47b42d
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef __fpa__Plugins__SimpleImageNeighborhood__h__
+#define __fpa__Plugins__SimpleImageNeighborhood__h__
+
+#include <plugins/fpaPlugins_Export.h>
+#include <cpPlugins/BaseObjects/ProcessObject.h>
+
+namespace fpaPlugins
+{
+  /**
+   */
+  class fpaPlugins_EXPORT SimpleImageNeighborhood
+    : public cpPlugins::BaseObjects::ProcessObject
+  {
+    cpPluginsObject(
+      SimpleImageNeighborhood,
+      cpPlugins::BaseObjects::ProcessObject,
+      fpaFunctors
+      );
+
+  protected:
+    template< class _TImage >
+    inline void _GD0( _TImage* image );
+  };
+
+} // ecapseman
+
+#endif // __fpa__Plugins__SimpleImageNeighborhood__h__
+
+// eof - $RCSfile$