From f25620187620e75772adc18eaf121ef00416c791 Mon Sep 17 00:00:00 2001 From: Jesse Yurkovich Date: Thu, 7 Jul 2022 02:08:32 -0700 Subject: Fix T99388: Obey relative path option when saving UDIMs Ensure that the Image maintains the proper file path after saving all the individual tiles. The image_save_post function is unaware that the filepath it receives is only for a single tile, not the entire Image, and happily keeps setting ima->filepath to the concrete filepath for each tile. There were 2 problems with the code that attempted to correct the Image filepath back to the UDIM virtual form: - It would trample the "relative" directory that might have been set - It would do the wrong thing if no tiles could be saved at all The design is now as follows: Example of trying to save to a new PathB | | all tiles ok | any tile not ok| | -------------------------------- | ---------------- | ---------------| | ima->filepath is currently empty | set to new PathB | keep empty | | ima->filepath is currently PathA | set to new PathB | keep PathA | Differential Revision: https://developer.blender.org/D15384 --- source/blender/blenkernel/intern/image_save.cc | 40 +++++++++++++++++--------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/source/blender/blenkernel/intern/image_save.cc b/source/blender/blenkernel/intern/image_save.cc index 9dda3762553..07ffc35907a 100644 --- a/source/blender/blenkernel/intern/image_save.cc +++ b/source/blender/blenkernel/intern/image_save.cc @@ -253,6 +253,21 @@ void BKE_image_save_options_free(ImageSaveOptions *opts) BKE_image_format_free(&opts->im_format); } +static void image_save_update_filepath(Image *ima, + const char *filepath, + const ImageSaveOptions *opts) +{ + if (opts->do_newpath) { + BLI_strncpy(ima->filepath, filepath, sizeof(ima->filepath)); + + /* only image path, never ibuf */ + if (opts->relative) { + const char *relbase = ID_BLEND_PATH(opts->bmain, &ima->id); + BLI_path_rel(ima->filepath, relbase); /* only after saving */ + } + } +} + static void image_save_post(ReportList *reports, Image *ima, ImBuf *ibuf, @@ -273,13 +288,11 @@ static void image_save_post(ReportList *reports, if (opts->do_newpath) { BLI_strncpy(ibuf->name, filepath, sizeof(ibuf->name)); - BLI_strncpy(ima->filepath, filepath, sizeof(ima->filepath)); + } - /* only image path, never ibuf */ - if (opts->relative) { - const char *relbase = ID_BLEND_PATH(opts->bmain, &ima->id); - BLI_path_rel(ima->filepath, relbase); /* only after saving */ - } + /* The tiled image codepath must call this on its own. */ + if (ima->source != IMA_SRC_TILED) { + image_save_update_filepath(ima, filepath, opts); } ibuf->userflags &= ~IB_BITMAPDIRTY; @@ -640,22 +653,23 @@ bool BKE_image_save( ok = image_save_single(reports, ima, iuser, opts, &colorspace_changed); } else { - char filepath[FILE_MAX]; - BLI_strncpy(filepath, opts->filepath, sizeof(filepath)); - /* Save all the tiles. */ LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) { + ImageSaveOptions tile_opts = *opts; BKE_image_set_filepath_from_tile_number( - opts->filepath, udim_pattern, tile_format, tile->tile_number); + tile_opts.filepath, udim_pattern, tile_format, tile->tile_number); iuser->tile = tile->tile_number; - ok = image_save_single(reports, ima, iuser, opts, &colorspace_changed); + ok = image_save_single(reports, ima, iuser, &tile_opts, &colorspace_changed); if (!ok) { break; } } - BLI_strncpy(ima->filepath, filepath, sizeof(ima->filepath)); - BLI_strncpy(opts->filepath, filepath, sizeof(opts->filepath)); + + /* Set the image path only if all tiles were ok. */ + if (ok) { + image_save_update_filepath(ima, opts->filepath, opts); + } MEM_freeN(udim_pattern); } -- cgit v1.2.3