1 // Created on: 2013-09-05
2 // Created by: Anton POLETAEV
3 // Copyright (c) 2013-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <OpenGl_Clipping.hxx>
18 #include <OpenGl_GlCore11.hxx>
19 #include <OpenGl_Workspace.hxx>
20 #include <OpenGl_Context.hxx>
22 // =======================================================================
23 // function : OpenGl_ClippingIterator
25 // =======================================================================
26 OpenGl_ClippingIterator::OpenGl_ClippingIterator (const OpenGl_Clipping& theClipping)
27 : myDisabled (&theClipping.myDisabledPlanes),
30 if (!theClipping.myPlanesGlobal.IsNull())
32 myIter1.Init (*theClipping.myPlanesGlobal);
34 if (!theClipping.myPlanesLocal.IsNull())
36 myIter2.Init (*theClipping.myPlanesLocal);
40 // =======================================================================
41 // function : OpenGl_ClippingState
43 // =======================================================================
44 OpenGl_Clipping::OpenGl_Clipping ()
50 // =======================================================================
53 // =======================================================================
54 void OpenGl_Clipping::Init (const Standard_Integer )
56 myPlanesGlobal.Nullify();
57 myPlanesLocal.Nullify();
64 // =======================================================================
67 // =======================================================================
68 void OpenGl_Clipping::Reset (const Handle(OpenGl_Context)& theGlCtx,
69 const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes)
71 const Standard_Integer aStartIndex = myPlanesGlobal.IsNull() ? 1 : myPlanesGlobal->Size() + 1;
72 remove (theGlCtx, myPlanesLocal, aStartIndex);
73 remove (theGlCtx, myPlanesGlobal, 1);
75 myPlanesGlobal = thePlanes;
76 myPlanesLocal.Nullify();
78 add (theGlCtx, thePlanes, 1);
81 // Method ::add() implicitly extends myDisabledPlanes (NCollection_Vector::SetValue()),
82 // however we do not reset myDisabledPlanes and mySkipFilter beforehand to avoid redundant memory re-allocations.
83 // So once extended, they will never reduce their size to lower values.
84 // This should not be a problem since overall number of clipping planes is expected to be quite small.
87 // =======================================================================
88 // function : SetLocalPlanes
90 // =======================================================================
91 void OpenGl_Clipping::SetLocalPlanes (const Handle(OpenGl_Context)& theGlCtx,
92 const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes)
94 const Standard_Integer aStartIndex = myPlanesGlobal.IsNull() ? 1 : myPlanesGlobal->Size() + 1;
95 remove (theGlCtx, myPlanesLocal, aStartIndex);
97 myPlanesLocal = thePlanes;
99 add (theGlCtx, thePlanes, aStartIndex);
102 // =======================================================================
105 // =======================================================================
106 void OpenGl_Clipping::add (const Handle(OpenGl_Context)& ,
107 const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes,
108 const Standard_Integer theStartIndex)
110 if (thePlanes.IsNull())
115 Standard_Integer aPlaneId = theStartIndex;
116 for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*thePlanes); aPlaneIt.More(); aPlaneIt.Next(), ++aPlaneId)
118 const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
119 myDisabledPlanes.SetValue (aPlaneId, Standard_False); // automatically resizes the vector
125 if (aPlane->IsCapping())
136 // =======================================================================
139 // =======================================================================
140 void OpenGl_Clipping::remove (const Handle(OpenGl_Context)& ,
141 const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes,
142 const Standard_Integer theStartIndex)
144 if (thePlanes.IsNull())
149 Standard_Integer aPlaneIndex = theStartIndex;
150 for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*thePlanes); aPlaneIt.More(); aPlaneIt.Next(), ++aPlaneIndex)
152 const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
154 || myDisabledPlanes.Value (aPlaneIndex))
159 if (aPlane->IsCapping())
170 // =======================================================================
171 // function : SetEnabled
173 // =======================================================================
174 Standard_Boolean OpenGl_Clipping::SetEnabled (const Handle(OpenGl_Context)& ,
175 const OpenGl_ClippingIterator& thePlane,
176 const Standard_Boolean theIsEnabled)
178 const Standard_Integer aPlaneIndex = thePlane.PlaneIndex();
179 Standard_Boolean& isDisabled = myDisabledPlanes.ChangeValue (aPlaneIndex);
180 if (isDisabled == !theIsEnabled)
182 return Standard_False;
185 isDisabled = !theIsEnabled;
186 if (thePlane.Value()->IsCapping())
188 myNbCapping += (theIsEnabled ? 1 : -1);
192 myNbClipping += (theIsEnabled ? 1 : -1);
194 myNbDisabled -= (theIsEnabled ? 1 : -1);
195 return Standard_True;
198 // =======================================================================
199 // function : RestoreDisabled
201 // =======================================================================
202 void OpenGl_Clipping::RestoreDisabled (const Handle(OpenGl_Context)& )
204 if (myNbDisabled == 0)
210 for (OpenGl_ClippingIterator aPlaneIter (*this); aPlaneIter.More(); aPlaneIter.Next())
212 Standard_Boolean& isDisabled = myDisabledPlanes.ChangeValue (aPlaneIter.PlaneIndex());
218 isDisabled = Standard_False;
219 const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIter.Value();
220 if (aPlane->IsCapping())
231 // =======================================================================
232 // function : DisableGlobal
234 // =======================================================================
235 void OpenGl_Clipping::DisableGlobal (const Handle(OpenGl_Context)& theGlCtx)
237 for (OpenGl_ClippingIterator aPlaneIter (*this); aPlaneIter.More(); aPlaneIter.Next())
239 if (!aPlaneIter.IsGlobal())
241 // local planes always follow global ones in iterator
245 SetEnabled (theGlCtx, aPlaneIter, Standard_False);
249 // =======================================================================
250 // function : DisableAllExcept
252 // =======================================================================
253 void OpenGl_Clipping::DisableAllExcept (const Handle(OpenGl_Context)& theGlCtx,
254 const OpenGl_ClippingIterator& thePlane)
256 for (OpenGl_ClippingIterator aPlaneIter (*this); aPlaneIter.More(); aPlaneIter.Next())
258 if (aPlaneIter.IsDisabled())
260 mySkipFilter.SetValue (aPlaneIter.PlaneIndex(), Standard_True);
264 const Standard_Boolean isOn = (aPlaneIter.PlaneIndex() == thePlane.PlaneIndex());
265 SetEnabled (theGlCtx, aPlaneIter, isOn);
266 mySkipFilter.SetValue (aPlaneIter.PlaneIndex(), Standard_False);
270 // =======================================================================
271 // function : EnableAllExcept
273 // =======================================================================
274 void OpenGl_Clipping::EnableAllExcept (const Handle(OpenGl_Context)& theGlCtx,
275 const OpenGl_ClippingIterator& thePlane)
277 for (OpenGl_ClippingIterator aPlaneIter (*this); aPlaneIter.More(); aPlaneIter.Next())
279 if (mySkipFilter.Value (aPlaneIter.PlaneIndex()))
284 const Standard_Boolean isOn = (aPlaneIter.PlaneIndex() != thePlane.PlaneIndex());
285 SetEnabled (theGlCtx, aPlaneIter, isOn);