diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-06-03 09:07:16 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-06-03 09:07:16 +0400 |
commit | 790e9d9fa084c30609a13d175c56a4f3c14f132e (patch) | |
tree | e56e66a7b0e5d1eef4153be76b1d2cc0b97c9fa6 /source/blender/bmesh | |
parent | 8a1ef33e88d2683f8566f4db8edbc3dc2f488307 (diff) |
fix [#35311] Planar Decimate / Limited Dissolve fails to merge some adjacent faces
optionally limit by face flipping, also added support to delimit by material and edge crease.
Diffstat (limited to 'source/blender/bmesh')
-rw-r--r-- | source/blender/bmesh/intern/bmesh_opdefines.c | 1 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_operator_api.h | 6 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_dissolve.c | 3 | ||||
-rw-r--r-- | source/blender/bmesh/tools/bmesh_decimate.h | 4 | ||||
-rw-r--r-- | source/blender/bmesh/tools/bmesh_decimate_dissolve.c | 50 |
5 files changed, 55 insertions, 9 deletions
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 59de3622adb..b42e6c537a9 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -941,6 +941,7 @@ static BMOpDefine bmo_dissolve_limit_def = { {"use_dissolve_boundaries", BMO_OP_SLOT_BOOL}, {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, + {"delimit", BMO_OP_SLOT_INT}, {{'\0'}}, }, {{{'\0'}}}, /* no output */ diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h b/source/blender/bmesh/intern/bmesh_operator_api.h index ccc90172d7a..24bfcd70d75 100644 --- a/source/blender/bmesh/intern/bmesh_operator_api.h +++ b/source/blender/bmesh/intern/bmesh_operator_api.h @@ -297,6 +297,12 @@ typedef enum { BMO_SYMMETRIZE_POSITIVE_Z, } BMO_SymmDirection; +typedef enum { + BMO_DELIM_NORMAL = 1 << 0, + BMO_DELIM_MATERIAL = 1 << 1, + BMO_DELIM_SEAM = 1 << 2, +} BMO_Delimit; + void BMO_op_flag_enable(BMesh *bm, BMOperator *op, const int op_flag); void BMO_op_flag_disable(BMesh *bm, BMOperator *op, const int op_flag); diff --git a/source/blender/bmesh/operators/bmo_dissolve.c b/source/blender/bmesh/operators/bmo_dissolve.c index ee483edbef5..0f72a016e2f 100644 --- a/source/blender/bmesh/operators/bmo_dissolve.c +++ b/source/blender/bmesh/operators/bmo_dissolve.c @@ -452,8 +452,9 @@ void bmo_dissolve_limit_exec(BMesh *bm, BMOperator *op) const float angle_max = (float)M_PI / 2.0f; const float angle_limit = min_ff(angle_max, BMO_slot_float_get(op->slots_in, "angle_limit")); const bool do_dissolve_boundaries = BMO_slot_bool_get(op->slots_in, "use_dissolve_boundaries"); + const BMO_Delimit delimit = BMO_slot_int_get(op->slots_in, "delimit"); - BM_mesh_decimate_dissolve_ex(bm, angle_limit, do_dissolve_boundaries, + BM_mesh_decimate_dissolve_ex(bm, angle_limit, do_dissolve_boundaries, delimit, (BMVert **)BMO_SLOT_AS_BUFFER(vinput), vinput->len, (BMEdge **)BMO_SLOT_AS_BUFFER(einput), einput->len); } diff --git a/source/blender/bmesh/tools/bmesh_decimate.h b/source/blender/bmesh/tools/bmesh_decimate.h index d3eaf1c6670..c77cb18c518 100644 --- a/source/blender/bmesh/tools/bmesh_decimate.h +++ b/source/blender/bmesh/tools/bmesh_decimate.h @@ -33,9 +33,11 @@ void BM_mesh_decimate_unsubdivide_ex(BMesh *bm, const int iterations, const bool void BM_mesh_decimate_unsubdivide(BMesh *bm, const int iterations); void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const bool do_dissolve_boundaries, + const BMO_Delimit delimit, BMVert **vinput_arr, const int vinput_len, BMEdge **einput_arr, const int einput_len); -void BM_mesh_decimate_dissolve(BMesh *bm, const float angle_limit, const bool do_dissolve_boundaries); +void BM_mesh_decimate_dissolve(BMesh *bm, const float angle_limit, const bool do_dissolve_boundaries, + const BMO_Delimit delimit); /* these weights are accumulated so too high values may reach 'inf' too quickly */ #define BM_MESH_DECIM_WEIGHT_MAX 100000.0f diff --git a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c index a5122b242be..9d4e01d19cd 100644 --- a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c +++ b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c @@ -70,6 +70,7 @@ static int dissolve_elem_cmp(const void *a1, const void *a2) } void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const bool do_dissolve_boundaries, + const BMO_Delimit delimit, BMVert **vinput_arr, const int vinput_len, BMEdge **einput_arr, const int einput_len) { @@ -77,7 +78,6 @@ void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const bool DissolveElemWeight *weight_elems = MEM_mallocN(max_ii(einput_len, vinput_len) * sizeof(DissolveElemWeight), __func__); int i, tot_found; - BMIter iter; BMEdge *e_iter; BMEdge **earray; @@ -94,7 +94,13 @@ void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const bool /* go through and split edge */ for (i = 0, tot_found = 0; i < einput_len; i++) { BMEdge *e = einput_arr[i]; - const float angle = BM_edge_calc_face_angle(e); + const bool is_contig = BM_edge_is_contiguous(e); + float angle; + + angle = BM_edge_calc_face_angle(e); + if (is_contig == false) { + angle = (float)M_PI - angle; + } if (angle < angle_limit) { tot_found++; @@ -108,12 +114,39 @@ void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const bool for (i = 0; i < tot_found; i++) { BMEdge *e = (BMEdge *)weight_elems[i].ele; + const bool is_contig = BM_edge_is_contiguous(e); + float angle; + + /* may have become non-manifold */ + if (!BM_edge_is_manifold(e)) { + continue; + } - if (/* may have become non-manifold */ - BM_edge_is_manifold(e) && - /* check twice because cumulative effect could dissolve over angle limit */ - (BM_edge_calc_face_angle(e) < angle_limit)) + if ((delimit & BMO_DELIM_SEAM) && + (BM_elem_flag_test(e, BM_ELEM_SEAM))) { + continue; + } + + if ((delimit & BMO_DELIM_MATERIAL) && + (e->l->f->mat_nr != e->l->radial_next->f->mat_nr)) + { + continue; + } + + if ((delimit & BMO_DELIM_NORMAL) && + (is_contig == false)) + { + continue; + } + + /* check twice because cumulative effect could dissolve over angle limit */ + angle = BM_edge_calc_face_angle(e); + if (is_contig == false) { + angle = (float)M_PI - angle; + } + + if (angle < angle_limit) { BMFace *f_new = BM_faces_join_pair(bm, e->l->f, e->l->radial_next->f, e, @@ -223,7 +256,8 @@ void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const bool MEM_freeN(weight_elems); } -void BM_mesh_decimate_dissolve(BMesh *bm, const float angle_limit, const bool do_dissolve_boundaries) +void BM_mesh_decimate_dissolve(BMesh *bm, const float angle_limit, const bool do_dissolve_boundaries, + const BMO_Delimit delimit) { int vinput_len; int einput_len; @@ -231,7 +265,9 @@ void BM_mesh_decimate_dissolve(BMesh *bm, const float angle_limit, const bool do BMVert **vinput_arr = BM_iter_as_arrayN(bm, BM_VERTS_OF_MESH, NULL, &vinput_len, NULL, 0); BMEdge **einput_arr = BM_iter_as_arrayN(bm, BM_EDGES_OF_MESH, NULL, &einput_len, NULL, 0); + BM_mesh_decimate_dissolve_ex(bm, angle_limit, do_dissolve_boundaries, + delimit, vinput_arr, vinput_len, einput_arr, einput_len); |