0027816: Visualization - provide an API for overriding clipping planes list
authorkgv <kgv@opencascade.com>
Wed, 14 Sep 2016 10:44:47 +0000 (13:44 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 15 Sep 2016 09:09:20 +0000 (12:09 +0300)
Graphic3d_SequenceOfHClipPlane now inherits Standard_Transient.
PrsMgr_PresentableObject, Graphic3d_Structure, Graphic3d_CStructure,
V3d_View, OpenGl_View now manages the plane list by Handle.
The getters ::GetClipPlanes() has been removed,
setters taking non-handle ::SetClipPlanes() has been marked deprecated.

OpenGl_Structure::Render() and SelectMgr_ViewerSelector::checkOverlap()
now disable global (view) clipping planes for objects
with flags Graphic3d_TMF_TriedronPers and Graphic3d_TMF_2d
or with new flag Graphic3d_SequenceOfHClipPlane::ToOverrideGlobal().

OpenGl_Clipping now implements interface for managing clipping planes
without copying the sequences.
The filtering of duplicates is no more performed by OpenGl_Clipping
- application is responsible to not do this.
OpenGl_Clipping tries avoiding unnecessary allocations for managing
list of active planes.

MFC sample has been updated to use V3d_View::ClipPlanes() method.

27 files changed:
samples/mfc/standard/04_Viewer3d/src/ModelClippingDlg.cpp
src/Graphic3d/Graphic3d_CStructure.hxx
src/Graphic3d/Graphic3d_CView.hxx
src/Graphic3d/Graphic3d_SequenceOfHClipPlane.hxx
src/Graphic3d/Graphic3d_Structure.cxx
src/Graphic3d/Graphic3d_Structure.hxx
src/OpenGl/OpenGl_CappingAlgo.cxx
src/OpenGl/OpenGl_Clipping.cxx
src/OpenGl/OpenGl_Clipping.hxx
src/OpenGl/OpenGl_ShaderManager.cxx
src/OpenGl/OpenGl_Structure.cxx
src/OpenGl/OpenGl_View.hxx
src/OpenGl/OpenGl_View_Redraw.cxx
src/PrsMgr/FILES
src/PrsMgr/PrsMgr_PresentableObject.cxx
src/PrsMgr/PrsMgr_PresentableObject.hxx
src/PrsMgr/PrsMgr_PresentableObject.lxx [deleted file]
src/PrsMgr/PrsMgr_PresentationManager.cxx
src/SelectMgr/SelectMgr_BaseFrustum.hxx
src/SelectMgr/SelectMgr_RectangularFrustum.cxx
src/SelectMgr/SelectMgr_RectangularFrustum.hxx
src/SelectMgr/SelectMgr_SelectingVolumeManager.cxx
src/SelectMgr/SelectMgr_SelectingVolumeManager.hxx
src/SelectMgr/SelectMgr_ViewerSelector.cxx
src/StdSelect/StdSelect_ViewerSelector3d.cxx
src/V3d/V3d_View.hxx
src/V3d/V3d_View_2.cxx

index 86fd233..82138e4 100755 (executable)
@@ -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 "  }"
index 2c914e1..ae7bd33 100644 (file)
@@ -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:
 
index 3a04dfb..01f9a7a 100644 (file)
@@ -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.
index 57d3376..457e799 100755 (executable)
 #define _Graphic3d_SequenceOfHClipPlane_HeaderFile
 
 #include <NCollection_Sequence.hxx>
+#include <NCollection_Shared.hxx>
 #include <Graphic3d_ClipPlane.hxx>
 
-// CDL-header shortcut for sequence of graphical clipping planes.
-typedef NCollection_Sequence<Handle(Graphic3d_ClipPlane)> Graphic3d_SequenceOfHClipPlane;
+//! Class defining the sequence of clipping planes.
+class Graphic3d_SequenceOfHClipPlane : public Standard_Transient, public NCollection_Sequence<Handle(Graphic3d_ClipPlane)>
+{
+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
index d783b22..c08ed02 100644 (file)
@@ -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();
 }
index adf1efa..5bf3474 100644 (file)
@@ -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 <me>.
index 36862c1..f0bfb66 100755 (executable)
@@ -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);
index 4ff3772..da56cd4 100755 (executable)
 #include <OpenGl_Workspace.hxx>
 #include <OpenGl_Context.hxx>
 
-#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<Aspect_GenId> (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<Aspect_GenId> (1, theMaxPlanes);
 }
 
 // =======================================================================
-// function : add
+// function : Reset
 // purpose  :
 // =======================================================================
-void OpenGl_Clipping::add (const Handle(OpenGl_Context)&   theGlCtx,
-                           Graphic3d_SequenceOfHClipPlane& thePlanes)
+void OpenGl_Clipping::Reset (const Handle(OpenGl_Context)& theGlCtx,
+                             const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes)
 {
-  const bool toUseFfp = theGlCtx->core11 != NULL
-                     && theGlCtx->caps->ffpEnable;
-  if (!toUseFfp)
-  {
-    addLazy (theGlCtx, thePlanes);
-    return;
-  }
+  const Standard_Integer aStartIndex = myPlanesGlobal.IsNull() ? 1 : myPlanesGlobal->Size() + 1;
+  remove (theGlCtx, myPlanesLocal,  aStartIndex);
+  remove (theGlCtx, myPlanesGlobal, 1);
 
-  // Set either identity or pure view matrix.
-  theGlCtx->ApplyWorldViewMatrix();
+  myPlanesGlobal = thePlanes;
+  myPlanesLocal.Nullify();
 
-  addLazy (theGlCtx, thePlanes);
+  add (theGlCtx, thePlanes, 1);
+  myNbDisabled = 0;
 
-  // Restore combined model-view matrix.
-  theGlCtx->ApplyModelViewMatrix();
+  // 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 : addLazy
+// function : add
 // purpose  :
 // =======================================================================
-void OpenGl_Clipping::addLazy (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)
 {
+  if (thePlanes.IsNull())
+  {
+    return;
+  }
+
 #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,26 +152,30 @@ void OpenGl_Clipping::addLazy (const Handle(OpenGl_Context)&   theGlCtx,
     {
       ++myNbClipping;
     }
-
-    aPlaneIt.Next();
   }
 
-  if (!myEmptyPlaneIds->HasFree())
+#if !defined(GL_ES_VERSION_2_0)
+  // Restore combined model-view matrix.
+  if (toUseFfp)
   {
-    while (aPlaneIt.More())
-    {
-      thePlanes.Remove (aPlaneIt);
-    }
+    theGlCtx->ApplyModelViewMatrix();
   }
+#endif
 }
 
 // =======================================================================
-// function : Remove
+// function : remove
 // purpose  :
 // =======================================================================
-void OpenGl_Clipping::Remove (const Handle(OpenGl_Context)&         theGlCtx,
-                              const Graphic3d_SequenceOfHClipPlane& thePlanes)
+void OpenGl_Clipping::remove (const Handle(OpenGl_Context)& theGlCtx,
+                              const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes,
+                              const Standard_Integer theStartIndex)
 {
+  if (thePlanes.IsNull())
+  {
+    return;
+  }
+
 #if !defined(GL_ES_VERSION_2_0)
   const bool toUseFfp = theGlCtx->core11 != NULL
                      && theGlCtx->caps->ffpEnable;
@@ -143,86 +183,130 @@ void OpenGl_Clipping::Remove (const Handle(OpenGl_Context)&         theGlCtx,
   (void )theGlCtx;
 #endif
 
-  Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (thePlanes);
-  for (; aPlaneIt.More(); aPlaneIt.Next())
+  Standard_Integer aPlaneIndex = theStartIndex;
+  for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*thePlanes); aPlaneIt.More(); aPlaneIt.Next(), ++aPlaneIndex)
   {
     const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
-    PlaneProps* aProps = myPlaneStates.ChangeSeek (aPlane);
-    if (aProps == NULL)
+    if (!aPlane->IsOn()
+     || myDisabledPlanes.Value (aPlaneIndex))
     {
       continue;
     }
 
-    Standard_Integer anID = aProps->ContextID;
-    if (aProps->IsEnabled)
+  #if !defined(GL_ES_VERSION_2_0)
+    const Standard_Integer anFfpPlaneID = myEmptyPlaneIds->Lower() + aPlaneIndex - 1;
+    if (anFfpPlaneID <= myEmptyPlaneIds->Upper())
     {
-    #if !defined(GL_ES_VERSION_2_0)
       if (toUseFfp)
       {
-        ::glDisable ((GLenum)anID);
+        ::glDisable (GLenum(GL_CLIP_PLANE0 + anFfpPlaneID));
       }
-    #endif
-      if (aPlane->IsCapping())
+      myEmptyPlaneIds->Free (anFfpPlaneID);
+    }
+  #endif
+
+    if (aPlane->IsCapping())
+    {
+      --myNbCapping;
+    }
+    else
+    {
+      --myNbClipping;
+    }
+  }
+}
+
+// =======================================================================
+// 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)
       {
-        --myNbCapping;
+        ::glEnable (GLenum(GL_CLIP_PLANE0 + anFfpPlaneID));
       }
       else
       {
-        --myNbClipping;
+        ::glDisable (GLenum(GL_CLIP_PLANE0 + anFfpPlaneID));
       }
     }
-
-    myEmptyPlaneIds->Free (anID);
-    myPlaneStates.UnBind (aPlane);
   }
+#else
+  (void )theGlCtx;
+#endif
 
-  // renew collection of planes
-  aPlaneIt.Init (myPlanes);
-  while (aPlaneIt.More())
+  if (thePlane.Value()->IsCapping())
   {
-    const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
-    if (!myPlaneStates.IsBound (aPlane))
-    {
-      myPlanes.Remove (aPlaneIt);
-    }
-    else
-    {
-      aPlaneIt.Next();
-    }
+    myNbCapping += (theIsEnabled ? 1 : -1);
+  }
+  else
+  {
+    myNbClipping += (theIsEnabled ? 1 : -1);
   }
+  myNbDisabled -= (theIsEnabled ? 1 : -1);
+  return Standard_True;
 }
 
 // =======================================================================
-// function : SetEnabled
+// function : RestoreDisabled
 // purpose  :
 // =======================================================================
-void OpenGl_Clipping::SetEnabled (const Handle(OpenGl_Context)&      theGlCtx,
-                                  const Handle(Graphic3d_ClipPlane)& thePlane,
-                                  const Standard_Boolean             theIsEnabled)
+void OpenGl_Clipping::RestoreDisabled (const Handle(OpenGl_Context)& theGlCtx)
 {
-  PlaneProps* aProps = myPlaneStates.ChangeSeek (thePlane);
-  if (aProps == NULL
-   || aProps->IsEnabled == theIsEnabled)
+  if (myNbDisabled == 0)
   {
     return;
   }
 
+  myNbDisabled = 0;
 #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)
+  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)
     {
-      ::glEnable (anID);
+      const Standard_Integer anFfpPlaneID = myEmptyPlaneIds->Lower() + aPlaneIter.PlaneIndex() - 1;
+      if (anFfpPlaneID <= myEmptyPlaneIds->Upper())
+      {
+        ::glEnable (GLenum(GL_CLIP_PLANE0 + anFfpPlaneID));
+      }
     }
   #endif
-    if (thePlane->IsCapping())
+
+    const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIter.Value();
+    if (aPlane->IsCapping())
     {
       ++myNbCapping;
     }
@@ -231,23 +315,62 @@ void OpenGl_Clipping::SetEnabled (const Handle(OpenGl_Context)&      theGlCtx,
       ++myNbClipping;
     }
   }
-  else
+}
+
+// =======================================================================
+// function : DisableGlobal
+// purpose  :
+// =======================================================================
+void OpenGl_Clipping::DisableGlobal (const Handle(OpenGl_Context)& theGlCtx)
+{
+  for (OpenGl_ClippingIterator aPlaneIter (*this); aPlaneIter.More(); aPlaneIter.Next())
   {
-  #if !defined(GL_ES_VERSION_2_0)
-    if (toUseFfp)
+    if (!aPlaneIter.IsGlobal())
     {
-      ::glDisable (anID);
+      // local planes always follow global ones in iterator
+      return;
     }
-  #endif
-    if (thePlane->IsCapping())
+
+    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())
     {
-      --myNbCapping;
+      mySkipFilter.SetValue (aPlaneIter.PlaneIndex(), Standard_True);
+      continue;
     }
-    else
+
+    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()))
     {
-      --myNbClipping;
+      continue;
     }
-  }
 
-  aProps->IsEnabled = theIsEnabled;
+    const Standard_Boolean isOn = (aPlaneIter.PlaneIndex() != thePlane.PlaneIndex());
+    SetEnabled (theGlCtx, aPlaneIter, isOn);
+  }
 }
index 4a13ac2..0086887 100755 (executable)
 #define _OpenGl_Clipping_H__
 
 #include <Aspect_GenId.hxx>
-#include <Graphic3d_ClipPlane.hxx>
 #include <Graphic3d_SequenceOfHClipPlane.hxx>
-#include <NCollection_DataMap.hxx>
-#include <NCollection_Handle.hxx>
+#include <NCollection_Vector.hxx>
 #include <Standard_TypeDef.hxx>
-#include <OpenGl_Matrix.hxx>
 
 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 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);
 
-public: //! @name clipping state modification commands
+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);
+  Standard_EXPORT void remove (const Handle(OpenGl_Context)& theGlCtx,
+                               const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes,
+                               const Standard_Integer theStartIndex);
+
+private:
 
-  //! 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);
+  Handle(Graphic3d_SequenceOfHClipPlane)   myPlanesGlobal;   //!< global clipping planes
+  Handle(Graphic3d_SequenceOfHClipPlane)   myPlanesLocal;    //!< object clipping planes
+  NCollection_Vector<Standard_Boolean>     myDisabledPlanes; //!< ids of disabled planes
+  NCollection_Vector<Standard_Boolean>     mySkipFilter;     //!< ids of planes that were disabled before calling ::DisableAllExcept()
+  Handle(NCollection_Shared<Aspect_GenId>) 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
 
-public: //! @name Short-cuts
+private:
 
-  //! 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);
-  }
+  //! Copying allowed only within Handles
+  OpenGl_Clipping            (const OpenGl_Clipping& );
+  OpenGl_Clipping& operator= (const OpenGl_Clipping& );
 
-  //! Remove all of the planes from context state.
-  inline void RemoveAll (const Handle(OpenGl_Context)& theGlCtx)
-  {
-    Remove (theGlCtx, Planes());
-  }
+  friend class OpenGl_ClippingIterator;
+};
 
-private:
+//! The iterator through clipping planes.
+class OpenGl_ClippingIterator
+{
+public:
+
+  //! Main constructor.
+  Standard_EXPORT OpenGl_ClippingIterator(const OpenGl_Clipping& theClipping);
 
-  struct PlaneProps
+  //! 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()
   {
-    // declare default constructor
-    // to allow compilation of template collections
-    PlaneProps() {}
-    PlaneProps (const Standard_Integer theID,
-                const Standard_Boolean theIsEnabled)
+    ++myCurrIndex;
+    if (myIter1.More())
+    {
+      myIter1.Next();
+    }
+    else
     {
-      ContextID  = theID;
-      IsEnabled  = theIsEnabled;
+      myIter2.Next();
     }
+  }
 
-    Standard_Integer ContextID;
-    Standard_Boolean IsEnabled;
-  };
+  //! 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(); }
 
-private:
+  //! Return the plane at current iterator position.
+  const Handle(Graphic3d_ClipPlane)& Value() const
+  {
+    return myIter1.More()
+         ? myIter1.Value()
+         : myIter2.Value();
+  }
 
-  typedef NCollection_DataMap<Handle(Graphic3d_ClipPlane), PlaneProps> OpenGl_MapOfPlaneStates;
-  typedef NCollection_Handle<Aspect_GenId> OpenGl_EmptyPlaneIds;
+  //! Return true if plane from the global (view) list.
+  bool IsGlobal() const { return myIter1.More(); }
 
-  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
+  //! Return the plane index.
+  Standard_Integer PlaneIndex() const { return myCurrIndex; }
 
 private:
 
-  //! Copying allowed only within Handles
-  OpenGl_Clipping            (const OpenGl_Clipping& );
-  OpenGl_Clipping& operator= (const OpenGl_Clipping& );
+  Graphic3d_SequenceOfHClipPlane::Iterator myIter1;
+  Graphic3d_SequenceOfHClipPlane::Iterator myIter2;
+  const NCollection_Vector<Standard_Boolean>* myDisabled;
+  Standard_Integer myCurrIndex;
+
 };
 
 #endif
index 270c5e9..2af3565 100644 (file)
@@ -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);
 }
 
index cd7139c..2b1b9e3 100644 (file)
@@ -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<Graphic3d_SequenceOfHClipPlane>) 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<Graphic3d_SequenceOfHClipPlane>();
-      }
-      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;
-      }
+        const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
+        if (!aPlane->IsOn())
+        {
+          continue;
+        }
 
-      // 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())
+        // 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
         {
-          aDisabledPlanes = new NCollection_Shared<Graphic3d_SequenceOfHClipPlane>();
-          if (aUserPlanes.IsNull())
-          {
-            aCtx->ShaderManager()->UpdateClippingState();
-          }
+          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();
   }
index 49d4152..49f4d32 100644 (file)
@@ -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;
index 5985b03..dab7ad6 100644 (file)
@@ -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();
   }
index bcec430..fa76169 100644 (file)
@@ -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
index 93394da..c2ff8c8 100644 (file)
@@ -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;
-}
index ed16250..9b7a2ee 100644 (file)
@@ -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 <PrsMgr_PresentableObject.lxx>
-
-
-
-
-
 #endif // _PrsMgr_PresentableObject_HeaderFile
diff --git a/src/PrsMgr/PrsMgr_PresentableObject.lxx b/src/PrsMgr/PrsMgr_PresentableObject.lxx
deleted file mode 100644 (file)
index a3ea557..0000000
+++ /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;
-}
index 9511ad2..aa05bec 100644 (file)
@@ -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);
index 88398fa..0ba1df7 100644 (file)
@@ -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)
 
index 1745cb7..ac2291a 100644 (file)
@@ -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;
index 53fa3db..ecad0b8 100644 (file)
@@ -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
index fd1b058..087efe4 100644 (file)
@@ -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);
+}
index d06b5ef..427e194 100644 (file)
@@ -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;
index ee20923..0f162e9 100644 (file)
@@ -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())
-    {
-      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;
-      }
+    theMgr.SetViewClippingEnabled (Standard_True);
+  }
 
-      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
+  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)
+    {
+      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);
+  }
 }
 
 //=======================================================================
index 40ca4fa..67840be 100644 (file)
@@ -128,7 +128,7 @@ void StdSelect_ViewerSelector3d::Pick (const Standard_Integer theXPix,
   gp_Pnt2d aMousePos (static_cast<Standard_Real> (theXPix),
                       static_cast<Standard_Real> (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();
 }
 
 //=======================================================================
index 49195ca..5771859 100644 (file)
@@ -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;
index bfbd368..4a6ae4d 100644 (file)
@@ -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();
 }