1 #include <cpExtensions/Visualization/ImageSliceActors.h>
6 #include <vtkAlgorithmOutput.h>
8 #include <vtkCellArray.h>
9 #include <vtkImageData.h>
10 #include <vtkImageProperty.h>
11 #include <vtkPoints.h>
12 #include <vtkProperty.h>
13 #include <vtkRenderer.h>
14 #include <vtkRendererCollection.h>
15 #include <vtkRenderWindow.h>
16 #include <vtkRenderWindowInteractor.h>
17 #include <vtkTextProperty.h>
19 // -------------------------------------------------------------------------
20 cpExtensions::Visualization::ImageSliceActors*
21 cpExtensions::Visualization::ImageSliceActors::
24 return( new Self( ) );
27 // -------------------------------------------------------------------------
28 void cpExtensions::Visualization::ImageSliceActors::
31 this->m_ImageMapper->SetOrientation( axis );
32 this->m_BlenderMapper->SetOrientation( axis );
33 this->m_ImageMapper->Update( );
34 this->m_BlenderMapper->Update( );
35 this->SetSliceNumber( this->GetSliceNumberMinValue( ) );
36 this->m_ImageActor->Modified( );
37 this->m_BlenderActor->Modified( );
42 // -------------------------------------------------------------------------
43 void cpExtensions::Visualization::ImageSliceActors::
44 SetInputConnection( vtkAlgorithmOutput* aout )
46 // Get input vtkImageData
50 // Create mapper and actors
51 this->m_ImageMapper->SetInputConnection( aout );
52 this->_ConfigureInputImage( );
55 // -------------------------------------------------------------------------
56 void cpExtensions::Visualization::ImageSliceActors::
57 SetInputImage( vtkImageData* data )
59 // Get input vtkImageData
63 // Create mapper and actors
64 this->m_ImageMapper->SetInputData( data );
65 this->_ConfigureInputImage( );
68 // -------------------------------------------------------------------------
69 int cpExtensions::Visualization::ImageSliceActors::
71 vtkAlgorithmOutput* aout,
72 const double& r, const double& g, const double& b
77 // -------------------------------------------------------------------------
78 int cpExtensions::Visualization::ImageSliceActors::
81 const double& r, const double& g, const double& b
87 this->m_Blender->AddInputData( data );
89 unsigned int nValues = this->m_BlenderLUT->GetNumberOfTableValues( );
90 this->m_BlenderLUT->SetNumberOfTableValues( nValues + 1 );
91 this->m_BlenderLUT->SetTableValue( nValues, r, g, b, 0.5 );
92 this->m_BlenderLUT->Build( );
94 this->m_BlenderLUT->Modified( );
95 this->m_Blender->Modified( );
96 this->m_Blender->Update( );
98 this->m_BlenderMapper->Modified( );
99 this->m_BlenderActor->Modified( );
102 // -------------------------------------------------------------------------
103 void cpExtensions::Visualization::ImageSliceActors::
106 // Unbind from container
107 this->RemoveAllItems( );
109 // Filters and mappers
110 this->m_ImageMapper = vtkSmartPointer< vtkImageSliceMapper >::New( );
111 this->m_ImageActor = vtkSmartPointer< vtkImageActor >::New( );
112 this->m_Blender = vtkSmartPointer< TBlender >::New( );
113 this->m_BlenderMapper = vtkSmartPointer< vtkImageSliceMapper >::New( );
114 this->m_BlenderLUT = vtkSmartPointer< vtkLookupTable >::New( );
115 this->m_BlenderActor = vtkSmartPointer< vtkImageActor >::New( );
117 this->m_ImageActor->SetMapper( this->m_ImageMapper );
118 this->m_BlenderMapper->
119 SetInputConnection( this->m_Blender->GetOutputPort( ) );
121 this->m_BlenderLUT->SetNumberOfTableValues( 1 );
122 this->m_BlenderLUT->SetTableValue( 0, 0, 0, 0, 0 );
123 this->m_BlenderLUT->Build( );
125 this->m_BlenderActor->SetMapper( this->m_BlenderMapper );
126 this->m_BlenderActor->GetProperty( )->SetLookupTable( this->m_BlenderLUT );
127 this->m_BlenderActor->GetProperty( )->UseLookupTableScalarRangeOn( );
129 // Remove associated objects
130 this->m_AssociatedSlices.clear( );
134 vtkSmartPointer< vtkPoints > cursor_points =
135 vtkSmartPointer< vtkPoints >::New( );
136 vtkSmartPointer< vtkCellArray > cursor_lines =
137 vtkSmartPointer< vtkCellArray >::New( );
138 cursor_points->InsertNextPoint( 0, 0, 0 );
139 cursor_points->InsertNextPoint( 0, 0, 0 );
140 cursor_points->InsertNextPoint( 0, 0, 0 );
141 cursor_points->InsertNextPoint( 0, 0, 0 );
142 cursor_points->InsertNextPoint( 0, 0, 0 );
143 cursor_points->InsertNextPoint( 0, 0, 0 );
144 cursor_points->InsertNextPoint( 0, 0, 0 );
145 cursor_points->InsertNextPoint( 0, 0, 0 );
146 cursor_lines->InsertNextCell( 2 );
147 cursor_lines->InsertCellPoint( 0 );
148 cursor_lines->InsertCellPoint( 1 );
149 cursor_lines->InsertNextCell( 2 );
150 cursor_lines->InsertCellPoint( 2 );
151 cursor_lines->InsertCellPoint( 3 );
152 cursor_lines->InsertNextCell( 2 );
153 cursor_lines->InsertCellPoint( 4 );
154 cursor_lines->InsertCellPoint( 5 );
155 cursor_lines->InsertNextCell( 2 );
156 cursor_lines->InsertCellPoint( 6 );
157 cursor_lines->InsertCellPoint( 7 );
159 this->m_Cursor = vtkSmartPointer< vtkPolyData >::New( );
160 this->m_CursorMapper = vtkSmartPointer< vtkPolyDataMapper >::New( );
161 this->m_CursorActor = vtkSmartPointer< vtkActor >::New( );
163 this->m_Cursor->SetPoints( cursor_points );
164 this->m_Cursor->SetLines( cursor_lines );
165 this->m_CursorMapper->SetInputData( this->m_Cursor );
166 this->m_CursorActor->SetMapper( this->m_CursorMapper );
170 vtkSmartPointer< vtkPolyDataMapper > m_CursorMapper;
171 vtkSmartPointer< vtkActor > m_CursorActor;
173 vtkSmartPointer< vtkPolyData > m_HorizontalLine;
174 vtkSmartPointer< vtkPolyDataMapper > m_HorizontalLineMapper;
175 vtkSmartPointer< vtkActor > m_HorizontalLineActor;
177 vtkSmartPointer< vtkPolyData > m_VerticalLine;
178 vtkSmartPointer< vtkPolyDataMapper > m_VerticalLineMapper;
179 vtkSmartPointer< vtkActor > m_VerticalLineActor;
181 vtkSmartPointer< vtkPolyData > m_Plane;
182 vtkSmartPointer< vtkPolyDataMapper > m_PlaneMapper;
183 vtkSmartPointer< vtkActor > m_PlaneActor;
185 char m_TextBuffer[ 1024 ];
186 vtkSmartPointer< vtkTextActor > m_TextActor;
195 this->m_VisibleExtent[ 0 ] =
196 this->m_VisibleExtent[ 2 ] =
197 this->m_VisibleExtent[ 4 ] = -1;
198 this->m_VisibleExtent[ 1 ] =
199 this->m_VisibleExtent[ 3 ] =
200 this->m_VisibleExtent[ 5 ] = 0;
201 this->m_VisibleBounds[ 0 ] =
202 this->m_VisibleBounds[ 2 ] =
203 this->m_VisibleBounds[ 4 ] = double( 0 );
204 this->m_VisibleBounds[ 1 ] =
205 this->m_VisibleBounds[ 3 ] =
206 this->m_VisibleBounds[ 5 ] = double( 0 );
209 this->m_ImageActor = NULL;
210 this->m_ImageMapper = NULL;
212 // Reconfigure unique objects
213 this->m_Cursor = vtkSmartPointer< vtkPolyData >::New( );
214 this->m_CursorMapper = vtkSmartPointer< vtkPolyDataMapper >::New( );
215 this->m_CursorActor = vtkSmartPointer< vtkActor >::New( );
216 this->m_HorizontalLine = vtkSmartPointer< vtkPolyData >::New( );
217 this->m_HorizontalLineMapper = vtkSmartPointer< vtkPolyDataMapper >::New( );
218 this->m_HorizontalLineActor = vtkSmartPointer< vtkActor >::New( );
219 this->m_VerticalLine = vtkSmartPointer< vtkPolyData >::New( );
220 this->m_VerticalLineMapper = vtkSmartPointer< vtkPolyDataMapper >::New( );
221 this->m_VerticalLineActor = vtkSmartPointer< vtkActor >::New( );
222 this->m_Plane = vtkSmartPointer< vtkPolyData >::New( );
223 this->m_PlaneMapper = vtkSmartPointer< vtkPolyDataMapper >::New( );
224 this->m_TextActor = vtkSmartPointer< vtkTextActor >::New( );
225 this->m_PlaneActor = vtkSmartPointer< vtkActor >::New( );
226 this->m_TextBuffer[ 0 ] = '\0';
228 // Unique objects configuration
229 vtkSmartPointer< vtkPoints > cursor_points =
230 vtkSmartPointer< vtkPoints >::New( );
231 vtkSmartPointer< vtkCellArray > cursor_lines =
232 vtkSmartPointer< vtkCellArray >::New( );
233 cursor_points->InsertNextPoint( 0, 0, 0 );
234 cursor_points->InsertNextPoint( 0, 0, 0 );
235 cursor_points->InsertNextPoint( 0, 0, 0 );
236 cursor_points->InsertNextPoint( 0, 0, 0 );
237 cursor_points->InsertNextPoint( 0, 0, 0 );
238 cursor_points->InsertNextPoint( 0, 0, 0 );
239 cursor_points->InsertNextPoint( 0, 0, 0 );
240 cursor_points->InsertNextPoint( 0, 0, 0 );
241 cursor_lines->InsertNextCell( 2 );
242 cursor_lines->InsertCellPoint( 0 );
243 cursor_lines->InsertCellPoint( 1 );
244 cursor_lines->InsertNextCell( 2 );
245 cursor_lines->InsertCellPoint( 2 );
246 cursor_lines->InsertCellPoint( 3 );
247 cursor_lines->InsertNextCell( 2 );
248 cursor_lines->InsertCellPoint( 4 );
249 cursor_lines->InsertCellPoint( 5 );
250 cursor_lines->InsertNextCell( 2 );
251 cursor_lines->InsertCellPoint( 6 );
252 cursor_lines->InsertCellPoint( 7 );
253 this->m_Cursor->SetPoints( cursor_points );
254 this->m_Cursor->SetLines( cursor_lines );
255 this->m_CursorMapper->SetInputData( this->m_Cursor );
256 this->m_CursorActor->SetMapper( this->m_CursorMapper );
258 vtkSmartPointer< vtkPoints > h_points =
259 vtkSmartPointer< vtkPoints >::New( );
260 vtkSmartPointer< vtkCellArray > h_lines =
261 vtkSmartPointer< vtkCellArray >::New( );
262 h_points->InsertNextPoint( 0, 0, 0 );
263 h_points->InsertNextPoint( 0, 0, 0 );
264 h_lines->InsertNextCell( 2 );
265 h_lines->InsertCellPoint( 0 );
266 h_lines->InsertCellPoint( 1 );
267 this->m_HorizontalLine->SetPoints( h_points );
268 this->m_HorizontalLine->SetLines( h_lines );
269 this->m_HorizontalLineMapper->SetInputData( this->m_HorizontalLine );
270 this->m_HorizontalLineActor->SetMapper( this->m_HorizontalLineMapper );
272 vtkSmartPointer< vtkPoints > v_points =
273 vtkSmartPointer< vtkPoints >::New( );
274 vtkSmartPointer< vtkCellArray > v_lines =
275 vtkSmartPointer< vtkCellArray >::New( );
276 v_points->InsertNextPoint( 0, 0, 0 );
277 v_points->InsertNextPoint( 0, 0, 0 );
278 v_lines->InsertNextCell( 2 );
279 v_lines->InsertCellPoint( 0 );
280 v_lines->InsertCellPoint( 1 );
281 this->m_VerticalLine->SetPoints( v_points );
282 this->m_VerticalLine->SetLines( v_lines );
283 this->m_VerticalLineMapper->SetInputData( this->m_VerticalLine );
284 this->m_VerticalLineActor->SetMapper( this->m_VerticalLineMapper );
286 vtkSmartPointer< vtkPoints > plane_points =
287 vtkSmartPointer< vtkPoints >::New( );
288 vtkSmartPointer< vtkCellArray > plane_lines =
289 vtkSmartPointer< vtkCellArray >::New( );
291 plane_points->InsertNextPoint( 0, 0, 0 );
292 plane_points->InsertNextPoint( 0, 1, 0 );
293 plane_points->InsertNextPoint( 1, 1, 0 );
294 plane_points->InsertNextPoint( 1, 0, 0 );
295 plane_lines->InsertNextCell( 5 );
296 plane_lines->InsertCellPoint( 0 );
297 plane_lines->InsertCellPoint( 1 );
298 plane_lines->InsertCellPoint( 2 );
299 plane_lines->InsertCellPoint( 3 );
300 plane_lines->InsertCellPoint( 0 );
301 this->m_Plane->SetPoints( plane_points );
302 this->m_Plane->SetLines( plane_lines );
304 this->m_PlaneMapper->SetInputData( this->m_Plane );
305 this->m_PlaneActor->SetMapper( this->m_PlaneMapper );
307 this->m_TextActor->SetTextScaleModeToNone( );
308 vtkTextProperty* textprop = this->m_TextActor->GetTextProperty( );
309 textprop->SetColor( 1, 1, 1 );
310 textprop->SetFontFamilyToCourier( );
311 textprop->SetFontSize( 18 );
312 textprop->BoldOff( );
313 textprop->ItalicOff( );
314 textprop->ShadowOff( );
315 textprop->SetJustificationToLeft( );
316 textprop->SetVerticalJustificationToBottom( );
317 vtkCoordinate* coord = this->m_TextActor->GetPositionCoordinate( );
318 coord->SetCoordinateSystemToNormalizedViewport( );
319 coord->SetValue( 0.01, 0.01 );
321 // Update actor collection
322 this->AddItem( this->m_CursorActor );
323 this->AddItem( this->m_HorizontalLineActor );
324 this->AddItem( this->m_VerticalLineActor );
325 this->AddItem( this->m_TextActor );
326 this->AddItem( this->m_PlaneActor );
330 // -------------------------------------------------------------------------
331 void cpExtensions::Visualization::ImageSliceActors::
332 AssociateSlice( Self* slice )
334 this->m_AssociatedSlices.push_back( slice );
338 // -------------------------------------------------------------------------
339 vtkInteractorStyle* cpExtensions::Visualization::ImageSliceActors::
342 return( this->m_Style.GetPointer( ) );
345 // -------------------------------------------------------------------------
346 const vtkInteractorStyle* cpExtensions::Visualization::ImageSliceActors::
349 return( this->m_Style.GetPointer( ) );
352 // -------------------------------------------------------------------------
353 vtkImageData* cpExtensions::Visualization::ImageSliceActors::
356 if( this->m_ImageMapper.GetPointer( ) != NULL )
357 return( this->m_ImageMapper->GetInput( ) );
362 // -------------------------------------------------------------------------
363 const vtkImageData* cpExtensions::Visualization::ImageSliceActors::
364 GetInputImage( ) const
366 if( this->m_ImageMapper.GetPointer( ) != NULL )
367 return( this->m_ImageMapper->GetInput( ) );
372 // -------------------------------------------------------------------------
373 void cpExtensions::Visualization::ImageSliceActors::
374 PushActorsInto( vtkRenderWindow* window, bool force_style )
376 this->m_Window = window;
379 vtkRenderWindowInteractor* rwi = window->GetInteractor( );
380 vtkRenderer* renderer = window->GetRenderers( )->GetFirstRenderer( );
381 if( rwi == NULL || renderer == NULL )
385 if( this->m_Style.GetPointer( ) != NULL && force_style )
386 rwi->SetInteractorStyle( this->m_Style );
389 renderer->AddViewProp( this->m_ImageActor );
390 renderer->AddViewProp( this->m_BlenderActor );
394 renderer->AddViewProp( this->m_CursorActor );
395 renderer->AddViewProp( this->m_HorizontalLineActor );
396 renderer->AddViewProp( this->m_VerticalLineActor );
397 renderer->AddViewProp( this->m_PlaneActor );
398 renderer->AddViewProp( this->m_TextActor );
404 vtkCamera* camera = renderer->GetActiveCamera( );
405 if( camera != NULL && force_style )
407 // Parallel projections are better when displaying 2D images
408 int axis = this->GetAxis( );
409 camera->ParallelProjectionOn( );
410 camera->SetFocalPoint( double( 0 ), double( 0 ), double( 0 ) );
413 camera->SetPosition( double( 1 ), double( 0 ), double( 0 ) );
414 camera->SetViewUp ( double( 0 ), double( 0 ), double( 1 ) );
418 camera->SetPosition( double( 0 ), double( -1 ), double( 0 ) );
419 camera->SetViewUp ( double( 0 ), double( 0 ), double( 1 ) );
421 else // if( axis == 2 )
423 camera->SetPosition( double( 0 ), double( 0 ), double( 1 ) );
424 camera->SetViewUp ( double( 0 ), double( -1 ), double( 0 ) );
429 this->ResetCamera( );
433 // -------------------------------------------------------------------------
434 void cpExtensions::Visualization::ImageSliceActors::
435 PopActorsFrom( vtkRenderWindow* window )
438 vtkRenderWindowInteractor* rwi = window->GetInteractor( );
439 vtkRenderer* renderer = window->GetRenderers( )->GetFirstRenderer( );
441 if( renderer != NULL )
445 this->InitTraversal( );
446 while( prop = this->GetNextProp( ) )
447 renderer->RemoveViewProp( prop );
448 renderer->Modified( );
456 // -------------------------------------------------------------------------
457 vtkImageActor* cpExtensions::Visualization::ImageSliceActors::
460 return( this->m_ImageActor );
463 // -------------------------------------------------------------------------
464 const vtkImageActor* cpExtensions::Visualization::ImageSliceActors::
465 GetImageActor( ) const
467 return( this->m_ImageActor );
470 // -------------------------------------------------------------------------
471 vtkImageActor* cpExtensions::Visualization::ImageSliceActors::
474 return( this->m_BlenderActor );
477 // -------------------------------------------------------------------------
478 const vtkImageActor* cpExtensions::Visualization::ImageSliceActors::
479 GetBinaryActor( ) const
481 return( this->m_BlenderActor );
484 // -------------------------------------------------------------------------
485 vtkTextActor* cpExtensions::Visualization::ImageSliceActors::
488 return( this->m_TextActor );
491 // -------------------------------------------------------------------------
492 const vtkTextActor* cpExtensions::Visualization::ImageSliceActors::
493 GetTextActor( ) const
495 return( this->m_TextActor );
498 // -------------------------------------------------------------------------
499 vtkActor* cpExtensions::Visualization::ImageSliceActors::
502 return( this->m_PlaneActor );
505 // -------------------------------------------------------------------------
506 const vtkActor* cpExtensions::Visualization::ImageSliceActors::
507 GetPlaneActor( ) const
509 return( this->m_PlaneActor );
512 // -------------------------------------------------------------------------
513 vtkPlane* cpExtensions::Visualization::ImageSliceActors::
516 if( this->m_ImageMapper.GetPointer( ) != NULL )
517 return( this->m_ImageMapper->GetSlicePlane( ) );
522 // -------------------------------------------------------------------------
523 const vtkPlane* cpExtensions::Visualization::ImageSliceActors::
524 GetPlaneFunction( ) const
526 if( this->m_ImageMapper.GetPointer( ) != NULL )
527 return( this->m_ImageMapper->GetSlicePlane( ) );
532 // -------------------------------------------------------------------------
533 void cpExtensions::Visualization::ImageSliceActors::
534 SetInterpolate( bool v )
536 if( this->m_Interpolate != v )
538 this->m_ImageActor->SetInterpolate( v );
539 this->m_BlenderActor->SetInterpolate( v );
540 this->m_Interpolate = v;
546 // -------------------------------------------------------------------------
547 void cpExtensions::Visualization::ImageSliceActors::
550 this->SetInterpolate( true );
553 // -------------------------------------------------------------------------
554 void cpExtensions::Visualization::ImageSliceActors::
557 this->SetInterpolate( false );
560 // -------------------------------------------------------------------------
561 double* cpExtensions::Visualization::ImageSliceActors::
562 GetDisplayBounds( ) const
564 if( this->m_ImageActor.GetPointer( ) != NULL )
565 return( this->m_ImageActor->GetDisplayBounds( ) );
570 // -------------------------------------------------------------------------
571 void cpExtensions::Visualization::ImageSliceActors::
572 GetDisplayBounds( double bounds[ 6 ] ) const
574 if( this->m_ImageActor.GetPointer( ) == NULL )
576 bounds[ 0 ] = bounds[ 2 ] = bounds[ 4 ] = double( -1 );
577 bounds[ 1 ] = bounds[ 3 ] = bounds[ 5 ] = double( -1 );
580 this->m_ImageActor->GetDisplayBounds( bounds );
583 // -------------------------------------------------------------------------
584 void cpExtensions::Visualization::ImageSliceActors::
588 if( this->m_ImageMapper.GetPointer( ) != NULL )
591 this->m_ImageMapper->GetInput( )->GetBounds( bounds );
594 this->m_VisibleBounds[ 0 ],
595 this->m_VisibleBounds[ 2 ],
596 this->m_VisibleBounds[ 4 ]
598 this->SetCursor( pos );
602 vtkPoints* points = this->m_Cursor->GetPoints( );
603 points->SetPoint( 0, 0, 0, 0 );
604 points->SetPoint( 1, 0, 0, 0 );
605 points->SetPoint( 2, 0, 0, 0 );
606 points->SetPoint( 3, 0, 0, 0 );
607 points->SetPoint( 4, 0, 0, 0 );
608 points->SetPoint( 5, 0, 0, 0 );
609 points->SetPoint( 6, 0, 0, 0 );
610 points->SetPoint( 7, 0, 0, 0 );
611 this->m_Cursor->Modified( );
612 this->m_CursorMapper->Modified( );
613 this->m_CursorActor->Modified( );
619 // -------------------------------------------------------------------------
620 void cpExtensions::Visualization::ImageSliceActors::
621 SetCursor( double pos[ 3 ] )
624 if( this->m_ImageMapper.GetPointer( ) == NULL )
628 int a0 = this->GetAxis( );
629 int a1 = ( a0 + 1 ) % 3;
630 int a2 = ( a0 + 2 ) % 3;
636 double* bounds = this->m_VisibleBounds;
638 p0[ 3 ], p1[ 3 ], p2[ 3 ], p3[ 3 ],
639 p4[ 3 ], p5[ 3 ], p6[ 3 ], p7[ 3 ];
641 p0[ a2 ] = p1[ a2 ] = p4[ a2 ] = p5[ a2 ] = pos[ a2 ];
642 p2[ a1 ] = p3[ a1 ] = p6[ a1 ] = p7[ a1 ] = pos[ a1 ];
643 p0[ a0 ] = p1[ a0 ] = p2[ a0 ] = p3[ a0 ] = bounds[ ma0 ];
644 p4[ a0 ] = p5[ a0 ] = p6[ a0 ] = p7[ a0 ] = bounds[ ma0 + 1 ];
645 p0[ a1 ] = p4[ a1 ] = bounds[ ma1 ];
646 p1[ a1 ] = p5[ a1 ] = bounds[ ma1 + 1 ];
647 p2[ a2 ] = p6[ a2 ] = bounds[ ma2 ];
648 p3[ a2 ] = p7[ a2 ] = bounds[ ma2 + 1 ];
650 vtkPoints* points = this->m_Cursor->GetPoints( );
651 points->SetPoint( 0, p0 );
652 points->SetPoint( 1, p1 );
653 points->SetPoint( 2, p2 );
654 points->SetPoint( 3, p3 );
655 points->SetPoint( 4, p4 );
656 points->SetPoint( 5, p5 );
657 points->SetPoint( 6, p6 );
658 points->SetPoint( 7, p7 );
659 this->m_Cursor->Modified( );
660 this->m_CursorMapper->Modified( );
661 this->m_CursorActor->Modified( );
665 // -------------------------------------------------------------------------
666 double cpExtensions::Visualization::ImageSliceActors::
667 GetMinWindow( ) const
669 return( this->m_WLRange[ 0 ] );
672 // -------------------------------------------------------------------------
673 double cpExtensions::Visualization::ImageSliceActors::
674 GetMaxWindow( ) const
676 return( this->m_WLRange[ 1 ] );
679 // -------------------------------------------------------------------------
680 double cpExtensions::Visualization::ImageSliceActors::
683 return( this->m_WLRange[ 2 ] );
686 // -------------------------------------------------------------------------
687 double cpExtensions::Visualization::ImageSliceActors::
690 return( this->m_WLRange[ 3 ] );
693 // -------------------------------------------------------------------------
694 double cpExtensions::Visualization::ImageSliceActors::
697 if( this->m_ImageActor.GetPointer( ) != NULL )
698 return( this->m_ImageActor->GetProperty( )->GetColorWindow( ) );
700 return( double( 0 ) );
703 // -------------------------------------------------------------------------
704 double cpExtensions::Visualization::ImageSliceActors::
707 if( this->m_ImageActor.GetPointer( ) != NULL )
708 return( this->m_ImageActor->GetProperty( )->GetColorLevel( ) );
710 return( double( 0 ) );
713 // -------------------------------------------------------------------------
714 void cpExtensions::Visualization::ImageSliceActors::
715 SetWindow( double w )
717 if( this->m_ImageActor.GetPointer( ) == NULL )
719 double v = ( w < this->m_WLRange[ 0 ] )? this->m_WLRange[ 0 ]: w;
720 v = ( v > this->m_WLRange[ 1 ] )? this->m_WLRange[ 1 ]: v;
721 this->m_ImageActor->GetProperty( )->SetColorWindow( v );
724 // -------------------------------------------------------------------------
725 void cpExtensions::Visualization::ImageSliceActors::
728 if( this->m_ImageActor.GetPointer( ) == NULL )
730 double v = ( l < this->m_WLRange[ 2 ] )? this->m_WLRange[ 2 ]: l;
731 v = ( v > this->m_WLRange[ 3 ] )? this->m_WLRange[ 3 ]: v;
732 this->m_ImageActor->GetProperty( )->SetColorLevel( v );
735 // -------------------------------------------------------------------------
736 void cpExtensions::Visualization::ImageSliceActors::
737 SetWindowLevel( double w, double l )
739 if( this->m_ImageActor.GetPointer( ) == NULL )
741 double a = ( w < this->m_WLRange[ 0 ] )? this->m_WLRange[ 0 ]: w;
742 a = ( a > this->m_WLRange[ 1 ] )? this->m_WLRange[ 1 ]: a;
743 double b = ( l < this->m_WLRange[ 2 ] )? this->m_WLRange[ 2 ]: l;
744 b = ( b > this->m_WLRange[ 3 ] )? this->m_WLRange[ 3 ]: b;
745 this->m_ImageActor->GetProperty( )->SetColorWindow( a );
746 this->m_ImageActor->GetProperty( )->SetColorLevel( b );
749 // -------------------------------------------------------------------------
750 void cpExtensions::Visualization::ImageSliceActors::
753 this->SetWindowLevel(
754 this->m_WLRange[ 1 ] * double( 0.5 ),
755 ( this->m_WLRange[ 3 ] + this->m_WLRange[ 2 ] ) * double( 0.5 )
759 // -------------------------------------------------------------------------
760 int cpExtensions::Visualization::ImageSliceActors::
763 if( this->m_ImageMapper.GetPointer( ) != NULL )
764 return( this->m_ImageMapper->GetOrientation( ) );
769 // -------------------------------------------------------------------------
770 int cpExtensions::Visualization::ImageSliceActors::
771 GetSliceNumber( ) const
773 if( this->m_ImageMapper.GetPointer( ) != NULL )
774 return( this->m_ImageMapper->GetSliceNumber( ) );
779 // -------------------------------------------------------------------------
780 int cpExtensions::Visualization::ImageSliceActors::
781 GetSliceNumberMinValue( ) const
783 if( this->m_ImageMapper.GetPointer( ) != NULL )
784 return( this->m_ImageMapper->GetSliceNumberMinValue( ) );
789 // -------------------------------------------------------------------------
790 int cpExtensions::Visualization::ImageSliceActors::
791 GetSliceNumberMaxValue( ) const
793 if( this->m_ImageMapper.GetPointer( ) != NULL )
794 return( this->m_ImageMapper->GetSliceNumberMaxValue( ) );
799 // -------------------------------------------------------------------------
800 void cpExtensions::Visualization::ImageSliceActors::
801 SetSliceNumber( const int& slice )
803 if( this->m_ImageMapper.GetPointer( ) == NULL )
806 int axis = this->GetAxis( );
807 double prev_pos = this->m_VisibleBounds[ axis << 1 ];
809 // Update mappers and display bounds
810 this->m_ImageMapper->SetSliceNumber( slice );
811 this->m_BlenderMapper->SetSliceNumber( slice );
812 this->m_ImageMapper->Modified( );
813 this->m_BlenderMapper->Modified( );
814 this->m_ImageActor->Modified( );
815 this->m_BlenderActor->Modified( );
817 // Update display extent (this isn't done automatically)
818 this->m_ImageMapper->GetInput( )->GetExtent( this->m_VisibleExtent );
819 this->m_VisibleExtent[ axis << 1 ] = slice;
820 this->m_VisibleExtent[ ( axis << 1 ) + 1 ] = slice;
821 this->m_ImageActor->SetDisplayExtent( this->m_VisibleExtent );
823 // Prepare plane data
824 this->m_ImageMapper->GetBounds( this->m_VisibleBounds );
828 this->m_VisibleBounds[ 0 ],
829 this->m_VisibleBounds[ 2 ],
830 this->m_VisibleBounds[ 4 ]
833 this->m_VisibleBounds[ 1 ],
834 this->m_VisibleBounds[ 3 ],
835 this->m_VisibleBounds[ 5 ]
840 vtkPlane* plane = this->m_ImageMapper->GetSlicePlane( );
841 plane->GeneralizedProjectPoint( x0[ 0 ], p0[ 0 ] );
842 plane->GeneralizedProjectPoint( x0[ 1 ], p0[ 1 ] );
844 this->m_VisibleBounds[ 0 ] = p0[ 0 ][ 0 ];
845 this->m_VisibleBounds[ 1 ] = p0[ 1 ][ 0 ];
846 this->m_VisibleBounds[ 2 ] = p0[ 0 ][ 1 ];
847 this->m_VisibleBounds[ 3 ] = p0[ 1 ][ 1 ];
848 this->m_VisibleBounds[ 4 ] = p0[ 0 ][ 2 ];
849 this->m_VisibleBounds[ 5 ] = p0[ 1 ][ 2 ];
850 double* bnds = this->m_VisibleBounds;
852 // Configure visualization and implicit plane orientation
854 this->m_PlaneActor->GetProperty( )->SetRepresentationToWireframe( );
855 this->m_PlaneActor->GetProperty( )->SetLineWidth( 3 );
856 vtkPoints* plane_points = this->m_Plane->GetPoints( );
857 plane_points->SetPoint( 0, bnds[ 0 ], bnds[ 2 ], bnds[ 4 ] );
858 plane_points->SetPoint( 2, bnds[ 1 ], bnds[ 3 ], bnds[ 5 ] );
859 if( axis == 0 || axis == 2 ) // YZ, x-normal
861 plane_points->SetPoint( 1, bnds[ 1 ], bnds[ 2 ], bnds[ 5 ] );
862 plane_points->SetPoint( 3, bnds[ 0 ], bnds[ 3 ], bnds[ 4 ] );
864 this->m_PlaneActor->GetProperty( )->SetColor( 1, 0, 0 );
866 this->m_PlaneActor->GetProperty( )->SetColor( 0, 0, 1 );
868 else if( axis == 1 ) // ZX, y-normal
870 plane_points->SetPoint( 1, bnds[ 0 ], bnds[ 2 ], bnds[ 5 ] );
871 plane_points->SetPoint( 3, bnds[ 1 ], bnds[ 3 ], bnds[ 4 ] );
872 this->m_PlaneActor->GetProperty( )->SetColor( 0, 1, 0 );
875 this->m_Plane->Modified( );
876 this->m_PlaneMapper->Modified( );
877 this->m_PlaneActor->Modified( );
883 // Update lines from associated slices
885 auto sIt = this->m_AssociatedSlices.begin( );
886 for( ; sIt != this->m_AssociatedSlices.end( ); ++sIt )
889 for( unsigned int id = 0; id < slice->m_AssociatedSlices.size( ); ++id )
891 std::cout << id << std::endl;
892 if( slice->m_AssociatedSlices[ id ] != this )
895 std::cout << "id : " << id << std::endl;
902 // Update camera position
903 if( this->m_Window == NULL )
905 vtkRenderer* renderer =
906 this->m_Window->GetRenderers( )->GetFirstRenderer( );
907 if( renderer == NULL )
909 vtkCamera* camera = renderer->GetActiveCamera( );
913 camera->GetPosition( cam_pos );
914 cam_pos[ axis ] += this->m_VisibleBounds[ axis << 1 ] - prev_pos;
915 camera->SetPosition( cam_pos );
918 // -------------------------------------------------------------------------
919 void cpExtensions::Visualization::ImageSliceActors::
920 SetSlice( double* pos )
922 vtkImageData* image = this->GetInputImage( );
928 image->ComputeStructuredCoordinates( pos, ijk, pcoords );
929 this->SetSliceNumber( ijk[ this->GetAxis( ) ] );
932 // -------------------------------------------------------------------------
933 void cpExtensions::Visualization::ImageSliceActors::
937 if( this->m_ImageMapper.GetPointer( ) != NULL )
940 int axId = this->m_ImageMapper->GetOrientation( );
941 if ( axId == 0 ) axis = 'X';
942 else if( axId == 1 ) axis = 'Y';
943 else if( axId == 2 ) axis = 'Z';
946 this->m_TextBuffer, "Axis: %c (%d)",
947 axis, this->m_ImageMapper->GetSliceNumber( )
951 this->m_TextBuffer[ 0 ] = '\0';
952 this->m_TextActor->SetInput( this->m_TextBuffer );
953 this->m_TextActor->Modified( );
958 // -------------------------------------------------------------------------
959 void cpExtensions::Visualization::ImageSliceActors::
960 UpdateText( double pos[ 3 ] )
963 if( this->m_ImageMapper.GetPointer( ) != NULL )
966 int axId = this->m_ImageMapper->GetOrientation( );
967 if ( axId == 0 ) axis = 'X';
968 else if( axId == 1 ) axis = 'Y';
969 else if( axId == 2 ) axis = 'Z';
970 int slice = this->GetSliceNumber( );
972 vtkImageData* image = this->GetInputImage( );
975 image->ComputeStructuredCoordinates( pos, ijk, pcoords );
979 image->GetExtent( ext );
981 ext[ 0 ] <= ijk[ 0 ] && ijk[ 0 ] <= ext[ 1 ] &&
982 ext[ 2 ] <= ijk[ 1 ] && ijk[ 1 ] <= ext[ 3 ] &&
983 ext[ 4 ] <= ijk[ 2 ] && ijk[ 2 ] <= ext[ 5 ]
986 int nScl = image->GetNumberOfScalarComponents( );
987 std::stringstream str;
991 << "," << ijk[ 2 ] << "]=(";
993 image->GetScalarComponentAsFloat( ijk[ 0 ], ijk[ 1 ], ijk[ 2 ], 0 );
994 for( int n = 1; n < nScl; ++n )
997 << image->GetScalarComponentAsFloat(
998 ijk[ 0 ], ijk[ 1 ], ijk[ 2 ], n
1002 this->m_TextBuffer, "Axis: %c (%d)\nPixel %s",
1003 axis, slice, str.str( ).c_str( )
1009 this->m_TextBuffer[ 0 ] = '\0';
1010 this->m_TextActor->SetInput( this->m_TextBuffer );
1011 this->m_TextActor->Modified( );
1016 // -------------------------------------------------------------------------
1017 void cpExtensions::Visualization::ImageSliceActors::
1018 UpdateText( const double& w, const double& l )
1021 if( this->m_ImageMapper.GetPointer( ) != NULL )
1024 int axId = this->m_ImageMapper->GetOrientation( );
1025 if ( axId == 0 ) axis = 'X';
1026 else if( axId == 1 ) axis = 'Y';
1027 else if( axId == 2 ) axis = 'Z';
1030 this->m_TextBuffer, "Axis: %c (%d)\nW/L (%.2f/%.2f)",
1031 axis, this->m_ImageMapper->GetSliceNumber( ), w, l
1035 this->m_TextBuffer[ 0 ] = '\0';
1036 this->m_TextActor->SetInput( this->m_TextBuffer );
1037 this->m_TextActor->Modified( );
1042 // -------------------------------------------------------------------------
1043 void cpExtensions::Visualization::ImageSliceActors::
1044 Render( const double& t )
1046 if( this->m_Window != NULL )
1048 vtkRenderer* renderer =
1049 this->m_Window->GetRenderers( )->GetFirstRenderer( );
1050 if( renderer != NULL )
1051 renderer->SetAllocatedRenderTime( t );
1052 this->m_Window->Render( );
1057 // -------------------------------------------------------------------------
1058 void cpExtensions::Visualization::ImageSliceActors::
1061 if( this->m_Window == NULL )
1063 vtkRenderer* renderer =
1064 this->m_Window->GetRenderers( )->GetFirstRenderer( );
1065 if( renderer != NULL )
1066 renderer->ResetCamera( this->m_VisibleBounds );
1069 // -------------------------------------------------------------------------
1070 cpExtensions::Visualization::ImageSliceActors::
1074 m_Interpolate( false )
1077 this->_ConfigureStyle( );
1080 // -------------------------------------------------------------------------
1081 cpExtensions::Visualization::ImageSliceActors::
1082 ~ImageSliceActors( )
1086 // -------------------------------------------------------------------------
1087 void cpExtensions::Visualization::ImageSliceActors::
1090 // Connect this view with a controller
1091 this->m_Style = vtkSmartPointer< TStyle >::New( );
1092 this->m_Style->AddMouseMoveCommand( Self::_MouseMoveCommand, this );
1093 this->m_Style->AddMouseClickCommand( Self::_MouseClickCommand, this );
1094 this->m_Style->AddMouseWheelCommand( Self::_MouseWheelCommand, this );
1095 this->m_Style->AddKeyCommand( Self::_KeyCommand, this );
1096 this->m_Style->AddEnterCommand( Self::_EnterCommand, this );
1097 this->m_Style->AddLeaveCommand( Self::_LeaveCommand, this );
1100 // -------------------------------------------------------------------------
1101 void cpExtensions::Visualization::ImageSliceActors::
1102 _ConfigureInputImage( )
1104 this->m_ImageMapper->SetOrientation( 0 );
1105 this->m_ImageMapper->Update( );
1108 this->m_ImageActor->SetInterpolate( this->m_Interpolate );
1109 this->m_ImageActor->Modified( );
1111 if( this->m_Style.GetPointer( ) != NULL )
1112 this->m_Style->AssociateImageActor( this->m_ImageActor );
1113 this->AddItem( this->m_ImageActor );
1115 this->SetSliceNumber( this->GetSliceNumberMinValue( ) );
1116 this->ResetCursor( );
1119 // Update window/level ranges
1120 vtkImageData* data = this->GetInputImage( );
1124 data->GetScalarRange( r );
1125 this->m_WLRange[ 0 ] = double( 0 );
1126 this->m_WLRange[ 1 ] = r[ 1 ] - r[ 0 ];
1127 this->m_WLRange[ 2 ] = r[ 0 ];
1128 this->m_WLRange[ 3 ] = r[ 1 ];
1129 this->ResetWindowLevel( );
1131 // Configure blender
1132 this->m_BlenderBase = vtkSmartPointer< vtkImageData >::New( );
1133 this->m_BlenderBase->ShallowCopy( data );
1134 this->m_BlenderBase->AllocateScalars( VTK_UNSIGNED_CHAR, 1 );
1136 this->m_BlenderBase->GetScalarPointer( ), 0,
1137 this->m_BlenderBase->GetActualMemorySize( )
1139 this->m_Blender->AddInputData( this->m_BlenderBase );
1144 // -------------------------------------------------------------------------
1145 void cpExtensions::Visualization::ImageSliceActors::
1147 void* data, const TStyle::ButtonID& btn, int* idx, double* pos,
1148 bool alt, bool ctr, bool sft
1151 ImageSliceActors* actors = reinterpret_cast< ImageSliceActors* >( data );
1152 if( actors == NULL )
1155 if( btn == TStyle::ButtonID_None )
1157 // Just show the pixel information
1158 actors->SetCursor( pos );
1159 actors->UpdateText( pos );
1160 actors->Render( 1e-3 );
1162 else if( btn == TStyle::ButtonID_Left )
1164 if( !alt && ctr && !sft )
1166 // Interactively move slices
1167 auto i = actors->m_SlicesCommands.begin( );
1168 for( ; i != actors->m_SlicesCommands.end( ); ++i )
1169 i->first( pos, actors->GetAxis( ), i->second );
1170 actors->Render( 1e-3 );
1174 else if( btn == TStyle::ButtonID_Right )
1176 if( !alt && !ctr && sft )
1178 // Change image window level
1180 actors->m_ImageMapper->GetBounds( bounds );
1182 int a0 = actors->GetAxis( );
1183 int a1 = ( a0 + 1 ) % 3;
1184 int a2 = ( a0 + 2 ) % 3;
1185 double dx = pos[ a1 ] - actors->m_StartWindowLevelPos[ a1 ];
1186 double dy = pos[ a2 ] - actors->m_StartWindowLevelPos[ a2 ];
1187 dx /= bounds[ ( a1 << 1 ) + 1 ] - bounds[ a1 << 1 ];
1188 dy /= bounds[ ( a2 << 1 ) + 1 ] - bounds[ a2 << 1 ];
1190 dx *= actors->m_StartWindowLevel[ 0 ];
1191 dy *= actors->m_StartWindowLevel[ 1 ];
1192 dx += actors->m_StartWindowLevel[ 0 ];
1193 dy += actors->m_StartWindowLevel[ 1 ];
1194 actors->SetWindowLevel( dx, dy );
1195 actors->Render( 1e-3 );
1197 // Associate objects
1198 auto i = actors->m_WindowLevelCommands.begin( );
1199 for( ; i != actors->m_WindowLevelCommands.end( ); ++i )
1200 i->first( dx, dy, i->second );
1207 // -------------------------------------------------------------------------
1208 void cpExtensions::Visualization::ImageSliceActors::
1210 void* data, const TStyle::ButtonID& btn, int* idx, double* pos,
1211 bool alt, bool ctr, bool sft
1214 ImageSliceActors* actors = reinterpret_cast< ImageSliceActors* >( data );
1215 if( actors == NULL )
1218 actors->m_StartWindowLevelPos[ 0 ] = pos[ 0 ];
1219 actors->m_StartWindowLevelPos[ 1 ] = pos[ 1 ];
1220 actors->m_StartWindowLevelPos[ 2 ] = pos[ 2 ];
1221 actors->m_StartWindowLevel[ 0 ] = actors->GetWindow( );
1222 actors->m_StartWindowLevel[ 1 ] = actors->GetLevel( );
1225 // -------------------------------------------------------------------------
1226 void cpExtensions::Visualization::ImageSliceActors::
1228 void* data, const int& dir,
1229 bool alt, bool ctr, bool sft
1232 ImageSliceActors* actors = reinterpret_cast< ImageSliceActors* >( data );
1233 if( actors == NULL )
1238 int slice = actors->GetSliceNumber( ) + ( dir * ( ( sft )? 10: 1 ) );
1239 if( slice < actors->GetSliceNumberMinValue( ) )
1240 slice = actors->GetSliceNumberMinValue( );
1241 if( slice > actors->GetSliceNumberMaxValue( ) )
1242 slice = actors->GetSliceNumberMaxValue( );
1243 actors->SetSliceNumber( slice );
1245 auto a = actors->m_AssociatedSlices.begin( );
1246 for( ; a != actors->m_AssociatedSlices.end( ); ++a )
1248 ( *a )->SetSliceNumber( slice );
1249 ( *a )->Render( 1e-3 );
1252 actors->Render( 1e-3 );
1254 // Associate objects
1255 auto i = actors->m_RenderCommands.begin( );
1256 for( ; i != actors->m_RenderCommands.end( ); ++i )
1257 i->first( i->second );
1262 // -------------------------------------------------------------------------
1263 void cpExtensions::Visualization::ImageSliceActors::
1264 _KeyCommand( void* data, const char& key )
1266 ImageSliceActors* actors = reinterpret_cast< ImageSliceActors* >( data );
1267 if( actors == NULL )
1274 actors->ResetCamera( );
1275 actors->Render( 1e-3 );
1277 // Associate objects
1278 auto i = actors->m_RenderCommands.begin( );
1279 for( ; i != actors->m_RenderCommands.end( ); ++i )
1280 i->first( i->second );
1285 actors->ResetWindowLevel( );
1286 actors->Render( 1e-3 );
1288 // Associate objects
1289 auto i = actors->m_RenderCommands.begin( );
1290 for( ; i != actors->m_RenderCommands.end( ); ++i )
1291 i->first( i->second );
1299 // -------------------------------------------------------------------------
1300 void cpExtensions::Visualization::ImageSliceActors::
1301 _EnterCommand( void* data )
1303 ImageSliceActors* actors = reinterpret_cast< ImageSliceActors* >( data );
1304 if( actors == NULL )
1307 actors->ResetCursor( );
1308 // TODO: actors->m_CursorActor->VisibilityOn( );
1309 actors->Render( 1e-3 );
1312 // -------------------------------------------------------------------------
1313 void cpExtensions::Visualization::ImageSliceActors::
1314 _LeaveCommand( void* data )
1316 ImageSliceActors* actors = reinterpret_cast< ImageSliceActors* >( data );
1317 if( actors == NULL )
1320 actors->ResetCursor( );
1321 // TODO: actors->m_CursorActor->VisibilityOff( );
1322 actors->Render( 1e-3 );