[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [59866] trunk/blender/source/blender/ blenlib/intern/math_geom.c: fix for barycentric_weights_v2_quad() divide by zero when the location we' re checking the weight of touches one of the weighting coords exactly.

Campbell Barton ideasman42 at gmail.com
Fri Sep 6 07:44:18 CEST 2013


Revision: 59866
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=59866
Author:   campbellbarton
Date:     2013-09-06 05:44:18 +0000 (Fri, 06 Sep 2013)
Log Message:
-----------
fix for barycentric_weights_v2_quad() divide by zero when the location we're checking the weight of touches one of the weighting coords exactly.

Modified Paths:
--------------
    trunk/blender/source/blender/blenlib/intern/math_geom.c

Modified: trunk/blender/source/blender/blenlib/intern/math_geom.c
===================================================================
--- trunk/blender/source/blender/blenlib/intern/math_geom.c	2013-09-06 02:59:25 UTC (rev 59865)
+++ trunk/blender/source/blender/blenlib/intern/math_geom.c	2013-09-06 05:44:18 UTC (rev 59866)
@@ -2200,8 +2200,6 @@
 	        ((_area = cross_v2v2(dirs[i1], dirs[i2])) != 0.0f ? \
 	         fabsf(((lens[i1] * lens[i2]) - dot_v2v2(dirs[i1], dirs[i2])) / _area) : 0.0f)
 
-	float wtot, area;
-
 	const float dirs[4][2] = {
 	    {v1[0] - co[0], v1[1] - co[1]},
 	    {v2[0] - co[0], v2[1] - co[1]},
@@ -2216,20 +2214,29 @@
 	    len_v2(dirs[3]),
 	};
 
-	/* variable 'area' is just for storage,
-	 * the order its initialized doesn't matter */
+	/* avoid divide by zero */
+	if      (UNLIKELY(lens[0] < FLT_EPSILON)) { w[0] = 1.0f; w[1] = w[2] = w[3] = 0.0f; }
+	else if (UNLIKELY(lens[1] < FLT_EPSILON)) { w[1] = 1.0f; w[0] = w[2] = w[3] = 0.0f; }
+	else if (UNLIKELY(lens[2] < FLT_EPSILON)) { w[2] = 1.0f; w[0] = w[1] = w[3] = 0.0f; }
+	else if (UNLIKELY(lens[3] < FLT_EPSILON)) { w[3] = 1.0f; w[0] = w[1] = w[2] = 0.0f;
+	}
+	else {
+		float wtot, area;
+
+		/* variable 'area' is just for storage,
+		 * the order its initialized doesn't matter */
 #ifdef __clang__
 #  pragma clang diagnostic push
 #  pragma clang diagnostic ignored "-Wunsequenced"
 #endif
 
-	/* inline mean_value_half_tan four times here */
-	float t[4] = {
-	    MEAN_VALUE_HALF_TAN_V2(area, 0, 1),
-	    MEAN_VALUE_HALF_TAN_V2(area, 1, 2),
-	    MEAN_VALUE_HALF_TAN_V2(area, 2, 3),
-	    MEAN_VALUE_HALF_TAN_V2(area, 3, 0),
-	};
+		/* inline mean_value_half_tan four times here */
+		float t[4] = {
+			MEAN_VALUE_HALF_TAN_V2(area, 0, 1),
+			MEAN_VALUE_HALF_TAN_V2(area, 1, 2),
+			MEAN_VALUE_HALF_TAN_V2(area, 2, 3),
+			MEAN_VALUE_HALF_TAN_V2(area, 3, 0),
+		};
 
 #ifdef __clang__
 #  pragma clang diagnostic pop
@@ -2237,19 +2244,20 @@
 
 #undef MEAN_VALUE_HALF_TAN_V2
 
-	w[0] = (t[3] + t[0]) / lens[0];
-	w[1] = (t[0] + t[1]) / lens[1];
-	w[2] = (t[1] + t[2]) / lens[2];
-	w[3] = (t[2] + t[3]) / lens[3];
+		w[0] = (t[3] + t[0]) / lens[0];
+		w[1] = (t[0] + t[1]) / lens[1];
+		w[2] = (t[1] + t[2]) / lens[2];
+		w[3] = (t[2] + t[3]) / lens[3];
 
-	wtot = w[0] + w[1] + w[2] + w[3];
+		wtot = w[0] + w[1] + w[2] + w[3];
 
-	if (wtot != 0.0f) {
-		mul_v4_fl(w, 1.0f / wtot);
+		if (wtot != 0.0f) {
+			mul_v4_fl(w, 1.0f / wtot);
+		}
+		else { /* dummy values for zero area face */
+			copy_v4_fl(w, 1.0f / 4.0f);
+		}
 	}
-	else { /* dummy values for zero area face */
-		copy_v4_fl(w, 1.0f / 4.0f);
-	}
 }
 
 /* given 2 triangles in 3D space, and a point in relation to the first triangle.




More information about the Bf-blender-cvs mailing list