From 1635d8e873eff8d49e7871047ca8b5c026cdf214 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 4 Apr 2012 14:48:10 +0000 Subject: add option not to delete edges/verts when joining faces, needed so we can loop over edges and join them without having to check if they have been removed. --- source/blender/bmesh/intern/bmesh_core.c | 28 ++++++++++++++-------- source/blender/bmesh/intern/bmesh_core.h | 2 +- source/blender/bmesh/intern/bmesh_mods.c | 14 +++++------ source/blender/bmesh/intern/bmesh_mods.h | 2 +- source/blender/bmesh/operators/bmo_dissolve.c | 14 +++++++---- .../blender/bmesh/operators/bmo_join_triangles.c | 4 ++-- source/blender/bmesh/tools/BME_bevel.c | 2 +- source/blender/python/bmesh/bmesh_py_utils.c | 18 ++++++++++---- 8 files changed, 53 insertions(+), 31 deletions(-) (limited to 'source/blender') diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index d9973550440..47e09d44de9 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -866,7 +866,7 @@ static int disk_is_flagged(BMVert *v, int flag) * \note this is a generic, flexible join faces function, * almost everything uses this, including #BM_faces_join_pair */ -BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface) +BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const short do_del) { BMFace *f, *newf; #ifdef USE_BMESH_HOLES @@ -924,18 +924,24 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface) /* don't remove an edge it makes up the side of another face * else this will remove the face as well - campbell */ if (BM_edge_face_count(l_iter->e) <= 2) { - BLI_array_append(deledges, l_iter->e); + if (do_del) { + BLI_array_append(deledges, l_iter->e); + } BM_ELEM_API_FLAG_ENABLE(l_iter->e, _FLAG_JF); } } else { if (d1 && !BM_ELEM_API_FLAG_TEST(l_iter->e->v1, _FLAG_JF)) { - BLI_array_append(delverts, l_iter->e->v1); + if (do_del) { + BLI_array_append(delverts, l_iter->e->v1); + } BM_ELEM_API_FLAG_ENABLE(l_iter->e->v1, _FLAG_JF); } if (d2 && !BM_ELEM_API_FLAG_TEST(l_iter->e->v2, _FLAG_JF)) { - BLI_array_append(delverts, l_iter->e->v2); + if (do_del) { + BLI_array_append(delverts, l_iter->e->v2); + } BM_ELEM_API_FLAG_ENABLE(l_iter->e->v2, _FLAG_JF); } } @@ -1019,13 +1025,15 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface) } while ((l_iter = l_iter->next) != l_first); } - /* delete old geometr */ - for (i = 0; i < BLI_array_count(deledges); i++) { - BM_edge_kill(bm, deledges[i]); - } + /* delete old geometry */ + if (do_del) { + for (i = 0; i < BLI_array_count(deledges); i++) { + BM_edge_kill(bm, deledges[i]); + } - for (i = 0; i < BLI_array_count(delverts); i++) { - BM_vert_kill(bm, delverts[i]); + for (i = 0; i < BLI_array_count(delverts); i++) { + BM_vert_kill(bm, delverts[i]); + } } BLI_array_free(edges); diff --git a/source/blender/bmesh/intern/bmesh_core.h b/source/blender/bmesh/intern/bmesh_core.h index 34947923572..491287993df 100644 --- a/source/blender/bmesh/intern/bmesh_core.h +++ b/source/blender/bmesh/intern/bmesh_core.h @@ -48,7 +48,7 @@ int bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_ int bmesh_loop_reverse(BMesh *bm, BMFace *f); -BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface); +BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const short do_del); int BM_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len, BMEdge **e_in, int e_in_len); diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c index da936079dc8..1deeb9fc310 100644 --- a/source/blender/bmesh/intern/bmesh_mods.c +++ b/source/blender/bmesh/intern/bmesh_mods.c @@ -153,7 +153,7 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v) f = e->l->f; f2 = e->l->radial_next->f; - if (f != f2 && !BM_faces_join_pair(bm, f, f2, e)) { + if (f != f2 && !BM_faces_join_pair(bm, f, f2, e, TRUE)) { return FALSE; } @@ -170,7 +170,7 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v) f = NULL; len = bmesh_radial_length(e->l); if (len == 2 && (e != baseedge) && (e != keepedge)) { - f = BM_faces_join_pair(bm, e->l->f, e->l->radial_next->f, e); + f = BM_faces_join_pair(bm, e->l->f, e->l->radial_next->f, e, TRUE); /* return if couldn't join faces in manifold * conditions */ //!disabled for testing why bad things happen @@ -200,7 +200,7 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v) if (f != f2) { /* join two remaining face */ - if (!BM_faces_join_pair(bm, f, f2, e)) { + if (!BM_faces_join_pair(bm, f, f2, e, TRUE)) { return FALSE; } } @@ -224,7 +224,7 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v) * * \return pointer to the combined face */ -BMFace *BM_faces_join_pair(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e) +BMFace *BM_faces_join_pair(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e, const short do_del) { BMLoop *l1, *l2; BMEdge *jed = NULL; @@ -260,7 +260,7 @@ BMFace *BM_faces_join_pair(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e) bmesh_loop_reverse(bm, f2); } - f1 = BM_faces_join(bm, faces, 2); + f1 = BM_faces_join(bm, faces, 2, do_del); return f1; } @@ -526,7 +526,7 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac, } if (BLI_array_count(faces) >= 2) { - BMFace *f2 = BM_faces_join(bm, faces, BLI_array_count(faces)); + BMFace *f2 = BM_faces_join(bm, faces, BLI_array_count(faces), TRUE); if (f2) { BMLoop *nl = NULL; if (BM_face_split(bm, f2, tv, tv2, &nl, NULL, FALSE)) { @@ -1057,7 +1057,7 @@ BMEdge *BM_edge_rotate(BMesh *bm, BMEdge *e, const short ccw, const short check_ f_hflag_prev_2 = l2->f->head.hflag; /* don't delete the edge, manually remove the egde after so we can copy its attributes */ - f = BM_faces_join_pair(bm, l1->f, l2->f, NULL); + f = BM_faces_join_pair(bm, l1->f, l2->f, NULL, TRUE); if (f == NULL) { return NULL; diff --git a/source/blender/bmesh/intern/bmesh_mods.h b/source/blender/bmesh/intern/bmesh_mods.h index f87cdcc02e2..ba601eb64dc 100644 --- a/source/blender/bmesh/intern/bmesh_mods.h +++ b/source/blender/bmesh/intern/bmesh_mods.h @@ -33,7 +33,7 @@ int BM_vert_dissolve(BMesh *bm, BMVert *v); int BM_disk_dissolve(BMesh *bm, BMVert *v); -BMFace *BM_faces_join_pair(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e); +BMFace *BM_faces_join_pair(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e, const short do_del); BMEdge *BM_verts_connect(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **r_f); diff --git a/source/blender/bmesh/operators/bmo_dissolve.c b/source/blender/bmesh/operators/bmo_dissolve.c index 40650f45fed..167556a158c 100644 --- a/source/blender/bmesh/operators/bmo_dissolve.c +++ b/source/blender/bmesh/operators/bmo_dissolve.c @@ -147,7 +147,7 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op) while (faces[tot]) tot++; - f = BM_faces_join(bm, faces, tot); + f = BM_faces_join(bm, faces, tot, TRUE); if (!f) { BMO_error_raise(bm, op, BMERR_DISSOLVEFACES_FAILED, "Could not create merged face"); @@ -210,7 +210,9 @@ void bmo_dissolve_edgeloop_exec(BMesh *bm, BMOperator *op) BMO_elem_flag_enable(bm, e->v1, VERT_MARK); BMO_elem_flag_enable(bm, e->v2, VERT_MARK); - BM_faces_join_pair(bm, fa, fb, e); + /* BMESH_TODO - check on delaying edge removal since we may end up removing more then + * one edge, and later referene a removed edge */ + BM_faces_join_pair(bm, fa, fb, e, TRUE); } } @@ -263,7 +265,10 @@ void bmo_dissolve_edges_exec(BMesh *bm, BMOperator *op) if (BM_edge_face_pair(e, &fa, &fb)) { /* join faces */ - BM_faces_join_pair(bm, fa, fb, e); + + /* BMESH_TODO - check on delaying edge removal since we may end up removing more then + * one edge, and later referene a removed edge */ + BM_faces_join_pair(bm, fa, fb, e, TRUE); } } @@ -519,7 +524,8 @@ void bmo_dissolve_limit_exec(BMesh *bm, BMOperator *op) if (BM_edge_face_angle(e) < angle_limit) { BMFace *nf = BM_faces_join_pair(bm, e->l->f, e->l->radial_next->f, - e); /* join faces */ + e, + TRUE); /* join faces */ /* there may be some errors, we don't mind, just move on */ if (nf == NULL) { diff --git a/source/blender/bmesh/operators/bmo_join_triangles.c b/source/blender/bmesh/operators/bmo_join_triangles.c index dda3e144220..e7de0044ab4 100644 --- a/source/blender/bmesh/operators/bmo_join_triangles.c +++ b/source/blender/bmesh/operators/bmo_join_triangles.c @@ -333,7 +333,7 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op) BM_edge_face_pair(e, &f1, &f2); /* checked above */ - BM_faces_join_pair(bm, f1, f2, e); + BM_faces_join_pair(bm, f1, f2, e, TRUE); } BM_ITER(e, &iter, bm, BM_EDGES_OF_MESH, NULL) { @@ -365,7 +365,7 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op) continue; } - BM_faces_join_pair(bm, f1, f2, e); + BM_faces_join_pair(bm, f1, f2, e, TRUE); } } diff --git a/source/blender/bmesh/tools/BME_bevel.c b/source/blender/bmesh/tools/BME_bevel.c index 9160848aa60..63976f25eff 100644 --- a/source/blender/bmesh/tools/BME_bevel.c +++ b/source/blender/bmesh/tools/BME_bevel.c @@ -988,7 +988,7 @@ static BMesh *BME_bevel_mesh(BMesh *bm, float value, int UNUSED(res), int option /* get rid of beveled edge */ BM_ITER(e, &iter, bm, BM_EDGES_OF_MESH, NULL) { if (BMO_elem_flag_test(bm, e, BME_BEVEL_BEVEL) && BMO_elem_flag_test(bm, e, BME_BEVEL_ORIG)) { - BM_faces_join_pair(bm, e->l->f, e->l->radial_next->f, e); + BM_faces_join_pair(bm, e->l->f, e->l->radial_next->f, e, TRUE); } } diff --git a/source/blender/python/bmesh/bmesh_py_utils.c b/source/blender/python/bmesh/bmesh_py_utils.c index bbec871a44b..fcc4ebc67e1 100644 --- a/source/blender/python/bmesh/bmesh_py_utils.c +++ b/source/blender/python/bmesh/bmesh_py_utils.c @@ -443,23 +443,31 @@ static PyObject *bpy_bm_utils_face_split(PyObject *UNUSED(self), PyObject *args) PyDoc_STRVAR(bpy_bm_utils_face_join_doc, -".. method:: face_join(faces)\n" +".. method:: face_join(faces, remove=True)\n" "\n" " Joins a sequence of faces.\n" "\n" " :arg faces: Sequence of faces.\n" " :type faces: :class:`bmesh.types.BMFace`\n" +" :arg remove: Remove the edges and vertices between the faces.\n" +" :type remove: boolean\n" " :return: The newly created face or None on failure.\n" " :rtype: :class:`bmesh.types.BMFace`\n" ); -static PyObject *bpy_bm_utils_face_join(PyObject *UNUSED(self), PyObject *value) +static PyObject *bpy_bm_utils_face_join(PyObject *UNUSED(self), PyObject *args) { BMesh *bm = NULL; + PyObject *py_face_array; BMFace **face_array; Py_ssize_t face_seq_len = 0; BMFace *f_new; + int do_remove = TRUE; - face_array = BPy_BMElem_PySeq_As_Array(&bm, value, 2, PY_SSIZE_T_MAX, + if (!PyArg_ParseTuple(args, "O|i:face_join", &py_face_array, &do_remove)) { + return NULL; + } + + face_array = BPy_BMElem_PySeq_As_Array(&bm, py_face_array, 2, PY_SSIZE_T_MAX, &face_seq_len, BM_FACE, TRUE, TRUE, "face_join(...)"); @@ -469,7 +477,7 @@ static PyObject *bpy_bm_utils_face_join(PyObject *UNUSED(self), PyObject *value) /* Go ahead and join the face! * --------------------------- */ - f_new = BM_faces_join(bm, face_array, (int)face_seq_len); + f_new = BM_faces_join(bm, face_array, (int)face_seq_len, do_remove); PyMem_FREE(face_array); @@ -615,7 +623,7 @@ static struct PyMethodDef BPy_BM_utils_methods[] = { {"edge_split", (PyCFunction)bpy_bm_utils_edge_split, METH_VARARGS, bpy_bm_utils_edge_split_doc}, {"edge_rotate", (PyCFunction)bpy_bm_utils_edge_rotate, METH_VARARGS, bpy_bm_utils_edge_rotate_doc}, {"face_split", (PyCFunction)bpy_bm_utils_face_split, METH_VARARGS, bpy_bm_utils_face_split_doc}, - {"face_join", (PyCFunction)bpy_bm_utils_face_join, METH_O, bpy_bm_utils_face_join_doc}, + {"face_join", (PyCFunction)bpy_bm_utils_face_join, METH_VARARGS, bpy_bm_utils_face_join_doc}, {"face_vert_separate", (PyCFunction)bpy_bm_utils_face_vert_separate, METH_VARARGS, bpy_bm_utils_face_vert_separate_doc}, {"face_flip", (PyCFunction)bpy_bm_utils_face_flip, METH_O, bpy_bm_utils_face_flip_doc}, {"loop_separate", (PyCFunction)bpy_bm_utils_loop_separate, METH_O, bpy_bm_utils_loop_separate_doc}, -- cgit v1.2.3