#include <cpExtensions/Config.h>
#include <itkImageSource.h>
-#include <vtkSmartPointer.h>
-
-// -------------------------------------------------------------------------
-class vtkPoints;
-class vtkPolygon;
+#include <deque>
// -------------------------------------------------------------------------
namespace cpExtensions
public:
void AddPoint( double x, double y );
void AddPoint( double p[ 2 ] );
- void AddPoints( vtkPoints* points );
+ template< class _TPoint >
+ inline void AddPoint( const _TPoint& p );
void ClearPoints( );
protected:
void operator=( const Self& );
protected:
- vtkSmartPointer< vtkPolygon > m_Polygon;
+ std::deque< TPoint > m_Contour;
+ std::deque< TIndex > m_Polygon;
+ TRegion m_ROI;
typename TImageBase::ConstPointer m_Template;
TPixel m_InsideValue;
TPixel m_OutsideValue;
} // ecapseman
+// -------------------------------------------------------------------------
+template< class _TImage >
+template< class _TPoint >
+void cpExtensions::Algorithms::RasterContourFilter< _TImage >::
+AddPoint( const _TPoint& p )
+{
+ TPoint pnt;
+ pnt[ 0 ] = p[ 0 ];
+ pnt[ 1 ] = p[ 2 ];
+ this->m_Contour.push_back( pnt );
+ this->Modified( );
+}
+
+// -------------------------------------------------------------------------
#ifndef ITK_MANUAL_INSTANTIATION
# include <cpExtensions/Algorithms/RasterContourFilter.hxx>
#endif // ITK_MANUAL_INSTANTIATION
void cpExtensions::Algorithms::RasterContourFilter< _TImage >::
AddPoint( double x, double y )
{
- this->m_Polygon->GetPoints( )->InsertNextPoint( x, y, 0 );
+ TPoint pnt;
+ pnt[ 0 ] = x;
+ pnt[ 1 ] = y;
+ this->m_Contour.push_back( pnt );
this->Modified( );
}
void cpExtensions::Algorithms::RasterContourFilter< _TImage >::
AddPoint( double p[ 2 ] )
{
- this->m_Polygon->GetPoints( )->InsertNextPoint( p[ 0 ], p[ 1 ], 0 );
- this->Modified( );
-}
-
-// -------------------------------------------------------------------------
-template< class _TImage >
-void cpExtensions::Algorithms::RasterContourFilter< _TImage >::
-AddPoints( vtkPoints* points )
-{
- double p[ 3 ];
- for( unsigned long i = 0; i < points->GetNumberOfPoints( ); ++i )
- {
- points->GetPoint( i, p );
- this->m_Polygon->GetPoints( )->InsertNextPoint( p[ 0 ], p[ 1 ], 0 );
-
- } // rof
+ TPoint pnt;
+ pnt[ 0 ] = p[ 0 ];
+ pnt[ 1 ] = p[ 2 ];
+ this->m_Contour.push_back( pnt );
this->Modified( );
}
void cpExtensions::Algorithms::RasterContourFilter< _TImage >::
ClearPoints( )
{
- this->m_Polygon = vtkSmartPointer< vtkPolygon >::New( );
+ this->m_Contour.clear( );
+ this->Modified( );
}
// -------------------------------------------------------------------------
void cpExtensions::Algorithms::RasterContourFilter< _TImage >::
BeforeThreadedGenerateData( )
{
+ // Keep just indices, not points
+ this->m_Polygon.clear( );
+ _TImage* out = this->GetOutput( 0 );
+ TIndex minIdx, maxIdx;
+ for( auto c = this->m_Contour.begin( ); c != this->m_Contour.end( ); ++c )
+ {
+ TIndex idx;
+ out->TransformPhysicalPointToIndex( *c, idx );
+ bool added = true;
+ if( this->m_Polygon.size( ) > 0 )
+ {
+ if( this->m_Polygon.back( ) != idx )
+ {
+ this->m_Polygon.push_back( idx );
+ minIdx[ 0 ] = ( idx[ 0 ] < minIdx[ 0 ] )? idx[ 0 ]: minIdx[ 0 ];
+ minIdx[ 1 ] = ( idx[ 1 ] < minIdx[ 1 ] )? idx[ 1 ]: minIdx[ 1 ];
+ maxIdx[ 0 ] = ( idx[ 0 ] > maxIdx[ 0 ] )? idx[ 0 ]: maxIdx[ 0 ];
+ maxIdx[ 1 ] = ( idx[ 1 ] > maxIdx[ 1 ] )? idx[ 1 ]: maxIdx[ 1 ];
+
+ } // fi
+ }
+ else
+ {
+ this->m_Polygon.push_back( idx );
+ minIdx = maxIdx = idx;
+
+ } // fi
+
+ } // rof
+
+ // Set ROI
+ typename _TImage::SizeType size;
+ size[ 0 ] = maxIdx[ 0 ] - minIdx[ 0 ] + 1;
+ size[ 1 ] = maxIdx[ 1 ] - minIdx[ 1 ] + 1;
+ this->m_ROI.SetIndex( minIdx );
+ this->m_ROI.SetSize( size );
}
// -------------------------------------------------------------------------
void cpExtensions::Algorithms::RasterContourFilter< _TImage >::
ThreadedGenerateData( const TRegion& region, itk::ThreadIdType id )
{
- vtkPoints* points = this->m_Polygon->GetPoints( );
- unsigned long nPoints = points->GetNumberOfPoints( );
- double* arr =
- static_cast< double* >( points->GetData()->GetVoidPointer( 0 ) );
- double p[ 3 ], n[ 3 ], b[ 6 ];
- this->m_Polygon->GetPoints( )->GetBounds( b );
- n[ 0 ] = n[ 1 ] = double( 0 );
- n[ 2 ] = double( 1 );
-
+ long nVerts = this->m_Polygon.size( );
_TImage* out = this->GetOutput( );
itk::ImageRegionIteratorWithIndex< _TImage > iIt( out, region );
for( iIt.GoToBegin( ); !iIt.IsAtEnd( ); ++iIt )
{
- TIndex idx = iIt.GetIndex( );
- TPoint pnt;
- out->TransformIndexToPhysicalPoint( idx, pnt );
- p[ 0 ] = pnt[ 0 ];
- p[ 1 ] = pnt[ 1 ];
- p[ 2 ] = double( 0 );
-
- int i, j, c = 0;
- int nvert = nPoints;
- for( i = 0, j = nvert - 1; i < nvert; j = i++ )
+ TIndex p = iIt.GetIndex( );
+ bool inside = false;
+ if( this->m_ROI.IsInside( p ) )
{
- double pi[ 3 ], pj[ 3 ];
- points->GetPoint( i, pi );
- points->GetPoint( j, pj );
-
- if(
- ( ( pi[ 1 ] > p[ 1 ] ) != ( pj[ 1 ] > p[ 1 ] ) ) &&
- ( p[ 0 ] < ( pj[ 0 ] - pi[ 0 ] ) * ( p[ 1 ] - pi[ 1 ] ) / ( pj[ 1 ] - pi[ 1 ] ) + pi[ 0 ] )
- )
- c = !c;
-
- } // rof
-
- if( c != 0 )
- iIt.Set( this->m_InsideValue );
- else
- iIt.Set( this->m_OutsideValue );
+ long i, j;
+ for( i = 0, j = nVerts - 1; i < nVerts; j = i++ )
+ {
+ TIndex pi = this->m_Polygon[ i ];
+ TIndex pj = this->m_Polygon[ j ];
+ double pi0 = double( pi[ 0 ] );
+ double pi1 = double( pi[ 1 ] );
+ double pj0 = double( pj[ 0 ] );
+ double pj1 = double( pj[ 1 ] );
+ double p0 = double( p[ 0 ] );
+ double p1 = double( p[ 1 ] );
+ double ji0 = pj0 - pi0;
+ double ji1 = pj1 - pi1;
+ double i1 = p1 - pi1;
+ if(
+ ( ( pi1 > p1 ) != ( pj1 > p1 ) ) &&
+ ( p0 < ( ( ji0 * i1 ) / ji1 ) + pi0 )
+ )
+ inside = !inside;
+
+ } // rof
+
+ } // fi
+ iIt.Set( ( inside )? this->m_InsideValue: this->m_OutsideValue );
} // rof
}