[Bf-blender-cvs] [bd5e578] master: BMesh: rework BM_vert_is_manifold (simplify logic)

Campbell Barton noreply at git.blender.org
Sat May 2 20:47:18 CEST 2015


Commit: bd5e578804d9debe0c8450d196b1960ee66dbaa9
Author: Campbell Barton
Date:   Sun May 3 04:40:02 2015 +1000
Branches: master
https://developer.blender.org/rBbd5e578804d9debe0c8450d196b1960ee66dbaa9

BMesh: rework BM_vert_is_manifold (simplify logic)

- simplify boundary handling (walk from boundary - no need to reset walking)
- early exit when the vert has >2 boundaries
- use BM_vert_step_fan_loop to walk the fan

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

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

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

diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c
index 296bde9..ece4d78 100644
--- a/source/blender/bmesh/intern/bmesh_queries.c
+++ b/source/blender/bmesh/intern/bmesh_queries.c
@@ -861,9 +861,9 @@ bool BM_vert_is_wire(const BMVert *v)
  */
 bool BM_vert_is_manifold(const BMVert *v)
 {
-	BMEdge *e, *e_old;
-	BMLoop *l;
-	int len, count, flag;
+	BMEdge *e_iter, *e_first, *e_prev;
+	BMLoop *l_iter, *l_first;
+	int edge_num = 0, loop_num = 0, loop_num_region = 0, boundary_num = 0;
 
 	if (v->e == NULL) {
 		/* loose vert */
@@ -871,51 +871,52 @@ bool BM_vert_is_manifold(const BMVert *v)
 	}
 
 	/* count edges while looking for non-manifold edges */
-	len = 0;
-	e_old = e = v->e;
+	e_first = e_iter = v->e;
+	l_first = e_iter->l ? e_iter->l : NULL;
 	do {
 		/* loose edge or edge shared by more than two faces,
 		 * edges with 1 face user are OK, otherwise we could
 		 * use BM_edge_is_manifold() here */
-		if (e->l == NULL || (e->l != e->l->radial_next->radial_next)) {
+		if (e_iter->l == NULL || (e_iter->l != e_iter->l->radial_next->radial_next)) {
 			return false;
 		}
-		len++;
-	} while ((e = bmesh_disk_edge_next(e, v)) != e_old);
-
-	count = 1;
-	flag = 1;
-	e = NULL;
-	e_old = v->e;
-	l = e_old->l;
-	while (e != e_old) {
-		l = (l->v == v) ? l->prev : l->next;
-		e = l->e;
-		count++; /* count the edges */
-
-		if (flag && l->radial_next == l) {
-			/* we've hit the edge of an open mesh, reset once */
-			flag = 0;
-			count = 1;
-			e_old = e;
-			e = NULL;
-			l = e_old->l;
+
+		/* count radial loops */
+		if (e_iter->l->v == v) {
+			loop_num += 1;
 		}
-		else if (l->radial_next == l) {
-			/* break the loop */
-			e = e_old;
+
+		if (!BM_edge_is_boundary(e_iter)) {
+			/* non boundary check opposite loop */
+			if (e_iter->l->radial_next->v == v) {
+				loop_num += 1;
+			}
 		}
 		else {
-			l = l->radial_next;
+			/* start at the boundary */
+			l_first = e_iter->l;
+			boundary_num += 1;
+			/* >2 boundaries cant be manifold */
+			if (boundary_num == 3) {
+				return false;
+			}
 		}
-	}
 
-	if (count < len) {
-		/* vert shared by multiple regions */
-		return false;
-	}
+		edge_num += 1;
+	} while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
 
-	return true;
+	e_first = l_first->e;
+	l_first = (l_first->v == v) ? l_first : l_first->next;
+	BLI_assert(l_first->v == v);
+
+	l_iter = l_first;
+	e_prev = e_first;
+
+	do {
+		loop_num_region += 1;
+	} while (((l_iter = BM_vert_step_fan_loop(l_iter, &e_prev)) != l_first) && (l_iter != NULL));
+
+	return (loop_num == loop_num_region);
 }
 
 /**




More information about the Bf-blender-cvs mailing list