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
This commit is contained in:
parent
79b7c46eec
commit
c1f7f18a8e
@ -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]);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user