From a1c05aa5ece36c49dc680430d32effea3ce791a6 Mon Sep 17 00:00:00 2001 From: dbp Date: Tue, 23 Jun 2015 12:34:06 +0300 Subject: [PATCH] 0026364: Foundation Classes, TKMath - Optimize BVH binned algorithm --- src/BVH/BVH_BinnedBuilder.hxx | 12 ++++++++- src/BVH/BVH_BinnedBuilder.lxx | 50 +++++++++++++++++------------------ 2 files changed, 35 insertions(+), 27 deletions(-) diff --git a/src/BVH/BVH_BinnedBuilder.hxx b/src/BVH/BVH_BinnedBuilder.hxx index 80d2dc98b6..011295f8a5 100644 --- a/src/BVH/BVH_BinnedBuilder.hxx +++ b/src/BVH/BVH_BinnedBuilder.hxx @@ -42,9 +42,19 @@ class BVH_BinnedBuilder : public BVH_QueueBuilder { public: - //! Type for the array of bins of BVH tree node. + //! Type of the array of bins of BVH tree node. typedef BVH_Bin BVH_BinVector[Bins]; + //! Describes split plane candidate. + struct BVH_SplitPlane + { + BVH_Bin LftVoxel; + BVH_Bin RghVoxel; + }; + + //! Type of the array of split plane candidates. + typedef BVH_SplitPlane BVH_SplitPlanes[Bins + 1]; + public: //! Creates binned SAH BVH builder. diff --git a/src/BVH/BVH_BinnedBuilder.lxx b/src/BVH/BVH_BinnedBuilder.lxx index c0d95c7020..5be6c34e97 100644 --- a/src/BVH/BVH_BinnedBuilder.lxx +++ b/src/BVH/BVH_BinnedBuilder.lxx @@ -212,45 +212,43 @@ typename BVH_QueueBuilder::BVH_ChildNodes BVH_BinnedBuilder::B for (Standard_Integer anAxis = myUseMainAxis ? aMainAxis : 0; anAxis <= (myUseMainAxis ? aMainAxis : Min (N - 1, 2)); ++anAxis) { if (BVH::VecComp::Get (aSize, anAxis) <= BVH::THE_NODE_MIN_SIZE) + { continue; + } - BVH_BinVector aBins; - GetSubVolumes (theSet, theBVH, theNode, aBins, anAxis); + BVH_BinVector aBinVector; + GetSubVolumes (theSet, theBVH, theNode, aBinVector, anAxis); + + BVH_SplitPlanes aSplitPlanes; + for (Standard_Integer aLftSplit = 1, aRghSplit = Bins - 1; aLftSplit < Bins; ++aLftSplit, --aRghSplit) + { + aSplitPlanes[aLftSplit].LftVoxel.Count = aSplitPlanes[aLftSplit - 1].LftVoxel.Count + aBinVector[aLftSplit - 1].Count; + aSplitPlanes[aRghSplit].RghVoxel.Count = aSplitPlanes[aRghSplit + 1].RghVoxel.Count + aBinVector[aRghSplit + 0].Count; + + aSplitPlanes[aLftSplit].LftVoxel.Box = aSplitPlanes[aLftSplit - 1].LftVoxel.Box; + aSplitPlanes[aRghSplit].RghVoxel.Box = aSplitPlanes[aRghSplit + 1].RghVoxel.Box; + + aSplitPlanes[aLftSplit].LftVoxel.Box.Combine (aBinVector[aLftSplit - 1].Box); + aSplitPlanes[aRghSplit].RghVoxel.Box.Combine (aBinVector[aRghSplit + 0].Box); + } // Choose the best split (with minimum SAH cost) for (Standard_Integer aSplit = 1; aSplit < Bins; ++aSplit) { - Standard_Integer aLftCount = 0; - Standard_Integer aRghCount = 0; - - BVH_Box aLftAABB; - BVH_Box aRghAABB; - - for (Standard_Integer anIndex = 0; anIndex < aSplit; ++anIndex) - { - aLftCount += aBins[anIndex].Count; - aLftAABB.Combine (aBins[anIndex].Box); - } - - for (Standard_Integer anIndex = aSplit; anIndex < Bins; ++anIndex) - { - aRghCount += aBins[anIndex].Count; - aRghAABB.Combine (aBins[anIndex].Box); - } - // Simple SAH evaluation - Standard_Real aCost = (static_cast (aLftAABB.Area()) /* / aNodeArea */) * aLftCount - + (static_cast (aRghAABB.Area()) /* / aNodeArea */) * aRghCount; + Standard_Real aCost = + (static_cast (aSplitPlanes[aSplit].LftVoxel.Box.Area()) /* / S(N) */) * aSplitPlanes[aSplit].LftVoxel.Count + + (static_cast (aSplitPlanes[aSplit].RghVoxel.Box.Area()) /* / S(N) */) * aSplitPlanes[aSplit].RghVoxel.Count; if (aCost <= aMinSplitCost) { aMinSplitCost = aCost; aMinSplitAxis = anAxis; aMinSplitIndex = aSplit; - aMinSplitBoxLft = aLftAABB; - aMinSplitBoxRgh = aRghAABB; - aMinSplitNumLft = aLftCount; - aMinSplitNumRgh = aRghCount; + aMinSplitBoxLft = aSplitPlanes[aSplit].LftVoxel.Box; + aMinSplitBoxRgh = aSplitPlanes[aSplit].RghVoxel.Box; + aMinSplitNumLft = aSplitPlanes[aSplit].LftVoxel.Count; + aMinSplitNumRgh = aSplitPlanes[aSplit].RghVoxel.Count; } } }