diff options
author | Campbell Barton <ideasman42@gmail.com> | 2012-04-05 05:20:32 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2012-04-05 05:20:32 +0400 |
commit | 784beb43385b10e01feb4d480a35cdccfaed70e2 (patch) | |
tree | 107d37fbebbc668566c6b2b89b19b52879c58c28 | |
parent | 680c23b77151640e0ddda9aad84d1a8e99ede037 (diff) |
adjust limited dissolve to take face angle into account when dissolving vertices between manifold edges.
stops artifact with zig-zag patterns between _almost_ planer faces.
-rw-r--r-- | source/blender/bmesh/intern/bmesh_core.c | 3 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_dissolve.c | 39 |
2 files changed, 35 insertions, 7 deletions
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index 65b144a7667..ca3b1c85aa4 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -1038,8 +1038,7 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const short do_del else { /* otherwise we get both old and new faces */ for (i = 0; i < totface; i++) { - f = faces[i]; - BM_face_kill(bm, f); + BM_face_kill(bm, faces[i]); } } diff --git a/source/blender/bmesh/operators/bmo_dissolve.c b/source/blender/bmesh/operators/bmo_dissolve.c index 29a0aa743b7..d42439d31fd 100644 --- a/source/blender/bmesh/operators/bmo_dissolve.c +++ b/source/blender/bmesh/operators/bmo_dissolve.c @@ -472,7 +472,29 @@ void dummy_exec(BMesh *bm, BMOperator *op) #endif -/**/ +/* Limited Dissolve */ + +#define UNIT_TO_ANGLE DEG2RADF(90.0) +#define ANGLE_TO_UNIT (1.0 / UNIT_TO_ANGLE) + +/* multiply vertex edge angle by face angle + * this means we are not left with sharp corners between _almost_ planer faces + * convert angles [0-PI/2] -> [0-1], multiply together, then convert back to radians. */ +float bm_vert_edge_face_angle(BMVert *v) +{ + const float angle = BM_vert_edge_angle(v); + /*note: could be either edge, it doesnt matter */ + if (v->e && BM_edge_is_manifold(v->e)) { + return ((angle * ANGLE_TO_UNIT) * (BM_edge_face_angle(v->e) * ANGLE_TO_UNIT)) * UNIT_TO_ANGLE; + } + else { + return angle; + } +} + +#undef UNIT_TO_ANGLE +#undef ANGLE_TO_UNIT + typedef struct DissolveElemWeight { BMHeader *ele; float weight; @@ -553,7 +575,7 @@ void bmo_dissolve_limit_exec(BMesh *bm, BMOperator *op) /* --- second verts --- */ for (i = 0, tot_found = 0; i < vinput->len; i++) { BMVert *v = ((BMVert **)vinput->data.p)[i]; - const float angle = BM_vert_edge_angle(v); + const float angle = bm_vert_edge_face_angle(v); if (angle < angle_limit) { weight_elems[i].ele = (BMHeader *)v; @@ -571,9 +593,16 @@ void bmo_dissolve_limit_exec(BMesh *bm, BMOperator *op) for (i = 0; i < tot_found; i++) { BMVert *v = (BMVert *)weight_elems[i].ele; - /* check twice because cumulative effect could dissolve over angle limit */ - if (BM_vert_edge_angle(v) < angle_limit) { - BM_vert_collapse_edge(bm, v->e, v, TRUE); /* join edges */ + if (/* topology changes may cause this to be un-collapsable */ + (BM_vert_edge_count(v) == 2) && + /* check twice because cumulative effect could dissolve over angle limit */ + bm_vert_edge_face_angle(v) < angle_limit) + { + BMEdge *ne = BM_vert_collapse_edge(bm, v->e, v, TRUE); /* join edges */ + + if (ne && ne->l) { + BM_edge_normals_update(bm, ne); + } } } } |