[Bf-blender-cvs] [93fb07f] master: BMesh: bmesh_jekv check for degenerate faces

Campbell Barton noreply at git.blender.org
Thu Nov 19 13:01:38 CET 2015


Commit: 93fb07fbd55afcaac15e96b93892e65341bb92c4
Author: Campbell Barton
Date:   Thu Nov 19 15:28:18 2015 +1100
Branches: master
https://developer.blender.org/rB93fb07fbd55afcaac15e96b93892e65341bb92c4

BMesh: bmesh_jekv check for degenerate faces

Move check for degenerate faces from BM_vert_collapse_faces into bmesh_jekv.

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

M	source/blender/bmesh/intern/bmesh_core.c
M	source/blender/bmesh/intern/bmesh_core.h
M	source/blender/bmesh/intern/bmesh_mods.c
M	source/blender/bmesh/operators/bmo_offset_edgeloops.c

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

diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c
index 5f184bb..618407b 100644
--- a/source/blender/bmesh/intern/bmesh_core.c
+++ b/source/blender/bmesh/intern/bmesh_core.c
@@ -1708,14 +1708,15 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
  */
 BMEdge *bmesh_jekv(
         BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
-        const bool do_del, const bool check_edge_double)
+        const bool do_del, const bool check_edge_double,
+        const bool kill_degenerate_faces)
 {
 	BMEdge *e_old;
 	BMVert *v_old, *tv;
 	BMLoop *l_kill;
-	int radlen = 0, i;
 	bool halt = false;
 #ifndef NDEBUG
+	int radlen, i;
 	bool edok;
 #endif
 
@@ -1757,11 +1758,17 @@ BMEdge *bmesh_jekv(
 			/* remove e_kill from tv's disk cycle */
 			bmesh_disk_edge_remove(e_kill, tv);
 
+#ifndef NDEBUG
 			/* deal with radial cycle of e_kill */
 			radlen = bmesh_radial_length(e_kill->l);
+#endif
 			if (e_kill->l) {
-				/* first step, fix the neighboring loops of all loops in e_kill's radial cycle */
-				for (i = 0, l_kill = e_kill->l; i < radlen; i++, l_kill = l_kill->radial_next) {
+				BLI_SMALLSTACK_DECLARE(faces_degenerate, BMFace *);
+				BMLoop *l_kill_next;
+
+				/* fix the neighboring loops of all loops in e_kill's radial cycle */
+				l_kill = e_kill->l;
+				do {
 					/* relink loops and fix vertex pointer */
 					if (l_kill->next->v == v_kill) {
 						l_kill->next->v = tv;
@@ -1772,34 +1779,31 @@ BMEdge *bmesh_jekv(
 					if (BM_FACE_FIRST_LOOP(l_kill->f) == l_kill) {
 						BM_FACE_FIRST_LOOP(l_kill->f) = l_kill->next;
 					}
-					l_kill->next = NULL;
-					l_kill->prev = NULL;
 
 					/* fix len attribute of face */
 					l_kill->f->len--;
-				}
-				/* second step, remove all the hanging loops attached to e_kill */
-				radlen = bmesh_radial_length(e_kill->l);
-
-				if (LIKELY(radlen)) {
-					BMLoop **loops = BLI_array_alloca(loops, radlen);
+					if (kill_degenerate_faces) {
+						if (l_kill->f->len < 3) {
+							BLI_SMALLSTACK_PUSH(faces_degenerate, l_kill->f);
+						}
+					}
+					l_kill_next = l_kill->radial_next;
 
-					l_kill = e_kill->l;
+					bm_kill_only_loop(bm, l_kill);
 
-					/* this should be wrapped into a bme_free_radial function to be used by bmesh_KF as well... */
-					for (i = 0; i < radlen; i++) {
-						loops[i] = l_kill;
-						l_kill = l_kill->radial_next;
-					}
-					for (i = 0; i < radlen; i++) {
-						bm_kill_only_loop(bm, loops[i]);
-					}
-				}
+				} while ((l_kill = l_kill_next) != e_kill->l);
+				/* `e_kill->l` is invalid but the edge is freed next. */
 #ifndef NDEBUG
 				/* Validate radial cycle of e_old */
 				edok = bmesh_radial_validate(radlen, e_old->l);
 				BMESH_ASSERT(edok != false);
 #endif
+				if (kill_degenerate_faces) {
+					BMFace *f_kill;
+					while ((f_kill = BLI_SMALLSTACK_POP(faces_degenerate))) {
+						BM_face_kill(bm, f_kill);
+					}
+				}
 			}
 			/* deallocate edge */
 			bm_kill_only_edge(bm, e_kill);
diff --git a/source/blender/bmesh/intern/bmesh_core.h b/source/blender/bmesh/intern/bmesh_core.h
index 2b100eb..d6d5a4d 100644
--- a/source/blender/bmesh/intern/bmesh_core.h
+++ b/source/blender/bmesh/intern/bmesh_core.h
@@ -98,7 +98,8 @@ BMFace *bmesh_sfme(
 BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e);
 BMEdge *bmesh_jekv(
         BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
-        const bool do_del, const bool check_edge_splice);
+        const bool do_del, const bool check_edge_splice,
+        const bool kill_degenerate_faces);
 BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e);
 BMVert *bmesh_urmv(BMesh *bm, BMFace *f_sep, BMVert *v_sep);
 BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *l_sep);
diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c
index 1b693f8..66be8e0 100644
--- a/source/blender/bmesh/intern/bmesh_mods.c
+++ b/source/blender/bmesh/intern/bmesh_mods.c
@@ -1066,32 +1066,8 @@ BMEdge *BM_vert_collapse_faces(
 		/* single face or no faces */
 		/* same as BM_vert_collapse_edge() however we already
 		 * have vars to perform this operation so don't call. */
-		e_new = bmesh_jekv(bm, e_kill, v_kill, do_del, true);
+		e_new = bmesh_jekv(bm, e_kill, v_kill, do_del, true, kill_degenerate_faces);
 		/* e_new = BM_edge_exists(tv, tv2); */ /* same as return above */
-
-		if (e_new && kill_degenerate_faces) {
-			BMFace **bad_faces = NULL;
-			BLI_array_staticdeclare(bad_faces, BM_DEFAULT_ITER_STACK_SIZE);
-
-			BMIter fiter;
-			BMFace *f;
-			BMVert *verts[2] = {e_new->v1, e_new->v2};
-			int i;
-
-			for (i = 0; i < 2; i++) {
-				/* cant kill data we loop on, build a list and remove those */
-				BLI_array_empty(bad_faces);
-				BM_ITER_ELEM (f, &fiter, verts[i], BM_FACES_OF_VERT) {
-					if (UNLIKELY(f->len < 3)) {
-						BLI_array_append(bad_faces, f);
-					}
-				}
-				while ((f = BLI_array_pop(bad_faces))) {
-					BM_face_kill(bm, f);
-				}
-			}
-			BLI_array_free(bad_faces);
-		}
 	}
 
 	return e_new;
diff --git a/source/blender/bmesh/operators/bmo_offset_edgeloops.c b/source/blender/bmesh/operators/bmo_offset_edgeloops.c
index a2f3f0b..8f4bc5e 100644
--- a/source/blender/bmesh/operators/bmo_offset_edgeloops.c
+++ b/source/blender/bmesh/operators/bmo_offset_edgeloops.c
@@ -278,7 +278,7 @@ void bmo_offset_edgeloops_exec(BMesh *bm, BMOperator *op)
 			}
 
 			while ((v = STACK_POP(varr))) {
-				bmesh_jekv(bm, v->e, v, true, false);
+				bmesh_jekv(bm, v->e, v, true, false, false);
 			}
 		}
 	}




More information about the Bf-blender-cvs mailing list