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