]> Creatis software - cpPlugins.git/blob - lib/ivq/ITK/RasterContourFilter.hxx
...
[cpPlugins.git] / lib / ivq / ITK / RasterContourFilter.hxx
1 // =======================================================================
2 // @author: Leonardo Florez-Valencia
3 // @email: florez-l@javeriana.edu.co
4 // =======================================================================
5 // Inclusion test taken from:
6 // https://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
7 // =======================================================================
8 #ifndef __ivq__ITK__RasterContourFilter__hxx__
9 #define __ivq__ITK__RasterContourFilter__hxx__
10
11 #include <itkImageRegionIteratorWithIndex.h>
12 #include <vtkPolygon.h>
13
14 // -------------------------------------------------------------------------
15 template< class _TImage >
16 void ivq::ITK::RasterContourFilter< _TImage >::
17 AddPoint( double x, double y )
18 {
19   TPoint pnt;
20   pnt[ 0 ] = x;
21   pnt[ 1 ] = y;
22   this->m_Contour.push_back( pnt );
23   this->Modified( );
24 }
25
26 // -------------------------------------------------------------------------
27 template< class _TImage >
28 void ivq::ITK::RasterContourFilter< _TImage >::
29 AddPoint( double p[ 2 ] )
30 {
31   TPoint pnt;
32   pnt[ 0 ] = p[ 0 ];
33   pnt[ 1 ] = p[ 1 ];
34   this->m_Contour.push_back( pnt );
35   this->Modified( );
36 }
37
38 // -------------------------------------------------------------------------
39 template< class _TImage >
40 void ivq::ITK::RasterContourFilter< _TImage >::
41 ClearPoints( )
42 {
43   this->m_Contour.clear( );
44   this->Modified( );
45 }
46
47 // -------------------------------------------------------------------------
48 template< class _TImage >
49 ivq::ITK::RasterContourFilter< _TImage >::
50 RasterContourFilter( )
51   : Superclass( ),
52     m_InsideValue( TPixel( 1 ) ),
53     m_OutsideValue( TPixel( 0 ) )
54 {
55   this->ClearPoints( );
56 }
57
58 // -------------------------------------------------------------------------
59 template< class _TImage >
60 ivq::ITK::RasterContourFilter< _TImage >::
61 ~RasterContourFilter( )
62 {
63 }
64
65 // -------------------------------------------------------------------------
66 template< class _TImage >
67 void ivq::ITK::RasterContourFilter< _TImage >::
68 AllocateOutputs( )
69 {
70   _TImage* out = this->GetOutput( 0 );
71   out->SetSpacing( this->m_Template->GetSpacing( ) );
72   out->SetRegions( this->m_Template->GetRequestedRegion( ) );
73   out->SetOrigin( this->m_Template->GetOrigin( ) );
74   out->SetDirection( this->m_Template->GetDirection( ) );
75   out->Allocate( );
76 }
77
78 // -------------------------------------------------------------------------
79 template< class _TImage >
80 void ivq::ITK::RasterContourFilter< _TImage >::
81 BeforeThreadedGenerateData( )
82 {
83   // Keep just indices, not points
84   this->m_Polygon.clear( );
85   _TImage* out = this->GetOutput( 0 );
86   TIndex minIdx, maxIdx;
87   std::deque< TPoint >::const_iterator c = this->m_Contour.begin( );
88   for( ; c != this->m_Contour.end( ); ++c )
89   {
90     TIndex idx;
91     out->TransformPhysicalPointToIndex( *c, idx );
92     bool added = true;
93     if( this->m_Polygon.size( ) > 0 )
94     {
95       if( this->m_Polygon.back( ) != idx )
96       {
97         this->m_Polygon.push_back( idx );
98         minIdx[ 0 ] = ( idx[ 0 ] < minIdx[ 0 ] )? idx[ 0 ]: minIdx[ 0 ];
99         minIdx[ 1 ] = ( idx[ 1 ] < minIdx[ 1 ] )? idx[ 1 ]: minIdx[ 1 ];
100         maxIdx[ 0 ] = ( idx[ 0 ] > maxIdx[ 0 ] )? idx[ 0 ]: maxIdx[ 0 ];
101         maxIdx[ 1 ] = ( idx[ 1 ] > maxIdx[ 1 ] )? idx[ 1 ]: maxIdx[ 1 ];
102
103       } // fi
104     }
105     else
106     {
107       this->m_Polygon.push_back( idx );
108       minIdx = maxIdx = idx;
109
110     } // fi
111
112   } // rof
113
114   // Set ROI
115   typename _TImage::SizeType size;
116   size[ 0 ] = maxIdx[ 0 ] - minIdx[ 0 ] + 1;
117   size[ 1 ] = maxIdx[ 1 ] - minIdx[ 1 ] + 1;
118   this->m_ROI.SetIndex( minIdx );
119   this->m_ROI.SetSize( size );
120 }
121
122 // -------------------------------------------------------------------------
123 template< class _TImage >
124 void ivq::ITK::RasterContourFilter< _TImage >::
125 AfterThreadedGenerateData( )
126 {
127 }
128
129 // -------------------------------------------------------------------------
130 template< class _TImage >
131 void ivq::ITK::RasterContourFilter< _TImage >::
132 ThreadedGenerateData( const TRegion& region, itk::ThreadIdType id )
133 {
134   long nVerts = this->m_Polygon.size( );
135   _TImage* out = this->GetOutput( );
136   itk::ImageRegionIteratorWithIndex< _TImage > iIt( out, region );
137   for( iIt.GoToBegin( ); !iIt.IsAtEnd( ); ++iIt )
138   {
139     TIndex p = iIt.GetIndex( );
140     bool inside = false;
141     if( this->m_ROI.IsInside( p ) )
142     {
143       long i, j;
144       for( i = 0, j = nVerts - 1; i < nVerts; j = i++ )
145       {
146         TIndex pi = this->m_Polygon[ i ];
147         TIndex pj = this->m_Polygon[ j ];
148         double pi0 = double( pi[ 0 ] );
149         double pi1 = double( pi[ 1 ] );
150         double pj0 = double( pj[ 0 ] );
151         double pj1 = double( pj[ 1 ] );
152         double p0 = double( p[ 0 ] );
153         double p1 = double( p[ 1 ] );
154         double ji0 = pj0 - pi0;
155         double ji1 = pj1 - pi1;
156         double i1 = p1 - pi1;
157         if(
158           ( ( pi1 > p1 ) != ( pj1 > p1 ) ) &&
159           ( p0 < ( ( ji0 * i1 ) / ji1 ) + pi0 )
160           )
161           inside = !inside;
162
163       } // rof
164
165     } // fi
166     iIt.Set( ( inside )? this->m_InsideValue: this->m_OutsideValue );
167
168   } // rof
169 }
170
171 #endif // __ivq__ITK__RasterContourFilter__hxx__
172
173 // eof - $RCSfile$