Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/bmesh/intern/bmesh_opdefines.c1
-rw-r--r--source/blender/bmesh/operators/bmo_extrude.c65
-rw-r--r--source/blender/editors/mesh/editmesh_extrude.c18
3 files changed, 80 insertions, 4 deletions
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c
index 4fa7bf64834..45666a21a2c 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -1046,6 +1046,7 @@ static BMOpDefine bmo_extrude_face_region_def = {
{"use_keep_orig", BMO_OP_SLOT_BOOL}, /* keep original geometry (requires ``geom`` to include edges). */
{"use_normal_flip", BMO_OP_SLOT_BOOL}, /* Create faces with reversed direction. */
{"use_normal_from_adjacent", BMO_OP_SLOT_BOOL}, /* Use winding from surrounding faces instead of this region. */
+ {"use_dissolve_ortho_edges", BMO_OP_SLOT_BOOL}, /* Dissolve edges whose faces form a flat surface. */
{"use_select_history", BMO_OP_SLOT_BOOL}, /* pass to duplicate */
{{'\0'}},
},
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);
diff --git a/source/blender/editors/mesh/editmesh_extrude.c b/source/blender/editors/mesh/editmesh_extrude.c
index 23f622ac359..bf6c5a2f829 100644
--- a/source/blender/editors/mesh/editmesh_extrude.c
+++ b/source/blender/editors/mesh/editmesh_extrude.c
@@ -226,6 +226,7 @@ static bool edbm_extrude_ex(Object *obedit,
char htype,
const char hflag,
const bool use_normal_flip,
+ const bool use_dissolve_ortho_edges,
const bool use_mirror,
const bool use_select_history)
{
@@ -241,6 +242,7 @@ static bool edbm_extrude_ex(Object *obedit,
BMO_op_init(bm, &extop, BMO_FLAG_DEFAULTS, "extrude_face_region");
BMO_slot_bool_set(extop.slots_in, "use_normal_flip", use_normal_flip);
+ BMO_slot_bool_set(extop.slots_in, "use_dissolve_ortho_edges", use_dissolve_ortho_edges);
BMO_slot_bool_set(extop.slots_in, "use_select_history", use_select_history);
BMO_slot_buffer_from_enabled_hflag(bm, &extop, extop.slots_in, "geom", htype, hflag);
@@ -312,7 +314,7 @@ static int edbm_extrude_repeat_exec(bContext *C, wmOperator *op)
mul_v3_m3v3(offset_local, tmat, offset);
for (int a = 0; a < steps; a++) {
- edbm_extrude_ex(obedit, em, BM_ALL_NOLOOP, BM_ELEM_SELECT, false, false, true);
+ edbm_extrude_ex(obedit, em, BM_ALL_NOLOOP, BM_ELEM_SELECT, false, false, false, true);
BMO_op_callf(
em->bm, BMO_FLAG_DEFAULTS, "translate vec=%v verts=%hv", offset_local, BM_ELEM_SELECT);
}
@@ -359,6 +361,7 @@ void MESH_OT_extrude_repeat(wmOperatorType *ot)
static bool edbm_extrude_mesh(Object *obedit, BMEditMesh *em, wmOperator *op)
{
const bool use_normal_flip = RNA_boolean_get(op->ptr, "use_normal_flip");
+ const bool use_dissolve_ortho_edges = RNA_boolean_get(op->ptr, "use_dissolve_ortho_edges");
const char htype = edbm_extrude_htype_from_em_select(em);
enum { NONE = 0, ELEM_FLAG, VERT_ONLY, EDGE_ONLY } nr;
bool changed = false;
@@ -401,7 +404,14 @@ static bool edbm_extrude_mesh(Object *obedit, BMEditMesh *em, wmOperator *op)
case NONE:
return false;
case ELEM_FLAG:
- changed = edbm_extrude_ex(obedit, em, htype, BM_ELEM_SELECT, use_normal_flip, true, true);
+ changed = edbm_extrude_ex(obedit,
+ em,
+ htype,
+ BM_ELEM_SELECT,
+ use_normal_flip,
+ use_dissolve_ortho_edges,
+ true,
+ true);
break;
case VERT_ONLY:
changed = edbm_extrude_verts_indiv(em, op, BM_ELEM_SELECT);
@@ -465,6 +475,7 @@ void MESH_OT_extrude_region(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
RNA_def_boolean(ot->srna, "use_normal_flip", false, "Flip Normals", "");
+ RNA_def_boolean(ot->srna, "use_dissolve_ortho_edges", false, "Dissolve Orthogonal Edges", "");
Transform_Properties(ot, P_NO_DEFAULTS | P_MIRROR_DUMMY);
}
@@ -519,6 +530,7 @@ void MESH_OT_extrude_context(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
RNA_def_boolean(ot->srna, "use_normal_flip", false, "Flip Normals", "");
+ RNA_def_boolean(ot->srna, "use_dissolve_ortho_edges", false, "Dissolve Orthogonal Edges", "");
Transform_Properties(ot, P_NO_DEFAULTS | P_MIRROR_DUMMY);
}
@@ -840,7 +852,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, const w
}
}
- edbm_extrude_ex(vc.obedit, vc.em, extrude_htype, BM_ELEM_SELECT, false, true, true);
+ edbm_extrude_ex(vc.obedit, vc.em, extrude_htype, BM_ELEM_SELECT, false, false, true, true);
EDBM_op_callf(
vc.em, op, "rotate verts=%hv cent=%v matrix=%m3", BM_ELEM_SELECT, local_center, mat);
EDBM_op_callf(vc.em, op, "translate verts=%hv vec=%v", BM_ELEM_SELECT, ofs);