0029874: Visualization - capping plane transparency does not work
authorkgv <kgv@opencascade.com>
Fri, 15 Jun 2018 16:39:31 +0000 (19:39 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 6 Jul 2018 12:56:08 +0000 (15:56 +0300)
Interface OpenGl_RenderFilter and its implementations have been merged into OpenGl_Workspace.
This limits flexibility of interface, but simplifies logic.
- OpenGl_RenderFilter_FillModeOnly flag replaces OpenGl_CappingAlgoFilter;
- OpenGl_RenderFilter_NonRaytraceableOnly flag replaces OpenGl_RaytraceFilter;
- OpenGl_RenderFilter_OpaqueOnly flag replaces OpenGl_OpaqueFilter;
- OpenGl_RenderFilter_TransparentOnly flag replaces OpenGl_TransparentFilter.

OpenGl_CappingAlgo now:
- avoids redundant Stencil clearing when Layer contains at least one transparent Element;
- renders semitransparent capping plane within transparent elements pass.

vclipplane command has been extended by new argument -transparency.

15 files changed:
src/OpenGl/FILES
src/OpenGl/OpenGl_CappingAlgo.cxx
src/OpenGl/OpenGl_CappingAlgo.hxx
src/OpenGl/OpenGl_Element.hxx
src/OpenGl/OpenGl_Group.cxx
src/OpenGl/OpenGl_LayerList.cxx
src/OpenGl/OpenGl_LayerList.hxx
src/OpenGl/OpenGl_RenderFilter.cxx [deleted file]
src/OpenGl/OpenGl_RenderFilter.hxx
src/OpenGl/OpenGl_View.hxx
src/OpenGl/OpenGl_View_Redraw.cxx
src/OpenGl/OpenGl_Workspace.cxx
src/OpenGl/OpenGl_Workspace.hxx
src/ViewerTest/ViewerTest_ViewerCommands.cxx
tests/bugs/vis/bug29874 [new file with mode: 0644]

index c9e4fa9..25b92ca 100755 (executable)
@@ -111,7 +111,6 @@ OpenGl_IndexBuffer.cxx
 OpenGl_IndexBuffer.hxx
 OpenGl_Layer.cxx
 OpenGl_Layer.hxx
-OpenGl_RenderFilter.cxx
 OpenGl_RenderFilter.hxx
 OpenGl_Sampler.cxx
 OpenGl_Sampler.hxx
index 0a438fb..4338d50 100755 (executable)
 #include <OpenGl_Structure.hxx>
 #include <OpenGl_ShaderManager.hxx>
 
-IMPLEMENT_STANDARD_RTTIEXT(OpenGl_CappingAlgoFilter,OpenGl_RenderFilter)
-
 namespace
 {
+  //! Auxiliary sentry object managing stencil test.
+  struct StencilTestSentry
+  {
+    StencilTestSentry() : myDepthFuncPrev (0) {}
+
+    //! Restore previous application state.
+    ~StencilTestSentry()
+    {
+      if (myDepthFuncPrev != 0)
+      {
+        glClear (GL_STENCIL_BUFFER_BIT);
+        glDepthFunc (myDepthFuncPrev);
+        glStencilFunc (GL_ALWAYS, 0, 0xFF);
+        glDisable (GL_STENCIL_TEST);
+      }
+    }
+
+    //! Prepare for rendering the clip planes.
+    void Init()
+    {
+      if (myDepthFuncPrev == 0)
+      {
+        glEnable (GL_STENCIL_TEST);
+        glGetIntegerv (GL_DEPTH_FUNC, &myDepthFuncPrev);
+        glDepthFunc (GL_LESS);
+      }
+    }
+
+  private:
+    GLint myDepthFuncPrev;
+  };
+
   //! Render infinite capping plane.
   //! @param theWorkspace [in] the GL workspace, context state.
   //! @param thePlane [in] the graphical plane, for which the capping surface is rendered.
   static void renderPlane (const Handle(OpenGl_Workspace)& theWorkspace,
-                           const Handle(OpenGl_CappingPlaneResource)& thePlane,
-                           const OpenGl_AspectFace* theAspectFace)
+                           const Handle(OpenGl_CappingPlaneResource)& thePlane)
   {
     const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
-    thePlane->Update (aContext, theAspectFace != NULL ? theAspectFace->Aspect() : Handle(Graphic3d_AspectFillArea3d)());
-
-    bool wasCullAllowed = theWorkspace->SetAllowFaceCulling (true);
-    const OpenGl_AspectFace* aFaceAspect = theWorkspace->AspectFace();
-    theWorkspace->SetAspectFace (thePlane->AspectFace());
+    const bool wasCullAllowed = theWorkspace->SetAllowFaceCulling (true);
 
     // set identity model matrix
     aContext->ModelWorldState.Push();
@@ -53,16 +78,19 @@ namespace
     aContext->ApplyModelViewMatrix();
 
     theWorkspace->SetAllowFaceCulling (wasCullAllowed);
-    theWorkspace->SetAspectFace (aFaceAspect);
   }
 
   //! Render capping for specific structure.
-  static void renderCappingForStructure (const Handle(OpenGl_Workspace)& theWorkspace,
+  static void renderCappingForStructure (StencilTestSentry& theStencilSentry,
+                                         const Handle(OpenGl_Workspace)& theWorkspace,
                                          const OpenGl_Structure&         theStructure,
                                          const Handle(Graphic3d_ClipPlane)& theClipChain,
                                          const Standard_Integer          theSubPlaneIndex,
                                          const Handle(OpenGl_CappingPlaneResource)& thePlane)
   {
+    const Standard_Integer aPrevFilter = theWorkspace->RenderFilter();
+    const Standard_Integer anAnyFilter = aPrevFilter & ~(Standard_Integer )(OpenGl_RenderFilter_OpaqueOnly | OpenGl_RenderFilter_TransparentOnly);
+
     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())
@@ -72,6 +100,22 @@ namespace
         continue;
       }
 
+      // clear stencil only if something has been actually drawn
+      theStencilSentry.Init();
+
+      // check if capping plane should be rendered within current pass (only opaque / only transparent)
+      const OpenGl_AspectFace* anObjAspectFace = aRenderPlane->ToUseObjectProperties() ? aGroupIter.Value()->AspectFace() : NULL;
+      thePlane->Update (aContext, anObjAspectFace != NULL ? anObjAspectFace->Aspect() : Handle(Graphic3d_AspectFillArea3d)());
+      theWorkspace->SetAspectFace (thePlane->AspectFace());
+      theWorkspace->SetRenderFilter (aPrevFilter);
+      if (!theWorkspace->ShouldRender (&thePlane->Primitives()))
+      {
+        continue;
+      }
+
+      // suppress only opaque/transparent filter since for filling stencil the whole geometry should be drawn
+      theWorkspace->SetRenderFilter (anAnyFilter);
+
       // enable only the rendering plane to generate stencil mask
       aContext->ChangeClipping().DisableAllExcept (theClipChain, theSubPlaneIndex);
       aContext->ShaderManager()->UpdateClippingState();
@@ -132,8 +176,8 @@ namespace
         glEnable (GL_DEPTH_TEST);
       }
 
-      renderPlane (theWorkspace, thePlane,
-                   aRenderPlane->ToUseObjectProperties() ? aGroupIter.Value()->AspectFace() : NULL);
+      theWorkspace->SetAspectFace (thePlane->AspectFace());
+      renderPlane (theWorkspace, thePlane);
 
       // turn on the current plane to restore initial state
       aContext->ChangeClipping().ResetCappingFilter();
@@ -143,7 +187,7 @@ namespace
 
     if (theStructure.InstancedStructure() != NULL)
     {
-      renderCappingForStructure (theWorkspace, *theStructure.InstancedStructure(), theClipChain, theSubPlaneIndex, thePlane);
+      renderCappingForStructure (theStencilSentry, theWorkspace, *theStructure.InstancedStructure(), theClipChain, theSubPlaneIndex, thePlane);
     }
   }
 }
@@ -165,20 +209,10 @@ void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorks
   // remember current aspect face defined in workspace
   const OpenGl_AspectFace* aFaceAsp = theWorkspace->AspectFace();
 
-  // replace primitive groups rendering filter
-  Handle(OpenGl_RenderFilter) aRenderFilter = theWorkspace->GetRenderFilter();
-  Handle(OpenGl_CappingAlgoFilter) aCappingFilter = theWorkspace->DefaultCappingAlgoFilter();
-  aCappingFilter->SetPreviousFilter (aRenderFilter);
-  theWorkspace->SetRenderFilter (aCappingFilter);
-
-  // prepare for rendering the clip planes
-  glEnable (GL_STENCIL_TEST);
-
-  // remember current state of depth
-  // function and change its value
-  GLint aDepthFuncPrev;
-  glGetIntegerv (GL_DEPTH_FUNC, &aDepthFuncPrev);
-  glDepthFunc (GL_LESS);
+  // only filled primitives should be rendered
+  const Standard_Integer aPrevFilter = theWorkspace->RenderFilter();
+  theWorkspace->SetRenderFilter (aPrevFilter | OpenGl_RenderFilter_FillModeOnly);
+  StencilTestSentry aStencilSentry;
 
   // generate capping for every clip plane
   for (OpenGl_ClippingIterator aCappingIt (aContext->Clipping()); aCappingIt.More(); aCappingIt.Next())
@@ -204,7 +238,7 @@ void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorks
         aContext->ShareResource (aResId, aPlaneRes);
       }
 
-      renderCappingForStructure (theWorkspace, theStructure, aClipChain, aSubPlaneIndex, aPlaneRes);
+      renderCappingForStructure (aStencilSentry, theWorkspace, theStructure, aClipChain, aSubPlaneIndex, aPlaneRes);
 
       // set delayed resource release
       aPlaneRes.Nullify();
@@ -212,28 +246,7 @@ void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorks
     }
   }
 
-  // restore previous application state
-  glClear (GL_STENCIL_BUFFER_BIT);
-  glDepthFunc (aDepthFuncPrev);
-  glStencilFunc (GL_ALWAYS, 0, 0xFF);
-  glDisable (GL_STENCIL_TEST);
-
   // restore rendering aspects
   theWorkspace->SetAspectFace (aFaceAsp);
-  theWorkspace->SetRenderFilter (aRenderFilter);
-}
-
-// =======================================================================
-// function : CanRender
-// purpose  :
-// =======================================================================
-Standard_Boolean OpenGl_CappingAlgoFilter::ShouldRender (const Handle(OpenGl_Workspace)& theWorkspace,
-                                                         const OpenGl_Element* theGlElement)
-{
-  if (!myFilter.IsNull() && !myFilter->ShouldRender (theWorkspace, theGlElement))
-  {
-    return Standard_False;
-  }
-
-  return theGlElement->IsFillDrawMode();
+  theWorkspace->SetRenderFilter (aPrevFilter);
 }
index e936779..9ad192d 100755 (executable)
 #ifndef _OpenGl_CappingAlgo_H__
 #define _OpenGl_CappingAlgo_H__
 
-#include <OpenGl_RenderFilter.hxx>
 #include <OpenGl_Group.hxx>
 
 // Forward declaration
-class OpenGl_CappingAlgoFilter;
 class OpenGl_CappingPlaneResource;
 class OpenGl_Structure;
 
-DEFINE_STANDARD_HANDLE (OpenGl_CappingAlgoFilter, OpenGl_RenderFilter)
-
 //! Capping surface rendering algorithm.
 class OpenGl_CappingAlgo
 {
@@ -40,32 +36,4 @@ public:
 
 };
 
-//! Graphical capping rendering algorithm filter.
-//! Filters out everything except shaded primitives.
-class OpenGl_CappingAlgoFilter : public OpenGl_RenderFilter
-{
-public:
-
-  //! Default constructor.
-  OpenGl_CappingAlgoFilter() {}
-
-  //! Sets the current active filter in workspace.
-  //! @param thePrevFilter [in] the previously active filter that should have additive effect.
-  void SetPreviousFilter (const Handle(OpenGl_RenderFilter)& thePrevFitler) { myFilter = thePrevFitler; }
-
-  //! Checks whether the element can be rendered or not.
-  //! @param theElement [in] the element to check.
-  //! @return True if element can be rendered.
-  virtual Standard_Boolean ShouldRender (const Handle(OpenGl_Workspace)& theWorkspace,
-                                         const OpenGl_Element* theGlElement) Standard_OVERRIDE;
-
-private:
-
-  Handle(OpenGl_RenderFilter) myFilter; //!< Previous active filter that should be combined.
-
-public:
-
-  DEFINE_STANDARD_RTTIEXT(OpenGl_CappingAlgoFilter,OpenGl_RenderFilter)
-};
-
 #endif
index 1df5afe..0708f42 100644 (file)
@@ -17,6 +17,7 @@
 #define OpenGl_Element_Header
 
 #include <OpenGl_RenderFilter.hxx>
+#include <Standard_Type.hxx>
 
 class OpenGl_Workspace;
 class OpenGl_Context;
@@ -59,30 +60,6 @@ public:
   //! Return TRUE if primitive type generates shaded triangulation (to be used in filters).
   virtual Standard_Boolean IsFillDrawMode() const { return false; }
 
-public:
-
-  //! Render element if it passes the filtering procedure. This method should
-  //! be used for elements which can be used in scope of rendering algorithms.
-  //! E.g. elements of groups during recursive rendering.
-  //! If render filter is null, pure rendering is performed.
-  //! @param theWorkspace [in] the rendering workspace.
-  //! @param theFilter [in] the rendering filter to check whether the element
-  //! should be rendered or not.
-  //! @return True if element passes the check and renders,
-  inline Standard_Boolean
-    RenderFiltered (const Handle(OpenGl_Workspace)& theWorkspace,
-                    const Handle(OpenGl_RenderFilter)& theFilter) const
-  {
-    if (!theFilter.IsNull() && !theFilter->ShouldRender (theWorkspace, this))
-    {
-      return Standard_False;
-    }
-
-    Render (theWorkspace);
-
-    return Standard_True;
-  }
-
 protected:
 
   Standard_EXPORT virtual ~OpenGl_Element();
index 1d44dd9..c9211ad 100644 (file)
 #include <Graphic3d_ArrayOfPrimitives.hxx>
 #include <Graphic3d_GroupDefinitionError.hxx>
 
-
 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Group,Graphic3d_Group)
 
+namespace
+{
+  //! Render element if it passes the filtering procedure. This method should
+  //! be used for elements which can be used in scope of rendering algorithms.
+  //! E.g. elements of groups during recursive rendering.
+  //! If render filter is null, pure rendering is performed.
+  //! @param theWorkspace [in] the rendering workspace.
+  //! @param theFilter [in] the rendering filter to check whether the element
+  //! should be rendered or not.
+  //! @return True if element passes the check and renders,
+  static bool renderFiltered (const Handle(OpenGl_Workspace)& theWorkspace,
+                              OpenGl_Element* theElement)
+  {
+    if (!theWorkspace->ShouldRender (theElement))
+    {
+      return false;
+    }
+
+    theElement->Render (theWorkspace);
+    return true;
+  }
+}
+
 // =======================================================================
 // function : OpenGl_Group
 // purpose  :
@@ -393,8 +415,6 @@ void OpenGl_Group::AddElement (OpenGl_Element* theElem)
 // =======================================================================
 void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
 {
-  const Handle(OpenGl_RenderFilter)& aFilter = theWorkspace->GetRenderFilter();
-
   // Setup aspects
   theWorkspace->SetAllowFaceCulling (myIsClosed
                                  && !theWorkspace->GetGlContext()->Clipping().IsClippingOrCappingOn());
@@ -402,15 +422,15 @@ void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
   const OpenGl_AspectFace*   aBackAspectFace   = theWorkspace->AspectFace();
   const OpenGl_AspectMarker* aBackAspectMarker = theWorkspace->AspectMarker();
   const OpenGl_AspectText*   aBackAspectText   = theWorkspace->AspectText();
-  Standard_Boolean isLineSet   = myAspectLine   && myAspectLine->RenderFiltered (theWorkspace, aFilter);
-  Standard_Boolean isFaceSet   = myAspectFace   && myAspectFace->RenderFiltered (theWorkspace, aFilter);
-  Standard_Boolean isMarkerSet = myAspectMarker && myAspectMarker->RenderFiltered (theWorkspace, aFilter);
-  Standard_Boolean isTextSet   = myAspectText   && myAspectText->RenderFiltered (theWorkspace, aFilter);
+  const bool isLineSet   = myAspectLine   && renderFiltered (theWorkspace, myAspectLine);
+  const bool isFaceSet   = myAspectFace   && renderFiltered (theWorkspace, myAspectFace);
+  const bool isMarkerSet = myAspectMarker && renderFiltered (theWorkspace, myAspectMarker);
+  const bool isTextSet   = myAspectText   && renderFiltered (theWorkspace, myAspectText);
 
   // Render group elements
   for (OpenGl_ElementNode* aNodeIter = myFirst; aNodeIter != NULL; aNodeIter = aNodeIter->next)
   {
-    aNodeIter->elem->RenderFiltered (theWorkspace, aFilter);
+    renderFiltered (theWorkspace, aNodeIter->elem);
   }
 
   // Restore aspects
index 6a0856d..c19ad51 100644 (file)
@@ -148,9 +148,7 @@ OpenGl_LayerList::OpenGl_LayerList (const Standard_Integer theNbPriorities)
   myNbPriorities (theNbPriorities),
   myNbStructures (0),
   myImmediateNbStructures (0),
-  myModifStateOfRaytraceable (0),
-  myRenderOpaqueFilter (new OpenGl_OpaqueFilter()),
-  myRenderTranspFilter (new OpenGl_TransparentFilter())
+  myModifStateOfRaytraceable (0)
 {
   // insert default priority layers
   myLayers.Append (new OpenGl_Layer (myNbPriorities, myBVHBuilder));
@@ -558,10 +556,8 @@ void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace,
   // was preallocated before going into this method and has enough space to keep
   // maximum number of references to layers, therefore it will not increase memory
   // fragmentation during regular rendering.
-  const Handle(OpenGl_RenderFilter) aPrevFilter = theWorkspace->GetRenderFilter();
-  myRenderOpaqueFilter->SetPreviousFilter (aPrevFilter);
-  myRenderTranspFilter->SetPreviousFilter (aPrevFilter);
-  theWorkspace->SetRenderFilter (myRenderOpaqueFilter);
+  const Standard_Integer aPrevFilter = theWorkspace->RenderFilter() & ~(Standard_Integer )(OpenGl_RenderFilter_OpaqueOnly | OpenGl_RenderFilter_TransparentOnly);
+  theWorkspace->SetRenderFilter (aPrevFilter | OpenGl_RenderFilter_OpaqueOnly);
 
   myTransparentToProcess.Clear();
 
@@ -647,12 +643,12 @@ void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace,
         // Render opaque OpenGl elements of a layer and count the number of skipped.
         // If a layer has skipped (e.g. transparent) elements it should be added into
         // the transparency post-processing stack.
-        myRenderOpaqueFilter->SetSkippedCounter (0);
+        theWorkspace->ResetSkippedCounter();
 
         aLayer.Render (theWorkspace, aDefaultSettings);
 
         if (aPassIter != 0
-         && myRenderOpaqueFilter->NbSkipped() > 0)
+         && theWorkspace->NbSkippedTransparentElements() > 0)
         {
           myTransparentToProcess.Push (&aLayer);
         }
@@ -716,7 +712,8 @@ void OpenGl_LayerList::renderTransparent (const Handle(OpenGl_Workspace)&   theW
   OpenGl_View* aView = theWorkspace->View();
   const float aDepthFactor =  aView != NULL ? aView->RenderingParams().OitDepthFactor : 0.0f;
 
-  theWorkspace->SetRenderFilter (myRenderTranspFilter);
+  const Standard_Integer aPrevFilter = theWorkspace->RenderFilter() & ~(Standard_Integer )(OpenGl_RenderFilter_OpaqueOnly | OpenGl_RenderFilter_TransparentOnly);
+  theWorkspace->SetRenderFilter (aPrevFilter | OpenGl_RenderFilter_TransparentOnly);
 
   aCtx->core11fwd->glEnable (GL_BLEND);
 
@@ -764,7 +761,7 @@ void OpenGl_LayerList::renderTransparent (const Handle(OpenGl_Workspace)&   theW
     aCtx->SetDrawBuffers (1, aDrawBuffers);
   }
 
-  theWorkspace->SetRenderFilter (myRenderOpaqueFilter);
+  theWorkspace->SetRenderFilter (aPrevFilter | OpenGl_RenderFilter_OpaqueOnly);
   if (isEnabledOit)
   {
     const Standard_Boolean isMSAA = theReadDrawFbo && theReadDrawFbo->NbSamples() > 0;
@@ -815,55 +812,3 @@ void OpenGl_LayerList::renderTransparent (const Handle(OpenGl_Workspace)&   theW
   aCtx->core11fwd->glDepthMask (theGlobalSettings.DepthMask);
   aCtx->core11fwd->glDepthFunc (theGlobalSettings.DepthFunc);
 }
-
-//=======================================================================
-//class    : OpenGl_OpaqueFilter
-//function : ShouldRender
-//purpose  : Checks whether the element should be rendered or skipped.
-//=======================================================================
-Standard_Boolean OpenGl_LayerList::OpenGl_OpaqueFilter::ShouldRender (const Handle(OpenGl_Workspace)& theWorkspace,
-                                                                      const OpenGl_Element*           theGlElement)
-{
-  if (!myFilter.IsNull()
-   && !myFilter->ShouldRender (theWorkspace, theGlElement))
-  {
-    return Standard_False;
-  }
-
-  if (!theGlElement->IsFillDrawMode())
-  {
-    return Standard_True;
-  }
-
-  if (OpenGl_Context::CheckIsTransparent (theWorkspace->AspectFace(),
-                                          theWorkspace->HighlightStyle()))
-  {
-    ++mySkippedCounter;
-    return Standard_False;
-  }
-
-  return Standard_True;
-}
-
-//=======================================================================
-//class    : OpenGl_TransparentFilter
-//function : ShouldRender
-//purpose  : Checks whether the element should be rendered or skipped.
-//=======================================================================
-Standard_Boolean OpenGl_LayerList::OpenGl_TransparentFilter::ShouldRender (const Handle(OpenGl_Workspace)& theWorkspace,
-                                                                           const OpenGl_Element*           theGlElement)
-{
-  if (!myFilter.IsNull()
-   && !myFilter->ShouldRender (theWorkspace, theGlElement))
-  {
-    return Standard_False;
-  }
-
-  if (!theGlElement->IsFillDrawMode())
-  {
-    return dynamic_cast<const OpenGl_AspectFace*> (theGlElement) != NULL;
-  }
-
-  return OpenGl_Context::CheckIsTransparent (theWorkspace->AspectFace(),
-                                             theWorkspace->HighlightStyle());
-}
index bf4063c..3701607 100644 (file)
@@ -120,65 +120,6 @@ public:
 
 protected:
 
-  //! Filter of TKOpenGl elements for processing only shading geometry and
-  //! for collecting number of skipped elements to an external counter.
-  class OpenGl_OpaqueFilter : public OpenGl_RenderFilter
-  {
-  public:
-
-    //! Constructor.
-    //! @param thePrevFilter [in] the previously active filter that should have additive effect.
-    OpenGl_OpaqueFilter() : mySkippedCounter (0) {}
-
-    //! Sets the current active filter in workspace.
-    //! @param thePrevFilter [in] the previously active filter that should have additive effect.
-    void SetPreviousFilter (const Handle(OpenGl_RenderFilter)& thePrevFitler) { myFilter = thePrevFitler; }
-
-    //! Sets the value of the skipped elements counter.
-    void SetSkippedCounter (const Standard_Size theCounter) { mySkippedCounter = theCounter; }
-
-    //! Returns number of skipped elements.
-    Standard_Size NbSkipped() const { return mySkippedCounter; }
-
-    //! Checks whether the element should be rendered or skipped.
-    //! @param theWorkspace [in] the currently used workspace for rendering.
-    //! @param theGlElement [in] the TKOpenGl rendering queue element that should be checked before streaming to GPU.
-    Standard_EXPORT virtual Standard_Boolean ShouldRender (const Handle(OpenGl_Workspace)& theWorkspace,
-                                                           const OpenGl_Element*           theGlElement) Standard_OVERRIDE;
-
-    DEFINE_STANDARD_RTTI_INLINE (OpenGl_OpaqueFilter, OpenGl_RenderFilter)
-
-  private:
-
-    Standard_Size mySkippedCounter;   //!< Counter of skipped elements.
-    Handle(OpenGl_RenderFilter) myFilter; //!< Previous active filter that should be combined.
-  };
-
-  //! Filter of TKOpenGl elements for keeping only shading geometry with transparency.
-  class OpenGl_TransparentFilter : public OpenGl_RenderFilter
-  {
-  public:
-
-    //! Constructor.
-    OpenGl_TransparentFilter() {}
-
-    //! Sets the current active filter in workspace.
-    //! @param thePrevFilter [in] the previously active filter that should have additive effect.
-    void SetPreviousFilter (const Handle(OpenGl_RenderFilter)& thePrevFitler) { myFilter = thePrevFitler; }
-
-    //! Checks whether the element should be rendered or skipped.
-    //! @param theWorkspace [in] the currently used workspace for rendering.
-    //! @param theGlElement [in] the TKOpenGl rendering queue element that should be checked before streaming to GPU.
-    Standard_EXPORT virtual Standard_Boolean ShouldRender (const Handle(OpenGl_Workspace)& theWorkspace,
-                                                           const OpenGl_Element*           theGlElement) Standard_OVERRIDE;
-
-    DEFINE_STANDARD_RTTI_INLINE (OpenGl_TransparentFilter, OpenGl_RenderFilter)
-
-  private:
-
-    Handle(OpenGl_RenderFilter) myFilter; //!< Previous active filter that should be combined.
-  };
-
   //! Stack of references to existing layers of predefined maximum size.
   class OpenGl_LayerStack
   {
@@ -261,9 +202,6 @@ protected:
   //! Collection of references to layers with transparency gathered during rendering pass.
   mutable OpenGl_LayerStack myTransparentToProcess;
 
-  Handle(OpenGl_OpaqueFilter)      myRenderOpaqueFilter; //!< rendering filter for opaque drawing pass (blended OIT).
-  Handle(OpenGl_TransparentFilter) myRenderTranspFilter; //!< rendering filter for transparency drawing pass (blended OIT).
-
 public:
 
   DEFINE_STANDARD_ALLOC
diff --git a/src/OpenGl/OpenGl_RenderFilter.cxx b/src/OpenGl/OpenGl_RenderFilter.cxx
deleted file mode 100755 (executable)
index 8e516dd..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// Created on: 2013-07-25
-// Created by: Anton POLETAEV
-// Copyright (c) 2013-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.
-
-#include <OpenGl_RenderFilter.hxx>
-
-
-
-IMPLEMENT_STANDARD_RTTIEXT(OpenGl_RenderFilter,Standard_Transient)
\ No newline at end of file
index ac1a156..69344d0 100755 (executable)
 #ifndef _OpenGl_RenderFilter_H__
 #define _OpenGl_RenderFilter_H__
 
-#include <Standard_Type.hxx>
-#include <Standard_Transient.hxx>
-
-class OpenGl_RenderFilter;
-DEFINE_STANDARD_HANDLE (OpenGl_RenderFilter, Standard_Transient)
-
-class OpenGl_Element;
-class OpenGl_Workspace;
-
-//! Base class for defining element rendering filters.
-//! This class can be used in pair with advance rendering passes, and for 
-//! disabling rendering (setting up) graphical aspects.
-class OpenGl_RenderFilter : public Standard_Transient
+//! Filter for rendering elements.
+enum OpenGl_RenderFilter
 {
-public:
-
-  //! Checks whether the element can be rendered or not.
-  //! @param theWorkspace [in] the current workspace.
-  //! @param theElement [in] the element to check.
-  //! @return True if element can be rendered.
-  virtual Standard_Boolean ShouldRender (const Handle(OpenGl_Workspace)& theWorkspace, const OpenGl_Element* theElement) = 0;
+  OpenGl_RenderFilter_Empty               = 0x000, //!< disabled filter
 
-public:
+  OpenGl_RenderFilter_OpaqueOnly          = 0x001, //!< render only opaque elements and any non-filling elements   (conflicts with OpenGl_RenderFilter_TransparentOnly)
+  OpenGl_RenderFilter_TransparentOnly     = 0x002, //!< render only semitransparent elements and OpenGl_AspectFace (conflicts with OpenGl_RenderFilter_OpaqueOnly)
 
-  DEFINE_STANDARD_RTTIEXT(OpenGl_RenderFilter, Standard_Transient)
+  OpenGl_RenderFilter_NonRaytraceableOnly = 0x004, //!< render only non-raytraceable elements
+  OpenGl_RenderFilter_FillModeOnly        = 0x008, //!< render only filled elements
 };
 
 #endif
index be34e50..5154272 100644 (file)
@@ -1027,9 +1027,6 @@ protected: //! @name fields related to ray-tracing
   //! Set of IDs of non-raytracable elements (to detect updates).
   std::set<Standard_Integer> myNonRaytraceStructureIDs;
 
-  //! Render filter to filter out all raytracable structures.
-  Handle(OpenGl_RaytraceFilter) myRaytraceFilter;
-
   //! Marks if environment map should be updated.
   Standard_Boolean myToUpdateEnvironmentMap;
 
index 247e44f..6db6934 100644 (file)
@@ -1095,11 +1095,6 @@ void OpenGl_View::renderStructs (Graphic3d_Camera::Projection theProjection,
       const Standard_Integer aSizeY = theReadDrawFbo != NULL ? theReadDrawFbo->GetVPSizeY() : myWindow->Height();
       myOpenGlFBO ->InitLazy (aCtx, aSizeX, aSizeY, myFboColorFormat, myFboDepthFormat, 0);
 
-      if (myRaytraceFilter.IsNull())
-        myRaytraceFilter = new OpenGl_RaytraceFilter;
-
-      myRaytraceFilter->SetPrevRenderFilter (myWorkspace->GetRenderFilter());
-
       if (theReadDrawFbo != NULL)
         theReadDrawFbo->UnbindBuffer (aCtx);
 
@@ -1109,7 +1104,8 @@ void OpenGl_View::renderStructs (Graphic3d_Camera::Projection theProjection,
         // Render bottom OSD layer
         myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_Bottom, theReadDrawFbo, theOitAccumFbo);
 
-        myWorkspace->SetRenderFilter (myRaytraceFilter);
+        const Standard_Integer aPrevFilter = myWorkspace->RenderFilter() & ~(Standard_Integer )(OpenGl_RenderFilter_NonRaytraceableOnly);
+        myWorkspace->SetRenderFilter (aPrevFilter | OpenGl_RenderFilter_NonRaytraceableOnly);
         {
           if (theReadDrawFbo != NULL)
           {
@@ -1123,7 +1119,7 @@ void OpenGl_View::renderStructs (Graphic3d_Camera::Projection theProjection,
           // Render non-polygonal elements in default layer
           myZLayers.Render (myWorkspace, theToDrawImmediate, OpenGl_LF_Default, theReadDrawFbo, theOitAccumFbo);
         }
-        myWorkspace->SetRenderFilter (myRaytraceFilter->PrevRenderFilter());
+        myWorkspace->SetRenderFilter (aPrevFilter);
       }
 
       if (theReadDrawFbo != NULL)
index 37060f3..7f5f59c 100644 (file)
@@ -37,7 +37,6 @@
 #include <NCollection_AlignedAllocator.hxx>
 
 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Workspace,Standard_Transient)
-IMPLEMENT_STANDARD_RTTIEXT(OpenGl_RaytraceFilter,OpenGl_RenderFilter)
 
 namespace
 {
@@ -126,6 +125,9 @@ OpenGl_Workspace::OpenGl_Workspace (OpenGl_View* theView, const Handle(OpenGl_Wi
   myUseZBuffer    (Standard_True),
   myUseDepthWrite (Standard_True),
   //
+  myNbSkippedTranspElems (0),
+  myRenderFilter (OpenGl_RenderFilter_Empty),
+  //
   myAspectLineSet (&myDefaultAspectLine),
   myAspectFaceSet (&myDefaultAspectFace),
   myAspectMarkerSet (&myDefaultAspectMarker),
@@ -158,8 +160,6 @@ OpenGl_Workspace::OpenGl_Workspace (OpenGl_View* theView, const Handle(OpenGl_Wi
   #endif
   }
 
-  myDefaultCappingAlgoFilter = new OpenGl_CappingAlgoFilter();
-
   myFontFaceAspect.Aspect()->SetAlphaMode (Graphic3d_AlphaMode_Mask, 0.285f);
   myFontFaceAspect.Aspect()->SetShadingModel (Graphic3d_TOSM_UNLIT);
 
@@ -483,14 +483,51 @@ Standard_Boolean OpenGl_Workspace::BufferDump (const Handle(OpenGl_FrameBuffer)&
 // function : ShouldRender
 // purpose  :
 // =======================================================================
-Standard_Boolean OpenGl_RaytraceFilter::ShouldRender (const Handle(OpenGl_Workspace)& theWorkspace,
-                                                      const OpenGl_Element*           theElement)
+bool OpenGl_Workspace::ShouldRender (const OpenGl_Element* theElement)
 {
-  Standard_Boolean aPrevFilterResult = Standard_True;
-  if (!myPrevRenderFilter.IsNull())
+  // render only non-raytracable elements when RayTracing is enabled
+  if ((myRenderFilter & OpenGl_RenderFilter_NonRaytraceableOnly) != 0)
+  {
+    if (OpenGl_Raytrace::IsRaytracedElement (theElement))
+    {
+      return false;
+    }
+  }
+  else if ((myRenderFilter & OpenGl_RenderFilter_FillModeOnly) != 0)
+  {
+    if (!theElement->IsFillDrawMode())
+    {
+      return false;
+    }
+  }
+
+  // handle opaque/transparency render passes
+  if ((myRenderFilter & OpenGl_RenderFilter_OpaqueOnly) != 0)
+  {
+    if (!theElement->IsFillDrawMode())
+    {
+      return true;
+    }
+
+    if (OpenGl_Context::CheckIsTransparent (myAspectFaceSet, myHighlightStyle))
+    {
+      ++myNbSkippedTranspElems;
+      return false;
+    }
+  }
+  else if ((myRenderFilter & OpenGl_RenderFilter_TransparentOnly) != 0)
   {
-    aPrevFilterResult = myPrevRenderFilter->ShouldRender (theWorkspace, theElement);
+    if (!theElement->IsFillDrawMode())
+    {
+      if (dynamic_cast<const OpenGl_AspectFace*> (theElement) == NULL)
+      {
+        return false;
+      }
+    }
+    else if (!OpenGl_Context::CheckIsTransparent (myAspectFaceSet, myHighlightStyle))
+    {
+      return false;
+    }
   }
-  return aPrevFilterResult &&
-    !OpenGl_Raytrace::IsRaytracedElement (theElement);
+  return true;
 }
index 7645942..33b97ce 100644 (file)
 #include <OpenGl_FrameBuffer.hxx>
 #include <OpenGl_Material.hxx>
 #include <OpenGl_Matrix.hxx>
-#include <OpenGl_RenderFilter.hxx>
 #include <OpenGl_ShaderObject.hxx>
 #include <OpenGl_ShaderProgram.hxx>
 #include <OpenGl_TextParam.hxx>
 #include <OpenGl_TextureBufferArb.hxx>
+#include <OpenGl_RenderFilter.hxx>
 #include <OpenGl_Vec.hxx>
 #include <OpenGl_Window.hxx>
 
 class OpenGl_View;
 class Image_PixMap;
 
-class OpenGl_RaytraceFilter;
-DEFINE_STANDARD_HANDLE (OpenGl_RaytraceFilter, OpenGl_RenderFilter)
-
-//! Graphical ray-tracing filter.
-//! Filters out all raytracable structures.
-class OpenGl_RaytraceFilter : public OpenGl_RenderFilter
-{
-public:
-
-  //! Default constructor.
-  OpenGl_RaytraceFilter() {}
-
-  //! Returns the previously set filter.
-  const Handle(OpenGl_RenderFilter)& PrevRenderFilter()
-  {
-    return myPrevRenderFilter;
-  }
-
-  //! Remembers the previously set filter.
-  void SetPrevRenderFilter (const Handle(OpenGl_RenderFilter)& theFilter)
-  {
-    myPrevRenderFilter = theFilter;
-  }
-
-  //! Checks whether the element can be rendered or not.
-  //! @param theElement [in] the element to check.
-  //! @return True if element can be rendered.
-  virtual Standard_Boolean ShouldRender (const Handle(OpenGl_Workspace)& theWorkspace,
-                                         const OpenGl_Element*           theElement) Standard_OVERRIDE;
-
-private:
-
-  Handle(OpenGl_RenderFilter) myPrevRenderFilter;
-
-public:
-
-  DEFINE_STANDARD_RTTIEXT(OpenGl_RaytraceFilter,OpenGl_RenderFilter)
-};
-
 class OpenGl_Workspace;
 DEFINE_STANDARD_HANDLE(OpenGl_Workspace,Standard_Transient)
 
@@ -240,21 +201,26 @@ public:
   //! Clear the applied aspect state to default values.
   void ResetAppliedAspect();
 
+  //! Get rendering filter.
+  //! @sa ShouldRender()
+  Standard_Integer RenderFilter() const { return myRenderFilter; }
+
   //! Set filter for restricting rendering of particular elements.
-  //! Filter can be applied for rendering passes used by recursive
-  //! rendering algorithms for rendering elements of groups.
-  //! @param theFilter [in] the filter instance.
-  inline void SetRenderFilter (const Handle(OpenGl_RenderFilter)& theFilter)
-  {
-    myRenderFilter = theFilter;
-  }
+  //! @sa ShouldRender()
+  void SetRenderFilter (Standard_Integer theFilter) { myRenderFilter = theFilter; }
 
-  //! Get rendering filter.
-  //! @return filter instance.
-  inline const Handle(OpenGl_RenderFilter)& GetRenderFilter() const
-  {
-    return myRenderFilter;
-  }
+  //! Checks whether the element can be rendered or not.
+  //! @param theElement [in] the element to check
+  //! @return True if element can be rendered
+  bool ShouldRender (const OpenGl_Element* theElement);
+
+  //! Return the number of skipped transparent elements within active OpenGl_RenderFilter_OpaqueOnly filter.
+  //! @sa OpenGl_LayerList::Render()
+  Standard_Integer NbSkippedTransparentElements() { return myNbSkippedTranspElems; }
+
+  //! Reset skipped transparent elements counter.
+  //! @sa OpenGl_LayerList::Render()
+  void ResetSkippedCounter() { myNbSkippedTranspElems = 0; }
 
   //! @return applied view matrix.
   inline const OpenGl_Matrix* ViewMatrix() const { return ViewMatrix_applied; }
@@ -265,9 +231,6 @@ public:
   //! Returns face aspect for textured font rendering.
   const OpenGl_AspectFace& FontFaceAspect() const { return myFontFaceAspect; }
 
-  //! Returns capping algorithm rendering filter.
-  const Handle(OpenGl_CappingAlgoFilter)& DefaultCappingAlgoFilter() const { return myDefaultCappingAlgoFilter; }
-
   //! Returns face aspect for none culling mode.
   const OpenGl_AspectFace& NoneCulling() const { return myNoneCulling; }
 
@@ -287,14 +250,15 @@ protected: //! @name protected fields
   Handle(OpenGl_Context)           myGlContext;
   Standard_Boolean                 myUseZBuffer;
   Standard_Boolean                 myUseDepthWrite;
-  Handle(OpenGl_CappingAlgoFilter) myDefaultCappingAlgoFilter;
   OpenGl_AspectFace                myNoneCulling;
   OpenGl_AspectFace                myFrontCulling;
   OpenGl_AspectFace                myFontFaceAspect;
 
 protected: //! @name fields related to status
 
-  Handle(OpenGl_RenderFilter) myRenderFilter;
+  Standard_Integer myNbSkippedTranspElems; //!< counter of skipped transparent elements for OpenGl_LayerList two rendering passes method
+  Standard_Integer myRenderFilter;         //!< active filter for skipping rendering of elements by some criteria (multiple render passes)
+
   const OpenGl_AspectLine*   myAspectLineSet;
   const OpenGl_AspectFace*   myAspectFaceSet;
   Handle(Graphic3d_AspectFillArea3d) myAspectFaceApplied;
index 76b261b..f408ac3 100644 (file)
@@ -8539,6 +8539,49 @@ static int VClipPlane (Draw_Interpretor& theDi, Standard_Integer theArgsNb, cons
       aClipPlane->SetCappingMaterial (aMat);
       anArgIter += aNbParsed;
     }
+    else if ((aChangeArg == "-transparency"
+           || aChangeArg == "-transp")
+          && aNbChangeArgs >= 2)
+    {
+      TCollection_AsciiString aValStr (aChangeArgs[1]);
+      Handle(Graphic3d_AspectFillArea3d) anAspect = aClipPlane->CappingAspect();
+      if (aValStr.IsRealValue())
+      {
+        Graphic3d_MaterialAspect aMat = aClipPlane->CappingMaterial();
+        aMat.SetTransparency ((float )aValStr.RealValue());
+        anAspect->SetAlphaMode (Graphic3d_AlphaMode_BlendAuto);
+        aClipPlane->SetCappingMaterial (aMat);
+      }
+      else
+      {
+        aValStr.LowerCase();
+        Graphic3d_AlphaMode aMode = Graphic3d_AlphaMode_BlendAuto;
+        if (aValStr == "opaque")
+        {
+          aMode = Graphic3d_AlphaMode_Opaque;
+        }
+        else if (aValStr == "mask")
+        {
+          aMode = Graphic3d_AlphaMode_Mask;
+        }
+        else if (aValStr == "blend")
+        {
+          aMode = Graphic3d_AlphaMode_Blend;
+        }
+        else if (aValStr == "blendauto")
+        {
+          aMode = Graphic3d_AlphaMode_BlendAuto;
+        }
+        else
+        {
+          std::cout << "Syntax error at '" << aValStr << "'\n";
+          return 1;
+        }
+        anAspect->SetAlphaMode (aMode);
+        aClipPlane->SetCappingAspect (anAspect);
+      }
+      anArgIter += 1;
+    }
     else if (aChangeArg == "-texname"
           || aChangeArg == "texname")
     {
@@ -12367,7 +12410,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
       "\n\t\t:   [-set|-unset|-setOverrideGlobal [objects|views]]"
       "\n\t\t:   [-maxPlanes]"
       "\n\t\t:   [-capping {0|1}]"
-      "\n\t\t:     [-color R G B] [-hatch {on|off|ID}]"
+      "\n\t\t:     [-color R G B] [-transparency Value] [-hatch {on|off|ID}]"
       "\n\t\t:     [-texName Texture] [-texScale SX SY] [-texOrigin TX TY]"
       "\n\t\t:       [-texRotate Angle]"
       "\n\t\t:     [-useObjMaterial {0|1}] [-useObjTexture {0|1}]"
@@ -12383,6 +12426,7 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
       "\n\t\t: Capping options:"
       "\n\t\t:   -capping {off|on|0|1} turn capping on/off"
       "\n\t\t:   -color R G B          set capping color"
+      "\n\t\t:   -transparency Value   set capping transparency 0..1"
       "\n\t\t:   -texName Texture      set capping texture"
       "\n\t\t:   -texScale SX SY       set capping tex scale"
       "\n\t\t:   -texOrigin TX TY      set capping tex origin"
diff --git a/tests/bugs/vis/bug29874 b/tests/bugs/vis/bug29874
new file mode 100644 (file)
index 0000000..6e5f7db
--- /dev/null
@@ -0,0 +1,23 @@
+puts "============"
+puts "0029874: Visualization - capping plane transparency does not work"
+puts "============"
+puts ""
+
+pload MODELING VISUALIZATION
+box b1 -30 0  30 20 20 20
+box b2 -30 0   0 20 20 20
+box b3 -30 0 -30 20 20 20
+box b4 -30 0 -60 20 20 20
+vclear
+vinit View1
+vzbufftrihedron
+vdisplay -dispMode 1 b1 b2 b3 b4
+vviewparams -scale 12.7 -proj 0.6 -0.16 0.79 -up -0.65 0.5 0.58 -at -24 12.4 -1.1
+vaspects b1 b4 -setTransparency 0.5
+vaspects b2 -setColor RED
+vaspects b3 -setColor GREEN
+
+vclipplane pln1 -set b1 b2 -equation -0.707 0.707 0 -25 -capping on -useObjMaterial 1
+vclipplane pln2 -set b3 b4 -equation -0.707 0.707 0 -25 -capping on -color 0.5 0.5 0.9 -transparency 0.2
+
+vdump $imagedir/${casename}.png