Add an optional "frame" & "tile_index" argument to Image.scale()

`BKE_image_scale` -- which is only used for the python API -- was
getting the `ImBuf` without providing an `ImageUser`.
This is fine, but always gets the first tile (and the current frame for sequences).

To resolve this, add an optional "frame" & "tile_index" argument so these can be specified explicitly (similar to layer_index and pass_index already used for some other API functions).

Fixes #117539 : Scaling UDIM images via Image.scale() only scales one tile

Pull Request: https://projects.blender.org/blender/blender/pulls/117549
This commit is contained in:
Philipp Oeser
2024-02-01 17:28:38 +01:00
committed by Philipp Oeser
parent 5d132ac0c6
commit 3d60209d3d
3 changed files with 21 additions and 6 deletions

View File

@@ -335,7 +335,7 @@ void BKE_image_merge(struct Main *bmain, struct Image *dest, struct Image *sourc
/**
* Scale the image.
*/
bool BKE_image_scale(struct Image *image, int width, int height);
bool BKE_image_scale(struct Image *image, int width, int height, struct ImageUser *iuser);
/**
* Check if texture has alpha `planes == 32 || planes == 16`.

View File

@@ -775,7 +775,7 @@ void BKE_image_merge(Main *bmain, Image *dest, Image *source)
}
}
bool BKE_image_scale(Image *image, int width, int height)
bool BKE_image_scale(Image *image, int width, int height, ImageUser *iuser)
{
/* NOTE: We could be clever and scale all imbuf's
* but since some are mipmaps its not so simple. */
@@ -783,7 +783,7 @@ bool BKE_image_scale(Image *image, int width, int height)
ImBuf *ibuf;
void *lock;
ibuf = BKE_image_acquire_ibuf(image, nullptr, &lock);
ibuf = BKE_image_acquire_ibuf(image, iuser, &lock);
if (ibuf) {
IMB_scaleImBuf(ibuf, width, height);

View File

@@ -10,6 +10,7 @@
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <fcntl.h>
#include "DNA_packedFile_types.h"
@@ -179,10 +180,21 @@ static void rna_Image_update(Image *image, ReportList *reports)
BKE_image_release_ibuf(image, ibuf, nullptr);
}
static void rna_Image_scale(Image *image, ReportList *reports, int width, int height)
static void rna_Image_scale(
Image *image, ReportList *reports, int width, int height, int frame, int tile_index)
{
if (!BKE_image_scale(image, width, height)) {
BKE_reportf(reports, RPT_ERROR, "Image '%s' does not have any image data", image->id.name + 2);
ImageUser iuser{};
BKE_imageuser_default(&iuser);
iuser.framenr = frame;
if (image->source == IMA_SRC_TILED) {
const ImageTile *tile = static_cast<ImageTile *>(BLI_findlink(&image->tiles, tile_index));
if (tile != nullptr) {
iuser.tile = tile->tile_number;
}
}
if (!BKE_image_scale(image, width, height, &iuser)) {
BKE_reportf(reports, RPT_ERROR, "Image '%s' failed to load image buffer", image->id.name + 2);
return;
}
BKE_image_partial_update_mark_full_update(image);
@@ -334,6 +346,9 @@ void RNA_api_image(StructRNA *srna)
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_int(func, "height", 1, 1, INT_MAX, "", "Height", 1, INT_MAX);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
RNA_def_int(func, "frame", 0, 0, INT_MAX, "Frame", "Frame (for image sequences)", 0, INT_MAX);
RNA_def_int(
func, "tile_index", 0, 0, INT_MAX, "Tile", "Tile index (for tiled images)", 0, INT_MAX);
func = RNA_def_function(srna, "gl_touch", "rna_Image_gl_touch");
RNA_def_function_ui_description(