diff options
author | Campbell Barton <ideasman42@gmail.com> | 2015-11-19 07:28:18 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2015-11-19 14:52:17 +0300 |
commit | 93fb07fbd55afcaac15e96b93892e65341bb92c4 (patch) | |
tree | de7928f6805dc3d116aeea5c3a2e7e78e14748bb /source | |
parent | ae8e4d37180b0fd24a6565551a8d63101555cad9 (diff) |
BMesh: bmesh_jekv check for degenerate faces
Move check for degenerate faces from BM_vert_collapse_faces into bmesh_jekv.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/bmesh/intern/bmesh_core.c | 48 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_core.h | 3 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_mods.c | 26 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_offset_edgeloops.c | 2 |
4 files changed, 30 insertions, 49 deletions
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index 5f184bb447d..618407ba5b6 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -1708,14 +1708,15 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e) */ BMEdge *bmesh_jekv( BMesh *bm, BMEdge *e_kill, BMVert *v_kill, - const bool do_del, const bool check_edge_double) + const bool do_del, const bool check_edge_double, + const bool kill_degenerate_faces) { BMEdge *e_old; BMVert *v_old, *tv; BMLoop *l_kill; - int radlen = 0, i; bool halt = false; #ifndef NDEBUG + int radlen, i; bool edok; #endif @@ -1757,11 +1758,17 @@ BMEdge *bmesh_jekv( /* remove e_kill from tv's disk cycle */ bmesh_disk_edge_remove(e_kill, tv); +#ifndef NDEBUG /* deal with radial cycle of e_kill */ radlen = bmesh_radial_length(e_kill->l); +#endif if (e_kill->l) { - /* first step, fix the neighboring loops of all loops in e_kill's radial cycle */ - for (i = 0, l_kill = e_kill->l; i < radlen; i++, l_kill = l_kill->radial_next) { + BLI_SMALLSTACK_DECLARE(faces_degenerate, BMFace *); + BMLoop *l_kill_next; + + /* fix the neighboring loops of all loops in e_kill's radial cycle */ + l_kill = e_kill->l; + do { /* relink loops and fix vertex pointer */ if (l_kill->next->v == v_kill) { l_kill->next->v = tv; @@ -1772,34 +1779,31 @@ BMEdge *bmesh_jekv( if (BM_FACE_FIRST_LOOP(l_kill->f) == l_kill) { BM_FACE_FIRST_LOOP(l_kill->f) = l_kill->next; } - l_kill->next = NULL; - l_kill->prev = NULL; /* fix len attribute of face */ l_kill->f->len--; - } - /* second step, remove all the hanging loops attached to e_kill */ - radlen = bmesh_radial_length(e_kill->l); - - if (LIKELY(radlen)) { - BMLoop **loops = BLI_array_alloca(loops, radlen); + if (kill_degenerate_faces) { + if (l_kill->f->len < 3) { + BLI_SMALLSTACK_PUSH(faces_degenerate, l_kill->f); + } + } + l_kill_next = l_kill->radial_next; - l_kill = e_kill->l; + bm_kill_only_loop(bm, l_kill); - /* this should be wrapped into a bme_free_radial function to be used by bmesh_KF as well... */ - for (i = 0; i < radlen; i++) { - loops[i] = l_kill; - l_kill = l_kill->radial_next; - } - for (i = 0; i < radlen; i++) { - bm_kill_only_loop(bm, loops[i]); - } - } + } while ((l_kill = l_kill_next) != e_kill->l); + /* `e_kill->l` is invalid but the edge is freed next. */ #ifndef NDEBUG /* Validate radial cycle of e_old */ edok = bmesh_radial_validate(radlen, e_old->l); BMESH_ASSERT(edok != false); #endif + if (kill_degenerate_faces) { + BMFace *f_kill; + while ((f_kill = BLI_SMALLSTACK_POP(faces_degenerate))) { + BM_face_kill(bm, f_kill); + } + } } /* deallocate edge */ bm_kill_only_edge(bm, e_kill); diff --git a/source/blender/bmesh/intern/bmesh_core.h b/source/blender/bmesh/intern/bmesh_core.h index 2b100eb7b8d..d6d5a4d7296 100644 --- a/source/blender/bmesh/intern/bmesh_core.h +++ b/source/blender/bmesh/intern/bmesh_core.h @@ -98,7 +98,8 @@ BMFace *bmesh_sfme( BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e); BMEdge *bmesh_jekv( BMesh *bm, BMEdge *e_kill, BMVert *v_kill, - const bool do_del, const bool check_edge_splice); + const bool do_del, const bool check_edge_splice, + const bool kill_degenerate_faces); BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e); BMVert *bmesh_urmv(BMesh *bm, BMFace *f_sep, BMVert *v_sep); BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *l_sep); diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c index 1b693f8e97d..66be8e0e757 100644 --- a/source/blender/bmesh/intern/bmesh_mods.c +++ b/source/blender/bmesh/intern/bmesh_mods.c @@ -1066,32 +1066,8 @@ BMEdge *BM_vert_collapse_faces( /* single face or no faces */ /* same as BM_vert_collapse_edge() however we already * have vars to perform this operation so don't call. */ - e_new = bmesh_jekv(bm, e_kill, v_kill, do_del, true); + e_new = bmesh_jekv(bm, e_kill, v_kill, do_del, true, kill_degenerate_faces); /* e_new = BM_edge_exists(tv, tv2); */ /* same as return above */ - - if (e_new && kill_degenerate_faces) { - BMFace **bad_faces = NULL; - BLI_array_staticdeclare(bad_faces, BM_DEFAULT_ITER_STACK_SIZE); - - BMIter fiter; - BMFace *f; - BMVert *verts[2] = {e_new->v1, e_new->v2}; - int i; - - for (i = 0; i < 2; i++) { - /* cant kill data we loop on, build a list and remove those */ - BLI_array_empty(bad_faces); - BM_ITER_ELEM (f, &fiter, verts[i], BM_FACES_OF_VERT) { - if (UNLIKELY(f->len < 3)) { - BLI_array_append(bad_faces, f); - } - } - while ((f = BLI_array_pop(bad_faces))) { - BM_face_kill(bm, f); - } - } - BLI_array_free(bad_faces); - } } return e_new; diff --git a/source/blender/bmesh/operators/bmo_offset_edgeloops.c b/source/blender/bmesh/operators/bmo_offset_edgeloops.c index a2f3f0bb519..8f4bc5ef3ad 100644 --- a/source/blender/bmesh/operators/bmo_offset_edgeloops.c +++ b/source/blender/bmesh/operators/bmo_offset_edgeloops.c @@ -278,7 +278,7 @@ void bmo_offset_edgeloops_exec(BMesh *bm, BMOperator *op) } while ((v = STACK_POP(varr))) { - bmesh_jekv(bm, v->e, v, true, false); + bmesh_jekv(bm, v->e, v, true, false, false); } } } |