cc25f07493d8e98da9a25a39b8f9bf199ad998a9
[occt.git] / src / OpenGl / OpenGl_LayerList.cxx
1 // Created on: 2012-02-02
2 // Created by: Anton POLETAEV
3 // Copyright (c) -1999 Matra Datavision
4 // Copyright (c) 2012-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21
22 #include <OpenGl_GlCore11.hxx>
23
24 #include <OpenGl_LayerList.hxx>
25 #include <OpenGl_Structure.hxx>
26
27 #include <InterfaceGraphic_Graphic3d.hxx>
28 #include <InterfaceGraphic.hxx>
29
30 //=======================================================================
31 //function : OpenGl_LayerList
32 //purpose  : Constructor
33 //=======================================================================
34
35 OpenGl_LayerList::OpenGl_LayerList (const Standard_Integer theNbPriorities)
36  : myNbPriorities (theNbPriorities),
37    myNbStructures (0)
38 {
39   // insert default priority layer
40   myLayers.Append (OpenGl_PriorityList (myNbPriorities));
41   myLayerIds.Bind (0, myLayers.Length());
42 }
43
44 //=======================================================================
45 //function : ~OpenGl_LayerList
46 //purpose  : Destructor
47 //=======================================================================
48
49 OpenGl_LayerList::~OpenGl_LayerList ()
50 {
51 }
52
53 //=======================================================================
54 //function : defaultLayer
55 //purpose  :
56 //=======================================================================
57
58 OpenGl_PriorityList& OpenGl_LayerList::defaultLayer()
59 {
60   return myLayers.ChangeValue (1);
61 }
62
63 //=======================================================================
64 //function : NbPriorities
65 //purpose  : Method returns the number of available priorities
66 //=======================================================================
67
68 Standard_Integer OpenGl_LayerList::NbPriorities () const
69 {
70   return myNbPriorities;
71 }
72
73 //=======================================================================
74 //function : NbStructures
75 //purpose  : Method returns the number of available structures
76 //=======================================================================
77
78 Standard_Integer OpenGl_LayerList::NbStructures () const
79 {
80   return myNbStructures;
81 }
82
83 //=======================================================================
84 //function : AddLayer
85 //purpose  : 
86 //=======================================================================
87
88 void OpenGl_LayerList::AddLayer (const Standard_Integer theLayerId)
89 {
90   if (HasLayer (theLayerId))
91     return;
92
93   // add the new layer
94   myLayers.Append (OpenGl_PriorityList (myNbPriorities));
95   myLayerIds.Bind (theLayerId, myLayers.Length());
96 }
97
98 //=======================================================================
99 //function : HasLayer
100 //purpose  : 
101 //=======================================================================
102
103 Standard_Boolean OpenGl_LayerList::HasLayer 
104   (const Standard_Integer theLayerId) const
105 {
106   return myLayerIds.IsBound (theLayerId);
107 }
108
109 //=======================================================================
110 //function : RemoveLayer
111 //purpose  :
112 //=======================================================================
113
114 void OpenGl_LayerList::RemoveLayer (const Standard_Integer theLayerId)
115 {
116   if (!HasLayer (theLayerId) || theLayerId == 0)
117     return;
118
119   Standard_Integer aRemovePos = myLayerIds.Find (theLayerId);
120   
121   // move all displayed structures to first layer
122   const OpenGl_PriorityList& aList = myLayers.Value (aRemovePos);
123   defaultLayer ().Append (aList);
124
125   // remove layer
126   myLayers.Remove (aRemovePos);
127   myLayerIds.UnBind (theLayerId);
128
129   // updated sequence indexes in map
130   OpenGl_LayerSeqIds::Iterator aMapIt (myLayerIds);
131   for ( ; aMapIt.More (); aMapIt.Next ())
132   {
133     Standard_Integer& aSeqIdx = aMapIt.ChangeValue ();
134     if (aSeqIdx > aRemovePos)
135       aSeqIdx--;
136   }
137 }
138
139 //=======================================================================
140 //function : AddStructure
141 //purpose  :
142 //=======================================================================
143
144 void OpenGl_LayerList::AddStructure (const OpenGl_Structure *theStructure,
145                                      const Standard_Integer  theLayerId,
146                                      const Standard_Integer  thePriority)
147 {
148   // add structure to associated layer,
149   // if layer doesn't exists, display structure in default layer
150   OpenGl_PriorityList& aList = !HasLayer (theLayerId) ? defaultLayer () :
151     myLayers.ChangeValue (myLayerIds.Find (theLayerId));
152
153   aList.Add (theStructure, thePriority);
154   myNbStructures++;
155 }
156
157 //=======================================================================
158 //function : RemoveStructure
159 //purpose  : 
160 //=======================================================================
161
162 void OpenGl_LayerList::RemoveStructure (const OpenGl_Structure *theStructure,
163                                         const Standard_Integer  theLayerId)
164 {
165   Standard_Integer aSeqPos = !HasLayer (theLayerId) ?
166     1 : myLayerIds.Find (theLayerId);
167   
168   OpenGl_PriorityList& aList = myLayers.ChangeValue (aSeqPos);
169
170   // remove structure from associated list
171   // if the structure is not found there,
172   // scan through layers and remove it
173   if (aList.Remove (theStructure) >= 0)
174   {
175     myNbStructures--;
176     return;
177   }
178   
179   // scan through layers and remove it
180   Standard_Integer aSeqId = 1;
181   OpenGl_SequenceOfLayers::Iterator anIts;
182   for (anIts.Init (myLayers); anIts.More (); anIts.Next (), aSeqId++)
183   {
184     OpenGl_PriorityList& aScanList = anIts.ChangeValue ();
185     if (aSeqPos == aSeqId)
186       continue;
187   
188     if (aScanList.Remove (theStructure) >= 0)
189     {
190       myNbStructures--;
191       return;
192     }
193   }
194 }
195
196 //=======================================================================
197 //function : ChangeLayer
198 //purpose  :
199 //=======================================================================
200
201 void OpenGl_LayerList::ChangeLayer (const OpenGl_Structure *theStructure,
202                                     const Standard_Integer  theOldLayerId,
203                                     const Standard_Integer  theNewLayerId)
204 {
205   Standard_Integer aSeqPos = !HasLayer (theOldLayerId) ?
206     1 : myLayerIds.Find (theOldLayerId);
207   
208   OpenGl_PriorityList& aList = myLayers.ChangeValue (aSeqPos);
209   Standard_Integer aPriority;
210
211   // take priority and remove structure from list found by <theOldLayerId>
212   // if the structure is not found there, scan through all other layers
213   if ((aPriority = aList.Remove (theStructure)) >= 0)
214   {
215     myNbStructures--;
216     AddStructure (theStructure, theNewLayerId, aPriority);
217   }
218   else
219   {
220     // scan through layers and remove it
221     Standard_Integer aSeqId = 1;
222     OpenGl_SequenceOfLayers::Iterator anIts;
223     for (anIts.Init (myLayers); anIts.More (); anIts.Next (), aSeqId++)
224     {
225       if (aSeqPos == aSeqId)
226         continue;
227   
228       // try to remove structure and get priority value from this layer
229       if ((aPriority = aList.Remove (theStructure)) >= 0)
230       {
231         myNbStructures--;
232         AddStructure (theStructure, theNewLayerId, aPriority);
233         break;
234       }
235     }
236   }
237 }
238
239 //=======================================================================
240 //function : Render
241 //purpose  : Render this element
242 //=======================================================================
243
244 void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace) &theWorkspace) const
245 {
246   OpenGl_SequenceOfLayers::Iterator anIts;
247   for(anIts.Init (myLayers); anIts.More (); anIts.Next ())
248   {
249     const OpenGl_PriorityList& aList = anIts.Value ();
250     if (aList.NbStructures () > 0)
251     {
252       // separate depth buffers
253       glClear (GL_DEPTH_BUFFER_BIT);
254
255       // render priority list
256       aList.Render (theWorkspace);
257     }
258   }
259 }