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