[Bf-blender-cvs] [ec2ca11c] master: BMesh Path Select: Add checker-select options

Campbell Barton noreply at git.blender.org
Sun Dec 27 09:56:41 CET 2015


Commit: ec2ca11cba496294838bfb5fb76f7bfcef2fe8cc
Author: Campbell Barton
Date:   Sun Dec 27 18:05:53 2015 +1100
Branches: master
https://developer.blender.org/rBec2ca11cba496294838bfb5fb76f7bfcef2fe8cc

BMesh Path Select: Add checker-select options

Allows to quickly select alternate elems in a path (matching checker-deselect options).

- adds redo support to MESH_OT_shortest_path_pick, allowing for other options.
- de-duplicates code between 2x path select operators.
- expose 'Topology Distance' property for path picking.
- remove unused 'extend' property.

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

M	source/blender/editors/mesh/editmesh_path.c

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

diff --git a/source/blender/editors/mesh/editmesh_path.c b/source/blender/editors/mesh/editmesh_path.c
index 72dfb89..5a57d17 100644
--- a/source/blender/editors/mesh/editmesh_path.c
+++ b/source/blender/editors/mesh/editmesh_path.c
@@ -53,6 +53,7 @@
 #include "RNA_access.h"
 #include "RNA_define.h"
 
+#include "WM_api.h"
 #include "WM_types.h"
 
 #include "bmesh.h"
@@ -60,10 +61,33 @@
 
 #include "mesh_intern.h"  /* own include */
 
+struct PathSelectParams {
+	bool track_active;  /* ensure the active element is the last selected item (handy for picking) */
+	bool topology_distance;
+	char edge_mode;
+	struct CheckerIntervalParams interval_params;
+};
+
+static void path_select_properties(wmOperatorType *ot)
+{
+	RNA_def_boolean(
+	        ot->srna, "topology_distance", false, "Topology Distance",
+	        "Find the minimum number of steps, ignoring spatial distance");
+	WM_operator_properties_checker_interval(ot, true);
+}
+
+static void path_select_params_from_op(wmOperator *op, struct PathSelectParams *op_params)
+{
+	op_params->edge_mode = EDGE_MODE_SELECT;
+	op_params->track_active = false;
+	op_params->topology_distance = RNA_boolean_get(op->ptr, "topology_distance");
+	WM_operator_properties_checker_interval_from_op(op, &op_params->interval_params);
+}
+
 struct UserData {
 	BMesh *bm;
 	Mesh  *me;
-	Scene *scene;
+	const struct PathSelectParams *op_params;
 };
 
 /* -------------------------------------------------------------------- */
@@ -84,70 +108,72 @@ static void verttag_set_cb(BMVert *v, bool val, void *user_data_v)
 	BM_vert_select_set(user_data->bm, v, val);
 }
 
-static bool mouse_mesh_shortest_path_vert(ViewContext *vc)
+static void mouse_mesh_shortest_path_vert(
+        Scene *scene, const struct PathSelectParams *op_params,
+        BMVert *v_act, BMVert *v_dst)
 {
-	/* unlike edge/face versions, this uses a bmesh operator */
-
-	BMEditMesh *em = vc->em;
+	Object *obedit = scene->obedit;
+	BMEditMesh *em = BKE_editmesh_from_object(obedit);
 	BMesh *bm = em->bm;
-	BMVert *v_dst;
-	float dist = ED_view3d_select_dist_px();
-	const bool use_length = true;
 
-	v_dst = EDBM_vert_find_nearest(vc, &dist);
-	if (v_dst) {
-		struct UserData user_data = {bm, vc->obedit->data, vc->scene};
-		LinkNode *path = NULL;
-		BMVert *v_act = BM_mesh_active_vert_get(bm);
+	struct UserData user_data = {bm, obedit->data, op_params};
+	LinkNode *path = NULL;
 
-		if (v_act && (v_act != v_dst)) {
-			if ((path = BM_mesh_calc_path_vert(bm, v_act, v_dst, use_length,
-			                                   verttag_filter_cb, &user_data)))
-			{
+	if (v_act && (v_act != v_dst)) {
+		if ((path = BM_mesh_calc_path_vert(
+		         bm, v_act, v_dst, !op_params->topology_distance,
+		         verttag_filter_cb, &user_data)))
+		{
+			if (op_params->track_active) {
 				BM_select_history_remove(bm, v_act);
 			}
 		}
+	}
 
-		if (path) {
-			/* toggle the flag */
-			bool all_set = true;
-			LinkNode *node;
+	BMVert *v_dst_last = v_dst;
 
-			node = path;
-			do {
-				if (!verttag_test_cb((BMVert *)node->link, &user_data)) {
-					all_set = false;
-					break;
-				}
-			} while ((node = node->next));
+	if (path) {
+		/* toggle the flag */
+		bool all_set = true;
+		LinkNode *node;
+
+		node = path;
+		do {
+			if (!verttag_test_cb((BMVert *)node->link, &user_data)) {
+				all_set = false;
+				break;
+			}
+		} while ((node = node->next));
 
-			node = path;
-			do {
+		int depth = 1;
+		node = path;
+		do {
+			if (WM_operator_properties_checker_interval_test(&op_params->interval_params, depth)) {
 				verttag_set_cb((BMVert *)node->link, !all_set, &user_data);
-			} while ((node = node->next));
+				v_dst_last = node->link;
+			}
+		} while (depth++, (node = node->next));
 
-			BLI_linklist_free(path, NULL);
-		}
-		else {
-			const bool is_act = !verttag_test_cb(v_dst, &user_data);
-			verttag_set_cb(v_dst, is_act, &user_data); /* switch the face option */
-		}
+		BLI_linklist_free(path, NULL);
+	}
+	else {
+		const bool is_act = !verttag_test_cb(v_dst, &user_data);
+		verttag_set_cb(v_dst, is_act, &user_data); /* switch the face option */
+	}
 
-		EDBM_selectmode_flush(em);
+	EDBM_selectmode_flush(em);
 
+	if (op_params->track_active) {
 		/* even if this is selected it may not be in the selection list */
-		if (BM_elem_flag_test(v_dst, BM_ELEM_SELECT) == 0)
-			BM_select_history_remove(bm, v_dst);
-		else
-			BM_select_history_store(bm, v_dst);
-
-		EDBM_update_generic(em, false, false);
-
-		return true;
-	}
-	else {
-		return false;
+		if (BM_elem_flag_test(v_dst_last, BM_ELEM_SELECT) == 0) {
+			BM_select_history_remove(bm, v_dst_last);
+		}
+		else {
+			BM_select_history_store(bm, v_dst_last);
+		}
 	}
+
+	EDBM_update_generic(em, false, false);
 }
 
 
@@ -163,10 +189,10 @@ static bool edgetag_filter_cb(BMEdge *e, void *UNUSED(user_data_v))
 static bool edgetag_test_cb(BMEdge *e, void *user_data_v)
 {
 	struct UserData *user_data = user_data_v;
-	Scene *scene = user_data->scene;
+	const char edge_mode = user_data->op_params->edge_mode;
 	BMesh *bm = user_data->bm;
 
-	switch (scene->toolsettings->edge_mode) {
+	switch (edge_mode) {
 		case EDGE_MODE_SELECT:
 			return BM_elem_flag_test(e, BM_ELEM_SELECT) ? true : false;
 		case EDGE_MODE_TAG_SEAM:
@@ -190,10 +216,10 @@ static bool edgetag_test_cb(BMEdge *e, void *user_data_v)
 static void edgetag_set_cb(BMEdge *e, bool val, void *user_data_v)
 {
 	struct UserData *user_data = user_data_v;
-	Scene *scene = user_data->scene;
+	const char edge_mode = user_data->op_params->edge_mode;
 	BMesh *bm = user_data->bm;
 
-	switch (scene->toolsettings->edge_mode) {
+	switch (edge_mode) {
 		case EDGE_MODE_SELECT:
 			BM_edge_select_set(bm, e, val);
 			break;
@@ -250,106 +276,109 @@ static void edgetag_ensure_cd_flag(Scene *scene, Mesh *me)
 /* mesh shortest path select, uses prev-selected edge */
 
 /* since you want to create paths with multiple selects, it doesn't have extend option */
-static bool mouse_mesh_shortest_path_edge(ViewContext *vc)
+static void mouse_mesh_shortest_path_edge(
+        Scene *scene, const struct PathSelectParams *op_params,
+        BMEdge *e_act, BMEdge *e_dst)
 {
-	BMEditMesh *em = vc->em;
+	Object *obedit = scene->obedit;
+	BMEditMesh *em = BKE_editmesh_from_object(obedit);
 	BMesh *bm = em->bm;
-	BMEdge *e_dst;
-	float dist = ED_view3d_select_dist_px();
-	const bool use_length = true;
 
-	e_dst = EDBM_edge_find_nearest(vc, &dist);
-	if (e_dst) {
-		const char edge_mode = vc->scene->toolsettings->edge_mode;
-		struct UserData user_data = {bm, vc->obedit->data, vc->scene};
-		LinkNode *path = NULL;
-		Mesh *me = vc->obedit->data;
-		BMEdge *e_act = BM_mesh_active_edge_get(bm);
+	struct UserData user_data = {bm, obedit->data, op_params};
+	LinkNode *path = NULL;
+	Mesh *me = obedit->data;
 
-		edgetag_ensure_cd_flag(vc->scene, em->ob->data);
+	edgetag_ensure_cd_flag(scene, obedit->data);
 
-		if (e_act && (e_act != e_dst)) {
-			if ((path = BM_mesh_calc_path_edge(bm, e_act, e_dst, use_length,
-			                                   edgetag_filter_cb, &user_data)))
-			{
+	if (e_act && (e_act != e_dst)) {
+		if ((path = BM_mesh_calc_path_edge(
+		         bm, e_act, e_dst, !op_params->topology_distance,
+		         edgetag_filter_cb, &user_data)))
+		{
+			if (op_params->track_active) {
 				BM_select_history_remove(bm, e_act);
 			}
 		}
+	}
 
-		if (path) {
-			/* toggle the flag */
-			bool all_set = true;
-			LinkNode *node;
+	BMEdge *e_dst_last = e_dst;
 
-			node = path;
-			do {
-				if (!edgetag_test_cb((BMEdge *)node->link, &user_data)) {
-					all_set = false;
-					break;
-				}
-			} while ((node = node->next));
+	if (path) {
+		/* toggle the flag */
+		bool all_set = true;
+		LinkNode *node;
 
-			node = path;
-			do {
+		node = path;
+		do {
+			if (!edgetag_test_cb((BMEdge *)node->link, &user_data)) {
+				all_set = false;
+				break;
+			}
+		} while ((node = node->next));
+
+		int depth = 1;
+		node = path;
+		do {
+			if (WM_operator_properties_checker_interval_test(&op_params->interval_params, depth)) {
 				edgetag_set_cb((BMEdge *)node->link, !all_set, &user_data);
-			} while ((node = node->next));
+				e_dst_last = node->link;
+			}
+		} while (depth++, (node = node->next));
 
-			BLI_linklist_free(path, NULL);
-		}
-		else {
-			const bool is_act = !edgetag_test_cb(e_dst, &user_data);
-			edgetag_ensure_cd_flag(vc->scene, vc->obedit->data);
-			edgetag_set_cb(e_dst, is_act, &user_data); /* switch the edge option */
-		}
+		BLI_linklist_free(path, NULL);
+	}
+	else {
+		const bool is_act = !edgetag_test_cb(e_dst, &user_data);
+		edgetag_ensure_cd_flag(scene, obedit->data);
+		edgetag_set_cb(e_dst, is_act, &user_data); /* switch the edge option */
+	}
 
-		if (edge_mode != EDGE_MODE_SELECT) {
+	if (op_params->edge_mode != EDGE_MODE_SELECT) {
+		if (op_params->track_active) {
 			/* simple rules - last edge is _always_ active and selected */
 			if (e_act)
 				BM_edge_select_set(bm, e_act, false);
-			BM_edge_select_set(bm, e_dst, true);
-			BM_select_history_store(bm, e_dst);
+			BM_edge_select_set(bm, e_dst_last, true);
+			BM_select_history_store(bm, e_dst_last);
 		}
+	}
 
-		EDBM_selectmode_flush(em);
+	EDBM_selectmode_flush(em);
 
+	if (op_params->track_active) {
 		/* even if this is selected it may not be in the selection list */
-		if (edge_mode == EDGE_MODE_SELECT) {
-			if (edgetag_test_cb(e_dst, &user_data) == 0)
-				BM_select_history_remove(bm, e_dst);
+		if (op_params->edge_mode == EDGE_MODE_SELECT) {
+			if (edgetag_test_cb(e_dst_last, &user_data) == 0)
+				BM_select_history_remove(bm, e_dst_last);
 			else
-				BM_select_history_store(bm, e_dst);
+				BM_select_history_store(bm, e_dst_last);
 		}
+	}
 
-		/* force drawmode for mesh */
-		switch (edge_mode) {
+	/* force drawmode for mesh */
+	switch (op_params->edge_mode) {
 
-			case EDGE_MODE_TAG_SEAM:
-				me->drawflag |= ME_DRAWSEAMS;
-				ED_uvedit_live_unwrap(vc->scene, vc->obedit);
-				break;
-			case EDGE_MODE_TAG_SHARP:
-				me->drawflag |= ME_DRAWSHARP;
-				break;
-			case EDGE_MODE_TAG_CREASE:
-				me->drawflag |= ME_DRAWCREASES;
-				break;
-			case EDGE_MODE_TAG_BEVEL:
-				me->drawflag |= ME_DRAWBWEIGHTS;
-				break;
+		case EDGE_MODE_TAG_SEAM:
+			me->drawflag |= ME_DRAWS

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list