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:
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_collection.h91
-rw-r--r--source/blender/blenkernel/BKE_context.h8
-rw-r--r--source/blender/blenkernel/BKE_group.h5
-rw-r--r--source/blender/blenkernel/BKE_layer.h189
-rw-r--r--source/blender/blenkernel/BKE_node.h7
-rw-r--r--source/blender/blenkernel/BKE_object.h9
-rw-r--r--source/blender/blenkernel/BKE_scene.h23
-rw-r--r--source/blender/blenkernel/CMakeLists.txt4
-rw-r--r--source/blender/blenkernel/intern/anim.c4
-rw-r--r--source/blender/blenkernel/intern/cachefile.c2
-rw-r--r--source/blender/blenkernel/intern/camera.c2
-rw-r--r--source/blender/blenkernel/intern/collection.c455
-rw-r--r--source/blender/blenkernel/intern/collision.c4
-rw-r--r--source/blender/blenkernel/intern/context.c70
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c4
-rw-r--r--source/blender/blenkernel/intern/effect.c2
-rw-r--r--source/blender/blenkernel/intern/group.c17
-rw-r--r--source/blender/blenkernel/intern/layer.c684
-rw-r--r--source/blender/blenkernel/intern/library_query.c27
-rw-r--r--source/blender/blenkernel/intern/library_remap.c63
-rw-r--r--source/blender/blenkernel/intern/mball.c32
-rw-r--r--source/blender/blenkernel/intern/mball_tessellate.c4
-rw-r--r--source/blender/blenkernel/intern/node.c17
-rw-r--r--source/blender/blenkernel/intern/object.c40
-rw-r--r--source/blender/blenkernel/intern/object_dupli.c2
-rw-r--r--source/blender/blenkernel/intern/particle_system.c2
-rw-r--r--source/blender/blenkernel/intern/pointcache.c2
-rw-r--r--source/blender/blenkernel/intern/scene.c240
-rw-r--r--source/blender/blenkernel/intern/smoke.c2
-rw-r--r--source/blender/blenkernel/intern/softbody.c6
-rw-r--r--source/blender/blenkernel/intern/sound.c2
31 files changed, 1849 insertions, 170 deletions
diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h
new file mode 100644
index 00000000000..c3f461dacd6
--- /dev/null
+++ b/source/blender/blenkernel/BKE_collection.h
@@ -0,0 +1,91 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Dalai Felinto
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __BKE_COLLECTION_H__
+#define __BKE_COLLECTION_H__
+
+/** \file blender/blenkernel/BKE_collection.h
+ * \ingroup bke
+ */
+
+#include "BLI_ghash.h"
+#include "BLI_iterator.h"
+#include "DNA_listBase.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct Iterator;
+struct SceneCollection;
+struct Object;
+struct Base;
+struct Main;
+struct Scene;
+
+struct SceneCollection *BKE_collection_add(struct Scene *scene, struct SceneCollection *sc_parent, const char *name);
+bool BKE_collection_remove(struct Scene *scene, struct SceneCollection *sc);
+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_add_from(struct Scene *scene, struct Object *ob_src, struct Object *ob_dst);
+void BKE_collection_object_remove(struct Main *bmain, struct Scene *scene, struct SceneCollection *sc, struct Object *object, const bool free_us);
+void BKE_collections_object_remove(struct Main *bmain, struct Scene *scene, struct Object *object, const bool free_us);
+
+typedef void (*BKE_scene_objects_Cb)(struct Object *ob, void *data);
+typedef void (*BKE_scene_collections_Cb)(struct SceneCollection *ob, void *data);
+
+void BKE_scene_collections_callback(struct Scene *scene, BKE_scene_collections_Cb callback, void *data);
+void BKE_scene_objects_callback(struct Scene *scene, BKE_scene_objects_Cb callback, void *data);
+
+/* iterators */
+void BKE_scene_collections_Iterator_begin(struct Iterator *iter, void *data_in);
+void BKE_scene_collections_Iterator_next(struct Iterator *iter);
+void BKE_scene_collections_Iterator_end(struct Iterator *iter);
+
+void BKE_scene_objects_Iterator_begin(struct Iterator *iter, void *data_in);
+void BKE_scene_objects_Iterator_next(struct Iterator *iter);
+void BKE_scene_objects_Iterator_end(struct Iterator *iter);
+
+#define FOREACH_SCENE_COLLECTION(scene, _sc) \
+ ITER_BEGIN(BKE_scene_collections_Iterator_begin, \
+ BKE_scene_collections_Iterator_next, \
+ BKE_scene_collections_Iterator_end, \
+ scene, _sc)
+
+#define FOREACH_SCENE_COLLECTION_END \
+ ITER_END
+
+#define FOREACH_SCENE_OBJECT(scene, _ob) \
+ ITER_BEGIN(BKE_scene_objects_Iterator_begin, \
+ BKE_scene_objects_Iterator_next, \
+ BKE_scene_objects_Iterator_end, \
+ scene, _ob)
+
+#define FOREACH_SCENE_OBJECT_END \
+ ITER_END
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BKE_COLLECTION_H__ */
diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h
index 4da6a61cbfa..23f9ff28f8b 100644
--- a/source/blender/blenkernel/BKE_context.h
+++ b/source/blender/blenkernel/BKE_context.h
@@ -40,12 +40,16 @@ extern "C" {
struct ARegion;
struct bScreen;
struct CacheFile;
+struct LayerCollection;
struct ListBase;
struct Main;
struct Object;
+struct Base;
struct PointerRNA;
struct ReportList;
struct Scene;
+struct SceneCollection;
+struct SceneLayer;
struct ScrArea;
struct SpaceLink;
struct View3D;
@@ -166,6 +170,7 @@ struct SpaceAction *CTX_wm_space_action(const bContext *C);
struct SpaceInfo *CTX_wm_space_info(const bContext *C);
struct SpaceUserPref *CTX_wm_space_userpref(const bContext *C);
struct SpaceClip *CTX_wm_space_clip(const bContext *C);
+struct SpaceCollections *CTX_wm_space_collections(const bContext *C);
void CTX_wm_manager_set(bContext *C, struct wmWindowManager *wm);
void CTX_wm_window_set(bContext *C, struct wmWindow *win);
@@ -239,6 +244,9 @@ 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 LayerCollection *CTX_data_layer_collection(const bContext *C);
+struct SceneCollection *CTX_data_scene_collection(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);
diff --git a/source/blender/blenkernel/BKE_group.h b/source/blender/blenkernel/BKE_group.h
index 09a069ee36f..f718e9c8555 100644
--- a/source/blender/blenkernel/BKE_group.h
+++ b/source/blender/blenkernel/BKE_group.h
@@ -33,6 +33,7 @@
* \author nzc
*/
+struct BaseLegacy;
struct Base;
struct EvaluationContext;
struct Group;
@@ -44,8 +45,8 @@ void BKE_group_free(struct Group *group);
struct Group *BKE_group_add(struct Main *bmain, const char *name);
struct Group *BKE_group_copy(struct Main *bmain, struct Group *group);
void BKE_group_make_local(struct Main *bmain, struct Group *group, const bool lib_local);
-bool BKE_group_object_add(struct Group *group, struct Object *ob, struct Scene *scene, struct Base *base);
-bool BKE_group_object_unlink(struct Group *group, struct Object *ob, struct Scene *scene, struct Base *base);
+bool BKE_group_object_add(struct Group *group, struct Object *ob);
+bool BKE_group_object_unlink(struct Group *group, struct Object *ob);
struct Group *BKE_group_object_find(struct Group *group, struct Object *ob);
bool BKE_group_object_exists(struct Group *group, struct Object *ob);
bool BKE_group_object_cyclic_check(struct Main *bmain, struct Object *object, struct Group *group);
diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
new file mode 100644
index 00000000000..850c63f535f
--- /dev/null
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -0,0 +1,189 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Dalai Felinto
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __BKE_LAYER_H__
+#define __BKE_LAYER_H__
+
+/** \file blender/blenkernel/BKE_layer.h
+ * \ingroup bke
+ */
+
+#include "BKE_collection.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#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_BASE /* BaseLegacy to Base related TODO */
+#define TODO_LAYER_OPERATORS /* collection mamanger and property panel operators */
+#define TODO_LAYER /* generic todo */
+
+struct Base;
+struct ID;
+struct LayerCollection;
+struct Main;
+struct Object;
+struct Scene;
+struct SceneCollection;
+struct SceneLayer;
+
+struct SceneLayer *BKE_scene_layer_add(struct Scene *scene, const char *name);
+
+bool BKE_scene_layer_remove(struct Main *bmain, struct Scene *scene, struct SceneLayer *sl);
+
+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 SceneLayer *BKE_scene_layer_find_from_collection(struct Scene *scene, struct LayerCollection *lc);
+struct Base *BKE_scene_layer_base_find(struct SceneLayer *sl, struct Object *ob);
+void BKE_scene_layer_base_deselect_all(struct SceneLayer *sl);
+void BKE_scene_layer_base_select(struct SceneLayer *sl, struct Base *selbase);
+void BKE_scene_layer_base_flag_recalculate(struct SceneLayer *sl);
+
+void BKE_layer_collection_free(struct SceneLayer *sl, struct LayerCollection *lc);
+
+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);
+
+struct LayerCollection *BKE_collection_link(struct SceneLayer *sl, struct SceneCollection *sc);
+
+void BKE_collection_unlink(struct SceneLayer *sl, struct LayerCollection *lc);
+
+bool BKE_scene_layer_has_collection(struct SceneLayer *sl, struct SceneCollection *sc);
+bool BKE_scene_has_object(struct Scene *scene, struct Object *ob);
+
+/* syncing */
+
+void BKE_layer_sync_new_scene_collection(struct Scene *scene, const struct SceneCollection *sc_parent, struct SceneCollection *sc);
+void BKE_layer_sync_object_link(struct Scene *scene, struct SceneCollection *sc, struct Object *ob);
+void BKE_layer_sync_object_unlink(struct Scene *scene, struct SceneCollection *sc, struct Object *ob);
+
+/* override */
+
+void BKE_collection_override_datablock_add(struct LayerCollection *lc, const char *data_path, struct ID *id);
+
+/* iterators */
+
+void BKE_selected_objects_Iterator_begin(Iterator *iter, void *data_in);
+void BKE_selected_objects_Iterator_next(Iterator *iter);
+void BKE_selected_objects_Iterator_end(Iterator *iter);
+
+void BKE_visible_objects_Iterator_begin(Iterator *iter, void *data_in);
+void BKE_visible_objects_Iterator_next(Iterator *iter);
+void BKE_visible_objects_Iterator_end(Iterator *iter);
+
+void BKE_visible_bases_Iterator_begin(Iterator *iter, void *data_in);
+void BKE_visible_bases_Iterator_next(Iterator *iter);
+void BKE_visible_bases_Iterator_end(Iterator *iter);
+
+#define FOREACH_SELECTED_OBJECT(sl, _ob) \
+ ITER_BEGIN(BKE_selected_objects_Iterator_begin, \
+ BKE_selected_objects_Iterator_next, \
+ BKE_selected_objects_Iterator_end, \
+ sl, _ob)
+
+#define FOREACH_SELECTED_OBJECT_END \
+ ITER_END
+
+#define FOREACH_VISIBLE_OBJECT(sl, _ob) \
+ ITER_BEGIN(BKE_visible_objects_Iterator_begin, \
+ BKE_visible_objects_Iterator_next, \
+ BKE_visible_objects_Iterator_end, \
+ sl, _ob)
+
+#define FOREACH_VISIBLE_OBJECT_END \
+ ITER_END
+
+
+#define FOREACH_VISIBLE_BASE(sl, _object_base) \
+ ITER_BEGIN(BKE_visible_bases_Iterator_begin, \
+ BKE_visible_bases_Iterator_next, \
+ BKE_visible_bases_Iterator_end, \
+ sl, _object_base)
+
+#define FOREACH_VISIBLE_BASE_END \
+ ITER_END
+
+
+#define FOREACH_OBJECT(sl, _ob) \
+{ \
+ Base *base; \
+ for (base = sl->object_bases.first; base; base = base->next) { \
+ _ob = base->object;
+
+#define FOREACH_OBJECT_END \
+ } \
+}
+
+#define FOREACH_OBJECT_FLAG(scene, sl, flag, _ob) \
+{ \
+ IteratorBeginCb func_begin; \
+ IteratorCb func_next, func_end; \
+ void *data_in; \
+ \
+ if (flag == SELECT) { \
+ func_begin = &BKE_selected_objects_Iterator_begin; \
+ func_next = &BKE_selected_objects_Iterator_next; \
+ func_end = &BKE_selected_objects_Iterator_end; \
+ data_in = sl; \
+ } \
+ else { \
+ func_begin = BKE_scene_objects_Iterator_begin; \
+ func_next = BKE_scene_objects_Iterator_next; \
+ func_end = BKE_scene_objects_Iterator_end; \
+ data_in = scene; \
+ } \
+ ITER_BEGIN(func_begin, func_next, func_end, data_in, _ob)
+
+
+#define FOREACH_OBJECT_FLAG_END \
+ ITER_END \
+}
+
+/* temporary hacky solution waiting for final depsgraph evaluation */
+#define DEG_OBJECT_ITER(sl_, ob_) \
+{ \
+ /* flush all the data to objects*/ \
+ Base *base_; \
+ for (base_ = sl->object_bases.first; base_; base_ = base_->next) { \
+ ob_ = base_->object; \
+ ob_->base_flag = base_->flag;
+
+#define DEG_OBJECT_ITER_END \
+ } \
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BKE_LAYER_H__ */
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 546f0d97c2b..67f7fa5e029 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -687,6 +687,13 @@ bool BKE_node_tree_iter_step(struct NodeTreeIterStore *ntreeiter,
}
/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Node Tree
+ */
+
+void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, const int layer_index);
+
/* -------------------------------------------------------------------- */
/** \name Shader Nodes
*/
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index b1e218d3e5f..c1655d3e9c6 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -35,12 +35,13 @@ extern "C" {
#include "BLI_compiler_attrs.h"
-struct Base;
+struct BaseLegacy;
struct EvaluationContext;
struct Scene;
struct Object;
struct BoundBox;
struct View3D;
+struct SceneLayer;
struct SoftBody;
struct BulletSoftBody;
struct MovieClip;
@@ -89,9 +90,9 @@ struct Object *BKE_object_add_only_object(
int type, const char *name)
ATTR_NONNULL(1) ATTR_RETURNS_NONNULL;
struct Object *BKE_object_add(
- struct Main *bmain, struct Scene *scene,
+ struct Main *bmain, struct Scene *scene, struct SceneLayer *sl,
int type, const char *name)
- ATTR_NONNULL(1, 2) ATTR_RETURNS_NONNULL;
+ ATTR_NONNULL(1, 2, 3) ATTR_RETURNS_NONNULL;
void *BKE_object_obdata_add_from_type(
struct Main *bmain,
int type, const char *name)
@@ -255,7 +256,7 @@ typedef enum eObjectSet {
struct LinkNode *BKE_object_relational_superset(struct Scene *scene, eObjectSet objectSet, eObRelationTypes includeFilter);
struct LinkNode *BKE_object_groups(struct Object *ob);
-void BKE_object_groups_clear(struct Scene *scene, struct Base *base, struct Object *object);
+void BKE_object_groups_clear(struct Object *object);
struct KDTree *BKE_object_as_kdtree(struct Object *ob, int *r_tot);
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h
index d2152950bff..53bb69aedb6 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -38,10 +38,11 @@ extern "C" {
#endif
struct AviCodecData;
-struct Base;
+struct BaseLegacy;
struct EvaluationContext;
struct Main;
struct Object;
+struct Base;
struct QuicktimeCodecData;
struct RenderData;
struct SceneRenderLayer;
@@ -61,7 +62,7 @@ struct Main;
_base; \
_base = _setlooper_base_step(&_sce_iter, _base)
-struct Base *_setlooper_base_step(struct Scene **sce_iter, struct Base *base);
+struct BaseLegacy *_setlooper_base_step(struct Scene **sce_iter, struct BaseLegacy *base);
void free_avicodecdata(struct AviCodecData *acd);
void free_qtcodecdata(struct QuicktimeCodecData *acd);
@@ -70,13 +71,15 @@ void BKE_scene_free(struct Scene *sce);
void BKE_scene_init(struct Scene *sce);
struct Scene *BKE_scene_add(struct Main *bmain, const char *name);
+void BKE_scene_remove_rigidbody_object(struct Scene *scene, struct Object *ob);
+
/* base functions */
-struct Base *BKE_scene_base_find_by_name(struct Scene *scene, const char *name);
-struct Base *BKE_scene_base_find(struct Scene *scene, struct Object *ob);
-struct Base *BKE_scene_base_add(struct Scene *sce, struct Object *ob);
-void BKE_scene_base_unlink(struct Scene *sce, struct Base *base);
+struct BaseLegacy *BKE_scene_base_find_by_name(struct Scene *scene, const char *name);
+struct BaseLegacy *BKE_scene_base_find(struct Scene *scene, struct Object *ob);
+struct BaseLegacy *BKE_scene_base_add(struct Scene *sce, struct Object *ob);
+void BKE_scene_base_unlink(struct Scene *sce, struct BaseLegacy *base);
void BKE_scene_base_deselect_all(struct Scene *sce);
-void BKE_scene_base_select(struct Scene *sce, struct Base *selbase);
+void BKE_scene_base_select(struct Scene *sce, struct BaseLegacy *selbase);
/* Scene base iteration function.
* Define struct here, so no need to bother with alloc/free it.
@@ -90,10 +93,14 @@ typedef struct SceneBaseIter {
} SceneBaseIter;
int BKE_scene_base_iter_next(struct EvaluationContext *eval_ctx, struct SceneBaseIter *iter,
- struct Scene **scene, int val, struct Base **base, struct Object **ob);
+ struct Scene **scene, int val, struct BaseLegacy **base, struct Object **ob);
void BKE_scene_base_flag_to_objects(struct Scene *scene);
void BKE_scene_base_flag_from_objects(struct Scene *scene);
+void BKE_scene_base_flag_sync_from_base(struct BaseLegacy *base);
+void BKE_scene_base_flag_sync_from_object(struct BaseLegacy *base);
+void BKE_scene_object_base_flag_sync_from_base(struct Base *base);
+void BKE_scene_object_base_flag_sync_from_object(struct Base *base);
void BKE_scene_set_background(struct Main *bmain, struct Scene *sce);
struct Scene *BKE_scene_set_name(struct Main *bmain, const char *name);
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index f3bab55b47d..6202c84f320 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -85,6 +85,7 @@ set(SRC
intern/camera.c
intern/cdderivedmesh.c
intern/cloth.c
+ intern/collection.c
intern/collision.c
intern/colortools.c
intern/constraint.c
@@ -157,6 +158,7 @@ set(SRC
intern/pbvh_bmesh.c
intern/pointcache.c
intern/property.c
+ intern/layer.c
intern/report.c
intern/rigidbody.c
intern/sca.c
@@ -214,6 +216,7 @@ set(SRC
BKE_ccg.h
BKE_cdderivedmesh.h
BKE_cloth.h
+ BKE_collection.h
BKE_collision.h
BKE_colortools.h
BKE_constraint.h
@@ -274,6 +277,7 @@ set(SRC
BKE_pbvh.h
BKE_pointcache.h
BKE_property.h
+ BKE_layer.h
BKE_report.h
BKE_rigidbody.h
BKE_sca.h
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index 2f65e71c6d2..237e4e80172 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -283,7 +283,7 @@ void animviz_get_object_motionpaths(Object *ob, ListBase *targets)
/* tweak the object ordering to trick depsgraph into making MotionPath calculations run faster */
static void motionpaths_calc_optimise_depsgraph(Scene *scene, ListBase *targets)
{
- Base *base, *baseNext;
+ BaseLegacy *base, *baseNext;
MPathTarget *mpt;
/* make sure our temp-tag isn't already in use */
@@ -321,7 +321,7 @@ static void motionpaths_calc_update_scene(Scene *scene)
BKE_scene_update_for_newframe(G.main->eval_ctx, G.main, scene, scene->lay);
}
else { /* otherwise we can optimize by restricting updates */
- Base *base, *last = NULL;
+ BaseLegacy *base, *last = NULL;
/* only stuff that moves or needs display still */
DAG_scene_update_flags(G.main, scene, scene->lay, true, false);
diff --git a/source/blender/blenkernel/intern/cachefile.c b/source/blender/blenkernel/intern/cachefile.c
index 3dce08eb756..8630e8562b0 100644
--- a/source/blender/blenkernel/intern/cachefile.c
+++ b/source/blender/blenkernel/intern/cachefile.c
@@ -205,7 +205,7 @@ float BKE_cachefile_time_offset(CacheFile *cache_file, const float time, const f
/* TODO(kevin): replace this with some depsgraph mechanism, or something similar. */
void BKE_cachefile_clean(Scene *scene, CacheFile *cache_file)
{
- for (Base *base = scene->base.first; base; base = base->next) {
+ for (BaseLegacy *base = scene->base.first; base; base = base->next) {
Object *ob = base->object;
ModifierData *md = modifiers_findByType(ob, eModifierType_MeshSequenceCache);
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index 9cb553aa27b..978204f1cf5 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -853,7 +853,7 @@ static Object *camera_multiview_advanced(Scene *scene, Object *camera, const cha
}
if (name[0] != '\0') {
- Base *base = BKE_scene_base_find_by_name(scene, name);
+ BaseLegacy *base = BKE_scene_base_find_by_name(scene, name);
if (base) {
return base->object;
}
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
new file mode 100644
index 00000000000..f374ebd1e53
--- /dev/null
+++ b/source/blender/blenkernel/intern/collection.c
@@ -0,0 +1,455 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Dalai Felinto
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/collection.c
+ * \ingroup bke
+ */
+
+#include "BLI_blenlib.h"
+#include "BLI_ghash.h"
+#include "BLI_iterator.h"
+#include "BLI_listbase.h"
+#include "BLT_translation.h"
+#include "BLI_string_utils.h"
+
+#include "BKE_collection.h"
+#include "BKE_layer.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
+#include "BKE_scene.h"
+
+#include "DNA_ID.h"
+#include "DNA_layer_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+
+#include "MEM_guardedalloc.h"
+
+/**
+ * Add a collection to a collection ListBase and syncronize all render layers
+ * The ListBase is NULL when the collection is to be added to the master collection
+ */
+SceneCollection *BKE_collection_add(Scene *scene, SceneCollection *sc_parent, const char *name)
+{
+ SceneCollection *sc_master = BKE_collection_master(scene);
+ SceneCollection *sc = MEM_callocN(sizeof(SceneCollection), "New Collection");
+
+ if (!name) {
+ name = DATA_("New Collection");
+ }
+
+ if (!sc_parent) {
+ sc_parent = sc_master;
+ }
+
+ BLI_strncpy(sc->name, name, sizeof(sc->name));
+ BLI_uniquename(&sc_master->scene_collections, sc, DATA_("Collection"), '.', offsetof(SceneCollection, name), sizeof(sc->name));
+
+ BLI_addtail(&sc_parent->scene_collections, sc);
+
+ BKE_layer_sync_new_scene_collection(scene, sc_parent, sc);
+ return sc;
+}
+
+/**
+ * Free the collection items recursively
+ */
+static void collection_free(SceneCollection *sc)
+{
+ for (LinkData *link = sc->objects.first; link; link = link->next) {
+ id_us_min(link->data);
+ }
+ BLI_freelistN(&sc->objects);
+
+ for (LinkData *link = sc->filter_objects.first; link; link = link->next) {
+ id_us_min(link->data);
+ }
+ BLI_freelistN(&sc->filter_objects);
+
+ for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
+ collection_free(nsc);
+ }
+ BLI_freelistN(&sc->scene_collections);
+}
+
+/**
+ * Unlink the collection recursively
+ * return true if unlinked
+ */
+static bool collection_remlink(SceneCollection *sc_parent, SceneCollection *sc_gone)
+{
+ for (SceneCollection *sc = sc_parent->scene_collections.first; sc; sc = sc->next)
+ {
+ if (sc == sc_gone) {
+ BLI_remlink(&sc_parent->scene_collections, sc_gone);
+ return true;
+ }
+
+ if (collection_remlink(sc, sc_gone)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * Recursively remove any instance of this SceneCollection
+ */
+static void layer_collection_remove(SceneLayer *sl, ListBase *lb, const SceneCollection *sc)
+{
+ LayerCollection *lc = lb->first;
+ while(lc) {
+ if (lc->scene_collection == sc) {
+ BKE_layer_collection_free(sl, lc);
+ BLI_remlink(lb, lc);
+
+ LayerCollection *lc_next = lc->next;
+ MEM_freeN(lc);
+ lc = lc_next;
+
+ /* only the "top-level" layer collections may have the
+ * same SceneCollection in a sibling tree.
+ */
+ if (lb != &sl->layer_collections) {
+ return;
+ }
+ }
+
+ else {
+ layer_collection_remove(sl, &lc->layer_collections, sc);
+ lc = lc->next;
+ }
+ }
+}
+
+/**
+ * Remove a collection from the scene, and syncronize all render layers
+ */
+bool BKE_collection_remove(Scene *scene, SceneCollection *sc)
+{
+ SceneCollection *sc_master = BKE_collection_master(scene);
+
+ /* the master collection cannot be removed */
+ if (sc == sc_master) {
+ return false;
+ }
+
+ /* unlink from the respective collection tree */
+ if (!collection_remlink(sc_master, sc)) {
+ BLI_assert(false);
+ }
+
+ /* clear the collection items */
+ collection_free(sc);
+
+ /* check all layers that use this collection and clear them */
+ for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
+ layer_collection_remove(sl, &sl->layer_collections, sc);
+ BKE_scene_layer_base_flag_recalculate(sl);
+ sl->active_collection = 0;
+ }
+
+ MEM_freeN(sc);
+ return true;
+}
+
+/**
+ * Returns the master collection
+ */
+SceneCollection *BKE_collection_master(Scene *scene)
+{
+ return scene->collection;
+}
+
+/**
+ * Free (or release) any data used by the master collection (does not free the master collection itself).
+ * Used only to clear the entire scene data since it's not doing re-syncing of the LayerCollection tree
+ */
+void BKE_collection_master_free(Scene *scene){
+ collection_free(BKE_collection_master(scene));
+}
+
+static void collection_object_add(Scene *scene, SceneCollection *sc, Object *ob)
+{
+ BLI_addtail(&sc->objects, BLI_genericNodeN(ob));
+ id_us_plus((ID *)ob);
+ BKE_layer_sync_object_link(scene, sc, ob);
+}
+
+/**
+ * Add object to collection
+ */
+void BKE_collection_object_add(Scene *scene, SceneCollection *sc, Object *ob)
+{
+ if (BLI_findptr(&sc->objects, ob, offsetof(LinkData, data))) {
+ /* don't add the same object twice */
+ return;
+ }
+ collection_object_add(scene, sc, ob);
+}
+
+/**
+ * Add object to all collections that reference objects is in
+ * (used to copy objects)
+ */
+void BKE_collection_object_add_from(Scene *scene, Object *ob_src, Object *ob_dst)
+{
+ SceneCollection *sc;
+ FOREACH_SCENE_COLLECTION(scene, sc)
+ {
+ if (BLI_findptr(&sc->objects, ob_src, offsetof(LinkData, data))) {
+ collection_object_add(scene, sc, ob_dst);
+ }
+ }
+ FOREACH_SCENE_COLLECTION_END
+}
+
+/**
+ * Remove object from collection
+ */
+void BKE_collection_object_remove(Main *bmain, Scene *scene, SceneCollection *sc, Object *ob, const bool free_us)
+{
+
+ LinkData *link = BLI_findptr(&sc->objects, ob, offsetof(LinkData, data));
+
+ if (link == NULL) {
+ return;
+ }
+
+ BLI_remlink(&sc->objects, link);
+ MEM_freeN(link);
+
+ TODO_LAYER_SYNC_FILTER; /* need to remove all instances of ob in scene collections -> filter_objects */
+ BKE_layer_sync_object_unlink(scene, sc, ob);
+
+ if (free_us) {
+ BKE_libblock_free_us(bmain, ob);
+ }
+ else {
+ id_us_min(&ob->id);
+ }
+}
+
+/**
+ * Remove object from all collections of scene
+ */
+void BKE_collections_object_remove(Main *bmain, Scene *scene, Object *ob, const bool free_us)
+{
+ BKE_scene_remove_rigidbody_object(scene, ob);
+
+ SceneCollection *sc;
+ FOREACH_SCENE_COLLECTION(scene, sc)
+ {
+ BKE_collection_object_remove(bmain, scene, sc, ob, free_us);
+ }
+ FOREACH_SCENE_COLLECTION_END
+}
+
+/* ---------------------------------------------------------------------- */
+/* Iteractors */
+/* scene collection iteractor */
+
+typedef struct SceneCollectionsIteratorData {
+ Scene *scene;
+ void **array;
+ int tot, cur;
+ } SceneCollectionsIteratorData;
+
+static void scene_collection_callback(SceneCollection *sc, BKE_scene_collections_Cb callback, void *data)
+{
+ callback(sc, data);
+
+ for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
+ scene_collection_callback(nsc, callback, data);
+ }
+}
+
+static void scene_collections_count(SceneCollection *UNUSED(sc), void *data)
+{
+ int *tot = data;
+ (*tot)++;
+}
+
+static void scene_collections_build_array(SceneCollection *sc, void *data)
+{
+ SceneCollection ***array = data;
+ **array = sc;
+ (*array)++;
+}
+
+static void scene_collections_array(Scene *scene, SceneCollection ***collections_array, int *tot)
+{
+ SceneCollection *sc = BKE_collection_master(scene);
+ SceneCollection **array;
+
+ *collections_array = NULL;
+ *tot = 0;
+
+ if (scene == NULL)
+ return;
+
+ scene_collection_callback(sc, scene_collections_count, tot);
+
+ if (*tot == 0)
+ return;
+
+ *collections_array = array = MEM_mallocN(sizeof(SceneCollection *) * (*tot), "SceneCollectionArray");
+ scene_collection_callback(sc, scene_collections_build_array, &array);
+}
+
+/**
+ * Only use this in non-performance critical situations
+ * (it iterates over all scene collections twice)
+ */
+void BKE_scene_collections_Iterator_begin(Iterator *iter, void *data_in)
+{
+ Scene *scene = data_in;
+ SceneCollectionsIteratorData *data = MEM_callocN(sizeof(SceneCollectionsIteratorData), __FUNCTION__);
+
+ data->scene = scene;
+ iter->data = data;
+
+ scene_collections_array(scene, (SceneCollection ***)&data->array, &data->tot);
+ BLI_assert(data->tot != 0);
+
+ data->cur = 0;
+ iter->current = data->array[data->cur];
+ iter->valid = true;
+}
+
+void BKE_scene_collections_Iterator_next(struct Iterator *iter)
+{
+ SceneCollectionsIteratorData *data = iter->data;
+
+ if (++data->cur < data->tot) {
+ iter->current = data->array[data->cur];
+ }
+ else {
+ iter->valid = false;
+ }
+}
+
+void BKE_scene_collections_Iterator_end(struct Iterator *iter)
+{
+ SceneCollectionsIteratorData *data = iter->data;
+
+ if (data) {
+ if (data->array) {
+ MEM_freeN(data->array);
+ }
+ MEM_freeN(data);
+ }
+ iter->valid = false;
+}
+
+
+/* scene objects iteractor */
+
+typedef struct SceneObjectsIteratorData {
+ GSet *visited;
+ LinkData *link;
+ Iterator scene_collection_iter;
+} SceneObjectsIteratorData;
+
+void BKE_scene_objects_Iterator_begin(Iterator *iter, void *data_in)
+{
+ Scene *scene = data_in;
+ SceneObjectsIteratorData *data = MEM_callocN(sizeof(SceneObjectsIteratorData), __FUNCTION__);
+ iter->data = data;
+
+ /* lookup list ot make sure each object is object called once */
+ data->visited = BLI_gset_ptr_new(__func__);
+
+ /* we wrap the scenecollection iterator here to go over the scene collections */
+ BKE_scene_collections_Iterator_begin(&data->scene_collection_iter, scene);
+
+ SceneCollection *sc = data->scene_collection_iter.current;
+ iter->current = sc->objects.first;
+
+ if (iter->current == NULL) {
+ BKE_scene_objects_Iterator_next(iter);
+ }
+}
+
+/**
+ * Gets the next unique object
+ */
+static LinkData *object_base_next(GSet *gs, LinkData *link)
+{
+ if (link == NULL) {
+ return NULL;
+ }
+
+ LinkData *link_next = link->next;
+ if (link_next) {
+ Object *ob = link_next->data;
+ if (!BLI_gset_haskey(gs, ob)) {
+ BLI_gset_add(gs, ob);
+ return link_next;
+ }
+ else {
+ return object_base_next(gs, link_next);
+ }
+ }
+ return NULL;
+}
+
+void BKE_scene_objects_Iterator_next(Iterator *iter)
+{
+ SceneObjectsIteratorData *data = iter->data;
+ LinkData *link = object_base_next(data->visited, data->link);
+
+ if (link) {
+ data->link = link;
+ iter->current = link->data;
+ }
+ else {
+ /* if this is the last object of this ListBase look at the next SceneCollection */
+ SceneCollection *sc;
+ BKE_scene_collections_Iterator_next(&data->scene_collection_iter);
+ do {
+ sc = data->scene_collection_iter.current;
+ /* get the first unique object of this collection */
+ LinkData *new_link = object_base_next(data->visited, sc->objects.first);
+ if (new_link) {
+ data->link = new_link;
+ iter->current = data->link->data;
+ return;
+ }
+ BKE_scene_collections_Iterator_next(&data->scene_collection_iter);
+ } while (data->scene_collection_iter.valid);
+
+ if (!data->scene_collection_iter.valid) {
+ iter->valid = false;
+ }
+ }
+}
+
+void BKE_scene_objects_Iterator_end(Iterator *iter)
+{
+ SceneObjectsIteratorData *data = iter->data;
+ if (data) {
+ BKE_scene_collections_Iterator_end(&data->scene_collection_iter);
+ BLI_gset_free(data->visited, NULL);
+ MEM_freeN(data);
+ }
+}
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index ee25be36855..b5f76240c0b 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -514,7 +514,7 @@ static void add_collision_object(Object ***objs, unsigned int *numobj, unsigned
// collision object will exclude self
Object **get_collisionobjects_ext(Scene *scene, Object *self, Group *group, int layer, unsigned int *numcollobj, unsigned int modifier_type, bool dupli)
{
- Base *base;
+ BaseLegacy *base;
Object **objs;
GroupObject *go;
unsigned int numobj= 0, maxobj= 100;
@@ -596,7 +596,7 @@ ListBase *get_collider_cache(Scene *scene, Object *self, Group *group)
}
else {
Scene *sce_iter;
- Base *base;
+ BaseLegacy *base;
/* add objects in same layer in scene */
for (SETLOOPER(scene, sce_iter, base)) {
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index 4c01bfd35f2..1cbf8cf01c8 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"
@@ -814,6 +815,14 @@ struct SpaceClip *CTX_wm_space_clip(const bContext *C)
return NULL;
}
+struct SpaceCollections *CTX_wm_space_collections(const bContext *C)
+{
+ ScrArea *sa = CTX_wm_area(C);
+ if (sa && sa->spacetype == SPACE_COLLECTIONS)
+ return sa->spacedata.first;
+ return NULL;
+}
+
void CTX_wm_manager_set(bContext *C, wmWindowManager *wm)
{
C->wm.manager = wm;
@@ -836,8 +845,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 +906,62 @@ 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 {
+ Scene *scene = CTX_data_scene(C);
+ sl = BLI_findlink(&scene->render_layers, scene->active_layer);
+ BLI_assert(sl);
+ return sl;
+ }
+}
+
+/**
+ * This is tricky. Sometimes the user overrides the render_layer
+ * but not the scene_collection. In this case what to do?
+ *
+ * If the scene_collection is linked to the SceneLayer we use it.
+ * Otherwise we fallback to the active one of the SceneLayer.
+ */
+LayerCollection *CTX_data_layer_collection(const bContext *C)
+{
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ LayerCollection *lc;
+
+ if (ctx_data_pointer_verify(C, "layer_collection", (void *)&lc)) {
+ if (BKE_scene_layer_has_collection(sl, lc->scene_collection)) {
+ return lc;
+ }
+ }
+
+ /* fallback */
+ return BKE_layer_collection_active(sl);
+}
+
+SceneCollection *CTX_data_scene_collection(const bContext *C)
+{
+ SceneCollection *sc;
+ if (ctx_data_pointer_verify(C, "scene_collection", (void *)&sc)) {
+ if (BKE_scene_layer_has_collection(CTX_data_scene_layer(C), sc)) {
+ return sc;
+ }
+ }
+
+ LayerCollection *lc = CTX_data_layer_collection(C);
+ if (lc) {
+ return lc->scene_collection;
+ }
+
+ /* fallback */
+ Scene *scene = CTX_data_scene(C);
+ return BKE_collection_master(scene);
+}
+
int CTX_data_mode_enum(const bContext *C)
{
Object *obedit = CTX_data_edit_object(C);
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index bc9871aee54..39d06a13e6e 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -488,7 +488,7 @@ static void scene_setSubframe(Scene *scene, float subframe)
static int surface_getBrushFlags(DynamicPaintSurface *surface, const Scene *scene)
{
- Base *base = NULL;
+ BaseLegacy *base = NULL;
GroupObject *go = NULL;
Object *brushObj = NULL;
ModifierData *md = NULL;
@@ -5780,7 +5780,7 @@ static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *su
* Loop through surface's target paint objects and do painting
*/
{
- Base *base = NULL;
+ BaseLegacy *base = NULL;
GroupObject *go = NULL;
Object *brushObj = NULL;
ModifierData *md = NULL;
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index fe8f5ebdca6..668d4d6c9e2 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -209,7 +209,7 @@ static void add_particles_to_effectors(ListBase **effectors, Scene *scene, Effec
ListBase *pdInitEffectors(Scene *scene, Object *ob_src, ParticleSystem *psys_src,
EffectorWeights *weights, bool for_simulation)
{
- Base *base;
+ BaseLegacy *base;
unsigned int layer= ob_src->lay;
ListBase *effectors = NULL;
diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c
index 9b011dbb003..9c81a8b49be 100644
--- a/source/blender/blenkernel/intern/group.c
+++ b/source/blender/blenkernel/intern/group.c
@@ -130,18 +130,11 @@ static bool group_object_add_internal(Group *group, Object *ob)
return true;
}
-bool BKE_group_object_add(Group *group, Object *object, Scene *scene, Base *base)
+bool BKE_group_object_add(Group *group, Object *object)
{
if (group_object_add_internal(group, object)) {
if ((object->flag & OB_FROMGROUP) == 0) {
-
- if (scene && base == NULL)
- base = BKE_scene_base_find(scene, object);
-
object->flag |= OB_FROMGROUP;
-
- if (base)
- base->flag |= OB_FROMGROUP;
}
return true;
}
@@ -208,18 +201,12 @@ bool BKE_group_object_cyclic_check(Main *bmain, Object *object, Group *group)
return group_object_cyclic_check_internal(object, group);
}
-bool BKE_group_object_unlink(Group *group, Object *object, Scene *scene, Base *base)
+bool BKE_group_object_unlink(Group *group, Object *object)
{
if (group_object_unlink_internal(group, object)) {
/* object can be NULL */
if (object && BKE_group_object_find(NULL, object) == NULL) {
- if (scene && base == NULL)
- base = BKE_scene_base_find(scene, object);
-
object->flag &= ~OB_FROMGROUP;
-
- if (base)
- base->flag &= ~OB_FROMGROUP;
}
return true;
}
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
new file mode 100644
index 00000000000..cec1d70463f
--- /dev/null
+++ b/source/blender/blenkernel/intern/layer.c
@@ -0,0 +1,684 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Dalai Felinto
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/layer.c
+ * \ingroup bke
+ */
+
+#include "BLI_listbase.h"
+#include "BLI_string.h"
+#include "BLI_string_utf8.h"
+#include "BLI_string_utils.h"
+#include "BLT_translation.h"
+
+#include "BKE_layer.h"
+#include "BKE_collection.h"
+#include "BKE_layer.h"
+#include "BKE_main.h"
+#include "BKE_node.h"
+
+#include "DNA_ID.h"
+#include "DNA_layer_types.h"
+#include "DNA_object_types.h"
+#include "DNA_node_types.h"
+#include "DNA_scene_types.h"
+
+#include "MEM_guardedalloc.h"
+
+/* prototype */
+static void layer_collection_free(SceneLayer *sl, LayerCollection *lc);
+static LayerCollection *layer_collection_add(SceneLayer *sl, ListBase *lb, SceneCollection *sc);
+static LayerCollection *find_layer_collection_by_scene_collection(LayerCollection *lc, const SceneCollection *sc);
+static void object_bases_Iterator_next(Iterator *iter, const int flag);
+
+/* RenderLayer */
+
+/**
+ * Add a new renderlayer
+ * by default, a renderlayer has the master collection
+ */
+SceneLayer *BKE_scene_layer_add(Scene *scene, const char *name)
+{
+ if (!name) {
+ name = DATA_("Render Layer");
+ }
+
+ SceneLayer *sl = MEM_callocN(sizeof(SceneLayer), "Scene Layer");
+ sl->flag |= SCENE_LAYER_RENDER;
+
+ BLI_addtail(&scene->render_layers, sl);
+
+ /* unique name */
+ BLI_strncpy_utf8(sl->name, name, sizeof(sl->name));
+ BLI_uniquename(&scene->render_layers, sl, DATA_("SceneLayer"), '.', offsetof(SceneLayer, name), sizeof(sl->name));
+
+ SceneCollection *sc = BKE_collection_master(scene);
+ layer_collection_add(sl, &sl->layer_collections, sc);
+
+ return sl;
+}
+
+bool BKE_scene_layer_remove(Main *bmain, Scene *scene, SceneLayer *sl)
+{
+ const int act = BLI_findindex(&scene->render_layers, sl);
+
+ if (act == -1) {
+ return false;
+ }
+ else if ( (scene->render_layers.first == scene->render_layers.last) &&
+ (scene->render_layers.first == sl))
+ {
+ /* ensure 1 layer is kept */
+ return false;
+ }
+
+ BLI_remlink(&scene->render_layers, sl);
+
+ BKE_scene_layer_free(sl);
+ MEM_freeN(sl);
+
+ scene->active_layer = 0;
+ /* TODO WORKSPACE: set active_layer to 0 */
+
+ for (Scene *sce = bmain->scene.first; sce; sce = sce->id.next) {
+ if (sce->nodetree) {
+ BKE_nodetree_remove_layer_n(sce->nodetree, scene, act);
+ }
+ }
+
+ return true;
+}
+
+/**
+ * Free (or release) any data used by this SceneLayer (does not free the SceneLayer itself).
+ */
+void BKE_scene_layer_free(SceneLayer *sl)
+{
+ sl->basact = NULL;
+ BLI_freelistN(&sl->object_bases);
+
+ for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
+ layer_collection_free(NULL, lc);
+ }
+ BLI_freelistN(&sl->layer_collections);
+}
+
+/**
+ * Set the render engine of a renderlayer
+ */
+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 (Base *base = sl->object_bases.first; base; base = base->next) {
+ if ((base->flag & BASE_SELECTED) != 0) {
+ base->object->flag |= tag;
+ }
+ else {
+ base->object->flag &= ~tag;
+ }
+ }
+}
+
+static bool find_scene_collection_in_scene_collections(ListBase *lb, const LayerCollection *lc)
+{
+ for (LayerCollection *lcn = lb->first; lcn; lcn = lcn->next) {
+ if (lcn == lc) {
+ return true;
+ }
+ if (find_scene_collection_in_scene_collections(&lcn->layer_collections, lc)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * Find the SceneLayer a LayerCollection belongs to
+ */
+SceneLayer *BKE_scene_layer_find_from_collection(Scene *scene, LayerCollection *lc)
+{
+ for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
+ if (find_scene_collection_in_scene_collections(&sl->layer_collections, lc)) {
+ return sl;
+ }
+ }
+ return NULL;
+}
+
+/* Base */
+
+Base *BKE_scene_layer_base_find(SceneLayer *sl, Object *ob)
+{
+ return BLI_findptr(&sl->object_bases, ob, offsetof(Base, object));
+}
+
+void BKE_scene_layer_base_deselect_all(SceneLayer *sl)
+{
+ Base *base;
+
+ for (base = sl->object_bases.first; base; base = base->next) {
+ base->flag &= ~BASE_SELECTED;
+ }
+}
+
+void BKE_scene_layer_base_select(struct SceneLayer *sl, Base *selbase)
+{
+ sl->basact = selbase;
+ if ((selbase->flag & BASE_SELECTABLED) != 0) {
+ selbase->flag |= BASE_SELECTED;
+ }
+}
+
+static void scene_layer_object_base_unref(SceneLayer* sl, Base *base)
+{
+ base->refcount--;
+
+ /* It only exists in the RenderLayer */
+ if (base->refcount == 0) {
+ if (sl->basact == base) {
+ sl->basact = NULL;
+ }
+
+ BLI_remlink(&sl->object_bases, base);
+ MEM_freeN(base);
+ }
+}
+
+static void layer_collection_base_flag_recalculate(LayerCollection *lc, const bool tree_is_visible, const bool tree_is_selectable)
+{
+ bool is_visible = tree_is_visible && ((lc->flag & COLLECTION_VISIBLE) != 0);
+ /* an object can only be selected if it's visible */
+ bool is_selectable = tree_is_selectable && is_visible && ((lc->flag & COLLECTION_SELECTABLE) != 0);
+
+ for (LinkData *link = lc->object_bases.first; link; link = link->next) {
+ Base *base = link->data;
+
+ if (is_visible) {
+ base->flag |= BASE_VISIBLED;
+ }
+ else {
+ base->flag &= ~BASE_VISIBLED;
+ }
+
+ if (is_selectable) {
+ base->flag |= BASE_SELECTABLED;
+ }
+ else {
+ base->flag &= ~BASE_SELECTABLED;
+ }
+ }
+
+ for (LayerCollection *lcn = lc->layer_collections.first; lcn; lcn = lcn->next) {
+ layer_collection_base_flag_recalculate(lcn, is_visible, is_selectable);
+ }
+}
+
+/**
+ * Re-evaluate the ObjectBase flags for SceneLayer
+ */
+void BKE_scene_layer_base_flag_recalculate(SceneLayer *sl)
+{
+ for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
+ layer_collection_base_flag_recalculate(lc, true, true);
+ }
+
+ /* if base is not selectabled, clear select */
+ for (Base *base = sl->object_bases.first; base; base = base->next) {
+ if ((base->flag & BASE_SELECTABLED) == 0) {
+ base->flag &= ~BASE_SELECTED;
+ }
+ }
+}
+
+/**
+ * Return the base if existent, or create it if necessary
+ * Always bump the refcount
+ */
+static Base *object_base_add(SceneLayer *sl, Object *ob)
+{
+ Base *base;
+ base = BKE_scene_layer_base_find(sl, ob);
+
+ if (base == NULL) {
+ base = MEM_callocN(sizeof(Base), "Object Base");
+
+ /* do not bump user count, leave it for SceneCollections */
+ base->object = ob;
+ BLI_addtail(&sl->object_bases, base);
+ }
+ base->refcount++;
+ return base;
+}
+
+/* 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
+ */
+static void layer_collection_free(SceneLayer *sl, LayerCollection *lc)
+{
+ if (sl) {
+ for (LinkData *link = lc->object_bases.first; link; link = link->next) {
+ scene_layer_object_base_unref(sl, link->data);
+ }
+ }
+
+ BLI_freelistN(&lc->object_bases);
+ BLI_freelistN(&lc->overrides);
+
+ for (LayerCollection *nlc = lc->layer_collections.first; nlc; nlc = nlc->next) {
+ layer_collection_free(sl, nlc);
+ }
+ BLI_freelistN(&lc->layer_collections);
+}
+
+/**
+ * Free (or release) LayerCollection from SceneLayer
+ * (does not free the LayerCollection itself).
+ */
+void BKE_layer_collection_free(SceneLayer *sl, LayerCollection *lc)
+{
+ layer_collection_free(sl, lc);
+}
+
+/* LayerCollection */
+
+/**
+ * Recursively get the collection for a given index
+ */
+static LayerCollection *collection_from_index(ListBase *lb, const int number, int *i)
+{
+ for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
+ if (*i == number) {
+ return lc;
+ }
+
+ (*i)++;
+
+ LayerCollection *lc_nested = collection_from_index(&lc->layer_collections, number, i);
+ if (lc_nested) {
+ return lc_nested;
+ }
+ }
+ return NULL;
+}
+
+/**
+ * Get the active collection
+ */
+LayerCollection *BKE_layer_collection_active(SceneLayer *sl)
+{
+ int i = 0;
+ return collection_from_index(&sl->layer_collections, sl->active_collection, &i);
+}
+
+/**
+ * Recursively get the count of collections
+ */
+static int collection_count(ListBase *lb)
+{
+ int i = 0;
+ for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
+ i += collection_count(&lc->layer_collections) + 1;
+ }
+ return i;
+}
+
+/**
+ * Get the total number of collections
+ * (including all the nested collections)
+ */
+int BKE_layer_collection_count(SceneLayer *sl)
+{
+ return collection_count(&sl->layer_collections);
+}
+
+/**
+ * Recursively get the index for a given collection
+ */
+static int index_from_collection(ListBase *lb, LayerCollection *lc, int *i)
+{
+ for (LayerCollection *lcol = lb->first; lcol; lcol = lcol->next) {
+ if (lcol == lc) {
+ return *i;
+ }
+
+ (*i)++;
+
+ int i_nested = index_from_collection(&lcol->layer_collections, lc, i);
+ if (i_nested != -1) {
+ return i_nested;
+ }
+ }
+ return -1;
+}
+
+/**
+ * Return -1 if not found
+ */
+int BKE_layer_collection_findindex(SceneLayer *sl, LayerCollection *lc)
+{
+ int i = 0;
+ return index_from_collection(&sl->layer_collections, lc, &i);
+}
+
+/**
+ * Link a collection to a renderlayer
+ * The collection needs to be created separately
+ */
+LayerCollection *BKE_collection_link(SceneLayer *sl, SceneCollection *sc)
+{
+ LayerCollection *lc = layer_collection_add(sl, &sl->layer_collections, sc);
+ sl->active_collection = BKE_layer_collection_findindex(sl, lc);
+ return lc;
+}
+
+/**
+ * Unlink a collection base from a renderlayer
+ * The corresponding collection is not removed from the master collection
+ */
+void BKE_collection_unlink(SceneLayer *sl, LayerCollection *lc)
+{
+ BKE_layer_collection_free(sl, lc);
+ BKE_scene_layer_base_flag_recalculate(sl);
+
+ BLI_remlink(&sl->layer_collections, lc);
+ MEM_freeN(lc);
+ sl->active_collection = 0;
+}
+
+static void layer_collection_object_add(SceneLayer *sl, LayerCollection *lc, Object *ob)
+{
+ Base *base = object_base_add(sl, ob);
+
+ /* only add an object once - prevent SceneCollection->objects and
+ * SceneCollection->filter_objects to add the same object */
+
+ if (BLI_findptr(&lc->object_bases, base, offsetof(LinkData, data))) {
+ return;
+ }
+
+ BLI_addtail(&lc->object_bases, BLI_genericNodeN(base));
+
+ BKE_scene_layer_base_flag_recalculate(sl);
+}
+
+static void layer_collection_object_remove(SceneLayer *sl, LayerCollection *lc, Object *ob)
+{
+ Base *base;
+ base = BKE_scene_layer_base_find(sl, ob);
+
+ LinkData *link = BLI_findptr(&lc->object_bases, base, offsetof(LinkData, data));
+ BLI_remlink(&lc->object_bases, link);
+ MEM_freeN(link);
+
+ scene_layer_object_base_unref(sl, base);
+}
+
+static void layer_collection_objects_populate(SceneLayer *sl, LayerCollection *lc, ListBase *objects)
+{
+ for (LinkData *link = objects->first; link; link = link->next) {
+ layer_collection_object_add(sl, lc, link->data);
+ }
+}
+
+static void layer_collection_populate(SceneLayer *sl, LayerCollection *lc, SceneCollection *sc)
+{
+ layer_collection_objects_populate(sl, lc, &sc->objects);
+ layer_collection_objects_populate(sl, lc, &sc->filter_objects);
+
+ for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
+ layer_collection_add(sl, &lc->layer_collections, nsc);
+ }
+}
+
+static LayerCollection *layer_collection_add(SceneLayer *sl, ListBase *lb, SceneCollection *sc)
+{
+ LayerCollection *lc = MEM_callocN(sizeof(LayerCollection), "Collection Base");
+ BLI_addtail(lb, lc);
+
+ lc->scene_collection = sc;
+ lc->flag = COLLECTION_VISIBLE + COLLECTION_SELECTABLE + COLLECTION_FOLDED;
+
+ layer_collection_populate(sl, lc, sc);
+ return lc;
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+/**
+ * See if render layer has the scene collection linked directly, or indirectly (nested)
+ */
+bool BKE_scene_layer_has_collection(struct SceneLayer *sl, struct SceneCollection *sc)
+{
+ for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
+ if (find_layer_collection_by_scene_collection(lc, sc) != NULL) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * See if the object is in any of the scene layers of the scene
+ */
+bool BKE_scene_has_object(Scene *scene, Object *ob)
+{
+ for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
+ Base *base = BKE_scene_layer_base_find(sl, ob);
+ if (base) {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+/* ---------------------------------------------------------------------- */
+/* Syncing */
+
+static LayerCollection *find_layer_collection_by_scene_collection(LayerCollection *lc, const SceneCollection *sc)
+{
+ if (lc->scene_collection == sc) {
+ return lc;
+ }
+
+ for (LayerCollection *nlc = lc->layer_collections.first; nlc; nlc = nlc->next) {
+ LayerCollection *found = find_layer_collection_by_scene_collection(nlc, sc);
+ if (found) {
+ return found;
+ }
+ }
+ return NULL;
+}
+
+/**
+ * Add a new LayerCollection for all the SceneLayers that have sc_parent
+ */
+void BKE_layer_sync_new_scene_collection(Scene *scene, const SceneCollection *sc_parent, SceneCollection *sc)
+{
+ for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
+ for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
+ LayerCollection *lc_parent = find_layer_collection_by_scene_collection(lc, sc_parent);
+ if (lc_parent) {
+ layer_collection_add(sl, &lc_parent->layer_collections, sc);
+ }
+ }
+ }
+}
+
+/**
+ * Add a corresponding ObjectBase to all the equivalent LayerCollection
+ */
+void BKE_layer_sync_object_link(Scene *scene, SceneCollection *sc, Object *ob)
+{
+ for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
+ for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
+ LayerCollection *found = find_layer_collection_by_scene_collection(lc, sc);
+ if (found) {
+ layer_collection_object_add(sl, found, ob);
+ }
+ }
+ }
+}
+
+/**
+ * Remove the equivalent object base to all layers that have this collection
+ * also remove all reference to ob in the filter_objects
+ */
+void BKE_layer_sync_object_unlink(Scene *scene, SceneCollection *sc, Object *ob)
+{
+ for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
+ for (LayerCollection *lc = sl->layer_collections.first; lc; lc = lc->next) {
+ LayerCollection *found = find_layer_collection_by_scene_collection(lc, sc);
+ if (found) {
+ layer_collection_object_remove(sl, found, ob);
+ }
+ }
+ BKE_scene_layer_base_flag_recalculate(sl);
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+/* Override */
+
+/**
+ * Add a new datablock override
+ */
+void BKE_collection_override_datablock_add(LayerCollection *UNUSED(lc), const char *UNUSED(data_path), ID *UNUSED(id))
+{
+ TODO_LAYER_OVERRIDE;
+}
+
+/* ---------------------------------------------------------------------- */
+/* Iterators */
+
+static void object_bases_Iterator_begin(Iterator *iter, void *data_in, const int flag)
+{
+ SceneLayer *sl = data_in;
+ Base *base = sl->object_bases.first;
+
+ /* when there are no objects */
+ if (base == NULL) {
+ iter->valid = false;
+ return;
+ }
+
+ iter->valid = true;
+ iter->data = base;
+
+ if ((base->flag & flag) == 0) {
+ object_bases_Iterator_next(iter, flag);
+ }
+ else {
+ iter->current = base;
+ }
+}
+
+static void object_bases_Iterator_next(Iterator *iter, const int flag)
+{
+ Base *base = ((Base *)iter->data)->next;
+
+ while (base) {
+ if ((base->flag & flag) != 0) {
+ iter->current = base;
+ iter->data = base;
+ return;
+ }
+ base = base->next;
+ }
+
+ iter->current = NULL;
+ iter->valid = false;
+}
+
+static void objects_Iterator_begin(Iterator *iter, void *data_in, const int flag)
+{
+ object_bases_Iterator_begin(iter, data_in, flag);
+
+ if (iter->valid) {
+ iter->current = ((Base *)iter->current)->object;
+ }
+}
+
+static void objects_Iterator_next(Iterator *iter, const int flag)
+{
+ object_bases_Iterator_next(iter, flag);
+
+ if (iter->valid) {
+ iter->current = ((Base *)iter->current)->object;
+ }
+}
+
+void BKE_selected_objects_Iterator_begin(Iterator *iter, void *data_in)
+{
+ objects_Iterator_begin(iter, data_in, BASE_SELECTED);
+}
+
+void BKE_selected_objects_Iterator_next(Iterator *iter)
+{
+ objects_Iterator_next(iter, BASE_SELECTED);
+}
+
+void BKE_selected_objects_Iterator_end(Iterator *UNUSED(iter))
+{
+ /* do nothing */
+}
+
+void BKE_visible_objects_Iterator_begin(Iterator *iter, void *data_in)
+{
+ objects_Iterator_begin(iter, data_in, BASE_VISIBLED);
+}
+
+void BKE_visible_objects_Iterator_next(Iterator *iter)
+{
+ objects_Iterator_next(iter, BASE_VISIBLED);
+}
+
+void BKE_visible_objects_Iterator_end(Iterator *UNUSED(iter))
+{
+ /* do nothing */
+}
+
+void BKE_visible_bases_Iterator_begin(Iterator *iter, void *data_in)
+{
+ object_bases_Iterator_begin(iter, data_in, BASE_VISIBLED);
+}
+
+void BKE_visible_bases_Iterator_next(Iterator *iter)
+{
+ object_bases_Iterator_next(iter, BASE_VISIBLED);
+}
+
+void BKE_visible_bases_Iterator_end(Iterator *UNUSED(iter))
+{
+ /* do nothing */
+}
diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c
index 9685f1f5af6..a071b3202be 100644
--- a/source/blender/blenkernel/intern/library_query.c
+++ b/source/blender/blenkernel/intern/library_query.c
@@ -68,6 +68,7 @@
#include "BLI_linklist_stack.h"
#include "BKE_animsys.h"
+#include "BKE_collection.h"
#include "BKE_constraint.h"
#include "BKE_fcurve.h"
#include "BKE_library.h"
@@ -354,7 +355,7 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
Scene *scene = (Scene *) id;
ToolSettings *toolsett = scene->toolsettings;
SceneRenderLayer *srl;
- Base *base;
+ BaseLegacy *legacy_base;
CALLBACK_INVOKE(scene->camera, IDWALK_CB_NOP);
CALLBACK_INVOKE(scene->world, IDWALK_CB_USER);
@@ -411,8 +412,28 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
CALLBACK_INVOKE(scene->gpd, IDWALK_CB_USER);
- for (base = scene->base.first; base; base = base->next) {
- CALLBACK_INVOKE(base->object, IDWALK_CB_USER);
+ for (legacy_base = scene->base.first; legacy_base; legacy_base = legacy_base->next) {
+ CALLBACK_INVOKE(legacy_base->object, IDWALK_CB_USER);
+ }
+
+ SceneCollection *sc;
+ FOREACH_SCENE_COLLECTION(scene, sc)
+ {
+ for (LinkData *link = sc->objects.first; link; link = link->next) {
+ CALLBACK_INVOKE_ID(link->data, IDWALK_CB_USER);
+ }
+
+ for (LinkData *link = sc->filter_objects.first; link; link = link->next) {
+ CALLBACK_INVOKE_ID(link->data, IDWALK_CB_USER);
+ }
+ }
+ FOREACH_SCENE_COLLECTION_END
+
+ SceneLayer *sl;
+ for (sl = scene->render_layers.first; sl; sl = sl->next) {
+ for (Base *base = sl->object_bases.first; base; base = base->next) {
+ CALLBACK_INVOKE(base->object, IDWALK_NOP);
+ }
}
for (TimeMarker *marker = scene->markers.first; marker; marker = marker->next) {
diff --git a/source/blender/blenkernel/intern/library_remap.c b/source/blender/blenkernel/intern/library_remap.c
index a408b498f18..9946d1cc81f 100644
--- a/source/blender/blenkernel/intern/library_remap.c
+++ b/source/blender/blenkernel/intern/library_remap.c
@@ -71,6 +71,7 @@
#include "BKE_brush.h"
#include "BKE_camera.h"
#include "BKE_cachefile.h"
+#include "BKE_collection.h"
#include "BKE_curve.h"
#include "BKE_depsgraph.h"
#include "BKE_fcurve.h"
@@ -242,7 +243,7 @@ static int foreach_libblock_remap_callback(void *user_data, ID *id_self, ID **id
/* Some reamapping unfortunately require extra and/or specific handling, tackle those here. */
static void libblock_remap_data_preprocess_scene_base_unlink(
- IDRemap *r_id_remap_data, Scene *sce, Base *base, const bool skip_indirect, const bool is_indirect)
+ IDRemap *r_id_remap_data, Scene *sce, BaseLegacy *base, const bool skip_indirect, const bool is_indirect)
{
if (skip_indirect && is_indirect) {
r_id_remap_data->skipped_indirect++;
@@ -258,6 +259,22 @@ static void libblock_remap_data_preprocess_scene_base_unlink(
}
}
+/* Some remapping unfortunately require extra and/or specific handling, tackle those here. */
+static void libblock_remap_data_preprocess_scene_object_unlink(
+ IDRemap *r_id_remap_data, Scene *sce, Object *ob, const bool skip_indirect, const bool is_indirect)
+{
+ if (skip_indirect && is_indirect) {
+ r_id_remap_data->skipped_indirect++;
+ r_id_remap_data->skipped_refcounted++;
+ }
+ else {
+ BKE_collections_object_remove(r_id_remap_data->bmain, sce, ob, false);
+ if (!is_indirect) {
+ r_id_remap_data->status |= ID_REMAP_IS_LINKED_DIRECT;
+ }
+ }
+}
+
static void libblock_remap_data_preprocess(IDRemap *r_id_remap_data)
{
switch (GS(r_id_remap_data->id->name)) {
@@ -272,7 +289,16 @@ static void libblock_remap_data_preprocess(IDRemap *r_id_remap_data)
/* In case we are unlinking... */
if (!r_id_remap_data->old_id) {
/* ... everything from scene. */
- Base *base, *base_next;
+ Object *ob_iter;
+ FOREACH_SCENE_OBJECT(sce, ob_iter)
+ {
+ libblock_remap_data_preprocess_scene_object_unlink(
+ r_id_remap_data, sce, ob_iter, skip_indirect, is_indirect);
+ }
+ FOREACH_SCENE_OBJECT_END
+
+
+ BaseLegacy *base, *base_next;
for (base = sce->base.first; base; base = base_next) {
base_next = base->next;
libblock_remap_data_preprocess_scene_base_unlink(
@@ -282,8 +308,11 @@ static void libblock_remap_data_preprocess(IDRemap *r_id_remap_data)
else if (GS(r_id_remap_data->old_id->name) == ID_OB) {
/* ... a specific object from scene. */
Object *old_ob = (Object *)r_id_remap_data->old_id;
- Base *base = BKE_scene_base_find(sce, old_ob);
+ libblock_remap_data_preprocess_scene_object_unlink(
+ r_id_remap_data, sce, old_ob, skip_indirect, is_indirect);
+
+ BaseLegacy *base = BKE_scene_base_find(sce, old_ob);
if (base) {
libblock_remap_data_preprocess_scene_base_unlink(
r_id_remap_data, sce, base, skip_indirect, is_indirect);
@@ -329,7 +358,7 @@ static void libblock_remap_data_postprocess_object_fromgroup_update(Main *bmain,
}
if (new_ob == NULL) { /* We need to remove NULL-ified groupobjects... */
for (Group *group = bmain->group.first; group; group = group->id.next) {
- BKE_group_object_unlink(group, NULL, NULL, NULL);
+ BKE_group_object_unlink(group, NULL);
}
}
else {
@@ -342,23 +371,17 @@ static void libblock_remap_data_postprocess_group_scene_unlink(Main *UNUSED(bmai
{
/* Note that here we assume no object has no base (i.e. all objects are assumed instanced
* in one scene...). */
- for (Base *base = sce->base.first; base; base = base->next) {
- if (base->flag & OB_FROMGROUP) {
- Object *ob = base->object;
-
- if (ob->flag & OB_FROMGROUP) {
- Group *grp = BKE_group_object_find(NULL, ob);
-
- /* Unlinked group (old_id) is still in bmain... */
- if (grp && (&grp->id == old_id || grp->id.us == 0)) {
- grp = BKE_group_object_find(grp, ob);
- }
- if (!grp) {
- ob->flag &= ~OB_FROMGROUP;
- }
+ for (BaseLegacy *base = sce->base.first; base; base = base->next) {
+ Object *ob = base->object;
+ if (ob->flag & OB_FROMGROUP) {
+ Group *grp = BKE_group_object_find(NULL, ob);
+
+ /* Unlinked group (old_id) is still in bmain... */
+ if (grp && (&grp->id == old_id || grp->id.us == 0)) {
+ grp = BKE_group_object_find(grp, ob);
}
- if (!(ob->flag & OB_FROMGROUP)) {
- base->flag &= ~OB_FROMGROUP;
+ if (!grp) {
+ ob->flag &= ~OB_FROMGROUP;
}
}
}
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c
index 97033a9555d..2632acea58b 100644
--- a/source/blender/blenkernel/intern/mball.c
+++ b/source/blender/blenkernel/intern/mball.c
@@ -316,7 +316,7 @@ bool BKE_mball_is_basis_for(Object *ob1, Object *ob2)
void BKE_mball_properties_copy(Scene *scene, Object *active_object)
{
Scene *sce_iter = scene;
- Base *base;
+ BaseLegacy *base;
Object *ob;
MetaBall *active_mball = (MetaBall *)active_object->data;
int basisnr, obnr;
@@ -359,27 +359,25 @@ void BKE_mball_properties_copy(Scene *scene, Object *active_object)
*/
Object *BKE_mball_basis_find(Scene *scene, Object *basis)
{
- Scene *sce_iter = scene;
- Base *base;
- Object *ob, *bob = basis;
+ Object *bob = basis;
int basisnr, obnr;
char basisname[MAX_ID_NAME], obname[MAX_ID_NAME];
- SceneBaseIter iter;
- EvaluationContext *eval_ctx = G.main->eval_ctx;
BLI_split_name_num(basisname, &basisnr, basis->id.name + 2, '.');
- BKE_scene_base_iter_next(eval_ctx, &iter, &sce_iter, 0, NULL, NULL);
- while (BKE_scene_base_iter_next(eval_ctx, &iter, &sce_iter, 1, &base, &ob)) {
- if ((ob->type == OB_MBALL) && !(base->flag & OB_FROMDUPLI)) {
- if (ob != bob) {
- BLI_split_name_num(obname, &obnr, ob->id.name + 2, '.');
-
- /* object ob has to be in same "group" ... it means, that it has to have same base of its name */
- if (STREQ(obname, basisname)) {
- if (obnr < basisnr) {
- basis = ob;
- basisnr = obnr;
+ for (SceneLayer *sl = scene->render_layers.first; sl; sl = sl->next) {
+ for (Base *base = sl->object_bases.first; base; base = base->next) {
+ Object *ob = base->object;
+ if ((ob->type == OB_MBALL) && !(base->flag & OB_FROMDUPLI)) {
+ if (ob != bob) {
+ BLI_split_name_num(obname, &obnr, ob->id.name + 2, '.');
+
+ /* object ob has to be in same "group" ... it means, that it has to have same base of its name */
+ if (STREQ(obname, basisname)) {
+ if (obnr < basisnr) {
+ basis = ob;
+ basisnr = obnr;
+ }
}
}
}
diff --git a/source/blender/blenkernel/intern/mball_tessellate.c b/source/blender/blenkernel/intern/mball_tessellate.c
index 5c0b09f0ff0..144a885ffd4 100644
--- a/source/blender/blenkernel/intern/mball_tessellate.c
+++ b/source/blender/blenkernel/intern/mball_tessellate.c
@@ -1080,7 +1080,7 @@ static void polygonize(PROCESS *process)
static void init_meta(EvaluationContext *eval_ctx, PROCESS *process, Scene *scene, Object *ob)
{
Scene *sce_iter = scene;
- Base *base;
+ BaseLegacy *base;
Object *bob;
MetaBall *mb;
const MetaElem *ml;
@@ -1102,7 +1102,7 @@ static void init_meta(EvaluationContext *eval_ctx, PROCESS *process, Scene *scen
zero_size = 0;
ml = NULL;
- if (bob == ob && (base->flag & OB_FROMDUPLI) == 0) {
+ if (bob == ob && (base->flag_legacy & OB_FROMDUPLI) == 0) {
mb = ob->data;
if (mb->editelems) ml = mb->editelems->first;
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 3f3b4896653..05422a01dbf 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -3776,3 +3776,20 @@ bool BKE_node_tree_iter_step(struct NodeTreeIterStore *ntreeiter,
return true;
}
+
+/* -------------------------------------------------------------------- */
+/* NodeTree kernel functions */
+
+void BKE_nodetree_remove_layer_n(bNodeTree *ntree, Scene *scene, const int layer_index)
+{
+ for (bNode *node = ntree->nodes.first; node; node = node->next) {
+ if (node->type == CMP_NODE_R_LAYERS && (Scene *)node->id == scene) {
+ if (node->custom1 == layer_index) {
+ node->custom1 = 0;
+ }
+ else if (node->custom1 > layer_index) {
+ node->custom1--;
+ }
+ }
+ }
+}
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index ff8be5892e9..08cb9e57ab4 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -91,6 +91,7 @@
#include "BKE_icons.h"
#include "BKE_key.h"
#include "BKE_lamp.h"
+#include "BKE_layer.h"
#include "BKE_lattice.h"
#include "BKE_library.h"
#include "BKE_library_query.h"
@@ -153,7 +154,7 @@ void BKE_object_workob_clear(Object *workob)
void BKE_object_update_base_layer(struct Scene *scene, Object *ob)
{
- Base *base = scene->base.first;
+ BaseLegacy *base = scene->base.first;
while (base) {
if (base->object == ob) base->lay = ob->lay;
@@ -677,23 +678,25 @@ Object *BKE_object_add_only_object(Main *bmain, int type, const char *name)
/* general add: to scene, with layer from area and default name */
/* creates minimum required data, but without vertices etc. */
Object *BKE_object_add(
- Main *bmain, Scene *scene,
+ Main *bmain, Scene *scene, SceneLayer *sl,
int type, const char *name)
{
Object *ob;
Base *base;
+ LayerCollection *lc;
ob = BKE_object_add_only_object(bmain, type, name);
ob->data = BKE_object_obdata_add_from_type(bmain, type, name);
- ob->lay = scene->lay;
-
- base = BKE_scene_base_add(scene, ob);
- BKE_scene_base_deselect_all(scene);
- BKE_scene_base_select(scene, base);
- DAG_id_tag_update_ex(bmain, &ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
+ lc = BKE_layer_collection_active(sl);
+ BKE_collection_object_add(scene, lc->scene_collection, ob);
+
+ base = BKE_scene_layer_base_find(sl, ob);
+ BKE_scene_layer_base_deselect_all(sl);
+ BKE_scene_layer_base_select(sl, base);
+ DAG_id_tag_update_ex(bmain, &ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
return ob;
}
@@ -2542,11 +2545,11 @@ void BKE_scene_foreach_display_point(
Scene *scene, View3D *v3d, const short flag,
void (*func_cb)(const float[3], void *), void *user_data)
{
- Base *base;
+ BaseLegacy *base;
Object *ob;
for (base = FIRSTBASE; base; base = base->next) {
- if (BASE_VISIBLE_BGMODE(v3d, scene, base) && (base->flag & flag) == flag) {
+ if (BASE_VISIBLE_BGMODE(v3d, scene, base) && (base->flag_legacy & flag) == flag) {
ob = base->object;
if ((ob->transflag & OB_DUPLI) == 0) {
@@ -3351,7 +3354,7 @@ LinkNode *BKE_object_relational_superset(struct Scene *scene, eObjectSet objectS
{
LinkNode *links = NULL;
- Base *base;
+ BaseLegacy *base;
/* Remove markers from all objects */
for (base = scene->base.first; base; base = base->next) {
@@ -3395,7 +3398,7 @@ LinkNode *BKE_object_relational_superset(struct Scene *scene, eObjectSet objectS
/* child relationship */
if (includeFilter & (OB_REL_CHILDREN | OB_REL_CHILDREN_RECURSIVE)) {
- Base *local_base;
+ BaseLegacy *local_base;
for (local_base = scene->base.first; local_base; local_base = local_base->next) {
if (BASE_EDITABLE_BGMODE(((View3D *)NULL), scene, local_base)) {
@@ -3441,18 +3444,11 @@ struct LinkNode *BKE_object_groups(Object *ob)
return group_linknode;
}
-void BKE_object_groups_clear(Scene *scene, Base *base, Object *object)
+void BKE_object_groups_clear(Object *ob)
{
Group *group = NULL;
-
- BLI_assert((base == NULL) || (base->object == object));
-
- if (scene && base == NULL) {
- base = BKE_scene_base_find(scene, object);
- }
-
- while ((group = BKE_group_object_find(group, base->object))) {
- BKE_group_object_unlink(group, object, scene, base);
+ while ((group = BKE_group_object_find(group, ob))) {
+ BKE_group_object_unlink(group, ob);
}
}
diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c
index e3b801b3193..26af1c48afb 100644
--- a/source/blender/blenkernel/intern/object_dupli.c
+++ b/source/blender/blenkernel/intern/object_dupli.c
@@ -241,7 +241,7 @@ static void make_child_duplis(const DupliContext *ctx, void *userdata, MakeChild
else {
unsigned int lay = ctx->scene->lay;
int baseid = 0;
- Base *base;
+ BaseLegacy *base;
for (base = ctx->scene->base.first; base; base = base->next, baseid++) {
Object *ob = base->object;
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 943dc781246..8531c7c9df9 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -2896,7 +2896,7 @@ static void psys_update_path_cache(ParticleSimulationData *sim, float cfra, cons
ParticleSystem *psys = sim->psys;
ParticleSettings *part = psys->part;
ParticleEditSettings *pset = &sim->scene->toolsettings->particle;
- Base *base;
+ BaseLegacy *base;
int distr=0, alloc=0, skip=0;
if ((psys->part->childtype && psys->totchild != psys_get_tot_child(sim->scene, psys)) || psys->recalc&PSYS_RECALC_RESET)
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 30eb8dcb287..c3f2107c5af 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -3541,7 +3541,7 @@ void BKE_ptcache_bake(PTCacheBaker *baker)
Main *bmain = baker->main;
Scene *scene = baker->scene;
Scene *sce_iter; /* SETLOOPER macro only */
- Base *base;
+ BaseLegacy *base;
ListBase pidlist;
PTCacheID *pid = &baker->pid;
PointCache *cache = NULL;
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index a1338b4ea10..d47982f96eb 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -67,6 +67,7 @@
#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_cachefile.h"
+#include "BKE_collection.h"
#include "BKE_colortools.h"
#include "BKE_depsgraph.h"
#include "BKE_editmesh.h"
@@ -78,6 +79,7 @@
#include "BKE_icons.h"
#include "BKE_idprop.h"
#include "BKE_image.h"
+#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_library_remap.h"
#include "BKE_linestyle.h"
@@ -154,13 +156,66 @@ 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;
SceneRenderLayer *srl, *new_srl;
FreestyleLineSet *lineset;
ToolSettings *ts;
- Base *base, *obase;
+ BaseLegacy *legacy_base, *olegacy_base;
if (type == SCE_COPY_EMPTY) {
ListBase rl, rv;
@@ -214,14 +269,14 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
BKE_libblock_relink_ex(bmain, scen->nodetree, &sce->id, &scen->id, false);
}
- obase = sce->base.first;
- base = scen->base.first;
- while (base) {
- id_us_plus(&base->object->id);
- if (obase == sce->basact) scen->basact = base;
+ olegacy_base = sce->base.first;
+ legacy_base = scen->base.first;
+ while (legacy_base) {
+ id_us_plus(&legacy_base->object->id);
+ if (olegacy_base == sce->basact) scen->basact = legacy_base;
- obase = obase->next;
- base = base->next;
+ olegacy_base = olegacy_base->next;
+ legacy_base = legacy_base->next;
}
/* copy action and remove animation used by sequencer */
@@ -244,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 (Base *base = new_sl->object_bases.first; base; base = base->next) {
+ if (base->object == active_ob) {
+ new_sl->basact = base;
+ break;
+ }
+ }
+ }
+ new_sl = new_sl->next;
+ }
}
/* copy color management settings */
@@ -471,6 +556,16 @@ void BKE_scene_free(Scene *sce)
BKE_previewimg_free(&sce->preview);
curvemapping_free_data(&sce->r.mblur_shutter_curve);
+
+ for (SceneLayer *sl = sce->render_layers.first; sl; sl = sl->next) {
+ BKE_scene_layer_free(sl);
+ }
+ BLI_freelistN(&sce->render_layers);
+
+ /* Master Collection */
+ BKE_collection_master_free(sce);
+ MEM_freeN(sce->collection);
+ sce->collection = NULL;
}
void BKE_scene_init(Scene *sce)
@@ -820,6 +915,12 @@ void BKE_scene_init(Scene *sce)
sce->toolsettings->gpencil_v2d_align = GP_PROJECT_VIEWSPACE;
sce->toolsettings->gpencil_seq_align = GP_PROJECT_VIEWSPACE;
sce->toolsettings->gpencil_ima_align = GP_PROJECT_VIEWSPACE;
+
+ /* Master Collection */
+ sce->collection = MEM_callocN(sizeof(SceneCollection), "Master Collection");
+ BLI_strncpy(sce->collection->name, "Master Collection", sizeof(sce->collection->name));
+
+ BKE_scene_layer_add(sce, "Render Layer");
}
Scene *BKE_scene_add(Main *bmain, const char *name)
@@ -835,9 +936,9 @@ Scene *BKE_scene_add(Main *bmain, const char *name)
return sce;
}
-Base *BKE_scene_base_find_by_name(struct Scene *scene, const char *name)
+BaseLegacy *BKE_scene_base_find_by_name(struct Scene *scene, const char *name)
{
- Base *base;
+ BaseLegacy *base;
for (base = scene->base.first; base; base = base->next) {
if (STREQ(base->object->id.name + 2, name)) {
@@ -848,9 +949,9 @@ Base *BKE_scene_base_find_by_name(struct Scene *scene, const char *name)
return base;
}
-Base *BKE_scene_base_find(Scene *scene, Object *ob)
+BaseLegacy *BKE_scene_base_find(Scene *scene, Object *ob)
{
- return BLI_findptr(&scene->base, ob, offsetof(Base, object));
+ return BLI_findptr(&scene->base, ob, offsetof(BaseLegacy, object));
}
/**
@@ -861,11 +962,10 @@ Base *BKE_scene_base_find(Scene *scene, Object *ob)
void BKE_scene_set_background(Main *bmain, Scene *scene)
{
Scene *sce;
- Base *base;
+ BaseLegacy *base;
Object *ob;
Group *group;
GroupObject *go;
- int flag;
/* check for cyclic sets, for reading old files but also for definite security (py?) */
BKE_scene_validate_setscene(bmain, scene);
@@ -897,13 +997,7 @@ void BKE_scene_set_background(Main *bmain, Scene *scene)
ob->lay = base->lay;
/* group patch... */
- base->flag &= ~(OB_FROMGROUP);
- flag = ob->flag & (OB_FROMGROUP);
- base->flag |= flag;
-
- /* not too nice... for recovering objects with lost data */
- //if (ob->pose == NULL) base->flag &= ~OB_POSEMODE;
- ob->flag = base->flag;
+ BKE_scene_base_flag_sync_from_base(base);
}
/* no full animation update, this to enable render code to work (render code calls own animation updates) */
}
@@ -924,7 +1018,7 @@ Scene *BKE_scene_set_name(Main *bmain, const char *name)
/* Used by metaballs, return *all* objects (including duplis) existing in the scene (including scene's sets) */
int BKE_scene_base_iter_next(EvaluationContext *eval_ctx, SceneBaseIter *iter,
- Scene **scene, int val, Base **base, Object **ob)
+ Scene **scene, int val, BaseLegacy **base, Object **ob)
{
bool run_again = true;
@@ -1006,7 +1100,7 @@ int BKE_scene_base_iter_next(EvaluationContext *eval_ctx, SceneBaseIter *iter,
}
/* handle dupli's */
if (iter->dupob) {
- (*base)->flag |= OB_FROMDUPLI;
+ (*base)->flag_legacy |= OB_FROMDUPLI;
*ob = iter->dupob->ob;
iter->phase = F_DUPLI;
@@ -1025,7 +1119,7 @@ int BKE_scene_base_iter_next(EvaluationContext *eval_ctx, SceneBaseIter *iter,
}
else if (iter->phase == F_DUPLI) {
iter->phase = F_SCENE;
- (*base)->flag &= ~OB_FROMDUPLI;
+ (*base)->flag_legacy &= ~OB_FROMDUPLI;
if (iter->dupli_refob) {
/* Restore last object's real matrix. */
@@ -1052,7 +1146,7 @@ int BKE_scene_base_iter_next(EvaluationContext *eval_ctx, SceneBaseIter *iter,
Object *BKE_scene_camera_find(Scene *sc)
{
- Base *base;
+ BaseLegacy *base;
for (base = sc->base.first; base; base = base->next)
if (base->object->type == OB_CAMERA)
@@ -1154,28 +1248,32 @@ char *BKE_scene_find_last_marker_name(Scene *scene, int frame)
return best_marker ? best_marker->name : NULL;
}
+void BKE_scene_remove_rigidbody_object(Scene *scene, Object *ob)
+{
+ /* remove rigid body constraint from world before removing object */
+ if (ob->rigidbody_constraint)
+ BKE_rigidbody_remove_constraint(scene, ob);
+ /* remove rigid body object from world before removing object */
+ if (ob->rigidbody_object)
+ BKE_rigidbody_remove_object(scene, ob);
+}
-Base *BKE_scene_base_add(Scene *sce, Object *ob)
+BaseLegacy *BKE_scene_base_add(Scene *sce, Object *ob)
{
- Base *b = MEM_callocN(sizeof(*b), __func__);
+ BaseLegacy *b = MEM_callocN(sizeof(*b), __func__);
BLI_addhead(&sce->base, b);
b->object = ob;
- b->flag = ob->flag;
+ b->flag_legacy = ob->flag;
b->lay = ob->lay;
return b;
}
-void BKE_scene_base_unlink(Scene *sce, Base *base)
+void BKE_scene_base_unlink(Scene *sce, BaseLegacy *base)
{
- /* remove rigid body constraint from world before removing object */
- if (base->object->rigidbody_constraint)
- BKE_rigidbody_remove_constraint(sce, base->object);
- /* remove rigid body object from world before removing object */
- if (base->object->rigidbody_object)
- BKE_rigidbody_remove_object(sce, base->object);
-
+ BKE_scene_remove_rigidbody_object(sce, base->object);
+
BLI_remlink(&sce->base, base);
if (sce->basact == base)
sce->basact = NULL;
@@ -1183,18 +1281,20 @@ void BKE_scene_base_unlink(Scene *sce, Base *base)
void BKE_scene_base_deselect_all(Scene *sce)
{
- Base *b;
+ BaseLegacy *b;
for (b = sce->base.first; b; b = b->next) {
- b->flag &= ~SELECT;
- b->object->flag = b->flag;
+ b->flag_legacy &= ~SELECT;
+ int flag = b->object->flag & (OB_FROMGROUP);
+ b->object->flag = b->flag_legacy;
+ b->object->flag |= flag;
}
}
-void BKE_scene_base_select(Scene *sce, Base *selbase)
+void BKE_scene_base_select(Scene *sce, BaseLegacy *selbase)
{
- selbase->flag |= SELECT;
- selbase->object->flag = selbase->flag;
+ selbase->flag_legacy |= SELECT;
+ selbase->object->flag = selbase->flag_legacy;
sce->basact = selbase;
}
@@ -1492,15 +1592,7 @@ bool BKE_scene_remove_render_layer(Main *bmain, Scene *scene, SceneRenderLayer *
for (sce = bmain->scene.first; sce; sce = sce->id.next) {
if (sce->nodetree) {
- bNode *node;
- for (node = sce->nodetree->nodes.first; node; node = node->next) {
- if (node->type == CMP_NODE_R_LAYERS && (Scene *)node->id == scene) {
- if (node->custom1 == act)
- node->custom1 = 0;
- else if (node->custom1 > act)
- node->custom1--;
- }
- }
+ BKE_nodetree_remove_layer_n(sce->nodetree, scene, act);
}
}
@@ -1588,7 +1680,7 @@ float get_render_aosss_error(const RenderData *r, float error)
}
/* helper function for the SETLOOPER macro */
-Base *_setlooper_base_step(Scene **sce_iter, Base *base)
+BaseLegacy *_setlooper_base_step(Scene **sce_iter, BaseLegacy *base)
{
if (base && base->next) {
/* common case, step to the next */
@@ -1596,12 +1688,12 @@ Base *_setlooper_base_step(Scene **sce_iter, Base *base)
}
else if (base == NULL && (*sce_iter)->base.first) {
/* first time looping, return the scenes first base */
- return (Base *)(*sce_iter)->base.first;
+ return (BaseLegacy *)(*sce_iter)->base.first;
}
else {
/* reached the end, get the next base in the set */
while ((*sce_iter = (*sce_iter)->set)) {
- base = (Base *)(*sce_iter)->base.first;
+ base = (BaseLegacy *)(*sce_iter)->base.first;
if (base) {
return base;
}
@@ -1648,24 +1740,56 @@ bool BKE_scene_uses_blender_game(const Scene *scene)
void BKE_scene_base_flag_to_objects(struct Scene *scene)
{
- Base *base = scene->base.first;
+ BaseLegacy *base = scene->base.first;
while (base) {
- base->object->flag = base->flag;
+ BKE_scene_base_flag_sync_from_base(base);
base = base->next;
}
}
void BKE_scene_base_flag_from_objects(struct Scene *scene)
{
- Base *base = scene->base.first;
+ BaseLegacy *base = scene->base.first;
while (base) {
- base->flag = base->object->flag;
+ BKE_scene_base_flag_sync_from_object(base);
base = base->next;
}
}
+void BKE_scene_base_flag_sync_from_base(BaseLegacy *base)
+{
+ Object *ob = base->object;
+
+ /* keep the object only flags untouched */
+ int flag = ob->flag & OB_FROMGROUP;
+
+ ob->flag = base->flag_legacy;
+ ob->flag |= flag;
+}
+
+void BKE_scene_base_flag_sync_from_object(BaseLegacy *base)
+{
+ base->flag_legacy = base->object->flag;
+}
+
+void BKE_scene_object_base_flag_sync_from_base(Base *base)
+{
+ Object *ob = base->object;
+
+ /* keep the object only flags untouched */
+ int flag = ob->flag & OB_FROMGROUP;
+
+ ob->flag = base->flag;
+ ob->flag |= flag;
+}
+
+void BKE_scene_object_base_flag_sync_from_object(Base *base)
+{
+ base->flag = base->object->flag;
+}
+
void BKE_scene_disable_color_management(Scene *scene)
{
ColorManagedDisplaySettings *display_settings = &scene->display_settings;
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index d0ef5cfc092..f1ce69d3945 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -698,7 +698,7 @@ static float calc_voxel_transp(float *result, float *input, int res[3], int *pix
static int get_lamp(Scene *scene, float *light)
{
- Base *base_tmp = NULL;
+ BaseLegacy *base_tmp = NULL;
int found_lamp = 0;
// try to find a lamp, preferably local
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index 660107eb2e6..e7df1d810c9 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -530,7 +530,7 @@ static void ccd_build_deflector_hash(Scene *scene, Group *group, Object *vertexo
}
}
else {
- for (Base *base = scene->base.first; base; base = base->next) {
+ for (BaseLegacy *base = scene->base.first; base; base = base->next) {
/*Only proceed for mesh object in same layer */
if (base->object->type == OB_MESH && (base->lay & vertexowner->lay)) {
ob= base->object;
@@ -576,7 +576,7 @@ static void ccd_update_deflector_hash(Scene *scene, Group *group, Object *vertex
}
}
else {
- for (Base *base = scene->base.first; base; base = base->next) {
+ for (BaseLegacy *base = scene->base.first; base; base = base->next) {
/*Only proceed for mesh object in same layer */
if (base->object->type == OB_MESH && (base->lay & vertexowner->lay)) {
ob= base->object;
@@ -986,7 +986,7 @@ static bool are_there_deflectors(Scene *scene, Group *group, unsigned int layer)
}
}
else {
- for (Base *base = scene->base.first; base; base= base->next) {
+ for (BaseLegacy *base = scene->base.first; base; base= base->next) {
if ( (base->lay & layer) && base->object->pd) {
if (base->object->pd->deflect)
return 1;
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index 22288127119..e10f9207896 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -782,7 +782,7 @@ void BKE_sound_read_waveform(bSound *sound, short *stop)
void BKE_sound_update_scene(Main *bmain, struct Scene *scene)
{
Object *ob;
- Base *base;
+ BaseLegacy *base;
NlaTrack *track;
NlaStrip *strip;
Speaker *speaker;