diff options
Diffstat (limited to 'source/blender/editors/transform/transform_mode_translate.c')
-rw-r--r-- | source/blender/editors/transform/transform_mode_translate.c | 71 |
1 files changed, 67 insertions, 4 deletions
diff --git a/source/blender/editors/transform/transform_mode_translate.c b/source/blender/editors/transform/transform_mode_translate.c index c881cde351e..67bdeb3fed0 100644 --- a/source/blender/editors/transform/transform_mode_translate.c +++ b/source/blender/editors/transform/transform_mode_translate.c @@ -16,6 +16,7 @@ #include "BLI_task.h" #include "BKE_context.h" +#include "BKE_image.h" #include "BKE_report.h" #include "BKE_unit.h" @@ -434,6 +435,60 @@ static void applyTranslationValue(TransInfo *t, const float vec[3]) custom_data->prev.rotate_mode = rotate_mode; } +static bool clip_uv_transform_translation(TransInfo *t, float vec[2]) +{ + /* Check if the current image in UV editor is a tiled image or not. */ + const SpaceImage *sima = t->area->spacedata.first; + const Image *image = sima->image; + const bool is_tiled_image = image && (image->source == IMA_SRC_TILED); + + /* Stores the coordinates of the closest UDIM tile. + * Also acts as an offset to the tile from the origin of UV space. */ + float base_offset[2] = {0.0f, 0.0f}; + + /* If tiled image then constrain to correct/closest UDIM tile, else 0-1 UV space. */ + if (is_tiled_image) { + int nearest_tile_index = BKE_image_find_nearest_tile(image, t->center_global); + if (nearest_tile_index != -1) { + nearest_tile_index -= 1001; + /* Getting coordinates of nearest tile from the tile index. */ + base_offset[0] = nearest_tile_index % 10; + base_offset[1] = nearest_tile_index / 10; + } + } + + float min[2], max[2]; + min[0] = min[1] = FLT_MAX; + max[0] = max[1] = -FLT_MAX; + + FOREACH_TRANS_DATA_CONTAINER (t, tc) { + for (TransData *td = tc->data; td < tc->data + tc->data_len; td++) { + minmax_v2v2_v2(min, max, td->loc); + } + } + + bool result = false; + if (min[0] < base_offset[0]) { + vec[0] += base_offset[0] - min[0]; + result = true; + } + else if (max[0] > base_offset[0] + t->aspect[0]) { + vec[0] -= max[0] - base_offset[0] - t->aspect[0]; + result = true; + } + + if (min[1] < base_offset[1]) { + vec[1] += base_offset[1] - min[1]; + result = true; + } + else if (max[1] > base_offset[1] + t->aspect[1]) { + vec[1] -= max[1] - base_offset[1] - t->aspect[1]; + result = true; + } + + return result; +} + static void applyTranslation(TransInfo *t, const int UNUSED(mval[2])) { char str[UI_MAX_DRAW_STR]; @@ -469,8 +524,8 @@ static void applyTranslation(TransInfo *t, const int UNUSED(mval[2])) add_v3_v3(global_dir, values_ofs); } - t->tsnap.snapElem = 0; - applySnapping(t, global_dir); + t->tsnap.snapElem = SCE_SNAP_MODE_NONE; + applySnappingAsGroup(t, global_dir); transform_snap_grid(t, global_dir); if (t->con.mode & CON_APPLY) { @@ -486,7 +541,7 @@ static void applyTranslation(TransInfo *t, const int UNUSED(mval[2])) /* Test for mixed snap with grid. */ float snap_dist_sq = FLT_MAX; - if (t->tsnap.snapElem != 0) { + if (t->tsnap.snapElem != SCE_SNAP_MODE_NONE) { snap_dist_sq = len_squared_v3v3(t->values, global_dir); } if ((snap_dist_sq == FLT_MAX) || (len_squared_v3v3(global_dir, incr_dir) < snap_dist_sq)) { @@ -498,7 +553,7 @@ static void applyTranslation(TransInfo *t, const int UNUSED(mval[2])) applyTranslationValue(t, global_dir); /* evil hack - redo translation if clipping needed */ - if (t->flag & T_CLIP_UV && clipUVTransform(t, global_dir, 0)) { + if (t->flag & T_CLIP_UV && clip_uv_transform_translation(t, global_dir)) { applyTranslationValue(t, global_dir); /* In proportional edit it can happen that */ @@ -518,6 +573,13 @@ static void applyTranslation(TransInfo *t, const int UNUSED(mval[2])) ED_area_status_text(t->area, str); } +static void applyTranslationMatrix(TransInfo *t, float mat_xform[4][4]) +{ + float delta[3]; + mul_v3_m3v3(delta, t->spacemtx, t->values_final); + add_v3_v3(mat_xform[3], delta); +} + void initTranslation(TransInfo *t) { if (t->spacetype == SPACE_ACTION) { @@ -530,6 +592,7 @@ void initTranslation(TransInfo *t) } t->transform = applyTranslation; + t->transform_matrix = applyTranslationMatrix; t->tsnap.applySnap = ApplySnapTranslation; t->tsnap.distance = transform_snap_distance_len_squared_fn; |