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