[Bf-blender-cvs] [284a3431aee] master: Cycles: Fix rendering of packed UDIM tiles with different sizes

Sergey Sharybin noreply at git.blender.org
Fri Jun 3 14:34:02 CEST 2022


Commit: 284a3431aeee3e6a922d26415afcb50d0bf30b66
Author: Sergey Sharybin
Date:   Fri Jun 3 12:52:09 2022 +0200
Branches: master
https://developer.blender.org/rB284a3431aeee3e6a922d26415afcb50d0bf30b66

Cycles: Fix rendering of packed UDIM tiles with different sizes

The packed image loader was not aware of the fact that UDIM tiles
can be of a different size.

Exposed Python API required to access this information. It has the
same complexity as the "regular" packed files: in both cases the
ImBuf will be acquired and released to access the information.

While the current workflow of packing UDIMs is not very streamlined,
it is still possible and is something what the studio is using here.

Test file:
{F13130516}

Expected behavior achieved with this patch: a bigger checker board
pattern in viewport render

Actual behavior prior to this patch: either memory corruption, or
wrong/black render result on the plane

Differential Revision: https://developer.blender.org/D15111

===================================================================

M	intern/cycles/blender/image.cpp
M	source/blender/makesrna/intern/rna_image.c

===================================================================

diff --git a/intern/cycles/blender/image.cpp b/intern/cycles/blender/image.cpp
index 98ca16fe678..058fe3d46ac 100644
--- a/intern/cycles/blender/image.cpp
+++ b/intern/cycles/blender/image.cpp
@@ -28,10 +28,33 @@ BlenderImageLoader::BlenderImageLoader(BL::Image b_image,
 
 bool BlenderImageLoader::load_metadata(const ImageDeviceFeatures &, ImageMetaData &metadata)
 {
-  metadata.width = b_image.size()[0];
-  metadata.height = b_image.size()[1];
+  if (b_image.source() != BL::Image::source_TILED) {
+    /* Image sequence might have different dimensions, and hence needs to be handled in a special
+     * manner.
+     * NOTE: Currently the sequences are not handled by this image laoder. */
+    assert(b_image.source() != BL::Image::source_SEQUENCE);
+
+    metadata.width = b_image.size()[0];
+    metadata.height = b_image.size()[1];
+    metadata.channels = b_image.channels();
+  }
+  else {
+    /* Different UDIM tiles might have different resolutions, so get resolution from the actual
+     * tile. */
+    BL::UDIMTile b_udim_tile = b_image.tiles.get(tile_number);
+    if (b_udim_tile) {
+      metadata.width = b_udim_tile.size()[0];
+      metadata.height = b_udim_tile.size()[1];
+      metadata.channels = b_udim_tile.channels();
+    }
+    else {
+      metadata.width = 0;
+      metadata.height = 0;
+      metadata.channels = 0;
+    }
+  }
+
   metadata.depth = 1;
-  metadata.channels = b_image.channels();
 
   if (b_image.is_float()) {
     if (metadata.channels == 1) {
diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c
index 269ebe1581f..c7b713d80f5 100644
--- a/source/blender/makesrna/intern/rna_image.c
+++ b/source/blender/makesrna/intern/rna_image.c
@@ -257,6 +257,51 @@ static void rna_Image_file_format_set(PointerRNA *ptr, int value)
   }
 }
 
+static void rna_UDIMTile_size_get(PointerRNA *ptr, int *values)
+{
+  ImageTile *tile = (ImageTile *)ptr->data;
+  Image *image = (Image *)ptr->owner_id;
+
+  ImageUser image_user;
+  BKE_imageuser_default(&image_user);
+  image_user.tile = tile->tile_number;
+
+  void *lock;
+  ImBuf *ibuf = BKE_image_acquire_ibuf(image, &image_user, &lock);
+  if (ibuf) {
+    values[0] = ibuf->x;
+    values[1] = ibuf->y;
+  }
+  else {
+    values[0] = 0;
+    values[1] = 0;
+  }
+
+  BKE_image_release_ibuf(image, ibuf, lock);
+}
+
+static int rna_UDIMTile_channels_get(PointerRNA *ptr)
+{
+  ImageTile *tile = (ImageTile *)ptr->data;
+  Image *image = (Image *)ptr->owner_id;
+
+  ImageUser image_user;
+  BKE_imageuser_default(&image_user);
+  image_user.tile = tile->tile_number;
+
+  int channels = 0;
+
+  void *lock;
+  ImBuf *ibuf = BKE_image_acquire_ibuf(image, &image_user, &lock);
+  if (ibuf) {
+    channels = ibuf->channels;
+  }
+
+  BKE_image_release_ibuf(image, ibuf, lock);
+
+  return channels;
+}
+
 static void rna_UDIMTile_label_get(PointerRNA *ptr, char *value)
 {
   ImageTile *tile = (ImageTile *)ptr->data;
@@ -826,6 +871,26 @@ static void rna_def_udim_tile(BlenderRNA *brna)
   RNA_def_property_ui_text(prop, "Number", "Number of the position that this tile covers");
   RNA_def_property_int_funcs(prop, NULL, "rna_UDIMTile_tile_number_set", NULL);
   RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, NULL);
+
+  prop = RNA_def_int_vector(
+      srna,
+      "size",
+      2,
+      NULL,
+      0,
+      0,
+      "Size",
+      "Width and height of the tile buffer in pixels, zero when image data can't be loaded",
+      0,
+      0);
+  RNA_def_property_subtype(prop, PROP_PIXEL);
+  RNA_def_property_int_funcs(prop, "rna_UDIMTile_size_get", NULL, NULL);
+  RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+  prop = RNA_def_property(srna, "channels", PROP_INT, PROP_UNSIGNED);
+  RNA_def_property_int_funcs(prop, "rna_UDIMTile_channels_get", NULL, NULL);
+  RNA_def_property_ui_text(prop, "Channels", "Number of channels in the tile pixels buffer");
+  RNA_def_property_clear_flag(prop, PROP_EDITABLE);
 }
 
 static void rna_def_udim_tiles(BlenderRNA *brna, PropertyRNA *cprop)



More information about the Bf-blender-cvs mailing list