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 vtkObject* cpExtensions::Interaction::BaseInteractorStyle::
23 GetAssociatedObject( )
25 return( this->m_AssociatedObject );
28 // -------------------------------------------------------------------------
29 const vtkObject* cpExtensions::Interaction::BaseInteractorStyle::
30 GetAssociatedObject( ) const
32 return( this->m_AssociatedObject );
35 // -------------------------------------------------------------------------
36 void cpExtensions::Interaction::BaseInteractorStyle::
37 SetAssociatedObject( vtkObject* obj )
39 if( this->m_AssociatedObject != obj )
41 this->m_AssociatedObject = obj;
47 // -------------------------------------------------------------------------
48 void cpExtensions::Interaction::BaseInteractorStyle::
49 DelegateTDxEvent( unsigned long event, void* calldata )
52 std::cerr << "No TDx support at this time!" << std::endl;
56 // -------------------------------------------------------------------------
57 void cpExtensions::Interaction::BaseInteractorStyle::
60 // Get current position on the associated actors
61 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
66 bool alt = ( rwi->GetAltKey( ) == 1 );
67 bool ctr = ( rwi->GetControlKey( ) == 1 );
68 bool sft = ( rwi->GetShiftKey( ) == 1 );
69 ButtonID button = this->GetButtonID( );
71 // Invoke possible generic events
72 if( button == Self::ButtonID_Right )
74 if( !alt && !ctr && !sft )
76 this->FindPokedRenderer(
77 rwi->GetEventPosition( )[ 0 ],
78 rwi->GetEventPosition( )[ 1 ]
84 else if( button == Self::ButtonID_Middle )
86 if( !alt && !ctr && !sft )
88 this->FindPokedRenderer(
89 rwi->GetEventPosition( )[ 0 ],
90 rwi->GetEventPosition( )[ 1 ]
98 // Get mouse pointer position
100 static double pos[ 3 ];
101 if( !( this->_PickPosition( idx, pos ) ) )
104 // Invoke possible specialized events
105 auto i = this->m_MouseMoveCommands.begin( );
106 for( ; i != this->m_MouseMoveCommands.end( ); ++i )
107 i->first( i->second, button, idx, pos, alt, ctr, sft );
110 // -------------------------------------------------------------------------
111 void cpExtensions::Interaction::BaseInteractorStyle::
112 OnMouseWheelForward( )
114 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
118 // Invoke possible events
119 auto i = this->m_MouseWheelCommands.begin( );
120 for( ; i != this->m_MouseWheelCommands.end( ); ++i )
123 rwi->GetAltKey( ) == 1,
124 rwi->GetControlKey( ) == 1,
125 rwi->GetShiftKey( ) == 1
129 // -------------------------------------------------------------------------
130 void cpExtensions::Interaction::BaseInteractorStyle::
131 OnMouseWheelBackward( )
133 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
137 // Invoke possible events
138 auto i = this->m_MouseWheelCommands.begin( );
139 for( ; i != this->m_MouseWheelCommands.end( ); ++i )
142 rwi->GetAltKey( ) == 1,
143 rwi->GetControlKey( ) == 1,
144 rwi->GetShiftKey( ) == 1
148 // -------------------------------------------------------------------------
149 void cpExtensions::Interaction::BaseInteractorStyle::
152 this->m_ActiveButton = Self::ButtonID_Left;
155 // -------------------------------------------------------------------------
156 void cpExtensions::Interaction::BaseInteractorStyle::
159 this->m_ActiveButton = Self::ButtonID_None;
162 // -------------------------------------------------------------------------
163 void cpExtensions::Interaction::BaseInteractorStyle::
164 OnMiddleButtonDown( )
166 this->m_ActiveButton = Self::ButtonID_Middle;
168 // Get current position on the associated actors
169 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
174 bool alt = ( rwi->GetAltKey( ) == 1 );
175 bool ctr = ( rwi->GetControlKey( ) == 1 );
176 bool sft = ( rwi->GetShiftKey( ) == 1 );
178 if( !alt && !ctr && !sft )
182 // -------------------------------------------------------------------------
183 void cpExtensions::Interaction::BaseInteractorStyle::
186 this->m_ActiveButton = Self::ButtonID_None;
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 switch( this->State )
208 // -------------------------------------------------------------------------
209 void cpExtensions::Interaction::BaseInteractorStyle::
212 this->m_ActiveButton = Self::ButtonID_Right;
214 // Get current position on the associated actors
215 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
220 bool alt = ( rwi->GetAltKey( ) == 1 );
221 bool ctr = ( rwi->GetControlKey( ) == 1 );
222 bool sft = ( rwi->GetShiftKey( ) == 1 );
224 if( !alt && !ctr && !sft )
228 // -------------------------------------------------------------------------
229 void cpExtensions::Interaction::BaseInteractorStyle::
232 this->m_ActiveButton = Self::ButtonID_None;
234 // Get current position on the associated actors
235 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
240 bool alt = ( rwi->GetAltKey( ) == 1 );
241 bool ctr = ( rwi->GetControlKey( ) == 1 );
242 bool sft = ( rwi->GetShiftKey( ) == 1 );
244 switch( this->State )
254 // -------------------------------------------------------------------------
255 #define cpExtensions_BaseInteractorStyle_Click( S, T ) \
256 void cpExtensions::Interaction::BaseInteractorStyle:: \
259 vtkRenderWindowInteractor* rwi = this->GetInteractor( ); \
262 static int idx[ 2 ]; \
263 static double pos[ 3 ]; \
264 if( !( this->_PickPosition( idx, pos ) ) ) \
266 auto i = this->m_Mouse##T##Commands.begin( ); \
267 for( ; i != this->m_Mouse##T##Commands.end( ); ++i ) \
270 Self::ButtonID_##S, \
272 rwi->GetAltKey( ) == 1, \
273 rwi->GetControlKey( ) == 1, \
274 rwi->GetShiftKey( ) == 1 \
278 cpExtensions_BaseInteractorStyle_Click( Left, Click );
279 cpExtensions_BaseInteractorStyle_Click( Middle, Click );
280 cpExtensions_BaseInteractorStyle_Click( Right, Click );
281 cpExtensions_BaseInteractorStyle_Click( Left, DoubleClick );
282 cpExtensions_BaseInteractorStyle_Click( Middle, DoubleClick );
283 cpExtensions_BaseInteractorStyle_Click( Right, DoubleClick );
285 // -------------------------------------------------------------------------
286 void cpExtensions::Interaction::BaseInteractorStyle::
289 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
293 // Invoke possible events
294 auto i = this->m_KeyCommands.begin( );
295 for( ; i != this->m_KeyCommands.end( ); ++i )
296 i->first( i->second, rwi->GetKeyCode( ) );
299 // -------------------------------------------------------------------------
300 #define cpExtensions_BaseInteractorStyle_Global( N ) \
301 void cpExtensions::Interaction::BaseInteractorStyle:: \
304 vtkRenderWindowInteractor* rwi = this->GetInteractor( ); \
307 auto i = this->m_##N##Commands.begin( ); \
308 for( ; i != this->m_##N##Commands.end( ); ++i ) \
309 i->first( i->second ); \
312 cpExtensions_BaseInteractorStyle_Global( Expose );
313 cpExtensions_BaseInteractorStyle_Global( Configure );
314 cpExtensions_BaseInteractorStyle_Global( Enter );
315 cpExtensions_BaseInteractorStyle_Global( Leave );
317 // -------------------------------------------------------------------------
318 void cpExtensions::Interaction::BaseInteractorStyle::
321 if( this->CurrentRenderer == NULL )
324 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
325 double *center = this->CurrentRenderer->GetCenter( );
326 int dy = rwi->GetEventPosition( )[ 1 ] - rwi->GetLastEventPosition( )[ 1 ];
327 double dyf = this->m_MotionFactor * dy / center[ 1 ];
328 this->_Dolly( std::pow( 1.1, dyf ) );
331 // -------------------------------------------------------------------------
332 void cpExtensions::Interaction::BaseInteractorStyle::
335 if( this->CurrentRenderer == NULL )
338 vtkRenderWindowInteractor* rwi = this->Interactor;
339 double viewFocus[ 4 ], focalDepth, viewPoint[ 3 ];
340 double newPickPoint[ 4 ], oldPickPoint[ 4 ], motionVector[ 3 ];
342 // Calculate the focal depth since we'll be using it a lot
343 vtkCamera* camera = this->CurrentRenderer->GetActiveCamera( );
344 camera->GetFocalPoint( viewFocus );
345 this->ComputeWorldToDisplay(
346 viewFocus[ 0 ], viewFocus[ 1 ], viewFocus[ 2 ], viewFocus
348 focalDepth = viewFocus[ 2 ];
349 this->ComputeDisplayToWorld(
350 rwi->GetEventPosition( )[ 0 ],
351 rwi->GetEventPosition( )[ 1 ],
356 // Has to recalc old mouse point since the viewport has moved,
357 // so can't move it outside the loop
358 this->ComputeDisplayToWorld(
359 rwi->GetLastEventPosition( )[ 0 ],
360 rwi->GetLastEventPosition( )[ 1 ],
365 // Camera motion is reversed
366 motionVector[ 0 ] = oldPickPoint[ 0 ] - newPickPoint[ 0 ];
367 motionVector[ 1 ] = oldPickPoint[ 1 ] - newPickPoint[ 1 ];
368 motionVector[ 2 ] = oldPickPoint[ 2 ] - newPickPoint[ 2 ];
370 camera->GetFocalPoint( viewFocus );
371 camera->GetPosition( viewPoint );
372 camera->SetFocalPoint(
373 motionVector[ 0 ] + viewFocus[ 0 ],
374 motionVector[ 1 ] + viewFocus[ 1 ],
375 motionVector[ 2 ] + viewFocus[ 2 ]
378 motionVector[ 0 ] + viewPoint[ 0 ],
379 motionVector[ 1 ] + viewPoint[ 1 ],
380 motionVector[ 2 ] + viewPoint[ 2 ]
382 if( rwi->GetLightFollowCamera( ) )
383 this->CurrentRenderer->UpdateLightsGeometryToFollowCamera( );
387 // -------------------------------------------------------------------------
388 cpExtensions::Interaction::BaseInteractorStyle::
389 BaseInteractorStyle( )
391 m_AssociatedObject( NULL ),
392 m_MotionFactor( double( 10 ) )
394 this->m_LeftButtonEvent.Reset( );
395 this->m_MiddleButtonEvent.Reset( );
396 this->m_RightButtonEvent.Reset( );
397 this->m_ActiveButton = Self::ButtonID_None;
399 this->EventCallbackCommand->SetCallback( Self::_ProcessEvents );
402 // -------------------------------------------------------------------------
403 cpExtensions::Interaction::BaseInteractorStyle::
404 ~BaseInteractorStyle( )
408 // -------------------------------------------------------------------------
409 void cpExtensions::Interaction::BaseInteractorStyle::
410 _Dolly( double factor )
412 if( this->CurrentRenderer == NULL )
415 vtkCamera* camera = this->CurrentRenderer->GetActiveCamera( );
416 if( camera->GetParallelProjection( ) == 0 )
418 camera->Dolly( factor );
419 if( this->AutoAdjustCameraClippingRange )
420 this->CurrentRenderer->ResetCameraClippingRange( );
423 camera->SetParallelScale( camera->GetParallelScale( ) / factor );
424 if( this->Interactor->GetLightFollowCamera( ) )
425 this->CurrentRenderer->UpdateLightsGeometryToFollowCamera( );
426 this->Interactor->Render( );
429 // -------------------------------------------------------------------------
430 void cpExtensions::Interaction::BaseInteractorStyle::
438 // Get active style and interactor
439 Self* s = reinterpret_cast< Self* >( clientdata );
446 case vtkCommand::MouseMoveEvent:
451 case vtkCommand::LeftButtonPressEvent:
453 unsigned char nc = s->m_LeftButtonEvent.Clicks( );
455 s->OnLeftDoubleClick( );
458 s->OnLeftButtonDown( );
461 case vtkCommand::LeftButtonReleaseEvent:
463 s->m_LeftButtonEvent.Release( );
464 s->OnLeftButtonUp( );
467 case vtkCommand::MiddleButtonPressEvent:
469 unsigned char nc = s->m_MiddleButtonEvent.Clicks( );
471 s->OnMiddleDoubleClick( );
474 s->OnMiddleButtonDown( );
477 case vtkCommand::MiddleButtonReleaseEvent:
479 s->m_MiddleButtonEvent.Release( );
480 s->OnMiddleButtonUp( );
483 case vtkCommand::RightButtonPressEvent:
485 unsigned char nc = s->m_RightButtonEvent.Clicks( );
487 s->OnRightDoubleClick( );
490 s->OnRightButtonDown( );
493 case vtkCommand::RightButtonReleaseEvent:
495 s->m_RightButtonEvent.Release( );
496 s->OnRightButtonUp( );
499 case vtkCommand::MouseWheelForwardEvent:
501 s->OnMouseWheelForward( );
504 case vtkCommand::MouseWheelBackwardEvent:
506 s->OnMouseWheelBackward( );
509 case vtkCommand::KeyPressEvent:
515 case vtkCommand::KeyReleaseEvent:
521 case vtkCommand::CharEvent:
526 case vtkCommand::ExposeEvent:
531 case vtkCommand::ConfigureEvent:
536 case vtkCommand::EnterEvent:
541 case vtkCommand::LeaveEvent:
546 case vtkCommand::TimerEvent:
551 case vtkCommand::DeleteEvent:
553 s->SetInteractor( 0 );
556 case vtkCommand::TDxMotionEvent:
557 case vtkCommand::TDxButtonPressEvent:
558 case vtkCommand::TDxButtonReleaseEvent:
560 s->DelegateTDxEvent( event, calldata );