Assets: allow creating preview image by rendering active object

For node groups there is no good default preview generation.
Nevertheless, t would be useful to generate a preview image for a
node group by rendering an object in some cases.

This commit adds a new operator that allows updating the preview
image for the active asset by rendering the active object.
Note, the operator can also be used for other asset types, not just
node groups.

The operator can be found in a menu right below the refresh-preview
button. Currently it is the only operator in that menu. In the future,
more operators to create previews may be added.

Differential Revision: https://developer.blender.org/D13747
This commit is contained in:
Jacques Lucke 2022-01-26 15:05:31 +01:00
parent 6738ecb64e
commit 12b26d21b0
Notes: blender-bot 2023-02-14 06:27:47 +01:00
Referenced by issue #93754, Preview generation for node groups
4 changed files with 101 additions and 4 deletions

View File

@ -761,6 +761,15 @@ class ASSETBROWSER_PT_metadata_preview(asset_utils.AssetMetaDataPanel, Panel):
col.operator("ed.lib_id_load_custom_preview", icon='FILEBROWSER', text="")
col.separator()
col.operator("ed.lib_id_generate_preview", icon='FILE_REFRESH', text="")
col.menu("ASSETBROWSER_MT_metadata_preview_menu", icon='DOWNARROW_HLT', text="")
class ASSETBROWSER_MT_metadata_preview_menu(bpy.types.Menu):
bl_label = "Preview"
def draw(self, context):
layout = self.layout
layout.operator("ed.lib_id_generate_preview_from_object", text="Render Active Object")
class ASSETBROWSER_PT_metadata_tags(asset_utils.AssetMetaDataPanel, Panel):
@ -840,6 +849,7 @@ classes = (
ASSETBROWSER_MT_view,
ASSETBROWSER_MT_select,
ASSETBROWSER_MT_edit,
ASSETBROWSER_MT_metadata_preview_menu,
ASSETBROWSER_PT_metadata,
ASSETBROWSER_PT_metadata_preview,
ASSETBROWSER_PT_metadata_tags,

View File

@ -82,6 +82,8 @@ int UI_icon_get_height(int icon_id);
bool UI_icon_get_theme_color(int icon_id, unsigned char color[4]);
/**
* Render a #PreviewImage for the data block.
*
* Note that if an ID doesn't support jobs for preview creation, \a use_job will be ignored.
*/
void UI_icon_render_id(const struct bContext *C,
@ -89,6 +91,18 @@ void UI_icon_render_id(const struct bContext *C,
struct ID *id,
enum eIconSizes size,
bool use_job);
/**
* Render the data block into the provided #PreviewImage.
*/
void UI_icon_render_id_ex(const struct bContext *C,
struct Scene *scene,
struct ID *id_to_render,
const enum eIconSizes size,
const bool use_job,
struct PreviewImage *r_preview_image);
/**
* Render size for preview images and icons
*/

View File

@ -1949,6 +1949,16 @@ static void ui_id_preview_image_render_size(
}
}
void UI_icon_render_id_ex(const bContext *C,
Scene *scene,
ID *id_to_render,
const enum eIconSizes size,
const bool use_job,
PreviewImage *r_preview_image)
{
ui_id_preview_image_render_size(C, scene, id_to_render, r_preview_image, size, use_job);
}
void UI_icon_render_id(
const bContext *C, Scene *scene, ID *id, const enum eIconSizes size, const bool use_job)
{
@ -1957,19 +1967,21 @@ void UI_icon_render_id(
return;
}
ID *id_to_render = id;
/* For objects, first try if a preview can created via the object data. */
if (GS(id->name) == ID_OB) {
Object *ob = (Object *)id;
if (ED_preview_id_is_supported(ob->data)) {
id = ob->data;
id_to_render = ob->data;
}
}
if (!ED_preview_id_is_supported(id)) {
if (!ED_preview_id_is_supported(id_to_render)) {
return;
}
ui_id_preview_image_render_size(C, scene, id, pi, size, use_job);
UI_icon_render_id_ex(C, scene, id_to_render, size, use_job, pi);
}
static void ui_id_icon_render(const bContext *C, ID *id, bool use_jobs)

View File

@ -121,6 +121,22 @@ static void ED_OT_lib_id_load_custom_preview(wmOperatorType *ot)
FILE_SORT_DEFAULT);
}
static bool lib_id_generate_preview_poll(bContext *C)
{
if (!lib_id_preview_editing_poll(C)) {
return false;
}
const PointerRNA idptr = CTX_data_pointer_get(C, "id");
const ID *id = (ID *)idptr.data;
if (GS(id->name) == ID_NT) {
CTX_wm_operator_poll_msg_set(C, TIP_("Can't generate automatic preview for node group"));
return false;
}
return true;
}
static int lib_id_generate_preview_exec(bContext *C, wmOperator *UNUSED(op))
{
PointerRNA idptr = CTX_data_pointer_get(C, "id");
@ -148,13 +164,57 @@ static void ED_OT_lib_id_generate_preview(wmOperatorType *ot)
ot->idname = "ED_OT_lib_id_generate_preview";
/* api callbacks */
ot->poll = lib_id_preview_editing_poll;
ot->poll = lib_id_generate_preview_poll;
ot->exec = lib_id_generate_preview_exec;
/* flags */
ot->flag = OPTYPE_INTERNAL | OPTYPE_REGISTER | OPTYPE_UNDO;
}
static bool lib_id_generate_preview_from_object_poll(bContext *C)
{
if (!lib_id_preview_editing_poll(C)) {
return false;
}
if (CTX_data_active_object(C) == nullptr) {
return false;
}
return true;
}
static int lib_id_generate_preview_from_object_exec(bContext *C, wmOperator *UNUSED(op))
{
PointerRNA idptr = CTX_data_pointer_get(C, "id");
ID *id = (ID *)idptr.data;
ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
Object *object_to_render = CTX_data_active_object(C);
BKE_previewimg_id_free(id);
PreviewImage *preview_image = BKE_previewimg_id_ensure(id);
UI_icon_render_id_ex(C, nullptr, &object_to_render->id, ICON_SIZE_PREVIEW, true, preview_image);
WM_event_add_notifier(C, NC_ASSET | NA_EDITED, nullptr);
ED_assetlist_storage_tag_main_data_dirty();
return OPERATOR_FINISHED;
}
static void ED_OT_lib_id_generate_preview_from_object(wmOperatorType *ot)
{
ot->name = "Generate Preview from Object";
ot->description = "Create a preview for this asset by rendering the active object";
ot->idname = "ED_OT_lib_id_generate_preview_from_object";
/* api callbacks */
ot->poll = lib_id_generate_preview_from_object_poll;
ot->exec = lib_id_generate_preview_from_object_exec;
/* flags */
ot->flag = OPTYPE_INTERNAL | OPTYPE_REGISTER | OPTYPE_UNDO;
}
/** \} */
/* -------------------------------------------------------------------- */
@ -280,6 +340,7 @@ void ED_operatortypes_edutils()
{
WM_operatortype_append(ED_OT_lib_id_load_custom_preview);
WM_operatortype_append(ED_OT_lib_id_generate_preview);
WM_operatortype_append(ED_OT_lib_id_generate_preview_from_object);
WM_operatortype_append(ED_OT_lib_id_fake_user_toggle);
WM_operatortype_append(ED_OT_lib_id_unlink);