0027961: Visualization - remove unused and no more working OpenGl_AVIWriter
[occt.git] / src / OpenGl / OpenGl_Clipping.cxx
index aa27efa..da56cd4 100755 (executable)
@@ -1,11 +1,11 @@
 // Created on: 2013-09-05
 // Created by: Anton POLETAEV
-// Copyright (c) 2013 OPEN CASCADE SAS
+// Copyright (c) 2013-2014 OPEN CASCADE SAS
 //
 // This file is part of Open CASCADE Technology software library.
 //
-// This library is free software; you can redistribute it and / or modify it
-// under the terms of the GNU Lesser General Public version 2.1 as published
+// 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.
 // commercial license or contractual agreement.
 
 #include <OpenGl_Clipping.hxx>
+
 #include <OpenGl_GlCore11.hxx>
 #include <OpenGl_Workspace.hxx>
+#include <OpenGl_Context.hxx>
 
-namespace
+// =======================================================================
+// function : OpenGl_ClippingIterator
+// purpose  :
+// =======================================================================
+OpenGl_ClippingIterator::OpenGl_ClippingIterator (const OpenGl_Clipping& theClipping)
+: myDisabled  (&theClipping.myDisabledPlanes),
+  myCurrIndex (1)
 {
-  static const GLdouble OpenGl_DefaultPlaneEq[] = {0.0, 0.0, 0.0, 0.0};
-};
+  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_PLANE5)),
+: myEmptyPlaneIds (new NCollection_Shared<Aspect_GenId> (1, 6)),
   myNbClipping (0),
-  myNbCapping  (0)
+  myNbCapping  (0),
+  myNbDisabled (0)
 {}
 
 // =======================================================================
@@ -38,74 +54,96 @@ 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 (Graphic3d_SequenceOfHClipPlane& thePlanes,
-                           const EquationCoords& theCoordSpace,
-                           const Handle(OpenGl_Workspace)& theWS)
+void OpenGl_Clipping::Reset (const Handle(OpenGl_Context)& theGlCtx,
+                             const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes)
 {
-  GLint aMatrixMode;
-  glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
+  const Standard_Integer aStartIndex = myPlanesGlobal.IsNull() ? 1 : myPlanesGlobal->Size() + 1;
+  remove (theGlCtx, myPlanesLocal,  aStartIndex);
+  remove (theGlCtx, myPlanesGlobal, 1);
 
-  OpenGl_Matrix aCurrentMx;
-  glGetFloatv (GL_MODELVIEW_MATRIX, (GLfloat*) &aCurrentMx);
+  myPlanesGlobal = thePlanes;
+  myPlanesLocal.Nullify();
 
-  if (aMatrixMode != GL_MODELVIEW)
-  {
-    glMatrixMode (GL_MODELVIEW);
-  }
+  add (theGlCtx, thePlanes, 1);
+  myNbDisabled = 0;
 
-  switch (theCoordSpace)
-  {
-    case EquationCoords_View:  glLoadMatrixf ((const GLfloat*) &OpenGl_IdentityMatrix); break;
-    case EquationCoords_World: glLoadMatrixf ((const GLfloat*) theWS->ViewMatrix());    break;
-  }
+  // 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.
+}
 
-  Add (thePlanes, theCoordSpace);
+// =======================================================================
+// 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);
 
-  // restore model-view matrix
-  glLoadMatrixf ((GLfloat*) &aCurrentMx);
+  myPlanesLocal = thePlanes;
 
-  // restore context matrix state
-  if (aMatrixMode != GL_MODELVIEW)
-  {
-    glMatrixMode (aMatrixMode);
-  }
+  add (theGlCtx, thePlanes, aStartIndex);
 }
 
 // =======================================================================
-// function : Add
+// function : add
 // purpose  :
 // =======================================================================
-void OpenGl_Clipping::Add (Graphic3d_SequenceOfHClipPlane& thePlanes, const EquationCoords& theCoordSpace)
+void OpenGl_Clipping::add (const Handle(OpenGl_Context)& theGlCtx,
+                           const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes,
+                           const Standard_Integer theStartIndex)
 {
-  Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (thePlanes);
-  while (aPlaneIt.More() && myEmptyPlaneIds->Available() > 0)
+  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
+
+  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 (theCoordSpace, anID, Standard_True));
-
-    glEnable ((GLenum)anID);
-    glClipPlane ((GLenum)anID, aPlane->GetEquation());
+  #if !defined(GL_ES_VERSION_2_0)
+    if (toUseFfp && myEmptyPlaneIds->HasFree())
+    {
+      const Standard_Integer anFfpPlaneID = GL_CLIP_PLANE0 + myEmptyPlaneIds->Next();
+      ::glEnable ((GLenum )anFfpPlaneID);
+      theGlCtx->core11->glClipPlane ((GLenum )anFfpPlaneID, aPlane->GetEquation());
+    }
+  #endif
     if (aPlane->IsCapping())
     {
       ++myNbCapping;
@@ -114,62 +152,66 @@ void OpenGl_Clipping::Add (Graphic3d_SequenceOfHClipPlane& thePlanes, const Equa
     {
       ++myNbClipping;
     }
-
-    aPlaneIt.Next();
   }
 
-  while (aPlaneIt.More() && myEmptyPlaneIds->Available() == 0)
+#if !defined(GL_ES_VERSION_2_0)
+  // Restore combined model-view matrix.
+  if (toUseFfp)
   {
-    thePlanes.Remove (aPlaneIt);
+    theGlCtx->ApplyModelViewMatrix();
   }
+#endif
 }
 
 // =======================================================================
-// function : Remove
+// function : remove
 // purpose  :
 // =======================================================================
-void OpenGl_Clipping::Remove (const Graphic3d_SequenceOfHClipPlane& thePlanes)
+void OpenGl_Clipping::remove (const Handle(OpenGl_Context)& theGlCtx,
+                              const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes,
+                              const Standard_Integer theStartIndex)
 {
-  Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (thePlanes);
-  for (; aPlaneIt.More(); aPlaneIt.Next())
+  if (thePlanes.IsNull())
+  {
+    return;
+  }
+
+#if !defined(GL_ES_VERSION_2_0)
+  const bool toUseFfp = theGlCtx->core11 != NULL
+                     && theGlCtx->caps->ffpEnable;
+#else
+  (void )theGlCtx;
+#endif
+
+  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())
     {
-      glDisable ((GLenum)anID);
-      if (aPlane->IsCapping())
+      if (toUseFfp)
       {
-        --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;
     }
   }
 }
@@ -178,25 +220,93 @@ void OpenGl_Clipping::Remove (const Graphic3d_SequenceOfHClipPlane& thePlanes)
 // function : SetEnabled
 // purpose  :
 // =======================================================================
-void OpenGl_Clipping::SetEnabled (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;
+  }
+
+  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;
+}
 
-  PlaneProps& aProps = myPlaneStates.ChangeFind (thePlane);
-  if (theIsEnabled == aProps.IsEnabled)
+// =======================================================================
+// function : RestoreDisabled
+// purpose  :
+// =======================================================================
+void OpenGl_Clipping::RestoreDisabled (const Handle(OpenGl_Context)& theGlCtx)
+{
+  if (myNbDisabled == 0)
   {
     return;
   }
 
-  GLenum anID = (GLenum)aProps.ContextID;
-  if (theIsEnabled)
+  myNbDisabled = 0;
+#if !defined(GL_ES_VERSION_2_0)
+  const bool toUseFfp = theGlCtx->core11 != NULL
+                     && theGlCtx->caps->ffpEnable;
+#else
+  (void )theGlCtx;
+#endif
+  for (OpenGl_ClippingIterator aPlaneIter (*this); aPlaneIter.More(); aPlaneIter.Next())
   {
-    glEnable (anID);
-    if (thePlane->IsCapping())
+    Standard_Boolean& isDisabled = myDisabledPlanes.ChangeValue (aPlaneIter.PlaneIndex());
+    if (!isDisabled)
+    {
+      continue;
+    }
+
+    isDisabled = Standard_False;
+  #if !defined(GL_ES_VERSION_2_0)
+    if (toUseFfp)
+    {
+      const Standard_Integer anFfpPlaneID = myEmptyPlaneIds->Lower() + aPlaneIter.PlaneIndex() - 1;
+      if (anFfpPlaneID <= myEmptyPlaneIds->Upper())
+      {
+        ::glEnable (GLenum(GL_CLIP_PLANE0 + anFfpPlaneID));
+      }
+    }
+  #endif
+
+    const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIter.Value();
+    if (aPlane->IsCapping())
     {
       ++myNbCapping;
     }
@@ -205,18 +315,62 @@ void OpenGl_Clipping::SetEnabled (const Handle(Graphic3d_ClipPlane)& thePlane,
       ++myNbClipping;
     }
   }
-  else
+}
+
+// =======================================================================
+// function : DisableGlobal
+// purpose  :
+// =======================================================================
+void OpenGl_Clipping::DisableGlobal (const Handle(OpenGl_Context)& theGlCtx)
+{
+  for (OpenGl_ClippingIterator aPlaneIter (*this); aPlaneIter.More(); aPlaneIter.Next())
   {
-    glDisable (anID);
-    if (thePlane->IsCapping())
+    if (!aPlaneIter.IsGlobal())
     {
-      --myNbCapping;
+      // local planes always follow global ones in iterator
+      return;
     }
-    else
+
+    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())
     {
-      --myNbClipping;
+      mySkipFilter.SetValue (aPlaneIter.PlaneIndex(), Standard_True);
+      continue;
     }
+
+    const Standard_Boolean isOn = (aPlaneIter.PlaneIndex() == thePlane.PlaneIndex());
+    SetEnabled (theGlCtx, aPlaneIter, isOn);
+    mySkipFilter.SetValue (aPlaneIter.PlaneIndex(), Standard_False);
   }
+}
+
+// =======================================================================
+// function : EnableAllExcept
+// purpose  :
+// =======================================================================
+void OpenGl_Clipping::EnableAllExcept (const Handle(OpenGl_Context)&  theGlCtx,
+                                       const OpenGl_ClippingIterator& thePlane)
+{
+  for (OpenGl_ClippingIterator aPlaneIter (*this); aPlaneIter.More(); aPlaneIter.Next())
+  {
+    if (mySkipFilter.Value (aPlaneIter.PlaneIndex()))
+    {
+      continue;
+    }
 
-  aProps.IsEnabled = theIsEnabled;
+    const Standard_Boolean isOn = (aPlaneIter.PlaneIndex() != thePlane.PlaneIndex());
+    SetEnabled (theGlCtx, aPlaneIter, isOn);
+  }
 }