0022795: Make possible to display some presentable objects in overlay of others,...
[occt.git] / src / OpenGl / OpenGl_LayerList.cxx
CommitLineData
59f45b7c 1// File: OpenGl_LayerList.hxx
2// Created: 2 February 2012
3// Author: Anton POLETAEV
4// Copyright: OPEN CASCADE 2012
5
6#include <OpenGl_LayerList.hxx>
7#include <OpenGl_tgl_all.hxx>
8#include <OpenGl_Structure.hxx>
9
10#include <InterfaceGraphic_Graphic3d.hxx>
11#include <InterfaceGraphic.hxx>
12
13//=======================================================================
14//function : OpenGl_LayerList
15//purpose : Constructor
16//=======================================================================
17
18OpenGl_LayerList::OpenGl_LayerList (const Standard_Integer theNbPriorities)
19 : myNbPriorities (theNbPriorities),
20 myNbStructures (0)
21{
22 // insert default priority layer
23 myLayers.Append (OpenGl_PriorityList (myNbPriorities));
24 myLayerIds.Bind (0, myLayers.Length());
25}
26
27//=======================================================================
28//function : ~OpenGl_LayerList
29//purpose : Destructor
30//=======================================================================
31
32OpenGl_LayerList::~OpenGl_LayerList ()
33{
34}
35
36//=======================================================================
37//function : defaultLayer
38//purpose :
39//=======================================================================
40
41OpenGl_PriorityList& OpenGl_LayerList::defaultLayer()
42{
43 return myLayers.ChangeValue (1);
44}
45
46//=======================================================================
47//function : NbPriorities
48//purpose : Method returns the number of available priorities
49//=======================================================================
50
51Standard_Integer OpenGl_LayerList::NbPriorities () const
52{
53 return myNbPriorities;
54}
55
56//=======================================================================
57//function : NbStructures
58//purpose : Method returns the number of available structures
59//=======================================================================
60
61Standard_Integer OpenGl_LayerList::NbStructures () const
62{
63 return myNbStructures;
64}
65
66//=======================================================================
67//function : AddLayer
68//purpose :
69//=======================================================================
70
71void OpenGl_LayerList::AddLayer (const Standard_Integer theLayerId)
72{
73 if (HasLayer (theLayerId))
74 return;
75
76 // add the new layer
77 myLayers.Append (OpenGl_PriorityList (myNbPriorities));
78 myLayerIds.Bind (theLayerId, myLayers.Length());
79}
80
81//=======================================================================
82//function : HasLayer
83//purpose :
84//=======================================================================
85
86Standard_Boolean OpenGl_LayerList::HasLayer
87 (const Standard_Integer theLayerId) const
88{
89 return myLayerIds.IsBound (theLayerId);
90}
91
92//=======================================================================
93//function : RemoveLayer
94//purpose :
95//=======================================================================
96
97void OpenGl_LayerList::RemoveLayer (const Standard_Integer theLayerId)
98{
99 if (!HasLayer (theLayerId) || theLayerId == 0)
100 return;
101
102 Standard_Integer aRemovePos = myLayerIds.Find (theLayerId);
103
104 // move all displayed structures to first layer
105 const OpenGl_PriorityList& aList = myLayers.Value (aRemovePos);
106 defaultLayer ().Append (aList);
107
108 // remove layer
109 myLayers.Remove (aRemovePos);
110 myLayerIds.UnBind (theLayerId);
111
112 // updated sequence indexes in map
113 OpenGl_LayerSeqIds::Iterator aMapIt (myLayerIds);
114 for ( ; aMapIt.More (); aMapIt.Next ())
115 {
116 Standard_Integer& aSeqIdx = aMapIt.ChangeValue ();
117 if (aSeqIdx > aRemovePos)
118 aSeqIdx--;
119 }
120}
121
122//=======================================================================
123//function : AddStructure
124//purpose :
125//=======================================================================
126
127void OpenGl_LayerList::AddStructure (const OpenGl_Structure *theStructure,
128 const Standard_Integer theLayerId,
129 const Standard_Integer thePriority)
130{
131 // add structure to associated layer,
132 // if layer doesn't exists, display structure in default layer
133 OpenGl_PriorityList& aList = !HasLayer (theLayerId) ? defaultLayer () :
134 myLayers.ChangeValue (myLayerIds.Find (theLayerId));
135
136 aList.Add (theStructure, thePriority);
137 myNbStructures++;
138}
139
140//=======================================================================
141//function : RemoveStructure
142//purpose :
143//=======================================================================
144
145void OpenGl_LayerList::RemoveStructure (const OpenGl_Structure *theStructure,
146 const Standard_Integer theLayerId)
147{
148 Standard_Integer aSeqPos = !HasLayer (theLayerId) ?
149 1 : myLayerIds.Find (theLayerId);
150
151 OpenGl_PriorityList& aList = myLayers.ChangeValue (aSeqPos);
152
153 // remove structure from associated list
154 // if the structure is not found there,
155 // scan through layers and remove it
156 if (aList.Remove (theStructure) >= 0)
157 {
158 myNbStructures--;
159 return;
160 }
161
162 // scan through layers and remove it
163 Standard_Integer aSeqId = 1;
164 OpenGl_SequenceOfLayers::Iterator anIts;
165 for (anIts.Init (myLayers); anIts.More (); anIts.Next (), aSeqId++)
166 {
167 OpenGl_PriorityList& aScanList = anIts.ChangeValue ();
168 if (aSeqPos == aSeqId)
169 continue;
170
171 if (aScanList.Remove (theStructure) >= 0)
172 {
173 myNbStructures--;
174 return;
175 }
176 }
177}
178
179//=======================================================================
180//function : ChangeLayer
181//purpose :
182//=======================================================================
183
184void OpenGl_LayerList::ChangeLayer (const OpenGl_Structure *theStructure,
185 const Standard_Integer theOldLayerId,
186 const Standard_Integer theNewLayerId)
187{
188 Standard_Integer aSeqPos = !HasLayer (theOldLayerId) ?
189 1 : myLayerIds.Find (theOldLayerId);
190
191 OpenGl_PriorityList& aList = myLayers.ChangeValue (aSeqPos);
192 Standard_Integer aPriority;
193
194 // take priority and remove structure from list found by <theOldLayerId>
195 // if the structure is not found there, scan through all other layers
196 if ((aPriority = aList.Remove (theStructure)) >= 0)
197 {
198 myNbStructures--;
199 AddStructure (theStructure, theNewLayerId, aPriority);
200 }
201 else
202 {
203 // scan through layers and remove it
204 Standard_Integer aSeqId = 1;
205 OpenGl_SequenceOfLayers::Iterator anIts;
206 for (anIts.Init (myLayers); anIts.More (); anIts.Next (), aSeqId++)
207 {
208 OpenGl_PriorityList& aScanList = anIts.ChangeValue ();
209 if (aSeqPos == aSeqId)
210 continue;
211
212 // try to remove structure and get priority value from this layer
213 if ((aPriority = aList.Remove (theStructure)) >= 0)
214 {
215 myNbStructures--;
216 AddStructure (theStructure, theNewLayerId, aPriority);
217 break;
218 }
219 }
220 }
221}
222
223//=======================================================================
224//function : Render
225//purpose : Render this element
226//=======================================================================
227
228void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace) &theWorkspace) const
229{
230 OpenGl_SequenceOfLayers::Iterator anIts;
231 for(anIts.Init (myLayers); anIts.More (); anIts.Next ())
232 {
233 const OpenGl_PriorityList& aList = anIts.Value ();
234 if (aList.NbStructures () > 0)
235 {
236 // separate depth buffers
237 glClear (GL_DEPTH_BUFFER_BIT);
238
239 // render priority list
240 aList.Render (theWorkspace);
241 }
242 }
243}