diff --git a/src/OpenGl/OpenGl_CappingAlgo.cxx b/src/OpenGl/OpenGl_CappingAlgo.cxx index 50cc18661c..33d6df3b33 100755 --- a/src/OpenGl/OpenGl_CappingAlgo.cxx +++ b/src/OpenGl/OpenGl_CappingAlgo.cxx @@ -37,8 +37,8 @@ namespace // function : RenderCapping // purpose : // ======================================================================= -void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorkspace, - const Graphic3d_SequenceOfGroup& theGroups) +void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorkspace, + const OpenGl_Structure& theStructure) { const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext(); @@ -110,13 +110,8 @@ void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWork glStencilFunc (GL_ALWAYS, 1, 0x01); glStencilOp (GL_KEEP, GL_INVERT, GL_INVERT); - for (OpenGl_Structure::GroupIterator aGroupIt (theGroups); aGroupIt.More(); aGroupIt.Next()) - { - if (aGroupIt.Value()->IsClosed()) - { - aGroupIt.Value()->Render (theWorkspace); - } - } + // render closed primitives + theStructure.renderClosedGeometry (theWorkspace); // override material, cull back faces theWorkspace->SetAspectFace (&theWorkspace->FrontCulling()); diff --git a/src/OpenGl/OpenGl_CappingAlgo.hxx b/src/OpenGl/OpenGl_CappingAlgo.hxx index cff4be93b1..76e7b2dfff 100755 --- a/src/OpenGl/OpenGl_CappingAlgo.hxx +++ b/src/OpenGl/OpenGl_CappingAlgo.hxx @@ -19,10 +19,9 @@ #include <OpenGl_RenderFilter.hxx> #include <OpenGl_Group.hxx> -#include <Graphic3d_SequenceOfGroup.hxx> - // Forward declaration class OpenGl_CappingAlgoFilter; +class OpenGl_Structure; DEFINE_STANDARD_HANDLE (OpenGl_CappingAlgoFilter, OpenGl_RenderFilter) //! Capping surface rendering algorithm. @@ -30,13 +29,12 @@ class OpenGl_CappingAlgo { public: - //! Draw capping surfaces by OpenGl for the clipping planes - //! enabled in current context state. Depth buffer must be generated - //! for the passed groups. - //! @param theWorkspace [in] the GL workspace, context state. - //! @param theGroups [in] the group of primitives to be capped. - Standard_EXPORT static void RenderCapping (const Handle(OpenGl_Workspace)& theWorkspace, - const Graphic3d_SequenceOfGroup& theGroups); + //! Draw capping surfaces by OpenGl for the clipping planes enabled in current context state. + //! Depth buffer must be generated for the passed groups. + //! @param theWorkspace [in] the GL workspace, context state + //! @param theStructure [in] the structure to be capped + Standard_EXPORT static void RenderCapping (const Handle(OpenGl_Workspace)& theWorkspace, + const OpenGl_Structure& theStructure); //! Render infinite capping plane. //! @param theWorkspace [in] the GL workspace, context state. diff --git a/src/OpenGl/OpenGl_Structure.cxx b/src/OpenGl/OpenGl_Structure.cxx index 1ede9f5f93..01e05467d3 100644 --- a/src/OpenGl/OpenGl_Structure.cxx +++ b/src/OpenGl/OpenGl_Structure.cxx @@ -490,19 +490,44 @@ void OpenGl_Structure::Clear (const Handle(OpenGl_Context)& theGlCtx) } // ======================================================================= -// function : RenderGeometry +// function : renderGeometry // purpose : // ======================================================================= -void OpenGl_Structure::RenderGeometry (const Handle(OpenGl_Workspace) &theWorkspace) const +void OpenGl_Structure::renderGeometry (const Handle(OpenGl_Workspace)& theWorkspace, + bool& theHasClosed) const { - // Render groups - const Graphic3d_SequenceOfGroup& aGroups = DrawGroups(); - for (OpenGl_Structure::GroupIterator aGroupIter (aGroups); aGroupIter.More(); aGroupIter.Next()) + if (myInstancedStructure != NULL) { + myInstancedStructure->renderGeometry (theWorkspace, theHasClosed); + } + + for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next()) + { + theHasClosed = theHasClosed || aGroupIter.Value()->IsClosed(); aGroupIter.Value()->Render (theWorkspace); } } +// ======================================================================= +// function : renderClosedGeometry +// purpose : +// ======================================================================= +void OpenGl_Structure::renderClosedGeometry (const Handle(OpenGl_Workspace)& theWorkspace) const +{ + if (myInstancedStructure != NULL) + { + myInstancedStructure->renderClosedGeometry (theWorkspace); + } + + for (OpenGl_Structure::GroupIterator aGroupIter (myGroups); aGroupIter.More(); aGroupIter.Next()) + { + if (aGroupIter.Value()->IsClosed()) + { + aGroupIter.Value()->Render (theWorkspace); + } + } +} + // ======================================================================= // function : Render // purpose : @@ -585,12 +610,6 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con if (myHighlightColor) theWorkspace->HighlightColor = myHighlightColor; - // Render instanced structure (if exists) - if (myInstancedStructure != NULL) - { - myInstancedStructure->RenderGeometry (theWorkspace); - } - // Set up plane equations for non-structure transformed global model-view matrix // List of planes to be applied to context state NCollection_Handle<Graphic3d_SequenceOfHClipPlane> aUserPlanes; @@ -629,11 +648,8 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con } // Render groups - const Graphic3d_SequenceOfGroup& aGroups = DrawGroups(); - for (OpenGl_Structure::GroupIterator aGroupIter (aGroups); aGroupIter.More(); aGroupIter.Next()) - { - aGroupIter.Value()->Render (theWorkspace); - } + bool hasClosedPrims = false; + renderGeometry (theWorkspace, hasClosedPrims); // Reset correction for mirror transform if (myIsMirrored) @@ -642,9 +658,10 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &theWorkspace) con } // Render capping for structure groups - if (!aCtx->Clipping().Planes().IsEmpty()) + if (hasClosedPrims + && !aCtx->Clipping().Planes().IsEmpty()) { - OpenGl_CappingAlgo::RenderCapping (theWorkspace, aGroups); + OpenGl_CappingAlgo::RenderCapping (theWorkspace, *this); } // Revert structure clippings diff --git a/src/OpenGl/OpenGl_Structure.hxx b/src/OpenGl/OpenGl_Structure.hxx index 479a683445..afe02b48cb 100644 --- a/src/OpenGl/OpenGl_Structure.hxx +++ b/src/OpenGl/OpenGl_Structure.hxx @@ -130,7 +130,13 @@ public: Standard_EXPORT void Clear (const Handle(OpenGl_Context)& theGlCtx); //! Renders groups of structure without applying any attributes (i.e. transform, material etc). - virtual void RenderGeometry (const Handle(OpenGl_Workspace)& theWorkspace) const; + //! @param theWorkspace current workspace + //! @param theHasClosed flag will be set to TRUE if structure contains at least one group of closed primitives + virtual void renderGeometry (const Handle(OpenGl_Workspace)& theWorkspace, + bool& theHasClosed) const; + + //! Renders groups of closed primitives without applying any attributes (i.e. transform, material etc). + virtual void renderClosedGeometry (const Handle(OpenGl_Workspace)& theWorkspace) const; //! Renders the structure. virtual void Render (const Handle(OpenGl_Workspace)& theWorkspace) const; diff --git a/src/OpenGl/OpenGl_StructureShadow.hxx b/src/OpenGl/OpenGl_StructureShadow.hxx index e9d2c58e60..04c70b1b48 100644 --- a/src/OpenGl/OpenGl_StructureShadow.hxx +++ b/src/OpenGl/OpenGl_StructureShadow.hxx @@ -28,9 +28,23 @@ public: Standard_EXPORT OpenGl_StructureShadow (const Handle(Graphic3d_StructureManager)& theManager, const Handle(OpenGl_Structure)& theStructure); + //! Return groups of parent structure. virtual const Graphic3d_SequenceOfGroup& DrawGroups() const Standard_OVERRIDE { return myParent->DrawGroups(); } + //! Renders groups of parent structure. + virtual void renderGeometry (const Handle(OpenGl_Workspace)& theWorkspace, + bool& theHasClosed) const Standard_OVERRIDE + { + myParent->renderGeometry (theWorkspace, theHasClosed); + } + + //! Renders closed groups of parent structure. + virtual void renderClosedGeometry (const Handle(OpenGl_Workspace)& theWorkspace) const Standard_OVERRIDE + { + myParent->renderClosedGeometry (theWorkspace); + } + private: Handle(OpenGl_Structure) myParent; diff --git a/tests/bugs/vis/bug26940 b/tests/bugs/vis/bug26940 new file mode 100644 index 0000000000..20ed679eb1 --- /dev/null +++ b/tests/bugs/vis/bug26940 @@ -0,0 +1,34 @@ +puts "============" +puts "0026940: Visualization, TKOpenGl - capping plane should be applied to connected structures" +puts "Tests capping plane rendering with connected structures" +puts "============" +puts "" + +vinit View1 +vclear +vaxo +vsetdispmode 1 +box b 1 1 1 +vdisplay b +vfit + +vclipplane create pln +vclipplane set pln view Driver1/Viewer1/View1 +vclipplane change pln equation 0 1 0 -0.5 +vclipplane change pln capping on + +vdump $imagedir/${casename}_normal.png +set aColorNorm [vreadpixel 200 250 rgb name] +if { "$aColorNorm" != "GRAY13" } { + puts "Error: Expected color of capping plane is GRAY13 (normal presentation). Actial is $aColorNorm" +} + +vclear + +vconnectto bb 0 0 0 b +vdump $imagedir/${casename}_connected.png +set aColorConn [vreadpixel 200 250 rgb name] + +if { "$aColorConn" != "GRAY13" } { + puts "Error: Expected color of capping plane is GRAY13 (connected presentation). Actial is $aColorConn" +}