0025679: Visualization, TKOpenGl - View frustum culling clips wrong objects
authorvpa <vpa@opencascade.com>
Wed, 28 Jan 2015 09:21:58 +0000 (12:21 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 29 Jan 2015 11:05:40 +0000 (14:05 +0300)
Corrected area calculation for degenerated AABBs in BVH_Box;
Test case for issue 25679.

src/BVH/BVH_Box.hxx
tests/bugs/vis/bug25679 [new file with mode: 0644]

index 95c2d7c..838fb90 100644 (file)
@@ -18,6 +18,8 @@
 
 #include <BVH_Types.hxx>
 
+#include <limits>
+
 //! Defines axis aligned bounding box (AABB) based on BVH vectors.
 //! \tparam T Numeric data type
 //! \tparam N Vector dimension
@@ -79,6 +81,7 @@ public:
   BVH_VecNt& CornerMax();
 
   //! Returns surface area of bounding box.
+  //! If the box is degenerated into line, returns the perimeter instead.
   T Area() const;
 
   //! Returns diagonal of bounding box.
@@ -182,7 +185,14 @@ namespace BVH
   {
     static T Area (const typename BVH_Box<T, 2>::BVH_VecNt& theSize)
     {
-      return theSize.x() * theSize.y();
+      const T anArea = theSize.x() * theSize.y();
+
+      if (anArea < std::numeric_limits<T>::epsilon())
+      {
+        return theSize.x() + theSize.y();
+      }
+
+      return anArea;
     }
   };
 
@@ -191,9 +201,18 @@ namespace BVH
   {
     static T Area (const typename BVH_Box<T, 3>::BVH_VecNt& theSize)
     {
-      return ( theSize.x() * theSize.y() +
-               theSize.x() * theSize.z() +
-               theSize.z() * theSize.y() ) * static_cast<T> (2.0);
+      const T anArea = ( theSize.x() * theSize.y() +
+                         theSize.x() * theSize.z() +
+                         theSize.z() * theSize.y() ) * static_cast<T> (2.0);
+
+      if (anArea < std::numeric_limits<T>::epsilon())
+      {
+        return theSize.x() +
+               theSize.y() +
+               theSize.z();
+      }
+
+      return anArea;
     }
   };
 
@@ -202,9 +221,18 @@ namespace BVH
   {
     static T Area (const typename BVH_Box<T, 4>::BVH_VecNt& theSize)
     {
-      return ( theSize.x() * theSize.y() +
-               theSize.x() * theSize.z() +
-               theSize.z() * theSize.y() ) * static_cast<T> (2.0);
+      const T anArea = ( theSize.x() * theSize.y() +
+                         theSize.x() * theSize.z() +
+                         theSize.z() * theSize.y() ) * static_cast<T> (2.0);
+
+      if (anArea < std::numeric_limits<T>::epsilon())
+      {
+        return theSize.x() +
+               theSize.y() +
+               theSize.z();
+      }
+
+      return anArea;
     }
   };
 
diff --git a/tests/bugs/vis/bug25679 b/tests/bugs/vis/bug25679
new file mode 100644 (file)
index 0000000..591c650
--- /dev/null
@@ -0,0 +1,38 @@
+puts "========"
+puts "OCC25679"
+puts "========"
+puts ""
+############################################################################
+# Visualization, TKOpenGl - View frustum culling clips wrong objects
+############################################################################
+
+pload VISUALIZATION MODELING
+
+set LINES_IN_ROW 50
+
+set aNoCulling $imagedir/${casename}_without.png
+set aWithCulling $imagedir/${casename}_with.png
+set aDiff $imagedir/${casename}_diff.png
+
+vinit
+
+for {set i 0} {$i < $LINES_IN_ROW} {incr i} {
+  for {set j 0} {$j < $LINES_IN_ROW} {incr j} {
+    set aLineName "line"
+    append aLineName [expr $i * $LINES_IN_ROW + $j]
+    vline $aLineName 0 0 0 1 0 0
+    vsetlocation $aLineName [expr $i * 3] [expr $j * 3] 0
+  }
+}
+
+vfit
+
+vfrustumculling 1
+vdump $aWithCulling
+vfrustumculling 0
+vdump $aNoCulling
+
+set aDiffRes [diffimage $aWithCulling $aNoCulling 0.1 0 0 $aDiff]
+if {$aDiffRes != 0} {
+  puts "ERROR : Test failed: there is a difference between images rendered with and without frustum culling"
+}