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:
-rw-r--r--source/blender/bmesh/intern/bmesh_core.c48
-rw-r--r--source/blender/bmesh/intern/bmesh_core.h3
-rw-r--r--source/blender/bmesh/intern/bmesh_mods.c26
-rw-r--r--source/blender/bmesh/operators/bmo_offset_edgeloops.c2
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);
}
}
}