From 58632a7f3c0f1be6cc860c7cad9c41ba43e6454f Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Sun, 5 Sep 2021 21:05:07 -0700 Subject: UI: Blend Preview Thumbnails Showing Workspace This adds an option to use a capture of the entire main window as the blend file preview thumbnail. See D10492 for details and examples. Differential Revision: https://developer.blender.org/D10492 Reviewed by Campbell Barton --- release/datafiles/userdef/userdef_default.c | 5 +- release/scripts/startup/bl_ui/space_userpref.py | 2 +- source/blender/blenkernel/BKE_blender_version.h | 2 +- source/blender/blenkernel/intern/icons.cc | 2 +- .../blender/blenloader/intern/versioning_userdef.c | 8 +++ source/blender/makesdna/DNA_userdef_types.h | 12 +++- source/blender/makesrna/intern/rna_userdef.c | 16 +++-- source/blender/windowmanager/intern/wm_files.c | 69 +++++++++++++++++++--- 8 files changed, 96 insertions(+), 20 deletions(-) diff --git a/release/datafiles/userdef/userdef_default.c b/release/datafiles/userdef/userdef_default.c index d51a82c482b..29288dcd8fd 100644 --- a/release/datafiles/userdef/userdef_default.c +++ b/release/datafiles/userdef/userdef_default.c @@ -33,8 +33,8 @@ const UserDef U_default = { .versionfile = BLENDER_FILE_VERSION, .subversionfile = BLENDER_FILE_SUBVERSION, - .flag = (USER_AUTOSAVE | USER_TOOLTIPS | USER_SAVE_PREVIEWS | USER_RELPATHS | - USER_RELEASECONFIRM | USER_SCRIPT_AUTOEXEC_DISABLE | USER_NONEGFRAMES), + .flag = (USER_AUTOSAVE | USER_TOOLTIPS | USER_RELPATHS | USER_RELEASECONFIRM | + USER_SCRIPT_AUTOEXEC_DISABLE | USER_NONEGFRAMES), .dupflag = USER_DUP_MESH | USER_DUP_CURVE | USER_DUP_SURF | USER_DUP_FONT | USER_DUP_MBALL | USER_DUP_LAMP | USER_DUP_ARM | USER_DUP_ACT | USER_DUP_LIGHTPROBE | USER_DUP_GPENCIL, @@ -231,6 +231,7 @@ const UserDef U_default = { .collection_instance_empty_size = 1.0f, .statusbar_flag = STATUSBAR_SHOW_VERSION, + .file_preview_type = USER_FILE_PREVIEW_CAMERA, .runtime = { diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 708701c4804..1ac19d020d8 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -1414,7 +1414,7 @@ class USERPREF_PT_saveload_blend(SaveLoadPanel, CenterAlignMixIn, Panel): col = layout.column(heading="Save") col.prop(view, "use_save_prompt") - col.prop(paths, "use_save_preview_images") + col.prop(paths, "file_preview_type") col = layout.column(heading="Default To") col.prop(paths, "use_relative_paths") diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index 5dc4ebaa7a4..e2788020628 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -39,7 +39,7 @@ extern "C" { /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 20 +#define BLENDER_FILE_SUBVERSION 21 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and show a warning if the file diff --git a/source/blender/blenkernel/intern/icons.cc b/source/blender/blenkernel/intern/icons.cc index 5a4b2448a73..ac45e57f413 100644 --- a/source/blender/blenkernel/intern/icons.cc +++ b/source/blender/blenkernel/intern/icons.cc @@ -634,7 +634,7 @@ void BKE_previewimg_blend_write(BlendWriter *writer, const PreviewImage *prv) PreviewImage prv_copy = *prv; /* don't write out large previews if not requested */ - if (!(U.flag & USER_SAVE_PREVIEWS)) { + if (U.file_preview_type == USER_FILE_PREVIEW_NONE) { prv_copy.w[1] = 0; prv_copy.h[1] = 0; prv_copy.rect[1] = nullptr; diff --git a/source/blender/blenloader/intern/versioning_userdef.c b/source/blender/blenloader/intern/versioning_userdef.c index 0042ff29dc2..19f6c1cbbf6 100644 --- a/source/blender/blenloader/intern/versioning_userdef.c +++ b/source/blender/blenloader/intern/versioning_userdef.c @@ -885,6 +885,14 @@ void blo_do_versions_userdef(UserDef *userdef) BKE_addon_ensure(&userdef->addons, "pose_library"); } + if (!USER_VERSION_ATLEAST(300, 21)) { + /* Deprecated userdef->flag USER_SAVE_PREVIEWS */ + userdef->file_preview_type = (userdef->flag & USER_FLAG_UNUSED_5) ? USER_FILE_PREVIEW_CAMERA : + USER_FILE_PREVIEW_NONE; + /* Clear for reuse. */ + userdef->flag &= ~USER_FLAG_UNUSED_5; + } + /** * Versioning code until next subversion bump goes here. * diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 27376432092..b519a6014f0 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -924,8 +924,9 @@ typedef struct UserDef { short sequencer_proxy_setup; /* eUserpref_SeqProxySetup */ float collection_instance_empty_size; - char _pad10[3]; + char _pad10[2]; + char file_preview_type; /* eUserpref_File_Preview_Type */ char statusbar_flag; /* eUserpref_StatusBar_Flag */ struct WalkNavigation walk_navigation; @@ -996,7 +997,7 @@ typedef enum eUserPref_Flag { USER_NONUMPAD = (1 << 13), USER_ADD_CURSORALIGNED = (1 << 14), USER_FILECOMPRESS = (1 << 15), - USER_SAVE_PREVIEWS = (1 << 16), + USER_FLAG_UNUSED_5 = (1 << 16), /* dirty */ USER_CUSTOM_RANGE = (1 << 17), USER_ADD_EDITMODE = (1 << 18), USER_ADD_VIEWALIGNED = (1 << 19), @@ -1010,6 +1011,13 @@ typedef enum eUserPref_Flag { USER_FLAG_UNUSED_27 = (1 << 27), /* dirty */ } eUserPref_Flag; +/** #UserDef.file_preview_type */ +typedef enum eUserpref_File_Preview_Type { + USER_FILE_PREVIEW_NONE = 0, + USER_FILE_PREVIEW_SCREENSHOT, + USER_FILE_PREVIEW_CAMERA, +} eUserpref_File_Preview_Type; + typedef enum eUserPref_PrefFlag { USER_PREF_FLAG_SAVE = (1 << 0), } eUserPref_PrefFlag; diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 73811924c23..fe1b0757690 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -6059,6 +6059,13 @@ static void rna_def_userdef_filepaths(BlenderRNA *brna) {0, NULL, 0, NULL, NULL}, }; + static const EnumPropertyItem preview_type_items[] = { + {USER_FILE_PREVIEW_NONE, "NONE", 0, "None", "Do not create blend previews"}, + {USER_FILE_PREVIEW_SCREENSHOT, "SCREENSHOT", 0, "Screenshot", "Capture the entire window"}, + {USER_FILE_PREVIEW_CAMERA, "CAMERA", 0, "Camera View", "Workbench render of scene"}, + {0, NULL, 0, NULL, NULL}, + }; + srna = RNA_def_struct(brna, "PreferencesFilePaths", NULL); RNA_def_struct_sdna(srna, "UserDef"); RNA_def_struct_nested(brna, srna, "Preferences"); @@ -6214,12 +6221,9 @@ static void rna_def_userdef_filepaths(BlenderRNA *brna) RNA_def_property_ui_text( prop, "Recent Files", "Maximum number of recently opened files to remember"); - prop = RNA_def_property(srna, "use_save_preview_images", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_SAVE_PREVIEWS); - RNA_def_property_ui_text(prop, - "Save Preview Images", - "Enables automatic saving of preview images in the .blend file " - "as well as a thumbnail of the .blend"); + prop = RNA_def_property(srna, "file_preview_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, preview_type_items); + RNA_def_property_ui_text(prop, "File Preview Type", "What type of blend preview to create"); rna_def_userdef_filepaths_asset_library(brna); diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 8eaac47471a..dbc5a801cac 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -1515,14 +1515,64 @@ static void wm_history_file_update(void) /** \} */ /* -------------------------------------------------------------------- */ -/** \name Save Main Blend-File (internal) +/** \name Save Main Blend-File (internal) by capturing main window. + * \{ */ + +static ImBuf *blend_file_thumb_from_screenshot(bContext *C, BlendThumbnail **thumb_pt) +{ + if (*thumb_pt) { + /* We are given a valid thumbnail data, so just generate image from it. */ + return BKE_main_thumbnail_to_imbuf(NULL, *thumb_pt); + } + + /* Redraw to remove menus that might be open. */ + WM_redraw_windows(C); + WM_cursor_wait(true); + + /* The window to capture should be a main window (without parent). */ + wmWindow *win = CTX_wm_window(C); + while (win && win->parent) { + win = win->parent; + } + + int win_size[2]; + uint *buffer = WM_window_pixels_read(CTX_wm_manager(C), win, win_size); + ImBuf *ibuf = IMB_allocFromBuffer(buffer, NULL, win_size[0], win_size[1], 24); + + if (ibuf) { + int ex = (ibuf->x > ibuf->y) ? BLEN_THUMB_SIZE : + (int)((ibuf->x / (float)ibuf->y) * BLEN_THUMB_SIZE); + int ey = (ibuf->x > ibuf->y) ? (int)((ibuf->y / (float)ibuf->x) * BLEN_THUMB_SIZE) : + BLEN_THUMB_SIZE; + /* Filesystem thumbnail image can be 256x256. */ + IMB_scaleImBuf(ibuf, ex * 2, ey * 2); + + /* Thumbnail inside blend should be 128x128. */ + ImBuf *thumb_ibuf = IMB_dupImBuf(ibuf); + IMB_scaleImBuf(thumb_ibuf, ex, ey); + + BlendThumbnail *thumb = BKE_main_thumbnail_from_imbuf(NULL, thumb_ibuf); + IMB_freeImBuf(thumb_ibuf); + MEM_freeN(buffer); + *thumb_pt = thumb; + } + WM_cursor_wait(false); + + /* Must be freed by caller. */ + return ibuf; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Save Main Blend-File (internal) by rendering scene * \{ */ /* screen can be NULL */ -static ImBuf *blend_file_thumb(const bContext *C, - Scene *scene, - bScreen *screen, - BlendThumbnail **thumb_pt) +static ImBuf *blend_file_thumb_from_camera(const bContext *C, + Scene *scene, + bScreen *screen, + BlendThumbnail **thumb_pt) { /* will be scaled down, but gives some nice oversampling */ ImBuf *ibuf; @@ -1704,8 +1754,13 @@ static bool wm_file_write(bContext *C, /* Main now can store a '.blend' thumbnail, useful for background mode * or thumbnail customization. */ main_thumb = thumb = bmain->blen_thumb; - if ((U.flag & USER_SAVE_PREVIEWS) && BLI_thread_is_main()) { - ibuf_thumb = blend_file_thumb(C, CTX_data_scene(C), CTX_wm_screen(C), &thumb); + if (BLI_thread_is_main()) { + if (U.file_preview_type == USER_FILE_PREVIEW_SCREENSHOT) { + ibuf_thumb = blend_file_thumb_from_screenshot(C, &thumb); + } + else if (U.file_preview_type == USER_FILE_PREVIEW_CAMERA) { + ibuf_thumb = blend_file_thumb_from_camera(C, CTX_data_scene(C), CTX_wm_screen(C), &thumb); + } } /* operator now handles overwrite checks */ -- cgit v1.2.3