[Bf-blender-cvs] [db0e2e7] master: Fix T42864 (partial): knife-project included uncut backfaces

Campbell Barton noreply at git.blender.org
Mon Dec 15 15:17:05 CET 2014


Commit: db0e2e7347db73786b38c0cbace60741ddd28b7e
Author: Campbell Barton
Date:   Mon Dec 15 14:17:28 2014 +0100
Branches: master
https://developer.blender.org/rBdb0e2e7347db73786b38c0cbace60741ddd28b7e

Fix T42864 (partial): knife-project included uncut backfaces

When knife-project ran with cut-through disabled,
it would still try to select faces behind the cut.

Now check if the faces are obscured.

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

M	source/blender/editors/mesh/editmesh_knife.c

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

diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index c94e4ca..c2aafba 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -3168,16 +3168,14 @@ void MESH_OT_knife_tool(wmOperatorType *ot)
  * tessellation here seems way overkill,
  * but without this its very hard to know of a point is inside the face
  */
-static void edvm_mesh_knife_face_point(BMFace *f, float r_cent[3])
+static void edbm_mesh_knife_face_point(BMFace *f, float r_cent[3])
 {
 	const int tottri = f->len - 2;
 	BMLoop **loops = BLI_array_alloca(loops, f->len);
 	unsigned int  (*index)[3] = BLI_array_alloca(index, tottri);
 	int j;
-
-	const float *best_co[3] = {NULL};
-	float best_area  = -1.0f;
-	bool ok = false;
+	int j_best = 0;  /* use as fallback when unset */
+	float area_best  = -1.0f;
 
 	BM_face_calc_tessellation(f, loops, index);
 
@@ -3190,49 +3188,34 @@ static void edvm_mesh_knife_face_point(BMFace *f, float r_cent[3])
 		float cross[3];
 		cross_v3_v3v3(cross, p2, p3);
 		area = fabsf(dot_v3v3(p1, cross));
-		if (area > best_area) {
-			best_co[0] = p1;
-			best_co[1] = p2;
-			best_co[2] = p3;
-			best_area = area;
-			ok = true;
+		if (area > area_best) {
+			j_best = j;
+			area_best = area;
 		}
 	}
 
-	if (ok) {
-		mid_v3_v3v3v3(r_cent, best_co[0], best_co[1], best_co[2]);
-	}
-	else {
-		mid_v3_v3v3v3(r_cent, loops[0]->v->co, loops[1]->v->co, loops[2]->v->co);
-	}
+	mid_v3_v3v3v3(
+	        r_cent,
+	        loops[index[j_best][0]]->v->co,
+	        loops[index[j_best][1]]->v->co,
+	        loops[index[j_best][2]]->v->co);
 }
 
-static bool edbm_mesh_knife_face_isect(ARegion *ar, LinkNode *polys, BMFace *f, float projmat[4][4])
+static bool edbm_mesh_knife_point_isect(LinkNode *polys, const float cent_ss[2])
 {
-	float cent_ss[2];
-	float cent[3];
-
-	edvm_mesh_knife_face_point(f, cent);
-
-	ED_view3d_project_float_v2_m4(ar, cent, cent_ss, projmat);
-
-	/* check */
-	{
-		LinkNode *p = polys;
-		int isect = 0;
-
-		while (p) {
-			const float (*mval_fl)[2] = p->link;
-			const int mval_tot = MEM_allocN_len(mval_fl) / sizeof(*mval_fl);
-			isect += (int)isect_point_poly_v2(cent_ss, mval_fl, mval_tot - 1, false);
-			p = p->next;
-		}
+	LinkNode *p = polys;
+	int isect = 0;
 
-		if (isect % 2) {
-			return true;
-		}
+	while (p) {
+		const float (*mval_fl)[2] = p->link;
+		const int mval_tot = MEM_allocN_len(mval_fl) / sizeof(*mval_fl);
+		isect += (int)isect_point_poly_v2(cent_ss, mval_fl, mval_tot - 1, false);
+		p = p->next;
 	}
 
+	if (isect % 2) {
+		return true;
+	}
 	return false;
 }
 
@@ -3242,6 +3225,7 @@ static bool edbm_mesh_knife_face_isect(ARegion *ar, LinkNode *polys, BMFace *f,
 void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_through)
 {
 	KnifeTool_OpData *kcd;
+	bglMats mats;
 
 	view3d_operator_needs_opengl(C);
 
@@ -3260,6 +3244,10 @@ void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_throug
 		if (use_tag) {
 			BM_mesh_elem_hflag_enable_all(kcd->em->bm, BM_EDGE, BM_ELEM_TAG, false);
 		}
+
+		if (kcd->cut_through == false) {
+			bgl_get_mats(&mats);
+		}
 	}
 
 	/* execute */
@@ -3324,7 +3312,10 @@ void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_throug
 					BMFace *f;
 					BMIter fiter;
 					BM_ITER_ELEM (f, &fiter, e, BM_FACES_OF_EDGE) {
-						if (edbm_mesh_knife_face_isect(kcd->ar, polys, f, projmat)) {
+						float cent[3], cent_ss[2];
+						edbm_mesh_knife_face_point(f, cent);
+						knife_project_v2(kcd, cent, cent_ss);
+						if (edbm_mesh_knife_point_isect(polys, cent_ss)) {
 							BM_elem_flag_enable(f, BM_ELEM_TAG);
 						}
 					}
@@ -3357,7 +3348,12 @@ void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_throug
 						} while ((l_iter = l_iter->next) != l_first && (found == false));
 
 						if (found) {
-							if (edbm_mesh_knife_face_isect(kcd->ar, polys, f, projmat)) {
+							float cent[3], cent_ss[2];
+							edbm_mesh_knife_face_point(f, cent);
+							knife_project_v2(kcd, cent, cent_ss);
+							if ((kcd->cut_through || point_is_visible(kcd, cent, cent_ss, &mats)) &&
+							    edbm_mesh_knife_point_isect(polys, cent_ss))
+							{
 								BM_elem_flag_enable(f, BM_ELEM_TAG);
 								keep_search = true;
 							}




More information about the Bf-blender-cvs mailing list