1 // Created on: 2012-02-02
2 // Created by: Anton POLETAEV
3 // Copyright (c) 2012-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <OpenGl_GlCore11.hxx>
18 #include <OpenGl_LayerList.hxx>
19 #include <OpenGl_Structure.hxx>
20 #include <OpenGl_Workspace.hxx>
22 #include <InterfaceGraphic_Graphic3d.hxx>
23 #include <InterfaceGraphic.hxx>
25 //=======================================================================
26 //function : OpenGl_LayerList
27 //purpose : Constructor
28 //=======================================================================
30 OpenGl_LayerList::OpenGl_LayerList (const Standard_Integer theNbPriorities)
31 : myNbPriorities (theNbPriorities),
34 // insert default priority layer
35 myLayers.Append (OpenGl_Layer (myNbPriorities));
36 myLayerIds.Bind (0, myLayers.Length());
39 //=======================================================================
40 //function : ~OpenGl_LayerList
41 //purpose : Destructor
42 //=======================================================================
44 OpenGl_LayerList::~OpenGl_LayerList ()
48 //=======================================================================
49 //function : defaultLayer
51 //=======================================================================
53 OpenGl_Layer& OpenGl_LayerList::defaultLayer()
55 return myLayers.ChangeValue (1);
58 //=======================================================================
59 //function : NbPriorities
60 //purpose : Method returns the number of available priorities
61 //=======================================================================
63 Standard_Integer OpenGl_LayerList::NbPriorities () const
65 return myNbPriorities;
68 //=======================================================================
69 //function : NbStructures
70 //purpose : Method returns the number of available structures
71 //=======================================================================
73 Standard_Integer OpenGl_LayerList::NbStructures () const
75 return myNbStructures;
78 //=======================================================================
81 //=======================================================================
83 void OpenGl_LayerList::AddLayer (const Standard_Integer theLayerId)
85 if (HasLayer (theLayerId))
89 myLayers.Append (OpenGl_Layer (myNbPriorities));
90 myLayerIds.Bind (theLayerId, myLayers.Length());
93 //=======================================================================
96 //=======================================================================
98 Standard_Boolean OpenGl_LayerList::HasLayer
99 (const Standard_Integer theLayerId) const
101 return myLayerIds.IsBound (theLayerId);
104 //=======================================================================
107 //=======================================================================
108 OpenGl_Layer& OpenGl_LayerList::Layer (const Standard_Integer theLayerId)
110 return myLayers.ChangeValue (myLayerIds.Find (theLayerId));
113 //=======================================================================
116 //=======================================================================
117 const OpenGl_Layer& OpenGl_LayerList::Layer (const Standard_Integer theLayerId) const
119 return myLayers.Value (myLayerIds.Find (theLayerId));
122 //=======================================================================
123 //function : RemoveLayer
125 //=======================================================================
127 void OpenGl_LayerList::RemoveLayer (const Standard_Integer theLayerId)
129 if (!HasLayer (theLayerId) || theLayerId == 0)
132 Standard_Integer aRemovePos = myLayerIds.Find (theLayerId);
134 // move all displayed structures to first layer
135 const OpenGl_PriorityList& aList = myLayers.Value (aRemovePos).PriorityList();
136 defaultLayer ().PriorityList().Append (aList);
139 myLayers.Remove (aRemovePos);
140 myLayerIds.UnBind (theLayerId);
142 // updated sequence indexes in map
143 OpenGl_LayerSeqIds::Iterator aMapIt (myLayerIds);
144 for ( ; aMapIt.More (); aMapIt.Next ())
146 Standard_Integer& aSeqIdx = aMapIt.ChangeValue ();
147 if (aSeqIdx > aRemovePos)
152 //=======================================================================
153 //function : AddStructure
155 //=======================================================================
157 void OpenGl_LayerList::AddStructure (const OpenGl_Structure *theStructure,
158 const Standard_Integer theLayerId,
159 const Standard_Integer thePriority,
160 Standard_Boolean isForChangePriority)
162 // add structure to associated layer,
163 // if layer doesn't exists, display structure in default layer
164 OpenGl_PriorityList& aList = !HasLayer (theLayerId) ? defaultLayer ().PriorityList() :
165 myLayers.ChangeValue (myLayerIds.Find (theLayerId)).PriorityList();
167 aList.Add (theStructure, thePriority, isForChangePriority);
170 // Note: In ray-tracing mode we don't modify modification
171 // state here. It is redundant, because the possible changes
172 // will be handled in the loop for structures
175 //=======================================================================
176 //function : RemoveStructure
178 //=======================================================================
180 void OpenGl_LayerList::RemoveStructure (const OpenGl_Structure *theStructure,
181 const Standard_Integer theLayerId)
183 Standard_Integer aSeqPos = !HasLayer (theLayerId) ?
184 1 : myLayerIds.Find (theLayerId);
186 OpenGl_PriorityList& aList = myLayers.ChangeValue (aSeqPos).PriorityList();
188 // remove structure from associated list
189 // if the structure is not found there,
190 // scan through layers and remove it
191 if (aList.Remove (theStructure) >= 0)
195 if (theStructure->IsRaytracable())
197 myModificationState++;
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++)
208 OpenGl_PriorityList& aScanList = anIts.ChangeValue ().PriorityList();
209 if (aSeqPos == aSeqId)
212 if (aScanList.Remove (theStructure) >= 0)
216 if (theStructure->IsRaytracable())
218 myModificationState++;
226 //=======================================================================
227 //function : InvalidateBVHData
229 //=======================================================================
230 void OpenGl_LayerList::InvalidateBVHData (const Standard_Integer theLayerId)
232 Standard_Integer aSeqPos = !HasLayer (theLayerId) ?
233 1 : myLayerIds.Find (theLayerId);
235 OpenGl_PriorityList& aList = myLayers.ChangeValue (aSeqPos).PriorityList();
237 aList.InvalidateBVHData();
240 //=======================================================================
241 //function : ChangeLayer
243 //=======================================================================
245 void OpenGl_LayerList::ChangeLayer (const OpenGl_Structure *theStructure,
246 const Standard_Integer theOldLayerId,
247 const Standard_Integer theNewLayerId)
249 Standard_Integer aSeqPos = !HasLayer (theOldLayerId) ?
250 1 : myLayerIds.Find (theOldLayerId);
252 OpenGl_PriorityList& aList = myLayers.ChangeValue (aSeqPos).PriorityList();
253 Standard_Integer aPriority;
255 // take priority and remove structure from list found by <theOldLayerId>
256 // if the structure is not found there, scan through all other layers
257 if ((aPriority = aList.Remove (theStructure, Standard_True)) >= 0)
260 AddStructure (theStructure, theNewLayerId, aPriority, Standard_True);
264 // scan through layers and remove it
265 Standard_Integer aSeqId = 1;
266 OpenGl_SequenceOfLayers::Iterator anIts;
267 for (anIts.Init (myLayers); anIts.More (); anIts.Next (), aSeqId++)
269 if (aSeqPos == aSeqId)
272 // try to remove structure and get priority value from this layer
273 if ((aPriority = aList.Remove (theStructure, Standard_True)) >= 0)
276 AddStructure (theStructure, theNewLayerId, aPriority, Standard_True);
283 //=======================================================================
284 //function : ChangePriority
286 //=======================================================================
287 void OpenGl_LayerList::ChangePriority (const OpenGl_Structure *theStructure,
288 const Standard_Integer theLayerId,
289 const Standard_Integer theNewPriority)
291 Standard_Integer aSeqPos = !HasLayer (theLayerId) ?
292 1 : myLayerIds.Find (theLayerId);
294 OpenGl_PriorityList& aList = myLayers.ChangeValue (aSeqPos).PriorityList();
296 if (aList.Remove (theStructure, Standard_True) >= 0)
299 AddStructure (theStructure, theLayerId, theNewPriority, Standard_True);
303 Standard_Integer aSeqId = 1;
304 OpenGl_SequenceOfLayers::Iterator anIts;
305 for (anIts.Init (myLayers); anIts.More (); anIts.Next (), aSeqId++)
307 if (aSeqPos == aSeqId)
310 if (aList.Remove (theStructure, Standard_True) >= 0)
313 AddStructure (theStructure, theLayerId, theNewPriority, Standard_True);
320 //=======================================================================
322 //purpose : Render this element
323 //=======================================================================
325 void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace) &theWorkspace) const
327 OpenGl_GlobalLayerSettings aDefaultSettings;
329 glGetIntegerv (GL_DEPTH_FUNC, &aDefaultSettings.DepthFunc);
330 glGetBooleanv (GL_DEPTH_WRITEMASK, &aDefaultSettings.DepthMask);
332 OpenGl_SequenceOfLayers::Iterator anIts;
333 for (anIts.Init (myLayers); anIts.More(); anIts.Next())
335 const OpenGl_Layer& aLayer = anIts.Value ();
336 if (aLayer.PriorityList().NbStructures () > 0)
339 aLayer.Render (theWorkspace, aDefaultSettings);
343 glDepthMask (aDefaultSettings.DepthMask);
344 glDepthFunc (aDefaultSettings.DepthFunc);