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))

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to