diff options
Diffstat (limited to 'source/blender/editors/uvedit/uvedit_path.c')
-rw-r--r-- | source/blender/editors/uvedit/uvedit_path.c | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/source/blender/editors/uvedit/uvedit_path.c b/source/blender/editors/uvedit/uvedit_path.c index 4f0c472158a..e9615b62523 100644 --- a/source/blender/editors/uvedit/uvedit_path.c +++ b/source/blender/editors/uvedit/uvedit_path.c @@ -677,3 +677,95 @@ void UV_OT_shortest_path_pick(wmOperatorType *ot) } /** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Select Path Between Existing Selection + * \{ */ + +static int uv_shortest_path_select_exec(bContext *C, wmOperator *op) +{ + Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); + Scene *scene = CTX_data_scene(C); + const ToolSettings *ts = scene->toolsettings; + bool found_valid_elements = false; + + float aspect_y; + { + Object *obedit = CTX_data_edit_object(C); + float aspx, aspy; + ED_uvedit_get_aspect(obedit, &aspx, &aspy); + aspect_y = aspx / aspy; + } + + 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; + const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + BMElem *ele_src = NULL, *ele_dst = NULL; + + /* Find 2x elements. */ + { + BMElem **ele_array = NULL; + int ele_array_len = 0; + if (ts->uv_selectmode & UV_SELECT_FACE) { + ele_array = (BMElem **)ED_uvedit_selected_faces(scene, bm, 3, &ele_array_len); + } + else if (ts->uv_selectmode & UV_SELECT_EDGE) { + ele_array = (BMElem **)ED_uvedit_selected_edges(scene, bm, 3, &ele_array_len); + } + else { + ele_array = (BMElem **)ED_uvedit_selected_verts(scene, bm, 3, &ele_array_len); + } + + if (ele_array_len == 2) { + ele_src = ele_array[0]; + ele_dst = ele_array[1]; + } + MEM_freeN(ele_array); + } + + if (ele_src && ele_dst) { + struct PathSelectParams op_params; + path_select_params_from_op(op, &op_params); + + uv_shortest_path_pick_ex( + scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, cd_loop_uv_offset); + + 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 UV_OT_shortest_path_select(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Shortest Path"; + ot->idname = "UV_OT_shortest_path_select"; + ot->description = "Selected shortest path between two vertices/edges/faces"; + + /* api callbacks */ + ot->exec = uv_shortest_path_select_exec; + ot->poll = ED_operator_editmesh; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + path_select_properties(ot); +} + +/** \} */ |