diff options
author | Campbell Barton <ideasman42@gmail.com> | 2015-06-17 19:20:18 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2015-06-17 20:17:20 +0300 |
commit | 937ecaf77eff307455c5825cb91f1072c4d3c3aa (patch) | |
tree | f52c88c8cd0288bb892724cca552e356224bb390 /source | |
parent | da61c36f2a8e57d4be3eb0d989200262042e770c (diff) |
BMesh: Add edge-offset option: cap-endpoint
Creating triangles at endpoints is often not so good, disable by default.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/bmesh/intern/bmesh_opdefines.c | 1 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_offset_edgeloops.c | 77 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_tools.c | 7 |
3 files changed, 77 insertions, 8 deletions
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 766db1db5b1..687fb62795f 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -1874,6 +1874,7 @@ static BMOpDefine bmo_offset_edgeloops_def = { "offset_edgeloops", /* slots_in */ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input faces */ + {"use_cap_endpoint", BMO_OP_SLOT_BOOL}, {{'\0'}}, }, /* slots_out */ diff --git a/source/blender/bmesh/operators/bmo_offset_edgeloops.c b/source/blender/bmesh/operators/bmo_offset_edgeloops.c index d4d77f9a1cc..993fe8bed37 100644 --- a/source/blender/bmesh/operators/bmo_offset_edgeloops.c +++ b/source/blender/bmesh/operators/bmo_offset_edgeloops.c @@ -41,7 +41,13 @@ #include "intern/bmesh_operators_private.h" /* own include */ -#define ELE_NEW 1 +#define USE_CAP_OPTION + +#define ELE_NEW (1 << 0) + +#ifdef USE_CAP_OPTION +#define ELE_VERT_ENDPOINT (1 << 1) +#endif /* set for debugging */ #define OFFSET 0.0f @@ -80,6 +86,11 @@ void bmo_offset_edgeloops_exec(BMesh *bm, BMOperator *op) STACK_DECLARE(verts); int i; +#ifdef USE_CAP_OPTION + bool use_cap_endpoint = BMO_slot_bool_get(op->slots_in, "use_cap_endpoint"); + int v_edges_max = 0; +#endif + BMOIter oiter; /* only so we can detect new verts (index == -1) */ @@ -138,6 +149,8 @@ void bmo_offset_edgeloops_exec(BMesh *bm, BMOperator *op) /* main loop */ for (i = 0; i < STACK_SIZE(verts); i++) { + int v_edges_num = 0; + int v_edges_num_untag = 0; BMVert *v = verts[i]; BMIter iter; BMEdge *e; @@ -155,7 +168,21 @@ void bmo_offset_edgeloops_exec(BMesh *bm, BMOperator *op) v_other = BM_edge_other_vert(e, v); BM_edge_split(bm, e, v_other, NULL, 1.0f - OFFSET); } + else { + v_edges_num_untag += 1; + } + + v_edges_num += 1; } + +#ifdef USE_CAP_OPTION + if (v_edges_num_untag == 1) { + BMO_elem_flag_enable(bm, v, ELE_VERT_ENDPOINT); + } + + CLAMP_MIN(v_edges_max, v_edges_num); +#endif + } @@ -172,11 +199,16 @@ void bmo_offset_edgeloops_exec(BMesh *bm, BMOperator *op) if ((BM_elem_index_get(l->next->v) == -1) && (BM_elem_index_get(l->prev->v) == -1)) { - BMLoop *l_new; - BM_face_split(bm, l->f, l->prev, l->next, &l_new, NULL, true); - BLI_assert(f_cmp == l->f); - BLI_assert(f_cmp != l_new->f); - BMO_elem_flag_enable(bm, l_new->e, ELE_NEW); +#ifdef USE_CAP_OPTION + if (use_cap_endpoint || (BMO_elem_flag_test(bm, v, ELE_VERT_ENDPOINT) == 0)) +#endif + { + BMLoop *l_new; + BM_face_split(bm, l->f, l->prev, l->next, &l_new, NULL, true); + BLI_assert(f_cmp == l->f); + BLI_assert(f_cmp != l_new->f); + BMO_elem_flag_enable(bm, l_new->e, ELE_NEW); + } } else if (l->f->len > 4) { if (BM_elem_flag_test(l->e, BM_ELEM_TAG) != @@ -217,6 +249,39 @@ void bmo_offset_edgeloops_exec(BMesh *bm, BMOperator *op) } } +#ifdef USE_CAP_OPTION + if (use_cap_endpoint == false) { + BMVert **varr = BLI_array_alloca(varr, v_edges_max); + STACK_DECLARE(varr); + BMVert *v; + + for (i = 0; i < STACK_SIZE(verts); i++) { + BMIter iter; + BMEdge *e; + + v = verts[i]; + + STACK_INIT(varr, v_edges_max); + + BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) { + BMVert *v_other; + v_other = BM_edge_other_vert(e, v); + if (BM_elem_index_get(v_other) == -1) { + if (BM_vert_is_edge_pair(v_other)) { + /* defer bmesh_jekv to avoid looping over data we're removing */ + v_other->e = e; + STACK_PUSH(varr, v_other); + } + } + } + + while ((v = STACK_POP(varr))) { + bmesh_jekv(bm, v->e, v, true, false); + } + } + } +#endif + MEM_freeN(verts); BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "edges.out", BM_EDGE, ELE_NEW); diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 0b13512b627..b47e1d54ed5 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -5186,11 +5186,12 @@ static int edbm_offset_edgeloop_exec(bContext *C, wmOperator *op) Object *obedit = CTX_data_edit_object(C); BMEditMesh *em = BKE_editmesh_from_object(obedit); BMOperator bmop; + const bool use_cap_endpoint = RNA_boolean_get(op->ptr, "use_cap_endpoint"); EDBM_op_init( em, &bmop, op, - "offset_edgeloops edges=%he", - BM_ELEM_SELECT); + "offset_edgeloops edges=%he use_cap_endpoint=%b", + BM_ELEM_SELECT, use_cap_endpoint); BMO_op_exec(em->bm, &bmop); @@ -5230,6 +5231,8 @@ void MESH_OT_offset_edge_loops(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; + + RNA_def_boolean(ot->srna, "use_cap_endpoint", false, "Cap Endpoint", "Extend loop around end-points"); } #ifdef WITH_BULLET |