[Bf-blender-cvs] [937ecaf] master: BMesh: Add edge-offset option: cap-endpoint

Campbell Barton noreply at git.blender.org
Wed Jun 17 19:23:00 CEST 2015


Commit: 937ecaf77eff307455c5825cb91f1072c4d3c3aa
Author: Campbell Barton
Date:   Thu Jun 18 02:20:18 2015 +1000
Branches: master
https://developer.blender.org/rB937ecaf77eff307455c5825cb91f1072c4d3c3aa

BMesh: Add edge-offset option: cap-endpoint

Creating triangles at endpoints is often not so good, disable by default.

===================================================================

M	source/blender/bmesh/intern/bmesh_opdefines.c
M	source/blender/bmesh/operators/bmo_offset_edgeloops.c
M	source/blender/editors/mesh/editmesh_tools.c

===================================================================

diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c
index 766db1d..687fb62 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 d4d77f9..993fe8b 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 0b13512..b47e1d5 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




More information about the Bf-blender-cvs mailing list