]> Creatis software - cpPlugins.git/blob - plugins/ImageMeshFilters/RasterMeshFilter.cxx
Spline widget finished.
[cpPlugins.git] / plugins / ImageMeshFilters / RasterMeshFilter.cxx
1 #include <plugins/ImageMeshFilters/RasterMeshFilter.h>
2 #include <cpPlugins/DataObjects/BoundingBox.h>
3 #include <cpPlugins/DataObjects/Mesh.h>
4
5 #include <vtkImageData.h>
6 #include <vtkImageStencil.h>
7 #include <vtkLinearExtrusionFilter.h>
8 #include <vtkPolyDataToImageStencil.h>
9 #include <vtkStripper.h>
10
11 #include <itkTriangleMeshToBinaryImageFilter.h>
12 #include <itkTriangleMeshToBinaryImageFilter.hxx>
13
14 // -------------------------------------------------------------------------
15 cpPluginsImageMeshFilters::RasterMeshFilter::
16 RasterMeshFilter( )
17   : Superclass( )
18 {
19   typedef cpPlugins::BaseObjects::DataObject _TDataObject;
20   typedef cpPlugins::DataObjects::Image      _TImage;
21   typedef cpPlugins::DataObjects::Mesh       _TMesh;
22
23   this->_ConfigureInput< _TMesh >( "Input", true, false );
24   this->_ConfigureInput< _TDataObject >( "Template", false, false );
25   this->_ConfigureOutput< _TImage >( "Output" );
26
27   this->m_Parameters.ConfigureAsUint( "InsideValue" );
28   this->m_Parameters.ConfigureAsUint( "OutsideValue" );
29   this->m_Parameters.ConfigureAsUint( "MinimumSize" );
30
31   this->m_Parameters.SetUint( "InsideValue", 1 );
32   this->m_Parameters.SetUint( "OutsideValue", 0 );
33   this->m_Parameters.SetUint( "MinimumSize", 100 );
34 }
35
36 // -------------------------------------------------------------------------
37 cpPluginsImageMeshFilters::RasterMeshFilter::
38 ~RasterMeshFilter( )
39 {
40 }
41
42 // -------------------------------------------------------------------------
43 void cpPluginsImageMeshFilters::RasterMeshFilter::
44 _GenerateData( )
45 {
46   typedef itk::Mesh< float, 3 >  _3F;
47   typedef itk::Mesh< double, 3 > _3D;
48
49   bool is_2d = false;
50   auto pd = this->GetInputData< vtkPolyData >( "Input" );
51   if( pd != NULL )
52   {
53     double bounds[ 6 ];
54     pd->GetBounds( bounds );
55     is_2d = ( bounds[ 4 ] == bounds[ 5 ] );
56
57   } // fi
58   if( !is_2d )
59   {
60     auto _3f = this->GetInputData< _3F >( "Input" );
61     auto _3d = this->GetInputData< _3D >( "Input" );
62     if     ( _3f != NULL ) this->_GD0_3D( _3f );
63     else if( _3d != NULL ) this->_GD0_3D( _3d );
64     else this->_Error( "No valid input mesh." );
65   }
66   else
67     this->_GD0_2D( pd );
68 }
69
70 // -------------------------------------------------------------------------
71 template< class _TMesh >
72 void cpPluginsImageMeshFilters::RasterMeshFilter::
73 _GD0_2D( _TMesh* mesh )
74 {
75   typedef itk::ImageBase< 2 > _TImageBase;
76   typedef itk::Image< unsigned char, 2 > _TImage;
77   typedef cpPlugins::DataObjects::BoundingBox _TBB;
78   typedef typename _TImage::PointType _TPoint;
79
80   static const unsigned int PAD = 10;
81
82   _TImage::Pointer white = this->GetOutputData< _TImage >( "Output" );
83   if( white.IsNull( ) )
84     white = _TImage::New( );
85
86   // Get configuration values
87   typename _TImage::SpacingType spac;
88   typename _TImage::SizeType size;
89   typename _TImage::PointType origin;
90   typename _TImage::DirectionType direction;
91   typename _TImage::IndexType index;
92
93   auto in_bb = this->GetInput< _TBB >( "Template" );
94   auto in_im = this->GetInputData< _TImageBase >( "Template" );
95   if( in_im != NULL )
96   {
97     spac = in_im->GetSpacing( );
98     size = in_im->GetLargestPossibleRegion( ).GetSize( );
99     origin = in_im->GetOrigin( );
100     direction = in_im->GetDirection( );
101     index = in_im->GetLargestPossibleRegion( ).GetIndex( );
102   }
103   else
104   {
105     _TPoint minBB, maxBB;
106     if( in_bb != NULL )
107     {
108       minBB = in_bb->GetMinimum< _TPoint >( );
109       maxBB = in_bb->GetMaximum< _TPoint >( );
110     }
111     else
112     {
113       double bounds[ 6 ];
114       mesh->GetBounds( bounds );
115       minBB[ 0 ] = bounds[ 0 ];
116       minBB[ 1 ] = bounds[ 1 ];
117       maxBB[ 0 ] = bounds[ 2 ];
118       maxBB[ 1 ] = bounds[ 3 ];
119
120     } // fi
121
122     double lx = double( maxBB[ 0 ] - minBB[ 0 ] );
123     double ly = double( maxBB[ 1 ] - minBB[ 1 ] );
124     double lm = ( lx < ly )? lx: ly;
125
126     // Compute spacing
127     spac.Fill( lm / double( this->m_Parameters.GetUint( "MinimumSize" ) ) );
128
129     // Compute size
130     size[ 0 ] = ( unsigned long )( std::ceil( lx / spac[ 0 ] ) );
131     size[ 1 ] = ( unsigned long )( std::ceil( ly / spac[ 1 ] ) );
132
133     // ... add some padding pixels
134     size[ 0 ] += PAD;
135     size[ 1 ] += PAD;
136
137     // Set origin
138     origin = minBB;
139     origin[ 0 ] -= double( PAD >> 1 ) * spac[ 0 ];
140     origin[ 1 ] -= double( PAD >> 1 ) * spac[ 1 ];
141
142     // Remaining values
143     direction.SetIdentity( );
144     index.Fill( 0 );
145
146   } // fi
147
148   // Configure output image
149   _TImage::RegionType region;
150   region.SetSize( size );
151   region.SetIndex( index );
152   white->SetSpacing( spac );
153   white->SetRegions( region );
154   white->SetOrigin( origin );
155   white->SetDirection( direction );
156   white->Allocate( );
157   white->FillBuffer( this->m_Parameters.GetUint( "InsideValue" ) );
158   if( this->m_WhiteImage.IsNull( ) )
159     this->m_WhiteImage = TImage::New( );
160   this->m_WhiteImage->SetITK( white );
161   vtkImageData* white_vtk = this->m_WhiteImage->GetVTK< vtkImageData >( );
162
163   // Configure mini-pipeline
164   if( this->m_Stripper.GetPointer( ) == NULL )
165     this->m_Stripper = vtkSmartPointer< vtkStripper >::New( );
166   this->m_Stripper->SetInputData( mesh );
167   this->m_Stripper->Update( );
168
169   if( this->m_Extruder.GetPointer( ) == NULL )
170     this->m_Extruder = vtkSmartPointer< vtkLinearExtrusionFilter >::New( );
171   this->m_Extruder->SetInputConnection( this->m_Stripper->GetOutputPort( ) );
172   this->m_Extruder->SetScaleFactor( double( 1 ) );
173   this->m_Extruder->SetExtrusionTypeToNormalExtrusion( );
174   this->m_Extruder->SetVector( 0, 0, 1 );
175   this->m_Extruder->Update( );
176
177   if( this->m_PolyDataToStencil.GetPointer( ) == NULL )
178     this->m_PolyDataToStencil =
179       vtkSmartPointer< vtkPolyDataToImageStencil >::New( );
180   this->m_PolyDataToStencil->SetTolerance( 0 );
181   this->m_PolyDataToStencil->SetInputConnection( this->m_Extruder->GetOutputPort( ) );
182   this->m_PolyDataToStencil->SetOutputOrigin( white_vtk->GetOrigin( ) );
183   this->m_PolyDataToStencil->SetOutputSpacing( white_vtk->GetSpacing( ) );
184   this->m_PolyDataToStencil->SetOutputWholeExtent( white_vtk->GetExtent( ) );
185   this->m_PolyDataToStencil->Update( );
186
187   this->m_ImageStencil = this->_CreateVTK< vtkImageStencil >( );
188   this->m_ImageStencil->SetInputData( white_vtk );
189   this->m_ImageStencil->SetStencilConnection( this->m_PolyDataToStencil->GetOutputPort( ) );
190   this->m_ImageStencil->ReverseStencilOff( );
191   this->m_ImageStencil->SetBackgroundValue( this->m_Parameters.GetUint( "OutsideValue" ) );
192   this->m_ImageStencil->Update( );
193   this->GetOutput( "Output" )->SetVTK( this->m_ImageStencil->GetOutput( ) );
194 }
195
196 // -------------------------------------------------------------------------
197 template< class _TMesh >
198 void cpPluginsImageMeshFilters::RasterMeshFilter::
199 _GD0_3D( _TMesh* mesh )
200 {
201   typedef unsigned char _TPixel;
202   typedef cpPlugins::DataObjects::BoundingBox _TBB;
203   typedef itk::ImageBase< _TMesh::PointDimension > _TImageBase;
204   typedef itk::Image< _TPixel, _TMesh::PointDimension > _TImage;
205   typedef itk::TriangleMeshToBinaryImageFilter< _TMesh, _TImage > _TFilter;
206   typedef typename _TImage::PointType _TPoint;
207
208   static const unsigned int PAD = 10;
209
210   _TFilter* filter = this->_CreateITK< _TFilter >( );
211   this->m_WhiteImage = NULL;
212   this->m_Stripper = NULL;
213   this->m_Extruder = NULL;
214   this->m_PolyDataToStencil = NULL;
215   this->m_ImageStencil = NULL;
216
217   // Get configuration values
218   typename _TImage::SpacingType spac;
219   typename _TImage::SizeType size;
220   typename _TImage::PointType origin;
221   typename _TImage::DirectionType direction;
222   typename _TImage::IndexType index;
223
224   auto in_bb = this->GetInput< _TBB >( "Template" );
225   auto in_im = this->GetInputData< _TImageBase >( "Template" );
226   if( in_im != NULL )
227   {
228     spac = in_im->GetSpacing( );
229     size = in_im->GetLargestPossibleRegion( ).GetSize( );
230     origin = in_im->GetOrigin( );
231     direction = in_im->GetDirection( );
232     index = in_im->GetLargestPossibleRegion( ).GetIndex( );
233   }
234   else
235   {
236     _TPoint minBB, maxBB;
237     if( in_bb != NULL )
238     {
239       minBB = in_bb->GetMinimum< _TPoint >( );
240       maxBB = in_bb->GetMaximum< _TPoint >( );
241     }
242     else
243     {
244       auto bb = mesh->GetBoundingBox( );
245       minBB = bb->GetMinimum( );
246       maxBB = bb->GetMaximum( );
247
248     } // fi
249
250     double lx = double( maxBB[ 0 ] - minBB[ 0 ] );
251     double ly = double( maxBB[ 1 ] - minBB[ 1 ] );
252     double lz = double( maxBB[ 2 ] - minBB[ 2 ] );
253     double lm = ( lx < ly )? lx: ly;
254     lm = ( lm < lz )? lm: lz;
255
256     // Compute spacing
257     spac.Fill( lm / double( this->m_Parameters.GetUint( "MinimumSize" ) ) );
258
259     // Compute size
260     size[ 0 ] = ( unsigned long )( std::ceil( lx / spac[ 0 ] ) );
261     size[ 1 ] = ( unsigned long )( std::ceil( ly / spac[ 1 ] ) );
262     size[ 2 ] = ( unsigned long )( std::ceil( lz / spac[ 2 ] ) );
263
264     // ... add some padding pixels
265     size[ 0 ] += PAD;
266     size[ 1 ] += PAD;
267     size[ 2 ] += PAD;
268
269     // Set origin
270     origin = minBB;
271     origin[ 0 ] -= double( PAD >> 1 ) * spac[ 0 ];
272     origin[ 1 ] -= double( PAD >> 1 ) * spac[ 1 ];
273     origin[ 2 ] -= double( PAD >> 1 ) * spac[ 2 ];
274
275     // Remaining values
276     direction.SetIdentity( );
277     index.Fill( 0 );
278
279   } // fi
280
281   // Execute
282   filter->SetInput( mesh );
283   filter->SetSpacing( spac );
284   filter->SetSize( size );
285   filter->SetOrigin( origin );
286   filter->SetDirection( direction );
287   filter->SetIndex( index );
288   filter->SetInsideValue( this->m_Parameters.GetUint( "InsideValue" ) );
289   filter->SetOutsideValue( this->m_Parameters.GetUint( "OutsideValue" ) );
290   filter->Update( );
291   this->GetOutput( "Output" )->SetITK( filter->GetOutput( ) );
292 }
293
294 // eof - $RCSfile$