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