forked from bartvdbraak/blender
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.
This commit is contained in:
parent
c93c8bda3d
commit
1635d8e873
@ -866,7 +866,7 @@ static int disk_is_flagged(BMVert *v, int flag)
|
|||||||
* \note this is a generic, flexible join faces function,
|
* \note this is a generic, flexible join faces function,
|
||||||
* almost everything uses this, including #BM_faces_join_pair
|
* 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;
|
BMFace *f, *newf;
|
||||||
#ifdef USE_BMESH_HOLES
|
#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
|
/* don't remove an edge it makes up the side of another face
|
||||||
* else this will remove the face as well - campbell */
|
* else this will remove the face as well - campbell */
|
||||||
if (BM_edge_face_count(l_iter->e) <= 2) {
|
if (BM_edge_face_count(l_iter->e) <= 2) {
|
||||||
|
if (do_del) {
|
||||||
BLI_array_append(deledges, l_iter->e);
|
BLI_array_append(deledges, l_iter->e);
|
||||||
|
}
|
||||||
BM_ELEM_API_FLAG_ENABLE(l_iter->e, _FLAG_JF);
|
BM_ELEM_API_FLAG_ENABLE(l_iter->e, _FLAG_JF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (d1 && !BM_ELEM_API_FLAG_TEST(l_iter->e->v1, _FLAG_JF)) {
|
if (d1 && !BM_ELEM_API_FLAG_TEST(l_iter->e->v1, _FLAG_JF)) {
|
||||||
|
if (do_del) {
|
||||||
BLI_array_append(delverts, l_iter->e->v1);
|
BLI_array_append(delverts, l_iter->e->v1);
|
||||||
|
}
|
||||||
BM_ELEM_API_FLAG_ENABLE(l_iter->e->v1, _FLAG_JF);
|
BM_ELEM_API_FLAG_ENABLE(l_iter->e->v1, _FLAG_JF);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d2 && !BM_ELEM_API_FLAG_TEST(l_iter->e->v2, _FLAG_JF)) {
|
if (d2 && !BM_ELEM_API_FLAG_TEST(l_iter->e->v2, _FLAG_JF)) {
|
||||||
|
if (do_del) {
|
||||||
BLI_array_append(delverts, l_iter->e->v2);
|
BLI_array_append(delverts, l_iter->e->v2);
|
||||||
|
}
|
||||||
BM_ELEM_API_FLAG_ENABLE(l_iter->e->v2, _FLAG_JF);
|
BM_ELEM_API_FLAG_ENABLE(l_iter->e->v2, _FLAG_JF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1019,7 +1025,8 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface)
|
|||||||
} while ((l_iter = l_iter->next) != l_first);
|
} while ((l_iter = l_iter->next) != l_first);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* delete old geometr */
|
/* delete old geometry */
|
||||||
|
if (do_del) {
|
||||||
for (i = 0; i < BLI_array_count(deledges); i++) {
|
for (i = 0; i < BLI_array_count(deledges); i++) {
|
||||||
BM_edge_kill(bm, deledges[i]);
|
BM_edge_kill(bm, deledges[i]);
|
||||||
}
|
}
|
||||||
@ -1027,6 +1034,7 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface)
|
|||||||
for (i = 0; i < BLI_array_count(delverts); i++) {
|
for (i = 0; i < BLI_array_count(delverts); i++) {
|
||||||
BM_vert_kill(bm, delverts[i]);
|
BM_vert_kill(bm, delverts[i]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BLI_array_free(edges);
|
BLI_array_free(edges);
|
||||||
BLI_array_free(deledges);
|
BLI_array_free(deledges);
|
||||||
|
@ -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);
|
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,
|
int BM_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len,
|
||||||
BMEdge **e_in, int e_in_len);
|
BMEdge **e_in, int e_in_len);
|
||||||
|
|
||||||
|
@ -153,7 +153,7 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v)
|
|||||||
f = e->l->f;
|
f = e->l->f;
|
||||||
f2 = e->l->radial_next->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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,7 +170,7 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v)
|
|||||||
f = NULL;
|
f = NULL;
|
||||||
len = bmesh_radial_length(e->l);
|
len = bmesh_radial_length(e->l);
|
||||||
if (len == 2 && (e != baseedge) && (e != keepedge)) {
|
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
|
/* return if couldn't join faces in manifold
|
||||||
* conditions */
|
* conditions */
|
||||||
//!disabled for testing why bad things happen
|
//!disabled for testing why bad things happen
|
||||||
@ -200,7 +200,7 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v)
|
|||||||
|
|
||||||
if (f != f2) {
|
if (f != f2) {
|
||||||
/* join two remaining face */
|
/* 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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -224,7 +224,7 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v)
|
|||||||
*
|
*
|
||||||
* \return pointer to the combined face
|
* \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;
|
BMLoop *l1, *l2;
|
||||||
BMEdge *jed = NULL;
|
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);
|
bmesh_loop_reverse(bm, f2);
|
||||||
}
|
}
|
||||||
|
|
||||||
f1 = BM_faces_join(bm, faces, 2);
|
f1 = BM_faces_join(bm, faces, 2, do_del);
|
||||||
|
|
||||||
return f1;
|
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) {
|
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) {
|
if (f2) {
|
||||||
BMLoop *nl = NULL;
|
BMLoop *nl = NULL;
|
||||||
if (BM_face_split(bm, f2, tv, tv2, &nl, NULL, FALSE)) {
|
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;
|
f_hflag_prev_2 = l2->f->head.hflag;
|
||||||
|
|
||||||
/* don't delete the edge, manually remove the egde after so we can copy its attributes */
|
/* 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) {
|
if (f == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -33,7 +33,7 @@ int BM_vert_dissolve(BMesh *bm, BMVert *v);
|
|||||||
|
|
||||||
int BM_disk_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);
|
BMEdge *BM_verts_connect(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **r_f);
|
||||||
|
|
||||||
|
@ -147,7 +147,7 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op)
|
|||||||
while (faces[tot])
|
while (faces[tot])
|
||||||
tot++;
|
tot++;
|
||||||
|
|
||||||
f = BM_faces_join(bm, faces, tot);
|
f = BM_faces_join(bm, faces, tot, TRUE);
|
||||||
if (!f) {
|
if (!f) {
|
||||||
BMO_error_raise(bm, op, BMERR_DISSOLVEFACES_FAILED,
|
BMO_error_raise(bm, op, BMERR_DISSOLVEFACES_FAILED,
|
||||||
"Could not create merged face");
|
"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->v1, VERT_MARK);
|
||||||
BMO_elem_flag_enable(bm, e->v2, 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)) {
|
if (BM_edge_face_pair(e, &fa, &fb)) {
|
||||||
|
|
||||||
/* join faces */
|
/* 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) {
|
if (BM_edge_face_angle(e) < angle_limit) {
|
||||||
BMFace *nf = BM_faces_join_pair(bm, e->l->f,
|
BMFace *nf = BM_faces_join_pair(bm, e->l->f,
|
||||||
e->l->radial_next->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 */
|
/* there may be some errors, we don't mind, just move on */
|
||||||
if (nf == NULL) {
|
if (nf == NULL) {
|
||||||
|
@ -333,7 +333,7 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op)
|
|||||||
|
|
||||||
|
|
||||||
BM_edge_face_pair(e, &f1, &f2); /* checked above */
|
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) {
|
BM_ITER(e, &iter, bm, BM_EDGES_OF_MESH, NULL) {
|
||||||
@ -365,7 +365,7 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
BM_faces_join_pair(bm, f1, f2, e);
|
BM_faces_join_pair(bm, f1, f2, e, TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -988,7 +988,7 @@ static BMesh *BME_bevel_mesh(BMesh *bm, float value, int UNUSED(res), int option
|
|||||||
/* get rid of beveled edge */
|
/* get rid of beveled edge */
|
||||||
BM_ITER(e, &iter, bm, BM_EDGES_OF_MESH, NULL) {
|
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)) {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,23 +443,31 @@ static PyObject *bpy_bm_utils_face_split(PyObject *UNUSED(self), PyObject *args)
|
|||||||
|
|
||||||
|
|
||||||
PyDoc_STRVAR(bpy_bm_utils_face_join_doc,
|
PyDoc_STRVAR(bpy_bm_utils_face_join_doc,
|
||||||
".. method:: face_join(faces)\n"
|
".. method:: face_join(faces, remove=True)\n"
|
||||||
"\n"
|
"\n"
|
||||||
" Joins a sequence of faces.\n"
|
" Joins a sequence of faces.\n"
|
||||||
"\n"
|
"\n"
|
||||||
" :arg faces: Sequence of faces.\n"
|
" :arg faces: Sequence of faces.\n"
|
||||||
" :type faces: :class:`bmesh.types.BMFace`\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"
|
" :return: The newly created face or None on failure.\n"
|
||||||
" :rtype: :class:`bmesh.types.BMFace`\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;
|
BMesh *bm = NULL;
|
||||||
|
PyObject *py_face_array;
|
||||||
BMFace **face_array;
|
BMFace **face_array;
|
||||||
Py_ssize_t face_seq_len = 0;
|
Py_ssize_t face_seq_len = 0;
|
||||||
BMFace *f_new;
|
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,
|
&face_seq_len, BM_FACE,
|
||||||
TRUE, TRUE, "face_join(...)");
|
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!
|
/* 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);
|
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_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},
|
{"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_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_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},
|
{"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},
|
{"loop_separate", (PyCFunction)bpy_bm_utils_loop_separate, METH_O, bpy_bm_utils_loop_separate_doc},
|
||||||
|
Loading…
Reference in New Issue
Block a user