diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-05-14 08:09:02 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-05-14 08:09:02 +0400 |
commit | b31e03fdd149c56bab6f3ffe171e1403f35f3d17 (patch) | |
tree | 9595f5c6526c55ec9f9bc67ea22de77cea11c894 /source | |
parent | ff1a587e1c5596c02e1eb5dafe6bcfb9051c6bc8 (diff) |
refactor bmesh edge loop walker,
was getting too complicated handing different cases at once, split out boundary case into its own branch.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/bmesh/intern/bmesh_walkers_impl.c | 148 |
1 files changed, 87 insertions, 61 deletions
diff --git a/source/blender/bmesh/intern/bmesh_walkers_impl.c b/source/blender/bmesh/intern/bmesh_walkers_impl.c index 187c808de41..c966ee337db 100644 --- a/source/blender/bmesh/intern/bmesh_walkers_impl.c +++ b/source/blender/bmesh/intern/bmesh_walkers_impl.c @@ -538,52 +538,56 @@ static void *bmw_LoopWalker_step(BMWalker *walker) } } } - 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) { @@ -591,42 +595,64 @@ static void *bmw_LoopWalker_step(BMWalker *walker) 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); } } } |