Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2013-05-14 08:09:02 +0400
committerCampbell Barton <ideasman42@gmail.com>2013-05-14 08:09:02 +0400
commitb31e03fdd149c56bab6f3ffe171e1403f35f3d17 (patch)
tree9595f5c6526c55ec9f9bc67ea22de77cea11c894 /source
parentff1a587e1c5596c02e1eb5dafe6bcfb9051c6bc8 (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.c148
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);
}
}
}