]> OCCT Git - occt.git/commitdiff
Foundation Classes - BVH surface area calculation for transformed boxes #322
authoroan <oan@opencascade.com>
Sat, 1 Feb 2025 00:22:19 +0000 (00:22 +0000)
committerdpasukhi <dpasukhi@opencascade.com>
Sat, 1 Feb 2025 00:22:19 +0000 (00:22 +0000)
BVH::SurfaceCalculator::Area() fails to calculate area of transformed box.
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..2bae241ffe5a04f48b0af57b66bf11496ec6ca3c 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;
@@ -443,13 +443,13 @@ 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())
-      * static_cast<T>(2.0);
+    const T anArea = (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;
@@ -461,13 +461,13 @@ 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())
-      * static_cast<T>(2.0);
+    const T anArea = (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;