025314: Usage of smart pointers for dynamically allocated memory in BVH
authordbp <dbp@opencascade.com>
Fri, 10 Oct 2014 12:14:53 +0000 (16:14 +0400)
committerbugmaster <bugmaster@opencascade.com>
Fri, 10 Oct 2014 12:16:23 +0000 (16:16 +0400)
src/BVH/BVH_LinearBuilder.lxx
src/BVH/BVH_SweepPlaneBuilder.lxx

index 3507771..478c788 100644 (file)
@@ -17,6 +17,8 @@
 
 #include <Standard_Assert.hxx>
 
+#include <NCollection_Array1.hxx>
+
 #ifdef HAVE_TBB
   // On Windows, function TryEnterCriticalSection has appeared in Windows NT
   // and is surrounded by #ifdef in MS VC++ 7.1 headers.
@@ -396,11 +398,11 @@ void BVH_LinearBuilder<T, N>::Build (BVH_Set<T, N>*       theSet,
   const BVH_VecNt aSceneMin = theBox.CornerMin();
   const BVH_VecNt aSceneMax = theBox.CornerMax();
 
-  const BVH_VecNt aSceneSize = aSceneMax - aSceneMin;
+  const T aMinSize = static_cast<T> (BVH::THE_NODE_MIN_SIZE);
 
-  const T aReverseSizeX = static_cast<T> (aDimensionX) / (aSceneMax.x() - aSceneMin.x());
-  const T aReverseSizeY = static_cast<T> (aDimensionY) / (aSceneMax.y() - aSceneMin.y());
-  const T aReverseSizeZ = static_cast<T> (aDimensionZ) / (aSceneMax.z() - aSceneMin.z());
+  const T aReverseSizeX = static_cast<T> (aDimensionX) / Max (aMinSize, aSceneMax.x() - aSceneMin.x());
+  const T aReverseSizeY = static_cast<T> (aDimensionY) / Max (aMinSize, aSceneMax.y() - aSceneMin.y());
+  const T aReverseSizeZ = static_cast<T> (aDimensionZ) / Max (aMinSize, aSceneMax.z() - aSceneMin.z());
 
   std::vector<BVH_EncodedLink> anEncodedLinks (theSet->Size(), BVH_EncodedLink());
 
@@ -453,11 +455,11 @@ void BVH_LinearBuilder<T, N>::Build (BVH_Set<T, N>*       theSet,
   // Step 3 -- Emitting BVH hierarchy from sorted Morton codes
   EmitHierachy (theBVH, 29, 0, anEncodedLinks.begin(), anEncodedLinks.end());
 
-  Standard_Integer* aLinkMap = new Standard_Integer[theSet->Size()];
+  NCollection_Array1<Standard_Integer> aLinkMap (0, theSet->Size() - 1);
 
   for (Standard_Integer aLinkIdx = 0; aLinkIdx < theSet->Size(); ++aLinkIdx)
   {
-    aLinkMap[anEncodedLinks[aLinkIdx].second] = aLinkIdx;
+    aLinkMap (anEncodedLinks[aLinkIdx].second) = aLinkIdx;
   }
 
   // Step 4 -- Rearranging primitive list according to Morton codes (in place)
@@ -465,14 +467,14 @@ void BVH_LinearBuilder<T, N>::Build (BVH_Set<T, N>*       theSet,
 
   while (aPrimIdx < theSet->Size())
   {
-    const Standard_Integer aSortIdx = aLinkMap[aPrimIdx];
+    const Standard_Integer aSortIdx = aLinkMap (aPrimIdx);
 
     if (aPrimIdx != aSortIdx)
     {
       theSet->Swap (aPrimIdx, aSortIdx);
 
-      std::swap (aLinkMap[aPrimIdx],
-                 aLinkMap[aSortIdx]);
+      std::swap (aLinkMap (aPrimIdx),
+                 aLinkMap (aSortIdx));
     }
     else
     {
@@ -488,6 +490,8 @@ void BVH_LinearBuilder<T, N>::Build (BVH_Set<T, N>*       theSet,
 
 #ifdef HAVE_TBB
 
+  // Note: Although TBB tasks are allocated using placement
+  // new, we do not need to delete them explicitly
   BVH::UpdateBoundTask<T, N>& aRootTask = *new ( tbb::task::allocate_root() )
     BVH::UpdateBoundTask<T, N> (theSet, theBVH, 0, 0, &aDepth);
 
index 9454fba..1e85e67 100644 (file)
@@ -15,6 +15,8 @@
 
 #include <BVH_Sorter.hxx>
 
+#include <NCollection_Array1.hxx>
+
 // =======================================================================
 // function : BVH_SweepPlaneBuilder
 // purpose  :
@@ -60,8 +62,8 @@ void BVH_SweepPlaneBuilder<T, N>::BuildNode (BVH_Set<T, N>*         theSet,
   Standard_Integer aMinSplitAxis = -1;
   Standard_Integer aMinSplitIndex = 0;
 
-  Standard_Real* aLftSet = new Standard_Real[aNodeNbPrimitives];
-  Standard_Real* aRghSet = new Standard_Real[aNodeNbPrimitives];
+  NCollection_Array1<Standard_Real> aLftSet (0, aNodeNbPrimitives - 1);
+  NCollection_Array1<Standard_Real> aRghSet (0, aNodeNbPrimitives - 1);
 
   Standard_Real aMinSplitCost = std::numeric_limits<Standard_Real>::max();
 
@@ -80,15 +82,15 @@ void BVH_SweepPlaneBuilder<T, N>::BuildNode (BVH_Set<T, N>*         theSet,
     BVH_Box<T, N> aLftBox;
     BVH_Box<T, N> aRghBox;
 
-    *aLftSet = std::numeric_limits<T>::max();
-    *aRghSet = std::numeric_limits<T>::max();
+    aLftSet.ChangeFirst() = std::numeric_limits<T>::max();
+    aRghSet.ChangeFirst() = std::numeric_limits<T>::max();
 
     // Sweep from left
     for (Standard_Integer anIndex = 1; anIndex < aNodeNbPrimitives; ++anIndex)
     {
       aLftBox.Combine (theSet->Box (anIndex + aNodeBegPrimitive - 1));
 
-      aLftSet[anIndex] = static_cast<Standard_Real> (aLftBox.Area());
+      aLftSet (anIndex) = static_cast<Standard_Real> (aLftBox.Area());
     }
 
     // Sweep from right
@@ -96,14 +98,14 @@ void BVH_SweepPlaneBuilder<T, N>::BuildNode (BVH_Set<T, N>*         theSet,
     {
       aRghBox.Combine (theSet->Box (aNodeEndPrimitive - anIndex + 1));
 
-      aRghSet[anIndex] = static_cast<Standard_Real> (aRghBox.Area());
+      aRghSet (anIndex) = static_cast<Standard_Real> (aRghBox.Area());
     }
 
     // Find best split using simplified SAH
     for (Standard_Integer aNbLft = 1, aNbRgh = aNodeNbPrimitives - 1; aNbLft < aNodeNbPrimitives; ++aNbLft, --aNbRgh)
     {
-      Standard_Real aCost = (aLftSet[aNbLft] /* / aNodeArea */) * aNbLft +
-                            (aRghSet[aNbRgh] /* / aNodeArea */) * aNbRgh;
+      Standard_Real aCost = (aLftSet (aNbLft) /* / aNodeArea */) * aNbLft +
+                            (aRghSet (aNbRgh) /* / aNodeArea */) * aNbRgh;
 
       if (aCost < aMinSplitCost)
       {
@@ -114,9 +116,6 @@ void BVH_SweepPlaneBuilder<T, N>::BuildNode (BVH_Set<T, N>*         theSet,
     }
   }
 
-  delete [] aLftSet;
-  delete [] aRghSet;
-
   if (aMinSplitAxis == -1)
   {
     return;