diff options
-rw-r--r-- | source/blender/editors/include/ED_render.h | 1 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_icons.c | 9 | ||||
-rw-r--r-- | source/blender/editors/render/render_preview.c | 91 |
3 files changed, 90 insertions, 11 deletions
diff --git a/source/blender/editors/include/ED_render.h b/source/blender/editors/include/ED_render.h index a49fe1aa544..ed35b9138f3 100644 --- a/source/blender/editors/include/ED_render.h +++ b/source/blender/editors/include/ED_render.h @@ -92,6 +92,7 @@ void ED_preview_shader_job(const struct bContext *C, int sizey, int method); void ED_preview_icon_render(struct Main *bmain, + struct Depsgraph *depsgraph, struct Scene *scene, struct ID *id, unsigned int *rect, diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index 1739035f92c..c16c3d2c49a 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -1426,8 +1426,13 @@ static void icon_set_image(const bContext *C, scene = CTX_data_scene(C); } /* Immediate version */ - ED_preview_icon_render( - CTX_data_main(C), scene, id, prv_img->rect[size], prv_img->w[size], prv_img->h[size]); + ED_preview_icon_render(CTX_data_main(C), + CTX_data_ensure_evaluated_depsgraph(C), + scene, + id, + prv_img->rect[size], + prv_img->w[size], + prv_img->h[size]); } } diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 4e766841c24..9811b7caa38 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -145,6 +145,7 @@ typedef struct IconPreviewSize { typedef struct IconPreview { Main *bmain; + Depsgraph *depsgraph; /* May be NULL (see #WM_OT_previews_ensure). */ Scene *scene; void *owner; ID *id, *id_copy; /* May be NULL! (see ICON_TYPE_PREVIEW case in #ui_icon_ensure_deferred()) */ @@ -808,6 +809,59 @@ static void object_preview_render(IconPreview *preview, IconPreviewSize *preview /** \} */ /* -------------------------------------------------------------------- */ +/** \name Action Preview + * \{ */ + +/* Render a pose. It is assumed that the pose has already been applied and that the scene camera is + * capturing the pose. In other words, this function just renders from the scene camera without + * evaluating the Action stored in preview->id. */ +static void action_preview_render(IconPreview *preview, IconPreviewSize *preview_sized) +{ + char err_out[256] = ""; + + Depsgraph *depsgraph = preview->depsgraph; + /* Not all code paths that lead to this function actually provide a depsgraph. + * The "Refresh Asset Preview" button (ED_OT_lib_id_generate_preview) does, + * but WM_OT_previews_ensure does not. */ + BLI_assert(depsgraph != NULL); + BLI_assert(preview->scene == DEG_get_input_scene(depsgraph)); + + Scene *scene_eval = DEG_get_evaluated_scene(depsgraph); + Object *camera_eval = scene_eval->camera; + if (camera_eval == NULL) { + printf("Scene has no camera, unable to render preview of %s without it.\n", + preview->id->name + 2); + return; + } + + /* This renders with the Workbench engine settings stored on the Scene. */ + ImBuf *ibuf = ED_view3d_draw_offscreen_imbuf_simple(depsgraph, + scene_eval, + NULL, + OB_SOLID, + camera_eval, + preview_sized->sizex, + preview_sized->sizey, + IB_rect, + V3D_OFSDRAW_NONE, + R_ALPHAPREMUL, + NULL, + NULL, + err_out); + + if (err_out[0] != '\0') { + printf("Error rendering Action %s preview: %s\n", preview->id->name + 2, err_out); + } + + if (ibuf) { + icon_copy_rect(ibuf, preview_sized->sizex, preview_sized->sizey, preview_sized->rect); + IMB_freeImBuf(ibuf); + } +} + +/** \} */ + +/* -------------------------------------------------------------------- */ /** \name New Shader Preview System * \{ */ @@ -1440,7 +1494,15 @@ static void icon_preview_startjob_all_sizes(void *customdata, continue; } - if (preview_method_is_render(pr_method) && !check_engine_supports_preview(ip->scene)) { + /* check_engine_supports_preview() checks whether the engine supports "preview mode" (think: + * Material Preview). This check is only relevant when the render function called below is + * going to use such a mode. Object and Action render functions use Solid mode, though, so they + * can skip this test. */ + /* TODO: Decouple the ID-type-specific render functions from this function, so that it's not + * necessary to know here what happens inside lower-level functions. */ + const bool use_solid_render_mode = (ip->id != NULL) && ELEM(GS(ip->id->name), ID_OB, ID_AC); + if (!use_solid_render_mode && preview_method_is_render(pr_method) && + !check_engine_supports_preview(ip->scene)) { continue; } @@ -1451,13 +1513,21 @@ static void icon_preview_startjob_all_sizes(void *customdata, } #endif - if (ip->id && ELEM(GS(ip->id->name), ID_OB)) { - /* Much simpler than the ShaderPreview mess used for other ID types. */ - object_preview_render(ip, cur_size); - } - else { - other_id_types_preview_render(ip, cur_size, pr_method, stop, do_update, progress); + if (ip->id != NULL) { + switch (GS(ip->id->name)) { + case ID_OB: + /* Much simpler than the ShaderPreview mess used for other ID types. */ + object_preview_render(ip, cur_size); + continue; + case ID_AC: + action_preview_render(ip, cur_size); + continue; + default: + /* Fall through to the same code as the `ip->id == NULL` case. */ + break; + } } + other_id_types_preview_render(ip, cur_size, pr_method, stop, do_update, progress); } } @@ -1537,7 +1607,8 @@ static void icon_preview_free(void *customdata) MEM_freeN(ip); } -void ED_preview_icon_render(Main *bmain, Scene *scene, ID *id, uint *rect, int sizex, int sizey) +void ED_preview_icon_render( + Main *bmain, Depsgraph *depsgraph, Scene *scene, ID *id, uint *rect, int sizex, int sizey) { IconPreview ip = {NULL}; short stop = false, update = false; @@ -1547,6 +1618,7 @@ void ED_preview_icon_render(Main *bmain, Scene *scene, ID *id, uint *rect, int s ip.bmain = bmain; ip.scene = scene; + ip.depsgraph = depsgraph; ip.owner = BKE_previewimg_id_ensure(id); ip.id = id; /* Control isn't given back to the caller until the preview is done. So we don't need to copy @@ -1591,7 +1663,8 @@ void ED_preview_icon_job( /* customdata for preview thread */ ip->bmain = CTX_data_main(C); - ip->scene = CTX_data_scene(C); + ip->depsgraph = CTX_data_ensure_evaluated_depsgraph(C); + ip->scene = DEG_get_input_scene(ip->depsgraph); ip->owner = owner; ip->id = id; ip->id_copy = duplicate_ids(id, false); |