[Bf-blender-cvs] [a28e014] master: BMesh: Add API call BM_face_calc_point_in_face

Campbell Barton noreply at git.blender.org
Fri Nov 27 12:16:17 CET 2015


Commit: a28e014313fbf4bc20af45fd8d45531f1eac2fbf
Author: Campbell Barton
Date:   Fri Nov 27 22:08:16 2015 +1100
Branches: master
https://developer.blender.org/rBa28e014313fbf4bc20af45fd8d45531f1eac2fbf

BMesh: Add API call BM_face_calc_point_in_face

Was local to knife code, but this is generally useful.

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

M	source/blender/bmesh/intern/bmesh_polygon.c
M	source/blender/bmesh/intern/bmesh_polygon.h
M	source/blender/bmesh/intern/bmesh_queries.c
M	source/blender/editors/mesh/editmesh_knife.c

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

diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c
index af0331d..8d8db79 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.c
+++ b/source/blender/bmesh/intern/bmesh_polygon.c
@@ -150,10 +150,14 @@ static void bm_face_calc_poly_center_mean_vertex_cos(
 /**
  * For tools that insist on using triangles, ideally we would cache this data.
  *
- * \param r_loops  Store face loop pointers, (f->len)
- * \param r_index  Store triangle triples, indices into \a r_loops,  ((f->len - 2) * 3)
+ * \param use_fixed_quad: When true, always split quad along (0 -> 2) regardless of concave corners,
+ * (as done in #BM_mesh_calc_tessellation).
+ * \param r_loops: Store face loop pointers, (f->len)
+ * \param r_index: Store triangle triples, indices into \a r_loops,  `((f->len - 2) * 3)`
  */
-void BM_face_calc_tessellation(const BMFace *f, BMLoop **r_loops, unsigned int (*r_index)[3])
+void BM_face_calc_tessellation(
+        const BMFace *f, const bool use_fixed_quad,
+        BMLoop **r_loops, unsigned int (*r_index)[3])
 {
 	BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
 	BMLoop *l_iter;
@@ -167,7 +171,7 @@ void BM_face_calc_tessellation(const BMFace *f, BMLoop **r_loops, unsigned int (
 		r_index[0][1] = 1;
 		r_index[0][2] = 2;
 	}
-	else if (f->len == 4) {
+	else if (f->len == 4 && use_fixed_quad) {
 		*r_loops++ = (l_iter = l_first);
 		*r_loops++ = (l_iter = l_iter->next);
 		*r_loops++ = (l_iter = l_iter->next);
@@ -202,6 +206,46 @@ void BM_face_calc_tessellation(const BMFace *f, BMLoop **r_loops, unsigned int (
 }
 
 /**
+ * Return a point inside the face.
+ */
+void BM_face_calc_point_in_face(const BMFace *f, float r_co[3])
+{
+	const BMLoop *l_tri[3];
+
+	if (f->len == 3) {
+		const BMLoop *l = BM_FACE_FIRST_LOOP(f);
+		ARRAY_SET_ITEMS(l_tri, l, l->next, l->prev);
+	}
+	else {
+		/* tessellation here seems overkill when in many cases this will be the center,
+		 * but without this we can't be sure the point is inside a concave face. */
+		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;
+		int j_best = 0;  /* use as fallback when unset */
+		float area_best  = -1.0f;
+
+		BM_face_calc_tessellation(f, false, loops, index);
+
+		for (j = 0; j < tottri; j++) {
+			const float *p1 = loops[index[j][0]]->v->co;
+			const float *p2 = loops[index[j][1]]->v->co;
+			const float *p3 = loops[index[j][2]]->v->co;
+			const float area = area_squared_tri_v3(p1, p2, p3);
+			if (area > area_best) {
+				j_best = j;
+				area_best = area;
+			}
+		}
+
+		ARRAY_SET_ITEMS(l_tri, loops[index[j_best][0]], loops[index[j_best][1]], loops[index[j_best][2]]);
+	}
+
+	mid_v3_v3v3v3(r_co, l_tri[0]->v->co, l_tri[1]->v->co, l_tri[2]->v->co);
+}
+
+/**
  * get the area of the face
  */
 float BM_face_calc_area(const BMFace *f)
diff --git a/source/blender/bmesh/intern/bmesh_polygon.h b/source/blender/bmesh/intern/bmesh_polygon.h
index a1866bb..c84f479 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.h
+++ b/source/blender/bmesh/intern/bmesh_polygon.h
@@ -34,7 +34,10 @@ struct Heap;
 
 void  BM_bmesh_calc_tessellation(BMesh *bm, BMLoop *(*looptris)[3], int *r_looptris_tot);
 
-void  BM_face_calc_tessellation(const BMFace *f, BMLoop **r_loops, unsigned int (*r_index)[3]);
+void  BM_face_calc_tessellation(
+        const BMFace *f, const bool use_fixed_quad,
+        BMLoop **r_loops, unsigned int (*r_index)[3]);
+void  BM_face_calc_point_in_face(const BMFace *f, float r_co[3]);
 float BM_face_calc_normal(const BMFace *f, float r_no[3]) ATTR_NONNULL();
 float BM_face_calc_normal_vcos(
         const BMesh *bm, const BMFace *f, float r_no[3],
diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c
index 1a8ea1e..064c8ec 100644
--- a/source/blender/bmesh/intern/bmesh_queries.c
+++ b/source/blender/bmesh/intern/bmesh_queries.c
@@ -2299,7 +2299,7 @@ static void bm_mesh_calc_volume_face(const BMFace *f, float *r_vol)
 	unsigned int (*index)[3] = BLI_array_alloca(index, tottri);
 	int j;
 
-	BM_face_calc_tessellation(f, loops, index);
+	BM_face_calc_tessellation(f, false, loops, index);
 
 	for (j = 0; j < tottri; j++) {
 		const float *p1 = loops[index[j][0]]->v->co;
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index baf1fa8..818526a 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -3341,43 +3341,6 @@ void MESH_OT_knife_tool(wmOperatorType *ot)
 /* Knife tool as a utility function
  * that can be used for internal slicing operations */
 
-/**
- * Return a point inside the face.
- *
- * tessellation here seems way overkill,
- * but without this its very hard to know of a point is inside the face
- */
-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;
-	int j_best = 0;  /* use as fallback when unset */
-	float area_best  = -1.0f;
-
-	BM_face_calc_tessellation(f, loops, index);
-
-	for (j = 0; j < tottri; j++) {
-		const float *p1 = loops[index[j][0]]->v->co;
-		const float *p2 = loops[index[j][1]]->v->co;
-		const float *p3 = loops[index[j][2]]->v->co;
-		float area;
-
-		area = area_squared_tri_v3(p1, p2, p3);
-		if (area > area_best) {
-			j_best = j;
-			area_best = area;
-		}
-	}
-
-	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_point_isect(LinkNode *polys, const float cent_ss[2])
 {
 	LinkNode *p = polys;
@@ -3495,7 +3458,7 @@ void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_throug
 					BMIter fiter;
 					BM_ITER_ELEM (f, &fiter, e, BM_FACES_OF_EDGE) {
 						float cent[3], cent_ss[2];
-						edbm_mesh_knife_face_point(f, cent);
+						BM_face_calc_point_in_face(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);
@@ -3531,7 +3494,7 @@ void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_throug
 
 						if (found) {
 							float cent[3], cent_ss[2];
-							edbm_mesh_knife_face_point(f, cent);
+							BM_face_calc_point_in_face(f, cent);
 							knife_project_v2(kcd, cent, cent_ss);
 							if ((kcd->cut_through || point_is_visible(kcd, cent, cent_ss, &mats, (BMElem *)f)) &&
 							    edbm_mesh_knife_point_isect(polys, cent_ss))




More information about the Bf-blender-cvs mailing list