0030675: Visualization - remove redundant proxy classes in hierarchy of PrsMgr_Presen...
[occt.git] / src / Graphic3d / Graphic3d_Layer.cxx
CommitLineData
d325cb7f 1// Copyright (c) 2011-2019 OPEN CASCADE SAS
c5751993 2//
3// This file is part of Open CASCADE Technology software library.
4//
0a36ca0a 5// This library is free software; you can redistribute it and/or modify it under
6// the terms of the GNU Lesser General Public License version 2.1 as published
c5751993 7// by the Free Software Foundation, with special exception defined in the file
8// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9// distribution for complete text of the license and disclaimer of any warranty.
10//
11// Alternatively, this file may be used under the terms of Open CASCADE
12// commercial license or contractual agreement.
13
d325cb7f 14#include <Graphic3d_Layer.hxx>
a1954302 15
d325cb7f 16#include <Graphic3d_CStructure.hxx>
17#include <Graphic3d_CullingTool.hxx>
c5751993 18
d325cb7f 19IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_Layer, Standard_Transient)
f5b72419 20
a1954302 21// =======================================================================
d325cb7f 22// function : Graphic3d_Layer
a1954302 23// purpose :
24// =======================================================================
d325cb7f 25Graphic3d_Layer::Graphic3d_Layer (Standard_Integer theNbPriorities,
26 const Handle(Select3D_BVHBuilder3d)& theBuilder)
50d06d8f 27: myArray (0, theNbPriorities - 1),
28 myNbStructures (0),
15669413 29 myNbStructuresNotCulled (0),
f5b72419 30 myBVHPrimitivesTrsfPers (theBuilder),
a1954302 31 myBVHIsLeftChildQueuedFirst (Standard_True),
15669413 32 myIsBVHPrimitivesNeedsReset (Standard_False)
c5751993 33{
50d06d8f 34 myIsBoundingBoxNeedsReset[0] = myIsBoundingBoxNeedsReset[1] = true;
c5751993 35}
36
a1954302 37// =======================================================================
d325cb7f 38// function : ~Graphic3d_Layer
a1954302 39// purpose :
40// =======================================================================
d325cb7f 41Graphic3d_Layer::~Graphic3d_Layer()
a1954302 42{
43 //
44}
45
46// =======================================================================
47// function : Add
48// purpose :
49// =======================================================================
d325cb7f 50void Graphic3d_Layer::Add (const Graphic3d_CStructure* theStruct,
51 Standard_Integer thePriority,
52 Standard_Boolean isForChangePriority)
a1954302 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// =======================================================================
d325cb7f 87bool Graphic3d_Layer::Remove (const Graphic3d_CStructure* theStruct,
88 Standard_Integer& thePriority,
89 Standard_Boolean isForChangePriority)
a1954302 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 {
d325cb7f 100 Graphic3d_IndexedMapOfStructure& aStructures = myArray (aPriorityIter);
9f112210 101 const Standard_Integer anIndex = aStructures.FindIndex (theStruct);
d325cb7f 102 if (anIndex == 0)
a1954302 103 {
d325cb7f 104 continue;
105 }
106
107 aStructures.Swap (anIndex, aStructures.Size());
108 aStructures.RemoveLast();
9f112210 109
d325cb7f 110 if (!isForChangePriority)
111 {
112 Standard_Boolean isAlwaysRend = theStruct->IsAlwaysRendered();
113 if (!isAlwaysRend)
a1954302 114 {
d325cb7f 115 if (!myBVHPrimitives.Remove (theStruct))
825aa485 116 {
d325cb7f 117 if (!myBVHPrimitivesTrsfPers.Remove (theStruct))
3fe9ce0e 118 {
d325cb7f 119 isAlwaysRend = Standard_True;
3fe9ce0e 120 }
121 }
d325cb7f 122 }
123 if (isAlwaysRend)
124 {
125 const Standard_Integer anIndex2 = myAlwaysRenderedMap.FindIndex (theStruct);
126 if (anIndex2 != 0)
3fe9ce0e 127 {
d325cb7f 128 myAlwaysRenderedMap.Swap (myAlwaysRenderedMap.Size(), anIndex2);
129 myAlwaysRenderedMap.RemoveLast();
825aa485 130 }
a1954302 131 }
132 }
d325cb7f 133 --myNbStructures;
134 thePriority = aPriorityIter;
135 return true;
a1954302 136 }
137
138 thePriority = -1;
139 return false;
140}
141
142// =======================================================================
143// function : InvalidateBVHData
144// purpose :
145// =======================================================================
d325cb7f 146void Graphic3d_Layer::InvalidateBVHData()
a1954302 147{
148 myIsBVHPrimitivesNeedsReset = Standard_True;
149}
150
3fe9ce0e 151//! Calculate a finite bounding box of infinite object as its middle point.
7c3ef2f7 152inline Graphic3d_BndBox3d centerOfinfiniteBndBox (const Graphic3d_BndBox3d& theBndBox)
3fe9ce0e 153{
154 // bounding borders of infinite line has been calculated as own point in center of this line
7c3ef2f7 155 const Graphic3d_Vec3d aDiagVec = theBndBox.CornerMax() - theBndBox.CornerMin();
156 return aDiagVec.SquareModulus() >= 500000.0 * 500000.0
157 ? Graphic3d_BndBox3d ((theBndBox.CornerMin() + theBndBox.CornerMax()) * 0.5)
158 : Graphic3d_BndBox3d();
3fe9ce0e 159}
160
161//! Return true if at least one vertex coordinate out of float range.
7c3ef2f7 162inline bool isInfiniteBndBox (const Graphic3d_BndBox3d& theBndBox)
3fe9ce0e 163{
164 return Abs (theBndBox.CornerMax().x()) >= ShortRealLast()
165 || Abs (theBndBox.CornerMax().y()) >= ShortRealLast()
166 || Abs (theBndBox.CornerMax().z()) >= ShortRealLast()
167 || Abs (theBndBox.CornerMin().x()) >= ShortRealLast()
168 || Abs (theBndBox.CornerMin().y()) >= ShortRealLast()
169 || Abs (theBndBox.CornerMin().z()) >= ShortRealLast();
170}
171
a1954302 172// =======================================================================
50d06d8f 173// function : BoundingBox
174// purpose :
175// =======================================================================
d325cb7f 176Bnd_Box Graphic3d_Layer::BoundingBox (Standard_Integer theViewId,
177 const Handle(Graphic3d_Camera)& theCamera,
178 Standard_Integer theWindowWidth,
179 Standard_Integer theWindowHeight,
180 Standard_Boolean theToIncludeAuxiliary) const
50d06d8f 181{
150ed3d5 182 updateBVH();
183
3fe9ce0e 184 const Standard_Integer aBoxId = !theToIncludeAuxiliary ? 0 : 1;
7c3ef2f7 185 const Graphic3d_Mat4d& aProjectionMat = theCamera->ProjectionMatrix();
186 const Graphic3d_Mat4d& aWorldViewMat = theCamera->OrientationMatrix();
50d06d8f 187 if (myIsBoundingBoxNeedsReset[aBoxId])
188 {
189 // Recompute layer bounding box
7c3ef2f7 190 myBoundingBox[aBoxId].SetVoid();
50d06d8f 191
d325cb7f 192 for (Graphic3d_ArrayOfIndexedMapOfStructure::Iterator aMapIter (myArray); aMapIter.More(); aMapIter.Next())
50d06d8f 193 {
d325cb7f 194 const Graphic3d_IndexedMapOfStructure& aStructures = aMapIter.Value();
195 for (Graphic3d_IndexedMapOfStructure::Iterator aStructIter (aStructures); aStructIter.More(); aStructIter.Next())
50d06d8f 196 {
d325cb7f 197 const Graphic3d_CStructure* aStructure = aStructIter.Value();
3fe9ce0e 198 if (!aStructure->IsVisible (theViewId))
50d06d8f 199 {
200 continue;
201 }
202
203 // "FitAll" operation ignores object with transform persistence parameter
204 // but adds transform persistence point in a bounding box of layer (only zoom pers. objects).
778cd667 205 if (!aStructure->TransformPersistence().IsNull())
50d06d8f 206 {
3fe9ce0e 207 if (!theToIncludeAuxiliary
778cd667 208 && aStructure->TransformPersistence()->IsZoomOrRotate())
50d06d8f 209 {
778cd667 210 const gp_Pnt anAnchor = aStructure->TransformPersistence()->AnchorPoint();
7c3ef2f7 211 myBoundingBox[aBoxId].Add (anAnchor);
50d06d8f 212 continue;
213 }
214 // Panning and 2d persistence apply changes to projection or/and its translation components.
215 // It makes them incompatible with z-fitting algorithm. Ignored by now.
3fe9ce0e 216 else if (!theToIncludeAuxiliary
778cd667 217 || aStructure->TransformPersistence()->IsTrihedronOr2d())
50d06d8f 218 {
219 continue;
220 }
221 }
222
7c3ef2f7 223 Graphic3d_BndBox3d aBox = aStructure->BoundingBox();
3fe9ce0e 224 if (!aBox.IsValid())
225 {
226 continue;
227 }
50d06d8f 228
229 if (aStructure->IsInfinite
3fe9ce0e 230 && !theToIncludeAuxiliary)
50d06d8f 231 {
3fe9ce0e 232 // include center of infinite object
233 aBox = centerOfinfiniteBndBox (aBox);
50d06d8f 234 }
235
778cd667 236 if (!aStructure->TransformPersistence().IsNull())
50d06d8f 237 {
778cd667 238 aStructure->TransformPersistence()->Apply (theCamera, aProjectionMat, aWorldViewMat, theWindowWidth, theWindowHeight, aBox);
50d06d8f 239 }
240
3fe9ce0e 241 // skip too big boxes to prevent float overflow at camera parameters calculation
7c3ef2f7 242 if (aBox.IsValid()
243 && !isInfiniteBndBox (aBox))
50d06d8f 244 {
7c3ef2f7 245 myBoundingBox[aBoxId].Add (gp_Pnt (aBox.CornerMin().x(), aBox.CornerMin().y(), aBox.CornerMin().z()));
246 myBoundingBox[aBoxId].Add (gp_Pnt (aBox.CornerMax().x(), aBox.CornerMax().y(), aBox.CornerMax().z()));
50d06d8f 247 }
50d06d8f 248 }
249 }
250
251 myIsBoundingBoxNeedsReset[aBoxId] = false;
252 }
253
7c3ef2f7 254 Bnd_Box aResBox = myBoundingBox[aBoxId];
3fe9ce0e 255 if (!theToIncludeAuxiliary
256 || myAlwaysRenderedMap.IsEmpty())
257 {
7c3ef2f7 258 return aResBox;
3fe9ce0e 259 }
260
261 // add transformation-persistent objects which depend on camera position (and thus can not be cached) for operations like Z-fit
d325cb7f 262 for (NCollection_IndexedMap<const Graphic3d_CStructure*>::Iterator aStructIter (myAlwaysRenderedMap); aStructIter.More(); aStructIter.Next())
3fe9ce0e 263 {
d325cb7f 264 const Graphic3d_CStructure* aStructure = aStructIter.Value();
3fe9ce0e 265 if (!aStructure->IsVisible (theViewId))
266 {
267 continue;
268 }
778cd667 269 else if (aStructure->TransformPersistence().IsNull()
270 || !aStructure->TransformPersistence()->IsTrihedronOr2d())
3fe9ce0e 271 {
272 continue;
273 }
274
7c3ef2f7 275 Graphic3d_BndBox3d aBox = aStructure->BoundingBox();
3fe9ce0e 276 if (!aBox.IsValid())
277 {
278 continue;
279 }
280
778cd667 281 aStructure->TransformPersistence()->Apply (theCamera, aProjectionMat, aWorldViewMat, theWindowWidth, theWindowHeight, aBox);
7c3ef2f7 282 if (aBox.IsValid()
283 && !isInfiniteBndBox (aBox))
3fe9ce0e 284 {
7c3ef2f7 285 aResBox.Add (gp_Pnt (aBox.CornerMin().x(), aBox.CornerMin().y(), aBox.CornerMin().z()));
286 aResBox.Add (gp_Pnt (aBox.CornerMax().x(), aBox.CornerMax().y(), aBox.CornerMax().z()));
3fe9ce0e 287 }
288 }
289
290 return aResBox;
50d06d8f 291}
292
293// =======================================================================
294// function : considerZoomPersistenceObjects
295// purpose :
296// =======================================================================
d325cb7f 297Standard_Real Graphic3d_Layer::considerZoomPersistenceObjects (Standard_Integer theViewId,
298 const Handle(Graphic3d_Camera)& theCamera,
299 Standard_Integer theWindowWidth,
300 Standard_Integer theWindowHeight) const
50d06d8f 301{
302 if (NbOfTransformPersistenceObjects() == 0)
303 {
304 return 1.0;
305 }
306
7c3ef2f7 307 const Graphic3d_Mat4d& aProjectionMat = theCamera->ProjectionMatrix();
308 const Graphic3d_Mat4d& aWorldViewMat = theCamera->OrientationMatrix();
50d06d8f 309 Standard_Real aMaxCoef = -std::numeric_limits<double>::max();
310
d325cb7f 311 for (Graphic3d_ArrayOfIndexedMapOfStructure::Iterator aMapIter (myArray); aMapIter.More(); aMapIter.Next())
50d06d8f 312 {
d325cb7f 313 const Graphic3d_IndexedMapOfStructure& aStructures = aMapIter.Value();
314 for (Graphic3d_IndexedMapOfStructure::Iterator aStructIter (aStructures); aStructIter.More(); aStructIter.Next())
50d06d8f 315 {
d325cb7f 316 const Graphic3d_CStructure* aStructure = aStructIter.Value();
3fe9ce0e 317 if (!aStructure->IsVisible (theViewId)
778cd667 318 || aStructure->TransformPersistence().IsNull()
319 || !aStructure->TransformPersistence()->IsZoomOrRotate())
50d06d8f 320 {
321 continue;
322 }
323
7c3ef2f7 324 Graphic3d_BndBox3d aBox = aStructure->BoundingBox();
3fe9ce0e 325 if (!aBox.IsValid())
50d06d8f 326 {
327 continue;
328 }
329
778cd667 330 aStructure->TransformPersistence()->Apply (theCamera, aProjectionMat, aWorldViewMat, theWindowWidth, theWindowHeight, aBox);
50d06d8f 331
7c3ef2f7 332 const BVH_Vec3d& aCornerMin = aBox.CornerMin();
333 const BVH_Vec3d& aCornerMax = aBox.CornerMax();
50d06d8f 334 const Standard_Integer aNbOfPoints = 8;
335 const gp_Pnt aPoints[aNbOfPoints] = { gp_Pnt (aCornerMin.x(), aCornerMin.y(), aCornerMin.z()),
336 gp_Pnt (aCornerMin.x(), aCornerMin.y(), aCornerMax.z()),
337 gp_Pnt (aCornerMin.x(), aCornerMax.y(), aCornerMin.z()),
338 gp_Pnt (aCornerMin.x(), aCornerMax.y(), aCornerMax.z()),
339 gp_Pnt (aCornerMax.x(), aCornerMin.y(), aCornerMin.z()),
340 gp_Pnt (aCornerMax.x(), aCornerMin.y(), aCornerMax.z()),
341 gp_Pnt (aCornerMax.x(), aCornerMax.y(), aCornerMin.z()),
342 gp_Pnt (aCornerMax.x(), aCornerMax.y(), aCornerMax.z()) };
343 gp_Pnt aConvertedPoints[aNbOfPoints];
344 Standard_Real aConvertedMinX = std::numeric_limits<double>::max();
345 Standard_Real aConvertedMaxX = -std::numeric_limits<double>::max();
346 Standard_Real aConvertedMinY = std::numeric_limits<double>::max();
347 Standard_Real aConvertedMaxY = -std::numeric_limits<double>::max();
348 for (Standard_Integer anIdx = 0; anIdx < aNbOfPoints; ++anIdx)
349 {
350 aConvertedPoints[anIdx] = theCamera->Project (aPoints[anIdx]);
351
352 aConvertedMinX = Min (aConvertedMinX, aConvertedPoints[anIdx].X());
353 aConvertedMaxX = Max (aConvertedMaxX, aConvertedPoints[anIdx].X());
354
355 aConvertedMinY = Min (aConvertedMinY, aConvertedPoints[anIdx].Y());
356 aConvertedMaxY = Max (aConvertedMaxY, aConvertedPoints[anIdx].Y());
357 }
358
359 const Standard_Boolean isBigObject = (Abs (aConvertedMaxX - aConvertedMinX) > 2.0) // width of zoom pers. object greater than width of window
360 || (Abs (aConvertedMaxY - aConvertedMinY) > 2.0); // height of zoom pers. object greater than height of window
361 const Standard_Boolean isAlreadyInScreen = (aConvertedMinX > -1.0 && aConvertedMinX < 1.0)
362 && (aConvertedMaxX > -1.0 && aConvertedMaxX < 1.0)
363 && (aConvertedMinY > -1.0 && aConvertedMinY < 1.0)
364 && (aConvertedMaxY > -1.0 && aConvertedMaxY < 1.0);
365 if (isBigObject || isAlreadyInScreen)
366 {
367 continue;
368 }
369
778cd667 370 const gp_Pnt aTPPoint = aStructure->TransformPersistence()->AnchorPoint();
50d06d8f 371 gp_Pnt aConvertedTPPoint = theCamera->Project (aTPPoint);
372 aConvertedTPPoint.SetZ (0.0);
373
374 if (aConvertedTPPoint.Coord().Modulus() < Precision::Confusion())
375 {
376 continue;
377 }
378
379 Standard_Real aShiftX = 0.0;
380 if (aConvertedMinX < -1.0)
381 {
382 aShiftX = ((aConvertedMaxX < -1.0) ? (-(1.0 + aConvertedMaxX) + (aConvertedMaxX - aConvertedMinX)) : -(1.0 + aConvertedMinX));
383 }
384 else if (aConvertedMaxX > 1.0)
385 {
386 aShiftX = ((aConvertedMinX > 1.0) ? ((aConvertedMinX - 1.0) + (aConvertedMaxX - aConvertedMinX)) : (aConvertedMaxX - 1.0));
387 }
388
389 Standard_Real aShiftY = 0.0;
390 if (aConvertedMinY < -1.0)
391 {
392 aShiftY = ((aConvertedMaxY < -1.0) ? (-(1.0 + aConvertedMaxY) + (aConvertedMaxY - aConvertedMinY)) : -(1.0 + aConvertedMinY));
393 }
394 else if (aConvertedMaxY > 1.0)
395 {
396 aShiftY = ((aConvertedMinY > 1.0) ? ((aConvertedMinY - 1.0) + (aConvertedMaxY - aConvertedMinY)) : (aConvertedMaxY - 1.0));
397 }
398
399 const Standard_Real aDifX = Abs (aConvertedTPPoint.X()) - aShiftX;
400 const Standard_Real aDifY = Abs (aConvertedTPPoint.Y()) - aShiftY;
401 if (aDifX > Precision::Confusion())
402 {
403 aMaxCoef = Max (aMaxCoef, Abs (aConvertedTPPoint.X()) / aDifX);
404 }
405 if (aDifY > Precision::Confusion())
406 {
407 aMaxCoef = Max (aMaxCoef, Abs (aConvertedTPPoint.Y()) / aDifY);
408 }
409 }
410 }
411
412 return (aMaxCoef > 0.0) ? aMaxCoef : 1.0;
413}
414
a1954302 415// =======================================================================
3fe9ce0e 416// function : updateBVH
a1954302 417// purpose :
418// =======================================================================
d325cb7f 419void Graphic3d_Layer::updateBVH() const
a1954302 420{
3fe9ce0e 421 if (!myIsBVHPrimitivesNeedsReset)
422 {
423 return;
424 }
425
426 myBVHPrimitives.Clear();
427 myBVHPrimitivesTrsfPers.Clear();
150ed3d5 428 myAlwaysRenderedMap.Clear();
3fe9ce0e 429 myIsBVHPrimitivesNeedsReset = Standard_False;
d325cb7f 430 for (Graphic3d_ArrayOfIndexedMapOfStructure::Iterator aMapIter (myArray); aMapIter.More(); aMapIter.Next())
a1954302 431 {
d325cb7f 432 const Graphic3d_IndexedMapOfStructure& aStructures = aMapIter.Value();
433 for (Graphic3d_IndexedMapOfStructure::Iterator aStructIter (aStructures); aStructIter.More(); aStructIter.Next())
825aa485 434 {
d325cb7f 435 const Graphic3d_CStructure* aStruct = aStructIter.Value();
3fe9ce0e 436 if (aStruct->IsAlwaysRendered())
825aa485 437 {
150ed3d5 438 aStruct->MarkAsNotCulled();
439 myAlwaysRenderedMap.Add (aStruct);
3fe9ce0e 440 }
778cd667 441 else if (aStruct->TransformPersistence().IsNull())
3fe9ce0e 442 {
443 myBVHPrimitives.Add (aStruct);
444 }
445 else
446 {
447 myBVHPrimitivesTrsfPers.Add (aStruct);
825aa485 448 }
449 }
a1954302 450 }
3fe9ce0e 451}
452
453// =======================================================================
2b8832bb 454// function : UpdateCulling
3fe9ce0e 455// purpose :
456// =======================================================================
d325cb7f 457void Graphic3d_Layer::UpdateCulling (Standard_Integer theViewId,
458 const Graphic3d_CullingTool& theSelector,
459 const Graphic3d_RenderingParams::FrustumCulling theFrustumCullingState)
3fe9ce0e 460{
461 updateBVH();
a1954302 462
15669413 463 myNbStructuresNotCulled = myNbStructures;
0e3025bc 464 if (theFrustumCullingState != Graphic3d_RenderingParams::FrustumCulling_NoUpdate)
a1954302 465 {
d325cb7f 466 Standard_Boolean toTraverse = (theFrustumCullingState == Graphic3d_RenderingParams::FrustumCulling_On);
467 for (Graphic3d_IndexedMapOfStructure::Iterator aStructIter (myBVHPrimitives.Structures()); aStructIter.More(); aStructIter.Next())
0e3025bc 468 {
d325cb7f 469 const Graphic3d_CStructure* aStruct = aStructIter.Value();
0e3025bc 470 aStruct->SetCulled (toTraverse);
471 }
d325cb7f 472 for (Graphic3d_IndexedMapOfStructure::Iterator aStructIter (myBVHPrimitivesTrsfPers.Structures()); aStructIter.More(); aStructIter.Next())
0e3025bc 473 {
d325cb7f 474 const Graphic3d_CStructure* aStruct = aStructIter.Value();
0e3025bc 475 aStruct->SetCulled (toTraverse);
476 }
a1954302 477 }
a1954302 478
0e3025bc 479 if (theFrustumCullingState != Graphic3d_RenderingParams::FrustumCulling_On)
2b8832bb 480 {
481 return;
482 }
483 if (myBVHPrimitives .Size() == 0
484 && myBVHPrimitivesTrsfPers.Size() == 0)
485 {
486 return;
487 }
488
15669413 489 myNbStructuresNotCulled = myAlwaysRenderedMap.Extent();
d325cb7f 490 Graphic3d_CullingTool::CullingContext aCullCtx;
2b8832bb 491 theSelector.SetCullingDistance(aCullCtx, myLayerSettings.CullingDistance());
492 theSelector.SetCullingSize (aCullCtx, myLayerSettings.CullingSize());
825aa485 493 for (Standard_Integer aBVHTreeIdx = 0; aBVHTreeIdx < 2; ++aBVHTreeIdx)
a1954302 494 {
825aa485 495 const Standard_Boolean isTrsfPers = aBVHTreeIdx == 1;
2b8832bb 496 opencascade::handle<BVH_Tree<Standard_Real, 3> > aBVHTree;
825aa485 497 if (isTrsfPers)
a1954302 498 {
825aa485 499 if (myBVHPrimitivesTrsfPers.Size() == 0)
825aa485 500 continue;
97f937cc 501
d325cb7f 502 const Graphic3d_Mat4d& aProjection = theSelector.ProjectionMatrix();
503 const Graphic3d_Mat4d& aWorldView = theSelector.WorldViewMatrix();
825aa485 504 const Graphic3d_WorldViewProjState& aWVPState = theSelector.WorldViewProjState();
91d96372 505 const Standard_Integer aViewportWidth = theSelector.ViewportWidth();
506 const Standard_Integer aViewportHeight = theSelector.ViewportHeight();
507
3fe9ce0e 508 aBVHTree = myBVHPrimitivesTrsfPers.BVH (theSelector.Camera(), aProjection, aWorldView, aViewportWidth, aViewportHeight, aWVPState);
825aa485 509 }
510 else
511 {
512 if (myBVHPrimitives.Size() == 0)
825aa485 513 continue;
97f937cc 514
825aa485 515 aBVHTree = myBVHPrimitives.BVH();
516 }
517
2b8832bb 518 if (theSelector.IsCulled (aCullCtx, aBVHTree->MinPoint (0), aBVHTree->MaxPoint (0)))
825aa485 519 {
520 continue;
521 }
522
f5b72419 523 Standard_Integer aStack[BVH_Constants_MaxTreeDepth];
825aa485 524 Standard_Integer aHead = -1;
2b8832bb 525 Standard_Integer aNode = 0; // a root node
825aa485 526 for (;;)
527 {
528 if (!aBVHTree->IsOuter (aNode))
a1954302 529 {
f2474958 530 const Standard_Integer aLeftChildIdx = aBVHTree->Child<0> (aNode);
531 const Standard_Integer aRightChildIdx = aBVHTree->Child<1> (aNode);
2b8832bb 532 const Standard_Boolean isLeftChildIn = !theSelector.IsCulled (aCullCtx, aBVHTree->MinPoint (aLeftChildIdx), aBVHTree->MaxPoint (aLeftChildIdx));
533 const Standard_Boolean isRightChildIn = !theSelector.IsCulled (aCullCtx, aBVHTree->MinPoint (aRightChildIdx), aBVHTree->MaxPoint (aRightChildIdx));
825aa485 534 if (isLeftChildIn
535 && isRightChildIn)
536 {
537 aNode = myBVHIsLeftChildQueuedFirst ? aLeftChildIdx : aRightChildIdx;
538 aStack[++aHead] = myBVHIsLeftChildQueuedFirst ? aRightChildIdx : aLeftChildIdx;
539 myBVHIsLeftChildQueuedFirst = !myBVHIsLeftChildQueuedFirst;
540 }
541 else if (isLeftChildIn
542 || isRightChildIn)
543 {
544 aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
545 }
546 else
547 {
548 if (aHead < 0)
549 {
550 break;
551 }
552
553 aNode = aStack[aHead--];
554 }
a1954302 555 }
556 else
557 {
825aa485 558 Standard_Integer aIdx = aBVHTree->BegPrimitive (aNode);
d325cb7f 559 const Graphic3d_CStructure* aStruct = isTrsfPers
560 ? myBVHPrimitivesTrsfPers.GetStructureById (aIdx)
561 : myBVHPrimitives.GetStructureById (aIdx);
5dc0517d 562 if (aStruct->IsVisible (theViewId))
563 {
564 aStruct->MarkAsNotCulled();
565 ++myNbStructuresNotCulled;
566 }
a1954302 567 if (aHead < 0)
568 {
825aa485 569 break;
a1954302 570 }
571
14a35e5d 572 aNode = aStack[aHead--];
a1954302 573 }
574 }
a1954302 575 }
576}
577
578// =======================================================================
579// function : Append
580// purpose :
581// =======================================================================
d325cb7f 582Standard_Boolean Graphic3d_Layer::Append (const Graphic3d_Layer& theOther)
a1954302 583{
584 // the source priority list shouldn't have more priorities
585 const Standard_Integer aNbPriorities = theOther.NbPriorities();
586 if (aNbPriorities > NbPriorities())
587 {
588 return Standard_False;
589 }
590
591 // add all structures to destination priority list
592 for (Standard_Integer aPriorityIter = 0; aPriorityIter < aNbPriorities; ++aPriorityIter)
593 {
d325cb7f 594 const Graphic3d_IndexedMapOfStructure& aStructures = theOther.myArray (aPriorityIter);
595 for (Graphic3d_IndexedMapOfStructure::Iterator aStructIter (aStructures); aStructIter.More(); aStructIter.Next())
a1954302 596 {
7c3ef2f7 597 Add (aStructIter.Value(), aPriorityIter);
a1954302 598 }
599 }
600
601 return Standard_True;
602}
603
7c3ef2f7 604//=======================================================================
605//function : SetLayerSettings
606//purpose :
607//=======================================================================
d325cb7f 608void Graphic3d_Layer::SetLayerSettings (const Graphic3d_ZLayerSettings& theSettings)
7c3ef2f7 609{
610 const Standard_Boolean toUpdateTrsf = !myLayerSettings.Origin().IsEqual (theSettings.Origin(), gp::Resolution());
611 myLayerSettings = theSettings;
d325cb7f 612 if (!toUpdateTrsf)
7c3ef2f7 613 {
d325cb7f 614 return;
7c3ef2f7 615 }
616
d325cb7f 617 for (Graphic3d_ArrayOfIndexedMapOfStructure::Iterator aMapIter (myArray); aMapIter.More(); aMapIter.Next())
83da37b1 618 {
d325cb7f 619 Graphic3d_IndexedMapOfStructure& aStructures = aMapIter.ChangeValue();
620 for (Graphic3d_IndexedMapOfStructure::Iterator aStructIter (aStructures); aStructIter.More(); aStructIter.Next())
621 {
622 Graphic3d_CStructure* aStructure = const_cast<Graphic3d_CStructure* >(aStructIter.Value());
623 aStructure->updateLayerTransformation();
624 }
83da37b1 625 }
c5751993 626}