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 AddMouseMoveCommand( TMouseCommand command, void* data )
27 this->m_MouseMoveCommands[ command ] = data;
33 // -------------------------------------------------------------------------
34 void cpExtensions::Interaction::BaseInteractorStyle::
35 AddMouseClickCommand( TMouseCommand command, void* data )
39 this->m_MouseClickCommands[ command ] = data;
45 // -------------------------------------------------------------------------
46 void cpExtensions::Interaction::BaseInteractorStyle::
47 AddMouseDoubleClickCommand( TMouseCommand command, void* data )
51 this->m_MouseDoubleClickCommands[ command ] = data;
57 // -------------------------------------------------------------------------
58 void cpExtensions::Interaction::BaseInteractorStyle::
59 AddMouseWheelCommand( TMouseWheelCommand command, void* data )
63 this->m_MouseWheelCommands[ command ] = data;
69 // -------------------------------------------------------------------------
70 void cpExtensions::Interaction::BaseInteractorStyle::
71 AddKeyCommand( TKeyCommand command, void* data )
75 this->m_KeyCommands[ command ] = data;
81 // -------------------------------------------------------------------------
82 void cpExtensions::Interaction::BaseInteractorStyle::
83 AddExposeCommand( TVoidCommand command, void* data )
87 this->m_ExposeCommands[ command ] = data;
93 // -------------------------------------------------------------------------
94 void cpExtensions::Interaction::BaseInteractorStyle::
95 AddConfigureCommand( TVoidCommand command, void* data )
99 this->m_ConfigureCommands[ command ] = data;
105 // -------------------------------------------------------------------------
106 void cpExtensions::Interaction::BaseInteractorStyle::
107 AddEnterCommand( TVoidCommand command, void* data )
109 if( command != NULL )
111 this->m_EnterCommands[ command ] = data;
117 // -------------------------------------------------------------------------
118 void cpExtensions::Interaction::BaseInteractorStyle::
119 AddLeaveCommand( TVoidCommand command, void* data )
121 if( command != NULL )
123 this->m_LeaveCommands[ command ] = data;
129 // -------------------------------------------------------------------------
130 void cpExtensions::Interaction::BaseInteractorStyle::
131 RemoveMouseMoveCommand( TMouseCommand command )
133 auto i = this->m_MouseMoveCommands.find( command );
134 if( i != this->m_MouseMoveCommands.end( ) )
136 this->m_MouseMoveCommands.erase( i );
142 // -------------------------------------------------------------------------
143 void cpExtensions::Interaction::BaseInteractorStyle::
144 RemoveMouseClickCommand( TMouseCommand command )
146 auto i = this->m_MouseClickCommands.find( command );
147 if( i != this->m_MouseClickCommands.end( ) )
149 this->m_MouseClickCommands.erase( i );
155 // -------------------------------------------------------------------------
156 void cpExtensions::Interaction::BaseInteractorStyle::
157 RemoveMouseDoubleClickCommand( TMouseCommand command )
159 auto i = this->m_MouseDoubleClickCommands.find( command );
160 if( i != this->m_MouseDoubleClickCommands.end( ) )
162 this->m_MouseDoubleClickCommands.erase( i );
168 // -------------------------------------------------------------------------
169 void cpExtensions::Interaction::BaseInteractorStyle::
170 RemoveMouseWheelCommand( TMouseWheelCommand command )
172 auto i = this->m_MouseWheelCommands.find( command );
173 if( i != this->m_MouseWheelCommands.end( ) )
175 this->m_MouseWheelCommands.erase( i );
181 // -------------------------------------------------------------------------
182 void cpExtensions::Interaction::BaseInteractorStyle::
183 RemoveKeyCommand( TKeyCommand command )
185 auto i = this->m_KeyCommands.find( command );
186 if( i != this->m_KeyCommands.end( ) )
188 this->m_KeyCommands.erase( i );
194 // -------------------------------------------------------------------------
195 void cpExtensions::Interaction::BaseInteractorStyle::
196 RemoveExposeCommand( TVoidCommand command )
198 auto i = this->m_ExposeCommands.find( command );
199 if( i != this->m_ExposeCommands.end( ) )
201 this->m_ExposeCommands.erase( i );
207 // -------------------------------------------------------------------------
208 void cpExtensions::Interaction::BaseInteractorStyle::
209 RemoveConfigureCommand( TVoidCommand command )
211 auto i = this->m_ConfigureCommands.find( command );
212 if( i != this->m_ConfigureCommands.end( ) )
214 this->m_ConfigureCommands.erase( i );
220 // -------------------------------------------------------------------------
221 void cpExtensions::Interaction::BaseInteractorStyle::
222 RemoveEnterCommand( TVoidCommand command )
224 auto i = this->m_EnterCommands.find( command );
225 if( i != this->m_EnterCommands.end( ) )
227 this->m_EnterCommands.erase( i );
233 // -------------------------------------------------------------------------
234 void cpExtensions::Interaction::BaseInteractorStyle::
235 RemoveLeaveCommand( TVoidCommand command )
237 auto i = this->m_LeaveCommands.find( command );
238 if( i != this->m_LeaveCommands.end( ) )
240 this->m_LeaveCommands.erase( i );
246 // -------------------------------------------------------------------------
247 void cpExtensions::Interaction::BaseInteractorStyle::
248 DelegateTDxEvent( unsigned long event, void* calldata )
251 std::cerr << "No TDx support at this time!" << std::endl;
255 // -------------------------------------------------------------------------
256 void cpExtensions::Interaction::BaseInteractorStyle::
259 // Get current position on the associated actors
260 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
265 bool alt = ( rwi->GetAltKey( ) == 1 );
266 bool ctr = ( rwi->GetControlKey( ) == 1 );
267 bool sft = ( rwi->GetShiftKey( ) == 1 );
268 ButtonID button = this->GetButtonID( );
270 // Invoke possible generic events
271 if( button == Self::ButtonID_Right )
273 if( !alt && !ctr && !sft )
275 this->FindPokedRenderer(
276 rwi->GetEventPosition( )[ 0 ],
277 rwi->GetEventPosition( )[ 1 ]
283 else if( button == Self::ButtonID_Middle )
285 if( !alt && !ctr && !sft )
287 this->FindPokedRenderer(
288 rwi->GetEventPosition( )[ 0 ],
289 rwi->GetEventPosition( )[ 1 ]
297 // Get mouse pointer position
299 static double pos[ 3 ];
300 if( !( this->_PickPosition( idx, pos ) ) )
303 // Invoke possible specialized events
304 auto i = this->m_MouseMoveCommands.begin( );
305 for( ; i != this->m_MouseMoveCommands.end( ); ++i )
306 i->first( i->second, button, idx, pos, alt, ctr, sft );
309 // -------------------------------------------------------------------------
310 void cpExtensions::Interaction::BaseInteractorStyle::
311 OnMouseWheelForward( )
313 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
317 // Invoke possible events
318 auto i = this->m_MouseWheelCommands.begin( );
319 for( ; i != this->m_MouseWheelCommands.end( ); ++i )
322 rwi->GetAltKey( ) == 1,
323 rwi->GetControlKey( ) == 1,
324 rwi->GetShiftKey( ) == 1
328 // -------------------------------------------------------------------------
329 void cpExtensions::Interaction::BaseInteractorStyle::
330 OnMouseWheelBackward( )
332 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
336 // Invoke possible events
337 auto i = this->m_MouseWheelCommands.begin( );
338 for( ; i != this->m_MouseWheelCommands.end( ); ++i )
341 rwi->GetAltKey( ) == 1,
342 rwi->GetControlKey( ) == 1,
343 rwi->GetShiftKey( ) == 1
347 // -------------------------------------------------------------------------
348 void cpExtensions::Interaction::BaseInteractorStyle::
351 this->m_ActiveButton = Self::ButtonID_Left;
354 // -------------------------------------------------------------------------
355 void cpExtensions::Interaction::BaseInteractorStyle::
358 this->m_ActiveButton = Self::ButtonID_None;
361 // -------------------------------------------------------------------------
362 void cpExtensions::Interaction::BaseInteractorStyle::
363 OnMiddleButtonDown( )
365 this->m_ActiveButton = Self::ButtonID_Middle;
367 // Get current position on the associated actors
368 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
373 bool alt = ( rwi->GetAltKey( ) == 1 );
374 bool ctr = ( rwi->GetControlKey( ) == 1 );
375 bool sft = ( rwi->GetShiftKey( ) == 1 );
377 if( !alt && !ctr && !sft )
381 // -------------------------------------------------------------------------
382 void cpExtensions::Interaction::BaseInteractorStyle::
385 this->m_ActiveButton = Self::ButtonID_None;
387 // Get current position on the associated actors
388 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
393 bool alt = ( rwi->GetAltKey( ) == 1 );
394 bool ctr = ( rwi->GetControlKey( ) == 1 );
395 bool sft = ( rwi->GetShiftKey( ) == 1 );
397 switch( this->State )
407 // -------------------------------------------------------------------------
408 void cpExtensions::Interaction::BaseInteractorStyle::
411 this->m_ActiveButton = Self::ButtonID_Right;
413 // Get current position on the associated actors
414 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
419 bool alt = ( rwi->GetAltKey( ) == 1 );
420 bool ctr = ( rwi->GetControlKey( ) == 1 );
421 bool sft = ( rwi->GetShiftKey( ) == 1 );
423 if( !alt && !ctr && !sft )
427 // -------------------------------------------------------------------------
428 void cpExtensions::Interaction::BaseInteractorStyle::
431 this->m_ActiveButton = Self::ButtonID_None;
433 // Get current position on the associated actors
434 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
439 bool alt = ( rwi->GetAltKey( ) == 1 );
440 bool ctr = ( rwi->GetControlKey( ) == 1 );
441 bool sft = ( rwi->GetShiftKey( ) == 1 );
443 switch( this->State )
453 // -------------------------------------------------------------------------
454 void cpExtensions::Interaction::BaseInteractorStyle::
457 // Get current position on the associated actors
458 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
462 // Get mouse pointer position
464 static double pos[ 3 ];
465 if( !( this->_PickPosition( idx, pos ) ) )
468 // Invoke possible events
469 auto i = this->m_MouseClickCommands.begin( );
470 for( ; i != this->m_MouseClickCommands.end( ); ++i )
475 rwi->GetAltKey( ) == 1,
476 rwi->GetControlKey( ) == 1,
477 rwi->GetShiftKey( ) == 1
481 // -------------------------------------------------------------------------
482 void cpExtensions::Interaction::BaseInteractorStyle::
485 // Get current position on the associated actors
486 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
490 // Get mouse pointer position
492 static double pos[ 3 ];
493 if( !( this->_PickPosition( idx, pos ) ) )
496 // Invoke possible events
497 auto i = this->m_MouseDoubleClickCommands.begin( );
498 for( ; i != this->m_MouseDoubleClickCommands.end( ); ++i )
503 rwi->GetAltKey( ) == 1,
504 rwi->GetControlKey( ) == 1,
505 rwi->GetShiftKey( ) == 1
509 // -------------------------------------------------------------------------
510 void cpExtensions::Interaction::BaseInteractorStyle::
513 // Get current position on the associated actors
514 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
518 // Get mouse pointer position
520 static double pos[ 3 ];
521 if( !( this->_PickPosition( idx, pos ) ) )
524 // Invoke possible events
525 auto i = this->m_MouseClickCommands.begin( );
526 for( ; i != this->m_MouseClickCommands.end( ); ++i )
529 Self::ButtonID_Middle,
531 rwi->GetAltKey( ) == 1,
532 rwi->GetControlKey( ) == 1,
533 rwi->GetShiftKey( ) == 1
537 // -------------------------------------------------------------------------
538 void cpExtensions::Interaction::BaseInteractorStyle::
539 OnMiddleDoubleClick( )
541 // Get current position on the associated actors
542 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
546 // Get mouse pointer position
548 static double pos[ 3 ];
549 if( !( this->_PickPosition( idx, pos ) ) )
552 // Invoke possible events
553 auto i = this->m_MouseDoubleClickCommands.begin( );
554 for( ; i != this->m_MouseDoubleClickCommands.end( ); ++i )
557 Self::ButtonID_Middle,
559 rwi->GetAltKey( ) == 1,
560 rwi->GetControlKey( ) == 1,
561 rwi->GetShiftKey( ) == 1
565 // -------------------------------------------------------------------------
566 void cpExtensions::Interaction::BaseInteractorStyle::
569 // Get current position on the associated actors
570 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
574 // Get mouse pointer position
576 static double pos[ 3 ];
577 if( !( this->_PickPosition( idx, pos ) ) )
580 // Invoke possible events
581 auto i = this->m_MouseClickCommands.begin( );
582 for( ; i != this->m_MouseClickCommands.end( ); ++i )
585 Self::ButtonID_Right,
587 rwi->GetAltKey( ) == 1,
588 rwi->GetControlKey( ) == 1,
589 rwi->GetShiftKey( ) == 1
593 // -------------------------------------------------------------------------
594 void cpExtensions::Interaction::BaseInteractorStyle::
595 OnRightDoubleClick( )
597 // Get current position on the associated actors
598 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
602 // Get mouse pointer position
604 static double pos[ 3 ];
605 if( !( this->_PickPosition( idx, pos ) ) )
608 // Invoke possible events
609 auto i = this->m_MouseDoubleClickCommands.begin( );
610 for( ; i != this->m_MouseDoubleClickCommands.end( ); ++i )
613 Self::ButtonID_Right,
615 rwi->GetAltKey( ) == 1,
616 rwi->GetControlKey( ) == 1,
617 rwi->GetShiftKey( ) == 1
621 // -------------------------------------------------------------------------
622 void cpExtensions::Interaction::BaseInteractorStyle::
625 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
629 // Invoke possible events
630 auto i = this->m_KeyCommands.begin( );
631 for( ; i != this->m_KeyCommands.end( ); ++i )
632 i->first( i->second, rwi->GetKeyCode( ) );
635 // -------------------------------------------------------------------------
636 void cpExtensions::Interaction::BaseInteractorStyle::
641 // -------------------------------------------------------------------------
642 void cpExtensions::Interaction::BaseInteractorStyle::
647 // -------------------------------------------------------------------------
648 void cpExtensions::Interaction::BaseInteractorStyle::
653 // -------------------------------------------------------------------------
654 void cpExtensions::Interaction::BaseInteractorStyle::
659 // -------------------------------------------------------------------------
660 void cpExtensions::Interaction::BaseInteractorStyle::
663 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
667 // Invoke possible events
668 auto i = this->m_ExposeCommands.begin( );
669 for( ; i != this->m_ExposeCommands.end( ); ++i )
670 i->first( i->second );
673 // -------------------------------------------------------------------------
674 void cpExtensions::Interaction::BaseInteractorStyle::
677 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
681 // Invoke possible events
682 auto i = this->m_ConfigureCommands.begin( );
683 for( ; i != this->m_ConfigureCommands.end( ); ++i )
684 i->first( i->second );
687 // -------------------------------------------------------------------------
688 void cpExtensions::Interaction::BaseInteractorStyle::
691 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
695 // Invoke possible events
696 auto i = this->m_EnterCommands.begin( );
697 for( ; i != this->m_EnterCommands.end( ); ++i )
698 i->first( i->second );
701 // -------------------------------------------------------------------------
702 void cpExtensions::Interaction::BaseInteractorStyle::
705 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
709 // Invoke possible events
710 auto i = this->m_LeaveCommands.begin( );
711 for( ; i != this->m_LeaveCommands.end( ); ++i )
712 i->first( i->second );
715 // -------------------------------------------------------------------------
716 void cpExtensions::Interaction::BaseInteractorStyle::
719 if( this->CurrentRenderer == NULL )
722 vtkRenderWindowInteractor* rwi = this->GetInteractor( );
723 double *center = this->CurrentRenderer->GetCenter( );
724 int dy = rwi->GetEventPosition( )[ 1 ] - rwi->GetLastEventPosition( )[ 1 ];
725 double dyf = this->m_MotionFactor * dy / center[ 1 ];
726 this->_Dolly( std::pow( 1.1, dyf ) );
729 // -------------------------------------------------------------------------
730 void cpExtensions::Interaction::BaseInteractorStyle::
733 if( this->CurrentRenderer == NULL )
736 vtkRenderWindowInteractor* rwi = this->Interactor;
737 double viewFocus[ 4 ], focalDepth, viewPoint[ 3 ];
738 double newPickPoint[ 4 ], oldPickPoint[ 4 ], motionVector[ 3 ];
740 // Calculate the focal depth since we'll be using it a lot
741 vtkCamera* camera = this->CurrentRenderer->GetActiveCamera( );
742 camera->GetFocalPoint( viewFocus );
743 this->ComputeWorldToDisplay(
744 viewFocus[ 0 ], viewFocus[ 1 ], viewFocus[ 2 ], viewFocus
746 focalDepth = viewFocus[ 2 ];
747 this->ComputeDisplayToWorld(
748 rwi->GetEventPosition( )[ 0 ],
749 rwi->GetEventPosition( )[ 1 ],
754 // Has to recalc old mouse point since the viewport has moved,
755 // so can't move it outside the loop
756 this->ComputeDisplayToWorld(
757 rwi->GetLastEventPosition( )[ 0 ],
758 rwi->GetLastEventPosition( )[ 1 ],
763 // Camera motion is reversed
764 motionVector[ 0 ] = oldPickPoint[ 0 ] - newPickPoint[ 0 ];
765 motionVector[ 1 ] = oldPickPoint[ 1 ] - newPickPoint[ 1 ];
766 motionVector[ 2 ] = oldPickPoint[ 2 ] - newPickPoint[ 2 ];
768 camera->GetFocalPoint( viewFocus );
769 camera->GetPosition( viewPoint );
770 camera->SetFocalPoint(
771 motionVector[ 0 ] + viewFocus[ 0 ],
772 motionVector[ 1 ] + viewFocus[ 1 ],
773 motionVector[ 2 ] + viewFocus[ 2 ]
776 motionVector[ 0 ] + viewPoint[ 0 ],
777 motionVector[ 1 ] + viewPoint[ 1 ],
778 motionVector[ 2 ] + viewPoint[ 2 ]
780 if( rwi->GetLightFollowCamera( ) )
781 this->CurrentRenderer->UpdateLightsGeometryToFollowCamera( );
785 // -------------------------------------------------------------------------
786 cpExtensions::Interaction::BaseInteractorStyle::
787 BaseInteractorStyle( )
789 m_MotionFactor( double( 10 ) )
791 this->m_LeftButtonEvent.Reset( );
792 this->m_MiddleButtonEvent.Reset( );
793 this->m_RightButtonEvent.Reset( );
794 this->m_ActiveButton = Self::ButtonID_None;
796 this->EventCallbackCommand->SetCallback( Self::_ProcessEvents );
799 // -------------------------------------------------------------------------
800 cpExtensions::Interaction::BaseInteractorStyle::
801 ~BaseInteractorStyle( )
805 // -------------------------------------------------------------------------
806 void cpExtensions::Interaction::BaseInteractorStyle::
807 _Dolly( double factor )
809 if( this->CurrentRenderer == NULL )
812 vtkCamera* camera = this->CurrentRenderer->GetActiveCamera( );
813 if( camera->GetParallelProjection( ) == 0 )
815 camera->Dolly( factor );
816 if( this->AutoAdjustCameraClippingRange )
817 this->CurrentRenderer->ResetCameraClippingRange( );
820 camera->SetParallelScale( camera->GetParallelScale( ) / factor );
821 if( this->Interactor->GetLightFollowCamera( ) )
822 this->CurrentRenderer->UpdateLightsGeometryToFollowCamera( );
823 this->Interactor->Render( );
826 // -------------------------------------------------------------------------
827 void cpExtensions::Interaction::BaseInteractorStyle::
835 // Get active style and interactor
836 Self* s = reinterpret_cast< Self* >( clientdata );
843 case vtkCommand::MouseMoveEvent:
848 case vtkCommand::LeftButtonPressEvent:
850 unsigned char nc = s->m_LeftButtonEvent.Clicks( );
852 s->OnLeftDoubleClick( );
855 s->OnLeftButtonDown( );
858 case vtkCommand::LeftButtonReleaseEvent:
860 s->m_LeftButtonEvent.Release( );
861 s->OnLeftButtonUp( );
864 case vtkCommand::MiddleButtonPressEvent:
866 unsigned char nc = s->m_MiddleButtonEvent.Clicks( );
868 s->OnMiddleDoubleClick( );
871 s->OnMiddleButtonDown( );
874 case vtkCommand::MiddleButtonReleaseEvent:
876 s->m_MiddleButtonEvent.Release( );
877 s->OnMiddleButtonUp( );
880 case vtkCommand::RightButtonPressEvent:
882 unsigned char nc = s->m_RightButtonEvent.Clicks( );
884 s->OnRightDoubleClick( );
887 s->OnRightButtonDown( );
890 case vtkCommand::RightButtonReleaseEvent:
892 s->m_RightButtonEvent.Release( );
893 s->OnRightButtonUp( );
896 case vtkCommand::MouseWheelForwardEvent:
898 s->OnMouseWheelForward( );
901 case vtkCommand::MouseWheelBackwardEvent:
903 s->OnMouseWheelBackward( );
906 case vtkCommand::KeyPressEvent:
912 case vtkCommand::KeyReleaseEvent:
918 case vtkCommand::CharEvent:
923 case vtkCommand::ExposeEvent:
928 case vtkCommand::ConfigureEvent:
933 case vtkCommand::EnterEvent:
938 case vtkCommand::LeaveEvent:
943 case vtkCommand::TimerEvent:
948 case vtkCommand::DeleteEvent:
950 s->SetInteractor( 0 );
953 case vtkCommand::TDxMotionEvent:
954 case vtkCommand::TDxButtonPressEvent:
955 case vtkCommand::TDxButtonReleaseEvent:
957 s->DelegateTDxEvent( event, calldata );