diff options
-rw-r--r-- | source/blender/blenkernel/BKE_image.h | 9 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/image.cc | 219 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/image_save.cc | 7 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_300.c | 14 | ||||
-rw-r--r-- | source/blender/editors/space_image/image_ops.c | 15 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_image_types.h | 19 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_image.c | 141 |
7 files changed, 312 insertions, 112 deletions
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index 8512992282f..8c66e92f762 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -364,14 +364,7 @@ bool BKE_image_remove_tile(struct Image *ima, struct ImageTile *tile); void BKE_image_reassign_tile(struct Image *ima, struct ImageTile *tile, int new_tile_number); void BKE_image_sort_tiles(struct Image *ima); -bool BKE_image_fill_tile(struct Image *ima, - struct ImageTile *tile, - int width, - int height, - const float color[4], - int gen_type, - int planes, - bool is_float); +bool BKE_image_fill_tile(struct Image *ima, struct ImageTile *tile); typedef enum { UDIM_TILE_FORMAT_NONE = 0, diff --git a/source/blender/blenkernel/intern/image.cc b/source/blender/blenkernel/intern/image.cc index 4ce413d3705..f3e7ae449a1 100644 --- a/source/blender/blenkernel/intern/image.cc +++ b/source/blender/blenkernel/intern/image.cc @@ -627,6 +627,16 @@ void BKE_image_free_data(Image *ima) image_free_data(&ima->id); } +static ImageTile *imagetile_alloc(int tile_number) +{ + ImageTile *tile = MEM_cnew<ImageTile>("Image Tile"); + tile->tile_number = tile_number; + tile->gen_x = 1024; + tile->gen_y = 1024; + tile->gen_type = IMA_GENTYPE_GRID; + return tile; +} + /* only image block itself */ static void image_init(Image *ima, short source, short type) { @@ -641,8 +651,7 @@ static void image_init(Image *ima, short source, short type) ima->flag |= IMA_VIEW_AS_RENDER; } - ImageTile *tile = MEM_cnew<ImageTile>("Image Tiles"); - tile->tile_number = 1001; + ImageTile *tile = imagetile_alloc(1001); BLI_addtail(&ima->tiles, tile); if (type == IMA_TYPE_R_RESULT) { @@ -1100,73 +1109,70 @@ static void image_buf_fill_isolated(void *usersata_v) } } -static ImBuf *add_ibuf_size(unsigned int width, - unsigned int height, - const char *name, - int depth, - int floatbuf, - short gen_type, - const float color[4], - ColorManagedColorspaceSettings *colorspace_settings) +static ImBuf *add_ibuf_for_tile(Image *ima, ImageTile *tile) { ImBuf *ibuf; unsigned char *rect = nullptr; float *rect_float = nullptr; float fill_color[4]; + const bool floatbuf = (tile->gen_flag & IMA_GEN_FLOAT) != 0; if (floatbuf) { - ibuf = IMB_allocImBuf(width, height, depth, IB_rectfloat); + ibuf = IMB_allocImBuf(tile->gen_x, tile->gen_y, tile->gen_depth, IB_rectfloat); - if (colorspace_settings->name[0] == '\0') { + if (ima->colorspace_settings.name[0] == '\0') { const char *colorspace = IMB_colormanagement_role_colorspace_name_get( COLOR_ROLE_DEFAULT_FLOAT); - STRNCPY(colorspace_settings->name, colorspace); + STRNCPY(ima->colorspace_settings.name, colorspace); } if (ibuf != nullptr) { rect_float = ibuf->rect_float; - IMB_colormanagement_check_is_data(ibuf, colorspace_settings->name); + IMB_colormanagement_check_is_data(ibuf, ima->colorspace_settings.name); } - if (IMB_colormanagement_space_name_is_data(colorspace_settings->name)) { - copy_v4_v4(fill_color, color); + if (IMB_colormanagement_space_name_is_data(ima->colorspace_settings.name)) { + copy_v4_v4(fill_color, tile->gen_color); } else { /* The input color here should ideally be linear already, but for now * we just convert and postpone breaking the API for later. */ - srgb_to_linearrgb_v4(fill_color, color); + srgb_to_linearrgb_v4(fill_color, tile->gen_color); } } else { - ibuf = IMB_allocImBuf(width, height, depth, IB_rect); + ibuf = IMB_allocImBuf(tile->gen_x, tile->gen_y, tile->gen_depth, IB_rect); - if (colorspace_settings->name[0] == '\0') { + if (ima->colorspace_settings.name[0] == '\0') { const char *colorspace = IMB_colormanagement_role_colorspace_name_get( COLOR_ROLE_DEFAULT_BYTE); - STRNCPY(colorspace_settings->name, colorspace); + STRNCPY(ima->colorspace_settings.name, colorspace); } if (ibuf != nullptr) { rect = (unsigned char *)ibuf->rect; - IMB_colormanagement_assign_rect_colorspace(ibuf, colorspace_settings->name); + IMB_colormanagement_assign_rect_colorspace(ibuf, ima->colorspace_settings.name); } - copy_v4_v4(fill_color, color); + copy_v4_v4(fill_color, tile->gen_color); } if (!ibuf) { return nullptr; } - STRNCPY(ibuf->name, name); + STRNCPY(ibuf->name, ima->filepath); + + /* Mark the tile itself as having been generated. */ + tile->gen_flag |= IMA_GEN_TILE; ImageFillData data; - data.gen_type = gen_type; - data.width = width; - data.height = height; + data.gen_type = tile->gen_type; + data.width = tile->gen_x; + data.height = tile->gen_y; data.rect = rect; data.rect_float = rect_float; copy_v4_v4(data.fill_color, fill_color); @@ -1205,12 +1211,16 @@ Image *BKE_image_add_generated(Main *bmain, /* NOTE: leave `ima->filepath` unset, * setting it to a dummy value may write to an invalid file-path. */ - ima->gen_x = width; - ima->gen_y = height; - ima->gen_type = gen_type; - ima->gen_flag |= (floatbuf ? IMA_GEN_FLOAT : 0); - ima->gen_depth = depth; - copy_v4_v4(ima->gen_color, color); + + /* The generation info is always stored in the tiles. The first tile + * will be used for non-tiled images. */ + ImageTile *tile = static_cast<ImageTile *>(ima->tiles.first); + tile->gen_x = width; + tile->gen_y = height; + tile->gen_type = gen_type; + tile->gen_flag |= (floatbuf ? IMA_GEN_FLOAT : 0); + tile->gen_depth = depth; + copy_v4_v4(tile->gen_color, color); if (is_data) { STRNCPY(ima->colorspace_settings.name, @@ -1219,8 +1229,7 @@ Image *BKE_image_add_generated(Main *bmain, for (view_id = 0; view_id < 2; view_id++) { ImBuf *ibuf; - ibuf = add_ibuf_size( - width, height, ima->filepath, depth, floatbuf, gen_type, color, &ima->colorspace_settings); + ibuf = add_ibuf_for_tile(ima, tile); int index = tiled ? 0 : IMA_NO_INDEX; int entry = tiled ? 1001 : 0; image_assign_ibuf(ima, ibuf, stereo3d ? view_id : index, entry); @@ -3001,6 +3010,28 @@ static void image_free_tile(Image *ima, ImageTile *tile) } } +static bool image_remove_tile(Image *ima, ImageTile *tile) +{ + if (BLI_listbase_is_single(&ima->tiles)) { + /* Can't remove the last remaining tile. */ + return false; + } + + image_free_tile(ima, tile); + BLI_remlink(&ima->tiles, tile); + MEM_freeN(tile); + + return true; +} + +static void image_remove_all_tiles(Image *ima) +{ + /* Remove all but the final tile. */ + while (image_remove_tile(ima, static_cast<ImageTile *>(ima->tiles.last))) { + ; + } +} + void BKE_image_signal(Main *bmain, Image *ima, ImageUser *iuser, int signal) { if (ima == nullptr) { @@ -3027,11 +3058,12 @@ void BKE_image_signal(Main *bmain, Image *ima, ImageUser *iuser, int signal) } if (ima->source == IMA_SRC_GENERATED) { - if (ima->gen_x == 0 || ima->gen_y == 0) { + ImageTile *base_tile = BKE_image_get_tile(ima, 0); + if (base_tile->gen_x == 0 || base_tile->gen_y == 0) { ImBuf *ibuf = image_get_cached_ibuf_for_index_entry(ima, IMA_NO_INDEX, 0, nullptr); if (ibuf) { - ima->gen_x = ibuf->x; - ima->gen_y = ibuf->y; + base_tile->gen_x = ibuf->x; + base_tile->gen_y = ibuf->y; IMB_freeImBuf(ibuf); } } @@ -3048,16 +3080,40 @@ void BKE_image_signal(Main *bmain, Image *ima, ImageUser *iuser, int signal) if (ima->source != IMA_SRC_TILED) { /* Free all but the first tile. */ + image_remove_all_tiles(ima); + + /* If the remaining tile is generated, we need to again ensure that we + * wouldn't continue to use the old filepath. + * + * Otherwise, if this used to be a UDIM image, get the concrete filepath associated + * with the remaining tile and use that as the new filepath. */ ImageTile *base_tile = BKE_image_get_tile(ima, 0); - BLI_assert(base_tile == ima->tiles.first); - for (ImageTile *tile = base_tile->next, *tile_next; tile; tile = tile_next) { - tile_next = tile->next; - image_free_tile(ima, tile); - MEM_freeN(tile); + if ((base_tile->gen_flag & IMA_GEN_TILE) != 0) { + ima->filepath[0] = '\0'; } - base_tile->next = nullptr; + else if (BKE_image_is_filename_tokenized(ima->filepath)) { + const bool was_relative = BLI_path_is_rel(ima->filepath); + + eUDIM_TILE_FORMAT tile_format; + char *udim_pattern = BKE_image_get_tile_strformat(ima->filepath, &tile_format); + BKE_image_set_filepath_from_tile_number( + ima->filepath, udim_pattern, tile_format, base_tile->tile_number); + MEM_freeN(udim_pattern); + + if (was_relative) { + const char *relbase = ID_BLEND_PATH(bmain, &ima->id); + BLI_path_rel(ima->filepath, relbase); + } + } + + /* If the remaining tile was not number 1001, we need to reassign it so that + * ibuf lookups from the cache still succeed. */ base_tile->tile_number = 1001; - ima->tiles.last = base_tile; + } + else { + /* When changing to UDIM, attempt to tokenize the filepath. */ + char *filename = (char *)BLI_path_basename(ima->filepath); + BKE_image_ensure_tile_token(filename); } /* image buffers for non-sequence multilayer will share buffers with RenderResult, @@ -3073,6 +3129,7 @@ void BKE_image_signal(Main *bmain, Image *ima, ImageUser *iuser, int signal) image_tag_frame_recalc(ima, nullptr, iuser, ima); } BKE_image_walk_all_users(bmain, ima, image_tag_frame_recalc); + BKE_image_partial_update_mark_full_update(ima); break; @@ -3124,9 +3181,7 @@ void BKE_image_signal(Main *bmain, Image *ima, ImageUser *iuser, int signal) * to account for how the two sets might or might not overlap. To be complete, we start * the refresh process by clearing all existing tiles, stopping when there's only 1 tile * left. */ - while (BKE_image_remove_tile(ima, static_cast<ImageTile *>(ima->tiles.last))) { - ; - } + image_remove_all_tiles(ima); int remaining_tile_number = ((ImageTile *)ima->tiles.first)->tile_number; bool needs_final_cleanup = true; @@ -3309,8 +3364,7 @@ ImageTile *BKE_image_add_tile(struct Image *ima, int tile_number, const char *la } } - ImageTile *tile = MEM_cnew<ImageTile>("image new tile"); - tile->tile_number = tile_number; + ImageTile *tile = imagetile_alloc(tile_number); if (next_tile) { BLI_insertlinkbefore(&ima->tiles, next_tile, tile); @@ -3345,16 +3399,7 @@ bool BKE_image_remove_tile(struct Image *ima, ImageTile *tile) return false; } - if (BLI_listbase_is_single(&ima->tiles)) { - /* Can't remove the last remaining tile. */ - return false; - } - - image_free_tile(ima, tile); - BLI_remlink(&ima->tiles, tile); - MEM_freeN(tile); - - return true; + return image_remove_tile(ima, tile); } void BKE_image_reassign_tile(struct Image *ima, ImageTile *tile, int new_tile_number) @@ -3416,14 +3461,7 @@ void BKE_image_sort_tiles(struct Image *ima) BLI_listbase_sort(&ima->tiles, tile_sort_cb); } -bool BKE_image_fill_tile(struct Image *ima, - ImageTile *tile, - int width, - int height, - const float color[4], - int gen_type, - int planes, - bool is_float) +bool BKE_image_fill_tile(struct Image *ima, ImageTile *tile) { if (ima == nullptr || tile == nullptr || ima->source != IMA_SRC_TILED) { return false; @@ -3431,8 +3469,7 @@ bool BKE_image_fill_tile(struct Image *ima, image_free_tile(ima, tile); - ImBuf *tile_ibuf = add_ibuf_size( - width, height, ima->filepath, planes, is_float, gen_type, color, &ima->colorspace_settings); + ImBuf *tile_ibuf = add_ibuf_for_tile(ima, tile); if (tile_ibuf != nullptr) { image_assign_ibuf(ima, tile_ibuf, 0, tile->tile_number); @@ -4605,14 +4642,22 @@ static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **r_lock) } } else if (ima->source == IMA_SRC_TILED) { - if (ima->type == IMA_TYPE_IMAGE) { - /* Regular files, ibufs in flip-book, allows saving */ - ibuf = image_load_image_file(ima, iuser, entry, 0, false); + /* Nothing was cached. Check to see if the tile should be generated. */ + ImageTile *tile = BKE_image_get_tile(ima, entry); + if ((tile->gen_flag & IMA_GEN_TILE) != 0) { + ibuf = add_ibuf_for_tile(ima, tile); + image_assign_ibuf(ima, ibuf, 0, entry); } - /* no else; on load the ima type can change */ - if (ima->type == IMA_TYPE_MULTILAYER) { - /* Only 1 layer/pass stored in imbufs, no EXR-handle anim storage, no saving. */ - ibuf = image_load_sequence_multilayer(ima, iuser, entry, 0); + else { + if (ima->type == IMA_TYPE_IMAGE) { + /* Regular files, ibufs in flip-book, allows saving */ + ibuf = image_load_image_file(ima, iuser, entry, 0, false); + } + /* no else; on load the ima type can change */ + if (ima->type == IMA_TYPE_MULTILAYER) { + /* Only 1 layer/pass stored in imbufs, no EXR-handle anim storage, no saving. */ + ibuf = image_load_sequence_multilayer(ima, iuser, entry, 0); + } } } else if (ima->source == IMA_SRC_FILE) { @@ -4630,23 +4675,17 @@ static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **r_lock) else if (ima->source == IMA_SRC_GENERATED) { /* Generated is: `ibuf` is allocated dynamically. */ /* UV test-grid or black or solid etc. */ - if (ima->gen_x == 0) { - ima->gen_x = 1024; + ImageTile *base_tile = BKE_image_get_tile(ima, 0); + if (base_tile->gen_x == 0) { + base_tile->gen_x = 1024; } - if (ima->gen_y == 0) { - ima->gen_y = 1024; + if (base_tile->gen_y == 0) { + base_tile->gen_y = 1024; } - if (ima->gen_depth == 0) { - ima->gen_depth = 24; + if (base_tile->gen_depth == 0) { + base_tile->gen_depth = 24; } - ibuf = add_ibuf_size(ima->gen_x, - ima->gen_y, - ima->filepath, - ima->gen_depth, - (ima->gen_flag & IMA_GEN_FLOAT) != 0, - ima->gen_type, - ima->gen_color, - &ima->colorspace_settings); + ibuf = add_ibuf_for_tile(ima, base_tile); image_assign_ibuf(ima, ibuf, index, 0); } else if (ima->source == IMA_SRC_VIEWER) { diff --git a/source/blender/blenkernel/intern/image_save.cc b/source/blender/blenkernel/intern/image_save.cc index cd86d3f7087..fec1bc8cd1a 100644 --- a/source/blender/blenkernel/intern/image_save.cc +++ b/source/blender/blenkernel/intern/image_save.cc @@ -320,6 +320,8 @@ static void image_save_post(ReportList *reports, if (ELEM(ima->source, IMA_SRC_GENERATED, IMA_SRC_VIEWER)) { ima->source = IMA_SRC_FILE; ima->type = IMA_TYPE_IMAGE; + ImageTile *base_tile = BKE_image_get_tile(ima, 0); + base_tile->gen_flag &= ~IMA_GEN_TILE; } /* Update image file color space when saving to another color space. */ @@ -666,8 +668,11 @@ bool BKE_image_save( } } - /* Set the image path only if all tiles were ok. */ + /* Set the image path and clear the per-tile generated flag only if all tiles were ok. */ if (ok) { + LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) { + tile->gen_flag &= ~IMA_GEN_TILE; + } image_save_update_filepath(ima, opts->filepath, opts); } MEM_freeN(udim_pattern); diff --git a/source/blender/blenloader/intern/versioning_300.c b/source/blender/blenloader/intern/versioning_300.c index 49b14dc84a6..41888e25fb7 100644 --- a/source/blender/blenloader/intern/versioning_300.c +++ b/source/blender/blenloader/intern/versioning_300.c @@ -3318,5 +3318,19 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain) */ { /* Keep this block, even when empty. */ + + /* Image generation information transfered to tiles. */ + if (!DNA_struct_elem_find(fd->filesdna, "ImageTile", "int", "gen_x")) { + for (Image *ima = bmain->images.first; ima; ima = ima->id.next) { + for (ImageTile *tile = ima->tiles.first; tile; tile = tile->next) { + tile->gen_x = ima->gen_x; + tile->gen_y = ima->gen_y; + tile->gen_type = ima->gen_type; + tile->gen_flag = ima->gen_flag; + tile->gen_depth = ima->gen_depth; + copy_v4_v4(tile->gen_color, ima->gen_color); + } + } + } } } diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 4036f859231..78aaf957a87 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -3847,15 +3847,16 @@ void IMAGE_OT_clear_render_border(wmOperatorType *ot) static bool do_fill_tile(PointerRNA *ptr, Image *ima, ImageTile *tile) { - float color[4]; - RNA_float_get_array(ptr, "color", color); - int gen_type = RNA_enum_get(ptr, "generated_type"); - int width = RNA_int_get(ptr, "width"); - int height = RNA_int_get(ptr, "height"); + RNA_float_get_array(ptr, "color", tile->gen_color); + tile->gen_type = RNA_enum_get(ptr, "generated_type"); + tile->gen_x = RNA_int_get(ptr, "width"); + tile->gen_y = RNA_int_get(ptr, "height"); bool is_float = RNA_boolean_get(ptr, "float"); - int planes = RNA_boolean_get(ptr, "alpha") ? 32 : 24; - return BKE_image_fill_tile(ima, tile, width, height, color, gen_type, planes, is_float); + tile->gen_flag = is_float ? IMA_GEN_FLOAT : 0; + tile->gen_depth = RNA_boolean_get(ptr, "alpha") ? 32 : 24; + + return BKE_image_fill_tile(ima, tile); } static void draw_fill_tile(PointerRNA *ptr, uiLayout *layout) diff --git a/source/blender/makesdna/DNA_image_types.h b/source/blender/makesdna/DNA_image_types.h index 6e4e515a0fe..f35c77f663b 100644 --- a/source/blender/makesdna/DNA_image_types.h +++ b/source/blender/makesdna/DNA_image_types.h @@ -92,8 +92,14 @@ typedef struct ImageTile { struct ImageTile_Runtime runtime; - char _pad[4]; int tile_number; + + /* for generated images */ + int gen_x, gen_y; + char gen_type, gen_flag; + short gen_depth; + float gen_color[4]; + char label[64]; } ImageTile; @@ -167,10 +173,10 @@ typedef struct Image { int lastused; /* for generated images */ - int gen_x, gen_y; - char gen_type, gen_flag; - short gen_depth; - float gen_color[4]; + int gen_x DNA_DEPRECATED, gen_y DNA_DEPRECATED; + char gen_type DNA_DEPRECATED, gen_flag DNA_DEPRECATED; + short gen_depth DNA_DEPRECATED; + float gen_color[4] DNA_DEPRECATED; /* display aspect - for UV editing images resized for faster openGL display */ float aspx, aspy; @@ -262,7 +268,8 @@ enum { /** #Image.gen_flag */ enum { - IMA_GEN_FLOAT = 1, + IMA_GEN_FLOAT = (1 << 0), + IMA_GEN_TILE = (1 << 1), }; /** #Image.alpha_mode */ diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c index 7f134c5055f..8f6aa55b9ac 100644 --- a/source/blender/makesrna/intern/rna_image.c +++ b/source/blender/makesrna/intern/rna_image.c @@ -52,6 +52,7 @@ static const EnumPropertyItem image_source_items[] = { #ifdef RNA_RUNTIME # include "BLI_math_base.h" +# include "BLI_math_vector.h" # include "BKE_global.h" @@ -85,6 +86,10 @@ static void rna_Image_source_set(PointerRNA *ptr, int value) ima->source = value; BLI_assert(BKE_id_is_in_global_main(&ima->id)); BKE_image_signal(G_MAIN, ima, NULL, IMA_SIGNAL_SRC_CHANGE); + if (ima->source == IMA_SRC_TILED) { + BKE_image_signal(G_MAIN, ima, NULL, IMA_SIGNAL_RELOAD); + } + DEG_id_tag_update(&ima->id, 0); DEG_id_tag_update(&ima->id, ID_RECALC_EDITORS); DEG_relations_tag_update(G_MAIN); @@ -100,6 +105,83 @@ static void rna_Image_reload_update(Main *bmain, Scene *UNUSED(scene), PointerRN DEG_id_tag_update(&ima->id, ID_RECALC_EDITORS); } +static int rna_Image_generated_type_get(PointerRNA *ptr) +{ + Image *ima = (Image *)ptr->data; + ImageTile *base_tile = BKE_image_get_tile(ima, 0); + return base_tile->gen_type; +} + +static void rna_Image_generated_type_set(PointerRNA *ptr, int value) +{ + Image *ima = (Image *)ptr->data; + ImageTile *base_tile = BKE_image_get_tile(ima, 0); + base_tile->gen_type = value; +} + +static int rna_Image_generated_width_get(PointerRNA *ptr) +{ + Image *ima = (Image *)ptr->data; + ImageTile *base_tile = BKE_image_get_tile(ima, 0); + return base_tile->gen_x; +} + +static void rna_Image_generated_width_set(PointerRNA *ptr, int value) +{ + Image *ima = (Image *)ptr->data; + ImageTile *base_tile = BKE_image_get_tile(ima, 0); + base_tile->gen_x = CLAMPIS(value, 1, 65536); +} + +static int rna_Image_generated_height_get(PointerRNA *ptr) +{ + Image *ima = (Image *)ptr->data; + ImageTile *base_tile = BKE_image_get_tile(ima, 0); + return base_tile->gen_y; +} + +static void rna_Image_generated_height_set(PointerRNA *ptr, int value) +{ + Image *ima = (Image *)ptr->data; + ImageTile *base_tile = BKE_image_get_tile(ima, 0); + base_tile->gen_y = CLAMPIS(value, 1, 65536); +} + +static bool rna_Image_generated_float_get(PointerRNA *ptr) +{ + Image *ima = (Image *)ptr->data; + ImageTile *base_tile = BKE_image_get_tile(ima, 0); + return (base_tile->gen_flag & IMA_GEN_FLOAT) != 0; +} + +static void rna_Image_generated_float_set(PointerRNA *ptr, bool value) +{ + Image *ima = (Image *)ptr->data; + ImageTile *base_tile = BKE_image_get_tile(ima, 0); + if (value) { + base_tile->gen_flag |= IMA_GEN_FLOAT; + } + else { + base_tile->gen_flag &= ~IMA_GEN_FLOAT; + } +} + +void rna_Image_generated_color_get(PointerRNA *ptr, float values[4]) +{ + Image *ima = (Image *)(ptr->data); + ImageTile *base_tile = BKE_image_get_tile(ima, 0); + copy_v4_v4(values, base_tile->gen_color); +} + +void rna_Image_generated_color_set(PointerRNA *ptr, const float values[4]) +{ + Image *ima = (Image *)(ptr->data); + ImageTile *base_tile = BKE_image_get_tile(ima, 0); + for (unsigned int i = 0; i < 4; i++) { + base_tile->gen_color[i] = CLAMPIS(values[i], 0.0f, FLT_MAX); + } +} + static void rna_Image_generated_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) { Image *ima = (Image *)ptr->owner_id; @@ -335,6 +417,18 @@ static void rna_UDIMTile_tile_number_set(PointerRNA *ptr, int value) } } +static void rna_UDIMTile_generated_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) +{ + Image *ima = (Image *)ptr->owner_id; + ImageTile *tile = (ImageTile *)ptr->data; + + /* If the tile is still marked as generated, then update the tile as requested. */ + if ((tile->gen_flag & IMA_GEN_TILE) != 0) { + BKE_image_fill_tile(ima, tile); + BKE_image_partial_update_mark_full_update(ima); + } +} + static int rna_Image_active_tile_index_get(PointerRNA *ptr) { Image *image = (Image *)ptr->data; @@ -896,6 +990,43 @@ static void rna_def_udim_tile(BlenderRNA *brna) 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); + + /* Generated tile information. */ + prop = RNA_def_property(srna, "generated_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "gen_type"); + RNA_def_property_enum_items(prop, rna_enum_image_generated_type_items); + RNA_def_property_ui_text(prop, "Generated Type", "Generated image type"); + RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_UDIMTile_generated_update"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + + prop = RNA_def_property(srna, "generated_width", PROP_INT, PROP_PIXEL); + RNA_def_property_int_sdna(prop, NULL, "gen_x"); + RNA_def_property_flag(prop, PROP_PROPORTIONAL); + RNA_def_property_range(prop, 1, 65536); + RNA_def_property_ui_text(prop, "Generated Width", "Generated image width"); + RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_UDIMTile_generated_update"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + + prop = RNA_def_property(srna, "generated_height", PROP_INT, PROP_PIXEL); + RNA_def_property_int_sdna(prop, NULL, "gen_y"); + RNA_def_property_flag(prop, PROP_PROPORTIONAL); + RNA_def_property_range(prop, 1, 65536); + RNA_def_property_ui_text(prop, "Generated Height", "Generated image height"); + RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_UDIMTile_generated_update"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + + prop = RNA_def_property(srna, "use_generated_float", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "gen_flag", IMA_GEN_FLOAT); + RNA_def_property_ui_text(prop, "Float Buffer", "Generate floating-point buffer"); + RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_UDIMTile_generated_update"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + + prop = RNA_def_property(srna, "generated_color", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "gen_color"); + RNA_def_property_array(prop, 4); + RNA_def_property_ui_text(prop, "Color", "Fill color for the generated image"); + RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_UDIMTile_generated_update"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); } static void rna_def_udim_tiles(BlenderRNA *brna, PropertyRNA *cprop) @@ -1079,6 +1210,8 @@ static void rna_def_image(BlenderRNA *brna) RNA_def_property_enum_sdna(prop, NULL, "gen_type"); RNA_def_property_enum_items(prop, rna_enum_image_generated_type_items); RNA_def_property_ui_text(prop, "Generated Type", "Generated image type"); + RNA_def_property_enum_funcs( + prop, "rna_Image_generated_type_get", "rna_Image_generated_type_set", NULL); RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_generated_update"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); @@ -1087,6 +1220,8 @@ static void rna_def_image(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_PROPORTIONAL); RNA_def_property_range(prop, 1, 65536); RNA_def_property_ui_text(prop, "Generated Width", "Generated image width"); + RNA_def_property_int_funcs( + prop, "rna_Image_generated_width_get", "rna_Image_generated_width_set", NULL); RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_generated_update"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); @@ -1095,12 +1230,16 @@ static void rna_def_image(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_PROPORTIONAL); RNA_def_property_range(prop, 1, 65536); RNA_def_property_ui_text(prop, "Generated Height", "Generated image height"); + RNA_def_property_int_funcs( + prop, "rna_Image_generated_height_get", "rna_Image_generated_height_set", NULL); RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_generated_update"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); prop = RNA_def_property(srna, "use_generated_float", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "gen_flag", IMA_GEN_FLOAT); RNA_def_property_ui_text(prop, "Float Buffer", "Generate floating-point buffer"); + RNA_def_property_boolean_funcs( + prop, "rna_Image_generated_float_get", "rna_Image_generated_float_set"); RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_generated_update"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); @@ -1108,6 +1247,8 @@ static void rna_def_image(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "gen_color"); RNA_def_property_array(prop, 4); RNA_def_property_ui_text(prop, "Color", "Fill color for the generated image"); + RNA_def_property_float_funcs( + prop, "rna_Image_generated_color_get", "rna_Image_generated_color_set", NULL); RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_generated_update"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); |