[Bf-blender-cvs] [83cb3879442] master: BLI math: clamped barycentric weight calculation

Campbell Barton noreply at git.blender.org
Sat Apr 21 18:35:59 CEST 2018


Commit: 83cb3879442ab29cbfc7a0c56af48bef823aa826
Author: Campbell Barton
Date:   Sat Apr 21 18:34:20 2018 +0200
Branches: master
https://developer.blender.org/rB83cb3879442ab29cbfc7a0c56af48bef823aa826

BLI math: clamped barycentric weight calculation

===================================================================

M	source/blender/blenlib/BLI_math_geom.h
M	source/blender/blenlib/intern/math_geom.c

===================================================================

diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h
index ffe0ce11cef..ff80d15ea5d 100644
--- a/source/blender/blenlib/BLI_math_geom.h
+++ b/source/blender/blenlib/BLI_math_geom.h
@@ -356,12 +356,18 @@ void transform_point_by_seg_v3(
         const float l_dst_p1[3], const float l_dst_p2[3],
         const float l_src_p1[3], const float l_src_p2[3]);
 
-void barycentric_weights_v2(const float v1[2], const float v2[2], const float v3[2],
-                            const float co[2], float w[3]);
-void barycentric_weights_v2_persp(const float v1[4], const float v2[4], const float v3[4],
-                                  const float co[2], float w[3]);
-void barycentric_weights_v2_quad(const float v1[2], const float v2[2], const float v3[2], const float v4[2],
-                                 const float co[2], float w[4]);
+void barycentric_weights_v2(
+        const float v1[2], const float v2[2], const float v3[2],
+        const float co[2], float w[3]);
+void barycentric_weights_v2_clamped(
+        const float v1[2], const float v2[2], const float v3[2],
+        const float co[2], float w[3]);
+void barycentric_weights_v2_persp(
+        const float v1[4], const float v2[4], const float v3[4],
+        const float co[2], float w[3]);
+void barycentric_weights_v2_quad(
+        const float v1[2], const float v2[2], const float v3[2], const float v4[2],
+        const float co[2], float w[4]);
 
 bool barycentric_coords_v2(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3]);
 int barycentric_inside_triangle_v2(const float w[3]);
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index e179447936a..ee6a3dcc9b3 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -3021,7 +3021,9 @@ bool barycentric_coords_v2(const float v1[2], const float v2[2], const float v3[
  * \note This is *exactly* the same calculation as #resolve_tri_uv_v2,
  * although it has double precision and is used for texture baking, so keep both.
  */
-void barycentric_weights_v2(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3])
+void barycentric_weights_v2(
+        const float v1[2], const float v2[2], const float v3[2],
+        const float co[2], float w[3])
 {
 	float wtot;
 
@@ -3038,11 +3040,36 @@ void barycentric_weights_v2(const float v1[2], const float v2[2], const float v3
 	}
 }
 
+/**
+ * A version of #barycentric_weights_v2 that doesn't allow negative weights.
+ * Useful when negative values cause problems and points are only ever slightly outside of the triangle.
+ */
+void barycentric_weights_v2_clamped(
+        const float v1[2], const float v2[2], const float v3[2],
+        const float co[2], float w[3])
+{
+	float wtot;
+
+	w[0] = max_ff(cross_tri_v2(v2, v3, co), 0.0f);
+	w[1] = max_ff(cross_tri_v2(v3, v1, co), 0.0f);
+	w[2] = max_ff(cross_tri_v2(v1, v2, co), 0.0f);
+	wtot = w[0] + w[1] + w[2];
+
+	if (wtot != 0.0f) {
+		mul_v3_fl(w, 1.0f / wtot);
+	}
+	else { /* dummy values for zero area face */
+		copy_v3_fl(w, 1.0f / 3.0f);
+	}
+}
+
 /**
  * still use 2D X,Y space but this works for verts transformed by a perspective matrix,
  * using their 4th component as a weight
  */
-void barycentric_weights_v2_persp(const float v1[4], const float v2[4], const float v3[4], const float co[2], float w[3])
+void barycentric_weights_v2_persp(
+        const float v1[4], const float v2[4], const float v3[4],
+        const float co[2], float w[3])
 {
 	float wtot;
 
@@ -3064,8 +3091,9 @@ void barycentric_weights_v2_persp(const float v1[4], const float v2[4], const fl
  * note: untested for values outside the quad's bounds
  * this is #interp_weights_poly_v2 expanded for quads only
  */
-void barycentric_weights_v2_quad(const float v1[2], const float v2[2], const float v3[2], const float v4[2],
-                                 const float co[2], float w[4])
+void barycentric_weights_v2_quad(
+        const float v1[2], const float v2[2], const float v3[2], const float v4[2],
+        const float co[2], float w[4])
 {
 	/* note: fabsf() here is not needed for convex quads (and not used in interp_weights_poly_v2).
 	 *       but in the case of concave/bow-tie quads for the mask rasterizer it gives unreliable results



More information about the Bf-blender-cvs mailing list