[Bf-blender-cvs] [812ea918422] master: UI/Assets: Operator to load custom preview images for data-blocks

Julian Eisel noreply at git.blender.org
Mon Dec 14 12:17:52 CET 2020


Commit: 812ea9184221a8ca5785528bebc3ef342a8ecfb4
Author: Julian Eisel
Date:   Fri Dec 11 23:49:13 2020 +0100
Branches: master
https://developer.blender.org/rB812ea9184221a8ca5785528bebc3ef342a8ecfb4

UI/Assets: Operator to load custom preview images for data-blocks

No automatic preview generation will ever be good enough to cover all cases
well. So custom preview images are a must for a preview driven data-block
selection - like for asset browsing.

The operator simply allows selecting an image file, which will then be read and
copied into the data-blocks preview (resized if necessary).

There's no UI for this currently and the operator won't be available in the
search menu yet. It will later once the Asset Browser UI is merged.

Reviewed as part of https://developer.blender.org/D9719.
Reviewed by: Bastien Montagne, Brecht Van Lommel

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

M	source/blender/blenkernel/BKE_icons.h
M	source/blender/blenkernel/intern/icons.c
M	source/blender/editors/include/ED_util.h
M	source/blender/editors/render/render_preview.c
M	source/blender/editors/screen/screen_ops.c
M	source/blender/editors/util/ed_util.c

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

diff --git a/source/blender/blenkernel/BKE_icons.h b/source/blender/blenkernel/BKE_icons.h
index d6cf5eae323..534b24236e8 100644
--- a/source/blender/blenkernel/BKE_icons.h
+++ b/source/blender/blenkernel/BKE_icons.h
@@ -130,6 +130,9 @@ void BKE_previewimg_clear_single(struct PreviewImage *prv, enum eIconSizes size)
 /* get the preview from any pointer */
 struct PreviewImage **BKE_previewimg_id_get_p(const struct ID *id);
 
+/* Trigger deferred loading of a custom image file into the preview buffer. */
+void BKE_previewimg_id_custom_set(struct ID *id, const char *path);
+
 /* free the preview image belonging to the id */
 void BKE_previewimg_id_free(struct ID *id);
 
@@ -156,7 +159,8 @@ struct PreviewImage *BKE_previewimg_cached_thumbnail_read(const char *name,
                                                           bool force_update);
 
 void BKE_previewimg_cached_release(const char *name);
-void BKE_previewimg_cached_release_pointer(struct PreviewImage *prv);
+
+void BKE_previewimg_deferred_release(struct PreviewImage *prv);
 
 void BKE_previewimg_blend_write(struct BlendWriter *writer, const struct PreviewImage *prv);
 void BKE_previewimg_blend_read(struct BlendDataReader *reader, struct PreviewImage *prv);
diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c
index eec9013d067..58b4a8ce315 100644
--- a/source/blender/blenkernel/intern/icons.c
+++ b/source/blender/blenkernel/intern/icons.c
@@ -230,6 +230,20 @@ static PreviewImage *previewimg_create_ex(size_t deferred_data_size)
   return prv_img;
 }
 
+static PreviewImage *previewimg_deferred_create(const char *path, int source)
+{
+  /* We pack needed data for lazy loading (source type, in a single char, and path). */
+  const size_t deferred_data_size = strlen(path) + 2;
+  char *deferred_data;
+
+  PreviewImage *prv = previewimg_create_ex(deferred_data_size);
+  deferred_data = (char *)PRV_DEFERRED_DATA(prv);
+  deferred_data[0] = source;
+  memcpy(&deferred_data[1], path, deferred_data_size - 1);
+
+  return prv;
+}
+
 PreviewImage *BKE_previewimg_create(void)
 {
   return previewimg_create_ex(0);
@@ -364,6 +378,42 @@ PreviewImage *BKE_previewimg_id_ensure(ID *id)
   return NULL;
 }
 
+void BKE_previewimg_deferred_release(PreviewImage *prv)
+{
+  if (prv) {
+    if (prv->tag & PRV_TAG_DEFFERED_RENDERING) {
+      /* We cannot delete the preview while it is being loaded in another thread... */
+      prv->tag |= PRV_TAG_DEFFERED_DELETE;
+      return;
+    }
+    if (prv->icon_id) {
+      BKE_icon_delete(prv->icon_id);
+    }
+    BKE_previewimg_freefunc(prv);
+  }
+}
+
+void BKE_previewimg_id_custom_set(ID *id, const char *path)
+{
+  PreviewImage **prv = BKE_previewimg_id_get_p(id);
+
+  /* Thumbnail previews must use the deferred pipeline. But we force them to be immediately
+   * generated here still. */
+
+  if (*prv) {
+    BKE_previewimg_deferred_release(*prv);
+  }
+  *prv = previewimg_deferred_create(path, THB_SOURCE_IMAGE);
+
+  /* Can't lazy-render the preview on access. ID previews are saved to files and we want them to be
+   * there in time. Not only if something happened to have accessed it meanwhile. */
+  for (int i = 0; i < NUM_ICON_SIZES; i++) {
+    BKE_previewimg_ensure(*prv, i);
+    /* Prevent auto-updates. */
+    (*prv)->flag[i] |= PRV_USER_EDITED;
+  }
+}
+
 PreviewImage *BKE_previewimg_cached_get(const char *name)
 {
   return BLI_ghash_lookup(gCachedPreviews, name);
@@ -417,15 +467,7 @@ PreviewImage *BKE_previewimg_cached_thumbnail_read(const char *name,
   }
 
   if (!prv) {
-    /* We pack needed data for lazy loading (source type, in a single char, and path). */
-    const size_t deferred_data_size = strlen(path) + 2;
-    char *deferred_data;
-
-    prv = previewimg_create_ex(deferred_data_size);
-    deferred_data = PRV_DEFERRED_DATA(prv);
-    deferred_data[0] = source;
-    memcpy(&deferred_data[1], path, deferred_data_size - 1);
-
+    previewimg_deferred_create(path, source);
     force_update = true;
   }
 
@@ -441,26 +483,11 @@ PreviewImage *BKE_previewimg_cached_thumbnail_read(const char *name,
   return prv;
 }
 
-void BKE_previewimg_cached_release_pointer(PreviewImage *prv)
-{
-  if (prv) {
-    if (prv->tag & PRV_TAG_DEFFERED_RENDERING) {
-      /* We cannot delete the preview while it is being loaded in another thread... */
-      prv->tag |= PRV_TAG_DEFFERED_DELETE;
-      return;
-    }
-    if (prv->icon_id) {
-      BKE_icon_delete(prv->icon_id);
-    }
-    BKE_previewimg_freefunc(prv);
-  }
-}
-
 void BKE_previewimg_cached_release(const char *name)
 {
   PreviewImage *prv = BLI_ghash_popkey(gCachedPreviews, name, MEM_freeN);
 
-  BKE_previewimg_cached_release_pointer(prv);
+  BKE_previewimg_deferred_release(prv);
 }
 
 /**
diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h
index 68ae3589064..d74a80045f1 100644
--- a/source/blender/editors/include/ED_util.h
+++ b/source/blender/editors/include/ED_util.h
@@ -53,6 +53,7 @@ void ED_spacedata_id_remap(struct ScrArea *area,
                            struct ID *new_id);
 
 void ED_OT_flush_edits(struct wmOperatorType *ot);
+void ED_OT_lib_id_load_custom_preview(struct wmOperatorType *ot);
 
 /* ************** XXX OLD CRUFT WARNING ************* */
 
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 095deccada0..d67113083a3 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -1304,7 +1304,7 @@ static void icon_preview_endjob(void *customdata)
     prv_img->tag &= ~PRV_TAG_DEFFERED_RENDERING;
     if (prv_img->tag & PRV_TAG_DEFFERED_DELETE) {
       BLI_assert(prv_img->tag & PRV_TAG_DEFFERED);
-      BKE_previewimg_cached_release_pointer(prv_img);
+      BKE_previewimg_deferred_release(prv_img);
     }
   }
 }
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 649279f8e08..a0c5762c73c 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -5510,6 +5510,7 @@ void ED_operatortypes_screen(void)
   WM_operatortype_append(ED_OT_undo_history);
 
   WM_operatortype_append(ED_OT_flush_edits);
+  WM_operatortype_append(ED_OT_lib_id_load_custom_preview);
 }
 
 /** \} */
diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c
index 76c261c9cba..5e3f443ce9c 100644
--- a/source/blender/editors/util/ed_util.c
+++ b/source/blender/editors/util/ed_util.c
@@ -35,6 +35,7 @@
 #include "DNA_screen_types.h"
 #include "DNA_space_types.h"
 
+#include "BLI_fileops.h"
 #include "BLI_listbase.h"
 #include "BLI_path_util.h"
 #include "BLI_string.h"
@@ -44,6 +45,7 @@
 
 #include "BKE_context.h"
 #include "BKE_global.h"
+#include "BKE_icons.h"
 #include "BKE_layer.h"
 #include "BKE_main.h"
 #include "BKE_material.h"
@@ -51,6 +53,7 @@
 #include "BKE_object.h"
 #include "BKE_packedFile.h"
 #include "BKE_paint.h"
+#include "BKE_report.h"
 #include "BKE_screen.h"
 #include "BKE_undo_system.h"
 #include "BKE_workspace.h"
@@ -501,3 +504,72 @@ void ED_OT_flush_edits(wmOperatorType *ot)
   /* flags */
   ot->flag = OPTYPE_INTERNAL;
 }
+
+static bool lib_id_load_custom_preview_poll(bContext *C)
+{
+  const PointerRNA idptr = CTX_data_pointer_get(C, "active_id");
+  BLI_assert(!idptr.data || RNA_struct_is_ID(idptr.type));
+
+  const ID *id = idptr.data;
+  if (!id) {
+    return false;
+  }
+  if (ID_IS_LINKED(id)) {
+    CTX_wm_operator_poll_msg_set(C, TIP_("Can't edit external library data"));
+    return false;
+  }
+  if (ID_IS_OVERRIDE_LIBRARY(id)) {
+    CTX_wm_operator_poll_msg_set(C, TIP_("Can't edit previews of overridden library data"));
+    return false;
+  }
+  if (!BKE_previewimg_id_get_p(id)) {
+    CTX_wm_operator_poll_msg_set(C, TIP_("Data-block does not support previews"));
+    return false;
+  }
+
+  return true;
+}
+
+static int lib_id_load_custom_preview_exec(bContext *C, wmOperator *op)
+{
+  char path[FILE_MAX];
+
+  RNA_string_get(op->ptr, "filepath", path);
+
+  if (!BLI_is_file(path)) {
+    BKE_reportf(op->reports, RPT_ERROR, "File not found '%s'", path);
+    return OPERATOR_CANCELLED;
+  }
+
+  PointerRNA idptr = CTX_data_pointer_get(C, "active_id");
+  ID *id = idptr.data;
+
+  BKE_previewimg_id_custom_set(id, path);
+
+  // WM_event_add_notifier(C, NC_ASSET, NULL);
+
+  return OPERATOR_FINISHED;
+}
+
+void ED_OT_lib_id_load_custom_preview(wmOperatorType *ot)
+{
+  ot->name = "Load Custom Preview";
+  ot->description = "Choose an image to help identify the data-block visually";
+  ot->idname = "ED_OT_lib_id_load_custom_preview";
+
+  /* api callbacks */
+  ot->poll = lib_id_load_custom_preview_poll;
+  ot->exec = lib_id_load_custom_preview_exec;
+  ot->invoke = WM_operator_filesel;
+
+  /* flags */
+  ot->flag = OPTYPE_INTERNAL;
+
+  WM_operator_properties_filesel(ot,
+                                 FILE_TYPE_FOLDER | FILE_TYPE_IMAGE,
+                                 FILE_SPECIAL,
+                                 FILE_OPENFILE,
+                                 WM_FILESEL_FILEPATH,
+                                 FILE_DEFAULTDISPLAY,
+                                 FILE_SORT_DEFAULT);
+}



More information about the Bf-blender-cvs mailing list