#include #include #include #include #include #include // ------------------------------------------------------------------------- long cpExtensions::Interaction::BaseStyle::_TMouseButtonEvent:: MaxDoubleClick = 350; // ms // ------------------------------------------------------------------------- void cpExtensions::Interaction::BaseStyle:: SetSetDoubleClickDelay( long delay ) { Self::_TMouseButtonEvent::MaxDoubleClick = delay; } // ------------------------------------------------------------------------- void cpExtensions::Interaction::BaseStyle:: DelegateTDxEvent( unsigned long event, void* calldata ) { // TODO std::cerr << "No TDx support at this time!" << std::endl; std::exit( 1 ); } // ------------------------------------------------------------------------- void cpExtensions::Interaction::BaseStyle:: OnMouseMove( ) { if( this->Interactor == NULL ) return; // Get modifiers bool alt = ( this->Interactor->GetAltKey( ) == 1 ); bool ctr = ( this->Interactor->GetControlKey( ) == 1 ); bool sft = ( this->Interactor->GetShiftKey( ) == 1 ); ButtonID button = this->GetButtonID( ); // Invoke possible generic events auto x = this->Interactor->GetEventPosition( )[ 0 ]; auto y = this->Interactor->GetEventPosition( )[ 1 ]; if( button == Self::ButtonID_Right ) { if( !alt && !ctr && !sft ) { this->FindPokedRenderer( x, y ); this->Dolly( ); } // fi } else if( button == Self::ButtonID_Middle ) { if( !alt && !ctr && !sft ) { this->FindPokedRenderer( x, y ); this->Pan( ); } // fi } // fi } // ------------------------------------------------------------------------- void cpExtensions::Interaction::BaseStyle:: OnLeftButtonDown( ) { this->m_ActiveButton = Self::ButtonID_Left; } // ------------------------------------------------------------------------- void cpExtensions::Interaction::BaseStyle:: OnLeftButtonUp( ) { this->m_ActiveButton = Self::ButtonID_None; } // ------------------------------------------------------------------------- void cpExtensions::Interaction::BaseStyle:: OnMiddleButtonDown( ) { this->m_ActiveButton = Self::ButtonID_Middle; // Get current position on the associated actors if( this->Interactor == NULL ) return; // Get modifiers bool alt = ( this->Interactor->GetAltKey( ) == 1 ); bool ctr = ( this->Interactor->GetControlKey( ) == 1 ); bool sft = ( this->Interactor->GetShiftKey( ) == 1 ); if( !alt && !ctr && !sft ) this->StartPan( ); } // ------------------------------------------------------------------------- void cpExtensions::Interaction::BaseStyle:: OnMiddleButtonUp( ) { this->m_ActiveButton = Self::ButtonID_None; // Get current position on the associated actors if( this->Interactor == NULL ) return; switch( this->State ) { case VTKIS_PAN: this->EndPan( ); break; default: break; } // hctiws } // ------------------------------------------------------------------------- void cpExtensions::Interaction::BaseStyle:: OnRightButtonDown( ) { this->m_ActiveButton = Self::ButtonID_Right; // Get current position on the associated actors if( this->Interactor == NULL ) return; // Get modifiers bool alt = ( this->Interactor->GetAltKey( ) == 1 ); bool ctr = ( this->Interactor->GetControlKey( ) == 1 ); bool sft = ( this->Interactor->GetShiftKey( ) == 1 ); if( !alt && !ctr && !sft ) this->StartDolly( ); } // ------------------------------------------------------------------------- void cpExtensions::Interaction::BaseStyle:: OnRightButtonUp( ) { this->m_ActiveButton = Self::ButtonID_None; // Get current position on the associated actors if( this->Interactor == NULL ) return; switch( this->State ) { case VTKIS_DOLLY: this->EndDolly( ); break; default: break; } // hctiws } // ------------------------------------------------------------------------- #define cpExtensions_BaseStyle_Click( S, T ) \ void cpExtensions::Interaction::BaseStyle:: \ On##S##T( ) \ { \ if( this->Interactor == NULL ) \ return; \ static int idx[ 2 ]; \ static double pos[ 3 ]; \ if( !( this->_PickPosition( idx, pos ) ) ) \ return; \ auto i = this->m_Mouse##T##Commands.begin( ); \ for( ; i != this->m_Mouse##T##Commands.end( ); ++i ) \ i->first( \ i->second, \ Self::ButtonID_##S, \ idx, pos, \ this->Interactor->GetAltKey( ) == 1, \ this->Interactor->GetControlKey( ) == 1, \ this->Interactor->GetShiftKey( ) == 1 \ ); \ } cpExtensions_BaseStyle_Click( Left, Click ); cpExtensions_BaseStyle_Click( Middle, Click ); cpExtensions_BaseStyle_Click( Right, Click ); cpExtensions_BaseStyle_Click( Left, DoubleClick ); cpExtensions_BaseStyle_Click( Middle, DoubleClick ); cpExtensions_BaseStyle_Click( Right, DoubleClick ); // ------------------------------------------------------------------------- void cpExtensions::Interaction::BaseStyle:: Dolly( ) { if( this->CurrentRenderer == NULL ) return; vtkRenderWindowInteractor* rwi = this->GetInteractor( ); double *center = this->CurrentRenderer->GetCenter( ); int dy = rwi->GetEventPosition( )[ 1 ] - rwi->GetLastEventPosition( )[ 1 ]; double dyf = this->m_MotionFactor * dy / center[ 1 ]; this->_Dolly( std::pow( 1.1, dyf ) ); } // ------------------------------------------------------------------------- void cpExtensions::Interaction::BaseStyle:: Pan( ) { if( this->CurrentRenderer == NULL ) return; vtkRenderWindowInteractor* rwi = this->Interactor; double viewFocus[ 4 ], focalDepth, viewPoint[ 3 ]; double newPickPoint[ 4 ], oldPickPoint[ 4 ], motionVector[ 3 ]; // Calculate the focal depth since we'll be using it a lot vtkCamera* camera = this->CurrentRenderer->GetActiveCamera( ); camera->GetFocalPoint( viewFocus ); this->ComputeWorldToDisplay( viewFocus[ 0 ], viewFocus[ 1 ], viewFocus[ 2 ], viewFocus ); focalDepth = viewFocus[ 2 ]; this->ComputeDisplayToWorld( rwi->GetEventPosition( )[ 0 ], rwi->GetEventPosition( )[ 1 ], focalDepth, newPickPoint ); // Has to recalc old mouse point since the viewport has moved, // so can't move it outside the loop this->ComputeDisplayToWorld( rwi->GetLastEventPosition( )[ 0 ], rwi->GetLastEventPosition( )[ 1 ], focalDepth, oldPickPoint ); // Camera motion is reversed motionVector[ 0 ] = oldPickPoint[ 0 ] - newPickPoint[ 0 ]; motionVector[ 1 ] = oldPickPoint[ 1 ] - newPickPoint[ 1 ]; motionVector[ 2 ] = oldPickPoint[ 2 ] - newPickPoint[ 2 ]; camera->GetFocalPoint( viewFocus ); camera->GetPosition( viewPoint ); camera->SetFocalPoint( motionVector[ 0 ] + viewFocus[ 0 ], motionVector[ 1 ] + viewFocus[ 1 ], motionVector[ 2 ] + viewFocus[ 2 ] ); camera->SetPosition( motionVector[ 0 ] + viewPoint[ 0 ], motionVector[ 1 ] + viewPoint[ 1 ], motionVector[ 2 ] + viewPoint[ 2 ] ); if( rwi->GetLightFollowCamera( ) ) this->CurrentRenderer->UpdateLightsGeometryToFollowCamera( ); rwi->Render( ); } // ------------------------------------------------------------------------- cpExtensions::Interaction::BaseStyle:: BaseStyle( ) : Superclass( ), m_MotionFactor( double( 10 ) ) { this->m_LeftButtonEvent.Reset( ); this->m_MiddleButtonEvent.Reset( ); this->m_RightButtonEvent.Reset( ); this->m_ActiveButton = Self::ButtonID_None; this->EventCallbackCommand->SetCallback( Self::_ProcessEvents ); } // ------------------------------------------------------------------------- cpExtensions::Interaction::BaseStyle:: ~BaseStyle( ) { } // ------------------------------------------------------------------------- void cpExtensions::Interaction::BaseStyle:: _Dolly( double factor ) { if( this->CurrentRenderer == NULL ) return; vtkCamera* camera = this->CurrentRenderer->GetActiveCamera( ); if( camera->GetParallelProjection( ) == 0 ) { camera->Dolly( factor ); if( this->AutoAdjustCameraClippingRange ) this->CurrentRenderer->ResetCameraClippingRange( ); } else camera->SetParallelScale( camera->GetParallelScale( ) / factor ); if( this->Interactor->GetLightFollowCamera( ) ) this->CurrentRenderer->UpdateLightsGeometryToFollowCamera( ); this->Interactor->Render( ); } // ------------------------------------------------------------------------- void cpExtensions::Interaction::BaseStyle:: _ProcessEvents( vtkObject* object, unsigned long event, void* clientdata, void* calldata ) { // Get active style and interactor Self* s = reinterpret_cast< Self* >( clientdata ); if( s == NULL ) return; // Process events switch( event ) { case vtkCommand::MouseMoveEvent: { s->OnMouseMove( ); } break; case vtkCommand::LeftButtonPressEvent: { unsigned char nc = s->m_LeftButtonEvent.Clicks( ); if( nc == 2 ) s->OnLeftDoubleClick( ); else if( nc == 1 ) s->OnLeftClick( ); s->OnLeftButtonDown( ); } break; case vtkCommand::LeftButtonReleaseEvent: { s->m_LeftButtonEvent.Release( ); s->OnLeftButtonUp( ); } break; case vtkCommand::MiddleButtonPressEvent: { unsigned char nc = s->m_MiddleButtonEvent.Clicks( ); if( nc == 2 ) s->OnMiddleDoubleClick( ); else if( nc == 1 ) s->OnMiddleClick( ); s->OnMiddleButtonDown( ); } break; case vtkCommand::MiddleButtonReleaseEvent: { s->m_MiddleButtonEvent.Release( ); s->OnMiddleButtonUp( ); } break; case vtkCommand::RightButtonPressEvent: { unsigned char nc = s->m_RightButtonEvent.Clicks( ); if( nc == 2 ) s->OnRightDoubleClick( ); else if( nc == 1 ) s->OnRightClick( ); s->OnRightButtonDown( ); } break; case vtkCommand::RightButtonReleaseEvent: { s->m_RightButtonEvent.Release( ); s->OnRightButtonUp( ); } break; case vtkCommand::MouseWheelForwardEvent: { s->OnMouseWheelForward( ); } break; case vtkCommand::MouseWheelBackwardEvent: { s->OnMouseWheelBackward( ); } break; case vtkCommand::KeyPressEvent: { s->OnKeyDown( ); s->OnKeyPress( ); } break; case vtkCommand::KeyReleaseEvent: { s->OnKeyUp( ); s->OnKeyRelease( ); } break; case vtkCommand::CharEvent: { s->OnChar( ); } break; case vtkCommand::ExposeEvent: { s->OnExpose( ); } break; case vtkCommand::ConfigureEvent: { s->OnConfigure( ); } break; case vtkCommand::EnterEvent: { s->OnEnter( ); } break; case vtkCommand::LeaveEvent: { s->OnLeave( ); } break; case vtkCommand::TimerEvent: { // Do nothing } break; case vtkCommand::DeleteEvent: { s->SetInteractor( 0 ); } break; case vtkCommand::TDxMotionEvent: case vtkCommand::TDxButtonPressEvent: case vtkCommand::TDxButtonReleaseEvent: { s->DelegateTDxEvent( event, calldata ); } break; default: break; } // hctiws } // eof - $RCSfile$