[Bf-blender-cvs] [c96c3c8] render-layers: Scene copy (full or link) working for layers

Dalai Felinto noreply at git.blender.org
Mon Dec 12 12:57:14 CET 2016


Commit: c96c3c8bbe51a7dd26addcdeac9d0bb2e992cca1
Author: Dalai Felinto
Date:   Sat Dec 10 17:54:35 2016 +0100
Branches: render-layers
https://developer.blender.org/rBc96c3c8bbe51a7dd26addcdeac9d0bb2e992cca1

Scene copy (full or link) working for layers

I'm using the flags in the objects instead of bases.

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

M	source/blender/blenkernel/BKE_collection.h
M	source/blender/blenkernel/BKE_context.h
M	source/blender/blenkernel/BKE_layer.h
M	source/blender/blenkernel/intern/collection.c
M	source/blender/blenkernel/intern/context.c
M	source/blender/blenkernel/intern/layer.c
M	source/blender/blenkernel/intern/scene.c
M	source/blender/editors/object/object_relations.c

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

diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h
index a839824..fc2cf1c 100644
--- a/source/blender/blenkernel/BKE_collection.h
+++ b/source/blender/blenkernel/BKE_collection.h
@@ -41,6 +41,7 @@ struct SceneCollection *BKE_collection_master(struct Scene *scene);
 void BKE_collection_master_free(struct Scene *scene);
 void BKE_collection_object_add(struct Scene *scene, struct SceneCollection *sc, struct Object *object);
 void BKE_collection_object_remove(struct Scene *scene, struct SceneCollection *sc, struct Object *object);
+void BKE_collection_objects_callback(struct SceneCollection *sc, void (*callback)(struct Object *_ob, void *_data), void *data);
 
 #ifdef __cplusplus
 }
diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h
index c6795f8..d22941c 100644
--- a/source/blender/blenkernel/BKE_context.h
+++ b/source/blender/blenkernel/BKE_context.h
@@ -46,6 +46,7 @@ struct Object;
 struct PointerRNA;
 struct ReportList;
 struct Scene;
+struct SceneLayer;
 struct ScrArea;
 struct SpaceLink;
 struct View3D;
@@ -238,6 +239,7 @@ int ctx_data_list_count(const bContext *C, int (*func)(const bContext *, ListBas
 
 struct Main *CTX_data_main(const bContext *C);
 struct Scene *CTX_data_scene(const bContext *C);
+struct SceneLayer *CTX_data_scene_layer(const bContext *C);
 struct ToolSettings *CTX_data_tool_settings(const bContext *C);
 
 const char *CTX_data_mode_string(const bContext *C);
@@ -245,6 +247,7 @@ int CTX_data_mode_enum(const bContext *C);
 
 void CTX_data_main_set(bContext *C, struct Main *bmain);
 void CTX_data_scene_set(bContext *C, struct Scene *bmain);
+void CTX_data_scene_layer_set(bContext *C, struct SceneLayer *sl);
 
 int CTX_data_selected_editable_objects(const bContext *C, ListBase *list);
 int CTX_data_selected_editable_bases(const bContext *C, ListBase *list);
diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
index 26df4ef..acfad81 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -31,8 +31,11 @@
 extern "C" {
 #endif
 
-#define TODO_LAYER_SYNC
-#define TODO_LAYER_OVERRIDE
+#define TODO_LAYER_SYNC /* syncing of SceneCollection and LayerCollection trees*/
+#define TODO_LAYER_SYNC_FILTER /* syncing of filter_objects across all trees */
+#define TODO_LAYER_OVERRIDE /* CollectionOverride */
+#define TODO_LAYER_CONTEXT /* get/set current (context) SceneLayer */
+#define TODO_LAYER /* generic todo */
 
 struct LayerCollection;
 struct ID;
@@ -51,6 +54,8 @@ void BKE_scene_layer_free(struct SceneLayer *sl);
 
 void BKE_scene_layer_engine_set(struct SceneLayer *sl, const char *engine);
 
+void BKE_scene_layer_selected_objects_tag(struct SceneLayer *sl, const int tag);
+
 struct ObjectBase *BKE_scene_layer_base_find(struct SceneLayer *sl, struct Object *ob);
 
 void BKE_layer_collection_free(struct SceneLayer *sl, struct LayerCollection *lc);
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index ed9aef2..a311209 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -34,6 +34,7 @@
 
 #include "DNA_ID.h"
 #include "DNA_layer_types.h"
+#include "DNA_object_types.h"
 #include "DNA_scene_types.h"
 
 #include "MEM_guardedalloc.h"
@@ -196,3 +197,21 @@ void BKE_collection_object_remove(struct Scene *UNUSED(scene), struct SceneColle
 	/* remove the equivalent object base to all layers that have this collection
 	 * also remove all reference to ob in the filter_objects */
 }
+
+/*
+ * Recursively calls the callback function for the objects in a SceneCollection
+ */
+void BKE_collection_objects_callback(SceneCollection *sc, void (*callback)(struct Object *_ob, void *_data), void *data)
+{
+	for (LinkData *link= sc->objects.first; link; link = link->next) {
+		callback(link->data, data);
+	}
+
+	for (LinkData *link= sc->filter_objects.first; link; link = link->next) {
+		callback(link->data, data);
+	}
+
+	for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
+		BKE_collection_objects_callback(nsc, callback, data);
+	}
+}
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index b38f59a..c9454f8 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -47,6 +47,7 @@
 #include "BLT_translation.h"
 
 #include "BKE_context.h"
+#include "BKE_layer.h"
 #include "BKE_main.h"
 #include "BKE_screen.h"
 #include "BKE_sound.h"
@@ -78,6 +79,7 @@ struct bContext {
 	struct {
 		struct Main *main;
 		struct Scene *scene;
+		struct SceneLayer *render_layer;
 
 		int recursion;
 		int py_init; /* true if python is initialized */
@@ -836,8 +838,9 @@ void CTX_wm_window_set(bContext *C, wmWindow *win)
 void CTX_wm_screen_set(bContext *C, bScreen *screen)
 {
 	C->wm.screen = screen;
-	if (C->wm.screen)
-		C->data.scene = C->wm.screen->scene;
+	if (C->wm.screen) {
+		CTX_data_scene_set(C, C->wm.screen->scene);
+	}
 	C->wm.area = NULL;
 	C->wm.region = NULL;
 }
@@ -896,6 +899,16 @@ Scene *CTX_data_scene(const bContext *C)
 		return C->data.scene;
 }
 
+SceneLayer *CTX_data_scene_layer(const bContext *C)
+{
+	SceneLayer *sl;
+
+	if (ctx_data_pointer_verify(C, "render_layer", (void *)&sl))
+		return sl;
+	else
+		return C->data.render_layer;
+}
+
 int CTX_data_mode_enum(const bContext *C)
 {
 	Object *obedit = CTX_data_edit_object(C);
@@ -960,6 +973,17 @@ const char *CTX_data_mode_string(const bContext *C)
 void CTX_data_scene_set(bContext *C, Scene *scene)
 {
 	C->data.scene = scene;
+	TODO_LAYER_CONTEXT
+
+	/* render_layer comes from workspace (or even viewport) actually
+	 * this is only while we wait for workspace changes to be merged
+	 */
+	CTX_data_scene_layer_set(C, scene->render_layers.last);
+}
+
+void CTX_data_scene_layer_set(bContext *C, SceneLayer *sl)
+{
+	C->data.render_layer = sl;
 }
 
 ToolSettings *CTX_data_tool_settings(const bContext *C)
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index b34f6da..a1d1e96 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -127,6 +127,21 @@ void BKE_scene_layer_engine_set(SceneLayer *sl, const char *engine)
 	BLI_strncpy_utf8(sl->engine, engine, sizeof(sl->engine));
 }
 
+/*
+ * Tag all the selected objects of a renderlayer
+ */
+void BKE_scene_layer_selected_objects_tag(SceneLayer *sl, const int tag)
+{
+	for (ObjectBase *ob_base = sl->object_bases.first; ob_base; ob_base = ob_base->next) {
+		if ((ob_base->flag & BASE_SELECTED) != 0) {
+			ob_base->object->flag |= tag;
+		}
+		else {
+			ob_base->object->flag &= ~tag;
+		}
+	}
+}
+
 /* ObjectBase */
 
 ObjectBase *BKE_scene_layer_base_find(SceneLayer *sl, Object *ob)
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 88c386a..2000417 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -154,6 +154,59 @@ static void remove_sequencer_fcurves(Scene *sce)
 	}
 }
 
+/* copy SceneCollection tree but keep pointing to the same objects */
+static void scene_collection_copy(SceneCollection *scn, SceneCollection *sc)
+{
+	BLI_duplicatelist(&scn->objects, &sc->objects);
+	for (LinkData *link = scn->objects.first; link; link = link->next) {
+		id_us_plus(link->data);
+	}
+
+	BLI_duplicatelist(&scn->filter_objects, &sc->filter_objects);
+	for (LinkData *link = scn->filter_objects.first; link; link = link->next) {
+		id_us_plus(link->data);
+	}
+
+	BLI_duplicatelist(&scn->scene_collections, &sc->scene_collections);
+	SceneCollection *nscn = scn->scene_collections.first; /* nested SceneCollection new */
+	for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
+		scene_collection_copy(nscn, nsc);
+		nscn = nscn->next;
+	}
+}
+
+/* Find the equivalent SceneCollection in the new tree */
+static SceneCollection *scene_collection_from_new_tree(SceneCollection *sc_reference, SceneCollection *scn, SceneCollection *sc)
+{
+	if (sc == sc_reference) {
+		return scn;
+	}
+
+	SceneCollection *nscn = scn->scene_collections.first; /* nested master collection new */
+	for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
+
+		SceneCollection *found = scene_collection_from_new_tree(sc_reference, nscn, nsc);
+		if (found) {
+			return found;
+		}
+		nscn = nscn->next;
+	}
+	return NULL;
+}
+
+/* recreate the LayerCollection tree */
+static void layer_collections_recreate(SceneLayer *sl, ListBase *lb, SceneCollection *mcn, SceneCollection *mc)
+{
+	for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
+
+		SceneCollection *sc = scene_collection_from_new_tree(lc->scene_collection, mcn, mc);
+		BLI_assert(sc);
+
+		/* instead of syncronizing both trees we simply re-create it */
+		BKE_collection_link(sl, sc);
+	}
+}
+
 Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
 {
 	Scene *scen;
@@ -246,6 +299,36 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
 			}
 			new_srl = new_srl->next;
 		}
+
+		/* layers and collections */
+		scen->collection = MEM_dupallocN(sce->collection);
+		SceneCollection *mcn = BKE_collection_master(scen);
+		SceneCollection *mc = BKE_collection_master(sce);
+
+		/* recursively creates a new SceneCollection tree */
+		scene_collection_copy(mcn, mc);
+
+		BLI_duplicatelist(&scen->render_layers, &sce->render_layers);
+		SceneLayer *new_sl = scen->render_layers.first;
+		for (SceneLayer *sl = sce->render_layers.first; sl; sl = sl->next) {
+
+			/* we start fresh with no overrides and no visibility flags set
+			 * instead of syncing both trees we simply unlink and relink the scene collection */
+			BLI_listbase_clear(&new_sl->layer_collections);
+			BLI_listbase_clear(&new_sl->object_bases);
+			layer_collections_recreate(new_sl, &sl->layer_collections, mcn, mc);
+
+			if (sl->basact) {
+				Object *active_ob = sl->basact->object;
+				for (ObjectBase *ob_base = new_sl->object_bases.first; ob_base; ob_base = ob_base->next) {
+					if (ob_base->object == active_ob) {
+						new_sl->bas

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list