diff options
author | Germano Cavalcante <germano.costa@ig.com.br> | 2020-04-15 17:54:41 +0300 |
---|---|---|
committer | Germano Cavalcante <germano.costa@ig.com.br> | 2020-04-15 18:01:54 +0300 |
commit | fe513a5b61ca0d8abac08f95b07103510a4626cb (patch) | |
tree | bbc5acf74f727b796552394e96ee7e6a969a7a56 /source/blender/bmesh/operators/bmo_extrude.c | |
parent | 7af84255c76b4da0cb180a2b5b296c2c5e2b4317 (diff) |
Operator: Add 'use_dissolve_ortho_edges' option for Extrude
Diffstat (limited to 'source/blender/bmesh/operators/bmo_extrude.c')
-rw-r--r-- | source/blender/bmesh/operators/bmo_extrude.c | 65 |
1 files changed, 64 insertions, 1 deletions
diff --git a/source/blender/bmesh/operators/bmo_extrude.c b/source/blender/bmesh/operators/bmo_extrude.c index 7a7f4a14db3..3c63f4a60d6 100644 --- a/source/blender/bmesh/operators/bmo_extrude.c +++ b/source/blender/bmesh/operators/bmo_extrude.c @@ -39,6 +39,7 @@ enum { EXT_INPUT = 1, EXT_KEEP = 2, EXT_DEL = 4, + EXT_TAG = 8, }; #define VERT_MARK 1 @@ -335,6 +336,8 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op) const bool use_normal_flip = BMO_slot_bool_get(op->slots_in, "use_normal_flip"); const bool use_normal_from_adjacent = BMO_slot_bool_get(op->slots_in, "use_normal_from_adjacent"); + const bool use_dissolve_ortho_edges = BMO_slot_bool_get(op->slots_in, + "use_dissolve_ortho_edges"); /* initialize our sub-operators */ BMO_op_initf(bm, @@ -442,6 +445,24 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op) } } + BMVert **dissolve_verts = NULL; + int dissolve_verts_len = 0; + float average_normal[3]; + if (use_dissolve_ortho_edges) { + /* Calc average normal. */ + zero_v3(average_normal); + BMO_ITER (f, &siter, dupeop.slots_out, "geom.out", BM_FACE) { + add_v3_v3(average_normal, f->no); + } + if (normalize_v3(average_normal) == 0.0f) { + average_normal[2] = 1.0f; + } + + /* Allocate array to store possible vertices that will be dissolved. */ + int boundary_verts_len = BMO_slot_map_count(dupeop.slots_out, "boundary_map.out"); + dissolve_verts = MEM_mallocN((size_t)boundary_verts_len * sizeof(*dissolve_verts), __func__); + } + BMO_slot_copy(&dupeop, slots_out, "geom.out", op, slots_out, "geom.out"); slot_edges_exclude = BMO_slot_get(op->slots_in, "edges_exclude"); @@ -483,6 +504,16 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op) continue; } + BMFace *join_face = NULL; + if (use_dissolve_ortho_edges) { + if (BM_edge_is_boundary(e)) { + join_face = e->l->f; + if (fabs(dot_v3v3(average_normal, join_face->no)) > 0.0001f) { + join_face = NULL; + } + } + } + bool edge_normal_flip; if (use_normal_from_adjacent == false) { /* Orient loop to give same normal as a loop of 'e_new' @@ -541,7 +572,22 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op) f = BM_face_create_verts(bm, f_verts, 4, NULL, BM_CREATE_NOP, true); #endif - bm_extrude_copy_face_loop_attributes(bm, f); + if (join_face) { + BMVert *v1 = e->v1; + BMVert *v2 = e->v2; + if (!BMO_elem_flag_test(bm, v1, EXT_TAG)) { + BMO_elem_flag_enable(bm, v1, EXT_TAG); + dissolve_verts[dissolve_verts_len++] = v1; + } + if (!BMO_elem_flag_test(bm, v2, EXT_TAG)) { + BMO_elem_flag_enable(bm, v2, EXT_TAG); + dissolve_verts[dissolve_verts_len++] = v2; + } + bmesh_kernel_join_face_kill_edge(bm, join_face, f, e); + } + else { + bm_extrude_copy_face_loop_attributes(bm, f); + } } /* link isolated vert */ @@ -559,6 +605,23 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op) BM_edge_create(bm, v, v2, NULL, BM_CREATE_NO_DOUBLE); } + if (dissolve_verts) { + BMVert **v_iter = &dissolve_verts[0]; + for (int i = dissolve_verts_len; i--; v_iter++) { + v = *v_iter; + e = v->e; + BMEdge *e_other = BM_DISK_EDGE_NEXT(e, v); + if ((e_other == e) || (BM_DISK_EDGE_NEXT(e_other, v) == e)) { + /* Lose edge or BMVert is edge pair. */ + BM_edge_collapse(bm, e, v, true, false); + } + else { + BLI_assert(!BM_vert_is_edge_pair(v)); + } + } + MEM_freeN(dissolve_verts); + } + /* cleanup */ if (delorig) { BMO_op_finish(bm, &delop); |