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:
authorCampbell Barton <ideasman42@gmail.com>2015-06-17 19:20:18 +0300
committerCampbell Barton <ideasman42@gmail.com>2015-06-17 20:17:20 +0300
commit937ecaf77eff307455c5825cb91f1072c4d3c3aa (patch)
treef52c88c8cd0288bb892724cca552e356224bb390 /source/blender
parentda61c36f2a8e57d4be3eb0d989200262042e770c (diff)
BMesh: Add edge-offset option: cap-endpoint
Creating triangles at endpoints is often not so good, disable by default.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/bmesh/intern/bmesh_opdefines.c1
-rw-r--r--source/blender/bmesh/operators/bmo_offset_edgeloops.c77
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c7
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