[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [49616] trunk/blender/source/blender/ editors/mesh/editmesh_knife.c: Fix to knife: would sometimes miss cuts on non-planar faces.

Howard Trickey howard.trickey at gmail.com
Mon Aug 6 15:37:25 CEST 2012


Revision: 49616
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=49616
Author:   howardt
Date:     2012-08-06 13:37:25 +0000 (Mon, 06 Aug 2012)
Log Message:
-----------
Fix to knife: would sometimes miss cuts on non-planar faces.
Also, there was a needless loop through all three loops of
a tesselation triangle, which all share the same original face.
Also, made an early out for case where an edge cut had already
been discovered on a Knife edge.

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	2012-08-06 13:31:28 UTC (rev 49615)
+++ trunk/blender/source/blender/editors/mesh/editmesh_knife.c	2012-08-06 13:37:25 UTC (rev 49616)
@@ -1092,9 +1092,9 @@
 	BLI_array_declare(edges);
 	BVHTreeOverlap *results, *result;
 	BMLoop **ls;
-	float cos[9], uv[3], lambda;
+	float cos[9], lambda;
 	unsigned int tot = 0;
-	int i, j;
+	int i;
 
 	/* for comparing distances, error of intersection depends on triangle scale.
 	 * need to scale down before squaring for accurate comparison */
@@ -1112,105 +1112,107 @@
 
 	for (i = 0; i < tot; i++, result++) {
 		float p[3];
+		BMLoop *l1;
+		BMFace *hitf;
+		ListBase *lst;
+		Ref *ref;
 
 		ls = (BMLoop **)kcd->em->looptris[result->indexA];
 
-		for (j = 0; j < 3; j++) {
-			BMLoop *l1 = ls[j];
-			BMFace *hitf;
-			ListBase *lst = knife_get_face_kedges(kcd, l1->f);
-			Ref *ref;
+		l1 = ls[0];
+		lst = knife_get_face_kedges(kcd, l1->f);
 
-			for (ref = lst->first; ref; ref = ref->next) {
-				KnifeEdge *kfe = ref->ref;
+		for (ref = lst->first; ref; ref = ref->next) {
+			KnifeEdge *kfe = ref->ref;
 
-				//if (kfe == kcd->cur.edge || kfe == kcd->prev.edge)
-				//	continue;
+			if (BLI_smallhash_haskey(ehash, (intptr_t)kfe)) {
+				continue;  // We already found a hit on this knife edge
+			}
 
-				if (isect_line_tri_v3(kfe->v1->cageco, kfe->v2->cageco, v1, v2, v3, &lambda, uv)) {
-					float no[3], view[3], sp[3];
+			if (isect_line_tri_v3(kfe->v1->cageco, kfe->v2->cageco, v1, v2, v3, &lambda, NULL)) {
+				float no[3], view[3], sp[3];
 
-					interp_v3_v3v3(p, kfe->v1->cageco, kfe->v2->cageco, lambda);
+				interp_v3_v3v3(p, kfe->v1->cageco, kfe->v2->cageco, lambda);
 
-					if (kcd->cur.vert && len_squared_v3v3(kcd->cur.vert->cageco, p) < depsilon_squared)
-						continue;
-					if (kcd->prev.vert && len_squared_v3v3(kcd->prev.vert->cageco, p) < depsilon_squared)
-						continue;
-					if (len_squared_v3v3(kcd->prev.cage, p) < depsilon_squared ||
-					    len_squared_v3v3(kcd->cur.cage, p) < depsilon_squared)
-					{
-						continue;
-					}
+				if (kcd->cur.vert && len_squared_v3v3(kcd->cur.vert->cageco, p) < depsilon_squared)
+					continue;
+				if (kcd->prev.vert && len_squared_v3v3(kcd->prev.vert->cageco, p) < depsilon_squared)
+					continue;
+				if (len_squared_v3v3(kcd->prev.cage, p) < depsilon_squared ||
+					   len_squared_v3v3(kcd->cur.cage, p) < depsilon_squared)
+					continue;
 
-					knife_project_v3(kcd, p, sp);
-					view3d_unproject(mats, view, sp[0], sp[1], 0.0f);
-					mul_m4_v3(kcd->ob->imat, view);
+				knife_project_v3(kcd, p, sp);
+				view3d_unproject(mats, view, sp[0], sp[1], 0.0f);
+				mul_m4_v3(kcd->ob->imat, view);
 
-					if (kcd->cut_through) {
-						hitf = FALSE;
+				if (kcd->cut_through) {
+					hitf = FALSE;
+				} else {
+					/* check if this point is visible in the viewport */
+					float p1[3], lambda1;
+
+					/* if face isn't planer, p may be behind the current tesselated tri,
+					   so move it onto that and then a little towards eye */
+					if (isect_line_tri_v3(p, view, ls[0]->v->co, ls[1]->v->co, ls[2]->v->co, &lambda1, NULL)) {
+						interp_v3_v3v3(p1, p, view, lambda1);
+					} else {
+						copy_v3_v3(p1, p);
 					}
-					else {
-						/* check if this point is visible in the viewport */
-						sub_v3_v3(view, p);
-						normalize_v3(view);
+					sub_v3_v3(view, p1);
+					normalize_v3(view);
 
-						copy_v3_v3(no, view);
-						mul_v3_fl(no, 0.003);
+					copy_v3_v3(no, view);
+					mul_v3_fl(no, 0.003);
 
-						/* go towards view a bit */
-						add_v3_v3(p, no);
-
-						/* ray cast */
-						hitf = BMBVH_RayCast(bmtree, p, no, NULL, NULL);
-					}
-
-					/* ok, if visible add the new point */
-					if (!hitf && !BLI_smallhash_haskey(ehash, (intptr_t)kfe)) {
-						BMEdgeHit hit;
+					/* go towards view a bit */
+					add_v3_v3(p1, no);
 						
-						if (len_squared_v3v3(p, kcd->cur.co) < depsilon_squared ||
-						    len_squared_v3v3(p, kcd->prev.co) < depsilon_squared)
-						{
-							continue;
-						}
+					/* ray cast */
+					hitf = BMBVH_RayCast(bmtree, p1, no, NULL, NULL);
+				}
 
-						hit.kfe = kfe;
-						hit.v = NULL;
+				/* ok, if visible add the new point */
+				if (!hitf && !BLI_smallhash_haskey(ehash, (intptr_t)kfe)) {
+					BMEdgeHit hit;
+	
+					if (len_squared_v3v3(p, kcd->cur.co) < depsilon_squared ||
+					    len_squared_v3v3(p, kcd->prev.co) < depsilon_squared)
+						continue;
 
-						knife_find_basef(kfe);
-						hit.f = kfe->basef;
-						hit.perc = len_v3v3(p, kfe->v1->cageco) / len_v3v3(kfe->v1->cageco, kfe->v2->cageco);
-						copy_v3_v3(hit.cagehit, p);
+					hit.kfe = kfe;
+					hit.v = NULL;
 
-						interp_v3_v3v3(p, kfe->v1->co, kfe->v2->co, hit.perc);
-						copy_v3_v3(hit.realhit, p);
+					knife_find_basef(kfe);
+					hit.f = kfe->basef;
+					hit.perc = len_v3v3(p, kfe->v1->cageco) / len_v3v3(kfe->v1->cageco, kfe->v2->cageco);
+					copy_v3_v3(hit.cagehit, p);
 
-						/* BMESH_TODO: should also snap to vertices */
-						if (kcd->snap_midpoints) {
-							float perc = hit.perc;
+					interp_v3_v3v3(p, kfe->v1->co, kfe->v2->co, hit.perc);
+					copy_v3_v3(hit.realhit, p);
 
-							/* select the closest from the edge endpoints or the midpoint */
-							if (perc < 0.25f) {
-								perc = 0.0f;
-							}
-							else if (perc < 0.75f) {
-								perc = 0.5f;
-							}
-							else {
-								perc = 1.0f;
-							}
+					/* BMESH_TODO: should also snap to vertices */
+					if (kcd->snap_midpoints) {
+						float perc = hit.perc;
 
-							interp_v3_v3v3(hit.hit, kfe->v1->co, kfe->v2->co, perc);
-							interp_v3_v3v3(hit.cagehit, kfe->v1->cageco, kfe->v2->cageco, perc);
+						/* select the closest from the edge endpoints or the midpoint */
+						if (perc < 0.25f) {
+							perc = 0.0f;
+						} else if (perc < 0.75f) {
+							perc = 0.5f;
+						} else {
+							perc = 1.0f;
 						}
-						else {
-							copy_v3_v3(hit.hit, p);
-						}
-						knife_project_v3(kcd, hit.cagehit, hit.schit);
 
-						BLI_array_append(edges, hit);
-						BLI_smallhash_insert(ehash, (intptr_t)kfe, NULL);
+						interp_v3_v3v3(hit.hit, kfe->v1->co, kfe->v2->co, perc);
+						interp_v3_v3v3(hit.cagehit, kfe->v1->cageco, kfe->v2->cageco, perc);
+					} else {
+						copy_v3_v3(hit.hit, p);
 					}
+					knife_project_v3(kcd, hit.cagehit, hit.schit);
+
+					BLI_array_append(edges, hit);
+					BLI_smallhash_insert(ehash, (intptr_t)kfe, NULL);
 				}
 			}
 		}




More information about the Bf-blender-cvs mailing list