diff options
Diffstat (limited to 'source/blender/bmesh/intern/bmesh_queries.c')
-rw-r--r-- | source/blender/bmesh/intern/bmesh_queries.c | 109 |
1 files changed, 82 insertions, 27 deletions
diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index 1a8ea1e3a0d..ffad3e59e47 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -768,13 +768,35 @@ bool BM_vert_is_edge_pair(const BMVert *v) { const BMEdge *e = v->e; if (e) { - const BMDiskLink *dl = bmesh_disk_edge_link_from_vert(e, v); - return (dl->next == dl->prev); + BMEdge *e_other = BM_DISK_EDGE_NEXT(e, v); + return ((e_other != e) && (BM_DISK_EDGE_NEXT(e_other, v) == e)); } return false; } /** + * Access a verts 2 connected edges. + * + * \return true when only 2 verts are found. + */ +bool BM_vert_edge_pair(BMVert *v, BMEdge **r_e_a, BMEdge **r_e_b) +{ + BMEdge *e_a = v->e; + if (e_a) { + BMEdge *e_b = BM_DISK_EDGE_NEXT(e_a, v); + if ((e_b != e_a) && (BM_DISK_EDGE_NEXT(e_b, v) == e_a)) { + *r_e_a = e_a; + *r_e_b = e_b; + return true; + } + } + + *r_e_a = NULL; + *r_e_b = NULL; + return false; +} + +/** * Returns the number of edges around this vertex. */ int BM_vert_edge_count(const BMVert *v) @@ -1216,6 +1238,53 @@ bool BM_face_share_edge_check(BMFace *f1, BMFace *f2) } /** + * Counts the number of verts two faces share (if any). + */ +int BM_face_share_vert_count(BMFace *f_a, BMFace *f_b) +{ + BMLoop *l_iter; + BMLoop *l_first; + int count = 0; + + l_iter = l_first = BM_FACE_FIRST_LOOP(f_a); + do { + if (BM_vert_in_face(l_iter->v, f_b)) { + count++; + } + } while ((l_iter = l_iter->next) != l_first); + + return count; +} + +/** + * Returns true if the faces share a vert. + */ +bool BM_face_share_vert_check(BMFace *f_a, BMFace *f_b) +{ + BMLoop *l_iter; + BMLoop *l_first; + + l_iter = l_first = BM_FACE_FIRST_LOOP(f_a); + do { + if (BM_vert_in_face(l_iter->v, f_b)) { + return true; + } + } while ((l_iter = l_iter->next) != l_first); + + return false; +} + +/** + * Returns true when 2 loops share an edge (are adjacent in the face-fan) + */ +bool BM_loop_share_edge_check(BMLoop *l_a, BMLoop *l_b) +{ + BLI_assert(l_a->v == l_b->v); + return (ELEM(l_a->e, l_b->e, l_b->prev->e) || + ELEM(l_b->e, l_a->e, l_a->prev->e)); +} + +/** * Test if e1 shares any faces with e2 */ bool BM_edge_share_face_check(BMEdge *e1, BMEdge *e2) @@ -1882,7 +1951,7 @@ bool BM_face_exists(BMVert **varr, int len, BMFace **r_existface) if (l_walk->v != varr[i_walk]) { break; } - } while ((l_walk = l_walk->next), ++i_walk != len); + } while ((void)(l_walk = l_walk->next), ++i_walk != len); } else if (l_iter_radial->prev->v == varr[1]) { BMLoop *l_walk = l_iter_radial->prev->prev; @@ -1890,7 +1959,7 @@ bool BM_face_exists(BMVert **varr, int len, BMFace **r_existface) if (l_walk->v != varr[i_walk]) { break; } - } while ((l_walk = l_walk->prev), ++i_walk != len); + } while ((void)(l_walk = l_walk->prev), ++i_walk != len); } if (i_walk == len) { @@ -2035,26 +2104,13 @@ bool BM_face_exists_multi_edge(BMEdge **earr, int len) { BMVert **varr = BLI_array_alloca(varr, len); - bool ok; - int i, i_next; - /* first check if verts have edges, if not we can bail out early */ - ok = true; - for (i = len - 1, i_next = 0; i_next < len; (i = i_next++)) { - if (!(varr[i] = BM_edge_share_vert(earr[i], earr[i_next]))) { - ok = false; - break; - } - } - - if (ok == false) { + if (!BM_verts_from_edges(varr, earr, len)) { BMESH_ASSERT(0); return false; } - ok = BM_face_exists_multi(varr, earr, len); - - return ok; + return BM_face_exists_multi(varr, earr, len); } @@ -2299,7 +2355,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; @@ -2339,8 +2395,7 @@ float BM_mesh_calc_volume(BMesh *bm, bool is_signed) * (or when hflag_test is set, the number of flagged faces). * \param r_group_index index, length pairs into \a r_groups_array, size of return value * int pairs: (array_start, array_length). - * \param filter_fn Filter the edges or verts we step over (depends on \a htype_step) - * as to which types we deal with. + * \param filter_fn Filter the edge-loops or vert-loops we step over (depends on \a htype_step). * \param user_data Optional user data for \a filter_fn, can be NULL. * \param hflag_test Optional flag to test faces, * use to exclude faces from the calculation, 0 for all faces. @@ -2350,7 +2405,7 @@ float BM_mesh_calc_volume(BMesh *bm, bool is_signed) */ int BM_mesh_calc_face_groups( BMesh *bm, int *r_groups_array, int (**r_group_index)[2], - BMElemFilterFunc filter_fn, void *user_data, + BMLoopFilterFunc filter_fn, void *user_data, const char hflag_test, const char htype_step) { #ifdef DEBUG @@ -2443,7 +2498,7 @@ int BM_mesh_calc_face_groups( do { BMLoop *l_radial_iter = l_iter->radial_next; if ((l_radial_iter != l_iter) && - ((filter_fn == NULL) || filter_fn((BMElem *)l_iter->e, user_data))) + ((filter_fn == NULL) || filter_fn(l_iter, user_data))) { do { BMFace *f_other = l_radial_iter->f; @@ -2461,7 +2516,7 @@ int BM_mesh_calc_face_groups( /* search for other faces */ l_iter = l_first = BM_FACE_FIRST_LOOP(f); do { - if ((filter_fn == NULL) || filter_fn((BMElem *)l_iter->v, user_data)) { + if ((filter_fn == NULL) || filter_fn(l_iter, user_data)) { BMLoop *l_other; BM_ITER_ELEM (l_other, &liter, l_iter, BM_LOOPS_OF_LOOP) { BMFace *f_other = l_other->f; @@ -2508,7 +2563,7 @@ int BM_mesh_calc_face_groups( */ int BM_mesh_calc_edge_groups( BMesh *bm, int *r_groups_array, int (**r_group_index)[2], - BMElemFilterFunc filter_fn, void *user_data, + BMVertFilterFunc filter_fn, void *user_data, const char hflag_test) { #ifdef DEBUG @@ -2597,7 +2652,7 @@ int BM_mesh_calc_edge_groups( /* search for other edges */ BM_ITER_ELEM (v, &viter, e, BM_VERTS_OF_EDGE) { - if ((filter_fn == NULL) || filter_fn((BMElem *)v, user_data)) { + if ((filter_fn == NULL) || filter_fn(v, user_data)) { BMEdge *e_other; BM_ITER_ELEM (e_other, &eiter, v, BM_EDGES_OF_VERT) { if (BM_elem_flag_test(e_other, BM_ELEM_TAG) == false) { |