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
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2012-03-13 22:37:31 +0400
committerCampbell Barton <ideasman42@gmail.com>2012-03-13 22:37:31 +0400
commit01b3e9cc9fdd0875b93ba749c8209e6c43570d13 (patch)
tree12694b11fa11e94fd6aaf8a79cc26edd92fbeec0 /source/blender/bmesh
parentb47e2ee907a7cc4c949a6a6e4dc895532ca53f5e (diff)
loopwalker support for selecting the sides of ngons
see: wiki.blender.org/uploads/d/dc/BMesh_NGon_Loop_Select.png
Diffstat (limited to 'source/blender/bmesh')
-rw-r--r--source/blender/bmesh/intern/bmesh_walkers_impl.c91
-rw-r--r--source/blender/bmesh/intern/bmesh_walkers_private.h1
2 files changed, 70 insertions, 22 deletions
diff --git a/source/blender/bmesh/intern/bmesh_walkers_impl.c b/source/blender/bmesh/intern/bmesh_walkers_impl.c
index 3c8e2c1f974..d4942412bae 100644
--- a/source/blender/bmesh/intern/bmesh_walkers_impl.c
+++ b/source/blender/bmesh/intern/bmesh_walkers_impl.c
@@ -385,22 +385,42 @@ static void bmw_LoopWalker_begin(BMWalker *walker, void *data)
BMwLoopWalker *lwalk = NULL, owalk;
BMEdge *e = data;
BMVert *v;
- /* int found = 1, val; */ /* UNUSED */
+ int vert_edge_count[2] = {BM_vert_edge_count_nonwire(e->v1),
+ BM_vert_edge_count_nonwire(e->v2)};
v = e->v1;
- /* val = BM_vert_edge_count(v); */ /* UNUSED */
-
lwalk = BMW_state_add(walker);
BLI_ghash_insert(walker->visithash, e, NULL);
lwalk->cur = lwalk->start = e;
lwalk->lastv = lwalk->startv = v;
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);
+ lwalk->is_single = (vert_edge_count[0] == 2 && vert_edge_count[1] == 2);
- /* rewin */
+ /* could also check that vertex*/
+ if ((lwalk->is_boundry == FALSE) &&
+ (vert_edge_count[0] == 3 || vert_edge_count[1] == 3))
+ {
+ BMIter iter;
+ BMFace *f_iter;
+ BMFace *f_best = NULL;
+
+ BM_ITER(f_iter, &iter, walker->bm, BM_FACES_OF_EDGE, e) {
+ if (f_best == NULL || f_best->len < f_iter->len) {
+ f_best = f_iter;
+ }
+ }
+
+ /* only use hub selection for 5+ sides else this could
+ * conflict with normal edge loop selection. */
+ lwalk->f_hub = f_best->len > 4 ? f_best : NULL;
+ }
+ else {
+ lwalk->f_hub = NULL;
+ }
+
+ /* rewind */
while (BMW_current_state(walker)) {
owalk = *((BMwLoopWalker *)BMW_current_state(walker));
BMW_walk(walker);
@@ -436,27 +456,29 @@ static void *bmw_LoopWalker_step(BMWalker *walker)
l = e->l;
- if (!l) { /* WIRE EDGE */
- BMIter eiter;
+ if (owalk.f_hub) { /* NGON EDGE */
+ 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(nexte, &eiter, walker->bm, BM_EDGES_OF_VERT, v) {
- if ((nexte->l == NULL) && !BLI_ghash_haskey(walker->visithash, nexte)) {
- lwalk = BMW_state_add(walker);
- lwalk->cur = nexte;
- lwalk->lastv = v;
- lwalk->is_boundry = owalk.is_boundry;
- lwalk->is_single = owalk.is_single;
+ vert_edge_tot = BM_vert_edge_count_nonwire(v);
- BLI_ghash_insert(walker->visithash, nexte, NULL);
- }
- }
+ if (vert_edge_tot == 3) {
+ l = BM_face_other_vert_loop(owalk.f_hub, lwalk->lastv, v);
+ nexte = BM_edge_exists(v, l->v);
+
+ lwalk = BMW_state_add(walker);
+ lwalk->cur = nexte;
+ lwalk->lastv = v;
+
+ lwalk->is_boundry = owalk.is_boundry;
+ lwalk->is_single = owalk.is_single;
+ lwalk->f_hub = owalk.f_hub;
+
+ BLI_ghash_insert(walker->visithash, nexte, NULL);
}
}
- else { /* FACE EDGE */
+ else if (l) { /* NORMAL EDGE WITH FACES */
int vert_edge_tot;
int stopi;
@@ -510,13 +532,38 @@ static void *bmw_LoopWalker_step(BMWalker *walker)
lwalk = BMW_state_add(walker);
lwalk->cur = l->e;
lwalk->lastv = v;
+
lwalk->is_boundry = owalk.is_boundry;
lwalk->is_single = owalk.is_single;
+ lwalk->f_hub = owalk.f_hub;
+
BLI_ghash_insert(walker->visithash, l->e, NULL);
}
}
}
}
+ else { /* WIRE EDGE */
+ BMIter eiter;
+
+ /* match trunk: mark all connected wire edges */
+ for (i = 0; i < 2; i++) {
+ v = i ? e->v2 : e->v1;
+
+ BM_ITER(nexte, &eiter, walker->bm, BM_EDGES_OF_VERT, v) {
+ if ((nexte->l == NULL) && !BLI_ghash_haskey(walker->visithash, nexte)) {
+ lwalk = BMW_state_add(walker);
+ lwalk->cur = nexte;
+ lwalk->lastv = v;
+
+ lwalk->is_boundry = owalk.is_boundry;
+ lwalk->is_single = owalk.is_single;
+ lwalk->f_hub = owalk.f_hub;
+
+ BLI_ghash_insert(walker->visithash, nexte, NULL);
+ }
+ }
+ }
+ }
return owalk.cur;
}
diff --git a/source/blender/bmesh/intern/bmesh_walkers_private.h b/source/blender/bmesh/intern/bmesh_walkers_private.h
index d8eccda2063..b6c7a974fce 100644
--- a/source/blender/bmesh/intern/bmesh_walkers_private.h
+++ b/source/blender/bmesh/intern/bmesh_walkers_private.h
@@ -61,6 +61,7 @@ typedef struct BMwLoopWalker {
BMwGenericWalker header;
BMEdge *cur, *start;
BMVert *lastv, *startv;
+ BMFace *f_hub;
short is_boundry; /* boundry looping changes behavior */
short is_single; /* single means the edge verts are only connected to 1 face */
} BMwLoopWalker;