Commit: d24cfa329b221cae4a6e7ecc4d0e4ea778ac5c71
Author: Campbell Barton
Date:   Thu Dec 6 14:50:25 2018 +1100
Branches: master
https://developer.blender.org/rBd24cfa329b221cae4a6e7ecc4d0e4ea778ac5c71

Fix T58832: Spin tool creates duplicate faces

===================================================================

M       source/blender/bmesh/intern/bmesh_query.c
M       source/blender/bmesh/intern/bmesh_query.h
M       source/blender/bmesh/operators/bmo_dupe.c

===================================================================

diff --git a/source/blender/bmesh/intern/bmesh_query.c 
b/source/blender/bmesh/intern/bmesh_query.c
index e1f16508b8b..13e2029381e 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 fb625c9acc8..17bf0f38d0c 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);

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to