From 7cb3cc75aadcbcb765962d4a326388b9c4fef984 Mon Sep 17 00:00:00 2001 From: Leonardo Florez-Valencia Date: Tue, 27 Sep 2016 13:51:22 +0200 Subject: [PATCH] Rasterization improved. --- .../Algorithms/RasterContourFilter.h | 27 +++- .../Algorithms/RasterContourFilter.hxx | 127 ++++++++++-------- plugins/ImageMeshFilters/RasterMeshFilter.cxx | 9 +- 3 files changed, 102 insertions(+), 61 deletions(-) diff --git a/lib/cpExtensions/Algorithms/RasterContourFilter.h b/lib/cpExtensions/Algorithms/RasterContourFilter.h index 8d22bba..4797dec 100644 --- a/lib/cpExtensions/Algorithms/RasterContourFilter.h +++ b/lib/cpExtensions/Algorithms/RasterContourFilter.h @@ -7,11 +7,7 @@ #include #include -#include - -// ------------------------------------------------------------------------- -class vtkPoints; -class vtkPolygon; +#include // ------------------------------------------------------------------------- namespace cpExtensions @@ -53,7 +49,8 @@ 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: @@ -73,7 +70,9 @@ namespace cpExtensions 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; @@ -83,6 +82,20 @@ namespace cpExtensions } // 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 #endif // ITK_MANUAL_INSTANTIATION diff --git a/lib/cpExtensions/Algorithms/RasterContourFilter.hxx b/lib/cpExtensions/Algorithms/RasterContourFilter.hxx index 2f7481f..4e7539a 100644 --- a/lib/cpExtensions/Algorithms/RasterContourFilter.hxx +++ b/lib/cpExtensions/Algorithms/RasterContourFilter.hxx @@ -16,7 +16,10 @@ template< class _TImage > 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( ); } @@ -25,22 +28,10 @@ template< class _TImage > 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( ); } @@ -49,7 +40,8 @@ template< class _TImage > void cpExtensions::Algorithms::RasterContourFilter< _TImage >:: ClearPoints( ) { - this->m_Polygon = vtkSmartPointer< vtkPolygon >::New( ); + this->m_Contour.clear( ); + this->Modified( ); } // ------------------------------------------------------------------------- @@ -88,6 +80,42 @@ template< class _TImage > 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 ); } // ------------------------------------------------------------------------- @@ -102,46 +130,39 @@ template< class _TImage > 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 } diff --git a/plugins/ImageMeshFilters/RasterMeshFilter.cxx b/plugins/ImageMeshFilters/RasterMeshFilter.cxx index 4124cb1..8452f2d 100644 --- a/plugins/ImageMeshFilters/RasterMeshFilter.cxx +++ b/plugins/ImageMeshFilters/RasterMeshFilter.cxx @@ -81,7 +81,14 @@ _GD0_2D( _TMesh* mesh ) _TPixel outside = _TPixel( this->m_Parameters.GetUint( "OutsideValue" ) ); auto filter = this->_CreateITK< _TFilter >( ); - filter->AddPoints( mesh->GetPoints( ) ); + filter->ClearPoints( ); + double pnt[ 3 ]; + for( unsigned long i = 0; i < mesh->GetNumberOfPoints( ); ++i ) + { + mesh->GetPoint( i, pnt ); + filter->AddPoint( pnt[ 0 ], pnt[ 1 ] ); + + } // rof filter->SetTemplate( in_im ); filter->SetInsideValue( inside ); filter->SetOutsideValue( outside ); -- 2.47.1