Commit: c1f7f18a8e6c82fddaa6ec06b7b78e3d2c64a1c8 Author: Siddhartha Jejurkar Date: Thu May 13 00:08:16 2021 +1000 Branches: blender-v2.93-release https://developer.blender.org/rBc1f7f18a8e6c82fddaa6ec06b7b78e3d2c64a1c8
Fix T81247: Constrain selected UVs to correct UDIM With Constrain to Image Bounds selected, UVs will be constrained to the correct/closest UDIM if the image is tiled. UVs will be constrained to the 0-1 UV space if the image is not tiled. This will override the present behavior of always constraining selected UVs to the 0-1 UV space (UDIM 1001). Reviewed By: campbellbarton Ref D11202 =================================================================== M source/blender/blenkernel/BKE_image.h M source/blender/blenkernel/intern/image.c M source/blender/editors/transform/transform_convert.c =================================================================== diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index c51a5f7e5e1..d298e5dcf6d 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -325,6 +325,7 @@ int BKE_image_get_tile_from_pos(struct Image *ima, const float uv[2], float r_uv[2], float r_ofs[2]); +int BKE_image_find_nearest_tile(const struct Image *image, const float co[2]); void BKE_image_get_size(struct Image *image, struct ImageUser *iuser, int *r_width, int *r_height); void BKE_image_get_size_fl(struct Image *image, struct ImageUser *iuser, float r_size[2]); diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 368b1c2e66b..2f7e2b41a73 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -735,6 +735,37 @@ int BKE_image_get_tile_from_pos(struct Image *ima, return tile_number; } +/** + * Return the tile_number for the closest UDIM tile. + */ +int BKE_image_find_nearest_tile(const Image *image, const float co[2]) +{ + const float co_floor[2] = {floorf(co[0]), floorf(co[1])}; + /* Distance to the closest UDIM tile. */ + float dist_best_sq = FLT_MAX; + int tile_number_best = -1; + + LISTBASE_FOREACH (const ImageTile *, tile, &image->tiles) { + const int tile_index = tile->tile_number - 1001; + /* Coordinates of the current tile. */ + const float tile_index_co[2] = {tile_index % 10, tile_index / 10}; + + if (equals_v2v2(co_floor, tile_index_co)) { + return tile->tile_number; + } + + /* Distance between co[2] and UDIM tile. */ + const float dist_sq = len_squared_v2v2(tile_index_co, co); + + if (dist_sq < dist_best_sq) { + dist_best_sq = dist_sq; + tile_number_best = tile->tile_number; + } + } + + return tile_number_best; +} + static void image_init_color_management(Image *ima) { ImBuf *ibuf; diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c index c021c084a23..7239bed1eeb 100644 --- a/source/blender/editors/transform/transform_convert.c +++ b/source/blender/editors/transform/transform_convert.c @@ -37,6 +37,7 @@ #include "BKE_context.h" #include "BKE_fcurve.h" #include "BKE_global.h" +#include "BKE_image.h" #include "BKE_layer.h" #include "BKE_lib_id.h" #include "BKE_main.h" @@ -505,9 +506,27 @@ bool clipUVTransform(TransInfo *t, float vec[2], const bool resize) bool clipx = true, clipy = true; float min[2], max[2]; - min[0] = min[1] = 0.0f; - max[0] = t->aspect[0]; - max[1] = t->aspect[1]; + /* 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; + } + } + + min[0] = min[1] = FLT_MAX; + max[0] = max[1] = FLT_MIN; FOREACH_TRANS_DATA_CONTAINER (t, tc) { @@ -520,42 +539,48 @@ bool clipUVTransform(TransInfo *t, float vec[2], const bool resize) } if (resize) { - if (min[0] < 0.0f && t->center_global[0] > 0.0f && t->center_global[0] < t->aspect[0] * 0.5f) { - vec[0] *= t->center_global[0] / (t->center_global[0] - min[0]); + if (min[0] < base_offset[0] && t->center_global[0] > base_offset[0] && + t->center_global[0] < base_offset[0] + (t->aspect[0] * 0.5f)) { + vec[0] *= (t->center_global[0] - base_offset[0]) / (t->center_global[0] - min[0]); } - else if (max[0] > t->aspect[0] && t->center_global[0] < t->aspect[0]) { - vec[0] *= (t->center_global[0] - t->aspect[0]) / (t->center_global[0] - max[0]); + else if (max[0] > (base_offset[0] + t->aspect[0]) && + t->center_global[0] < (base_offset[0] + t->aspect[0])) { + vec[0] *= (t->center_global[0] - (base_offset[0] + t->aspect[0])) / + (t->center_global[0] - max[0]); } else { clipx = 0; } - if (min[1] < 0.0f && t->center_global[1] > 0.0f && t->center_global[1] < t->aspect[1] * 0.5f) { - vec[1] *= t->center_global[1] / (t->center_global[1] - min[1]); + if (min[1] < base_offset[1] && t->center_global[1] > base_offset[1] && + t->center_global[1] < base_offset[1] + (t->aspect[1] * 0.5f)) { + vec[1] *= (t->center_global[1] - base_offset[1]) / (t->center_global[1] - min[1]); } - else if (max[1] > t->aspect[1] && t->center_global[1] < t->aspect[1]) { - vec[1] *= (t->center_global[1] - t->aspect[1]) / (t->center_global[1] - max[1]); + else if (max[1] > (base_offset[1] + t->aspect[1]) && + t->center_global[1] < (base_offset[1] + t->aspect[1])) { + vec[1] *= (t->center_global[1] - (base_offset[1] + t->aspect[1])) / + (t->center_global[1] - max[1]); } else { clipy = 0; } } else { - if (min[0] < 0.0f) { - vec[0] -= min[0]; + if (min[0] < base_offset[0]) { + vec[0] += base_offset[0] - min[0]; } - else if (max[0] > t->aspect[0]) { - vec[0] -= max[0] - t->aspect[0]; + else if (max[0] > base_offset[0] + t->aspect[0]) { + vec[0] -= max[0] - base_offset[0] - t->aspect[0]; } else { clipx = 0; } - if (min[1] < 0.0f) { - vec[1] -= min[1]; + if (min[1] < base_offset[1]) { + vec[1] += base_offset[1] - min[1]; } - else if (max[1] > t->aspect[1]) { - vec[1] -= max[1] - t->aspect[1]; + else if (max[1] > base_offset[1] + t->aspect[1]) { + vec[1] -= max[1] - base_offset[1] - t->aspect[1]; } else { clipy = 0; _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs