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
path: root/source
diff options
context:
space:
mode:
authorDalai Felinto <dfelinto@gmail.com>2016-12-10 19:54:35 +0300
committerDalai Felinto <dfelinto@gmail.com>2016-12-12 14:12:42 +0300
commitc96c3c8bbe51a7dd26addcdeac9d0bb2e992cca1 (patch)
treeab57375b818795e66019cec09f0eb68de2b0975e /source
parentef6a35b0afa256b9ed5b293f684a29909c44fe9c (diff)
Scene copy (full or link) working for layers
I'm using the flags in the objects instead of bases.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_collection.h1
-rw-r--r--source/blender/blenkernel/BKE_context.h3
-rw-r--r--source/blender/blenkernel/BKE_layer.h9
-rw-r--r--source/blender/blenkernel/intern/collection.c19
-rw-r--r--source/blender/blenkernel/intern/context.c28
-rw-r--r--source/blender/blenkernel/intern/layer.c15
-rw-r--r--source/blender/blenkernel/intern/scene.c83
-rw-r--r--source/blender/editors/object/object_relations.c139
8 files changed, 247 insertions, 50 deletions
diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h
index a839824d229..fc2cf1c268d 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 c6795f87eab..d22941cac6a 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 26df4ef466b..acfad811693 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 ed9aef21dd6..a3112097141 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 b38f59a3723..c9454f84690 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 b34f6dac13c..a1d1e9649cd 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 88c386abb80..200041747c5 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->basact = ob_base;
+ break;
+ }
+ }
+ }
+ new_sl = new_sl->next;
+ }
}
/* copy color management settings */
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index a3ff8dcb676..18884881a04 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -62,6 +62,7 @@
#include "BKE_animsys.h"
#include "BKE_armature.h"
#include "BKE_camera.h"
+#include "BKE_collection.h"
#include "BKE_context.h"
#include "BKE_constraint.h"
#include "BKE_curve.h"
@@ -73,6 +74,7 @@
#include "BKE_fcurve.h"
#include "BKE_lamp.h"
#include "BKE_lattice.h"
+#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_library_query.h"
#include "BKE_main.h"
@@ -1730,10 +1732,68 @@ void OBJECT_OT_make_links_data(wmOperatorType *ot)
/**************************** Make Single User ********************************/
+static Object *single_object_users_object(Main *bmain, Scene *scene, Object *ob, const bool copy_groups)
+{
+ if (!ID_IS_LINKED_DATABLOCK(ob) && ob->id.us > 1) {
+ /* base gets copy of object */
+ Object *obn = BKE_object_copy(bmain, ob);
+
+ if (copy_groups) {
+ if (ob->flag & OB_FROMGROUP) {
+ obn->flag |= OB_FROMGROUP;
+ }
+ }
+ else {
+ /* copy already clears */
+ }
+ /* remap gpencil parenting */
+
+ if (scene->gpd) {
+ bGPdata *gpd = scene->gpd;
+ for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+ if (gpl->parent == ob) {
+ gpl->parent = obn;
+ }
+ }
+ }
+
+ id_us_min(&ob->id);
+ return obn;
+ }
+ return NULL;
+}
+
+static void libblock_relink_scene_collection(SceneCollection *sc)
+{
+ for (LinkData *link = sc->objects.first; link; link = link->next) {
+ BKE_libblock_relink(link->data);
+ }
+
+ for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
+ libblock_relink_scene_collection(nsc);
+ }
+}
+
+static void single_object_users_scene_collection(Main *bmain, Scene *scene, SceneCollection *sc, const int flag, const bool copy_groups)
+{
+ for (LinkData *link = sc->objects.first; link; link = link->next) {
+ Object *ob = link->data;
+ /* an object may be in more than one collection */
+ if ((ob->id.newid == NULL) && ((ob->flag & flag) == flag)) {
+ link->data = single_object_users_object(bmain, scene, link->data, copy_groups);
+ }
+ }
+
+ /* we reset filter objects because they should be regenerated after this */
+ BLI_freelistN(&sc->filter_objects);
+
+ for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
+ single_object_users_scene_collection(bmain, scene, nsc, flag, copy_groups);
+ }
+}
+
static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const int flag, const bool copy_groups)
{
- Base *base;
- Object *ob, *obn;
Group *group, *groupn;
GroupObject *go;
@@ -1750,39 +1810,14 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in
}
}
- /* duplicate (must set newid) */
- for (base = FIRSTBASE; base; base = base->next) {
- ob = base->object;
-
- if ((base->flag & flag) == flag) {
- if (!ID_IS_LINKED_DATABLOCK(ob) && ob->id.us > 1) {
- /* base gets copy of object */
- obn = BKE_object_copy(bmain, ob);
- base->object = obn;
-
- if (copy_groups) {
- if (ob->flag & OB_FROMGROUP) {
- obn->flag |= OB_FROMGROUP;
- }
- }
- else {
- /* copy already clears */
- }
- /* remap gpencil parenting */
+ /* duplicate all the objects of the scene */
+ SceneCollection *msc = BKE_collection_master(scene);
+ single_object_users_scene_collection(bmain, scene, msc, flag, copy_groups);
- if (scene->gpd) {
- bGPdata *gpd = scene->gpd;
- for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
- if (gpl->parent == ob) {
- gpl->parent = obn;
- }
- }
- }
-
- base->flag = obn->flag;
-
- id_us_min(&ob->id);
- }
+ /* loop over SceneLayers and assign the pointers accordingly */
+ for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
+ for (ObjectBase *ob_base = sl->object_bases.first; ob_base; ob_base = ob_base->next) {
+ ID_NEW(ob_base->object);
}
}
@@ -1816,26 +1851,28 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in
if (v3d) ID_NEW(v3d->camera);
/* object and group pointers */
- for (base = FIRSTBASE; base; base = base->next) {
- BKE_libblock_relink(&base->object->id);
- }
+ libblock_relink_scene_collection(msc);
set_sca_new_poins();
+
+ /* TODO redo filter */
+ TODO_LAYER_SYNC_FILTER
+}
+
+static void object_untag_OB_DONE(Object *ob, void *UNUSED(data))
+{
+ ob->flag &= ~OB_DONE;
}
/* not an especially efficient function, only added so the single user
* button can be functional.*/
void ED_object_single_user(Main *bmain, Scene *scene, Object *ob)
{
- Base *base;
- const bool copy_groups = false;
-
- for (base = FIRSTBASE; base; base = base->next) {
- if (base->object == ob) base->flag |= OB_DONE;
- else base->flag &= ~OB_DONE;
- }
+ SceneCollection *msc = BKE_collection_master(scene);
+ BKE_collection_objects_callback(msc, object_untag_OB_DONE, NULL);
- single_object_users(bmain, scene, NULL, OB_DONE, copy_groups);
+ ob->flag |= OB_DONE;
+ single_object_users(bmain, scene, NULL, OB_DONE, false);
}
static void new_id_matar(Main *bmain, Material **matar, const int totcol)
@@ -1872,6 +1909,8 @@ static void single_obdata_users(Main *bmain, Scene *scene, const int flag)
ID *id;
int a;
+ TODO_LAYER; /* need to use scene->collection base instead of scene->bases */
+
for (base = FIRSTBASE; base; base = base->next) {
ob = base->object;
if (!ID_IS_LINKED_DATABLOCK(ob) && (base->flag & flag) == flag) {
@@ -2379,7 +2418,15 @@ static int make_single_user_exec(bContext *C, wmOperator *op)
BKE_main_id_clear_newpoins(bmain);
if (RNA_boolean_get(op->ptr, "object")) {
- single_object_users(bmain, scene, v3d, flag, copy_groups);
+ if (flag == SELECT) {
+ SceneLayer *sl = CTX_data_scene_layer(C);
+
+ BKE_scene_layer_selected_objects_tag(sl, OB_DONE);
+ single_object_users(bmain, scene, v3d, OB_DONE, copy_groups);
+ }
+ else {
+ single_object_users(bmain, scene, v3d, 0, copy_groups);
+ }
/* needed since object relationships may have changed */
update_deps = true;