diff --git a/release/scripts/startup/bl_ui/space_filebrowser.py b/release/scripts/startup/bl_ui/space_filebrowser.py index 731a220848e..50005a8f7f0 100644 --- a/release/scripts/startup/bl_ui/space_filebrowser.py +++ b/release/scripts/startup/bl_ui/space_filebrowser.py @@ -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, diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h index 6ffeb4134ae..1009ae5cd3f 100644 --- a/source/blender/editors/include/UI_interface_icons.h +++ b/source/blender/editors/include/UI_interface_icons.h @@ -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 */ diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index 0f5b4a1a0f1..c0d6b8a1a6c 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -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) diff --git a/source/blender/editors/util/ed_util_ops.cc b/source/blender/editors/util/ed_util_ops.cc index a1b17d799bc..ae37dab7bb4 100644 --- a/source/blender/editors/util/ed_util_ops.cc +++ b/source/blender/editors/util/ed_util_ops.cc @@ -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);