[Bf-blender-cvs] [67b18739ea0] temp-group-collections: Groups and collections 3/3
Dalai Felinto
noreply at git.blender.org
Wed Nov 1 18:14:30 CET 2017
Commit: 67b18739ea0c7241ac565ca303d554d6a8d4e944
Author: Dalai Felinto
Date: Thu Oct 26 17:19:52 2017 -0200
Branches: temp-group-collections
https://developer.blender.org/rB67b18739ea0c7241ac565ca303d554d6a8d4e944
Groups and collections 3/3
This allows you to create a group from a collection.
It is i the Menu when you click in the collections in the Outliner.
===================================================================
M source/blender/blenkernel/BKE_collection.h
M source/blender/blenkernel/BKE_layer.h
M source/blender/blenkernel/intern/collection.c
M source/blender/blenkernel/intern/group.c
M source/blender/blenkernel/intern/layer.c
M source/blender/editors/space_outliner/outliner_tools.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h
index c2d6fe3feeb..f5a0270b6a1 100644
--- a/source/blender/blenkernel/BKE_collection.h
+++ b/source/blender/blenkernel/BKE_collection.h
@@ -36,6 +36,7 @@ extern "C" {
#endif
struct BLI_Iterator;
+struct LayerCollection;
struct SceneCollection;
struct Object;
struct Base;
@@ -60,6 +61,7 @@ bool BKE_collections_object_remove(struct Main *bmain, struct ID *id, struct Obj
void BKE_collection_object_move(struct Scene *scene, struct SceneCollection *sc_dst, struct SceneCollection *sc_src, struct Object *ob);
void BKE_collection_group_set(struct Scene *scene, struct SceneCollection *sc, struct Group *group);
+void 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/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
index 3d3bf011791..1ef8ffec99a 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -79,6 +79,7 @@ void BKE_scene_layer_copy_data(struct SceneLayer *sl_dst, struct SceneLayer *sl_
const int flag);
void BKE_layer_collection_free(struct SceneLayer *sl, struct LayerCollection *lc);
+void BKE_layer_collection_convert(struct SceneLayer *sl, struct LayerCollection *lc, const int type);
struct LayerCollection *BKE_layer_collection_get_active(struct SceneLayer *sl);
struct LayerCollection *BKE_layer_collection_get_active_ensure(struct Scene *scene, struct SceneLayer *sl);
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index 912b6c28543..08b6c341ae7 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 *id)
{
switch (GS(id->name)) {
@@ -442,6 +446,108 @@ void BKE_collection_group_set(Scene *UNUSED(scene), SceneCollection *sc, Group *
sc->group = group;
}
+/**
+ * @brief collection_group_convert_layer_collections
+ * \param lb: ListBase of LayerCollection elements.
+ */
+static void collection_group_convert_layer_collections(const Group *group, SceneLayer *sl,
+ const SceneCollection *sc, ListBase *lb)
+{
+ for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
+ if (lc->scene_collection == sc) {
+ BKE_layer_collection_convert(sl, lc, COLLECTION_TYPE_GROUP);
+ }
+ else {
+ collection_group_convert_layer_collections(group, sl, sc, &lc->layer_collections);
+ }
+ }
+}
+
+static void layer_collection_sync(LayerCollection *lc_dst, LayerCollection *lc_src)
+{
+ lc_dst->flag = lc_src->flag;
+ lc_dst->flag_evaluated = lc_src->flag_evaluated;
+
+ /* Pending: sync overrides. */
+ TODO_LAYER_OVERRIDE;
+
+ /* 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->scene_layer->layer_collections.last != NULL) {
+ BKE_collection_unlink(group->scene_layer, group->scene_layer->layer_collections.last);
+ }
+
+ /* Remove all the SceneCollections but the master. */
+ collection_free(group->collection, false);
+}
+
+/**
+ * Convert a collection into a group
+ *
+ * Any SceneLayer that may have this the related SceneCollection linked is converted
+ * to a Group Collection.
+ */
+void BKE_collection_group_create(Main *bmain, Scene *scene, LayerCollection *lc_src)
+{
+ SceneCollection *sc_dst, *sc_src = lc_src->scene_collection;
+ LayerCollection *lc_dst;
+
+ /* We can't convert group collections into groups. */
+ if (sc_src->type == COLLECTION_TYPE_GROUP) {
+ return;
+ }
+
+ /* The master collection can't be converted. */
+ if (sc_src == BKE_collection_master(scene)) {
+ return;
+ }
+
+ /* If a sub-collection of sc_dst is directly linked into a SceneLayer we can't convert. */
+ for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
+ for (LayerCollection *lc_child = sl->layer_collections.first; lc_child; lc_child = lc_child->next) {
+ if (is_collection_in_tree(lc_child->scene_collection, sc_src)) {
+ return;
+ }
+ }
+ }
+
+ /* 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, LIB_ID_CREATE_NO_USER_REFCOUNT);
+
+ lc_dst = BKE_collection_link(group->scene_layer, sc_dst);
+ layer_collection_sync(lc_dst, lc_src);
+
+ /* Convert existing collections into group collections. */
+ for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
+ collection_group_convert_layer_collections(group, sl, sc_src, &sl->layer_collections);
+ }
+
+ /* Convert original SceneCollection into a group collection. */
+ BKE_collection_group_set(scene, sc_src, group);
+ sc_src->type = COLLECTION_TYPE_GROUP;
+ collection_free(sc_src, true);
+}
+
/* ---------------------------------------------------------------------- */
/* Outliner drag and drop */
diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c
index 72321ae31b1..34109572436 100644
--- a/source/blender/blenkernel/intern/group.c
+++ b/source/blender/blenkernel/intern/group.c
@@ -89,7 +89,6 @@ void BKE_group_init(Group *group)
/* Create and link a new default collection. */
SceneCollection *defaut_collection = BKE_collection_add(&group->id, NULL, COLLECTION_TYPE_NONE, "Default Collection");
BKE_collection_link(group->scene_layer, defaut_collection);
-
}
Group *BKE_group_add(Main *bmain, const char *name)
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index 2869e683680..58211d16205 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -311,7 +311,7 @@ static void layer_collections_recreate(
}
/**
- * Only copy internal data of SceneLayer rom source to already allocated/initialized destination.
+ * Only copy internal data of SceneLayer from source to already allocated/initialized destination.
*
* \param mc_src Master Collection the source SceneLayer links in.
* \param mc_dst Master Collection the destination SceneLayer links in.
@@ -411,6 +411,9 @@ static void layer_collection_objects_unpopulate(SceneLayer *sl, LayerCollection
/**
* When freeing the entire SceneLayer at once we don't bother with unref
* otherwise SceneLayer is passed to keep the syncing of the LayerCollection tree
+ *
+ * \note
+ * Keep it in sync with BKE_layer_collection_convert.
*/
static void layer_collection_free(SceneLayer *sl, LayerCollection *lc)
{
@@ -443,6 +446,29 @@ void BKE_layer_collection_free(SceneLayer *sl, LayerCollection *lc)
layer_collection_free(sl, lc);
}
+/**
+ * Convert a layer collection to a new type
+ *
+ * \param lc: LayerCollection to be converted.
+ * \param type: New type for the LayerCollection->scene_collection.
+ *
+ * \note
+ * Keep it in sync with BKE_layer_collection_free.
+ */
+void BKE_layer_collection_convert(SceneLayer *sl, LayerCollection *lc, const int type)
+{
+ /* Support group convertion only at the moment. */
+ BLI_assert(type == COLLECTION_TYPE_GROUP);
+
+ layer_collection_objects_unpopulate(sl, lc);
+ BLI_freelistN(&lc->overrides);
+
+ for (LayerCollection *nlc = lc->layer_collections.first; nlc; nlc = nlc->next) {
+ BKE_layer_collection_convert(sl, nlc, type);
+ }
+ BLI_freelistN(&lc->layer_collections);
+}
+
/* LayerCollection */
/**
@@ -2132,9 +2158,10 @@ void BKE_layer_eval_layer_collection(const struct EvaluationContext *eval_ctx,
switch (scene_collection->type) {
case COLLECTION_TYPE_GROUP:
{
- if (scene_collection->group) {
+ Group *group = scene_collection->group;
+ if (group) {
LayerCollection *group_layer_collection;
- for (group_layer_collection = scene_collection->group->scene_layer->layer_collections.first;
+ for (group_layer_collection = group->scene_layer->layer_collections.first;
group_layer_collection;
group_layer_collection = group_layer_collection->next)
{
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index 0e23b70da69..d492bb189a5 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -667,6 +667,7 @@ typedef enum eOutliner_PropCollectionOps {
OL_COLLECTION_OP_COLLECTION_NEW,
OL_COLLECTION_OP_COLLECTION_DEL,
OL_COLLECTION_OP_COLLECTION_UNLINK,
+ OL_COLLECTION_OP_GROUP_CREATE,
} eOutliner_PropCollectionOps;
static void pchan_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *UNUSED(arg))
@@ -874,6 +875,17 @@ static void collection_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tsel
TODO_LAYER_OPERATORS; /* this shouldn't be in the menu in those cases */
}
}
+ else if (event == OL_COLLECTION_OP_GROUP_CREATE) {
+ Main *bmain = CTX_data_main(C);
+ BKE_collection_group_create(bmain,
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list