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:
authorDalai Felinto <dfelinto@gmail.com>2017-12-01 17:23:05 +0300
committerDalai Felinto <dfelinto@gmail.com>2017-12-01 19:15:54 +0300
commitaeaf87bbeb011e9a571eefa12d81fa6fb2b8bd5b (patch)
tree895f28e2650a2436ebbf8f699d838d71c83d9d5b /source/blender/blenkernel
parentbe9e469ead227aee8d4c29b98a125cf599c5c8bb (diff)
Groups and collection: create group from collection
You could still create groups as before, with Ctl + G. This will create a group with a single visible collection. However you can also create a group from an existing collection. Just go to the menu you get in the outliner when clicking in a collection and pick "Create Group". Remember to instance the group afterwards, or link it into a new scene or file. The group and the collection are not kept in sync afterwards. You need to manually edit the group for further changes.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_collection.h2
-rw-r--r--source/blender/blenkernel/intern/collection.c80
2 files changed, 82 insertions, 0 deletions
diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h
index c305a05ddd0..48b4ff881ae 100644
--- a/source/blender/blenkernel/BKE_collection.h
+++ b/source/blender/blenkernel/BKE_collection.h
@@ -58,6 +58,8 @@ bool BKE_collection_object_remove(struct Main *bmain, struct ID *owner_id, struc
bool BKE_collections_object_remove(struct Main *bmain, struct ID *owner_id, struct Object *object, const bool free_us);
void BKE_collection_object_move(struct ID *owner_id, struct SceneCollection *sc_dst, struct SceneCollection *sc_src, struct Object *ob);
+struct Group *BKE_collection_group_create(struct Main *bmain, struct Scene *scene, struct LayerCollection *lc);
+
void BKE_collection_reinsert_after(const struct Scene *scene, struct SceneCollection *sc_reinsert, struct SceneCollection *sc_after);
void BKE_collection_reinsert_into(struct SceneCollection *sc_reinsert, struct SceneCollection *sc_into);
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index aa5b9e7eb25..8d69563f5ff 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -34,6 +34,7 @@
#include "BLI_string_utils.h"
#include "BKE_collection.h"
+#include "BKE_group.h"
#include "BKE_idprop.h"
#include "BKE_layer.h"
#include "BKE_library.h"
@@ -48,6 +49,9 @@
#include "MEM_guardedalloc.h"
+/* Prototypes. */
+static bool is_collection_in_tree(const struct SceneCollection *sc_reference, struct SceneCollection *sc_parent);
+
static SceneCollection *collection_master_from_id(const ID *owner_id)
{
switch (GS(owner_id->name)) {
@@ -407,6 +411,82 @@ bool BKE_collections_object_remove(Main *bmain, ID *owner_id, Object *ob, const
return removed;
}
+static void layer_collection_sync(LayerCollection *lc_dst, LayerCollection *lc_src)
+{
+ lc_dst->flag = lc_src->flag;
+
+ /* Pending: sync overrides. */
+ IDP_MergeGroup(lc_dst->properties, lc_src->properties, true);
+
+ /* Continue recursively. */
+ LayerCollection *lc_dst_nested, *lc_src_nested;
+ lc_src_nested = lc_src->layer_collections.first;
+ for (lc_dst_nested = lc_dst->layer_collections.first;
+ lc_dst_nested && lc_src_nested;
+ lc_dst_nested = lc_dst_nested->next, lc_src_nested = lc_src_nested->next)
+ {
+ layer_collection_sync(lc_dst_nested, lc_src_nested);
+ }
+}
+
+/**
+ * Leave only the master collection in, remove everything else.
+ * @param group
+ */
+static void collection_group_cleanup(Group *group)
+{
+ /* Unlink all the LayerCollections. */
+ while (group->view_layer->layer_collections.last != NULL) {
+ BKE_collection_unlink(group->view_layer, group->view_layer->layer_collections.last);
+ }
+
+ /* Remove all the SceneCollections but the master. */
+ collection_free(group->collection, false);
+}
+
+/**
+ * Create a group from a collection
+ *
+ * Any ViewLayer that may have this the related SceneCollection linked is converted
+ * to a Group Collection.
+ */
+Group *BKE_collection_group_create(Main *bmain, Scene *scene, LayerCollection *lc_src)
+{
+ SceneCollection *sc_dst, *sc_src = lc_src->scene_collection;
+ LayerCollection *lc_dst;
+
+ /* The master collection can't be converted. */
+ if (sc_src == BKE_collection_master(&scene->id)) {
+ return NULL;
+ }
+
+ /* If a sub-collection of sc_dst is directly linked into a ViewLayer we can't convert. */
+ for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
+ for (LayerCollection *lc_child = view_layer->layer_collections.first; lc_child; lc_child = lc_child->next) {
+ if (is_collection_in_tree(lc_child->scene_collection, sc_src)) {
+ return NULL;
+ }
+ }
+ }
+
+ /* Create new group with the same data as the original collection. */
+ Group *group = BKE_group_add(bmain, sc_src->name);
+ collection_group_cleanup(group);
+
+ sc_dst = BKE_collection_add(&group->id, NULL, COLLECTION_TYPE_GROUP_INTERNAL, sc_src->name);
+ BKE_collection_copy_data(sc_dst, sc_src, 0);
+ FOREACH_SCENE_COLLECTION(&group->id, sc_group)
+ {
+ sc_group->type = COLLECTION_TYPE_GROUP_INTERNAL;
+ }
+ FOREACH_SCENE_COLLECTION_END
+
+ lc_dst = BKE_collection_link(group->view_layer, sc_dst);
+ layer_collection_sync(lc_dst, lc_src);
+
+ return group;
+}
+
/* ---------------------------------------------------------------------- */
/* Outliner drag and drop */