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.
This commit is contained in:
Campbell Barton
2012-04-05 01:20:32 +00:00
parent 680c23b771
commit 784beb4338
2 changed files with 35 additions and 7 deletions

View File

@@ -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]);
}
}

View File

@@ -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);
}
}
}
}