0027961: Visualization - remove unused and no more working OpenGl_AVIWriter
[occt.git] / src / OpenGl / OpenGl_Clipping.cxx
index 25398dc..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,51 +183,35 @@ 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();
-    if (!Contains (aPlane))
+    if (!aPlane->IsOn()
+     || myDisabledPlanes.Value (aPlaneIndex))
     {
       continue;
     }
 
-    Standard_Integer anID = myPlaneStates.Find (aPlane).ContextID;
-    PlaneProps& aProps = myPlaneStates.ChangeFind (aPlane);
-    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);
-      }
-    #endif
-      if (aPlane->IsCapping())
-      {
-        --myNbCapping;
-      }
-      else
-      {
-        --myNbClipping;
+        ::glDisable (GLenum(GL_CLIP_PLANE0 + anFfpPlaneID));
       }
+      myEmptyPlaneIds->Free (anFfpPlaneID);
     }
+  #endif
 
-    myEmptyPlaneIds->Free (anID);
-    myPlaneStates.UnBind (aPlane);
-  }
-
-  // renew collection of planes
-  aPlaneIt.Init (myPlanes);
-  while (aPlaneIt.More())
-  {
-    const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
-    if (!myPlaneStates.IsBound (aPlane))
+    if (aPlane->IsCapping())
     {
-      myPlanes.Remove (aPlaneIt);
+      --myNbCapping;
     }
     else
     {
-      aPlaneIt.Next();
+      --myNbClipping;
     }
   }
 }
@@ -196,37 +220,93 @@ void OpenGl_Clipping::Remove (const Handle(OpenGl_Context)&         theGlCtx,
 // function : SetEnabled
 // purpose  :
 // =======================================================================
-void OpenGl_Clipping::SetEnabled (const Handle(OpenGl_Context)&      theGlCtx,
-                                  const Handle(Graphic3d_ClipPlane)& thePlane,
-                                  const Standard_Boolean             theIsEnabled)
+Standard_Boolean OpenGl_Clipping::SetEnabled (const Handle(OpenGl_Context)&  theGlCtx,
+                                              const OpenGl_ClippingIterator& thePlane,
+                                              const Standard_Boolean         theIsEnabled)
 {
-  if (!Contains (thePlane))
+  const Standard_Integer aPlaneIndex = thePlane.PlaneIndex();
+  Standard_Boolean& isDisabled = myDisabledPlanes.ChangeValue (aPlaneIndex);
+  if (isDisabled == !theIsEnabled)
   {
-    return;
+    return Standard_False;
   }
 
-  PlaneProps& aProps = myPlaneStates.ChangeFind (thePlane);
-  if (theIsEnabled == aProps.IsEnabled)
+  isDisabled = !theIsEnabled;
+
+#if !defined(GL_ES_VERSION_2_0)
+  const bool toUseFfp = theGlCtx->core11 != NULL
+                     && theGlCtx->caps->ffpEnable;
+  if (toUseFfp)
+  {
+    const Standard_Integer anFfpPlaneID = myEmptyPlaneIds->Lower() + aPlaneIndex - 1;
+    if (anFfpPlaneID <= myEmptyPlaneIds->Upper())
+    {
+      if (theIsEnabled)
+      {
+        ::glEnable (GLenum(GL_CLIP_PLANE0 + anFfpPlaneID));
+      }
+      else
+      {
+        ::glDisable (GLenum(GL_CLIP_PLANE0 + anFfpPlaneID));
+      }
+    }
+  }
+#else
+  (void )theGlCtx;
+#endif
+
+  if (thePlane.Value()->IsCapping())
+  {
+    myNbCapping += (theIsEnabled ? 1 : -1);
+  }
+  else
+  {
+    myNbClipping += (theIsEnabled ? 1 : -1);
+  }
+  myNbDisabled -= (theIsEnabled ? 1 : -1);
+  return Standard_True;
+}
+
+// =======================================================================
+// function : RestoreDisabled
+// purpose  :
+// =======================================================================
+void OpenGl_Clipping::RestoreDisabled (const Handle(OpenGl_Context)& theGlCtx)
+{
+  if (myNbDisabled == 0)
   {
     return;
   }
 
+  myNbDisabled = 0;
 #if !defined(GL_ES_VERSION_2_0)
-  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;
     }
@@ -235,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);
+  }
 }