+#ifndef __FPA__VTK__IMAGESKELETONTOPOLYDATA__HXX__
+#define __FPA__VTK__IMAGESKELETONTOPOLYDATA__HXX__
+
+#include <vtkInformation.h>
+#include <vtkInformationVector.h>
+#include <vtkSmartPointer.h>
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+typename fpa::VTK::Image::ImageSkeletonToPolyData< _TSkeleton >::
+Self* fpa::VTK::Image::ImageSkeletonToPolyData< _TSkeleton >::
+New( )
+{
+ return( new Self( ) );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+const _TSkeleton* fpa::VTK::Image::ImageSkeletonToPolyData< _TSkeleton >::
+GetInput( ) const
+{
+ return( this->m_Skeleton );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+void fpa::VTK::Image::ImageSkeletonToPolyData< _TSkeleton >::
+SetInput( const _TSkeleton* sk )
+{
+ if( this->m_Skeleton != sk )
+ {
+ this->m_Skeleton = sk;
+ this->Modified( );
+
+ } // fi
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+fpa::VTK::Image::ImageSkeletonToPolyData< _TSkeleton >::
+ImageSkeletonToPolyData( )
+ : vtkPolyDataAlgorithm( ),
+ m_Skeleton( NULL )
+{
+ this->SetNumberOfInputPorts( 0 );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+fpa::VTK::Image::ImageSkeletonToPolyData< _TSkeleton >::
+~ImageSkeletonToPolyData( )
+{
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+int fpa::VTK::Image::ImageSkeletonToPolyData< _TSkeleton >::
+RequestData(
+ vtkInformation* information,
+ vtkInformationVector** input,
+ vtkInformationVector* output
+ )
+{
+ typedef typename _TSkeleton::TVertex _TVertex;
+ typedef typename _TSkeleton::TVertexCmp _TCmp;
+ typedef itk::Point< double, _TVertex::Dimension > _TPoint;
+ typedef
+ std::map< _TVertex, std::map< _TVertex, bool, _TCmp >, _TCmp >
+ _TMarks;
+ static const unsigned int dim = _TVertex::Dimension;
+
+ if( this->m_Skeleton == NULL )
+ return( 0 );
+
+ // Get output
+ vtkInformation* info = output->GetInformationObject( 0 );
+ vtkPolyData* out = vtkPolyData::SafeDownCast(
+ info->Get( vtkDataObject::DATA_OBJECT( ) )
+ );
+
+ // Prepare points and cells
+ vtkSmartPointer< vtkPoints > points =
+ vtkSmartPointer< vtkPoints >::New( );
+ vtkSmartPointer< vtkCellArray > lines =
+ vtkSmartPointer< vtkCellArray >::New( );
+
+ // Iterator over input data
+ auto& sk = this->m_Skeleton->Get( );
+ auto mst = this->m_Skeleton->GetMinimumSpanningTree( );
+ _TMarks marks;
+ for( auto i = sk.begin( ); i != sk.end( ); ++i )
+ {
+ for( auto j = i->second.begin( ); j != i->second.end( ); ++j )
+ {
+ if( !marks[ i->first ][ j->first ] )
+ {
+ auto path = j->second.GetPointer( );
+ if( path != NULL )
+ {
+ auto vertices = path->GetVertexList( );
+ for( unsigned int v = 0; v < vertices->Size( ); ++v )
+ {
+ auto idx = vertices->GetElement( v );
+ _TPoint pnt;
+ mst->TransformContinuousIndexToPhysicalPoint( idx, pnt );
+ if( dim == 1 )
+ points->InsertNextPoint( pnt[ 0 ], 0, 0 );
+ else if( dim == 2 )
+ points->InsertNextPoint( pnt[ 0 ], pnt[ 1 ], 0 );
+ else
+ points->InsertNextPoint( pnt[ 0 ], pnt[ 1 ], pnt[ 2 ] );
+ if( v > 0 )
+ {
+ lines->InsertNextCell( 2 );
+ lines->InsertCellPoint( points->GetNumberOfPoints( ) - 2 );
+ lines->InsertCellPoint( points->GetNumberOfPoints( ) - 1 );
+
+ } // fi
+
+ } // rof
+
+ } // fi
+
+ // Mark path and its symmetric as visited
+ marks[ i->first ][ j->first ] = true;
+ marks[ j->first ][ i->first ] = true;
+
+ } // fi
+
+ } // rof
+
+ } // rof
+ out->SetPoints( points );
+ out->SetLines( lines );
+ return( 1 );
+}
+
+// -------------------------------------------------------------------------
+template< class _TSkeleton >
+int fpa::VTK::Image::ImageSkeletonToPolyData< _TSkeleton >::
+RequestInformation(
+ vtkInformation* information,
+ vtkInformationVector** input,
+ vtkInformationVector* output
+ )
+{
+ vtkInformation* info = output->GetInformationObject( 0 );
+ /* TODO
+ info->Set(
+ vtkStreamingDemandDrivenPipeline::MAXIMUM_NUMBER_OF_PIECES( ), -1
+ );
+ */
+
+ if( this->m_Skeleton != NULL )
+ {
+ /* TODO
+ typename C::TScalar len = this->m_RGC->GetTotalLength( );
+ typename C::TScalar s0 = this->m_RGC->Gets0( );
+ typename C::TPoint p0 = this->m_RGC->Axis( s0 );
+ typename C::TPoint p1 = this->m_RGC->Axis( s0 + len );
+
+ info->Set(
+ vtkStreamingDemandDrivenPipeline::WHOLE_BOUNDING_BOX( ),
+ double( p0[ 0 ] ), double( p1[ 0 ] ),
+ double( p0[ 1 ] ), double( p1[ 1 ] ),
+ double( p0[ 2 ] ), double( p1[ 2 ] )
+ );
+ */
+
+ } // fi
+ return( 1 );
+}
+
+#endif // __FPA__VTK__IMAGESKELETONTOPOLYDATA__HXX__
+
+// eof - $RCSfile$