1 #include <cpExtensions/Visualization/ImageSliceActors.h>
5 #include <vtkAlgorithmOutput.h>
7 #include <vtkCellArray.h>
8 #include <vtkImageData.h>
9 #include <vtkImageProperty.h>
10 #include <vtkPoints.h>
11 #include <vtkProperty.h>
12 #include <vtkRenderer.h>
13 #include <vtkRendererCollection.h>
14 #include <vtkRenderWindow.h>
15 #include <vtkRenderWindowInteractor.h>
16 #include <vtkTextProperty.h>
18 // -------------------------------------------------------------------------
19 cpExtensions::Visualization::ImageSliceActors*
20 cpExtensions::Visualization::ImageSliceActors::
23 return( new Self( ) );
26 // -------------------------------------------------------------------------
27 void cpExtensions::Visualization::ImageSliceActors::
30 this->m_ImageMapper->SetOrientation( axis );
31 this->m_ImageMapper->Update( );
32 this->SetSliceNumber( this->GetSliceNumberMinValue( ) );
33 this->m_ImageActor->Modified( );
38 // -------------------------------------------------------------------------
39 void cpExtensions::Visualization::ImageSliceActors::
40 AddInputConnection( vtkAlgorithmOutput* aout )
42 // Get input vtkImageData
46 // Create mapper and actors
47 this->m_ImageMapper = vtkSmartPointer< vtkImageSliceMapper >::New( );
48 this->m_ImageMapper->SetInputConnection( aout );
49 this->m_ImageMapper->SetOrientation( 0 );
50 this->m_ImageMapper->Update( );
53 this->m_ImageActor = vtkSmartPointer< vtkImageActor >::New( );
54 this->m_ImageActor->SetMapper( this->m_ImageMapper );
55 this->m_ImageActor->SetInterpolate( this->m_Interpolate );
56 this->m_ImageActor->Modified( );
58 if( this->m_Style.GetPointer( ) != NULL )
59 this->m_Style->AssociateImageActor( this->m_ImageActor );
60 this->AddItem( this->m_ImageActor );
62 this->SetSliceNumber( this->GetSliceNumberMinValue( ) );
66 // Update window/level ranges
67 vtkImageData* data = this->GetInputImage( );
71 data->GetScalarRange( r );
72 this->m_WLRange[ 0 ] = double( 0 );
73 this->m_WLRange[ 1 ] = r[ 1 ] - r[ 0 ];
74 this->m_WLRange[ 2 ] = r[ 0 ];
75 this->m_WLRange[ 3 ] = r[ 1 ];
76 this->ResetWindowLevel( );
81 // -------------------------------------------------------------------------
82 void cpExtensions::Visualization::ImageSliceActors::
83 AddInputData( vtkImageData* data )
85 // Get input vtkImageData
89 // Create mapper and actors
90 this->m_ImageMapper = vtkSmartPointer< vtkImageSliceMapper >::New( );
91 this->m_ImageMapper->SetInputData( data );
92 this->m_ImageMapper->SetOrientation( 0 );
93 this->m_ImageMapper->Update( );
96 this->m_ImageActor = vtkSmartPointer< vtkImageActor >::New( );
97 this->m_ImageActor->SetMapper( this->m_ImageMapper );
98 this->m_ImageActor->SetInterpolate( this->m_Interpolate );
99 this->m_ImageActor->Modified( );
101 if( this->m_Style.GetPointer( ) != NULL )
102 this->m_Style->AssociateImageActor( this->m_ImageActor );
103 this->AddItem( this->m_ImageActor );
105 this->SetSliceNumber( this->GetSliceNumberMinValue( ) );
106 this->ResetCursor( );
109 // Update window/level ranges
111 data->GetScalarRange( r );
112 this->m_WLRange[ 0 ] = double( 0 );
113 this->m_WLRange[ 1 ] = r[ 1 ] - r[ 0 ];
114 this->m_WLRange[ 2 ] = r[ 0 ];
115 this->m_WLRange[ 3 ] = r[ 1 ];
116 this->ResetWindowLevel( );
119 // -------------------------------------------------------------------------
120 void cpExtensions::Visualization::ImageSliceActors::
124 this->m_VisibleExtent[ 0 ] =
125 this->m_VisibleExtent[ 2 ] =
126 this->m_VisibleExtent[ 4 ] = -1;
127 this->m_VisibleExtent[ 1 ] =
128 this->m_VisibleExtent[ 3 ] =
129 this->m_VisibleExtent[ 5 ] = 0;
130 this->m_VisibleBounds[ 0 ] =
131 this->m_VisibleBounds[ 2 ] =
132 this->m_VisibleBounds[ 4 ] = double( 0 );
133 this->m_VisibleBounds[ 1 ] =
134 this->m_VisibleBounds[ 3 ] =
135 this->m_VisibleBounds[ 5 ] = double( 0 );
137 // Unbind from container
138 this->RemoveAllItems( );
141 this->m_ImageActor = NULL;
142 this->m_ImageMapper = NULL;
144 // Reconfigure unique objects
145 this->m_Cursor = vtkSmartPointer< vtkPolyData >::New( );
146 this->m_CursorMapper = vtkSmartPointer< vtkPolyDataMapper >::New( );
147 this->m_CursorActor = vtkSmartPointer< vtkActor >::New( );
148 this->m_HorizontalLine = vtkSmartPointer< vtkPolyData >::New( );
149 this->m_HorizontalLineMapper = vtkSmartPointer< vtkPolyDataMapper >::New( );
150 this->m_HorizontalLineActor = vtkSmartPointer< vtkActor >::New( );
151 this->m_VerticalLine = vtkSmartPointer< vtkPolyData >::New( );
152 this->m_VerticalLineMapper = vtkSmartPointer< vtkPolyDataMapper >::New( );
153 this->m_VerticalLineActor = vtkSmartPointer< vtkActor >::New( );
154 this->m_Plane = vtkSmartPointer< vtkPolyData >::New( );
155 this->m_PlaneMapper = vtkSmartPointer< vtkPolyDataMapper >::New( );
156 this->m_TextActor = vtkSmartPointer< vtkTextActor >::New( );
157 this->m_PlaneActor = vtkSmartPointer< vtkActor >::New( );
158 this->m_TextBuffer[ 0 ] = '\0';
160 // Unique objects configuration
161 vtkSmartPointer< vtkPoints > cursor_points =
162 vtkSmartPointer< vtkPoints >::New( );
163 vtkSmartPointer< vtkCellArray > cursor_lines =
164 vtkSmartPointer< vtkCellArray >::New( );
165 cursor_points->InsertNextPoint( 0, 0, 0 );
166 cursor_points->InsertNextPoint( 0, 0, 0 );
167 cursor_points->InsertNextPoint( 0, 0, 0 );
168 cursor_points->InsertNextPoint( 0, 0, 0 );
169 cursor_points->InsertNextPoint( 0, 0, 0 );
170 cursor_points->InsertNextPoint( 0, 0, 0 );
171 cursor_points->InsertNextPoint( 0, 0, 0 );
172 cursor_points->InsertNextPoint( 0, 0, 0 );
173 cursor_lines->InsertNextCell( 2 );
174 cursor_lines->InsertCellPoint( 0 );
175 cursor_lines->InsertCellPoint( 1 );
176 cursor_lines->InsertNextCell( 2 );
177 cursor_lines->InsertCellPoint( 2 );
178 cursor_lines->InsertCellPoint( 3 );
179 cursor_lines->InsertNextCell( 2 );
180 cursor_lines->InsertCellPoint( 4 );
181 cursor_lines->InsertCellPoint( 5 );
182 cursor_lines->InsertNextCell( 2 );
183 cursor_lines->InsertCellPoint( 6 );
184 cursor_lines->InsertCellPoint( 7 );
185 this->m_Cursor->SetPoints( cursor_points );
186 this->m_Cursor->SetLines( cursor_lines );
187 this->m_CursorMapper->SetInputData( this->m_Cursor );
188 this->m_CursorActor->SetMapper( this->m_CursorMapper );
190 vtkSmartPointer< vtkPoints > h_points =
191 vtkSmartPointer< vtkPoints >::New( );
192 vtkSmartPointer< vtkCellArray > h_lines =
193 vtkSmartPointer< vtkCellArray >::New( );
194 h_points->InsertNextPoint( 0, 0, 0 );
195 h_points->InsertNextPoint( 0, 0, 0 );
196 h_lines->InsertNextCell( 2 );
197 h_lines->InsertCellPoint( 0 );
198 h_lines->InsertCellPoint( 1 );
199 this->m_HorizontalLine->SetPoints( h_points );
200 this->m_HorizontalLine->SetLines( h_lines );
201 this->m_HorizontalLineMapper->SetInputData( this->m_HorizontalLine );
202 this->m_HorizontalLineActor->SetMapper( this->m_HorizontalLineMapper );
204 vtkSmartPointer< vtkPoints > v_points =
205 vtkSmartPointer< vtkPoints >::New( );
206 vtkSmartPointer< vtkCellArray > v_lines =
207 vtkSmartPointer< vtkCellArray >::New( );
208 v_points->InsertNextPoint( 0, 0, 0 );
209 v_points->InsertNextPoint( 0, 0, 0 );
210 v_lines->InsertNextCell( 2 );
211 v_lines->InsertCellPoint( 0 );
212 v_lines->InsertCellPoint( 1 );
213 this->m_VerticalLine->SetPoints( v_points );
214 this->m_VerticalLine->SetLines( v_lines );
215 this->m_VerticalLineMapper->SetInputData( this->m_VerticalLine );
216 this->m_VerticalLineActor->SetMapper( this->m_VerticalLineMapper );
218 vtkSmartPointer< vtkPoints > plane_points =
219 vtkSmartPointer< vtkPoints >::New( );
220 vtkSmartPointer< vtkCellArray > plane_lines =
221 vtkSmartPointer< vtkCellArray >::New( );
223 plane_points->InsertNextPoint( 0, 0, 0 );
224 plane_points->InsertNextPoint( 0, 1, 0 );
225 plane_points->InsertNextPoint( 1, 1, 0 );
226 plane_points->InsertNextPoint( 1, 0, 0 );
227 plane_lines->InsertNextCell( 5 );
228 plane_lines->InsertCellPoint( 0 );
229 plane_lines->InsertCellPoint( 1 );
230 plane_lines->InsertCellPoint( 2 );
231 plane_lines->InsertCellPoint( 3 );
232 plane_lines->InsertCellPoint( 0 );
233 this->m_Plane->SetPoints( plane_points );
234 this->m_Plane->SetLines( plane_lines );
236 this->m_PlaneMapper->SetInputData( this->m_Plane );
237 this->m_PlaneActor->SetMapper( this->m_PlaneMapper );
239 this->m_TextActor->SetTextScaleModeToNone( );
240 vtkTextProperty* textprop = this->m_TextActor->GetTextProperty( );
241 textprop->SetColor( 1, 1, 1 );
242 textprop->SetFontFamilyToCourier( );
243 textprop->SetFontSize( 18 );
244 textprop->BoldOff( );
245 textprop->ItalicOff( );
246 textprop->ShadowOff( );
247 textprop->SetJustificationToLeft( );
248 textprop->SetVerticalJustificationToBottom( );
249 vtkCoordinate* coord = this->m_TextActor->GetPositionCoordinate( );
250 coord->SetCoordinateSystemToNormalizedViewport( );
251 coord->SetValue( 0.01, 0.01 );
253 // Update actor collection
254 this->AddItem( this->m_CursorActor );
255 this->AddItem( this->m_HorizontalLineActor );
256 this->AddItem( this->m_VerticalLineActor );
257 this->AddItem( this->m_TextActor );
258 this->AddItem( this->m_PlaneActor );
261 // -------------------------------------------------------------------------
262 void cpExtensions::Visualization::ImageSliceActors::
263 AssociateSlice( Self* slice )
265 this->m_AssociatedSlices.push_back( slice );
269 // -------------------------------------------------------------------------
270 vtkInteractorStyle* cpExtensions::Visualization::ImageSliceActors::
273 return( this->m_Style.GetPointer( ) );
276 // -------------------------------------------------------------------------
277 const vtkInteractorStyle* cpExtensions::Visualization::ImageSliceActors::
280 return( this->m_Style.GetPointer( ) );
283 // -------------------------------------------------------------------------
284 vtkImageData* cpExtensions::Visualization::ImageSliceActors::
287 if( this->m_ImageMapper.GetPointer( ) != NULL )
289 dynamic_cast< vtkImageData* >( this->m_ImageMapper->GetInput( ) )
295 // -------------------------------------------------------------------------
296 const vtkImageData* cpExtensions::Visualization::ImageSliceActors::
297 GetInputImage( ) const
299 if( this->m_ImageMapper.GetPointer( ) != NULL )
301 dynamic_cast< const vtkImageData* >(
302 this->m_ImageMapper->GetInput( )
309 // -------------------------------------------------------------------------
310 void cpExtensions::Visualization::ImageSliceActors::
311 PushActorsInto( vtkRenderWindow* window, bool force_style )
313 this->m_Window = window;
316 vtkRenderWindowInteractor* rwi = window->GetInteractor( );
317 vtkRenderer* renderer = window->GetRenderers( )->GetFirstRenderer( );
318 if( rwi == NULL || renderer == NULL )
322 if( this->m_Style.GetPointer( ) != NULL && force_style )
323 rwi->SetInteractorStyle( this->m_Style );
327 this->InitTraversal( );
328 while( prop = this->GetNextProp( ) )
329 renderer->AddViewProp( prop );
330 renderer->Modified( );
333 renderer->RemoveViewProp( this->m_CursorActor );
334 renderer->RemoveViewProp( this->m_TextActor );
339 vtkCamera* camera = renderer->GetActiveCamera( );
340 if( camera != NULL && force_style )
342 // Parallel projections are better when displaying 2D images
343 int axis = this->GetAxis( );
344 camera->ParallelProjectionOn( );
345 camera->SetFocalPoint( double( 0 ), double( 0 ), double( 0 ) );
348 camera->SetPosition( double( 1 ), double( 0 ), double( 0 ) );
349 camera->SetViewUp ( double( 0 ), double( 0 ), double( 1 ) );
353 camera->SetPosition( double( 0 ), double( -1 ), double( 0 ) );
354 camera->SetViewUp ( double( 0 ), double( 0 ), double( 1 ) );
356 else // if( axis == 2 )
358 camera->SetPosition( double( 0 ), double( 0 ), double( 1 ) );
359 camera->SetViewUp ( double( 0 ), double( -1 ), double( 0 ) );
364 this->ResetCamera( );
368 // -------------------------------------------------------------------------
369 void cpExtensions::Visualization::ImageSliceActors::
370 PopActorsFrom( vtkRenderWindow* window )
372 vtkRenderWindowInteractor* rwi = window->GetInteractor( );
373 vtkRenderer* renderer = window->GetRenderers( )->GetFirstRenderer( );
375 if( renderer != NULL )
379 this->InitTraversal( );
380 while( prop = this->GetNextProp( ) )
381 renderer->RemoveViewProp( prop );
382 renderer->Modified( );
389 // -------------------------------------------------------------------------
390 vtkImageActor* cpExtensions::Visualization::ImageSliceActors::
393 return( this->m_ImageActor );
396 // -------------------------------------------------------------------------
397 const vtkImageActor* cpExtensions::Visualization::ImageSliceActors::
398 GetImageActor( ) const
400 return( this->m_ImageActor );
403 // -------------------------------------------------------------------------
404 vtkTextActor* cpExtensions::Visualization::ImageSliceActors::
407 return( this->m_TextActor );
410 // -------------------------------------------------------------------------
411 const vtkTextActor* cpExtensions::Visualization::ImageSliceActors::
412 GetTextActor( ) const
414 return( this->m_TextActor );
417 // -------------------------------------------------------------------------
418 vtkActor* cpExtensions::Visualization::ImageSliceActors::
421 return( this->m_PlaneActor );
424 // -------------------------------------------------------------------------
425 const vtkActor* cpExtensions::Visualization::ImageSliceActors::
426 GetPlaneActor( ) const
428 return( this->m_PlaneActor );
431 // -------------------------------------------------------------------------
432 vtkPlane* cpExtensions::Visualization::ImageSliceActors::
435 if( this->m_ImageMapper.GetPointer( ) != NULL )
436 return( this->m_ImageMapper->GetSlicePlane( ) );
441 // -------------------------------------------------------------------------
442 const vtkPlane* cpExtensions::Visualization::ImageSliceActors::
443 GetPlaneFunction( ) const
445 if( this->m_ImageMapper.GetPointer( ) != NULL )
446 return( this->m_ImageMapper->GetSlicePlane( ) );
451 // -------------------------------------------------------------------------
452 void cpExtensions::Visualization::ImageSliceActors::
453 SetInterpolate( bool v )
455 if( this->m_Interpolate != v )
457 this->m_ImageActor->SetInterpolate( v );
458 this->m_Interpolate = v;
464 // -------------------------------------------------------------------------
465 void cpExtensions::Visualization::ImageSliceActors::
468 this->SetInterpolate( true );
471 // -------------------------------------------------------------------------
472 void cpExtensions::Visualization::ImageSliceActors::
475 this->SetInterpolate( false );
478 // -------------------------------------------------------------------------
479 double* cpExtensions::Visualization::ImageSliceActors::
480 GetDisplayBounds( ) const
482 if( this->m_ImageActor.GetPointer( ) != NULL )
483 return( this->m_ImageActor->GetDisplayBounds( ) );
488 // -------------------------------------------------------------------------
489 void cpExtensions::Visualization::ImageSliceActors::
490 GetDisplayBounds( double bounds[ 6 ] ) const
492 if( this->m_ImageActor.GetPointer( ) == NULL )
494 bounds[ 0 ] = bounds[ 2 ] = bounds[ 4 ] = double( -1 );
495 bounds[ 1 ] = bounds[ 3 ] = bounds[ 5 ] = double( -1 );
498 this->m_ImageActor->GetDisplayBounds( bounds );
501 // -------------------------------------------------------------------------
502 void cpExtensions::Visualization::ImageSliceActors::
505 if( this->m_ImageMapper.GetPointer( ) != NULL )
508 this->m_ImageMapper->GetInput( )->GetBounds( bounds );
511 this->m_VisibleBounds[ 0 ],
512 this->m_VisibleBounds[ 2 ],
513 this->m_VisibleBounds[ 4 ]
515 this->SetCursor( pos );
519 vtkPoints* points = this->m_Cursor->GetPoints( );
520 points->SetPoint( 0, 0, 0, 0 );
521 points->SetPoint( 1, 0, 0, 0 );
522 points->SetPoint( 2, 0, 0, 0 );
523 points->SetPoint( 3, 0, 0, 0 );
524 points->SetPoint( 4, 0, 0, 0 );
525 points->SetPoint( 5, 0, 0, 0 );
526 points->SetPoint( 6, 0, 0, 0 );
527 points->SetPoint( 7, 0, 0, 0 );
528 this->m_Cursor->Modified( );
529 this->m_CursorMapper->Modified( );
530 this->m_CursorActor->Modified( );
535 // -------------------------------------------------------------------------
536 void cpExtensions::Visualization::ImageSliceActors::
537 SetCursor( double pos[ 3 ] )
539 if( this->m_ImageMapper.GetPointer( ) == NULL )
543 int a0 = this->GetAxis( );
544 int a1 = ( a0 + 1 ) % 3;
545 int a2 = ( a0 + 2 ) % 3;
551 double* bounds = this->m_VisibleBounds;
553 p0[ 3 ], p1[ 3 ], p2[ 3 ], p3[ 3 ],
554 p4[ 3 ], p5[ 3 ], p6[ 3 ], p7[ 3 ];
556 p0[ a2 ] = p1[ a2 ] = p4[ a2 ] = p5[ a2 ] = pos[ a2 ];
557 p2[ a1 ] = p3[ a1 ] = p6[ a1 ] = p7[ a1 ] = pos[ a1 ];
558 p0[ a0 ] = p1[ a0 ] = p2[ a0 ] = p3[ a0 ] = bounds[ ma0 ];
559 p4[ a0 ] = p5[ a0 ] = p6[ a0 ] = p7[ a0 ] = bounds[ ma0 + 1 ];
560 p0[ a1 ] = p4[ a1 ] = bounds[ ma1 ];
561 p1[ a1 ] = p5[ a1 ] = bounds[ ma1 + 1 ];
562 p2[ a2 ] = p6[ a2 ] = bounds[ ma2 ];
563 p3[ a2 ] = p7[ a2 ] = bounds[ ma2 + 1 ];
565 vtkPoints* points = this->m_Cursor->GetPoints( );
566 points->SetPoint( 0, p0 );
567 points->SetPoint( 1, p1 );
568 points->SetPoint( 2, p2 );
569 points->SetPoint( 3, p3 );
570 points->SetPoint( 4, p4 );
571 points->SetPoint( 5, p5 );
572 points->SetPoint( 6, p6 );
573 points->SetPoint( 7, p7 );
574 this->m_Cursor->Modified( );
575 this->m_CursorMapper->Modified( );
576 this->m_CursorActor->Modified( );
579 // -------------------------------------------------------------------------
580 double cpExtensions::Visualization::ImageSliceActors::
581 GetMinWindow( ) const
583 return( this->m_WLRange[ 0 ] );
586 // -------------------------------------------------------------------------
587 double cpExtensions::Visualization::ImageSliceActors::
588 GetMaxWindow( ) const
590 return( this->m_WLRange[ 1 ] );
593 // -------------------------------------------------------------------------
594 double cpExtensions::Visualization::ImageSliceActors::
597 return( this->m_WLRange[ 2 ] );
600 // -------------------------------------------------------------------------
601 double cpExtensions::Visualization::ImageSliceActors::
604 return( this->m_WLRange[ 3 ] );
607 // -------------------------------------------------------------------------
608 double cpExtensions::Visualization::ImageSliceActors::
611 if( this->m_ImageActor.GetPointer( ) != NULL )
612 return( this->m_ImageActor->GetProperty( )->GetColorWindow( ) );
614 return( double( 0 ) );
617 // -------------------------------------------------------------------------
618 double cpExtensions::Visualization::ImageSliceActors::
621 if( this->m_ImageActor.GetPointer( ) != NULL )
622 return( this->m_ImageActor->GetProperty( )->GetColorLevel( ) );
624 return( double( 0 ) );
627 // -------------------------------------------------------------------------
628 void cpExtensions::Visualization::ImageSliceActors::
629 SetWindow( double w )
631 if( this->m_ImageActor.GetPointer( ) == NULL )
633 double v = ( w < this->m_WLRange[ 0 ] )? this->m_WLRange[ 0 ]: w;
634 v = ( v > this->m_WLRange[ 1 ] )? this->m_WLRange[ 1 ]: v;
635 this->m_ImageActor->GetProperty( )->SetColorWindow( v );
638 // -------------------------------------------------------------------------
639 void cpExtensions::Visualization::ImageSliceActors::
642 if( this->m_ImageActor.GetPointer( ) == NULL )
644 double v = ( l < this->m_WLRange[ 2 ] )? this->m_WLRange[ 2 ]: l;
645 v = ( v > this->m_WLRange[ 3 ] )? this->m_WLRange[ 3 ]: v;
646 this->m_ImageActor->GetProperty( )->SetColorLevel( v );
649 // -------------------------------------------------------------------------
650 void cpExtensions::Visualization::ImageSliceActors::
651 SetWindowLevel( double w, double l )
653 if( this->m_ImageActor.GetPointer( ) == NULL )
655 double a = ( w < this->m_WLRange[ 0 ] )? this->m_WLRange[ 0 ]: w;
656 a = ( a > this->m_WLRange[ 1 ] )? this->m_WLRange[ 1 ]: a;
657 double b = ( l < this->m_WLRange[ 2 ] )? this->m_WLRange[ 2 ]: l;
658 b = ( b > this->m_WLRange[ 3 ] )? this->m_WLRange[ 3 ]: b;
659 this->m_ImageActor->GetProperty( )->SetColorWindow( a );
660 this->m_ImageActor->GetProperty( )->SetColorLevel( b );
663 // -------------------------------------------------------------------------
664 void cpExtensions::Visualization::ImageSliceActors::
667 this->SetWindowLevel(
668 this->m_WLRange[ 1 ] * double( 0.5 ),
669 ( this->m_WLRange[ 3 ] + this->m_WLRange[ 2 ] ) * double( 0.5 )
673 // -------------------------------------------------------------------------
674 int cpExtensions::Visualization::ImageSliceActors::
677 if( this->m_ImageMapper.GetPointer( ) != NULL )
678 return( this->m_ImageMapper->GetOrientation( ) );
683 // -------------------------------------------------------------------------
684 int cpExtensions::Visualization::ImageSliceActors::
685 GetSliceNumber( ) const
687 if( this->m_ImageMapper.GetPointer( ) != NULL )
688 return( this->m_ImageMapper->GetSliceNumber( ) );
693 // -------------------------------------------------------------------------
694 int cpExtensions::Visualization::ImageSliceActors::
695 GetSliceNumberMinValue( ) const
697 if( this->m_ImageMapper.GetPointer( ) != NULL )
698 return( this->m_ImageMapper->GetSliceNumberMinValue( ) );
703 // -------------------------------------------------------------------------
704 int cpExtensions::Visualization::ImageSliceActors::
705 GetSliceNumberMaxValue( ) const
707 if( this->m_ImageMapper.GetPointer( ) != NULL )
708 return( this->m_ImageMapper->GetSliceNumberMaxValue( ) );
713 // -------------------------------------------------------------------------
714 void cpExtensions::Visualization::ImageSliceActors::
715 SetSliceNumber( const int& slice )
717 if( this->m_ImageMapper.GetPointer( ) == NULL )
720 int axis = this->GetAxis( );
721 double prev_pos = this->m_VisibleBounds[ axis << 1 ];
723 // Update mappers and display bounds
724 this->m_ImageMapper->SetSliceNumber( slice );
725 this->m_ImageMapper->Modified( );
726 this->m_ImageActor->Modified( );
727 this->m_ImageMapper->Update( );
729 // Update display extent (this isn't done automatically)
730 this->m_ImageMapper->GetInput( )->GetExtent( this->m_VisibleExtent );
731 this->m_VisibleExtent[ axis << 1 ] = slice;
732 this->m_VisibleExtent[ ( axis << 1 ) + 1 ] = slice;
733 this->m_ImageActor->SetDisplayExtent( this->m_VisibleExtent );
735 // Prepare plane data
736 this->m_ImageMapper->GetBounds( this->m_VisibleBounds );
740 this->m_VisibleBounds[ 0 ],
741 this->m_VisibleBounds[ 2 ],
742 this->m_VisibleBounds[ 4 ]
745 this->m_VisibleBounds[ 1 ],
746 this->m_VisibleBounds[ 3 ],
747 this->m_VisibleBounds[ 5 ]
752 vtkPlane* plane = this->m_ImageMapper->GetSlicePlane( );
753 plane->GeneralizedProjectPoint( x0[ 0 ], p0[ 0 ] );
754 plane->GeneralizedProjectPoint( x0[ 1 ], p0[ 1 ] );
756 this->m_VisibleBounds[ 0 ] = p0[ 0 ][ 0 ];
757 this->m_VisibleBounds[ 1 ] = p0[ 1 ][ 0 ];
758 this->m_VisibleBounds[ 2 ] = p0[ 0 ][ 1 ];
759 this->m_VisibleBounds[ 3 ] = p0[ 1 ][ 1 ];
760 this->m_VisibleBounds[ 4 ] = p0[ 0 ][ 2 ];
761 this->m_VisibleBounds[ 5 ] = p0[ 1 ][ 2 ];
762 double* bnds = this->m_VisibleBounds;
764 // Configure visualization and implicit plane orientation
765 this->m_PlaneActor->GetProperty( )->SetRepresentationToWireframe( );
766 this->m_PlaneActor->GetProperty( )->SetLineWidth( 3 );
767 vtkPoints* plane_points = this->m_Plane->GetPoints( );
768 plane_points->SetPoint( 0, bnds[ 0 ], bnds[ 2 ], bnds[ 4 ] );
769 plane_points->SetPoint( 2, bnds[ 1 ], bnds[ 3 ], bnds[ 5 ] );
770 if( axis == 0 || axis == 2 ) // YZ, x-normal
772 plane_points->SetPoint( 1, bnds[ 1 ], bnds[ 2 ], bnds[ 5 ] );
773 plane_points->SetPoint( 3, bnds[ 0 ], bnds[ 3 ], bnds[ 4 ] );
775 this->m_PlaneActor->GetProperty( )->SetColor( 1, 0, 0 );
777 this->m_PlaneActor->GetProperty( )->SetColor( 0, 0, 1 );
779 else if( axis == 1 ) // ZX, y-normal
781 plane_points->SetPoint( 1, bnds[ 0 ], bnds[ 2 ], bnds[ 5 ] );
782 plane_points->SetPoint( 3, bnds[ 1 ], bnds[ 3 ], bnds[ 4 ] );
783 this->m_PlaneActor->GetProperty( )->SetColor( 0, 1, 0 );
786 this->m_Plane->Modified( );
787 this->m_PlaneMapper->Modified( );
788 this->m_PlaneActor->Modified( );
793 // Update lines from associated slices
795 auto sIt = this->m_AssociatedSlices.begin( );
796 for( ; sIt != this->m_AssociatedSlices.end( ); ++sIt )
799 for( unsigned int id = 0; id < slice->m_AssociatedSlices.size( ); ++id )
801 std::cout << id << std::endl;
802 if( slice->m_AssociatedSlices[ id ] != this )
805 std::cout << "id : " << id << std::endl;
812 // Update camera position
813 if( this->m_Window == NULL )
815 vtkRenderer* renderer =
816 this->m_Window->GetRenderers( )->GetFirstRenderer( );
817 if( renderer == NULL )
819 vtkCamera* camera = renderer->GetActiveCamera( );
823 camera->GetPosition( cam_pos );
824 cam_pos[ axis ] += this->m_VisibleBounds[ axis << 1 ] - prev_pos;
825 camera->SetPosition( cam_pos );
828 // -------------------------------------------------------------------------
829 void cpExtensions::Visualization::ImageSliceActors::
830 SetSlice( double* pos )
832 vtkImageData* image = this->GetInputImage( );
838 image->ComputeStructuredCoordinates( pos, ijk, pcoords );
839 this->SetSliceNumber( ijk[ this->GetAxis( ) ] );
842 // -------------------------------------------------------------------------
843 void cpExtensions::Visualization::ImageSliceActors::
846 if( this->m_ImageMapper.GetPointer( ) != NULL )
849 int axId = this->m_ImageMapper->GetOrientation( );
850 if ( axId == 0 ) axis = 'X';
851 else if( axId == 1 ) axis = 'Y';
852 else if( axId == 2 ) axis = 'Z';
855 this->m_TextBuffer, "Axis: %c (%d)",
856 axis, this->m_ImageMapper->GetSliceNumber( )
860 this->m_TextBuffer[ 0 ] = '\0';
861 this->m_TextActor->SetInput( this->m_TextBuffer );
862 this->m_TextActor->Modified( );
866 // -------------------------------------------------------------------------
867 void cpExtensions::Visualization::ImageSliceActors::
868 UpdateText( double pos[ 3 ] )
870 if( this->m_ImageMapper.GetPointer( ) != NULL )
873 int axId = this->m_ImageMapper->GetOrientation( );
874 if ( axId == 0 ) axis = 'X';
875 else if( axId == 1 ) axis = 'Y';
876 else if( axId == 2 ) axis = 'Z';
877 int slice = this->GetSliceNumber( );
879 vtkImageData* image = this->GetInputImage( );
882 image->ComputeStructuredCoordinates( pos, ijk, pcoords );
886 image->GetExtent( ext );
888 ext[ 0 ] <= ijk[ 0 ] && ijk[ 0 ] <= ext[ 1 ] &&
889 ext[ 2 ] <= ijk[ 1 ] && ijk[ 1 ] <= ext[ 3 ] &&
890 ext[ 4 ] <= ijk[ 2 ] && ijk[ 2 ] <= ext[ 5 ]
893 int nScl = image->GetNumberOfScalarComponents( );
894 std::stringstream str;
898 << "," << ijk[ 2 ] << "]=(";
900 image->GetScalarComponentAsFloat( ijk[ 0 ], ijk[ 1 ], ijk[ 2 ], 0 );
901 for( int n = 1; n < nScl; ++n )
904 << image->GetScalarComponentAsFloat(
905 ijk[ 0 ], ijk[ 1 ], ijk[ 2 ], n
909 this->m_TextBuffer, "Axis: %c (%d)\nPixel %s",
910 axis, slice, str.str( ).c_str( )
916 this->m_TextBuffer[ 0 ] = '\0';
917 this->m_TextActor->SetInput( this->m_TextBuffer );
918 this->m_TextActor->Modified( );
922 // -------------------------------------------------------------------------
923 void cpExtensions::Visualization::ImageSliceActors::
924 UpdateText( const double& w, const double& l )
926 if( this->m_ImageMapper.GetPointer( ) != NULL )
929 int axId = this->m_ImageMapper->GetOrientation( );
930 if ( axId == 0 ) axis = 'X';
931 else if( axId == 1 ) axis = 'Y';
932 else if( axId == 2 ) axis = 'Z';
935 this->m_TextBuffer, "Axis: %c (%d)\nW/L (%.2f/%.2f)",
936 axis, this->m_ImageMapper->GetSliceNumber( ), w, l
940 this->m_TextBuffer[ 0 ] = '\0';
941 this->m_TextActor->SetInput( this->m_TextBuffer );
942 this->m_TextActor->Modified( );
946 // -------------------------------------------------------------------------
947 void cpExtensions::Visualization::ImageSliceActors::
948 Render( const double& t )
950 if( this->m_Window != NULL )
952 vtkRenderer* renderer =
953 this->m_Window->GetRenderers( )->GetFirstRenderer( );
954 if( renderer != NULL )
955 renderer->SetAllocatedRenderTime( t );
956 this->m_Window->Render( );
961 // -------------------------------------------------------------------------
962 void cpExtensions::Visualization::ImageSliceActors::
965 if( this->m_Window == NULL )
967 vtkRenderer* renderer =
968 this->m_Window->GetRenderers( )->GetFirstRenderer( );
969 if( renderer != NULL )
970 renderer->ResetCamera( this->m_VisibleBounds );
973 // -------------------------------------------------------------------------
974 cpExtensions::Visualization::ImageSliceActors::
978 m_Interpolate( false )
981 this->_ConfigureStyle( );
984 // -------------------------------------------------------------------------
985 cpExtensions::Visualization::ImageSliceActors::
990 // -------------------------------------------------------------------------
991 void cpExtensions::Visualization::ImageSliceActors::
994 // Connect this view with a controller
995 this->m_Style = vtkSmartPointer< TStyle >::New( );
996 this->m_Style->AddMouseMoveCommand( Self::_MouseMoveCommand, this );
997 this->m_Style->AddMouseClickCommand( Self::_MouseClickCommand, this );
998 this->m_Style->AddMouseWheelCommand( Self::_MouseWheelCommand, this );
999 this->m_Style->AddKeyCommand( Self::_KeyCommand, this );
1000 this->m_Style->AddEnterCommand( Self::_EnterCommand, this );
1001 this->m_Style->AddLeaveCommand( Self::_LeaveCommand, this );
1004 // -------------------------------------------------------------------------
1005 void cpExtensions::Visualization::ImageSliceActors::
1007 void* data, const TStyle::ButtonID& btn, int* idx, double* pos,
1008 bool alt, bool ctr, bool sft
1011 ImageSliceActors* actors = reinterpret_cast< ImageSliceActors* >( data );
1012 if( actors == NULL )
1015 if( btn == TStyle::ButtonID_None )
1017 // Just show the pixel information
1018 actors->SetCursor( pos );
1019 actors->UpdateText( pos );
1020 actors->Render( 1e-3 );
1022 else if( btn == TStyle::ButtonID_Left )
1024 if( !alt && ctr && !sft )
1026 // Interactively move slices
1027 auto i = actors->m_SlicesCommands.begin( );
1028 for( ; i != actors->m_SlicesCommands.end( ); ++i )
1029 i->first( pos, actors->GetAxis( ), i->second );
1030 actors->Render( 1e-3 );
1034 else if( btn == TStyle::ButtonID_Right )
1036 if( !alt && !ctr && sft )
1038 // Change image window level
1040 actors->m_ImageMapper->GetBounds( bounds );
1042 int a0 = actors->GetAxis( );
1043 int a1 = ( a0 + 1 ) % 3;
1044 int a2 = ( a0 + 2 ) % 3;
1045 double dx = pos[ a1 ] - actors->m_StartWindowLevelPos[ a1 ];
1046 double dy = pos[ a2 ] - actors->m_StartWindowLevelPos[ a2 ];
1047 dx /= bounds[ ( a1 << 1 ) + 1 ] - bounds[ a1 << 1 ];
1048 dy /= bounds[ ( a2 << 1 ) + 1 ] - bounds[ a2 << 1 ];
1050 dx *= actors->m_StartWindowLevel[ 0 ];
1051 dy *= actors->m_StartWindowLevel[ 1 ];
1052 dx += actors->m_StartWindowLevel[ 0 ];
1053 dy += actors->m_StartWindowLevel[ 1 ];
1054 actors->SetWindowLevel( dx, dy );
1055 actors->Render( 1e-3 );
1057 // Associate objects
1058 auto i = actors->m_WindowLevelCommands.begin( );
1059 for( ; i != actors->m_WindowLevelCommands.end( ); ++i )
1060 i->first( dx, dy, i->second );
1067 // -------------------------------------------------------------------------
1068 void cpExtensions::Visualization::ImageSliceActors::
1070 void* data, const TStyle::ButtonID& btn, int* idx, double* pos,
1071 bool alt, bool ctr, bool sft
1074 ImageSliceActors* actors = reinterpret_cast< ImageSliceActors* >( data );
1075 if( actors == NULL )
1078 actors->m_StartWindowLevelPos[ 0 ] = pos[ 0 ];
1079 actors->m_StartWindowLevelPos[ 1 ] = pos[ 1 ];
1080 actors->m_StartWindowLevelPos[ 2 ] = pos[ 2 ];
1081 actors->m_StartWindowLevel[ 0 ] = actors->GetWindow( );
1082 actors->m_StartWindowLevel[ 1 ] = actors->GetLevel( );
1085 // -------------------------------------------------------------------------
1086 void cpExtensions::Visualization::ImageSliceActors::
1088 void* data, const int& dir,
1089 bool alt, bool ctr, bool sft
1092 ImageSliceActors* actors = reinterpret_cast< ImageSliceActors* >( data );
1093 if( actors == NULL )
1098 int slice = actors->GetSliceNumber( ) + ( dir * ( ( sft )? 10: 1 ) );
1099 if( slice < actors->GetSliceNumberMinValue( ) )
1100 slice = actors->GetSliceNumberMinValue( );
1101 if( slice > actors->GetSliceNumberMaxValue( ) )
1102 slice = actors->GetSliceNumberMaxValue( );
1103 actors->SetSliceNumber( slice );
1105 auto a = actors->m_AssociatedSlices.begin( );
1106 for( ; a != actors->m_AssociatedSlices.end( ); ++a )
1108 ( *a )->SetSliceNumber( slice );
1109 ( *a )->Render( 1e-3 );
1112 actors->Render( 1e-3 );
1114 // Associate objects
1115 auto i = actors->m_RenderCommands.begin( );
1116 for( ; i != actors->m_RenderCommands.end( ); ++i )
1117 i->first( i->second );
1122 // -------------------------------------------------------------------------
1123 void cpExtensions::Visualization::ImageSliceActors::
1124 _KeyCommand( void* data, const char& key )
1126 ImageSliceActors* actors = reinterpret_cast< ImageSliceActors* >( data );
1127 if( actors == NULL )
1134 actors->ResetCamera( );
1135 actors->Render( 1e-3 );
1137 // Associate objects
1138 auto i = actors->m_RenderCommands.begin( );
1139 for( ; i != actors->m_RenderCommands.end( ); ++i )
1140 i->first( i->second );
1145 actors->ResetWindowLevel( );
1146 actors->Render( 1e-3 );
1148 // Associate objects
1149 auto i = actors->m_RenderCommands.begin( );
1150 for( ; i != actors->m_RenderCommands.end( ); ++i )
1151 i->first( i->second );
1159 // -------------------------------------------------------------------------
1160 void cpExtensions::Visualization::ImageSliceActors::
1161 _EnterCommand( void* data )
1163 ImageSliceActors* actors = reinterpret_cast< ImageSliceActors* >( data );
1164 if( actors == NULL )
1167 actors->ResetCursor( );
1168 actors->m_CursorActor->VisibilityOn( );
1169 actors->Render( 1e-3 );
1172 // -------------------------------------------------------------------------
1173 void cpExtensions::Visualization::ImageSliceActors::
1174 _LeaveCommand( void* data )
1176 ImageSliceActors* actors = reinterpret_cast< ImageSliceActors* >( data );
1177 if( actors == NULL )
1180 actors->ResetCursor( );
1181 actors->m_CursorActor->VisibilityOff( );
1182 actors->Render( 1e-3 );