[Bf-blender-cvs] [1e9003a] surface-deform-modifier: Add is_poly_convex_v3 function

Luca Rood noreply at git.blender.org
Wed Nov 30 02:09:45 CET 2016


Commit: 1e9003aea5a9da97974fa3bafcc20eb4a0b3c925
Author: Luca Rood
Date:   Fri Nov 25 14:46:11 2016 -0200
Branches: surface-deform-modifier
https://developer.blender.org/rB1e9003aea5a9da97974fa3bafcc20eb4a0b3c925

Add is_poly_convex_v3 function

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

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 514b030..9039225 100644
--- a/source/blender/blenlib/BLI_math_geom.h
+++ b/source/blender/blenlib/BLI_math_geom.h
@@ -85,6 +85,7 @@ float volume_tetrahedron_v3(const float v1[3], const float v2[3], const float v3
 float volume_tetrahedron_signed_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
 
 bool is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
+bool is_poly_convex_v3(const float verts[][3], unsigned int nr);
 bool is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]);
 bool is_poly_convex_v2(const float verts[][2], unsigned int nr);
 int  is_quad_flip_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index f31d093..654c2ae 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -4791,54 +4791,56 @@ float form_factor_hemi_poly(float p[3], float n[3], float v1[3], float v2[3], fl
  */
 bool is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3])
 {
-	/**
-	 * Method projects points onto a plane and checks its convex using following method:
-	 *
-	 * - Create a plane from the cross-product of both diagonal vectors.
-	 * - Project all points onto the plane.
-	 * - Subtract for direction vectors.
-	 * - Return true if all corners cross-products point the direction of the plane.
-	 */
+	const float verts[4][3] = {{UNPACK3(v1)}, {UNPACK3(v2)}, {UNPACK3(v3)}, {UNPACK3(v4)}};
+	return is_poly_convex_v3(verts, 4);
+}
+
+/**
+ * Check if polygon is convex
+ */
+bool is_poly_convex_v3(const float verts[][3], unsigned int nr)
+{
+	const float *co_curr, *co_prev;
+	float vec_curr[3], vec_prev[3];
+	float normal[3];
+	unsigned int i;
 
-	/* non-unit length normal, used as a projection plane */
-	float plane[3];
+	if (nr == 3)
+		return true;
 
-	{
-		float v13[3], v24[3];
+	co_prev = verts[nr - 1];
+	co_curr = verts[0];
 
-		sub_v3_v3v3(v13, v1, v3);
-		sub_v3_v3v3(v24, v2, v4);
+	/* Non-unit length normal, just to check angle directions */
+	cross_poly_v3(normal, verts, nr);
 
-		cross_v3_v3v3(plane, v13, v24);
+	sub_v3_v3v3(vec_prev, co_prev, verts[nr - 2]);
 
-		if (len_squared_v3(plane) < FLT_EPSILON) {
-			return false;
-		}
-	}
+	/**
+	 * Implementation note: there is no need to project the vertices onto the normal plane,
+	 * because even if the polygon is highly non-planar, the cross product between
+	 * adjacent edges will always point to the same side as the normal when convex,
+	 * and to the opposite side when concave.
+	 */
 
-	const float *quad_coords[4] = {v1, v2, v3, v4};
-	float        quad_proj[4][3];
+	for (i = 0; i < nr; i++) {
+		float cross[3];
 
-	for (int i = 0; i < 4; i++) {
-		project_plane_v3_v3v3(quad_proj[i], quad_coords[i], plane);
-	}
+		sub_v3_v3v3(vec_curr, co_curr, co_prev);
 
-	float        quad_dirs[4][3];
-	for (int i = 0, j = 3; i < 4; j = i++) {
-		sub_v3_v3v3(quad_dirs[i], quad_proj[i], quad_proj[j]);
-	}
+		cross_v3_v3v3(cross, vec_prev, vec_curr);
 
-	float test_dir[3];
+		if (dot_v3v3(cross, normal) < 0.0f) {
+			return false;
+		}
 
-#define CROSS_SIGN(dir_a, dir_b) \
-	((void)cross_v3_v3v3(test_dir, dir_a, dir_b), (dot_v3v3(plane, test_dir) > 0.0f))
+		copy_v3_v3(vec_prev, vec_curr);
 
-	return (CROSS_SIGN(quad_dirs[0], quad_dirs[1]) &&
-	        CROSS_SIGN(quad_dirs[1], quad_dirs[2]) &&
-	        CROSS_SIGN(quad_dirs[2], quad_dirs[3]) &&
-	        CROSS_SIGN(quad_dirs[3], quad_dirs[0]));
+		co_prev = co_curr;
+		co_curr += 3;
+	}
 
-#undef CROSS_SIGN
+	return true;
 }
 
 bool is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2])




More information about the Bf-blender-cvs mailing list