]> Creatis software - cpMesh.git/blob - appli/InteractiveDeformableMeshSegmentation/InteractorStyleImage.cxx
First commit
[cpMesh.git] / appli / InteractiveDeformableMeshSegmentation / InteractorStyleImage.cxx
1 #include "InteractorStyleImage.h"
2 #include "VolumeActors.h"
3
4 #include <cmath>
5
6 #include <vtkAbstractPropPicker.h>
7 #include <vtkAnnotatedCubeActor.h>
8 #include <vtkAxesActor.h>
9 #include <vtkCamera.h>
10 #include <vtkCommand.h>
11 #include <vtkImageData.h>
12 #include <vtkPropAssembly.h>
13 #include <vtkProperty.h>
14 #include <vtkRendererCollection.h>
15 #include <vtkRenderWindow.h>
16 #include <vtkRenderWindowInteractor.h>
17
18 // -------------------------------------------------------------------------
19 int idms::InteractorStyleImage::SliceEvent = vtkCommand::UserEvent + 1;
20
21 // -------------------------------------------------------------------------
22 idms::InteractorStyleImage::
23 Self* idms::InteractorStyleImage::
24 New( )
25 {
26   return( new Self( ) );
27 }
28
29 // -------------------------------------------------------------------------
30 void idms::InteractorStyleImage::
31 Configure( VolumeActors* actors, const int& axis )
32 {
33   this->Actors = actors;
34   this->Axis = axis;
35   this->SetModeToNavigation( );
36
37   if( axis == 0 )
38     this->PropPicker->AddPickList( actors->GetXPlaneActor( ) );
39   else if( axis == 1 )
40     this->PropPicker->AddPickList( actors->GetYPlaneActor( ) );
41   else // if( axis == 2 )
42     this->PropPicker->AddPickList( actors->GetZPlaneActor( ) );
43
44   this->Modified( );
45 }
46
47 // -------------------------------------------------------------------------
48 void idms::InteractorStyleImage::
49 SetModeToNavigation( )
50 {
51   this->Mode = Self::NavigationMode;
52 }
53
54 // -------------------------------------------------------------------------
55 void idms::InteractorStyleImage::
56 SetModeToDeformation( )
57 {
58   this->Mode = Self::DeformationMode;
59 }
60
61 // -------------------------------------------------------------------------
62 void idms::InteractorStyleImage::
63 SetInteractor( vtkRenderWindowInteractor* rwi )
64 {
65   this->Superclass::SetInteractor( rwi );
66   this->OrientationWidget->SetInteractor( rwi );
67   this->LineWdg->SetInteractor( rwi );
68   if( rwi == NULL )
69     return;
70
71   rwi->SetPicker( this->PropPicker );
72
73   // Enable 2D orientation widget
74   this->OrientationWidget->SetEnabled( 1 );
75   this->OrientationWidget->InteractiveOff( );
76
77   // Disable line widget
78   this->LineWdg->SetEnabled( 0 );
79
80   // Get camera, avoiding segfaults
81   vtkRenderer* ren =
82     rwi->GetRenderWindow( )->GetRenderers( )->GetFirstRenderer( );
83   if( ren == NULL )
84     return;
85   vtkCamera* cam = ren->GetActiveCamera( );
86   if( cam == NULL )
87     return;
88
89   // Parallel projections are better when displaying 2D images
90   cam->ParallelProjectionOn( );
91   cam->SetFocalPoint( double( 0 ), double( 0 ), double( 0 ) );
92   this->Plane->SetOrigin( double( 0 ), double( 0 ), double( 0 ) );
93   if( this->Axis == 0 )
94   {
95     cam->SetPosition( double( 1 ), double( 0 ), double( 0 ) );
96     cam->SetViewUp  ( double( 0 ), double( 1 ), double( 0 ) );
97     this->Plane->SetNormal( double( 1 ), double( 0 ), double( 0 ) );
98   }
99   else if( this->Axis == 1 )
100   {
101     cam->SetPosition( double( 0 ), double( 1 ), double(  0 ) );
102     cam->SetViewUp  ( double( 0 ), double( 0 ), double( -1 ) );
103     this->Plane->SetNormal( double( 0 ), double( 1 ), double( 0 ) );
104   }
105   else // if( this->Axis == 2 )
106   {
107     cam->SetPosition( double( 0 ), double( 0 ), double( 1 ) );
108     cam->SetViewUp  ( double( 0 ), double( 1 ), double( 0 ) );
109     this->Plane->SetNormal( double( 0 ), double( 0 ), double( 1 ) );
110
111   } // fi
112 }
113
114 // -------------------------------------------------------------------------
115 void idms::InteractorStyleImage::
116 OnMouseMove( )
117 {
118   if( this->Mode == Self::DeformationMode )
119     this->_UpdateCursor( );
120
121   // Propagate event
122   this->Superclass::OnMouseMove( );
123 }
124
125 // -------------------------------------------------------------------------
126 void idms::InteractorStyleImage::
127 OnLeftButtonDown( )
128 {
129   if( this->Mode == Self::DeformationMode )
130   {
131     vtkRenderWindowInteractor* rwi = this->GetInteractor( );
132     if( this->Actors != NULL && rwi != NULL )
133     {
134       if( rwi->GetShiftKey( ) == 1 )
135       {
136         this->Actors->GetRegionActor( )->GetProperty( )->SetOpacity( 0.3 );
137         this->UpdatingRegion = true;
138       }
139       else
140         this->Superclass::OnLeftButtonDown( );
141     }
142     else
143       this->Superclass::OnLeftButtonDown( );
144   }
145   else if( this->Mode == Self::NavigationMode )
146     this->Superclass::OnLeftButtonDown( );
147 }
148
149 // -------------------------------------------------------------------------
150 void idms::InteractorStyleImage::
151 OnLeftButtonUp( )
152 {
153   if( this->Mode == Self::DeformationMode )
154   {
155     vtkRenderWindowInteractor* rwi = this->GetInteractor( );
156     if( this->Actors != NULL && rwi != NULL )
157     {
158       if( rwi->GetShiftKey( ) == 1 )
159       {
160         this->Actors->GetRegionActor( )->GetProperty( )->SetOpacity( 0 );
161         this->UpdatingRegion = false;
162       }
163       else
164         this->Superclass::OnLeftButtonUp( );
165     }
166     else
167       this->Superclass::OnLeftButtonUp( );
168   }
169   else if( this->Mode == Self::NavigationMode )
170     this->Superclass::OnLeftButtonUp( );
171 }
172
173 // -------------------------------------------------------------------------
174 void idms::InteractorStyleImage::
175 OnMouseWheelForward( )
176 {
177   vtkRenderWindowInteractor* rwi = this->GetInteractor( );
178   if( this->Actors == NULL || rwi == NULL )
179     return;
180   int off = 1;
181   if( rwi->GetShiftKey( ) == 1 )
182     off *= 10;
183   int s = this->Actors->GetSlice( this->Axis ) + off;
184   int maxs = this->Actors->GetSliceNumberMaxValue( this->Axis );
185   this->Actors->SetSlice( this->Axis, ( s < maxs )? s: maxs );
186   this->Actors->Render( );
187
188   if( this->Mode == Self::DeformationMode )
189     this->_UpdateCursor( );
190
191   this->InvokeEvent( Self::SliceEvent, &( this->Axis ) );
192 }
193
194 // -------------------------------------------------------------------------
195 void idms::InteractorStyleImage::
196 OnMouseWheelBackward( )
197 {
198   vtkRenderWindowInteractor* rwi = this->GetInteractor( );
199   if( this->Actors == NULL || rwi == NULL )
200     return;
201   int off = 1;
202   if( rwi->GetShiftKey( ) == 1 )
203     off *= 10;
204   int s = this->Actors->GetSlice( this->Axis ) - off;
205   int mins = this->Actors->GetSliceNumberMinValue( this->Axis );
206   this->Actors->SetSlice( this->Axis, ( s < mins )? mins: s );
207   this->Actors->Render( );
208
209   if( this->Mode == Self::DeformationMode )
210     this->_UpdateCursor( );
211
212   this->InvokeEvent( Self::SliceEvent, &( this->Axis ) );
213 }
214
215 // -------------------------------------------------------------------------
216 void idms::InteractorStyleImage::
217 OnChar( )
218 {
219   vtkRenderWindowInteractor* rwi = this->GetInteractor( );
220   if( rwi == NULL )
221     return;
222
223   switch( rwi->GetKeyCode( ) )
224   {
225   case 'r': case 'R':
226   {
227     vtkRenderer* ren =
228       rwi->GetRenderWindow( )->GetRenderers( )->GetFirstRenderer( );
229     if( ren != NULL )
230     {
231       double bounds[ 6 ];
232       this->Actors->GetImageBounds( bounds );
233       ren->ResetCamera( bounds );
234       rwi->Render( );
235       
236     } // fi
237   }
238   break;
239   case 'l': case 'L':
240   {
241     this->Actors->ResetWindowLevel( );
242     this->Actors->Render( );
243   }
244   break;
245   case 's': case 'S':
246   {
247     int idx[ 3 ];
248     idx[ 0 ] = this->Actors->GetSlice( 0 );
249     idx[ 1 ] = this->Actors->GetSlice( 1 );
250     idx[ 2 ] = this->Actors->GetSlice( 2 );
251     this->Actors->AddSeed( idx );
252   }
253   break;
254   default:
255     break;
256   } // hctiws
257 }
258
259 // -------------------------------------------------------------------------
260 void idms::InteractorStyleImage::
261 Pan( )
262 {
263   if( this->Mode == Self::DeformationMode )
264   {
265     this->Actors->Render( ); 
266   }
267   else if( this->Mode == Self::NavigationMode )
268     this->Superclass::Pan( );
269 }
270
271 // -------------------------------------------------------------------------
272 void idms::InteractorStyleImage::
273 Spin( )
274 {
275   if( this->Mode == Self::NavigationMode )
276   {
277     double pos[ 3 ];
278     if( this->_PickPosition( pos ) )
279     {
280       if( this->Axis != 0 ) this->Actors->SetSlice( 0, pos[ 0 ] );
281       if( this->Axis != 1 ) this->Actors->SetSlice( 1, pos[ 1 ] );
282       if( this->Axis != 2 ) this->Actors->SetSlice( 2, pos[ 2 ] );
283       this->Actors->Render( );
284
285     } // fi
286   }
287   else if( this->Mode == Self::DeformationMode )
288   {
289     // TODO
290
291   } // fi
292 }
293
294 // -------------------------------------------------------------------------
295 void idms::InteractorStyleImage::
296 StartWindowLevel( )
297 {
298   if( this->Mode == Self::NavigationMode )
299   {
300     if( this->State != VTKIS_NONE )
301       return;
302     this->StartState( VTKIS_WINDOW_LEVEL );
303
304     this->WindowLevelInitial[ 0 ] = this->Actors->GetWindow( );
305     this->WindowLevelInitial[ 1 ] = this->Actors->GetLevel( );
306   }
307   else if( this->Mode == Self::DeformationMode )
308   {
309     // TODO
310
311   } // fi
312 }
313
314 // -------------------------------------------------------------------------
315 void idms::InteractorStyleImage::
316 WindowLevel( )
317 {
318   if( this->Mode == Self::NavigationMode )
319   {
320     vtkRenderWindowInteractor* rwi = this->GetInteractor( );
321     if( rwi == NULL )
322       return;
323     vtkRenderer* ren =
324       rwi->GetRenderWindow( )->GetRenderers( )->GetFirstRenderer( );
325     if( ren == NULL )
326       return;
327
328     // Compute scales
329     this->WindowLevelCurrentPosition[ 0 ] = rwi->GetEventPosition( )[ 0 ];
330     this->WindowLevelCurrentPosition[ 1 ] = rwi->GetEventPosition( )[ 1 ];
331     int* size = ren->GetSize( );
332     double sw = double(
333       this->WindowLevelCurrentPosition[ 0 ] -
334       this->WindowLevelStartPosition[ 0 ]
335       ) / double( size[ 0 ] );
336     double sl = (
337       this->WindowLevelStartPosition[ 1 ] -
338       this->WindowLevelCurrentPosition[ 1 ]
339       ) / double( size[ 1 ] );
340
341     double w = this->WindowLevelInitial[ 0 ] * ( double( 1 ) + sw );
342     double l = this->WindowLevelInitial[ 1 ] * ( double( 1 ) + sl );
343     double minw = this->Actors->GetMinWindow( );
344     double maxw = this->Actors->GetMaxWindow( );
345     double minl = this->Actors->GetMinLevel( );
346     double maxl = this->Actors->GetMaxLevel( );
347
348     if( w < minw ) w = minw;
349     if( maxw < w ) w = maxw;
350     if( l < minl ) l = minl;
351     if( maxl < l ) l = maxl;
352
353     this->Actors->SetWindowLevel( w, l );
354     this->Actors->Render( );
355   }
356   else if( this->Mode == Self::DeformationMode )
357   {
358     // TODO
359
360   } // fi
361 }
362
363 // -------------------------------------------------------------------------
364 idms::InteractorStyleImage::
365 InteractorStyleImage( )
366   : Superclass( ),
367     Mode( Self::NavigationMode ),
368     Actors( NULL ),
369     Axis( 2 )
370 {
371   // Orientation marks
372   vtkSmartPointer< vtkAnnotatedCubeActor > cube =
373     vtkSmartPointer< vtkAnnotatedCubeActor >::New( );
374   cube->GetCubeProperty( )->SetColor( 0.9, 0.7, 0.2 );
375   cube->GetTextEdgesProperty( )->SetLineWidth( 1 );
376   cube->GetTextEdgesProperty( )->SetDiffuse( 0 );
377   cube->GetTextEdgesProperty( )->SetAmbient( 1 );
378   cube->GetTextEdgesProperty( )->SetColor( 0.18, 0.28, 0.23 );
379   cube->GetXPlusFaceProperty( )->SetColor( 1, 0, 0 );
380   cube->GetXPlusFaceProperty( )->SetInterpolationToFlat( );
381   cube->GetXMinusFaceProperty( )->SetColor( 1, 0, 0 );
382   cube->GetXMinusFaceProperty( )->SetInterpolationToFlat( );
383   cube->GetYPlusFaceProperty( )->SetColor( 0, 1, 0 );
384   cube->GetYPlusFaceProperty( )->SetInterpolationToFlat( );
385   cube->GetYMinusFaceProperty( )->SetColor( 0, 1, 0 );
386   cube->GetYMinusFaceProperty( )->SetInterpolationToFlat( );
387   cube->GetZPlusFaceProperty( )->SetColor( 0, 0, 1 );
388   cube->GetZPlusFaceProperty( )->SetInterpolationToFlat( );
389   cube->GetZMinusFaceProperty( )->SetColor( 0, 0, 1 );
390   cube->GetZMinusFaceProperty( )->SetInterpolationToFlat( );
391
392   vtkSmartPointer< vtkAxesActor > axes =
393     vtkSmartPointer< vtkAxesActor >::New( );
394   axes->AxisLabelsOff( );
395   axes->SetShaftTypeToCylinder( );
396   axes->SetTotalLength( 2, 2, 2 );
397
398   vtkSmartPointer< vtkPropAssembly > actors =
399     vtkSmartPointer< vtkPropAssembly >::New( );
400   actors->AddPart( cube );
401   actors->AddPart( axes );
402
403   this->OrientationWidget =
404     vtkSmartPointer< vtkOrientationMarkerWidget >::New( );
405   this->OrientationWidget->SetOutlineColor( 0.93, 0.57, 0.13 );
406   this->OrientationWidget->SetOrientationMarker( actors );
407   this->OrientationWidget->SetViewport( 0.0, 0.0, 0.2, 0.2 );
408
409   this->Plane = vtkSmartPointer< vtkPlane >::New( );
410
411   this->PropPicker = vtkSmartPointer< vtkPropPicker >::New( );
412   this->PropPicker->PickFromListOn( );
413
414   this->LineRep = vtkSmartPointer< vtkLineRepresentation >::New( );
415   this->LineWdg = vtkSmartPointer< vtkLineWidget2 >::New( );
416
417   this->LineWdg->SetRepresentation( this->LineRep );
418 }
419
420 // -------------------------------------------------------------------------
421 idms::InteractorStyleImage::
422 ~InteractorStyleImage( )
423 {
424 }
425
426 // -------------------------------------------------------------------------
427 bool idms::InteractorStyleImage::
428 _PickPosition( double pos[ 3 ] )
429 {
430   vtkRenderWindowInteractor* rwi = this->GetInteractor( );
431   if( this->Actors == NULL || rwi == NULL )
432     return( false );
433   this->FindPokedRenderer(
434     rwi->GetEventPosition( )[ 0 ],
435     rwi->GetEventPosition( )[ 1 ]
436     );
437   int success = rwi->GetPicker( )->Pick(
438     rwi->GetEventPosition( )[ 0 ],
439     rwi->GetEventPosition( )[ 1 ],
440     0.0,
441     this->CurrentRenderer
442     );
443   if( success == 0 )
444     return( false );
445
446   /*
447     vtkAbstractPropPicker* picker =
448     vtkAbstractPropPicker::SafeDownCast( rwi->GetPicker( ) );
449     if( picker != NULL )
450     {
451   */
452   this->PropPicker->GetPickPosition( pos );
453   return( true );
454   /*
455     }
456     else
457     return( false );
458   */
459 }
460
461 // -------------------------------------------------------------------------
462 void idms::InteractorStyleImage::
463 _UpdateCursor( )
464 {
465   double p[ 3 ];
466   if( this->_PickPosition( p ) )
467   {
468     this->Actors->SetCursorPosition( p );
469     if( this->UpdatingRegion )
470       this->Actors->SetRegionRadius( p );
471     else
472       this->Actors->SetRegionPosition( p );
473     this->Actors->RenderAuxiliaryInteractors( );
474
475     /* TODO
476        double c[ 3 ];
477        int i[ 3 ];
478        vtkImageData* img = this->Actors->GetImage( );
479        bool inside = ( img->ComputeStructuredCoordinates( p, i, c ) != 0 );
480        if( inside )
481        {
482        std::cout
483        << i[ 0 ] << " "
484        << i[ 1 ] << " "
485        << i[ 2 ]
486        << std::endl;
487
488        } // fi
489     */
490   } // fi
491 }
492
493 // eof - $RCSfile$