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>2019-04-17 07:17:24 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-04-17 07:21:24 +0300
commite12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch)
tree8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/editors/mesh/editmesh_path.c
parentb3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff)
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/editors/mesh/editmesh_path.c')
-rw-r--r--source/blender/editors/mesh/editmesh_path.c1282
1 files changed, 648 insertions, 634 deletions
diff --git a/source/blender/editors/mesh/editmesh_path.c b/source/blender/editors/mesh/editmesh_path.c
index d16cd639c0d..c6b1ab9f1f2 100644
--- a/source/blender/editors/mesh/editmesh_path.c
+++ b/source/blender/editors/mesh/editmesh_path.c
@@ -57,50 +57,56 @@
#include "DEG_depsgraph.h"
-#include "mesh_intern.h" /* own include */
+#include "mesh_intern.h" /* own include */
/* -------------------------------------------------------------------- */
/** \name Path Select Struct & Properties
* \{ */
struct PathSelectParams {
- /** ensure the active element is the last selected item (handy for picking) */
- bool track_active;
- bool use_topology_distance;
- bool use_face_step;
- bool use_fill;
- char edge_mode;
- struct CheckerIntervalParams interval_params;
+ /** ensure the active element is the last selected item (handy for picking) */
+ bool track_active;
+ bool use_topology_distance;
+ bool use_face_step;
+ bool use_fill;
+ char edge_mode;
+ struct CheckerIntervalParams interval_params;
};
static void path_select_properties(wmOperatorType *ot)
{
- RNA_def_boolean(
- ot->srna, "use_face_step", false, "Face Stepping",
- "Traverse connected faces (includes diagonals and edge-rings)");
- RNA_def_boolean(
- ot->srna, "use_topology_distance", false, "Topology Distance",
- "Find the minimum number of steps, ignoring spatial distance");
- RNA_def_boolean(
- ot->srna, "use_fill", false, "Fill Region",
- "Select all paths between the source/destination elements");
- WM_operator_properties_checker_interval(ot, true);
+ RNA_def_boolean(ot->srna,
+ "use_face_step",
+ false,
+ "Face Stepping",
+ "Traverse connected faces (includes diagonals and edge-rings)");
+ RNA_def_boolean(ot->srna,
+ "use_topology_distance",
+ false,
+ "Topology Distance",
+ "Find the minimum number of steps, ignoring spatial distance");
+ RNA_def_boolean(ot->srna,
+ "use_fill",
+ false,
+ "Fill Region",
+ "Select all paths between the source/destination elements");
+ 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->use_face_step = RNA_boolean_get(op->ptr, "use_face_step");
- op_params->use_fill = RNA_boolean_get(op->ptr, "use_fill");
- op_params->use_topology_distance = RNA_boolean_get(op->ptr, "use_topology_distance");
- WM_operator_properties_checker_interval_from_op(op, &op_params->interval_params);
+ op_params->edge_mode = EDGE_MODE_SELECT;
+ op_params->track_active = false;
+ op_params->use_face_step = RNA_boolean_get(op->ptr, "use_face_step");
+ op_params->use_fill = RNA_boolean_get(op->ptr, "use_fill");
+ op_params->use_topology_distance = RNA_boolean_get(op->ptr, "use_topology_distance");
+ WM_operator_properties_checker_interval_from_op(op, &op_params->interval_params);
}
struct UserData {
- BMesh *bm;
- Mesh *me;
- const struct PathSelectParams *op_params;
+ BMesh *bm;
+ Mesh *me;
+ const struct PathSelectParams *op_params;
};
/** \} */
@@ -112,102 +118,104 @@ struct UserData {
/* callbacks */
static bool verttag_filter_cb(BMVert *v, void *UNUSED(user_data_v))
{
- return !BM_elem_flag_test(v, BM_ELEM_HIDDEN);
+ return !BM_elem_flag_test(v, BM_ELEM_HIDDEN);
}
static bool verttag_test_cb(BMVert *v, void *UNUSED(user_data_v))
{
- return BM_elem_flag_test_bool(v, BM_ELEM_SELECT);
+ return BM_elem_flag_test_bool(v, BM_ELEM_SELECT);
}
static void verttag_set_cb(BMVert *v, bool val, void *user_data_v)
{
- struct UserData *user_data = user_data_v;
- BM_vert_select_set(user_data->bm, v, val);
+ struct UserData *user_data = user_data_v;
+ BM_vert_select_set(user_data->bm, v, val);
}
-static void mouse_mesh_shortest_path_vert(
- Scene *UNUSED(scene), Object *obedit, const struct PathSelectParams *op_params,
- BMVert *v_act, BMVert *v_dst)
+static void mouse_mesh_shortest_path_vert(Scene *UNUSED(scene),
+ Object *obedit,
+ const struct PathSelectParams *op_params,
+ BMVert *v_act,
+ BMVert *v_dst)
{
- BMEditMesh *em = BKE_editmesh_from_object(obedit);
- BMesh *bm = em->bm;
-
- struct UserData user_data = {bm, obedit->data, op_params};
- LinkNode *path = NULL;
- bool is_path_ordered = false;
-
- if (v_act && (v_act != v_dst)) {
- if (op_params->use_fill) {
- path = BM_mesh_calc_path_region_vert(
- bm, (BMElem *)v_act, (BMElem *)v_dst,
- verttag_filter_cb, &user_data);
- }
- else {
- is_path_ordered = true;
- path = BM_mesh_calc_path_vert(
- bm, v_act, v_dst,
- &(const struct BMCalcPathParams) {
- .use_topology_distance = op_params->use_topology_distance,
- .use_step_face = op_params->use_face_step,
- },
- verttag_filter_cb, &user_data);
- }
-
- if (path) {
- if (op_params->track_active) {
- BM_select_history_remove(bm, v_act);
- }
- }
- }
-
- BMVert *v_dst_last = v_dst;
-
- 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));
-
- /* We need to start as if just *after* a 'skip' block... */
- int depth = op_params->interval_params.skip;
- node = path;
- do {
- if ((is_path_ordered == false) ||
- WM_operator_properties_checker_interval_test(&op_params->interval_params, depth))
- {
- verttag_set_cb((BMVert *)node->link, !all_set, &user_data);
- if (is_path_ordered) {
- v_dst_last = node->link;
- }
- }
- } while ((void)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 */
- }
-
- 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_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);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMesh *bm = em->bm;
+
+ struct UserData user_data = {bm, obedit->data, op_params};
+ LinkNode *path = NULL;
+ bool is_path_ordered = false;
+
+ if (v_act && (v_act != v_dst)) {
+ if (op_params->use_fill) {
+ path = BM_mesh_calc_path_region_vert(
+ bm, (BMElem *)v_act, (BMElem *)v_dst, verttag_filter_cb, &user_data);
+ }
+ else {
+ is_path_ordered = true;
+ path = BM_mesh_calc_path_vert(bm,
+ v_act,
+ v_dst,
+ &(const struct BMCalcPathParams){
+ .use_topology_distance = op_params->use_topology_distance,
+ .use_step_face = op_params->use_face_step,
+ },
+ verttag_filter_cb,
+ &user_data);
+ }
+
+ if (path) {
+ if (op_params->track_active) {
+ BM_select_history_remove(bm, v_act);
+ }
+ }
+ }
+
+ BMVert *v_dst_last = v_dst;
+
+ 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));
+
+ /* We need to start as if just *after* a 'skip' block... */
+ int depth = op_params->interval_params.skip;
+ node = path;
+ do {
+ if ((is_path_ordered == false) ||
+ WM_operator_properties_checker_interval_test(&op_params->interval_params, depth)) {
+ verttag_set_cb((BMVert *)node->link, !all_set, &user_data);
+ if (is_path_ordered) {
+ v_dst_last = node->link;
+ }
+ }
+ } while ((void)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 */
+ }
+
+ 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_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);
}
/** \} */
@@ -219,195 +227,195 @@ static void mouse_mesh_shortest_path_vert(
/* callbacks */
static bool edgetag_filter_cb(BMEdge *e, void *UNUSED(user_data_v))
{
- return !BM_elem_flag_test(e, BM_ELEM_HIDDEN);
+ return !BM_elem_flag_test(e, BM_ELEM_HIDDEN);
}
static bool edgetag_test_cb(BMEdge *e, void *user_data_v)
{
- struct UserData *user_data = user_data_v;
- const char edge_mode = user_data->op_params->edge_mode;
- BMesh *bm = user_data->bm;
-
- switch (edge_mode) {
- case EDGE_MODE_SELECT:
- return BM_elem_flag_test(e, BM_ELEM_SELECT) ? true : false;
- case EDGE_MODE_TAG_SEAM:
- return BM_elem_flag_test(e, BM_ELEM_SEAM) ? true : false;
- case EDGE_MODE_TAG_SHARP:
- return BM_elem_flag_test(e, BM_ELEM_SMOOTH) ? false : true;
- case EDGE_MODE_TAG_CREASE:
- return BM_elem_float_data_get(&bm->edata, e, CD_CREASE) ? true : false;
- case EDGE_MODE_TAG_BEVEL:
- return BM_elem_float_data_get(&bm->edata, e, CD_BWEIGHT) ? true : false;
+ struct UserData *user_data = user_data_v;
+ const char edge_mode = user_data->op_params->edge_mode;
+ BMesh *bm = user_data->bm;
+
+ switch (edge_mode) {
+ case EDGE_MODE_SELECT:
+ return BM_elem_flag_test(e, BM_ELEM_SELECT) ? true : false;
+ case EDGE_MODE_TAG_SEAM:
+ return BM_elem_flag_test(e, BM_ELEM_SEAM) ? true : false;
+ case EDGE_MODE_TAG_SHARP:
+ return BM_elem_flag_test(e, BM_ELEM_SMOOTH) ? false : true;
+ case EDGE_MODE_TAG_CREASE:
+ return BM_elem_float_data_get(&bm->edata, e, CD_CREASE) ? true : false;
+ case EDGE_MODE_TAG_BEVEL:
+ return BM_elem_float_data_get(&bm->edata, e, CD_BWEIGHT) ? true : false;
#ifdef WITH_FREESTYLE
- case EDGE_MODE_TAG_FREESTYLE:
- {
- FreestyleEdge *fed = CustomData_bmesh_get(&bm->edata, e->head.data, CD_FREESTYLE_EDGE);
- return (!fed) ? false : (fed->flag & FREESTYLE_EDGE_MARK) ? true : false;
- }
+ case EDGE_MODE_TAG_FREESTYLE: {
+ FreestyleEdge *fed = CustomData_bmesh_get(&bm->edata, e->head.data, CD_FREESTYLE_EDGE);
+ return (!fed) ? false : (fed->flag & FREESTYLE_EDGE_MARK) ? true : false;
+ }
#endif
- }
- return 0;
+ }
+ return 0;
}
static void edgetag_set_cb(BMEdge *e, bool val, void *user_data_v)
{
- struct UserData *user_data = user_data_v;
- const char edge_mode = user_data->op_params->edge_mode;
- BMesh *bm = user_data->bm;
-
- switch (edge_mode) {
- case EDGE_MODE_SELECT:
- BM_edge_select_set(bm, e, val);
- break;
- case EDGE_MODE_TAG_SEAM:
- BM_elem_flag_set(e, BM_ELEM_SEAM, val);
- break;
- case EDGE_MODE_TAG_SHARP:
- BM_elem_flag_set(e, BM_ELEM_SMOOTH, !val);
- break;
- case EDGE_MODE_TAG_CREASE:
- BM_elem_float_data_set(&bm->edata, e, CD_CREASE, (val) ? 1.0f : 0.0f);
- break;
- case EDGE_MODE_TAG_BEVEL:
- BM_elem_float_data_set(&bm->edata, e, CD_BWEIGHT, (val) ? 1.0f : 0.0f);
- break;
+ struct UserData *user_data = user_data_v;
+ const char edge_mode = user_data->op_params->edge_mode;
+ BMesh *bm = user_data->bm;
+
+ switch (edge_mode) {
+ case EDGE_MODE_SELECT:
+ BM_edge_select_set(bm, e, val);
+ break;
+ case EDGE_MODE_TAG_SEAM:
+ BM_elem_flag_set(e, BM_ELEM_SEAM, val);
+ break;
+ case EDGE_MODE_TAG_SHARP:
+ BM_elem_flag_set(e, BM_ELEM_SMOOTH, !val);
+ break;
+ case EDGE_MODE_TAG_CREASE:
+ BM_elem_float_data_set(&bm->edata, e, CD_CREASE, (val) ? 1.0f : 0.0f);
+ break;
+ case EDGE_MODE_TAG_BEVEL:
+ BM_elem_float_data_set(&bm->edata, e, CD_BWEIGHT, (val) ? 1.0f : 0.0f);
+ break;
#ifdef WITH_FREESTYLE
- case EDGE_MODE_TAG_FREESTYLE:
- {
- FreestyleEdge *fed;
- fed = CustomData_bmesh_get(&bm->edata, e->head.data, CD_FREESTYLE_EDGE);
- if (!val)
- fed->flag &= ~FREESTYLE_EDGE_MARK;
- else
- fed->flag |= FREESTYLE_EDGE_MARK;
- break;
- }
+ case EDGE_MODE_TAG_FREESTYLE: {
+ FreestyleEdge *fed;
+ fed = CustomData_bmesh_get(&bm->edata, e->head.data, CD_FREESTYLE_EDGE);
+ if (!val)
+ fed->flag &= ~FREESTYLE_EDGE_MARK;
+ else
+ fed->flag |= FREESTYLE_EDGE_MARK;
+ break;
+ }
#endif
- }
+ }
}
static void edgetag_ensure_cd_flag(Mesh *me, const char edge_mode)
{
- BMesh *bm = me->edit_mesh->bm;
-
- switch (edge_mode) {
- case EDGE_MODE_TAG_CREASE:
- BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_EDGE_CREASE);
- break;
- case EDGE_MODE_TAG_BEVEL:
- BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_EDGE_BWEIGHT);
- break;
+ BMesh *bm = me->edit_mesh->bm;
+
+ switch (edge_mode) {
+ case EDGE_MODE_TAG_CREASE:
+ BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_EDGE_CREASE);
+ break;
+ case EDGE_MODE_TAG_BEVEL:
+ BM_mesh_cd_flag_ensure(bm, me, ME_CDFLAG_EDGE_BWEIGHT);
+ break;
#ifdef WITH_FREESTYLE
- case EDGE_MODE_TAG_FREESTYLE:
- if (!CustomData_has_layer(&bm->edata, CD_FREESTYLE_EDGE)) {
- BM_data_layer_add(bm, &bm->edata, CD_FREESTYLE_EDGE);
- }
- break;
+ case EDGE_MODE_TAG_FREESTYLE:
+ if (!CustomData_has_layer(&bm->edata, CD_FREESTYLE_EDGE)) {
+ BM_data_layer_add(bm, &bm->edata, CD_FREESTYLE_EDGE);
+ }
+ break;
#endif
- default:
- break;
- }
+ default:
+ break;
+ }
}
/* mesh shortest path select, uses prev-selected edge */
/* since you want to create paths with multiple selects, it doesn't have extend option */
-static void mouse_mesh_shortest_path_edge(
- Scene *UNUSED(scene), Object *obedit, const struct PathSelectParams *op_params,
- BMEdge *e_act, BMEdge *e_dst)
+static void mouse_mesh_shortest_path_edge(Scene *UNUSED(scene),
+ Object *obedit,
+ const struct PathSelectParams *op_params,
+ BMEdge *e_act,
+ BMEdge *e_dst)
{
- BMEditMesh *em = BKE_editmesh_from_object(obedit);
- BMesh *bm = em->bm;
-
- struct UserData user_data = {bm, obedit->data, op_params};
- LinkNode *path = NULL;
- bool is_path_ordered = false;
-
- edgetag_ensure_cd_flag(obedit->data, op_params->edge_mode);
-
- if (e_act && (e_act != e_dst)) {
- if (op_params->use_fill) {
- path = BM_mesh_calc_path_region_edge(
- bm, (BMElem *)e_act, (BMElem *)e_dst,
- edgetag_filter_cb, &user_data);
- }
- else {
- is_path_ordered = true;
- path = BM_mesh_calc_path_edge(
- bm, e_act, e_dst,
- &(const struct BMCalcPathParams) {
- .use_topology_distance = op_params->use_topology_distance,
- .use_step_face = op_params->use_face_step,
- },
- edgetag_filter_cb, &user_data);
- }
-
- if (path) {
- if (op_params->track_active) {
- BM_select_history_remove(bm, e_act);
- }
- }
- }
-
- BMEdge *e_dst_last = e_dst;
-
- if (path) {
- /* toggle the flag */
- bool all_set = true;
- LinkNode *node;
-
- node = path;
- do {
- if (!edgetag_test_cb((BMEdge *)node->link, &user_data)) {
- all_set = false;
- break;
- }
- } while ((node = node->next));
-
- /* We need to start as if just *after* a 'skip' block... */
- int depth = op_params->interval_params.skip;
- node = path;
- do {
- if ((is_path_ordered == false) ||
- WM_operator_properties_checker_interval_test(&op_params->interval_params, depth))
- {
- edgetag_set_cb((BMEdge *)node->link, !all_set, &user_data);
- if (is_path_ordered) {
- e_dst_last = node->link;
- }
- }
- } while ((void)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(obedit->data, op_params->edge_mode);
- edgetag_set_cb(e_dst, is_act, &user_data); /* switch the edge option */
- }
-
- 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_last, true);
- BM_select_history_store(bm, e_dst_last);
- }
- }
-
- EDBM_selectmode_flush(em);
-
- if (op_params->track_active) {
- /* even if this is selected it may not be in the selection list */
- 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_last);
- }
- }
-
- EDBM_update_generic(em, false, false);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMesh *bm = em->bm;
+
+ struct UserData user_data = {bm, obedit->data, op_params};
+ LinkNode *path = NULL;
+ bool is_path_ordered = false;
+
+ edgetag_ensure_cd_flag(obedit->data, op_params->edge_mode);
+
+ if (e_act && (e_act != e_dst)) {
+ if (op_params->use_fill) {
+ path = BM_mesh_calc_path_region_edge(
+ bm, (BMElem *)e_act, (BMElem *)e_dst, edgetag_filter_cb, &user_data);
+ }
+ else {
+ is_path_ordered = true;
+ path = BM_mesh_calc_path_edge(bm,
+ e_act,
+ e_dst,
+ &(const struct BMCalcPathParams){
+ .use_topology_distance = op_params->use_topology_distance,
+ .use_step_face = op_params->use_face_step,
+ },
+ edgetag_filter_cb,
+ &user_data);
+ }
+
+ if (path) {
+ if (op_params->track_active) {
+ BM_select_history_remove(bm, e_act);
+ }
+ }
+ }
+
+ BMEdge *e_dst_last = e_dst;
+
+ if (path) {
+ /* toggle the flag */
+ bool all_set = true;
+ LinkNode *node;
+
+ node = path;
+ do {
+ if (!edgetag_test_cb((BMEdge *)node->link, &user_data)) {
+ all_set = false;
+ break;
+ }
+ } while ((node = node->next));
+
+ /* We need to start as if just *after* a 'skip' block... */
+ int depth = op_params->interval_params.skip;
+ node = path;
+ do {
+ if ((is_path_ordered == false) ||
+ WM_operator_properties_checker_interval_test(&op_params->interval_params, depth)) {
+ edgetag_set_cb((BMEdge *)node->link, !all_set, &user_data);
+ if (is_path_ordered) {
+ e_dst_last = node->link;
+ }
+ }
+ } while ((void)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(obedit->data, op_params->edge_mode);
+ edgetag_set_cb(e_dst, is_act, &user_data); /* switch the edge option */
+ }
+
+ 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_last, true);
+ BM_select_history_store(bm, e_dst_last);
+ }
+ }
+
+ EDBM_selectmode_flush(em);
+
+ if (op_params->track_active) {
+ /* even if this is selected it may not be in the selection list */
+ 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_last);
+ }
+ }
+
+ EDBM_update_generic(em, false, false);
}
/** \} */
@@ -419,107 +427,109 @@ static void mouse_mesh_shortest_path_edge(
/* callbacks */
static bool facetag_filter_cb(BMFace *f, void *UNUSED(user_data_v))
{
- return !BM_elem_flag_test(f, BM_ELEM_HIDDEN);
+ return !BM_elem_flag_test(f, BM_ELEM_HIDDEN);
}
//static bool facetag_test_cb(Scene *UNUSED(scene), BMesh *UNUSED(bm), BMFace *f)
static bool facetag_test_cb(BMFace *f, void *UNUSED(user_data_v))
{
- return BM_elem_flag_test_bool(f, BM_ELEM_SELECT);
+ return BM_elem_flag_test_bool(f, BM_ELEM_SELECT);
}
//static void facetag_set_cb(BMesh *bm, Scene *UNUSED(scene), BMFace *f, const bool val)
static void facetag_set_cb(BMFace *f, bool val, void *user_data_v)
{
- struct UserData *user_data = user_data_v;
- BM_face_select_set(user_data->bm, f, val);
+ struct UserData *user_data = user_data_v;
+ BM_face_select_set(user_data->bm, f, val);
}
-static void mouse_mesh_shortest_path_face(
- Scene *UNUSED(scene), Object *obedit, const struct PathSelectParams *op_params,
- BMFace *f_act, BMFace *f_dst)
+static void mouse_mesh_shortest_path_face(Scene *UNUSED(scene),
+ Object *obedit,
+ const struct PathSelectParams *op_params,
+ BMFace *f_act,
+ BMFace *f_dst)
{
- BMEditMesh *em = BKE_editmesh_from_object(obedit);
- BMesh *bm = em->bm;
-
- struct UserData user_data = {bm, obedit->data, op_params};
- LinkNode *path = NULL;
- bool is_path_ordered = false;
-
- if (f_act) {
- if (op_params->use_fill) {
- path = BM_mesh_calc_path_region_face(
- bm, (BMElem *)f_act, (BMElem *)f_dst,
- facetag_filter_cb, &user_data);
- }
- else {
- is_path_ordered = true;
- path = BM_mesh_calc_path_face(
- bm, f_act, f_dst,
- &(const struct BMCalcPathParams) {
- .use_topology_distance = op_params->use_topology_distance,
- .use_step_face = op_params->use_face_step,
- },
- facetag_filter_cb, &user_data);
- }
-
- if (f_act != f_dst) {
- if (path) {
- if (op_params->track_active) {
- BM_select_history_remove(bm, f_act);
- }
- }
- }
- }
-
- BMFace *f_dst_last = f_dst;
-
- if (path) {
- /* toggle the flag */
- bool all_set = true;
- LinkNode *node;
-
- node = path;
- do {
- if (!facetag_test_cb((BMFace *)node->link, &user_data)) {
- all_set = false;
- break;
- }
- } while ((node = node->next));
-
- /* We need to start as if just *after* a 'skip' block... */
- int depth = op_params->interval_params.skip;
- node = path;
- do {
- if ((is_path_ordered == false) ||
- WM_operator_properties_checker_interval_test(&op_params->interval_params, depth))
- {
- facetag_set_cb((BMFace *)node->link, !all_set, &user_data);
- if (is_path_ordered) {
- f_dst_last = node->link;
- }
- }
- } while ((void)depth++, (node = node->next));
-
- BLI_linklist_free(path, NULL);
- }
- else {
- const bool is_act = !facetag_test_cb(f_dst, &user_data);
- facetag_set_cb(f_dst, is_act, &user_data); /* switch the face option */
- }
-
- EDBM_selectmode_flush(em);
-
- if (op_params->track_active) {
- /* even if this is selected it may not be in the selection list */
- if (facetag_test_cb(f_dst_last, &user_data) == 0) {
- BM_select_history_remove(bm, f_dst_last);
- }
- else {
- BM_select_history_store(bm, f_dst_last);
- }
- BM_mesh_active_face_set(bm, f_dst_last);
- }
-
- EDBM_update_generic(em, false, false);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMesh *bm = em->bm;
+
+ struct UserData user_data = {bm, obedit->data, op_params};
+ LinkNode *path = NULL;
+ bool is_path_ordered = false;
+
+ if (f_act) {
+ if (op_params->use_fill) {
+ path = BM_mesh_calc_path_region_face(
+ bm, (BMElem *)f_act, (BMElem *)f_dst, facetag_filter_cb, &user_data);
+ }
+ else {
+ is_path_ordered = true;
+ path = BM_mesh_calc_path_face(bm,
+ f_act,
+ f_dst,
+ &(const struct BMCalcPathParams){
+ .use_topology_distance = op_params->use_topology_distance,
+ .use_step_face = op_params->use_face_step,
+ },
+ facetag_filter_cb,
+ &user_data);
+ }
+
+ if (f_act != f_dst) {
+ if (path) {
+ if (op_params->track_active) {
+ BM_select_history_remove(bm, f_act);
+ }
+ }
+ }
+ }
+
+ BMFace *f_dst_last = f_dst;
+
+ if (path) {
+ /* toggle the flag */
+ bool all_set = true;
+ LinkNode *node;
+
+ node = path;
+ do {
+ if (!facetag_test_cb((BMFace *)node->link, &user_data)) {
+ all_set = false;
+ break;
+ }
+ } while ((node = node->next));
+
+ /* We need to start as if just *after* a 'skip' block... */
+ int depth = op_params->interval_params.skip;
+ node = path;
+ do {
+ if ((is_path_ordered == false) ||
+ WM_operator_properties_checker_interval_test(&op_params->interval_params, depth)) {
+ facetag_set_cb((BMFace *)node->link, !all_set, &user_data);
+ if (is_path_ordered) {
+ f_dst_last = node->link;
+ }
+ }
+ } while ((void)depth++, (node = node->next));
+
+ BLI_linklist_free(path, NULL);
+ }
+ else {
+ const bool is_act = !facetag_test_cb(f_dst, &user_data);
+ facetag_set_cb(f_dst, is_act, &user_data); /* switch the face option */
+ }
+
+ EDBM_selectmode_flush(em);
+
+ if (op_params->track_active) {
+ /* even if this is selected it may not be in the selection list */
+ if (facetag_test_cb(f_dst_last, &user_data) == 0) {
+ BM_select_history_remove(bm, f_dst_last);
+ }
+ else {
+ BM_select_history_store(bm, f_dst_last);
+ }
+ BM_mesh_active_face_set(bm, f_dst_last);
+ }
+
+ EDBM_update_generic(em, false, false);
}
/** \} */
@@ -528,206 +538,204 @@ static void mouse_mesh_shortest_path_face(
/** \name Main Operator for vert/edge/face tag
* \{ */
-static bool edbm_shortest_path_pick_ex(
- Scene *scene, Object *obedit, const struct PathSelectParams *op_params,
- BMElem *ele_src, BMElem *ele_dst)
+static bool edbm_shortest_path_pick_ex(Scene *scene,
+ Object *obedit,
+ const struct PathSelectParams *op_params,
+ BMElem *ele_src,
+ BMElem *ele_dst)
{
- bool ok = false;
-
- if (ELEM(NULL, ele_src, ele_dst) || (ele_src->head.htype != ele_dst->head.htype)) {
- /* pass */
- }
- else if (ele_src->head.htype == BM_VERT) {
- mouse_mesh_shortest_path_vert(scene, obedit, op_params, (BMVert *)ele_src, (BMVert *)ele_dst);
- ok = true;
- }
- else if (ele_src->head.htype == BM_EDGE) {
- mouse_mesh_shortest_path_edge(scene, obedit, op_params, (BMEdge *)ele_src, (BMEdge *)ele_dst);
- ok = true;
- }
- else if (ele_src->head.htype == BM_FACE) {
- mouse_mesh_shortest_path_face(scene, obedit, op_params, (BMFace *)ele_src, (BMFace *)ele_dst);
- ok = true;
- }
-
- if (ok) {
- DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
- WM_main_add_notifier(NC_GEOM | ND_SELECT, obedit->data);
- }
-
- return ok;
+ bool ok = false;
+
+ if (ELEM(NULL, ele_src, ele_dst) || (ele_src->head.htype != ele_dst->head.htype)) {
+ /* pass */
+ }
+ else if (ele_src->head.htype == BM_VERT) {
+ mouse_mesh_shortest_path_vert(scene, obedit, op_params, (BMVert *)ele_src, (BMVert *)ele_dst);
+ ok = true;
+ }
+ else if (ele_src->head.htype == BM_EDGE) {
+ mouse_mesh_shortest_path_edge(scene, obedit, op_params, (BMEdge *)ele_src, (BMEdge *)ele_dst);
+ ok = true;
+ }
+ else if (ele_src->head.htype == BM_FACE) {
+ mouse_mesh_shortest_path_face(scene, obedit, op_params, (BMFace *)ele_src, (BMFace *)ele_dst);
+ ok = true;
+ }
+
+ if (ok) {
+ DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
+ WM_main_add_notifier(NC_GEOM | ND_SELECT, obedit->data);
+ }
+
+ return ok;
}
static int edbm_shortest_path_pick_exec(bContext *C, wmOperator *op);
static BMElem *edbm_elem_find_nearest(ViewContext *vc, const char htype)
{
- BMEditMesh *em = vc->em;
- float dist = ED_view3d_select_dist_px();
-
- if ((em->selectmode & SCE_SELECT_VERTEX) && (htype == BM_VERT)) {
- return (BMElem *)EDBM_vert_find_nearest(vc, &dist);
- }
- else if ((em->selectmode & SCE_SELECT_EDGE) && (htype == BM_EDGE)) {
- return (BMElem *)EDBM_edge_find_nearest(vc, &dist);
- }
- else if ((em->selectmode & SCE_SELECT_FACE) && (htype == BM_FACE)) {
- return (BMElem *)EDBM_face_find_nearest(vc, &dist);
- }
-
- return NULL;
+ BMEditMesh *em = vc->em;
+ float dist = ED_view3d_select_dist_px();
+
+ if ((em->selectmode & SCE_SELECT_VERTEX) && (htype == BM_VERT)) {
+ return (BMElem *)EDBM_vert_find_nearest(vc, &dist);
+ }
+ else if ((em->selectmode & SCE_SELECT_EDGE) && (htype == BM_EDGE)) {
+ return (BMElem *)EDBM_edge_find_nearest(vc, &dist);
+ }
+ else if ((em->selectmode & SCE_SELECT_FACE) && (htype == BM_FACE)) {
+ return (BMElem *)EDBM_face_find_nearest(vc, &dist);
+ }
+
+ return NULL;
}
static BMElem *edbm_elem_active_elem_or_face_get(BMesh *bm)
{
- BMElem *ele = BM_mesh_active_elem_get(bm);
+ BMElem *ele = BM_mesh_active_elem_get(bm);
- if ((ele == NULL) && bm->act_face && BM_elem_flag_test(bm->act_face, BM_ELEM_SELECT)) {
- ele = (BMElem *)bm->act_face;
- }
+ if ((ele == NULL) && bm->act_face && BM_elem_flag_test(bm->act_face, BM_ELEM_SELECT)) {
+ ele = (BMElem *)bm->act_face;
+ }
- return ele;
+ return ele;
}
static int edbm_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (RNA_struct_property_is_set(op->ptr, "index")) {
- return edbm_shortest_path_pick_exec(C, op);
- }
-
- Base *basact = NULL;
- BMVert *eve = NULL;
- BMEdge *eed = NULL;
- BMFace *efa = NULL;
-
- ViewContext vc;
- BMEditMesh *em;
- bool track_active = true;
-
- em_setup_viewcontext(C, &vc);
- copy_v2_v2_int(vc.mval, event->mval);
- em = vc.em;
-
- view3d_operator_needs_opengl(C);
-
- {
- int base_index = -1;
- uint bases_len = 0;
- Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(vc.view_layer, vc.v3d, &bases_len);
- if (EDBM_unified_findnearest(&vc, bases, bases_len, &base_index, &eve, &eed, &efa)) {
- basact = bases[base_index];
- ED_view3d_viewcontext_init_object(&vc, basact->object);
- em = vc.em;
- }
- MEM_freeN(bases);
- }
-
- /* If nothing is selected, let's select the picked vertex/edge/face. */
- if ((vc.em->bm->totvertsel == 0) && (eve || eed || efa)) {
- /* TODO (dfelinto) right now we try to find the closest element twice.
- * The ideal is to refactor EDBM_select_pick so it doesn't
- * have to pick the nearest vert/edge/face again.
- */
- EDBM_select_pick(C, event->mval, true, false, false);
- return OPERATOR_FINISHED;
- }
-
- BMElem *ele_src, *ele_dst;
- if (!(ele_src = edbm_elem_active_elem_or_face_get(em->bm)) ||
- !(ele_dst = edbm_elem_find_nearest(&vc, ele_src->head.htype)))
- {
- /* special case, toggle edge tags even when we don't have a path */
- if (((em->selectmode & SCE_SELECT_EDGE) &&
- (vc.scene->toolsettings->edge_mode != EDGE_MODE_SELECT)) &&
- /* check if we only have a destination edge */
- ((ele_src == NULL) &&
- (ele_dst = edbm_elem_find_nearest(&vc, BM_EDGE))))
- {
- ele_src = ele_dst;
- track_active = false;
- }
- else {
- return OPERATOR_PASS_THROUGH;
- }
- }
-
- struct PathSelectParams op_params;
-
- path_select_params_from_op(op, &op_params);
- op_params.track_active = track_active;
- op_params.edge_mode = vc.scene->toolsettings->edge_mode;
-
- if (!edbm_shortest_path_pick_ex(vc.scene, vc.obedit, &op_params, ele_src, ele_dst)) {
- return OPERATOR_PASS_THROUGH;
- }
-
- if (vc.view_layer->basact != basact) {
- ED_object_base_activate(C, basact);
- }
-
- /* to support redo */
- BM_mesh_elem_index_ensure(em->bm, ele_dst->head.htype);
- int index = EDBM_elem_to_index_any(em, ele_dst);
-
- RNA_int_set(op->ptr, "index", index);
-
- return OPERATOR_FINISHED;
+ if (RNA_struct_property_is_set(op->ptr, "index")) {
+ return edbm_shortest_path_pick_exec(C, op);
+ }
+
+ Base *basact = NULL;
+ BMVert *eve = NULL;
+ BMEdge *eed = NULL;
+ BMFace *efa = NULL;
+
+ ViewContext vc;
+ BMEditMesh *em;
+ bool track_active = true;
+
+ em_setup_viewcontext(C, &vc);
+ copy_v2_v2_int(vc.mval, event->mval);
+ em = vc.em;
+
+ view3d_operator_needs_opengl(C);
+
+ {
+ int base_index = -1;
+ uint bases_len = 0;
+ Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(vc.view_layer, vc.v3d, &bases_len);
+ if (EDBM_unified_findnearest(&vc, bases, bases_len, &base_index, &eve, &eed, &efa)) {
+ basact = bases[base_index];
+ ED_view3d_viewcontext_init_object(&vc, basact->object);
+ em = vc.em;
+ }
+ MEM_freeN(bases);
+ }
+
+ /* If nothing is selected, let's select the picked vertex/edge/face. */
+ if ((vc.em->bm->totvertsel == 0) && (eve || eed || efa)) {
+ /* TODO (dfelinto) right now we try to find the closest element twice.
+ * The ideal is to refactor EDBM_select_pick so it doesn't
+ * have to pick the nearest vert/edge/face again.
+ */
+ EDBM_select_pick(C, event->mval, true, false, false);
+ return OPERATOR_FINISHED;
+ }
+
+ BMElem *ele_src, *ele_dst;
+ if (!(ele_src = edbm_elem_active_elem_or_face_get(em->bm)) ||
+ !(ele_dst = edbm_elem_find_nearest(&vc, ele_src->head.htype))) {
+ /* special case, toggle edge tags even when we don't have a path */
+ if (((em->selectmode & SCE_SELECT_EDGE) &&
+ (vc.scene->toolsettings->edge_mode != EDGE_MODE_SELECT)) &&
+ /* check if we only have a destination edge */
+ ((ele_src == NULL) && (ele_dst = edbm_elem_find_nearest(&vc, BM_EDGE)))) {
+ ele_src = ele_dst;
+ track_active = false;
+ }
+ else {
+ return OPERATOR_PASS_THROUGH;
+ }
+ }
+
+ struct PathSelectParams op_params;
+
+ path_select_params_from_op(op, &op_params);
+ op_params.track_active = track_active;
+ op_params.edge_mode = vc.scene->toolsettings->edge_mode;
+
+ if (!edbm_shortest_path_pick_ex(vc.scene, vc.obedit, &op_params, ele_src, ele_dst)) {
+ return OPERATOR_PASS_THROUGH;
+ }
+
+ if (vc.view_layer->basact != basact) {
+ ED_object_base_activate(C, basact);
+ }
+
+ /* to support redo */
+ BM_mesh_elem_index_ensure(em->bm, ele_dst->head.htype);
+ int index = EDBM_elem_to_index_any(em, ele_dst);
+
+ RNA_int_set(op->ptr, "index", index);
+
+ return OPERATOR_FINISHED;
}
static int edbm_shortest_path_pick_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
- Object *obedit = CTX_data_edit_object(C);
- BMEditMesh *em = BKE_editmesh_from_object(obedit);
- BMesh *bm = em->bm;
-
- const int index = RNA_int_get(op->ptr, "index");
- if (index < 0 || index >= (bm->totvert + bm->totedge + bm->totface)) {
- return OPERATOR_CANCELLED;
- }
-
- BMElem *ele_src, *ele_dst;
- if (!(ele_src = edbm_elem_active_elem_or_face_get(em->bm)) ||
- !(ele_dst = EDBM_elem_from_index_any(em, index)))
- {
- return OPERATOR_CANCELLED;
- }
-
- struct PathSelectParams op_params;
- path_select_params_from_op(op, &op_params);
- op_params.track_active = true;
- op_params.edge_mode = scene->toolsettings->edge_mode;
-
- if (!edbm_shortest_path_pick_ex(scene, obedit, &op_params, ele_src, ele_dst)) {
- return OPERATOR_CANCELLED;
- }
-
- return OPERATOR_FINISHED;
+ Scene *scene = CTX_data_scene(C);
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMesh *bm = em->bm;
+
+ const int index = RNA_int_get(op->ptr, "index");
+ if (index < 0 || index >= (bm->totvert + bm->totedge + bm->totface)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ BMElem *ele_src, *ele_dst;
+ if (!(ele_src = edbm_elem_active_elem_or_face_get(em->bm)) ||
+ !(ele_dst = EDBM_elem_from_index_any(em, index))) {
+ return OPERATOR_CANCELLED;
+ }
+
+ struct PathSelectParams op_params;
+ path_select_params_from_op(op, &op_params);
+ op_params.track_active = true;
+ op_params.edge_mode = scene->toolsettings->edge_mode;
+
+ if (!edbm_shortest_path_pick_ex(scene, obedit, &op_params, ele_src, ele_dst)) {
+ return OPERATOR_CANCELLED;
+ }
+
+ return OPERATOR_FINISHED;
}
void MESH_OT_shortest_path_pick(wmOperatorType *ot)
{
- PropertyRNA *prop;
+ PropertyRNA *prop;
- /* identifiers */
- ot->name = "Pick Shortest Path";
- ot->idname = "MESH_OT_shortest_path_pick";
- ot->description = "Select shortest path between two selections";
+ /* identifiers */
+ ot->name = "Pick Shortest Path";
+ ot->idname = "MESH_OT_shortest_path_pick";
+ ot->description = "Select shortest path between two selections";
- /* api callbacks */
- ot->invoke = edbm_shortest_path_pick_invoke;
- ot->exec = edbm_shortest_path_pick_exec;
- ot->poll = ED_operator_editmesh_region_view3d;
+ /* api callbacks */
+ ot->invoke = edbm_shortest_path_pick_invoke;
+ ot->exec = edbm_shortest_path_pick_exec;
+ ot->poll = ED_operator_editmesh_region_view3d;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- path_select_properties(ot);
+ /* properties */
+ path_select_properties(ot);
- /* use for redo */
- prop = RNA_def_int(ot->srna, "index", -1, -1, INT_MAX, "", "", 0, INT_MAX);
- RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+ /* use for redo */
+ prop = RNA_def_int(ot->srna, "index", -1, -1, INT_MAX, "", "", 0, INT_MAX);
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
}
/** \} */
@@ -738,106 +746,112 @@ void MESH_OT_shortest_path_pick(wmOperatorType *ot)
static int edbm_shortest_path_select_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
- bool found_valid_elements = false;
-
- ViewLayer *view_layer = CTX_data_view_layer(C);
- uint objects_len = 0;
- Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, CTX_wm_view3d(C), &objects_len);
- for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
- Object *obedit = objects[ob_index];
- BMEditMesh *em = BKE_editmesh_from_object(obedit);
- BMesh *bm = em->bm;
- BMIter iter;
- BMEditSelection *ese_src, *ese_dst;
- BMElem *ele_src = NULL, *ele_dst = NULL, *ele;
-
- if ((em->bm->totvertsel == 0) &&
- (em->bm->totedgesel == 0) &&
- (em->bm->totfacesel == 0))
- {
- continue;
- }
-
- /* first try to find vertices in edit selection */
- ese_src = bm->selected.last;
- if (ese_src && (ese_dst = ese_src->prev) && (ese_src->htype == ese_dst->htype)) {
- ele_src = ese_src->ele;
- ele_dst = ese_dst->ele;
- }
- else {
- /* if selection history isn't available, find two selected elements */
- ele_src = ele_dst = NULL;
- if ((em->selectmode & SCE_SELECT_VERTEX) && (bm->totvertsel >= 2)) {
- BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) {
- if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) {
- if (ele_src == NULL) ele_src = ele;
- else if (ele_dst == NULL) ele_dst = ele;
- else break;
- }
- }
- }
-
- if ((ele_dst == NULL) && (em->selectmode & SCE_SELECT_EDGE) && (bm->totedgesel >= 2)) {
- ele_src = NULL;
- BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
- if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) {
- if (ele_src == NULL) ele_src = ele;
- else if (ele_dst == NULL) ele_dst = ele;
- else break;
- }
- }
- }
-
- if ((ele_dst == NULL) && (em->selectmode & SCE_SELECT_FACE) && (bm->totfacesel >= 2)) {
- ele_src = NULL;
- BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {
- if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) {
- if (ele_src == NULL) ele_src = ele;
- else if (ele_dst == NULL) ele_dst = ele;
- else break;
- }
- }
- }
- }
-
- if (ele_src && ele_dst) {
- struct PathSelectParams op_params;
- path_select_params_from_op(op, &op_params);
-
- edbm_shortest_path_pick_ex(scene, obedit, &op_params, ele_src, ele_dst);
-
- found_valid_elements = true;
- }
- }
- MEM_freeN(objects);
-
- if (!found_valid_elements) {
- BKE_report(op->reports,
- RPT_WARNING,
- "Path selection requires two matching elements to be selected");
- return OPERATOR_CANCELLED;
- }
-
- return OPERATOR_FINISHED;
+ Scene *scene = CTX_data_scene(C);
+ bool found_valid_elements = false;
+
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMesh *bm = em->bm;
+ BMIter iter;
+ BMEditSelection *ese_src, *ese_dst;
+ BMElem *ele_src = NULL, *ele_dst = NULL, *ele;
+
+ if ((em->bm->totvertsel == 0) && (em->bm->totedgesel == 0) && (em->bm->totfacesel == 0)) {
+ continue;
+ }
+
+ /* first try to find vertices in edit selection */
+ ese_src = bm->selected.last;
+ if (ese_src && (ese_dst = ese_src->prev) && (ese_src->htype == ese_dst->htype)) {
+ ele_src = ese_src->ele;
+ ele_dst = ese_dst->ele;
+ }
+ else {
+ /* if selection history isn't available, find two selected elements */
+ ele_src = ele_dst = NULL;
+ if ((em->selectmode & SCE_SELECT_VERTEX) && (bm->totvertsel >= 2)) {
+ BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) {
+ if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) {
+ if (ele_src == NULL)
+ ele_src = ele;
+ else if (ele_dst == NULL)
+ ele_dst = ele;
+ else
+ break;
+ }
+ }
+ }
+
+ if ((ele_dst == NULL) && (em->selectmode & SCE_SELECT_EDGE) && (bm->totedgesel >= 2)) {
+ ele_src = NULL;
+ BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) {
+ if (ele_src == NULL)
+ ele_src = ele;
+ else if (ele_dst == NULL)
+ ele_dst = ele;
+ else
+ break;
+ }
+ }
+ }
+
+ if ((ele_dst == NULL) && (em->selectmode & SCE_SELECT_FACE) && (bm->totfacesel >= 2)) {
+ ele_src = NULL;
+ BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {
+ if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) {
+ if (ele_src == NULL)
+ ele_src = ele;
+ else if (ele_dst == NULL)
+ ele_dst = ele;
+ else
+ break;
+ }
+ }
+ }
+ }
+
+ if (ele_src && ele_dst) {
+ struct PathSelectParams op_params;
+ path_select_params_from_op(op, &op_params);
+
+ edbm_shortest_path_pick_ex(scene, obedit, &op_params, ele_src, ele_dst);
+
+ found_valid_elements = true;
+ }
+ }
+ MEM_freeN(objects);
+
+ if (!found_valid_elements) {
+ BKE_report(
+ op->reports, RPT_WARNING, "Path selection requires two matching elements to be selected");
+ return OPERATOR_CANCELLED;
+ }
+
+ return OPERATOR_FINISHED;
}
void MESH_OT_shortest_path_select(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Select Shortest Path";
- ot->idname = "MESH_OT_shortest_path_select";
- ot->description = "Selected shortest path between two vertices/edges/faces";
+ /* identifiers */
+ ot->name = "Select Shortest Path";
+ ot->idname = "MESH_OT_shortest_path_select";
+ ot->description = "Selected shortest path between two vertices/edges/faces";
- /* api callbacks */
- ot->exec = edbm_shortest_path_select_exec;
- ot->poll = ED_operator_editmesh;
+ /* api callbacks */
+ ot->exec = edbm_shortest_path_select_exec;
+ ot->poll = ED_operator_editmesh;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- path_select_properties(ot);
+ /* properties */
+ path_select_properties(ot);
}
/** \} */