X-Git-Url: http://git.dev.opencascade.org/gitweb/?p=occt.git;a=blobdiff_plain;f=src%2FGraphic3d%2FGraphic3d_Layer.cxx;h=6b723c8f31118229743394c57927729b8727668c;hp=2fb67ab20e5631b5a1e35a77e197951e2cb8a96d;hb=9ad4ff93a03daf951ec773b676c47f7c849cc35c;hpb=89fcfe15511463c9588c34d101fba7e795198200 diff --git a/src/Graphic3d/Graphic3d_Layer.cxx b/src/Graphic3d/Graphic3d_Layer.cxx index 2fb67ab..6b723c8 100644 --- a/src/Graphic3d/Graphic3d_Layer.cxx +++ b/src/Graphic3d/Graphic3d_Layer.cxx @@ -452,6 +452,19 @@ void Graphic3d_Layer::updateBVH() const } } +namespace +{ + //! This structure describes the node in BVH + struct NodeInStack + { + NodeInStack (Standard_Integer theId = 0, + Standard_Boolean theIsFullInside = false) : Id (theId), IsFullInside (theIsFullInside) {} + + Standard_Integer Id; //!< node identifier + Standard_Boolean IsFullInside; //!< if the node is completely inside + }; +} + // ======================================================================= // function : UpdateCulling // purpose : @@ -517,33 +530,54 @@ void Graphic3d_Layer::UpdateCulling (Standard_Integer theViewId, aBVHTree = myBVHPrimitives.BVH(); } - if (theSelector.IsCulled (aCullCtx, aBVHTree->MinPoint (0), aBVHTree->MaxPoint (0))) + const bool toCheckFullInside = true; + NodeInStack aNode (0, toCheckFullInside); // a root node + if (theSelector.IsCulled (aCullCtx, aBVHTree->MinPoint (0), aBVHTree->MaxPoint (0), toCheckFullInside ? &aNode.IsFullInside : NULL)) { continue; } - Standard_Integer aStack[BVH_Constants_MaxTreeDepth]; + NodeInStack aStack[BVH_Constants_MaxTreeDepth]; Standard_Integer aHead = -1; - Standard_Integer aNode = 0; // a root node for (;;) { - if (!aBVHTree->IsOuter (aNode)) + if (!aBVHTree->IsOuter (aNode.Id)) { - const Standard_Integer aLeftChildIdx = aBVHTree->Child<0> (aNode); - const Standard_Integer aRightChildIdx = aBVHTree->Child<1> (aNode); - const Standard_Boolean isLeftChildIn = !theSelector.IsCulled (aCullCtx, aBVHTree->MinPoint (aLeftChildIdx), aBVHTree->MaxPoint (aLeftChildIdx)); - const Standard_Boolean isRightChildIn = !theSelector.IsCulled (aCullCtx, aBVHTree->MinPoint (aRightChildIdx), aBVHTree->MaxPoint (aRightChildIdx)); + NodeInStack aLeft (aBVHTree->Child<0> (aNode.Id), toCheckFullInside); + NodeInStack aRight(aBVHTree->Child<1> (aNode.Id), toCheckFullInside); + bool isLeftChildIn = true, isRightChildIn = true; + if (aNode.IsFullInside) + { + // small size should be always checked + isLeftChildIn = !theSelector.IsTooSmall (aCullCtx, aBVHTree->MinPoint (aLeft.Id), aBVHTree->MaxPoint (aLeft.Id)); + isRightChildIn = !theSelector.IsTooSmall (aCullCtx, aBVHTree->MinPoint (aRight.Id), aBVHTree->MaxPoint (aRight.Id)); + } + else + { + isLeftChildIn = !theSelector.IsCulled (aCullCtx, aBVHTree->MinPoint (aLeft.Id), aBVHTree->MaxPoint (aLeft.Id), toCheckFullInside ? &aLeft.IsFullInside : NULL); + if (!isLeftChildIn) + { + aLeft.IsFullInside = false; + } + + isRightChildIn = !theSelector.IsCulled (aCullCtx, aBVHTree->MinPoint (aRight.Id), aBVHTree->MaxPoint (aRight.Id), toCheckFullInside ? &aRight.IsFullInside : NULL); + if (!isRightChildIn) + { + aRight.IsFullInside = false; + } + } + if (isLeftChildIn && isRightChildIn) { - aNode = myBVHIsLeftChildQueuedFirst ? aLeftChildIdx : aRightChildIdx; - aStack[++aHead] = myBVHIsLeftChildQueuedFirst ? aRightChildIdx : aLeftChildIdx; + aNode = myBVHIsLeftChildQueuedFirst ? aLeft : aRight; + aStack[++aHead] = myBVHIsLeftChildQueuedFirst ? aRight : aLeft; myBVHIsLeftChildQueuedFirst = !myBVHIsLeftChildQueuedFirst; } else if (isLeftChildIn || isRightChildIn) { - aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx; + aNode = isLeftChildIn ? aLeft : aRight; } else { @@ -557,8 +591,8 @@ void Graphic3d_Layer::UpdateCulling (Standard_Integer theViewId, } else { - const Standard_Integer aStartIdx = aBVHTree->BegPrimitive (aNode); - const Standard_Integer anEndIdx = aBVHTree->EndPrimitive (aNode); + const Standard_Integer aStartIdx = aBVHTree->BegPrimitive (aNode.Id); + const Standard_Integer anEndIdx = aBVHTree->EndPrimitive (aNode.Id); for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx) { const Graphic3d_CStructure* aStruct = isTrsfPers