From: apl Date: Thu, 1 Nov 2012 12:29:35 +0000 (+0000) Subject: View synchronization issues fixed: X-Git-Tag: pal21808_v2~1 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=dbd5a82d373da4e940a7bb1615b49d48dff39a31;p=modules%2Fgui.git View synchronization issues fixed: 1) camera clipping range 2) OCC <-> OCC with rotation 3) axial scale 4) perspective projection synchronization --- diff --git a/src/OCCViewer/OCCViewer_ViewWindow.cxx b/src/OCCViewer/OCCViewer_ViewWindow.cxx index 595257cf8..8866d7c1b 100755 --- a/src/OCCViewer/OCCViewer_ViewWindow.cxx +++ b/src/OCCViewer/OCCViewer_ViewWindow.cxx @@ -1542,7 +1542,10 @@ void OCCViewer_ViewWindow::onAxialScale() myScalingDlg = new OCCViewer_AxialScaleDlg( this ); if ( !myScalingDlg->isVisible() ) + { + myScalingDlg->Update(); myScalingDlg->show(); + } } /*! @@ -2513,15 +2516,25 @@ SUIT_CameraProperties OCCViewer_ViewWindow::cameraProperties() Standard_Real aPrjDir[3]; Standard_Real aMapScale[2]; Standard_Real aTranslation[3]; - + Standard_Real anAxialScale[3]; + aSourceView->Up(anUpDir[0], anUpDir[1], anUpDir[2]); aSourceView->Proj(aPrjDir[0], aPrjDir[1], aPrjDir[2]); aSourceView->At(aTranslation[0], aTranslation[1], aTranslation[2]); aSourceView->Size(aMapScale[0], aMapScale[1]); + getViewPort()->getAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]); + + // we use similar depth to the one used in perspective projection + // to proivde a convinience synchronization with other camera views that + // can switch between orthogonal & perspective projection. otherwise, + // the camera will get to close when switching from orthogonal to perspective. + Standard_Real aCameraDepth = aSourceView->Depth() + aSourceView->ZSize() * 0.5; + // store common props aProps.setViewUp(anUpDir[0], anUpDir[1], anUpDir[2]); aProps.setMappingScale(aMapScale[1] / 2.0); + aProps.setAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]); // generate view orientation matrix for transforming OCC projection reference point // into a camera (eye) position. @@ -2539,14 +2552,14 @@ SUIT_CameraProperties OCCViewer_ViewWindow::cameraProperties() Graphic3d_Vertex aProjRef = aSourceView->ViewMapping().ProjectionReferencePoint(); // transform to world-space coordinate system - gp_Pnt aPosition = gp_Pnt(aProjRef.X(), aProjRef.Y(), aProjRef.Z()).Transformed(aTrsf); + gp_Pnt aPosition = gp_Pnt(aProjRef.X(), aProjRef.Y(), aCameraDepth).Transformed(aTrsf); // compute focal point double aFocalPoint[3]; - aFocalPoint[0] = aPosition.X() - aPrjDir[0] * aProjRef.Z(); - aFocalPoint[1] = aPosition.Y() - aPrjDir[1] * aProjRef.Z(); - aFocalPoint[2] = aPosition.Z() - aPrjDir[2] * aProjRef.Z(); + aFocalPoint[0] = aPosition.X() - aPrjDir[0] * aCameraDepth; + aFocalPoint[1] = aPosition.Y() - aPrjDir[1] * aCameraDepth; + aFocalPoint[2] = aPosition.Z() - aPrjDir[2] * aCameraDepth; aProps.setFocalPoint(aFocalPoint[0], aFocalPoint[1], aFocalPoint[2]); aProps.setPosition(aPosition.X(), aPosition.Y(), aPosition.Z()); @@ -2564,19 +2577,21 @@ void OCCViewer_ViewWindow::synchronize( SUIT_ViewWindow* theView ) SUIT_CameraProperties aProps = theView->cameraProperties(); - Handle(V3d_View) aSourceView = getViewPort()->getView(); + Handle(V3d_View) aDestView = getViewPort()->getView(); - aSourceView->SetImmediateUpdate( Standard_False ); + aDestView->SetImmediateUpdate( Standard_False ); double anUpDir[3]; double aPosition[3]; double aFocalPoint[3]; double aMapScaling; + double anAxialScale[3]; // get common properties aProps.getFocalPoint(aFocalPoint[0], aFocalPoint[1], aFocalPoint[2]); aProps.getPosition(aPosition[0], aPosition[1], aPosition[2]); aProps.getViewUp(anUpDir[0], anUpDir[1], anUpDir[2]); + aProps.getAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]); aMapScaling = aProps.getMappingScale() * 2.0; gp_Dir aProjDir(aPosition[0] - aFocalPoint[0], @@ -2585,7 +2600,7 @@ void OCCViewer_ViewWindow::synchronize( SUIT_ViewWindow* theView ) // get custom view translation Standard_Real aTranslation[3]; - aSourceView->At(aTranslation[0], aTranslation[1], aTranslation[2]); + aDestView->At(aTranslation[0], aTranslation[1], aTranslation[2]); gp_Dir aLeftDir = gp_Dir(anUpDir[0], anUpDir[1], anUpDir[2]).Crossed( gp_Dir(aProjDir.X(), aProjDir.Y(), aProjDir.Z())); @@ -2603,26 +2618,41 @@ void OCCViewer_ViewWindow::synchronize( SUIT_ViewWindow* theView ) gp_Pnt aProjRef(aPosition[0], aPosition[1], aPosition[2]); aProjRef.Transform(aTrsf); - aSourceView->SetProj(aProjDir.X(), aProjDir.Y(), aProjDir.Z()); + // set view camera properties using low-level approach. this is done + // in order to avoid interference with static variables in v3d view used + // when rotation is in process in another view. + Visual3d_ViewMapping aMapping = aDestView->View()->ViewMapping(); + Visual3d_ViewOrientation anOrientation = aDestView->View()->ViewOrientation(); + + Graphic3d_Vector aMappingProj(aProjDir.X(), aProjDir.Y(), aProjDir.Z()); + Graphic3d_Vector aMappingUp(anUpDir[0], anUpDir[1], anUpDir[2]); - aSourceView->SetUp((Standard_Real)anUpDir[0], - (Standard_Real)anUpDir[1], - (Standard_Real)anUpDir[2]); + aMappingProj.Normalize(); + aMappingUp.Normalize(); + + anOrientation.SetViewReferencePlane(aMappingProj); + anOrientation.SetViewReferenceUp(aMappingUp); + + aDestView->SetViewMapping(aMapping); + aDestView->SetViewOrientation(anOrientation); // set panning - aSourceView->SetCenter(aProjRef.X(), aProjRef.Y()); + aDestView->SetCenter(aProjRef.X(), aProjRef.Y()); // set mapping scale Standard_Real aWidth, aHeight; - aSourceView->Size(aWidth, aHeight); + aDestView->Size(aWidth, aHeight); if ( aWidth > aHeight ) - aSourceView->SetSize (aMapScaling * (aWidth / aHeight)); + aDestView->SetSize (aMapScaling * (aWidth / aHeight)); else - aSourceView->SetSize (aMapScaling); + aDestView->SetSize (aMapScaling); + + getViewPort()->setAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]); - aSourceView->Update(); - aSourceView->SetImmediateUpdate( Standard_True ); + aDestView->ZFitAll(); + aDestView->SetImmediateUpdate( Standard_True ); + aDestView->Redraw(); blockSignals( blocked ); } diff --git a/src/SUIT/SUIT_CameraProperties.cxx b/src/SUIT/SUIT_CameraProperties.cxx index 0eb7d9212..2c88fc6e1 100644 --- a/src/SUIT/SUIT_CameraProperties.cxx +++ b/src/SUIT/SUIT_CameraProperties.cxx @@ -64,6 +64,8 @@ SUIT_CameraProperties::SUIT_CameraProperties() myDimension = DimNone; // none dimension by default myProjection = PrjOrthogonal; // orthogonal projection by default myViewSide = ViewNone; // no side view by default + + myViewAngle = 45.0; } /*! @@ -372,3 +374,23 @@ void SUIT_CameraProperties::setAxialScale(const double theScaleX, const double t myAxialScale[1] = theScaleY; myAxialScale[2] = theScaleZ; } + +/*! + \brief get angle (typically in degrees) of view for perpective projection mode. + \return the angle of view. + \sa setViewAngle() +*/ +double SUIT_CameraProperties::getViewAngle() const +{ + return myViewAngle; +} + +/*! + \brief set angle (typically in degrees) of view for perpective projection mode. + \param theViewAngle [in] the angle of view. + \sa getViewAngle() +*/ +void SUIT_CameraProperties::setViewAngle(const double theViewAngle) +{ + myViewAngle = theViewAngle; +} diff --git a/src/SUIT/SUIT_CameraProperties.h b/src/SUIT/SUIT_CameraProperties.h index 532c39f06..30cfbbe09 100644 --- a/src/SUIT/SUIT_CameraProperties.h +++ b/src/SUIT/SUIT_CameraProperties.h @@ -65,6 +65,9 @@ public: void getAxialScale(double& theScaleX, double& theScaleY, double& theScaleZ); void setAxialScale(const double theScaleX, const double theScaleY, const double theScaleZ); + double getViewAngle() const; + void setViewAngle(const double theViewAngle); + // common properties for all viewers private: Dimension myDimension; //!< dimension @@ -76,6 +79,7 @@ private: double myClippingRange[2]; //!< distance to front and back clipping planes double myMappingScale; //!< window mapping scale (parallel projection scale) double myAxialScale[3]; //!< scaling factors for world axes + double myViewAngle; //!< perspective view angle in degrees }; #endif // SUIT_CAMERAPROPERITES_H diff --git a/src/SVTK/SVTK_ViewWindow.cxx b/src/SVTK/SVTK_ViewWindow.cxx index 908fce24d..73ebce101 100755 --- a/src/SVTK/SVTK_ViewWindow.cxx +++ b/src/SVTK/SVTK_ViewWindow.cxx @@ -2398,6 +2398,7 @@ SUIT_CameraProperties SVTK_ViewWindow::cameraProperties() double aFocalPoint[3]; double aPosition[3]; double aViewUp[3]; + double anAxialScale[3]; aCamera->OrthogonalizeViewUp(); aCamera->GetFocalPoint(aFocalPoint); @@ -2408,6 +2409,14 @@ SUIT_CameraProperties SVTK_ViewWindow::cameraProperties() aProps.setPosition(aPosition[0], aPosition[1], aPosition[2]); aProps.setViewUp(aViewUp[0], aViewUp[1], aViewUp[2]); aProps.setMappingScale(aCamera->GetParallelScale()); + + if (aProps.getProjection() == SUIT_CameraProperties::PrjPerspective) + { + aProps.setViewAngle(aCamera->GetViewAngle()); + } + + GetRenderer()->GetScale(anAxialScale); + aProps.setAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]); return aProps; } @@ -2428,11 +2437,13 @@ void SVTK_ViewWindow::synchronize( SUIT_ViewWindow* theView ) double aFocalPoint[3]; double aPosition[3]; double aViewUp[3]; + double anAxialScale[3]; // get common properties aProps.getViewUp(aViewUp[0], aViewUp[1], aViewUp[2]); aProps.getPosition(aPosition[0], aPosition[1], aPosition[2]); aProps.getFocalPoint(aFocalPoint[0], aFocalPoint[1], aFocalPoint[2]); + aProps.getAxialScale(anAxialScale[0], anAxialScale[1], anAxialScale[2]); // restore properties to the camera aCamera->SetViewUp(aViewUp); @@ -2440,7 +2451,15 @@ void SVTK_ViewWindow::synchronize( SUIT_ViewWindow* theView ) aCamera->SetFocalPoint(aFocalPoint); aCamera->SetParallelScale(aProps.getMappingScale()); - Repaint(); + if (aProps.getProjection() == SUIT_CameraProperties::PrjPerspective) + { + aCamera->SetViewAngle(aProps.getViewAngle()); + } + + GetRenderer()->SetScale(anAxialScale); + + getRenderer()->ResetCameraClippingRange(); + Repaint(false); blockSignals( blocked ); }