0024785: Visualization - Modifying z-layers concept to gain more control over OpenGl...
[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
21 #include <InterfaceGraphic_Graphic3d.hxx>
22 #include <InterfaceGraphic.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 {
33   // insert default priority layer
34   myLayers.Append (OpenGl_Layer (myNbPriorities));
35   myLayerIds.Bind (0, myLayers.Length());
36 }
37
38 //=======================================================================
39 //function : ~OpenGl_LayerList
40 //purpose  : Destructor
41 //=======================================================================
42
43 OpenGl_LayerList::~OpenGl_LayerList ()
44 {
45 }
46
47 //=======================================================================
48 //function : defaultLayer
49 //purpose  :
50 //=======================================================================
51
52 OpenGl_Layer& OpenGl_LayerList::defaultLayer()
53 {
54   return myLayers.ChangeValue (1);
55 }
56
57 //=======================================================================
58 //function : NbPriorities
59 //purpose  : Method returns the number of available priorities
60 //=======================================================================
61
62 Standard_Integer OpenGl_LayerList::NbPriorities () const
63 {
64   return myNbPriorities;
65 }
66
67 //=======================================================================
68 //function : NbStructures
69 //purpose  : Method returns the number of available structures
70 //=======================================================================
71
72 Standard_Integer OpenGl_LayerList::NbStructures () const
73 {
74   return myNbStructures;
75 }
76
77 //=======================================================================
78 //function : AddLayer
79 //purpose  : 
80 //=======================================================================
81
82 void OpenGl_LayerList::AddLayer (const Standard_Integer theLayerId)
83 {
84   if (HasLayer (theLayerId))
85     return;
86
87   // add the new layer
88   myLayers.Append (OpenGl_Layer (myNbPriorities));
89   myLayerIds.Bind (theLayerId, myLayers.Length());
90 }
91
92 //=======================================================================
93 //function : HasLayer
94 //purpose  : 
95 //=======================================================================
96
97 Standard_Boolean OpenGl_LayerList::HasLayer 
98   (const Standard_Integer theLayerId) const
99 {
100   return myLayerIds.IsBound (theLayerId);
101 }
102
103 //=======================================================================
104 //function : Layer
105 //purpose  : 
106 //=======================================================================
107 OpenGl_Layer& OpenGl_LayerList::Layer (const Standard_Integer theLayerId)
108 {
109   return myLayers.ChangeValue (myLayerIds.Find (theLayerId));
110 }
111
112 //=======================================================================
113 //function : Layer
114 //purpose  : 
115 //=======================================================================
116 const OpenGl_Layer& OpenGl_LayerList::Layer (const Standard_Integer theLayerId) const
117 {
118   return myLayers.Value (myLayerIds.Find (theLayerId));
119 }
120
121 //=======================================================================
122 //function : RemoveLayer
123 //purpose  :
124 //=======================================================================
125
126 void OpenGl_LayerList::RemoveLayer (const Standard_Integer theLayerId)
127 {
128   if (!HasLayer (theLayerId) || theLayerId == 0)
129     return;
130
131   Standard_Integer aRemovePos = myLayerIds.Find (theLayerId);
132   
133   // move all displayed structures to first layer
134   const OpenGl_PriorityList& aList = myLayers.Value (aRemovePos).PriorityList();
135   defaultLayer ().PriorityList().Append (aList);
136
137   // remove layer
138   myLayers.Remove (aRemovePos);
139   myLayerIds.UnBind (theLayerId);
140
141   // updated sequence indexes in map
142   OpenGl_LayerSeqIds::Iterator aMapIt (myLayerIds);
143   for ( ; aMapIt.More (); aMapIt.Next ())
144   {
145     Standard_Integer& aSeqIdx = aMapIt.ChangeValue ();
146     if (aSeqIdx > aRemovePos)
147       aSeqIdx--;
148   }
149 }
150
151 //=======================================================================
152 //function : AddStructure
153 //purpose  :
154 //=======================================================================
155
156 void OpenGl_LayerList::AddStructure (const OpenGl_Structure *theStructure,
157                                      const Standard_Integer  theLayerId,
158                                      const Standard_Integer  thePriority)
159 {
160   // add structure to associated layer,
161   // if layer doesn't exists, display structure in default layer
162   OpenGl_PriorityList& aList = !HasLayer (theLayerId) ? defaultLayer ().PriorityList() :
163     myLayers.ChangeValue (myLayerIds.Find (theLayerId)).PriorityList();
164
165   aList.Add (theStructure, thePriority);
166   myNbStructures++;
167
168   // Note: In ray-tracing mode we don't modify modification
169   // state here. It is redundant, because the possible changes
170   // will be handled in the loop for structures
171 }
172
173 //=======================================================================
174 //function : RemoveStructure
175 //purpose  : 
176 //=======================================================================
177
178 void OpenGl_LayerList::RemoveStructure (const OpenGl_Structure *theStructure,
179                                         const Standard_Integer  theLayerId)
180 {
181   Standard_Integer aSeqPos = !HasLayer (theLayerId) ?
182     1 : myLayerIds.Find (theLayerId);
183   
184   OpenGl_PriorityList& aList = myLayers.ChangeValue (aSeqPos).PriorityList();
185
186   // remove structure from associated list
187   // if the structure is not found there,
188   // scan through layers and remove it
189   if (aList.Remove (theStructure) >= 0)
190   {
191     myNbStructures--;
192
193     if (theStructure->IsRaytracable())
194     {
195       myModificationState++;
196     }
197
198     return;
199   }
200   
201   // scan through layers and remove it
202   Standard_Integer aSeqId = 1;
203   OpenGl_SequenceOfLayers::Iterator anIts;
204   for (anIts.Init (myLayers); anIts.More (); anIts.Next (), aSeqId++)
205   {
206     OpenGl_PriorityList& aScanList = anIts.ChangeValue ().PriorityList();
207     if (aSeqPos == aSeqId)
208       continue;
209   
210     if (aScanList.Remove (theStructure) >= 0)
211     {
212       myNbStructures--;
213
214       if (theStructure->IsRaytracable())
215       {
216         myModificationState++;
217       }
218
219       return;
220     }
221   }
222 }
223
224 //=======================================================================
225 //function : ChangeLayer
226 //purpose  :
227 //=======================================================================
228
229 void OpenGl_LayerList::ChangeLayer (const OpenGl_Structure *theStructure,
230                                     const Standard_Integer  theOldLayerId,
231                                     const Standard_Integer  theNewLayerId)
232 {
233   Standard_Integer aSeqPos = !HasLayer (theOldLayerId) ?
234     1 : myLayerIds.Find (theOldLayerId);
235   
236   OpenGl_PriorityList& aList = myLayers.ChangeValue (aSeqPos).PriorityList();
237   Standard_Integer aPriority;
238
239   // take priority and remove structure from list found by <theOldLayerId>
240   // if the structure is not found there, scan through all other layers
241   if ((aPriority = aList.Remove (theStructure)) >= 0)
242   {
243     myNbStructures--;
244     AddStructure (theStructure, theNewLayerId, aPriority);
245   }
246   else
247   {
248     // scan through layers and remove it
249     Standard_Integer aSeqId = 1;
250     OpenGl_SequenceOfLayers::Iterator anIts;
251     for (anIts.Init (myLayers); anIts.More (); anIts.Next (), aSeqId++)
252     {
253       if (aSeqPos == aSeqId)
254         continue;
255   
256       // try to remove structure and get priority value from this layer
257       if ((aPriority = aList.Remove (theStructure)) >= 0)
258       {
259         myNbStructures--;
260         AddStructure (theStructure, theNewLayerId, aPriority);
261         break;
262       }
263     }
264   }
265 }
266
267 //=======================================================================
268 //function : Render
269 //purpose  : Render this element
270 //=======================================================================
271
272 void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace) &theWorkspace) const
273 {
274   int aDefaultDepthFunc;
275   glGetIntegerv (GL_DEPTH_FUNC, &aDefaultDepthFunc);
276
277   OpenGl_SequenceOfLayers::Iterator anIts;
278   for(anIts.Init (myLayers); anIts.More (); anIts.Next ())
279   {
280     const OpenGl_Layer& aLayer = anIts.Value ();
281     if (aLayer.PriorityList().NbStructures () > 0)
282     {
283       // render layer
284       aLayer.Render (theWorkspace, aDefaultDepthFunc);
285     }
286   }
287 }