1 #include <cpExtensions/Visualization/ImageSliceActors.h>
6 #include <vtkAlgorithmOutput.h>
8 #include <vtkCellArray.h>
9 #include <vtkImageData.h>
10 #include <vtkInformation.h>
12 #include <vtkPoints.h>
13 #include <vtkProperty.h>
14 #include <vtkRenderer.h>
15 #include <vtkRendererCollection.h>
16 #include <vtkRenderWindow.h>
17 #include <vtkRenderWindowInteractor.h>
18 #include <vtkStreamingDemandDrivenPipeline.h>
19 #include <vtkTextProperty.h>
20 #include <vtkWindowLevelLookupTable.h>
22 // -------------------------------------------------------------------------
23 cpExtensions::Visualization::ImageSliceActors*
24 cpExtensions::Visualization::ImageSliceActors::
27 return( new Self( ) );
30 // -------------------------------------------------------------------------
31 void cpExtensions::Visualization::ImageSliceActors::
32 AddInputConnection( vtkAlgorithmOutput* aout, int axis, LUTType lut )
34 vtkImageData* data = dynamic_cast< vtkImageData* >(
35 aout->GetProducer( )->GetOutputDataObject( aout->GetIndex( ) )
40 vtkImageMapToColors* new_map =
41 dynamic_cast< vtkImageMapToColors* >( aout->GetProducer( ) );
45 this->_ConfigureNewLUT( data, lut );
46 new_map = *( this->ImageMaps.rbegin( ) );
49 new_map->SetInputConnection( aout );
55 this->ImageMaps.push_back( new_map );
57 // Create mapper and actors
58 vtkSmartPointer< vtkImageSliceMapper > mapper =
59 vtkSmartPointer< vtkImageSliceMapper >::New( );
61 mapper->SetInputConnection( new_map->GetOutputPort( ) );
63 mapper->SetInputConnection( aout );
64 this->SliceMappers.push_back( mapper );
65 this->_ConfigureNewInput( axis );
68 // -------------------------------------------------------------------------
69 void cpExtensions::Visualization::ImageSliceActors::
70 AddInputData( vtkImageData* data, int axis, LUTType lut )
73 this->_ConfigureNewLUT( data, lut );
74 vtkImageMapToColors* new_map = *( this->ImageMaps.rbegin( ) );
77 new_map->SetInputData( data );
82 // Create mapper and actors
83 vtkSmartPointer< vtkImageSliceMapper > mapper =
84 vtkSmartPointer< vtkImageSliceMapper >::New( );
86 mapper->SetInputConnection( new_map->GetOutputPort( ) );
88 mapper->SetInputData( data );
89 this->SliceMappers.push_back( mapper );
90 this->_ConfigureNewInput( axis );
93 // -------------------------------------------------------------------------
94 void cpExtensions::Visualization::ImageSliceActors::
97 // Unbind from container
98 this->RemoveAllItems( );
101 this->ImageMaps.clear( );
102 this->SliceMappers.clear( );
103 this->ImageActors.clear( );
104 this->AssociatedActors.clear( );
106 // Reconfigure unique objects
107 this->Cursor = vtkSmartPointer< vtkPolyData >::New( );
108 this->CursorMapper = vtkSmartPointer< vtkPolyDataMapper >::New( );
109 this->CursorActor = vtkSmartPointer< vtkActor >::New( );
110 this->PlaneFunction = vtkSmartPointer< vtkPlane >::New( );
111 this->PlaneSource = vtkSmartPointer< vtkPolyData >::New( );
112 this->PlaneMapper = vtkSmartPointer< vtkPolyDataMapper >::New( );
113 this->TextActor = vtkSmartPointer< vtkTextActor >::New( );
114 this->PlaneActor = vtkSmartPointer< vtkActor >::New( );
115 this->TextBuffer[ 0 ] = '\0';
117 // Unique objects configuration
118 vtkSmartPointer< vtkPoints > cursor_points =
119 vtkSmartPointer< vtkPoints >::New( );
120 vtkSmartPointer< vtkCellArray > cursor_lines =
121 vtkSmartPointer< vtkCellArray >::New( );
122 cursor_points->InsertNextPoint( 0, 0, 0 );
123 cursor_points->InsertNextPoint( 0, 0, 0 );
124 cursor_points->InsertNextPoint( 0, 0, 0 );
125 cursor_points->InsertNextPoint( 0, 0, 0 );
126 cursor_points->InsertNextPoint( 0, 0, 0 );
127 cursor_points->InsertNextPoint( 0, 0, 0 );
128 cursor_points->InsertNextPoint( 0, 0, 0 );
129 cursor_points->InsertNextPoint( 0, 0, 0 );
130 cursor_lines->InsertNextCell( 2 );
131 cursor_lines->InsertCellPoint( 0 );
132 cursor_lines->InsertCellPoint( 1 );
133 cursor_lines->InsertNextCell( 2 );
134 cursor_lines->InsertCellPoint( 2 );
135 cursor_lines->InsertCellPoint( 3 );
136 cursor_lines->InsertNextCell( 2 );
137 cursor_lines->InsertCellPoint( 4 );
138 cursor_lines->InsertCellPoint( 5 );
139 cursor_lines->InsertNextCell( 2 );
140 cursor_lines->InsertCellPoint( 6 );
141 cursor_lines->InsertCellPoint( 7 );
142 this->Cursor->SetPoints( cursor_points );
143 this->Cursor->SetLines( cursor_lines );
144 this->CursorMapper->SetInputData( this->Cursor );
145 this->CursorActor->SetMapper( this->CursorMapper );
147 vtkSmartPointer< vtkPoints > plane_points =
148 vtkSmartPointer< vtkPoints >::New( );
149 vtkSmartPointer< vtkCellArray > plane_lines =
150 vtkSmartPointer< vtkCellArray >::New( );
152 plane_points->InsertNextPoint( 0, 0, 0 );
153 plane_points->InsertNextPoint( 0, 1, 0 );
154 plane_points->InsertNextPoint( 1, 1, 0 );
155 plane_points->InsertNextPoint( 1, 0, 0 );
156 plane_lines->InsertNextCell( 5 );
157 plane_lines->InsertCellPoint( 0 );
158 plane_lines->InsertCellPoint( 1 );
159 plane_lines->InsertCellPoint( 2 );
160 plane_lines->InsertCellPoint( 3 );
161 plane_lines->InsertCellPoint( 0 );
162 this->PlaneSource->SetPoints( plane_points );
163 this->PlaneSource->SetLines( plane_lines );
165 this->PlaneMapper->SetInputData( this->PlaneSource );
166 this->PlaneActor->SetMapper( this->PlaneMapper );
168 this->TextActor->SetTextScaleModeToNone( );
169 vtkTextProperty* textprop = this->TextActor->GetTextProperty( );
170 textprop->SetColor( 1, 1, 1 );
171 textprop->SetFontFamilyToCourier( );
172 textprop->SetFontSize( 18 );
173 textprop->BoldOff( );
174 textprop->ItalicOff( );
175 textprop->ShadowOff( );
176 textprop->SetJustificationToLeft( );
177 textprop->SetVerticalJustificationToBottom( );
178 vtkCoordinate* coord = this->TextActor->GetPositionCoordinate( );
179 coord->SetCoordinateSystemToNormalizedViewport( );
180 coord->SetValue( 0.01, 0.01 );
183 // -------------------------------------------------------------------------
184 vtkInteractorStyle* cpExtensions::Visualization::ImageSliceActors::
187 return( this->Style.GetPointer( ) );
190 // -------------------------------------------------------------------------
191 const vtkInteractorStyle* cpExtensions::Visualization::ImageSliceActors::
194 return( this->Style.GetPointer( ) );
197 // -------------------------------------------------------------------------
198 void cpExtensions::Visualization::ImageSliceActors::
199 PushActorsInto( vtkRenderWindow* window, bool force_style )
201 vtkRenderWindowInteractor* rwi = window->GetInteractor( );
202 vtkRenderer* renderer = window->GetRenderers( )->GetFirstRenderer( );
205 if( rwi != NULL && force_style )
207 if( rwi->GetInteractorStyle( ) != this->Style.GetPointer( ) )
209 rwi->SetInteractorStyle( this->Style );
215 if( renderer != NULL )
218 unsigned int N = this->GetNumberOfImageActors( );
219 for( unsigned int n = 0; n < N; ++n )
220 renderer->AddActor( this->GetImageActor( n ) );
221 renderer->AddActor( this->CursorActor );
222 renderer->AddActor( this->PlaneActor );
223 renderer->AddActor( this->TextActor );
224 renderer->Modified( );
227 vtkCamera* camera = renderer->GetActiveCamera( );
231 // Parallel projections are better when displaying 2D images
234 int axis = this->GetAxis( );
235 camera->ParallelProjectionOn( );
236 camera->SetFocalPoint( double( 0 ), double( 0 ), double( 0 ) );
239 camera->SetPosition( double( 1 ), double( 0 ), double( 0 ) );
240 camera->SetViewUp ( double( 0 ), double( 1 ), double( 0 ) );
244 camera->SetPosition( double( 0 ), double( 1 ), double( 0 ) );
245 camera->SetViewUp ( double( 0 ), double( 0 ), double( -1 ) );
247 else // if( axis == 2 )
249 camera->SetPosition( double( 0 ), double( 0 ), double( 1 ) );
250 camera->SetViewUp ( double( 0 ), double( 1 ), double( 0 ) );
255 renderer->ResetCamera( );
261 // -------------------------------------------------------------------------
262 void cpExtensions::Visualization::ImageSliceActors::
263 PopActorsFrom( vtkRenderWindow* window )
265 vtkRenderWindowInteractor* rwi = window->GetInteractor( );
266 vtkRenderer* renderer = window->GetRenderers( )->GetFirstRenderer( );
268 if( renderer != NULL )
271 unsigned int N = this->GetNumberOfImageActors( );
272 for( unsigned int n = 0; n < N; ++n )
273 renderer->RemoveActor( this->GetImageActor( n ) );
274 renderer->RemoveActor( this->CursorActor );
275 renderer->RemoveActor( this->PlaneActor );
276 renderer->RemoveActor( this->TextActor );
277 renderer->Modified( );
282 // -------------------------------------------------------------------------
283 unsigned int cpExtensions::Visualization::ImageSliceActors::
284 GetNumberOfImageActors( ) const
286 return( this->ImageActors.size( ) );
289 // -------------------------------------------------------------------------
290 vtkImageActor* cpExtensions::Visualization::ImageSliceActors::
291 GetImageActor( unsigned int id )
293 if( id < this->ImageActors.size( ) )
294 return( this->ImageActors[ id ] );
299 // -------------------------------------------------------------------------
300 const vtkImageActor* cpExtensions::Visualization::ImageSliceActors::
301 GetImageActor( unsigned int id ) const
303 if( id < this->ImageActors.size( ) )
304 return( this->ImageActors[ id ] );
309 // -------------------------------------------------------------------------
310 vtkTextActor* cpExtensions::Visualization::ImageSliceActors::
313 return( this->TextActor );
316 // -------------------------------------------------------------------------
317 const vtkTextActor* cpExtensions::Visualization::ImageSliceActors::
318 GetTextActor( ) const
320 return( this->TextActor );
323 // -------------------------------------------------------------------------
324 vtkActor* cpExtensions::Visualization::ImageSliceActors::
327 return( this->PlaneActor );
330 // -------------------------------------------------------------------------
331 const vtkActor* cpExtensions::Visualization::ImageSliceActors::
332 GetPlaneActor( ) const
334 return( this->PlaneActor );
337 // -------------------------------------------------------------------------
338 vtkPlane* cpExtensions::Visualization::ImageSliceActors::
341 return( this->PlaneFunction );
344 // -------------------------------------------------------------------------
345 const vtkPlane* cpExtensions::Visualization::ImageSliceActors::
346 GetPlaneFunction( ) const
348 return( this->PlaneFunction );
351 // -------------------------------------------------------------------------
352 void cpExtensions::Visualization::ImageSliceActors::
353 AddActor( vtkAlgorithm* algorithm, vtkActor* actor )
355 this->AssociatedActors.push_back( TAssociatedActor( algorithm, actor ) );
356 this->AddItem( actor );
359 // -------------------------------------------------------------------------
360 void cpExtensions::Visualization::ImageSliceActors::
361 AddActor( vtkActor* actor )
363 this->AddActor( NULL, actor );
366 // -------------------------------------------------------------------------
367 void cpExtensions::Visualization::ImageSliceActors::
368 SetInterpolate( bool v )
370 if( this->Interpolate != v )
372 for( unsigned int i = 0; i < this->ImageActors.size( ); ++i )
373 this->ImageActors[ i ]->SetInterpolate( v );
374 this->Interpolate = v;
380 // -------------------------------------------------------------------------
381 void cpExtensions::Visualization::ImageSliceActors::
384 this->SetInterpolate( true );
387 // -------------------------------------------------------------------------
388 void cpExtensions::Visualization::ImageSliceActors::
391 this->SetInterpolate( false );
394 // -------------------------------------------------------------------------
395 double* cpExtensions::Visualization::ImageSliceActors::
396 GetDisplayBounds( ) const
398 if( this->ImageActors.size( ) > 0 )
399 return( this->ImageActors[ 0 ]->GetDisplayBounds( ) );
404 // -------------------------------------------------------------------------
405 void cpExtensions::Visualization::ImageSliceActors::
406 GetDisplayBounds( double bounds[ 6 ] ) const
408 if( this->ImageActors.size( ) == 0 )
410 bounds[ 0 ] = bounds[ 2 ] = bounds[ 4 ] = double( -1 );
411 bounds[ 1 ] = bounds[ 3 ] = bounds[ 5 ] = double( -1 );
414 this->ImageActors[ 0 ]->GetDisplayBounds( bounds );
417 // -------------------------------------------------------------------------
418 void cpExtensions::Visualization::ImageSliceActors::
421 vtkPoints* points = this->Cursor->GetPoints( );
422 points->SetPoint( 0, 0, 0, 0 );
423 points->SetPoint( 1, 0, 0, 0 );
424 points->SetPoint( 2, 0, 0, 0 );
425 points->SetPoint( 3, 0, 0, 0 );
426 points->SetPoint( 4, 0, 0, 0 );
427 points->SetPoint( 5, 0, 0, 0 );
428 points->SetPoint( 6, 0, 0, 0 );
429 points->SetPoint( 7, 0, 0, 0 );
430 this->Cursor->Modified( );
431 this->CursorMapper->Modified( );
432 this->CursorActor->Modified( );
435 // -------------------------------------------------------------------------
436 void cpExtensions::Visualization::ImageSliceActors::
437 SetCursor( double pos[ 3 ] )
439 if( this->SliceMappers.size( ) == 0 )
443 int a0 = this->GetAxis( );
444 int a1 = ( a0 + 1 ) % 3;
445 int a2 = ( a0 + 2 ) % 3;
451 this->SliceMappers[ 0 ]->GetInput( )->GetBounds( bounds );
454 p0[ 3 ], p1[ 3 ], p2[ 3 ], p3[ 3 ],
455 p4[ 3 ], p5[ 3 ], p6[ 3 ], p7[ 3 ];
457 p0[ a2 ] = p1[ a2 ] = p4[ a2 ] = p5[ a2 ] = pos[ a2 ];
458 p2[ a1 ] = p3[ a1 ] = p6[ a1 ] = p7[ a1 ] = pos[ a1 ];
459 p0[ a0 ] = p1[ a0 ] = p2[ a0 ] = p3[ a0 ] = bounds[ ma0 ];
460 p4[ a0 ] = p5[ a0 ] = p6[ a0 ] = p7[ a0 ] = bounds[ ma0 + 1 ];
461 p0[ a1 ] = p4[ a1 ] = bounds[ ma1 ];
462 p1[ a1 ] = p5[ a1 ] = bounds[ ma1 + 1 ];
463 p2[ a2 ] = p6[ a2 ] = bounds[ ma2 ];
464 p3[ a2 ] = p7[ a2 ] = bounds[ ma2 + 1 ];
466 vtkPoints* points = this->Cursor->GetPoints( );
467 points->SetPoint( 0, p0 );
468 points->SetPoint( 1, p1 );
469 points->SetPoint( 2, p2 );
470 points->SetPoint( 3, p3 );
471 points->SetPoint( 4, p4 );
472 points->SetPoint( 5, p5 );
473 points->SetPoint( 6, p6 );
474 points->SetPoint( 7, p7 );
475 this->Cursor->Modified( );
476 this->CursorMapper->Modified( );
477 this->CursorActor->Modified( );
480 // -------------------------------------------------------------------------
481 vtkImageMapToColors* cpExtensions::Visualization::ImageSliceActors::
482 GetImageMap( unsigned int id )
484 if( id < this->ImageMaps.size( ) )
485 return( this->ImageMaps[ id ].GetPointer( ) );
490 // -------------------------------------------------------------------------
491 const vtkImageMapToColors* cpExtensions::Visualization::ImageSliceActors::
492 GetImageMap( unsigned int id ) const
494 if( id < this->ImageMaps.size( ) )
495 return( this->ImageMaps[ id ].GetPointer( ) );
500 // -------------------------------------------------------------------------
501 double cpExtensions::Visualization::ImageSliceActors::
502 GetWindow( unsigned int id ) const
504 if( this->ImageMaps[ id ].GetPointer( ) != NULL )
506 vtkWindowLevelLookupTable* lut =
507 dynamic_cast< vtkWindowLevelLookupTable* >(
508 this->ImageMaps[ id ]->GetLookupTable( )
511 return( lut->GetWindow( ) );
513 return( double( 0 ) );
516 return( double( 0 ) );
519 // -------------------------------------------------------------------------
520 double cpExtensions::Visualization::ImageSliceActors::
521 GetLevel( unsigned int id ) const
523 if( this->ImageMaps[ id ].GetPointer( ) != NULL )
525 vtkWindowLevelLookupTable* lut =
526 dynamic_cast< vtkWindowLevelLookupTable* >(
527 this->ImageMaps[ id ]->GetLookupTable( )
530 return( lut->GetLevel( ) );
532 return( double( 0 ) );
535 return( double( 0 ) );
538 // -------------------------------------------------------------------------
539 void cpExtensions::Visualization::ImageSliceActors::
540 SetWindow( unsigned int id, double w )
542 if( this->ImageMaps[ id ].GetPointer( ) != NULL )
544 vtkWindowLevelLookupTable* lut =
545 dynamic_cast< vtkWindowLevelLookupTable* >(
546 this->ImageMaps[ id ]->GetLookupTable( )
552 this->ImageMaps[ id ]->Modified( );
560 // -------------------------------------------------------------------------
561 void cpExtensions::Visualization::ImageSliceActors::
562 SetLevel( unsigned int id, double l )
564 if( this->ImageMaps[ id ].GetPointer( ) != NULL )
566 vtkWindowLevelLookupTable* lut =
567 dynamic_cast< vtkWindowLevelLookupTable* >(
568 this->ImageMaps[ id ]->GetLookupTable( )
574 this->ImageMaps[ id ]->Modified( );
582 // -------------------------------------------------------------------------
583 void cpExtensions::Visualization::ImageSliceActors::
584 SetWindowLevel( unsigned int id, double w, double l )
586 if( this->ImageMaps[ id ].GetPointer( ) != NULL )
588 vtkWindowLevelLookupTable* lut =
589 dynamic_cast< vtkWindowLevelLookupTable* >(
590 this->ImageMaps[ id ]->GetLookupTable( )
597 this->ImageMaps[ id ]->Modified( );
598 this->UpdateText( w, l );
606 // -------------------------------------------------------------------------
607 void cpExtensions::Visualization::ImageSliceActors::
608 ResetWindowLevel( unsigned int id )
612 // -------------------------------------------------------------------------
613 int cpExtensions::Visualization::ImageSliceActors::
616 if( this->SliceMappers.size( ) > 0 )
617 return( this->SliceMappers[ 0 ]->GetOrientation( ) );
622 // -------------------------------------------------------------------------
623 int cpExtensions::Visualization::ImageSliceActors::
624 GetSliceNumber( ) const
626 if( this->SliceMappers.size( ) > 0 )
627 return( this->SliceMappers[ 0 ]->GetSliceNumber( ) );
632 // -------------------------------------------------------------------------
633 int cpExtensions::Visualization::ImageSliceActors::
634 GetSliceNumberMinValue( ) const
636 if( this->SliceMappers.size( ) > 0 )
637 return( this->SliceMappers[ 0 ]->GetSliceNumberMinValue( ) );
642 // -------------------------------------------------------------------------
643 int cpExtensions::Visualization::ImageSliceActors::
644 GetSliceNumberMaxValue( ) const
646 if( this->SliceMappers.size( ) > 0 )
647 return( this->SliceMappers[ 0 ]->GetSliceNumberMaxValue( ) );
652 // -------------------------------------------------------------------------
653 void cpExtensions::Visualization::ImageSliceActors::
654 SetSliceNumber( const int& slice )
656 unsigned int nImages = this->SliceMappers.size( );
660 // Change visualization extent
661 for( unsigned int i = 0; i < nImages; ++i )
663 this->SliceMappers[ i ]->SetSliceNumber( slice );
664 this->SliceMappers[ i ]->Modified( );
665 this->ImageActors[ i ]->Modified( );
666 this->SliceMappers[ i ]->Update( );
671 vtkAlgorithm* algo = this->SliceMappers[ 0 ]->GetInputAlgorithm( );
672 vtkInformation* info = algo->GetOutputInformation( 0 );
674 double ori[ 3 ], spac[ 3 ], pos[ 3 ];
675 info->Get( vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT( ), ext );
676 info->Get( vtkDataObject::ORIGIN( ), ori );
677 info->Get( vtkDataObject::SPACING( ), spac );
678 this->SliceMappers[ 0 ]->GetSlicePlane( )->GetOrigin( pos );
680 // Prevent obscuring voxels by offsetting the plane geometry
683 ori[ 0 ] + ( spac[ 0 ] * double( ext[ 0 ] ) ),
684 ori[ 0 ] + ( spac[ 0 ] * double( ext[ 1 ] ) )
688 ori[ 1 ] + ( spac[ 1 ] * double( ext[ 2 ] ) ),
689 ori[ 1 ] + ( spac[ 1 ] * double( ext[ 3 ] ) )
693 ori[ 2 ] + ( spac[ 2 ] * double( ext[ 4 ] ) ),
694 ori[ 2 ] + ( spac[ 2 ] * double( ext[ 5 ] ) )
697 if( spac[ 0 ] < double( 0 ) )
699 double t = xbnds[ 0 ];
700 xbnds[ 0 ] = xbnds[ 1 ];
704 if( spac[ 1 ] < double( 0 ) )
706 double t = ybnds[ 0 ];
707 ybnds[ 0 ] = ybnds[ 1 ];
711 if( spac[ 2 ] < double( 0 ) )
713 double t = zbnds[ 0 ];
714 zbnds[ 0 ] = zbnds[ 1 ];
719 // Plane function origin
720 this->PlaneFunction->SetOrigin( pos );
722 // Configure visualization and implicit plane orientation
723 int axis = this->SliceMappers[ 0 ]->GetOrientation( );
724 this->PlaneActor->GetProperty( )->SetRepresentationToWireframe( );
725 this->PlaneActor->GetProperty( )->SetLineWidth( 2 );
726 vtkPoints* plane_points = this->PlaneSource->GetPoints( );
727 if( axis == 0 ) // YZ, x-normal
729 this->PlaneFunction->SetNormal( 1, 0, 0 );
730 plane_points->SetPoint( 0, pos[ 0 ], ybnds[ 0 ], zbnds[ 0 ] );
731 plane_points->SetPoint( 1, pos[ 0 ], ybnds[ 1 ], zbnds[ 0 ] );
732 plane_points->SetPoint( 2, pos[ 0 ], ybnds[ 1 ], zbnds[ 1 ] );
733 plane_points->SetPoint( 3, pos[ 0 ], ybnds[ 0 ], zbnds[ 1 ] );
734 this->PlaneActor->GetProperty( )->SetColor( 1, 0, 0 );
736 else if( axis == 1 ) // ZX, y-normal
738 this->PlaneFunction->SetNormal( 0, 1, 0 );
739 plane_points->SetPoint( 0, xbnds[ 0 ], pos[ 1 ], zbnds[ 0 ] );
740 plane_points->SetPoint( 1, xbnds[ 0 ], pos[ 1 ], zbnds[ 1 ] );
741 plane_points->SetPoint( 2, xbnds[ 1 ], pos[ 1 ], zbnds[ 1 ] );
742 plane_points->SetPoint( 3, xbnds[ 1 ], pos[ 1 ], zbnds[ 0 ] );
743 this->PlaneActor->GetProperty( )->SetColor( 0, 1, 0 );
747 this->PlaneFunction->SetNormal( 0, 0, 1 );
748 plane_points->SetPoint( 0, xbnds[ 0 ], ybnds[ 0 ], pos[ 2 ] );
749 plane_points->SetPoint( 1, xbnds[ 1 ], ybnds[ 0 ], pos[ 2 ] );
750 plane_points->SetPoint( 2, xbnds[ 1 ], ybnds[ 1 ], pos[ 2 ] );
751 plane_points->SetPoint( 3, xbnds[ 0 ], ybnds[ 1 ], pos[ 2 ] );
752 this->PlaneActor->GetProperty( )->SetColor( 0, 0, 1 );
755 this->PlaneFunction->Modified( );
756 this->PlaneSource->Modified( );
757 this->PlaneMapper->Modified( );
758 this->PlaneActor->Modified( );
760 // Prepare other actors to update
762 for( unsigned int i = 0; i < this->OtherActors.size( ); ++i )
764 if( this->OtherActors[ i ].first.GetPointer( ) != NULL )
766 this->OtherActors[ i ].first->Modified( );
767 this->OtherActors[ i ].first->Update( );
771 if( this->OtherActors[ i ].second.GetPointer( ) != NULL )
773 this->OtherActors[ i ].second->GetMapper( )->Modified( );
774 this->OtherActors[ i ].second->Modified( );
780 if( this->m_UpdateCommand != NULL )
781 this->m_UpdateCommand( this->m_UpdateData );
788 // -------------------------------------------------------------------------
789 void cpExtensions::Visualization::ImageSliceActors::
792 if( this->SliceMappers.size( ) > 0 )
795 int axId = this->SliceMappers[ 0 ]->GetOrientation( );
796 if ( axId == 0 ) axis = 'X';
797 else if( axId == 1 ) axis = 'Y';
798 else if( axId == 2 ) axis = 'Z';
801 this->TextBuffer, "Axis: %c (%d)",
802 axis, this->SliceMappers[ 0 ]->GetSliceNumber( )
806 this->TextBuffer[ 0 ] = '\0';
807 this->TextActor->SetInput( this->TextBuffer );
808 this->TextActor->Modified( );
812 // -------------------------------------------------------------------------
813 void cpExtensions::Visualization::ImageSliceActors::
814 UpdateText( double pos[ 3 ] )
816 if( this->SliceMappers.size( ) > 0 )
819 int axId = this->SliceMappers[ 0 ]->GetOrientation( );
820 if ( axId == 0 ) axis = 'X';
821 else if( axId == 1 ) axis = 'Y';
822 else if( axId == 2 ) axis = 'Z';
823 int slice = this->GetSliceNumber( );
826 if( this->ImageMaps[ 0 ] != NULL )
828 dynamic_cast< vtkImageData* >( this->ImageMaps[ 0 ]->GetInput( ) );
830 image = this->SliceMappers[ 0 ]->GetInput( );
834 image->ComputeStructuredCoordinates( pos, ijk, pcoords );
838 image->GetExtent( ext );
840 ext[ 0 ] <= ijk[ 0 ] && ijk[ 0 ] <= ext[ 1 ] &&
841 ext[ 2 ] <= ijk[ 1 ] && ijk[ 1 ] <= ext[ 3 ] &&
842 ext[ 4 ] <= ijk[ 2 ] && ijk[ 2 ] <= ext[ 5 ]
845 int nScl = image->GetNumberOfScalarComponents( );
846 std::stringstream str;
850 << "," << ijk[ 2 ] << "]=(";
852 image->GetScalarComponentAsFloat( ijk[ 0 ], ijk[ 1 ], ijk[ 2 ], 0 );
853 for( int n = 1; n < nScl; ++n )
856 << image->GetScalarComponentAsFloat(
857 ijk[ 0 ], ijk[ 1 ], ijk[ 2 ], n
861 this->TextBuffer, "Axis: %c (%d) | Pixel %s",
862 axis, slice, str.str( ).c_str( )
868 this->TextBuffer[ 0 ] = '\0';
869 this->TextActor->SetInput( this->TextBuffer );
870 this->TextActor->Modified( );
874 // -------------------------------------------------------------------------
875 void cpExtensions::Visualization::ImageSliceActors::
876 UpdateText( const double& w, const double& l )
878 if( this->SliceMappers.size( ) > 0 )
881 int axId = this->SliceMappers[ 0 ]->GetOrientation( );
882 if ( axId == 0 ) axis = 'X';
883 else if( axId == 1 ) axis = 'Y';
884 else if( axId == 2 ) axis = 'Z';
887 this->TextBuffer, "Axis: %c (%d) | W/L (%.2f/%.2f)",
888 axis, this->SliceMappers[ 0 ]->GetSliceNumber( ), w, l
892 this->TextBuffer[ 0 ] = '\0';
893 this->TextActor->SetInput( this->TextBuffer );
894 this->TextActor->Modified( );
898 // -------------------------------------------------------------------------
899 cpExtensions::Visualization::ImageSliceActors::
906 // Connect this view with a controller
907 this->Style = vtkSmartPointer< ImageInteractorStyle >::New( );
908 this->Style->AssociateView( this );
909 this->Style->SetMouseMoveCommand( Self::_MouseMoveCommand );
910 this->Style->SetMouseClickCommand( Self::_MouseClickCommand );
911 this->Style->SetMouseDoubleClickCommand( Self::_MouseDoubleClickCommand );
912 this->Style->SetMouseWheelCommand( Self::_MouseWheelCommand );
913 this->Style->SetKeyCommand( Self::_KeyCommand );
916 // -------------------------------------------------------------------------
917 cpExtensions::Visualization::ImageSliceActors::
922 // -------------------------------------------------------------------------
923 void cpExtensions::Visualization::ImageSliceActors::
924 _ConfigureNewLUT( vtkImageData* data, LUTType lut_t )
926 static const double _0 = double( 0 );
927 static const double _1 = double( 1 );
928 static const double _2 = double( 2 );
929 static const double _4 = double( 4 );
930 static const double _6 = double( 6 );
931 static const double _OPACITY = double( 0.6 );
934 vtkSmartPointer< vtkImageMapToColors > new_map( NULL );
935 if( data->GetNumberOfScalarComponents( ) == 1 )
938 data->GetScalarRange( range );
939 if( lut_t == Self::LUTType_WindowLevel )
941 vtkSmartPointer< vtkWindowLevelLookupTable > lut =
942 vtkSmartPointer< vtkWindowLevelLookupTable >::New( );
943 lut->SetScaleToLinear( );
944 lut->SetTableRange( range );
945 lut->SetWindow( range[ 1 ] - range[ 0 ] );
946 lut->SetLevel( ( range[ 1 ] + range[ 0 ] ) / double( 2 ) );
949 new_map = vtkSmartPointer< vtkImageMapToColors >::New( );
950 new_map->SetLookupTable( lut );
952 else if( lut_t == LUTType_Colors )
954 // Get HSV from display color
955 double r = 1, g = 0, b = 0;
956 double cmax = ( r > g )? r: g; cmax = ( b > cmax )? b: cmax;
957 double cmin = ( r < g )? r: g; cmin = ( b < cmin )? b: cmin;
958 double d = cmax - cmin;
960 double saturation = ( std::fabs( cmax ) > _0 )? d / cmax: _0;
966 hue = std::fmod( ( g - b ) / d, _6 );
968 hue = ( ( b - r ) / d ) + _2;
970 hue = ( ( r - g ) / d ) + _4;
975 // Define new lookup table
976 vtkSmartPointer< vtkLookupTable > lut =
977 vtkSmartPointer< vtkLookupTable >::New( );
978 lut->SetScaleToLinear( );
979 lut->SetNanColor( _0, _0, _0, _0 );
980 lut->SetTableRange( range[ 0 ], range[ 1 ] );
981 lut->SetAlphaRange( _0, _OPACITY );
982 lut->SetHueRange( _0, hue );
983 lut->SetSaturationRange( _0, saturation );
984 lut->SetValueRange( _0, value );
987 new_map = vtkSmartPointer< vtkImageMapToColors >::New( );
988 new_map->SetLookupTable( lut );
993 this->ImageMaps.push_back( new_map );
996 // -------------------------------------------------------------------------
997 void cpExtensions::Visualization::ImageSliceActors::
998 _ConfigureNewInput( int axis )
1000 unsigned int nImages = this->ImageActors.size( );
1003 vtkImageSliceMapper* mapper = this->SliceMappers[ nImages ];
1005 mapper->SetOrientation( axis );
1007 mapper->SetOrientation( this->SliceMappers[ 0 ]->GetOrientation( ) );
1011 vtkSmartPointer< vtkImageActor > actor =
1012 vtkSmartPointer< vtkImageActor >::New( );
1013 this->ImageActors.push_back( actor );
1014 actor->SetMapper( mapper );
1015 actor->SetInterpolate( this->Interpolate );
1020 this->AddItem( this->CursorActor );
1021 this->AddItem( this->PlaneActor );
1022 this->AddItem( this->TextActor );
1023 this->Style->AssociateImageActor( actor );
1026 this->AddItem( actor );
1029 this->SetSliceNumber( this->GetSliceNumber( ) );
1033 // -------------------------------------------------------------------------
1034 void cpExtensions::Visualization::ImageSliceActors::
1037 const ImageInteractorStyle::ButtonID& btn, double* pos,
1038 bool alt, bool ctr, bool sft
1041 ImageSliceActors* actors = reinterpret_cast< ImageSliceActors* >( data );
1042 if( actors == NULL )
1045 if( btn == ImageInteractorStyle::ButtonID_None )
1047 actors->UpdateText( pos );
1049 else if( btn == ImageInteractorStyle::ButtonID_Left )
1052 else if( btn == ImageInteractorStyle::ButtonID_Middle )
1055 else if( btn == ImageInteractorStyle::ButtonID_Right )
1057 if( !alt && !ctr && sft )
1060 actors->SliceMappers[ 0 ]->GetBounds( bounds );
1062 int a0 = actors->GetAxis( );
1063 int a1 = ( a0 + 1 ) % 3;
1064 int a2 = ( a0 + 2 ) % 3;
1065 double dx = pos[ a1 ] - actors->StartWindowLevelPos[ a1 ];
1066 double dy = pos[ a2 ] - actors->StartWindowLevelPos[ a2 ];
1067 dx /= bounds[ ( a1 << 1 ) + 1 ] - bounds[ a1 << 1 ];
1068 dy /= bounds[ ( a2 << 1 ) + 1 ] - bounds[ a2 << 1 ];
1070 dx *= actors->StartWindowLevel[ 0 ];
1071 dy *= actors->StartWindowLevel[ 1 ];
1072 actors->SetWindowLevel(
1074 actors->StartWindowLevel[ 0 ] + dx,
1075 actors->StartWindowLevel[ 1 ] + dy
1083 // -------------------------------------------------------------------------
1084 void cpExtensions::Visualization::ImageSliceActors::
1087 const ImageInteractorStyle::ButtonID& btn, double* pos,
1088 bool alt, bool ctr, bool sft
1091 ImageSliceActors* actors = reinterpret_cast< ImageSliceActors* >( data );
1092 if( actors == NULL )
1095 actors->StartWindowLevelPos[ 0 ] = pos[ 0 ];
1096 actors->StartWindowLevelPos[ 1 ] = pos[ 1 ];
1097 actors->StartWindowLevelPos[ 2 ] = pos[ 2 ];
1098 actors->StartWindowLevel[ 0 ] = actors->GetWindow( 0 );
1099 actors->StartWindowLevel[ 1 ] = actors->GetLevel( 0 );
1102 // -------------------------------------------------------------------------
1103 void cpExtensions::Visualization::ImageSliceActors::
1104 _MouseDoubleClickCommand(
1106 const ImageInteractorStyle::ButtonID& btn, double* pos,
1107 bool alt, bool ctr, bool sft
1110 ImageSliceActors* actors = reinterpret_cast< ImageSliceActors* >( data );
1111 if( actors == NULL )
1114 if( btn == ImageInteractorStyle::ButtonID_Left )
1116 if( !alt && !ctr && !sft )
1118 actors->SetCursor( pos );
1122 else if( btn == ImageInteractorStyle::ButtonID_Middle )
1125 else if( btn == ImageInteractorStyle::ButtonID_Right )
1130 // -------------------------------------------------------------------------
1131 void cpExtensions::Visualization::ImageSliceActors::
1134 const int& dir, bool alt, bool ctr, bool sft
1137 ImageSliceActors* actors = reinterpret_cast< ImageSliceActors* >( data );
1138 if( actors == NULL )
1141 if( !alt && !ctr && !sft )
1143 actors->SetSliceNumber( actors->GetSliceNumber( ) + dir );
1145 else if( !alt && !ctr && sft )
1147 actors->SetSliceNumber( actors->GetSliceNumber( ) + ( dir * 10 ) );
1152 // -------------------------------------------------------------------------
1153 void cpExtensions::Visualization::ImageSliceActors::