1 #include <cpPlugins/Extensions/Visualization/ImageInteractorStyle.h>
5 #include <vtkAnnotatedCubeActor.h>
6 #include <vtkAxesActor.h>
7 #include <vtkCallbackCommand.h>
9 #include <vtkCommand.h>
10 #include <vtkPropAssembly.h>
11 #include <vtkProperty.h>
12 #include <vtkRendererCollection.h>
13 #include <vtkRenderWindow.h>
14 #include <vtkRenderWindowInteractor.h>
16 #include <cpPlugins/Extensions/Visualization/ImageSliceActors.h>
17 #include <cpPlugins/Extensions/Visualization/MPRActors.h>
19 // -------------------------------------------------------------------------
20 const int cpPlugins::Extensions::Visualization::
21 ImageInteractorStyle::DoubleClickEvent = vtkCommand::UserEvent + 1;
23 // -------------------------------------------------------------------------
24 cpPlugins::Extensions::Visualization::ImageInteractorStyle::
25 Self* cpPlugins::Extensions::Visualization::ImageInteractorStyle::
28 return( new Self( ) );
31 // -------------------------------------------------------------------------
32 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
33 Configure( ImageSliceActors* slice_actors, MPRActors* mpr_actors )
35 this->m_SliceActors = slice_actors;
36 this->m_MPRActors = mpr_actors;
37 this->SetModeToNavigation( );
38 this->PropPicker->AddPickList( slice_actors->GetImageActor( ) );
42 // -------------------------------------------------------------------------
43 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
44 AssociateInteractor( vtkRenderWindowInteractor* interactor )
46 if( interactor != NULL )
48 this->AssociatedInteractors.push_back( interactor );
54 // -------------------------------------------------------------------------
55 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
56 SetModeToNavigation( )
58 this->Mode = Self::NavigationMode;
61 // -------------------------------------------------------------------------
62 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
63 SetModeToDeformation( )
65 this->Mode = Self::DeformationMode;
68 // -------------------------------------------------------------------------
69 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
70 SetInteractor( vtkRenderWindowInteractor* interactor, const int& axis )
72 this->Superclass::SetInteractor( interactor );
73 this->OrientationWidget->SetInteractor( interactor );
74 interactor->SetInteractorStyle( this );
75 if( interactor == NULL )
78 // TODO: interactor->SetPicker( this->PropPicker );
80 // Get camera, avoiding segfaults
82 interactor->GetRenderWindow( )->GetRenderers( )->GetFirstRenderer( );
85 vtkCamera* cam = ren->GetActiveCamera( );
89 // Parallel projections are better when displaying 2D images
90 cam->ParallelProjectionOn( );
91 cam->SetFocalPoint( double( 0 ), double( 0 ), double( 0 ) );
94 cam->SetPosition( double( 1 ), double( 0 ), double( 0 ) );
95 cam->SetViewUp ( double( 0 ), double( 1 ), double( 0 ) );
99 cam->SetPosition( double( 0 ), double( 1 ), double( 0 ) );
100 cam->SetViewUp ( double( 0 ), double( 0 ), double( -1 ) );
102 else // if( axis == 2 )
104 cam->SetPosition( double( 0 ), double( 0 ), double( 1 ) );
105 cam->SetViewUp ( double( 0 ), double( 1 ), double( 0 ) );
110 // Enable 2D orientation widget
111 this->OrientationWidget->SetEnabled( 1 );
112 this->OrientationWidget->InteractiveOff( );
115 // -------------------------------------------------------------------------
116 unsigned long cpPlugins::Extensions::Visualization::ImageInteractorStyle::
117 AddDoubleClickObserver( vtkCommand* observer )
119 return( this->AddObserver( Self::DoubleClickEvent, observer ) );
122 // -------------------------------------------------------------------------
123 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
124 RemoveDoubleClickObserver( unsigned long tag )
126 this->RemoveObserver( tag );
129 // -------------------------------------------------------------------------
130 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
131 RemoveDoubleClickObserver( vtkCommand* observer )
133 this->RemoveObserver( observer );
136 // -------------------------------------------------------------------------
137 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
138 RemoveDoubleClickObservers( )
140 this->RemoveObservers( Self::DoubleClickEvent );
143 // -------------------------------------------------------------------------
144 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
147 if( this->m_MPRActors == NULL )
151 if( this->CursorMoving )
153 bool picked = this->_PickPosition( pos );
156 for( int i = 0; i < 3; ++i )
157 if( this->m_SliceActors->GetAxis( ) != i )
158 this->m_MPRActors->SetSlice( i, pos[ i ] );
159 this->Interactor->Render( );
160 this->_RenderAssociateInteractors( );
166 switch( this->State )
168 case VTKIS_WINDOW_LEVEL:
169 this->WindowLevel( );
182 // -------------------------------------------------------------------------
183 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
186 static double pnt[ 3 ];
188 this->Interactor->GetEventPosition( pos );
189 this->FindPokedRenderer( pos[ 0 ], pos[ 1 ] );
190 if( this->CurrentRenderer == NULL )
192 this->GrabFocus( this->EventCallbackCommand );
194 // TODO: check this code
195 // Manage double-click
196 static const long epsilon_time = 250;
197 static long last_click_time = -( epsilon_time << 1 );
198 long click_time = static_cast< long >( std::clock( ) );
199 if( ( click_time - last_click_time ) < epsilon_time )
201 last_click_time = -( epsilon_time << 1 );
202 if( this->_PickPosition( pnt ) )
203 this->InvokeEvent( Self::DoubleClickEvent, pnt );
207 last_click_time = click_time;
208 if( this->Interactor->GetControlKey( ) )
209 this->StartCursorMoving( );
214 // -------------------------------------------------------------------------
215 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
218 if( this->CursorMoving )
220 this->EndCursorMoving( );
221 if( this->Interactor )
222 this->ReleaseFocus( );
227 // -------------------------------------------------------------------------
228 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
229 OnMiddleButtonDown( )
231 int x = this->Interactor->GetEventPosition( )[ 0 ];
232 int y = this->Interactor->GetEventPosition( )[ 1 ];
234 this->FindPokedRenderer( x, y );
235 if( this->CurrentRenderer == NULL )
237 this->GrabFocus( this->EventCallbackCommand );
239 if( this->Interactor->GetAltKey( ) )
242 else if( this->Interactor->GetControlKey( ) )
245 else if( this->Interactor->GetShiftKey( ) )
252 // -------------------------------------------------------------------------
253 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
256 switch( this->State )
264 // -------------------------------------------------------------------------
265 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
268 int x = this->Interactor->GetEventPosition( )[ 0 ];
269 int y = this->Interactor->GetEventPosition( )[ 1 ];
271 this->FindPokedRenderer( x, y );
272 if( this->CurrentRenderer == NULL )
274 this->GrabFocus( this->EventCallbackCommand );
276 if( this->Interactor->GetControlKey( ) )
278 this->WindowLevelStartPosition[ 0 ] = x;
279 this->WindowLevelStartPosition[ 1 ] = y;
280 this->StartWindowLevel( );
288 // -------------------------------------------------------------------------
289 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
292 switch( this->State )
294 case VTKIS_WINDOW_LEVEL:
296 this->EndWindowLevel( );
297 if( this->Interactor )
298 this->ReleaseFocus( );
307 // -------------------------------------------------------------------------
308 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
309 OnMouseWheelForward( )
311 if( this->m_SliceActors == NULL || this->Interactor == NULL )
314 if( this->Interactor->GetShiftKey( ) == 1 )
316 int s = this->m_SliceActors->GetSliceNumber( ) + off;
317 int maxs = this->m_SliceActors->GetSliceNumberMaxValue( );
318 this->m_SliceActors->SetSliceNumber( ( s < maxs )? s: maxs );
319 this->Interactor->Render( );
320 this->_RenderAssociateInteractors( );
323 // -------------------------------------------------------------------------
324 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
325 OnMouseWheelBackward( )
327 if( this->m_SliceActors == NULL || this->Interactor == NULL )
330 if( this->Interactor->GetShiftKey( ) == 1 )
332 int s = this->m_SliceActors->GetSliceNumber( ) - off;
333 int mins = this->m_SliceActors->GetSliceNumberMinValue( );
334 this->m_SliceActors->SetSliceNumber( ( mins < s )? s: mins );
335 this->Interactor->Render( );
336 this->_RenderAssociateInteractors( );
339 // -------------------------------------------------------------------------
340 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
343 switch( this->Interactor->GetKeyCode( ) )
348 this->Interactor->GetRenderWindow( )->
349 GetRenderers( )->GetFirstRenderer( );
352 this->Interactor->Render( );
355 case 'w': case 'W': case 'l': case 'L':
357 if( this->m_MPRActors != NULL )
359 this->m_MPRActors->ResetWindowLevel( );
360 this->Interactor->Render( );
361 this->_RenderAssociateInteractors( );
369 // -------------------------------------------------------------------------
370 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
373 if( this->Mode == Self::NavigationMode )
375 if( this->Interactor == NULL )
378 this->Interactor->GetRenderWindow( )->
379 GetRenderers( )->GetFirstRenderer( );
384 this->WindowLevelCurrentPosition[ 0 ] =
385 this->Interactor->GetEventPosition( )[ 0 ];
386 this->WindowLevelCurrentPosition[ 1 ] =
387 this->Interactor->GetEventPosition( )[ 1 ];
388 int* size = ren->GetSize( );
390 this->WindowLevelCurrentPosition[ 0 ] -
391 this->WindowLevelStartPosition[ 0 ]
392 ) / double( size[ 0 ] );
394 this->WindowLevelStartPosition[ 1 ] -
395 this->WindowLevelCurrentPosition[ 1 ]
396 ) / double( size[ 1 ] );
398 double w = this->WindowLevelInitial[ 0 ] * ( double( 1 ) + sw );
399 double l = this->WindowLevelInitial[ 1 ] * ( double( 1 ) + sl );
400 double minw = this->m_MPRActors->GetMinWindow( );
401 double maxw = this->m_MPRActors->GetMaxWindow( );
402 double minl = this->m_MPRActors->GetMinLevel( );
403 double maxl = this->m_MPRActors->GetMaxLevel( );
405 if( w < minw ) w = minw;
406 if( maxw < w ) w = maxw;
407 if( l < minl ) l = minl;
408 if( maxl < l ) l = maxl;
410 this->m_MPRActors->SetWindowLevel( w, l );
411 this->Interactor->Render( );
412 this->_RenderAssociateInteractors( );
414 else if( this->Mode == Self::DeformationMode )
421 // -------------------------------------------------------------------------
422 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
425 if( this->State != VTKIS_NONE )
427 if( this->Mode == Self::NavigationMode )
429 this->StartState( VTKIS_WINDOW_LEVEL );
431 this->WindowLevelInitial[ 0 ] = this->m_MPRActors->GetWindow( );
432 this->WindowLevelInitial[ 1 ] = this->m_MPRActors->GetLevel( );
434 else if( this->Mode == Self::DeformationMode )
441 // -------------------------------------------------------------------------
442 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
445 if( this->Mode == Self::NavigationMode )
447 if( this->State != VTKIS_WINDOW_LEVEL )
458 // -------------------------------------------------------------------------
459 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
462 if( this->CursorMoving )
464 this->CursorMoving = true;
467 // -------------------------------------------------------------------------
468 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
471 if( !( this->CursorMoving ) )
473 this->CursorMoving = false;
476 // -------------------------------------------------------------------------
477 cpPlugins::Extensions::Visualization::ImageInteractorStyle::
478 ImageInteractorStyle( )
480 Mode( Self::NavigationMode ),
481 m_SliceActors( NULL ),
483 CursorMoving( false )
486 vtkSmartPointer< vtkAnnotatedCubeActor > cube =
487 vtkSmartPointer< vtkAnnotatedCubeActor >::New( );
488 cube->GetCubeProperty( )->SetColor( 0.9, 0.7, 0.2 );
489 cube->GetTextEdgesProperty( )->SetLineWidth( 1 );
490 cube->GetTextEdgesProperty( )->SetDiffuse( 0 );
491 cube->GetTextEdgesProperty( )->SetAmbient( 1 );
492 cube->GetTextEdgesProperty( )->SetColor( 0.18, 0.28, 0.23 );
493 cube->GetXPlusFaceProperty( )->SetColor( 1, 0, 0 );
494 cube->GetXPlusFaceProperty( )->SetInterpolationToFlat( );
495 cube->GetXMinusFaceProperty( )->SetColor( 1, 0, 0 );
496 cube->GetXMinusFaceProperty( )->SetInterpolationToFlat( );
497 cube->GetYPlusFaceProperty( )->SetColor( 0, 1, 0 );
498 cube->GetYPlusFaceProperty( )->SetInterpolationToFlat( );
499 cube->GetYMinusFaceProperty( )->SetColor( 0, 1, 0 );
500 cube->GetYMinusFaceProperty( )->SetInterpolationToFlat( );
501 cube->GetZPlusFaceProperty( )->SetColor( 0, 0, 1 );
502 cube->GetZPlusFaceProperty( )->SetInterpolationToFlat( );
503 cube->GetZMinusFaceProperty( )->SetColor( 0, 0, 1 );
504 cube->GetZMinusFaceProperty( )->SetInterpolationToFlat( );
506 vtkSmartPointer< vtkAxesActor > axes =
507 vtkSmartPointer< vtkAxesActor >::New( );
508 axes->AxisLabelsOff( );
509 axes->SetShaftTypeToCylinder( );
510 axes->SetTotalLength( 2, 2, 2 );
512 vtkSmartPointer< vtkPropAssembly > actors =
513 vtkSmartPointer< vtkPropAssembly >::New( );
514 actors->AddPart( cube );
515 actors->AddPart( axes );
517 this->OrientationWidget =
518 vtkSmartPointer< vtkOrientationMarkerWidget >::New( );
519 this->OrientationWidget->SetOutlineColor( 0.93, 0.57, 0.13 );
520 this->OrientationWidget->SetOrientationMarker( actors );
521 this->OrientationWidget->SetViewport( 0.0, 0.0, 0.2, 0.2 );
523 this->PropPicker = vtkSmartPointer< vtkPropPicker >::New( );
524 this->PropPicker->PickFromListOn( );
527 // -------------------------------------------------------------------------
528 cpPlugins::Extensions::Visualization::ImageInteractorStyle::
529 ~ImageInteractorStyle( )
533 // -------------------------------------------------------------------------
534 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
535 _RenderAssociateInteractors( )
537 std::vector< vtkRenderWindowInteractor* >::iterator rIt =
538 this->AssociatedInteractors.begin( );
539 for( ; rIt != this->AssociatedInteractors.end( ); ++rIt )
543 // -------------------------------------------------------------------------
544 bool cpPlugins::Extensions::Visualization::ImageInteractorStyle::
545 _PickPosition( double pos[ 3 ] )
547 if( this->m_SliceActors == NULL )
550 double x = double( this->Interactor->GetEventPosition( )[ 0 ] );
551 double y = double( this->Interactor->GetEventPosition( )[ 1 ] );
552 this->FindPokedRenderer( x, y );
554 this->PropPicker->Pick( x, y, double( 0 ), this->CurrentRenderer );
557 this->PropPicker->GetPickPosition( pos );
561 // -------------------------------------------------------------------------
562 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
565 std::cout << "upcur" << std::endl;