diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h index 86c0d4b534f..ace5c79a928 100644 --- a/source/blender/bmesh/bmesh.h +++ b/source/blender/bmesh/bmesh.h @@ -219,8 +219,10 @@ BMFace *BM_face_split(BMesh *bm, BMFace *f, struct BMLoop **nl, BMEdge *example); /* these 2 functions are very similar */ -BMEdge* BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac, const int join_faces); -BMEdge* BM_vert_collapse_edge(BMesh *bm, BMEdge *ke, BMVert *kv); +BMEdge* BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac, + const short join_faces, const short kill_degenerate_faces); +BMEdge* BM_vert_collapse_edge(BMesh *bm, BMEdge *ke, BMVert *kv, + const short kill_degenerate_faces); /* splits an edge. ne is set to the new edge created. */ diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h index 77fcfe6a820..5a0158a7b9a 100644 --- a/source/blender/bmesh/bmesh_class.h +++ b/source/blender/bmesh/bmesh_class.h @@ -51,7 +51,7 @@ struct Object; typedef struct BMHeader { void *data; /* customdata layers */ int index; /* notes: - * - Use BM_elem_index_get/SetIndex macros for index + * - Use BM_elem_index_get/set macros for index * - Unitialized to -1 so we can easily tell its not set. * - Used for edge/vert/face, check BMesh.elem_index_dirty for valid index values, * this is abused by various tools which set it dirty. diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c index e512126ce80..d32f516f26e 100644 --- a/source/blender/bmesh/intern/bmesh_mods.c +++ b/source/blender/bmesh/intern/bmesh_mods.c @@ -72,7 +72,7 @@ int BM_vert_dissolve(BMesh *bm, BMVert *v) } else if (!v->e->l) { if (len == 2) { - return (BM_vert_collapse_edge(bm, v->e, v) != NULL); + return (BM_vert_collapse_edge(bm, v->e, v, TRUE) != NULL); } else { /* used to kill the vertex here, but it may be connected to faces. @@ -86,7 +86,7 @@ int BM_vert_dissolve(BMesh *bm, BMVert *v) } else if (len == 2 && BM_vert_face_count(v) == 1) { /* boundry vertex on a face */ - return (BM_vert_collapse_edge(bm, v->e, v) != NULL); + return (BM_vert_collapse_edge(bm, v->e, v, TRUE) != NULL); } else { return BM_disk_dissolve(bm, v); @@ -134,7 +134,7 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v) } else if (keepedge == NULL && len == 2) { /* collapse the verte */ - e = BM_vert_collapse_faces(bm, v->e, v, 1.0, TRUE); + e = BM_vert_collapse_faces(bm, v->e, v, 1.0, TRUE, TRUE); if (!e) { return FALSE; @@ -179,7 +179,7 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v) } /* collapse the verte */ - e = BM_vert_collapse_faces(bm, baseedge, v, 1.0, TRUE); + e = BM_vert_collapse_faces(bm, baseedge, v, 1.0, TRUE, TRUE); if (!e) { return FALSE; @@ -410,7 +410,8 @@ BMFace *BM_face_split(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **nl, * @returns The New Edge */ -BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac, const int join_faces) +BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac, + const short join_faces, const short kill_degenerate_faces) { BMEdge *ne = NULL; BMVert *tv = bmesh_edge_getothervert(ke, kv); @@ -471,15 +472,28 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac, con } BLI_array_free(faces); - - return ne; } + else { + /* single face or no faces */ + /* same as BM_vert_collapse_edge() however we already + * have vars to perform this operation so dont call. */ + ne = bmesh_jekv(bm, ke, kv, TRUE); + /* ne = BM_edge_exists(tv, tv2); */ /* same as return above */ - /* single face or no faces */ - /* same as BM_vert_collapse_edge() however we already - * have vars to perform this operation so dont call. */ - ne = bmesh_jekv(bm, ke, kv, TRUE); - /* ne = BM_edge_exists(tv, tv2); */ /* same as return above */ + if (kill_degenerate_faces) { + BMIter fiter; + BMFace *f; + BMVert *verts[2] = {ne->v1, ne->v2}; + int i; + for (i = 0; i < 2; i++) { + BM_ITER(f, &fiter, bm, BM_FACES_OF_VERT, verts[i]) { + if (f->len < 3) { + BM_face_kill(bm, f); + } + } + } + } + } return ne; } @@ -494,7 +508,8 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac, con * The New Edge */ -BMEdge *BM_vert_collapse_edge(BMesh *bm, BMEdge *ke, BMVert *kv) +BMEdge *BM_vert_collapse_edge(BMesh *bm, BMEdge *ke, BMVert *kv, + const short kill_degenerate_faces) { /* nice example implementation but we want loops to have their customdata * accounted for */ @@ -523,7 +538,7 @@ BMEdge *BM_vert_collapse_edge(BMesh *bm, BMEdge *ke, BMVert *kv) #else /* with these args faces are never joined, same as above * but account for loop customdata */ - return BM_vert_collapse_faces(bm, ke, kv, 1.0f, FALSE); + return BM_vert_collapse_faces(bm, ke, kv, 1.0f, FALSE, kill_degenerate_faces); #endif } diff --git a/source/blender/bmesh/operators/bmo_dissolve.c b/source/blender/bmesh/operators/bmo_dissolve.c index 62c98dc2871..8b04f2deb65 100644 --- a/source/blender/bmesh/operators/bmo_dissolve.c +++ b/source/blender/bmesh/operators/bmo_dissolve.c @@ -165,7 +165,7 @@ void dissolvefaces_exec(BMesh *bm, BMOperator *op) BM_ITER(v, &viter, bm, BM_VERTS_OF_MESH, NULL) { if (BMO_elem_flag_test(bm, v, VERT_MARK)) { if (BM_vert_edge_count(v) == 2) { - BM_vert_collapse_edge(bm, v->e, v); + BM_vert_collapse_edge(bm, v->e, v, TRUE); } } } @@ -216,7 +216,7 @@ void dissolve_edgeloop_exec(BMesh *bm, BMOperator *op) /* clean up extreneous 2-valence vertice */ for (i = 0; i < BLI_array_count(verts); i++) { if (verts[i]->e) { - BM_vert_collapse_edge(bm, verts[i]->e, verts[i]); + BM_vert_collapse_edge(bm, verts[i]->e, verts[i], TRUE); } } @@ -265,7 +265,7 @@ void dissolveedges_exec(BMesh *bm, BMOperator *op) BM_ITER(v, &viter, bm, BM_VERTS_OF_MESH, NULL) { if (BMO_elem_flag_test(bm, v, VERT_MARK)) { if (BM_vert_edge_count(v) == 2) { - BM_vert_collapse_edge(bm, v->e, v); + BM_vert_collapse_edge(bm, v->e, v, TRUE); } } } @@ -334,7 +334,14 @@ void dissolveverts_exec(BMesh *bm, BMOperator *op) if (BM_vert_edge_count(v) == 2) { /* collapse the ver */ - BM_vert_collapse_faces(bm, v->e, v, 1.0f, FALSE); + /* previously the faces were joined, but collapsing between 2 edges + * gives some advantage/difference in using vertex-dissolve over edge-dissolve */ +#if 0 + BM_vert_collapse_faces(bm, v->e, v, 1.0f, TRUE, TRUE); +#else + BM_vert_collapse_edge(bm, v->e, v, TRUE); +#endif + continue; } @@ -540,7 +547,7 @@ void dissolvelimit_exec(BMesh *bm, BMOperator *op) BMVert *v = (BMVert *)weight_elems[i].ele; /* check twice because cumulative effect could disolve over angle limit */ if (BM_vert_edge_angle(bm, v) < angle_limit) { - BM_vert_collapse_edge(bm, v->e, v); /* join edges */ + BM_vert_collapse_edge(bm, v->e, v, TRUE); /* join edges */ } } } diff --git a/source/blender/bmesh/tools/BME_bevel.c b/source/blender/bmesh/tools/BME_bevel.c index 903500b2b06..385c5662716 100644 --- a/source/blender/bmesh/tools/BME_bevel.c +++ b/source/blender/bmesh/tools/BME_bevel.c @@ -530,14 +530,14 @@ static BMLoop *BME_bevel_edge(BMesh *bm, BMLoop *l, float value, int UNUSED(opti ke = kl->e; /* BMESH-TODO: jfke doesn't handle customdata */ jf = bmesh_jfke(bm, kl->prev->radial_next->f, kl->f, kl->prev->e); - BM_vert_collapse_edge(bm, ke, kv); + BM_vert_collapse_edge(bm, ke, kv, FALSE); } else { BM_face_split(bm, kl->f, kl->next->next->v, kl->v, &nl, kl->next->e); ke = kl->e; /* BMESH-TODO: jfke doesn't handle customdata */ jf = bmesh_jfke(bm, kl->next->radial_next->f, kl->f, kl->next->e); - BM_vert_collapse_edge(bm, ke, kv); + BM_vert_collapse_edge(bm, ke, kv, FALSE); } /* find saved loop pointer */ l = se->l; @@ -576,14 +576,14 @@ static BMLoop *BME_bevel_edge(BMesh *bm, BMLoop *l, float value, int UNUSED(opti ke = kl->e; /* BMESH-TODO: jfke doesn't handle customdata */ jf = bmesh_jfke(bm, kl->prev->radial_next->f, kl->f, kl->prev->e); - BM_vert_collapse_edge(bm, ke, kv); + BM_vert_collapse_edge(bm, ke, kv, FALSE); } else { BM_face_split(bm, kl->f, kl->next->next->v, kl->v, &nl, kl->next->e); ke = kl->e; /* BMESH-TODO: jfke doesn't handle customdata */ jf = bmesh_jfke(bm, kl->next->radial_next->f, kl->f, kl->next->e); - BM_vert_collapse_edge(bm, ke, kv); + BM_vert_collapse_edge(bm, ke, kv, FALSE); } /* find saved loop pointer */ l = se->l; diff --git a/source/blender/python/bmesh/bmesh_py_utils.c b/source/blender/python/bmesh/bmesh_py_utils.c index 19832b67962..a8d90522c15 100644 --- a/source/blender/python/bmesh/bmesh_py_utils.c +++ b/source/blender/python/bmesh/bmesh_py_utils.c @@ -88,7 +88,7 @@ static PyObject *bpy_bm_utils_vert_collapse_edge(PyObject *UNUSED(self), PyObjec bm = py_edge->bm; - e_new = BM_vert_collapse_edge(bm, py_edge->e, py_vert->v); + e_new = BM_vert_collapse_edge(bm, py_edge->e, py_vert->v, TRUE); if (e_new) { return BPy_BMEdge_CreatePyObject(bm, e_new); @@ -154,7 +154,7 @@ static PyObject *bpy_bm_utils_vert_collapse_faces(PyObject *UNUSED(self), PyObje bm = py_edge->bm; - e_new = BM_vert_collapse_faces(bm, py_edge->e, py_vert->v, CLAMPIS(fac, 0.0f, 1.0f), do_join_faces); + e_new = BM_vert_collapse_faces(bm, py_edge->e, py_vert->v, CLAMPIS(fac, 0.0f, 1.0f), do_join_faces, TRUE); if (e_new) { return BPy_BMEdge_CreatePyObject(bm, e_new);