diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt_uv.c | 2 | ||||
-rw-r--r-- | source/blender/editors/uvedit/uvedit_intern.h | 26 | ||||
-rw-r--r-- | source/blender/editors/uvedit/uvedit_ops.c | 22 | ||||
-rw-r--r-- | source/blender/editors/uvedit/uvedit_path.c | 8 | ||||
-rw-r--r-- | source/blender/editors/uvedit/uvedit_select.c | 73 | ||||
-rw-r--r-- | source/blender/editors/uvedit/uvedit_smart_stitch.c | 2 |
6 files changed, 64 insertions, 69 deletions
diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c index f77d473ae57..219a8303674 100644 --- a/source/blender/editors/sculpt_paint/sculpt_uv.c +++ b/source/blender/editors/sculpt_paint/sculpt_uv.c @@ -543,7 +543,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm /* we need to find the active island here */ if (do_island_optimization) { UvElement *element; - UvNearestHit hit = UV_NEAREST_HIT_INIT; + UvNearestHit hit = UV_NEAREST_HIT_INIT_MAX(®ion->v2d); uv_find_nearest_vert(scene, obedit, co, 0.0f, &hit); element = BM_uv_element_get(data->elementMap, hit.efa, hit.l); diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h index 28567234fab..6fef7ebcf22 100644 --- a/source/blender/editors/uvedit/uvedit_intern.h +++ b/source/blender/editors/uvedit/uvedit_intern.h @@ -41,13 +41,34 @@ typedef struct UvNearestHit { /** Always set if we have a hit. */ struct BMFace *efa; struct BMLoop *l; - /** Needs to be set before calling nearest functions. */ + /** + * Needs to be set before calling nearest functions. + * + * \note When #UV_NEAREST_HIT_INIT_DIST_PX or #UV_NEAREST_HIT_INIT_MAX are used, + * this value is pixels squared. + */ float dist_sq; + + /** Scale the UV's to account for aspect ratio from the image view. */ + float scale[2]; } UvNearestHit; -#define UV_NEAREST_HIT_INIT \ +#define UV_NEAREST_HIT_INIT_DIST_PX(v2d, dist_px) \ + { \ + .dist_sq = square_f(U.pixelsize * dist_px), \ + .scale = { \ + UI_view2d_scale_get_x(v2d), \ + UI_view2d_scale_get_y(v2d), \ + }, \ + } + +#define UV_NEAREST_HIT_INIT_MAX(v2d) \ { \ .dist_sq = FLT_MAX, \ + .scale = { \ + UI_view2d_scale_get_x(v2d), \ + UI_view2d_scale_get_y(v2d), \ + }, \ } bool uv_find_nearest_vert(struct Scene *scene, @@ -96,7 +117,6 @@ BMLoop *uv_find_nearest_loop_from_edge(struct Scene *scene, void uvedit_live_unwrap_update(struct SpaceImage *sima, struct Scene *scene, struct Object *obedit); -void uvedit_pixel_to_float(struct SpaceImage *sima, float pixeldist, float r_dist[2]); /* operators */ diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index aac5b96f737..167acf7da18 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -187,28 +187,6 @@ void ED_object_assign_active_image(Main *bmain, Object *ob, int mat_nr, Image *i /** \} */ /* -------------------------------------------------------------------- */ -/** \name Space Conversion - * \{ */ - -void uvedit_pixel_to_float(SpaceImage *sima, float pixeldist, float r_dist[2]) -{ - int width, height; - - if (sima) { - ED_space_image_get_size(sima, &width, &height); - } - else { - width = IMG_SIZE_FALLBACK; - height = IMG_SIZE_FALLBACK; - } - - r_dist[0] = pixeldist / width; - r_dist[1] = pixeldist / height; -} - -/** \} */ - -/* -------------------------------------------------------------------- */ /** \name Live Unwrap Utilities * \{ */ diff --git a/source/blender/editors/uvedit/uvedit_path.c b/source/blender/editors/uvedit/uvedit_path.c index 51de199c696..016a054cf21 100644 --- a/source/blender/editors/uvedit/uvedit_path.c +++ b/source/blender/editors/uvedit/uvedit_path.c @@ -574,7 +574,7 @@ static bool uv_shortest_path_pick_ex(const SpaceImage *sima, static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - const SpaceImage *sima = CTX_wm_space_image(C); + SpaceImage *sima = CTX_wm_space_image(C); Scene *scene = CTX_data_scene(C); const ToolSettings *ts = scene->toolsettings; const char uv_selectmode = ED_uvedit_select_mode_get(scene); @@ -613,7 +613,7 @@ static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEve BMElem *ele_src = NULL, *ele_dst = NULL; if (uv_selectmode == UV_SELECT_FACE) { - UvNearestHit hit = UV_NEAREST_HIT_INIT; + UvNearestHit hit = UV_NEAREST_HIT_INIT_MAX(®ion->v2d); if (!uv_find_nearest_face(scene, obedit, co, &hit)) { return OPERATOR_CANCELLED; } @@ -626,7 +626,7 @@ static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEve } else if (uv_selectmode & UV_SELECT_EDGE) { - UvNearestHit hit = UV_NEAREST_HIT_INIT; + UvNearestHit hit = UV_NEAREST_HIT_INIT_MAX(®ion->v2d); if (!uv_find_nearest_edge(scene, obedit, co, &hit)) { return OPERATOR_CANCELLED; } @@ -652,7 +652,7 @@ static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEve ele_dst = (BMElem *)hit.l; } else { - UvNearestHit hit = UV_NEAREST_HIT_INIT; + UvNearestHit hit = UV_NEAREST_HIT_INIT_MAX(®ion->v2d); if (!uv_find_nearest_vert(scene, obedit, co, 0.0f, &hit)) { return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/uvedit/uvedit_select.c b/source/blender/editors/uvedit/uvedit_select.c index bfb01cb073e..118a2263cc3 100644 --- a/source/blender/editors/uvedit/uvedit_select.c +++ b/source/blender/editors/uvedit/uvedit_select.c @@ -201,21 +201,6 @@ void ED_uvedit_select_sync_flush(const ToolSettings *ts, BMEditMesh *em, const b } } -/** - * Apply a penalty to elements that are already selected - * so elements that aren't already selected are prioritized. - * - * \note This is calculated in screen-space otherwise zooming in on a uv-vert and - * shift-selecting can consider an adjacent point close enough to add to - * the selection rather than de-selecting the closest. - */ -static float uv_select_penalty_default(SpaceImage *sima) -{ - float penalty[2]; - uvedit_pixel_to_float(sima, 5.0f / (sima ? sima->zoom : 1.0f), penalty); - return len_v2(penalty); -} - static void uvedit_vertex_select_tagged(BMEditMesh *em, Scene *scene, bool select, @@ -680,6 +665,7 @@ static BMLoop *uvedit_loop_find_other_boundary_loop_with_visible_face(const Scen bool uv_find_nearest_edge(Scene *scene, Object *obedit, const float co[2], UvNearestHit *hit) { + BLI_assert((hit->scale[0] > 0.0f) && (hit->scale[1] > 0.0f)); BMEditMesh *em = BKE_editmesh_from_object(obedit); BMFace *efa; BMLoop *l; @@ -700,7 +686,13 @@ bool uv_find_nearest_edge(Scene *scene, Object *obedit, const float co[2], UvNea luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset); - const float dist_test_sq = dist_squared_to_line_segment_v2(co, luv->uv, luv_next->uv); + float delta[2]; + closest_to_line_segment_v2(delta, co, luv->uv, luv_next->uv); + + sub_v2_v2(delta, co); + mul_v2_v2(delta, hit->scale); + + const float dist_test_sq = len_squared_v2(delta); if (dist_test_sq < hit->dist_sq) { hit->efa = efa; @@ -734,6 +726,7 @@ bool uv_find_nearest_edge_multi(Scene *scene, bool uv_find_nearest_face(Scene *scene, Object *obedit, const float co[2], UvNearestHit *hit_final) { + BLI_assert((hit_final->scale[0] > 0.0f) && (hit_final->scale[1] > 0.0f)); BMEditMesh *em = BKE_editmesh_from_object(obedit); bool found = false; @@ -757,7 +750,11 @@ bool uv_find_nearest_face(Scene *scene, Object *obedit, const float co[2], UvNea float cent[2]; BM_face_uv_calc_center_median(efa, cd_loop_uv_offset, cent); - const float dist_test_sq = len_squared_v2v2(co, cent); + float delta[2]; + sub_v2_v2v2(delta, co, cent); + mul_v2_v2(delta, hit.scale); + + const float dist_test_sq = len_squared_v2(delta); if (dist_test_sq < hit.dist_sq) { hit.efa = efa; @@ -805,9 +802,10 @@ bool uv_find_nearest_vert(Scene *scene, const float penalty_dist, UvNearestHit *hit_final) { + BLI_assert((hit_final->scale[0] > 0.0f) && (hit_final->scale[1] > 0.0f)); bool found = false; - /* this will fill in hit.vert1 and hit.vert2 */ + /* This will fill in `hit.l`. */ float dist_sq_init = hit_final->dist_sq; UvNearestHit hit = *hit_final; if (uv_find_nearest_edge(scene, obedit, co, &hit)) { @@ -832,14 +830,17 @@ bool uv_find_nearest_vert(Scene *scene, BMLoop *l; int i; BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { - float dist_test_sq; MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if (penalty_dist != 0.0f && uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { - dist_test_sq = len_v2v2(co, luv->uv) + penalty_dist; - dist_test_sq = square_f(dist_test_sq); - } - else { - dist_test_sq = len_squared_v2v2(co, luv->uv); + + float delta[2]; + + sub_v2_v2v2(delta, co, luv->uv); + mul_v2_v2(delta, hit.scale); + + float dist_test_sq = len_squared_v2(delta); + + if ((penalty_dist != 0.0f) && uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { + dist_test_sq = square_f(sqrtf(dist_test_sq) + penalty_dist); } if (dist_test_sq <= hit.dist_sq) { @@ -1912,15 +1913,18 @@ static int uv_mouse_select_multi(bContext *C, { Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); SpaceImage *sima = CTX_wm_space_image(C); + const ARegion *region = CTX_wm_region(C); Scene *scene = CTX_data_scene(C); const ToolSettings *ts = scene->toolsettings; - UvNearestHit hit = UV_NEAREST_HIT_INIT; + UvNearestHit hit = UV_NEAREST_HIT_INIT_DIST_PX(®ion->v2d, 75.0f); int selectmode, sticky; bool found_item = false; /* 0 == don't flush, 1 == sel, -1 == desel; only use when selection sync is enabled */ int flush = 0; - const float penalty_dist = uv_select_penalty_default(sima); + /* Penalty (in pixels) applied to elements that are already selected + * so elements that aren't already selected are prioritized. */ + const float penalty_dist = 3.0f * U.pixelsize; /* retrieve operation mode */ if (ts->uv_flag & UV_SYNC_SELECTION) { @@ -1945,8 +1949,6 @@ static int uv_mouse_select_multi(bContext *C, if (selectmode == UV_SELECT_VERTEX) { /* find vertex */ found_item = uv_find_nearest_vert_multi(scene, objects, objects_len, co, penalty_dist, &hit); - found_item = found_item && (!deselect_all || hit.dist_sq < penalty_dist); - if (found_item) { if ((ts->uv_flag & UV_SYNC_SELECTION) == 0) { BMesh *bm = BKE_editmesh_from_object(hit.ob)->bm; @@ -1957,8 +1959,6 @@ static int uv_mouse_select_multi(bContext *C, else if (selectmode == UV_SELECT_EDGE) { /* find edge */ found_item = uv_find_nearest_edge_multi(scene, objects, objects_len, co, &hit); - found_item = found_item && (!deselect_all || hit.dist_sq < penalty_dist); - if (found_item) { if ((ts->uv_flag & UV_SYNC_SELECTION) == 0) { BMesh *bm = BKE_editmesh_from_object(hit.ob)->bm; @@ -1969,8 +1969,6 @@ static int uv_mouse_select_multi(bContext *C, else if (selectmode == UV_SELECT_FACE) { /* find face */ found_item = uv_find_nearest_face_multi(scene, objects, objects_len, co, &hit); - found_item = found_item && (!deselect_all || hit.dist_sq < penalty_dist); - if (found_item) { BMesh *bm = BKE_editmesh_from_object(hit.ob)->bm; BM_mesh_active_face_set(bm, hit.efa); @@ -1978,7 +1976,6 @@ static int uv_mouse_select_multi(bContext *C, } else if (selectmode == UV_SELECT_ISLAND) { found_item = uv_find_nearest_edge_multi(scene, objects, objects_len, co, &hit); - found_item = found_item && (!deselect_all || hit.dist_sq < penalty_dist); } if (!found_item) { @@ -2173,10 +2170,11 @@ static int uv_mouse_select_loop_generic_multi(bContext *C, enum eUVLoopGenericType loop_type) { SpaceImage *sima = CTX_wm_space_image(C); + const ARegion *region = CTX_wm_region(C); Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); Scene *scene = CTX_data_scene(C); const ToolSettings *ts = scene->toolsettings; - UvNearestHit hit = UV_NEAREST_HIT_INIT; + UvNearestHit hit = UV_NEAREST_HIT_INIT_MAX(®ion->v2d); bool found_item = false; /* 0 == don't flush, 1 == sel, -1 == desel; only use when selection sync is enabled */ int flush = 0; @@ -2367,6 +2365,7 @@ void UV_OT_select_edge_ring(wmOperatorType *ot) static int uv_select_linked_internal(bContext *C, wmOperator *op, const wmEvent *event, bool pick) { + const ARegion *region = CTX_wm_region(C); Scene *scene = CTX_data_scene(C); const ToolSettings *ts = scene->toolsettings; ViewLayer *view_layer = CTX_data_view_layer(C); @@ -2374,7 +2373,7 @@ static int uv_select_linked_internal(bContext *C, wmOperator *op, const wmEvent bool deselect = false; bool select_faces = (ts->uv_flag & UV_SYNC_SELECTION) && (ts->selectmode & SCE_SELECT_FACE); - UvNearestHit hit = UV_NEAREST_HIT_INIT; + UvNearestHit hit = UV_NEAREST_HIT_INIT_MAX(®ion->v2d); if (pick) { extend = RNA_boolean_get(op->ptr, "extend"); @@ -2390,8 +2389,6 @@ static int uv_select_linked_internal(bContext *C, wmOperator *op, const wmEvent if (event) { /* invoke */ - const ARegion *region = CTX_wm_region(C); - UI_view2d_region_to_view(®ion->v2d, event->mval[0], event->mval[1], &co[0], &co[1]); RNA_float_set_array(op->ptr, "location", co); } diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index c1d222c9368..7b27bb570cc 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -2539,8 +2539,8 @@ static StitchState *stitch_select(bContext *C, { /* add uv under mouse to processed uv's */ float co[2]; - UvNearestHit hit = UV_NEAREST_HIT_INIT; ARegion *region = CTX_wm_region(C); + UvNearestHit hit = UV_NEAREST_HIT_INIT_MAX(®ion->v2d); UI_view2d_region_to_view(®ion->v2d, event->mval[0], event->mval[1], &co[0], &co[1]); |