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 double cpExtensions::Visualization::ImageSliceActors::
21 m_PlaneColors[ 3 ][ 3 ] =
28 // -------------------------------------------------------------------------
29 cpExtensions::Visualization::ImageSliceActors*
30 cpExtensions::Visualization::ImageSliceActors::
33 return( new Self( ) );
36 // -------------------------------------------------------------------------
37 void cpExtensions::Visualization::ImageSliceActors::
40 this->m_ImageMapper->SetOrientation( axis );
41 this->m_BlenderMapper->SetOrientation( axis );
42 this->m_ImageMapper->Update( );
43 this->m_BlenderMapper->Update( );
44 this->SetSliceNumber( this->GetSliceNumberMinValue( ) );
45 this->m_ImageActor->Modified( );
46 this->m_BlenderActor->Modified( );
51 // -------------------------------------------------------------------------
52 void cpExtensions::Visualization::ImageSliceActors::
53 SetInputConnection( vtkAlgorithmOutput* aout )
55 // Get input vtkImageData
59 // Create mapper and actors
60 this->m_ImageMapper->SetInputConnection( aout );
61 this->_ConfigureInputImage( );
64 // -------------------------------------------------------------------------
65 void cpExtensions::Visualization::ImageSliceActors::
66 SetInputImage( vtkImageData* data )
68 // Get input vtkImageData
72 // Create mapper and actors
73 this->m_ImageMapper->SetInputData( data );
74 this->_ConfigureInputImage( );
77 // -------------------------------------------------------------------------
78 int cpExtensions::Visualization::ImageSliceActors::
80 vtkAlgorithmOutput* aout,
81 const double& r, const double& g, const double& b
86 this->m_Blender->AddInputConnection( aout );
87 this->_ConfigureBinaryImage( r, g, b );
88 return( this->m_Blender->GetNumberOfInputPorts( ) - 1 );
91 // -------------------------------------------------------------------------
92 int cpExtensions::Visualization::ImageSliceActors::
95 const double& r, const double& g, const double& b
100 this->m_Blender->AddInputData( data );
101 this->_ConfigureBinaryImage( r, g, b );
102 return( this->m_Blender->GetNumberOfInputPorts( ) - 1 );
105 // -------------------------------------------------------------------------
106 void cpExtensions::Visualization::ImageSliceActors::
109 // Unbind from container
110 this->RemoveAllItems( );
112 // Filters and mappers
113 this->m_ImageMapper = vtkSmartPointer< vtkImageSliceMapper >::New( );
114 this->m_ImageActor = vtkSmartPointer< vtkImageActor >::New( );
115 this->m_Blender = vtkSmartPointer< TBlender >::New( );
116 this->m_BlenderMapper = vtkSmartPointer< vtkImageSliceMapper >::New( );
117 this->m_BlenderLUT = vtkSmartPointer< vtkLookupTable >::New( );
118 this->m_BlenderActor = vtkSmartPointer< vtkImageActor >::New( );
120 this->m_ImageActor->SetMapper( this->m_ImageMapper );
121 this->m_BlenderMapper->
122 SetInputConnection( this->m_Blender->GetOutputPort( ) );
124 this->m_BlenderLUT->SetNumberOfTableValues( 1 );
125 this->m_BlenderLUT->SetTableRange( 0, 1 );
126 this->m_BlenderLUT->SetTableValue( 0, 0, 0, 0, 0 );
127 this->m_BlenderLUT->Build( );
129 this->m_BlenderActor->SetMapper( this->m_BlenderMapper );
130 this->m_BlenderActor->GetProperty( )->SetLookupTable( this->m_BlenderLUT );
131 this->m_BlenderActor->GetProperty( )->UseLookupTableScalarRangeOn( );
133 // Remove associated objects
134 this->m_AssociatedSlices.clear( );
137 vtkSmartPointer< vtkPoints > cursor_points =
138 vtkSmartPointer< vtkPoints >::New( );
139 vtkSmartPointer< vtkCellArray > cursor_lines =
140 vtkSmartPointer< vtkCellArray >::New( );
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_lines->InsertNextCell( 2 );
146 cursor_lines->InsertCellPoint( 0 );
147 cursor_lines->InsertCellPoint( 1 );
148 cursor_lines->InsertNextCell( 2 );
149 cursor_lines->InsertCellPoint( 2 );
150 cursor_lines->InsertCellPoint( 3 );
152 this->m_Cursor = vtkSmartPointer< vtkPolyData >::New( );
153 this->m_CursorMapper = vtkSmartPointer< vtkPolyDataMapper >::New( );
154 this->m_CursorActor = vtkSmartPointer< vtkActor >::New( );
156 this->m_Cursor->SetPoints( cursor_points );
157 this->m_Cursor->SetLines( cursor_lines );
158 this->m_CursorMapper->SetInputData( this->m_Cursor );
159 this->m_CursorActor->SetMapper( this->m_CursorMapper );
160 this->m_CursorActor->GetProperty( )->SetColor( 1, 1, 0 );
161 this->m_CursorActor->GetProperty( )->SetLineWidth( 2 );
163 // Plane intersections
164 this->m_Axis1 = vtkSmartPointer< vtkPolyData >::New( );
165 this->m_Axis1Mapper = vtkSmartPointer< vtkPolyDataMapper >::New( );
166 this->m_Axis1Actor = vtkSmartPointer< vtkActor >::New( );
168 vtkSmartPointer< vtkPoints > h_points =
169 vtkSmartPointer< vtkPoints >::New( );
170 vtkSmartPointer< vtkCellArray > h_lines =
171 vtkSmartPointer< vtkCellArray >::New( );
172 h_points->InsertNextPoint( 0, 0, 0 );
173 h_points->InsertNextPoint( 0, 0, 0 );
174 h_lines->InsertNextCell( 2 );
175 h_lines->InsertCellPoint( 0 );
176 h_lines->InsertCellPoint( 1 );
177 this->m_Axis1->SetPoints( h_points );
178 this->m_Axis1->SetLines( h_lines );
179 this->m_Axis1Mapper->SetInputData( this->m_Axis1 );
180 this->m_Axis1Actor->SetMapper( this->m_Axis1Mapper );
182 this->m_Axis2 = vtkSmartPointer< vtkPolyData >::New( );
183 this->m_Axis2Mapper = vtkSmartPointer< vtkPolyDataMapper >::New( );
184 this->m_Axis2Actor = vtkSmartPointer< vtkActor >::New( );
186 vtkSmartPointer< vtkPoints > v_points =
187 vtkSmartPointer< vtkPoints >::New( );
188 vtkSmartPointer< vtkCellArray > v_lines =
189 vtkSmartPointer< vtkCellArray >::New( );
190 v_points->InsertNextPoint( 0, 0, 0 );
191 v_points->InsertNextPoint( 0, 0, 0 );
192 v_lines->InsertNextCell( 2 );
193 v_lines->InsertCellPoint( 0 );
194 v_lines->InsertCellPoint( 1 );
195 this->m_Axis2->SetPoints( v_points );
196 this->m_Axis2->SetLines( v_lines );
197 this->m_Axis2Mapper->SetInputData( this->m_Axis2 );
198 this->m_Axis2Actor->SetMapper( this->m_Axis2Mapper );
201 this->m_Plane = vtkSmartPointer< vtkPolyData >::New( );
202 this->m_PlaneMapper = vtkSmartPointer< vtkPolyDataMapper >::New( );
203 this->m_PlaneActor = vtkSmartPointer< vtkActor >::New( );
205 vtkSmartPointer< vtkPoints > plane_points =
206 vtkSmartPointer< vtkPoints >::New( );
207 vtkSmartPointer< vtkCellArray > plane_lines =
208 vtkSmartPointer< vtkCellArray >::New( );
209 plane_points->InsertNextPoint( 0, 0, 0 );
210 plane_points->InsertNextPoint( 0, 1, 0 );
211 plane_points->InsertNextPoint( 1, 1, 0 );
212 plane_points->InsertNextPoint( 1, 0, 0 );
213 plane_lines->InsertNextCell( 5 );
214 plane_lines->InsertCellPoint( 0 );
215 plane_lines->InsertCellPoint( 1 );
216 plane_lines->InsertCellPoint( 2 );
217 plane_lines->InsertCellPoint( 3 );
218 plane_lines->InsertCellPoint( 0 );
219 this->m_Plane->SetPoints( plane_points );
220 this->m_Plane->SetLines( plane_lines );
222 this->m_PlaneMapper->SetInputData( this->m_Plane );
223 this->m_PlaneActor->SetMapper( this->m_PlaneMapper );
226 this->m_TextActor = vtkSmartPointer< vtkTextActor >::New( );
227 this->m_TextBuffer[ 0 ] = '\0';
228 this->m_TextActor->SetTextScaleModeToNone( );
229 vtkTextProperty* textprop = this->m_TextActor->GetTextProperty( );
230 textprop->SetColor( 1, 1, 0 );
231 textprop->SetFontFamilyToCourier( );
232 textprop->SetFontSize( 18 );
233 textprop->BoldOff( );
234 textprop->ItalicOff( );
235 textprop->ShadowOff( );
236 textprop->SetJustificationToLeft( );
237 textprop->SetVerticalJustificationToBottom( );
238 vtkCoordinate* coord = this->m_TextActor->GetPositionCoordinate( );
239 coord->SetCoordinateSystemToNormalizedViewport( );
240 coord->SetValue( 0.01, 0.01 );
243 // -------------------------------------------------------------------------
244 void cpExtensions::Visualization::ImageSliceActors::
245 AssociateSlice( Self* slice )
247 this->m_AssociatedSlices.push_back( slice );
251 // -------------------------------------------------------------------------
252 vtkInteractorStyle* cpExtensions::Visualization::ImageSliceActors::
255 return( this->m_Style.GetPointer( ) );
258 // -------------------------------------------------------------------------
259 const vtkInteractorStyle* cpExtensions::Visualization::ImageSliceActors::
262 return( this->m_Style.GetPointer( ) );
265 // -------------------------------------------------------------------------
266 vtkImageData* cpExtensions::Visualization::ImageSliceActors::
269 if( this->m_ImageMapper.GetPointer( ) != NULL )
270 return( this->m_ImageMapper->GetInput( ) );
275 // -------------------------------------------------------------------------
276 const vtkImageData* cpExtensions::Visualization::ImageSliceActors::
277 GetInputImage( ) const
279 if( this->m_ImageMapper.GetPointer( ) != NULL )
280 return( this->m_ImageMapper->GetInput( ) );
285 // -------------------------------------------------------------------------
286 void cpExtensions::Visualization::ImageSliceActors::
287 PushActorsInto( vtkRenderWindow* window, bool force_style )
289 this->m_Window = window;
292 vtkRenderWindowInteractor* rwi = window->GetInteractor( );
293 vtkRenderer* renderer = window->GetRenderers( )->GetFirstRenderer( );
294 if( rwi == NULL || renderer == NULL )
298 if( this->m_Style.GetPointer( ) != NULL && force_style )
299 rwi->SetInteractorStyle( this->m_Style );
302 renderer->AddViewProp( this->m_ImageActor );
303 renderer->AddViewProp( this->m_BlenderActor );
306 renderer->AddViewProp( this->m_CursorActor );
307 renderer->AddViewProp( this->m_PlaneActor );
308 renderer->AddViewProp( this->m_TextActor );
309 renderer->AddViewProp( this->m_Axis1Actor );
310 renderer->AddViewProp( this->m_Axis2Actor );
315 vtkCamera* camera = renderer->GetActiveCamera( );
316 if( camera != NULL && force_style )
318 // Parallel projections are better when displaying 2D images
319 int axis = this->GetAxis( );
320 camera->ParallelProjectionOn( );
321 camera->SetFocalPoint( double( 0 ), double( 0 ), double( 0 ) );
324 camera->SetPosition( double( 1 ), double( 0 ), double( 0 ) );
325 camera->SetViewUp ( double( 0 ), double( 0 ), double( 1 ) );
329 camera->SetPosition( double( 0 ), double( -1 ), double( 0 ) );
330 camera->SetViewUp ( double( 0 ), double( 0 ), double( 1 ) );
332 else // if( axis == 2 )
334 camera->SetPosition( double( 0 ), double( 0 ), double( 1 ) );
335 camera->SetViewUp ( double( 0 ), double( -1 ), double( 0 ) );
340 this->ResetCamera( );
344 // -------------------------------------------------------------------------
345 void cpExtensions::Visualization::ImageSliceActors::
346 PopActorsFrom( vtkRenderWindow* window )
348 vtkRenderWindowInteractor* rwi = window->GetInteractor( );
349 vtkRenderer* renderer = window->GetRenderers( )->GetFirstRenderer( );
350 if( renderer != NULL )
352 renderer->RemoveViewProp( this->m_ImageActor );
353 renderer->RemoveViewProp( this->m_BlenderActor );
354 renderer->RemoveViewProp( this->m_CursorActor );
355 renderer->RemoveViewProp( this->m_PlaneActor );
356 renderer->RemoveViewProp( this->m_TextActor );
357 renderer->RemoveViewProp( this->m_Axis1Actor );
358 renderer->RemoveViewProp( this->m_Axis2Actor );
365 // -------------------------------------------------------------------------
366 unsigned int cpExtensions::Visualization::ImageSliceActors::
367 GetNumberOfImages( ) const
369 return( this->m_Blender->GetNumberOfInputPorts( ) );
372 // -------------------------------------------------------------------------
373 vtkImageActor* cpExtensions::Visualization::ImageSliceActors::
376 return( this->m_ImageActor );
379 // -------------------------------------------------------------------------
380 const vtkImageActor* cpExtensions::Visualization::ImageSliceActors::
381 GetImageActor( ) const
383 return( this->m_ImageActor );
386 // -------------------------------------------------------------------------
387 vtkImageActor* cpExtensions::Visualization::ImageSliceActors::
390 return( this->m_BlenderActor );
393 // -------------------------------------------------------------------------
394 const vtkImageActor* cpExtensions::Visualization::ImageSliceActors::
395 GetBinaryActor( ) const
397 return( this->m_BlenderActor );
400 // -------------------------------------------------------------------------
401 vtkTextActor* cpExtensions::Visualization::ImageSliceActors::
404 return( this->m_TextActor );
407 // -------------------------------------------------------------------------
408 const vtkTextActor* cpExtensions::Visualization::ImageSliceActors::
409 GetTextActor( ) const
411 return( this->m_TextActor );
414 // -------------------------------------------------------------------------
415 vtkActor* cpExtensions::Visualization::ImageSliceActors::
418 return( this->m_PlaneActor );
421 // -------------------------------------------------------------------------
422 const vtkActor* cpExtensions::Visualization::ImageSliceActors::
423 GetPlaneActor( ) const
425 return( this->m_PlaneActor );
428 // -------------------------------------------------------------------------
429 vtkPlane* cpExtensions::Visualization::ImageSliceActors::
432 if( this->m_ImageMapper.GetPointer( ) != NULL )
433 return( this->m_ImageMapper->GetSlicePlane( ) );
438 // -------------------------------------------------------------------------
439 const vtkPlane* cpExtensions::Visualization::ImageSliceActors::
440 GetPlaneFunction( ) const
442 if( this->m_ImageMapper.GetPointer( ) != NULL )
443 return( this->m_ImageMapper->GetSlicePlane( ) );
448 // -------------------------------------------------------------------------
449 void cpExtensions::Visualization::ImageSliceActors::
450 SetInterpolate( bool v )
452 if( this->m_Interpolate != v )
454 this->m_ImageActor->SetInterpolate( v );
455 this->m_BlenderActor->SetInterpolate( v );
456 this->m_Interpolate = v;
462 // -------------------------------------------------------------------------
463 void cpExtensions::Visualization::ImageSliceActors::
466 this->SetInterpolate( true );
469 // -------------------------------------------------------------------------
470 void cpExtensions::Visualization::ImageSliceActors::
473 this->SetInterpolate( false );
476 // -------------------------------------------------------------------------
477 double* cpExtensions::Visualization::ImageSliceActors::
478 GetDisplayBounds( ) const
480 if( this->m_ImageActor.GetPointer( ) != NULL )
481 return( this->m_ImageActor->GetDisplayBounds( ) );
486 // -------------------------------------------------------------------------
487 void cpExtensions::Visualization::ImageSliceActors::
488 GetDisplayBounds( double bounds[ 6 ] ) const
490 if( this->m_ImageActor.GetPointer( ) == NULL )
492 bounds[ 0 ] = bounds[ 2 ] = bounds[ 4 ] = double( 0 );
493 bounds[ 1 ] = bounds[ 3 ] = bounds[ 5 ] = double( -1 );
496 this->m_ImageActor->GetDisplayBounds( bounds );
499 // -------------------------------------------------------------------------
500 void cpExtensions::Visualization::ImageSliceActors::
503 if( this->m_ImageMapper.GetPointer( ) != NULL )
507 this->m_VisibleBounds[ 0 ],
508 this->m_VisibleBounds[ 2 ],
509 this->m_VisibleBounds[ 4 ]
511 this->SetCursor( pos );
515 vtkPoints* points = this->m_Cursor->GetPoints( );
516 points->SetPoint( 0, 0, 0, 0 );
517 points->SetPoint( 1, 0, 0, 0 );
518 points->SetPoint( 2, 0, 0, 0 );
519 points->SetPoint( 3, 0, 0, 0 );
520 this->m_Cursor->Modified( );
521 this->m_CursorMapper->Modified( );
522 this->m_CursorActor->Modified( );
527 // -------------------------------------------------------------------------
528 void cpExtensions::Visualization::ImageSliceActors::
529 SetCursor( double pos[ 3 ] )
531 if( this->m_ImageMapper.GetPointer( ) == NULL )
535 int a0 = this->GetAxis( );
536 int a1 = ( a0 + 1 ) % 3;
537 int a2 = ( a0 + 2 ) % 3;
543 double* bounds = this->m_VisibleBounds;
544 double p0[ 3 ], p1[ 3 ], p2[ 3 ], p3[ 3 ];
546 p0[ a2 ] = p1[ a2 ] = pos[ a2 ];
547 p2[ a1 ] = p3[ a1 ] = pos[ a1 ];
548 p0[ a0 ] = p1[ a0 ] = p2[ a0 ] = p3[ a0 ] = bounds[ ma0 ];
549 p0[ a1 ] = bounds[ ma1 ];
550 p1[ a1 ] = bounds[ ma1 + 1 ];
551 p2[ a2 ] = bounds[ ma2 ];
552 p3[ a2 ] = bounds[ ma2 + 1 ];
554 vtkPoints* points = this->m_Cursor->GetPoints( );
555 points->SetPoint( 0, p0 );
556 points->SetPoint( 1, p1 );
557 points->SetPoint( 2, p2 );
558 points->SetPoint( 3, p3 );
559 this->m_Cursor->Modified( );
560 this->m_CursorMapper->Modified( );
561 this->m_CursorActor->Modified( );
564 // -------------------------------------------------------------------------
565 void cpExtensions::Visualization::ImageSliceActors::
568 if( this->m_ImageMapper.GetPointer( ) != NULL )
572 this->m_VisibleBounds[ 0 ],
573 this->m_VisibleBounds[ 2 ],
574 this->m_VisibleBounds[ 4 ]
576 this->SetAxesCursor( pos );
580 vtkPoints* points = this->m_Axis1->GetPoints( );
581 points->SetPoint( 0, 0, 0, 0 );
582 points->SetPoint( 1, 0, 0, 0 );
583 this->m_Axis1->Modified( );
584 this->m_Axis1Mapper->Modified( );
585 this->m_Axis1Actor->Modified( );
587 points = this->m_Axis2->GetPoints( );
588 points->SetPoint( 0, 0, 0, 0 );
589 points->SetPoint( 1, 0, 0, 0 );
590 this->m_Axis2->Modified( );
591 this->m_Axis2Mapper->Modified( );
592 this->m_Axis2Actor->Modified( );
597 // -------------------------------------------------------------------------
598 void cpExtensions::Visualization::ImageSliceActors::
599 SetAxesCursor( double pos[ 3 ] )
601 if( this->m_ImageMapper.GetPointer( ) == NULL )
605 int a0 = this->GetAxis( );
606 int a1 = ( a0 + 1 ) % 3;
607 int a2 = ( a0 + 2 ) % 3;
613 double* bounds = this->m_VisibleBounds;
614 double p0[ 3 ], p1[ 3 ], p2[ 3 ], p3[ 3 ];
616 p0[ a2 ] = p1[ a2 ] = pos[ a2 ];
617 p2[ a1 ] = p3[ a1 ] = pos[ a1 ];
618 p0[ a0 ] = p1[ a0 ] = p2[ a0 ] = p3[ a0 ] = bounds[ ma0 ];
619 p0[ a1 ] = bounds[ ma1 ];
620 p1[ a1 ] = bounds[ ma1 + 1 ];
621 p2[ a2 ] = bounds[ ma2 ];
622 p3[ a2 ] = bounds[ ma2 + 1 ];
624 vtkPoints* points1 = this->m_Axis1->GetPoints( );
625 points1->SetPoint( 0, p2 );
626 points1->SetPoint( 1, p3 );
628 vtkPoints* points2 = this->m_Axis2->GetPoints( );
629 points2->SetPoint( 0, p0 );
630 points2->SetPoint( 1, p1 );
632 this->m_Axis1->Modified( );
633 this->m_Axis1Mapper->Modified( );
634 this->m_Axis1Actor->Modified( );
636 this->m_Axis2->Modified( );
637 this->m_Axis2Mapper->Modified( );
638 this->m_Axis2Actor->Modified( );
641 // -------------------------------------------------------------------------
642 double cpExtensions::Visualization::ImageSliceActors::
643 GetMinWindow( ) const
645 return( this->m_WLRange[ 0 ] );
648 // -------------------------------------------------------------------------
649 double cpExtensions::Visualization::ImageSliceActors::
650 GetMaxWindow( ) const
652 return( this->m_WLRange[ 1 ] );
655 // -------------------------------------------------------------------------
656 double cpExtensions::Visualization::ImageSliceActors::
659 return( this->m_WLRange[ 2 ] );
662 // -------------------------------------------------------------------------
663 double cpExtensions::Visualization::ImageSliceActors::
666 return( this->m_WLRange[ 3 ] );
669 // -------------------------------------------------------------------------
670 double cpExtensions::Visualization::ImageSliceActors::
673 if( this->m_ImageActor.GetPointer( ) != NULL )
674 return( this->m_ImageActor->GetProperty( )->GetColorWindow( ) );
676 return( double( 0 ) );
679 // -------------------------------------------------------------------------
680 double cpExtensions::Visualization::ImageSliceActors::
683 if( this->m_ImageActor.GetPointer( ) != NULL )
684 return( this->m_ImageActor->GetProperty( )->GetColorLevel( ) );
686 return( double( 0 ) );
689 // -------------------------------------------------------------------------
690 void cpExtensions::Visualization::ImageSliceActors::
691 SetWindow( double w )
693 if( this->m_ImageActor.GetPointer( ) == NULL )
695 double v = ( w < this->m_WLRange[ 0 ] )? this->m_WLRange[ 0 ]: w;
696 v = ( v > this->m_WLRange[ 1 ] )? this->m_WLRange[ 1 ]: v;
697 this->m_ImageActor->GetProperty( )->SetColorWindow( v );
700 // -------------------------------------------------------------------------
701 void cpExtensions::Visualization::ImageSliceActors::
704 if( this->m_ImageActor.GetPointer( ) == NULL )
706 double v = ( l < this->m_WLRange[ 2 ] )? this->m_WLRange[ 2 ]: l;
707 v = ( v > this->m_WLRange[ 3 ] )? this->m_WLRange[ 3 ]: v;
708 this->m_ImageActor->GetProperty( )->SetColorLevel( v );
711 // -------------------------------------------------------------------------
712 void cpExtensions::Visualization::ImageSliceActors::
713 SetWindowLevel( double w, double l )
715 if( this->m_ImageActor.GetPointer( ) == NULL )
717 double a = ( w < this->m_WLRange[ 0 ] )? this->m_WLRange[ 0 ]: w;
718 a = ( a > this->m_WLRange[ 1 ] )? this->m_WLRange[ 1 ]: a;
719 double b = ( l < this->m_WLRange[ 2 ] )? this->m_WLRange[ 2 ]: l;
720 b = ( b > this->m_WLRange[ 3 ] )? this->m_WLRange[ 3 ]: b;
721 this->m_ImageActor->GetProperty( )->SetColorWindow( a );
722 this->m_ImageActor->GetProperty( )->SetColorLevel( b );
723 this->UpdateText( a, b );
726 // -------------------------------------------------------------------------
727 void cpExtensions::Visualization::ImageSliceActors::
730 this->SetWindowLevel(
731 this->m_WLRange[ 1 ] * double( 0.5 ),
732 ( this->m_WLRange[ 3 ] + this->m_WLRange[ 2 ] ) * double( 0.5 )
736 // -------------------------------------------------------------------------
737 int cpExtensions::Visualization::ImageSliceActors::
740 if( this->m_ImageMapper.GetPointer( ) != NULL )
741 return( this->m_ImageMapper->GetOrientation( ) );
746 // -------------------------------------------------------------------------
747 int cpExtensions::Visualization::ImageSliceActors::
748 GetSliceNumber( ) const
750 if( this->m_ImageMapper.GetPointer( ) != NULL )
751 return( this->m_ImageMapper->GetSliceNumber( ) );
756 // -------------------------------------------------------------------------
757 int cpExtensions::Visualization::ImageSliceActors::
758 GetSliceNumberMinValue( ) const
760 if( this->m_ImageMapper.GetPointer( ) != NULL )
761 return( this->m_ImageMapper->GetSliceNumberMinValue( ) );
766 // -------------------------------------------------------------------------
767 int cpExtensions::Visualization::ImageSliceActors::
768 GetSliceNumberMaxValue( ) const
770 if( this->m_ImageMapper.GetPointer( ) != NULL )
771 return( this->m_ImageMapper->GetSliceNumberMaxValue( ) );
776 // -------------------------------------------------------------------------
777 void cpExtensions::Visualization::ImageSliceActors::
778 SetSliceNumber( const int& slice )
780 if( this->m_ImageMapper.GetPointer( ) == NULL )
783 int axis = this->GetAxis( );
784 double prev_pos = this->m_VisibleBounds[ axis << 1 ];
786 // Update mappers and display bounds
787 this->m_ImageMapper->SetSliceNumber( slice );
788 this->m_BlenderMapper->SetSliceNumber( slice );
789 this->m_ImageMapper->Modified( );
790 this->m_BlenderMapper->Modified( );
791 this->m_ImageActor->Modified( );
792 this->m_BlenderActor->Modified( );
794 // Update display extent (this isn't done automatically)
795 this->m_ImageMapper->GetInput( )->GetExtent( this->m_VisibleExtent );
796 this->m_VisibleExtent[ axis << 1 ] = slice;
797 this->m_VisibleExtent[ ( axis << 1 ) + 1 ] = slice;
798 this->m_ImageActor->SetDisplayExtent( this->m_VisibleExtent );
800 // Prepare plane data
801 this->m_ImageMapper->GetBounds( this->m_VisibleBounds );
805 this->m_VisibleBounds[ 0 ],
806 this->m_VisibleBounds[ 2 ],
807 this->m_VisibleBounds[ 4 ]
810 this->m_VisibleBounds[ 1 ],
811 this->m_VisibleBounds[ 3 ],
812 this->m_VisibleBounds[ 5 ]
817 vtkPlane* plane = this->m_ImageMapper->GetSlicePlane( );
818 plane->GeneralizedProjectPoint( x0[ 0 ], p0[ 0 ] );
819 plane->GeneralizedProjectPoint( x0[ 1 ], p0[ 1 ] );
821 this->m_VisibleBounds[ 0 ] = p0[ 0 ][ 0 ];
822 this->m_VisibleBounds[ 1 ] = p0[ 1 ][ 0 ];
823 this->m_VisibleBounds[ 2 ] = p0[ 0 ][ 1 ];
824 this->m_VisibleBounds[ 3 ] = p0[ 1 ][ 1 ];
825 this->m_VisibleBounds[ 4 ] = p0[ 0 ][ 2 ];
826 this->m_VisibleBounds[ 5 ] = p0[ 1 ][ 2 ];
827 double* bnds = this->m_VisibleBounds;
829 // Configure visualization and implicit plane orientation
830 this->m_PlaneActor->GetProperty( )->SetRepresentationToWireframe( );
831 this->m_PlaneActor->GetProperty( )->SetLineWidth( 3 );
832 vtkPoints* plane_points = this->m_Plane->GetPoints( );
833 plane_points->SetPoint( 0, bnds[ 0 ], bnds[ 2 ], bnds[ 4 ] );
834 plane_points->SetPoint( 2, bnds[ 1 ], bnds[ 3 ], bnds[ 5 ] );
835 if( axis == 0 || axis == 2 ) // YZ, x-normal
837 plane_points->SetPoint( 1, bnds[ 1 ], bnds[ 2 ], bnds[ 5 ] );
838 plane_points->SetPoint( 3, bnds[ 0 ], bnds[ 3 ], bnds[ 4 ] );
840 else if( axis == 1 ) // ZX, y-normal
842 plane_points->SetPoint( 1, bnds[ 0 ], bnds[ 2 ], bnds[ 5 ] );
843 plane_points->SetPoint( 3, bnds[ 1 ], bnds[ 3 ], bnds[ 4 ] );
848 this->m_PlaneActor->GetProperty( )->
849 SetColor( this->m_PlaneColors[ axis ] );
850 this->m_Axis1Actor->GetProperty( )->
851 SetColor( this->m_PlaneColors[ ( axis + 1 ) % 3 ] );
852 this->m_Axis2Actor->GetProperty( )->
853 SetColor( this->m_PlaneColors[ ( axis + 2 ) % 3 ] );
855 this->m_Plane->Modified( );
856 this->m_PlaneMapper->Modified( );
857 this->m_PlaneActor->Modified( );
859 this->m_Axis1->Modified( );
860 this->m_Axis1Mapper->Modified( );
861 this->m_Axis1Actor->Modified( );
863 this->m_Axis2->Modified( );
864 this->m_Axis2Mapper->Modified( );
865 this->m_Axis2Actor->Modified( );
870 // Update lines from associated slices
872 auto sIt = this->m_AssociatedSlices.begin( );
873 for( ; sIt != this->m_AssociatedSlices.end( ); ++sIt )
876 for( unsigned int id = 0; id < slice->m_AssociatedSlices.size( ); ++id )
878 std::cout << id << std::endl;
879 if( slice->m_AssociatedSlices[ id ] != this )
882 std::cout << "id : " << id << std::endl;
889 // Update camera position
890 if( this->m_Window == NULL )
892 vtkRenderer* renderer =
893 this->m_Window->GetRenderers( )->GetFirstRenderer( );
894 if( renderer == NULL )
896 vtkCamera* camera = renderer->GetActiveCamera( );
900 camera->GetPosition( cam_pos );
901 cam_pos[ axis ] += this->m_VisibleBounds[ axis << 1 ] - prev_pos;
902 camera->SetPosition( cam_pos );
905 // -------------------------------------------------------------------------
906 void cpExtensions::Visualization::ImageSliceActors::
907 SetSlice( double* pos )
909 vtkImageData* image = this->GetInputImage( );
915 image->ComputeStructuredCoordinates( pos, ijk, pcoords );
916 this->SetSliceNumber( ijk[ this->GetAxis( ) ] );
919 // -------------------------------------------------------------------------
920 void cpExtensions::Visualization::ImageSliceActors::
923 if( this->m_ImageMapper.GetPointer( ) != NULL )
926 int axId = this->m_ImageMapper->GetOrientation( );
927 if ( axId == 0 ) axis = 'X';
928 else if( axId == 1 ) axis = 'Y';
929 else if( axId == 2 ) axis = 'Z';
932 this->m_TextBuffer, "Axis: %c (%d)",
933 axis, this->m_ImageMapper->GetSliceNumber( )
937 this->m_TextBuffer[ 0 ] = '\0';
938 this->m_TextActor->SetInput( this->m_TextBuffer );
939 this->m_TextActor->Modified( );
943 // -------------------------------------------------------------------------
944 void cpExtensions::Visualization::ImageSliceActors::
945 UpdateText( double pos[ 3 ] )
947 if( this->m_ImageMapper.GetPointer( ) != NULL )
950 int axId = this->m_ImageMapper->GetOrientation( );
951 if ( axId == 0 ) axis = 'X';
952 else if( axId == 1 ) axis = 'Y';
953 else if( axId == 2 ) axis = 'Z';
954 int slice = this->GetSliceNumber( );
956 vtkImageData* image = this->GetInputImage( );
959 image->ComputeStructuredCoordinates( pos, ijk, pcoords );
963 image->GetExtent( ext );
965 ext[ 0 ] <= ijk[ 0 ] && ijk[ 0 ] <= ext[ 1 ] &&
966 ext[ 2 ] <= ijk[ 1 ] && ijk[ 1 ] <= ext[ 3 ] &&
967 ext[ 4 ] <= ijk[ 2 ] && ijk[ 2 ] <= ext[ 5 ]
970 int nScl = image->GetNumberOfScalarComponents( );
971 std::stringstream str;
975 << "," << ijk[ 2 ] << "]=(";
977 image->GetScalarComponentAsFloat( ijk[ 0 ], ijk[ 1 ], ijk[ 2 ], 0 );
978 for( int n = 1; n < nScl; ++n )
981 << image->GetScalarComponentAsFloat(
982 ijk[ 0 ], ijk[ 1 ], ijk[ 2 ], n
986 this->m_TextBuffer, "Axis: %c (%d)\nPixel %s",
987 axis, slice, str.str( ).c_str( )
993 this->m_TextBuffer[ 0 ] = '\0';
994 this->m_TextActor->SetInput( this->m_TextBuffer );
995 this->m_TextActor->Modified( );
999 // -------------------------------------------------------------------------
1000 void cpExtensions::Visualization::ImageSliceActors::
1001 UpdateText( const double& w, const double& l )
1003 if( this->m_ImageMapper.GetPointer( ) != NULL )
1006 int axId = this->m_ImageMapper->GetOrientation( );
1007 if ( axId == 0 ) axis = 'X';
1008 else if( axId == 1 ) axis = 'Y';
1009 else if( axId == 2 ) axis = 'Z';
1012 this->m_TextBuffer, "Axis: %c (%d)\nW/L (%.2f/%.2f)",
1013 axis, this->m_ImageMapper->GetSliceNumber( ), w, l
1017 this->m_TextBuffer[ 0 ] = '\0';
1018 this->m_TextActor->SetInput( this->m_TextBuffer );
1019 this->m_TextActor->Modified( );
1023 // -------------------------------------------------------------------------
1024 void cpExtensions::Visualization::ImageSliceActors::
1025 Render( const double& t )
1027 if( this->m_Window != NULL )
1029 vtkRenderer* renderer =
1030 this->m_Window->GetRenderers( )->GetFirstRenderer( );
1031 if( renderer != NULL )
1032 renderer->SetAllocatedRenderTime( t );
1033 this->m_Window->Render( );
1038 // -------------------------------------------------------------------------
1039 void cpExtensions::Visualization::ImageSliceActors::
1042 if( this->m_Window == NULL )
1044 vtkRenderer* renderer =
1045 this->m_Window->GetRenderers( )->GetFirstRenderer( );
1046 if( renderer != NULL )
1047 renderer->ResetCamera( this->m_VisibleBounds );
1050 // -------------------------------------------------------------------------
1051 cpExtensions::Visualization::ImageSliceActors::
1055 m_Interpolate( false )
1058 this->_ConfigureStyle( );
1061 // -------------------------------------------------------------------------
1062 cpExtensions::Visualization::ImageSliceActors::
1063 ~ImageSliceActors( )
1067 // -------------------------------------------------------------------------
1068 void cpExtensions::Visualization::ImageSliceActors::
1071 // Connect this view with a controller
1072 this->m_Style = vtkSmartPointer< TStyle >::New( );
1073 this->m_Style->AddMouseMoveCommand( Self::_MouseMoveCommand, this );
1074 this->m_Style->AddMouseClickCommand( Self::_MouseClickCommand, this );
1075 this->m_Style->AddMouseWheelCommand( Self::_MouseWheelCommand, this );
1076 this->m_Style->AddKeyCommand( Self::_KeyCommand, this );
1077 this->m_Style->AddEnterCommand( Self::_EnterCommand, this );
1078 this->m_Style->AddLeaveCommand( Self::_LeaveCommand, this );
1081 // -------------------------------------------------------------------------
1082 void cpExtensions::Visualization::ImageSliceActors::
1083 _ConfigureInputImage( )
1085 this->m_ImageMapper->SetOrientation( 0 );
1086 this->m_ImageMapper->Update( );
1089 this->m_ImageActor->SetInterpolate( this->m_Interpolate );
1090 this->m_ImageActor->Modified( );
1092 if( this->m_Style.GetPointer( ) != NULL )
1093 this->m_Style->AssociateImageActor( this->m_ImageActor );
1094 this->AddItem( this->m_ImageActor );
1096 this->SetSliceNumber( this->GetSliceNumberMinValue( ) );
1097 this->ResetCursor( );
1101 this->ResetCursor( );
1102 this->ResetAxesCursor( );
1104 // Update window/level ranges
1105 vtkImageData* data = this->GetInputImage( );
1109 data->GetScalarRange( r );
1110 this->m_WLRange[ 0 ] = double( 0 );
1111 this->m_WLRange[ 1 ] = r[ 1 ] - r[ 0 ];
1112 this->m_WLRange[ 2 ] = r[ 0 ];
1113 this->m_WLRange[ 3 ] = r[ 1 ];
1114 this->ResetWindowLevel( );
1116 // Configure blender
1117 this->m_BlenderBase = vtkSmartPointer< vtkImageData >::New( );
1118 this->m_BlenderBase->ShallowCopy( data );
1119 this->m_BlenderBase->AllocateScalars( VTK_UNSIGNED_CHAR, 1 );
1121 this->m_BlenderBase->GetScalarPointer( ), 0,
1122 this->m_BlenderBase->GetActualMemorySize( )
1124 this->m_Blender->AddInputData( this->m_BlenderBase );
1129 // -------------------------------------------------------------------------
1130 void cpExtensions::Visualization::ImageSliceActors::
1131 _ConfigureBinaryImage( const double& r, const double& g, const double& b )
1133 unsigned int nValues = this->m_BlenderLUT->GetNumberOfTableValues( );
1134 this->m_BlenderLUT->SetNumberOfTableValues( nValues + 1 );
1135 this->m_BlenderLUT->SetTableRange( 0, nValues );
1136 this->m_BlenderLUT->SetTableValue( nValues, r, g, b, 0.5 );
1137 this->m_BlenderLUT->Build( );
1139 this->m_BlenderLUT->Modified( );
1140 this->m_Blender->Modified( );
1141 this->m_Blender->Update( );
1143 this->m_BlenderMapper->Modified( );
1144 this->m_BlenderActor->Modified( );
1147 // -------------------------------------------------------------------------
1148 void cpExtensions::Visualization::ImageSliceActors::
1150 void* data, const TStyle::ButtonID& btn, int* idx, double* pos,
1151 bool alt, bool ctr, bool sft
1154 ImageSliceActors* actors = reinterpret_cast< ImageSliceActors* >( data );
1155 if( actors == NULL )
1158 if( btn == TStyle::ButtonID_None )
1160 // Just show the pixel information
1161 actors->SetCursor( pos );
1162 actors->UpdateText( pos );
1163 actors->Render( 1e-3 );
1165 else if( btn == TStyle::ButtonID_Left )
1167 if( !alt && ctr && !sft )
1169 // Show axes in current renderer
1170 actors->SetAxesCursor( pos );
1172 // Interactively move slices
1173 auto i = actors->m_SlicesCommands.begin( );
1174 for( ; i != actors->m_SlicesCommands.end( ); ++i )
1175 i->first( pos, actors->GetAxis( ), i->second );
1176 actors->Render( 1e-3 );
1180 else if( btn == TStyle::ButtonID_Right )
1182 if( !alt && !ctr && sft )
1184 // Change image window level
1186 actors->m_ImageMapper->GetBounds( bounds );
1188 int a0 = actors->GetAxis( );
1189 int a1 = ( a0 + 1 ) % 3;
1190 int a2 = ( a0 + 2 ) % 3;
1191 double dx = pos[ a1 ] - actors->m_StartWindowLevelPos[ a1 ];
1192 double dy = pos[ a2 ] - actors->m_StartWindowLevelPos[ a2 ];
1193 dx /= bounds[ ( a1 << 1 ) + 1 ] - bounds[ a1 << 1 ];
1194 dy /= bounds[ ( a2 << 1 ) + 1 ] - bounds[ a2 << 1 ];
1196 dx *= actors->m_StartWindowLevel[ 0 ];
1197 dy *= actors->m_StartWindowLevel[ 1 ];
1198 dx += actors->m_StartWindowLevel[ 0 ];
1199 dy += actors->m_StartWindowLevel[ 1 ];
1200 actors->SetWindowLevel( dx, dy );
1201 actors->Render( 1e-3 );
1203 // Associate objects
1204 auto i = actors->m_WindowLevelCommands.begin( );
1205 for( ; i != actors->m_WindowLevelCommands.end( ); ++i )
1206 i->first( dx, dy, i->second );
1213 // -------------------------------------------------------------------------
1214 void cpExtensions::Visualization::ImageSliceActors::
1216 void* data, const TStyle::ButtonID& btn, int* idx, double* pos,
1217 bool alt, bool ctr, bool sft
1220 ImageSliceActors* actors = reinterpret_cast< ImageSliceActors* >( data );
1221 if( actors == NULL )
1224 actors->m_StartWindowLevelPos[ 0 ] = pos[ 0 ];
1225 actors->m_StartWindowLevelPos[ 1 ] = pos[ 1 ];
1226 actors->m_StartWindowLevelPos[ 2 ] = pos[ 2 ];
1227 actors->m_StartWindowLevel[ 0 ] = actors->GetWindow( );
1228 actors->m_StartWindowLevel[ 1 ] = actors->GetLevel( );
1231 // -------------------------------------------------------------------------
1232 void cpExtensions::Visualization::ImageSliceActors::
1234 void* data, const int& dir,
1235 bool alt, bool ctr, bool sft
1238 ImageSliceActors* actors = reinterpret_cast< ImageSliceActors* >( data );
1239 if( actors == NULL )
1244 int slice = actors->GetSliceNumber( ) + ( dir * ( ( sft )? 10: 1 ) );
1245 if( slice < actors->GetSliceNumberMinValue( ) )
1246 slice = actors->GetSliceNumberMinValue( );
1247 if( slice > actors->GetSliceNumberMaxValue( ) )
1248 slice = actors->GetSliceNumberMaxValue( );
1249 actors->SetSliceNumber( slice );
1251 auto a = actors->m_AssociatedSlices.begin( );
1252 for( ; a != actors->m_AssociatedSlices.end( ); ++a )
1254 ( *a )->SetSliceNumber( slice );
1255 ( *a )->Render( 1e-3 );
1258 actors->Render( 1e-3 );
1260 // Associate objects
1261 auto i = actors->m_RenderCommands.begin( );
1262 for( ; i != actors->m_RenderCommands.end( ); ++i )
1263 i->first( i->second );
1268 // -------------------------------------------------------------------------
1269 void cpExtensions::Visualization::ImageSliceActors::
1270 _KeyCommand( void* data, const char& key )
1272 ImageSliceActors* actors = reinterpret_cast< ImageSliceActors* >( data );
1273 if( actors == NULL )
1280 actors->ResetCamera( );
1281 actors->Render( 1e-3 );
1283 // Associate objects
1284 auto i = actors->m_RenderCommands.begin( );
1285 for( ; i != actors->m_RenderCommands.end( ); ++i )
1286 i->first( i->second );
1291 actors->ResetWindowLevel( );
1292 actors->Render( 1e-3 );
1294 // Associate objects
1295 auto i = actors->m_RenderCommands.begin( );
1296 for( ; i != actors->m_RenderCommands.end( ); ++i )
1297 i->first( i->second );
1305 // -------------------------------------------------------------------------
1306 void cpExtensions::Visualization::ImageSliceActors::
1307 _EnterCommand( void* data )
1309 ImageSliceActors* actors = reinterpret_cast< ImageSliceActors* >( data );
1310 if( actors == NULL )
1313 actors->ResetCursor( );
1314 actors->m_CursorActor->VisibilityOn( );
1315 actors->Render( 1e-3 );
1318 // -------------------------------------------------------------------------
1319 void cpExtensions::Visualization::ImageSliceActors::
1320 _LeaveCommand( void* data )
1322 ImageSliceActors* actors = reinterpret_cast< ImageSliceActors* >( data );
1323 if( actors == NULL )
1326 actors->ResetCursor( );
1327 actors->m_CursorActor->VisibilityOff( );
1328 actors->Render( 1e-3 );