1906214be5285872511e48189d89f9efbcfa7b7a
[occt.git] / src / OpenGl / OpenGl_LayerList.cxx
1 // Created on: 2012-02-02
2 // Created by: Anton POLETAEV
3 // Copyright (c) 2012-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_GlCore11.hxx>
17
18 #include <OpenGl_LayerList.hxx>
19 #include <OpenGl_Structure.hxx>
20 #include <OpenGl_Workspace.hxx>
21
22 #include <InterfaceGraphic_Graphic3d.hxx>
23 #include <InterfaceGraphic.hxx>
24
25 //=======================================================================
26 //function : OpenGl_LayerList
27 //purpose  : Constructor
28 //=======================================================================
29
30 OpenGl_LayerList::OpenGl_LayerList (const Standard_Integer theNbPriorities)
31 : myNbPriorities (theNbPriorities),
32   myNbStructures (0),
33   myImmediateNbStructures (0)
34 {
35   // insert default priority layers
36   myLayers.Append (OpenGl_Layer (myNbPriorities));
37   myLayerIds.Bind (Graphic3d_ZLayerId_BotOSD,  myLayers.Upper());
38
39   myLayers.Append (OpenGl_Layer (myNbPriorities));
40   myLayerIds.Bind (Graphic3d_ZLayerId_Default, myLayers.Upper());
41
42   myLayers.Append (OpenGl_Layer (myNbPriorities));
43   myLayerIds.Bind (Graphic3d_ZLayerId_Top,     myLayers.Upper());
44
45   myLayers.Append (OpenGl_Layer (myNbPriorities));
46   myLayerIds.Bind (Graphic3d_ZLayerId_Topmost, myLayers.Upper());
47
48   myLayers.Append (OpenGl_Layer (myNbPriorities));
49   myLayerIds.Bind (Graphic3d_ZLayerId_TopOSD,  myLayers.Upper());
50 }
51
52 //=======================================================================
53 //function : ~OpenGl_LayerList
54 //purpose  : Destructor
55 //=======================================================================
56
57 OpenGl_LayerList::~OpenGl_LayerList()
58 {
59 }
60
61 //=======================================================================
62 //function : AddLayer
63 //purpose  : 
64 //=======================================================================
65
66 void OpenGl_LayerList::AddLayer (const Graphic3d_ZLayerId theLayerId)
67 {
68   if (myLayerIds.IsBound (theLayerId))
69   {
70     return;
71   }
72
73   // add the new layer
74   myLayers.Append (OpenGl_Layer (myNbPriorities));
75   myLayerIds.Bind (theLayerId, myLayers.Length());
76 }
77
78 //=======================================================================
79 //function : Layer
80 //purpose  : 
81 //=======================================================================
82 OpenGl_Layer& OpenGl_LayerList::Layer (const Graphic3d_ZLayerId theLayerId)
83 {
84   return myLayers.ChangeValue (myLayerIds.Find (theLayerId));
85 }
86
87 //=======================================================================
88 //function : Layer
89 //purpose  : 
90 //=======================================================================
91 const OpenGl_Layer& OpenGl_LayerList::Layer (const Graphic3d_ZLayerId theLayerId) const
92 {
93   return myLayers.Value (myLayerIds.Find (theLayerId));
94 }
95
96 //=======================================================================
97 //function : RemoveLayer
98 //purpose  :
99 //=======================================================================
100
101 void OpenGl_LayerList::RemoveLayer (const Graphic3d_ZLayerId theLayerId)
102 {
103   if (!myLayerIds.IsBound (theLayerId)
104     || theLayerId <= 0)
105   {
106     return;
107   }
108
109   const Standard_Integer aRemovePos = myLayerIds.Find (theLayerId);
110   
111   // move all displayed structures to first layer
112   const OpenGl_Layer& aLayerToMove = myLayers.Value (aRemovePos);
113   myLayers.ChangeFirst().Append (aLayerToMove);
114
115   // remove layer
116   myLayers.Remove (aRemovePos);
117   myLayerIds.UnBind (theLayerId);
118
119   // updated sequence indexes in map
120   OpenGl_LayerSeqIds::Iterator aMapIt (myLayerIds);
121   for ( ; aMapIt.More (); aMapIt.Next ())
122   {
123     Standard_Integer& aSeqIdx = aMapIt.ChangeValue ();
124     if (aSeqIdx > aRemovePos)
125       aSeqIdx--;
126   }
127 }
128
129 //=======================================================================
130 //function : AddStructure
131 //purpose  :
132 //=======================================================================
133
134 void OpenGl_LayerList::AddStructure (const OpenGl_Structure*  theStruct,
135                                      const Graphic3d_ZLayerId theLayerId,
136                                      const Standard_Integer   thePriority,
137                                      Standard_Boolean         isForChangePriority)
138 {
139   // add structure to associated layer,
140   // if layer doesn't exists, display structure in default layer
141   Standard_Integer aSeqPos = myLayers.Lower();
142   myLayerIds.Find (theLayerId, aSeqPos);
143
144   OpenGl_Layer& aLayer = myLayers.ChangeValue (aSeqPos);
145   aLayer.Add (theStruct, thePriority, isForChangePriority);
146   ++myNbStructures;
147   if (aLayer.LayerSettings().IsImmediate)
148   {
149     ++myImmediateNbStructures;
150   }
151
152   // Note: In ray-tracing mode we don't modify modification
153   // state here. It is redundant, because the possible changes
154   // will be handled in the loop for structures
155 }
156
157 //=======================================================================
158 //function : RemoveStructure
159 //purpose  :
160 //=======================================================================
161
162 void OpenGl_LayerList::RemoveStructure (const Handle(Graphic3d_Structure)& theStructure)
163 {
164   const OpenGl_Structure*  aStruct  = reinterpret_cast<const OpenGl_Structure* > (theStructure->CStructure().operator->());
165   const Graphic3d_ZLayerId aLayerId = aStruct->ZLayer();
166
167   Standard_Integer aSeqPos = myLayers.Lower();
168   myLayerIds.Find (aLayerId, aSeqPos);
169
170   OpenGl_Layer&    aLayer    = myLayers.ChangeValue (aSeqPos);
171   Standard_Integer aPriority = -1;
172
173   // remove structure from associated list
174   // if the structure is not found there,
175   // scan through layers and remove it
176   if (aLayer.Remove (aStruct, aPriority))
177   {
178     --myNbStructures;
179     if (aLayer.LayerSettings().IsImmediate)
180     {
181       --myImmediateNbStructures;
182     }
183
184     if (aStruct->IsRaytracable())
185     {
186       ++myModificationState;
187     }
188
189     return;
190   }
191
192   // scan through layers and remove it
193   Standard_Integer aSeqId = 1;
194   for (OpenGl_SequenceOfLayers::Iterator anIts (myLayers); anIts.More(); anIts.Next(), ++aSeqId)
195   {
196     OpenGl_Layer& aLayerEx = anIts.ChangeValue();
197     if (aSeqPos == aSeqId)
198     {
199       continue;
200     }
201
202     if (aLayerEx.Remove (aStruct, aPriority))
203     {
204       --myNbStructures;
205       if (aLayerEx.LayerSettings().IsImmediate)
206       {
207         --myImmediateNbStructures;
208       }
209
210       if (aStruct->IsRaytracable())
211       {
212         ++myModificationState;
213       }
214       return;
215     }
216   }
217 }
218
219 //=======================================================================
220 //function : InvalidateBVHData
221 //purpose  :
222 //=======================================================================
223 void OpenGl_LayerList::InvalidateBVHData (const Graphic3d_ZLayerId theLayerId)
224 {
225   Standard_Integer aSeqPos = myLayers.Lower();
226   myLayerIds.Find (theLayerId, aSeqPos);
227   OpenGl_Layer& aLayer = myLayers.ChangeValue (aSeqPos);
228   aLayer.InvalidateBVHData();
229 }
230
231 //=======================================================================
232 //function : ChangeLayer
233 //purpose  :
234 //=======================================================================
235
236 void OpenGl_LayerList::ChangeLayer (const OpenGl_Structure*  theStructure,
237                                     const Graphic3d_ZLayerId theOldLayerId,
238                                     const Graphic3d_ZLayerId theNewLayerId)
239 {
240   Standard_Integer aSeqPos = myLayers.Lower();
241   myLayerIds.Find (theOldLayerId, aSeqPos);
242   OpenGl_Layer&    aLayer    = myLayers.ChangeValue (aSeqPos);
243   Standard_Integer aPriority = -1;
244
245   // take priority and remove structure from list found by <theOldLayerId>
246   // if the structure is not found there, scan through all other layers
247   if (aLayer.Remove (theStructure, aPriority, Standard_True))
248   {
249     --myNbStructures;
250     if (aLayer.LayerSettings().IsImmediate)
251     {
252       --myImmediateNbStructures;
253     }
254
255     // isForChangePriority should be Standard_False below, because we want
256     // the BVH tree in the target layer to be updated with theStructure
257     AddStructure (theStructure, theNewLayerId, aPriority);
258     return;
259   }
260
261   // scan through layers and remove it
262   Standard_Integer aSeqId = 1;
263   for (OpenGl_SequenceOfLayers::Iterator anIts (myLayers); anIts.More(); anIts.Next(), ++aSeqId)
264   {
265     if (aSeqPos == aSeqId)
266     {
267       continue;
268     }
269   
270     // try to remove structure and get priority value from this layer
271     OpenGl_Layer& aLayerEx = anIts.ChangeValue();
272     if (aLayerEx.Remove (theStructure, aPriority, Standard_True))
273     {
274       --myNbStructures;
275       if (aLayerEx.LayerSettings().IsImmediate)
276       {
277         --myImmediateNbStructures;
278       }
279
280       // isForChangePriority should be Standard_False below, because we want
281       // the BVH tree in the target layer to be updated with theStructure
282       AddStructure (theStructure, theNewLayerId, aPriority);
283       return;
284     }
285   }
286 }
287
288 //=======================================================================
289 //function : ChangePriority
290 //purpose  :
291 //=======================================================================
292 void OpenGl_LayerList::ChangePriority (const OpenGl_Structure*  theStructure,
293                                        const Graphic3d_ZLayerId theLayerId,
294                                        const Standard_Integer   theNewPriority)
295 {
296   Standard_Integer aSeqPos = myLayers.Lower();
297   myLayerIds.Find (theLayerId, aSeqPos);
298   OpenGl_Layer&    aLayer        = myLayers.ChangeValue (aSeqPos);
299   Standard_Integer anOldPriority = -1;
300
301   if (aLayer.Remove (theStructure, anOldPriority, Standard_True))
302   {
303     --myNbStructures;
304     if (aLayer.LayerSettings().IsImmediate)
305     {
306       --myImmediateNbStructures;
307     }
308
309     AddStructure (theStructure, theLayerId, theNewPriority, Standard_True);
310     return;
311   }
312
313   Standard_Integer aSeqId = 1;
314   for (OpenGl_SequenceOfLayers::Iterator anIts (myLayers); anIts.More(); anIts.Next(), ++aSeqId)
315   {
316     if (aSeqPos == aSeqId)
317     {
318       continue;
319     }
320
321     OpenGl_Layer& aLayerEx = anIts.ChangeValue();
322     if (aLayerEx.Remove (theStructure, anOldPriority, Standard_True))
323     {
324       --myNbStructures;
325       if (aLayerEx.LayerSettings().IsImmediate)
326       {
327         --myImmediateNbStructures;
328       }
329
330       AddStructure (theStructure, theLayerId, theNewPriority, Standard_True);
331       return;
332     }
333   }
334 }
335
336 //=======================================================================
337 //function : SetLayerSettings
338 //purpose  :
339 //=======================================================================
340 void OpenGl_LayerList::SetLayerSettings (const Graphic3d_ZLayerId        theLayerId,
341                                          const Graphic3d_ZLayerSettings& theSettings)
342 {
343   OpenGl_Layer& aLayer = Layer (theLayerId);
344   if (aLayer.LayerSettings().IsImmediate != theSettings.IsImmediate)
345   {
346     if (theSettings.IsImmediate)
347     {
348       myImmediateNbStructures += aLayer.NbStructures();
349     }
350     else
351     {
352       myImmediateNbStructures -= aLayer.NbStructures();
353     }
354   }
355   aLayer.SetLayerSettings (theSettings);
356 }
357
358 //=======================================================================
359 //function : Render
360 //purpose  :
361 //=======================================================================
362 void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace,
363                                const Standard_Boolean          theToDrawImmediate,
364                                const OpenGl_LayerFilter        theLayersToProcess) const
365 {
366   OpenGl_GlobalLayerSettings aDefaultSettings;
367
368   const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
369   aCtx->core11fwd->glGetIntegerv (GL_DEPTH_FUNC,      &aDefaultSettings.DepthFunc);
370   aCtx->core11fwd->glGetBooleanv (GL_DEPTH_WRITEMASK, &aDefaultSettings.DepthMask);
371
372   Standard_Integer aSeqId = myLayers.Lower(), aMainId = myLayerIds.Find (Graphic3d_ZLayerId_Default);
373   for (OpenGl_SequenceOfLayers::Iterator anIts (myLayers); anIts.More(); anIts.Next(), ++aSeqId)
374   {
375     if (theLayersToProcess == OpenGl_LF_Bottom)
376     {
377       if (aSeqId >= aMainId) continue;
378     }
379     else if (theLayersToProcess == OpenGl_LF_Upper)
380     {
381       if (aSeqId <= aMainId) continue;
382     }
383     else if (theLayersToProcess == OpenGl_LF_Default)
384     {
385       if (aSeqId != aMainId) continue;
386     }
387
388     const OpenGl_Layer& aLayer = anIts.Value();
389     if (aLayer.NbStructures() < 1)
390     {
391       continue;
392     }
393     else if (theToDrawImmediate)
394     {
395       if (!aLayer.LayerSettings().IsImmediate)
396       {
397         continue;
398       }
399     }
400     else
401     {
402       if (aLayer.LayerSettings().IsImmediate)
403       {
404         continue;
405       }
406     }
407
408     // render layer
409     aLayer.Render (theWorkspace, aDefaultSettings);
410   }
411
412   aCtx->core11fwd->glDepthMask (aDefaultSettings.DepthMask);
413   aCtx->core11fwd->glDepthFunc (aDefaultSettings.DepthFunc);
414 }