Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/uvedit/uvedit_path.c
| Show First 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | struct PathSelectParams { | ||||
| bool use_face_step; | bool use_face_step; | ||||
| bool use_fill; | bool use_fill; | ||||
| struct CheckerIntervalParams interval_params; | struct CheckerIntervalParams interval_params; | ||||
| }; | }; | ||||
| struct UserData_UV { | struct UserData_UV { | ||||
| Scene *scene; | Scene *scene; | ||||
| BMEditMesh *em; | BMEditMesh *em; | ||||
| int cd_loop_uv_offset; | BMUVOffsets offsets; | ||||
| }; | }; | ||||
| static void path_select_properties(wmOperatorType *ot) | static void path_select_properties(wmOperatorType *ot) | ||||
| { | { | ||||
| RNA_def_boolean(ot->srna, | RNA_def_boolean(ot->srna, | ||||
| "use_face_step", | "use_face_step", | ||||
| false, | false, | ||||
| "Face Stepping", | "Face Stepping", | ||||
| Show All 33 Lines | static bool verttag_filter_cb(BMLoop *l, void *user_data_v) | ||||
| struct UserData_UV *user_data = user_data_v; | struct UserData_UV *user_data = user_data_v; | ||||
| return uvedit_face_visible_test(user_data->scene, l->f); | return uvedit_face_visible_test(user_data->scene, l->f); | ||||
| } | } | ||||
| static bool verttag_test_cb(BMLoop *l, void *user_data_v) | static bool verttag_test_cb(BMLoop *l, void *user_data_v) | ||||
| { | { | ||||
| /* All connected loops are selected or we return false. */ | /* All connected loops are selected or we return false. */ | ||||
| struct UserData_UV *user_data = user_data_v; | struct UserData_UV *user_data = user_data_v; | ||||
| const Scene *scene = user_data->scene; | const Scene *scene = user_data->scene; | ||||
| const int cd_loop_uv_offset = user_data->cd_loop_uv_offset; | const int cd_loop_uv_offset = user_data->offsets.uv; | ||||
| const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); | const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); | ||||
| BMIter iter; | BMIter iter; | ||||
| BMLoop *l_iter; | BMLoop *l_iter; | ||||
| BM_ITER_ELEM (l_iter, &iter, l->v, BM_LOOPS_OF_VERT) { | BM_ITER_ELEM (l_iter, &iter, l->v, BM_LOOPS_OF_VERT) { | ||||
| if (verttag_filter_cb(l_iter, user_data)) { | if (verttag_filter_cb(l_iter, user_data)) { | ||||
| const MLoopUV *luv_iter = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset); | const float *luv_iter = BM_ELEM_CD_GET_FLOAT_P(l_iter, cd_loop_uv_offset); | ||||
| if (equals_v2v2(luv->uv, luv_iter->uv)) { | if (equals_v2v2(luv, luv_iter)) { | ||||
| if (!uvedit_uv_select_test(scene, l_iter, cd_loop_uv_offset)) { | if (!uvedit_uv_select_test(scene, l_iter, user_data->offsets)) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| return true; | return true; | ||||
| } | } | ||||
| static void verttag_set_cb(BMLoop *l, bool val, void *user_data_v) | static void verttag_set_cb(BMLoop *l, bool val, void *user_data_v) | ||||
| { | { | ||||
| struct UserData_UV *user_data = user_data_v; | struct UserData_UV *user_data = user_data_v; | ||||
| const Scene *scene = user_data->scene; | const Scene *scene = user_data->scene; | ||||
| BMEditMesh *em = user_data->em; | BMEditMesh *em = user_data->em; | ||||
| const int cd_loop_uv_offset = user_data->cd_loop_uv_offset; | const uint cd_loop_uv_offset = user_data->offsets.uv; | ||||
| const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); | const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); | ||||
| BMIter iter; | BMIter iter; | ||||
| BMLoop *l_iter; | BMLoop *l_iter; | ||||
| BM_ITER_ELEM (l_iter, &iter, l->v, BM_LOOPS_OF_VERT) { | BM_ITER_ELEM (l_iter, &iter, l->v, BM_LOOPS_OF_VERT) { | ||||
| if (verttag_filter_cb(l_iter, user_data)) { | if (verttag_filter_cb(l_iter, user_data)) { | ||||
| MLoopUV *luv_iter = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset); | const float *luv_iter = BM_ELEM_CD_GET_FLOAT_P(l_iter, cd_loop_uv_offset); | ||||
| if (equals_v2v2(luv->uv, luv_iter->uv)) { | if (equals_v2v2(luv, luv_iter)) { | ||||
| uvedit_uv_select_set(scene, em->bm, l_iter, val, false, cd_loop_uv_offset); | uvedit_uv_select_set(scene, em->bm, l_iter, val, false, user_data->offsets); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static int mouse_mesh_uv_shortest_path_vert(Scene *scene, | static int mouse_mesh_uv_shortest_path_vert(Scene *scene, | ||||
| Object *obedit, | Object *obedit, | ||||
| const struct PathSelectParams *op_params, | const struct PathSelectParams *op_params, | ||||
| BMLoop *l_src, | BMLoop *l_src, | ||||
| BMLoop *l_dst, | BMLoop *l_dst, | ||||
| const float aspect_y, | const float aspect_y, | ||||
| const int cd_loop_uv_offset) | const BMUVOffsets offsets) | ||||
| { | { | ||||
| BMEditMesh *em = BKE_editmesh_from_object(obedit); | BMEditMesh *em = BKE_editmesh_from_object(obedit); | ||||
| BMesh *bm = em->bm; | BMesh *bm = em->bm; | ||||
| int flush = 0; | int flush = 0; | ||||
| struct UserData_UV user_data = { | struct UserData_UV user_data = { | ||||
| .scene = scene, | .scene = scene, | ||||
| .em = em, | .em = em, | ||||
| .cd_loop_uv_offset = cd_loop_uv_offset, | .offsets = offsets, | ||||
| }; | }; | ||||
| const struct BMCalcPathUVParams params = { | const struct BMCalcPathUVParams params = { | ||||
| .use_topology_distance = op_params->use_topology_distance, | .use_topology_distance = op_params->use_topology_distance, | ||||
| .use_step_face = op_params->use_face_step, | .use_step_face = op_params->use_face_step, | ||||
| .aspect_y = aspect_y, | .aspect_y = aspect_y, | ||||
| .cd_loop_uv_offset = cd_loop_uv_offset, | .cd_loop_uv_offset = offsets.uv, | ||||
| }; | }; | ||||
| LinkNode *path = NULL; | LinkNode *path = NULL; | ||||
| bool is_path_ordered = false; | bool is_path_ordered = false; | ||||
| if (l_src != l_dst) { | if (l_src != l_dst) { | ||||
| if (op_params->use_fill) { | if (op_params->use_fill) { | ||||
| path = BM_mesh_calc_path_uv_region_vert(bm, | path = BM_mesh_calc_path_uv_region_vert(bm, | ||||
| ▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | static bool edgetag_filter_cb(BMLoop *l, void *user_data_v) | ||||
| struct UserData_UV *user_data = user_data_v; | struct UserData_UV *user_data = user_data_v; | ||||
| return uvedit_face_visible_test(user_data->scene, l->f); | return uvedit_face_visible_test(user_data->scene, l->f); | ||||
| } | } | ||||
| static bool edgetag_test_cb(BMLoop *l, void *user_data_v) | static bool edgetag_test_cb(BMLoop *l, void *user_data_v) | ||||
| { | { | ||||
| /* All connected loops (UV) are selected or we return false. */ | /* All connected loops (UV) are selected or we return false. */ | ||||
| struct UserData_UV *user_data = user_data_v; | struct UserData_UV *user_data = user_data_v; | ||||
| const Scene *scene = user_data->scene; | const Scene *scene = user_data->scene; | ||||
| const int cd_loop_uv_offset = user_data->cd_loop_uv_offset; | |||||
| BMIter iter; | BMIter iter; | ||||
| BMLoop *l_iter; | BMLoop *l_iter; | ||||
| BM_ITER_ELEM (l_iter, &iter, l->e, BM_LOOPS_OF_EDGE) { | BM_ITER_ELEM (l_iter, &iter, l->e, BM_LOOPS_OF_EDGE) { | ||||
| if (edgetag_filter_cb(l_iter, user_data)) { | if (edgetag_filter_cb(l_iter, user_data)) { | ||||
| if (BM_loop_uv_share_edge_check(l, l_iter, cd_loop_uv_offset)) { | if (BM_loop_uv_share_edge_check(l, l_iter, user_data->offsets.uv)) { | ||||
| if (!uvedit_edge_select_test(scene, l_iter, cd_loop_uv_offset)) { | if (!uvedit_edge_select_test(scene, l_iter, user_data->offsets)) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| return true; | return true; | ||||
| } | } | ||||
| static void edgetag_set_cb(BMLoop *l, bool val, void *user_data_v) | static void edgetag_set_cb(BMLoop *l, bool val, void *user_data_v) | ||||
| { | { | ||||
| struct UserData_UV *user_data = user_data_v; | struct UserData_UV *user_data = user_data_v; | ||||
| const Scene *scene = user_data->scene; | const Scene *scene = user_data->scene; | ||||
| BMEditMesh *em = user_data->em; | BMEditMesh *em = user_data->em; | ||||
| const int cd_loop_uv_offset = user_data->cd_loop_uv_offset; | uvedit_edge_select_set_with_sticky(scene, em, l, val, false, user_data->offsets); | ||||
| uvedit_edge_select_set_with_sticky(scene, em, l, val, false, cd_loop_uv_offset); | |||||
| } | } | ||||
| static int mouse_mesh_uv_shortest_path_edge(Scene *scene, | static int mouse_mesh_uv_shortest_path_edge(Scene *scene, | ||||
| Object *obedit, | Object *obedit, | ||||
| const struct PathSelectParams *op_params, | const struct PathSelectParams *op_params, | ||||
| BMLoop *l_src, | BMLoop *l_src, | ||||
| BMLoop *l_dst, | BMLoop *l_dst, | ||||
| const float aspect_y, | const float aspect_y, | ||||
| const int cd_loop_uv_offset) | const BMUVOffsets offsets) | ||||
| { | { | ||||
| BMEditMesh *em = BKE_editmesh_from_object(obedit); | BMEditMesh *em = BKE_editmesh_from_object(obedit); | ||||
| BMesh *bm = em->bm; | BMesh *bm = em->bm; | ||||
| int flush = 0; | int flush = 0; | ||||
| struct UserData_UV user_data = { | struct UserData_UV user_data = { | ||||
| .scene = scene, | .scene = scene, | ||||
| .em = em, | .em = em, | ||||
| .cd_loop_uv_offset = cd_loop_uv_offset, | .offsets = offsets, | ||||
| }; | }; | ||||
| const struct BMCalcPathUVParams params = { | const struct BMCalcPathUVParams params = { | ||||
| .use_topology_distance = op_params->use_topology_distance, | .use_topology_distance = op_params->use_topology_distance, | ||||
| .use_step_face = op_params->use_face_step, | .use_step_face = op_params->use_face_step, | ||||
| .aspect_y = aspect_y, | .aspect_y = aspect_y, | ||||
| .cd_loop_uv_offset = cd_loop_uv_offset, | .cd_loop_uv_offset = offsets.uv, | ||||
| }; | }; | ||||
| LinkNode *path = NULL; | LinkNode *path = NULL; | ||||
| bool is_path_ordered = false; | bool is_path_ordered = false; | ||||
| if (l_src != l_dst) { | if (l_src != l_dst) { | ||||
| if (op_params->use_fill) { | if (op_params->use_fill) { | ||||
| path = BM_mesh_calc_path_uv_region_edge(bm, | path = BM_mesh_calc_path_uv_region_edge(bm, | ||||
| ▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | static bool facetag_filter_cb(BMFace *f, void *user_data_v) | ||||
| struct UserData_UV *user_data = user_data_v; | struct UserData_UV *user_data = user_data_v; | ||||
| return uvedit_face_visible_test(user_data->scene, f); | return uvedit_face_visible_test(user_data->scene, f); | ||||
| } | } | ||||
| static bool facetag_test_cb(BMFace *f, void *user_data_v) | static bool facetag_test_cb(BMFace *f, void *user_data_v) | ||||
| { | { | ||||
| /* All connected loops are selected or we return false. */ | /* All connected loops are selected or we return false. */ | ||||
| struct UserData_UV *user_data = user_data_v; | struct UserData_UV *user_data = user_data_v; | ||||
| const Scene *scene = user_data->scene; | const Scene *scene = user_data->scene; | ||||
| const int cd_loop_uv_offset = user_data->cd_loop_uv_offset; | |||||
| BMIter iter; | BMIter iter; | ||||
| BMLoop *l_iter; | BMLoop *l_iter; | ||||
| BM_ITER_ELEM (l_iter, &iter, f, BM_LOOPS_OF_FACE) { | BM_ITER_ELEM (l_iter, &iter, f, BM_LOOPS_OF_FACE) { | ||||
| if (!uvedit_edge_select_test(scene, l_iter, cd_loop_uv_offset)) { | if (!uvedit_edge_select_test(scene, l_iter, user_data->offsets)) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| } | } | ||||
| return true; | return true; | ||||
| } | } | ||||
| static void facetag_set_cb(BMFace *f, bool val, void *user_data_v) | static void facetag_set_cb(BMFace *f, bool val, void *user_data_v) | ||||
| { | { | ||||
| struct UserData_UV *user_data = user_data_v; | struct UserData_UV *user_data = user_data_v; | ||||
| const Scene *scene = user_data->scene; | const Scene *scene = user_data->scene; | ||||
| BMEditMesh *em = user_data->em; | BMEditMesh *em = user_data->em; | ||||
| const int cd_loop_uv_offset = user_data->cd_loop_uv_offset; | uvedit_face_select_set_with_sticky(scene, em, f, val, false, user_data->offsets); | ||||
| uvedit_face_select_set_with_sticky(scene, em, f, val, false, cd_loop_uv_offset); | |||||
| } | } | ||||
| static int mouse_mesh_uv_shortest_path_face(Scene *scene, | static int mouse_mesh_uv_shortest_path_face(Scene *scene, | ||||
| Object *obedit, | Object *obedit, | ||||
| const struct PathSelectParams *op_params, | const struct PathSelectParams *op_params, | ||||
| BMFace *f_src, | BMFace *f_src, | ||||
| BMFace *f_dst, | BMFace *f_dst, | ||||
| const float aspect_y, | const float aspect_y, | ||||
| const int cd_loop_uv_offset) | const BMUVOffsets offsets) | ||||
| { | { | ||||
| BMEditMesh *em = BKE_editmesh_from_object(obedit); | BMEditMesh *em = BKE_editmesh_from_object(obedit); | ||||
| BMesh *bm = em->bm; | BMesh *bm = em->bm; | ||||
| int flush = 0; | int flush = 0; | ||||
| struct UserData_UV user_data = { | struct UserData_UV user_data = { | ||||
| .scene = scene, | .scene = scene, | ||||
| .em = em, | .em = em, | ||||
| .cd_loop_uv_offset = cd_loop_uv_offset, | .offsets = offsets, | ||||
| }; | }; | ||||
| const struct BMCalcPathUVParams params = { | const struct BMCalcPathUVParams params = { | ||||
| .use_topology_distance = op_params->use_topology_distance, | .use_topology_distance = op_params->use_topology_distance, | ||||
| .use_step_face = op_params->use_face_step, | .use_step_face = op_params->use_face_step, | ||||
| .aspect_y = aspect_y, | .aspect_y = aspect_y, | ||||
| .cd_loop_uv_offset = cd_loop_uv_offset, | .cd_loop_uv_offset = offsets.uv, | ||||
| }; | }; | ||||
| LinkNode *path = NULL; | LinkNode *path = NULL; | ||||
| bool is_path_ordered = false; | bool is_path_ordered = false; | ||||
| if (f_src != f_dst) { | if (f_src != f_dst) { | ||||
| if (op_params->use_fill) { | if (op_params->use_fill) { | ||||
| path = BM_mesh_calc_path_uv_region_face(bm, | path = BM_mesh_calc_path_uv_region_face(bm, | ||||
| ▲ Show 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | |||||
| static bool uv_shortest_path_pick_ex(Scene *scene, | static bool uv_shortest_path_pick_ex(Scene *scene, | ||||
| Depsgraph *depsgraph, | Depsgraph *depsgraph, | ||||
| Object *obedit, | Object *obedit, | ||||
| const struct PathSelectParams *op_params, | const struct PathSelectParams *op_params, | ||||
| BMElem *ele_src, | BMElem *ele_src, | ||||
| BMElem *ele_dst, | BMElem *ele_dst, | ||||
| const float aspect_y, | const float aspect_y, | ||||
| const int cd_loop_uv_offset) | const BMUVOffsets offsets) | ||||
| { | { | ||||
| const ToolSettings *ts = scene->toolsettings; | const ToolSettings *ts = scene->toolsettings; | ||||
| const char uv_selectmode = ED_uvedit_select_mode_get(scene); | const char uv_selectmode = ED_uvedit_select_mode_get(scene); | ||||
| bool ok = false; | bool ok = false; | ||||
| int flush = 0; | int flush = 0; | ||||
| if (ELEM(NULL, ele_src, ele_dst) || (ele_src->head.htype != ele_dst->head.htype)) { | if (ELEM(NULL, ele_src, ele_dst) || (ele_src->head.htype != ele_dst->head.htype)) { | ||||
| /* pass */ | /* pass */ | ||||
| } | } | ||||
| else if (ele_src->head.htype == BM_FACE) { | else if (ele_src->head.htype == BM_FACE) { | ||||
| flush = mouse_mesh_uv_shortest_path_face(scene, | flush = mouse_mesh_uv_shortest_path_face( | ||||
| obedit, | scene, obedit, op_params, (BMFace *)ele_src, (BMFace *)ele_dst, aspect_y, offsets); | ||||
| op_params, | |||||
| (BMFace *)ele_src, | |||||
| (BMFace *)ele_dst, | |||||
| aspect_y, | |||||
| cd_loop_uv_offset); | |||||
| ok = true; | ok = true; | ||||
| } | } | ||||
| else if (ele_src->head.htype == BM_LOOP) { | else if (ele_src->head.htype == BM_LOOP) { | ||||
| if (uv_selectmode & UV_SELECT_EDGE) { | if (uv_selectmode & UV_SELECT_EDGE) { | ||||
| flush = mouse_mesh_uv_shortest_path_edge(scene, | flush = mouse_mesh_uv_shortest_path_edge( | ||||
| obedit, | scene, obedit, op_params, (BMLoop *)ele_src, (BMLoop *)ele_dst, aspect_y, offsets); | ||||
| op_params, | } | ||||
| (BMLoop *)ele_src, | else { | ||||
| (BMLoop *)ele_dst, | flush = mouse_mesh_uv_shortest_path_vert( | ||||
| aspect_y, | scene, obedit, op_params, (BMLoop *)ele_src, (BMLoop *)ele_dst, aspect_y, offsets); | ||||
| cd_loop_uv_offset); | |||||
| } | |||||
| else { | |||||
| flush = mouse_mesh_uv_shortest_path_vert(scene, | |||||
| obedit, | |||||
| op_params, | |||||
| (BMLoop *)ele_src, | |||||
| (BMLoop *)ele_dst, | |||||
| aspect_y, | |||||
| cd_loop_uv_offset); | |||||
| } | } | ||||
| ok = true; | ok = true; | ||||
| } | } | ||||
| if (ok) { | if (ok) { | ||||
| if (flush != 0) { | if (flush != 0) { | ||||
| const bool select = (flush == 1); | const bool select = (flush == 1); | ||||
| BMEditMesh *em = BKE_editmesh_from_object(obedit); | BMEditMesh *em = BKE_editmesh_from_object(obedit); | ||||
| Show All 40 Lines | static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event) | ||||
| float co[2]; | float co[2]; | ||||
| const ARegion *region = CTX_wm_region(C); | const ARegion *region = CTX_wm_region(C); | ||||
| Object *obedit = CTX_data_edit_object(C); | Object *obedit = CTX_data_edit_object(C); | ||||
| BMEditMesh *em = BKE_editmesh_from_object(obedit); | BMEditMesh *em = BKE_editmesh_from_object(obedit); | ||||
| BMesh *bm = em->bm; | BMesh *bm = em->bm; | ||||
| const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); | const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); | ||||
| float aspect_y; | float aspect_y; | ||||
| { | { | ||||
| float aspx, aspy; | float aspx, aspy; | ||||
| ED_uvedit_get_aspect(obedit, &aspx, &aspy); | ED_uvedit_get_aspect(obedit, &aspx, &aspy); | ||||
| aspect_y = aspx / aspy; | aspect_y = aspx / aspy; | ||||
| } | } | ||||
| Show All 25 Lines | if (ts->uv_flag & UV_SYNC_SELECTION) { | ||||
| BMEdge *e_src = BM_mesh_active_edge_get(bm); | BMEdge *e_src = BM_mesh_active_edge_get(bm); | ||||
| if (e_src != NULL) { | if (e_src != NULL) { | ||||
| l_src = uv_find_nearest_loop_from_edge(scene, obedit, e_src, co); | l_src = uv_find_nearest_loop_from_edge(scene, obedit, e_src, co); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| l_src = ED_uvedit_active_edge_loop_get(bm); | l_src = ED_uvedit_active_edge_loop_get(bm); | ||||
| if (l_src != NULL) { | if (l_src != NULL) { | ||||
| if (!uvedit_uv_select_test(scene, l_src, cd_loop_uv_offset) && | if (!uvedit_uv_select_test(scene, l_src, offsets) && | ||||
| !uvedit_uv_select_test(scene, l_src->next, cd_loop_uv_offset)) { | !uvedit_uv_select_test(scene, l_src->next, offsets)) { | ||||
| l_src = NULL; | l_src = NULL; | ||||
| } | } | ||||
| ele_src = (BMElem *)l_src; | ele_src = (BMElem *)l_src; | ||||
| } | } | ||||
| } | } | ||||
| ele_src = (BMElem *)l_src; | ele_src = (BMElem *)l_src; | ||||
| ele_dst = (BMElem *)hit.l; | ele_dst = (BMElem *)hit.l; | ||||
| } | } | ||||
| else { | else { | ||||
| UvNearestHit hit = UV_NEAREST_HIT_INIT_MAX(®ion->v2d); | UvNearestHit hit = UV_NEAREST_HIT_INIT_MAX(®ion->v2d); | ||||
| if (!uv_find_nearest_vert(scene, obedit, co, 0.0f, &hit)) { | if (!uv_find_nearest_vert(scene, obedit, co, 0.0f, &hit)) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| BMLoop *l_src = NULL; | BMLoop *l_src = NULL; | ||||
| if (ts->uv_flag & UV_SYNC_SELECTION) { | if (ts->uv_flag & UV_SYNC_SELECTION) { | ||||
| BMVert *v_src = BM_mesh_active_vert_get(bm); | BMVert *v_src = BM_mesh_active_vert_get(bm); | ||||
| if (v_src != NULL) { | if (v_src != NULL) { | ||||
| l_src = uv_find_nearest_loop_from_vert(scene, obedit, v_src, co); | l_src = uv_find_nearest_loop_from_vert(scene, obedit, v_src, co); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| l_src = ED_uvedit_active_vert_loop_get(bm); | l_src = ED_uvedit_active_vert_loop_get(bm); | ||||
| if (l_src != NULL) { | if (l_src != NULL) { | ||||
| if (!uvedit_uv_select_test(scene, l_src, cd_loop_uv_offset)) { | if (!uvedit_uv_select_test(scene, l_src, offsets)) { | ||||
| l_src = NULL; | l_src = NULL; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| ele_src = (BMElem *)l_src; | ele_src = (BMElem *)l_src; | ||||
| ele_dst = (BMElem *)hit.l; | ele_dst = (BMElem *)hit.l; | ||||
| } | } | ||||
| if (ele_src == NULL || ele_dst == NULL) { | if (ele_src == NULL || ele_dst == NULL) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| uv_shortest_path_pick_ex( | uv_shortest_path_pick_ex( | ||||
| scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, cd_loop_uv_offset); | scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, offsets); | ||||
| /* To support redo. */ | /* To support redo. */ | ||||
| int index; | int index; | ||||
| if (uv_selectmode & UV_SELECT_FACE) { | if (uv_selectmode & UV_SELECT_FACE) { | ||||
| BM_mesh_elem_index_ensure(bm, BM_FACE); | BM_mesh_elem_index_ensure(bm, BM_FACE); | ||||
| index = BM_elem_index_get(ele_dst); | index = BM_elem_index_get(ele_dst); | ||||
| } | } | ||||
| else if (uv_selectmode & UV_SELECT_EDGE) { | else if (uv_selectmode & UV_SELECT_EDGE) { | ||||
| Show All 12 Lines | |||||
| static int uv_shortest_path_pick_exec(bContext *C, wmOperator *op) | static int uv_shortest_path_pick_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); | Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); | ||||
| Scene *scene = CTX_data_scene(C); | Scene *scene = CTX_data_scene(C); | ||||
| const char uv_selectmode = ED_uvedit_select_mode_get(scene); | const char uv_selectmode = ED_uvedit_select_mode_get(scene); | ||||
| Object *obedit = CTX_data_edit_object(C); | Object *obedit = CTX_data_edit_object(C); | ||||
| BMEditMesh *em = BKE_editmesh_from_object(obedit); | BMEditMesh *em = BKE_editmesh_from_object(obedit); | ||||
| BMesh *bm = em->bm; | BMesh *bm = em->bm; | ||||
| const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); | const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); | ||||
| float aspect_y; | float aspect_y; | ||||
| { | { | ||||
| float aspx, aspy; | float aspx, aspy; | ||||
| ED_uvedit_get_aspect(obedit, &aspx, &aspy); | ED_uvedit_get_aspect(obedit, &aspx, &aspy); | ||||
| aspect_y = aspx / aspy; | aspect_y = aspx / aspy; | ||||
| } | } | ||||
| Show All 29 Lines | else { | ||||
| } | } | ||||
| } | } | ||||
| struct PathSelectParams op_params; | struct PathSelectParams op_params; | ||||
| path_select_params_from_op(op, &op_params); | path_select_params_from_op(op, &op_params); | ||||
| op_params.track_active = true; | op_params.track_active = true; | ||||
| if (!uv_shortest_path_pick_ex( | if (!uv_shortest_path_pick_ex( | ||||
| scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, cd_loop_uv_offset)) { | scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, offsets)) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void UV_OT_shortest_path_pick(wmOperatorType *ot) | void UV_OT_shortest_path_pick(wmOperatorType *ot) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | static int uv_shortest_path_select_exec(bContext *C, wmOperator *op) | ||||
| ViewLayer *view_layer = CTX_data_view_layer(C); | ViewLayer *view_layer = CTX_data_view_layer(C); | ||||
| uint objects_len = 0; | uint objects_len = 0; | ||||
| Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data( | Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data( | ||||
| scene, view_layer, CTX_wm_view3d(C), &objects_len); | scene, view_layer, CTX_wm_view3d(C), &objects_len); | ||||
| for (uint ob_index = 0; ob_index < objects_len; ob_index++) { | for (uint ob_index = 0; ob_index < objects_len; ob_index++) { | ||||
| Object *obedit = objects[ob_index]; | Object *obedit = objects[ob_index]; | ||||
| BMEditMesh *em = BKE_editmesh_from_object(obedit); | BMEditMesh *em = BKE_editmesh_from_object(obedit); | ||||
| BMesh *bm = em->bm; | BMesh *bm = em->bm; | ||||
| const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); | |||||
| const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); | |||||
| BMElem *ele_src = NULL, *ele_dst = NULL; | BMElem *ele_src = NULL, *ele_dst = NULL; | ||||
| /* Find 2x elements. */ | /* Find 2x elements. */ | ||||
| { | { | ||||
| BMElem **ele_array = NULL; | BMElem **ele_array = NULL; | ||||
| int ele_array_len = 0; | int ele_array_len = 0; | ||||
| if (uv_selectmode & UV_SELECT_FACE) { | if (uv_selectmode & UV_SELECT_FACE) { | ||||
| ele_array = (BMElem **)ED_uvedit_selected_faces(scene, bm, 3, &ele_array_len); | ele_array = (BMElem **)ED_uvedit_selected_faces(scene, bm, 3, &ele_array_len); | ||||
| Show All 12 Lines | /* Find 2x elements. */ | ||||
| MEM_freeN(ele_array); | MEM_freeN(ele_array); | ||||
| } | } | ||||
| if (ele_src && ele_dst) { | if (ele_src && ele_dst) { | ||||
| struct PathSelectParams op_params; | struct PathSelectParams op_params; | ||||
| path_select_params_from_op(op, &op_params); | path_select_params_from_op(op, &op_params); | ||||
| uv_shortest_path_pick_ex( | uv_shortest_path_pick_ex( | ||||
| scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, cd_loop_uv_offset); | scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, offsets); | ||||
| found_valid_elements = true; | found_valid_elements = true; | ||||
| } | } | ||||
| } | } | ||||
| MEM_freeN(objects); | MEM_freeN(objects); | ||||
| if (!found_valid_elements) { | if (!found_valid_elements) { | ||||
| BKE_report( | BKE_report( | ||||
| Show All 26 Lines | |||||