[Bf-blender-cvs] [481dc773892] soc-2017-normal-tools: Heavy refactor of 'Point To' editing normals tools.

Bastien Montagne noreply at git.blender.org
Mon Mar 5 22:13:00 CET 2018


Commit: 481dc7738925b30a2a6676ca32ea382be0919a26
Author: Bastien Montagne
Date:   Mon Mar 5 22:01:57 2018 +0100
Branches: soc-2017-normal-tools
https://developer.blender.org/rB481dc7738925b30a2a6676ca32ea382be0919a26

Heavy refactor of 'Point To' editing normals tools.

Core code remains the same, but UI/UX was quiet deeply changed:
* Some fixes in core code (like missing normalization of new normal in
spherize case), as well as some optimizations (reducing amount of vector
operations per affected normals) and cleanup/simplifications.
* Moving modal part of the op closer to moder 'state of the art' Blender
code, mainly:
** Use a modal keymap instead of hard-coded shortcuts.
** Use of proper header message generator extracting shortcuts from
modal keymap.
** Get rid of odd 'callback' function stuff for 'point to mouse', this
can be handled much more simply directly in main modal function.
** Adding some more keymap shortcuts (to temporarily reset normals, to
toggle invert, aligned and spherize options...).
** Do not immediately finish when selecting 'point to pivot/object/etc.',
keep consistent behavior requiring an explicit validation. This also
makes it possible to cancel after seeing effects of changes, or to try
another option, go back and forth between original and changed versions,
etc.
* Fixed memleak in case one would close Blender while modal op was
running (we need to define cancel operator callback for that case).

Note that we could (should?) go further still, adding ways to edit
spherize strength, even with some numinput. We could also add an option
to handle target value as global (current case) or local coordinates.
And so on. For now that will do though.

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

M	release/scripts/modules/bpy_extras/keyconfig_utils.py
M	source/blender/bmesh/bmesh_class.h
M	source/blender/bmesh/intern/bmesh_mesh.c
M	source/blender/editors/mesh/editmesh_tools.c
M	source/blender/editors/mesh/mesh_intern.h
M	source/blender/editors/mesh/mesh_ops.c

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

diff --git a/release/scripts/modules/bpy_extras/keyconfig_utils.py b/release/scripts/modules/bpy_extras/keyconfig_utils.py
index 9d206afb2c5..23ef0f30f86 100644
--- a/release/scripts/modules/bpy_extras/keyconfig_utils.py
+++ b/release/scripts/modules/bpy_extras/keyconfig_utils.py
@@ -56,6 +56,7 @@ KM_HIERARCHY = [
         ('Particle', 'EMPTY', 'WINDOW', []),
 
         ('Knife Tool Modal Map', 'EMPTY', 'WINDOW', []),
+        ('Custom Normals Modal Map', 'EMPTY', 'WINDOW', []),
         ('Paint Stroke Modal', 'EMPTY', 'WINDOW', []),
         ('Paint Curve', 'EMPTY', 'WINDOW', []),
 
diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h
index faba8e2b954..155e51acbf5 100644
--- a/source/blender/bmesh/bmesh_class.h
+++ b/source/blender/bmesh/bmesh_class.h
@@ -286,7 +286,6 @@ typedef struct BMLoopNorEditDataArray {
 
 	int cd_custom_normal_offset;
 	int totloop;
-	void *funcdata;
 } BMLoopNorEditDataArray;
 
 #define BM_ALL (BM_VERT | BM_EDGE | BM_LOOP | BM_FACE)
diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c
index 99582089bde..36033aa8fe9 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.c
+++ b/source/blender/bmesh/intern/bmesh_mesh.c
@@ -1348,12 +1348,7 @@ static void loop_normal_editdata_init(BMesh *bm, BMLoopNorEditData *lnor_ed, BMV
 	copy_v3_v3(lnor_ed->nloc, custom_normal);
 	copy_v3_v3(lnor_ed->niloc, custom_normal);
 
-	if (v) {
-		lnor_ed->loc = v->co;
-	}
-	else {
-		lnor_ed->loc = NULL;
-	}
+	lnor_ed->loc = v->co;
 }
 
 BMLoopNorEditDataArray *BM_loop_normal_editdata_array_init(BMesh *bm)
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 79adba36302..d2e805c5a1b 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -5994,6 +5994,102 @@ void MESH_OT_mark_freestyle_face(wmOperatorType *ot)
 
 #endif
 
+/********************** Loop normals editing tools modal map. **********************/
+
+/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */
+/* NOTE: We could add more here, like e.g. a switch between local or global coordinates of target,
+ *       use numinput to type in explicit vector values... */
+enum {
+	/* Generic commands. */
+	EDBM_CLNOR_MODAL_CANCEL                   = 1,
+	EDBM_CLNOR_MODAL_CONFIRM                  = 2,
+
+	/* Point To operator. */
+	EDBM_CLNOR_MODAL_POINTTO_RESET            = 101,
+	EDBM_CLNOR_MODAL_POINTTO_INVERT           = 102,
+	EDBM_CLNOR_MODAL_POINTTO_SPHERIZE         = 103,
+	EDBM_CLNOR_MODAL_POINTTO_ALIGN            = 104,
+
+	EDBM_CLNOR_MODAL_POINTTO_USE_MOUSE        = 110,
+	EDBM_CLNOR_MODAL_POINTTO_USE_PIVOT        = 111,
+	EDBM_CLNOR_MODAL_POINTTO_USE_OBJECT       = 112,
+	EDBM_CLNOR_MODAL_POINTTO_SET_USE_3DCURSOR = 113,
+	EDBM_CLNOR_MODAL_POINTTO_SET_USE_SELECTED = 114,
+};
+
+/* called in transform_ops.c, on each regeneration of keymaps */
+wmKeyMap *point_normals_modal_keymap(wmKeyConfig *keyconf)
+{
+	static const EnumPropertyItem modal_items[] = {
+		{EDBM_CLNOR_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""},
+		{EDBM_CLNOR_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
+
+		/* Point To operator. */
+		{EDBM_CLNOR_MODAL_POINTTO_RESET, "RESET", 0, "Reset", "Reset normals to initial ones"},
+		{EDBM_CLNOR_MODAL_POINTTO_INVERT, "INVERT", 0, "Invert", "Toggle inversion of affected normals"},
+		{EDBM_CLNOR_MODAL_POINTTO_SPHERIZE, "SPHERIZE", 0, "Spherize", "Interpolate between new and original normals"},
+		{EDBM_CLNOR_MODAL_POINTTO_ALIGN, "ALIGN", 0, "Align", "Make all affected normals parallel"},
+
+		{EDBM_CLNOR_MODAL_POINTTO_USE_MOUSE, "USE_MOUSE", 0, "Use Mouse", "Follow mouse cursor position"},
+		{EDBM_CLNOR_MODAL_POINTTO_USE_PIVOT, "USE_PIVOT", 0, "Use Pivot",
+		 "Use current rotation/scaling pivot point coordinates"},
+		{EDBM_CLNOR_MODAL_POINTTO_USE_OBJECT, "USE_OBJECT", 0, "Use Object", "Use current edited object's location"},
+		{EDBM_CLNOR_MODAL_POINTTO_SET_USE_3DCURSOR, "SET_USE_3DCURSOR", 0, "Set and Use 3D Cursor",
+		 "Set new 3D cursor position and use it"},
+		{EDBM_CLNOR_MODAL_POINTTO_SET_USE_SELECTED, "SET_USE_SELECTED", 0, "Select and Use Mesh Item",
+		 "Select new active mesh element and use its location"},
+		{0, NULL, 0, NULL, NULL}
+	};
+	static const char *keymap_name = "Custom Normals Modal Map";
+
+	wmKeyMap *keymap = WM_modalkeymap_get(keyconf, keymap_name);
+
+	/* We only need to add map once */
+	if (keymap && keymap->modal_items)
+		return NULL;
+
+	keymap = WM_modalkeymap_add(keyconf, keymap_name, modal_items);
+
+	/* Generic items for modal map. */
+	WM_modalkeymap_add_item(keymap, ESCKEY,     KM_PRESS, KM_ANY,     0, EDBM_CLNOR_MODAL_CANCEL);
+	WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_PRESS, KM_NOTHING, 0, EDBM_CLNOR_MODAL_CANCEL);
+
+	WM_modalkeymap_add_item(keymap, RETKEY,     KM_PRESS, KM_ANY,     0, EDBM_CLNOR_MODAL_CONFIRM);
+	WM_modalkeymap_add_item(keymap, PADENTER,   KM_PRESS, KM_ANY,     0, EDBM_CLNOR_MODAL_CONFIRM);
+	WM_modalkeymap_add_item(keymap, LEFTMOUSE,  KM_PRESS, KM_NOTHING, 0, EDBM_CLNOR_MODAL_CONFIRM);
+
+	/* Point To items for modal map */
+	WM_modalkeymap_add_item(keymap, RKEY,       KM_PRESS, KM_NOTHING, 0, EDBM_CLNOR_MODAL_POINTTO_RESET);
+	WM_modalkeymap_add_item(keymap, IKEY,       KM_PRESS, KM_NOTHING, 0, EDBM_CLNOR_MODAL_POINTTO_INVERT);
+	WM_modalkeymap_add_item(keymap, SKEY,       KM_PRESS, KM_NOTHING, 0, EDBM_CLNOR_MODAL_POINTTO_SPHERIZE);
+	WM_modalkeymap_add_item(keymap, AKEY,       KM_PRESS, KM_NOTHING, 0, EDBM_CLNOR_MODAL_POINTTO_ALIGN);
+
+	WM_modalkeymap_add_item(keymap, MKEY,       KM_PRESS, KM_NOTHING, 0, EDBM_CLNOR_MODAL_POINTTO_USE_MOUSE);
+	WM_modalkeymap_add_item(keymap, LKEY,       KM_PRESS, KM_NOTHING, 0, EDBM_CLNOR_MODAL_POINTTO_USE_PIVOT);
+	WM_modalkeymap_add_item(keymap, OKEY,       KM_PRESS, KM_NOTHING, 0, EDBM_CLNOR_MODAL_POINTTO_USE_OBJECT);
+
+	WM_modalkeymap_add_item(keymap, LEFTMOUSE,  KM_CLICK, KM_CTRL,    0, EDBM_CLNOR_MODAL_POINTTO_SET_USE_3DCURSOR);
+	WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_CLICK, KM_CTRL,    0, EDBM_CLNOR_MODAL_POINTTO_SET_USE_SELECTED);
+
+	WM_modalkeymap_assign(keymap, "MESH_OT_point_normals");
+
+	return keymap;
+}
+
+/********************** 'Point to' Loop Normals **********************/
+
+enum {
+	EDBM_CLNOR_POINTTO_MODE_COORDINATES = 1,
+	EDBM_CLNOR_POINTTO_MODE_MOUSE = 2,
+};
+
+static EnumPropertyItem clnors_pointto_mode_items[] = {
+	{EDBM_CLNOR_POINTTO_MODE_COORDINATES, "COORDINATES", 0, "Coordinates",
+	                                      "Use static coordinates (defined by various means)"},
+	{EDBM_CLNOR_POINTTO_MODE_MOUSE, "MOUSE", 0, "Mouse", "Follow mouse cursor"},
+	{0, NULL, 0, NULL, NULL}
+};
+
 /* Initialize loop normal data */
 static int point_normals_init(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
 {
@@ -6004,263 +6100,298 @@ static int point_normals_init(bContext *C, wmOperator *op, const wmEvent *UNUSED
 	BKE_editmesh_lnorspace_update(em);
 	BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm);
 
-	lnors_ed_arr->funcdata = NULL;
 	op->customdata = lnors_ed_arr;
 
 	return lnors_ed_arr->totloop;
 }
 
-static void point_normals_apply(bContext *C, wmOperator *op, const wmEvent *UNUSED(event), float target[3])
+static void point_normals_free(bContext *C, wmOperator *op)
+{
+	BMLoopNorEditDataArray *lnors_ed_arr = op->customdata;
+	BM_loop_normal_editdata_array_free(lnors_ed_arr);
+	op->customdata = NULL;
+	ED_area_headerprint(CTX_wm_area(C), NULL);
+}
+
+static void point_normals_update_header(bContext *C, wmOperator *op)
+{
+	char header[UI_MAX_DRAW_STR];
+	char buf[UI_MAX_DRAW_STR];
+
+	char *p = buf;
+	int available_len = sizeof(buf);
+
+#define WM_MODALKEY(_id) \
+	WM_modalkeymap_operator_items_to_string_buf(op->type, (_id), true, UI_MAX_SHORTCUT_STR, &available_len, &p)
+
+	BLI_snprintf(header, sizeof(header), IFACE_("%s: confirm, %s: cancel, "
+	                                            "%s: point to mouse (%s), %s: point to Pivot, "
+	                                            "%s: point to object origin, %s: reset normals, "
+	                                            "%s: set & point to 3D cursor, %s: select & point to mesh item, "
+	                                            "%s: invert normals (%s), %s: spherize (%s), %s: align (%s)"),
+	             WM_MODALKEY(EDBM_CLNOR_MODAL_CONFIRM), WM_MODALKEY(EDBM_CLNOR_MODAL_CANCEL),
+	             WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_USE_MOUSE),
+	             WM_bool_as_string(RNA_enum_get(op->ptr, "mode") == EDBM_CLNOR_POINTTO_MODE_MOUSE),
+	             WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_USE_PIVOT), WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_USE_OBJECT),
+	             WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_RESET), WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_SET_USE_3DCURSOR),
+	             WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_SET_USE_SELECTED),
+	             WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_INVERT), WM_bool_as_string(RNA_boolean_get(op->ptr, "invert")),
+	             WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_SPHERIZE), WM_bool_as_string(RNA_boolean_get(op->ptr, "spherize")),
+	             WM_MODALKEY(EDBM_CLNOR_MODAL_POINTTO_ALIGN), WM_bool_as_string(RNA_boolean_get(op->ptr, "align")));
+
+#undef WM_MODALKEY
+
+	ED_area_headerprint(CTX_wm_area(C), header);
+}
+
+/* TODO move that to generic function in BMesh? */
+static void bmesh_selected_verts_center_calc(BMesh *bm, float *r_center)
+{
+	BMVert *v;
+	BMIter viter;
+	int i = 0;
+
+	zero_v3(r_center);
+	BM_ITER_MESH(v, &viter, bm, BM_VERTS_OF_MESH) {
+		if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
+			add_v3_v3(r_center, v->co);
+			i++;
+		}
+	}
+	mul_v3_fl(r_center, 1.0f / (float)i);
+}
+
+static void point_normals_apply(bContext *C, wmOperator *op, float target[3], const bool do_reset)
 {
 	Object *obedit = CTX_data_edit_object(C);
 	BMesh *bm = BKE_editmesh_from_object(obedit)->bm;
 	BMLoopNorEditDataArray *lnors_ed_arr = op->customdata;
 
-	const bool do_point_away = RNA_boolean_get(op->ptr, "point_away");
+	const bool do_invert = RNA_boolean_get(op->ptr, "invert");
 	const bool do_spherize = RNA_boolean_get(op->ptr, "spherize");
 	const bool do_align = RNA_boolean_

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list