1 #include <cpExtensions/Interaction/BaseInteractorStyle.h>
5 #include <vtkCallbackCommand.h>
7 #include <vtkRenderer.h>
8 #include <vtkRenderWindowInteractor.h>
10 // -------------------------------------------------------------------------
11 long cpExtensions::Interaction::BaseInteractorStyle::_TMouseButtonEvent::
12 MaxDoubleClick = 350; // ms
14 // -------------------------------------------------------------------------
15 void cpExtensions::Interaction::BaseInteractorStyle::
16 SetSetDoubleClickDelay( long delay )
18 Self::_TMouseButtonEvent::MaxDoubleClick = delay;
21 // -------------------------------------------------------------------------
22 void cpExtensions::Interaction::BaseInteractorStyle::
23 DelegateTDxEvent( unsigned long event, void* calldata )
26 std::cerr << "No TDx support at this time!" << std::endl;
30 // -------------------------------------------------------------------------
31 void cpExtensions::Interaction::BaseInteractorStyle::
34 // Get current position on the associated actors
35 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
40 bool alt = ( rwi->GetAltKey( ) == 1 );
41 bool ctr = ( rwi->GetControlKey( ) == 1 );
42 bool sft = ( rwi->GetShiftKey( ) == 1 );
43 ButtonID button = this->GetButtonID( );
45 // Invoke possible generic events
46 if( button == Self::ButtonID_Right )
48 if( !alt && !ctr && !sft )
50 this->FindPokedRenderer(
51 rwi->GetEventPosition( )[ 0 ],
52 rwi->GetEventPosition( )[ 1 ]
58 else if( button == Self::ButtonID_Middle )
60 if( !alt && !ctr && !sft )
62 this->FindPokedRenderer(
63 rwi->GetEventPosition( )[ 0 ],
64 rwi->GetEventPosition( )[ 1 ]
72 // Get mouse pointer position
74 static double pos[ 3 ];
75 if( !( this->_PickPosition( idx, pos ) ) )
78 // Invoke possible specialized events
79 auto i = this->m_MouseMoveCommands.begin( );
80 for( ; i != this->m_MouseMoveCommands.end( ); ++i )
81 i->first( i->second, button, idx, pos, alt, ctr, sft );
84 // -------------------------------------------------------------------------
85 void cpExtensions::Interaction::BaseInteractorStyle::
86 OnMouseWheelForward( )
88 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
92 // Invoke possible events
93 auto i = this->m_MouseWheelCommands.begin( );
94 for( ; i != this->m_MouseWheelCommands.end( ); ++i )
97 rwi->GetAltKey( ) == 1,
98 rwi->GetControlKey( ) == 1,
99 rwi->GetShiftKey( ) == 1
103 // -------------------------------------------------------------------------
104 void cpExtensions::Interaction::BaseInteractorStyle::
105 OnMouseWheelBackward( )
107 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
111 // Invoke possible events
112 auto i = this->m_MouseWheelCommands.begin( );
113 for( ; i != this->m_MouseWheelCommands.end( ); ++i )
116 rwi->GetAltKey( ) == 1,
117 rwi->GetControlKey( ) == 1,
118 rwi->GetShiftKey( ) == 1
122 // -------------------------------------------------------------------------
123 void cpExtensions::Interaction::BaseInteractorStyle::
126 this->m_ActiveButton = Self::ButtonID_Left;
129 // -------------------------------------------------------------------------
130 void cpExtensions::Interaction::BaseInteractorStyle::
133 this->m_ActiveButton = Self::ButtonID_None;
136 // -------------------------------------------------------------------------
137 void cpExtensions::Interaction::BaseInteractorStyle::
138 OnMiddleButtonDown( )
140 this->m_ActiveButton = Self::ButtonID_Middle;
142 // Get current position on the associated actors
143 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
148 bool alt = ( rwi->GetAltKey( ) == 1 );
149 bool ctr = ( rwi->GetControlKey( ) == 1 );
150 bool sft = ( rwi->GetShiftKey( ) == 1 );
152 if( !alt && !ctr && !sft )
156 // -------------------------------------------------------------------------
157 void cpExtensions::Interaction::BaseInteractorStyle::
160 this->m_ActiveButton = Self::ButtonID_None;
162 // Get current position on the associated actors
163 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
168 bool alt = ( rwi->GetAltKey( ) == 1 );
169 bool ctr = ( rwi->GetControlKey( ) == 1 );
170 bool sft = ( rwi->GetShiftKey( ) == 1 );
172 switch( this->State )
182 // -------------------------------------------------------------------------
183 void cpExtensions::Interaction::BaseInteractorStyle::
186 this->m_ActiveButton = Self::ButtonID_Right;
188 // Get current position on the associated actors
189 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
194 bool alt = ( rwi->GetAltKey( ) == 1 );
195 bool ctr = ( rwi->GetControlKey( ) == 1 );
196 bool sft = ( rwi->GetShiftKey( ) == 1 );
198 if( !alt && !ctr && !sft )
202 // -------------------------------------------------------------------------
203 void cpExtensions::Interaction::BaseInteractorStyle::
206 this->m_ActiveButton = Self::ButtonID_None;
208 // Get current position on the associated actors
209 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
214 bool alt = ( rwi->GetAltKey( ) == 1 );
215 bool ctr = ( rwi->GetControlKey( ) == 1 );
216 bool sft = ( rwi->GetShiftKey( ) == 1 );
218 switch( this->State )
228 // -------------------------------------------------------------------------
229 #define cpExtensions_BaseInteractorStyle_Click( S, T ) \
230 void cpExtensions::Interaction::BaseInteractorStyle:: \
233 vtkRenderWindowInteractor* rwi = this->GetInteractor( ); \
236 static int idx[ 2 ]; \
237 static double pos[ 3 ]; \
238 if( !( this->_PickPosition( idx, pos ) ) ) \
240 auto i = this->m_Mouse##T##Commands.begin( ); \
241 for( ; i != this->m_Mouse##T##Commands.end( ); ++i ) \
244 Self::ButtonID_##S, \
246 rwi->GetAltKey( ) == 1, \
247 rwi->GetControlKey( ) == 1, \
248 rwi->GetShiftKey( ) == 1 \
252 cpExtensions_BaseInteractorStyle_Click( Left, Click );
253 cpExtensions_BaseInteractorStyle_Click( Middle, Click );
254 cpExtensions_BaseInteractorStyle_Click( Right, Click );
255 cpExtensions_BaseInteractorStyle_Click( Left, DoubleClick );
256 cpExtensions_BaseInteractorStyle_Click( Middle, DoubleClick );
257 cpExtensions_BaseInteractorStyle_Click( Right, DoubleClick );
259 // -------------------------------------------------------------------------
260 void cpExtensions::Interaction::BaseInteractorStyle::
263 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
267 // Invoke possible events
268 auto i = this->m_KeyCommands.begin( );
269 for( ; i != this->m_KeyCommands.end( ); ++i )
270 i->first( i->second, rwi->GetKeyCode( ) );
273 // -------------------------------------------------------------------------
274 #define cpExtensions_BaseInteractorStyle_Global( N ) \
275 void cpExtensions::Interaction::BaseInteractorStyle:: \
278 vtkRenderWindowInteractor* rwi = this->GetInteractor( ); \
281 auto i = this->m_##N##Commands.begin( ); \
282 for( ; i != this->m_##N##Commands.end( ); ++i ) \
283 i->first( i->second ); \
286 cpExtensions_BaseInteractorStyle_Global( Expose );
287 cpExtensions_BaseInteractorStyle_Global( Configure );
288 cpExtensions_BaseInteractorStyle_Global( Enter );
289 cpExtensions_BaseInteractorStyle_Global( Leave );
291 // -------------------------------------------------------------------------
292 void cpExtensions::Interaction::BaseInteractorStyle::
295 if( this->CurrentRenderer == NULL )
298 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
299 double *center = this->CurrentRenderer->GetCenter( );
300 int dy = rwi->GetEventPosition( )[ 1 ] - rwi->GetLastEventPosition( )[ 1 ];
301 double dyf = this->m_MotionFactor * dy / center[ 1 ];
302 this->_Dolly( std::pow( 1.1, dyf ) );
305 // -------------------------------------------------------------------------
306 void cpExtensions::Interaction::BaseInteractorStyle::
309 if( this->CurrentRenderer == NULL )
312 vtkRenderWindowInteractor* rwi = this->Interactor;
313 double viewFocus[ 4 ], focalDepth, viewPoint[ 3 ];
314 double newPickPoint[ 4 ], oldPickPoint[ 4 ], motionVector[ 3 ];
316 // Calculate the focal depth since we'll be using it a lot
317 vtkCamera* camera = this->CurrentRenderer->GetActiveCamera( );
318 camera->GetFocalPoint( viewFocus );
319 this->ComputeWorldToDisplay(
320 viewFocus[ 0 ], viewFocus[ 1 ], viewFocus[ 2 ], viewFocus
322 focalDepth = viewFocus[ 2 ];
323 this->ComputeDisplayToWorld(
324 rwi->GetEventPosition( )[ 0 ],
325 rwi->GetEventPosition( )[ 1 ],
330 // Has to recalc old mouse point since the viewport has moved,
331 // so can't move it outside the loop
332 this->ComputeDisplayToWorld(
333 rwi->GetLastEventPosition( )[ 0 ],
334 rwi->GetLastEventPosition( )[ 1 ],
339 // Camera motion is reversed
340 motionVector[ 0 ] = oldPickPoint[ 0 ] - newPickPoint[ 0 ];
341 motionVector[ 1 ] = oldPickPoint[ 1 ] - newPickPoint[ 1 ];
342 motionVector[ 2 ] = oldPickPoint[ 2 ] - newPickPoint[ 2 ];
344 camera->GetFocalPoint( viewFocus );
345 camera->GetPosition( viewPoint );
346 camera->SetFocalPoint(
347 motionVector[ 0 ] + viewFocus[ 0 ],
348 motionVector[ 1 ] + viewFocus[ 1 ],
349 motionVector[ 2 ] + viewFocus[ 2 ]
352 motionVector[ 0 ] + viewPoint[ 0 ],
353 motionVector[ 1 ] + viewPoint[ 1 ],
354 motionVector[ 2 ] + viewPoint[ 2 ]
356 if( rwi->GetLightFollowCamera( ) )
357 this->CurrentRenderer->UpdateLightsGeometryToFollowCamera( );
361 // -------------------------------------------------------------------------
362 cpExtensions::Interaction::BaseInteractorStyle::
363 BaseInteractorStyle( )
365 m_MotionFactor( double( 10 ) )
367 this->m_LeftButtonEvent.Reset( );
368 this->m_MiddleButtonEvent.Reset( );
369 this->m_RightButtonEvent.Reset( );
370 this->m_ActiveButton = Self::ButtonID_None;
372 this->EventCallbackCommand->SetCallback( Self::_ProcessEvents );
375 // -------------------------------------------------------------------------
376 cpExtensions::Interaction::BaseInteractorStyle::
377 ~BaseInteractorStyle( )
381 // -------------------------------------------------------------------------
382 void cpExtensions::Interaction::BaseInteractorStyle::
383 _Dolly( double factor )
385 if( this->CurrentRenderer == NULL )
388 vtkCamera* camera = this->CurrentRenderer->GetActiveCamera( );
389 if( camera->GetParallelProjection( ) == 0 )
391 camera->Dolly( factor );
392 if( this->AutoAdjustCameraClippingRange )
393 this->CurrentRenderer->ResetCameraClippingRange( );
396 camera->SetParallelScale( camera->GetParallelScale( ) / factor );
397 if( this->Interactor->GetLightFollowCamera( ) )
398 this->CurrentRenderer->UpdateLightsGeometryToFollowCamera( );
399 this->Interactor->Render( );
402 // -------------------------------------------------------------------------
403 void cpExtensions::Interaction::BaseInteractorStyle::
411 // Get active style and interactor
412 Self* s = reinterpret_cast< Self* >( clientdata );
419 case vtkCommand::MouseMoveEvent:
424 case vtkCommand::LeftButtonPressEvent:
426 unsigned char nc = s->m_LeftButtonEvent.Clicks( );
428 s->OnLeftDoubleClick( );
431 s->OnLeftButtonDown( );
434 case vtkCommand::LeftButtonReleaseEvent:
436 s->m_LeftButtonEvent.Release( );
437 s->OnLeftButtonUp( );
440 case vtkCommand::MiddleButtonPressEvent:
442 unsigned char nc = s->m_MiddleButtonEvent.Clicks( );
444 s->OnMiddleDoubleClick( );
447 s->OnMiddleButtonDown( );
450 case vtkCommand::MiddleButtonReleaseEvent:
452 s->m_MiddleButtonEvent.Release( );
453 s->OnMiddleButtonUp( );
456 case vtkCommand::RightButtonPressEvent:
458 unsigned char nc = s->m_RightButtonEvent.Clicks( );
460 s->OnRightDoubleClick( );
463 s->OnRightButtonDown( );
466 case vtkCommand::RightButtonReleaseEvent:
468 s->m_RightButtonEvent.Release( );
469 s->OnRightButtonUp( );
472 case vtkCommand::MouseWheelForwardEvent:
474 s->OnMouseWheelForward( );
477 case vtkCommand::MouseWheelBackwardEvent:
479 s->OnMouseWheelBackward( );
482 case vtkCommand::KeyPressEvent:
488 case vtkCommand::KeyReleaseEvent:
494 case vtkCommand::CharEvent:
499 case vtkCommand::ExposeEvent:
504 case vtkCommand::ConfigureEvent:
509 case vtkCommand::EnterEvent:
514 case vtkCommand::LeaveEvent:
519 case vtkCommand::TimerEvent:
524 case vtkCommand::DeleteEvent:
526 s->SetInteractor( 0 );
529 case vtkCommand::TDxMotionEvent:
530 case vtkCommand::TDxButtonPressEvent:
531 case vtkCommand::TDxButtonReleaseEvent:
533 s->DelegateTDxEvent( event, calldata );