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:
authorJesse Yurkovich <jesse.y@gmail.com>2021-12-31 09:06:23 +0300
committerJesse Yurkovich <jesse.y@gmail.com>2022-01-03 07:48:59 +0300
commit180b66ae8a1ffc0a1bb7d3993028240b4c7f7246 (patch)
treecbc9405b97f02826d181829859b12ce82a672def /source/blender/editors/space_image
parent367fc69dc1c5ebb6e30ef74488a041502ea8a370 (diff)
UDIM: Support virtual filenames
This implements the design detailed in T92696 to support virtual filenames for UDIM textures. Currently, the following 2 substitution tokens are supported: | Token | Meaning | | ----- | ---- | | <UDIM> | 1001 + u-tile + v-tile * 10 | | <UVTILE> | Equivalent to u<u-tile + 1>_v<v-tile + 1> | Example for u-tile of 3 and v-tile of 1: filename.<UDIM>_ver0023.png --> filename.1014_ver0023.png filename.<UVTILE>_ver0023.png --> filename.u4_v2_ver0023.png For image loading, the existing workflow is unchanged. A user can select one or more image files, belonging to one or more UDIM tile sets, and have Blender load them all as it does today. Now the <UVTILE> format is "guessed" just as the <UDIM> format was guessed before. If guessing fails, the user can simply go into the Image Editor and type the proper substitution in the filename. Once typing is complete, Blender will reload the files and correctly fill the tiles. This workflow is new as attempting to fix the guessing in current versions did not really work, and the user was often stuck with a confusing situation. For image saving, the existing workflow is changed slightly. Currently, when saving, a user has to be sure to type the filename of the first tile (e.g. filename.1001.png) to save the entire UDIM set. The number could differ if they start at a different tile etc. This is confusing. Now, the user should type a filename containing the appropriate substitution token. By default Blender will fill in a default name using the <UDIM> token but the user is free to save out images using <UVTILE> if they wish. Differential Revision: https://developer.blender.org/D13057
Diffstat (limited to 'source/blender/editors/space_image')
-rw-r--r--source/blender/editors/space_image/image_ops.c27
-rw-r--r--source/blender/editors/space_image/image_sequence.c68
2 files changed, 22 insertions, 73 deletions
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index f9160774c41..b72fe40d510 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -1499,6 +1499,13 @@ static void image_open_draw(bContext *UNUSED(C), wmOperator *op)
}
}
+static void image_operator_prop_allow_tokens(wmOperatorType *ot)
+{
+ PropertyRNA *prop = RNA_def_boolean(
+ ot->srna, "allow_path_tokens", true, "", "Allow the path to contain substitution tokens");
+ RNA_def_property_flag(prop, PROP_HIDDEN);
+}
+
void IMAGE_OT_open(wmOperatorType *ot)
{
/* identifiers */
@@ -1516,6 +1523,7 @@ void IMAGE_OT_open(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
+ image_operator_prop_allow_tokens(ot);
WM_operator_properties_filesel(ot,
FILE_TYPE_FOLDER | FILE_TYPE_IMAGE | FILE_TYPE_MOVIE,
FILE_SPECIAL,
@@ -1767,7 +1775,13 @@ static int image_save_options_init(Main *bmain,
opts->im_format.views_format = ima->views_format;
}
- BLI_strncpy(opts->filepath, ibuf->name, sizeof(opts->filepath));
+ if (ima->source == IMA_SRC_TILED) {
+ BLI_strncpy(opts->filepath, ima->filepath, sizeof(opts->filepath));
+ BLI_path_abs(opts->filepath, ID_BLEND_PATH_FROM_GLOBAL(&ima->id));
+ }
+ else {
+ BLI_strncpy(opts->filepath, ibuf->name, sizeof(opts->filepath));
+ }
/* sanitize all settings */
@@ -1804,14 +1818,10 @@ static int image_save_options_init(Main *bmain,
BLI_path_abs(opts->filepath, is_prev_save ? G.ima : BKE_main_blendfile_path(bmain));
}
- /* append UDIM numbering if not present */
- if (ima->source == IMA_SRC_TILED) {
- char udim[6];
- ImageTile *tile = ima->tiles.first;
- BLI_snprintf(udim, sizeof(udim), ".%d", tile->tile_number);
-
+ /* append UDIM marker if not present */
+ if (ima->source == IMA_SRC_TILED && strstr(opts->filepath, "<UDIM>") == NULL) {
int len = strlen(opts->filepath);
- STR_CONCAT(opts->filepath, len, udim);
+ STR_CONCAT(opts->filepath, len, ".<UDIM>");
}
}
@@ -2070,6 +2080,7 @@ void IMAGE_OT_save_as(wmOperatorType *ot)
"Copy",
"Create a new image file without modifying the current image in blender");
+ image_operator_prop_allow_tokens(ot);
WM_operator_properties_filesel(ot,
FILE_TYPE_FOLDER | FILE_TYPE_IMAGE | FILE_TYPE_MOVIE,
FILE_SPECIAL,
diff --git a/source/blender/editors/space_image/image_sequence.c b/source/blender/editors/space_image/image_sequence.c
index 87bff913ff2..84b85b396fe 100644
--- a/source/blender/editors/space_image/image_sequence.c
+++ b/source/blender/editors/space_image/image_sequence.c
@@ -115,79 +115,17 @@ static int image_cmp_frame(const void *a, const void *b)
return 0;
}
-/*
- * Checks whether the given filepath refers to a UDIM texture.
- * If yes, the range from 1001 to the highest tile is returned, otherwise 0.
- *
- * If the result is positive, the filepath will be overwritten with that of
- * the 1001 tile.
- *
- * udim_tiles may get filled even if the result ultimately is false!
- */
-static bool image_get_udim(char *filepath, ListBase *udim_tiles, int *udim_start, int *udim_range)
-{
- char filename[FILE_MAX], dirname[FILE_MAXDIR];
- BLI_split_dirfile(filepath, dirname, filename, sizeof(dirname), sizeof(filename));
-
- ushort digits;
- char base_head[FILE_MAX], base_tail[FILE_MAX];
- int id = BLI_path_sequence_decode(filename, base_head, base_tail, &digits);
-
- if (id < 1001 || id > IMA_UDIM_MAX) {
- return false;
- }
-
- bool is_udim = true;
- int min_udim = IMA_UDIM_MAX + 1;
- int max_udim = 0;
-
- struct direntry *dir;
- uint totfile = BLI_filelist_dir_contents(dirname, &dir);
- for (int i = 0; i < totfile; i++) {
- if (!(dir[i].type & S_IFREG)) {
- continue;
- }
- char head[FILE_MAX], tail[FILE_MAX];
- id = BLI_path_sequence_decode(dir[i].relname, head, tail, &digits);
-
- if (digits > 4 || !(STREQLEN(base_head, head, FILE_MAX)) ||
- !(STREQLEN(base_tail, tail, FILE_MAX))) {
- continue;
- }
-
- if (id < 1001 || id > IMA_UDIM_MAX) {
- is_udim = false;
- break;
- }
-
- BLI_addtail(udim_tiles, BLI_genericNodeN(POINTER_FROM_INT(id)));
- min_udim = min_ii(min_udim, id);
- max_udim = max_ii(max_udim, id);
- }
- BLI_filelist_free(dir, totfile);
-
- if (is_udim && min_udim <= IMA_UDIM_MAX) {
- char primary_filename[FILE_MAX];
- BLI_path_sequence_encode(primary_filename, base_head, base_tail, digits, min_udim);
- BLI_join_dirfile(filepath, FILE_MAX, dirname, primary_filename);
-
- *udim_start = min_udim;
- *udim_range = max_udim - min_udim + 1;
- return true;
- }
- return false;
-}
-
/**
* From a list of frames, compute the start (offset) and length of the sequence
- * of contiguous frames. If UDIM is detect, it will return UDIM tiles as well.
+ * of contiguous frames. If `detect_udim` is set, it will return UDIM tiles as well.
*/
static void image_detect_frame_range(ImageFrameRange *range, const bool detect_udim)
{
/* UDIM */
if (detect_udim) {
int udim_start, udim_range;
- bool result = image_get_udim(range->filepath, &range->udim_tiles, &udim_start, &udim_range);
+ bool result = BKE_image_get_tile_info(
+ range->filepath, &range->udim_tiles, &udim_start, &udim_range);
if (result) {
range->offset = udim_start;