BMesh: rework BM_vert_is_manifold (simplify logic)

- simplify boundary handling (walk from boundary - no need to reset walking)
- early exit when the vert has >2 boundaries
- use BM_vert_step_fan_loop to walk the fan
This commit is contained in:
Campbell Barton 2015-05-03 04:40:02 +10:00
parent de031b7c89
commit bd5e578804

@ -861,9 +861,9 @@ bool BM_vert_is_wire(const BMVert *v)
*/
bool BM_vert_is_manifold(const BMVert *v)
{
BMEdge *e, *e_old;
BMLoop *l;
int len, count, flag;
BMEdge *e_iter, *e_first, *e_prev;
BMLoop *l_iter, *l_first;
int edge_num = 0, loop_num = 0, loop_num_region = 0, boundary_num = 0;
if (v->e == NULL) {
/* loose vert */
@ -871,51 +871,52 @@ bool BM_vert_is_manifold(const BMVert *v)
}
/* count edges while looking for non-manifold edges */
len = 0;
e_old = e = v->e;
e_first = e_iter = v->e;
l_first = e_iter->l ? e_iter->l : NULL;
do {
/* loose edge or edge shared by more than two faces,
* edges with 1 face user are OK, otherwise we could
* use BM_edge_is_manifold() here */
if (e->l == NULL || (e->l != e->l->radial_next->radial_next)) {
if (e_iter->l == NULL || (e_iter->l != e_iter->l->radial_next->radial_next)) {
return false;
}
len++;
} while ((e = bmesh_disk_edge_next(e, v)) != e_old);
count = 1;
flag = 1;
e = NULL;
e_old = v->e;
l = e_old->l;
while (e != e_old) {
l = (l->v == v) ? l->prev : l->next;
e = l->e;
count++; /* count the edges */
if (flag && l->radial_next == l) {
/* we've hit the edge of an open mesh, reset once */
flag = 0;
count = 1;
e_old = e;
e = NULL;
l = e_old->l;
/* count radial loops */
if (e_iter->l->v == v) {
loop_num += 1;
}
else if (l->radial_next == l) {
/* break the loop */
e = e_old;
if (!BM_edge_is_boundary(e_iter)) {
/* non boundary check opposite loop */
if (e_iter->l->radial_next->v == v) {
loop_num += 1;
}
}
else {
l = l->radial_next;
/* start at the boundary */
l_first = e_iter->l;
boundary_num += 1;
/* >2 boundaries cant be manifold */
if (boundary_num == 3) {
return false;
}
}
}
if (count < len) {
/* vert shared by multiple regions */
return false;
}
edge_num += 1;
} while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
return true;
e_first = l_first->e;
l_first = (l_first->v == v) ? l_first : l_first->next;
BLI_assert(l_first->v == v);
l_iter = l_first;
e_prev = e_first;
do {
loop_num_region += 1;
} while (((l_iter = BM_vert_step_fan_loop(l_iter, &e_prev)) != l_first) && (l_iter != NULL));
return (loop_num == loop_num_region);
}
/**