diff --git a/src/OpenGl/OpenGl_CappingPlaneResource.cxx b/src/OpenGl/OpenGl_CappingPlaneResource.cxx index 7c028b34fb..6825aefea1 100755 --- a/src/OpenGl/OpenGl_CappingPlaneResource.cxx +++ b/src/OpenGl/OpenGl_CappingPlaneResource.cxx @@ -17,6 +17,7 @@ #include #include #include +#include #include IMPLEMENT_STANDARD_RTTIEXT(OpenGl_CappingPlaneResource,OpenGl_Resource) @@ -99,10 +100,10 @@ OpenGl_CappingPlaneResource::~OpenGl_CappingPlaneResource() // function : Update // purpose : // ======================================================================= -void OpenGl_CappingPlaneResource::Update (const Handle(OpenGl_Context)& , +void OpenGl_CappingPlaneResource::Update (const Handle(OpenGl_Context)& theCtx, const Handle(Graphic3d_Aspects)& theObjAspect) { - updateTransform(); + updateTransform (theCtx); updateAspect (theObjAspect); } @@ -179,55 +180,47 @@ void OpenGl_CappingPlaneResource::updateAspect (const Handle(Graphic3d_Aspects)& // function : updateTransform // purpose : // ======================================================================= -void OpenGl_CappingPlaneResource::updateTransform() +void OpenGl_CappingPlaneResource::updateTransform (const Handle(OpenGl_Context)& theCtx) { - const Graphic3d_ClipPlane::Equation& anEquation = myPlaneRoot->GetEquation(); - if (myEquationMod == myPlaneRoot->MCountEquation()) + if (myEquationMod == myPlaneRoot->MCountEquation() + && myLocalOrigin.IsEqual (theCtx->ShaderManager()->LocalOrigin(), gp::Resolution())) { return; // nothing to update } + myEquationMod = myPlaneRoot->MCountEquation(); + myLocalOrigin = theCtx->ShaderManager()->LocalOrigin(); + + const Graphic3d_ClipPlane::Equation& anEq = myPlaneRoot->GetEquation(); + const Standard_Real anEqW = theCtx->ShaderManager()->LocalClippingPlaneW (*myPlaneRoot); + // re-evaluate infinite plane transformation matrix - Standard_ShortReal N[3] = - { (Standard_ShortReal)anEquation[0], - (Standard_ShortReal)anEquation[1], - (Standard_ShortReal)anEquation[2] }; - - Standard_ShortReal T[3] = - { (Standard_ShortReal)(anEquation[0] * -anEquation[3]), - (Standard_ShortReal)(anEquation[1] * -anEquation[3]), - (Standard_ShortReal)(anEquation[2] * -anEquation[3]) }; - - Standard_ShortReal L[3] = { 0.0f, 0.0f, 0.0f }; - Standard_ShortReal F[3] = { 0.0f, 0.0f, 0.0f }; + const Graphic3d_Vec3 aNorm (anEq.xyz()); + const Graphic3d_Vec3 T (anEq.xyz() * -anEqW); // project plane normal onto OX to find left vector - Standard_ShortReal aProjLen = - sqrt ( (Standard_ShortReal)(anEquation[0] * anEquation[0]) - + (Standard_ShortReal)(anEquation[2] * anEquation[2])); + const Standard_ShortReal aProjLen = sqrt ((Standard_ShortReal)anEq.xz().SquareModulus()); + Graphic3d_Vec3 aLeft; if (aProjLen < ShortRealSmall()) { - L[0] = 1.0f; + aLeft[0] = 1.0f; } else { - L[0] = N[2] / aProjLen; - L[2] = -N[0] / aProjLen; + aLeft[0] = aNorm[2] / aProjLen; + aLeft[2] = -aNorm[0] / aProjLen; } - // (-aLeft) x aNorm - F[0] = (-L[1])*N[2] - (-L[2])*N[1]; - F[1] = (-L[2])*N[0] - (-L[0])*N[2]; - F[2] = (-L[0])*N[1] - (-L[1])*N[0]; + const Graphic3d_Vec3 F = Graphic3d_Vec3::Cross (-aLeft, aNorm); - myOrientation.mat[0][0] = L[0]; - myOrientation.mat[0][1] = L[1]; - myOrientation.mat[0][2] = L[2]; + myOrientation.mat[0][0] = aLeft[0]; + myOrientation.mat[0][1] = aLeft[1]; + myOrientation.mat[0][2] = aLeft[2]; myOrientation.mat[0][3] = 0.0f; - myOrientation.mat[1][0] = N[0]; - myOrientation.mat[1][1] = N[1]; - myOrientation.mat[1][2] = N[2]; + myOrientation.mat[1][0] = aNorm[0]; + myOrientation.mat[1][1] = aNorm[1]; + myOrientation.mat[1][2] = aNorm[2]; myOrientation.mat[1][3] = 0.0f; myOrientation.mat[2][0] = F[0]; @@ -239,6 +232,4 @@ void OpenGl_CappingPlaneResource::updateTransform() myOrientation.mat[3][1] = T[1]; myOrientation.mat[3][2] = T[2]; myOrientation.mat[3][3] = 1.0f; - - myEquationMod = myPlaneRoot->MCountEquation(); } diff --git a/src/OpenGl/OpenGl_CappingPlaneResource.hxx b/src/OpenGl/OpenGl_CappingPlaneResource.hxx index 0e61e35501..9547b82b3e 100755 --- a/src/OpenGl/OpenGl_CappingPlaneResource.hxx +++ b/src/OpenGl/OpenGl_CappingPlaneResource.hxx @@ -72,7 +72,7 @@ public: private: //! Update precomputed plane orientation matrix. - void updateTransform(); + void updateTransform (const Handle(OpenGl_Context)& theCtx); //! Update resources. void updateAspect (const Handle(Graphic3d_Aspects)& theObjAspect); @@ -84,6 +84,7 @@ private: OpenGl_Aspects* myAspect; //!< capping face aspect. Handle(Graphic3d_ClipPlane) myPlaneRoot; //!< parent clipping plane structure. Handle(Graphic3d_Aspects) myFillAreaAspect;//!< own capping aspect + gp_XYZ myLocalOrigin; //!< layer origin unsigned int myEquationMod; //!< modification counter for plane equation. unsigned int myAspectMod; //!< modification counter for aspect. diff --git a/src/OpenGl/OpenGl_ShaderManager.hxx b/src/OpenGl/OpenGl_ShaderManager.hxx index 6a00b7e947..ec3661fe94 100644 --- a/src/OpenGl/OpenGl_ShaderManager.hxx +++ b/src/OpenGl/OpenGl_ShaderManager.hxx @@ -60,6 +60,18 @@ public: myHasLocalOrigin = !theOrigin.IsEqual (gp_XYZ(0.0, 0.0, 0.0), gp::Resolution()); } + //! Return clipping plane W equation value moved considering local camera transformation. + Standard_Real LocalClippingPlaneW (const Graphic3d_ClipPlane& thePlane) const + { + const Graphic3d_Vec4d& anEq = thePlane.GetEquation(); + if (myHasLocalOrigin) + { + const gp_XYZ aPos = thePlane.ToPlane().Position().Location().XYZ() - myLocalOrigin; + return -(anEq.x() * aPos.X() + anEq.y() * aPos.Y() + anEq.z() * aPos.Z()); + } + return anEq.w(); + } + //! Creates new shader program or re-use shared instance. //! @param theProxy [IN] program definition //! @param theShareKey [OUT] sharing key @@ -733,9 +745,7 @@ protected: aPlaneEq.w() = float(theEq.w()); if (myHasLocalOrigin) { - const gp_XYZ aPos = thePlane.ToPlane().Position().Location().XYZ() - myLocalOrigin; - const Standard_Real aD = -(theEq.x() * aPos.X() + theEq.y() * aPos.Y() + theEq.z() * aPos.Z()); - aPlaneEq.w() = float(aD); + aPlaneEq.w() = float(LocalClippingPlaneW (thePlane)); } ++thePlaneId; } diff --git a/src/ViewerTest/ViewerTest_ViewerCommands.cxx b/src/ViewerTest/ViewerTest_ViewerCommands.cxx index dd217d6dc4..465947ff6b 100644 --- a/src/ViewerTest/ViewerTest_ViewerCommands.cxx +++ b/src/ViewerTest/ViewerTest_ViewerCommands.cxx @@ -2963,33 +2963,29 @@ void VT_ProcessKeyPress (const char* buf_ret) Draw_Interprete (Draw_ToExitOnCloseView ? "exit" : "vclose"); } } - else + else if (*buf_ret >= '0' && *buf_ret <= '7') // Number { - // Number - const Standard_Integer aSelMode = Draw::Atoi(buf_ret); - if (aSelMode >= 0 && aSelMode <= 7) + const Standard_Integer aSelMode = Draw::Atoi (buf_ret); + bool toEnable = true; + if (const Handle(AIS_InteractiveContext)& aCtx = ViewerTest::GetAISContext()) { - bool toEnable = true; - if (const Handle(AIS_InteractiveContext) aCtx = ViewerTest::GetAISContext()) + AIS_ListOfInteractive aPrsList; + aCtx->DisplayedObjects (aPrsList); + for (AIS_ListOfInteractive::Iterator aPrsIter (aPrsList); aPrsIter.More() && toEnable; aPrsIter.Next()) { - AIS_ListOfInteractive aPrsList; - aCtx->DisplayedObjects (aPrsList); - for (AIS_ListOfInteractive::Iterator aPrsIter (aPrsList); aPrsIter.More() && toEnable; aPrsIter.Next()) + TColStd_ListOfInteger aModes; + aCtx->ActivatedModes (aPrsIter.Value(), aModes); + for (TColStd_ListOfInteger::Iterator aModeIter (aModes); aModeIter.More() && toEnable; aModeIter.Next()) { - TColStd_ListOfInteger aModes; - aCtx->ActivatedModes (aPrsIter.Value(), aModes); - for (TColStd_ListOfInteger::Iterator aModeIter (aModes); aModeIter.More() && toEnable; aModeIter.Next()) + if (aModeIter.Value() == aSelMode) { - if (aModeIter.Value() == aSelMode) - { - toEnable = false; - } + toEnable = false; } } } - TCollection_AsciiString aCmd = TCollection_AsciiString ("vselmode ") + aSelMode + (toEnable ? " 1" : " 0"); - Draw_Interprete (aCmd.ToCString()); } + TCollection_AsciiString aCmd = TCollection_AsciiString ("vselmode ") + aSelMode + (toEnable ? " 1" : " 0"); + Draw_Interprete (aCmd.ToCString()); } } diff --git a/tests/bugs/vis/bug30756 b/tests/bugs/vis/bug30756 new file mode 100644 index 0000000000..d5eb111eba --- /dev/null +++ b/tests/bugs/vis/bug30756 @@ -0,0 +1,19 @@ +puts "=============" +puts "0030756: Visualization, TKOpenGl - capping plane does not work for ZLayer with non-zero origin" +puts "=============" + +pload MODELING VISUALIZATION +box b 1 2 3 +vclear +vclose ALL +vinit View1 +vzbufftrihedron +vaxo +vdisplay -dispMode 1 b +vfit +vclipplane p 1 -equation 0 1 0 -1 -set -capping 1 +if { [vreadpixel 200 200 rgb name] != "GRAY13" } { puts "Error: capping does not work with zero origin" } +vzlayer DEFAULT -origin 0 10 0 +if { [vreadpixel 200 200 rgb name] != "GRAY13" } { puts "Error: capping does not work with non-zero origin" } + +vdump ${imagedir}/${casename}.png