0030748: Visualization - Marker displayed in immediate layer ruins QT Quick view...
[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_ClippingIterator.hxx>
19
20 // =======================================================================
21 // function : OpenGl_Clipping
22 // purpose  :
23 // =======================================================================
24 OpenGl_Clipping::OpenGl_Clipping()
25 : myCappedSubPlane (0),
26   myNbClipping (0),
27   myNbCapping  (0),
28   myNbChains   (0),
29   myNbDisabled (0)
30 {}
31
32 // =======================================================================
33 // function : Init
34 // purpose  :
35 // =======================================================================
36 void OpenGl_Clipping::Init()
37 {
38   myPlanesGlobal.Nullify();
39   myPlanesLocal.Nullify();
40
41   myNbClipping = 0;
42   myNbCapping  = 0;
43   myNbChains   = 0;
44   myNbDisabled = 0;
45   myCappedSubPlane = 0;
46   myCappedChain.Nullify();
47 }
48
49 // =======================================================================
50 // function : Reset
51 // purpose  :
52 // =======================================================================
53 void OpenGl_Clipping::Reset (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes)
54 {
55   const Standard_Integer aStartIndex = myPlanesGlobal.IsNull() ? 1 : myPlanesGlobal->Size() + 1;
56   remove (myPlanesLocal,  aStartIndex);
57   remove (myPlanesGlobal, 1);
58
59   myPlanesGlobal = thePlanes;
60   myPlanesLocal.Nullify();
61
62   add (thePlanes, 1);
63   myNbDisabled = 0;
64   myCappedSubPlane = 0;
65   myCappedChain.Nullify();
66
67   // Method ::add() implicitly extends myDisabledPlanes (NCollection_Vector::SetValue()),
68   // however we do not reset myDisabledPlanes and mySkipFilter beforehand to avoid redundant memory re-allocations.
69   // So once extended, they will never reduce their size to lower values.
70   // This should not be a problem since overall number of clipping planes is expected to be quite small.
71 }
72
73 // =======================================================================
74 // function : SetLocalPlanes
75 // purpose  :
76 // =======================================================================
77 void OpenGl_Clipping::SetLocalPlanes (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes)
78 {
79   const Standard_Integer aStartIndex = myPlanesGlobal.IsNull() ? 1 : myPlanesGlobal->Size() + 1;
80   remove (myPlanesLocal, aStartIndex);
81
82   myPlanesLocal = thePlanes;
83
84   add (thePlanes, aStartIndex);
85 }
86
87 // =======================================================================
88 // function : add
89 // purpose  :
90 // =======================================================================
91 void OpenGl_Clipping::add (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes,
92                            const Standard_Integer theStartIndex)
93 {
94   if (thePlanes.IsNull())
95   {
96     return;
97   }
98
99   Standard_Integer aPlaneId = theStartIndex;
100   for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*thePlanes); aPlaneIt.More(); aPlaneIt.Next(), ++aPlaneId)
101   {
102     const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
103     myDisabledPlanes.SetValue (aPlaneId, Standard_False); // automatically resizes the vector
104     if (!aPlane->IsOn())
105     {
106       continue;
107     }
108
109     const Standard_Integer aNbSubPlanes = aPlane->NbChainNextPlanes();
110     myNbChains += 1;
111     if (aPlane->IsCapping())
112     {
113       myNbCapping += aNbSubPlanes;
114     }
115     else
116     {
117       myNbClipping += aNbSubPlanes;
118     }
119   }
120 }
121
122 // =======================================================================
123 // function : remove
124 // purpose  :
125 // =======================================================================
126 void OpenGl_Clipping::remove (const Handle(Graphic3d_SequenceOfHClipPlane)& thePlanes,
127                               const Standard_Integer theStartIndex)
128 {
129   if (thePlanes.IsNull())
130   {
131     return;
132   }
133
134   Standard_Integer aPlaneIndex = theStartIndex;
135   for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*thePlanes); aPlaneIt.More(); aPlaneIt.Next(), ++aPlaneIndex)
136   {
137     const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
138     if (!aPlane->IsOn()
139      || myDisabledPlanes.Value (aPlaneIndex))
140     {
141       continue;
142     }
143
144     const Standard_Integer aNbSubPlanes = aPlane->NbChainNextPlanes();
145     myNbChains -= 1;
146     if (aPlane->IsCapping())
147     {
148       myNbCapping -= aNbSubPlanes;
149     }
150     else
151     {
152       myNbClipping -= aNbSubPlanes;
153     }
154   }
155 }
156
157 // =======================================================================
158 // function : SetEnabled
159 // purpose  :
160 // =======================================================================
161 Standard_Boolean OpenGl_Clipping::SetEnabled (const OpenGl_ClippingIterator& thePlane,
162                                               const Standard_Boolean         theIsEnabled)
163 {
164   const Standard_Integer aPlaneIndex = thePlane.PlaneIndex();
165   Standard_Boolean& isDisabled = myDisabledPlanes.ChangeValue (aPlaneIndex);
166   if (isDisabled == !theIsEnabled)
167   {
168     return Standard_False;
169   }
170
171   isDisabled = !theIsEnabled;
172   const Standard_Integer aNbSubPlanes = thePlane.Value()->NbChainNextPlanes();
173   if (thePlane.Value()->IsCapping())
174   {
175     myNbCapping += (theIsEnabled ? aNbSubPlanes : -aNbSubPlanes);
176   }
177   else
178   {
179     myNbClipping += (theIsEnabled ? aNbSubPlanes : -aNbSubPlanes);
180   }
181   myNbChains   += (theIsEnabled ? 1 : -1);
182   myNbDisabled += (theIsEnabled ? -aNbSubPlanes : aNbSubPlanes);
183   return Standard_True;
184 }
185
186 // =======================================================================
187 // function : RestoreDisabled
188 // purpose  :
189 // =======================================================================
190 void OpenGl_Clipping::RestoreDisabled()
191 {
192   if (myNbDisabled == 0)
193   {
194     return;
195   }
196
197   myNbDisabled = 0;
198   for (OpenGl_ClippingIterator aPlaneIter (*this); aPlaneIter.More(); aPlaneIter.Next())
199   {
200     Standard_Boolean& isDisabled = myDisabledPlanes.ChangeValue (aPlaneIter.PlaneIndex());
201     if (!isDisabled)
202     {
203       continue;
204     }
205
206     isDisabled = Standard_False;
207     const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIter.Value();
208     const Standard_Integer aNbSubPlanes = aPlane->NbChainNextPlanes();
209     myNbChains += 1;
210     if (aPlane->IsCapping())
211     {
212       myNbCapping += aNbSubPlanes;
213     }
214     else
215     {
216       myNbClipping += aNbSubPlanes;
217     }
218   }
219 }
220
221 // =======================================================================
222 // function : DisableGlobal
223 // purpose  :
224 // =======================================================================
225 void OpenGl_Clipping::DisableGlobal()
226 {
227   for (OpenGl_ClippingIterator aPlaneIter (*this); aPlaneIter.More(); aPlaneIter.Next())
228   {
229     if (!aPlaneIter.IsGlobal())
230     {
231       // local planes always follow global ones in iterator
232       return;
233     }
234
235     SetEnabled (aPlaneIter, Standard_False);
236   }
237 }
238
239 // =======================================================================
240 // function : DisableAllExcept
241 // purpose  :
242 // =======================================================================
243 void OpenGl_Clipping::DisableAllExcept (const Handle(Graphic3d_ClipPlane)& theChain,
244                                         const Standard_Integer theSubPlaneIndex)
245 {
246   myCappedChain = theChain;
247   myCappedSubPlane = theSubPlaneIndex;
248 }
249
250 // =======================================================================
251 // function : EnableAllExcept
252 // purpose  :
253 // =======================================================================
254 void OpenGl_Clipping::EnableAllExcept (const Handle(Graphic3d_ClipPlane)& theChain,
255                                        const Standard_Integer theSubPlaneIndex)
256 {
257   myCappedChain = theChain;
258   myCappedSubPlane = -theSubPlaneIndex;
259 }
260
261 // =======================================================================
262 // function : ResetCappingFilter
263 // purpose  :
264 // =======================================================================
265 void OpenGl_Clipping::ResetCappingFilter()
266 {
267   myCappedChain.Nullify();
268   myCappedSubPlane = 0;
269 }