[Bf-blender-cvs] [304315d181d] master: BMesh: Fix BM_face_loop_separate_multi

Campbell Barton noreply at git.blender.org
Sat Mar 11 13:23:16 CET 2017


Commit: 304315d181dba4f45093950b448608e1194e8bbd
Author: Campbell Barton
Date:   Sat Mar 11 23:21:37 2017 +1100
Branches: master
https://developer.blender.org/rB304315d181dba4f45093950b448608e1194e8bbd

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.

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

M	source/blender/bmesh/intern/bmesh_core.c

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

diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c
index d1178a198dc..68cacf55efe 100644
--- a/source/blender/bmesh/intern/bmesh_core.c
+++ b/source/blender/bmesh/intern/bmesh_core.c
@@ -2692,10 +2692,12 @@ BMVert *bmesh_urmv_loop_multi(
 {
 	BMVert *v_sep = larr[0]->v;
 	BMVert *v_new;
+	int edges_len = 0;
 	int i;
-	bool is_mixed_any = false;
-
-	BLI_SMALLSTACK_DECLARE(edges, BMEdge *);
+	/* any edges not owned by 'larr' loops connected to 'v_sep'? */
+	bool is_mixed_edge_any = false;
+	/* any loops not owned by 'larr' radially connected to 'larr' loop edges? */
+	bool is_mixed_loop_any = false;
 
 #define LOOP_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) */
 		BM_ELEM_API_FLAG_ENABLE(l_sep->next, 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};
-		int j;
-		for (j = 0; j < ARRAY_SIZE(loop_pair); j++) {
+		for (int j = 0; j < ARRAY_SIZE(loop_pair); j++) {
 			BMEdge *e = loop_pair[j]->e;
 			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);
+				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 {
 					if (!BM_ELEM_API_FLAG_TEST(l_iter, LOOP_VISIT)) {
-						is_mixed = true;
-						is_mixed_any = true;
+						is_mixed_loop = true;
 						break;
 					}
 				} 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
 					 * on the edge's loop-flag to see if the edge is mixed or not. */
-					e->l = l_iter;
+					e_iter->l = l_iter;
+
+					is_mixed_loop_any = true;
 				}
-				BLI_SMALLSTACK_PUSH(edges, e);
+
+				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);
 	}
 
-	if (is_mixed_any == false) {
+	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.
 		 * nothing to split away from, this is a no-op */
 		v_new = v_sep;
 	}
 	else {
-		BMEdge *e;
-
-		BLI_assert(!BLI_SMALLSTACK_IS_EMPTY(edges));
-
 		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;
 			BMEdge *e_new;
 
 			/* disable so copied edge isn't left dirty (loop edges are cleared last too) */
 			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)) {
 				/* edge has some loops owned by us, some owned by other loops */
 				BMVert *e_new_v_pair[2];




More information about the Bf-blender-cvs mailing list