Warnings on vc14 were eliminated
[occt.git] / src / OpenGl / OpenGl_Clipping.cxx
1 // Created on: 2013-09-05
2 // Created by: Anton POLETAEV
3 // Copyright (c) 2013-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
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.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <OpenGl_Clipping.hxx>
17
18 #include <OpenGl_GlCore11.hxx>
19 #include <OpenGl_Workspace.hxx>
20 #include <OpenGl_Context.hxx>
21
22 // =======================================================================
23 // function : OpenGl_ClippingIterator
24 // purpose  :
25 // =======================================================================
26 OpenGl_ClippingIterator::OpenGl_ClippingIterator (const OpenGl_Clipping& theClipping)
27 : myDisabled  (&theClipping.myDisabledPlanes),
28   myCurrIndex (1)
29 {
30   if (!theClipping.myPlanesGlobal.IsNull())
31   {
32     myIter1.Init (*theClipping.myPlanesGlobal);
33   }
34   if (!theClipping.myPlanesLocal.IsNull())
35   {
36     myIter2.Init (*theClipping.myPlanesLocal);
37   }
38 }
39
40 // =======================================================================
41 // function : OpenGl_ClippingState
42 // purpose  :
43 // =======================================================================
44 OpenGl_Clipping::OpenGl_Clipping ()
45 : myNbClipping (0),
46   myNbCapping  (0),
47   myNbDisabled (0)
48 {}
49
50 // =======================================================================
51 // function : Init
52 // purpose  :
53 // =======================================================================
54 void OpenGl_Clipping::Init (const Standard_Integer )
55 {
56   myPlanesGlobal.Nullify();
57   myPlanesLocal.Nullify();
58
59   myNbClipping = 0;
60   myNbCapping  = 0;
61   myNbDisabled = 0;
62 }
63
64 // =======================================================================
65 // function : Reset
66 // purpose  :
67 // =======================================================================
68 void OpenGl_Clipping::Reset (const Handle(OpenGl_Context)& theGlCtx,
69                              const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes)
70 {
71   const Standard_Integer aStartIndex = myPlanesGlobal.IsNull() ? 1 : myPlanesGlobal->Size() + 1;
72   remove (theGlCtx, myPlanesLocal,  aStartIndex);
73   remove (theGlCtx, myPlanesGlobal, 1);
74
75   myPlanesGlobal = thePlanes;
76   myPlanesLocal.Nullify();
77
78   add (theGlCtx, thePlanes, 1);
79   myNbDisabled = 0;
80
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.
85 }
86
87 // =======================================================================
88 // function : SetLocalPlanes
89 // purpose  :
90 // =======================================================================
91 void OpenGl_Clipping::SetLocalPlanes (const Handle(OpenGl_Context)& theGlCtx,
92                                       const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes)
93 {
94   const Standard_Integer aStartIndex = myPlanesGlobal.IsNull() ? 1 : myPlanesGlobal->Size() + 1;
95   remove (theGlCtx, myPlanesLocal, aStartIndex);
96
97   myPlanesLocal = thePlanes;
98
99   add (theGlCtx, thePlanes, aStartIndex);
100 }
101
102 // =======================================================================
103 // function : add
104 // purpose  :
105 // =======================================================================
106 void OpenGl_Clipping::add (const Handle(OpenGl_Context)& ,
107                            const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes,
108                            const Standard_Integer theStartIndex)
109 {
110   if (thePlanes.IsNull())
111   {
112     return;
113   }
114
115   Standard_Integer aPlaneId = theStartIndex;
116   for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*thePlanes); aPlaneIt.More(); aPlaneIt.Next(), ++aPlaneId)
117   {
118     const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
119     myDisabledPlanes.SetValue (aPlaneId, Standard_False); // automatically resizes the vector
120     if (!aPlane->IsOn())
121     {
122       continue;
123     }
124
125     if (aPlane->IsCapping())
126     {
127       ++myNbCapping;
128     }
129     else
130     {
131       ++myNbClipping;
132     }
133   }
134 }
135
136 // =======================================================================
137 // function : remove
138 // purpose  :
139 // =======================================================================
140 void OpenGl_Clipping::remove (const Handle(OpenGl_Context)& ,
141                               const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes,
142                               const Standard_Integer theStartIndex)
143 {
144   if (thePlanes.IsNull())
145   {
146     return;
147   }
148
149   Standard_Integer aPlaneIndex = theStartIndex;
150   for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*thePlanes); aPlaneIt.More(); aPlaneIt.Next(), ++aPlaneIndex)
151   {
152     const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
153     if (!aPlane->IsOn()
154      || myDisabledPlanes.Value (aPlaneIndex))
155     {
156       continue;
157     }
158
159     if (aPlane->IsCapping())
160     {
161       --myNbCapping;
162     }
163     else
164     {
165       --myNbClipping;
166     }
167   }
168 }
169
170 // =======================================================================
171 // function : SetEnabled
172 // purpose  :
173 // =======================================================================
174 Standard_Boolean OpenGl_Clipping::SetEnabled (const Handle(OpenGl_Context)&  ,
175                                               const OpenGl_ClippingIterator& thePlane,
176                                               const Standard_Boolean         theIsEnabled)
177 {
178   const Standard_Integer aPlaneIndex = thePlane.PlaneIndex();
179   Standard_Boolean& isDisabled = myDisabledPlanes.ChangeValue (aPlaneIndex);
180   if (isDisabled == !theIsEnabled)
181   {
182     return Standard_False;
183   }
184
185   isDisabled = !theIsEnabled;
186   if (thePlane.Value()->IsCapping())
187   {
188     myNbCapping += (theIsEnabled ? 1 : -1);
189   }
190   else
191   {
192     myNbClipping += (theIsEnabled ? 1 : -1);
193   }
194   myNbDisabled -= (theIsEnabled ? 1 : -1);
195   return Standard_True;
196 }
197
198 // =======================================================================
199 // function : RestoreDisabled
200 // purpose  :
201 // =======================================================================
202 void OpenGl_Clipping::RestoreDisabled (const Handle(OpenGl_Context)& )
203 {
204   if (myNbDisabled == 0)
205   {
206     return;
207   }
208
209   myNbDisabled = 0;
210   for (OpenGl_ClippingIterator aPlaneIter (*this); aPlaneIter.More(); aPlaneIter.Next())
211   {
212     Standard_Boolean& isDisabled = myDisabledPlanes.ChangeValue (aPlaneIter.PlaneIndex());
213     if (!isDisabled)
214     {
215       continue;
216     }
217
218     isDisabled = Standard_False;
219     const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIter.Value();
220     if (aPlane->IsCapping())
221     {
222       ++myNbCapping;
223     }
224     else
225     {
226       ++myNbClipping;
227     }
228   }
229 }
230
231 // =======================================================================
232 // function : DisableGlobal
233 // purpose  :
234 // =======================================================================
235 void OpenGl_Clipping::DisableGlobal (const Handle(OpenGl_Context)& theGlCtx)
236 {
237   for (OpenGl_ClippingIterator aPlaneIter (*this); aPlaneIter.More(); aPlaneIter.Next())
238   {
239     if (!aPlaneIter.IsGlobal())
240     {
241       // local planes always follow global ones in iterator
242       return;
243     }
244
245     SetEnabled (theGlCtx, aPlaneIter, Standard_False);
246   }
247 }
248
249 // =======================================================================
250 // function : DisableAllExcept
251 // purpose  :
252 // =======================================================================
253 void OpenGl_Clipping::DisableAllExcept (const Handle(OpenGl_Context)&  theGlCtx,
254                                         const OpenGl_ClippingIterator& thePlane)
255 {
256   for (OpenGl_ClippingIterator aPlaneIter (*this); aPlaneIter.More(); aPlaneIter.Next())
257   {
258     if (aPlaneIter.IsDisabled())
259     {
260       mySkipFilter.SetValue (aPlaneIter.PlaneIndex(), Standard_True);
261       continue;
262     }
263
264     const Standard_Boolean isOn = (aPlaneIter.PlaneIndex() == thePlane.PlaneIndex());
265     SetEnabled (theGlCtx, aPlaneIter, isOn);
266     mySkipFilter.SetValue (aPlaneIter.PlaneIndex(), Standard_False);
267   }
268 }
269
270 // =======================================================================
271 // function : EnableAllExcept
272 // purpose  :
273 // =======================================================================
274 void OpenGl_Clipping::EnableAllExcept (const Handle(OpenGl_Context)&  theGlCtx,
275                                        const OpenGl_ClippingIterator& thePlane)
276 {
277   for (OpenGl_ClippingIterator aPlaneIter (*this); aPlaneIter.More(); aPlaneIter.Next())
278   {
279     if (mySkipFilter.Value (aPlaneIter.PlaneIndex()))
280     {
281       continue;
282     }
283
284     const Standard_Boolean isOn = (aPlaneIter.PlaneIndex() != thePlane.PlaneIndex());
285     SetEnabled (theGlCtx, aPlaneIter, isOn);
286   }
287 }