]> Creatis software - cpPlugins.git/blob - lib/cpExtensions/Visualization/ImageSliceActors.cxx
MPR almost working with multiple images
[cpPlugins.git] / lib / cpExtensions / Visualization / ImageSliceActors.cxx
1 #include <cpExtensions/Visualization/ImageSliceActors.h>
2
3 #include <vtkAlgorithmOutput.h>
4 #include <vtkCellArray.h>
5 #include <vtkImageData.h>
6 #include <vtkInformation.h>
7 #include <vtkPlane.h>
8 #include <vtkPoints.h>
9 #include <vtkProperty.h>
10 #include <vtkStreamingDemandDrivenPipeline.h>
11 #include <vtkTextProperty.h>
12
13 // -------------------------------------------------------------------------
14 cpExtensions::Visualization::ImageSliceActors*
15 cpExtensions::Visualization::ImageSliceActors::
16 New( )
17 {
18   return( new Self( ) );
19 }
20
21 // -------------------------------------------------------------------------
22 void cpExtensions::Visualization::ImageSliceActors::
23 AddInputConnection( vtkAlgorithmOutput* aout, int axis )
24 {
25   unsigned int nImages = this->SliceMappers.size( );
26
27   vtkSmartPointer< vtkImageSliceMapper > mapper =
28     vtkSmartPointer< vtkImageSliceMapper >::New( );
29   this->SliceMappers.push_back( mapper );
30   mapper->SetInputConnection( aout );
31   mapper->SetOrientation(
32     ( nImages == 0 )? axis: this->SliceMappers[ 0 ]->GetOrientation( )
33     );
34   mapper->Update( );
35   
36   vtkSmartPointer< vtkImageActor > actor =
37     vtkSmartPointer< vtkImageActor >::New( );
38   this->ImageActors.push_back( actor );
39   actor->SetMapper( mapper );
40   actor->Modified( );
41
42   if( nImages == 0 )
43   {
44     this->AddItem( this->TextActor );
45     this->AddItem( this->PlaneActor );
46
47   } // fi
48   this->AddItem( actor );
49   this->Modified( );
50 }
51
52 // -------------------------------------------------------------------------
53 void cpExtensions::Visualization::ImageSliceActors::
54 AddInputData( vtkImageData* data, int axis )
55 {
56   unsigned int nImages = this->SliceMappers.size( );
57
58   vtkSmartPointer< vtkImageSliceMapper > mapper =
59     vtkSmartPointer< vtkImageSliceMapper >::New( );
60   this->SliceMappers.push_back( mapper );
61   mapper->SetInputData( data );
62   mapper->SetOrientation(
63     ( nImages == 0 )? axis: this->SliceMappers[ 0 ]->GetOrientation( )
64     );
65   mapper->Update( );
66
67   vtkSmartPointer< vtkImageActor > actor =
68     vtkSmartPointer< vtkImageActor >::New( );
69   this->ImageActors.push_back( actor );
70   actor->SetMapper( mapper );
71   actor->Modified( );
72
73   if( nImages == 0 )
74   {
75     this->AddItem( this->TextActor );
76     this->AddItem( this->PlaneActor );
77
78   } // fi
79   this->AddItem( actor );
80   this->Modified( );
81 }
82
83 // -------------------------------------------------------------------------
84 void cpExtensions::Visualization::ImageSliceActors::
85 Clear( )
86 {
87   // Unbind from container
88   this->RemoveAllItems( );
89
90   // Delete all images
91   this->SliceMappers.clear( );
92   this->ImageActors.clear( );
93
94   // Reconfigure unique objects
95   this->PlaneSource = vtkSmartPointer< vtkPolyData >::New( );
96   this->PlaneMapper = vtkSmartPointer< vtkPolyDataMapper >::New( );
97   this->TextActor   = vtkSmartPointer< vtkTextActor >::New( );
98   this->PlaneActor  = vtkSmartPointer< vtkActor >::New( );
99   this->TextBuffer[ 0 ] = '\0';
100
101   // Unique objects configuration
102   vtkSmartPointer< vtkPoints > plane_points =
103     vtkSmartPointer< vtkPoints >::New( );
104   vtkSmartPointer< vtkCellArray > plane_lines =
105     vtkSmartPointer< vtkCellArray >::New( );
106
107   plane_points->InsertNextPoint( 0, 0, 0 );
108   plane_points->InsertNextPoint( 0, 1, 0 );
109   plane_points->InsertNextPoint( 1, 1, 0 );
110   plane_points->InsertNextPoint( 1, 0, 0 );
111   plane_lines->InsertNextCell( 5 );
112   plane_lines->InsertCellPoint( 0 );
113   plane_lines->InsertCellPoint( 1 );
114   plane_lines->InsertCellPoint( 2 );
115   plane_lines->InsertCellPoint( 3 );
116   plane_lines->InsertCellPoint( 0 );
117   this->PlaneSource->SetPoints( plane_points );
118   this->PlaneSource->SetLines( plane_lines );
119
120   this->PlaneMapper->SetInputData( this->PlaneSource );
121   this->PlaneActor->SetMapper( this->PlaneMapper );
122
123   this->TextActor->SetTextScaleModeToNone( );
124   vtkTextProperty* textprop = this->TextActor->GetTextProperty( );
125   textprop->SetColor( 1, 1, 1 );
126   textprop->SetFontFamilyToCourier( );
127   textprop->SetFontSize( 18 );
128   textprop->BoldOff( );
129   textprop->ItalicOff( );
130   textprop->ShadowOff( );
131   textprop->SetJustificationToLeft( );
132   textprop->SetVerticalJustificationToBottom( );
133   vtkCoordinate* coord = this->TextActor->GetPositionCoordinate( );
134   coord->SetCoordinateSystemToNormalizedViewport( );
135   coord->SetValue( 0.01, 0.01 );
136 }
137
138 // -------------------------------------------------------------------------
139 unsigned int cpExtensions::Visualization::ImageSliceActors::
140 GetNumberOfImageActors( ) const
141 {
142   return( this->ImageActors.size( ) );
143 }
144
145 // -------------------------------------------------------------------------
146 vtkImageActor* cpExtensions::Visualization::ImageSliceActors::
147 GetImageActor( unsigned int id )
148 {
149   if( id < this->ImageActors.size( ) )
150     return( this->ImageActors[ id ] );
151   else
152     return( NULL );
153 }
154
155 // -------------------------------------------------------------------------
156 const vtkImageActor* cpExtensions::Visualization::ImageSliceActors::
157 GetImageActor( unsigned int id ) const
158 {
159   if( id < this->ImageActors.size( ) )
160     return( this->ImageActors[ id ] );
161   else
162     return( NULL );
163 }
164
165 // -------------------------------------------------------------------------
166 vtkTextActor* cpExtensions::Visualization::ImageSliceActors::
167 GetTextActor( )
168 {
169   return( this->TextActor );
170 }
171
172 // -------------------------------------------------------------------------
173 const vtkTextActor* cpExtensions::Visualization::ImageSliceActors::
174 GetTextActor( ) const
175 {
176   return( this->TextActor );
177 }
178
179 // -------------------------------------------------------------------------
180 vtkActor* cpExtensions::Visualization::ImageSliceActors::
181 GetPlaneActor( )
182 {
183   return( this->PlaneActor );
184 }
185
186 // -------------------------------------------------------------------------
187 const vtkActor* cpExtensions::Visualization::ImageSliceActors::
188 GetPlaneActor( ) const
189 {
190   return( this->PlaneActor );
191 }
192
193 // -------------------------------------------------------------------------
194 double* cpExtensions::Visualization::ImageSliceActors::
195 GetDisplayBounds( ) const
196 {
197   if( this->ImageActors.size( ) > 0 )
198     return( this->ImageActors[ 0 ]->GetDisplayBounds( ) );
199   else
200     return( NULL );
201 }
202
203 // -------------------------------------------------------------------------
204 void cpExtensions::Visualization::ImageSliceActors::
205 GetDisplayBounds( double bounds[ 6 ] ) const
206 {
207   if( this->ImageActors.size( ) > 0 )
208     this->ImageActors[ 0 ]->GetDisplayBounds( bounds );
209 }
210
211 // -------------------------------------------------------------------------
212 int cpExtensions::Visualization::ImageSliceActors::
213 GetAxis( ) const
214 {
215   if( this->SliceMappers.size( ) > 0 )
216     return( this->SliceMappers[ 0 ]->GetOrientation( ) );
217   else
218     return( -1 );
219 }
220
221 // -------------------------------------------------------------------------
222 int cpExtensions::Visualization::ImageSliceActors::
223 GetSliceNumber( ) const
224 {
225   if( this->SliceMappers.size( ) > 0 )
226     return( this->SliceMappers[ 0 ]->GetSliceNumber( ) );
227   else
228     return( -1 );
229 }
230
231 // -------------------------------------------------------------------------
232 int cpExtensions::Visualization::ImageSliceActors::
233 GetSliceNumberMinValue( ) const
234 {
235   if( this->SliceMappers.size( ) > 0 )
236     return( this->SliceMappers[ 0 ]->GetSliceNumberMinValue( ) );
237   else
238     return( -1 );
239 }
240
241 // -------------------------------------------------------------------------
242 int cpExtensions::Visualization::ImageSliceActors::
243 GetSliceNumberMaxValue( ) const
244 {
245   if( this->SliceMappers.size( ) > 0 )
246     return( this->SliceMappers[ 0 ]->GetSliceNumberMaxValue( ) );
247   else
248     return( -1 );
249 }
250
251 // -------------------------------------------------------------------------
252 void cpExtensions::Visualization::ImageSliceActors::
253 SetSliceNumber( const int& slice )
254 {
255   unsigned int nImages = this->SliceMappers.size( );
256   if( nImages == 0 )
257     return;
258
259   // Change visualization extent
260   for( unsigned int i = 0; i < nImages; ++i )
261   {
262     this->SliceMappers[ i ]->SetSliceNumber( slice );
263     this->SliceMappers[ i ]->Modified( );
264     this->ImageActors[ i ]->Modified( );
265     this->SliceMappers[ i ]->Update( );
266
267   } // rof
268
269   // Compute plane
270   vtkAlgorithm* algo = this->SliceMappers[ 0 ]->GetInputAlgorithm( );
271   vtkInformation* info = algo->GetOutputInformation( 0 );
272   int ext[ 6 ];
273   double ori[ 3 ], spac[ 3 ], pos[ 3 ];
274   info->Get( vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT( ), ext );
275   info->Get( vtkDataObject::ORIGIN( ), ori );
276   info->Get( vtkDataObject::SPACING( ), spac );
277   this->SliceMappers[ 0 ]->GetSlicePlane( )->GetOrigin( pos );
278
279   // Prevent obscuring voxels by offsetting the plane geometry
280   double xbnds[ ] =
281     {
282       ori[ 0 ] + ( spac[ 0 ] * double( ext[ 0 ] ) ),
283       ori[ 0 ] + ( spac[ 0 ] * double( ext[ 1 ] ) )
284     };
285   double ybnds[ ] =
286     {
287       ori[ 1 ] + ( spac[ 1 ] * double( ext[ 2 ] ) ),
288       ori[ 1 ] + ( spac[ 1 ] * double( ext[ 3 ] ) )
289     };
290   double zbnds[ ] =
291     {
292       ori[ 2 ] + ( spac[ 2 ] * double( ext[ 4 ] ) ),
293       ori[ 2 ] + ( spac[ 2 ] * double( ext[ 5 ] ) )
294     };
295
296   if( spac[ 0 ] < double( 0 ) )
297   {
298     double t = xbnds[ 0 ];
299     xbnds[ 0 ] = xbnds[ 1 ];
300     xbnds[ 1 ] = t;
301
302   } // fi
303   if( spac[ 1 ] < double( 0 ) )
304   {
305     double t = ybnds[ 0 ];
306     ybnds[ 0 ] = ybnds[ 1 ];
307     ybnds[ 1 ] = t;
308
309   } // fi
310   if( spac[ 2 ] < double( 0 ) )
311   {
312     double t = zbnds[ 0 ];
313     zbnds[ 0 ] = zbnds[ 1 ];
314     zbnds[ 1 ] = t;
315
316   } // fi
317
318   int axis = this->SliceMappers[ 0 ]->GetOrientation( );
319   this->PlaneActor->GetProperty( )->SetRepresentationToWireframe( );
320   this->PlaneActor->GetProperty( )->SetLineWidth( 2 );
321   vtkPoints* plane_points = this->PlaneSource->GetPoints( );
322   if( axis == 0 ) // YZ, x-normal
323   {
324     plane_points->SetPoint( 0, pos[ 0 ], ybnds[ 0 ], zbnds[ 0 ] );
325     plane_points->SetPoint( 1, pos[ 0 ], ybnds[ 1 ], zbnds[ 0 ] );
326     plane_points->SetPoint( 2, pos[ 0 ], ybnds[ 1 ], zbnds[ 1 ] );
327     plane_points->SetPoint( 3, pos[ 0 ], ybnds[ 0 ], zbnds[ 1 ] );
328     this->PlaneActor->GetProperty( )->SetColor( 1, 0, 0 );
329   }
330   else if( axis == 1 ) // ZX, y-normal
331   {
332     plane_points->SetPoint( 0, xbnds[ 0 ], pos[ 1 ], zbnds[ 0 ] );
333     plane_points->SetPoint( 1, xbnds[ 0 ], pos[ 1 ], zbnds[ 1 ] );
334     plane_points->SetPoint( 2, xbnds[ 1 ], pos[ 1 ], zbnds[ 1 ] );
335     plane_points->SetPoint( 3, xbnds[ 1 ], pos[ 1 ], zbnds[ 0 ] );
336     this->PlaneActor->GetProperty( )->SetColor( 0, 1, 0 );
337   }
338   else // XY, z-normal
339   {
340     plane_points->SetPoint( 0, xbnds[ 0 ], ybnds[ 0 ], pos[ 2 ] );
341     plane_points->SetPoint( 1, xbnds[ 1 ], ybnds[ 0 ], pos[ 2 ] );
342     plane_points->SetPoint( 2, xbnds[ 1 ], ybnds[ 1 ], pos[ 2 ] );
343     plane_points->SetPoint( 3, xbnds[ 0 ], ybnds[ 1 ], pos[ 2 ] );
344     this->PlaneActor->GetProperty( )->SetColor( 0, 0, 1 );
345
346   } // fi
347   this->PlaneSource->Modified( );
348   this->PlaneMapper->Modified( );
349   this->PlaneActor->Modified( );
350   this->Modified( );
351 }
352
353 // -------------------------------------------------------------------------
354 void cpExtensions::Visualization::ImageSliceActors::
355 UpdateText( )
356 {
357   if( this->SliceMappers.size( ) > 0 )
358   {
359     char axis;
360     int axId = this->SliceMappers[ 0 ]->GetOrientation( );
361     if     ( axId == 0 ) axis = 'X';
362     else if( axId == 1 ) axis = 'Y';
363     else if( axId == 2 ) axis = 'Z';
364
365     std::sprintf(
366       this->TextBuffer, "Axis: %c (%d)",
367       axis, this->SliceMappers[ 0 ]->GetSliceNumber( )
368       );
369   }
370   else
371     this->TextBuffer[ 0 ] = '\0';
372   this->TextActor->SetInput( this->TextBuffer );
373   this->TextActor->Modified( );
374   this->Modified( );
375 }
376
377 // -------------------------------------------------------------------------
378 cpExtensions::Visualization::ImageSliceActors::
379 ImageSliceActors( )
380   : Superclass( )
381 {
382   this->Clear( );
383 }
384
385 // -------------------------------------------------------------------------
386 cpExtensions::Visualization::ImageSliceActors::
387 ~ImageSliceActors( )
388 {
389 }
390
391 // eof - $RCSfile$