[Bf-blender-cvs] [a0706d6cf00] master: Fix T102680: UV Pick shortest Path wrong for multi-object editing
Campbell Barton
noreply at git.blender.org
Fri Jan 20 04:04:57 CET 2023
Commit: a0706d6cf0000813568c05ebae1dfabf9c721002
Author: Campbell Barton
Date: Fri Jan 20 12:51:50 2023 +1100
Branches: master
https://developer.blender.org/rBa0706d6cf0000813568c05ebae1dfabf9c721002
Fix T102680: UV Pick shortest Path wrong for multi-object editing
Path selection support from [0] didn't account for multiple objects in
edit-mode. Now picking the UV also picks the object to operate on.
[0]: ea5fe7abc183c1e53d327f97280f589499fe60bb
===================================================================
M source/blender/editors/uvedit/uvedit_path.c
===================================================================
diff --git a/source/blender/editors/uvedit/uvedit_path.c b/source/blender/editors/uvedit/uvedit_path.c
index 82d8c536fba..1e50ddba3a3 100644
--- a/source/blender/editors/uvedit/uvedit_path.c
+++ b/source/blender/editors/uvedit/uvedit_path.c
@@ -38,6 +38,7 @@
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
+#include "ED_object.h"
#include "ED_screen.h"
#include "ED_transform.h"
#include "ED_uvedit.h"
@@ -559,135 +560,158 @@ static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEve
op_params.track_active = true;
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ 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(
+ scene, view_layer, CTX_wm_view3d(C), &objects_len);
float co[2];
const ARegion *region = CTX_wm_region(C);
- Object *obedit = CTX_data_edit_object(C);
- BMEditMesh *em = BKE_editmesh_from_object(obedit);
- BMesh *bm = em->bm;
- const BMUVOffsets offsets = BM_uv_map_get_offsets(bm);
-
- float aspect_y;
- {
- float aspx, aspy;
- ED_uvedit_get_aspect(obedit, &aspx, &aspy);
- aspect_y = aspx / aspy;
- }
-
UI_view2d_region_to_view(®ion->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
BMElem *ele_src = NULL, *ele_dst = NULL;
+ /* Detect the hit. */
+ UvNearestHit hit = UV_NEAREST_HIT_INIT_MAX(®ion->v2d);
+ bool hit_found = false;
if (uv_selectmode == UV_SELECT_FACE) {
- UvNearestHit hit = UV_NEAREST_HIT_INIT_MAX(®ion->v2d);
- if (!uv_find_nearest_face(scene, obedit, co, &hit)) {
- return OPERATOR_CANCELLED;
+ if (uv_find_nearest_face_multi(scene, objects, objects_len, co, &hit)) {
+ hit_found = true;
}
-
- BMFace *f_src = BM_mesh_active_face_get(bm, false, false);
- /* Check selection? */
-
- ele_src = (BMElem *)f_src;
- ele_dst = (BMElem *)hit.efa;
}
-
else if (uv_selectmode & UV_SELECT_EDGE) {
- UvNearestHit hit = UV_NEAREST_HIT_INIT_MAX(®ion->v2d);
- if (!uv_find_nearest_edge(scene, obedit, co, 0.0f, &hit)) {
- return OPERATOR_CANCELLED;
- }
-
- BMLoop *l_src = NULL;
- if (ts->uv_flag & UV_SYNC_SELECTION) {
- BMEdge *e_src = BM_mesh_active_edge_get(bm);
- if (e_src != NULL) {
- l_src = uv_find_nearest_loop_from_edge(scene, obedit, e_src, co);
- }
+ if (uv_find_nearest_edge_multi(scene, objects, objects_len, co, 0.0f, &hit)) {
+ hit_found = true;
}
- else {
- l_src = ED_uvedit_active_edge_loop_get(bm);
- if (l_src != NULL) {
- if (!uvedit_uv_select_test(scene, l_src, offsets) &&
- !uvedit_uv_select_test(scene, l_src->next, offsets)) {
- l_src = NULL;
- }
- ele_src = (BMElem *)l_src;
- }
- }
- ele_src = (BMElem *)l_src;
- ele_dst = (BMElem *)hit.l;
}
else {
- UvNearestHit hit = UV_NEAREST_HIT_INIT_MAX(®ion->v2d);
- if (!uv_find_nearest_vert(scene, obedit, co, 0.0f, &hit)) {
- return OPERATOR_CANCELLED;
+ if (uv_find_nearest_vert_multi(scene, objects, objects_len, co, 0.0f, &hit)) {
+ hit_found = true;
}
+ }
- BMLoop *l_src = NULL;
- if (ts->uv_flag & UV_SYNC_SELECTION) {
- BMVert *v_src = BM_mesh_active_vert_get(bm);
- if (v_src != NULL) {
- l_src = uv_find_nearest_loop_from_vert(scene, obedit, v_src, co);
+ bool changed = false;
+ if (hit_found) {
+ /* This may not be the active object. */
+ Object *obedit = hit.ob;
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMesh *bm = em->bm;
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(bm);
+
+ /* Respond to the hit. */
+ if (uv_selectmode == UV_SELECT_FACE) {
+ /* Face selection. */
+ BMFace *f_src = BM_mesh_active_face_get(bm, false, false);
+ /* Check selection? */
+ ele_src = (BMElem *)f_src;
+ ele_dst = (BMElem *)hit.efa;
+ }
+ else if (uv_selectmode & UV_SELECT_EDGE) {
+ /* Edge selection. */
+ BMLoop *l_src = NULL;
+ if (ts->uv_flag & UV_SYNC_SELECTION) {
+ BMEdge *e_src = BM_mesh_active_edge_get(bm);
+ if (e_src != NULL) {
+ l_src = uv_find_nearest_loop_from_edge(scene, obedit, e_src, co);
+ }
+ }
+ else {
+ l_src = ED_uvedit_active_edge_loop_get(bm);
+ if (l_src != NULL) {
+ if (!uvedit_uv_select_test(scene, l_src, offsets) &&
+ !uvedit_uv_select_test(scene, l_src->next, offsets)) {
+ l_src = NULL;
+ }
+ ele_src = (BMElem *)l_src;
+ }
}
+ ele_src = (BMElem *)l_src;
+ ele_dst = (BMElem *)hit.l;
}
else {
- l_src = ED_uvedit_active_vert_loop_get(bm);
- if (l_src != NULL) {
- if (!uvedit_uv_select_test(scene, l_src, offsets)) {
- l_src = NULL;
+ /* Vertex selection. */
+ BMLoop *l_src = NULL;
+ if (ts->uv_flag & UV_SYNC_SELECTION) {
+ BMVert *v_src = BM_mesh_active_vert_get(bm);
+ if (v_src != NULL) {
+ l_src = uv_find_nearest_loop_from_vert(scene, obedit, v_src, co);
}
}
+ else {
+ l_src = ED_uvedit_active_vert_loop_get(bm);
+ if (l_src != NULL) {
+ if (!uvedit_uv_select_test(scene, l_src, offsets)) {
+ l_src = NULL;
+ }
+ }
+ }
+ ele_src = (BMElem *)l_src;
+ ele_dst = (BMElem *)hit.l;
}
- ele_src = (BMElem *)l_src;
- ele_dst = (BMElem *)hit.l;
- }
- if (ele_src == NULL || ele_dst == NULL) {
- return OPERATOR_CANCELLED;
- }
+ if (ele_src && ele_dst) {
+ /* Always use the active object, not `obedit` as the active defines the UV display. */
+ float aspect_y;
+ {
+ float aspx, aspy;
+ ED_uvedit_get_aspect(CTX_data_edit_object(C), &aspx, &aspy);
+ aspect_y = aspx / aspy;
+ }
- uv_shortest_path_pick_ex(
- scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, offsets);
+ uv_shortest_path_pick_ex(
+ scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, offsets);
- /* To support redo. */
- int index;
- if (uv_selectmode & UV_SELECT_FACE) {
- BM_mesh_elem_index_ensure(bm, BM_FACE);
- index = BM_elem_index_get(ele_dst);
- }
- else if (uv_selectmode & UV_SELECT_EDGE) {
- BM_mesh_elem_index_ensure(bm, BM_LOOP);
- index = BM_elem_index_get(ele_dst);
- }
- else {
- BM_mesh_elem_index_ensure(bm, BM_LOOP);
- index = BM_elem_index_get(ele_dst);
+ /* Store the object and it's index so redo is possible. */
+ int index;
+ if (uv_selectmode & UV_SELECT_FACE) {
+ BM_mesh_elem_index_ensure(bm, BM_FACE);
+ index = BM_elem_index_get(ele_dst);
+ }
+ else if (uv_selectmode & UV_SELECT_EDGE) {
+ BM_mesh_elem_index_ensure(bm, BM_LOOP);
+ index = BM_elem_index_get(ele_dst);
+ }
+ else {
+ BM_mesh_elem_index_ensure(bm, BM_LOOP);
+ index = BM_elem_index_get(ele_dst);
+ }
+
+ const int object_index = ED_object_in_mode_to_index(scene, view_layer, OB_MODE_EDIT, obedit);
+ BLI_assert(object_index != -1);
+ RNA_int_set(op->ptr, "object_index", object_index);
+ RNA_int_set(op->ptr, "index", index);
+ changed = true;
+ }
}
- RNA_int_set(op->ptr, "index", index);
- return OPERATOR_FINISHED;
+ MEM_freeN(objects);
+
+ return changed ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
static int uv_shortest_path_pick_exec(bContext *C, wmOperator *op)
{
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
const char uv_selectmode = ED_uvedit_select_mode_get(scene);
- Object *obedit = CTX_data_edit_object(C);
- BMEditMesh *em = BKE_editmesh_from_object(obedit);
- BMesh *bm = em->bm;
- const BMUVOffsets offsets = BM_uv_map_get_offsets(bm);
- float aspect_y;
- {
- float aspx, aspy;
- ED_uvedit_get_aspect(obedit, &aspx, &aspy);
- aspect_y = aspx / aspy;
+ const int object_index = RNA_int_get(op->ptr, "object_index");
+ const int index = RNA_int_get(op->ptr, "index");
+ if (object_index == -1) {
+ return OPERATOR_CANCELLED;
}
- const int index = RNA_int_get(op->ptr, "index");
+ Object *obedit = ED_object_in_mode_from_index(scene, view_layer, OB_MODE_EDIT, object_index);
+ if (obedit == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMesh *bm = em->bm;
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(bm);
BMElem *ele_src, *ele_dst;
@@ -719,6 +743,14 @@ static int uv_shortest_path_pick_exec(bContext *C, wmOperator *op)
}
}
+ /* Always use the active object, not `obedit` as the active defines the UV display. */
+ float aspect_y;
+ {
+ float aspx, aspy;
+ ED_uvedit_get_aspect(CTX_data_edit_object(C), &aspx, &aspy);
+ aspect_y = aspx / aspy;
+ }
+
struct PathSelectParams op_params;
path_select_params_from_op(op, &op_params);
op_params.track_active = true;
@@ -752,6 +784,8 @@ void UV_OT_shortest_path_pick(wmOperatorType *ot)
path_select_properties(ot);
/* use for redo */
+ prop = RNA_def_int(ot->srna, "object_index", -1, -1, INT_MAX, "", "", 0, INT_MAX);
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
prop = RNA_def_int(ot->srna, "index", -1, -1, INT_MAX, "", "", 0, INT_MAX);
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
}
More information about the Bf-blender-cvs
mailing list