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