diff options
author | Campbell Barton <ideasman42@gmail.com> | 2012-03-12 01:47:14 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2012-03-12 01:47:14 +0400 |
commit | ac24d98e24c0d8d1dfd005d4f332e906f1b9664c (patch) | |
tree | b4b305c41940f8ac2a3ea85152a19dd910bbd007 /source | |
parent | 33d81047163cf13c45e6f9914a10d16a768d954b (diff) |
bmesh: edge loop select
add support for loop selecting boundry edges only - handy for loop selecting the side of an ngon.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/bmesh/intern/bmesh_queries.c | 13 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_queries.h | 3 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_walkers_impl.c | 39 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_walkers_private.h | 4 |
4 files changed, 35 insertions, 24 deletions
diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index 357afbe391e..cc9dfe1701b 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -291,20 +291,15 @@ int BM_vert_edge_count(BMVert *v) 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; } diff --git a/source/blender/bmesh/intern/bmesh_queries.h b/source/blender/bmesh/intern/bmesh_queries.h index 0ce5fb3a665..2524d090a4e 100644 --- a/source/blender/bmesh/intern/bmesh_queries.h +++ b/source/blender/bmesh/intern/bmesh_queries.h @@ -42,6 +42,7 @@ BMVert *BM_edge_other_vert(BMEdge *e, BMVert *v); 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_face_count(BMVert *v); 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); diff --git a/source/blender/bmesh/intern/bmesh_walkers_impl.c b/source/blender/bmesh/intern/bmesh_walkers_impl.c index 20386a78604..cd815c9be83 100644 --- a/source/blender/bmesh/intern/bmesh_walkers_impl.c +++ b/source/blender/bmesh/intern/bmesh_walkers_impl.c @@ -398,7 +398,9 @@ static void bmw_LoopWalker_begin(BMWalker *walker, void *data) 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 @@ static void *bmw_LoopWalker_step(BMWalker *walker) 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 @@ static void *bmw_LoopWalker_step(BMWalker *walker) 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 @@ static void *bmw_LoopWalker_step(BMWalker *walker) 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 @@ static void *bmw_LoopWalker_step(BMWalker *walker) } 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); } } diff --git a/source/blender/bmesh/intern/bmesh_walkers_private.h b/source/blender/bmesh/intern/bmesh_walkers_private.h index b1447b52d1a..d51a3b3ddb1 100644 --- a/source/blender/bmesh/intern/bmesh_walkers_private.h +++ b/source/blender/bmesh/intern/bmesh_walkers_private.h @@ -61,7 +61,9 @@ typedef struct BMwLoopWalker { 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 { |