[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [56783] trunk/blender/source/blender/bmesh /intern/bmesh_walkers_impl.c: refactor bmesh edge loop walker,

Campbell Barton ideasman42 at gmail.com
Tue May 14 06:09:03 CEST 2013


Revision: 56783
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=56783
Author:   campbellbarton
Date:     2013-05-14 04:09:02 +0000 (Tue, 14 May 2013)
Log Message:
-----------
refactor bmesh edge loop walker,
was getting too complicated handing different cases at once, split out boundary case into its own branch.

Modified Paths:
--------------
    trunk/blender/source/blender/bmesh/intern/bmesh_walkers_impl.c

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_walkers_impl.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_walkers_impl.c	2013-05-14 03:06:58 UTC (rev 56782)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_walkers_impl.c	2013-05-14 04:09:02 UTC (rev 56783)
@@ -538,95 +538,121 @@
 			}
 		}
 	}
-	else if (l) { /* NORMAL EDGE WITH FACES */
-		int vert_edge_tot;
-		int stopi = 0;
+	else if (l == NULL) {  /* WIRE EDGE */
+		BMIter eiter;
 
-		v = BM_edge_other_vert(e, lwalk->lastv);
+		/* match trunk: mark all connected wire edges */
+		for (i = 0; i < 2; i++) {
+			v = i ? e->v2 : e->v1;
 
-		vert_edge_tot = BM_vert_edge_count_nonwire(v);
+			BM_ITER_ELEM (nexte, &eiter, v, BM_EDGES_OF_VERT) {
+				if ((nexte->l == NULL) &&
+				    bmw_mask_check_edge(walker, nexte) &&
+				    !BLI_ghash_haskey(walker->visithash, nexte))
+				{
+					lwalk = BMW_state_add(walker);
+					lwalk->cur = nexte;
+					lwalk->lastv = v;
 
-		if (/* check if we should step, this is fairly involved */
+					lwalk->is_boundary = owalk.is_boundary;
+					lwalk->is_single = owalk.is_single;
+					lwalk->f_hub = owalk.f_hub;
 
-			/* typical loopiong over edges in the middle of a mesh */
-			/* however, why use 2 here at all? I guess for internal ngon loops it can be useful. Antony R. */
-			((vert_edge_tot == 4 || vert_edge_tot == 2) && owalk.is_boundary == false) ||
+					BLI_ghash_insert(walker->visithash, nexte, NULL);
+				}
+			}
+		}
+	}
+	else if (owalk.is_boundary == false) {  /* NORMAL EDGE WITH FACES */
+		int vert_edge_tot;
 
-			/* walk over boundary of faces but stop at corners */
-			(owalk.is_boundary == true && owalk.is_single == false && vert_edge_tot > 2) ||
+		v = BM_edge_other_vert(e, lwalk->lastv);
 
-			/* initial edge was a boundary, so is this edge and vertex is only apart of this face
-			 * this lets us walk over the the boundary of an ngon which is handy */
-			(owalk.is_boundary == true && owalk.is_single == true && vert_edge_tot == 2 && BM_edge_is_boundary(e)))
-		{
-			i = 0;
-			stopi = vert_edge_tot / 2;
-			while (1) {
-				if ((owalk.is_boundary == false) && (i == stopi)) {
-					break;
-				}
+		vert_edge_tot = BM_vert_edge_count_nonwire(v);
 
+		/* typical loopiong over edges in the middle of a mesh */
+		/* however, why use 2 here at all? I guess for internal ngon loops it can be useful. Antony R. */
+		if (vert_edge_tot == 4 || vert_edge_tot == 2) {
+			int i_opposite = vert_edge_tot / 2;
+			int i = 0;
+			do {
 				l = BM_loop_other_edge_loop(l, v);
-
-				if (l == NULL) {
-					break;
+				if (BM_edge_is_manifold(l->e)) {
+					l = l->radial_next;
 				}
 				else {
-					BMLoop *l_next;
-
-					l_next = l->radial_next;
-
-					if ((l_next == l) || (l_next == NULL)) {
-						break;
-					}
-
-					l = l_next;
-					i++;
+					l = NULL;
+					break;
 				}
-			}
+			} while ((++i != i_opposite));
 		}
+		else {
+			l = NULL;
+		}
 
 		if (l != NULL) {
 			if (l != e->l &&
 			    bmw_mask_check_edge(walker, l->e) &&
 			    !BLI_ghash_haskey(walker->visithash, l->e))
 			{
-				if (!(owalk.is_boundary == false && i != stopi)) {
-					lwalk = BMW_state_add(walker);
-					lwalk->cur = l->e;
-					lwalk->lastv = v;
+				lwalk = BMW_state_add(walker);
+				lwalk->cur = l->e;
+				lwalk->lastv = v;
 
-					lwalk->is_boundary = owalk.is_boundary;
-					lwalk->is_single = owalk.is_single;
-					lwalk->f_hub = owalk.f_hub;
+				lwalk->is_boundary = owalk.is_boundary;
+				lwalk->is_single = owalk.is_single;
+				lwalk->f_hub = owalk.f_hub;
 
-					BLI_ghash_insert(walker->visithash, l->e, NULL);
-				}
+				BLI_ghash_insert(walker->visithash, l->e, NULL);
 			}
 		}
 	}
-	else {  /* WIRE EDGE */
-		BMIter eiter;
+	else if (owalk.is_boundary == true) {  /* BOUNDARY EDGE WITH FACES */
+		int vert_edge_tot;
 
-		/* match trunk: mark all connected wire edges */
-		for (i = 0; i < 2; i++) {
-			v = i ? e->v2 : e->v1;
+		v = BM_edge_other_vert(e, lwalk->lastv);
 
-			BM_ITER_ELEM (nexte, &eiter, v, BM_EDGES_OF_VERT) {
-				if ((nexte->l == NULL) &&
-				    bmw_mask_check_edge(walker, nexte) &&
-				    !BLI_ghash_haskey(walker->visithash, nexte))
-				{
-					lwalk = BMW_state_add(walker);
-					lwalk->cur = nexte;
-					lwalk->lastv = v;
+		vert_edge_tot = BM_vert_edge_count_nonwire(v);
 
-					lwalk->is_boundary = owalk.is_boundary;
-					lwalk->is_single = owalk.is_single;
-					lwalk->f_hub = owalk.f_hub;
+		/* check if we should step, this is fairly involved */
+		if (
+			/* walk over boundary of faces but stop at corners */
+			(owalk.is_single == false && vert_edge_tot > 2) ||
 
-					BLI_ghash_insert(walker->visithash, nexte, NULL);
+			/* initial edge was a boundary, so is this edge and vertex is only apart of this face
+			 * this lets us walk over the the boundary of an ngon which is handy */
+			(owalk.is_single == true && vert_edge_tot == 2 && BM_edge_is_boundary(e)))
+		{
+			/* find next boundary edge in the fan */
+			do {
+				l = BM_loop_other_edge_loop(l, v);
+				if (BM_edge_is_manifold(l->e)) {
+					l = l->radial_next;
 				}
+				else if (BM_edge_is_boundary(l->e)) {
+					break;
+				}
+				else {
+					l = NULL;
+					break;
+				}
+			} while (true);
+		}
+
+		if (l != NULL) {
+			if (l != e->l &&
+			    bmw_mask_check_edge(walker, l->e) &&
+			    !BLI_ghash_haskey(walker->visithash, l->e))
+			{
+				lwalk = BMW_state_add(walker);
+				lwalk->cur = l->e;
+				lwalk->lastv = v;
+
+				lwalk->is_boundary = owalk.is_boundary;
+				lwalk->is_single = owalk.is_single;
+				lwalk->f_hub = owalk.f_hub;
+
+				BLI_ghash_insert(walker->visithash, l->e, NULL);
 			}
 		}
 	}




More information about the Bf-blender-cvs mailing list