diff --git a/src/AIS/AIS_ViewController.cxx b/src/AIS/AIS_ViewController.cxx index 61aaac54c5..0e2ce3a0a9 100644 --- a/src/AIS/AIS_ViewController.cxx +++ b/src/AIS/AIS_ViewController.cxx @@ -1453,6 +1453,7 @@ void AIS_ViewController::handleOrbitRotation (const Handle(V3d_View)& theView, myRotatePnt3d = thePnt; myCamStartOpUp = aCam->Up(); + myCamStartOpDir = aCam->Direction(); myCamStartOpEye = aCam->Eye(); myCamStartOpCenter = aCam->Center(); @@ -1493,8 +1494,9 @@ void AIS_ViewController::handleOrbitRotation (const Handle(V3d_View)& theView, const gp_Dir aNewUp = gp::DZ().Transformed (aTrsfRot); aCam->SetUp (aNewUp); - aCam->SetCenter(myRotatePnt3d.XYZ() + myCamStartOpToCenter.Transformed (aTrsfRot).XYZ()); - aCam->SetEye (myRotatePnt3d.XYZ() + myCamStartOpToEye .Transformed (aTrsfRot).XYZ()); + aCam->SetEyeAndCenter (myRotatePnt3d.XYZ() + myCamStartOpToEye .Transformed (aTrsfRot).XYZ(), + myRotatePnt3d.XYZ() + myCamStartOpToCenter.Transformed (aTrsfRot).XYZ()); + aCam->OrthogonalizeUp(); } else @@ -1504,9 +1506,9 @@ void AIS_ViewController::handleOrbitRotation (const Handle(V3d_View)& theView, //theView->Rotate (aDX, aDY, aDZ, myRotatePnt3d.X(), myRotatePnt3d.Y(), myRotatePnt3d.Z(), false); // restore previous camera state - aCam->SetUp (myCamStartOpUp); - aCam->SetEye (myCamStartOpEye); - aCam->SetCenter (myCamStartOpCenter); + aCam->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter); + aCam->SetUp (myCamStartOpUp); + aCam->SetDirectionFromEye (myCamStartOpDir); Graphic3d_Vec2d aWinXY; theView->Size (aWinXY.x(), aWinXY.y()); @@ -1599,11 +1601,10 @@ void AIS_ViewController::handleViewRotation (const Handle(V3d_View)& theView, gp_Trsf aTrsfRot; aTrsfRot.SetRotation (aRot); - const double aDist = aCam->Distance(); const gp_Dir aNewUp = gp::DZ().Transformed (aTrsfRot); const gp_Dir aNewDir = gp::DX().Transformed (aTrsfRot); - aCam->SetUp (aNewUp); - aCam->SetCenter (aCam->Eye().Translated (gp_Vec (aNewDir) * aDist)); + aCam->SetUp (aNewUp); + aCam->SetDirectionFromEye (aNewDir); aCam->OrthogonalizeUp(); theView->Invalidate(); } diff --git a/src/AIS/AIS_ViewController.hxx b/src/AIS/AIS_ViewController.hxx index 01e1f517be..7c566b2dcc 100644 --- a/src/AIS/AIS_ViewController.hxx +++ b/src/AIS/AIS_ViewController.hxx @@ -672,6 +672,7 @@ protected: //! @name rotation/panning transient state variables gp_Pnt myPanPnt3d; //!< active panning anchor point gp_Pnt myRotatePnt3d; //!< active rotation center of gravity gp_Dir myCamStartOpUp; //!< camera Up direction at the beginning of rotation + gp_Dir myCamStartOpDir; //!< camera View direction at the beginning of rotation gp_Pnt myCamStartOpEye; //!< camera Eye position at the beginning of rotation gp_Pnt myCamStartOpCenter; //!< camera Center position at the beginning of rotation gp_Vec myCamStartOpToCenter; //!< vector from rotation gravity point to camera Center at the beginning of rotation diff --git a/src/Graphic3d/Graphic3d_Camera.cxx b/src/Graphic3d/Graphic3d_Camera.cxx index a47309427c..916d08048b 100644 --- a/src/Graphic3d/Graphic3d_Camera.cxx +++ b/src/Graphic3d/Graphic3d_Camera.cxx @@ -39,9 +39,6 @@ namespace // atomic state counter static volatile Standard_Integer THE_STATE_COUNTER = 0; - // minimum camera distance - static const Standard_Real MIN_DISTANCE = Pow (0.1, ShortRealDigits() - 2); - // z-range tolerance compatible with for floating point. static Standard_Real zEpsilon() { @@ -64,7 +61,7 @@ namespace //! Convert camera definition to Ax3 gp_Ax3 cameraToAx3 (const Graphic3d_Camera& theCamera) { - const gp_Dir aBackDir(gp_Vec(theCamera.Center(), theCamera.Eye())); + const gp_Dir aBackDir = -theCamera.Direction(); const gp_Dir anXAxis (theCamera.Up().Crossed (aBackDir)); const gp_Dir anYAxis (aBackDir .Crossed (anXAxis)); const gp_Dir aZAxis (anXAxis .Crossed (anYAxis)); @@ -78,8 +75,9 @@ namespace // ======================================================================= Graphic3d_Camera::Graphic3d_Camera() : myUp (0.0, 1.0, 0.0), + myDirection (0.0, 0.0, 1.0), myEye (0.0, 0.0, -1500.0), - myCenter (0.0, 0.0, 0.0), + myDistance (1500.0), myAxialScale (1.0, 1.0, 1.0), myProjType (Projection_Orthographic), myFOVy (45.0), @@ -104,8 +102,9 @@ Graphic3d_Camera::Graphic3d_Camera() // ======================================================================= Graphic3d_Camera::Graphic3d_Camera (const Handle(Graphic3d_Camera)& theOther) : myUp (0.0, 1.0, 0.0), + myDirection (0.0, 0.0, 1.0), myEye (0.0, 0.0, -1500.0), - myCenter (0.0, 0.0, 0.0), + myDistance (1500.0), myAxialScale (1.0, 1.0, 1.0), myProjType (Projection_Orthographic), myFOVy (45.0), @@ -146,9 +145,17 @@ void Graphic3d_Camera::CopyMappingData (const Handle(Graphic3d_Camera)& theOther // ======================================================================= void Graphic3d_Camera::CopyOrientationData (const Handle(Graphic3d_Camera)& theOtherCamera) { - SetUp (theOtherCamera->Up()); - SetEye (theOtherCamera->Eye()); - SetCenter (theOtherCamera->Center()); + if (!myEye.IsEqual (theOtherCamera->Eye(), 0.0) + || !myUp.IsEqual (theOtherCamera->Up(), 0.0) + || !myDirection.IsEqual (theOtherCamera->Direction(), 0.0) + || myDistance != theOtherCamera->Distance()) + { + myEye = theOtherCamera->Eye(); + myUp = theOtherCamera->Up(); + myDirection = theOtherCamera->Direction(); + myDistance = theOtherCamera->Distance(); + InvalidateOrientation(); + } SetAxialScale (theOtherCamera->AxialScale()); } @@ -162,6 +169,43 @@ void Graphic3d_Camera::Copy (const Handle(Graphic3d_Camera)& theOther) CopyOrientationData (theOther); } +// ======================================================================= +// function : MoveEyeTo +// purpose : +// ======================================================================= +void Graphic3d_Camera::MoveEyeTo (const gp_Pnt& theEye) +{ + if (myEye.IsEqual (theEye, 0.0)) + { + return; + } + + myEye = theEye; + InvalidateOrientation(); +} + +// ======================================================================= +// function : SetEyeAndCenter +// purpose : +// ======================================================================= +void Graphic3d_Camera::SetEyeAndCenter (const gp_Pnt& theEye, + const gp_Pnt& theCenter) +{ + if (Eye() .IsEqual (theEye, 0.0) + && Center().IsEqual (theCenter, 0.0)) + { + return; + } + + myEye = theEye; + myDistance = theEye.Distance (theCenter); + if (myDistance > gp::Resolution()) + { + myDirection = gp_Dir (theCenter.XYZ() - theEye.XYZ()); + } + InvalidateOrientation(); +} + // ======================================================================= // function : SetEye // purpose : @@ -173,7 +217,13 @@ void Graphic3d_Camera::SetEye (const gp_Pnt& theEye) return; } + const gp_Pnt aCenter = Center(); myEye = theEye; + myDistance = myEye.Distance (aCenter); + if (myDistance > gp::Resolution()) + { + myDirection = gp_Dir (aCenter.XYZ() - myEye.XYZ()); + } InvalidateOrientation(); } @@ -183,12 +233,17 @@ void Graphic3d_Camera::SetEye (const gp_Pnt& theEye) // ======================================================================= void Graphic3d_Camera::SetCenter (const gp_Pnt& theCenter) { - if (Center().IsEqual (theCenter, 0.0)) + const Standard_Real aDistance = myEye.Distance (theCenter); + if (myDistance == aDistance) { return; } - myCenter = theCenter; + myDistance = aDistance; + if (myDistance > gp::Resolution()) + { + myDirection = gp_Dir (theCenter.XYZ() - myEye.XYZ()); + } InvalidateOrientation(); } @@ -228,26 +283,30 @@ void Graphic3d_Camera::SetAxialScale (const gp_XYZ& theAxialScale) // ======================================================================= void Graphic3d_Camera::SetDistance (const Standard_Real theDistance) { - if (Distance() == theDistance) + if (myDistance == theDistance) { return; } - gp_Vec aCenter2Eye (Direction()); - aCenter2Eye.Reverse(); - - // Camera should have non-zero distance. - aCenter2Eye.Scale (Max (theDistance, MIN_DISTANCE)); - SetEye (Center().Translated (aCenter2Eye)); + const gp_Pnt aCenter = Center(); + myDistance = theDistance; + myEye = aCenter.XYZ() - myDirection.XYZ() * myDistance; + InvalidateOrientation(); } // ======================================================================= -// function : Distance +// function : SetDirectionFromEye // purpose : // ======================================================================= -Standard_Real Graphic3d_Camera::Distance() const +void Graphic3d_Camera::SetDirectionFromEye (const gp_Dir& theDir) { - return myEye.Distance (myCenter); + if (myDirection.IsEqual (theDir, 0.0)) + { + return; + } + + myDirection = theDir; + InvalidateOrientation(); } // ======================================================================= @@ -256,24 +315,15 @@ Standard_Real Graphic3d_Camera::Distance() const // ======================================================================= void Graphic3d_Camera::SetDirection (const gp_Dir& theDir) { - if (Direction().IsEqual (theDir, 0.0)) + if (myDirection.IsEqual (theDir, 0.0)) { return; } - gp_Vec aScaledDir (theDir); - aScaledDir.Scale (Distance()); - aScaledDir.Reverse(); - SetEye (Center().Translated (aScaledDir)); -} - -// ======================================================================= -// function : Direction -// purpose : -// ======================================================================= -gp_Dir Graphic3d_Camera::Direction() const -{ - return gp_Dir (gp_Vec (myEye, myCenter)); + const gp_Pnt aCenter = Center(); + myDirection = theDir; + myEye = aCenter.XYZ() - theDir.XYZ() * myDistance; + InvalidateOrientation(); } // ======================================================================= @@ -500,9 +550,10 @@ void Graphic3d_Camera::Transform (const gp_Trsf& theTrsf) return; } - SetUp (myUp.Transformed (theTrsf)); - SetEye (myEye.Transformed (theTrsf)); - SetCenter (myCenter.Transformed (theTrsf)); + myUp .Transform (theTrsf); + myDirection.Transform (theTrsf); + myEye.Transform (theTrsf); + InvalidateOrientation(); } // ======================================================================= @@ -953,9 +1004,9 @@ Graphic3d_Camera::TransformMatrices& static_cast (myEye.Y()), static_cast (myEye.Z())); - NCollection_Vec3 aCenter (static_cast (myCenter.X()), - static_cast (myCenter.Y()), - static_cast (myCenter.Z())); + NCollection_Vec3 aViewDir (static_cast (myDirection.X()), + static_cast (myDirection.Y()), + static_cast (myDirection.Z())); NCollection_Vec3 anUp (static_cast (myUp.X()), static_cast (myUp.Y()), @@ -965,7 +1016,7 @@ Graphic3d_Camera::TransformMatrices& static_cast (myAxialScale.Y()), static_cast (myAxialScale.Z())); - LookOrientation (anEye, aCenter, anUp, anAxialScale, theMatrices.Orientation); + LookOrientation (anEye, aViewDir, anUp, anAxialScale, theMatrices.Orientation); return theMatrices; // for inline accessors } @@ -1106,12 +1157,12 @@ void Graphic3d_Camera::StereoEyeProj (const Elem_t theLeft, // ======================================================================= template void Graphic3d_Camera::LookOrientation (const NCollection_Vec3& theEye, - const NCollection_Vec3& theLookAt, + const NCollection_Vec3& theFwdDir, const NCollection_Vec3& theUpDir, const NCollection_Vec3& theAxialScale, NCollection_Mat4& theOutMx) { - NCollection_Vec3 aForward = theLookAt - theEye; + NCollection_Vec3 aForward = theFwdDir; aForward.Normalize(); // side = forward x up @@ -1219,7 +1270,9 @@ bool Graphic3d_Camera::ZFitAll (const Standard_Real theScaleFactor, Standard_Real aDistance = aCamPln.Distance (aMeasurePnt); // Check if the camera is intruded into the scene. - if (aCamDir.IsOpposite (gp_Vec (aCamEye, aMeasurePnt), M_PI * 0.5)) + gp_Vec aVecToMeasurePnt (aCamEye, aMeasurePnt); + if (aVecToMeasurePnt.Magnitude() > gp::Resolution() + && aCamDir.IsOpposite (aVecToMeasurePnt, M_PI * 0.5)) { aDistance *= -1; } @@ -1310,6 +1363,10 @@ bool Graphic3d_Camera::ZFitAll (const Standard_Real theScaleFactor, { // Clip zNear according to the minimum value matching the quality. aZNear = aZNearMin; + if (aZFar < aZNear) + { + aZFar = aZNear; + } } else { @@ -1325,10 +1382,12 @@ bool Graphic3d_Camera::ZFitAll (const Standard_Real theScaleFactor, { aZNear = zEpsilon(); } + Standard_ASSERT_RAISE (aZFar > aZNear, "ZFar should be greater than ZNear"); } theZNear = aZNear; theZFar = aZFar; + Standard_ASSERT_RAISE (aZFar > aZNear, "ZFar should be greater than ZNear"); return true; } @@ -1400,8 +1459,7 @@ Standard_EXPORT void NCollection_Lerp::Interpolate (co aCenter = anAnchor + aDirEyeToCenter.XYZ() * aDistEyeCenter * aKc; anEye = anAnchor - aDirEyeToCenter.XYZ() * aDistEyeCenter * (1.0 - aKc); - theCamera->SetCenter (aCenter); - theCamera->SetEye (anEye); + theCamera->SetEyeAndCenter (anEye, aCenter); } // apply scaling diff --git a/src/Graphic3d/Graphic3d_Camera.hxx b/src/Graphic3d/Graphic3d_Camera.hxx index f532763ef2..62fc9f77d8 100644 --- a/src/Graphic3d/Graphic3d_Camera.hxx +++ b/src/Graphic3d/Graphic3d_Camera.hxx @@ -155,30 +155,28 @@ public: //! @name Public camera properties public: - //! Sets camera Eye position. - //! @param theEye [in] the location of camera's Eye. - Standard_EXPORT void SetEye (const gp_Pnt& theEye); + //! Get camera look direction. + //! @return camera look direction. + const gp_Dir& Direction() const { return myDirection; } - //! Get camera Eye position. - //! @return camera eye location. - const gp_Pnt& Eye() const - { - return myEye; - } + //! Sets camera look direction preserving the current Eye() position. + //! WARNING! This method does NOT verify that the current Up() vector is orthogonal to the new Direction. + //! @param theDir [in] the direction. + Standard_EXPORT void SetDirectionFromEye (const gp_Dir& theDir); - //! Sets Center of the camera. - //! @param theCenter [in] the point where the camera looks at. - Standard_EXPORT void SetCenter (const gp_Pnt& theCenter); + //! Sets camera look direction and computes the new Eye position relative to current Center. + //! WARNING! This method does NOT verify that the current Up() vector is orthogonal to the new Direction. + //! @param theDir [in] the direction. + Standard_EXPORT void SetDirection (const gp_Dir& theDir); - //! Get Center of the camera. - //! @return the point where the camera looks at. - const gp_Pnt& Center() const - { - return myCenter; - } + //! Get camera Up direction vector. + //! @return Camera's Up direction vector. + const gp_Dir& Up() const { return myUp; } //! Sets camera Up direction vector, orthogonal to camera direction. + //! WARNING! This method does NOT verify that the new Up vector is orthogonal to the current Direction(). //! @param theUp [in] the Up direction vector. + //! @sa OrthogonalizeUp(). Standard_EXPORT void SetUp (const gp_Dir& theUp); //! Orthogonalize up direction vector. @@ -187,39 +185,54 @@ public: //! Return a copy of orthogonalized up direction vector. Standard_EXPORT gp_Dir OrthogonalizedUp() const; - //! Get camera Up direction vector. - //! @return Camera's Up direction vector. - const gp_Dir& Up() const + //! Get camera Eye position. + //! @return camera eye location. + const gp_Pnt& Eye() const { return myEye; } + + //! Sets camera Eye position. + //! Unlike SetEye(), this method only changes Eye point and preserves camera direction. + //! @param theEye [in] the location of camera's Eye. + //! @sa SetEye() + Standard_EXPORT void MoveEyeTo (const gp_Pnt& theEye); + + //! Sets camera Eye and Center positions. + //! @param theEye [in] the location of camera's Eye + //! @param theCenter [in] the location of camera's Center + Standard_EXPORT void SetEyeAndCenter (const gp_Pnt& theEye, + const gp_Pnt& theCenter); + + //! Sets camera Eye position. + //! WARNING! For backward compatibility reasons, this method also changes view direction, + //! so that the new direction is computed from new Eye position to old Center position. + //! @param theEye [in] the location of camera's Eye. + //! @sa MoveEyeTo(), SetEyeAndCenter() + Standard_EXPORT void SetEye (const gp_Pnt& theEye); + + //! Get Center of the camera, e.g. the point where camera looks at. + //! This point is computed as Eye() translated along Direction() at Distance(). + //! @return the point where the camera looks at. + gp_Pnt Center() const { - return myUp; + return myEye.XYZ() + myDirection.XYZ() * myDistance; } - //! Set camera axial scale. - //! @param theAxialScale [in] the axial scale vector. - Standard_EXPORT void SetAxialScale (const gp_XYZ& theAxialScale); + //! Sets Center of the camera, e.g. the point where camera looks at. + //! This methods changes camera direction, so that the new direction is computed + //! from current Eye position to specified Center position. + //! @param theCenter [in] the point where the camera looks at. + Standard_EXPORT void SetCenter (const gp_Pnt& theCenter); - //! Get camera axial scale. - //! @return Camera's axial scale. - const gp_XYZ& AxialScale() const - { - return myAxialScale; - } + //! Get distance of Eye from camera Center. + //! @return the distance. + Standard_Real Distance() const { return myDistance; } //! Set distance of Eye from camera Center. //! @param theDistance [in] the distance. Standard_EXPORT void SetDistance (const Standard_Real theDistance); - //! Get distance of Eye from camera Center. - //! @return the distance. - Standard_EXPORT Standard_Real Distance() const; - - //! Sets camera look direction. - //! @param theDir [in] the direction. - Standard_EXPORT void SetDirection (const gp_Dir& theDir); - - //! Get camera look direction. - //! @return camera look direction. - Standard_EXPORT gp_Dir Direction() const; + //! Get camera scale. + //! @return camera scale factor. + Standard_EXPORT Standard_Real Scale() const; //! Sets camera scale. For orthographic projection the scale factor //! corresponds to parallel scale of view mapping (i.e. size @@ -231,9 +244,13 @@ public: //! @param theScale [in] the scale factor. Standard_EXPORT void SetScale (const Standard_Real theScale); - //! Get camera scale. - //! @return camera scale factor. - Standard_EXPORT Standard_Real Scale() const; + //! Get camera axial scale. + //! @return Camera's axial scale. + const gp_XYZ& AxialScale() const { return myAxialScale; } + + //! Set camera axial scale. + //! @param theAxialScale [in] the axial scale vector. + Standard_EXPORT void SetAxialScale (const gp_XYZ& theAxialScale); //! Change camera projection type. //! When switching to perspective projection from orthographic one, @@ -619,14 +636,14 @@ private: //! Reference point differs for perspective and ortho modes //! (made for compatibility, to be improved..). //! @param theEye [in] the eye coordinates in 3D space. - //! @param theLookAt [in] the point the camera looks at. + //! @param theFwdDir [in] view direction //! @param theUpDir [in] the up direction vector. //! @param theAxialScale [in] the axial scale vector. //! @param theOutMx [in/out] the orientation matrix. template static void LookOrientation (const NCollection_Vec3& theEye, - const NCollection_Vec3& theLookAt, + const NCollection_Vec3& theFwdDir, const NCollection_Vec3& theUpDir, const NCollection_Vec3& theAxialScale, NCollection_Mat4& theOutMx); @@ -654,9 +671,10 @@ public: private: - gp_Dir myUp; //!< Camera up direction vector. - gp_Pnt myEye; //!< Camera eye position. - gp_Pnt myCenter; //!< Camera center. + gp_Dir myUp; //!< Camera up direction vector + gp_Dir myDirection;//!< Camera view direction (from eye) + gp_Pnt myEye; //!< Camera eye position + Standard_Real myDistance; //!< distance from Eye to Center gp_XYZ myAxialScale; //!< World axial scale. diff --git a/src/Graphic3d/Graphic3d_TransformPers.hxx b/src/Graphic3d/Graphic3d_TransformPers.hxx index 7ad65a0a50..cdc832a7f4 100644 --- a/src/Graphic3d/Graphic3d_TransformPers.hxx +++ b/src/Graphic3d/Graphic3d_TransformPers.hxx @@ -349,7 +349,7 @@ void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera, // scale factor to pixels const gp_XYZ aViewDim = theCamera->ViewDimensions (aFocus); const Standard_Real aScale = Abs(aViewDim.Y()) / Standard_Real(aVPSizeY); - const gp_Dir aForward (theCamera->Center().XYZ() - theCamera->Eye().XYZ()); + const gp_Dir aForward = theCamera->Direction(); gp_XYZ aCenter = theCamera->Center().XYZ() + aForward.XYZ() * (aFocus - theCamera->Distance()); if ((myParams.Params2d.Corner & (Aspect_TOTP_LEFT | Aspect_TOTP_RIGHT)) != 0) { diff --git a/src/V3d/V3d_View.cxx b/src/V3d/V3d_View.cxx index 61ae63bd2b..c46590ae4f 100644 --- a/src/V3d/V3d_View.cxx +++ b/src/V3d/V3d_View.cxx @@ -609,16 +609,17 @@ void V3d_View::Rotate (const Standard_Real ax, if (Start) { myCamStartOpUp = aCamera->Up(); + myCamStartOpDir = aCamera->Direction(); myCamStartOpEye = aCamera->Eye(); myCamStartOpCenter = aCamera->Center(); } - aCamera->SetUp (myCamStartOpUp); - aCamera->SetEye (myCamStartOpEye); - aCamera->SetCenter (myCamStartOpCenter); + aCamera->SetUp (myCamStartOpUp); + aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter); + aCamera->SetDirectionFromEye (myCamStartOpDir); // rotate camera around 3 initial axes - gp_Dir aBackDir (gp_Vec (myCamStartOpCenter, myCamStartOpEye)); + gp_Dir aBackDir = -myCamStartOpDir; gp_Dir aXAxis (myCamStartOpUp.Crossed (aBackDir)); gp_Dir aYAxis (aBackDir.Crossed (aXAxis)); gp_Dir aZAxis (aXAxis.Crossed (aYAxis)); @@ -663,15 +664,16 @@ void V3d_View::Rotate(const Standard_Real ax, const Standard_Real ay, const Stan { myGravityReferencePoint.SetCoord (X, Y, Z); myCamStartOpUp = aCamera->Up(); + myCamStartOpDir = aCamera->Direction(); myCamStartOpEye = aCamera->Eye(); myCamStartOpCenter = aCamera->Center(); } const Graphic3d_Vertex& aVref = myGravityReferencePoint; - aCamera->SetUp (myCamStartOpUp); - aCamera->SetEye (myCamStartOpEye); - aCamera->SetCenter (myCamStartOpCenter); + aCamera->SetUp (myCamStartOpUp); + aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter); + aCamera->SetDirectionFromEye (myCamStartOpDir); // rotate camera around 3 initial axes gp_Pnt aRCenter (aVref.X(), aVref.Y(), aVref.Z()); @@ -732,26 +734,22 @@ void V3d_View::Rotate (const V3d_TypeOfAxe theAxe, const Standard_Real theAngle, { myGravityReferencePoint.SetCoord (theX, theY, theZ); myCamStartOpUp = aCamera->Up(); + myCamStartOpDir = aCamera->Direction(); myCamStartOpEye = aCamera->Eye(); myCamStartOpCenter = aCamera->Center(); - switch (theAxe) { case V3d_X: myViewAxis = gp::DX(); break; case V3d_Y: myViewAxis = gp::DY(); break; case V3d_Z: myViewAxis = gp::DZ(); break; } - - myCamStartOpUp = aCamera->Up(); - myCamStartOpEye = aCamera->Eye(); - myCamStartOpCenter = aCamera->Center(); } const Graphic3d_Vertex& aVref = myGravityReferencePoint; - aCamera->SetUp (myCamStartOpUp); - aCamera->SetEye (myCamStartOpEye); - aCamera->SetCenter (myCamStartOpCenter); + aCamera->SetUp (myCamStartOpUp); + aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter); + aCamera->SetDirectionFromEye (myCamStartOpDir); // rotate camera around passed axis gp_Trsf aRotation; @@ -782,15 +780,17 @@ void V3d_View::Rotate(const Standard_Real angle, const Standard_Boolean Start) Handle(Graphic3d_Camera) aCamera = Camera(); - if( Start ) { + if (Start) + { myCamStartOpUp = aCamera->Up(); + myCamStartOpDir = aCamera->Direction(); myCamStartOpEye = aCamera->Eye(); myCamStartOpCenter = aCamera->Center(); } - aCamera->SetUp (myCamStartOpUp); - aCamera->SetEye (myCamStartOpEye); - aCamera->SetCenter (myCamStartOpCenter); + aCamera->SetUp (myCamStartOpUp); + aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter); + aCamera->SetDirectionFromEye (myCamStartOpDir); gp_Trsf aRotation; gp_Pnt aRCenter (myDefaultViewPoint); @@ -823,15 +823,17 @@ void V3d_View::Turn(const Standard_Real ax, const Standard_Real ay, const Standa Handle(Graphic3d_Camera) aCamera = Camera(); - if( Start ) { + if (Start) + { myCamStartOpUp = aCamera->Up(); + myCamStartOpDir = aCamera->Direction(); myCamStartOpEye = aCamera->Eye(); myCamStartOpCenter = aCamera->Center(); } - aCamera->SetUp (myCamStartOpUp); - aCamera->SetEye (myCamStartOpEye); - aCamera->SetCenter (myCamStartOpCenter); + aCamera->SetUp (myCamStartOpUp); + aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter); + aCamera->SetDirectionFromEye (myCamStartOpDir); // rotate camera around 3 initial axes gp_Pnt aRCenter = aCamera->Eye(); @@ -886,15 +888,17 @@ void V3d_View::Turn(const Standard_Real angle, const Standard_Boolean Start) Handle(Graphic3d_Camera) aCamera = Camera(); - if( Start ) { + if (Start) + { myCamStartOpUp = aCamera->Up(); + myCamStartOpDir = aCamera->Direction(); myCamStartOpEye = aCamera->Eye(); myCamStartOpCenter = aCamera->Center(); } - aCamera->SetUp (myCamStartOpUp); - aCamera->SetEye (myCamStartOpEye); - aCamera->SetCenter (myCamStartOpCenter); + aCamera->SetUp (myCamStartOpUp); + aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter); + aCamera->SetDirectionFromEye (myCamStartOpDir); gp_Trsf aRotation; gp_Pnt aRCenter = aCamera->Eye(); @@ -1054,8 +1058,10 @@ void V3d_View::SetProj (const V3d_TypeOfOrientation theOrientation, const Handle(Graphic3d_Camera)& aCamera = Camera(); const gp_Pnt anOriginVCS = aCamera->ConvertWorld2View (gp::Origin()); - aCamera->SetCenter (gp_Pnt (0, 0, 0)); - aCamera->SetDirection (gp_Dir (aBck.X(), aBck.Y(), aBck.Z()).Reversed()); + const Standard_Real aNewDist = aCamera->Eye().Distance (gp_Pnt (0, 0, 0)); + aCamera->SetEyeAndCenter (gp_XYZ (0, 0, 0) + aBck.XYZ() * aNewDist, + gp_XYZ (0, 0, 0)); + aCamera->SetDirectionFromEye (-aBck); aCamera->SetUp (gp_Dir (anUp.x(), anUp.y(), anUp.z())); aCamera->OrthogonalizeUp(); @@ -2343,6 +2349,7 @@ void V3d_View::Panning (const Standard_Real theDXv, if (theToStart) { + myCamStartOpDir = aCamera->Direction(); myCamStartOpEye = aCamera->Eye(); myCamStartOpCenter = aCamera->Center(); } @@ -2351,8 +2358,8 @@ void V3d_View::Panning (const Standard_Real theDXv, gp_Pnt aViewDims = aCamera->ViewDimensions(); - aCamera->SetEye (myCamStartOpEye); - aCamera->SetCenter (myCamStartOpCenter); + aCamera->SetEyeAndCenter (myCamStartOpEye, myCamStartOpCenter); + aCamera->SetDirectionFromEye (myCamStartOpDir); Translate (aCamera, -theDXv, -theDYv); Scale (aCamera, aViewDims.X() / theZoomFactor, aViewDims.Y() / theZoomFactor); diff --git a/src/V3d/V3d_View.hxx b/src/V3d/V3d_View.hxx index c27d6f8af5..e6a1dd51f9 100644 --- a/src/V3d/V3d_View.hxx +++ b/src/V3d/V3d_View.hxx @@ -995,6 +995,7 @@ protected: Standard_Real myOldMouseX; Standard_Real myOldMouseY; gp_Dir myCamStartOpUp; + gp_Dir myCamStartOpDir; gp_Pnt myCamStartOpEye; Standard_Real myCamStartOpBnd[6]; gp_Pnt myCamStartOpCenter; diff --git a/tests/bugs/vis/bug29837 b/tests/bugs/vis/bug29837 new file mode 100644 index 0000000000..01019a5bd3 --- /dev/null +++ b/tests/bugs/vis/bug29837 @@ -0,0 +1,20 @@ +puts "============" +puts "0029837: Visualization, Graphic3d_Camera - Fit All operation works incorrectly on flat object" +puts "============" +puts "" + +pload VISUALIZATION +vclear +vinit View1 +vtop +vpoint p1 0 0 4000 +vpoint p2 200 0 4000 +vaspects p1 -setColor RED +vaspects p2 -setColor GREEN +vaspects p1 p2 -setMarkerType . -setMarkerSize 20 +vsegment s p1 p2 +vfit +if { [vreadpixel 5 200 -rgb -name] != "RED" } { puts "Error: p1 not found" } +if { [vreadpixel 402 200 -rgb -name] != "GREEN" } { puts "Error: p2 not found" } + +vdump $::imagedir/${::casename}.png