diff options
author | Campbell Barton <ideasman42@gmail.com> | 2018-12-06 07:08:42 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2018-12-06 07:08:42 +0300 |
commit | 45afcd6b86be25c4acede0c7afcf1a3384d99cad (patch) | |
tree | 49594ae8623faa3a3318c15f0ab164f0b4ca33d6 /source/blender | |
parent | 1cc070506232cc59e993cc8ddad9b272c413a860 (diff) | |
parent | d24cfa329b221cae4a6e7ecc4d0e4ea778ac5c71 (diff) |
Merge branch 'master' into blender2.8
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/bmesh/intern/bmesh_query.c | 34 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_query.h | 1 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_dupe.c | 15 |
3 files changed, 50 insertions, 0 deletions
diff --git a/source/blender/bmesh/intern/bmesh_query.c b/source/blender/bmesh/intern/bmesh_query.c index c446ce5ab49..cc042bd001c 100644 --- a/source/blender/bmesh/intern/bmesh_query.c +++ b/source/blender/bmesh/intern/bmesh_query.c @@ -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 diff --git a/source/blender/bmesh/intern/bmesh_query.h b/source/blender/bmesh/intern/bmesh_query.h index 7c087a5150f..e5830a25312 100644 --- a/source/blender/bmesh/intern/bmesh_query.h +++ b/source/blender/bmesh/intern/bmesh_query.h @@ -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(); diff --git a/source/blender/bmesh/operators/bmo_dupe.c b/source/blender/bmesh/operators/bmo_dupe.c index c50c7657deb..77019e13969 100644 --- a/source/blender/bmesh/operators/bmo_dupe.c +++ b/source/blender/bmesh/operators/bmo_dupe.c @@ -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); |