1 #include <cpExtensions/Visualization/ImageSliceActors.h>
3 #include <vtkAlgorithmOutput.h>
4 #include <vtkCellArray.h>
5 #include <vtkImageData.h>
6 #include <vtkInformation.h>
9 #include <vtkProperty.h>
10 #include <vtkStreamingDemandDrivenPipeline.h>
11 #include <vtkTextProperty.h>
13 // -------------------------------------------------------------------------
14 cpExtensions::Visualization::ImageSliceActors*
15 cpExtensions::Visualization::ImageSliceActors::
18 return( new Self( ) );
21 // -------------------------------------------------------------------------
22 void cpExtensions::Visualization::ImageSliceActors::
23 AddInputConnection( vtkAlgorithmOutput* aout, int axis )
25 vtkSmartPointer< vtkImageSliceMapper > mapper =
26 vtkSmartPointer< vtkImageSliceMapper >::New( );
27 this->SliceMappers.push_back( mapper );
28 mapper->SetInputConnection( aout );
29 this->_ConfigureNewInput( axis );
32 // -------------------------------------------------------------------------
33 void cpExtensions::Visualization::ImageSliceActors::
34 AddInputData( vtkImageData* data, int axis )
36 vtkSmartPointer< vtkImageSliceMapper > mapper =
37 vtkSmartPointer< vtkImageSliceMapper >::New( );
38 this->SliceMappers.push_back( mapper );
39 mapper->SetInputData( data );
40 this->_ConfigureNewInput( axis );
43 // -------------------------------------------------------------------------
44 void cpExtensions::Visualization::ImageSliceActors::
47 // Unbind from container
48 this->RemoveAllItems( );
51 this->SliceMappers.clear( );
52 this->ImageActors.clear( );
54 // Reconfigure unique objects
55 this->PlaneSource = vtkSmartPointer< vtkPolyData >::New( );
56 this->PlaneMapper = vtkSmartPointer< vtkPolyDataMapper >::New( );
57 this->TextActor = vtkSmartPointer< vtkTextActor >::New( );
58 this->PlaneActor = vtkSmartPointer< vtkActor >::New( );
59 this->TextBuffer[ 0 ] = '\0';
61 // Unique objects configuration
62 vtkSmartPointer< vtkPoints > plane_points =
63 vtkSmartPointer< vtkPoints >::New( );
64 vtkSmartPointer< vtkCellArray > plane_lines =
65 vtkSmartPointer< vtkCellArray >::New( );
67 plane_points->InsertNextPoint( 0, 0, 0 );
68 plane_points->InsertNextPoint( 0, 1, 0 );
69 plane_points->InsertNextPoint( 1, 1, 0 );
70 plane_points->InsertNextPoint( 1, 0, 0 );
71 plane_lines->InsertNextCell( 5 );
72 plane_lines->InsertCellPoint( 0 );
73 plane_lines->InsertCellPoint( 1 );
74 plane_lines->InsertCellPoint( 2 );
75 plane_lines->InsertCellPoint( 3 );
76 plane_lines->InsertCellPoint( 0 );
77 this->PlaneSource->SetPoints( plane_points );
78 this->PlaneSource->SetLines( plane_lines );
80 this->PlaneMapper->SetInputData( this->PlaneSource );
81 this->PlaneActor->SetMapper( this->PlaneMapper );
83 this->TextActor->SetTextScaleModeToNone( );
84 vtkTextProperty* textprop = this->TextActor->GetTextProperty( );
85 textprop->SetColor( 1, 1, 1 );
86 textprop->SetFontFamilyToCourier( );
87 textprop->SetFontSize( 18 );
89 textprop->ItalicOff( );
90 textprop->ShadowOff( );
91 textprop->SetJustificationToLeft( );
92 textprop->SetVerticalJustificationToBottom( );
93 vtkCoordinate* coord = this->TextActor->GetPositionCoordinate( );
94 coord->SetCoordinateSystemToNormalizedViewport( );
95 coord->SetValue( 0.01, 0.01 );
98 // -------------------------------------------------------------------------
99 unsigned int cpExtensions::Visualization::ImageSliceActors::
100 GetNumberOfImageActors( ) const
102 return( this->ImageActors.size( ) );
105 // -------------------------------------------------------------------------
106 vtkImageActor* cpExtensions::Visualization::ImageSliceActors::
107 GetImageActor( unsigned int id )
109 if( id < this->ImageActors.size( ) )
110 return( this->ImageActors[ id ] );
115 // -------------------------------------------------------------------------
116 const vtkImageActor* cpExtensions::Visualization::ImageSliceActors::
117 GetImageActor( unsigned int id ) const
119 if( id < this->ImageActors.size( ) )
120 return( this->ImageActors[ id ] );
125 // -------------------------------------------------------------------------
126 vtkTextActor* cpExtensions::Visualization::ImageSliceActors::
129 return( this->TextActor );
132 // -------------------------------------------------------------------------
133 const vtkTextActor* cpExtensions::Visualization::ImageSliceActors::
134 GetTextActor( ) const
136 return( this->TextActor );
139 // -------------------------------------------------------------------------
140 vtkActor* cpExtensions::Visualization::ImageSliceActors::
143 return( this->PlaneActor );
146 // -------------------------------------------------------------------------
147 const vtkActor* cpExtensions::Visualization::ImageSliceActors::
148 GetPlaneActor( ) const
150 return( this->PlaneActor );
153 // -------------------------------------------------------------------------
154 void cpExtensions::Visualization::ImageSliceActors::
155 SetInterpolate( bool v )
157 if( this->Interpolate != v )
159 for( unsigned int i = 0; i < this->ImageActors.size( ); ++i )
160 this->ImageActors[ i ]->SetInterpolate( v );
161 this->Interpolate = v;
167 // -------------------------------------------------------------------------
168 void cpExtensions::Visualization::ImageSliceActors::
171 this->SetInterpolate( true );
174 // -------------------------------------------------------------------------
175 void cpExtensions::Visualization::ImageSliceActors::
178 this->SetInterpolate( false );
181 // -------------------------------------------------------------------------
182 double* cpExtensions::Visualization::ImageSliceActors::
183 GetDisplayBounds( ) const
185 if( this->ImageActors.size( ) > 0 )
186 return( this->ImageActors[ 0 ]->GetDisplayBounds( ) );
191 // -------------------------------------------------------------------------
192 void cpExtensions::Visualization::ImageSliceActors::
193 GetDisplayBounds( double bounds[ 6 ] ) const
195 if( this->ImageActors.size( ) == 0 )
197 bounds[ 0 ] = bounds[ 2 ] = bounds[ 4 ] = double( -1 );
198 bounds[ 1 ] = bounds[ 3 ] = bounds[ 5 ] = double( -1 );
201 this->ImageActors[ 0 ]->GetDisplayBounds( bounds );
204 // -------------------------------------------------------------------------
205 int cpExtensions::Visualization::ImageSliceActors::
208 if( this->SliceMappers.size( ) > 0 )
209 return( this->SliceMappers[ 0 ]->GetOrientation( ) );
214 // -------------------------------------------------------------------------
215 int cpExtensions::Visualization::ImageSliceActors::
216 GetSliceNumber( ) const
218 if( this->SliceMappers.size( ) > 0 )
219 return( this->SliceMappers[ 0 ]->GetSliceNumber( ) );
224 // -------------------------------------------------------------------------
225 int cpExtensions::Visualization::ImageSliceActors::
226 GetSliceNumberMinValue( ) const
228 if( this->SliceMappers.size( ) > 0 )
229 return( this->SliceMappers[ 0 ]->GetSliceNumberMinValue( ) );
234 // -------------------------------------------------------------------------
235 int cpExtensions::Visualization::ImageSliceActors::
236 GetSliceNumberMaxValue( ) const
238 if( this->SliceMappers.size( ) > 0 )
239 return( this->SliceMappers[ 0 ]->GetSliceNumberMaxValue( ) );
244 // -------------------------------------------------------------------------
245 void cpExtensions::Visualization::ImageSliceActors::
246 SetSliceNumber( const int& slice )
248 unsigned int nImages = this->SliceMappers.size( );
252 // Change visualization extent
253 for( unsigned int i = 0; i < nImages; ++i )
255 this->SliceMappers[ i ]->SetSliceNumber( slice );
256 this->SliceMappers[ i ]->Modified( );
257 this->ImageActors[ i ]->Modified( );
258 this->SliceMappers[ i ]->Update( );
263 vtkAlgorithm* algo = this->SliceMappers[ 0 ]->GetInputAlgorithm( );
264 vtkInformation* info = algo->GetOutputInformation( 0 );
266 double ori[ 3 ], spac[ 3 ], pos[ 3 ];
267 info->Get( vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT( ), ext );
268 info->Get( vtkDataObject::ORIGIN( ), ori );
269 info->Get( vtkDataObject::SPACING( ), spac );
270 this->SliceMappers[ 0 ]->GetSlicePlane( )->GetOrigin( pos );
272 // Prevent obscuring voxels by offsetting the plane geometry
275 ori[ 0 ] + ( spac[ 0 ] * double( ext[ 0 ] ) ),
276 ori[ 0 ] + ( spac[ 0 ] * double( ext[ 1 ] ) )
280 ori[ 1 ] + ( spac[ 1 ] * double( ext[ 2 ] ) ),
281 ori[ 1 ] + ( spac[ 1 ] * double( ext[ 3 ] ) )
285 ori[ 2 ] + ( spac[ 2 ] * double( ext[ 4 ] ) ),
286 ori[ 2 ] + ( spac[ 2 ] * double( ext[ 5 ] ) )
289 if( spac[ 0 ] < double( 0 ) )
291 double t = xbnds[ 0 ];
292 xbnds[ 0 ] = xbnds[ 1 ];
296 if( spac[ 1 ] < double( 0 ) )
298 double t = ybnds[ 0 ];
299 ybnds[ 0 ] = ybnds[ 1 ];
303 if( spac[ 2 ] < double( 0 ) )
305 double t = zbnds[ 0 ];
306 zbnds[ 0 ] = zbnds[ 1 ];
311 int axis = this->SliceMappers[ 0 ]->GetOrientation( );
312 this->PlaneActor->GetProperty( )->SetRepresentationToWireframe( );
313 this->PlaneActor->GetProperty( )->SetLineWidth( 2 );
314 vtkPoints* plane_points = this->PlaneSource->GetPoints( );
315 if( axis == 0 ) // YZ, x-normal
317 plane_points->SetPoint( 0, pos[ 0 ], ybnds[ 0 ], zbnds[ 0 ] );
318 plane_points->SetPoint( 1, pos[ 0 ], ybnds[ 1 ], zbnds[ 0 ] );
319 plane_points->SetPoint( 2, pos[ 0 ], ybnds[ 1 ], zbnds[ 1 ] );
320 plane_points->SetPoint( 3, pos[ 0 ], ybnds[ 0 ], zbnds[ 1 ] );
321 this->PlaneActor->GetProperty( )->SetColor( 1, 0, 0 );
323 else if( axis == 1 ) // ZX, y-normal
325 plane_points->SetPoint( 0, xbnds[ 0 ], pos[ 1 ], zbnds[ 0 ] );
326 plane_points->SetPoint( 1, xbnds[ 0 ], pos[ 1 ], zbnds[ 1 ] );
327 plane_points->SetPoint( 2, xbnds[ 1 ], pos[ 1 ], zbnds[ 1 ] );
328 plane_points->SetPoint( 3, xbnds[ 1 ], pos[ 1 ], zbnds[ 0 ] );
329 this->PlaneActor->GetProperty( )->SetColor( 0, 1, 0 );
333 plane_points->SetPoint( 0, xbnds[ 0 ], ybnds[ 0 ], pos[ 2 ] );
334 plane_points->SetPoint( 1, xbnds[ 1 ], ybnds[ 0 ], pos[ 2 ] );
335 plane_points->SetPoint( 2, xbnds[ 1 ], ybnds[ 1 ], pos[ 2 ] );
336 plane_points->SetPoint( 3, xbnds[ 0 ], ybnds[ 1 ], pos[ 2 ] );
337 this->PlaneActor->GetProperty( )->SetColor( 0, 0, 1 );
340 this->PlaneSource->Modified( );
341 this->PlaneMapper->Modified( );
342 this->PlaneActor->Modified( );
346 // -------------------------------------------------------------------------
347 void cpExtensions::Visualization::ImageSliceActors::
350 if( this->SliceMappers.size( ) > 0 )
353 int axId = this->SliceMappers[ 0 ]->GetOrientation( );
354 if ( axId == 0 ) axis = 'X';
355 else if( axId == 1 ) axis = 'Y';
356 else if( axId == 2 ) axis = 'Z';
359 this->TextBuffer, "Axis: %c (%d)",
360 axis, this->SliceMappers[ 0 ]->GetSliceNumber( )
364 this->TextBuffer[ 0 ] = '\0';
365 this->TextActor->SetInput( this->TextBuffer );
366 this->TextActor->Modified( );
370 // -------------------------------------------------------------------------
371 void cpExtensions::Visualization::ImageSliceActors::
372 UpdateText( const double& w, const double& l )
374 if( this->SliceMappers.size( ) > 0 )
377 int axId = this->SliceMappers[ 0 ]->GetOrientation( );
378 if ( axId == 0 ) axis = 'X';
379 else if( axId == 1 ) axis = 'Y';
380 else if( axId == 2 ) axis = 'Z';
383 this->TextBuffer, "Axis: %c (%d) | W/L (%.2f/%.2f)",
384 axis, this->SliceMappers[ 0 ]->GetSliceNumber( ), w, l
388 this->TextBuffer[ 0 ] = '\0';
389 this->TextActor->SetInput( this->TextBuffer );
390 this->TextActor->Modified( );
394 // -------------------------------------------------------------------------
395 cpExtensions::Visualization::ImageSliceActors::
403 // -------------------------------------------------------------------------
404 cpExtensions::Visualization::ImageSliceActors::
409 // -------------------------------------------------------------------------
410 void cpExtensions::Visualization::ImageSliceActors::
411 _ConfigureNewInput( int axis )
413 unsigned int nImages = this->ImageActors.size( );
416 vtkImageSliceMapper* mapper = this->SliceMappers[ nImages ];
418 mapper->SetOrientation( axis );
420 mapper->SetOrientation( this->SliceMappers[ 0 ]->GetOrientation( ) );
424 vtkSmartPointer< vtkImageActor > actor =
425 vtkSmartPointer< vtkImageActor >::New( );
426 this->ImageActors.push_back( actor );
427 actor->SetMapper( mapper );
428 actor->SetInterpolate( this->Interpolate );
433 this->AddItem( this->TextActor );
434 this->AddItem( this->PlaneActor );
437 this->AddItem( actor );
440 this->SetSliceNumber( this->GetSliceNumber( ) );