[Bf-blender-cvs] [d8e994b] master: BMesh: edge-offset feature (Ctrl+Shift+R)

Campbell Barton noreply at git.blender.org
Mon Jun 15 03:08:53 CEST 2015


Commit: d8e994b35f247c3156a93f6901f0442eee08c13d
Author: Campbell Barton
Date:   Mon Jun 15 10:58:07 2015 +1000
Branches: master
https://developer.blender.org/rBd8e994b35f247c3156a93f6901f0442eee08c13d

BMesh: edge-offset feature (Ctrl+Shift+R)

Ability to quickly add 2x edge loops  on either side of selected loops.

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

M	release/scripts/startup/bl_ui/space_view3d_toolbar.py
M	source/blender/bmesh/CMakeLists.txt
M	source/blender/bmesh/intern/bmesh_opdefines.c
M	source/blender/bmesh/intern/bmesh_operators_private.h
M	source/blender/editors/mesh/editmesh_tools.c
M	source/blender/editors/mesh/mesh_intern.h
M	source/blender/editors/mesh/mesh_ops.c
M	source/blender/editors/transform/transform.c
M	source/blender/editors/transform/transform_ops.c

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

diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 362b7b0..14e8bd0 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -327,6 +327,7 @@ class VIEW3D_PT_tools_meshedit(View3DPanel, Panel):
         col.operator("mesh.edge_face_add")
         col.operator("mesh.subdivide")
         col.operator("mesh.loopcut_slide")
+        col.operator("mesh.offset_edge_loops_slide")
         col.operator("mesh.duplicate_move", text="Duplicate")
         row = col.row(align=True)
         row.operator("mesh.spin")
diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt
index 2946e1b..66ee184 100644
--- a/source/blender/bmesh/CMakeLists.txt
+++ b/source/blender/bmesh/CMakeLists.txt
@@ -61,6 +61,7 @@ set(SRC
 	operators/bmo_mesh_conv.c
 	operators/bmo_mirror.c
 	operators/bmo_normals.c
+	operators/bmo_offset_edgeloops.c
 	operators/bmo_planar_faces.c
 	operators/bmo_poke.c
 	operators/bmo_primitive.c
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c
index 096c307..766db1d 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -1866,6 +1866,26 @@ static BMOpDefine bmo_inset_region_def = {
 };
 
 /*
+ * Edgeloop Offset.
+ *
+ * Creates edge loops based on simple edge-outset method.
+ */
+static BMOpDefine bmo_offset_edgeloops_def = {
+	"offset_edgeloops",
+	/* slots_in */
+	{{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},    /* input faces */
+	 {{'\0'}},
+	},
+	/* slots_out */
+	{{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* output faces */
+	 {{'\0'}},
+	},
+	bmo_offset_edgeloops_exec,
+	(BMO_OPTYPE_FLAG_NORMALS_CALC |
+	 BMO_OPTYPE_FLAG_SELECT_FLUSH),
+};
+
+/*
  * Wire Frame.
  *
  * Makes a wire-frame copy of faces.
@@ -2021,6 +2041,7 @@ const BMOpDefine *bmo_opdefines[] = {
 	&bmo_duplicate_def,
 	&bmo_holes_fill_def,
 	&bmo_face_attribute_fill_def,
+	&bmo_offset_edgeloops_def,
 	&bmo_edgeloop_fill_def,
 	&bmo_edgenet_fill_def,
 	&bmo_edgenet_prepare_def,
diff --git a/source/blender/bmesh/intern/bmesh_operators_private.h b/source/blender/bmesh/intern/bmesh_operators_private.h
index 25340ee..5548ee7 100644
--- a/source/blender/bmesh/intern/bmesh_operators_private.h
+++ b/source/blender/bmesh/intern/bmesh_operators_private.h
@@ -82,6 +82,7 @@ void bmo_pointmerge_exec(BMesh *bm, BMOperator *op);
 void bmo_pointmerge_facedata_exec(BMesh *bm, BMOperator *op);
 void bmo_recalc_face_normals_exec(BMesh *bm, BMOperator *op);
 void bmo_poke_exec(BMesh *bm, BMOperator *op);
+void bmo_offset_edgeloops_exec(BMesh *bm, BMOperator *op);
 void bmo_planar_faces_exec(BMesh *bm, BMOperator *op);
 void bmo_region_extend_exec(BMesh *bm, BMOperator *op);
 void bmo_remove_doubles_exec(BMesh *bm, BMOperator *op);
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 62aec78..202ce8d 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -5181,6 +5181,57 @@ void MESH_OT_wireframe(wmOperatorType *ot)
 	RNA_def_property_ui_range(prop, 0.0, 1.0, 0.1, 2);
 }
 
+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;
+
+	EDBM_op_init(
+	        em, &bmop, op,
+	        "offset_edgeloops edges=%he",
+	        BM_ELEM_SELECT);
+
+	BMO_op_exec(em->bm, &bmop);
+
+	BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false);
+
+	/* If in face-only select mode, switch to edge select mode so that
+	 * an edge-only selection is not inconsistent state */
+	if (em->selectmode == SCE_SELECT_FACE) {
+		em->selectmode = SCE_SELECT_EDGE;
+		EDBM_selectmode_set(em);
+		EDBM_selectmode_to_scene(C);
+	}
+
+	BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "edges.out", BM_EDGE, BM_ELEM_SELECT, true);
+
+	if (!EDBM_op_finish(em, &bmop, op, true)) {
+		return OPERATOR_CANCELLED;
+	}
+	else {
+		EDBM_update_generic(em, true, true);
+		return OPERATOR_FINISHED;
+	}
+}
+
+void MESH_OT_offset_edge_loops(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name = "Offset Edge Loop";
+	ot->idname = "MESH_OT_offset_edge_loops";
+	ot->description = "Creates offset edge loop from the current selection";
+
+	/* api callbacks */
+	ot->exec = edbm_offset_edgeloop_exec;
+	ot->poll = ED_operator_editmesh;
+
+	/* Keep internal, since this is only meant to be accessed via 'MESH_OT_offset_edge_loops_slide' */
+
+	/* flags */
+	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+}
+
 #ifdef WITH_BULLET
 static int edbm_convex_hull_exec(bContext *C, wmOperator *op)
 {
diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h
index 8c44d5a..c56465f 100644
--- a/source/blender/editors/mesh/mesh_intern.h
+++ b/source/blender/editors/mesh/mesh_intern.h
@@ -176,6 +176,7 @@ void MESH_OT_vert_connect_nonplanar(struct wmOperatorType *ot);
 void MESH_OT_face_make_planar(struct wmOperatorType *ot);
 void MESH_OT_edge_split(struct wmOperatorType *ot);
 void MESH_OT_bridge_edge_loops(struct wmOperatorType *ot);
+void MESH_OT_offset_edge_loops(struct wmOperatorType *ot);
 void MESH_OT_wireframe(struct wmOperatorType *ot);
 void MESH_OT_convex_hull(struct wmOperatorType *ot);
 void MESH_OT_symmetrize(struct wmOperatorType *ot);
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index 20f222b..9718e63 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -177,6 +177,7 @@ void ED_operatortypes_mesh(void)
 
 	WM_operatortype_append(MESH_OT_bridge_edge_loops);
 	WM_operatortype_append(MESH_OT_inset);
+	WM_operatortype_append(MESH_OT_offset_edge_loops);
 	WM_operatortype_append(MESH_OT_intersect);
 	WM_operatortype_append(MESH_OT_face_split_by_edges);
 	WM_operatortype_append(MESH_OT_poke);
@@ -225,6 +226,13 @@ void ED_operatormacros_mesh(void)
 	otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_edge_slide");
 	RNA_boolean_set(otmacro->ptr, "release_confirm", false);
 
+	ot = WM_operatortype_append_macro("MESH_OT_offset_edge_loops_slide", "Offset Edge Slide", "Offset edge loop slide",
+	                                  OPTYPE_UNDO | OPTYPE_REGISTER);
+	WM_operatortype_macro_define(ot, "MESH_OT_offset_edge_loops");
+	otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_edge_slide");
+	RNA_boolean_set(otmacro->ptr, "release_confirm", false);
+	RNA_boolean_set(otmacro->ptr, "single_side", true);
+
 	ot = WM_operatortype_append_macro("MESH_OT_duplicate_move", "Add Duplicate", "Duplicate mesh and move",
 	                                  OPTYPE_UNDO | OPTYPE_REGISTER);
 	WM_operatortype_macro_define(ot, "MESH_OT_duplicate");
@@ -302,7 +310,8 @@ void ED_keymap_mesh(wmKeyConfig *keyconf)
 	keymap = WM_keymap_find(keyconf, "Mesh", 0, 0);
 	keymap->poll = ED_operator_editmesh;
 	
-	WM_keymap_add_item(keymap, "MESH_OT_loopcut_slide", RKEY, KM_PRESS, KM_CTRL, 0);	
+	WM_keymap_add_item(keymap, "MESH_OT_loopcut_slide", RKEY, KM_PRESS, KM_CTRL, 0);
+	WM_keymap_add_item(keymap, "MESH_OT_offset_edge_loops_slide", RKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
 	WM_keymap_add_item(keymap, "MESH_OT_inset", IKEY, KM_PRESS, 0, 0);
 	WM_keymap_add_item(keymap, "MESH_OT_poke", PKEY, KM_PRESS, KM_ALT, 0);
 	kmi = WM_keymap_add_item(keymap, "MESH_OT_bevel", BKEY, KM_PRESS, KM_CTRL, 0);
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index f2c44e6..a2bfef8 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -167,6 +167,7 @@ static void applyBoneEnvelope(TransInfo *t, const int mval[2]);
 static void initBoneRoll(TransInfo *t);
 static void applyBoneRoll(TransInfo *t, const int mval[2]);
 
+static void initEdgeSlide_ex(TransInfo *t, bool use_double_side);
 static void initEdgeSlide(TransInfo *t);
 static eRedrawFlag handleEventEdgeSlide(TransInfo *t, const struct wmEvent *event);
 static void applyEdgeSlide(TransInfo *t, const int mval[2]);
@@ -2229,8 +2230,11 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
 			initBoneEnvelope(t);
 			break;
 		case TFM_EDGE_SLIDE:
-			initEdgeSlide(t);
+		{
+			const bool use_double_side = (op ? !RNA_boolean_get(op->ptr, "single_side") : true);
+			initEdgeSlide_ex(t, use_double_side);
 			break;
+		}
 		case TFM_VERT_SLIDE:
 			initVertSlide(t);
 			break;
@@ -5684,8 +5688,11 @@ static void calcEdgeSlide_mval_range(
 	float projectMat[4][4];
 	BMBVHTree *btree;
 
+	/* only for use_calc_direction */
+	float (*loop_dir)[3] = NULL, *loop_maxdist = NULL;
+
 	float mval_start[2], mval_end[2];
-	float mval_dir[3], dist_best_sq, (*loop_dir)[3], *loop_maxdist;
+	float mval_dir[3], dist_best_sq;
 	BMIter iter;
 	BMEdge *e;
 
@@ -5715,9 +5722,11 @@ static void calcEdgeSlide_mval_range(
 	zero_v3(mval_dir);
 	dist_best_sq = -1.0f;
 
-	loop_dir = MEM_callocN(sizeof(float[3]) * loop_nr, "sv loop_dir");
-	loop_maxdist = MEM_mallocN(sizeof(float) * loop_nr, "sv loop_maxdist");
-	copy_vn_fl(loop_maxdist, loop_nr, -1.0f);
+	if (use_calc_direction) {
+		loop_dir = MEM_callocN(sizeof(float[3]) * loop_nr, "sv loop_dir");
+		loop_maxdist = MEM_mallocN(sizeof(float) * loop_nr, "sv loop_maxdist");
+		copy_vn_fl(loop_maxdist, loop_nr, -1.0f);
+	}
 
 	BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
 		if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
@@ -5773,11 +5782,13 @@ static void calcEdgeSlide_mval_range(
 						sub_v3_v3v3(mval_dir, sco_b, sco_a);
 					}
 
-					/* per loop direction */
-					l_nr = sv_array[j].loop_nr;
-					if (loop_maxdist[l_nr] == -1.0f || dist_sq < loop_maxdist[l_nr]) {
-						loop_maxdist[l_nr] = dist_sq;
-						sub_v3_v3v3(loop_dir[l_nr], sco_b, sco_a);
+					if (use_calc_direction) {
+						/* per loop direction */
+						l_nr = sv_array[j].loop_nr;
+						if (loop_maxdist[l_nr] == -1.0f || dist_sq < loop_maxdist[l_nr]) {
+							loop_maxdist[l_nr] = dist_sq;
+							

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list