]> Creatis software - FrontAlgorithms.git/commitdiff
Skeletonization ready to use
authorLeonardo Florez-Valencia <florez-l@javeriana.edu.co>
Fri, 10 Apr 2015 02:40:15 +0000 (21:40 -0500)
committerLeonardo Florez-Valencia <florez-l@javeriana.edu.co>
Fri, 10 Apr 2015 02:40:15 +0000 (21:40 -0500)
appli/examples/CMakeLists.txt
appli/examples/example_ShowSkeleton.cxx [new file with mode: 0644]
lib/fpa/Base/MinimumSpanningTree.h
lib/fpa/IO/MatrixValuesContainerReader.h [new file with mode: 0644]
lib/fpa/IO/MatrixValuesContainerReader.hxx [new file with mode: 0644]
lib/fpa/IO/MinimumSpanningTreeReader.h [new file with mode: 0644]
lib/fpa/IO/MinimumSpanningTreeReader.hxx [new file with mode: 0644]
lib/fpa/IO/UniqueValuesContainerReader.h [new file with mode: 0644]
lib/fpa/IO/UniqueValuesContainerReader.hxx [new file with mode: 0644]

index fd255c15d27dbb2ccf809a3a86634c4dc34094b1..3e000b89de5836599318ee1557fa7fb3544db10d 100644 (file)
@@ -18,6 +18,7 @@ IF(USE_VTK)
     example_Image_Dijkstra_DanielssonCost
     example_Image_Dijkstra_DanielssonCost_TwoSeedsPath
     example_Image_Dijkstra_EndPointDetection
+    example_ShowSkeleton
     )
   FOREACH(EX ${SIMPLE_VTK_EXAMPLES})
     ADD_EXECUTABLE(${EX} ${EX}.cxx)
diff --git a/appli/examples/example_ShowSkeleton.cxx b/appli/examples/example_ShowSkeleton.cxx
new file mode 100644 (file)
index 0000000..b4d03b4
--- /dev/null
@@ -0,0 +1,254 @@
+#include <cstdlib>
+#include <ctime>
+#include <iostream>
+#include <limits>
+#include <string>
+
+#include <itkImage.h>
+#include <itkImageToVTKImageFilter.h>
+
+#include <itkImageFileReader.h>
+#include <fpa/VTK/ImageMPR.h>
+
+#include <fpa/Image/DijkstraWithEndPointDetection.h>
+#include <fpa/IO/MinimumSpanningTreeReader.h>
+#include <fpa/IO/UniqueValuesContainerReader.h>
+#include <fpa/IO/MatrixValuesContainerReader.h>
+
+#include <vtkCellArray.h>
+#include <vtkFloatArray.h>
+#include <vtkImageMarchingCubes.h>
+#include <vtkPoints.h>
+#include <vtkPointData.h>
+#include <vtkPolyData.h>
+#include <vtkSmartPointer.h>
+
+// -------------------------------------------------------------------------
+const unsigned int Dim = 3;
+typedef unsigned char TPixel;
+
+typedef itk::Image< TPixel, Dim >            TImage;
+typedef itk::ImageToVTKImageFilter< TImage > TVTKInputImage;
+
+typedef fpa::Image::DijkstraWithEndPointDetection< TImage, TImage > TFilter;
+typedef TFilter::TMinimumSpanningTree TMinimumSpanningTree;
+typedef TFilter::TUniqueVertices TUniqueVertices;
+typedef TFilter::TBranches TBranches;
+typedef TFilter::TVertices TVertices;
+
+// -------------------------------------------------------------------------
+int main( int argc, char* argv[] )
+{
+  if( argc < 6 )
+  {
+    std::cerr
+      << "Usage: " << argv[ 0 ] << std::endl
+      << " input_image" << std::endl
+      << " input_minimum_spanning_tree" << std::endl
+      << " input_endpoints" << std::endl
+      << " input_bifurcations" << std::endl
+      << " input_branches" << std::endl
+      << std::endl;
+    return( 1 );
+
+  } // fi
+  std::string input_image_fn = argv[ 1 ];
+  std::string mst_input_fn = argv[ 2 ];
+  std::string endpoints_input_fn = argv[ 3 ];
+  std::string bifurcations_input_fn = argv[ 4 ];
+  std::string branches_input_fn = argv[ 5 ];
+
+  // Read image
+  typename itk::ImageFileReader< TImage >::Pointer input_image_reader =
+    itk::ImageFileReader< TImage >::New( );
+  input_image_reader->SetFileName( input_image_fn );
+  input_image_reader->Update( );
+  TImage::ConstPointer input_image = input_image_reader->GetOutput( );
+
+  TVTKInputImage::Pointer vtk_input_image = TVTKInputImage::New( );
+  vtk_input_image->SetInput( input_image );
+  vtk_input_image->Update( );
+
+  // Read minimum spanning tree
+  fpa::IO::MinimumSpanningTreeReader< TMinimumSpanningTree >::Pointer
+    mst_input_reader =
+    fpa::IO::MinimumSpanningTreeReader< TMinimumSpanningTree >::New( );
+  mst_input_reader->SetFileName( mst_input_fn );
+  mst_input_reader->Update( );
+  TMinimumSpanningTree::ConstPointer mst_input = mst_input_reader->GetOutput( );
+
+  fpa::IO::UniqueValuesContainerReader< TUniqueVertices >::Pointer
+    endpoints_input_reader =
+    fpa::IO::UniqueValuesContainerReader< TUniqueVertices >::New( );
+  endpoints_input_reader->SetFileName( endpoints_input_fn );
+  endpoints_input_reader->Update( );
+  TUniqueVertices::ConstPointer endpoints_input = endpoints_input_reader->GetOutput( );
+
+  fpa::IO::UniqueValuesContainerReader< TUniqueVertices >::Pointer
+    bifurcations_input_reader =
+    fpa::IO::UniqueValuesContainerReader< TUniqueVertices >::New( );
+  bifurcations_input_reader->SetFileName( bifurcations_input_fn );
+  bifurcations_input_reader->Update( );
+  TUniqueVertices::ConstPointer bifurcations_input =
+    bifurcations_input_reader->GetOutput( );
+
+  fpa::IO::MatrixValuesContainerReader< TBranches >::Pointer
+    branches_input_reader =
+    fpa::IO::MatrixValuesContainerReader< TBranches >::New( );
+  branches_input_reader->SetFileName( branches_input_fn );
+  branches_input_reader->Update( );
+  TBranches::ConstPointer branches_input = branches_input_reader->GetOutput( );
+  unsigned int nBranches = branches_input_reader->GetNumberOfLabels( );
+
+  // Show input image and let some interaction
+  fpa::VTK::ImageMPR view;
+  view.SetBackground( 0.3, 0.2, 0.8 );
+  view.SetSize( 800, 800 );
+  view.SetImage( vtk_input_image->GetOutput( ) );
+
+  vtkSmartPointer< vtkImageMarchingCubes > mc =
+    vtkSmartPointer< vtkImageMarchingCubes >::New( );
+  mc->SetInputData( vtk_input_image->GetOutput( ) );
+  mc->SetValue( 0, 1e-1 );
+  mc->Update( );
+  view.AddPolyData( mc->GetOutput( ), 1, 1, 1, 0.4 );
+
+  // Show endpoints
+  vtkSmartPointer< vtkPoints > endpoints_points =
+    vtkSmartPointer< vtkPoints >::New( );
+  vtkSmartPointer< vtkCellArray > endpoints_cells =
+    vtkSmartPointer< vtkCellArray >::New( );
+  for(
+    TUniqueVertices::ConstIterator epIt = endpoints_input->Begin( );
+    epIt != endpoints_input->End( );
+    ++epIt
+    )
+  {
+    TImage::PointType pnt;
+    input_image->TransformIndexToPhysicalPoint( *epIt, pnt );
+    endpoints_points->InsertNextPoint( pnt[ 0 ], pnt[ 1 ], pnt[ 2 ] );
+    endpoints_cells->InsertNextCell( 1 );
+    endpoints_cells->
+      InsertCellPoint( endpoints_points->GetNumberOfPoints( ) - 1 );
+
+  } // rof
+  vtkSmartPointer< vtkPolyData > endpoints_polydata =
+    vtkSmartPointer< vtkPolyData >::New( );
+  endpoints_polydata->SetPoints( endpoints_points );
+  endpoints_polydata->SetVerts( endpoints_cells );
+  view.AddPolyData( endpoints_polydata, 0, 0, 1, 1 );
+
+  // Show bifurcations
+  vtkSmartPointer< vtkPoints > bifurcations_points =
+    vtkSmartPointer< vtkPoints >::New( );
+  vtkSmartPointer< vtkCellArray > bifurcations_cells =
+    vtkSmartPointer< vtkCellArray >::New( );
+  for(
+    TUniqueVertices::ConstIterator bfIt = bifurcations_input->Begin( );
+    bfIt != bifurcations_input->End( );
+    ++bfIt
+    )
+  {
+    TImage::PointType pnt;
+    input_image->TransformIndexToPhysicalPoint( *bfIt, pnt );
+    bifurcations_points->InsertNextPoint( pnt[ 0 ], pnt[ 1 ], pnt[ 2 ] );
+    bifurcations_cells->InsertNextCell( 1 );
+    bifurcations_cells->
+      InsertCellPoint( bifurcations_points->GetNumberOfPoints( ) - 1 );
+
+  } // rof
+  vtkSmartPointer< vtkPolyData > bifurcations_polydata =
+    vtkSmartPointer< vtkPolyData >::New( );
+  bifurcations_polydata->SetPoints( bifurcations_points );
+  bifurcations_polydata->SetVerts( bifurcations_cells );
+  view.AddPolyData( bifurcations_polydata, 0, 1, 0, 1 );
+
+  // Show branches (simple and detailed)
+  vtkSmartPointer< vtkPoints > simple_branches_points =
+    vtkSmartPointer< vtkPoints >::New( );
+  vtkSmartPointer< vtkCellArray > simple_branches_cells =
+    vtkSmartPointer< vtkCellArray >::New( );
+
+  vtkSmartPointer< vtkPoints > detailed_branches_points =
+    vtkSmartPointer< vtkPoints >::New( );
+  vtkSmartPointer< vtkCellArray > detailed_branches_cells =
+    vtkSmartPointer< vtkCellArray >::New( );
+  vtkSmartPointer< vtkFloatArray > detailed_branches_scalars =
+    vtkSmartPointer< vtkFloatArray >::New( );
+
+  TBranches::ConstIterator brIt = branches_input->Begin( );
+  for( ; brIt != branches_input->End( ); ++brIt )
+  {
+    // Branch's first point
+    TImage::PointType first_point;
+    input_image->TransformIndexToPhysicalPoint( brIt->first, first_point );
+    unsigned long first_id = simple_branches_points->GetNumberOfPoints( );
+    simple_branches_points->InsertNextPoint(
+      first_point[ 0 ], first_point[ 1 ], first_point[ 2 ]
+      );
+
+    TBranches::ConstRowIterator brRowIt = branches_input->Begin( brIt );
+    for( ; brRowIt != branches_input->End( brIt ); ++brRowIt )
+    {
+      // Branch's second point
+      TImage::PointType second_point;
+      input_image->
+        TransformIndexToPhysicalPoint( brRowIt->first, second_point );
+      unsigned long second_id = simple_branches_points->GetNumberOfPoints( );
+      simple_branches_points->InsertNextPoint(
+        second_point[ 0 ], second_point[ 1 ], second_point[ 2 ]
+        );
+      simple_branches_cells->InsertNextCell( 2 );
+      simple_branches_cells->InsertCellPoint( first_id );
+      simple_branches_cells->InsertCellPoint( second_id );
+
+      // Detailed path
+      double pathId = double( brRowIt->second - 1 ) / double( nBranches - 1 );
+      TVertices path;
+      mst_input->GetPath( path, brIt->first, brRowIt->first );
+      TVertices::const_iterator pIt = path.begin( );
+      for( ; pIt != path.end( ); ++pIt )
+      {
+        TImage::PointType path_point;
+        input_image->TransformIndexToPhysicalPoint( *pIt, path_point );
+        detailed_branches_points->InsertNextPoint(
+          path_point[ 0 ], path_point[ 1 ], path_point[ 2 ]
+          );
+        detailed_branches_scalars->InsertNextTuple1( pathId );
+        if( pIt != path.begin( ) )
+        {
+          unsigned long nPoints =
+            detailed_branches_points->GetNumberOfPoints( );
+          detailed_branches_cells->InsertNextCell( 2 );
+          detailed_branches_cells->InsertCellPoint( nPoints - 2 );
+          detailed_branches_cells->InsertCellPoint( nPoints - 1 );
+
+        } // fi
+
+      } // rof
+
+    } // rof
+
+  } // rof
+  vtkSmartPointer< vtkPolyData > simple_branches_polydata =
+    vtkSmartPointer< vtkPolyData >::New( );
+  simple_branches_polydata->SetPoints( simple_branches_points );
+  simple_branches_polydata->SetLines( simple_branches_cells );
+  view.AddPolyData( simple_branches_polydata, 1, 0, 1, 1 );
+
+  vtkSmartPointer< vtkPolyData > detailed_branches_polydata =
+    vtkSmartPointer< vtkPolyData >::New( );
+  detailed_branches_polydata->SetPoints( detailed_branches_points );
+  detailed_branches_polydata->SetLines( detailed_branches_cells );
+  detailed_branches_polydata->
+    GetPointData( )->SetScalars( detailed_branches_scalars );
+  view.AddPolyData( detailed_branches_polydata, 1 );
+
+  // Allow some interaction
+  view.Render( );
+  view.Start( );
+
+  return( 0 );
+}
+
+// eof - $RCSfile$
index be6dae416b8fbbfe35e06ffb84de137dd3759b5e..a020d4795d1f78e25f0d13fab1cc006971c63f46 100644 (file)
@@ -46,7 +46,12 @@ namespace fpa
           this->Get( )[ v ] = TNodeInfo( p, fid );
           this->Modified( );
         }
-
+      void Clear( )
+        {
+          this->Get( ).clear( );
+          this->m_Collisions.clear( );
+          this->m_FrontPaths.clear( );
+        }
       virtual void GetPath(
         std::vector< V >& path, const V& a, const V& b
         ) const;
diff --git a/lib/fpa/IO/MatrixValuesContainerReader.h b/lib/fpa/IO/MatrixValuesContainerReader.h
new file mode 100644 (file)
index 0000000..8d65074
--- /dev/null
@@ -0,0 +1,63 @@
+#ifndef __FPA__IO__MATRIXVALUESCONTAINERREADER__H__
+#define __FPA__IO__MATRIXVALUESCONTAINERREADER__H__
+
+#include <string>
+#include <itkProcessObject.h>
+
+namespace fpa
+{
+  namespace IO
+  {
+    /**
+     */
+    template< class T >
+    class MatrixValuesContainerReader
+      : public itk::ProcessObject
+    {
+    public:
+      typedef MatrixValuesContainerReader       Self;
+      typedef itk::ProcessObject              Superclass;
+      typedef itk::SmartPointer< Self >       Pointer;
+      typedef itk::SmartPointer< const Self > ConstPointer;
+
+      typedef T TTree;
+
+    public:
+      itkNewMacro( Self );
+      itkTypeMacro( MatrixValuesContainerReader, itkProcessObject );
+
+      itkGetConstMacro( FileName, std::string );
+      itkGetConstMacro( NumberOfLabels, unsigned int );
+
+      itkSetMacro( FileName, std::string );
+
+    public:
+      T* GetOutput( );
+
+      virtual void Update( );
+
+    protected:
+      MatrixValuesContainerReader( );
+      virtual ~MatrixValuesContainerReader( );
+
+      virtual void GenerateData( );
+
+    private:
+      // Purposely not implemented
+      MatrixValuesContainerReader( const Self& other );
+      Self& operator=( const Self& other );
+
+    protected:
+      std::string m_FileName;
+      unsigned int m_NumberOfLabels;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#include <fpa/IO/MatrixValuesContainerReader.hxx>
+
+#endif // __FPA__IO__MATRIXVALUESCONTAINERREADER__H__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/IO/MatrixValuesContainerReader.hxx b/lib/fpa/IO/MatrixValuesContainerReader.hxx
new file mode 100644 (file)
index 0000000..902462b
--- /dev/null
@@ -0,0 +1,103 @@
+#ifndef __FPA__IO__MATRIXVALUESCONTAINERREADER__HXX__
+#define __FPA__IO__MATRIXVALUESCONTAINERREADER__HXX__
+
+#include <fstream>
+
+// -------------------------------------------------------------------------
+template< class T >
+T* fpa::IO::MatrixValuesContainerReader< T >::
+GetOutput( )
+{
+  return( itkDynamicCastInDebugMode< T* >( this->GetPrimaryOutput( ) ) );
+}
+
+// -------------------------------------------------------------------------
+template< class T >
+void fpa::IO::MatrixValuesContainerReader< T >::
+Update( )
+{
+  this->GenerateData( );
+}
+
+// -------------------------------------------------------------------------
+template< class T >
+fpa::IO::MatrixValuesContainerReader< T >::
+MatrixValuesContainerReader( )
+  : Superclass( ),
+    m_FileName( "" )
+{
+  this->itk::ProcessObject::SetNumberOfRequiredOutputs( 1 );
+  this->itk::ProcessObject::SetNthOutput( 0, T::New( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class T >
+fpa::IO::MatrixValuesContainerReader< T >::
+~MatrixValuesContainerReader( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class T >
+void fpa::IO::MatrixValuesContainerReader< T >::
+GenerateData( )
+{
+  T* output = this->GetOutput( );
+  output->Clear( );
+
+  std::ifstream in( this->m_FileName.c_str( ) );
+  if( !in )
+  {
+    itkExceptionMacro(
+      << "Error opening file to read a minimum spanning tree: \""
+      << this->m_FileName
+      << "\""
+      );
+    return;
+
+  } // fi
+
+  unsigned int dim;
+  unsigned long nTuples;
+  in >> dim >> nTuples;
+  this->m_NumberOfLabels = 0;
+  for( unsigned long tId = 0; tId < nTuples; ++tId )
+  {
+    unsigned long nCouples;
+    in >> nCouples;
+    typename T::TIndex v0;
+    for( unsigned int d = 0; d < dim; ++d )
+    {
+      long val;
+      in >> val;
+      if( d < T::TIndex::Dimension )
+        v0[ d ] = val;
+    
+    } // rof
+
+    for( unsigned long cId = 0; cId < nCouples; ++cId )
+    {
+      typename T::TIndex v1;
+      for( unsigned int d = 0; d < dim; ++d )
+      {
+        long val;
+        in >> val;
+        if( d < T::TIndex::Dimension )
+          v1[ d ] = val;
+    
+      } // rof
+      typename T::TValue val;
+      in >> val;
+      output->SetValue( v0, v1, val );
+      if( val > this->m_NumberOfLabels )
+        this->m_NumberOfLabels = val;
+
+    } // rof
+
+  } // rof
+  in.close( );
+}
+
+#endif // __FPA__IO__MATRIXVALUESCONTAINERREADER__HXX__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/IO/MinimumSpanningTreeReader.h b/lib/fpa/IO/MinimumSpanningTreeReader.h
new file mode 100644 (file)
index 0000000..40bf102
--- /dev/null
@@ -0,0 +1,60 @@
+#ifndef __FPA__IO__MINIMUMSPANNINGTREEREADER__H__
+#define __FPA__IO__MINIMUMSPANNINGTREEREADER__H__
+
+#include <string>
+#include <itkProcessObject.h>
+
+namespace fpa
+{
+  namespace IO
+  {
+    /**
+     */
+    template< class T >
+    class MinimumSpanningTreeReader
+      : public itk::ProcessObject
+    {
+    public:
+      typedef MinimumSpanningTreeReader       Self;
+      typedef itk::ProcessObject              Superclass;
+      typedef itk::SmartPointer< Self >       Pointer;
+      typedef itk::SmartPointer< const Self > ConstPointer;
+
+      typedef T TTree;
+
+    public:
+      itkNewMacro( Self );
+      itkTypeMacro( MinimumSpanningTreeReader, itkProcessObject );
+
+      itkGetConstMacro( FileName, std::string );
+      itkSetMacro( FileName, std::string );
+
+    public:
+      T* GetOutput( );
+
+      virtual void Update( );
+
+    protected:
+      MinimumSpanningTreeReader( );
+      virtual ~MinimumSpanningTreeReader( );
+
+      virtual void GenerateData( );
+
+    private:
+      // Purposely not implemented
+      MinimumSpanningTreeReader( const Self& other );
+      Self& operator=( const Self& other );
+
+    protected:
+      std::string m_FileName;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#include <fpa/IO/MinimumSpanningTreeReader.hxx>
+
+#endif // __FPA__IO__MINIMUMSPANNINGTREEREADER__H__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/IO/MinimumSpanningTreeReader.hxx b/lib/fpa/IO/MinimumSpanningTreeReader.hxx
new file mode 100644 (file)
index 0000000..9a41db5
--- /dev/null
@@ -0,0 +1,114 @@
+#ifndef __FPA__IO__MINIMUMSPANNINGTREEREADER__HXX__
+#define __FPA__IO__MINIMUMSPANNINGTREEREADER__HXX__
+
+#include <fstream>
+
+// -------------------------------------------------------------------------
+template< class T >
+T* fpa::IO::MinimumSpanningTreeReader< T >::
+GetOutput( )
+{
+  return( itkDynamicCastInDebugMode< T* >( this->GetPrimaryOutput( ) ) );
+}
+
+// -------------------------------------------------------------------------
+template< class T >
+void fpa::IO::MinimumSpanningTreeReader< T >::
+Update( )
+{
+  this->GenerateData( );
+}
+
+// -------------------------------------------------------------------------
+template< class T >
+fpa::IO::MinimumSpanningTreeReader< T >::
+MinimumSpanningTreeReader( )
+  : Superclass( ),
+    m_FileName( "" )
+{
+  this->itk::ProcessObject::SetNumberOfRequiredOutputs( 1 );
+  this->itk::ProcessObject::SetNthOutput( 0, T::New( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class T >
+fpa::IO::MinimumSpanningTreeReader< T >::
+~MinimumSpanningTreeReader( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class T >
+void fpa::IO::MinimumSpanningTreeReader< T >::
+GenerateData( )
+{
+  T* output = this->GetOutput( );
+  output->Clear( );
+
+  std::ifstream in( this->m_FileName.c_str( ) );
+  if( !in )
+  {
+    itkExceptionMacro(
+      << "Error opening file to read a minimum spanning tree: \""
+      << this->m_FileName
+      << "\""
+      );
+    return;
+
+  } // fi
+
+  unsigned int dim;
+  unsigned long nSeeds, nVertices;
+  in >> dim >> nSeeds;
+
+  typedef typename T::TCollisions _TCollisions;
+  typedef typename _TCollisions::value_type _TCollisionsRow;
+  typedef typename _TCollisionsRow::value_type _TCollision;
+  typedef typename T::TVertex _TVertex;
+
+  _TCollisions
+    collisions( nSeeds, _TCollisionsRow( nSeeds, _TCollision( _TVertex( ), false ) ) );
+  for( unsigned long i = 0; i < nSeeds; ++i )
+  {
+    for( unsigned long j = 0; j < nSeeds; ++j )
+    {
+      int val;
+      in >> val;
+      collisions[ i ][ j ].second = ( val == 1 );
+
+    } // rof
+
+  } // rof
+
+  in >> nVertices;
+  for( unsigned long vId = 0; vId < nVertices; ++vId )
+  {
+    typename T::TVertex v0, v1;
+    for( unsigned int d = 0; d < dim; ++d )
+    {
+      long val;
+      in >> val;
+      if( d < T::TVertex::Dimension )
+        v0[ d ] = val;
+
+    } // rof
+    for( unsigned int d = 0; d < dim; ++d )
+    {
+      long val;
+      in >> val;
+      if( d < T::TVertex::Dimension )
+        v1[ d ] = val;
+
+    } // rof
+    short fId;
+    in >> fId;
+    output->SetParent( v0, v1, fId );
+
+  } // rof
+  output->SetCollisions( collisions );
+  in.close( );
+}
+
+#endif // __FPA__IO__MINIMUMSPANNINGTREEREADER__HXX__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/IO/UniqueValuesContainerReader.h b/lib/fpa/IO/UniqueValuesContainerReader.h
new file mode 100644 (file)
index 0000000..5dc895b
--- /dev/null
@@ -0,0 +1,60 @@
+#ifndef __FPA__IO__UNIQUEVALUESCONTAINERREADER__H__
+#define __FPA__IO__UNIQUEVALUESCONTAINERREADER__H__
+
+#include <string>
+#include <itkProcessObject.h>
+
+namespace fpa
+{
+  namespace IO
+  {
+    /**
+     */
+    template< class T >
+    class UniqueValuesContainerReader
+      : public itk::ProcessObject
+    {
+    public:
+      typedef UniqueValuesContainerReader       Self;
+      typedef itk::ProcessObject              Superclass;
+      typedef itk::SmartPointer< Self >       Pointer;
+      typedef itk::SmartPointer< const Self > ConstPointer;
+
+      typedef T TTree;
+
+    public:
+      itkNewMacro( Self );
+      itkTypeMacro( UniqueValuesContainerReader, itkProcessObject );
+
+      itkGetConstMacro( FileName, std::string );
+      itkSetMacro( FileName, std::string );
+
+    public:
+      T* GetOutput( );
+
+      virtual void Update( );
+
+    protected:
+      UniqueValuesContainerReader( );
+      virtual ~UniqueValuesContainerReader( );
+
+      virtual void GenerateData( );
+
+    private:
+      // Purposely not implemented
+      UniqueValuesContainerReader( const Self& other );
+      Self& operator=( const Self& other );
+
+    protected:
+      std::string m_FileName;
+    };
+
+  } // ecapseman
+
+} // ecapseman
+
+#include <fpa/IO/UniqueValuesContainerReader.hxx>
+
+#endif // __FPA__IO__UNIQUEVALUESCONTAINERREADER__H__
+
+// eof - $RCSfile$
diff --git a/lib/fpa/IO/UniqueValuesContainerReader.hxx b/lib/fpa/IO/UniqueValuesContainerReader.hxx
new file mode 100644 (file)
index 0000000..16719f2
--- /dev/null
@@ -0,0 +1,82 @@
+#ifndef __FPA__IO__UNIQUEVALUESCONTAINERREADER__HXX__
+#define __FPA__IO__UNIQUEVALUESCONTAINERREADER__HXX__
+
+#include <fstream>
+
+// -------------------------------------------------------------------------
+template< class T >
+T* fpa::IO::UniqueValuesContainerReader< T >::
+GetOutput( )
+{
+  return( itkDynamicCastInDebugMode< T* >( this->GetPrimaryOutput( ) ) );
+}
+
+// -------------------------------------------------------------------------
+template< class T >
+void fpa::IO::UniqueValuesContainerReader< T >::
+Update( )
+{
+  this->GenerateData( );
+}
+
+// -------------------------------------------------------------------------
+template< class T >
+fpa::IO::UniqueValuesContainerReader< T >::
+UniqueValuesContainerReader( )
+  : Superclass( ),
+    m_FileName( "" )
+{
+  this->itk::ProcessObject::SetNumberOfRequiredOutputs( 1 );
+  this->itk::ProcessObject::SetNthOutput( 0, T::New( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class T >
+fpa::IO::UniqueValuesContainerReader< T >::
+~UniqueValuesContainerReader( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class T >
+void fpa::IO::UniqueValuesContainerReader< T >::
+GenerateData( )
+{
+  T* output = this->GetOutput( );
+  output->Clear( );
+
+  std::ifstream in( this->m_FileName.c_str( ) );
+  if( !in )
+  {
+    itkExceptionMacro(
+      << "Error opening file to read a minimum spanning tree: \""
+      << this->m_FileName
+      << "\""
+      );
+    return;
+
+  } // fi
+
+  unsigned int dim;
+  unsigned long nVertices;
+  in >> dim >> nVertices;
+  for( unsigned long vId = 0; vId < nVertices; ++vId )
+  {
+    typename T::TValue v;
+    for( unsigned int d = 0; d < dim; ++d )
+    {
+      long val;
+      in >> val;
+      if( d < T::TValue::Dimension )
+        v[ d ] = val;
+
+    } // rof
+    output->Insert( v );
+
+  } // rof
+  in.close( );
+}
+
+#endif // __FPA__IO__UNIQUEVALUESCONTAINERREADER__HXX__
+
+// eof - $RCSfile$