[Bf-blender-cvs] [3a1748146bc] blender2.8: Layers: move SceneCollection

Dalai Felinto noreply at git.blender.org
Wed Mar 8 23:37:44 CET 2017


Commit: 3a1748146bcdb0d99d9620b3a52b77110e2eb5f1
Author: Dalai Felinto
Date:   Fri Mar 3 16:14:21 2017 +0100
Branches: blender2.8
https://developer.blender.org/rB3a1748146bcdb0d99d9620b3a52b77110e2eb5f1

Layers: move SceneCollection

This is to be used from the Outliner, when dragging and dropping.
It does not include moving LayerCollection (from Active Render Layer)

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

M	release/scripts/addons
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/layer.c
M	source/blender/editors/space_outliner/outliner_tree.c
M	source/blender/makesrna/intern/rna_scene.c
M	tests/python/render_layer/CMakeLists.txt
M	tests/python/render_layer/render_layer_common.py
A	tests/python/render_layer/test_move_above_below_scene_collection_a.py
A	tests/python/render_layer/test_move_above_below_scene_collection_b.py
A	tests/python/render_layer/test_move_above_below_scene_collection_c.py
A	tests/python/render_layer/test_move_above_below_scene_collection_d.py
A	tests/python/render_layer/test_move_above_below_scene_collection_e.py
A	tests/python/render_layer/test_move_above_below_scene_collection_f.py
A	tests/python/render_layer/test_move_above_below_scene_collection_g.py
A	tests/python/render_layer/test_move_above_below_scene_collection_h.py
A	tests/python/render_layer/test_move_above_below_scene_collection_i.py
A	tests/python/render_layer/test_move_above_below_scene_collection_sync_a.py
A	tests/python/render_layer/test_move_above_below_scene_collection_sync_b.py
A	tests/python/render_layer/test_move_above_below_scene_collection_sync_c.py
A	tests/python/render_layer/test_move_above_below_scene_collection_sync_d.py
A	tests/python/render_layer/test_move_above_below_scene_collection_sync_e.py
A	tests/python/render_layer/test_move_above_below_scene_collection_sync_f.py
A	tests/python/render_layer/test_move_above_below_scene_collection_sync_g.py
A	tests/python/render_layer/test_move_above_below_scene_collection_sync_h.py
A	tests/python/render_layer/test_move_above_below_scene_collection_sync_i.py
A	tests/python/render_layer/test_move_into_scene_collection_a.py
A	tests/python/render_layer/test_move_into_scene_collection_b.py
A	tests/python/render_layer/test_move_into_scene_collection_c.py
A	tests/python/render_layer/test_move_into_scene_collection_d.py
A	tests/python/render_layer/test_move_into_scene_collection_e.py
A	tests/python/render_layer/test_move_into_scene_collection_f.py
A	tests/python/render_layer/test_move_into_scene_collection_g.py
A	tests/python/render_layer/test_move_into_scene_collection_h.py
A	tests/python/render_layer/test_move_into_scene_collection_i.py
A	tests/python/render_layer/test_move_into_scene_collection_j.py
A	tests/python/render_layer/test_move_into_scene_collection_k.py
A	tests/python/render_layer/test_move_into_scene_collection_l.py
A	tests/python/render_layer/test_move_into_scene_collection_sync_a.py
A	tests/python/render_layer/test_move_into_scene_collection_sync_b.py
A	tests/python/render_layer/test_move_into_scene_collection_sync_c.py
A	tests/python/render_layer/test_move_into_scene_collection_sync_d.py
A	tests/python/render_layer/test_move_into_scene_collection_sync_e.py
A	tests/python/render_layer/test_move_into_scene_collection_sync_f.py
A	tests/python/render_layer/test_move_into_scene_collection_sync_g.py
A	tests/python/render_layer/test_move_into_scene_collection_sync_h.py
A	tests/python/render_layer/test_move_into_scene_collection_sync_i.py
A	tests/python/render_layer/test_move_into_scene_collection_sync_j.py
A	tests/python/render_layer/test_move_into_scene_collection_sync_k.py
A	tests/python/render_layer/test_move_into_scene_collection_sync_l.py

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

diff --git a/release/scripts/addons b/release/scripts/addons
index f2bb66b68b4..371960484a3 160000
--- a/release/scripts/addons
+++ b/release/scripts/addons
@@ -1 +1 @@
-Subproject commit f2bb66b68b4071c6554cae881010a783b3ebbdf0
+Subproject commit 371960484a38fc64e0a2635170a41a0d8ab2f6bd
diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h
index e090584ad7a..2ea2c23dadd 100644
--- a/source/blender/blenkernel/BKE_collection.h
+++ b/source/blender/blenkernel/BKE_collection.h
@@ -55,6 +55,10 @@ void BKE_collections_object_remove(struct Main *bmain, struct Scene *scene, stru
 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);
 
+bool BKE_collection_move_above(const struct Scene *scene, struct SceneCollection *sc_dst, struct SceneCollection *sc_src);
+bool BKE_collection_move_below(const struct Scene *scene, struct SceneCollection *sc_dst, struct SceneCollection *sc_src);
+bool BKE_collection_move_into(const struct Scene *scene, struct SceneCollection *sc_dst, struct SceneCollection *sc_src);
+
 typedef void (*BKE_scene_objects_Cb)(struct Object *ob, void *data);
 typedef void (*BKE_scene_collections_Cb)(struct SceneCollection *ob, void *data);
 
diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
index aa1d537a28e..14324f27bfe 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -84,9 +84,14 @@ struct LayerCollection *BKE_layer_collection_active(struct SceneLayer *sl);
 int BKE_layer_collection_count(struct SceneLayer *sl);
 
 int BKE_layer_collection_findindex(struct SceneLayer *sl, struct LayerCollection *lc);
-void BKE_layer_collection_reinsert_after(const struct Scene *scene, struct SceneLayer *sl,
+bool BKE_layer_collection_reinsert_after(const struct Scene *scene, struct SceneLayer *sl,
                                          struct LayerCollection *lc_reinsert, struct LayerCollection *lc_after);
-void BKE_layer_collection_reinsert_into(struct LayerCollection *lc_reinsert, struct LayerCollection *lc_into);
+
+bool BKE_layer_collection_move_above(const struct Scene *scene, struct LayerCollection *lc_dst, struct LayerCollection *lc_src);
+bool BKE_layer_collection_move_below(const struct Scene *scene, struct LayerCollection *lc_dst, struct LayerCollection *lc_src);
+bool BKE_layer_collection_move_into(const struct Scene *scene, struct LayerCollection *lc_dst, struct LayerCollection *lc_src);
+
+void BKE_layer_collection_resync(const struct Scene *scene, const struct SceneCollection *sc);
 
 struct LayerCollection *BKE_collection_link(struct SceneLayer *sl, struct SceneCollection *sc);
 
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index b423efdda24..564fa5d9593 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -298,16 +298,150 @@ void BKE_collections_object_remove(Main *bmain, Scene *scene, Object *ob, const
 	FOREACH_SCENE_COLLECTION_END
 }
 
-void BKE_collection_reinsert_after(const struct Scene *scene, SceneCollection *sc_reinsert, SceneCollection *sc_after)
+/* ---------------------------------------------------------------------- */
+/* Outliner drag and drop */
+
+/**
+ * Find and return the SceneCollection that has \a sc_child as one of its directly
+ * nested SceneCollection.
+ *
+ * \param sc_parent Initial SceneCollection to look into recursively, usually the master collection
+ */
+static SceneCollection *find_collection_parent(const SceneCollection *sc_child, SceneCollection *sc_parent)
+{
+	for (SceneCollection *sc_nested = sc_parent->scene_collections.first; sc_nested; sc_nested = sc_nested->next) {
+		if (sc_nested == sc_child) {
+			return sc_parent;
+		}
+
+		SceneCollection *found = find_collection_parent(sc_child, sc_nested);
+		if (found) {
+			return found;
+		}
+	}
+
+	return NULL;
+}
+
+/**
+ * Check if \a sc_reference is nested to \a sc_parent SceneCollection
+ */
+static bool is_collection_in_tree(const SceneCollection *sc_reference, SceneCollection *sc_parent)
+{
+	return find_collection_parent(sc_reference, sc_parent) != NULL;
+}
+
+bool BKE_collection_move_above(const Scene *scene, SceneCollection *sc_dst, SceneCollection *sc_src)
+{
+	/* Find the SceneCollection the sc_src belongs to */
+	SceneCollection *sc_master = BKE_collection_master(scene);
+
+	/* Master Layer can't be moved around*/
+	if (ELEM(sc_master, sc_src, sc_dst)) {
+		return false;
+	}
+
+	/* collection is already where we wanted it to be */
+	if (sc_dst->prev == sc_src) {
+		return false;
+	}
+
+	/* We can't move a collection fs the destiny collection
+	 * is nested to the source collection */
+	if (is_collection_in_tree(sc_dst, sc_src)) {
+		return false;
+	}
+
+	SceneCollection *sc_src_parent = find_collection_parent(sc_src, sc_master);
+	SceneCollection *sc_dst_parent = find_collection_parent(sc_dst, sc_master);
+	BLI_assert(sc_src_parent);
+	BLI_assert(sc_dst_parent);
+
+	/* Remove sc_src from its parent */
+	BLI_remlink(&sc_src_parent->scene_collections, sc_src);
+
+	/* Re-insert it where it belongs */
+	BLI_insertlinkbefore(&sc_dst_parent->scene_collections, sc_dst, sc_src);
+
+	/* Update the tree */
+	BKE_layer_collection_resync(scene, sc_src_parent);
+	BKE_layer_collection_resync(scene, sc_dst_parent);
+
+	return true;
+}
+
+bool BKE_collection_move_below(const Scene *scene, SceneCollection *sc_dst, SceneCollection *sc_src)
 {
-	UNUSED_VARS(scene, sc_reinsert, sc_after);
-	TODO_LAYER_OPERATORS;
+	/* Find the SceneCollection the sc_src belongs to */
+	SceneCollection *sc_master = BKE_collection_master(scene);
+
+	/* Master Layer can't be moved around*/
+	if (ELEM(sc_master, sc_src, sc_dst)) {
+		return false;
+	}
+
+	/* Collection is already where we wanted it to be */
+	if (sc_dst->next == sc_src) {
+		return false;
+	}
+
+	/* We can't move a collection if the destiny collection
+	 * is nested to the source collection */
+	if (is_collection_in_tree(sc_dst, sc_src)) {
+		return false;
+	}
+
+	SceneCollection *sc_src_parent = find_collection_parent(sc_src, sc_master);
+	SceneCollection *sc_dst_parent = find_collection_parent(sc_dst, sc_master);
+	BLI_assert(sc_src_parent);
+	BLI_assert(sc_dst_parent);
+
+	/* Remove sc_src from its parent */
+	BLI_remlink(&sc_src_parent->scene_collections, sc_src);
+
+	/* Re-insert it where it belongs */
+	BLI_insertlinkafter(&sc_dst_parent->scene_collections, sc_dst, sc_src);
+
+	/* Update the tree */
+	BKE_layer_collection_resync(scene, sc_src_parent);
+	BKE_layer_collection_resync(scene, sc_dst_parent);
+
+	return true;
 }
 
-void BKE_collection_reinsert_into(SceneCollection *sc_reinsert, SceneCollection *sc_into)
+bool BKE_collection_move_into(const Scene *scene, SceneCollection *sc_dst, SceneCollection *sc_src)
 {
-	UNUSED_VARS(sc_reinsert, sc_into);
-	TODO_LAYER_OPERATORS;
+	/* Find the SceneCollection the sc_src belongs to */
+	SceneCollection *sc_master = BKE_collection_master(scene);
+	if (sc_src == sc_master) {
+		return false;
+	}
+
+	/* We can't move a collection if the destiny collection
+	 * is nested to the source collection */
+	if (is_collection_in_tree(sc_dst, sc_src)) {
+		return false;
+	}
+
+	SceneCollection *sc_src_parent = find_collection_parent(sc_src, sc_master);
+	BLI_assert(sc_src_parent);
+
+	/* collection is already where we wanted it to be */
+	if (sc_dst->scene_collections.last == sc_src) {
+		return false;
+	}
+
+	/* Remove sc_src from it */
+	BLI_remlink(&sc_src_parent->scene_collections, sc_src);
+
+	/* Insert sc_src into sc_dst */
+	BLI_addtail(&sc_dst->scene_collections, sc_src);
+
+	/* Update the tree */
+	BKE_layer_collection_resync(scene, sc_src_parent);
+	BKE_layer_collection_resync(scene, sc_dst);
+
+	return true;
 }
 
 /* ---------------------------------------------------------------------- */
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index 77501c4acce..fb1a35d210c 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -533,13 +533,13 @@ static ListBase *scene_collection_listbase_find(ListBase *lb, SceneCollection *s
  * Move \a lc_reinsert so that it follows \a lc_after. Both have to be stored in \a sl.
  * \param lc_after: Can be NULL to reinsert \a lc_after as first collection of its own list.
  */
-void BKE_layer_collection_reinsert_after(
+bool BKE_layer_collection_reinsert_after(
         const Scene *scene, SceneLayer *sl, LayerCollection *lc_reinsert, LayerCollection *lc_after)
 {
 	/* TODO this function probably needs to be rewritten completely to support all cases
 	 * (reinserting master collection, reinsert into different hierarchy levels, etc) */
 	TODO_LAYER_OPERATORS;
-
+#if 0
 	SceneCollection *sc_master = BKE_collection_master(scene);
 	SceneCollection *sc_reinsert = lc_reinsert->scene_collection;
 	ListBase *lc_reinsert_lb = layer_collection_listbase_find(&sl->layer_collections, lc_reinsert);
@@ -566,16 +566,107 @@ void BKE_layer_collection_reinsert_after(
 
 	BKE_scene_layer_base_flag_recalculate(sl);
 	BKE_scene_layer_engine_settings_collection_recalculate(sl, lc_reinsert);
+#else
+	UNUSED_VARS(scene, sl, lc_reinsert, lc_after);
+	UNUSED_VARS(layer_collection_listbase_find, scene_collection_listbase_find);
+	return false;
+#endif
 }
 
-void BKE_layer_collection_reinsert_into(LayerCollection *lc_reinsert, LayerCollection *lc_into)
+/* ---------------------------------------------------------------------- */
+/* Outliner drag and drop */
+
+/**
+ * Nest a LayerCollection into another one
+ * Both collections must be from the same SceneLayer, return true if succeded.
+ *
+ * The LayerCollection will effectively be moved into the
+ * new (nested) position. So all the settings, overrides, ... go with it, and
+ * if the collection was directly linked to the SceneLayer it's then unlinked.
+ *
+ * For the other SceneLayers we simply resync the tree, without changing directly
+ * linked collections (even if they link

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list