BMesh: Fix BM_face_loop_separate_multi
When the loop region passed in had no loops to edge-split from, it was assumed nothing needed to be done. This ignored the case where loops share a vertex without any shared edges. Now BM_face_loop_separate_multi behaves like BM_face_loop_separate. Fixed error where faces remained connected by verts in BM_mesh_separate_faces.
This commit is contained in:
parent
ce155ad2f6
commit
304315d181
@ -2692,10 +2692,12 @@ BMVert *bmesh_urmv_loop_multi(
|
||||
{
|
||||
BMVert *v_sep = larr[0]->v;
|
||||
BMVert *v_new;
|
||||
int edges_len = 0;
|
||||
int i;
|
||||
bool is_mixed_any = false;
|
||||
|
||||
BLI_SMALLSTACK_DECLARE(edges, BMEdge *);
|
||||
/* any edges not owned by 'larr' loops connected to 'v_sep'? */
|
||||
bool is_mixed_edge_any = false;
|
||||
/* any loops not owned by 'larr' radially connected to 'larr' loop edges? */
|
||||
bool is_mixed_loop_any = false;
|
||||
|
||||
#define LOOP_VISIT _FLAG_WALK
|
||||
#define EDGE_VISIT _FLAG_WALK
|
||||
@ -2713,58 +2715,73 @@ BMVert *bmesh_urmv_loop_multi(
|
||||
* while doing a radial loop (where loops may be adjacent) */
|
||||
BM_ELEM_API_FLAG_ENABLE(l_sep->next, LOOP_VISIT);
|
||||
BM_ELEM_API_FLAG_ENABLE(l_sep->prev, LOOP_VISIT);
|
||||
}
|
||||
|
||||
for (i = 0; i < larr_len; i++) {
|
||||
BMLoop *l_sep = larr[i];
|
||||
|
||||
BMLoop *loop_pair[2] = {l_sep, l_sep->prev};
|
||||
int j;
|
||||
for (j = 0; j < ARRAY_SIZE(loop_pair); j++) {
|
||||
for (int j = 0; j < ARRAY_SIZE(loop_pair); j++) {
|
||||
BMEdge *e = loop_pair[j]->e;
|
||||
if (!BM_ELEM_API_FLAG_TEST(e, EDGE_VISIT)) {
|
||||
BMLoop *l_iter, *l_first;
|
||||
bool is_mixed = false;
|
||||
|
||||
BM_ELEM_API_FLAG_ENABLE(e, EDGE_VISIT);
|
||||
|
||||
l_iter = l_first = e->l;
|
||||
do {
|
||||
if (!BM_ELEM_API_FLAG_TEST(l_iter, LOOP_VISIT)) {
|
||||
is_mixed = true;
|
||||
is_mixed_any = true;
|
||||
break;
|
||||
}
|
||||
} while ((l_iter = l_iter->radial_next) != l_first);
|
||||
|
||||
if (is_mixed) {
|
||||
/* ensure the first loop is one we don't own so we can do a quick check below
|
||||
* on the edge's loop-flag to see if the edge is mixed or not. */
|
||||
e->l = l_iter;
|
||||
}
|
||||
BLI_SMALLSTACK_PUSH(edges, e);
|
||||
edges_len += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_mixed_any == false) {
|
||||
BMEdge **edges = BLI_array_alloca(edges, edges_len);
|
||||
STACK_DECLARE(edges);
|
||||
|
||||
STACK_INIT(edges, edges_len);
|
||||
|
||||
{
|
||||
BMEdge *e_first, *e_iter;
|
||||
e_iter = e_first = v_sep->e;
|
||||
do {
|
||||
if (BM_ELEM_API_FLAG_TEST(e_iter, EDGE_VISIT)) {
|
||||
BMLoop *l_iter, *l_first;
|
||||
bool is_mixed_loop = false;
|
||||
|
||||
l_iter = l_first = e_iter->l;
|
||||
do {
|
||||
if (!BM_ELEM_API_FLAG_TEST(l_iter, LOOP_VISIT)) {
|
||||
is_mixed_loop = true;
|
||||
break;
|
||||
}
|
||||
} while ((l_iter = l_iter->radial_next) != l_first);
|
||||
|
||||
if (is_mixed_loop) {
|
||||
/* ensure the first loop is one we don't own so we can do a quick check below
|
||||
* on the edge's loop-flag to see if the edge is mixed or not. */
|
||||
e_iter->l = l_iter;
|
||||
|
||||
is_mixed_loop_any = true;
|
||||
}
|
||||
|
||||
STACK_PUSH(edges, e_iter);
|
||||
} else {
|
||||
/* at least one edge attached isn't connected to our loops */
|
||||
is_mixed_edge_any = true;
|
||||
}
|
||||
} while ((e_iter = bmesh_disk_edge_next(e_iter, v_sep)) != e_first);
|
||||
}
|
||||
|
||||
BLI_assert(edges_len == STACK_SIZE(edges));
|
||||
|
||||
if (is_mixed_loop_any == false && is_mixed_edge_any == false) {
|
||||
/* all loops in 'larr' are the sole owners of their edges.
|
||||
* nothing to split away from, this is a no-op */
|
||||
v_new = v_sep;
|
||||
}
|
||||
else {
|
||||
BMEdge *e;
|
||||
|
||||
BLI_assert(!BLI_SMALLSTACK_IS_EMPTY(edges));
|
||||
|
||||
v_new = BM_vert_create(bm, v_sep->co, v_sep, BM_CREATE_NOP);
|
||||
while ((e = BLI_SMALLSTACK_POP(edges))) {
|
||||
|
||||
for (i = 0; i < STACK_SIZE(edges); i++) {
|
||||
BMEdge *e = edges[i];
|
||||
BMLoop *l_iter, *l_first, *l_next;
|
||||
BMEdge *e_new;
|
||||
|
||||
/* disable so copied edge isn't left dirty (loop edges are cleared last too) */
|
||||
BM_ELEM_API_FLAG_DISABLE(e, EDGE_VISIT);
|
||||
|
||||
/* will always be false when (is_mixed_loop_any == false) */
|
||||
if (!BM_ELEM_API_FLAG_TEST(e->l, LOOP_VISIT)) {
|
||||
/* edge has some loops owned by us, some owned by other loops */
|
||||
BMVert *e_new_v_pair[2];
|
||||
|
Loading…
Reference in New Issue
Block a user