diff options
author | Campbell Barton <ideasman42@gmail.com> | 2015-11-27 14:08:16 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2015-11-27 14:08:16 +0300 |
commit | a28e014313fbf4bc20af45fd8d45531f1eac2fbf (patch) | |
tree | 6ffd049f683489463696319c1bf1fc51fcd2bb4a /source/blender/bmesh/intern | |
parent | bfaebeaee64399e4c6da65b8aaa63e1a3cc3d000 (diff) |
BMesh: Add API call BM_face_calc_point_in_face
Was local to knife code, but this is generally useful.
Diffstat (limited to 'source/blender/bmesh/intern')
-rw-r--r-- | source/blender/bmesh/intern/bmesh_polygon.c | 52 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_polygon.h | 5 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_queries.c | 2 |
3 files changed, 53 insertions, 6 deletions
diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index af0331d7771..8d8db799afa 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 a1866bb010d..c84f4798ee4 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 1a8ea1e3a0d..064c8ecea1e 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; |