BMesh: new API call to collapse an edge
Existing collapse functions were strict regarding the number of verts sharing an edge. BM_edge_collapse allows any edge to be passed in without first having to manipulate geometry.
This commit is contained in:
@@ -1855,6 +1855,104 @@ BMEdge *bmesh_jekv(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Join Vert Kill Edge (JVKE)
|
||||
*
|
||||
* Collapse an edge, merging surrounding data.
|
||||
*
|
||||
* Unlike #BM_vert_collapse_edge & #bmesh_jekv which only handle 2 valence verts,
|
||||
* this can handle any number of connected edges/faces.
|
||||
*
|
||||
* <pre>
|
||||
* Before: -> After:
|
||||
* +-+-+-+ +-+-+-+
|
||||
* | | | | | \ / |
|
||||
* +-+-+-+ +--+--+
|
||||
* | | | | | / \ |
|
||||
* +-+-+-+ +-+-+-+
|
||||
* </pre>
|
||||
*/
|
||||
BMVert *bmesh_jvke(
|
||||
BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
|
||||
const bool do_del, const bool check_edge_double,
|
||||
const bool kill_degenerate_faces)
|
||||
{
|
||||
BLI_SMALLSTACK_DECLARE(faces_degenerate, BMFace *);
|
||||
BMVert *v_target = BM_edge_other_vert(e_kill, v_kill);
|
||||
|
||||
BLI_assert(BM_vert_in_edge(e_kill, v_kill));
|
||||
|
||||
if (e_kill->l) {
|
||||
BMLoop *l_kill, *l_first, *l_kill_next;
|
||||
l_kill = l_first = e_kill->l;
|
||||
do {
|
||||
/* relink loops and fix vertex pointer */
|
||||
if (l_kill->next->v == v_kill) {
|
||||
l_kill->next->v = v_target;
|
||||
}
|
||||
|
||||
l_kill->next->prev = l_kill->prev;
|
||||
l_kill->prev->next = l_kill->next;
|
||||
if (BM_FACE_FIRST_LOOP(l_kill->f) == l_kill) {
|
||||
BM_FACE_FIRST_LOOP(l_kill->f) = l_kill->next;
|
||||
}
|
||||
|
||||
/* fix len attribute of face */
|
||||
l_kill->f->len--;
|
||||
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;
|
||||
|
||||
bm_kill_only_loop(bm, l_kill);
|
||||
|
||||
} while ((l_kill = l_kill_next) != l_first);
|
||||
|
||||
e_kill->l = NULL;
|
||||
}
|
||||
|
||||
BM_edge_kill(bm, e_kill);
|
||||
BM_CHECK_ELEMENT(v_kill);
|
||||
BM_CHECK_ELEMENT(v_target);
|
||||
|
||||
if (v_target->e && v_kill->e) {
|
||||
/* inline BM_vert_splice(bm, v_target, v_kill); */
|
||||
BMEdge *e;
|
||||
while ((e = v_kill->e)) {
|
||||
BMEdge *e_target;
|
||||
|
||||
if (check_edge_double) {
|
||||
e_target = BM_edge_exists(v_target, BM_edge_other_vert(e, v_kill));
|
||||
}
|
||||
|
||||
bmesh_edge_vert_swap(e, v_target, v_kill);
|
||||
BLI_assert(e->v1 != e->v2);
|
||||
|
||||
if (check_edge_double) {
|
||||
if (e_target) {
|
||||
BM_edge_splice(bm, e_target, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (kill_degenerate_faces) {
|
||||
BMFace *f_kill;
|
||||
while ((f_kill = BLI_SMALLSTACK_POP(faces_degenerate))) {
|
||||
BM_face_kill(bm, f_kill);
|
||||
}
|
||||
}
|
||||
|
||||
if (do_del) {
|
||||
BLI_assert(v_kill->e == NULL);
|
||||
bm_kill_only_vert(bm, v_kill);
|
||||
}
|
||||
|
||||
return v_target;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Join Face Kill Edge (JFKE)
|
||||
*
|
||||
|
||||
@@ -100,6 +100,10 @@ BMEdge *bmesh_jekv(
|
||||
BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
|
||||
const bool do_del, const bool check_edge_splice,
|
||||
const bool kill_degenerate_faces);
|
||||
BMVert *bmesh_jvke(
|
||||
BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
|
||||
const bool do_del, const bool check_edge_double,
|
||||
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);
|
||||
|
||||
@@ -1116,6 +1116,16 @@ BMEdge *BM_vert_collapse_edge(
|
||||
|
||||
#undef DO_V_INTERP
|
||||
|
||||
/**
|
||||
* Collapse and edge into a single vertex.
|
||||
*/
|
||||
BMVert *BM_edge_collapse(
|
||||
BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
|
||||
const bool do_del, const bool kill_degenerate_faces)
|
||||
{
|
||||
return bmesh_jvke(bm, e_kill, v_kill, do_del, true, kill_degenerate_faces);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Edge Split
|
||||
*
|
||||
|
||||
@@ -59,6 +59,9 @@ BMEdge *BM_vert_collapse_edge(
|
||||
BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
|
||||
const bool do_del, const bool kill_degenerate_faces);
|
||||
|
||||
BMVert *BM_edge_collapse(
|
||||
BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
|
||||
const bool do_del, const bool kill_degenerate_faces);
|
||||
|
||||
BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float percent);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user