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
This commit is contained in:
parent
91bca410c0
commit
58632a7f3c
Notes:
blender-bot
2023-02-14 09:34:18 +01:00
Referenced by commit81978594a8
, Fix tests broken by rB58632a7f3c0f1be6. Referenced by commitb4c9f88cbe
, Fix thumbnail screenshot error in58632a7f3c
|
@ -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 =
|
||||
{
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue