c266a639a9e112e7beb87af481884a781dfbe6d0
[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.hxx>
23 #include <Graphic3d_GraphicDriver.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 OpenGl_Structure* theStructure)
163 {
164   const Graphic3d_ZLayerId aLayerId = theStructure->ZLayer();
165
166   Standard_Integer aSeqPos = myLayers.Lower();
167   myLayerIds.Find (aLayerId, aSeqPos);
168
169   OpenGl_Layer&    aLayer    = myLayers.ChangeValue (aSeqPos);
170   Standard_Integer aPriority = -1;
171
172   // remove structure from associated list
173   // if the structure is not found there,
174   // scan through layers and remove it
175   if (aLayer.Remove (theStructure, aPriority))
176   {
177     --myNbStructures;
178     if (aLayer.LayerSettings().IsImmediate)
179     {
180       --myImmediateNbStructures;
181     }
182
183     if (theStructure->IsRaytracable())
184     {
185       ++myModificationState;
186     }
187
188     return;
189   }
190
191   // scan through layers and remove it
192   Standard_Integer aSeqId = 1;
193   for (OpenGl_SequenceOfLayers::Iterator anIts (myLayers); anIts.More(); anIts.Next(), ++aSeqId)
194   {
195     OpenGl_Layer& aLayerEx = anIts.ChangeValue();
196     if (aSeqPos == aSeqId)
197     {
198       continue;
199     }
200
201     if (aLayerEx.Remove (theStructure, aPriority))
202     {
203       --myNbStructures;
204       if (aLayerEx.LayerSettings().IsImmediate)
205       {
206         --myImmediateNbStructures;
207       }
208
209       if (theStructure->IsRaytracable())
210       {
211         ++myModificationState;
212       }
213       return;
214     }
215   }
216 }
217
218 //=======================================================================
219 //function : InvalidateBVHData
220 //purpose  :
221 //=======================================================================
222 void OpenGl_LayerList::InvalidateBVHData (const Graphic3d_ZLayerId theLayerId)
223 {
224   Standard_Integer aSeqPos = myLayers.Lower();
225   myLayerIds.Find (theLayerId, aSeqPos);
226   OpenGl_Layer& aLayer = myLayers.ChangeValue (aSeqPos);
227   aLayer.InvalidateBVHData();
228 }
229
230 //=======================================================================
231 //function : ChangeLayer
232 //purpose  :
233 //=======================================================================
234
235 void OpenGl_LayerList::ChangeLayer (const OpenGl_Structure*  theStructure,
236                                     const Graphic3d_ZLayerId theOldLayerId,
237                                     const Graphic3d_ZLayerId theNewLayerId)
238 {
239   Standard_Integer aSeqPos = myLayers.Lower();
240   myLayerIds.Find (theOldLayerId, aSeqPos);
241   OpenGl_Layer&    aLayer    = myLayers.ChangeValue (aSeqPos);
242   Standard_Integer aPriority = -1;
243
244   // take priority and remove structure from list found by <theOldLayerId>
245   // if the structure is not found there, scan through all other layers
246   if (aLayer.Remove (theStructure, aPriority, Standard_True))
247   {
248     --myNbStructures;
249     if (aLayer.LayerSettings().IsImmediate)
250     {
251       --myImmediateNbStructures;
252     }
253
254     // isForChangePriority should be Standard_False below, because we want
255     // the BVH tree in the target layer to be updated with theStructure
256     AddStructure (theStructure, theNewLayerId, aPriority);
257     return;
258   }
259
260   // scan through layers and remove it
261   Standard_Integer aSeqId = 1;
262   for (OpenGl_SequenceOfLayers::Iterator anIts (myLayers); anIts.More(); anIts.Next(), ++aSeqId)
263   {
264     if (aSeqPos == aSeqId)
265     {
266       continue;
267     }
268   
269     // try to remove structure and get priority value from this layer
270     OpenGl_Layer& aLayerEx = anIts.ChangeValue();
271     if (aLayerEx.Remove (theStructure, aPriority, Standard_True))
272     {
273       --myNbStructures;
274       if (aLayerEx.LayerSettings().IsImmediate)
275       {
276         --myImmediateNbStructures;
277       }
278
279       // isForChangePriority should be Standard_False below, because we want
280       // the BVH tree in the target layer to be updated with theStructure
281       AddStructure (theStructure, theNewLayerId, aPriority);
282       return;
283     }
284   }
285 }
286
287 //=======================================================================
288 //function : ChangePriority
289 //purpose  :
290 //=======================================================================
291 void OpenGl_LayerList::ChangePriority (const OpenGl_Structure*  theStructure,
292                                        const Graphic3d_ZLayerId theLayerId,
293                                        const Standard_Integer   theNewPriority)
294 {
295   Standard_Integer aSeqPos = myLayers.Lower();
296   myLayerIds.Find (theLayerId, aSeqPos);
297   OpenGl_Layer&    aLayer        = myLayers.ChangeValue (aSeqPos);
298   Standard_Integer anOldPriority = -1;
299
300   if (aLayer.Remove (theStructure, anOldPriority, Standard_True))
301   {
302     --myNbStructures;
303     if (aLayer.LayerSettings().IsImmediate)
304     {
305       --myImmediateNbStructures;
306     }
307
308     AddStructure (theStructure, theLayerId, theNewPriority, Standard_True);
309     return;
310   }
311
312   Standard_Integer aSeqId = 1;
313   for (OpenGl_SequenceOfLayers::Iterator anIts (myLayers); anIts.More(); anIts.Next(), ++aSeqId)
314   {
315     if (aSeqPos == aSeqId)
316     {
317       continue;
318     }
319
320     OpenGl_Layer& aLayerEx = anIts.ChangeValue();
321     if (aLayerEx.Remove (theStructure, anOldPriority, Standard_True))
322     {
323       --myNbStructures;
324       if (aLayerEx.LayerSettings().IsImmediate)
325       {
326         --myImmediateNbStructures;
327       }
328
329       AddStructure (theStructure, theLayerId, theNewPriority, Standard_True);
330       return;
331     }
332   }
333 }
334
335 //=======================================================================
336 //function : SetLayerSettings
337 //purpose  :
338 //=======================================================================
339 void OpenGl_LayerList::SetLayerSettings (const Graphic3d_ZLayerId        theLayerId,
340                                          const Graphic3d_ZLayerSettings& theSettings)
341 {
342   OpenGl_Layer& aLayer = Layer (theLayerId);
343   if (aLayer.LayerSettings().IsImmediate != theSettings.IsImmediate)
344   {
345     if (theSettings.IsImmediate)
346     {
347       myImmediateNbStructures += aLayer.NbStructures();
348     }
349     else
350     {
351       myImmediateNbStructures -= aLayer.NbStructures();
352     }
353   }
354   aLayer.SetLayerSettings (theSettings);
355 }
356
357 //=======================================================================
358 //function : Render
359 //purpose  :
360 //=======================================================================
361 void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace,
362                                const Standard_Boolean          theToDrawImmediate,
363                                const OpenGl_LayerFilter        theLayersToProcess) const
364 {
365   OpenGl_GlobalLayerSettings aDefaultSettings;
366
367   const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
368   aCtx->core11fwd->glGetIntegerv (GL_DEPTH_FUNC,      &aDefaultSettings.DepthFunc);
369   aCtx->core11fwd->glGetBooleanv (GL_DEPTH_WRITEMASK, &aDefaultSettings.DepthMask);
370
371   Standard_Integer aSeqId = myLayers.Lower(), aMainId = myLayerIds.Find (Graphic3d_ZLayerId_Default);
372   for (OpenGl_SequenceOfLayers::Iterator anIts (myLayers); anIts.More(); anIts.Next(), ++aSeqId)
373   {
374     if (theLayersToProcess == OpenGl_LF_Bottom)
375     {
376       if (aSeqId >= aMainId) continue;
377     }
378     else if (theLayersToProcess == OpenGl_LF_Upper)
379     {
380       if (aSeqId <= aMainId) continue;
381     }
382     else if (theLayersToProcess == OpenGl_LF_Default)
383     {
384       if (aSeqId != aMainId) continue;
385     }
386
387     const OpenGl_Layer& aLayer = anIts.Value();
388     if (aLayer.NbStructures() < 1)
389     {
390       continue;
391     }
392     else if (theToDrawImmediate)
393     {
394       if (!aLayer.LayerSettings().IsImmediate)
395       {
396         continue;
397       }
398     }
399     else
400     {
401       if (aLayer.LayerSettings().IsImmediate)
402       {
403         continue;
404       }
405     }
406
407     // render layer
408     aLayer.Render (theWorkspace, aDefaultSettings);
409   }
410
411   aCtx->core11fwd->glDepthMask (aDefaultSettings.DepthMask);
412   aCtx->core11fwd->glDepthFunc (aDefaultSettings.DepthFunc);
413 }