]> OCCT Git - occt.git/commitdiff
0033866: Foundation Classes - BVH::SurfaceCalculator::Area() fails to calculate area... CR33866
authoroan <oan@opencascade.com>
Thu, 30 Jan 2025 15:35:15 +0000 (15:35 +0000)
committeroan <oan@opencascade.com>
Thu, 30 Jan 2025 15:35:15 +0000 (15:35 +0000)
Use absolute values of intermediate calculations to compute surface area of a box, so they do not diminish each other.

src/BVH/BVH_Box.hxx

index 6f808d31f55204de6760a9731b6d4cafaf973b30..85e18a4013edf99d7be8325a27d561d6f618b407 100644 (file)
@@ -427,11 +427,11 @@ struct SurfaceCalculator<T, 2>
 {
   static T Area(const typename BVH_Box<T, 2>::BVH_VecNt& theSize)
   {
-    const T anArea = theSize.x() * theSize.y();
+    const T anArea = std::abs (theSize.x() * theSize.y());
 
     if (anArea < std::numeric_limits<T>::epsilon())
     {
-      return theSize.x() + theSize.y();
+      return std::abs (theSize.x()) + std::abs (theSize.y());
     }
 
     return anArea;
@@ -444,12 +444,14 @@ struct SurfaceCalculator<T, 3>
   static T Area(const typename BVH_Box<T, 3>::BVH_VecNt& theSize)
   {
     const T anArea =
-      (theSize.x() * theSize.y() + theSize.x() * theSize.z() + theSize.z() * theSize.y())
+      (std::abs (theSize.x() * theSize.y()) + 
+       std::abs (theSize.x() * theSize.z()) + 
+       std::abs (theSize.z() * theSize.y()))
       * static_cast<T>(2.0);
 
     if (anArea < std::numeric_limits<T>::epsilon())
     {
-      return theSize.x() + theSize.y() + theSize.z();
+      return std::abs (theSize.x()) + std::abs (theSize.y()) + std::abs (theSize.z());
     }
 
     return anArea;
@@ -462,12 +464,14 @@ struct SurfaceCalculator<T, 4>
   static T Area(const typename BVH_Box<T, 4>::BVH_VecNt& theSize)
   {
     const T anArea =
-      (theSize.x() * theSize.y() + theSize.x() * theSize.z() + theSize.z() * theSize.y())
+      (std::abs (theSize.x() * theSize.y()) + 
+       std::abs (theSize.x() * theSize.z()) + 
+       std::abs (theSize.z() * theSize.y()))
       * static_cast<T>(2.0);
 
     if (anArea < std::numeric_limits<T>::epsilon())
     {
-      return theSize.x() + theSize.y() + theSize.z();
+      return std::abs (theSize.x()) + std::abs (theSize.y()) + std::abs (theSize.z());
     }
 
     return anArea;