BMesh: radial loop (internal API symmetry)

Radial append/remove had swapped args and *slightly* different behavior.
- bmesh_radial_append(edge, loop)
- bmesh_radial_loop_remove(loop, edge)

Match logic for append/remove,
Logic for the one case where the edge needs to be left untouched
has been moved to: `bmesh_radial_loop_unlink`.
This commit is contained in:
Campbell Barton 2016-10-31 22:52:06 +11:00
parent 6488ce7f33
commit aad46dd175
3 changed files with 72 additions and 56 deletions

View File

@ -287,7 +287,7 @@ static BMLoop *bm_face_boundary_add(
#endif
BMLoop *l = bm_loop_create(bm, startv, starte, f, NULL /* starte->l */, create_flag);
bmesh_radial_append(starte, l);
bmesh_radial_loop_append(starte, l);
#ifdef USE_BMESH_HOLES
lst->first = lst->last = l;
@ -460,7 +460,7 @@ BMFace *BM_face_create(
for (i = 1; i < len; i++) {
l = bm_loop_create(bm, verts[i], edges[i], f, NULL /* edges[i]->l */, create_flag);
bmesh_radial_append(edges[i], l);
bmesh_radial_loop_append(edges[i], l);
l->prev = lastl;
lastl->next = l;
@ -899,7 +899,7 @@ void BM_face_kill(BMesh *bm, BMFace *f)
do {
l_next = l_iter->next;
bmesh_radial_loop_remove(l_iter, l_iter->e);
bmesh_radial_loop_remove(l_iter->e, l_iter);
bm_kill_only_loop(bm, l_iter);
} while ((l_iter = l_next) != l_first);
@ -944,7 +944,7 @@ void BM_face_kill_loose(BMesh *bm, BMFace *f)
l_next = l_iter->next;
e = l_iter->e;
bmesh_radial_loop_remove(l_iter, e);
bmesh_radial_loop_remove(e, l_iter);
bm_kill_only_loop(bm, l_iter);
if (e->l == NULL) {
@ -1050,7 +1050,7 @@ static bool bm_loop_reverse_loop(
int i, j, edok;
for (i = 0, l_iter = l_first; i < len; i++, l_iter = l_iter->next) {
bmesh_radial_loop_remove(l_iter, (edar[i] = l_iter->e));
bmesh_radial_loop_remove((edar[i] = l_iter->e), l_iter);
}
/* actually reverse the loop */
@ -1086,7 +1086,7 @@ static bool bm_loop_reverse_loop(
}
/* rebuild radial */
for (i = 0, l_iter = l_first; i < len; i++, l_iter = l_iter->next)
bmesh_radial_append(l_iter->e, l_iter);
bmesh_radial_loop_append(l_iter->e, l_iter);
#ifndef NDEBUG
/* validate radial */
@ -1558,8 +1558,8 @@ BMFace *bmesh_sfme(
} while ((l_iter = l_iter->next) != l_first);
/* link up the new loops into the new edges radial */
bmesh_radial_append(e, l_f1);
bmesh_radial_append(e, l_f2);
bmesh_radial_loop_append(e, l_f1);
bmesh_radial_loop_append(e, l_f2);
f2->len = f2len;
@ -1673,7 +1673,7 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
l = l_next;
l->f->len++;
l_next = l_next != l_next->radial_next ? l_next->radial_next : NULL;
bmesh_radial_loop_remove(l, NULL);
bmesh_radial_loop_unlink(l);
l_new = bm_loop_create(bm, NULL, NULL, l->f, l, 0);
l_new->prev = l;
@ -1698,8 +1698,8 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
l->radial_next = l->radial_prev = NULL;
}
bmesh_radial_append(l_new->e, l_new);
bmesh_radial_append(l->e, l);
bmesh_radial_loop_append(l_new->e, l_new);
bmesh_radial_loop_append(l->e, l);
}
else if (BM_verts_in_edge(l_new->v, l_new->next->v, e_new)) {
l_new->e = e_new;
@ -1716,8 +1716,8 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
l->radial_next = l->radial_prev = NULL;
}
bmesh_radial_append(l_new->e, l_new);
bmesh_radial_append(l->e, l);
bmesh_radial_loop_append(l_new->e, l_new);
bmesh_radial_loop_append(l->e, l);
}
}
@ -2592,8 +2592,8 @@ bool BM_edge_splice(BMesh *bm, BMEdge *e_dst, BMEdge *e_src)
l = e_src->l;
BLI_assert(BM_vert_in_edge(e_dst, l->v));
BLI_assert(BM_vert_in_edge(e_dst, l->next->v));
bmesh_radial_loop_remove(l, e_src);
bmesh_radial_append(e_dst, l);
bmesh_radial_loop_remove(e_src, l);
bmesh_radial_loop_append(e_dst, l);
}
BLI_assert(bmesh_radial_length(e_src->l) == 0);
@ -2640,8 +2640,8 @@ void bmesh_edge_separate(
}
e_new = BM_edge_create(bm, e->v1, e->v2, e, BM_CREATE_NOP);
bmesh_radial_loop_remove(l_sep, e);
bmesh_radial_append(e_new, l_sep);
bmesh_radial_loop_remove(e, l_sep);
bmesh_radial_loop_append(e_new, l_sep);
l_sep->e = e_new;
if (copy_select) {
@ -2828,8 +2828,8 @@ BMVert *bmesh_urmv_loop_multi(
do {
l_next = l_iter->radial_next;
if (BM_ELEM_API_FLAG_TEST(l_iter, LOOP_VISIT)) {
bmesh_radial_loop_remove(l_iter, e);
bmesh_radial_append(e_new, l_iter);
bmesh_radial_loop_remove(e, l_iter);
bmesh_radial_loop_append(e_new, l_iter);
l_iter->e = e_new;
}
} while ((l_iter = l_next) != l_first);

View File

@ -143,7 +143,7 @@ void bmesh_disk_vert_replace(BMEdge *e, BMVert *v_dst, BMVert *v_src)
* to store non-manifold conditions since BM does not keep track of region/shell information.
*
* Functions relating to this cycle:
* - #bmesh_radial_append
* - #bmesh_radial_loop_append
* - #bmesh_radial_loop_remove
* - #bmesh_radial_facevert_count
* - #bmesh_radial_facevert_check
@ -389,6 +389,30 @@ bool bmesh_radial_validate(int radlen, BMLoop *l)
return true;
}
void bmesh_radial_loop_append(BMEdge *e, BMLoop *l)
{
if (e->l == NULL) {
e->l = l;
l->radial_next = l->radial_prev = l;
}
else {
l->radial_prev = e->l;
l->radial_next = e->l->radial_next;
e->l->radial_next->radial_prev = l;
e->l->radial_next = l;
e->l = l;
}
if (UNLIKELY(l->e && l->e != e)) {
/* l is already in a radial cycle for a different edge */
BMESH_ASSERT(0);
}
l->e = e;
}
/**
* \brief BMESH RADIAL REMOVE LOOP
*
@ -397,28 +421,27 @@ bool bmesh_radial_validate(int radlen, BMLoop *l)
* updated (in the case that the edge's link into the radial
* cycle was the loop which is being removed from the cycle).
*/
void bmesh_radial_loop_remove(BMLoop *l, BMEdge *e)
void bmesh_radial_loop_remove(BMEdge *e, BMLoop *l)
{
/* if e is non-NULL, l must be in the radial cycle of e */
if (UNLIKELY(e && e != l->e)) {
if (UNLIKELY(e != l->e)) {
BMESH_ASSERT(0);
}
if (l->radial_next != l) {
if (e && l == e->l)
if (l == e->l) {
e->l = l->radial_next;
}
l->radial_next->radial_prev = l->radial_prev;
l->radial_prev->radial_next = l->radial_next;
}
else {
if (e) {
if (l == e->l) {
e->l = NULL;
}
else {
BMESH_ASSERT(0);
}
if (l == e->l) {
e->l = NULL;
}
else {
BMESH_ASSERT(0);
}
}
@ -428,6 +451,22 @@ void bmesh_radial_loop_remove(BMLoop *l, BMEdge *e)
l->e = NULL;
}
/**
* A version of #bmesh_radial_loop_remove which only performs the radial unlink,
* leaving the edge untouched.
*/
void bmesh_radial_loop_unlink(BMLoop *l)
{
if (l->radial_next != l) {
l->radial_next->radial_prev = l->radial_prev;
l->radial_prev->radial_next = l->radial_next;
}
/* l is no longer in a radial cycle; empty the links
* to the cycle and the link back to an edge */
l->radial_next = l->radial_prev = NULL;
l->e = NULL;
}
/**
* \brief BME RADIAL FIND FIRST FACE VERT
@ -484,30 +523,6 @@ int bmesh_radial_length(const BMLoop *l)
return i;
}
void bmesh_radial_append(BMEdge *e, BMLoop *l)
{
if (e->l == NULL) {
e->l = l;
l->radial_next = l->radial_prev = l;
}
else {
l->radial_prev = e->l;
l->radial_next = e->l->radial_next;
e->l->radial_next->radial_prev = l;
e->l->radial_next = l;
e->l = l;
}
if (UNLIKELY(l->e && l->e != e)) {
/* l is already in a radial cycle for a different edge */
BMESH_ASSERT(0);
}
l->e = e;
}
/**
* \brief RADIAL COUNT FACE VERT
*

View File

@ -55,8 +55,9 @@ BMEdge *bmesh_disk_faceedge_find_first(const BMEdge *e, const BMVert *v) ATTR_WA
BMEdge *bmesh_disk_faceedge_find_next(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
/* RADIAL CYCLE MANAGMENT */
void bmesh_radial_append(BMEdge *e, BMLoop *l) ATTR_NONNULL();
void bmesh_radial_loop_remove(BMLoop *l, BMEdge *e) ATTR_NONNULL(1);
void bmesh_radial_loop_append(BMEdge *e, BMLoop *l) ATTR_NONNULL();
void bmesh_radial_loop_remove(BMEdge *e, BMLoop *l) ATTR_NONNULL();
void bmesh_radial_loop_unlink(BMLoop *l) ATTR_NONNULL();
/* note:
* bmesh_radial_loop_next(BMLoop *l) / prev.
* just use member access l->radial_next, l->radial_prev now */