[Bf-blender-cvs] [3027ff8] master: Second try to fix missing previews of mat/tex/etc. in .blend files.

Bastien Montagne noreply at git.blender.org
Mon Jan 12 15:18:40 CET 2015


Commit: 3027ff8b13fb29e9249382ef400331783b2e06f6
Author: Bastien Montagne
Date:   Mon Jan 12 14:44:54 2015 +0100
Branches: master
https://developer.blender.org/rB3027ff8b13fb29e9249382ef400331783b2e06f6

Second try to fix missing previews of mat/tex/etc. in .blend files.

This time, it's a dedicated operator user has to run before saving the file.

And it recursively check all IDs linked from each scene, therefore rendering
materials etc. previews using a scene they are used in.

Note the renderengine issue is not completely addressed this way
(existing code for icon previews seems to ignore completely other engines,
and IDs not linked anywhere (fake-user ones) will be rendered with current scene's engine
as fallback, also you can get a material linked to an hidden object in a scene, etc.).

Reviewers: sergey, campbellbarton

Reviewed By: campbellbarton

Differential Revision: https://developer.blender.org/D980

===================================================================

M	release/scripts/startup/bl_ui/space_info.py
M	source/blender/editors/include/ED_render.h
M	source/blender/editors/include/UI_interface_icons.h
M	source/blender/editors/interface/interface_icons.c
M	source/blender/editors/render/render_preview.c
M	source/blender/windowmanager/intern/wm_files.c
M	source/blender/windowmanager/intern/wm_operators.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py
index 2b07512..b642b61 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 32fa641..de3843c 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 2ba3d30..7492742 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 ac9abe8..679681c 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 8833d76..ea80a07 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 fabb69b..c1c31f6 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 5b944a7..02a029f 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) {

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list