// commercial license or contractual agreement.
#include <OpenGl_Clipping.hxx>
-#include <OpenGl_GlCore11.hxx>
-#include <OpenGl_Workspace.hxx>
+
+#include <OpenGl_ClippingIterator.hxx>
// =======================================================================
-// function : OpenGl_ClippingState
+// function : OpenGl_Clipping
// purpose :
// =======================================================================
-OpenGl_Clipping::OpenGl_Clipping ()
-: myEmptyPlaneIds (new Aspect_GenId (GL_CLIP_PLANE0, GL_CLIP_PLANE5)),
+OpenGl_Clipping::OpenGl_Clipping()
+: myCappedSubPlane (0),
myNbClipping (0),
- myNbCapping (0)
+ myNbCapping (0),
+ myNbChains (0),
+ myNbDisabled (0)
{}
// =======================================================================
// function : Init
// purpose :
// =======================================================================
-void OpenGl_Clipping::Init (const Standard_Integer theMaxPlanes)
+void OpenGl_Clipping::Init()
{
- 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);
+ myNbChains = 0;
+ myNbDisabled = 0;
+ myCappedSubPlane = 0;
+ myCappedChain.Nullify();
}
// =======================================================================
-// 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(Graphic3d_SequenceOfHClipPlane)& thePlanes)
{
- GLint aMatrixMode;
- glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
+ const Standard_Integer aStartIndex = myPlanesGlobal.IsNull() ? 1 : myPlanesGlobal->Size() + 1;
+ remove (myPlanesLocal, aStartIndex);
+ remove (myPlanesGlobal, 1);
- OpenGl_Matrix aCurrentMx;
- glGetFloatv (GL_MODELVIEW_MATRIX, (GLfloat*) &aCurrentMx);
+ myPlanesGlobal = thePlanes;
+ myPlanesLocal.Nullify();
- if (aMatrixMode != GL_MODELVIEW)
- {
- glMatrixMode (GL_MODELVIEW);
- }
+ add (thePlanes, 1);
+ myNbDisabled = 0;
+ myCappedSubPlane = 0;
+ myCappedChain.Nullify();
- 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(Graphic3d_SequenceOfHClipPlane)& thePlanes)
+{
+ const Standard_Integer aStartIndex = myPlanesGlobal.IsNull() ? 1 : myPlanesGlobal->Size() + 1;
+ remove (myPlanesLocal, aStartIndex);
- // restore model-view matrix
- glLoadMatrixf ((GLfloat*) &aCurrentMx);
+ myPlanesLocal = thePlanes;
- // restore context matrix state
- if (aMatrixMode != GL_MODELVIEW)
- {
- glMatrixMode (aMatrixMode);
- }
+ add (thePlanes, aStartIndex);
}
// =======================================================================
-// function : Add
+// function : add
// purpose :
// =======================================================================
-void OpenGl_Clipping::Add (Graphic3d_SequenceOfHClipPlane& thePlanes, const EquationCoords& theCoordSpace)
+void OpenGl_Clipping::add (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes,
+ const Standard_Integer theStartIndex)
{
- Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (thePlanes);
- while (aPlaneIt.More() && myEmptyPlaneIds->HasFree())
+ if (thePlanes.IsNull())
+ {
+ return;
+ }
+
+ 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());
+ const Standard_Integer aNbSubPlanes = aPlane->NbChainNextPlanes();
+ myNbChains += 1;
if (aPlane->IsCapping())
{
- ++myNbCapping;
+ myNbCapping += aNbSubPlanes;
}
else
{
- ++myNbClipping;
- }
-
- aPlaneIt.Next();
- }
-
- if (!myEmptyPlaneIds->HasFree())
- {
- while (aPlaneIt.More())
- {
- thePlanes.Remove (aPlaneIt);
+ myNbClipping += aNbSubPlanes;
}
}
}
// =======================================================================
-// function : Remove
+// function : remove
// purpose :
// =======================================================================
-void OpenGl_Clipping::Remove (const Graphic3d_SequenceOfHClipPlane& thePlanes)
+void OpenGl_Clipping::remove (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes,
+ const Standard_Integer theStartIndex)
{
- Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (thePlanes);
- for (; aPlaneIt.More(); aPlaneIt.Next())
+ if (thePlanes.IsNull())
+ {
+ return;
+ }
+
+ 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)
- {
- glDisable ((GLenum)anID);
- if (aPlane->IsCapping())
- {
- --myNbCapping;
- }
- else
- {
- --myNbClipping;
- }
- }
-
- 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))
+ const Standard_Integer aNbSubPlanes = aPlane->NbChainNextPlanes();
+ myNbChains -= 1;
+ if (aPlane->IsCapping())
{
- myPlanes.Remove (aPlaneIt);
+ myNbCapping -= aNbSubPlanes;
}
else
{
- aPlaneIt.Next();
+ myNbClipping -= aNbSubPlanes;
}
}
}
// function : SetEnabled
// purpose :
// =======================================================================
-void OpenGl_Clipping::SetEnabled (const Handle(Graphic3d_ClipPlane)& thePlane,
- const Standard_Boolean theIsEnabled)
+Standard_Boolean OpenGl_Clipping::SetEnabled (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;
+ const Standard_Integer aNbSubPlanes = thePlane.Value()->NbChainNextPlanes();
+ if (thePlane.Value()->IsCapping())
+ {
+ myNbCapping += (theIsEnabled ? aNbSubPlanes : -aNbSubPlanes);
+ }
+ else
+ {
+ myNbClipping += (theIsEnabled ? aNbSubPlanes : -aNbSubPlanes);
+ }
+ myNbChains += (theIsEnabled ? 1 : -1);
+ myNbDisabled += (theIsEnabled ? -aNbSubPlanes : aNbSubPlanes);
+ return Standard_True;
+}
+
+// =======================================================================
+// function : RestoreDisabled
+// purpose :
+// =======================================================================
+void OpenGl_Clipping::RestoreDisabled()
+{
+ if (myNbDisabled == 0)
{
return;
}
- GLenum anID = (GLenum)aProps.ContextID;
- if (theIsEnabled)
+ myNbDisabled = 0;
+ 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;
+ const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIter.Value();
+ const Standard_Integer aNbSubPlanes = aPlane->NbChainNextPlanes();
+ myNbChains += 1;
+ if (aPlane->IsCapping())
{
- ++myNbCapping;
+ myNbCapping += aNbSubPlanes;
}
else
{
- ++myNbClipping;
+ myNbClipping += aNbSubPlanes;
}
}
- else
+}
+
+// =======================================================================
+// function : DisableGlobal
+// purpose :
+// =======================================================================
+void OpenGl_Clipping::DisableGlobal()
+{
+ for (OpenGl_ClippingIterator aPlaneIter (*this); aPlaneIter.More(); aPlaneIter.Next())
{
- glDisable (anID);
- if (thePlane->IsCapping())
- {
- --myNbCapping;
- }
- else
+ if (!aPlaneIter.IsGlobal())
{
- --myNbClipping;
+ // local planes always follow global ones in iterator
+ return;
}
+
+ SetEnabled (aPlaneIter, Standard_False);
}
+}
+
+// =======================================================================
+// function : DisableAllExcept
+// purpose :
+// =======================================================================
+void OpenGl_Clipping::DisableAllExcept (const Handle(Graphic3d_ClipPlane)& theChain,
+ const Standard_Integer theSubPlaneIndex)
+{
+ myCappedChain = theChain;
+ myCappedSubPlane = theSubPlaneIndex;
+}
- aProps.IsEnabled = theIsEnabled;
+// =======================================================================
+// function : EnableAllExcept
+// purpose :
+// =======================================================================
+void OpenGl_Clipping::EnableAllExcept (const Handle(Graphic3d_ClipPlane)& theChain,
+ const Standard_Integer theSubPlaneIndex)
+{
+ myCappedChain = theChain;
+ myCappedSubPlane = -theSubPlaneIndex;
+}
+
+// =======================================================================
+// function : ResetCappingFilter
+// purpose :
+// =======================================================================
+void OpenGl_Clipping::ResetCappingFilter()
+{
+ myCappedChain.Nullify();
+ myCappedSubPlane = 0;
}