]> Creatis software - cpPlugins.git/blob - lib/cpExtensions/Visualization/BaseInteractorStyle.cxx
Intermediary commit
[cpPlugins.git] / lib / cpExtensions / Visualization / BaseInteractorStyle.cxx
1 #include <cpExtensions/Visualization/BaseInteractorStyle.h>
2
3 #include <cmath>
4
5 #include <vtkCallbackCommand.h>
6 #include <vtkCamera.h>
7 #include <vtkRenderer.h>
8 #include <vtkRenderWindowInteractor.h>
9
10 // -------------------------------------------------------------------------
11 const long cpExtensions::Visualization::BaseInteractorStyle::MouseButtonEvent::
12 MAX_DOUBLE_CLICK = 200; // ms
13
14 // -------------------------------------------------------------------------
15 cpExtensions::Visualization::BaseInteractorStyle::
16 Self* cpExtensions::Visualization::BaseInteractorStyle::
17 New( )
18 {
19   return( new Self );
20 }
21
22 // -------------------------------------------------------------------------
23 void cpExtensions::Visualization::BaseInteractorStyle::
24 DelegateTDxEvent( unsigned long event, void* calldata )
25 {
26   // TODO
27   std::cerr << "No TDx support at this time!" << std::endl;
28   std::exit( 1 );
29 }
30
31 // -------------------------------------------------------------------------
32 void cpExtensions::Visualization::BaseInteractorStyle::
33 OnMouseMove( )
34 {
35   // Get current position on the associated actors
36   vtkRenderWindowInteractor* rwi = this->GetInteractor( );
37   if( rwi == NULL )
38     return;
39
40   // Get modifiers
41   bool alt = ( rwi->GetAltKey( ) == 1 );
42   bool ctr = ( rwi->GetControlKey( ) == 1 );
43   bool sft = ( rwi->GetShiftKey( ) == 1 );
44   ButtonID button = this->GetButtonID( );
45
46   // Invoke possible generic events
47   if( button == Self::ButtonID_Right )
48   {
49     if( !alt && !ctr && !sft )
50     {
51       this->FindPokedRenderer(
52         rwi->GetEventPosition( )[ 0 ],
53         rwi->GetEventPosition( )[ 1 ]
54         );
55       this->Dolly( );
56
57     } // fi
58   }
59   else if( button == Self::ButtonID_Middle )
60   {
61     if( !alt && !ctr && !sft )
62     {
63       this->FindPokedRenderer(
64         rwi->GetEventPosition( )[ 0 ],
65         rwi->GetEventPosition( )[ 1 ]
66         );
67       this->Pan( );
68
69     } // fi
70
71   } // fi
72 }
73
74 // -------------------------------------------------------------------------
75 void cpExtensions::Visualization::BaseInteractorStyle::
76 OnLeftButtonDown( )
77 {
78   this->ActiveButton = Self::ButtonID_Left;
79 }
80
81 // -------------------------------------------------------------------------
82 void cpExtensions::Visualization::BaseInteractorStyle::
83 OnLeftButtonUp( )
84 {
85   this->ActiveButton = Self::ButtonID_None;
86 }
87
88 // -------------------------------------------------------------------------
89 void cpExtensions::Visualization::BaseInteractorStyle::
90 OnMiddleButtonDown( )
91 {
92   this->ActiveButton = Self::ButtonID_Middle;
93
94   // Get current position on the associated actors
95   vtkRenderWindowInteractor* rwi = this->GetInteractor( );
96   if( rwi == NULL )
97     return;
98
99   // Get modifiers
100   bool alt = ( rwi->GetAltKey( ) == 1 );
101   bool ctr = ( rwi->GetControlKey( ) == 1 );
102   bool sft = ( rwi->GetShiftKey( ) == 1 );
103
104   if( !alt && !ctr && !sft )
105     this->StartPan( );
106 }
107
108 // -------------------------------------------------------------------------
109 void cpExtensions::Visualization::BaseInteractorStyle::
110 OnMiddleButtonUp( )
111 {
112   this->ActiveButton = Self::ButtonID_None;
113
114   // Get current position on the associated actors
115   vtkRenderWindowInteractor* rwi = this->GetInteractor( );
116   if( rwi == NULL )
117     return;
118
119   // Get modifiers
120   bool alt = ( rwi->GetAltKey( ) == 1 );
121   bool ctr = ( rwi->GetControlKey( ) == 1 );
122   bool sft = ( rwi->GetShiftKey( ) == 1 );
123
124   switch( this->State )
125   {
126   case VTKIS_PAN:
127     this->EndPan( );
128     break;
129   default:
130     break;
131   } // hctiws
132 }
133
134 // -------------------------------------------------------------------------
135 void cpExtensions::Visualization::BaseInteractorStyle::
136 OnRightButtonDown( )
137 {
138   this->ActiveButton = Self::ButtonID_Right;
139
140   // Get current position on the associated actors
141   vtkRenderWindowInteractor* rwi = this->GetInteractor( );
142   if( rwi == NULL )
143     return;
144
145   // Get modifiers
146   bool alt = ( rwi->GetAltKey( ) == 1 );
147   bool ctr = ( rwi->GetControlKey( ) == 1 );
148   bool sft = ( rwi->GetShiftKey( ) == 1 );
149
150   if( !alt && !ctr && !sft )
151     this->StartDolly( );
152 }
153
154 // -------------------------------------------------------------------------
155 void cpExtensions::Visualization::BaseInteractorStyle::
156 OnRightButtonUp( )
157 {
158   this->ActiveButton = Self::ButtonID_None;
159
160   // Get current position on the associated actors
161   vtkRenderWindowInteractor* rwi = this->GetInteractor( );
162   if( rwi == NULL )
163     return;
164
165   // Get modifiers
166   bool alt = ( rwi->GetAltKey( ) == 1 );
167   bool ctr = ( rwi->GetControlKey( ) == 1 );
168   bool sft = ( rwi->GetShiftKey( ) == 1 );
169
170   switch( this->State )
171   {
172   case VTKIS_DOLLY:
173     this->EndDolly( );
174     break;
175   default:
176     break;
177   } // hctiws
178 }
179
180 // -------------------------------------------------------------------------
181 void cpExtensions::Visualization::BaseInteractorStyle::
182 Dolly( )
183 {
184   if( this->CurrentRenderer == NULL )
185     return;
186
187   vtkRenderWindowInteractor* rwi = this->GetInteractor( );
188   double *center = this->CurrentRenderer->GetCenter( );
189   int dy = rwi->GetEventPosition( )[ 1 ] - rwi->GetLastEventPosition( )[ 1 ];
190   double dyf = this->MotionFactor * dy / center[ 1 ];
191   this->_Dolly( std::pow( 1.1, dyf ) );
192 }
193
194 // -------------------------------------------------------------------------
195 void cpExtensions::Visualization::BaseInteractorStyle::
196 Pan( )
197 {
198   if( this->CurrentRenderer == NULL )
199     return;
200
201   vtkRenderWindowInteractor* rwi = this->Interactor;
202   double viewFocus[ 4 ], focalDepth, viewPoint[ 3 ];
203   double newPickPoint[ 4 ], oldPickPoint[ 4 ], motionVector[ 3 ];
204
205   // Calculate the focal depth since we'll be using it a lot
206   vtkCamera* camera = this->CurrentRenderer->GetActiveCamera( );
207   camera->GetFocalPoint( viewFocus );
208   this->ComputeWorldToDisplay(
209     viewFocus[ 0 ], viewFocus[ 1 ], viewFocus[ 2 ], viewFocus
210     );
211   focalDepth = viewFocus[ 2 ];
212   this->ComputeDisplayToWorld(
213     rwi->GetEventPosition( )[ 0 ],
214     rwi->GetEventPosition( )[ 1 ],
215     focalDepth,
216     newPickPoint
217     );
218
219   // Has to recalc old mouse point since the viewport has moved,
220   // so can't move it outside the loop
221   this->ComputeDisplayToWorld(
222     rwi->GetLastEventPosition( )[ 0 ],
223     rwi->GetLastEventPosition( )[ 1 ],
224     focalDepth,
225     oldPickPoint
226     );
227
228   // Camera motion is reversed
229   motionVector[ 0 ] = oldPickPoint[ 0 ] - newPickPoint[ 0 ];
230   motionVector[ 1 ] = oldPickPoint[ 1 ] - newPickPoint[ 1 ];
231   motionVector[ 2 ] = oldPickPoint[ 2 ] - newPickPoint[ 2 ];
232
233   camera->GetFocalPoint( viewFocus );
234   camera->GetPosition( viewPoint );
235   camera->SetFocalPoint(
236     motionVector[ 0 ] + viewFocus[ 0 ],
237     motionVector[ 1 ] + viewFocus[ 1 ],
238     motionVector[ 2 ] + viewFocus[ 2 ]
239     );
240   camera->SetPosition(
241     motionVector[ 0 ] + viewPoint[ 0 ],
242     motionVector[ 1 ] + viewPoint[ 1 ],
243     motionVector[ 2 ] + viewPoint[ 2 ]
244     );
245   if( rwi->GetLightFollowCamera( ) )
246     this->CurrentRenderer->UpdateLightsGeometryToFollowCamera( );
247   rwi->Render( );
248 }
249
250 // -------------------------------------------------------------------------
251 cpExtensions::Visualization::BaseInteractorStyle::
252 BaseInteractorStyle( )
253   : Superclass( ),
254     MotionFactor( double( 10 ) )
255 {
256   this->LeftButtonEvent.Reset( );
257   this->MiddleButtonEvent.Reset( );
258   this->RightButtonEvent.Reset( );
259   this->ActiveButton = Self::ButtonID_None;
260
261   this->EventCallbackCommand->SetCallback( Self::_ProcessEvents );
262 }
263
264 // -------------------------------------------------------------------------
265 cpExtensions::Visualization::BaseInteractorStyle::
266 ~BaseInteractorStyle( )
267 {
268 }
269
270 // -------------------------------------------------------------------------
271 void cpExtensions::Visualization::BaseInteractorStyle::
272 _Dolly( double factor )
273 {
274   if( this->CurrentRenderer == NULL )
275     return;
276
277   vtkCamera* camera = this->CurrentRenderer->GetActiveCamera( );
278   if( camera->GetParallelProjection( ) == 0 )
279   {
280     camera->Dolly( factor );
281     if( this->AutoAdjustCameraClippingRange )
282       this->CurrentRenderer->ResetCameraClippingRange( );
283   }
284   else
285     camera->SetParallelScale( camera->GetParallelScale( ) / factor );
286   if( this->Interactor->GetLightFollowCamera( ) )
287     this->CurrentRenderer->UpdateLightsGeometryToFollowCamera( );
288   this->Interactor->Render( );
289 }
290
291 // -------------------------------------------------------------------------
292 void cpExtensions::Visualization::BaseInteractorStyle::
293 _ProcessEvents(
294   vtkObject* object,
295   unsigned long event,
296   void* clientdata,
297   void* calldata
298   )
299 {
300   // Get active style and interactor
301   Self* s = reinterpret_cast< Self* >( clientdata );
302   if( s == NULL )
303     return;
304
305   // Process events
306   switch( event )
307   {
308   case vtkCommand::MouseMoveEvent:
309   {
310     s->OnMouseMove( );
311   }
312   break;
313   case vtkCommand::LeftButtonPressEvent:
314   {
315     unsigned char nc = s->LeftButtonEvent.Clicks( );
316     if( nc == 2 )
317       s->OnLeftDoubleClick( );
318     else if( nc == 1 )
319       s->OnLeftClick( );
320     s->OnLeftButtonDown( );
321   }
322   break;
323   case vtkCommand::LeftButtonReleaseEvent:
324   {
325     s->LeftButtonEvent.Release( );
326     s->OnLeftButtonUp( );
327   }
328   break;
329   case vtkCommand::MiddleButtonPressEvent:
330   {
331     unsigned char nc = s->MiddleButtonEvent.Clicks( );
332     if( nc == 2 )
333       s->OnMiddleDoubleClick( );
334     else if( nc == 1 )
335       s->OnMiddleClick( );
336     s->OnMiddleButtonDown( );
337   }
338   break;
339   case vtkCommand::MiddleButtonReleaseEvent:
340   {
341     s->MiddleButtonEvent.Release( );
342     s->OnMiddleButtonUp( );
343   }
344   break;
345   case vtkCommand::RightButtonPressEvent:
346   {
347     unsigned char nc = s->RightButtonEvent.Clicks( );
348     if( nc == 2 )
349       s->OnRightDoubleClick( );
350     else if( nc == 1 )
351       s->OnRightClick( );
352     s->OnRightButtonDown( );
353   }
354   break;
355   case vtkCommand::RightButtonReleaseEvent:
356   {
357     s->RightButtonEvent.Release( );
358     s->OnRightButtonUp( );
359   }
360   break;
361   case vtkCommand::MouseWheelForwardEvent:
362   {
363     s->OnMouseWheelForward( );
364   }
365   break;
366   case vtkCommand::MouseWheelBackwardEvent:
367   {
368     s->OnMouseWheelBackward( );
369   }
370   break;
371   case vtkCommand::KeyPressEvent:
372   {
373     s->OnKeyDown( );
374     s->OnKeyPress( );
375   }
376   break;
377   case vtkCommand::KeyReleaseEvent:
378   {
379     s->OnKeyUp( );
380     s->OnKeyRelease( );
381   }
382   break;
383   case vtkCommand::CharEvent:
384   {
385     s->OnChar( );
386   }
387   break;
388   case vtkCommand::ExposeEvent:
389   {
390     s->OnExpose( );
391   }
392   break;
393   case vtkCommand::ConfigureEvent:
394   {
395     s->OnConfigure( );
396   }
397   break;
398   case vtkCommand::EnterEvent:
399   {
400     s->OnEnter( );
401   }
402   break;
403   case vtkCommand::LeaveEvent:
404   {
405     s->OnLeave( );
406   }
407   break;
408   case vtkCommand::TimerEvent:
409   {
410     // Do nothing
411   }
412   break;
413   case vtkCommand::DeleteEvent:
414   {
415     s->SetInteractor( 0 );
416   }
417   break;
418   case vtkCommand::TDxMotionEvent:
419   case vtkCommand::TDxButtonPressEvent:
420   case vtkCommand::TDxButtonReleaseEvent:
421   {
422     s->DelegateTDxEvent( event, calldata );
423   }
424   break;
425   default:
426     break;
427   } // hctiws
428 }
429
430 // eof - $RCSfile$