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:
-rw-r--r--release/scripts/startup/bl_ui/space_info.py10
-rw-r--r--source/blender/editors/include/ED_render.h2
-rw-r--r--source/blender/editors/include/UI_interface_icons.h3
-rw-r--r--source/blender/editors/interface/interface_icons.c23
-rw-r--r--source/blender/editors/render/render_preview.c5
-rw-r--r--source/blender/windowmanager/intern/wm_files.c19
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c88
7 files changed, 117 insertions, 33 deletions
diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py
index 2b075128fef..b642b61fcdc 100644
--- a/release/scripts/startup/bl_ui/space_info.py
+++ b/release/scripts/startup/bl_ui/space_info.py
@@ -132,6 +132,7 @@ class INFO_MT_file(Menu):
layout.operator_context = 'INVOKE_AREA'
layout.operator("wm.link", text="Link", icon='LINK_BLEND')
layout.operator("wm.append", text="Append", icon='APPEND_BLEND')
+ layout.menu("INFO_MT_file_previews")
layout.separator()
@@ -195,6 +196,15 @@ class INFO_MT_file_external_data(Menu):
layout.operator("file.find_missing_files")
+class INFO_MT_file_previews(Menu):
+ bl_label = "Data Previews"
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.operator("wm.previews_ensure")
+
+
class INFO_MT_game(Menu):
bl_label = "Game"
diff --git a/source/blender/editors/include/ED_render.h b/source/blender/editors/include/ED_render.h
index 32fa641e3ae..de3843c91eb 100644
--- a/source/blender/editors/include/ED_render.h
+++ b/source/blender/editors/include/ED_render.h
@@ -72,7 +72,7 @@ void ED_preview_init_dbase(void);
void ED_preview_free_dbase(void);
void ED_preview_shader_job(const struct bContext *C, void *owner, struct ID *id, struct ID *parent, struct MTex *slot, int sizex, int sizey, int method);
-void ED_preview_icon_render(const struct bContext *C, void *owner, struct ID *id, unsigned int *rect, int sizex, int sizey);
+void ED_preview_icon_render(struct Scene *scene, struct ID *id, unsigned int *rect, int sizex, int sizey);
void ED_preview_icon_job(const struct bContext *C, void *owner, struct ID *id, unsigned int *rect, int sizex, int sizey);
void ED_preview_kill_jobs(struct wmWindowManager *wm, struct Main *bmain);
diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h
index 2ba3d309aa7..74927428363 100644
--- a/source/blender/editors/include/UI_interface_icons.h
+++ b/source/blender/editors/include/UI_interface_icons.h
@@ -64,7 +64,8 @@ void UI_icons_init(int first_dyn_id);
int UI_icon_get_width(int icon_id);
int UI_icon_get_height(int icon_id);
-void UI_id_icon_render(const struct bContext *C, struct ID *id, const bool big, const bool use_job);
+void UI_id_icon_render(
+ const struct bContext *C, struct Scene *scene, struct ID *id, const bool big, const bool use_job);
void UI_icon_draw(float x, float y, int icon_id);
void UI_icon_draw_preview(float x, float y, int icon_id);
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index ac9abe8e781..679681cb372 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -931,7 +931,8 @@ static void icon_create_rect(struct PreviewImage *prv_img, enum eIconSizes size)
/* only called when icon has changed */
/* only call with valid pointer from UI_icon_draw */
-static void icon_set_image(const bContext *C, ID *id, PreviewImage *prv_img, enum eIconSizes size, const bool use_job)
+static void icon_set_image(
+ const bContext *C, Scene *scene, ID *id, PreviewImage *prv_img, enum eIconSizes size, const bool use_job)
{
if (!prv_img) {
if (G.debug & G_DEBUG)
@@ -946,8 +947,11 @@ static void icon_set_image(const bContext *C, ID *id, PreviewImage *prv_img, enu
ED_preview_icon_job(C, prv_img, id, prv_img->rect[size], prv_img->w[size], prv_img->h[size]);
}
else {
+ if (!scene) {
+ scene = CTX_data_scene(C);
+ }
/* Immediate version */
- ED_preview_icon_render(C, prv_img, id, prv_img->rect[size], prv_img->w[size], prv_img->h[size]);
+ ED_preview_icon_render(scene, id, prv_img->rect[size], prv_img->w[size], prv_img->h[size]);
}
}
@@ -1155,25 +1159,26 @@ static void icon_draw_size(float x, float y, int icon_id, float aspect, float al
}
}
-static void ui_id_preview_image_render_size(const bContext *C, ID *id, PreviewImage *pi, int size, const bool use_job)
+static void ui_id_preview_image_render_size(
+ const bContext *C, Scene *scene, ID *id, PreviewImage *pi, int size, const bool use_job)
{
if ((pi->changed[size] || !pi->rect[size])) { /* changed only ever set by dynamic icons */
/* create the rect if necessary */
- icon_set_image(C, id, pi, size, use_job);
+ icon_set_image(C, scene, id, pi, size, use_job);
pi->changed[size] = 0;
}
}
-void UI_id_icon_render(const bContext *C, ID *id, const bool big, const bool use_job)
+void UI_id_icon_render(const bContext *C, Scene *scene, ID *id, const bool big, const bool use_job)
{
PreviewImage *pi = BKE_previewimg_get(id);
if (pi) {
if (big)
- ui_id_preview_image_render_size(C, id, pi, ICON_SIZE_PREVIEW, use_job); /* bigger preview size */
+ ui_id_preview_image_render_size(C, scene, id, pi, ICON_SIZE_PREVIEW, use_job); /* bigger preview size */
else
- ui_id_preview_image_render_size(C, id, pi, ICON_SIZE_ICON, use_job); /* icon size */
+ ui_id_preview_image_render_size(C, scene, id, pi, ICON_SIZE_ICON, use_job); /* icon size */
}
}
@@ -1189,7 +1194,7 @@ static void ui_id_brush_render(const bContext *C, ID *id)
/* check if rect needs to be created; changed
* only set by dynamic icons */
if ((pi->changed[i] || !pi->rect[i])) {
- icon_set_image(C, id, pi, i, true);
+ icon_set_image(C, NULL, id, pi, i, true);
pi->changed[i] = 0;
}
}
@@ -1265,7 +1270,7 @@ int ui_id_icon_get(const bContext *C, ID *id, const bool big)
case ID_LA: /* fall through */
iconid = BKE_icon_getid(id);
/* checks if not exists, or changed */
- UI_id_icon_render(C, id, big, true);
+ UI_id_icon_render(C, NULL, id, big, true);
break;
default:
break;
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 8833d76fde2..ea80a07fdd4 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -1098,14 +1098,13 @@ static void icon_preview_free(void *customdata)
MEM_freeN(ip);
}
-void ED_preview_icon_render(const bContext *C, void *UNUSED(owner), ID *id, unsigned int *rect, int sizex, int sizey)
+void ED_preview_icon_render(Scene *scene, ID *id, unsigned int *rect, int sizex, int sizey)
{
IconPreview ip = {0};
short stop = false, update = false;
float progress = 0.0f;
- /* customdata for preview thread */
- ip.scene = CTX_data_scene(C);
+ ip.scene = scene;
ip.owner = id;
ip.id = id;
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index fabb69b8eff..c1c31f6795d 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -101,7 +101,6 @@
#include "GHOST_Path-api.h"
#include "UI_interface.h"
-#include "UI_interface_icons.h"
#include "UI_view2d.h"
#include "GPU_draw.h"
@@ -895,24 +894,6 @@ bool write_crash_blend(void)
}
}
-static void UNUSED_FUNCTION(wm_ensure_previews)(bContext *C, Main *mainvar)
-{
- ListBase *lb[] = {&mainvar->mat, &mainvar->tex, &mainvar->image, &mainvar->world, &mainvar->lamp, NULL};
- ID *id;
- int i;
-
- for (i = 0; lb[i]; i++) {
- for (id = lb[i]->first; id; id = id->next) {
- /* Only preview non-library datablocks, lib ones do not pertain to this .blend file!
- * Same goes for ID with no user. */
- if (!id->lib && (id->us != 0)) {
- UI_id_icon_render(C, id, false, false);
- UI_id_icon_render(C, id, true, false);
- }
- }
- }
-}
-
/**
* \see #wm_homefile_write_exec wraps #BLO_write_file in a similar way.
*/
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 5b944a7b1ec..02a029fc3f3 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -61,6 +61,7 @@
#include "BLI_blenlib.h"
#include "BLI_dial.h"
#include "BLI_dynstr.h" /*for WM_operator_pystring */
+#include "BLI_linklist_stack.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
@@ -76,6 +77,7 @@
#include "BKE_idprop.h"
#include "BKE_image.h"
#include "BKE_library.h"
+#include "BKE_library_query.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_material.h"
@@ -105,6 +107,7 @@
#include "RNA_enum_types.h"
#include "UI_interface.h"
+#include "UI_interface_icons.h"
#include "UI_resources.h"
#include "WM_api.h"
@@ -4705,6 +4708,90 @@ static void WM_OT_dependency_relations(wmOperatorType *ot)
ot->exec = dependency_relations_exec;
}
+/* *************************** Mat/tex/etc. previews generation ************* */
+
+typedef struct PreviewsIDEnsureStack {
+ Scene *scene;
+
+ BLI_LINKSTACK_DECLARE(id_stack, ID *);
+} PreviewsIDEnsureStack;
+
+static void previews_id_ensure(bContext *C, Scene *scene, ID *id)
+{
+ BLI_assert(ELEM(GS(id->name), ID_MA, ID_TE, ID_IM, ID_WO, ID_LA));
+
+ /* Only preview non-library datablocks, lib ones do not pertain to this .blend file!
+ * Same goes for ID with no user. */
+ if (!id->lib && (id->us != 0)) {
+ UI_id_icon_render(C, scene, id, false, false);
+ UI_id_icon_render(C, scene, id, true, false);
+ }
+}
+
+static bool previews_id_ensure_callback(void *todo_v, ID **idptr, int UNUSED(cd_flag))
+{
+ PreviewsIDEnsureStack *todo = todo_v;
+ ID *id = *idptr;
+
+ if (id && (id->flag & LIB_DOIT)) {
+ if (ELEM(GS(id->name), ID_MA, ID_TE, ID_IM, ID_WO, ID_LA)) {
+ previews_id_ensure(NULL, todo->scene, id);
+ }
+ id->flag &= ~LIB_DOIT; /* Tag the ID as done in any case. */
+ BLI_LINKSTACK_PUSH(todo->id_stack, id);
+ }
+
+ return true;
+}
+
+static int previews_ensure_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ Main *bmain = CTX_data_main(C);
+ ListBase *lb[] = {&bmain->mat, &bmain->tex, &bmain->image, &bmain->world, &bmain->lamp, NULL};
+ PreviewsIDEnsureStack preview_id_stack;
+ Scene *scene;
+ ID *id;
+ int i;
+
+ /* We use LIB_DOIT to check whether we have already handled a given ID or not. */
+ BKE_main_id_flag_all(bmain, LIB_DOIT, true);
+
+ BLI_LINKSTACK_INIT(preview_id_stack.id_stack);
+
+ for (scene = bmain->scene.first; scene; scene = scene->id.next) {
+ preview_id_stack.scene = scene;
+ id = (ID *)scene;
+
+ do {
+ /* This will loop over all IDs linked by current one, render icons for them if needed,
+ * and add them to 'todo' preview_id_stack. */
+ BKE_library_foreach_ID_link(id, previews_id_ensure_callback, &preview_id_stack, IDWALK_READONLY);
+ } while((id = BLI_LINKSTACK_POP(preview_id_stack.id_stack)));
+ }
+
+ BLI_LINKSTACK_FREE(preview_id_stack.id_stack);
+
+ /* Check a last time for ID not used (fake users only, in theory), and
+ * do our best for those, using current scene... */
+ for (i = 0; lb[i]; i++) {
+ for (id = lb[i]->first; id; id = id->next) {
+ previews_id_ensure(C, NULL, id);
+ }
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+static void WM_OT_previews_ensure(wmOperatorType *ot)
+{
+ ot->name = "Refresh DataBlock Previews";
+ ot->idname = "WM_OT_previews_ensure";
+ ot->description = "Ensure datablock previews are available and up-to-date "
+ "(to be saved in .blend file, only for some types like materials, textures, etc.)";
+
+ ot->exec = previews_ensure_exec;
+}
+
/* ******************************************************* */
static void operatortype_ghash_free_cb(wmOperatorType *ot)
@@ -4768,6 +4855,7 @@ void wm_operatortype_init(void)
#if defined(WIN32)
WM_operatortype_append(WM_OT_console_toggle);
#endif
+ WM_operatortype_append(WM_OT_previews_ensure);
}
/* circleselect-like modal operators */