0027972: Visualization - remove unused and not implemented property V3d_View::EnableG...
[occt.git] / src / OpenGl / OpenGl_Layer.cxx
CommitLineData
c5751993 1// Created on: 2014-03-31
2// Created by: Danila ULYANOV
3// Copyright (c) 2014 OPEN CASCADE SAS
4//
5// This file is part of Open CASCADE Technology software library.
6//
0a36ca0a 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
c5751993 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_Layer.hxx>
a1954302 17
18#include <OpenGl_BVHTreeSelector.hxx>
19#include <OpenGl_Structure.hxx>
20#include <OpenGl_View.hxx>
550f3b8b 21#include <OpenGl_Workspace.hxx>
c04c30b3 22#include <Graphic3d_GraphicDriver.hxx>
c5751993 23
a1954302 24// =======================================================================
825aa485 25// function : OpenGl_Layer
a1954302 26// purpose :
27// =======================================================================
c5751993 28OpenGl_Layer::OpenGl_Layer (const Standard_Integer theNbPriorities)
50d06d8f 29: myArray (0, theNbPriorities - 1),
30 myNbStructures (0),
a1954302 31 myBVHIsLeftChildQueuedFirst (Standard_True),
32 myIsBVHPrimitivesNeedsReset (Standard_False)
c5751993 33{
50d06d8f 34 myIsBoundingBoxNeedsReset[0] = myIsBoundingBoxNeedsReset[1] = true;
c5751993 35}
36
a1954302 37// =======================================================================
38// function : ~OpenGl_Layer
39// purpose :
40// =======================================================================
41OpenGl_Layer::~OpenGl_Layer()
42{
43 //
44}
45
46// =======================================================================
47// function : Add
48// purpose :
49// =======================================================================
50void OpenGl_Layer::Add (const OpenGl_Structure* theStruct,
51 const Standard_Integer thePriority,
52 Standard_Boolean isForChangePriority)
53{
54 const Standard_Integer anIndex = Min (Max (thePriority, 0), myArray.Length() - 1);
55 if (theStruct == NULL)
56 {
57 return;
58 }
59
9f112210 60 myArray (anIndex).Add (theStruct);
a1954302 61 if (theStruct->IsAlwaysRendered())
62 {
63 theStruct->MarkAsNotCulled();
3fe9ce0e 64 if (!isForChangePriority)
65 {
66 myAlwaysRenderedMap.Add (theStruct);
67 }
a1954302 68 }
69 else if (!isForChangePriority)
70 {
778cd667 71 if (theStruct->TransformPersistence().IsNull())
825aa485 72 {
73 myBVHPrimitives.Add (theStruct);
74 }
75 else
76 {
77 myBVHPrimitivesTrsfPers.Add (theStruct);
78 }
a1954302 79 }
80 ++myNbStructures;
81}
82
83// =======================================================================
84// function : Remove
85// purpose :
86// =======================================================================
87bool OpenGl_Layer::Remove (const OpenGl_Structure* theStruct,
88 Standard_Integer& thePriority,
89 Standard_Boolean isForChangePriority)
90{
91 if (theStruct == NULL)
92 {
93 thePriority = -1;
94 return false;
95 }
96
97 const Standard_Integer aNbPriorities = myArray.Length();
98 for (Standard_Integer aPriorityIter = 0; aPriorityIter < aNbPriorities; ++aPriorityIter)
99 {
9f112210 100 OpenGl_IndexedMapOfStructure& aStructures = myArray (aPriorityIter);
101
102 const Standard_Integer anIndex = aStructures.FindIndex (theStruct);
103 if (anIndex != 0)
a1954302 104 {
9f112210 105 aStructures.Swap (anIndex, aStructures.Size());
106 aStructures.RemoveLast();
107
3fe9ce0e 108 if (!isForChangePriority)
a1954302 109 {
3fe9ce0e 110 if (theStruct->IsAlwaysRendered())
825aa485 111 {
3fe9ce0e 112 const Standard_Integer anIndex2 = myAlwaysRenderedMap.FindIndex (theStruct);
113 if (anIndex2 != 0)
114 {
115 myAlwaysRenderedMap.Swap (myAlwaysRenderedMap.Size(), anIndex2);
116 myAlwaysRenderedMap.RemoveLast();
117 }
118 }
119 else
120 {
121 if (!myBVHPrimitives.Remove (theStruct))
122 {
123 myBVHPrimitivesTrsfPers.Remove (theStruct);
124 }
825aa485 125 }
a1954302 126 }
9f112210 127 --myNbStructures;
128 thePriority = aPriorityIter;
129 return true;
a1954302 130 }
131 }
132
133 thePriority = -1;
134 return false;
135}
136
137// =======================================================================
138// function : InvalidateBVHData
139// purpose :
140// =======================================================================
50d06d8f 141void OpenGl_Layer::InvalidateBVHData() const
a1954302 142{
143 myIsBVHPrimitivesNeedsReset = Standard_True;
144}
145
3fe9ce0e 146//! Calculate a finite bounding box of infinite object as its middle point.
147inline Graphic3d_BndBox4f centerOfinfiniteBndBox (const Graphic3d_BndBox4f& theBndBox)
148{
149 // bounding borders of infinite line has been calculated as own point in center of this line
150 const Graphic3d_Vec4 aDiagVec = theBndBox.CornerMax() - theBndBox.CornerMin();
151 return aDiagVec.xyz().SquareModulus() >= 500000.0f * 500000.0f
152 ? Graphic3d_BndBox4f ((theBndBox.CornerMin() + theBndBox.CornerMax()) * 0.5f)
153 : Graphic3d_BndBox4f();
154}
155
156//! Return true if at least one vertex coordinate out of float range.
157inline bool isInfiniteBndBox (const Graphic3d_BndBox4f& theBndBox)
158{
159 return Abs (theBndBox.CornerMax().x()) >= ShortRealLast()
160 || Abs (theBndBox.CornerMax().y()) >= ShortRealLast()
161 || Abs (theBndBox.CornerMax().z()) >= ShortRealLast()
162 || Abs (theBndBox.CornerMin().x()) >= ShortRealLast()
163 || Abs (theBndBox.CornerMin().y()) >= ShortRealLast()
164 || Abs (theBndBox.CornerMin().z()) >= ShortRealLast();
165}
166
a1954302 167// =======================================================================
50d06d8f 168// function : BoundingBox
169// purpose :
170// =======================================================================
3fe9ce0e 171Graphic3d_BndBox4f OpenGl_Layer::BoundingBox (const Standard_Integer theViewId,
172 const Handle(Graphic3d_Camera)& theCamera,
173 const Standard_Integer theWindowWidth,
174 const Standard_Integer theWindowHeight,
175 const Standard_Boolean theToIncludeAuxiliary) const
50d06d8f 176{
150ed3d5 177 updateBVH();
178
3fe9ce0e 179 const Standard_Integer aBoxId = !theToIncludeAuxiliary ? 0 : 1;
180 const Graphic3d_Mat4& aProjectionMat = theCamera->ProjectionMatrixF();
181 const Graphic3d_Mat4& aWorldViewMat = theCamera->OrientationMatrixF();
50d06d8f 182 if (myIsBoundingBoxNeedsReset[aBoxId])
183 {
184 // Recompute layer bounding box
185 myBoundingBox[aBoxId].Clear();
186
187 const Standard_Integer aNbPriorities = myArray.Length();
188 for (Standard_Integer aPriorityIter = 0; aPriorityIter < aNbPriorities; ++aPriorityIter)
189 {
190 const OpenGl_IndexedMapOfStructure& aStructures = myArray (aPriorityIter);
191 for (Standard_Integer aStructIdx = 1; aStructIdx <= aStructures.Size(); ++aStructIdx)
192 {
193 const OpenGl_Structure* aStructure = aStructures.FindKey (aStructIdx);
3fe9ce0e 194 if (!aStructure->IsVisible (theViewId))
50d06d8f 195 {
196 continue;
197 }
198
199 // "FitAll" operation ignores object with transform persistence parameter
200 // but adds transform persistence point in a bounding box of layer (only zoom pers. objects).
778cd667 201 if (!aStructure->TransformPersistence().IsNull())
50d06d8f 202 {
3fe9ce0e 203 if (!theToIncludeAuxiliary
778cd667 204 && aStructure->TransformPersistence()->IsZoomOrRotate())
50d06d8f 205 {
778cd667 206 const gp_Pnt anAnchor = aStructure->TransformPersistence()->AnchorPoint();
207 BVH_Vec4f aTPPoint (static_cast<float> (anAnchor.X()),
208 static_cast<float> (anAnchor.Y()),
209 static_cast<float> (anAnchor.Z()),
50d06d8f 210 1.0f);
211
212 myBoundingBox[aBoxId].Combine (aTPPoint);
213 continue;
214 }
215 // Panning and 2d persistence apply changes to projection or/and its translation components.
216 // It makes them incompatible with z-fitting algorithm. Ignored by now.
3fe9ce0e 217 else if (!theToIncludeAuxiliary
778cd667 218 || aStructure->TransformPersistence()->IsTrihedronOr2d())
50d06d8f 219 {
220 continue;
221 }
222 }
223
224 Graphic3d_BndBox4f aBox = aStructure->BoundingBox();
3fe9ce0e 225 if (!aBox.IsValid())
226 {
227 continue;
228 }
50d06d8f 229
230 if (aStructure->IsInfinite
3fe9ce0e 231 && !theToIncludeAuxiliary)
50d06d8f 232 {
3fe9ce0e 233 // include center of infinite object
234 aBox = centerOfinfiniteBndBox (aBox);
50d06d8f 235 }
236
778cd667 237 if (!aStructure->TransformPersistence().IsNull())
50d06d8f 238 {
778cd667 239 aStructure->TransformPersistence()->Apply (theCamera, aProjectionMat, aWorldViewMat, theWindowWidth, theWindowHeight, aBox);
50d06d8f 240 }
241
3fe9ce0e 242 // skip too big boxes to prevent float overflow at camera parameters calculation
243 if (!isInfiniteBndBox (aBox))
50d06d8f 244 {
3fe9ce0e 245 myBoundingBox[aBoxId].Combine (aBox);
50d06d8f 246 }
50d06d8f 247 }
248 }
249
250 myIsBoundingBoxNeedsReset[aBoxId] = false;
251 }
252
3fe9ce0e 253 if (!theToIncludeAuxiliary
254 || myAlwaysRenderedMap.IsEmpty())
255 {
256 return myBoundingBox[aBoxId];
257 }
258
259 // add transformation-persistent objects which depend on camera position (and thus can not be cached) for operations like Z-fit
260 Graphic3d_BndBox4f aResBox = myBoundingBox[aBoxId];
261 for (NCollection_IndexedMap<const OpenGl_Structure*>::Iterator aStructIter (myAlwaysRenderedMap); aStructIter.More(); aStructIter.Next())
262 {
263 const OpenGl_Structure* aStructure = aStructIter.Value();
264 if (!aStructure->IsVisible (theViewId))
265 {
266 continue;
267 }
778cd667 268 else if (aStructure->TransformPersistence().IsNull()
269 || !aStructure->TransformPersistence()->IsTrihedronOr2d())
3fe9ce0e 270 {
271 continue;
272 }
273
274 Graphic3d_BndBox4f aBox = aStructure->BoundingBox();
275 if (!aBox.IsValid())
276 {
277 continue;
278 }
279
778cd667 280 aStructure->TransformPersistence()->Apply (theCamera, aProjectionMat, aWorldViewMat, theWindowWidth, theWindowHeight, aBox);
3fe9ce0e 281 if (!isInfiniteBndBox (aBox))
282 {
283 aResBox.Combine (aBox);
284 }
285 }
286
287 return aResBox;
50d06d8f 288}
289
290// =======================================================================
291// function : considerZoomPersistenceObjects
292// purpose :
293// =======================================================================
294Standard_Real OpenGl_Layer::considerZoomPersistenceObjects (const Standard_Integer theViewId,
295 const Handle(Graphic3d_Camera)& theCamera,
296 Standard_Integer theWindowWidth,
3fe9ce0e 297 Standard_Integer theWindowHeight) const
50d06d8f 298{
299 if (NbOfTransformPersistenceObjects() == 0)
300 {
301 return 1.0;
302 }
303
304 const Standard_Integer aNbPriorities = myArray.Length();
305 const Graphic3d_Mat4& aProjectionMat = theCamera->ProjectionMatrixF();
306 const Graphic3d_Mat4& aWorldViewMat = theCamera->OrientationMatrixF();
307 Standard_Real aMaxCoef = -std::numeric_limits<double>::max();
308
309 for (Standard_Integer aPriorityIter = 0; aPriorityIter < aNbPriorities; ++aPriorityIter)
310 {
311 const OpenGl_IndexedMapOfStructure& aStructures = myArray (aPriorityIter);
312 for (Standard_Integer aStructIdx = 1; aStructIdx <= aStructures.Size(); ++aStructIdx)
313 {
314 OpenGl_Structure* aStructure = const_cast<OpenGl_Structure*> (aStructures.FindKey (aStructIdx));
3fe9ce0e 315 if (!aStructure->IsVisible (theViewId)
778cd667 316 || aStructure->TransformPersistence().IsNull()
317 || !aStructure->TransformPersistence()->IsZoomOrRotate())
50d06d8f 318 {
319 continue;
320 }
321
3fe9ce0e 322 Graphic3d_BndBox4f aBox = aStructure->BoundingBox();
323 if (!aBox.IsValid())
50d06d8f 324 {
325 continue;
326 }
327
778cd667 328 aStructure->TransformPersistence()->Apply (theCamera, aProjectionMat, aWorldViewMat, theWindowWidth, theWindowHeight, aBox);
50d06d8f 329
330 const BVH_Vec4f& aCornerMin = aBox.CornerMin();
331 const BVH_Vec4f& aCornerMax = aBox.CornerMax();
332 const Standard_Integer aNbOfPoints = 8;
333 const gp_Pnt aPoints[aNbOfPoints] = { gp_Pnt (aCornerMin.x(), aCornerMin.y(), aCornerMin.z()),
334 gp_Pnt (aCornerMin.x(), aCornerMin.y(), aCornerMax.z()),
335 gp_Pnt (aCornerMin.x(), aCornerMax.y(), aCornerMin.z()),
336 gp_Pnt (aCornerMin.x(), aCornerMax.y(), aCornerMax.z()),
337 gp_Pnt (aCornerMax.x(), aCornerMin.y(), aCornerMin.z()),
338 gp_Pnt (aCornerMax.x(), aCornerMin.y(), aCornerMax.z()),
339 gp_Pnt (aCornerMax.x(), aCornerMax.y(), aCornerMin.z()),
340 gp_Pnt (aCornerMax.x(), aCornerMax.y(), aCornerMax.z()) };
341 gp_Pnt aConvertedPoints[aNbOfPoints];
342 Standard_Real aConvertedMinX = std::numeric_limits<double>::max();
343 Standard_Real aConvertedMaxX = -std::numeric_limits<double>::max();
344 Standard_Real aConvertedMinY = std::numeric_limits<double>::max();
345 Standard_Real aConvertedMaxY = -std::numeric_limits<double>::max();
346 for (Standard_Integer anIdx = 0; anIdx < aNbOfPoints; ++anIdx)
347 {
348 aConvertedPoints[anIdx] = theCamera->Project (aPoints[anIdx]);
349
350 aConvertedMinX = Min (aConvertedMinX, aConvertedPoints[anIdx].X());
351 aConvertedMaxX = Max (aConvertedMaxX, aConvertedPoints[anIdx].X());
352
353 aConvertedMinY = Min (aConvertedMinY, aConvertedPoints[anIdx].Y());
354 aConvertedMaxY = Max (aConvertedMaxY, aConvertedPoints[anIdx].Y());
355 }
356
357 const Standard_Boolean isBigObject = (Abs (aConvertedMaxX - aConvertedMinX) > 2.0) // width of zoom pers. object greater than width of window
358 || (Abs (aConvertedMaxY - aConvertedMinY) > 2.0); // height of zoom pers. object greater than height of window
359 const Standard_Boolean isAlreadyInScreen = (aConvertedMinX > -1.0 && aConvertedMinX < 1.0)
360 && (aConvertedMaxX > -1.0 && aConvertedMaxX < 1.0)
361 && (aConvertedMinY > -1.0 && aConvertedMinY < 1.0)
362 && (aConvertedMaxY > -1.0 && aConvertedMaxY < 1.0);
363 if (isBigObject || isAlreadyInScreen)
364 {
365 continue;
366 }
367
778cd667 368 const gp_Pnt aTPPoint = aStructure->TransformPersistence()->AnchorPoint();
50d06d8f 369 gp_Pnt aConvertedTPPoint = theCamera->Project (aTPPoint);
370 aConvertedTPPoint.SetZ (0.0);
371
372 if (aConvertedTPPoint.Coord().Modulus() < Precision::Confusion())
373 {
374 continue;
375 }
376
377 Standard_Real aShiftX = 0.0;
378 if (aConvertedMinX < -1.0)
379 {
380 aShiftX = ((aConvertedMaxX < -1.0) ? (-(1.0 + aConvertedMaxX) + (aConvertedMaxX - aConvertedMinX)) : -(1.0 + aConvertedMinX));
381 }
382 else if (aConvertedMaxX > 1.0)
383 {
384 aShiftX = ((aConvertedMinX > 1.0) ? ((aConvertedMinX - 1.0) + (aConvertedMaxX - aConvertedMinX)) : (aConvertedMaxX - 1.0));
385 }
386
387 Standard_Real aShiftY = 0.0;
388 if (aConvertedMinY < -1.0)
389 {
390 aShiftY = ((aConvertedMaxY < -1.0) ? (-(1.0 + aConvertedMaxY) + (aConvertedMaxY - aConvertedMinY)) : -(1.0 + aConvertedMinY));
391 }
392 else if (aConvertedMaxY > 1.0)
393 {
394 aShiftY = ((aConvertedMinY > 1.0) ? ((aConvertedMinY - 1.0) + (aConvertedMaxY - aConvertedMinY)) : (aConvertedMaxY - 1.0));
395 }
396
397 const Standard_Real aDifX = Abs (aConvertedTPPoint.X()) - aShiftX;
398 const Standard_Real aDifY = Abs (aConvertedTPPoint.Y()) - aShiftY;
399 if (aDifX > Precision::Confusion())
400 {
401 aMaxCoef = Max (aMaxCoef, Abs (aConvertedTPPoint.X()) / aDifX);
402 }
403 if (aDifY > Precision::Confusion())
404 {
405 aMaxCoef = Max (aMaxCoef, Abs (aConvertedTPPoint.Y()) / aDifY);
406 }
407 }
408 }
409
410 return (aMaxCoef > 0.0) ? aMaxCoef : 1.0;
411}
412
413// =======================================================================
a1954302 414// function : renderAll
415// purpose :
416// =======================================================================
417void OpenGl_Layer::renderAll (const Handle(OpenGl_Workspace)& theWorkspace) const
418{
419 const Standard_Integer aNbPriorities = myArray.Length();
c357e426 420 const Standard_Integer aViewId = theWorkspace->View()->Identification();
a1954302 421 for (Standard_Integer aPriorityIter = 0; aPriorityIter < aNbPriorities; ++aPriorityIter)
422 {
9f112210 423 const OpenGl_IndexedMapOfStructure& aStructures = myArray (aPriorityIter);
424 for (Standard_Integer aStructIdx = 1; aStructIdx <= aStructures.Size(); ++aStructIdx)
a1954302 425 {
9f112210 426 const OpenGl_Structure* aStruct = aStructures.FindKey (aStructIdx);
a1954302 427 if (!aStruct->IsVisible())
428 {
429 continue;
430 }
a272ed94 431 else if (!aStruct->ViewAffinity.IsNull()
432 && !aStruct->ViewAffinity->IsVisible (aViewId))
433 {
434 continue;
435 }
a1954302 436
437 aStruct->Render (theWorkspace);
438 }
439 }
440}
441
442// =======================================================================
3fe9ce0e 443// function : updateBVH
a1954302 444// purpose :
445// =======================================================================
3fe9ce0e 446void OpenGl_Layer::updateBVH() const
a1954302 447{
3fe9ce0e 448 if (!myIsBVHPrimitivesNeedsReset)
449 {
450 return;
451 }
452
453 myBVHPrimitives.Clear();
454 myBVHPrimitivesTrsfPers.Clear();
150ed3d5 455 myAlwaysRenderedMap.Clear();
3fe9ce0e 456 myIsBVHPrimitivesNeedsReset = Standard_False;
457 for (Standard_Integer aPriorityIdx = 0, aNbPriorities = myArray.Length(); aPriorityIdx < aNbPriorities; ++aPriorityIdx)
a1954302 458 {
3fe9ce0e 459 for (OpenGl_IndexedMapOfStructure::Iterator aStructIter (myArray (aPriorityIdx)); aStructIter.More(); aStructIter.Next())
825aa485 460 {
3fe9ce0e 461 const OpenGl_Structure* aStruct = aStructIter.Value();
462 if (aStruct->IsAlwaysRendered())
825aa485 463 {
150ed3d5 464 aStruct->MarkAsNotCulled();
465 myAlwaysRenderedMap.Add (aStruct);
3fe9ce0e 466 }
778cd667 467 else if (aStruct->TransformPersistence().IsNull())
3fe9ce0e 468 {
469 myBVHPrimitives.Add (aStruct);
470 }
471 else
472 {
473 myBVHPrimitivesTrsfPers.Add (aStruct);
825aa485 474 }
475 }
a1954302 476 }
3fe9ce0e 477}
478
479// =======================================================================
480// function : renderTraverse
481// purpose :
482// =======================================================================
483void OpenGl_Layer::renderTraverse (const Handle(OpenGl_Workspace)& theWorkspace) const
484{
485 updateBVH();
a1954302 486
c357e426 487 OpenGl_BVHTreeSelector& aSelector = theWorkspace->View()->BVHTreeSelector();
a1954302 488 traverse (aSelector);
489
490 const Standard_Integer aNbPriorities = myArray.Length();
c357e426 491 const Standard_Integer aViewId = theWorkspace->View()->Identification();
a1954302 492 for (Standard_Integer aPriorityIter = 0; aPriorityIter < aNbPriorities; ++aPriorityIter)
493 {
9f112210 494 const OpenGl_IndexedMapOfStructure& aStructures = myArray (aPriorityIter);
495 for (Standard_Integer aStructIdx = 1; aStructIdx <= aStructures.Size(); ++aStructIdx)
a1954302 496 {
9f112210 497 const OpenGl_Structure* aStruct = aStructures.FindKey (aStructIdx);
3fe9ce0e 498 if (aStruct->IsCulled()
499 || !aStruct->IsVisible (aViewId))
a272ed94 500 {
501 continue;
502 }
a1954302 503
504 aStruct->Render (theWorkspace);
505 aStruct->ResetCullingStatus();
506 }
507 }
508}
509
510// =======================================================================
511// function : traverse
512// purpose :
513// =======================================================================
514void OpenGl_Layer::traverse (OpenGl_BVHTreeSelector& theSelector) const
515{
516 // handle a case when all objects are infinite
97f937cc 517 if (myBVHPrimitives .Size() == 0
518 && myBVHPrimitivesTrsfPers.Size() == 0)
a1954302 519 return;
520
a1954302 521 theSelector.CacheClipPtsProjections();
a1954302 522
825aa485 523 NCollection_Handle<BVH_Tree<Standard_ShortReal, 4> > aBVHTree;
524
525 for (Standard_Integer aBVHTreeIdx = 0; aBVHTreeIdx < 2; ++aBVHTreeIdx)
a1954302 526 {
825aa485 527 const Standard_Boolean isTrsfPers = aBVHTreeIdx == 1;
528 if (isTrsfPers)
a1954302 529 {
825aa485 530 if (myBVHPrimitivesTrsfPers.Size() == 0)
825aa485 531 continue;
97f937cc 532
533 const OpenGl_Mat4& aProjection = theSelector.ProjectionMatrix();
534 const OpenGl_Mat4& aWorldView = theSelector.WorldViewMatrix();
825aa485 535 const Graphic3d_WorldViewProjState& aWVPState = theSelector.WorldViewProjState();
91d96372 536 const Standard_Integer aViewportWidth = theSelector.ViewportWidth();
537 const Standard_Integer aViewportHeight = theSelector.ViewportHeight();
538
3fe9ce0e 539 aBVHTree = myBVHPrimitivesTrsfPers.BVH (theSelector.Camera(), aProjection, aWorldView, aViewportWidth, aViewportHeight, aWVPState);
825aa485 540 }
541 else
542 {
543 if (myBVHPrimitives.Size() == 0)
825aa485 544 continue;
97f937cc 545
825aa485 546 aBVHTree = myBVHPrimitives.BVH();
547 }
548
549 Standard_Integer aNode = 0; // a root node
550
551 if (!theSelector.Intersect (aBVHTree->MinPoint (0),
552 aBVHTree->MaxPoint (0)))
553 {
554 continue;
555 }
556
557 Standard_Integer aStack[32];
558 Standard_Integer aHead = -1;
559 for (;;)
560 {
561 if (!aBVHTree->IsOuter (aNode))
a1954302 562 {
f2474958 563 const Standard_Integer aLeftChildIdx = aBVHTree->Child<0> (aNode);
564 const Standard_Integer aRightChildIdx = aBVHTree->Child<1> (aNode);
825aa485 565 const Standard_Boolean isLeftChildIn = theSelector.Intersect (aBVHTree->MinPoint (aLeftChildIdx),
566 aBVHTree->MaxPoint (aLeftChildIdx));
567 const Standard_Boolean isRightChildIn = theSelector.Intersect (aBVHTree->MinPoint (aRightChildIdx),
568 aBVHTree->MaxPoint (aRightChildIdx));
569 if (isLeftChildIn
570 && isRightChildIn)
571 {
572 aNode = myBVHIsLeftChildQueuedFirst ? aLeftChildIdx : aRightChildIdx;
573 aStack[++aHead] = myBVHIsLeftChildQueuedFirst ? aRightChildIdx : aLeftChildIdx;
574 myBVHIsLeftChildQueuedFirst = !myBVHIsLeftChildQueuedFirst;
575 }
576 else if (isLeftChildIn
577 || isRightChildIn)
578 {
579 aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
580 }
581 else
582 {
583 if (aHead < 0)
584 {
585 break;
586 }
587
588 aNode = aStack[aHead--];
589 }
a1954302 590 }
591 else
592 {
825aa485 593 Standard_Integer aIdx = aBVHTree->BegPrimitive (aNode);
594 const OpenGl_Structure* aStruct =
595 isTrsfPers ? myBVHPrimitivesTrsfPers.GetStructureById (aIdx)
596 : myBVHPrimitives.GetStructureById (aIdx);
597 aStruct->MarkAsNotCulled();
a1954302 598 if (aHead < 0)
599 {
825aa485 600 break;
a1954302 601 }
602
14a35e5d 603 aNode = aStack[aHead--];
a1954302 604 }
605 }
a1954302 606 }
607}
608
609// =======================================================================
610// function : Append
611// purpose :
612// =======================================================================
613Standard_Boolean OpenGl_Layer::Append (const OpenGl_Layer& theOther)
614{
615 // the source priority list shouldn't have more priorities
616 const Standard_Integer aNbPriorities = theOther.NbPriorities();
617 if (aNbPriorities > NbPriorities())
618 {
619 return Standard_False;
620 }
621
622 // add all structures to destination priority list
623 for (Standard_Integer aPriorityIter = 0; aPriorityIter < aNbPriorities; ++aPriorityIter)
624 {
9f112210 625 const OpenGl_IndexedMapOfStructure& aStructures = theOther.myArray (aPriorityIter);
626 for (Standard_Integer aStructIdx = 1; aStructIdx <= aStructures.Size(); ++aStructIdx)
a1954302 627 {
9f112210 628 Add (aStructures.FindKey (aStructIdx), aPriorityIter);
a1954302 629 }
630 }
631
632 return Standard_True;
633}
634
c5751993 635//=======================================================================
636//function : Render
a1954302 637//purpose :
c5751993 638//=======================================================================
a1954302 639void OpenGl_Layer::Render (const Handle(OpenGl_Workspace)& theWorkspace,
640 const OpenGl_GlobalLayerSettings& theDefaultSettings) const
c5751993 641{
b6472664 642 Graphic3d_PolygonOffset anAppliedOffsetParams = theWorkspace->AppliedPolygonOffset();
550f3b8b 643
c5751993 644 // separate depth buffers
645 if (IsSettingEnabled (Graphic3d_ZLayerDepthClear))
646 {
647 glClear (GL_DEPTH_BUFFER_BIT);
648 }
eae454e3 649
c5751993 650 // handle depth test
651 if (IsSettingEnabled (Graphic3d_ZLayerDepthTest))
652 {
550f3b8b 653 // assuming depth test is enabled by default
654 glDepthFunc (theDefaultSettings.DepthFunc);
c5751993 655 }
656 else
657 {
658 glDepthFunc (GL_ALWAYS);
659 }
eae454e3 660
83da37b1 661 // save environment texture
662 Handle(OpenGl_Texture) anEnvironmentTexture = theWorkspace->EnvironmentTexture();
663 if (!myLayerSettings.UseEnvironmentTexture)
664 {
665 theWorkspace->SetEnvironmentTexture (Handle(OpenGl_Texture)());
666 }
667
c5751993 668 // handle depth offset
669 if (IsSettingEnabled (Graphic3d_ZLayerDepthOffset))
670 {
b6472664 671 Graphic3d_PolygonOffset aLayerPolygonOffset;
672 aLayerPolygonOffset.Mode = Aspect_POM_Fill;
673 aLayerPolygonOffset.Factor = myLayerSettings.DepthOffsetFactor;
674 aLayerPolygonOffset.Units = myLayerSettings.DepthOffsetUnits;
675 theWorkspace->SetPolygonOffset (aLayerPolygonOffset);
c5751993 676 }
677 else
678 {
b6472664 679 theWorkspace->SetPolygonOffset (anAppliedOffsetParams);
c5751993 680 }
681
682 // handle depth write
eae454e3 683 theWorkspace->UseDepthWrite() = IsSettingEnabled (Graphic3d_ZLayerDepthWrite);
684 glDepthMask (theWorkspace->UseDepthWrite() ? GL_TRUE : GL_FALSE);
c5751993 685
686 // render priority list
a1954302 687 theWorkspace->IsCullingEnabled() ? renderTraverse (theWorkspace) : renderAll (theWorkspace);
550f3b8b 688
689 // always restore polygon offset between layers rendering
b6472664 690 theWorkspace->SetPolygonOffset (anAppliedOffsetParams);
83da37b1 691
692 // restore environment texture
693 if (!myLayerSettings.UseEnvironmentTexture)
694 {
695 theWorkspace->SetEnvironmentTexture (anEnvironmentTexture);
696 }
c5751993 697}