Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSybren A. Stüvel <sybren@blender.org>2021-02-26 14:44:08 +0300
committerSybren A. Stüvel <sybren@blender.org>2021-02-26 14:44:08 +0300
commit17534e28ff44cf3d002e9ca198fd83909814c0f7 (patch)
tree42bcdda833399cc6098ce904641ec4ad515b5862
parente1a541c689b21e4aa759bb497dbcfc45b8220637 (diff)
Assets: Preview rendering for Action datablocks
Render previews for Action datablocks by rendering the scene camera with the Workbench (solid) engine. The //look// can be configured by setting the scene's render engine to Workbench and editing the scene's shading properties. It is assumed that the pose has already been applied and that the scene camera is capturing the pose. In other words, the render function just renders from the scene camera without evaluating/applying the Action stored in `preview->id`. The ID is only used to determine its type and to store the resulting preview. Not all code paths that lead to the `action_preview_render()` function actually provide a depsgraph. The "Refresh Asset Preview" button (`ED_OT_lib_id_generate_preview`) does, but `WM_OT_previews_ensure` does not. Reviewed By: Severin Differential Revision: https://developer.blender.org/D10543
-rw-r--r--source/blender/editors/include/ED_render.h1
-rw-r--r--source/blender/editors/interface/interface_icons.c9
-rw-r--r--source/blender/editors/render/render_preview.c91
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);