]> Creatis software - cpPlugins.git/blob - lib/cpPlugins/Extensions/Visualization/ImageInteractorStyle.cxx
Use of MPR simplified
[cpPlugins.git] / lib / cpPlugins / Extensions / Visualization / ImageInteractorStyle.cxx
1 #include <cpPlugins/Extensions/Visualization/ImageInteractorStyle.h>
2
3 #include <vtkAnnotatedCubeActor.h>
4 #include <vtkAxesActor.h>
5 #include <vtkCallbackCommand.h>
6 #include <vtkCamera.h>
7 #include <vtkCommand.h>
8 #include <vtkPropAssembly.h>
9 #include <vtkProperty.h>
10 #include <vtkRendererCollection.h>
11 #include <vtkRenderWindow.h>
12 #include <vtkRenderWindowInteractor.h>
13
14 #include <cpPlugins/Extensions/Visualization/ImageSliceActors.h>
15 #include <cpPlugins/Extensions/Visualization/MPRActors.h>
16
17 // -------------------------------------------------------------------------
18 const int cpPlugins::Extensions::Visualization::
19 ImageInteractorStyle::SliceEvent = vtkCommand::UserEvent + 1;
20
21 // -------------------------------------------------------------------------
22 cpPlugins::Extensions::Visualization::ImageInteractorStyle::
23 Self* cpPlugins::Extensions::Visualization::ImageInteractorStyle::
24 New( )
25 {
26   return( new Self( ) );
27 }
28
29 // -------------------------------------------------------------------------
30 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
31 Configure( ImageSliceActors* slice_actors, MPRActors* mpr_actors )
32 {
33   this->m_SliceActors = slice_actors;
34   this->m_MPRActors = mpr_actors;
35   this->SetModeToNavigation( );
36   this->PropPicker->AddPickList( slice_actors->GetImageActor( ) );
37   this->Modified( );
38 }
39
40 // -------------------------------------------------------------------------
41 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
42 AssociateInteractor( vtkRenderWindowInteractor* interactor )
43 {
44   if( interactor != NULL )
45   {
46     this->AssociatedInteractors.push_back( interactor );
47     this->Modified( );
48
49   } // fi
50 }
51
52 // -------------------------------------------------------------------------
53 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
54 SetModeToNavigation( )
55 {
56   this->Mode = Self::NavigationMode;
57 }
58
59 // -------------------------------------------------------------------------
60 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
61 SetModeToDeformation( )
62 {
63   this->Mode = Self::DeformationMode;
64 }
65
66 // -------------------------------------------------------------------------
67 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
68 SetInteractor( vtkRenderWindowInteractor* interactor, const int& axis )
69 {
70   this->Superclass::SetInteractor( interactor );
71   this->OrientationWidget->SetInteractor( interactor );
72   interactor->SetInteractorStyle( this );
73   if( interactor == NULL )
74     return;
75
76   // TODO: interactor->SetPicker( this->PropPicker );
77
78   // Get camera, avoiding segfaults
79   vtkRenderer* ren =
80     interactor->GetRenderWindow( )->GetRenderers( )->GetFirstRenderer( );
81   if( ren == NULL )
82     return;
83   vtkCamera* cam = ren->GetActiveCamera( );
84   if( cam == NULL )
85     return;
86
87   // Parallel projections are better when displaying 2D images
88   cam->ParallelProjectionOn( );
89   cam->SetFocalPoint( double( 0 ), double( 0 ), double( 0 ) );
90   if( axis == 0 )
91   {
92     cam->SetPosition( double( 1 ), double( 0 ), double( 0 ) );
93     cam->SetViewUp  ( double( 0 ), double( 1 ), double( 0 ) );
94   }
95   else if( axis == 1 )
96   {
97     cam->SetPosition( double( 0 ), double( 1 ), double(  0 ) );
98     cam->SetViewUp  ( double( 0 ), double( 0 ), double( -1 ) );
99   }
100   else // if( axis == 2 )
101   {
102     cam->SetPosition( double( 0 ), double( 0 ), double( 1 ) );
103     cam->SetViewUp  ( double( 0 ), double( 1 ), double( 0 ) );
104
105   } // fi
106   ren->ResetCamera( );
107
108   // Enable 2D orientation widget
109   this->OrientationWidget->SetEnabled( 1 );
110   this->OrientationWidget->InteractiveOff( );
111 }
112
113 // -------------------------------------------------------------------------
114 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
115 OnMouseMove( )
116 {
117   if( this->m_MPRActors == NULL )
118     return;
119   
120   double pos[ 3 ];
121   if( this->CursorMoving )
122   {
123     bool picked = this->_PickPosition( pos );
124     if( picked )
125     {
126       for( int i = 0; i < 3; ++i )
127         if( this->m_SliceActors->GetAxis( ) != i )
128           this->m_MPRActors->SetSlice( i, pos[ i ] );
129       this->Interactor->Render( );
130       this->_RenderAssociateInteractors( );
131
132     } // fi
133   }
134   else
135   {
136     switch( this->State )
137     {
138     case VTKIS_WINDOW_LEVEL:
139       this->WindowLevel( );
140       break;
141     case VTKIS_DOLLY:
142       this->Dolly( );
143       break;
144     case VTKIS_PAN:
145       this->Pan( );
146       break;
147     } // hctiws
148
149   } // fi
150 }
151
152 // -------------------------------------------------------------------------
153 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
154 OnLeftButtonDown( )
155 {
156   int x = this->Interactor->GetEventPosition( )[ 0 ];
157   int y = this->Interactor->GetEventPosition( )[ 1 ];
158
159   this->FindPokedRenderer( x, y );
160   if( this->CurrentRenderer == NULL )
161     return;
162   this->GrabFocus( this->EventCallbackCommand );
163
164   if( this->Interactor->GetControlKey( ) )
165     this->StartCursorMoving( );
166
167   /* TODO
168      if (!this->Interactor->GetShiftKey() && !this->Interactor->GetControlKey())
169      {
170      this->WindowLevelStartPosition[0] = x;
171      this->WindowLevelStartPosition[1] = y;
172      this->StartWindowLevel();
173      }
174
175      // If shift is held down, do a rotation
176      else if (this->InteractionMode == VTKIS_IMAGE3D &&
177      this->Interactor->GetShiftKey())
178      {
179      this->StartRotate();
180      }
181
182      // If ctrl is held down in slicing mode, slice the image
183      else if (this->InteractionMode == VTKIS_IMAGE_SLICING &&
184      this->Interactor->GetControlKey())
185      {
186      this->StartSlice();
187      }
188
189      // The rest of the button + key combinations remain the same
190
191      else
192      {
193      this->Superclass::OnLeftButtonDown();
194      }
195   */
196 }
197
198 // -------------------------------------------------------------------------
199 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
200 OnLeftButtonUp( )
201 {
202   if( this->CursorMoving )
203   {
204     this->EndCursorMoving( );
205     if( this->Interactor )
206       this->ReleaseFocus( );
207
208   } // fi
209 }
210
211 // -------------------------------------------------------------------------
212 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
213 OnMiddleButtonDown( )
214 {
215   int x = this->Interactor->GetEventPosition( )[ 0 ];
216   int y = this->Interactor->GetEventPosition( )[ 1 ];
217
218   this->FindPokedRenderer( x, y );
219   if( this->CurrentRenderer == NULL )
220     return;
221   this->GrabFocus( this->EventCallbackCommand );
222
223   if( this->Interactor->GetAltKey( ) )
224   {
225   }
226   else if( this->Interactor->GetControlKey( ) )
227   {
228   }
229   else if( this->Interactor->GetShiftKey( ) )
230   {
231   }
232   else
233     this->StartPan( );
234 }
235
236 // -------------------------------------------------------------------------
237 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
238 OnMiddleButtonUp( )
239 {
240   switch( this->State )
241   {
242   case VTKIS_PAN:
243     this->EndPan( );
244     break;
245   } // hctiws
246 }
247
248 // -------------------------------------------------------------------------
249 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
250 OnRightButtonDown( )
251 {
252   int x = this->Interactor->GetEventPosition( )[ 0 ];
253   int y = this->Interactor->GetEventPosition( )[ 1 ];
254
255   this->FindPokedRenderer( x, y );
256   if( this->CurrentRenderer == NULL )
257     return;
258   this->GrabFocus( this->EventCallbackCommand );
259
260   if( this->Interactor->GetControlKey( ) )
261   {
262     this->WindowLevelStartPosition[ 0 ] = x;
263     this->WindowLevelStartPosition[ 1 ] = y;
264     this->StartWindowLevel( );
265   }
266   else
267   {
268     this->StartDolly( );
269   } // fi
270 }
271
272 // -------------------------------------------------------------------------
273 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
274 OnRightButtonUp( )
275 {
276   switch( this->State )
277   {
278   case VTKIS_WINDOW_LEVEL:
279   {
280     this->EndWindowLevel( );
281     if( this->Interactor )
282       this->ReleaseFocus( );
283   }
284   break;
285   case VTKIS_DOLLY:
286     this->EndDolly( );
287     break;
288   } // hctiws
289 }
290
291 // -------------------------------------------------------------------------
292 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
293 OnMouseWheelForward( )
294 {
295   if( this->m_SliceActors == NULL || this->Interactor == NULL )
296     return;
297   int off = 1;
298   if( this->Interactor->GetShiftKey( ) == 1 )
299     off *= 10;
300   int s = this->m_SliceActors->GetSliceNumber( ) + off;
301   int maxs = this->m_SliceActors->GetSliceNumberMaxValue( );
302   this->m_SliceActors->SetSliceNumber( ( s < maxs )? s: maxs );
303   this->Interactor->Render( );
304   this->_RenderAssociateInteractors( );
305 }
306
307 // -------------------------------------------------------------------------
308 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
309 OnMouseWheelBackward( )
310 {
311   if( this->m_SliceActors == NULL || this->Interactor == NULL )
312     return;
313   int off = 1;
314   if( this->Interactor->GetShiftKey( ) == 1 )
315     off *= 10;
316   int s = this->m_SliceActors->GetSliceNumber( ) - off;
317   int mins = this->m_SliceActors->GetSliceNumberMinValue( );
318   this->m_SliceActors->SetSliceNumber( ( mins < s )? s: mins );
319   this->Interactor->Render( );
320   this->_RenderAssociateInteractors( );
321 }
322
323 // -------------------------------------------------------------------------
324 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
325 OnChar( )
326 {
327   switch( this->Interactor->GetKeyCode( ) )
328   {
329   case 'r': case 'R':
330   {
331     vtkRenderer* ren =
332       this->Interactor->GetRenderWindow( )->
333       GetRenderers( )->GetFirstRenderer( );
334     if( ren != NULL )
335       ren->ResetCamera( );
336     this->Interactor->Render( );
337   }
338   break;
339   case 'w': case 'W': case 'l': case 'L':
340   {
341     if( this->m_MPRActors != NULL )
342     {
343       this->m_MPRActors->ResetWindowLevel( );
344       this->Interactor->Render( );
345       this->_RenderAssociateInteractors( );
346
347     } // fi
348   }
349   break;
350   } // hctiws
351 }
352
353 // -------------------------------------------------------------------------
354 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
355 WindowLevel( )
356 {
357   if( this->Mode == Self::NavigationMode )
358   {
359     if( this->Interactor == NULL )
360       return;
361     vtkRenderer* ren =
362       this->Interactor->GetRenderWindow( )->
363       GetRenderers( )->GetFirstRenderer( );
364     if( ren == NULL )
365       return;
366
367     // Compute scales
368     this->WindowLevelCurrentPosition[ 0 ] =
369       this->Interactor->GetEventPosition( )[ 0 ];
370     this->WindowLevelCurrentPosition[ 1 ] =
371       this->Interactor->GetEventPosition( )[ 1 ];
372     int* size = ren->GetSize( );
373     double sw = double(
374       this->WindowLevelCurrentPosition[ 0 ] -
375       this->WindowLevelStartPosition[ 0 ]
376       ) / double( size[ 0 ] );
377     double sl = (
378       this->WindowLevelStartPosition[ 1 ] -
379       this->WindowLevelCurrentPosition[ 1 ]
380       ) / double( size[ 1 ] );
381
382     double w = this->WindowLevelInitial[ 0 ] * ( double( 1 ) + sw );
383     double l = this->WindowLevelInitial[ 1 ] * ( double( 1 ) + sl );
384     double minw = this->m_MPRActors->GetMinWindow( );
385     double maxw = this->m_MPRActors->GetMaxWindow( );
386     double minl = this->m_MPRActors->GetMinLevel( );
387     double maxl = this->m_MPRActors->GetMaxLevel( );
388
389     if( w < minw ) w = minw;
390     if( maxw < w ) w = maxw;
391     if( l < minl ) l = minl;
392     if( maxl < l ) l = maxl;
393
394     this->m_MPRActors->SetWindowLevel( w, l );
395     this->Interactor->Render( );
396     this->_RenderAssociateInteractors( );
397   }
398   else if( this->Mode == Self::DeformationMode )
399   {
400     // TODO
401
402   } // fi
403 }
404
405 // -------------------------------------------------------------------------
406 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
407 StartWindowLevel( )
408 {
409   if( this->State != VTKIS_NONE )
410     return;
411   if( this->Mode == Self::NavigationMode )
412   {
413     this->StartState( VTKIS_WINDOW_LEVEL );
414
415     this->WindowLevelInitial[ 0 ] = this->m_MPRActors->GetWindow( );
416     this->WindowLevelInitial[ 1 ] = this->m_MPRActors->GetLevel( );
417   }
418   else if( this->Mode == Self::DeformationMode )
419   {
420     // TODO
421
422   } // fi
423 }
424
425 // -------------------------------------------------------------------------
426 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
427 EndWindowLevel( )
428 {
429   if( this->Mode == Self::NavigationMode )
430   {
431     if( this->State != VTKIS_WINDOW_LEVEL )
432       return;
433     this->StopState( );
434   }
435   else
436   {
437     // TODO
438
439   } // fi
440 }
441
442 // -------------------------------------------------------------------------
443 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
444 StartCursorMoving( )
445 {
446   if( this->CursorMoving )
447     return;
448   this->CursorMoving = true;
449 }
450
451 // -------------------------------------------------------------------------
452 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
453 EndCursorMoving( )
454 {
455   if( !( this->CursorMoving ) )
456     return;
457   this->CursorMoving = false;
458 }
459
460 // -------------------------------------------------------------------------
461 cpPlugins::Extensions::Visualization::ImageInteractorStyle::
462 ImageInteractorStyle( )
463   : Superclass( ),
464     Mode( Self::NavigationMode ),
465     m_SliceActors( NULL ),
466     m_MPRActors( NULL ),
467     CursorMoving( false )
468 {
469   // Orientation marks
470   vtkSmartPointer< vtkAnnotatedCubeActor > cube =
471     vtkSmartPointer< vtkAnnotatedCubeActor >::New( );
472   cube->GetCubeProperty( )->SetColor( 0.9, 0.7, 0.2 );
473   cube->GetTextEdgesProperty( )->SetLineWidth( 1 );
474   cube->GetTextEdgesProperty( )->SetDiffuse( 0 );
475   cube->GetTextEdgesProperty( )->SetAmbient( 1 );
476   cube->GetTextEdgesProperty( )->SetColor( 0.18, 0.28, 0.23 );
477   cube->GetXPlusFaceProperty( )->SetColor( 1, 0, 0 );
478   cube->GetXPlusFaceProperty( )->SetInterpolationToFlat( );
479   cube->GetXMinusFaceProperty( )->SetColor( 1, 0, 0 );
480   cube->GetXMinusFaceProperty( )->SetInterpolationToFlat( );
481   cube->GetYPlusFaceProperty( )->SetColor( 0, 1, 0 );
482   cube->GetYPlusFaceProperty( )->SetInterpolationToFlat( );
483   cube->GetYMinusFaceProperty( )->SetColor( 0, 1, 0 );
484   cube->GetYMinusFaceProperty( )->SetInterpolationToFlat( );
485   cube->GetZPlusFaceProperty( )->SetColor( 0, 0, 1 );
486   cube->GetZPlusFaceProperty( )->SetInterpolationToFlat( );
487   cube->GetZMinusFaceProperty( )->SetColor( 0, 0, 1 );
488   cube->GetZMinusFaceProperty( )->SetInterpolationToFlat( );
489
490   vtkSmartPointer< vtkAxesActor > axes =
491     vtkSmartPointer< vtkAxesActor >::New( );
492   axes->AxisLabelsOff( );
493   axes->SetShaftTypeToCylinder( );
494   axes->SetTotalLength( 2, 2, 2 );
495
496   vtkSmartPointer< vtkPropAssembly > actors =
497     vtkSmartPointer< vtkPropAssembly >::New( );
498   actors->AddPart( cube );
499   actors->AddPart( axes );
500
501   this->OrientationWidget =
502     vtkSmartPointer< vtkOrientationMarkerWidget >::New( );
503   this->OrientationWidget->SetOutlineColor( 0.93, 0.57, 0.13 );
504   this->OrientationWidget->SetOrientationMarker( actors );
505   this->OrientationWidget->SetViewport( 0.0, 0.0, 0.2, 0.2 );
506
507   this->PropPicker = vtkSmartPointer< vtkPropPicker >::New( );
508   this->PropPicker->PickFromListOn( );
509 }
510
511 // -------------------------------------------------------------------------
512 cpPlugins::Extensions::Visualization::ImageInteractorStyle::
513 ~ImageInteractorStyle( )
514 {
515 }
516
517 // -------------------------------------------------------------------------
518 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
519 _RenderAssociateInteractors( )
520 {
521   std::vector< vtkRenderWindowInteractor* >::iterator rIt =
522     this->AssociatedInteractors.begin( );
523   for( ; rIt != this->AssociatedInteractors.end( ); ++rIt )
524     ( *rIt )->Render( );
525 }
526
527 // -------------------------------------------------------------------------
528 bool cpPlugins::Extensions::Visualization::ImageInteractorStyle::
529 _PickPosition( double pos[ 3 ] )
530 {
531   if( this->m_SliceActors == NULL )
532     return( false );
533
534   double x = double( this->Interactor->GetEventPosition( )[ 0 ] );
535   double y = double( this->Interactor->GetEventPosition( )[ 1 ] );
536   this->FindPokedRenderer( x, y );
537   int success =
538     this->PropPicker->Pick( x, y, double( 0 ), this->CurrentRenderer );
539   if( success == 0 )
540     return( false );
541   this->PropPicker->GetPickPosition( pos );
542   return( true );
543 }
544
545 // -------------------------------------------------------------------------
546 void cpPlugins::Extensions::Visualization::ImageInteractorStyle::
547 _UpdateCursor( )
548 {
549   std::cout << "upcur" << std::endl;
550 }
551
552 // eof - $RCSfile$