diff options
-rw-r--r-- | source/blender/blenkernel/BKE_object.h | 7 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/icons.cc | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.cc | 2 | ||||
-rw-r--r-- | source/blender/editors/render/render_preview.cc | 53 |
4 files changed, 60 insertions, 4 deletions
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: @@ -884,6 +892,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; } |