[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [60362] trunk/blender/source/blender/ editors/mesh/editmesh_knife.c: fix [#36780] Knife Project broken

Campbell Barton ideasman42 at gmail.com
Wed Sep 25 10:23:31 CEST 2013


Revision: 60362
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=60362
Author:   campbellbarton
Date:     2013-09-25 08:23:31 +0000 (Wed, 25 Sep 2013)
Log Message:
-----------
fix [#36780] Knife Project broken
was regression in r59665 (fix for [#35002]).

now when checking a segment that lies on the same plane as the triangle intersects,
clip the segment by the triangle bounds so we know the points remain inside the triangle.

Revision Links:
--------------
    http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=59665

Modified Paths:
--------------
    trunk/blender/source/blender/editors/mesh/editmesh_knife.c

Modified: trunk/blender/source/blender/editors/mesh/editmesh_knife.c
===================================================================
--- trunk/blender/source/blender/editors/mesh/editmesh_knife.c	2013-09-24 23:28:19 UTC (rev 60361)
+++ trunk/blender/source/blender/editors/mesh/editmesh_knife.c	2013-09-25 08:23:31 UTC (rev 60362)
@@ -1233,6 +1233,69 @@
 	return sqrtf(max_fff(s1, s2, s3));
 }
 
+/**
+ * given a tri, return 3 planes aligned with the tri's normal.
+ *
+ * If the triangle were extruded along its normal,
+ * the planes calculated would be the 3 sides around the extrusion.
+ */
+static void plane_from_tri_clip3_v3(
+        float tri_plane_clip[3][4],
+        const float v0[3], const float v1[3], const float v2[3])
+{
+	float tri_norm[3];
+	float tvec[3], cross[3];
+
+	normal_tri_v3(tri_norm, v0, v1, v2);
+
+	sub_v3_v3v3(tvec, v0, v1);
+	cross_v3_v3v3(cross, tvec, tri_norm);
+	plane_from_point_normal_v3(tri_plane_clip[0], v0, cross);
+
+	sub_v3_v3v3(tvec, v1, v2);
+	cross_v3_v3v3(cross, tvec, tri_norm);
+	plane_from_point_normal_v3(tri_plane_clip[1], v1, cross);
+
+	sub_v3_v3v3(tvec, v2, v0);
+	cross_v3_v3v3(cross, tvec, tri_norm);
+	plane_from_point_normal_v3(tri_plane_clip[2], v2, cross);
+}
+
+/**
+ * Given a line that is planar with a tri, clip the segment by that tri.
+ *
+ * This is needed so we end up with both points in the triangle.
+ */
+static bool isect_line_tri_coplanar_v3(
+        const float p1[3], const float p2[3],
+        const float v0[3], const float v1[3], const float v2[3],
+        float r_isects[2][3],
+
+        /* avoid re-calculating every time */
+        float tri_plane[4], float tri_plane_clip[3][4])
+{
+	float p1_tmp[3] = {UNPACK3(p1)};
+	float p2_tmp[3] = {UNPACK3(p2)};
+
+	(void)v0, (void)v1, (void)v2;
+
+	/* first check if the points are planar with the tri */
+	if ((fabsf(dist_squared_to_plane_v3(p1, tri_plane)) < KNIFE_FLT_EPS_SQUARED) &&
+	    (fabsf(dist_squared_to_plane_v3(p2, tri_plane)) < KNIFE_FLT_EPS_SQUARED) &&
+	    /* clip the segment by planes around the triangle so we can be sure the points
+	     * aren't outside the triangle */
+	    (clip_segment_v3_plane_n(p1_tmp, p2_tmp, tri_plane_clip, 3)))
+	{
+		copy_v3_v3(r_isects[0], p1_tmp);
+		copy_v3_v3(r_isects[1], p2_tmp);
+
+		return true;
+	}
+	else {
+		return false;
+	}
+}
+
 static BMEdgeHit *knife_edge_tri_isect(KnifeTool_OpData *kcd, BMBVHTree *bmtree,
                                        const float v1[3],  const float v2[3], const float v3[3],
                                        SmallHash *ehash, bglMats *mats, int *count)
@@ -1243,9 +1306,11 @@
 	BVHTreeOverlap *results, *result;
 	BMLoop **ls;
 	float cos[9], tri_norm[3], tri_plane[4], isects[2][3], lambda;
+	float tri_plane_clip[3][4];
 	unsigned int tot = 0;
 	int i, j, n_isects;
 
+
 	/* for comparing distances, error of intersection depends on triangle scale.
 	 * need to scale down before squaring for accurate comparison */
 	const float depsilon = (FLT_EPSILON / 2.0f) * len_v3_tri_side_max(v1, v2, v3);
@@ -1255,8 +1320,10 @@
 	copy_v3_v3(cos + 3, v2);
 	copy_v3_v3(cos + 6, v3);
 
+	/* avoid re-calculation in #isect_line_tri_coplanar_v3 */
 	normal_tri_v3(tri_norm, v1, v2, v3);
 	plane_from_point_normal_v3(tri_plane, v1, tri_norm);
+	plane_from_tri_clip3_v3(tri_plane_clip, v1, v2, v3);
 
 	BLI_bvhtree_insert(tree2, 0, cos, 3);
 	BLI_bvhtree_balance(tree2);
@@ -1282,12 +1349,13 @@
 			}
 
 			n_isects = 0;
-			if (fabsf(dist_to_plane_v3(kfe->v1->cageco, tri_plane)) < KNIFE_FLT_EPS &&
-			    fabsf(dist_to_plane_v3(kfe->v2->cageco, tri_plane)) < KNIFE_FLT_EPS)
+
+			if (isect_line_tri_coplanar_v3(kfe->v1->cageco, kfe->v2->cageco, v1, v2, v3,
+			                               isects,
+			                               /* cached values */
+			                               tri_plane, tri_plane_clip))
 			{
 				/* both kfe ends are in cutting triangle */
-				copy_v3_v3(isects[0], kfe->v1->cageco);
-				copy_v3_v3(isects[1], kfe->v2->cageco);
 				n_isects = 2;
 			}
 			else if (isect_line_tri_epsilon_v3(kfe->v1->cageco, kfe->v2->cageco, v1, v2, v3, &lambda, NULL, depsilon)) {




More information about the Bf-blender-cvs mailing list