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:
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_uv.c2
-rw-r--r--source/blender/editors/uvedit/uvedit_intern.h26
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c22
-rw-r--r--source/blender/editors/uvedit/uvedit_path.c8
-rw-r--r--source/blender/editors/uvedit/uvedit_select.c73
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c2
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(&region->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(&region->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(&region->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(&region->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(&region->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(&region->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(&region->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(&region->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(&region->v2d);
UI_view2d_region_to_view(&region->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);