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:
@@ -2692,10 +2692,12 @@ BMVert *bmesh_urmv_loop_multi(
|
|||||||
{
|
{
|
||||||
BMVert *v_sep = larr[0]->v;
|
BMVert *v_sep = larr[0]->v;
|
||||||
BMVert *v_new;
|
BMVert *v_new;
|
||||||
|
int edges_len = 0;
|
||||||
int i;
|
int i;
|
||||||
bool is_mixed_any = false;
|
/* any edges not owned by 'larr' loops connected to 'v_sep'? */
|
||||||
|
bool is_mixed_edge_any = false;
|
||||||
BLI_SMALLSTACK_DECLARE(edges, BMEdge *);
|
/* any loops not owned by 'larr' radially connected to 'larr' loop edges? */
|
||||||
|
bool is_mixed_loop_any = false;
|
||||||
|
|
||||||
#define LOOP_VISIT _FLAG_WALK
|
#define LOOP_VISIT _FLAG_WALK
|
||||||
#define EDGE_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) */
|
* 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->next, LOOP_VISIT);
|
||||||
BM_ELEM_API_FLAG_ENABLE(l_sep->prev, 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};
|
BMLoop *loop_pair[2] = {l_sep, l_sep->prev};
|
||||||
int j;
|
for (int j = 0; j < ARRAY_SIZE(loop_pair); j++) {
|
||||||
for (j = 0; j < ARRAY_SIZE(loop_pair); j++) {
|
|
||||||
BMEdge *e = loop_pair[j]->e;
|
BMEdge *e = loop_pair[j]->e;
|
||||||
if (!BM_ELEM_API_FLAG_TEST(e, EDGE_VISIT)) {
|
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);
|
BM_ELEM_API_FLAG_ENABLE(e, EDGE_VISIT);
|
||||||
|
edges_len += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
l_iter = l_first = e->l;
|
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 {
|
do {
|
||||||
if (!BM_ELEM_API_FLAG_TEST(l_iter, LOOP_VISIT)) {
|
if (!BM_ELEM_API_FLAG_TEST(l_iter, LOOP_VISIT)) {
|
||||||
is_mixed = true;
|
is_mixed_loop = true;
|
||||||
is_mixed_any = true;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while ((l_iter = l_iter->radial_next) != l_first);
|
} while ((l_iter = l_iter->radial_next) != l_first);
|
||||||
|
|
||||||
if (is_mixed) {
|
if (is_mixed_loop) {
|
||||||
/* ensure the first loop is one we don't own so we can do a quick check below
|
/* 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. */
|
* on the edge's loop-flag to see if the edge is mixed or not. */
|
||||||
e->l = l_iter;
|
e_iter->l = l_iter;
|
||||||
}
|
|
||||||
BLI_SMALLSTACK_PUSH(edges, e);
|
is_mixed_loop_any = true;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_mixed_any == false) {
|
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.
|
/* all loops in 'larr' are the sole owners of their edges.
|
||||||
* nothing to split away from, this is a no-op */
|
* nothing to split away from, this is a no-op */
|
||||||
v_new = v_sep;
|
v_new = v_sep;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
BMEdge *e;
|
|
||||||
|
|
||||||
BLI_assert(!BLI_SMALLSTACK_IS_EMPTY(edges));
|
|
||||||
|
|
||||||
v_new = BM_vert_create(bm, v_sep->co, v_sep, BM_CREATE_NOP);
|
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;
|
BMLoop *l_iter, *l_first, *l_next;
|
||||||
BMEdge *e_new;
|
BMEdge *e_new;
|
||||||
|
|
||||||
/* disable so copied edge isn't left dirty (loop edges are cleared last too) */
|
/* disable so copied edge isn't left dirty (loop edges are cleared last too) */
|
||||||
BM_ELEM_API_FLAG_DISABLE(e, EDGE_VISIT);
|
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)) {
|
if (!BM_ELEM_API_FLAG_TEST(e->l, LOOP_VISIT)) {
|
||||||
/* edge has some loops owned by us, some owned by other loops */
|
/* edge has some loops owned by us, some owned by other loops */
|
||||||
BMVert *e_new_v_pair[2];
|
BMVert *e_new_v_pair[2];
|
||||||
|
Reference in New Issue
Block a user