diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2015-05-11 17:29:12 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2015-05-11 17:37:15 +0300 |
commit | d30f664c0438e8378c79d5beb114b1338d0e1d94 (patch) | |
tree | 77e6684c118464c899f6e031fe999891eb38fb52 /source/blender/editors/render | |
parent | e38f9144212dc0e7e7f3e6be9b3315435d1669eb (diff) |
Expose PreviewImage & custom icons to py API.
This commit mainly:
* Exposes PreviewImage struct in RNA, including ways for user to set images data.
* Adds a new kind of PreviewImage, using a file path and IMB_thumb to get image.
* Adds a new kind of custom icon using PreviewImage, unrelated to ID previews system.
* Adds a python API (utils.previews) to allow python scripts to access those custom previews/icons.
Note that loading image from files' thumbnails is done when needed (deferred loading), not
when defining the custom preview/icon.
WARNING: for release addons who would want to use this, please keep it to a strict minimum, really needed level.
We do not want our UI to explode under hundreds of different flashy icons!
For more info, see also the release notes of Blender 2.75 (http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.75/Addons)
and the example/templates featured with Blender.
Patch by Campbell (ideasman42), Inês (brita) and Bastien (mont29).
Differential Revision: https://developer.blender.org/D1255
Diffstat (limited to 'source/blender/editors/render')
-rw-r--r-- | source/blender/editors/render/render_preview.c | 149 | ||||
-rw-r--r-- | source/blender/editors/render/render_update.c | 16 |
2 files changed, 96 insertions, 69 deletions
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 65d4c2301a9..5112cd84d09 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -79,7 +79,7 @@ #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" - +#include "IMB_thumbs.h" #include "BIF_gl.h" #include "BIF_glutil.h" @@ -128,7 +128,7 @@ ImBuf *get_brush_icon(Brush *brush) } if (brush->icon_imbuf) - BKE_icon_changed(BKE_icon_getid(&brush->id)); + BKE_icon_changed(BKE_icon_id_ensure(&brush->id)); } } } @@ -935,65 +935,87 @@ static void set_alpha(char *cp, int sizex, int sizey, char alpha) static void icon_preview_startjob(void *customdata, short *stop, short *do_update) { ShaderPreview *sp = customdata; - ID *id = sp->id; - short idtype = GS(id->name); - - if (idtype == ID_IM) { - Image *ima = (Image *)id; - ImBuf *ibuf = NULL; - ImageUser iuser = {NULL}; - /* ima->ok is zero when Image cannot load */ - if (ima == NULL || ima->ok == 0) - return; + if (sp->pr_method == PR_ICON_DEFERRED) { + PreviewImage *prv = sp->owner; + ImBuf *thumb; + char *deferred_data = PRV_DEFERRED_DATA(prv); + int source = deferred_data[0]; + char *path = &deferred_data[1]; - /* setup dummy image user */ - iuser.ok = iuser.framenr = 1; - iuser.scene = sp->scene; - - /* elubie: this needs to be changed: here image is always loaded if not - * already there. Very expensive for large images. Need to find a way to - * only get existing ibuf */ - ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); - if (ibuf == NULL || ibuf->rect == NULL) { - BKE_image_release_ibuf(ima, ibuf, NULL); - return; - } - - icon_copy_rect(ibuf, sp->sizex, sp->sizey, sp->pr_rect); +// printf("generating deferred %d×%d preview for %s\n", sp->sizex, sp->sizey, path); + + thumb = IMB_thumb_manage(path, THB_LARGE, source); - *do_update = true; + if (thumb) { + /* PreviewImage assumes premultiplied alhpa... */ + IMB_premultiply_alpha(thumb); - BKE_image_release_ibuf(ima, ibuf, NULL); + icon_copy_rect(thumb, sp->sizex, sp->sizey, sp->pr_rect); + IMB_freeImBuf(thumb); + } } - else if (idtype == ID_BR) { - Brush *br = (Brush *)id; + else { + ID *id = sp->id; + short idtype = GS(id->name); + + if (idtype == ID_IM) { + Image *ima = (Image *)id; + ImBuf *ibuf = NULL; + ImageUser iuser = {NULL}; + + /* ima->ok is zero when Image cannot load */ + if (ima == NULL || ima->ok == 0) + return; + + /* setup dummy image user */ + iuser.ok = iuser.framenr = 1; + iuser.scene = sp->scene; + + /* elubie: this needs to be changed: here image is always loaded if not + * already there. Very expensive for large images. Need to find a way to + * only get existing ibuf */ + ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); + if (ibuf == NULL || ibuf->rect == NULL) { + BKE_image_release_ibuf(ima, ibuf, NULL); + return; + } - br->icon_imbuf = get_brush_icon(br); + icon_copy_rect(ibuf, sp->sizex, sp->sizey, sp->pr_rect); - memset(sp->pr_rect, 0x88, sp->sizex * sp->sizey * sizeof(unsigned int)); + *do_update = true; - if (!(br->icon_imbuf) || !(br->icon_imbuf->rect)) - return; + BKE_image_release_ibuf(ima, ibuf, NULL); + } + else if (idtype == ID_BR) { + Brush *br = (Brush *)id; - icon_copy_rect(br->icon_imbuf, sp->sizex, sp->sizey, sp->pr_rect); + br->icon_imbuf = get_brush_icon(br); - *do_update = true; - } - else { - /* re-use shader job */ - shader_preview_startjob(customdata, stop, do_update); + memset(sp->pr_rect, 0x88, sp->sizex * sp->sizey * sizeof(unsigned int)); + + if (!(br->icon_imbuf) || !(br->icon_imbuf->rect)) + return; - /* world is rendered with alpha=0, so it wasn't displayed - * this could be render option for sky to, for later */ - if (idtype == ID_WO) { - set_alpha((char *)sp->pr_rect, sp->sizex, sp->sizey, 255); + icon_copy_rect(br->icon_imbuf, sp->sizex, sp->sizey, sp->pr_rect); + + *do_update = true; } - else if (idtype == ID_MA) { - Material *ma = (Material *)id; + else { + /* re-use shader job */ + shader_preview_startjob(customdata, stop, do_update); - if (ma->material_type == MA_TYPE_HALO) + /* world is rendered with alpha=0, so it wasn't displayed + * this could be render option for sky to, for later */ + if (idtype == ID_WO) { set_alpha((char *)sp->pr_rect, sp->sizex, sp->sizey, 255); + } + else if (idtype == ID_MA) { + Material *ma = (Material *)id; + + if (ma->material_type == MA_TYPE_HALO) + set_alpha((char *)sp->pr_rect, sp->sizex, sp->sizey, 255); + } } } } @@ -1005,7 +1027,7 @@ static void common_preview_startjob(void *customdata, short *stop, short *do_upd { ShaderPreview *sp = customdata; - if (sp->pr_method == PR_ICON_RENDER) + if (ELEM(sp->pr_method, PR_ICON_RENDER, PR_ICON_DEFERRED)) icon_preview_startjob(customdata, stop, do_update); else shader_preview_startjob(customdata, stop, do_update); @@ -1041,29 +1063,34 @@ static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short const bool use_new_shading = BKE_scene_use_new_shading_nodes(ip->scene); while (cur_size) { + PreviewImage *prv = ip->owner; ShaderPreview *sp = MEM_callocN(sizeof(ShaderPreview), "Icon ShaderPreview"); + const bool is_render = !prv->use_deferred; /* construct shader preview from image size and previewcustomdata */ sp->scene = ip->scene; sp->owner = ip->owner; sp->sizex = cur_size->sizex; sp->sizey = cur_size->sizey; - sp->pr_method = PR_ICON_RENDER; + sp->pr_method = is_render ? PR_ICON_RENDER : PR_ICON_DEFERRED; sp->pr_rect = cur_size->rect; sp->id = ip->id; - if (use_new_shading) { - /* texture icon rendering is hardcoded to use BI, - * so don't even think of using cycle's bmain for - * texture icons - */ - if (GS(ip->id->name) != ID_TE) - sp->pr_main = G_pr_main_cycles; - else + if (is_render) { + BLI_assert(ip->id); + if (use_new_shading) { + /* texture icon rendering is hardcoded to use BI, + * so don't even think of using cycle's bmain for + * texture icons + */ + if (GS(ip->id->name) != ID_TE) + sp->pr_main = G_pr_main_cycles; + else + sp->pr_main = G_pr_main; + } + else { sp->pr_main = G_pr_main; - } - else { - sp->pr_main = G_pr_main; + } } common_preview_startjob(sp, stop, do_update, progress); @@ -1145,7 +1172,7 @@ void ED_preview_icon_job(const bContext *C, void *owner, ID *id, unsigned int *r /* customdata for preview thread */ ip->scene = CTX_data_scene(C); - ip->owner = id; + ip->owner = owner; ip->id = id; icon_preview_add_size(ip, rect, sizex, sizey); diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c index d3d5cb12ac8..dedcbb144aa 100644 --- a/source/blender/editors/render/render_update.c +++ b/source/blender/editors/render/render_update.c @@ -270,7 +270,7 @@ static void material_changed(Main *bmain, Material *ma) int texture_draw = false; /* icons */ - BKE_icon_changed(BKE_icon_getid(&ma->id)); + BKE_icon_changed(BKE_icon_id_ensure(&ma->id)); /* glsl */ if (ma->gpumaterial.first) @@ -285,7 +285,7 @@ static void material_changed(Main *bmain, Material *ma) continue; } - BKE_icon_changed(BKE_icon_getid(&parent->id)); + BKE_icon_changed(BKE_icon_id_ensure(&parent->id)); if (parent->gpumaterial.first) GPU_material_free(&parent->gpumaterial); @@ -325,7 +325,7 @@ static void lamp_changed(Main *bmain, Lamp *la) Material *ma; /* icons */ - BKE_icon_changed(BKE_icon_getid(&la->id)); + BKE_icon_changed(BKE_icon_id_ensure(&la->id)); /* glsl */ for (ob = bmain->object.first; ob; ob = ob->id.next) @@ -361,7 +361,7 @@ static void texture_changed(Main *bmain, Tex *tex) bool texture_draw = false; /* icons */ - BKE_icon_changed(BKE_icon_getid(&tex->id)); + BKE_icon_changed(BKE_icon_id_ensure(&tex->id)); /* paint overlays */ for (scene = bmain->scene.first; scene; scene = scene->id.next) @@ -372,7 +372,7 @@ static void texture_changed(Main *bmain, Tex *tex) if (!material_uses_texture(ma, tex)) continue; - BKE_icon_changed(BKE_icon_getid(&ma->id)); + BKE_icon_changed(BKE_icon_id_ensure(&ma->id)); if (ma->gpumaterial.first) GPU_material_free(&ma->gpumaterial); @@ -403,7 +403,7 @@ static void texture_changed(Main *bmain, Tex *tex) continue; } - BKE_icon_changed(BKE_icon_getid(&wo->id)); + BKE_icon_changed(BKE_icon_id_ensure(&wo->id)); if (wo->gpumaterial.first) GPU_material_free(&wo->gpumaterial); @@ -451,7 +451,7 @@ static void world_changed(Main *bmain, World *wo) Material *ma; /* icons */ - BKE_icon_changed(BKE_icon_getid(&wo->id)); + BKE_icon_changed(BKE_icon_id_ensure(&wo->id)); /* glsl */ for (ma = bmain->mat.first; ma; ma = ma->id.next) @@ -470,7 +470,7 @@ static void image_changed(Main *bmain, Image *ima) Tex *tex; /* icons */ - BKE_icon_changed(BKE_icon_getid(&ima->id)); + BKE_icon_changed(BKE_icon_id_ensure(&ima->id)); /* textures */ for (tex = bmain->tex.first; tex; tex = tex->id.next) |