[Bf-blender-cvs] [d24cfa329b2] master: Fix T58832: Spin tool creates duplicate faces

Campbell Barton noreply at git.blender.org
Thu Dec 6 04:53:03 CET 2018


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);



More information about the Bf-blender-cvs mailing list