[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [44817] trunk/blender/source/blender/bmesh /intern: bmesh: edge loop select

Campbell Barton ideasman42 at gmail.com
Sun Mar 11 22:47:24 CET 2012


Revision: 44817
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=44817
Author:   campbellbarton
Date:     2012-03-11 21:47:14 +0000 (Sun, 11 Mar 2012)
Log Message:
-----------
bmesh: edge loop select
    add support for loop selecting boundry edges only - handy for loop selecting the side of an ngon.

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

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_queries.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_queries.c	2012-03-11 20:45:58 UTC (rev 44816)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_queries.c	2012-03-11 21:47:14 UTC (rev 44817)
@@ -291,20 +291,15 @@
 	return bmesh_disk_count(v);
 }
 
-int BM_vert_edge_count_nonwire( BMesh *bm, BMVert *v)
+int BM_vert_edge_count_nonwire(BMVert *v)
 {
 	int count = 0;
 	BMIter eiter;
 	BMEdge *edge;
-	BM_ITER(edge, &eiter, bm, BM_EDGES_OF_VERT, v){
-		if (!edge) return count;
-
-		if (count >= (1 << 20)) {
-			printf(" bmesh error: infinite loop in disk cycle!\n");
-			return 0;
+	BM_ITER(edge, &eiter, NULL, BM_EDGES_OF_VERT, v){
+		if(edge->l) {
+			count++;
 		}
-
-		if(edge->l) count++;
 	}
 	return count;
 }

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_queries.h
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_queries.h	2012-03-11 20:45:58 UTC (rev 44816)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_queries.h	2012-03-11 21:47:14 UTC (rev 44817)
@@ -42,6 +42,7 @@
 BMLoop *BM_face_other_edge_loop(BMFace *f, BMEdge *e, BMVert *v);
 BMLoop *BM_face_other_vert_loop(BMFace *f, BMVert *v_prev, BMVert *v);
 
+int     BM_vert_edge_count_nonwire(BMVert *v);
 int     BM_vert_edge_count(BMVert *v);
 int     BM_edge_face_count(BMEdge *e);
 int     BM_vert_face_count(BMVert *v);
@@ -49,8 +50,6 @@
 int     BM_vert_is_wire(BMesh *bm, BMVert *v);
 int     BM_edge_is_wire(BMesh *bm, BMEdge *e);
 
-int 	BM_vert_edge_count_nonwire( BMesh *bm, BMVert *v);
-
 int     BM_vert_is_manifold(BMesh *bm, BMVert *v);
 int     BM_edge_is_manifold(BMesh *bm, BMEdge *e);
 int     BM_edge_is_boundary(BMEdge *e);

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_walkers_impl.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_walkers_impl.c	2012-03-11 20:45:58 UTC (rev 44816)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_walkers_impl.c	2012-03-11 21:47:14 UTC (rev 44817)
@@ -398,7 +398,9 @@
 	lwalk->cur = lwalk->start = e;
 	lwalk->lastv = lwalk->startv = v;
 	lwalk->stage2 = 0;
-	lwalk->startrad = BM_edge_face_count(e);
+	lwalk->is_boundry = BM_edge_is_boundary(e);
+	lwalk->is_single = (BM_vert_edge_count_nonwire(e->v1) == 2 &&
+	                    BM_vert_edge_count_nonwire(e->v2) == 2);
 
 	/* rewin */
 	while (BMW_current_state(walker)) {
@@ -433,7 +435,9 @@
 	BMEdge *e = lwalk->cur, *nexte = NULL;
 	BMLoop *l, *l2;
 	BMVert *v;
-	int val, rlen /* , found = 0 */, i = 0, stopi;
+	int vert_edge_tot;
+	int i = 0, stopi;
+	/* int found = 0; */ /* UNUSED */
 
 	owalk = *lwalk;
 	BMW_state_remove(walker);
@@ -452,7 +456,8 @@
 					lwalk = BMW_state_add(walker);
 					lwalk->cur = nexte;
 					lwalk->lastv = v;
-					lwalk->startrad = owalk.startrad;
+					lwalk->is_boundry = owalk.is_boundry;
+					lwalk->is_single = owalk.is_single;
 
 					BLI_ghash_insert(walker->visithash, nexte, NULL);
 				}
@@ -462,18 +467,27 @@
 		return owalk.cur;
 	}
 
-	v = (e->v1 == lwalk->lastv) ? e->v2 : e->v1;
+	v = BM_edge_other_vert(e, lwalk->lastv);
 
-	rlen = owalk.startrad;
+	vert_edge_tot = BM_vert_edge_count_nonwire(v);
 
-	val = BM_vert_edge_count_nonwire(walker->bm, v);
+	if (/* check if we should step, this is fairly involved */
 
-	/* however, why use 2 here at all? I guess for internal ngon loops it can be useful. Antony R. */
-	if (((val == 4 || val == 2) && rlen > 1) || (rlen == 1 && val > 2)) {
+	    /* 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_boundry == FALSE) ||
+
+	    /* walk over boundry of faces but stop at corners */
+	    (owalk.is_boundry == TRUE && owalk.is_single  == FALSE && vert_edge_tot > 2) ||
+
+	    /* initial edge was a boundry, so is this edge and vertex is only apart of this face
+	     * this lets us walk over the the boundry of an ngon which is handy */
+	    (owalk.is_boundry == TRUE && owalk.is_single == TRUE && vert_edge_tot == 2 && BM_edge_is_boundary(e)))
+	{
 		i = 0;
-		stopi = val / 2;
+		stopi = vert_edge_tot / 2;
 		while (1) {
-			if (rlen != 1 && i == stopi) break;
+			if (owalk.is_boundry == FALSE && i == stopi) break;
 
 			l = BM_face_other_edge_loop(l->f, l->e, v);
 
@@ -496,11 +510,12 @@
 	}
 
 	if (l != e->l && !BLI_ghash_haskey(walker->visithash, l->e)) {
-		if (!(rlen != 1 && i != stopi)) {
+		if (!(owalk.is_boundry == FALSE && i != stopi)) {
 			lwalk = BMW_state_add(walker);
 			lwalk->cur = l->e;
 			lwalk->lastv = v;
-			lwalk->startrad = owalk.startrad;
+			lwalk->is_boundry = owalk.is_boundry;
+			lwalk->is_single = owalk.is_single;
 			BLI_ghash_insert(walker->visithash, l->e, NULL);
 		}
 	}

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_walkers_private.h
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_walkers_private.h	2012-03-11 20:45:58 UTC (rev 44816)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_walkers_private.h	2012-03-11 21:47:14 UTC (rev 44817)
@@ -61,7 +61,9 @@
 	BMwGenericWalker header;
 	BMEdge *cur, *start;
 	BMVert *lastv, *startv;
-	int startrad, stage2;
+	int stage2;
+	short is_boundry; /* boundry looping changes behavior */
+	short is_single;  /* single means the edge verts are only connected to 1 face */
 } BMwLoopWalker;
 
 typedef struct BMwFaceLoopWalker {




More information about the Bf-blender-cvs mailing list