forked from bartvdbraak/blender
BMesh: add ability not to delete vertex when collapsing
This commit is contained in:
parent
07a5caad5f
commit
c3deb16c16
@ -1657,7 +1657,8 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
|
||||
* faces with just 2 edges. It is up to the caller to decide what to do with
|
||||
* these faces.
|
||||
*/
|
||||
BMEdge *bmesh_jekv(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool check_edge_double)
|
||||
BMEdge *bmesh_jekv(BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
|
||||
const bool do_del, const bool check_edge_double)
|
||||
{
|
||||
BMEdge *e_old;
|
||||
BMVert *v_old, *tv;
|
||||
@ -1668,6 +1669,8 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool check_e
|
||||
bool edok;
|
||||
#endif
|
||||
|
||||
BLI_assert(BM_vert_in_edge(e_kill, v_kill));
|
||||
|
||||
if (BM_vert_in_edge(e_kill, v_kill) == 0) {
|
||||
return NULL;
|
||||
}
|
||||
@ -1759,7 +1762,12 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool check_e
|
||||
bm_kill_only_edge(bm, e_kill);
|
||||
|
||||
/* deallocate vertex */
|
||||
bm_kill_only_vert(bm, v_kill);
|
||||
if (do_del) {
|
||||
bm_kill_only_vert(bm, v_kill);
|
||||
}
|
||||
else {
|
||||
v_kill->e = NULL;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
/* Validate disk cycle lengths of v_old, tv are unchanged */
|
||||
|
@ -83,7 +83,8 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f,
|
||||
);
|
||||
|
||||
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 check_edge_splice);
|
||||
BMEdge *bmesh_jekv(BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
|
||||
const bool do_del, const bool check_edge_splice);
|
||||
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);
|
||||
|
@ -78,7 +78,7 @@ bool BM_vert_dissolve(BMesh *bm, BMVert *v)
|
||||
}
|
||||
else if (!v->e->l) {
|
||||
if (len == 2) {
|
||||
return (BM_vert_collapse_edge(bm, v->e, v, true) != NULL);
|
||||
return (BM_vert_collapse_edge(bm, v->e, v, true, true) != NULL);
|
||||
}
|
||||
else {
|
||||
/* used to kill the vertex here, but it may be connected to faces.
|
||||
@ -92,7 +92,7 @@ bool BM_vert_dissolve(BMesh *bm, BMVert *v)
|
||||
}
|
||||
else if (len == 2 && BM_vert_face_count(v) == 1) {
|
||||
/* boundary vertex on a face */
|
||||
return (BM_vert_collapse_edge(bm, v->e, v, true) != NULL);
|
||||
return (BM_vert_collapse_edge(bm, v->e, v, true, true) != NULL);
|
||||
}
|
||||
else {
|
||||
return BM_disk_dissolve(bm, v);
|
||||
@ -144,7 +144,7 @@ bool BM_disk_dissolve(BMesh *bm, BMVert *v)
|
||||
if (UNLIKELY(!BM_faces_join_pair(bm, e->l->f, e->l->radial_next->f, e, true))) {
|
||||
return false;
|
||||
}
|
||||
else if (UNLIKELY(!BM_vert_collapse_faces(bm, v->e, v, 1.0, false, true))) {
|
||||
else if (UNLIKELY(!BM_vert_collapse_faces(bm, v->e, v, 1.0, true, false, true))) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
@ -152,7 +152,7 @@ bool BM_disk_dissolve(BMesh *bm, BMVert *v)
|
||||
}
|
||||
else if (keepedge == NULL && len == 2) {
|
||||
/* collapse the vertex */
|
||||
e = BM_vert_collapse_faces(bm, v->e, v, 1.0, true, true);
|
||||
e = BM_vert_collapse_faces(bm, v->e, v, 1.0, true, true, true);
|
||||
|
||||
if (!e) {
|
||||
return false;
|
||||
@ -196,7 +196,7 @@ bool BM_disk_dissolve(BMesh *bm, BMVert *v)
|
||||
|
||||
/* collapse the vertex */
|
||||
/* note, the baseedge can be a boundary of manifold, use this as join_faces arg */
|
||||
e = BM_vert_collapse_faces(bm, baseedge, v, 1.0, !BM_edge_is_boundary(baseedge), true);
|
||||
e = BM_vert_collapse_faces(bm, baseedge, v, 1.0, true, !BM_edge_is_boundary(baseedge), true);
|
||||
|
||||
if (!e) {
|
||||
return false;
|
||||
@ -440,7 +440,7 @@ BMFace *BM_face_split_n(BMesh *bm, BMFace *f,
|
||||
* \returns The New Edge
|
||||
*/
|
||||
BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, float fac,
|
||||
const bool join_faces, const bool kill_degenerate_faces)
|
||||
const bool do_del, const bool join_faces, const bool kill_degenerate_faces)
|
||||
{
|
||||
BMEdge *e_new = NULL;
|
||||
BMVert *tv = BM_edge_other_vert(e_kill, v_kill);
|
||||
@ -513,7 +513,7 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, float
|
||||
/* 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, true);
|
||||
e_new = bmesh_jekv(bm, e_kill, v_kill, do_del, true);
|
||||
/* e_new = BM_edge_exists(tv, tv2); */ /* same as return above */
|
||||
|
||||
if (e_new && kill_degenerate_faces) {
|
||||
@ -553,7 +553,7 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, float
|
||||
* \return The New Edge
|
||||
*/
|
||||
BMEdge *BM_vert_collapse_edge(BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
|
||||
const bool kill_degenerate_faces)
|
||||
const bool do_del, const bool kill_degenerate_faces)
|
||||
{
|
||||
/* nice example implementation but we want loops to have their customdata
|
||||
* accounted for */
|
||||
@ -571,9 +571,7 @@ BMEdge *BM_vert_collapse_edge(BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
|
||||
BMVert *tv2 = BM_edge_other_vert(e2, v_kill);
|
||||
if (tv2) {
|
||||
/* only action, other calls here only get the edge to return */
|
||||
e_new = bmesh_jekv(bm, e_kill, v_kill);
|
||||
|
||||
/* e_new = BM_edge_exists(tv, tv2); */ /* same as return above */
|
||||
e_new = bmesh_jekv(bm, e_kill, v_kill, do_del);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -582,7 +580,7 @@ BMEdge *BM_vert_collapse_edge(BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
|
||||
#else
|
||||
/* with these args faces are never joined, same as above
|
||||
* but account for loop customdata */
|
||||
return BM_vert_collapse_faces(bm, e_kill, v_kill, 1.0f, false, kill_degenerate_faces);
|
||||
return BM_vert_collapse_faces(bm, e_kill, v_kill, 1.0f, do_del, false, kill_degenerate_faces);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -46,9 +46,9 @@ BMFace *BM_face_split_n(BMesh *bm, BMFace *f,
|
||||
BMLoop **r_l, BMEdge *example);
|
||||
|
||||
BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, float fac,
|
||||
const bool join_faces, const bool kill_degenerate_faces);
|
||||
const bool do_del, const bool join_faces, const bool kill_degenerate_faces);
|
||||
BMEdge *BM_vert_collapse_edge(BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
|
||||
const bool kill_degenerate_faces);
|
||||
const bool do_del, const bool kill_degenerate_faces);
|
||||
|
||||
|
||||
BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float percent);
|
||||
|
@ -216,7 +216,7 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op)
|
||||
BM_ITER_MESH_MUTABLE (v, v_next, &viter, bm, BM_VERTS_OF_MESH) {
|
||||
if (BMO_elem_flag_test(bm, v, VERT_MARK)) {
|
||||
if (BM_vert_edge_count(v) == 2) {
|
||||
BM_vert_collapse_edge(bm, v->e, v, true);
|
||||
BM_vert_collapse_edge(bm, v->e, v, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -328,7 +328,7 @@ void bmo_dissolve_edges_exec(BMesh *bm, BMOperator *op)
|
||||
BM_ITER_MESH_MUTABLE (v, v_next, &iter, bm, BM_VERTS_OF_MESH) {
|
||||
if (BMO_elem_flag_test(bm, v, VERT_MARK)) {
|
||||
if (BM_vert_edge_count(v) == 2) {
|
||||
BM_vert_collapse_edge(bm, v->e, v, true);
|
||||
BM_vert_collapse_edge(bm, v->e, v, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -410,7 +410,7 @@ void bmo_dissolve_verts_exec(BMesh *bm, BMOperator *op)
|
||||
BM_ITER_MESH_MUTABLE (v, v_next, &iter, bm, BM_VERTS_OF_MESH) {
|
||||
if (BMO_elem_flag_test(bm, v, VERT_MARK)) {
|
||||
if (BM_vert_edge_count(v) == 2) {
|
||||
BM_vert_collapse_edge(bm, v->e, v, true);
|
||||
BM_vert_collapse_edge(bm, v->e, v, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -237,7 +237,7 @@ void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const bool
|
||||
if (LIKELY(v != NULL) &&
|
||||
BM_vert_edge_count(v) == 2)
|
||||
{
|
||||
BM_vert_collapse_edge(bm, v->e, v, true); /* join edges */
|
||||
BM_vert_collapse_edge(bm, v->e, v, true, true); /* join edges */
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -275,7 +275,7 @@ void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const bool
|
||||
i = BM_elem_index_get(v);
|
||||
|
||||
if (BM_vert_edge_count(v) == 2) {
|
||||
e_new = BM_vert_collapse_edge(bm, v->e, v, true); /* join edges */
|
||||
e_new = BM_vert_collapse_edge(bm, v->e, v, true, true); /* join edges */
|
||||
|
||||
if (e_new) {
|
||||
|
||||
|
@ -119,7 +119,7 @@ static bool bm_vert_dissolve_fan(BMesh *bm, BMVert *v)
|
||||
if (tot_edge == 2) {
|
||||
/* check for 2 wire verts only */
|
||||
if (tot_edge_wire == 2) {
|
||||
return (BM_vert_collapse_edge(bm, v->e, v, true) != NULL);
|
||||
return (BM_vert_collapse_edge(bm, v->e, v, true, true) != NULL);
|
||||
}
|
||||
}
|
||||
else if (tot_edge == 4) {
|
||||
|
@ -90,7 +90,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, true);
|
||||
e_new = BM_vert_collapse_edge(bm, py_edge->e, py_vert->v, true, true);
|
||||
|
||||
if (e_new) {
|
||||
return BPy_BMEdge_CreatePyObject(bm, e_new);
|
||||
@ -156,7 +156,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, true);
|
||||
e_new = BM_vert_collapse_faces(bm, py_edge->e, py_vert->v, CLAMPIS(fac, 0.0f, 1.0f), true, do_join_faces, true);
|
||||
|
||||
if (e_new) {
|
||||
return BPy_BMEdge_CreatePyObject(bm, e_new);
|
||||
|
Loading…
Reference in New Issue
Block a user