USD import: temp fix for broken UDIMS.

Applying patch authored by Jesse Yurkovich to support
single file UDIMs, while this code is still under review,
to temporarily prevent a regression for those testing USD
features.  If the patch is rejected or rewritten, it might
be necessary to back out this commit or merge it with the
latest changes.
This commit is contained in:
Michael Kowalski 2022-05-14 18:12:10 -04:00
parent 69c2c9de0f
commit 7aa4b6f93f
5 changed files with 29 additions and 12 deletions

View File

@ -378,6 +378,11 @@ typedef enum {
UDIM_TILE_FORMAT_UVTILE = 2
} eUDIM_TILE_FORMAT;
/**
* Checks if the filename portion of the path contains a UDIM token.
*/
bool BKE_image_is_filename_tokenized(char *filepath);
/**
* Ensures that `filename` contains a UDIM token if we find a supported format pattern.
* \note This must only be the name component (without slashes).

View File

@ -2927,6 +2927,7 @@ void BKE_image_signal(Main *bmain, Image *ima, ImageUser *iuser, int signal)
MEM_freeN(tile);
}
base_tile->next = nullptr;
base_tile->tile_number = 1001;
ima->tiles.last = base_tile;
}
@ -3108,7 +3109,12 @@ bool BKE_image_get_tile_info(char *filepath, ListBase *tiles, int *r_tile_start,
char filename[FILE_MAXFILE], dirname[FILE_MAXDIR];
BLI_split_dirfile(filepath, dirname, filename, sizeof(dirname), sizeof(filename));
BKE_image_ensure_tile_token(filename);
/* If a tokenized path was provided, allow single-file sequences. Otherwise
* tokenize it here and attempt to find 2 or more files in the sequence. */
bool allow_single = BKE_image_is_filename_tokenized(filename);
if (!allow_single) {
BKE_image_ensure_tile_token(filename);
}
eUDIM_TILE_FORMAT tile_format;
char *udim_pattern = BKE_image_get_tile_strformat(filename, &tile_format);
@ -3142,10 +3148,10 @@ bool BKE_image_get_tile_info(char *filepath, ListBase *tiles, int *r_tile_start,
BLI_filelist_free(dirs, dirs_num);
MEM_SAFE_FREE(udim_pattern);
/* Ensure that all discovered UDIMs are valid and that there's at least 2 files in total.
* Downstream code checks the range value to determine tiled-ness; it's important we match that
* expectation here too (T97366). */
if (all_valid_udim && min_udim <= IMA_UDIM_MAX && max_udim > min_udim) {
/* Ensure that all discovered UDIMs are valid and that there's at least 2 files in total if
* allow_single is false (T97366). */
bool valid_count = allow_single || max_udim > min_udim;
if (all_valid_udim && min_udim <= IMA_UDIM_MAX && valid_count) {
BLI_join_dirfile(filepath, FILE_MAX, dirname, filename);
*r_tile_start = min_udim;
@ -3317,13 +3323,18 @@ bool BKE_image_fill_tile(struct Image *ima,
return false;
}
bool BKE_image_is_filename_tokenized(char *filepath)
{
const char *filename = BLI_path_basename(filepath);
return strstr(filename, "<UDIM>") != nullptr || strstr(filename, "<UVTILE>") != nullptr;
}
void BKE_image_ensure_tile_token(char *filename)
{
BLI_assert_msg(BLI_path_slash_find(filename) == nullptr,
"Only the file-name component should be used!");
/* Is there a '<' character in the filename? Assume tokens already present. */
if (strstr(filename, "<") != nullptr) {
if (BKE_image_is_filename_tokenized(filename)) {
return;
}

View File

@ -173,6 +173,7 @@ typedef struct ImageFrameRange {
int length;
int offset;
/* UDIM tiles. */
bool udims_detected;
ListBase udim_tiles;
/* Temporary data. */

View File

@ -1274,8 +1274,8 @@ static Image *image_open_single(Main *bmain,
BKE_image_free_views(ima);
}
if ((range->length > 1) && (ima->source == IMA_SRC_FILE)) {
if (range->udim_tiles.first) {
if (ima->source == IMA_SRC_FILE) {
if (range->udims_detected && range->udim_tiles.first) {
ima->source = IMA_SRC_TILED;
ImageTile *first_tile = ima->tiles.first;
first_tile->tile_number = range->offset;
@ -1283,7 +1283,7 @@ static Image *image_open_single(Main *bmain,
BKE_image_add_tile(ima, POINTER_AS_INT(node->data), NULL);
}
}
else {
else if (range->length > 1) {
ima->source = IMA_SRC_SEQUENCE;
}
}

View File

@ -107,10 +107,10 @@ static void image_detect_frame_range(ImageFrameRange *range, const bool detect_u
/* UDIM */
if (detect_udim) {
int udim_start, udim_range;
bool result = BKE_image_get_tile_info(
range->udims_detected = BKE_image_get_tile_info(
range->filepath, &range->udim_tiles, &udim_start, &udim_range);
if (result) {
if (range->udims_detected) {
range->offset = udim_start;
range->length = udim_range;
return;