Fix T58832: Spin tool creates duplicate faces

This commit is contained in:
2018-12-06 14:50:25 +11:00
parent f6c615a8c2
commit d24cfa329b
3 changed files with 50 additions and 0 deletions

View File

@@ -2063,6 +2063,40 @@ BMFace *BM_face_exists(BMVert **varr, int len)
return NULL;
}
/**
* Check if the face has an exact duplicate (both winding directions).
*/
BMFace *BM_face_find_double(BMFace *f)
{
BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
for (BMLoop *l_iter = l_first->radial_next; l_first != l_iter; l_iter = l_iter->radial_next) {
if (l_iter->f->len == l_first->f->len) {
if (l_iter->v == l_first->v) {
BMLoop *l_a = l_first, *l_b = l_iter, *l_b_init = l_iter;
do {
if (l_a->e != l_b->e) {
break;
}
} while (((void)(l_a = l_a->next), (l_b = l_b->next)) != l_b_init);
if (l_b == l_b_init) {
return l_iter->f;
}
}
else {
BMLoop *l_a = l_first, *l_b = l_iter, *l_b_init = l_iter;
do {
if (l_a->e != l_b->e) {
break;
}
} while (((void)(l_a = l_a->prev), (l_b = l_b->next)) != l_b_init);
if (l_b == l_b_init) {
return l_iter->f;
}
}
}
}
return NULL;
}
/**
* Given a set of vertices and edges (\a varr, \a earr), find out if

View File

@@ -141,6 +141,7 @@ BMEdge *BM_edge_exists(BMVert *v1, BMVert *v2) ATTR_WARN_UNUSED_RESULT ATTR_NONN
BMEdge *BM_edge_find_double(BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
BMFace *BM_face_exists(BMVert **varr, int len) ATTR_NONNULL(1);
BMFace *BM_face_find_double(BMFace *f) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
bool BM_face_exists_multi(BMVert **varr, BMEdge **earr, int len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
bool BM_face_exists_multi_edge(BMEdge **earr, int len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();

View File

@@ -564,6 +564,21 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op)
i++;
}
}
/* Full copies of faces may cause overlap. */
for (int i = 0; i < elem_array_len; ) {
if (elem_array[i]->head.htype == BM_FACE) {
BMFace *f_src = (BMFace *)elem_array[i];
BMFace *f_dst = BM_face_find_double(f_src);
if (f_dst != NULL) {
BM_face_kill(bm, f_src);
elem_array_len--;
elem_array[i] = elem_array[elem_array_len];
}
}
else {
i++;
}
}
slot_geom_out->len = elem_array_len;
}
BMO_op_finish(bm, &extop);