diff --git a/samples/mfc/standard/04_Viewer3d/src/ModelClippingDlg.cpp b/samples/mfc/standard/04_Viewer3d/src/ModelClippingDlg.cpp index 86fd233f07..82138e4673 100755 --- a/samples/mfc/standard/04_Viewer3d/src/ModelClippingDlg.cpp +++ b/samples/mfc/standard/04_Viewer3d/src/ModelClippingDlg.cpp @@ -121,13 +121,16 @@ BOOL CModelClippingDlg::OnInitDialog() { // register and activate clipping plane Standard_Boolean toAddPlane = Standard_True; - Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (myView->GetClipPlanes()); - for (; aPlaneIt.More(); aPlaneIt.Next()) + Handle(Graphic3d_SequenceOfHClipPlane) aPlanes = myView->ClipPlanes(); + if (!aPlanes.IsNull()) { - if (aPlaneIt.Value() == myClippingPlane) + for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*aPlanes); aPlaneIt.More(); aPlaneIt.Next()) { - toAddPlane = Standard_False; - break; + if (aPlaneIt.Value() == myClippingPlane) + { + toAddPlane = Standard_False; + break; + } } } @@ -200,13 +203,16 @@ void CModelClippingDlg::OnCheckModelclippingonoff() { // register and activate clipping plane Standard_Boolean toAddPlane = Standard_True; - Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (myView->GetClipPlanes()); - for (; aPlaneIt.More(); aPlaneIt.Next()) + Handle(Graphic3d_SequenceOfHClipPlane) aPlanes = myView->ClipPlanes(); + if (!aPlanes.IsNull()) { - if (aPlaneIt.Value() == myClippingPlane) + for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*aPlanes); aPlaneIt.More(); aPlaneIt.Next()) { - toAddPlane = Standard_False; - break; + if (aPlaneIt.Value() == myClippingPlane) + { + toAddPlane = Standard_False; + break; + } } } @@ -233,7 +239,7 @@ void CModelClippingDlg::OnCheckModelclippingonoff() EOL "if (...)" EOL "{" EOL " // register and activate clipping plane" - EOL " if (!myView->GetClipPlanes().Contains (myClippingPlane))" + EOL " if (!myView->ClipPlanes()->Contains (myClippingPlane))" EOL " {" EOL " myView->AddClipPlane (myClippingPlane);" EOL " }" diff --git a/src/Graphic3d/Graphic3d_CStructure.hxx b/src/Graphic3d/Graphic3d_CStructure.hxx index 2c914e1f7f..ae7bd3331c 100644 --- a/src/Graphic3d/Graphic3d_CStructure.hxx +++ b/src/Graphic3d/Graphic3d_CStructure.hxx @@ -47,13 +47,13 @@ public: } //! @return associated clip planes - const Graphic3d_SequenceOfHClipPlane& ClipPlanes() const + const Handle(Graphic3d_SequenceOfHClipPlane)& ClipPlanes() const { return myClipPlanes; } //! Pass clip planes to the associated graphic driver structure - void SetClipPlanes (const Graphic3d_SequenceOfHClipPlane& thePlanes) { myClipPlanes = thePlanes; } + void SetClipPlanes (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes) { myClipPlanes = thePlanes; } //! @return bounding box of this presentation const Graphic3d_BndBox4f& BoundingBox() const @@ -155,7 +155,7 @@ protected: Handle(Graphic3d_GraphicDriver) myGraphicDriver; Graphic3d_SequenceOfGroup myGroups; Graphic3d_BndBox4f myBndBox; - Graphic3d_SequenceOfHClipPlane myClipPlanes; + Handle(Graphic3d_SequenceOfHClipPlane) myClipPlanes; public: diff --git a/src/Graphic3d/Graphic3d_CView.hxx b/src/Graphic3d/Graphic3d_CView.hxx index 3a04dfbe52..01f9a7a776 100644 --- a/src/Graphic3d/Graphic3d_CView.hxx +++ b/src/Graphic3d/Graphic3d_CView.hxx @@ -456,10 +456,10 @@ public: virtual void SetLights (const Graphic3d_ListOfCLight& theLights) = 0; //! Returns list of clip planes set for the view. - virtual const Graphic3d_SequenceOfHClipPlane& ClipPlanes() const = 0; + virtual const Handle(Graphic3d_SequenceOfHClipPlane)& ClipPlanes() const = 0; //! Sets list of clip planes for the view. - virtual void SetClipPlanes (const Graphic3d_SequenceOfHClipPlane& thePlanes) = 0; + virtual void SetClipPlanes (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes) = 0; //! Fill in the dictionary with diagnostic info. //! Should be called within rendering thread. diff --git a/src/Graphic3d/Graphic3d_SequenceOfHClipPlane.hxx b/src/Graphic3d/Graphic3d_SequenceOfHClipPlane.hxx index 57d337615e..457e799609 100755 --- a/src/Graphic3d/Graphic3d_SequenceOfHClipPlane.hxx +++ b/src/Graphic3d/Graphic3d_SequenceOfHClipPlane.hxx @@ -17,9 +17,32 @@ #define _Graphic3d_SequenceOfHClipPlane_HeaderFile #include +#include #include -// CDL-header shortcut for sequence of graphical clipping planes. -typedef NCollection_Sequence Graphic3d_SequenceOfHClipPlane; +//! Class defining the sequence of clipping planes. +class Graphic3d_SequenceOfHClipPlane : public Standard_Transient, public NCollection_Sequence +{ +DEFINE_STANDARD_RTTI_INLINE(Graphic3d_SequenceOfHClipPlane,Standard_Transient) +public: + DEFINE_STANDARD_ALLOC + DEFINE_NCOLLECTION_ALLOC -#endif + //! Empty constructor. + Graphic3d_SequenceOfHClipPlane() : myToOverrideGlobal (Standard_False) {} + + //! Return true if local properties should override global properties. + Standard_Boolean ToOverrideGlobal() const { return myToOverrideGlobal; } + + //! Setup flag defining if local properties should override global properties. + void SetOverrideGlobal (const Standard_Boolean theToOverride) { myToOverrideGlobal = theToOverride; } + +private: + + Standard_Boolean myToOverrideGlobal; + +}; + +DEFINE_STANDARD_HANDLE(Graphic3d_SequenceOfHClipPlane, Standard_Transient) + +#endif // _Graphic3d_SequenceOfHClipPlane_HeaderFile diff --git a/src/Graphic3d/Graphic3d_Structure.cxx b/src/Graphic3d/Graphic3d_Structure.cxx index d783b22017..c08ed0258f 100644 --- a/src/Graphic3d/Graphic3d_Structure.cxx +++ b/src/Graphic3d/Graphic3d_Structure.cxx @@ -1595,7 +1595,7 @@ Graphic3d_ZLayerId Graphic3d_Structure::GetZLayer() const //function : SetClipPlanes //purpose : //======================================================================= -void Graphic3d_Structure::SetClipPlanes (const Graphic3d_SequenceOfHClipPlane& thePlanes) +void Graphic3d_Structure::SetClipPlanes (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes) { myCStructure->SetClipPlanes (thePlanes); } @@ -1604,7 +1604,7 @@ void Graphic3d_Structure::SetClipPlanes (const Graphic3d_SequenceOfHClipPlane& t //function : GetClipPlanes //purpose : //======================================================================= -const Graphic3d_SequenceOfHClipPlane& Graphic3d_Structure::GetClipPlanes() const +const Handle(Graphic3d_SequenceOfHClipPlane)& Graphic3d_Structure::ClipPlanes() const { return myCStructure->ClipPlanes(); } diff --git a/src/Graphic3d/Graphic3d_Structure.hxx b/src/Graphic3d/Graphic3d_Structure.hxx index adf1efa33c..5bf3474d05 100644 --- a/src/Graphic3d/Graphic3d_Structure.hxx +++ b/src/Graphic3d/Graphic3d_Structure.hxx @@ -161,11 +161,11 @@ public: //! Changes a sequence of clip planes slicing the structure on rendering. //! @param thePlanes [in] the set of clip planes. - Standard_EXPORT void SetClipPlanes (const Graphic3d_SequenceOfHClipPlane& thePlanes); + Standard_EXPORT void SetClipPlanes (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes); //! Get clip planes slicing the structure on rendering. //! @return set of clip planes. - Standard_EXPORT const Graphic3d_SequenceOfHClipPlane& GetClipPlanes() const; + Standard_EXPORT const Handle(Graphic3d_SequenceOfHClipPlane)& ClipPlanes() const; //! Modifies the visibility indicator to Standard_True or //! Standard_False for the structure . diff --git a/src/OpenGl/OpenGl_CappingAlgo.cxx b/src/OpenGl/OpenGl_CappingAlgo.cxx index 36862c1359..f0bfb6695a 100755 --- a/src/OpenGl/OpenGl_CappingAlgo.cxx +++ b/src/OpenGl/OpenGl_CappingAlgo.cxx @@ -64,11 +64,11 @@ namespace //! Render capping for specific structure. static void renderCappingForStructure (const Handle(OpenGl_Workspace)& theWorkspace, const OpenGl_Structure& theStructure, + const OpenGl_ClippingIterator& thePlaneIter, const Handle(OpenGl_CappingPlaneResource)& thePlane) { - const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext(); - const Graphic3d_SequenceOfHClipPlane& aContextPlanes = aContext->Clipping().Planes(); - const Handle(Graphic3d_ClipPlane)& aRenderPlane = thePlane->Plane(); + const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext(); + const Handle(Graphic3d_ClipPlane)& aRenderPlane = thePlane->Plane(); for (OpenGl_Structure::GroupIterator aGroupIter (theStructure.Groups()); aGroupIter.More(); aGroupIter.Next()) { if (!aGroupIter.Value()->IsClosed()) @@ -77,11 +77,7 @@ namespace } // enable only the rendering plane to generate stencil mask - for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (aContextPlanes); aPlaneIt.More(); aPlaneIt.Next()) - { - const Standard_Boolean isOn = (aPlaneIt.Value() == aRenderPlane); - aContext->ChangeClipping().SetEnabled (aContext, aPlaneIt.Value(), isOn); - } + aContext->ChangeClipping().DisableAllExcept (aContext, thePlaneIter); aContext->ShaderManager()->UpdateClippingState(); glClear (GL_STENCIL_BUFFER_BIT); @@ -118,11 +114,7 @@ namespace theWorkspace->ApplyAspectFace(); // enable all clip plane except the rendered one - for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (aContextPlanes); aPlaneIt.More(); aPlaneIt.Next()) - { - const Standard_Boolean isOn = (aPlaneIt.Value() != aRenderPlane); - aContext->ChangeClipping().SetEnabled (aContext, aPlaneIt.Value(), isOn); - } + aContext->ChangeClipping().EnableAllExcept (aContext, thePlaneIter); aContext->ShaderManager()->UpdateClippingState(); // render capping plane using the generated stencil mask @@ -136,13 +128,15 @@ namespace ? aGroupIter.Value()->AspectFace() : NULL); + // turn on the current plane to restore initial state + aContext->ChangeClipping().SetEnabled (aContext, thePlaneIter, Standard_True); aContext->ShaderManager()->RevertClippingState(); aContext->ShaderManager()->RevertClippingState(); } if (theStructure.InstancedStructure() != NULL) { - renderCappingForStructure (theWorkspace, *theStructure.InstancedStructure(), thePlane); + renderCappingForStructure (theWorkspace, *theStructure.InstancedStructure(), thePlaneIter, thePlane); } } } @@ -155,23 +149,9 @@ void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorks const OpenGl_Structure& theStructure) { const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext(); - - // check whether algorithm need to be performed - Standard_Boolean isCapping = Standard_False; - const Graphic3d_SequenceOfHClipPlane& aContextPlanes = aContext->Clipping().Planes(); - for (Graphic3d_SequenceOfHClipPlane::Iterator aCappingIt (aContextPlanes); aCappingIt.More(); aCappingIt.Next()) - { - const Handle(Graphic3d_ClipPlane)& aPlane = aCappingIt.Value(); - if (aPlane->IsCapping()) - { - isCapping = Standard_True; - break; - } - } - - // do not perform algorithm is there is nothing to render - if (!isCapping) + if (!aContext->Clipping().IsCappingOn()) { + // do not perform algorithm if there is nothing to render return; } @@ -192,11 +172,12 @@ void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorks glDepthFunc (GL_LESS); // generate capping for every clip plane - for (Graphic3d_SequenceOfHClipPlane::Iterator aCappingIt (aContextPlanes); aCappingIt.More(); aCappingIt.Next()) + for (OpenGl_ClippingIterator aCappingIt (aContext->Clipping()); aCappingIt.More(); aCappingIt.Next()) { // get plane being rendered const Handle(Graphic3d_ClipPlane)& aRenderPlane = aCappingIt.Value(); - if (!aRenderPlane->IsCapping()) + if (!aRenderPlane->IsCapping() + || aCappingIt.IsDisabled()) { continue; } @@ -211,7 +192,7 @@ void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorks aContext->ShareResource (aResId, aPlaneRes); } - renderCappingForStructure (theWorkspace, theStructure, aPlaneRes); + renderCappingForStructure (theWorkspace, theStructure, aCappingIt, aPlaneRes); // set delayed resource release aPlaneRes.Nullify(); @@ -224,12 +205,6 @@ void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorks glStencilFunc (GL_ALWAYS, 0, 0xFF); glDisable (GL_STENCIL_TEST); - // enable clipping - for (Graphic3d_SequenceOfHClipPlane::Iterator aCappingIt (aContextPlanes); aCappingIt.More(); aCappingIt.Next()) - { - aContext->ChangeClipping().SetEnabled (aContext, aCappingIt.Value(), Standard_True); - } - // restore rendering aspects theWorkspace->SetAspectFace (aFaceAsp); theWorkspace->SetRenderFilter (aRenderFilter); diff --git a/src/OpenGl/OpenGl_Clipping.cxx b/src/OpenGl/OpenGl_Clipping.cxx index 4ff37726c4..da56cd4966 100755 --- a/src/OpenGl/OpenGl_Clipping.cxx +++ b/src/OpenGl/OpenGl_Clipping.cxx @@ -19,19 +19,33 @@ #include #include -#if defined(GL_ES_VERSION_2_0) - // id does not matter for GLSL-based clipping, just for consistency - #define GL_CLIP_PLANE0 0x3000 -#endif +// ======================================================================= +// function : OpenGl_ClippingIterator +// purpose : +// ======================================================================= +OpenGl_ClippingIterator::OpenGl_ClippingIterator (const OpenGl_Clipping& theClipping) +: myDisabled (&theClipping.myDisabledPlanes), + myCurrIndex (1) +{ + if (!theClipping.myPlanesGlobal.IsNull()) + { + myIter1.Init (*theClipping.myPlanesGlobal); + } + if (!theClipping.myPlanesLocal.IsNull()) + { + myIter2.Init (*theClipping.myPlanesLocal); + } +} // ======================================================================= // function : OpenGl_ClippingState // purpose : // ======================================================================= OpenGl_Clipping::OpenGl_Clipping () -: myEmptyPlaneIds (new Aspect_GenId (GL_CLIP_PLANE0, GL_CLIP_PLANE0 + 5)), +: myEmptyPlaneIds (new NCollection_Shared (1, 6)), myNbClipping (0), - myNbCapping (0) + myNbCapping (0), + myNbDisabled (0) {} // ======================================================================= @@ -40,72 +54,94 @@ OpenGl_Clipping::OpenGl_Clipping () // ======================================================================= void OpenGl_Clipping::Init (const Standard_Integer theMaxPlanes) { - myPlanes.Clear(); - myPlaneStates.Clear(); + myPlanesGlobal.Nullify(); + myPlanesLocal.Nullify(); + myNbClipping = 0; myNbCapping = 0; - Standard_Integer aLowerId = GL_CLIP_PLANE0; - Standard_Integer aUpperId = GL_CLIP_PLANE0 + theMaxPlanes - 1; - myEmptyPlaneIds = new Aspect_GenId (aLowerId, aUpperId); + myNbDisabled = 0; + myEmptyPlaneIds = new NCollection_Shared (1, theMaxPlanes); +} + +// ======================================================================= +// function : Reset +// purpose : +// ======================================================================= +void OpenGl_Clipping::Reset (const Handle(OpenGl_Context)& theGlCtx, + const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes) +{ + const Standard_Integer aStartIndex = myPlanesGlobal.IsNull() ? 1 : myPlanesGlobal->Size() + 1; + remove (theGlCtx, myPlanesLocal, aStartIndex); + remove (theGlCtx, myPlanesGlobal, 1); + + myPlanesGlobal = thePlanes; + myPlanesLocal.Nullify(); + + add (theGlCtx, thePlanes, 1); + myNbDisabled = 0; + + // Method ::add() implicitly extends myDisabledPlanes (NCollection_Vector::SetValue()), + // however we do not reset myDisabledPlanes and mySkipFilter beforehand to avoid redundant memory re-allocations. + // So once extended, they will never reduce their size to lower values. + // This should not be a problem since overall number of clipping planes is expected to be quite small. +} + +// ======================================================================= +// function : SetLocalPlanes +// purpose : +// ======================================================================= +void OpenGl_Clipping::SetLocalPlanes (const Handle(OpenGl_Context)& theGlCtx, + const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes) +{ + const Standard_Integer aStartIndex = myPlanesGlobal.IsNull() ? 1 : myPlanesGlobal->Size() + 1; + remove (theGlCtx, myPlanesLocal, aStartIndex); + + myPlanesLocal = thePlanes; + + add (theGlCtx, thePlanes, aStartIndex); } // ======================================================================= // function : add // purpose : // ======================================================================= -void OpenGl_Clipping::add (const Handle(OpenGl_Context)& theGlCtx, - Graphic3d_SequenceOfHClipPlane& thePlanes) +void OpenGl_Clipping::add (const Handle(OpenGl_Context)& theGlCtx, + const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes, + const Standard_Integer theStartIndex) { - const bool toUseFfp = theGlCtx->core11 != NULL - && theGlCtx->caps->ffpEnable; - if (!toUseFfp) + if (thePlanes.IsNull()) { - addLazy (theGlCtx, thePlanes); return; } - // Set either identity or pure view matrix. - theGlCtx->ApplyWorldViewMatrix(); - - addLazy (theGlCtx, thePlanes); - - // Restore combined model-view matrix. - theGlCtx->ApplyModelViewMatrix(); -} - -// ======================================================================= -// function : addLazy -// purpose : -// ======================================================================= -void OpenGl_Clipping::addLazy (const Handle(OpenGl_Context)& theGlCtx, - Graphic3d_SequenceOfHClipPlane& thePlanes) -{ #if !defined(GL_ES_VERSION_2_0) const bool toUseFfp = theGlCtx->core11 != NULL && theGlCtx->caps->ffpEnable; + if (toUseFfp) + { + // Set either identity or pure view matrix. + theGlCtx->ApplyWorldViewMatrix(); + } #else (void )theGlCtx; #endif - Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (thePlanes); - while (aPlaneIt.More() && myEmptyPlaneIds->HasFree()) + Standard_Integer aPlaneId = theStartIndex; + for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*thePlanes); aPlaneIt.More(); aPlaneIt.Next(), ++aPlaneId) { const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value(); - if (Contains (aPlane)) + myDisabledPlanes.SetValue (aPlaneId, Standard_False); // automatically resizes the vector + if (!aPlane->IsOn()) { - thePlanes.Remove (aPlaneIt); continue; } - Standard_Integer anID = myEmptyPlaneIds->Next(); - myPlanes.Append (aPlane); - myPlaneStates.Bind (aPlane, PlaneProps (anID, Standard_True)); - #if !defined(GL_ES_VERSION_2_0) - if (toUseFfp) + if (toUseFfp && myEmptyPlaneIds->HasFree()) { - ::glEnable ((GLenum)anID); - theGlCtx->core11->glClipPlane ((GLenum)anID, aPlane->GetEquation()); + const Standard_Integer anFfpPlaneID = GL_CLIP_PLANE0 + myEmptyPlaneIds->Next(); + ::glEnable ((GLenum )anFfpPlaneID); + theGlCtx->core11->glClipPlane ((GLenum )anFfpPlaneID, aPlane->GetEquation()); } #endif if (aPlane->IsCapping()) @@ -116,130 +152,60 @@ void OpenGl_Clipping::addLazy (const Handle(OpenGl_Context)& theGlCtx, { ++myNbClipping; } - - aPlaneIt.Next(); } - if (!myEmptyPlaneIds->HasFree()) - { - while (aPlaneIt.More()) - { - thePlanes.Remove (aPlaneIt); - } - } -} - -// ======================================================================= -// function : Remove -// purpose : -// ======================================================================= -void OpenGl_Clipping::Remove (const Handle(OpenGl_Context)& theGlCtx, - const Graphic3d_SequenceOfHClipPlane& thePlanes) -{ #if !defined(GL_ES_VERSION_2_0) - const bool toUseFfp = theGlCtx->core11 != NULL - && theGlCtx->caps->ffpEnable; -#else - (void )theGlCtx; + // Restore combined model-view matrix. + if (toUseFfp) + { + theGlCtx->ApplyModelViewMatrix(); + } #endif - - Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (thePlanes); - for (; aPlaneIt.More(); aPlaneIt.Next()) - { - const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value(); - PlaneProps* aProps = myPlaneStates.ChangeSeek (aPlane); - if (aProps == NULL) - { - continue; - } - - Standard_Integer anID = aProps->ContextID; - if (aProps->IsEnabled) - { - #if !defined(GL_ES_VERSION_2_0) - if (toUseFfp) - { - ::glDisable ((GLenum)anID); - } - #endif - if (aPlane->IsCapping()) - { - --myNbCapping; - } - else - { - --myNbClipping; - } - } - - myEmptyPlaneIds->Free (anID); - myPlaneStates.UnBind (aPlane); - } - - // renew collection of planes - aPlaneIt.Init (myPlanes); - while (aPlaneIt.More()) - { - const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value(); - if (!myPlaneStates.IsBound (aPlane)) - { - myPlanes.Remove (aPlaneIt); - } - else - { - aPlaneIt.Next(); - } - } } // ======================================================================= -// function : SetEnabled +// function : remove // purpose : // ======================================================================= -void OpenGl_Clipping::SetEnabled (const Handle(OpenGl_Context)& theGlCtx, - const Handle(Graphic3d_ClipPlane)& thePlane, - const Standard_Boolean theIsEnabled) +void OpenGl_Clipping::remove (const Handle(OpenGl_Context)& theGlCtx, + const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes, + const Standard_Integer theStartIndex) { - PlaneProps* aProps = myPlaneStates.ChangeSeek (thePlane); - if (aProps == NULL - || aProps->IsEnabled == theIsEnabled) + if (thePlanes.IsNull()) { return; } #if !defined(GL_ES_VERSION_2_0) - GLenum anID = (GLenum)aProps->ContextID; const bool toUseFfp = theGlCtx->core11 != NULL && theGlCtx->caps->ffpEnable; #else (void )theGlCtx; #endif - if (theIsEnabled) + + Standard_Integer aPlaneIndex = theStartIndex; + for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*thePlanes); aPlaneIt.More(); aPlaneIt.Next(), ++aPlaneIndex) { - #if !defined(GL_ES_VERSION_2_0) - if (toUseFfp) + const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value(); + if (!aPlane->IsOn() + || myDisabledPlanes.Value (aPlaneIndex)) { - ::glEnable (anID); + continue; + } + + #if !defined(GL_ES_VERSION_2_0) + const Standard_Integer anFfpPlaneID = myEmptyPlaneIds->Lower() + aPlaneIndex - 1; + if (anFfpPlaneID <= myEmptyPlaneIds->Upper()) + { + if (toUseFfp) + { + ::glDisable (GLenum(GL_CLIP_PLANE0 + anFfpPlaneID)); + } + myEmptyPlaneIds->Free (anFfpPlaneID); } #endif - if (thePlane->IsCapping()) - { - ++myNbCapping; - } - else - { - ++myNbClipping; - } - } - else - { - #if !defined(GL_ES_VERSION_2_0) - if (toUseFfp) - { - ::glDisable (anID); - } - #endif - if (thePlane->IsCapping()) + + if (aPlane->IsCapping()) { --myNbCapping; } @@ -248,6 +214,163 @@ void OpenGl_Clipping::SetEnabled (const Handle(OpenGl_Context)& theGlCtx, --myNbClipping; } } - - aProps->IsEnabled = theIsEnabled; +} + +// ======================================================================= +// function : SetEnabled +// purpose : +// ======================================================================= +Standard_Boolean OpenGl_Clipping::SetEnabled (const Handle(OpenGl_Context)& theGlCtx, + const OpenGl_ClippingIterator& thePlane, + const Standard_Boolean theIsEnabled) +{ + const Standard_Integer aPlaneIndex = thePlane.PlaneIndex(); + Standard_Boolean& isDisabled = myDisabledPlanes.ChangeValue (aPlaneIndex); + if (isDisabled == !theIsEnabled) + { + return Standard_False; + } + + isDisabled = !theIsEnabled; + +#if !defined(GL_ES_VERSION_2_0) + const bool toUseFfp = theGlCtx->core11 != NULL + && theGlCtx->caps->ffpEnable; + if (toUseFfp) + { + const Standard_Integer anFfpPlaneID = myEmptyPlaneIds->Lower() + aPlaneIndex - 1; + if (anFfpPlaneID <= myEmptyPlaneIds->Upper()) + { + if (theIsEnabled) + { + ::glEnable (GLenum(GL_CLIP_PLANE0 + anFfpPlaneID)); + } + else + { + ::glDisable (GLenum(GL_CLIP_PLANE0 + anFfpPlaneID)); + } + } + } +#else + (void )theGlCtx; +#endif + + if (thePlane.Value()->IsCapping()) + { + myNbCapping += (theIsEnabled ? 1 : -1); + } + else + { + myNbClipping += (theIsEnabled ? 1 : -1); + } + myNbDisabled -= (theIsEnabled ? 1 : -1); + return Standard_True; +} + +// ======================================================================= +// function : RestoreDisabled +// purpose : +// ======================================================================= +void OpenGl_Clipping::RestoreDisabled (const Handle(OpenGl_Context)& theGlCtx) +{ + if (myNbDisabled == 0) + { + return; + } + + myNbDisabled = 0; +#if !defined(GL_ES_VERSION_2_0) + const bool toUseFfp = theGlCtx->core11 != NULL + && theGlCtx->caps->ffpEnable; +#else + (void )theGlCtx; +#endif + for (OpenGl_ClippingIterator aPlaneIter (*this); aPlaneIter.More(); aPlaneIter.Next()) + { + Standard_Boolean& isDisabled = myDisabledPlanes.ChangeValue (aPlaneIter.PlaneIndex()); + if (!isDisabled) + { + continue; + } + + isDisabled = Standard_False; + #if !defined(GL_ES_VERSION_2_0) + if (toUseFfp) + { + const Standard_Integer anFfpPlaneID = myEmptyPlaneIds->Lower() + aPlaneIter.PlaneIndex() - 1; + if (anFfpPlaneID <= myEmptyPlaneIds->Upper()) + { + ::glEnable (GLenum(GL_CLIP_PLANE0 + anFfpPlaneID)); + } + } + #endif + + const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIter.Value(); + if (aPlane->IsCapping()) + { + ++myNbCapping; + } + else + { + ++myNbClipping; + } + } +} + +// ======================================================================= +// function : DisableGlobal +// purpose : +// ======================================================================= +void OpenGl_Clipping::DisableGlobal (const Handle(OpenGl_Context)& theGlCtx) +{ + for (OpenGl_ClippingIterator aPlaneIter (*this); aPlaneIter.More(); aPlaneIter.Next()) + { + if (!aPlaneIter.IsGlobal()) + { + // local planes always follow global ones in iterator + return; + } + + SetEnabled (theGlCtx, aPlaneIter, Standard_False); + } +} + +// ======================================================================= +// function : DisableAllExcept +// purpose : +// ======================================================================= +void OpenGl_Clipping::DisableAllExcept (const Handle(OpenGl_Context)& theGlCtx, + const OpenGl_ClippingIterator& thePlane) +{ + for (OpenGl_ClippingIterator aPlaneIter (*this); aPlaneIter.More(); aPlaneIter.Next()) + { + if (aPlaneIter.IsDisabled()) + { + mySkipFilter.SetValue (aPlaneIter.PlaneIndex(), Standard_True); + continue; + } + + const Standard_Boolean isOn = (aPlaneIter.PlaneIndex() == thePlane.PlaneIndex()); + SetEnabled (theGlCtx, aPlaneIter, isOn); + mySkipFilter.SetValue (aPlaneIter.PlaneIndex(), Standard_False); + } +} + +// ======================================================================= +// function : EnableAllExcept +// purpose : +// ======================================================================= +void OpenGl_Clipping::EnableAllExcept (const Handle(OpenGl_Context)& theGlCtx, + const OpenGl_ClippingIterator& thePlane) +{ + for (OpenGl_ClippingIterator aPlaneIter (*this); aPlaneIter.More(); aPlaneIter.Next()) + { + if (mySkipFilter.Value (aPlaneIter.PlaneIndex())) + { + continue; + } + + const Standard_Boolean isOn = (aPlaneIter.PlaneIndex() != thePlane.PlaneIndex()); + SetEnabled (theGlCtx, aPlaneIter, isOn); + } } diff --git a/src/OpenGl/OpenGl_Clipping.hxx b/src/OpenGl/OpenGl_Clipping.hxx index 4a13ac29cc..00868871d9 100755 --- a/src/OpenGl/OpenGl_Clipping.hxx +++ b/src/OpenGl/OpenGl_Clipping.hxx @@ -17,15 +17,12 @@ #define _OpenGl_Clipping_H__ #include -#include #include -#include -#include +#include #include -#include class OpenGl_Context; -class OpenGl_Workspace; +class OpenGl_ClippingIterator; //! This class contains logics related to tracking and modification of clipping plane //! state for particular OpenGl context. It contains information about enabled @@ -43,56 +40,55 @@ public: //! @name general methods //! @param theMaxPlanes [in] number of clipping planes supported by OpenGl context. Standard_EXPORT void Init (const Standard_Integer theMaxPlanes); -public: //! @name non-modifying getters + //! Setup list of global (for entire view) clipping planes + //! and clears local plane list if it was not released before. + Standard_EXPORT void Reset (const Handle(OpenGl_Context)& theGlCtx, + const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes); - //! Check whether the clipping plane has been added to the current context state. - //! @param thePlane [in] the plane to check. - //! @return True if plane is set. - inline Standard_Boolean Contains (const Handle(Graphic3d_ClipPlane)& thePlane) const - { - return myPlaneStates.IsBound (thePlane); - } - - //! Get clip planes defined for context. - //! @return sequence of set clipping planes. - inline const Graphic3d_SequenceOfHClipPlane& Planes() const - { - return myPlanes; - } - - //! Check whether the clipping plane has been set and enabled for the current context state. - //! @param thePlane [in] the plane to check. - //! @return True if plane is enabled. - inline Standard_Boolean IsEnabled (const Handle(Graphic3d_ClipPlane)& thePlane) const - { - return myPlaneStates.Find (thePlane).IsEnabled; - } + //! Setup list of local (for current object) clipping planes. + Standard_EXPORT void SetLocalPlanes (const Handle(OpenGl_Context)& theGlCtx, + const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes); //! @return true if there are enabled clipping planes (NOT capping) - inline Standard_Boolean IsClippingOn() const - { - return myNbClipping > 0; - } + Standard_Boolean IsClippingOn() const { return myNbClipping > 0; } //! @return true if there are enabled capping planes - inline Standard_Boolean IsCappingOn() const - { - return myNbCapping > 0; - } + Standard_Boolean IsCappingOn() const { return myNbCapping > 0; } //! @return true if there are enabled clipping or capping planes - inline Standard_Boolean IsClippingOrCappingOn() const - { - return (myNbClipping + myNbCapping) > 0; - } + Standard_Boolean IsClippingOrCappingOn() const { return (myNbClipping + myNbCapping) > 0; } //! @return number of enabled clipping + capping planes - Standard_Integer NbClippingOrCappingOn() const - { - return myNbClipping + myNbCapping; - } + Standard_Integer NbClippingOrCappingOn() const { return myNbClipping + myNbCapping; } -public: //! @name clipping state modification commands +public: //! @name advanced method for disabling defined planes + + //! Return true if some clipping planes have been temporarily disabled. + Standard_Boolean HasDisabled() const { return myNbDisabled > 0; } + + //! Disable plane temporarily. + Standard_EXPORT Standard_Boolean SetEnabled (const Handle(OpenGl_Context)& theGlCtx, + const OpenGl_ClippingIterator& thePlane, + const Standard_Boolean theIsEnabled); + + //! Temporarily disable all planes from the global (view) list, keep only local (object) list. + Standard_EXPORT void DisableGlobal (const Handle(OpenGl_Context)& theGlCtx); + + //! Restore all temporarily disabled planes. + //! Does NOT affect constantly disabled planes Graphic3d_ClipPlane::IsOn(). + Standard_EXPORT void RestoreDisabled (const Handle(OpenGl_Context)& theGlCtx); + + //! Temporarily disable all planes except specified one. + //! Does not affect already disabled planes. + Standard_EXPORT void DisableAllExcept (const Handle(OpenGl_Context)& theGlCtx, + const OpenGl_ClippingIterator& thePlane); + + //! Enable back planes disabled by ::DisableAllExcept(). + //! Keeps only specified plane enabled. + Standard_EXPORT void EnableAllExcept (const Handle(OpenGl_Context)& theGlCtx, + const OpenGl_ClippingIterator& thePlane); + +protected: //! @name clipping state modification commands //! Add planes to the context clipping at the specified system of coordinates. //! This methods loads appropriate transformation matrix from workspace to @@ -107,86 +103,86 @@ public: //! @name clipping state modification commands //! @param thePlanes [in/out] the list of planes to be added //! The list then provides information on which planes were really added to clipping state. //! This list then can be used to fall back to previous state. - Standard_EXPORT void add (const Handle(OpenGl_Context)& theGlCtx, - Graphic3d_SequenceOfHClipPlane& thePlanes); - - //! Add planes to the context clipping at the specified system of coordinates. - //! This method assumes that appropriate matrix is already set in context state. - //! If the number of the passed planes exceeds capabilities of OpenGl, the last planes - //! are simply ignored. - //! @param thePlanes [in/out] the list of planes to be added. - //! The list then provides information on which planes were really added to clipping state. - //! This list then can be used to fall back to previous state. - Standard_EXPORT void addLazy (const Handle(OpenGl_Context)& theGlCtx, - Graphic3d_SequenceOfHClipPlane& thePlanes); + Standard_EXPORT void add (const Handle(OpenGl_Context)& theGlCtx, + const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes, + const Standard_Integer theStartIndex); //! Remove the passed set of clipping planes from the context state. //! @param thePlanes [in] the planes to remove from list. - Standard_EXPORT void Remove (const Handle(OpenGl_Context)& theGlCtx, - const Graphic3d_SequenceOfHClipPlane& thePlanes); - - //! Enable or disable clipping plane in the OpenGl context. - //! @param thePlane [in] the plane to affect. - //! @param theIsEnabled [in] the state of the plane. - Standard_EXPORT void SetEnabled (const Handle(OpenGl_Context)& theGlCtx, - const Handle(Graphic3d_ClipPlane)& thePlane, - const Standard_Boolean theIsEnabled); - -public: //! @name Short-cuts - - //! Add planes to the context clipping at the world system of coordinates. - //! If the number of the passed planes exceeds capabilities of OpenGl, the last planes - //! are simply ignored. - //! @param theGlCtx [in] context to access the matrices - //! @param thePlanes [in/out] the list of planes to be added - //! The list then provides information on which planes were really added to clipping state. - //! This list then can be used to fall back to previous state. - inline void AddWorld (const Handle(OpenGl_Context)& theGlCtx, - Graphic3d_SequenceOfHClipPlane& thePlanes) - { - add (theGlCtx, thePlanes); - } - - //! Remove all of the planes from context state. - inline void RemoveAll (const Handle(OpenGl_Context)& theGlCtx) - { - Remove (theGlCtx, Planes()); - } + Standard_EXPORT void remove (const Handle(OpenGl_Context)& theGlCtx, + const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes, + const Standard_Integer theStartIndex); private: - struct PlaneProps - { - // declare default constructor - // to allow compilation of template collections - PlaneProps() {} - PlaneProps (const Standard_Integer theID, - const Standard_Boolean theIsEnabled) - { - ContextID = theID; - IsEnabled = theIsEnabled; - } - - Standard_Integer ContextID; - Standard_Boolean IsEnabled; - }; - -private: - - typedef NCollection_DataMap OpenGl_MapOfPlaneStates; - typedef NCollection_Handle OpenGl_EmptyPlaneIds; - - Graphic3d_SequenceOfHClipPlane myPlanes; //!< defined clipping planes - OpenGl_MapOfPlaneStates myPlaneStates; //!< map of clip planes bound for the props - OpenGl_EmptyPlaneIds myEmptyPlaneIds; //!< generator of empty ids - Standard_Integer myNbClipping; //!< number of enabled clipping-only planes (NOT capping) - Standard_Integer myNbCapping; //!< number of enabled capping planes + Handle(Graphic3d_SequenceOfHClipPlane) myPlanesGlobal; //!< global clipping planes + Handle(Graphic3d_SequenceOfHClipPlane) myPlanesLocal; //!< object clipping planes + NCollection_Vector myDisabledPlanes; //!< ids of disabled planes + NCollection_Vector mySkipFilter; //!< ids of planes that were disabled before calling ::DisableAllExcept() + Handle(NCollection_Shared) myEmptyPlaneIds; //!< generator of empty ids for FFP clipping planes + Standard_Integer myNbClipping; //!< number of enabled clipping-only planes (NOT capping) + Standard_Integer myNbCapping; //!< number of enabled capping planes + Standard_Integer myNbDisabled; //!< number of defined but disabled planes private: //! Copying allowed only within Handles OpenGl_Clipping (const OpenGl_Clipping& ); OpenGl_Clipping& operator= (const OpenGl_Clipping& ); + + friend class OpenGl_ClippingIterator; +}; + +//! The iterator through clipping planes. +class OpenGl_ClippingIterator +{ +public: + + //! Main constructor. + Standard_EXPORT OpenGl_ClippingIterator(const OpenGl_Clipping& theClipping); + + //! Return true if iterator points to the valid clipping plane. + bool More() const { return myIter1.More() || myIter2.More(); } + + //! Go to the next clipping plane. + void Next() + { + ++myCurrIndex; + if (myIter1.More()) + { + myIter1.Next(); + } + else + { + myIter2.Next(); + } + } + + //! Return true if plane has been temporarily disabled + //! either by Graphic3d_ClipPlane->IsOn() property or by temporary filter. + bool IsDisabled() const { return myDisabled->Value (myCurrIndex) || !Value()->IsOn(); } + + //! Return the plane at current iterator position. + const Handle(Graphic3d_ClipPlane)& Value() const + { + return myIter1.More() + ? myIter1.Value() + : myIter2.Value(); + } + + //! Return true if plane from the global (view) list. + bool IsGlobal() const { return myIter1.More(); } + + //! Return the plane index. + Standard_Integer PlaneIndex() const { return myCurrIndex; } + +private: + + Graphic3d_SequenceOfHClipPlane::Iterator myIter1; + Graphic3d_SequenceOfHClipPlane::Iterator myIter2; + const NCollection_Vector* myDisabled; + Standard_Integer myCurrIndex; + }; #endif diff --git a/src/OpenGl/OpenGl_ShaderManager.cxx b/src/OpenGl/OpenGl_ShaderManager.cxx index 270c5e96b4..2af356571c 100644 --- a/src/OpenGl/OpenGl_ShaderManager.cxx +++ b/src/OpenGl/OpenGl_ShaderManager.cxx @@ -767,30 +767,21 @@ void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram) return; } - GLint aPlanesNb = 0; - for (Graphic3d_SequenceOfHClipPlane::Iterator anIter (myContext->Clipping().Planes()); - anIter.More(); anIter.Next()) - { - const Handle(Graphic3d_ClipPlane)& aPlane = anIter.Value(); - if (!myContext->Clipping().IsEnabled (aPlane)) - { - continue; - } - - ++aPlanesNb; - } - if (aPlanesNb < 1) + const GLint aNbPlanes = Min (myContext->Clipping().NbClippingOrCappingOn(), THE_MAX_CLIP_PLANES); + theProgram->SetUniform (myContext, + theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_COUNT), + aNbPlanes); + if (aNbPlanes < 1) { return; } OpenGl_Vec4 anEquations[THE_MAX_CLIP_PLANES]; GLuint aPlaneId = 0; - for (Graphic3d_SequenceOfHClipPlane::Iterator anIter (myContext->Clipping().Planes()); - anIter.More(); anIter.Next()) + for (OpenGl_ClippingIterator aPlaneIter (myContext->Clipping()); aPlaneIter.More(); aPlaneIter.Next()) { - const Handle(Graphic3d_ClipPlane)& aPlane = anIter.Value(); - if (!myContext->Clipping().IsEnabled (aPlane)) + const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIter.Value(); + if (aPlaneIter.IsDisabled()) { continue; } @@ -810,9 +801,6 @@ void OpenGl_ShaderManager::PushClippingState (const Handle(OpenGl_ShaderProgram) ++aPlaneId; } - theProgram->SetUniform (myContext, - theProgram->GetStateLocation (OpenGl_OCC_CLIP_PLANE_COUNT), - aPlanesNb); theProgram->SetUniform (myContext, aLocEquations, THE_MAX_CLIP_PLANES, anEquations); } diff --git a/src/OpenGl/OpenGl_Structure.cxx b/src/OpenGl/OpenGl_Structure.cxx index cd7139c905..2b1b9e364a 100644 --- a/src/OpenGl/OpenGl_Structure.cxx +++ b/src/OpenGl/OpenGl_Structure.cxx @@ -517,84 +517,67 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con if (myHighlightColor) theWorkspace->HighlightColor = myHighlightColor; - // Set up plane equations for non-structure transformed global model-view matrix - // List of planes to be applied to context state - Handle(NCollection_Shared) aUserPlanes, aDisabledPlanes; - // Collect clipping planes of structure scope - if (!myClipPlanes.IsEmpty()) - { - for (Graphic3d_SequenceOfHClipPlane::Iterator aClippingIter (myClipPlanes); aClippingIter.More(); aClippingIter.Next()) - { - const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIter.Value(); - if (!aClipPlane->IsOn()) - { - continue; - } - - if (aUserPlanes.IsNull()) - { - aUserPlanes = new NCollection_Shared(); - } - aUserPlanes->Append (aClipPlane); - } - } - if (!aUserPlanes.IsNull()) - { - // add planes at loaded view matrix state - aCtx->ChangeClipping().AddWorld (aCtx, *aUserPlanes); - - // Set OCCT state uniform variables - aCtx->ShaderManager()->UpdateClippingState(); - } + aCtx->ChangeClipping().SetLocalPlanes (aCtx, myClipPlanes); // True if structure is fully clipped bool isClipped = false; - - // Set of clipping planes that do not intersect the structure, - // and thus can be disabled to improve rendering performance - const Graphic3d_BndBox4f& aBBox = BoundingBox(); - if (!aCtx->Clipping().Planes().IsEmpty() && aBBox.IsValid() && TransformPersistence.Flags == Graphic3d_TMF_None) + bool hasDisabled = false; + if (aCtx->Clipping().IsClippingOrCappingOn()) { - for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (aCtx->Clipping().Planes()); aPlaneIt.More(); aPlaneIt.Next()) + const Graphic3d_BndBox4f& aBBox = BoundingBox(); + if (TransformPersistence.Flags == Graphic3d_TMF_TriedronPers + || TransformPersistence.Flags == Graphic3d_TMF_2d + || (!myClipPlanes.IsNull() && myClipPlanes->ToOverrideGlobal())) { - const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value(); - if (!aPlane->IsOn()) - { - continue; - } + aCtx->ChangeClipping().DisableGlobal (aCtx); + hasDisabled = aCtx->Clipping().HasDisabled(); + } - // check for clipping - const Graphic3d_Vec4d& aPlaneEquation = aPlane->GetEquation(); - const Graphic3d_Vec4d aMaxPnt (aPlaneEquation.x() > 0.0 ? aBBox.CornerMax().x() : aBBox.CornerMin().x(), - aPlaneEquation.y() > 0.0 ? aBBox.CornerMax().y() : aBBox.CornerMin().y(), - aPlaneEquation.z() > 0.0 ? aBBox.CornerMax().z() : aBBox.CornerMin().z(), - 1.0); - if (aPlaneEquation.Dot (aMaxPnt) < 0.0) // max vertex is outside the half-space + // Set of clipping planes that do not intersect the structure, + // and thus can be disabled to improve rendering performance + if (aBBox.IsValid() + && TransformPersistence.Flags == Graphic3d_TMF_None) + { + for (OpenGl_ClippingIterator aPlaneIt (aCtx->Clipping()); aPlaneIt.More(); aPlaneIt.Next()) { - isClipped = true; - break; - } - - // check for no intersection (e.g. object is "entirely not clipped") - const Graphic3d_Vec4d aMinPnt (aPlaneEquation.x() > 0.0 ? aBBox.CornerMin().x() : aBBox.CornerMax().x(), - aPlaneEquation.y() > 0.0 ? aBBox.CornerMin().y() : aBBox.CornerMax().y(), - aPlaneEquation.z() > 0.0 ? aBBox.CornerMin().z() : aBBox.CornerMax().z(), - 1.0); - if (aPlaneEquation.Dot (aMinPnt) > 0.0) // min vertex is inside the half-space - { - aCtx->ChangeClipping().SetEnabled (aCtx, aPlane, Standard_False); - if (aDisabledPlanes.IsNull()) + const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value(); + if (!aPlane->IsOn()) { - aDisabledPlanes = new NCollection_Shared(); - if (aUserPlanes.IsNull()) - { - aCtx->ShaderManager()->UpdateClippingState(); - } + continue; + } + + // check for clipping + const Graphic3d_Vec4d& aPlaneEquation = aPlane->GetEquation(); + const Graphic3d_Vec4d aMaxPnt (aPlaneEquation.x() > 0.0 ? aBBox.CornerMax().x() : aBBox.CornerMin().x(), + aPlaneEquation.y() > 0.0 ? aBBox.CornerMax().y() : aBBox.CornerMin().y(), + aPlaneEquation.z() > 0.0 ? aBBox.CornerMax().z() : aBBox.CornerMin().z(), + 1.0); + if (aPlaneEquation.Dot (aMaxPnt) < 0.0) // max vertex is outside the half-space + { + isClipped = true; + break; + } + + // check for no intersection (e.g. object is "entirely not clipped") + const Graphic3d_Vec4d aMinPnt (aPlaneEquation.x() > 0.0 ? aBBox.CornerMin().x() : aBBox.CornerMax().x(), + aPlaneEquation.y() > 0.0 ? aBBox.CornerMin().y() : aBBox.CornerMax().y(), + aPlaneEquation.z() > 0.0 ? aBBox.CornerMin().z() : aBBox.CornerMax().z(), + 1.0); + if (aPlaneEquation.Dot (aMinPnt) > 0.0) // min vertex is inside the half-space + { + aCtx->ChangeClipping().SetEnabled (aCtx, aPlaneIt, Standard_False); + hasDisabled = true; } - aDisabledPlanes->Append (aPlane); } } + + if ((!myClipPlanes.IsNull() && !myClipPlanes->IsEmpty()) + || hasDisabled) + { + // Set OCCT state uniform variables + aCtx->ShaderManager()->UpdateClippingState(); + } } // Render groups @@ -618,22 +601,15 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con } // Revert structure clippings - if (!aDisabledPlanes.IsNull()) + if (hasDisabled) { // enable planes that were previously disabled - for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*aDisabledPlanes); aPlaneIt.More(); aPlaneIt.Next()) - { - aCtx->ChangeClipping().SetEnabled (aCtx, aPlaneIt.Value(), Standard_True); - } - if (aUserPlanes.IsNull()) - { - aCtx->ShaderManager()->RevertClippingState(); - } + aCtx->ChangeClipping().RestoreDisabled (aCtx); } - if (!aUserPlanes.IsNull()) + aCtx->ChangeClipping().SetLocalPlanes (aCtx, Handle(Graphic3d_SequenceOfHClipPlane)()); + if ((!myClipPlanes.IsNull() && !myClipPlanes->IsEmpty()) + || hasDisabled) { - aCtx->ChangeClipping().Remove (aCtx, *aUserPlanes); - // Set OCCT state uniform variables aCtx->ShaderManager()->RevertClippingState(); } diff --git a/src/OpenGl/OpenGl_View.hxx b/src/OpenGl/OpenGl_View.hxx index 49d415297b..49f4d32144 100644 --- a/src/OpenGl/OpenGl_View.hxx +++ b/src/OpenGl/OpenGl_View.hxx @@ -309,10 +309,10 @@ public: } //! Returns list of clip planes set for the view. - virtual const Graphic3d_SequenceOfHClipPlane& ClipPlanes() const Standard_OVERRIDE { return myClipPlanes; } + virtual const Handle(Graphic3d_SequenceOfHClipPlane)& ClipPlanes() const Standard_OVERRIDE { return myClipPlanes; } //! Sets list of clip planes for the view. - virtual void SetClipPlanes (const Graphic3d_SequenceOfHClipPlane& thePlanes) Standard_OVERRIDE { myClipPlanes = thePlanes; } + virtual void SetClipPlanes (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes) Standard_OVERRIDE { myClipPlanes = thePlanes; } //! Fill in the dictionary with diagnostic info. //! Should be called within rendering thread. @@ -481,7 +481,7 @@ protected: Graphic3d_TypeOfShadingModel myShadingModel; Graphic3d_TypeOfBackfacingModel myBackfacing; Quantity_ColorRGBA myBgColor; - Graphic3d_SequenceOfHClipPlane myClipPlanes; + Handle(Graphic3d_SequenceOfHClipPlane) myClipPlanes; Handle(Graphic3d_Camera) myCamera; Handle(OpenGl_FrameBuffer) myFBO; Standard_Boolean myUseGLLight; diff --git a/src/OpenGl/OpenGl_View_Redraw.cxx b/src/OpenGl/OpenGl_View_Redraw.cxx index 5985b030fd..dab7ad6bfd 100644 --- a/src/OpenGl/OpenGl_View_Redraw.cxx +++ b/src/OpenGl/OpenGl_View_Redraw.cxx @@ -1087,25 +1087,10 @@ void OpenGl_View::renderScene (Graphic3d_Camera::Projection theProjection, const Handle(OpenGl_Context)& aContext = myWorkspace->GetGlContext(); // Specify clipping planes in view transformation space - aContext->ChangeClipping().RemoveAll (aContext); - if (!myClipPlanes.IsEmpty()) + aContext->ChangeClipping().Reset (aContext, myClipPlanes); + if (!myClipPlanes.IsNull() + && !myClipPlanes->IsEmpty()) { - Graphic3d_SequenceOfHClipPlane aUserPlanes; - Graphic3d_SequenceOfHClipPlane::Iterator aClippingIt (myClipPlanes); - for (; aClippingIt.More(); aClippingIt.Next()) - { - const Handle(Graphic3d_ClipPlane)& aClipPlane = aClippingIt.Value(); - if (aClipPlane->IsOn()) - { - aUserPlanes.Append (aClipPlane); - } - } - - if (!aUserPlanes.IsEmpty()) - { - aContext->ChangeClipping().AddWorld (aContext, aUserPlanes); - } - aContext->ShaderManager()->UpdateClippingState(); } @@ -1193,8 +1178,9 @@ void OpenGl_View::renderScene (Graphic3d_Camera::Projection theProjection, // Apply restored view matrix. aContext->ApplyWorldViewMatrix(); - aContext->ChangeClipping().RemoveAll (aContext); - if (!myClipPlanes.IsEmpty()) + aContext->ChangeClipping().Reset (aContext, Handle(Graphic3d_SequenceOfHClipPlane)()); + if (!myClipPlanes.IsNull() + && !myClipPlanes->IsEmpty()) { aContext->ShaderManager()->RevertClippingState(); } diff --git a/src/PrsMgr/FILES b/src/PrsMgr/FILES index bcec43054a..fa76169037 100644 --- a/src/PrsMgr/FILES +++ b/src/PrsMgr/FILES @@ -4,7 +4,6 @@ PrsMgr_ModedPresentation.cxx PrsMgr_ModedPresentation.hxx PrsMgr_PresentableObject.cxx PrsMgr_PresentableObject.hxx -PrsMgr_PresentableObject.lxx PrsMgr_PresentableObjectPointer.hxx PrsMgr_Presentation.cxx PrsMgr_Presentation.hxx diff --git a/src/PrsMgr/PrsMgr_PresentableObject.cxx b/src/PrsMgr/PrsMgr_PresentableObject.cxx index 93394da5bf..c2ff8c8d4c 100644 --- a/src/PrsMgr/PrsMgr_PresentableObject.cxx +++ b/src/PrsMgr/PrsMgr_PresentableObject.cxx @@ -422,7 +422,12 @@ Graphic3d_ZLayerId PrsMgr_PresentableObject::ZLayer() const void PrsMgr_PresentableObject::AddClipPlane (const Handle(Graphic3d_ClipPlane)& thePlane) { // add to collection and process changes - myClipPlanes.Append (thePlane); + if (myClipPlanes.IsNull()) + { + myClipPlanes = new Graphic3d_SequenceOfHClipPlane(); + } + + myClipPlanes->Append (thePlane); UpdateClipping(); } @@ -432,15 +437,19 @@ void PrsMgr_PresentableObject::AddClipPlane (const Handle(Graphic3d_ClipPlane)& // ======================================================================= void PrsMgr_PresentableObject::RemoveClipPlane (const Handle(Graphic3d_ClipPlane)& thePlane) { + if (myClipPlanes.IsNull()) + { + return; + } + // remove from collection and process changes - Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (myClipPlanes); - for (; aPlaneIt.More(); aPlaneIt.Next()) + for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*myClipPlanes); aPlaneIt.More(); aPlaneIt.Next()) { const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value(); if (aPlane != thePlane) continue; - myClipPlanes.Remove (aPlaneIt); + myClipPlanes->Remove (aPlaneIt); UpdateClipping(); return; } @@ -450,7 +459,7 @@ void PrsMgr_PresentableObject::RemoveClipPlane (const Handle(Graphic3d_ClipPlane // function : SetClipPlanes // purpose : // ======================================================================= -void PrsMgr_PresentableObject::SetClipPlanes (const Graphic3d_SequenceOfHClipPlane& thePlanes) +void PrsMgr_PresentableObject::SetClipPlanes (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes) { // change collection and process changes myClipPlanes = thePlanes; @@ -503,12 +512,3 @@ void PrsMgr_PresentableObject::SetMutable (const Standard_Boolean theIsMutable) aModedPrs.Presentation()->Presentation()->SetMutable (theIsMutable); } } - -// ======================================================================= -// function : IsMutable -// purpose : -// ======================================================================= -Standard_Boolean PrsMgr_PresentableObject::IsMutable() const -{ - return myIsMutable; -} diff --git a/src/PrsMgr/PrsMgr_PresentableObject.hxx b/src/PrsMgr/PrsMgr_PresentableObject.hxx index ed1625041f..9b7a2eeda8 100644 --- a/src/PrsMgr/PrsMgr_PresentableObject.hxx +++ b/src/PrsMgr/PrsMgr_PresentableObject.hxx @@ -76,7 +76,7 @@ public: Standard_EXPORT PrsMgr_Presentations& Presentations(); //! Returns information on whether the object accepts display in HLR mode or not. - PrsMgr_TypeOfPresentation3d TypeOfPresentation3d() const; + PrsMgr_TypeOfPresentation3d TypeOfPresentation3d() const { return myTypeOfPresentation3d; } //! Sets up Transform Persistence Mode for this object. //! This function used to lock in object position, rotation and / or zooming relative to camera position. @@ -107,7 +107,7 @@ public: Standard_EXPORT gp_Pnt GetTransformPersistencePoint() const; //! @return transform persistence of the presentable object. - const Graphic3d_TransformPers& TransformPersistence() const; + const Graphic3d_TransformPers& TransformPersistence() const { return myTransformPersistence; } Standard_EXPORT void SetTypeOfPresentation (const PrsMgr_TypeOfPresentation3d aType); @@ -126,12 +126,12 @@ public: //! Returns true if object has a transformation that is different from the identity. Standard_EXPORT Standard_Boolean HasTransformation() const; - - const gp_Trsf& LocalTransformation() const; - - const gp_Trsf& Transformation() const; - - const gp_GTrsf& InversedTransformation() const; + + const gp_Trsf& LocalTransformation() const { return myLocalTransformation; } + + const gp_Trsf& Transformation() const { return myTransformation; } + + const gp_GTrsf& InversedTransformation() const { return myInvTransformation; } //! resets local transformation to identity. Standard_EXPORT virtual void ResetTransformation(); @@ -162,25 +162,32 @@ public: Standard_EXPORT virtual void RemoveClipPlane (const Handle(Graphic3d_ClipPlane)& thePlane); //! Set clip planes for graphical clipping for all display mode presentations. - //! The composition of clip planes truncates the rendering space to convex - //! volume. Please be aware that number of supported clip plane is limited. - //! The planes which exceed the limit are ignored. Besides of this, some - //! planes can be already set in view where the object is shown: the number - //! of these planes should be substracted from limit to predict the maximum + //! The composition of clip planes truncates the rendering space to convex volume. + //! Please be aware that number of supported clip plane is limited. + //! The planes which exceed the limit are ignored. + //! Besides of this, some planes can be already set in view where the object is shown: + //! the number of these planes should be subtracted from limit to predict the maximum //! possible number of object clipping planes. - Standard_EXPORT virtual void SetClipPlanes (const Graphic3d_SequenceOfHClipPlane& thePlanes); - + Standard_EXPORT virtual void SetClipPlanes (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes); + + Standard_DEPRECATED("This method is deprecated - overload taking Handle should be used instead") + void SetClipPlanes (const Graphic3d_SequenceOfHClipPlane& thePlanes) + { + Handle(Graphic3d_SequenceOfHClipPlane) aPlanes = new Graphic3d_SequenceOfHClipPlane (thePlanes); + SetClipPlanes (aPlanes); + } + //! Get clip planes. //! @return set of previously added clip planes for all display mode presentations. - const Graphic3d_SequenceOfHClipPlane& GetClipPlanes() const; - + const Handle(Graphic3d_SequenceOfHClipPlane)& ClipPlanes() const { return myClipPlanes; } + //! Sets if the object has mutable nature (content or location will be changed regularly). //! This method should be called before object displaying to take effect. Standard_EXPORT virtual void SetMutable (const Standard_Boolean theIsMutable); //! Returns true if object has mutable nature (content or location are be changed regularly). //! Mutable object will be managed in different way than static onces (another optimizations). - Standard_EXPORT Standard_Boolean IsMutable() const; + Standard_Boolean IsMutable() const { return myIsMutable; } //! Makes theObject child of current object in scene hierarchy. Standard_EXPORT virtual void AddChild (const Handle(PrsMgr_PresentableObject)& theObject); @@ -189,13 +196,13 @@ public: Standard_EXPORT virtual void RemoveChild (const Handle(PrsMgr_PresentableObject)& theObject); //! Returns children of the current object. - const PrsMgr_ListOfPresentableObjects& Children() const; + const PrsMgr_ListOfPresentableObjects& Children() const { return myChildren; } //! Returns true if object should have own presentations. - Standard_Boolean HasOwnPresentations() const; + Standard_Boolean HasOwnPresentations() const { return myHasOwnPresentations; } //! Returns parent of current object in scene hierarchy. - PrsMgr_PresentableObjectPointer Parent() const; + PrsMgr_PresentableObjectPointer Parent() const { return myParent; } friend class PrsMgr_Presentation; @@ -271,17 +278,17 @@ Standard_EXPORT virtual ~PrsMgr_PresentableObject(); //! implementation propagate clip planes to every presentation. Standard_EXPORT virtual void UpdateClipping(); +protected: + PrsMgr_Presentations myPresentations; PrsMgr_TypeOfPresentation3d myTypeOfPresentation3d; - Graphic3d_SequenceOfHClipPlane myClipPlanes; + Handle(Graphic3d_SequenceOfHClipPlane) myClipPlanes; Standard_Boolean myIsMutable; Graphic3d_ZLayerId myZLayer; Standard_Boolean myHasOwnPresentations; - private: - Graphic3d_TransformPers myTransformPersistence; PrsMgr_PresentableObjectPointer myParent; gp_Trsf myLocalTransformation; @@ -290,14 +297,6 @@ private: gp_Trsf myCombinedParentTransform; PrsMgr_ListOfPresentableObjects myChildren; - }; - -#include - - - - - #endif // _PrsMgr_PresentableObject_HeaderFile diff --git a/src/PrsMgr/PrsMgr_PresentableObject.lxx b/src/PrsMgr/PrsMgr_PresentableObject.lxx deleted file mode 100644 index a3ea557eee..0000000000 --- a/src/PrsMgr/PrsMgr_PresentableObject.lxx +++ /dev/null @@ -1,58 +0,0 @@ -// Created on: 1997-07-04 -// Created by: Robert COUBLANC -// Copyright (c) 1997-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -inline PrsMgr_TypeOfPresentation3d PrsMgr_PresentableObject::TypeOfPresentation3d() const -{return myTypeOfPresentation3d;} - -inline const Graphic3d_TransformPers& PrsMgr_PresentableObject::TransformPersistence() const -{ - return myTransformPersistence; -} - -inline const gp_Trsf& PrsMgr_PresentableObject::LocalTransformation() const -{ - return myLocalTransformation; -} - -inline const gp_Trsf& PrsMgr_PresentableObject::Transformation() const -{ - return myTransformation; -} - -inline const gp_GTrsf& PrsMgr_PresentableObject::InversedTransformation() const -{ - return myInvTransformation; -} - -inline const PrsMgr_ListOfPresentableObjects& PrsMgr_PresentableObject::Children() const -{ - return myChildren; -} - -inline Standard_Boolean PrsMgr_PresentableObject::HasOwnPresentations() const -{ - return myHasOwnPresentations; -} - -inline PrsMgr_PresentableObjectPointer PrsMgr_PresentableObject::Parent() const -{ - return myParent; -} - -inline const Graphic3d_SequenceOfHClipPlane& PrsMgr_PresentableObject::GetClipPlanes() const -{ - return myClipPlanes; -} diff --git a/src/PrsMgr/PrsMgr_PresentationManager.cxx b/src/PrsMgr/PrsMgr_PresentationManager.cxx index 9511ad2c86..aa05bec3a6 100644 --- a/src/PrsMgr/PrsMgr_PresentationManager.cxx +++ b/src/PrsMgr/PrsMgr_PresentationManager.cxx @@ -371,7 +371,7 @@ void PrsMgr_PresentationManager::displayImmediate (const Handle(V3d_Viewer)& the aShadowPrs = new Prs3d_PresentationShadow (myStructureManager, Handle(Prs3d_Presentation)::DownCast (aViewDepPrs)); aShadowPrs->SetZLayer (aViewDepPrs->CStructure()->ZLayer()); - aShadowPrs->SetClipPlanes (aViewDepPrs->GetClipPlanes()); + aShadowPrs->SetClipPlanes (aViewDepPrs->ClipPlanes()); aShadowPrs->CStructure()->IsForHighlight = 1; aShadowPrs->Highlight (Aspect_TOHM_COLOR, aPrs->HighlightColor()); myViewDependentImmediateList.Append (aShadowPrs); @@ -626,7 +626,7 @@ void PrsMgr_PresentationManager::Color (const Handle(PrsMgr_PresentableObject)& { Handle(Prs3d_PresentationShadow) aShadow = new Prs3d_PresentationShadow (myStructureManager, aPrs->Presentation()); aShadow->SetZLayer (theImmediateStructLayerId); - aShadow->SetClipPlanes (aPrs->Presentation()->GetClipPlanes()); + aShadow->SetClipPlanes (aPrs->Presentation()->ClipPlanes()); aShadow->CStructure()->IsForHighlight = 1; aShadow->Highlight (Aspect_TOHM_COLOR, theColor); AddToImmediateList (aShadow); diff --git a/src/SelectMgr/SelectMgr_BaseFrustum.hxx b/src/SelectMgr/SelectMgr_BaseFrustum.hxx index 88398faf87..0ba1df784a 100644 --- a/src/SelectMgr/SelectMgr_BaseFrustum.hxx +++ b/src/SelectMgr/SelectMgr_BaseFrustum.hxx @@ -167,7 +167,11 @@ public: //! Valid for point selection only! //! Computes depth range for global (defined for the whole view) clipping planes. - virtual void SetViewClipping (const Graphic3d_SequenceOfHClipPlane& /*thePlanes*/) {}; + virtual void SetViewClipping (const Handle(Graphic3d_SequenceOfHClipPlane)& /*thePlanes*/) {}; + + //! Set if view clipping plane is enabled or not. + //! @return previous value of the flag + virtual Standard_Boolean SetViewClippingEnabled (const Standard_Boolean /*theToEnable*/) { return Standard_False; } DEFINE_STANDARD_RTTIEXT(SelectMgr_BaseFrustum,Standard_Transient) diff --git a/src/SelectMgr/SelectMgr_RectangularFrustum.cxx b/src/SelectMgr/SelectMgr_RectangularFrustum.cxx index 1745cb74c5..ac2291a646 100644 --- a/src/SelectMgr/SelectMgr_RectangularFrustum.cxx +++ b/src/SelectMgr/SelectMgr_RectangularFrustum.cxx @@ -399,6 +399,7 @@ Handle(SelectMgr_BaseFrustum) SelectMgr_RectangularFrustum::ScaleAndTransform (c cacheVertexProjections (aRes.get()); aRes->myViewClipRange = myViewClipRange; + aRes->myIsViewClipEnabled = myIsViewClipEnabled; aRes->myMousePos = myMousePos; return aRes; @@ -716,16 +717,17 @@ Standard_Boolean SelectMgr_RectangularFrustum::IsClipped (const Graphic3d_Sequen // function : SetViewClipping // purpose : // ======================================================================= -void SelectMgr_RectangularFrustum::SetViewClipping (const Graphic3d_SequenceOfHClipPlane& thePlanes) +void SelectMgr_RectangularFrustum::SetViewClipping (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes) { - if (thePlanes.Size() == 0) + if (thePlanes.IsNull() + || thePlanes->IsEmpty()) { myViewClipRange.Clear(); return; } Standard_Real aMaxDepth, aMinDepth; - computeClippingRange (thePlanes, aMinDepth, aMaxDepth); + computeClippingRange (*thePlanes, aMinDepth, aMaxDepth); myViewClipRange.Set (aMinDepth, aMaxDepth); } @@ -735,8 +737,11 @@ void SelectMgr_RectangularFrustum::SetViewClipping (const Graphic3d_SequenceOfHC // ======================================================================= Standard_Boolean SelectMgr_RectangularFrustum::isViewClippingOk (const Standard_Real theDepth) const { - if (!myViewClipRange.IsValid()) + if (!myViewClipRange.IsValid() + || !myIsViewClipEnabled) + { return Standard_True; + } return myViewClipRange.MaxDepth() > theDepth && myViewClipRange.MinDepth() < theDepth; diff --git a/src/SelectMgr/SelectMgr_RectangularFrustum.hxx b/src/SelectMgr/SelectMgr_RectangularFrustum.hxx index 53fa3db504..ecad0b8b84 100644 --- a/src/SelectMgr/SelectMgr_RectangularFrustum.hxx +++ b/src/SelectMgr/SelectMgr_RectangularFrustum.hxx @@ -34,7 +34,7 @@ class SelectMgr_RectangularFrustum : public SelectMgr_Frustum<4> { public: - SelectMgr_RectangularFrustum() : myScale (1.0) {}; + SelectMgr_RectangularFrustum() : myScale (1.0), myIsViewClipEnabled (Standard_True) {}; //! Builds volume according to the point and given pixel tolerance Standard_EXPORT virtual void Build (const gp_Pnt2d& thePoint) Standard_OVERRIDE; @@ -109,7 +109,16 @@ public: //! Valid for point selection only! //! Computes depth range for global (defined for the whole view) clipping planes. - Standard_EXPORT virtual void SetViewClipping (const Graphic3d_SequenceOfHClipPlane& thePlanes) Standard_OVERRIDE; + Standard_EXPORT virtual void SetViewClipping (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes) Standard_OVERRIDE; + + //! Set if view clipping plane is enabled or not. + //! @return previous value of the flag + virtual Standard_Boolean SetViewClippingEnabled (const Standard_Boolean theToEnable) Standard_OVERRIDE + { + Standard_Boolean aPrevValue = myIsViewClipEnabled; + myIsViewClipEnabled = theToEnable; + return aPrevValue; + } //! A set of helper functions that return rectangular selecting frustum data inline const gp_Pnt* GetVertices() const { return myVertices; } @@ -159,6 +168,8 @@ private: gp_Pnt2d myMousePos; //!< Mouse coordinates Standard_Real myScale; //!< Scale factor of applied transformation, if there was any SelectMgr_ViewClipRange myViewClipRange; + Standard_Boolean myIsViewClipEnabled; //!< view clipping enabled state + }; #endif // _SelectMgr_RectangularFrustum_HeaderFile diff --git a/src/SelectMgr/SelectMgr_SelectingVolumeManager.cxx b/src/SelectMgr/SelectMgr_SelectingVolumeManager.cxx index fd1b0588a7..087efe4c0d 100644 --- a/src/SelectMgr/SelectMgr_SelectingVolumeManager.cxx +++ b/src/SelectMgr/SelectMgr_SelectingVolumeManager.cxx @@ -465,10 +465,22 @@ gp_Pnt SelectMgr_SelectingVolumeManager::GetFarPickedPnt() const // function : SetViewClipping // purpose : //======================================================================= -void SelectMgr_SelectingVolumeManager::SetViewClipping (const Graphic3d_SequenceOfHClipPlane& thePlanes) +void SelectMgr_SelectingVolumeManager::SetViewClipping (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes) { if (myActiveSelectionType != Point) return; mySelectingVolumes[Frustum]->SetViewClipping (thePlanes); } + +//======================================================================= +// function : SetViewClippingEnabled +// purpose : +//======================================================================= +Standard_Boolean SelectMgr_SelectingVolumeManager::SetViewClippingEnabled (const Standard_Boolean theToEnable) +{ + if (myActiveSelectionType != Point) + return Standard_False; + + return mySelectingVolumes[Frustum]->SetViewClippingEnabled (theToEnable); +} diff --git a/src/SelectMgr/SelectMgr_SelectingVolumeManager.hxx b/src/SelectMgr/SelectMgr_SelectingVolumeManager.hxx index d06b5ef1e8..427e194700 100644 --- a/src/SelectMgr/SelectMgr_SelectingVolumeManager.hxx +++ b/src/SelectMgr/SelectMgr_SelectingVolumeManager.hxx @@ -172,7 +172,11 @@ public: //! Valid for point selection only! //! Computes depth range for global (defined for the whole view) clipping planes. - Standard_EXPORT void SetViewClipping (const Graphic3d_SequenceOfHClipPlane& thePlanes); + Standard_EXPORT void SetViewClipping (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes); + + //! Set if view clipping plane is enabled or not. + //! @return previous flag value + Standard_EXPORT Standard_Boolean SetViewClippingEnabled (const Standard_Boolean theToEnable); //! A set of helper functions that return rectangular selecting frustum data Standard_EXPORT const gp_Pnt* GetVertices() const; diff --git a/src/SelectMgr/SelectMgr_ViewerSelector.cxx b/src/SelectMgr/SelectMgr_ViewerSelector.cxx index ee209239ad..0f162e9079 100644 --- a/src/SelectMgr/SelectMgr_ViewerSelector.cxx +++ b/src/SelectMgr/SelectMgr_ViewerSelector.cxx @@ -166,50 +166,69 @@ void SelectMgr_ViewerSelector::checkOverlap (const Handle(SelectBasics_Sensitive SelectMgr_SelectingVolumeManager& theMgr) { Handle(SelectMgr_EntityOwner) anOwner (Handle(SelectMgr_EntityOwner)::DownCast (theEntity->OwnerId())); + Handle(SelectMgr_SelectableObject) aSelectable; + Standard_Boolean toRestoresViewClipEnabled = Standard_False; + if (!anOwner.IsNull()) + { + aSelectable = anOwner->Selectable(); + if (aSelectable->TransformPersistence().Flags == Graphic3d_TMF_TriedronPers + || aSelectable->TransformPersistence().Flags == Graphic3d_TMF_2d + || (!aSelectable->ClipPlanes().IsNull() && aSelectable->ClipPlanes()->ToOverrideGlobal())) + { + theMgr.SetViewClippingEnabled (Standard_False); + toRestoresViewClipEnabled = Standard_True; + } + } SelectBasics_PickResult aPickResult; - if (theEntity->Matches (theMgr, aPickResult)) + const Standard_Boolean isMatched = theEntity->Matches(theMgr, aPickResult); + if (toRestoresViewClipEnabled) { - if (!anOwner.IsNull()) + theMgr.SetViewClippingEnabled (Standard_True); + } + + if (!isMatched + || anOwner.IsNull()) + { + return; + } + + if (HasDepthClipping (anOwner) + && theMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point) + { + Standard_Boolean isClipped = mySelectingVolumeMgr.IsClipped (*aSelectable->ClipPlanes(), + aPickResult.Depth()); + if (isClipped) + return; + } + + SelectMgr_SortCriterion aCriterion; + myZLayerOrderMap.Find (aSelectable->ZLayer(), aCriterion.ZLayerPosition); + aCriterion.Entity = theEntity; + aCriterion.Priority = anOwner->Priority(); + aCriterion.Depth = aPickResult.Depth(); + aCriterion.MinDist = aPickResult.DistToGeomCenter(); + aCriterion.Tolerance = theEntity->SensitivityFactor() / 33.0; + aCriterion.ToPreferClosest = preferclosest; + + const Standard_Integer aPrevStoredIndex = mystored.FindIndex (anOwner); + if (aPrevStoredIndex != 0) + { + if (theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Box) { - Handle(SelectMgr_SelectableObject) aSelectable = anOwner->Selectable(); - if (HasDepthClipping (anOwner) && theMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point) - { - Standard_Boolean isClipped = mySelectingVolumeMgr.IsClipped (aSelectable->GetClipPlanes(), - aPickResult.Depth()); - if (isClipped) - return; - } - - SelectMgr_SortCriterion aCriterion; - myZLayerOrderMap.Find (aSelectable->ZLayer(), aCriterion.ZLayerPosition); - aCriterion.Entity = theEntity; - aCriterion.Priority = anOwner->Priority(); - aCriterion.Depth = aPickResult.Depth(); - aCriterion.MinDist = aPickResult.DistToGeomCenter(); - aCriterion.Tolerance = theEntity->SensitivityFactor() / 33.0; - aCriterion.ToPreferClosest = preferclosest; - - const Standard_Integer aPrevStoredIndex = mystored.FindIndex (anOwner); - if (aPrevStoredIndex != 0) - { - if (theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Box) - { - SelectMgr_SortCriterion& aPrevCriterion = mystored.ChangeFromIndex (aPrevStoredIndex); - if (aCriterion > aPrevCriterion) - { - updatePoint3d (aCriterion, theInversedTrsf, theMgr); - aPrevCriterion = aCriterion; - } - } - } - else + SelectMgr_SortCriterion& aPrevCriterion = mystored.ChangeFromIndex (aPrevStoredIndex); + if (aCriterion > aPrevCriterion) { updatePoint3d (aCriterion, theInversedTrsf, theMgr); - mystored.Add (anOwner, aCriterion); + aPrevCriterion = aCriterion; } } } + else + { + updatePoint3d (aCriterion, theInversedTrsf, theMgr); + mystored.Add (anOwner, aCriterion); + } } //======================================================================= diff --git a/src/StdSelect/StdSelect_ViewerSelector3d.cxx b/src/StdSelect/StdSelect_ViewerSelector3d.cxx index 40ca4fa751..67840be3f4 100644 --- a/src/StdSelect/StdSelect_ViewerSelector3d.cxx +++ b/src/StdSelect/StdSelect_ViewerSelector3d.cxx @@ -128,7 +128,7 @@ void StdSelect_ViewerSelector3d::Pick (const Standard_Integer theXPix, gp_Pnt2d aMousePos (static_cast (theXPix), static_cast (theYPix)); mySelectingVolumeMgr.BuildSelectingVolume (aMousePos); - mySelectingVolumeMgr.SetViewClipping (theView->GetClipPlanes()); + mySelectingVolumeMgr.SetViewClipping (theView->ClipPlanes()); TraverseSensitives(); } @@ -644,7 +644,8 @@ Standard_Boolean StdSelect_ViewerSelector3d::HasDepthClipping (const Handle(Sele } const Handle(SelectMgr_SelectableObject)& aSelectable = theOwner->Selectable(); - return (aSelectable->GetClipPlanes().Size() > 0); + return !aSelectable->ClipPlanes().IsNull() + && !aSelectable->ClipPlanes()->IsEmpty(); } //======================================================================= diff --git a/src/V3d/V3d_View.hxx b/src/V3d/V3d_View.hxx index 49195ca5cb..5771859362 100644 --- a/src/V3d/V3d_View.hxx +++ b/src/V3d/V3d_View.hxx @@ -880,11 +880,18 @@ public: //! Graphic3d_GraphicDriver. Please be aware that the planes that //! exceed the limit are ignored during rendering. //! @param thePlanes [in] the clip planes to set. - Standard_EXPORT void SetClipPlanes (const Graphic3d_SequenceOfHClipPlane& thePlanes); + Standard_EXPORT void SetClipPlanes (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes); + + Standard_DEPRECATED("This method is deprecated - overload taking Handle should be used instead") + void SetClipPlanes (const Graphic3d_SequenceOfHClipPlane& thePlanes) + { + Handle(Graphic3d_SequenceOfHClipPlane) aPlanes = new Graphic3d_SequenceOfHClipPlane (thePlanes); + SetClipPlanes (aPlanes); + } //! Get clip planes. //! @return sequence clip planes that have been set for the view - Standard_EXPORT const Graphic3d_SequenceOfHClipPlane& GetClipPlanes() const; + Standard_EXPORT const Handle(Graphic3d_SequenceOfHClipPlane)& ClipPlanes() const; //! Returns the MAX number of clipping planes associated to the view. Standard_EXPORT Standard_Integer PlaneLimit() const; diff --git a/src/V3d/V3d_View_2.cxx b/src/V3d/V3d_View_2.cxx index bfbd368143..4a6ae4d526 100644 --- a/src/V3d/V3d_View_2.cxx +++ b/src/V3d/V3d_View_2.cxx @@ -185,8 +185,13 @@ Standard_Integer V3d_View::LightLimit() const //======================================================================= void V3d_View::AddClipPlane (const Handle(Graphic3d_ClipPlane)& thePlane) { - Graphic3d_SequenceOfHClipPlane aSeqOfPlanes = GetClipPlanes(); - aSeqOfPlanes.Append (thePlane); + Handle(Graphic3d_SequenceOfHClipPlane) aSeqOfPlanes = ClipPlanes(); + if (aSeqOfPlanes.IsNull()) + { + aSeqOfPlanes = new Graphic3d_SequenceOfHClipPlane(); + } + + aSeqOfPlanes->Append (thePlane); SetClipPlanes (aSeqOfPlanes); } @@ -196,15 +201,19 @@ void V3d_View::AddClipPlane (const Handle(Graphic3d_ClipPlane)& thePlane) //======================================================================= void V3d_View::RemoveClipPlane (const Handle(Graphic3d_ClipPlane)& thePlane) { - Graphic3d_SequenceOfHClipPlane aSeqOfPlanes = GetClipPlanes(); - Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (aSeqOfPlanes); - for (; aPlaneIt.More(); aPlaneIt.Next()) + Handle(Graphic3d_SequenceOfHClipPlane) aSeqOfPlanes = ClipPlanes(); + if (aSeqOfPlanes.IsNull()) + { + return; + } + + for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt(*aSeqOfPlanes); aPlaneIt.More(); aPlaneIt.Next()) { const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value(); if (aPlane != thePlane) continue; - aSeqOfPlanes.Remove (aPlaneIt); + aSeqOfPlanes->Remove (aPlaneIt); SetClipPlanes (aSeqOfPlanes); return; } @@ -214,16 +223,16 @@ void V3d_View::RemoveClipPlane (const Handle(Graphic3d_ClipPlane)& thePlane) //function : SetClipPlanes //purpose : //======================================================================= -void V3d_View::SetClipPlanes (const Graphic3d_SequenceOfHClipPlane& thePlanes) +void V3d_View::SetClipPlanes (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes) { myView->SetClipPlanes (thePlanes); } //======================================================================= -//function : GetClipPlanes +//function : ClipPlanes //purpose : //======================================================================= -const Graphic3d_SequenceOfHClipPlane& V3d_View::GetClipPlanes() const +const Handle(Graphic3d_SequenceOfHClipPlane)& V3d_View::ClipPlanes() const { return myView->ClipPlanes(); }