[Bf-blender-cvs] [810e225c260] master: Assets: Support automatic collection previews

Julian Eisel noreply at git.blender.org
Tue Mar 29 15:37:40 CEST 2022


Commit: 810e225c260dfc2eac9c6b8bfd3271066dc0224b
Author: Julian Eisel
Date:   Tue Mar 29 15:36:02 2022 +0200
Branches: master
https://developer.blender.org/rB810e225c260dfc2eac9c6b8bfd3271066dc0224b

Assets: Support automatic collection previews

Adds supports for collection previews that are rendered automatically when
collections are marked as assets. (Or when preview rendering is triggered
differently, e.g. through the //Refresh Data-Block Previews// operator).

Idea in this patch is to create a collection instance empty outside of main for
the collection, and then reuse the object rendering code to render the preview.
This keeps things very simple and works just fine.

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

Reviewed by: Bastien Montagne

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

M	source/blender/blenkernel/BKE_object.h
M	source/blender/blenkernel/intern/icons.cc
M	source/blender/blenkernel/intern/object.cc
M	source/blender/editors/render/render_preview.cc

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

diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 17d90e64459..4d699e1ff54 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -163,9 +163,12 @@ int BKE_object_visibility(const struct Object *ob, int dag_eval_mode);
 
 /**
  * More general add: creates minimum required data, but without vertices etc.
+ *
+ * \param bmain: The main to add the object to. May be null for #LIB_ID_CREATE_NO_MAIN behavior.
  */
-struct Object *BKE_object_add_only_object(struct Main *bmain, int type, const char *name)
-    ATTR_NONNULL(1) ATTR_RETURNS_NONNULL;
+struct Object *BKE_object_add_only_object(struct Main *bmain,
+                                          int type,
+                                          const char *name) ATTR_RETURNS_NONNULL;
 /**
  * General add: to scene, with layer from area and default name.
  *
diff --git a/source/blender/blenkernel/intern/icons.cc b/source/blender/blenkernel/intern/icons.cc
index 8883613786b..2ba6510ee71 100644
--- a/source/blender/blenkernel/intern/icons.cc
+++ b/source/blender/blenkernel/intern/icons.cc
@@ -416,7 +416,7 @@ void BKE_previewimg_id_custom_set(ID *id, const char *path)
 
 bool BKE_previewimg_id_supports_jobs(const ID *id)
 {
-  return ELEM(GS(id->name), ID_OB, ID_MA, ID_TE, ID_LA, ID_WO, ID_IM, ID_BR);
+  return ELEM(GS(id->name), ID_OB, ID_MA, ID_TE, ID_LA, ID_WO, ID_IM, ID_BR, ID_GR);
 }
 
 void BKE_previewimg_deferred_release(PreviewImage *prv)
diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc
index 6006ce88896..84d9002f4d2 100644
--- a/source/blender/blenkernel/intern/object.cc
+++ b/source/blender/blenkernel/intern/object.cc
@@ -2217,7 +2217,7 @@ Object *BKE_object_add_only_object(Main *bmain, int type, const char *name)
   }
 
   /* We cannot use #BKE_id_new here as we need some custom initialization code. */
-  Object *ob = (Object *)BKE_libblock_alloc(bmain, ID_OB, name, 0);
+  Object *ob = (Object *)BKE_libblock_alloc(bmain, ID_OB, name, bmain ? 0 : LIB_ID_CREATE_NO_MAIN);
 
   /* We increase object user count when linking to Collections. */
   id_us_min(&ob->id);
diff --git a/source/blender/editors/render/render_preview.cc b/source/blender/editors/render/render_preview.cc
index ef0f0b6225c..7e01754bb3a 100644
--- a/source/blender/editors/render/render_preview.cc
+++ b/source/blender/editors/render/render_preview.cc
@@ -374,6 +374,14 @@ static ID *duplicate_ids(ID *id, const bool allow_failure)
                                        LIB_ID_COPY_NO_ANIMDATA);
       return id_copy;
     }
+    case ID_GR: {
+      /* Doesn't really duplicate the collection. Just creates a collection instance empty. */
+      BLI_assert(BKE_previewimg_id_supports_jobs(id));
+      Object *instance_empty = BKE_object_add_only_object(nullptr, OB_EMPTY, nullptr);
+      instance_empty->instance_collection = (Collection *)id;
+      instance_empty->transflag |= OB_DUPLICOLLECTION;
+      return &instance_empty->id;
+    }
     /* These support threading, but don't need duplicating. */
     case ID_IM:
     case ID_BR:
@@ -883,6 +891,42 @@ static void object_preview_render(IconPreview *preview, IconPreviewSize *preview
 
 /** \} */
 
+/* -------------------------------------------------------------------- */
+/** \name Collection Preview
+ *
+ * For the most part this reuses the object preview code by creating an instance collection empty
+ * object and rendering that.
+ *
+ * \{ */
+
+/**
+ * Check if the collection contains any geometry that can be rendered. Otherwise there's nothing to
+ * display in the preview, so don't generate one.
+ * Objects and sub-collections hidden in the render will be skipped.
+ */
+static bool collection_preview_contains_geometry_recursive(const Collection *collection)
+{
+  LISTBASE_FOREACH (CollectionObject *, col_ob, &collection->gobject) {
+    if (col_ob->ob->visibility_flag & OB_HIDE_RENDER) {
+      continue;
+    }
+    if (OB_TYPE_IS_GEOMETRY(col_ob->ob->type)) {
+      return true;
+    }
+  }
+
+  LISTBASE_FOREACH (CollectionChild *, child_col, &collection->children) {
+    if (child_col->collection->flag & COLLECTION_HIDE_RENDER) {
+      continue;
+    }
+    if (collection_preview_contains_geometry_recursive(child_col->collection)) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
 /* -------------------------------------------------------------------- */
 /** \name Action Preview
  * \{ */
@@ -1577,6 +1621,12 @@ static void icon_preview_startjob_all_sizes(void *customdata,
             continue;
           }
           break;
+        case ID_GR:
+          BLI_assert(collection_preview_contains_geometry_recursive((Collection *)ip->id));
+          /* A collection instance empty was created, so this can just reuse the object preview
+           * rendering. */
+          object_preview_render(ip, cur_size);
+          continue;
         case ID_AC:
           action_preview_render(ip, cur_size);
           continue;
@@ -1868,6 +1918,9 @@ bool ED_preview_id_is_supported(const ID *id)
   if (GS(id->name) == ID_OB) {
     return object_preview_is_type_supported((const Object *)id);
   }
+  if (GS(id->name) == ID_GR) {
+    return collection_preview_contains_geometry_recursive((const Collection *)id);
+  }
   return BKE_previewimg_id_get_p(id) != nullptr;
 }



More information about the Bf-blender-cvs mailing list