diff options
Diffstat (limited to 'source/blender/blenkernel/intern/image.cc')
-rw-r--r-- | source/blender/blenkernel/intern/image.cc | 125 |
1 files changed, 97 insertions, 28 deletions
diff --git a/source/blender/blenkernel/intern/image.cc b/source/blender/blenkernel/intern/image.cc index 0c1f01c3796..c2b8ec95a46 100644 --- a/source/blender/blenkernel/intern/image.cc +++ b/source/blender/blenkernel/intern/image.cc @@ -863,33 +863,46 @@ void BKE_image_get_tile_uv(const Image *ima, const int tile_number, float r_uv[2 } } -int BKE_image_find_nearest_tile(const Image *image, const float co[2]) +int BKE_image_find_nearest_tile_with_offset(const Image *image, + const float co[2], + float r_uv_offset[2]) { - const float co_floor[2] = {floorf(co[0]), floorf(co[1])}; - /* Distance to the closest UDIM tile. */ + /* Distance squared to the closest UDIM tile. */ float dist_best_sq = FLT_MAX; + float uv_offset_best[2] = {0, 0}; int tile_number_best = -1; + const float co_offset[2] = {co[0] - 0.5f, co[1] - 0.5f}; + LISTBASE_FOREACH (const ImageTile *, tile, &image->tiles) { float uv_offset[2]; BKE_image_get_tile_uv(image, tile->tile_number, uv_offset); - if (equals_v2v2(co_floor, uv_offset)) { - return tile->tile_number; - } - - /* Distance between co[2] and UDIM tile. */ - const float dist_sq = len_squared_v2v2(uv_offset, co); + /* Distance squared between co[2] and center of UDIM tile. */ + const float dist_sq = len_squared_v2v2(uv_offset, co_offset); if (dist_sq < dist_best_sq) { dist_best_sq = dist_sq; tile_number_best = tile->tile_number; + copy_v2_v2(uv_offset_best, uv_offset); + + if (dist_best_sq < 0.5f * 0.5f) { + break; /* No other tile can be closer. */ + } } } - + if (tile_number_best != -1) { + copy_v2_v2(r_uv_offset, uv_offset_best); + } return tile_number_best; } +int BKE_image_find_nearest_tile(const struct Image *image, const float co[2]) +{ + float uv_offset_dummy[2]; + return BKE_image_find_nearest_tile_with_offset(image, co, uv_offset_dummy); +} + static void image_init_color_management(Image *ima) { ImBuf *ibuf; @@ -1172,24 +1185,83 @@ Image *BKE_image_add_generated(Main *bmain, return ima; } -Image *BKE_image_add_from_imbuf(Main *bmain, ImBuf *ibuf, const char *name) +static void image_colorspace_from_imbuf(Image *image, const ImBuf *ibuf) { - Image *ima; + const char *colorspace_name = NULL; + if (ibuf->rect_float) { + if (ibuf->float_colorspace) { + colorspace_name = IMB_colormanagement_colorspace_get_name(ibuf->float_colorspace); + } + else { + colorspace_name = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_FLOAT); + } + } + + if (ibuf->rect && !colorspace_name) { + if (ibuf->rect_colorspace) { + colorspace_name = IMB_colormanagement_colorspace_get_name(ibuf->rect_colorspace); + } + else { + colorspace_name = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_BYTE); + } + } + + if (colorspace_name) { + STRNCPY(image->colorspace_settings.name, colorspace_name); + } +} + +Image *BKE_image_add_from_imbuf(Main *bmain, ImBuf *ibuf, const char *name) +{ if (name == nullptr) { name = BLI_path_basename(ibuf->name); } - ima = image_alloc(bmain, name, IMA_SRC_FILE, IMA_TYPE_IMAGE); + /* When the image buffer has valid path create a new image with "file" source and copy the path + * from the image buffer. + * Otherwise create "generated" image, avoiding invalid configuration with an empty file path. */ + const eImageSource source = ibuf->name[0] != '\0' ? IMA_SRC_FILE : IMA_SRC_GENERATED; - if (ima) { - STRNCPY(ima->filepath, ibuf->name); - image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0); + Image *ima = image_alloc(bmain, name, source, IMA_TYPE_IMAGE); + + if (!ima) { + return nullptr; } + BKE_image_replace_imbuf(ima, ibuf); + return ima; } +void BKE_image_replace_imbuf(Image *image, ImBuf *ibuf) +{ + BLI_assert(image->type == IMA_TYPE_IMAGE && + ELEM(image->source, IMA_SRC_FILE, IMA_SRC_GENERATED)); + + BKE_image_free_buffers(image); + + image_assign_ibuf(image, ibuf, IMA_NO_INDEX, 0); + image_colorspace_from_imbuf(image, ibuf); + + /* Keep generated image type flags consistent with the image buffer. */ + if (image->source == IMA_SRC_GENERATED) { + if (ibuf->rect_float) { + image->gen_flag |= IMA_GEN_FLOAT; + } + else { + image->gen_flag &= ~IMA_GEN_FLOAT; + } + + image->gen_x = ibuf->x; + image->gen_y = ibuf->y; + } + + /* Consider image dirty since its content can not be re-created unless the image is explicitly + * saved. */ + BKE_image_mark_dirty(image, ibuf); +} + /** Pack image buffer to memory as PNG or EXR. */ static bool image_memorypack_imbuf( Image *ima, ImBuf *ibuf, int view, int tile_number, const char *filepath) @@ -1582,7 +1654,7 @@ static void stampdata( } if (use_dynamic && scene->r.stamp & R_STAMP_MARKER) { - const char *name = BKE_scene_find_last_marker_name(scene, CFRA); + const char *name = BKE_scene_find_last_marker_name(scene, scene->r.cfra); if (name) { STRNCPY(text, name); @@ -1950,7 +2022,7 @@ void BKE_image_stamp_buf(Scene *scene, y -= BUFF_MARGIN_Y * 2; } - /* Top left corner, below File, Date, Rendertime */ + /* Top left corner, below File, Date, Render-time */ if (TEXT_SIZE_CHECK(stamp_data.memory, w, h)) { y -= h; @@ -1973,7 +2045,7 @@ void BKE_image_stamp_buf(Scene *scene, y -= BUFF_MARGIN_Y * 2; } - /* Top left corner, below File, Date, Rendertime, Memory */ + /* Top left corner, below: File, Date, Render-time, Memory. */ if (TEXT_SIZE_CHECK(stamp_data.hostname, w, h)) { y -= h; @@ -1996,7 +2068,7 @@ void BKE_image_stamp_buf(Scene *scene, y -= BUFF_MARGIN_Y * 2; } - /* Top left corner, below File, Date, Memory, Rendertime, Hostname */ + /* Top left corner, below: File, Date, Memory, Render-time, Host-name. */ BLF_enable(mono, BLF_WORD_WRAP); if (TEXT_SIZE_CHECK_WORD_WRAP(stamp_data.note, w, h)) { y -= h; @@ -2416,7 +2488,10 @@ int BKE_imbuf_write(ImBuf *ibuf, const char *name, const ImageFormatData *imf) return ok; } -int BKE_imbuf_write_as(ImBuf *ibuf, const char *name, ImageFormatData *imf, const bool save_copy) +int BKE_imbuf_write_as(ImBuf *ibuf, + const char *name, + const ImageFormatData *imf, + const bool save_copy) { ImBuf ibuf_back = *ibuf; int ok; @@ -4998,13 +5073,7 @@ void BKE_image_get_size(Image *image, ImageUser *iuser, int *r_width, int *r_hei } else if (image != nullptr && image->type == IMA_TYPE_R_RESULT && iuser != nullptr && iuser->scene != nullptr) { - Scene *scene = iuser->scene; - *r_width = (scene->r.xsch * scene->r.size) / 100; - *r_height = (scene->r.ysch * scene->r.size) / 100; - if ((scene->r.mode & R_BORDER) && (scene->r.mode & R_CROP)) { - *r_width *= BLI_rctf_size_x(&scene->r.border); - *r_height *= BLI_rctf_size_y(&scene->r.border); - } + BKE_render_resolution(&iuser->scene->r, true, r_width, r_height); } else { *r_width = IMG_SIZE_FALLBACK; |