forked from bartvdbraak/blender
bmesh - remove faces with <3 sides after dissolve/collapse (most tools already did this).
This commit is contained in:
parent
ff7ddb1925
commit
1004b03578
@ -219,8 +219,10 @@ BMFace *BM_face_split(BMesh *bm, BMFace *f,
|
|||||||
struct BMLoop **nl, BMEdge *example);
|
struct BMLoop **nl, BMEdge *example);
|
||||||
|
|
||||||
/* these 2 functions are very similar */
|
/* 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_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac,
|
||||||
BMEdge* BM_vert_collapse_edge(BMesh *bm, BMEdge *ke, BMVert *kv);
|
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. */
|
/* splits an edge. ne is set to the new edge created. */
|
||||||
|
@ -51,7 +51,7 @@ struct Object;
|
|||||||
typedef struct BMHeader {
|
typedef struct BMHeader {
|
||||||
void *data; /* customdata layers */
|
void *data; /* customdata layers */
|
||||||
int index; /* notes:
|
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.
|
* - 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,
|
* - Used for edge/vert/face, check BMesh.elem_index_dirty for valid index values,
|
||||||
* this is abused by various tools which set it dirty.
|
* this is abused by various tools which set it dirty.
|
||||||
|
@ -72,7 +72,7 @@ int BM_vert_dissolve(BMesh *bm, BMVert *v)
|
|||||||
}
|
}
|
||||||
else if (!v->e->l) {
|
else if (!v->e->l) {
|
||||||
if (len == 2) {
|
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 {
|
else {
|
||||||
/* used to kill the vertex here, but it may be connected to faces.
|
/* 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) {
|
else if (len == 2 && BM_vert_face_count(v) == 1) {
|
||||||
/* boundry vertex on a face */
|
/* 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 {
|
else {
|
||||||
return BM_disk_dissolve(bm, v);
|
return BM_disk_dissolve(bm, v);
|
||||||
@ -134,7 +134,7 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v)
|
|||||||
}
|
}
|
||||||
else if (keepedge == NULL && len == 2) {
|
else if (keepedge == NULL && len == 2) {
|
||||||
/* collapse the verte */
|
/* 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) {
|
if (!e) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -179,7 +179,7 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* collapse the verte */
|
/* 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) {
|
if (!e) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -410,7 +410,8 @@ BMFace *BM_face_split(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **nl,
|
|||||||
* @returns The New Edge
|
* @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;
|
BMEdge *ne = NULL;
|
||||||
BMVert *tv = bmesh_edge_getothervert(ke, kv);
|
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);
|
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 */
|
if (kill_degenerate_faces) {
|
||||||
/* same as BM_vert_collapse_edge() however we already
|
BMIter fiter;
|
||||||
* have vars to perform this operation so dont call. */
|
BMFace *f;
|
||||||
ne = bmesh_jekv(bm, ke, kv, TRUE);
|
BMVert *verts[2] = {ne->v1, ne->v2};
|
||||||
/* ne = BM_edge_exists(tv, tv2); */ /* same as return above */
|
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;
|
return ne;
|
||||||
}
|
}
|
||||||
@ -494,7 +508,8 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac, con
|
|||||||
* The New Edge
|
* 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
|
/* nice example implementation but we want loops to have their customdata
|
||||||
* accounted for */
|
* accounted for */
|
||||||
@ -523,7 +538,7 @@ BMEdge *BM_vert_collapse_edge(BMesh *bm, BMEdge *ke, BMVert *kv)
|
|||||||
#else
|
#else
|
||||||
/* with these args faces are never joined, same as above
|
/* with these args faces are never joined, same as above
|
||||||
* but account for loop customdata */
|
* 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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,7 +165,7 @@ void dissolvefaces_exec(BMesh *bm, BMOperator *op)
|
|||||||
BM_ITER(v, &viter, bm, BM_VERTS_OF_MESH, NULL) {
|
BM_ITER(v, &viter, bm, BM_VERTS_OF_MESH, NULL) {
|
||||||
if (BMO_elem_flag_test(bm, v, VERT_MARK)) {
|
if (BMO_elem_flag_test(bm, v, VERT_MARK)) {
|
||||||
if (BM_vert_edge_count(v) == 2) {
|
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 */
|
/* clean up extreneous 2-valence vertice */
|
||||||
for (i = 0; i < BLI_array_count(verts); i++) {
|
for (i = 0; i < BLI_array_count(verts); i++) {
|
||||||
if (verts[i]->e) {
|
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) {
|
BM_ITER(v, &viter, bm, BM_VERTS_OF_MESH, NULL) {
|
||||||
if (BMO_elem_flag_test(bm, v, VERT_MARK)) {
|
if (BMO_elem_flag_test(bm, v, VERT_MARK)) {
|
||||||
if (BM_vert_edge_count(v) == 2) {
|
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) {
|
if (BM_vert_edge_count(v) == 2) {
|
||||||
|
|
||||||
/* collapse the ver */
|
/* 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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -540,7 +547,7 @@ void dissolvelimit_exec(BMesh *bm, BMOperator *op)
|
|||||||
BMVert *v = (BMVert *)weight_elems[i].ele;
|
BMVert *v = (BMVert *)weight_elems[i].ele;
|
||||||
/* check twice because cumulative effect could disolve over angle limit */
|
/* check twice because cumulative effect could disolve over angle limit */
|
||||||
if (BM_vert_edge_angle(bm, v) < 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 */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -530,14 +530,14 @@ static BMLoop *BME_bevel_edge(BMesh *bm, BMLoop *l, float value, int UNUSED(opti
|
|||||||
ke = kl->e;
|
ke = kl->e;
|
||||||
/* BMESH-TODO: jfke doesn't handle customdata */
|
/* BMESH-TODO: jfke doesn't handle customdata */
|
||||||
jf = bmesh_jfke(bm, kl->prev->radial_next->f, kl->f, kl->prev->e);
|
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 {
|
else {
|
||||||
BM_face_split(bm, kl->f, kl->next->next->v, kl->v, &nl, kl->next->e);
|
BM_face_split(bm, kl->f, kl->next->next->v, kl->v, &nl, kl->next->e);
|
||||||
ke = kl->e;
|
ke = kl->e;
|
||||||
/* BMESH-TODO: jfke doesn't handle customdata */
|
/* BMESH-TODO: jfke doesn't handle customdata */
|
||||||
jf = bmesh_jfke(bm, kl->next->radial_next->f, kl->f, kl->next->e);
|
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 */
|
/* find saved loop pointer */
|
||||||
l = se->l;
|
l = se->l;
|
||||||
@ -576,14 +576,14 @@ static BMLoop *BME_bevel_edge(BMesh *bm, BMLoop *l, float value, int UNUSED(opti
|
|||||||
ke = kl->e;
|
ke = kl->e;
|
||||||
/* BMESH-TODO: jfke doesn't handle customdata */
|
/* BMESH-TODO: jfke doesn't handle customdata */
|
||||||
jf = bmesh_jfke(bm, kl->prev->radial_next->f, kl->f, kl->prev->e);
|
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 {
|
else {
|
||||||
BM_face_split(bm, kl->f, kl->next->next->v, kl->v, &nl, kl->next->e);
|
BM_face_split(bm, kl->f, kl->next->next->v, kl->v, &nl, kl->next->e);
|
||||||
ke = kl->e;
|
ke = kl->e;
|
||||||
/* BMESH-TODO: jfke doesn't handle customdata */
|
/* BMESH-TODO: jfke doesn't handle customdata */
|
||||||
jf = bmesh_jfke(bm, kl->next->radial_next->f, kl->f, kl->next->e);
|
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 */
|
/* find saved loop pointer */
|
||||||
l = se->l;
|
l = se->l;
|
||||||
|
@ -88,7 +88,7 @@ static PyObject *bpy_bm_utils_vert_collapse_edge(PyObject *UNUSED(self), PyObjec
|
|||||||
|
|
||||||
bm = py_edge->bm;
|
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) {
|
if (e_new) {
|
||||||
return BPy_BMEdge_CreatePyObject(bm, 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;
|
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) {
|
if (e_new) {
|
||||||
return BPy_BMEdge_CreatePyObject(bm, e_new);
|
return BPy_BMEdge_CreatePyObject(bm, e_new);
|
||||||
|
Loading…
Reference in New Issue
Block a user