From ad9840d4d47c96fbdfab7fc30b439d67e1d1d722 Mon Sep 17 00:00:00 2001 From: drochalo Date: Thu, 7 Mar 2024 11:38:36 +0000 Subject: [PATCH] 0033533: Visualization - possibility to redefine Graphic3d_TransformPers Split template method apply and moved calculations to virtual method. --- src/Graphic3d/Graphic3d_TransformPers.hxx | 309 +++++++++++----------- 1 file changed, 161 insertions(+), 148 deletions(-) diff --git a/src/Graphic3d/Graphic3d_TransformPers.hxx b/src/Graphic3d/Graphic3d_TransformPers.hxx index 36dc3636a1..20835744da 100644 --- a/src/Graphic3d/Graphic3d_TransformPers.hxx +++ b/src/Graphic3d/Graphic3d_TransformPers.hxx @@ -345,6 +345,163 @@ public: const gp_Pnt* theAnchor = NULL, const Standard_Boolean theToApplyProjPers = true) const; + //! Perform computations for applying transformation persistence on specified matrices. + //! @param theCamera [in] camera definition + //! @param theViewportWidth [in] viewport width + //! @param theViewportHeight [in] viewport height + //! @param theAnchor [in] if not NULL, overrides anchor point + virtual NCollection_Mat4 ComputeApply (Handle(Graphic3d_Camera)& theCamera, + const Standard_Integer theViewportWidth, + const Standard_Integer theViewportHeight, + const gp_Pnt* theAnchor = NULL) const + { + (void)theViewportWidth; + Handle(Graphic3d_Camera) aProxyCamera = theCamera; + if (IsOrthoPers() && !aProxyCamera->IsOrthographic()) + { + aProxyCamera = new Graphic3d_Camera(*theCamera); // If OrthoPers, copy camera and set to orthographic projection + aProxyCamera->SetProjectionType (Graphic3d_Camera::Projection_Orthographic); + } + + NCollection_Mat4 aWorldView = aProxyCamera->OrientationMatrix(); + + // use total size when tiling is active + const Standard_Integer aVPSizeY = aProxyCamera->Tile().IsValid() ? aProxyCamera->Tile().TotalSize.y() : theViewportHeight; + + // a small enough jitter compensation offset + // to avoid image dragging within single pixel in corner cases + const Standard_Real aJitterComp = 0.001; + if ((myMode & Graphic3d_TMF_TriedronPers) != 0) + { + // reset Z focus for trihedron persistence + const Standard_Real aFocus = aProxyCamera->IsOrthographic() + ? aProxyCamera->Distance() + : (aProxyCamera->ZFocusType() == Graphic3d_Camera::FocusType_Relative + ? Standard_Real(aProxyCamera->ZFocus() * aProxyCamera->Distance()) + : Standard_Real(aProxyCamera->ZFocus())); + + // scale factor to pixels + const gp_XYZ aViewDim = aProxyCamera->ViewDimensions (aFocus); + const Standard_Real aScale = Abs(aViewDim.Y()) / Standard_Real(aVPSizeY); + const gp_Dir aForward = aProxyCamera->Direction(); + gp_XYZ aCenter = aProxyCamera->Center().XYZ() + aForward.XYZ() * (aFocus - aProxyCamera->Distance()); + if ((myParams.Params2d.Corner & (Aspect_TOTP_LEFT | Aspect_TOTP_RIGHT)) != 0) + { + const Standard_Real anOffsetX = (Standard_Real(myParams.Params2d.OffsetX) + aJitterComp) * aScale; + const gp_Dir aSide = aForward.Crossed (aProxyCamera->Up()); + const gp_XYZ aDeltaX = aSide.XYZ() * (Abs(aViewDim.X()) * aProxyCamera->NDC2dOffsetX() - anOffsetX); + if ((myParams.Params2d.Corner & Aspect_TOTP_RIGHT) != 0) + { + aCenter += aDeltaX; + } + else + { + aCenter -= aDeltaX; + } + } + if ((myParams.Params2d.Corner & (Aspect_TOTP_TOP | Aspect_TOTP_BOTTOM)) != 0) + { + const Standard_Real anOffsetY = (Standard_Real(myParams.Params2d.OffsetY) + aJitterComp) * aScale; + const gp_XYZ aDeltaY = aProxyCamera->Up().XYZ() * (Abs(aViewDim.Y()) * aProxyCamera->NDC2dOffsetY() - anOffsetY); + if ((myParams.Params2d.Corner & Aspect_TOTP_TOP) != 0) + { + aCenter += aDeltaY; + } + else + { + aCenter -= aDeltaY; + } + } + Graphic3d_TransformUtils::Scale (aWorldView, + 1.0 / theCamera->AxialScale().X(), + 1.0 / theCamera->AxialScale().Y(), + 1.0 / theCamera->AxialScale().Z()); + Graphic3d_TransformUtils::Translate (aWorldView, aCenter.X(), aCenter.Y(), aCenter.Z()); + Graphic3d_TransformUtils::Scale (aWorldView, aScale, aScale, aScale); + } + else if ((myMode & Graphic3d_TMF_2d) != 0) + { + const Standard_Real aFocus = aProxyCamera->IsOrthographic() + ? aProxyCamera->Distance() + : (aProxyCamera->ZFocusType() == Graphic3d_Camera::FocusType_Relative + ? Standard_Real(aProxyCamera->ZFocus() * aProxyCamera->Distance()) + : Standard_Real(aProxyCamera->ZFocus())); + + // scale factor to pixels + const gp_XYZ aViewDim = aProxyCamera->ViewDimensions (aFocus); + const Standard_Real aScale = Abs(aViewDim.Y()) / Standard_Real(aVPSizeY); + gp_XYZ aCenter (0.0, 0.0, -aFocus); + if ((myParams.Params2d.Corner & (Aspect_TOTP_LEFT | Aspect_TOTP_RIGHT)) != 0) + { + aCenter.SetX (-aViewDim.X() * aProxyCamera->NDC2dOffsetX() + (Standard_Real(myParams.Params2d.OffsetX) + aJitterComp) * aScale); + if ((myParams.Params2d.Corner & Aspect_TOTP_RIGHT) != 0) + { + aCenter.SetX (-aCenter.X()); + } + } + if ((myParams.Params2d.Corner & (Aspect_TOTP_TOP | Aspect_TOTP_BOTTOM)) != 0) + { + aCenter.SetY (-aViewDim.Y() * aProxyCamera->NDC2dOffsetY() + (Standard_Real(myParams.Params2d.OffsetY) + aJitterComp) * aScale); + if ((myParams.Params2d.Corner & Aspect_TOTP_TOP) != 0) + { + aCenter.SetY (-aCenter.Y()); + } + } + + aWorldView.InitIdentity(); + Graphic3d_TransformUtils::Translate (aWorldView, aCenter.X(), aCenter.Y(), aCenter.Z()); + Graphic3d_TransformUtils::Scale (aWorldView, aScale, aScale, aScale); + } + else if ((myMode & Graphic3d_TMF_CameraPers) != 0) + { + aWorldView.InitIdentity(); + } + else + { + // Compute reference point for transformation in untransformed projection space. + if (theAnchor != NULL) + { + Graphic3d_TransformUtils::Translate (aWorldView, theAnchor->X(), theAnchor->Y(), theAnchor->Z()); + } + else + { + Graphic3d_TransformUtils::Translate (aWorldView, myParams.Params3d.PntX, myParams.Params3d.PntY, myParams.Params3d.PntZ); + } + + if ((myMode & Graphic3d_TMF_RotatePers) != 0) + { + NCollection_Mat3 aRotMat = persistentRotationMatrix (theCamera, theViewportWidth, theViewportHeight); + + aWorldView.SetValue (0, 0, aRotMat.GetColumn (0).x()); + aWorldView.SetValue (1, 0, aRotMat.GetColumn (0).y()); + aWorldView.SetValue (2, 0, aRotMat.GetColumn (0).z()); + + aWorldView.SetValue (0, 1, aRotMat.GetColumn (1).x()); + aWorldView.SetValue (1, 1, aRotMat.GetColumn (1).y()); + aWorldView.SetValue (2, 1, aRotMat.GetColumn (1).z()); + + aWorldView.SetValue (0, 2, aRotMat.GetColumn (2).x()); + aWorldView.SetValue (1, 2, aRotMat.GetColumn (2).y()); + aWorldView.SetValue (2, 2, aRotMat.GetColumn (2).z()); + } + if (IsAxial()) + { + Graphic3d_TransformUtils::Scale (aWorldView, + 1.0 / theCamera->AxialScale().X(), + 1.0 / theCamera->AxialScale().Y(), + 1.0 / theCamera->AxialScale().Z()); + } + if ((myMode & Graphic3d_TMF_ZoomPers) != 0) + { + // lock zooming + Standard_Real aScale = persistentScale (aProxyCamera, theViewportWidth, theViewportHeight); + Graphic3d_TransformUtils::Scale (aWorldView, aScale, aScale, aScale); + } + } + theCamera = aProxyCamera; + return aWorldView; + } + //! Dumps the content of me into the stream Standard_EXPORT virtual void DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth = -1) const; @@ -396,158 +553,14 @@ void Graphic3d_TransformPers::Apply (const Handle(Graphic3d_Camera)& theCamera, const gp_Pnt* theAnchor, const Standard_Boolean theToApplyProjPers) const { - (void )theViewportWidth; - if (myMode == Graphic3d_TMF_None - || theViewportHeight == 0) + (void)theViewportWidth; + if (myMode == Graphic3d_TMF_None || theViewportHeight == 0) { return; } - Handle(Graphic3d_Camera) aCamera = theCamera; - if (IsOrthoPers() && !aCamera->IsOrthographic()) - { - aCamera = new Graphic3d_Camera(*theCamera); // If OrthoPers, copy camera and set to orthographic projection - aCamera->SetProjectionType (Graphic3d_Camera::Projection_Orthographic); - } - - NCollection_Mat4 aWorldView = aCamera->OrientationMatrix(); - - // use total size when tiling is active - const Standard_Integer aVPSizeY = aCamera->Tile().IsValid() ? aCamera->Tile().TotalSize.y() : theViewportHeight; - - // a small enough jitter compensation offset - // to avoid image dragging within single pixel in corner cases - const Standard_Real aJitterComp = 0.001; - if ((myMode & Graphic3d_TMF_TriedronPers) != 0) - { - // reset Z focus for trihedron persistence - const Standard_Real aFocus = aCamera->IsOrthographic() - ? aCamera->Distance() - : (aCamera->ZFocusType() == Graphic3d_Camera::FocusType_Relative - ? Standard_Real(aCamera->ZFocus() * aCamera->Distance()) - : Standard_Real(aCamera->ZFocus())); - - // scale factor to pixels - const gp_XYZ aViewDim = aCamera->ViewDimensions (aFocus); - const Standard_Real aScale = Abs(aViewDim.Y()) / Standard_Real(aVPSizeY); - const gp_Dir aForward = aCamera->Direction(); - gp_XYZ aCenter = aCamera->Center().XYZ() + aForward.XYZ() * (aFocus - aCamera->Distance()); - if ((myParams.Params2d.Corner & (Aspect_TOTP_LEFT | Aspect_TOTP_RIGHT)) != 0) - { - const Standard_Real anOffsetX = (Standard_Real(myParams.Params2d.OffsetX) + aJitterComp) * aScale; - const gp_Dir aSide = aForward.Crossed (aCamera->Up()); - const gp_XYZ aDeltaX = aSide.XYZ() * (Abs(aViewDim.X()) * aCamera->NDC2dOffsetX() - anOffsetX); - if ((myParams.Params2d.Corner & Aspect_TOTP_RIGHT) != 0) - { - aCenter += aDeltaX; - } - else - { - aCenter -= aDeltaX; - } - } - if ((myParams.Params2d.Corner & (Aspect_TOTP_TOP | Aspect_TOTP_BOTTOM)) != 0) - { - const Standard_Real anOffsetY = (Standard_Real(myParams.Params2d.OffsetY) + aJitterComp) * aScale; - const gp_XYZ aDeltaY = aCamera->Up().XYZ() * (Abs(aViewDim.Y()) * aCamera->NDC2dOffsetY() - anOffsetY); - if ((myParams.Params2d.Corner & Aspect_TOTP_TOP) != 0) - { - aCenter += aDeltaY; - } - else - { - aCenter -= aDeltaY; - } - } - - Graphic3d_TransformUtils::Scale (aWorldView, - 1.0 / theCamera->AxialScale().X(), - 1.0 / theCamera->AxialScale().Y(), - 1.0 / theCamera->AxialScale().Z()); - Graphic3d_TransformUtils::Translate (aWorldView, aCenter.X(), aCenter.Y(), aCenter.Z()); - Graphic3d_TransformUtils::Scale (aWorldView, aScale, aScale, aScale); - } - else if ((myMode & Graphic3d_TMF_2d) != 0) - { - const Standard_Real aFocus = aCamera->IsOrthographic() - ? aCamera->Distance() - : (aCamera->ZFocusType() == Graphic3d_Camera::FocusType_Relative - ? Standard_Real(aCamera->ZFocus() * aCamera->Distance()) - : Standard_Real(aCamera->ZFocus())); - - // scale factor to pixels - const gp_XYZ aViewDim = aCamera->ViewDimensions (aFocus); - const Standard_Real aScale = Abs(aViewDim.Y()) / Standard_Real(aVPSizeY); - gp_XYZ aCenter (0.0, 0.0, -aFocus); - if ((myParams.Params2d.Corner & (Aspect_TOTP_LEFT | Aspect_TOTP_RIGHT)) != 0) - { - aCenter.SetX (-aViewDim.X() * aCamera->NDC2dOffsetX() + (Standard_Real(myParams.Params2d.OffsetX) + aJitterComp) * aScale); - if ((myParams.Params2d.Corner & Aspect_TOTP_RIGHT) != 0) - { - aCenter.SetX (-aCenter.X()); - } - } - if ((myParams.Params2d.Corner & (Aspect_TOTP_TOP | Aspect_TOTP_BOTTOM)) != 0) - { - aCenter.SetY (-aViewDim.Y() * aCamera->NDC2dOffsetY() + (Standard_Real(myParams.Params2d.OffsetY) + aJitterComp) * aScale); - if ((myParams.Params2d.Corner & Aspect_TOTP_TOP) != 0) - { - aCenter.SetY (-aCenter.Y()); - } - } - - aWorldView.InitIdentity(); - Graphic3d_TransformUtils::Translate (aWorldView, aCenter.X(), aCenter.Y(), aCenter.Z()); - Graphic3d_TransformUtils::Scale (aWorldView, aScale, aScale, aScale); - } - else if ((myMode & Graphic3d_TMF_CameraPers) != 0) - { - aWorldView.InitIdentity(); - } - else - { - // Compute reference point for transformation in untransformed projection space. - if (theAnchor != NULL) - { - Graphic3d_TransformUtils::Translate (aWorldView, theAnchor->X(), theAnchor->Y(), theAnchor->Z()); - } - else - { - Graphic3d_TransformUtils::Translate (aWorldView, myParams.Params3d.PntX, myParams.Params3d.PntY, myParams.Params3d.PntZ); - } - - if ((myMode & Graphic3d_TMF_RotatePers) != 0) - { - NCollection_Mat3 aRotMat = persistentRotationMatrix (theCamera, theViewportWidth, theViewportHeight); - - aWorldView.SetValue (0, 0, aRotMat.GetColumn (0).x()); - aWorldView.SetValue (1, 0, aRotMat.GetColumn (0).y()); - aWorldView.SetValue (2, 0, aRotMat.GetColumn (0).z()); - - aWorldView.SetValue (0, 1, aRotMat.GetColumn (1).x()); - aWorldView.SetValue (1, 1, aRotMat.GetColumn (1).y()); - aWorldView.SetValue (2, 1, aRotMat.GetColumn (1).z()); - - aWorldView.SetValue (0, 2, aRotMat.GetColumn (2).x()); - aWorldView.SetValue (1, 2, aRotMat.GetColumn (2).y()); - aWorldView.SetValue (2, 2, aRotMat.GetColumn (2).z()); - } - - if (IsAxial()) - { - Graphic3d_TransformUtils::Scale (aWorldView, - 1.0 / theCamera->AxialScale().X(), - 1.0 / theCamera->AxialScale().Y(), - 1.0 / theCamera->AxialScale().Z()); - } - - if ((myMode & Graphic3d_TMF_ZoomPers) != 0) - { - // lock zooming - Standard_Real aScale = persistentScale (aCamera, theViewportWidth, theViewportHeight); - Graphic3d_TransformUtils::Scale (aWorldView, aScale, aScale, aScale); - } - } + Handle(Graphic3d_Camera) aCamera = new Graphic3d_Camera(*theCamera); + NCollection_Mat4 aWorldView = ComputeApply (aCamera, theViewportWidth, theViewportHeight, theAnchor); if (!theCamera->IsOrthographic() && IsOrthoPers() && theToApplyProjPers) {