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>2017-12-01 16:24:21 +0300
committerDalai Felinto <dfelinto@gmail.com>2017-12-01 19:15:54 +0300
commitbe9e469ead227aee8d4c29b98a125cf599c5c8bb (patch)
tree381ee3e58a94495a923c575bb8185899d84ab4bc /source
parente8c15e0ed15f8369d0d0f706b4953fb64e357902 (diff)
Groups and collection: initial integration
Since we are ditching layers from Blender (2.8) we need a replacement to control groups visibility. This commit introduces collections as the building blocks for groups, allowing users to control visibility as well as overrides for groups. Features ======== * Groups now have collections This way you can change the visibility of a collection inside a group, and add overrides which are part of the group and are prioritized over other overrides. * Outliner Groups can inspect their collections, change visibility, and add/remove members. To change an override of a group collection, you need to select an instance of the group, and then you can choose "group" in the collection properties editor to edit this group active collection instead of the view layer one. * Dupli groups overrides We can now have multiple instances of the same group with an original "override" and different overrides depending on the collection the instanced object is part of. Technical ========= * Layers We use the same api for groups and scene as much as possible. Reviewers: sergey (depsgraph), mont29 (read/write and user count) Differential Revision: https://developer.blender.org/D2892
Diffstat (limited to 'source')
-rw-r--r--source/blender/alembic/intern/alembic_capi.cc4
-rw-r--r--source/blender/blenkernel/BKE_collection.h31
-rw-r--r--source/blender/blenkernel/BKE_group.h21
-rw-r--r--source/blender/blenkernel/BKE_layer.h28
-rw-r--r--source/blender/blenkernel/intern/collection.c206
-rw-r--r--source/blender/blenkernel/intern/collision.c35
-rw-r--r--source/blender/blenkernel/intern/context.c2
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c36
-rw-r--r--source/blender/blenkernel/intern/effect.c49
-rw-r--r--source/blender/blenkernel/intern/group.c142
-rw-r--r--source/blender/blenkernel/intern/layer.c264
-rw-r--r--source/blender/blenkernel/intern/library_query.c8
-rw-r--r--source/blender/blenkernel/intern/library_remap.c2
-rw-r--r--source/blender/blenkernel/intern/object.c2
-rw-r--r--source/blender/blenkernel/intern/object_dupli.c123
-rw-r--r--source/blender/blenkernel/intern/particle.c23
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c148
-rw-r--r--source/blender/blenkernel/intern/scene.c136
-rw-r--r--source/blender/blenkernel/intern/softbody.c76
-rw-r--r--source/blender/blenloader/intern/readfile.c159
-rw-r--r--source/blender/blenloader/intern/versioning_280.c51
-rw-r--r--source/blender/blenloader/intern/writefile.c60
-rw-r--r--source/blender/collada/DocumentImporter.cpp2
-rw-r--r--source/blender/collada/SceneExporter.cpp12
-rw-r--r--source/blender/collada/collada_utils.cpp2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc10
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.h8
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_layer_collection.cc18
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc24
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.h8
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_layer_collection.cc15
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc2
-rw-r--r--source/blender/depsgraph/intern/depsgraph_query_iter.cc7
-rw-r--r--source/blender/editors/gpencil/gpencil_convert.c2
-rw-r--r--source/blender/editors/object/object_add.c2
-rw-r--r--source/blender/editors/object/object_relations.c36
-rw-r--r--source/blender/editors/space_info/info_stats.c49
-rw-r--r--source/blender/editors/space_outliner/outliner_collections.c29
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c40
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.c8
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h5
-rw-r--r--source/blender/editors/space_outliner/outliner_ops.c17
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c28
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c72
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c86
-rw-r--r--source/blender/editors/space_view3d/view3d_ops.c7
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp4
-rw-r--r--source/blender/makesdna/DNA_group_types.h7
-rw-r--r--source/blender/makesdna/DNA_layer_types.h8
-rw-r--r--source/blender/makesdna/DNA_object_types.h1
-rw-r--r--source/blender/makesrna/RNA_enum_types.h2
-rw-r--r--source/blender/makesrna/intern/rna_group.c18
-rw-r--r--source/blender/makesrna/intern/rna_layer.c88
-rw-r--r--source/blender/render/intern/source/convertblender.c67
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp6
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp10
57 files changed, 1371 insertions, 937 deletions
diff --git a/source/blender/alembic/intern/alembic_capi.cc b/source/blender/alembic/intern/alembic_capi.cc
index 7003547ead2..5e93779b5f6 100644
--- a/source/blender/alembic/intern/alembic_capi.cc
+++ b/source/blender/alembic/intern/alembic_capi.cc
@@ -845,7 +845,7 @@ static void import_endjob(void *user_data)
if (lc == NULL) {
BLI_assert(BLI_listbase_count_ex(&view_layer->layer_collections, 1) == 0);
/* when there is no collection linked to this ViewLayer, create one */
- SceneCollection *sc = BKE_collection_add(data->scene, NULL, NULL);
+ SceneCollection *sc = BKE_collection_add(&data->scene->id, NULL, COLLECTION_TYPE_NONE, NULL);
lc = BKE_collection_link(view_layer, sc);
}
@@ -853,7 +853,7 @@ static void import_endjob(void *user_data)
Object *ob = (*iter)->object();
ob->lay = data->scene->lay;
- BKE_collection_object_add(data->scene, lc->scene_collection, ob);
+ BKE_collection_object_add(&data->scene->id, lc->scene_collection, ob);
base = BKE_view_layer_base_find(view_layer, ob);
BKE_view_layer_base_select(view_layer, base);
diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h
index 52985d3ec56..c305a05ddd0 100644
--- a/source/blender/blenkernel/BKE_collection.h
+++ b/source/blender/blenkernel/BKE_collection.h
@@ -37,28 +37,33 @@ extern "C" {
struct Base;
struct BLI_Iterator;
+struct Group;
+struct ID;
+struct LayerCollection;
struct Main;
struct Object;
struct Scene;
struct SceneCollection;
-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(const struct Scene *scene);
+struct SceneCollection *BKE_collection_add(
+ struct ID *owner_id, struct SceneCollection *sc_parent, const int type, const char *name);
+bool BKE_collection_remove(struct ID *owner_id, struct SceneCollection *sc);
+void BKE_collection_copy_data(struct SceneCollection *sc_dst, struct SceneCollection *sc_src, const int flag);
+struct SceneCollection *BKE_collection_master(const struct ID *owner_id);
void BKE_collection_rename(const struct Scene *scene, struct SceneCollection *sc, const char *name);
-void BKE_collection_master_free(struct Scene *scene, const bool do_id_user);
-void BKE_collection_object_add(const struct Scene *scene, struct SceneCollection *sc, struct Object *object);
+void BKE_collection_master_free(struct ID *owner_id, const bool do_id_user);
+bool BKE_collection_object_add(const struct ID *owner_id, 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, const 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);
-void BKE_collection_object_move(const struct Scene *scene, struct SceneCollection *sc_dst, struct SceneCollection *sc_src, struct Object *ob);
+bool BKE_collection_object_remove(struct Main *bmain, struct ID *owner_id, struct SceneCollection *sc, struct Object *object, const bool free_us);
+bool BKE_collections_object_remove(struct Main *bmain, struct ID *owner_id, struct Object *object, const bool free_us);
+void BKE_collection_object_move(struct ID *owner_id, struct SceneCollection *sc_dst, struct SceneCollection *sc_src, struct Object *ob);
void BKE_collection_reinsert_after(const struct Scene *scene, struct SceneCollection *sc_reinsert, struct SceneCollection *sc_after);
void BKE_collection_reinsert_into(struct SceneCollection *sc_reinsert, struct SceneCollection *sc_into);
-bool BKE_collection_move_above(const struct Scene *scene, struct SceneCollection *sc_dst, struct SceneCollection *sc_src);
-bool BKE_collection_move_below(const struct Scene *scene, struct SceneCollection *sc_dst, struct SceneCollection *sc_src);
-bool BKE_collection_move_into(const struct Scene *scene, struct SceneCollection *sc_dst, struct SceneCollection *sc_src);
+bool BKE_collection_move_above(const struct ID *owner_id, struct SceneCollection *sc_dst, struct SceneCollection *sc_src);
+bool BKE_collection_move_below(const struct ID *owner_id, struct SceneCollection *sc_dst, struct SceneCollection *sc_src);
+bool BKE_collection_move_into(const struct ID *owner_id, struct SceneCollection *sc_dst, struct SceneCollection *sc_src);
typedef void (*BKE_scene_objects_Cb)(struct Object *ob, void *data);
typedef void (*BKE_scene_collections_Cb)(struct SceneCollection *ob, void *data);
@@ -75,11 +80,11 @@ void BKE_scene_objects_iterator_begin(struct BLI_Iterator *iter, void *data_in);
void BKE_scene_objects_iterator_next(struct BLI_Iterator *iter);
void BKE_scene_objects_iterator_end(struct BLI_Iterator *iter);
-#define FOREACH_SCENE_COLLECTION(scene, _instance) \
+#define FOREACH_SCENE_COLLECTION(_id, _instance) \
ITER_BEGIN(BKE_scene_collections_iterator_begin, \
BKE_scene_collections_iterator_next, \
BKE_scene_collections_iterator_end, \
- scene, SceneCollection *, _instance)
+ _id, SceneCollection *, _instance)
#define FOREACH_SCENE_COLLECTION_END \
ITER_END
diff --git a/source/blender/blenkernel/BKE_group.h b/source/blender/blenkernel/BKE_group.h
index 1d35e6ab9fc..ac436876dc4 100644
--- a/source/blender/blenkernel/BKE_group.h
+++ b/source/blender/blenkernel/BKE_group.h
@@ -41,6 +41,7 @@ struct Object;
struct Scene;
void BKE_group_free(struct Group *group);
+void BKE_group_init(struct Group *group);
struct Group *BKE_group_add(struct Main *bmain, const char *name);
void BKE_group_copy_data(struct Main *bmain, struct Group *group_dst, const struct Group *group_src, const int flag);
struct Group *BKE_group_copy(struct Main *bmain, const struct Group *group);
@@ -54,4 +55,24 @@ bool BKE_group_is_animated(struct Group *group, struct Object *parent);
void BKE_group_handle_recalc_and_update(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *parent, struct Group *group);
+#define FOREACH_GROUP_BASE(_group, _base) \
+ for (Base *_base = (Base *)(_group)->view_layer->object_bases.first; \
+ _base; \
+ _base = _base->next) \
+ {
+
+#define FOREACH_GROUP_BASE_END \
+ }
+
+#define FOREACH_GROUP_OBJECT(_group, _object) \
+ for (Base *_base = (Base *)(_group)->view_layer->object_bases.first; \
+ _base; \
+ _base = _base->next) \
+ { \
+ Object *_object = _base->object; \
+ BLI_assert(_object != NULL);
+
+#define FOREACH_GROUP_OBJECT_END \
+ }
+
#endif /* __BKE_GROUP_H__ */
diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
index ecad9c21f99..55337fa5ed0 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -42,6 +42,7 @@ extern "C" {
struct Base;
struct EvaluationContext;
+struct Group;
struct ID;
struct IDProperty;
struct LayerCollection;
@@ -59,6 +60,7 @@ void BKE_layer_exit(void);
struct ViewLayer *BKE_view_layer_from_scene_get(const struct Scene *scene);
struct ViewLayer *BKE_view_layer_from_workspace_get(const struct Scene *scene, const struct WorkSpace *workspace);
struct ViewLayer *BKE_view_layer_add(struct Scene *scene, const char *name);
+struct ViewLayer *BKE_view_layer_group_add(struct Group *group);
/* DEPRECATED */
struct ViewLayer *BKE_view_layer_context_active_PLACEHOLDER(const struct Scene *scene);
@@ -68,12 +70,16 @@ void BKE_view_layer_free(struct ViewLayer *view_layer);
void BKE_view_layer_selected_objects_tag(struct ViewLayer *view_layer, const int tag);
struct Object *BKE_view_layer_camera_find(struct ViewLayer *view_layer);
-struct ViewLayer *BKE_view_layer_find_from_collection(const struct Scene *scene, struct LayerCollection *lc);
+struct ViewLayer *BKE_view_layer_first_from_id(const struct ID *owner_id);
+struct ViewLayer *BKE_view_layer_find_from_collection(const struct ID *owner_id, struct LayerCollection *lc);
struct Base *BKE_view_layer_base_find(struct ViewLayer *view_layer, struct Object *ob);
-struct Base *BKE_view_layer_base_find_by_name(struct ViewLayer *view_layer, struct Object *ob);
void BKE_view_layer_base_deselect_all(struct ViewLayer *view_layer);
void BKE_view_layer_base_select(struct ViewLayer *view_layer, struct Base *selbase);
+void BKE_view_layer_copy_data(struct ViewLayer *view_layer_dst, struct ViewLayer *view_layer_src,
+ struct SceneCollection* mc_dst, struct SceneCollection* mc_src,
+ const int flag);
+
void BKE_layer_collection_free(struct ViewLayer *view_layer, struct LayerCollection *lc);
struct LayerCollection *BKE_layer_collection_get_active(struct ViewLayer *view_layer);
@@ -84,11 +90,11 @@ int BKE_layer_collection_count(struct ViewLayer *view_layer);
struct LayerCollection *BKE_layer_collection_from_index(struct ViewLayer *view_layer, const int index);
int BKE_layer_collection_findindex(struct ViewLayer *view_layer, const struct LayerCollection *lc);
-bool BKE_layer_collection_move_above(const struct Scene *scene, struct LayerCollection *lc_dst, struct LayerCollection *lc_src);
-bool BKE_layer_collection_move_below(const struct Scene *scene, struct LayerCollection *lc_dst, struct LayerCollection *lc_src);
-bool BKE_layer_collection_move_into(const struct Scene *scene, struct LayerCollection *lc_dst, struct LayerCollection *lc_src);
+bool BKE_layer_collection_move_above(const struct ID *owner_id, struct LayerCollection *lc_dst, struct LayerCollection *lc_src);
+bool BKE_layer_collection_move_below(const struct ID *owner_id, struct LayerCollection *lc_dst, struct LayerCollection *lc_src);
+bool BKE_layer_collection_move_into(const struct ID *owner_id, struct LayerCollection *lc_dst, struct LayerCollection *lc_src);
-void BKE_layer_collection_resync(const struct Scene *scene, const struct SceneCollection *sc);
+void BKE_layer_collection_resync(const struct ID *owner_id, const struct SceneCollection *sc);
struct LayerCollection *BKE_collection_link(struct ViewLayer *view_layer, struct SceneCollection *sc);
@@ -102,13 +108,13 @@ 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(const struct Scene *scene, struct SceneCollection *sc, struct Object *ob);
-void BKE_layer_sync_object_unlink(const struct Scene *scene, struct SceneCollection *sc, struct Object *ob);
+void BKE_layer_sync_new_scene_collection(struct ID *owner_id, const struct SceneCollection *sc_parent, struct SceneCollection *sc);
+void BKE_layer_sync_object_link(const struct ID *owner_id, struct SceneCollection *sc, struct Object *ob);
+void BKE_layer_sync_object_unlink(const struct ID *owner_id, struct SceneCollection *sc, struct Object *ob);
/* override */
-void BKE_override_view_layer_datablock_add(struct ViewLayer *view_layer, int id_type, const char *data_path, const struct ID *id);
+void BKE_override_view_layer_datablock_add(struct ViewLayer *view_layer, int id_type, const char *data_path, const struct ID *owner_id);
void BKE_override_view_layer_int_add(struct ViewLayer *view_layer, int id_type, const char *data_path, const int value);
void BKE_override_layer_collection_boolean_add(struct LayerCollection *layer_collection, int id_type, const char *data_path, const bool value);
@@ -152,7 +158,7 @@ void BKE_collection_engine_property_value_set_bool(struct IDProperty *props, con
/* evaluation */
void BKE_layer_eval_layer_collection_pre(const struct EvaluationContext *eval_ctx,
- struct Scene *scene,
+ struct ID *owner_id,
struct ViewLayer *view_layer);
void BKE_layer_eval_layer_collection(const struct EvaluationContext *eval_ctx,
struct LayerCollection *layer_collection,
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index 25305b1d25a..aa5b9e7eb25 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -40,6 +40,7 @@
#include "BKE_main.h"
#include "BKE_scene.h"
+#include "DNA_group_types.h"
#include "DNA_ID.h"
#include "DNA_layer_types.h"
#include "DNA_object_types.h"
@@ -47,15 +48,28 @@
#include "MEM_guardedalloc.h"
+static SceneCollection *collection_master_from_id(const ID *owner_id)
+{
+ switch (GS(owner_id->name)) {
+ case ID_SCE:
+ return ((Scene *)owner_id)->collection;
+ case ID_GR:
+ return ((Group *)owner_id)->collection;
+ default:
+ BLI_assert(!"ID doesn't support collections");
+ return NULL;
+ }
+}
/**
* 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 *BKE_collection_add(ID *owner_id, SceneCollection *sc_parent, const int type, const char *name)
{
- SceneCollection *sc_master = BKE_collection_master(scene);
+ SceneCollection *sc_master = collection_master_from_id(owner_id);
SceneCollection *sc = MEM_callocN(sizeof(SceneCollection), "New Collection");
+ sc->type = type;
if (!name) {
name = DATA_("New Collection");
@@ -65,10 +79,10 @@ SceneCollection *BKE_collection_add(Scene *scene, SceneCollection *sc_parent, co
sc_parent = sc_master;
}
- BKE_collection_rename(scene, sc, name);
+ BKE_collection_rename((Scene *)owner_id, sc, name);
BLI_addtail(&sc_parent->scene_collections, sc);
- BKE_layer_sync_new_scene_collection(scene, sc_parent, sc);
+ BKE_layer_sync_new_scene_collection(owner_id, sc_parent, sc);
return sc;
}
@@ -147,25 +161,25 @@ static void layer_collection_remove(ViewLayer *view_layer, ListBase *lb, const S
/**
* Remove a collection from the scene, and syncronize all render layers
*/
-bool BKE_collection_remove(Scene *scene, SceneCollection *sc)
+bool BKE_collection_remove(ID *owner_id, SceneCollection *sc)
{
- SceneCollection *sc_master = BKE_collection_master(scene);
+ SceneCollection *sc_master = collection_master_from_id(owner_id);
- /* the master collection cannot be removed */
+ /* The master collection cannot be removed. */
if (sc == sc_master) {
return false;
}
- /* unlink from the respective collection tree */
+ /* Unlink from the respective collection tree. */
if (!collection_remlink(sc_master, sc)) {
BLI_assert(false);
}
- /* clear the collection items */
+ /* Clear the collection items. */
collection_free(sc, true);
/* check all layers that use this collection and clear them */
- for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
+ for (ViewLayer *view_layer = BKE_view_layer_first_from_id(owner_id); view_layer; view_layer = view_layer->next) {
layer_collection_remove(view_layer, &view_layer->layer_collections, sc);
view_layer->active_collection = 0;
}
@@ -175,11 +189,54 @@ bool BKE_collection_remove(Scene *scene, SceneCollection *sc)
}
/**
- * Returns the master collection
+ * Copy SceneCollection tree but keep pointing to the same objects
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_collection_copy_data(SceneCollection *sc_dst, SceneCollection *sc_src, const int flag)
+{
+ BLI_duplicatelist(&sc_dst->objects, &sc_src->objects);
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ for (LinkData *link = sc_dst->objects.first; link; link = link->next) {
+ id_us_plus(link->data);
+ }
+ }
+
+ BLI_duplicatelist(&sc_dst->filter_objects, &sc_src->filter_objects);
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ for (LinkData *link = sc_dst->filter_objects.first; link; link = link->next) {
+ id_us_plus(link->data);
+ }
+ }
+
+ BLI_duplicatelist(&sc_dst->scene_collections, &sc_src->scene_collections);
+ for (SceneCollection *nsc_src = sc_src->scene_collections.first, *nsc_dst = sc_dst->scene_collections.first;
+ nsc_src;
+ nsc_src = nsc_src->next, nsc_dst = nsc_dst->next)
+ {
+ BKE_collection_copy_data(nsc_dst, nsc_src, flag);
+ }
+}
+
+static SceneCollection *master_collection_from_id(const ID *owner_id)
+{
+ switch (GS(owner_id->name)) {
+ case ID_SCE:
+ return ((const Scene *)owner_id)->collection;
+ case ID_GR:
+ return ((const Group *)owner_id)->collection;
+ default:
+ BLI_assert(!"ID doesn't support scene collection");
+ return NULL;
+ }
+}
+
+/**
+ * Returns the master collection of the scene or group
*/
-SceneCollection *BKE_collection_master(const Scene *scene)
+SceneCollection *BKE_collection_master(const ID *owner_id)
{
- return scene->collection;
+ return master_collection_from_id(owner_id);
}
struct UniqueNameCheckData {
@@ -207,41 +264,58 @@ static bool collection_unique_name_check(void *arg, const char *name)
return false;
}
-void BKE_collection_rename(const Scene *scene, SceneCollection *sc, const char *name)
+static void collection_rename(const ID *owner_id, SceneCollection *sc, const char *name)
{
- SceneCollection *sc_master = BKE_collection_master(scene);
+ SceneCollection *sc_master = collection_master_from_id(owner_id);
struct UniqueNameCheckData data = {.lb = &sc_master->scene_collections, .lookup_sc = sc};
BLI_strncpy(sc->name, name, sizeof(sc->name));
BLI_uniquename_cb(collection_unique_name_check, &data, DATA_("Collection"), '.', sc->name, sizeof(sc->name));
}
+void BKE_collection_rename(const Scene *scene, SceneCollection *sc, const char *name)
+{
+ collection_rename(&scene->id, sc, name);
+}
+
/**
* 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
+ * Used only to clear the entire scene or group data since it's not doing re-syncing of the LayerCollection tree
*/
-void BKE_collection_master_free(Scene *scene, const bool do_id_user)
+void BKE_collection_master_free(ID *owner_id, const bool do_id_user)
{
- collection_free(BKE_collection_master(scene), do_id_user);
+ collection_free(BKE_collection_master(owner_id), do_id_user);
}
-static void collection_object_add(const Scene *scene, SceneCollection *sc, Object *ob)
+static void collection_object_add(const ID *owner_id, SceneCollection *sc, Object *ob)
{
BLI_addtail(&sc->objects, BLI_genericNodeN(ob));
- id_us_plus((ID *)ob);
- BKE_layer_sync_object_link(scene, sc, ob);
+
+ if (GS(owner_id->name) == ID_SCE) {
+ id_us_plus((ID *)ob);
+ }
+ else {
+ BLI_assert(GS(owner_id->name) == ID_GR);
+ if ((ob->flag & OB_FROMGROUP) == 0) {
+ ob->flag |= OB_FROMGROUP;
+ }
+ }
+
+ BKE_layer_sync_object_link(owner_id, sc, ob);
}
/**
* Add object to collection
*/
-void BKE_collection_object_add(const Scene *scene, SceneCollection *sc, Object *ob)
+bool BKE_collection_object_add(const ID *owner_id, SceneCollection *sc, Object *ob)
{
if (BLI_findptr(&sc->objects, ob, offsetof(LinkData, data))) {
/* don't add the same object twice */
- return;
+ return false;
}
- collection_object_add(scene, sc, ob);
+
+ collection_object_add(owner_id, sc, ob);
+ return true;
}
/**
@@ -253,7 +327,7 @@ void BKE_collection_object_add_from(Scene *scene, Object *ob_src, Object *ob_dst
FOREACH_SCENE_COLLECTION(scene, sc)
{
if (BLI_findptr(&sc->objects, ob_src, offsetof(LinkData, data))) {
- collection_object_add(scene, sc, ob_dst);
+ collection_object_add(&scene->id, sc, ob_dst);
}
}
FOREACH_SCENE_COLLECTION_END
@@ -274,50 +348,63 @@ void BKE_collection_object_add_from(Scene *scene, Object *ob_src, Object *ob_dst
* Remove object from collection.
* \param bmain: Can be NULL if free_us is false.
*/
-void BKE_collection_object_remove(Main *bmain, const Scene *scene, SceneCollection *sc, Object *ob, const bool free_us)
+bool BKE_collection_object_remove(Main *bmain, ID *owner_id, SceneCollection *sc, Object *ob, const bool free_us)
{
-
LinkData *link = BLI_findptr(&sc->objects, ob, offsetof(LinkData, data));
if (link == NULL) {
- return;
+ return false;
}
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);
+ BKE_layer_sync_object_unlink(owner_id, sc, ob);
- if (free_us) {
- BKE_libblock_free_us(bmain, ob);
+ if (GS(owner_id->name) == ID_SCE) {
+ if (free_us) {
+ BKE_libblock_free_us(bmain, ob);
+ }
+ else {
+ id_us_min(&ob->id);
+ }
}
else {
- id_us_min(&ob->id);
+ BLI_assert(GS(owner_id->name) == ID_GR);
}
+
+ return true;
}
/**
* Move object from a collection into another
*/
-void BKE_collection_object_move(const Scene *scene, SceneCollection *sc_dst, SceneCollection *sc_src, Object *ob)
+void BKE_collection_object_move(ID *owner_id, SceneCollection *sc_dst, SceneCollection *sc_src, Object *ob)
{
- BKE_collection_object_add(scene, sc_dst, ob);
- BKE_collection_object_remove(NULL, scene, sc_src, ob, false);
+ BKE_collection_object_add(owner_id, sc_dst, ob);
+ BKE_collection_object_remove(NULL, owner_id, sc_src, ob, false);
}
/**
* Remove object from all collections of scene
*/
-void BKE_collections_object_remove(Main *bmain, Scene *scene, Object *ob, const bool free_us)
+bool BKE_collections_object_remove(Main *bmain, ID *owner_id, Object *ob, const bool free_us)
{
- BKE_scene_remove_rigidbody_object(scene, ob);
+ bool removed = false;
+ if (GS(owner_id->name) == ID_SCE) {
+ BKE_scene_remove_rigidbody_object((Scene *)owner_id, ob);
+ }
+ else {
+ BLI_assert(GS(owner_id->name) == ID_GR);
+ }
- FOREACH_SCENE_COLLECTION(scene, sc)
+ FOREACH_SCENE_COLLECTION(owner_id, sc)
{
- BKE_collection_object_remove(bmain, scene, sc, ob, free_us);
+ removed |= BKE_collection_object_remove(bmain, owner_id, sc, ob, free_us);
}
FOREACH_SCENE_COLLECTION_END
+ return removed;
}
/* ---------------------------------------------------------------------- */
@@ -353,10 +440,10 @@ static bool is_collection_in_tree(const SceneCollection *sc_reference, SceneColl
return find_collection_parent(sc_reference, sc_parent) != NULL;
}
-bool BKE_collection_move_above(const Scene *scene, SceneCollection *sc_dst, SceneCollection *sc_src)
+bool BKE_collection_move_above(const ID *owner_id, SceneCollection *sc_dst, SceneCollection *sc_src)
{
/* Find the SceneCollection the sc_src belongs to */
- SceneCollection *sc_master = BKE_collection_master(scene);
+ SceneCollection *sc_master = master_collection_from_id(owner_id);
/* Master Layer can't be moved around*/
if (ELEM(sc_master, sc_src, sc_dst)) {
@@ -386,16 +473,16 @@ bool BKE_collection_move_above(const Scene *scene, SceneCollection *sc_dst, Scen
BLI_insertlinkbefore(&sc_dst_parent->scene_collections, sc_dst, sc_src);
/* Update the tree */
- BKE_layer_collection_resync(scene, sc_src_parent);
- BKE_layer_collection_resync(scene, sc_dst_parent);
+ BKE_layer_collection_resync(owner_id, sc_src_parent);
+ BKE_layer_collection_resync(owner_id, sc_dst_parent);
return true;
}
-bool BKE_collection_move_below(const Scene *scene, SceneCollection *sc_dst, SceneCollection *sc_src)
+bool BKE_collection_move_below(const ID *owner_id, SceneCollection *sc_dst, SceneCollection *sc_src)
{
/* Find the SceneCollection the sc_src belongs to */
- SceneCollection *sc_master = BKE_collection_master(scene);
+ SceneCollection *sc_master = master_collection_from_id(owner_id);
/* Master Layer can't be moved around*/
if (ELEM(sc_master, sc_src, sc_dst)) {
@@ -425,16 +512,16 @@ bool BKE_collection_move_below(const Scene *scene, SceneCollection *sc_dst, Scen
BLI_insertlinkafter(&sc_dst_parent->scene_collections, sc_dst, sc_src);
/* Update the tree */
- BKE_layer_collection_resync(scene, sc_src_parent);
- BKE_layer_collection_resync(scene, sc_dst_parent);
+ BKE_layer_collection_resync(owner_id, sc_src_parent);
+ BKE_layer_collection_resync(owner_id, sc_dst_parent);
return true;
}
-bool BKE_collection_move_into(const Scene *scene, SceneCollection *sc_dst, SceneCollection *sc_src)
+bool BKE_collection_move_into(const ID *owner_id, SceneCollection *sc_dst, SceneCollection *sc_src)
{
/* Find the SceneCollection the sc_src belongs to */
- SceneCollection *sc_master = BKE_collection_master(scene);
+ SceneCollection *sc_master = master_collection_from_id(owner_id);
if (sc_src == sc_master) {
return false;
}
@@ -460,8 +547,8 @@ bool BKE_collection_move_into(const Scene *scene, SceneCollection *sc_dst, Scene
BLI_addtail(&sc_dst->scene_collections, sc_src);
/* Update the tree */
- BKE_layer_collection_resync(scene, sc_src_parent);
- BKE_layer_collection_resync(scene, sc_dst);
+ BKE_layer_collection_resync(owner_id, sc_src_parent);
+ BKE_layer_collection_resync(owner_id, sc_dst);
return true;
}
@@ -471,7 +558,7 @@ bool BKE_collection_move_into(const Scene *scene, SceneCollection *sc_dst, Scene
/* scene collection iteractor */
typedef struct SceneCollectionsIteratorData {
- Scene *scene;
+ ID *owner_id;
void **array;
int tot, cur;
} SceneCollectionsIteratorData;
@@ -498,17 +585,20 @@ static void scene_collections_build_array(SceneCollection *sc, void *data)
(*array)++;
}
-static void scene_collections_array(Scene *scene, SceneCollection ***collections_array, int *tot)
+static void scene_collections_array(ID *owner_id, SceneCollection ***collections_array, int *tot)
{
- SceneCollection *sc = BKE_collection_master(scene);
+ SceneCollection *sc;
SceneCollection **array;
*collections_array = NULL;
*tot = 0;
- if (scene == NULL)
+ if (owner_id == NULL) {
return;
+ }
+ sc = master_collection_from_id(owner_id);
+ BLI_assert(sc != NULL);
scene_collection_callback(sc, scene_collections_count, tot);
if (*tot == 0)
@@ -524,13 +614,13 @@ static void scene_collections_array(Scene *scene, SceneCollection ***collections
*/
void BKE_scene_collections_iterator_begin(BLI_Iterator *iter, void *data_in)
{
- Scene *scene = data_in;
+ ID *owner_id = data_in;
SceneCollectionsIteratorData *data = MEM_callocN(sizeof(SceneCollectionsIteratorData), __func__);
- data->scene = scene;
+ data->owner_id = owner_id;
iter->data = data;
- scene_collections_array(scene, (SceneCollection ***)&data->array, &data->tot);
+ scene_collections_array(owner_id, (SceneCollection ***)&data->array, &data->tot);
BLI_assert(data->tot != 0);
data->cur = 0;
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index d21b527bbd6..2f80fbbec46 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -47,6 +47,7 @@
#include "BKE_cloth.h"
#include "BKE_effect.h"
+#include "BKE_group.h"
#include "BKE_layer.h"
#include "BKE_modifier.h"
#include "BKE_scene.h"
@@ -502,12 +503,14 @@ static void add_collision_object(Object ***objs, unsigned int *numobj, unsigned
/* objects in dupli groups, one level only for now */
if (ob->dup_group && level == 0) {
- GroupObject *go;
Group *group= ob->dup_group;
/* add objects */
- for (go= group->gobject.first; go; go= go->next)
- add_collision_object(objs, numobj, maxobj, go->ob, self, level+1, modifier_type);
+ FOREACH_GROUP_OBJECT(group, object)
+ {
+ add_collision_object(objs, numobj, maxobj, object, self, level+1, modifier_type);
+ }
+ FOREACH_GROUP_OBJECT_END
}
}
@@ -515,9 +518,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, unsigned int *numcollobj, unsigned int modifier_type, bool dupli)
{
- Base *base;
Object **objs;
- GroupObject *go;
unsigned int numobj= 0, maxobj= 100;
int level = dupli ? 0 : 1;
@@ -526,11 +527,15 @@ Object **get_collisionobjects_ext(Scene *scene, Object *self, Group *group, unsi
/* gather all collision objects */
if (group) {
/* use specified group */
- for (go= group->gobject.first; go; go= go->next)
- add_collision_object(&objs, &numobj, &maxobj, go->ob, self, level, modifier_type);
+ FOREACH_GROUP_OBJECT(group, object)
+ {
+ add_collision_object(&objs, &numobj, &maxobj, object, self, level, modifier_type);
+ }
+ FOREACH_GROUP_OBJECT_END
}
else {
Scene *sce_iter;
+ Base *base;
/* add objects in same layer in scene */
for (SETLOOPER(scene, sce_iter, base)) {
if ((base->flag & BASE_VISIBLED) != 0) {
@@ -576,24 +581,28 @@ static void add_collider_cache_object(ListBase **objs, Object *ob, Object *self,
/* objects in dupli groups, one level only for now */
if (ob->dup_group && level == 0) {
- GroupObject *go;
Group *group= ob->dup_group;
/* add objects */
- for (go= group->gobject.first; go; go= go->next)
- add_collider_cache_object(objs, go->ob, self, level+1);
+ FOREACH_GROUP_OBJECT(group, object)
+ {
+ add_collider_cache_object(objs, object, self, level+1);
+ }
+ FOREACH_GROUP_OBJECT_END
}
}
ListBase *get_collider_cache(Scene *scene, Object *self, Group *group)
{
- GroupObject *go;
ListBase *objs= NULL;
/* add object in same layer in scene */
if (group) {
- for (go= group->gobject.first; go; go= go->next)
- add_collider_cache_object(&objs, go->ob, self, 0);
+ FOREACH_GROUP_OBJECT(group, object)
+ {
+ add_collider_cache_object(&objs, object, self, 0);
+ }
+ FOREACH_GROUP_OBJECT_END
}
else {
Scene *sce_iter;
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index 3a4de77a3b5..855216d089b 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -991,7 +991,7 @@ SceneCollection *CTX_data_scene_collection(const bContext *C)
/* fallback */
Scene *scene = CTX_data_scene(C);
- return BKE_collection_master(scene);
+ return BKE_collection_master(&scene->id);
}
int CTX_data_mode_enum_ex(const Object *obedit, const Object *ob)
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 9e292422019..80a31697424 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -491,33 +491,24 @@ static void scene_setSubframe(Scene *scene, float subframe)
static int surface_getBrushFlags(DynamicPaintSurface *surface, const ViewLayer *view_layer)
{
Base *base = NULL;
- GroupObject *go = NULL;
Object *brushObj = NULL;
ModifierData *md = NULL;
int flags = 0;
if (surface->brush_group)
- go = surface->brush_group->gobject.first;
+ base = FIRSTBASE(surface->brush_group->view_layer);
else
base = FIRSTBASE(view_layer);
- while (base || go) {
+ while (base) {
brushObj = NULL;
/* select object */
- if (surface->brush_group) {
- if (go->ob)
- brushObj = go->ob;
- }
- else {
- brushObj = base->object;
- }
+ brushObj = base->object;
- if (surface->brush_group)
- go = go->next;
- else
- base = base->next;
+ /* next item */
+ base = base->next;
if (!brushObj) {
continue;
@@ -5780,7 +5771,6 @@ static int dynamicPaint_doStep(const struct EvaluationContext *eval_ctx, Scene *
*/
{
Base *base = NULL;
- GroupObject *go = NULL;
Object *brushObj = NULL;
ModifierData *md = NULL;
ViewLayer *view_layer = eval_ctx->view_layer;
@@ -5791,25 +5781,17 @@ static int dynamicPaint_doStep(const struct EvaluationContext *eval_ctx, Scene *
/* either from group or from all objects */
if (surface->brush_group)
- go = surface->brush_group->gobject.first;
+ base = FIRSTBASE(surface->brush_group->view_layer);
else
base = FIRSTBASE(view_layer);
- while (base || go) {
+ while (base) {
brushObj = NULL;
/* select object */
- if (surface->brush_group) {
- if (go->ob)
- brushObj = go->ob;
- }
- else
- brushObj = base->object;
+ brushObj = base->object;
/* next item */
- if (surface->brush_group)
- go = go->next;
- else
- base = base->next;
+ base = base->next;
if (!brushObj) {
/* skip item */
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index 502ad9c44a7..16124fb4777 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -64,6 +64,7 @@
#include "BKE_cdderivedmesh.h"
#include "BKE_effect.h"
#include "BKE_global.h"
+#include "BKE_group.h"
#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_modifier.h"
@@ -215,51 +216,41 @@ ListBase *pdInitEffectors(
{
ViewLayer *view_layer;
Base *base;
- unsigned int layer= ob_src->lay;
ListBase *effectors = NULL;
- /* eval_ctx is NULL during deg build */
- if (eval_ctx) {
+ if (weights->group) {
+ view_layer = weights->group->view_layer;
+ }
+ else if (eval_ctx) {
view_layer = eval_ctx->view_layer;
}
else {
+ /* eval_ctx is NULL during deg build */
view_layer = BKE_view_layer_context_active_PLACEHOLDER(scene);
}
-
- if (weights->group) {
- GroupObject *go;
-
- for (go= weights->group->gobject.first; go; go= go->next) {
- if ( (go->ob->lay & layer) ) {
- if ( go->ob->pd && go->ob->pd->forcefield )
- add_object_to_effectors(&effectors, eval_ctx, scene, weights, go->ob, ob_src, for_simulation);
- if ( go->ob->particlesystem.first ) {
- ParticleSystem *psys= go->ob->particlesystem.first;
+ for (base = FIRSTBASE(view_layer); base; base = base->next) {
+ if ((base->flag & BASE_VISIBLED) == 0) {
+ continue;
+ }
- for ( ; psys; psys=psys->next )
- add_particles_to_effectors(&effectors, eval_ctx, scene, weights, go->ob, psys, psys_src, for_simulation);
- }
- }
+ if (base->object->pd && base->object->pd->forcefield) {
+ add_object_to_effectors(&effectors, eval_ctx, scene, weights, base->object, ob_src, for_simulation);
}
- }
- else {
- for (base = FIRSTBASE(view_layer); base; base = base->next) {
- if ( base->object->pd && base->object->pd->forcefield )
- add_object_to_effectors(&effectors, eval_ctx, scene, weights, base->object, ob_src, for_simulation);
- if ( base->object->particlesystem.first ) {
- ParticleSystem *psys= base->object->particlesystem.first;
+ if (base->object->particlesystem.first) {
+ ParticleSystem *psys= base->object->particlesystem.first;
- for ( ; psys; psys=psys->next )
- add_particles_to_effectors(&effectors, eval_ctx, scene, weights, base->object, psys, psys_src, for_simulation);
+ for (; psys; psys=psys->next) {
+ add_particles_to_effectors(&effectors, eval_ctx, scene, weights, base->object, psys, psys_src, for_simulation);
}
}
}
-
- if (for_simulation)
+
+ if (for_simulation) {
pdPrecalculateEffectors(eval_ctx, effectors);
-
+ }
+
return effectors;
}
diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c
index f4555ceac38..7c2eefe657c 100644
--- a/source/blender/blenkernel/intern/group.c
+++ b/source/blender/blenkernel/intern/group.c
@@ -45,32 +45,53 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
+#include "BKE_collection.h"
#include "BKE_global.h"
#include "BKE_group.h"
#include "BKE_icons.h"
+#include "BKE_layer.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_object.h"
#include "BKE_scene.h"
-static void free_group_object(GroupObject *go)
-{
- MEM_freeN(go);
-}
-
/** Free (or release) any data used by this group (does not free the group itself). */
void BKE_group_free(Group *group)
{
- /* don't free group itself */
- GroupObject *go;
-
/* No animdata here. */
+ BKE_previewimg_free(&group->preview);
- while ((go = BLI_pophead(&group->gobject))) {
- free_group_object(go);
+ if (group->view_layer != NULL) {
+ BKE_view_layer_free(group->view_layer);
+ group->view_layer = NULL;
}
- BKE_previewimg_free(&group->preview);
+ if (group->collection != NULL) {
+ BKE_collection_master_free(&group->id, false);
+ MEM_freeN(group->collection);
+ group->collection = NULL;
+ }
+}
+
+/**
+ * Run when adding new groups or during doversion.
+ */
+void BKE_group_init(Group *group)
+{
+ group->collection = MEM_callocN(sizeof(SceneCollection), __func__);
+ BLI_strncpy(group->collection->name, "Master Collection", sizeof(group->collection->name));
+ group->view_layer = NULL; /* groups are not calloced. */
+ group->view_layer = BKE_view_layer_group_add(group);
+
+ /* Unlink the master collection. */
+ BKE_collection_unlink(group->view_layer, group->view_layer->layer_collections.first);
+
+ /* Create and link a new default collection. */
+ SceneCollection *defaut_collection = BKE_collection_add(&group->id,
+ NULL,
+ COLLECTION_TYPE_GROUP_INTERNAL,
+ "Default Collection");
+ BKE_collection_link(group->view_layer, defaut_collection);
}
Group *BKE_group_add(Main *bmain, const char *name)
@@ -83,7 +104,7 @@ Group *BKE_group_add(Main *bmain, const char *name)
group->layer = (1 << 20) - 1;
group->preview = NULL;
-
+ BKE_group_init(group);
return group;
}
@@ -97,7 +118,8 @@ Group *BKE_group_add(Main *bmain, const char *name)
*/
void BKE_group_copy_data(Main *UNUSED(bmain), Group *group_dst, const Group *group_src, const int flag)
{
- BLI_duplicatelist(&group_dst->gobject, &group_src->gobject);
+ /* We never handle usercount here for own data. */
+ const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
/* Do not copy group's preview (same behavior as for objects). */
if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0 && false) { /* XXX TODO temp hack */
@@ -106,6 +128,18 @@ void BKE_group_copy_data(Main *UNUSED(bmain), Group *group_dst, const Group *gro
else {
group_dst->preview = NULL;
}
+
+ group_dst->collection = MEM_dupallocN(group_src->collection);
+ SceneCollection *master_collection_src = BKE_collection_master(&group_src->id);
+ SceneCollection *master_collection_dst = BKE_collection_master(&group_dst->id);
+
+ /* Recursively creates a new SceneCollection tree. */
+ BKE_collection_copy_data(master_collection_dst, master_collection_src,
+ flag_subdata);
+
+ BKE_view_layer_copy_data(group_dst->view_layer, group_src->view_layer,
+ master_collection_dst, master_collection_src,
+ flag_subdata);
}
Group *BKE_group_copy(Main *bmain, const Group *group)
@@ -123,23 +157,19 @@ void BKE_group_make_local(Main *bmain, Group *group, const bool lib_local)
/* external */
static bool group_object_add_internal(Group *group, Object *ob)
{
- GroupObject *go;
-
if (group == NULL || ob == NULL) {
return false;
}
-
- /* check if the object has been added already */
- if (BLI_findptr(&group->gobject, ob, offsetof(GroupObject, ob))) {
+
+ /* For now always add to master collection of the group. */
+ SceneCollection *scene_collection = GROUP_MASTER_COLLECTION(group);
+
+ /* If the object has been added already it returns false. */
+ if (BKE_collection_object_add(&group->id, scene_collection, ob) == false) {
return false;
}
-
- go = MEM_callocN(sizeof(GroupObject), "groupobject");
- BLI_addtail(&group->gobject, go);
-
- go->ob = ob;
- id_us_ensure_real(&go->ob->id);
-
+
+ id_us_ensure_real(&ob->id);
return true;
}
@@ -157,24 +187,17 @@ bool BKE_group_object_add(Group *group, Object *object)
}
/* also used for (ob == NULL) */
-static int group_object_unlink_internal(Group *group, Object *ob)
+static bool group_object_unlink_internal(Group *group, Object *ob)
{
- GroupObject *go, *gon;
- int removed = 0;
- if (group == NULL) return 0;
-
- go = group->gobject.first;
- while (go) {
- gon = go->next;
- if (go->ob == ob) {
- BLI_remlink(&group->gobject, go);
- free_group_object(go);
- removed = 1;
- /* should break here since an object being in a group twice cant happen? */
- }
- go = gon;
+ if (group == NULL) {
+ return false;
}
- return removed;
+
+ if (BKE_collections_object_remove(NULL, &group->id, ob, false)) {
+ return true;
+ }
+
+ return false;
}
static bool group_object_cyclic_check_internal(Object *object, Group *group)
@@ -191,12 +214,13 @@ static bool group_object_cyclic_check_internal(Object *object, Group *group)
if (dup_group == group)
return true;
else {
- GroupObject *gob;
- for (gob = dup_group->gobject.first; gob; gob = gob->next) {
- if (group_object_cyclic_check_internal(gob->ob, group)) {
+ FOREACH_GROUP_OBJECT(dup_group, group_object)
+ {
+ if (group_object_cyclic_check_internal(group_object, dup_group)) {
return true;
}
}
+ FOREACH_GROUP_OBJECT_END
}
/* un-flag the object, it's allowed to have the same group multiple times in parallel */
@@ -234,7 +258,7 @@ bool BKE_group_object_exists(Group *group, Object *ob)
return false;
}
else {
- return (BLI_findptr(&group->gobject, ob, offsetof(GroupObject, ob)) != NULL);
+ return (BLI_findptr(&group->view_layer->object_bases, ob, offsetof(Base, object)));
}
}
@@ -255,17 +279,13 @@ Group *BKE_group_object_find(Group *group, Object *ob)
bool BKE_group_is_animated(Group *group, Object *UNUSED(parent))
{
- GroupObject *go;
-
-#if 0 /* XXX OLD ANIMSYS, NLASTRIPS ARE NO LONGER USED */
- if (parent->nlastrips.first)
- return 1;
-#endif
-
- for (go = group->gobject.first; go; go = go->next)
- if (go->ob && go->ob->proxy)
+ FOREACH_GROUP_OBJECT(group, object)
+ {
+ if (object->proxy) {
return true;
-
+ }
+ }
+ FOREACH_GROUP_OBJECT_END
return false;
}
@@ -317,8 +337,6 @@ static void group_replaces_nla(Object *parent, Object *target, char mode)
/* note: does not work for derivedmesh and render... it recreates all again in convertblender.c */
void BKE_group_handle_recalc_and_update(const struct EvaluationContext *eval_ctx, Scene *scene, Object *UNUSED(parent), Group *group)
{
- GroupObject *go;
-
#if 0 /* warning, isn't clearing the recalc flag on the object which causes it to run all the time,
* not just on frame change.
* This isn't working because the animation data is only re-evaluated on frame change so commenting for now
@@ -352,12 +370,12 @@ void BKE_group_handle_recalc_and_update(const struct EvaluationContext *eval_ctx
#endif
{
/* only do existing tags, as set by regular depsgraph */
- for (go = group->gobject.first; go; go = go->next) {
- if (go->ob) {
- if (go->ob->id.tag & LIB_TAG_ID_RECALC_ALL) {
- BKE_object_handle_update(eval_ctx, scene, go->ob);
- }
+ FOREACH_GROUP_OBJECT(group, object)
+ {
+ if (object->id.tag & LIB_TAG_ID_RECALC_ALL) {
+ BKE_object_handle_update(eval_ctx, scene, object);
}
}
+ FOREACH_GROUP_OBJECT_END
}
}
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index f841181f7c4..363dc53496f 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -35,12 +35,14 @@
#include "BKE_collection.h"
#include "BKE_freestyle.h"
#include "BKE_global.h"
+#include "BKE_group.h"
#include "BKE_idprop.h"
#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_node.h"
#include "BKE_workspace.h"
+#include "DNA_group_types.h"
#include "DNA_ID.h"
#include "DNA_layer_types.h"
#include "DNA_object_types.h"
@@ -102,11 +104,7 @@ ViewLayer *BKE_view_layer_context_active_PLACEHOLDER(const Scene *scene)
return BKE_view_layer_from_scene_get(scene);
}
-/**
- * Add a new renderlayer
- * by default, a renderlayer has the master collection
- */
-ViewLayer *BKE_view_layer_add(Scene *scene, const char *name)
+static ViewLayer *view_layer_add(const char *name, SceneCollection *master_scene_collection)
{
if (!name) {
name = DATA_("View Layer");
@@ -118,15 +116,10 @@ ViewLayer *BKE_view_layer_add(Scene *scene, const char *name)
view_layer->properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
layer_engine_settings_init(view_layer->properties, false);
-
- BLI_addtail(&scene->view_layers, view_layer);
-
- /* unique name */
BLI_strncpy_utf8(view_layer->name, name, sizeof(view_layer->name));
- BLI_uniquename(&scene->view_layers, view_layer, DATA_("ViewLayer"), '.', offsetof(ViewLayer, name), sizeof(view_layer->name));
- SceneCollection *sc = BKE_collection_master(scene);
- layer_collection_add(view_layer, NULL, sc);
+ /* Link the master collection by default. */
+ layer_collection_add(view_layer, NULL, master_scene_collection);
/* Pure rendering pipeline settings. */
view_layer->layflag = 0x7FFF; /* solid ztra halo edge strand */
@@ -138,6 +131,35 @@ ViewLayer *BKE_view_layer_add(Scene *scene, const char *name)
}
/**
+ * Add a new view layer
+ * by default, a view layer has the master collection
+ */
+ViewLayer *BKE_view_layer_add(Scene *scene, const char *name)
+{
+ SceneCollection *sc = BKE_collection_master(&scene->id);
+ ViewLayer *view_layer = view_layer_add(name, sc);
+
+ BLI_addtail(&scene->view_layers, view_layer);
+
+ /* unique name */
+ BLI_uniquename(&scene->view_layers, view_layer, DATA_("ViewLayer"), '.', offsetof(ViewLayer, name), sizeof(view_layer->name));
+
+ return view_layer;
+}
+
+/**
+ * Add a ViewLayer for a Group
+ * It should be added only once
+ */
+ViewLayer *BKE_view_layer_group_add(Group *group)
+{
+ BLI_assert(group->view_layer == NULL);
+ SceneCollection *sc = BKE_collection_master(&group->id);
+ ViewLayer *view_layer = view_layer_add(group->id.name + 2, sc);
+ return view_layer;
+}
+
+/**
* Free (or release) any data used by this ViewLayer.
*/
void BKE_view_layer_free(ViewLayer *view_layer)
@@ -204,6 +226,22 @@ void BKE_view_layer_selected_objects_tag(ViewLayer *view_layer, const int tag)
}
}
+/**
+ * Return the first ViewLayer for a given id
+ */
+ViewLayer *BKE_view_layer_first_from_id(const ID *owner_id)
+{
+ switch (GS(owner_id->name)) {
+ case ID_SCE:
+ return ((Scene *)owner_id)->view_layers.first;
+ case ID_GR:
+ return ((Group *)owner_id)->view_layer;
+ default:
+ BLI_assert(!"ID doesn't support view layers");
+ return NULL;
+ }
+}
+
static bool find_scene_collection_in_scene_collections(ListBase *lb, const LayerCollection *lc)
{
for (LayerCollection *lcn = lb->first; lcn; lcn = lcn->next) {
@@ -238,14 +276,25 @@ Object *BKE_view_layer_camera_find(ViewLayer *view_layer)
/**
* Find the ViewLayer a LayerCollection belongs to
*/
-ViewLayer *BKE_view_layer_find_from_collection(const Scene *scene, LayerCollection *lc)
-{
- for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
- if (find_scene_collection_in_scene_collections(&view_layer->layer_collections, lc)) {
- return view_layer;
+ViewLayer *BKE_view_layer_find_from_collection(const ID *owner_id, LayerCollection *lc)
+{
+ switch (GS(owner_id->name)) {
+ case ID_GR:
+ return ((Group *)owner_id)->view_layer;
+ case ID_SCE:
+ {
+ Scene *scene = (Scene *)owner_id;
+ for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
+ if (find_scene_collection_in_scene_collections(&view_layer->layer_collections, lc)) {
+ return view_layer;
+ }
+ }
+ return NULL;
}
+ default:
+ BLI_assert(!"ID doesn't support scene layers");
+ return NULL;
}
- return NULL;
}
/* Base */
@@ -272,6 +321,112 @@ void BKE_view_layer_base_select(struct ViewLayer *view_layer, Base *selbase)
}
}
+/****************************************************************************/
+/* Copying functions for datablocks that use ViewLayer/SceneCollection */
+
+/* Find the equivalent SceneCollection in the new tree */
+static SceneCollection *scene_collection_from_new_tree(SceneCollection *sc_reference, SceneCollection *sc_dst, SceneCollection *sc_src)
+{
+ if (sc_src == sc_reference) {
+ return sc_dst;
+ }
+
+ for (SceneCollection *nsc_src = sc_src->scene_collections.first, *nsc_dst = sc_dst->scene_collections.first;
+ nsc_src;
+ nsc_src = nsc_src->next, nsc_dst = nsc_dst->next)
+ {
+ SceneCollection *found = scene_collection_from_new_tree(sc_reference, nsc_dst, nsc_src);
+ if (found != NULL) {
+ return found;
+ }
+ }
+ return NULL;
+}
+
+static void layer_collections_sync_flags(ListBase *layer_collections_dst, const ListBase *layer_collections_src)
+{
+ LayerCollection *layer_collection_dst = (LayerCollection *)layer_collections_dst->first;
+ const LayerCollection *layer_collection_src = (const LayerCollection *)layer_collections_src->first;
+ while (layer_collection_dst != NULL) {
+ layer_collection_dst->flag = layer_collection_src->flag;
+
+ if (layer_collection_dst->properties != NULL) {
+ IDP_FreeProperty(layer_collection_dst->properties);
+ MEM_SAFE_FREE(layer_collection_dst->properties);
+ }
+
+ if (layer_collection_src->properties != NULL) {
+ layer_collection_dst->properties = IDP_CopyProperty(layer_collection_src->properties);
+ }
+
+ layer_collections_sync_flags(&layer_collection_dst->layer_collections,
+ &layer_collection_src->layer_collections);
+
+ layer_collection_dst = layer_collection_dst->next;
+ layer_collection_src = layer_collection_src->next;
+ }
+}
+
+/* recreate the LayerCollection tree */
+static void layer_collections_recreate(
+ ViewLayer *view_layer_dst, ListBase *lb_src, SceneCollection *mc_dst, SceneCollection *mc_src)
+{
+ for (LayerCollection *lc_src = lb_src->first; lc_src; lc_src = lc_src->next) {
+ SceneCollection *sc_dst = scene_collection_from_new_tree(lc_src->scene_collection, mc_dst, mc_src);
+ BLI_assert(sc_dst);
+
+ /* instead of synchronizing both trees we simply re-create it */
+ BKE_collection_link(view_layer_dst, sc_dst);
+ }
+}
+
+/**
+ * Only copy internal data of ViewLayer from source to already allocated/initialized destination.
+ *
+ * \param mc_src Master Collection the source ViewLayer links in.
+ * \param mc_dst Master Collection the destination ViewLayer links in.
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_view_layer_copy_data(ViewLayer *view_layer_dst, ViewLayer *view_layer_src, SceneCollection* mc_dst, SceneCollection* mc_src,
+ const int flag)
+{
+ IDPropertyTemplate val = {0};
+
+ if (view_layer_dst->id_properties != NULL) {
+ view_layer_dst->id_properties = IDP_CopyProperty_ex(view_layer_dst->id_properties, flag);
+ }
+ BKE_freestyle_config_copy(&view_layer_dst->freestyle_config, &view_layer_src->freestyle_config, flag);
+
+ view_layer_dst->stats = NULL;
+ view_layer_dst->properties_evaluated = NULL;
+ view_layer_dst->properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
+ IDP_MergeGroup_ex(view_layer_dst->properties, view_layer_src->properties, true, flag);
+
+ /* 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(&view_layer_dst->layer_collections);
+ BLI_listbase_clear(&view_layer_dst->object_bases);
+ BLI_listbase_clear(&view_layer_dst->drawdata);
+
+ layer_collections_recreate(view_layer_dst, &view_layer_src->layer_collections, mc_dst, mc_src);
+
+ /* Now we handle the syncing for visibility, selectability, ... */
+ layer_collections_sync_flags(&view_layer_dst->layer_collections, &view_layer_src->layer_collections);
+
+ Object *active_ob = OBACT(view_layer_src);
+ for (Base *base_src = view_layer_src->object_bases.first, *base_dst = view_layer_dst->object_bases.first;
+ base_src;
+ base_src = base_src->next, base_dst = base_dst->next)
+ {
+ base_dst->flag = base_src->flag;
+ base_dst->flag_legacy = base_src->flag_legacy;
+
+ if (base_dst->object == active_ob) {
+ view_layer_dst->basact = base_dst;
+ }
+ }
+}
+
static void view_layer_object_base_unref(ViewLayer *view_layer, Base *base)
{
base->refcount--;
@@ -416,7 +571,7 @@ LayerCollection *BKE_layer_collection_get_active_ensure(Scene *scene, ViewLayer
if (lc == NULL) {
BLI_assert(BLI_listbase_is_empty(&view_layer->layer_collections));
/* When there is no collection linked to this ViewLayer, create one. */
- SceneCollection *sc = BKE_collection_add(scene, NULL, NULL);
+ SceneCollection *sc = BKE_collection_add(&scene->id, NULL, COLLECTION_TYPE_NONE, NULL);
lc = BKE_collection_link(view_layer, sc);
/* New collection has to be the active one. */
BLI_assert(lc == BKE_layer_collection_get_active(view_layer));
@@ -552,15 +707,15 @@ static void layer_collection_swap(
}
/**
- * Move \a lc_src into \a lc_dst. Both have to be stored in \a sl.
+ * Move \a lc_src into \a lc_dst. Both have to be stored in \a view_layer.
* If \a lc_src is directly linked to the ViewLayer it's unlinked
*/
-bool BKE_layer_collection_move_into(const Scene *scene, LayerCollection *lc_dst, LayerCollection *lc_src)
+bool BKE_layer_collection_move_into(const ID *owner_id, LayerCollection *lc_dst, LayerCollection *lc_src)
{
- ViewLayer *view_layer = BKE_view_layer_find_from_collection(scene, lc_src);
+ ViewLayer *view_layer = BKE_view_layer_find_from_collection(owner_id, lc_src);
bool is_directly_linked = false;
- if ((!view_layer) || (view_layer != BKE_view_layer_find_from_collection(scene, lc_dst))) {
+ if ((!view_layer) || (view_layer != BKE_view_layer_find_from_collection(owner_id, lc_dst))) {
return false;
}
@@ -596,7 +751,7 @@ bool BKE_layer_collection_move_into(const Scene *scene, LayerCollection *lc_dst,
layer_collection_swap(view_layer, &view_layer->layer_collections, NULL, lc_temp, lc_src);
}
- if (!BKE_collection_move_into(scene, lc_dst->scene_collection, lc_src->scene_collection)) {
+ if (!BKE_collection_move_into(owner_id, lc_dst->scene_collection, lc_src->scene_collection)) {
if (!is_directly_linked) {
/* Swap back and remove */
layer_collection_swap(view_layer, NULL, NULL, lc_temp, lc_src);
@@ -622,13 +777,13 @@ bool BKE_layer_collection_move_into(const Scene *scene, LayerCollection *lc_dst,
* Move \a lc_src above \a lc_dst. Both have to be stored in \a view_layer.
* If \a lc_src is directly linked to the ViewLayer it's unlinked
*/
-bool BKE_layer_collection_move_above(const Scene *scene, LayerCollection *lc_dst, LayerCollection *lc_src)
+bool BKE_layer_collection_move_above(const ID *owner_id, LayerCollection *lc_dst, LayerCollection *lc_src)
{
- ViewLayer *view_layer = BKE_view_layer_find_from_collection(scene, lc_src);
+ ViewLayer *view_layer = BKE_view_layer_find_from_collection(owner_id, lc_src);
const bool is_directly_linked_src = BLI_findindex(&view_layer->layer_collections, lc_src) != -1;
const bool is_directly_linked_dst = BLI_findindex(&view_layer->layer_collections, lc_dst) != -1;
- if ((!view_layer) || (view_layer != BKE_view_layer_find_from_collection(scene, lc_dst))) {
+ if ((!view_layer) || (view_layer != BKE_view_layer_find_from_collection(owner_id, lc_dst))) {
return false;
}
@@ -671,7 +826,7 @@ bool BKE_layer_collection_move_above(const Scene *scene, LayerCollection *lc_dst
layer_collection_swap(view_layer, &view_layer->layer_collections, NULL, lc_temp, lc_src);
}
- if (!BKE_collection_move_above(scene, lc_dst->scene_collection, lc_src->scene_collection)) {
+ if (!BKE_collection_move_above(owner_id, lc_dst->scene_collection, lc_src->scene_collection)) {
if (!is_directly_linked_src) {
/* Swap back and remove */
layer_collection_swap(view_layer, NULL, NULL, lc_temp, lc_src);
@@ -694,16 +849,16 @@ bool BKE_layer_collection_move_above(const Scene *scene, LayerCollection *lc_dst
}
/**
- * Move \a lc_src below \a lc_dst. Both have to be stored in \a sl.
+ * Move \a lc_src below \a lc_dst. Both have to be stored in \a view_layer.
* If \a lc_src is directly linked to the ViewLayer it's unlinked
*/
-bool BKE_layer_collection_move_below(const Scene *scene, LayerCollection *lc_dst, LayerCollection *lc_src)
+bool BKE_layer_collection_move_below(const ID *owner_id, LayerCollection *lc_dst, LayerCollection *lc_src)
{
- ViewLayer *view_layer = BKE_view_layer_find_from_collection(scene, lc_src);
+ ViewLayer *view_layer = BKE_view_layer_find_from_collection(owner_id, lc_src);
const bool is_directly_linked_src = BLI_findindex(&view_layer->layer_collections, lc_src) != -1;
const bool is_directly_linked_dst = BLI_findindex(&view_layer->layer_collections, lc_dst) != -1;
- if ((!view_layer) || (view_layer != BKE_view_layer_find_from_collection(scene, lc_dst))) {
+ if ((!view_layer) || (view_layer != BKE_view_layer_find_from_collection(owner_id, lc_dst))) {
return false;
}
@@ -746,7 +901,7 @@ bool BKE_layer_collection_move_below(const Scene *scene, LayerCollection *lc_dst
layer_collection_swap(view_layer, &view_layer->layer_collections, NULL, lc_temp, lc_src);
}
- if (!BKE_collection_move_below(scene, lc_dst->scene_collection, lc_src->scene_collection)) {
+ if (!BKE_collection_move_below(owner_id, lc_dst->scene_collection, lc_src->scene_collection)) {
if (!is_directly_linked_src) {
/* Swap back and remove */
layer_collection_swap(view_layer, NULL, NULL, lc_temp, lc_src);
@@ -809,9 +964,9 @@ static bool layer_collection_resync(ViewLayer *view_layer, LayerCollection *lc,
* Update the scene layers so that any LayerCollection that points
* to \a sc is re-synced again
*/
-void BKE_layer_collection_resync(const Scene *scene, const SceneCollection *sc)
+void BKE_layer_collection_resync(const ID *owner_id, const SceneCollection *sc)
{
- for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
+ for (ViewLayer *view_layer = BKE_view_layer_first_from_id(owner_id); view_layer; view_layer = view_layer->next) {
for (LayerCollection *lc = view_layer->layer_collections.first; lc; lc = lc->next) {
layer_collection_resync(view_layer, lc, sc);
}
@@ -1025,9 +1180,9 @@ static LayerCollection *find_layer_collection_by_scene_collection(LayerCollectio
/**
* Add a new LayerCollection for all the ViewLayers that have sc_parent
*/
-void BKE_layer_sync_new_scene_collection(Scene *scene, const SceneCollection *sc_parent, SceneCollection *sc)
+void BKE_layer_sync_new_scene_collection(ID *owner_id, const SceneCollection *sc_parent, SceneCollection *sc)
{
- for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
+ for (ViewLayer *view_layer = BKE_view_layer_first_from_id(owner_id); view_layer; view_layer = view_layer->next) {
for (LayerCollection *lc = view_layer->layer_collections.first; lc; lc = lc->next) {
LayerCollection *lc_parent = find_layer_collection_by_scene_collection(lc, sc_parent);
if (lc_parent) {
@@ -1040,9 +1195,9 @@ void BKE_layer_sync_new_scene_collection(Scene *scene, const SceneCollection *sc
/**
* Add a corresponding ObjectBase to all the equivalent LayerCollection
*/
-void BKE_layer_sync_object_link(const Scene *scene, SceneCollection *sc, Object *ob)
+void BKE_layer_sync_object_link(const ID *owner_id, SceneCollection *sc, Object *ob)
{
- for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
+ for (ViewLayer *view_layer = BKE_view_layer_first_from_id(owner_id); view_layer; view_layer = view_layer->next) {
for (LayerCollection *lc = view_layer->layer_collections.first; lc; lc = lc->next) {
LayerCollection *found = find_layer_collection_by_scene_collection(lc, sc);
if (found) {
@@ -1056,9 +1211,9 @@ void BKE_layer_sync_object_link(const Scene *scene, SceneCollection *sc, Object
* 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(const Scene *scene, SceneCollection *sc, Object *ob)
+void BKE_layer_sync_object_unlink(const ID *owner_id, SceneCollection *sc, Object *ob)
{
- for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
+ for (ViewLayer *view_layer = BKE_view_layer_first_from_id(owner_id); view_layer; view_layer = view_layer->next) {
for (LayerCollection *lc = view_layer->layer_collections.first; lc; lc = lc->next) {
LayerCollection *found = find_layer_collection_by_scene_collection(lc, sc);
if (found) {
@@ -1074,9 +1229,9 @@ void BKE_layer_sync_object_unlink(const Scene *scene, SceneCollection *sc, Objec
/**
* Add a new datablock override
*/
-void BKE_override_view_layer_datablock_add(ViewLayer *view_layer, int id_type, const char *data_path, const ID *id)
+void BKE_override_view_layer_datablock_add(ViewLayer *view_layer, int id_type, const char *data_path, const ID *owner_id)
{
- UNUSED_VARS(view_layer, id_type, data_path, id);
+ UNUSED_VARS(view_layer, id_type, data_path, owner_id);
TODO_LAYER_OVERRIDE;
}
@@ -1934,32 +2089,43 @@ static void idproperty_reset(IDProperty **props, IDProperty *props_ref)
}
void BKE_layer_eval_layer_collection_pre(const struct EvaluationContext *UNUSED(eval_ctx),
- Scene *scene, ViewLayer *view_layer)
+ ID *owner_id, ViewLayer *view_layer)
{
- DEBUG_PRINT("%s on scene:%s %s (%p)\n", __func__, scene->id.name, view_layer->name, view_layer);
+ DEBUG_PRINT("%s on %s (%p)\n", __func__, view_layer->name, view_layer);
+ Scene *scene = (GS(owner_id->name) == ID_SCE) ? (Scene *)owner_id : NULL;
+
for (Base *base = view_layer->object_bases.first; base != NULL; base = base->next) {
base->flag &= ~(BASE_VISIBLED | BASE_SELECTABLED);
- idproperty_reset(&base->collection_properties, scene->collection_properties);
+ idproperty_reset(&base->collection_properties, scene ? scene->collection_properties : NULL);
}
/* Sync properties from scene to scene layer. */
- idproperty_reset(&view_layer->properties_evaluated, scene->layer_properties);
+ idproperty_reset(&view_layer->properties_evaluated, scene ? scene->layer_properties : NULL);
IDP_MergeGroup(view_layer->properties_evaluated, view_layer->properties, true);
/* TODO(sergey): Is it always required? */
view_layer->flag |= VIEW_LAYER_ENGINE_DIRTY;
}
+static const char *collection_type_lookup[] =
+{
+ "None", /* COLLECTION_TYPE_NONE */
+ "Group Internal", /* COLLECTION_TYPE_GROUP_INTERNAL */
+};
+
void BKE_layer_eval_layer_collection(const struct EvaluationContext *UNUSED(eval_ctx),
LayerCollection *layer_collection,
LayerCollection *parent_layer_collection)
{
- DEBUG_PRINT("%s on %s (%p), parent %s (%p)\n",
+ DEBUG_PRINT("%s on %s (%p) [%s], parent %s (%p) [%s]\n",
__func__,
layer_collection->scene_collection->name,
layer_collection->scene_collection,
+ collection_type_lookup[layer_collection->scene_collection->type],
(parent_layer_collection != NULL) ? parent_layer_collection->scene_collection->name : "NONE",
- (parent_layer_collection != NULL) ? parent_layer_collection->scene_collection : NULL);
+ (parent_layer_collection != NULL) ? parent_layer_collection->scene_collection : NULL,
+ (parent_layer_collection != NULL) ? collection_type_lookup[parent_layer_collection->scene_collection->type] : "");
+ BLI_assert(layer_collection != parent_layer_collection);
/* visibility */
layer_collection->flag_evaluated = layer_collection->flag;
diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c
index c0698849045..e25a354c8af 100644
--- a/source/blender/blenkernel/intern/library_query.c
+++ b/source/blender/blenkernel/intern/library_query.c
@@ -75,6 +75,7 @@
#include "BKE_collection.h"
#include "BKE_constraint.h"
#include "BKE_fcurve.h"
+#include "BKE_group.h"
#include "BKE_idprop.h"
#include "BKE_library.h"
#include "BKE_library_query.h"
@@ -772,10 +773,11 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
case ID_GR:
{
Group *group = (Group *) id;
- GroupObject *gob;
- for (gob = group->gobject.first; gob; gob = gob->next) {
- CALLBACK_INVOKE(gob->ob, IDWALK_CB_USER_ONE);
+ FOREACH_GROUP_OBJECT(group, object)
+ {
+ CALLBACK_INVOKE(object, IDWALK_CB_USER_ONE);
}
+ FOREACH_GROUP_OBJECT_END
break;
}
diff --git a/source/blender/blenkernel/intern/library_remap.c b/source/blender/blenkernel/intern/library_remap.c
index a3376dff98c..fb672cb8b9f 100644
--- a/source/blender/blenkernel/intern/library_remap.c
+++ b/source/blender/blenkernel/intern/library_remap.c
@@ -270,7 +270,7 @@ static void libblock_remap_data_preprocess_scene_object_unlink(
r_id_remap_data->skipped_refcounted++;
}
else {
- BKE_collections_object_remove(r_id_remap_data->bmain, sce, ob, false);
+ BKE_collections_object_remove(r_id_remap_data->bmain, &sce->id, ob, false);
if (!is_indirect) {
r_id_remap_data->status |= ID_REMAP_IS_LINKED_DIRECT;
}
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 5f12a5715ca..bea9e3bdcac 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -746,7 +746,7 @@ Object *BKE_object_add(
ob = object_add_common(bmain, view_layer, type, name);
layer_collection = BKE_layer_collection_get_active_ensure(scene, view_layer);
- BKE_collection_object_add(scene, layer_collection->scene_collection, ob);
+ BKE_collection_object_add(&scene->id, layer_collection->scene_collection, ob);
base = BKE_view_layer_base_find(view_layer, ob);
BKE_view_layer_base_select(view_layer, base);
diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c
index 85635cb7d77..a16acd9d564 100644
--- a/source/blender/blenkernel/intern/object_dupli.c
+++ b/source/blender/blenkernel/intern/object_dupli.c
@@ -50,8 +50,9 @@
#include "BKE_animsys.h"
#include "BKE_DerivedMesh.h"
#include "BKE_font.h"
-#include "BKE_group.h"
#include "BKE_global.h"
+#include "BKE_group.h"
+#include "BKE_idprop.h"
#include "BKE_lattice.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
@@ -143,7 +144,8 @@ static void copy_dupli_context(DupliContext *r_ctx, const DupliContext *ctx, Obj
*/
static DupliObject *make_dupli(const DupliContext *ctx,
Object *ob, float mat[4][4], int index,
- bool animated, bool hide)
+ bool animated, bool hide,
+ IDProperty *collection_properties)
{
DupliObject *dob;
int i;
@@ -198,6 +200,10 @@ static DupliObject *make_dupli(const DupliContext *ctx,
dob->random_id ^= BLI_hash_int(BLI_hash_string(ctx->object->id.name + 2));
}
+ if (collection_properties) {
+ dob->collection_properties = IDP_CopyProperty(collection_properties);
+ }
+
return dob;
}
@@ -238,23 +244,23 @@ static void make_child_duplis(const DupliContext *ctx, void *userdata, MakeChild
Object *obedit = ctx->scene->obedit;
if (ctx->group) {
- unsigned int lay = ctx->group->layer;
int groupid = 0;
- GroupObject *go;
- for (go = ctx->group->gobject.first; go; go = go->next, groupid++) {
- Object *ob = go->ob;
-
- if ((ob->lay & lay) && ob != obedit && is_child(ob, parent)) {
+ FOREACH_GROUP_BASE(ctx->group, base)
+ {
+ Object *ob = base->object;
+ if ((base->flag & BASE_VISIBLED) && ob != obedit && is_child(ob, parent)) {
DupliContext pctx;
copy_dupli_context(&pctx, ctx, ctx->object, NULL, groupid, false);
/* mballs have a different dupli handling */
- if (ob->type != OB_MBALL)
+ if (ob->type != OB_MBALL) {
ob->flag |= OB_DONE; /* doesnt render */
-
+ }
make_child_duplis_cb(&pctx, userdata, ob);
}
+ groupid++;
}
+ FOREACH_GROUP_BASE_END
}
else {
int baseid = 0;
@@ -281,13 +287,12 @@ static void make_child_duplis(const DupliContext *ctx, void *userdata, MakeChild
/* OB_DUPLIGROUP */
static void make_duplis_group(const DupliContext *ctx)
{
- bool for_render = (ctx->eval_ctx->mode == DAG_EVAL_RENDER);
Object *ob = ctx->object;
Group *group;
- GroupObject *go;
+ Base *base;
float group_mat[4][4];
int id;
- bool animated, hide;
+ bool animated;
if (ob->dup_group == NULL) return;
group = ob->dup_group;
@@ -309,34 +314,18 @@ static void make_duplis_group(const DupliContext *ctx)
animated = BKE_group_is_animated(group, ob);
- for (go = group->gobject.first, id = 0; go; go = go->next, id++) {
- /* note, if you check on layer here, render goes wrong... it still deforms verts and uses parent imat */
- if (go->ob != ob) {
+ for (base = group->view_layer->object_bases.first, id = 0; base; base = base->next, id++) {
+ if (base->object != ob && (base->flag & BASE_VISIBLED)) {
float mat[4][4];
- /* Special case for instancing dupli-groups, see: T40051
- * this object may be instanced via dupli-verts/faces, in this case we don't want to render
- * (blender convention), but _do_ show in the viewport.
- *
- * Regular objects work fine but not if we're instancing dupli-groups,
- * because the rules for rendering aren't applied to objects they instance.
- * We could recursively pass down the 'hide' flag instead, but that seems unnecessary.
- */
- if (for_render && go->ob->parent && go->ob->parent->transflag & (OB_DUPLIVERTS | OB_DUPLIFACES)) {
- continue;
- }
-
/* group dupli offset, should apply after everything else */
- mul_m4_m4m4(mat, group_mat, go->ob->obmat);
+ mul_m4_m4m4(mat, group_mat, base->object->obmat);
- /* check the group instance and object layers match, also that the object visible flags are ok. */
- hide = (go->ob->lay & group->layer) == 0 ||
- (for_render ? go->ob->restrictflag & OB_RESTRICT_RENDER : go->ob->restrictflag & OB_RESTRICT_VIEW);
-
- make_dupli(ctx, go->ob, mat, id, animated, hide);
+ BLI_assert(base->collection_properties != NULL);
+ make_dupli(ctx, base->object, mat, id, animated, false, base->collection_properties);
/* recursion */
- make_recursive_duplis(ctx, go->ob, group_mat, id, animated);
+ make_recursive_duplis(ctx, base->object, group_mat, id, animated);
}
}
}
@@ -399,7 +388,7 @@ static void make_duplis_frames(const DupliContext *ctx)
BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, (float)scene->r.cfra, ADT_RECALC_ANIM); /* ob-eval will do drivers, so we don't need to do them */
BKE_object_where_is_calc_time(ctx->eval_ctx, scene, ob, (float)scene->r.cfra);
- make_dupli(ctx, ob, ob->obmat, scene->r.cfra, false, false);
+ make_dupli(ctx, ob, ob->obmat, scene->r.cfra, false, false, NULL);
}
}
@@ -484,7 +473,7 @@ static void vertex_dupli__mapFunc(void *userData, int index, const float co[3],
*/
mul_m4_m4m4(space_mat, obmat, inst_ob->imat);
- dob = make_dupli(vdd->ctx, vdd->inst_ob, obmat, index, false, false);
+ dob = make_dupli(vdd->ctx, vdd->inst_ob, obmat, index, false, false, NULL);
if (vdd->orco)
copy_v3_v3(dob->orco, vdd->orco[index]);
@@ -669,7 +658,7 @@ static void make_duplis_font(const DupliContext *ctx)
copy_v3_v3(obmat[3], vec);
- make_dupli(ctx, ob, obmat, a, false, false);
+ make_dupli(ctx, ob, obmat, a, false, false, NULL);
}
}
@@ -775,7 +764,7 @@ static void make_child_duplis_faces(const DupliContext *ctx, void *userdata, Obj
*/
mul_m4_m4m4(space_mat, obmat, inst_ob->imat);
- dob = make_dupli(ctx, inst_ob, obmat, a, false, false);
+ dob = make_dupli(ctx, inst_ob, obmat, a, false, false, NULL);
if (use_texcoords) {
float w = 1.0f / (float)mp->totloop;
@@ -858,7 +847,6 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
bool for_render = ctx->eval_ctx->mode == DAG_EVAL_RENDER;
bool use_texcoords = ELEM(ctx->eval_ctx->mode, DAG_EVAL_RENDER, DAG_EVAL_PREVIEW);
- GroupObject *go;
Object *ob = NULL, **oblist = NULL, obcopy, *obcopylist = NULL;
DupliObject *dob;
ParticleDupliWeight *dw;
@@ -912,10 +900,10 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
return;
}
else { /*PART_DRAW_GR */
- if (part->dup_group == NULL || BLI_listbase_is_empty(&part->dup_group->gobject))
+ if (part->dup_group == NULL || BLI_listbase_is_empty(&part->dup_group->view_layer->object_bases))
return;
- if (BLI_findptr(&part->dup_group->gobject, par, offsetof(GroupObject, ob))) {
+ if (BLI_findptr(&part->dup_group->view_layer->object_bases, par, offsetof(Base, object))) {
return;
}
}
@@ -947,8 +935,12 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
totgroup += dw->count;
}
else {
- for (go = part->dup_group->gobject.first; go; go = go->next)
+ FOREACH_GROUP_OBJECT(part->dup_group, object)
+ {
+ (void) object;
totgroup++;
+ }
+ FOREACH_GROUP_OBJECT_END
}
/* we also copy the actual objects to restore afterwards, since
@@ -967,11 +959,18 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
}
}
else {
- go = part->dup_group->gobject.first;
- for (a = 0; a < totgroup; a++, go = go->next) {
- oblist[a] = go->ob;
- obcopylist[a] = *go->ob;
+ a = 0;
+ FOREACH_GROUP_OBJECT(part->dup_group, object)
+ {
+ oblist[a] = object;
+ obcopylist[a] = *object;
+ a++;
+
+ if (a >= totgroup) {
+ continue;
+ }
}
+ FOREACH_GROUP_OBJECT_END
}
}
else {
@@ -1060,23 +1059,33 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
}
if (part->ren_as == PART_DRAW_GR && psys->part->draw & PART_DRAW_WHOLE_GR) {
- for (go = part->dup_group->gobject.first, b = 0; go; go = go->next, b++) {
-
+ b = 0;
+ FOREACH_GROUP_OBJECT(part->dup_group, object)
+ {
copy_m4_m4(tmat, oblist[b]->obmat);
+
/* apply particle scale */
mul_mat3_m4_fl(tmat, size * scale);
mul_v3_fl(tmat[3], size * scale);
+
/* group dupli offset, should apply after everything else */
- if (!is_zero_v3(part->dup_group->dupli_ofs))
+ if (!is_zero_v3(part->dup_group->dupli_ofs)) {
sub_v3_v3(tmat[3], part->dup_group->dupli_ofs);
+ }
+
/* individual particle transform */
mul_m4_m4m4(mat, pamat, tmat);
- dob = make_dupli(ctx, go->ob, mat, a, false, false);
+ dob = make_dupli(ctx, object, mat, a, false, false, NULL);
dob->particle_system = psys;
- if (use_texcoords)
+
+ if (use_texcoords) {
psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco);
+ }
+
+ b++;
}
+ FOREACH_GROUP_OBJECT_END
}
else {
/* to give ipos in object correct offset */
@@ -1121,7 +1130,7 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
if (part->draw & PART_DRAW_GLOBAL_OB)
add_v3_v3v3(mat[3], mat[3], vec);
- dob = make_dupli(ctx, ob, mat, a, false, false);
+ dob = make_dupli(ctx, ob, mat, a, false, false, NULL);
dob->particle_system = psys;
if (use_texcoords)
psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco);
@@ -1238,6 +1247,14 @@ ListBase *object_duplilist(const EvaluationContext *eval_ctx, Scene *sce, Object
void free_object_duplilist(ListBase *lb)
{
+
+ for (DupliObject *dob = lb->first; dob; dob = dob->next) {
+ if (dob->collection_properties) {
+ IDP_FreeProperty(dob->collection_properties);
+ MEM_freeN(dob->collection_properties);
+ }
+ }
+
BLI_freelistN(lb);
MEM_freeN(lb);
}
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 209c7398d38..7d1c80dca41 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -327,18 +327,17 @@ bool psys_check_edited(ParticleSystem *psys)
void psys_check_group_weights(ParticleSettings *part)
{
ParticleDupliWeight *dw, *tdw;
- GroupObject *go;
int current = 0;
- if (part->ren_as == PART_DRAW_GR && part->dup_group && part->dup_group->gobject.first) {
+ if (part->ren_as == PART_DRAW_GR && part->dup_group && part->dup_group->view_layer->object_bases.first) {
/* First try to find NULL objects from their index,
* and remove all weights that don't have an object in the group. */
dw = part->dupliweights.first;
while (dw) {
if (dw->ob == NULL || !BKE_group_object_exists(part->dup_group, dw->ob)) {
- go = (GroupObject *)BLI_findlink(&part->dup_group->gobject, dw->index);
- if (go) {
- dw->ob = go->ob;
+ Base *base = BLI_findlink(&part->dup_group->view_layer->object_bases, dw->index);
+ if (base != NULL) {
+ dw->ob = base->object;
}
else {
tdw = dw->next;
@@ -352,21 +351,21 @@ void psys_check_group_weights(ParticleSettings *part)
}
/* then add objects in the group to new list */
- go = part->dup_group->gobject.first;
- while (go) {
+ FOREACH_GROUP_OBJECT(part->dup_group, object)
+ {
dw = part->dupliweights.first;
- while (dw && dw->ob != go->ob)
+ while (dw && dw->ob != object) {
dw = dw->next;
-
+ }
+
if (!dw) {
dw = MEM_callocN(sizeof(ParticleDupliWeight), "ParticleDupliWeight");
- dw->ob = go->ob;
+ dw->ob = object;
dw->count = 1;
BLI_addtail(&part->dupliweights, dw);
}
-
- go = go->next;
}
+ FOREACH_GROUP_OBJECT_END
dw = part->dupliweights.first;
for (; dw; dw = dw->next) {
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index f75b14579c7..bd4b817c8cd 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -57,6 +57,7 @@
#include "BKE_cdderivedmesh.h"
#include "BKE_effect.h"
#include "BKE_global.h"
+#include "BKE_group.h"
#include "BKE_library.h"
#include "BKE_library_query.h"
#include "BKE_mesh.h"
@@ -90,26 +91,30 @@ void BKE_rigidbody_free_world(RigidBodyWorld *rbw)
if (rbw->physics_world) {
/* free physics references, we assume that all physics objects in will have been added to the world */
- GroupObject *go;
if (rbw->constraints) {
- for (go = rbw->constraints->gobject.first; go; go = go->next) {
- if (go->ob && go->ob->rigidbody_constraint) {
- RigidBodyCon *rbc = go->ob->rigidbody_constraint;
-
- if (rbc->physics_constraint)
+ FOREACH_GROUP_OBJECT(rbw->constraints, object)
+ {
+ if (object->rigidbody_constraint) {
+ RigidBodyCon *rbc = object->rigidbody_constraint;
+ if (rbc->physics_constraint) {
RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint);
+ }
}
}
+ FOREACH_GROUP_OBJECT_END
}
- if (rbw->group) {
- for (go = rbw->group->gobject.first; go; go = go->next) {
- if (go->ob && go->ob->rigidbody_object) {
- RigidBodyOb *rbo = go->ob->rigidbody_object;
- if (rbo->physics_object)
+ if (rbw->group) {
+ FOREACH_GROUP_OBJECT(rbw->group, object)
+ {
+ if (object->rigidbody_object) {
+ RigidBodyOb *rbo = object->rigidbody_object;
+ if (rbo->physics_object) {
RB_dworld_remove_body(rbw->physics_world, rbo->physics_object);
+ }
}
}
+ FOREACH_GROUP_OBJECT_END
}
/* free dynamics world */
RB_dworld_delete(rbw->physics_world);
@@ -1124,7 +1129,6 @@ void BKE_rigidbody_remove_object(Scene *scene, Object *ob)
RigidBodyWorld *rbw = scene->rigidbody_world;
RigidBodyOb *rbo = ob->rigidbody_object;
RigidBodyCon *rbc;
- GroupObject *go;
int i;
if (rbw) {
@@ -1144,8 +1148,8 @@ void BKE_rigidbody_remove_object(Scene *scene, Object *ob)
/* remove object from rigid body constraints */
if (rbw->constraints) {
- for (go = rbw->constraints->gobject.first; go; go = go->next) {
- Object *obt = go->ob;
+ FOREACH_GROUP_OBJECT(rbw->constraints, obt)
+ {
if (obt && obt->rigidbody_constraint) {
rbc = obt->rigidbody_constraint;
if (ELEM(ob, rbc->ob1, rbc->ob2)) {
@@ -1153,6 +1157,7 @@ void BKE_rigidbody_remove_object(Scene *scene, Object *ob)
}
}
}
+ FOREACH_GROUP_OBJECT_END
}
}
@@ -1186,20 +1191,22 @@ void BKE_rigidbody_remove_constraint(Scene *scene, Object *ob)
/* Update object array and rigid body count so they're in sync with the rigid body group */
static void rigidbody_update_ob_array(RigidBodyWorld *rbw)
{
- GroupObject *go;
int i, n;
- n = BLI_listbase_count(&rbw->group->gobject);
+ n = BLI_listbase_count(&rbw->group->view_layer->object_bases);
if (rbw->numbodies != n) {
rbw->numbodies = n;
rbw->objects = realloc(rbw->objects, sizeof(Object *) * rbw->numbodies);
}
- for (go = rbw->group->gobject.first, i = 0; go; go = go->next, i++) {
- Object *ob = go->ob;
- rbw->objects[i] = ob;
+ i = 0;
+ FOREACH_GROUP_OBJECT(rbw->group, object)
+ {
+ rbw->objects[i] = object;
+ i++;
}
+ FOREACH_GROUP_OBJECT_END
}
static void rigidbody_update_sim_world(Scene *scene, RigidBodyWorld *rbw)
@@ -1313,8 +1320,6 @@ static void rigidbody_update_sim_ob(const struct EvaluationContext *eval_ctx, Sc
*/
static void rigidbody_update_simulation(const struct EvaluationContext *eval_ctx, Scene *scene, RigidBodyWorld *rbw, bool rebuild)
{
- GroupObject *go;
-
/* update world */
if (rebuild)
BKE_rigidbody_validate_sim_world(scene, rbw, true);
@@ -1327,24 +1332,22 @@ static void rigidbody_update_simulation(const struct EvaluationContext *eval_ctx
* Memory management needs redesign here, this is just a dirty workaround.
*/
if (rebuild && rbw->constraints) {
- for (go = rbw->constraints->gobject.first; go; go = go->next) {
- Object *ob = go->ob;
- if (ob) {
- RigidBodyCon *rbc = ob->rigidbody_constraint;
- if (rbc && rbc->physics_constraint) {
- RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint);
- RB_constraint_delete(rbc->physics_constraint);
- rbc->physics_constraint = NULL;
- }
+ FOREACH_GROUP_OBJECT(rbw->constraints, ob)
+ {
+ RigidBodyCon *rbc = ob->rigidbody_constraint;
+ if (rbc && rbc->physics_constraint) {
+ RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint);
+ RB_constraint_delete(rbc->physics_constraint);
+ rbc->physics_constraint = NULL;
}
}
+ FOREACH_GROUP_OBJECT_END
}
/* update objects */
- for (go = rbw->group->gobject.first; go; go = go->next) {
- Object *ob = go->ob;
-
- if (ob && ob->type == OB_MESH) {
+ FOREACH_GROUP_OBJECT(rbw->group, ob)
+ {
+ if (ob->type == OB_MESH) {
/* validate that we've got valid object set up here... */
RigidBodyOb *rbo = ob->rigidbody_object;
/* update transformation matrix of the object so we don't get a frame of lag for simple animations */
@@ -1385,62 +1388,59 @@ static void rigidbody_update_simulation(const struct EvaluationContext *eval_ctx
rigidbody_update_sim_ob(eval_ctx, scene, rbw, ob, rbo);
}
}
+ FOREACH_GROUP_OBJECT_END
/* update constraints */
if (rbw->constraints == NULL) /* no constraints, move on */
return;
- for (go = rbw->constraints->gobject.first; go; go = go->next) {
- Object *ob = go->ob;
- if (ob) {
- /* validate that we've got valid object set up here... */
- RigidBodyCon *rbc = ob->rigidbody_constraint;
- /* update transformation matrix of the object so we don't get a frame of lag for simple animations */
- BKE_object_where_is_calc(eval_ctx, scene, ob);
+ FOREACH_GROUP_OBJECT(rbw->constraints, ob)
+ {
+ /* validate that we've got valid object set up here... */
+ RigidBodyCon *rbc = ob->rigidbody_constraint;
+ /* update transformation matrix of the object so we don't get a frame of lag for simple animations */
+ BKE_object_where_is_calc(eval_ctx, scene, ob);
- if (rbc == NULL) {
- /* Since this object is included in the group but doesn't have
- * constraint settings (perhaps it was added manually), add!
- */
- ob->rigidbody_constraint = BKE_rigidbody_create_constraint(scene, ob, RBC_TYPE_FIXED);
- rigidbody_validate_sim_constraint(rbw, ob, true);
+ if (rbc == NULL) {
+ /* Since this object is included in the group but doesn't have
+ * constraint settings (perhaps it was added manually), add!
+ */
+ ob->rigidbody_constraint = BKE_rigidbody_create_constraint(scene, ob, RBC_TYPE_FIXED);
+ rigidbody_validate_sim_constraint(rbw, ob, true);
- rbc = ob->rigidbody_constraint;
+ rbc = ob->rigidbody_constraint;
+ }
+ else {
+ /* perform simulation data updates as tagged */
+ if (rebuild) {
+ /* World has been rebuilt so rebuild constraint */
+ rigidbody_validate_sim_constraint(rbw, ob, true);
}
- else {
- /* perform simulation data updates as tagged */
- if (rebuild) {
- /* World has been rebuilt so rebuild constraint */
- rigidbody_validate_sim_constraint(rbw, ob, true);
- }
- else if (rbc->flag & RBC_FLAG_NEEDS_VALIDATE) {
- rigidbody_validate_sim_constraint(rbw, ob, false);
- }
- rbc->flag &= ~RBC_FLAG_NEEDS_VALIDATE;
+ else if (rbc->flag & RBC_FLAG_NEEDS_VALIDATE) {
+ rigidbody_validate_sim_constraint(rbw, ob, false);
}
+ rbc->flag &= ~RBC_FLAG_NEEDS_VALIDATE;
}
}
+ FOREACH_GROUP_OBJECT_END
}
static void rigidbody_update_simulation_post_step(RigidBodyWorld *rbw)
{
- GroupObject *go;
-
- for (go = rbw->group->gobject.first; go; go = go->next) {
- Object *ob = go->ob;
-
- if (ob) {
- RigidBodyOb *rbo = ob->rigidbody_object;
- /* reset kinematic state for transformed objects */
- if (rbo && (ob->flag & SELECT) && (G.moving & G_TRANSFORM_OBJ)) {
- RB_body_set_kinematic_state(rbo->physics_object, rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED);
- RB_body_set_mass(rbo->physics_object, RBO_GET_MASS(rbo));
- /* deactivate passive objects so they don't interfere with deactivation of active objects */
- if (rbo->type == RBO_TYPE_PASSIVE)
- RB_body_deactivate(rbo->physics_object);
- }
+ FOREACH_GROUP_BASE(rbw->group, base)
+ {
+ Object *ob = base->object;
+ RigidBodyOb *rbo = ob->rigidbody_object;
+ /* Reset kinematic state for transformed objects. */
+ if (rbo && (base->flag & BASE_SELECTED) && (G.moving & G_TRANSFORM_OBJ)) {
+ RB_body_set_kinematic_state(rbo->physics_object, rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED);
+ RB_body_set_mass(rbo->physics_object, RBO_GET_MASS(rbo));
+ /* Deactivate passive objects so they don't interfere with deactivation of active objects. */
+ if (rbo->type == RBO_TYPE_PASSIVE)
+ RB_body_deactivate(rbo->physics_object);
}
}
+ FOREACH_GROUP_BASE_END
}
bool BKE_rigidbody_check_sim_running(RigidBodyWorld *rbw, float ctime)
@@ -1567,7 +1567,7 @@ void BKE_rigidbody_rebuild_world(const struct EvaluationContext *eval_ctx, Scene
cache = rbw->pointcache;
/* flag cache as outdated if we don't have a world or number of objects in the simulation has changed */
- if (rbw->physics_world == NULL || rbw->numbodies != BLI_listbase_count(&rbw->group->gobject)) {
+ if (rbw->physics_world == NULL || rbw->numbodies != BLI_listbase_count(&rbw->group->view_layer->object_bases)) {
cache->flag |= PTCACHE_OUTDATED;
}
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index ca31eed6552..b3d7e2affd3 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -151,89 +151,6 @@ static void remove_sequencer_fcurves(Scene *sce)
}
}
-/* copy SceneCollection tree but keep pointing to the same objects */
-static void scene_collection_copy(SceneCollection *sc_dst, SceneCollection *sc_src, const int flag)
-{
- BLI_duplicatelist(&sc_dst->objects, &sc_src->objects);
- if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
- for (LinkData *link = sc_dst->objects.first; link; link = link->next) {
- id_us_plus(link->data);
- }
- }
-
- BLI_duplicatelist(&sc_dst->filter_objects, &sc_src->filter_objects);
- if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
- for (LinkData *link = sc_dst->filter_objects.first; link; link = link->next) {
- id_us_plus(link->data);
- }
- }
-
- BLI_duplicatelist(&sc_dst->scene_collections, &sc_src->scene_collections);
- for (SceneCollection *nsc_src = sc_src->scene_collections.first, *nsc_dst = sc_dst->scene_collections.first;
- nsc_src;
- nsc_src = nsc_src->next, nsc_dst = nsc_dst->next)
- {
- scene_collection_copy(nsc_dst, nsc_src, flag);
- }
-}
-
-/* Find the equivalent SceneCollection in the new tree */
-static SceneCollection *scene_collection_from_new_tree(SceneCollection *sc_reference, SceneCollection *sc_dst, SceneCollection *sc_src)
-{
- if (sc_src == sc_reference) {
- return sc_dst;
- }
-
- for (SceneCollection *nsc_src = sc_src->scene_collections.first, *nsc_dst = sc_dst->scene_collections.first;
- nsc_src;
- nsc_src = nsc_src->next, nsc_dst = nsc_dst->next)
- {
- SceneCollection *found = scene_collection_from_new_tree(sc_reference, nsc_dst, nsc_src);
- if (found != NULL) {
- return found;
- }
- }
- return NULL;
-}
-
-static void layer_collections_sync_flags(ListBase *layer_collections_dst, const ListBase *layer_collections_src)
-{
- LayerCollection *layer_collection_dst = (LayerCollection *)layer_collections_dst->first;
- const LayerCollection *layer_collection_src = (const LayerCollection *)layer_collections_src->first;
- while (layer_collection_dst != NULL) {
- layer_collection_dst->flag = layer_collection_src->flag;
-
- if (layer_collection_dst->properties != NULL) {
- IDP_FreeProperty(layer_collection_dst->properties);
- MEM_SAFE_FREE(layer_collection_dst->properties);
- }
-
- if (layer_collection_src->properties != NULL) {
- layer_collection_dst->properties = IDP_CopyProperty(layer_collection_src->properties);
- }
-
- layer_collections_sync_flags(&layer_collection_dst->layer_collections,
- &layer_collection_src->layer_collections);
-
- layer_collection_dst = layer_collection_dst->next;
- layer_collection_src = layer_collection_src->next;
- }
-}
-
-
-/* recreate the LayerCollection tree */
-static void layer_collections_recreate(
- ViewLayer *view_layer_dst, ListBase *lb_src, SceneCollection *mc_dst, SceneCollection *mc_src)
-{
- for (LayerCollection *lc_src = lb_src->first; lc_src; lc_src = lc_src->next) {
- SceneCollection *sc_dst = scene_collection_from_new_tree(lc_src->scene_collection, mc_dst, mc_src);
- BLI_assert(sc_dst);
-
- /* instead of synchronizing both trees we simply re-create it */
- BKE_collection_link(view_layer_dst, sc_dst);
- }
-}
-
/**
* Only copy internal data of Scene ID from source to already allocated/initialized destination.
* You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
@@ -254,11 +171,11 @@ void BKE_scene_copy_data(Main *bmain, Scene *sce_dst, const Scene *sce_src, cons
/* layers and collections */
sce_dst->collection = MEM_dupallocN(sce_src->collection);
- SceneCollection *mc_src = BKE_collection_master(sce_src);
- SceneCollection *mc_dst = BKE_collection_master(sce_dst);
+ SceneCollection *mc_src = BKE_collection_master(&sce_src->id);
+ SceneCollection *mc_dst = BKE_collection_master(&sce_dst->id);
- /* recursively creates a new SceneCollection tree */
- scene_collection_copy(mc_dst, mc_src, flag_subdata);
+ /* Recursively creates a new SceneCollection tree. */
+ BKE_collection_copy_data(mc_dst, mc_src, flag_subdata);
IDPropertyTemplate val = {0};
BLI_duplicatelist(&sce_dst->view_layers, &sce_src->view_layers);
@@ -266,39 +183,7 @@ void BKE_scene_copy_data(Main *bmain, Scene *sce_dst, const Scene *sce_src, cons
view_layer_src;
view_layer_src = view_layer_src->next, view_layer_dst = view_layer_dst->next)
{
- if (view_layer_dst->id_properties != NULL) {
- view_layer_dst->id_properties = IDP_CopyProperty_ex(view_layer_dst->id_properties, flag_subdata);
- }
- BKE_freestyle_config_copy(&view_layer_dst->freestyle_config, &view_layer_src->freestyle_config, flag_subdata);
-
- view_layer_dst->stats = NULL;
- view_layer_dst->properties_evaluated = NULL;
- view_layer_dst->properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
- IDP_MergeGroup_ex(view_layer_dst->properties, view_layer_src->properties, true, flag_subdata);
-
- /* 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(&view_layer_dst->layer_collections);
- BLI_listbase_clear(&view_layer_dst->object_bases);
- BLI_listbase_clear(&view_layer_dst->drawdata);
-
- layer_collections_recreate(view_layer_dst, &view_layer_src->layer_collections, mc_dst, mc_src);
-
- /* Now we handle the syncing for visibility, selectability, ... */
- layer_collections_sync_flags(&view_layer_dst->layer_collections, &view_layer_src->layer_collections);
-
- Object *active_ob = OBACT(view_layer_src);
- for (Base *base_src = view_layer_src->object_bases.first, *base_dst = view_layer_dst->object_bases.first;
- base_src;
- base_src = base_src->next, base_dst = base_dst->next)
- {
- base_dst->flag = base_src->flag;
- base_dst->flag_legacy = base_src->flag_legacy;
-
- if (base_dst->object == active_ob) {
- view_layer_dst->basact = base_dst;
- }
- }
+ BKE_view_layer_copy_data(view_layer_dst, view_layer_src, mc_dst, mc_src, flag_subdata);
}
sce_dst->collection_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
@@ -659,7 +544,7 @@ void BKE_scene_free_ex(Scene *sce, const bool do_id_user)
}
/* Master Collection */
- BKE_collection_master_free(sce, do_id_user);
+ BKE_collection_master_free(&sce->id, do_id_user);
MEM_freeN(sce->collection);
sce->collection = NULL;
@@ -1092,7 +977,6 @@ void BKE_scene_set_background(Main *bmain, Scene *scene)
{
Object *ob;
Group *group;
- GroupObject *go;
/* check for cyclic sets, for reading old files but also for definite security (py?) */
BKE_scene_validate_setscene(bmain, scene);
@@ -1107,11 +991,11 @@ void BKE_scene_set_background(Main *bmain, Scene *scene)
/* group flags again */
for (group = bmain->group.first; group; group = group->id.next) {
- for (go = group->gobject.first; go; go = go->next) {
- if (go->ob) {
- go->ob->flag |= OB_FROMGROUP;
- }
+ FOREACH_GROUP_OBJECT(group, object)
+ {
+ object->flag |= OB_FROMGROUP;
}
+ FOREACH_GROUP_OBJECT_END
}
/* copy layers and flags from bases to objects */
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index d7d274f32b5..e3af77166a9 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -74,6 +74,7 @@ variables on the UI for now
#include "BKE_curve.h"
#include "BKE_effect.h"
#include "BKE_global.h"
+#include "BKE_group.h"
#include "BKE_modifier.h"
#include "BKE_softbody.h"
#include "BKE_pointcache.h"
@@ -520,29 +521,20 @@ static void ccd_build_deflector_hash(ViewLayer *view_layer, Group *group, Object
if (!hash) return;
+ /* Explicit collision group. */
if (group) {
- /* Explicit collision group */
- for (GroupObject *go = group->gobject.first; go; go = go->next) {
- ob = go->ob;
-
- if (ob == vertexowner || ob->type != OB_MESH)
- continue;
-
- ccd_build_deflector_hash_single(hash, ob);
- }
+ view_layer = group->view_layer;
}
- else {
- for (Base *base = FIRSTBASE(view_layer); base; base = base->next) {
- /*Only proceed for mesh object in same layer */
- if (base->object->type == OB_MESH) {
- ob = base->object;
- if ((vertexowner) && (ob == vertexowner)) {
- /* if vertexowner is given we don't want to check collision with owner object */
- continue;
- }
- ccd_build_deflector_hash_single(hash, ob);
+ for (Base *base = FIRSTBASE(view_layer); base; base = base->next) {
+ /* Only proceed for mesh object in same layer. */
+ if (base->object->type == OB_MESH) {
+ ob = base->object;
+ if (ob == vertexowner) {
+ /* If vertexowner is given we don't want to check collision with owner object. */
+ continue;
}
+ ccd_build_deflector_hash_single(hash, ob);
}
}
}
@@ -566,31 +558,23 @@ static void ccd_update_deflector_hash(ViewLayer *view_layer, Group *group, Objec
if ((!hash) || (!vertexowner)) return;
+ /* Explicit collision group. */
if (group) {
- /* Explicit collision group */
- for (GroupObject *go = group->gobject.first; go; go = go->next) {
- ob = go->ob;
+ view_layer = group->view_layer;
+ }
- if (ob == vertexowner || ob->type != OB_MESH)
+ for (Base *base = FIRSTBASE(view_layer); base; base = base->next) {
+ /* Only proceed for mesh object in same layer. */
+ if (base->object->type == OB_MESH) {
+ ob = base->object;
+ if (ob == vertexowner) {
+ /* If vertexowner is given we don't want to check collision with owner object. */
continue;
+ }
ccd_update_deflector_hash_single(hash, ob);
}
}
- else {
- for (Base *base = FIRSTBASE(view_layer); base; base = base->next) {
- /*Only proceed for mesh object in same layer */
- if (base->object->type == OB_MESH) {
- ob = base->object;
- if (ob == vertexowner) {
- /* if vertexowner is given we don't want to check collision with owner object */
- continue;
- }
-
- ccd_update_deflector_hash_single(hash, ob);
- }
- }
- }
}
@@ -979,29 +963,21 @@ static void free_softbody_intern(SoftBody *sb)
/**
* \note group overrides scene when not NULL.
*/
-static bool are_there_deflectors(ViewLayer *view_layer, Group *group)
+static bool are_there_deflectors(ViewLayer *view_layer)
{
- if (group) {
- for (GroupObject *go = group->gobject.first; go; go = go->next) {
- if (go->ob->pd && go->ob->pd->deflect)
+ for (Base *base = FIRSTBASE(view_layer); base; base = base->next) {
+ if (base->object->pd) {
+ if (base->object->pd->deflect)
return 1;
}
}
- else {
- for (Base *base = FIRSTBASE(view_layer); base; base = base->next) {
- if (base->object->pd) {
- if (base->object->pd->deflect)
- return 1;
- }
- }
- }
return 0;
}
static int query_external_colliders(ViewLayer *view_layer, Group *group)
{
- return(are_there_deflectors(view_layer, group));
+ return(are_there_deflectors(group != NULL ? group->view_layer : view_layer));
}
/* --- dependency information functions*/
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 323586b66b2..a91c83c68ef 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -253,6 +253,7 @@ static void *read_struct(FileData *fd, BHead *bh, const char *blockname);
static void direct_link_modifiers(FileData *fd, ListBase *lb);
static BHead *find_bhead_from_code_name(FileData *fd, const short idcode, const char *name);
static BHead *find_bhead_from_idname(FileData *fd, const char *idname);
+static void expand_scene_collection(FileData *fd, Main *mainvar, SceneCollection *sc);
static SceneCollection *get_scene_collection_active_or_create(struct Scene *scene, struct ViewLayer *view_layer, const short flag);
/* this function ensures that reports are printed,
@@ -5832,6 +5833,28 @@ static void lib_link_scene_collection(FileData *fd, Library *lib, SceneCollectio
}
}
+static void lib_link_view_layer(FileData *fd, Library *lib, ViewLayer *view_layer)
+{
+ /* tag scene layer to update for collection tree evaluation */
+ view_layer->flag |= VIEW_LAYER_ENGINE_DIRTY;
+
+ for (FreestyleModuleConfig *fmc = view_layer->freestyle_config.modules.first; fmc; fmc = fmc->next) {
+ fmc->script = newlibadr(fd, lib, fmc->script);
+ }
+
+ for (FreestyleLineSet *fls = view_layer->freestyle_config.linesets.first; fls; fls = fls->next) {
+ fls->linestyle = newlibadr_us(fd, lib, fls->linestyle);
+ fls->group = newlibadr_us(fd, lib, fls->group);
+ }
+
+ for (Base *base = view_layer->object_bases.first; base; base = base->next) {
+ /* we only bump the use count for the collection objects */
+ base->object = newlibadr(fd, lib, base->object);
+ base->flag |= BASE_DIRTY_ENGINE_SETTINGS;
+ base->collection_properties = NULL;
+ }
+}
+
static void lib_link_scene(FileData *fd, Main *main)
{
#ifdef USE_SETSCENE_CHECK
@@ -5980,24 +6003,7 @@ static void lib_link_scene(FileData *fd, Main *main)
lib_link_scene_collection(fd, sce->id.lib, sce->collection);
for (ViewLayer *view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) {
- /* tag scene layer to update for collection tree evaluation */
- view_layer->flag |= VIEW_LAYER_ENGINE_DIRTY;
-
- for (FreestyleModuleConfig *fmc = view_layer->freestyle_config.modules.first; fmc; fmc = fmc->next) {
- fmc->script = newlibadr(fd, sce->id.lib, fmc->script);
- }
-
- for (FreestyleLineSet *fls = view_layer->freestyle_config.linesets.first; fls; fls = fls->next) {
- fls->linestyle = newlibadr_us(fd, sce->id.lib, fls->linestyle);
- fls->group = newlibadr_us(fd, sce->id.lib, fls->group);
- }
-
- for (Base *base = view_layer->object_bases.first; base; base = base->next) {
- /* we only bump the use count for the collection objects */
- base->object = newlibadr(fd, sce->id.lib, base->object);
- base->flag |= BASE_DIRTY_ENGINE_SETTINGS;
- base->collection_properties = NULL;
- }
+ lib_link_view_layer(fd, sce->id.lib, view_layer);
}
#ifdef USE_SETSCENE_CHECK
@@ -6139,6 +6145,31 @@ static void direct_link_layer_collections(FileData *fd, ListBase *lb)
}
}
+static void direct_link_view_layer(FileData *fd, ViewLayer *view_layer)
+{
+ view_layer->stats = NULL;
+ link_list(fd, &view_layer->object_bases);
+ view_layer->basact = newdataadr(fd, view_layer->basact);
+ direct_link_layer_collections(fd, &view_layer->layer_collections);
+
+ if (view_layer->properties != NULL) {
+ view_layer->properties = newdataadr(fd, view_layer->properties);
+ BLI_assert(view_layer->properties != NULL);
+ IDP_DirectLinkGroup_OrFree(&view_layer->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ BKE_view_layer_engine_settings_validate_layer(view_layer);
+ }
+
+ view_layer->id_properties = newdataadr(fd, view_layer->id_properties);
+ IDP_DirectLinkGroup_OrFree(&view_layer->id_properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+
+ link_list(fd, &(view_layer->freestyle_config.modules));
+ link_list(fd, &(view_layer->freestyle_config.linesets));
+
+ view_layer->properties_evaluated = NULL;
+
+ BLI_listbase_clear(&view_layer->drawdata);
+}
+
/**
* Workspaces store a render layer pointer which can only be read after scene is read.
*/
@@ -6416,27 +6447,7 @@ static void direct_link_scene(FileData *fd, Scene *sce, Main *bmain)
/* insert into global old-new map for reading without UI (link_global accesses it again) */
link_glob_list(fd, &sce->view_layers);
for (view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) {
- view_layer->stats = NULL;
- link_list(fd, &view_layer->object_bases);
- view_layer->basact = newdataadr(fd, view_layer->basact);
- direct_link_layer_collections(fd, &view_layer->layer_collections);
-
- if (view_layer->properties != NULL) {
- view_layer->properties = newdataadr(fd, view_layer->properties);
- BLI_assert(view_layer->properties != NULL);
- IDP_DirectLinkGroup_OrFree(&view_layer->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
- BKE_view_layer_engine_settings_validate_layer(view_layer);
- }
-
- view_layer->id_properties = newdataadr(fd, view_layer->id_properties);
- IDP_DirectLinkGroup_OrFree(&view_layer->id_properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
-
- link_list(fd, &(view_layer->freestyle_config.modules));
- link_list(fd, &(view_layer->freestyle_config.linesets));
-
- view_layer->properties_evaluated = NULL;
-
- BLI_listbase_clear(&view_layer->drawdata);
+ direct_link_view_layer(fd, view_layer);
}
sce->collection_properties = newdataadr(fd, sce->collection_properties);
@@ -7781,30 +7792,61 @@ static void direct_link_group(FileData *fd, Group *group)
link_list(fd, &group->gobject);
group->preview = direct_link_preview_image(fd, group->preview);
+
+ /* This runs before the very first doversion. */
+ if (group->collection != NULL) {
+ group->collection = newdataadr(fd, group->collection);
+ direct_link_scene_collection(fd, group->collection);
+ }
+
+ if (group->view_layer != NULL) {
+ group->view_layer = newdataadr(fd, group->view_layer);
+ direct_link_view_layer(fd, group->view_layer);
+ }
}
static void lib_link_group(FileData *fd, Main *main)
{
for (Group *group = main->group.first; group; group = group->id.next) {
if (group->id.tag & LIB_TAG_NEED_LINK) {
+ group->id.tag &= ~LIB_TAG_NEED_LINK;
IDP_LibLinkProperty(group->id.properties, fd);
-
- bool add_us = false;
-
- for (GroupObject *go = group->gobject.first; go; go = go->next) {
- go->ob = newlibadr_real_us(fd, group->id.lib, go->ob);
- if (go->ob) {
- go->ob->flag |= OB_FROMGROUP;
- /* if group has an object, it increments user... */
- add_us = true;
+
+ if (group->view_layer == NULL) {
+ /* Old file, this is required for doversion. */
+ bool add_us = false;
+
+ GroupObject *go, *gon;
+ go = group->gobject.first;
+ while (go) {
+ gon = go->next;
+ go->ob = newlibadr_real_us(fd, group->id.lib, go->ob);
+ if (go->ob != NULL) {
+ go->ob->flag |= OB_FROMGROUP;
+ /* If group has an object, it increments user... */
+ add_us = true;
+ }
+ else {
+ /* Remove NULL objects. */
+ BLI_remlink(&group->gobject, go);
+ MEM_freeN(go);
+ }
+ go = gon;
}
+
+ if (add_us) {
+ id_us_ensure_real(&group->id);
+ }
+ /* The rest of the read code is only for new files, skip it. */
+ continue;
}
- if (add_us) {
+
+ lib_link_scene_collection(fd, group->id.lib, group->collection);
+ lib_link_view_layer(fd, group->id.lib, group->view_layer);
+
+ if (!BLI_listbase_is_empty(&group->view_layer->object_bases)) {
id_us_ensure_real(&group->id);
}
- BKE_group_object_unlink(group, NULL); /* removes NULL entries */
-
- group->id.tag &= ~LIB_TAG_NEED_LINK;
}
}
}
@@ -9407,6 +9449,11 @@ static void expand_group(FileData *fd, Main *mainvar, Group *group)
for (go = group->gobject.first; go; go = go->next) {
expand_doit(fd, mainvar, go->ob);
}
+
+ if (group->collection != NULL) {
+ expand_scene_collection(fd, mainvar, group->collection);
+ }
+
}
static void expand_key(FileData *fd, Main *mainvar, Key *key)
@@ -10233,7 +10280,7 @@ static void give_base_to_objects(
scene_collection = get_scene_collection_active_or_create(scene, view_layer, FILE_ACTIVE_COLLECTION);
}
- BKE_collection_object_add(scene, scene_collection, ob);
+ BKE_collection_object_add(&scene->id, scene_collection, ob);
base = BKE_view_layer_base_find(view_layer, ob);
BKE_scene_object_base_flag_sync_from_base(base);
@@ -10275,7 +10322,7 @@ static void give_base_to_groups(
ob = BKE_object_add_only_object(mainvar, OB_EMPTY, group->id.name + 2);
ob->type = OB_EMPTY;
- BKE_collection_object_add(scene, scene_collection, ob);
+ BKE_collection_object_add(&scene->id, scene_collection, ob);
base = BKE_view_layer_base_find(view_layer, ob);
if (base->flag & BASE_SELECTABLED) {
@@ -10369,7 +10416,7 @@ static SceneCollection *get_scene_collection_active_or_create(struct Scene *scen
lc = BKE_layer_collection_get_active_ensure(scene, view_layer);
}
else {
- SceneCollection *sc = BKE_collection_add(scene, NULL, NULL);
+ SceneCollection *sc = BKE_collection_add(&scene->id, NULL, COLLECTION_TYPE_NONE, NULL);
lc = BKE_collection_link(view_layer, sc);
}
@@ -10388,7 +10435,7 @@ static void link_object_postprocess(ID *id, Scene *scene, ViewLayer *view_layer,
ob->mode = OB_MODE_OBJECT;
sc = get_scene_collection_active_or_create(scene, view_layer, flag);
- BKE_collection_object_add(scene, sc, ob);
+ BKE_collection_object_add(&scene->id, sc, ob);
base = BKE_view_layer_base_find(view_layer, ob);
BKE_scene_object_base_flag_sync_from_base(base);
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index 3b5e248f58b..8f2295781bf 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -39,6 +39,7 @@
#include "DNA_object_types.h"
#include "DNA_camera_types.h"
#include "DNA_gpu_types.h"
+#include "DNA_group_types.h"
#include "DNA_lamp_types.h"
#include "DNA_layer_types.h"
#include "DNA_material_types.h"
@@ -52,6 +53,7 @@
#include "BKE_collection.h"
#include "BKE_customdata.h"
#include "BKE_freestyle.h"
+#include "BKE_group.h"
#include "BKE_idprop.h"
#include "BKE_layer.h"
#include "BKE_main.h"
@@ -171,7 +173,7 @@ void do_versions_after_linking_280(Main *main)
for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
/* since we don't have access to FileData we check the (always valid) first render layer instead */
if (scene->view_layers.first == NULL) {
- SceneCollection *sc_master = BKE_collection_master(scene);
+ SceneCollection *sc_master = BKE_collection_master(&scene->id);
BLI_strncpy(sc_master->name, "Master Collection", sizeof(sc_master->name));
struct DoVersionSceneCollections {
@@ -242,7 +244,7 @@ void do_versions_after_linking_280(Main *main)
layer + 1,
collections[DO_VERSION_COLLECTION_VISIBLE].suffix);
collections[DO_VERSION_COLLECTION_VISIBLE].collections[layer] =
- BKE_collection_add(scene, sc_master, name);
+ BKE_collection_add(&scene->id, sc_master, COLLECTION_TYPE_NONE, name);
collections[DO_VERSION_COLLECTION_VISIBLE].created |= (1 << layer);
}
@@ -254,12 +256,16 @@ void do_versions_after_linking_280(Main *main)
"Collection %d%s",
layer + 1,
collections[collection_index].suffix);
- collections[collection_index].collections[layer] = BKE_collection_add(scene, sc_parent, name);
+ collections[collection_index].collections[layer] = BKE_collection_add(
+ &scene->id,
+ sc_parent,
+ COLLECTION_TYPE_NONE,
+ name);
collections[collection_index].created |= (1 << layer);
}
}
- BKE_collection_object_add(scene, collections[collection_index].collections[layer], base->object);
+ BKE_collection_object_add(&scene->id, collections[collection_index].collections[layer], base->object);
}
if (base->flag & SELECT) {
@@ -542,6 +548,43 @@ void do_versions_after_linking_280(Main *main)
BLI_freelistN(&scene->r.layers);
}
}
+
+ {
+ /* Since we don't have access to FileData we check the (always valid) master collection of the group. */
+ for (Group *group = main->group.first; group; group = group->id.next) {
+ if (group->collection == NULL) {
+ BKE_group_init(group);
+ SceneCollection *sc = GROUP_MASTER_COLLECTION(group);
+ SceneCollection *sc_hidden = NULL;
+
+ for (GroupObject *go = group->gobject.first; go; go = go->next) {
+ if (go->ob->lay & group->layer){
+ BKE_collection_object_add(&group->id, sc, go->ob);
+ }
+ else {
+ if (sc_hidden == NULL) {
+ sc_hidden = BKE_collection_add(&group->id, sc, COLLECTION_TYPE_GROUP_INTERNAL, "Hidden");
+ }
+ BKE_collection_object_add(&group->id, sc_hidden, go->ob);
+ }
+ }
+
+ if (sc_hidden != NULL) {
+ LayerCollection *layer_collection_master, *layer_collection_hidden;
+
+ layer_collection_master = group->view_layer->layer_collections.first;
+ layer_collection_hidden = layer_collection_master->layer_collections.first;
+
+ layer_collection_hidden->flag &= ~COLLECTION_VISIBLE;
+ }
+ }
+
+ GroupObject *go;
+ while ((go = BLI_pophead(&group->gobject))) {
+ MEM_freeN(go);
+ }
+ }
+ }
}
static void do_version_layer_collections_idproperties(ListBase *lb)
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 08ec2231e38..36ce277e4cf 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -168,6 +168,7 @@
#include "BKE_curve.h"
#include "BKE_constraint.h"
#include "BKE_global.h" // for G
+#include "BKE_group.h"
#include "BKE_idcode.h"
#include "BKE_library.h" // for set_listbasepointers
#include "BKE_library_override.h"
@@ -1348,9 +1349,13 @@ static void write_particlesettings(WriteData *wd, ParticleSettings *part)
if (dw->ob != NULL) {
dw->index = 0;
if (part->dup_group) { /* can be NULL if lining fails or set to None */
- for (GroupObject *go = part->dup_group->gobject.first;
- go && go->ob != dw->ob;
- go = go->next, dw->index++);
+ FOREACH_GROUP_OBJECT(part->dup_group, object)
+ {
+ if (object != dw->ob) {
+ dw->index++;
+ }
+ }
+ FOREACH_GROUP_OBJECT_END
}
}
writestruct(wd, DATA, ParticleDupliWeight, 1, dw);
@@ -2612,6 +2617,28 @@ static void write_layer_collections(WriteData *wd, ListBase *lb)
}
}
+static void write_view_layer(WriteData *wd, ViewLayer *view_layer)
+{
+ writestruct(wd, DATA, ViewLayer, 1, view_layer);
+ writelist(wd, DATA, Base, &view_layer->object_bases);
+ if (view_layer->properties) {
+ IDP_WriteProperty(view_layer->properties, wd);
+ }
+
+ if (view_layer->id_properties) {
+ IDP_WriteProperty(view_layer->id_properties, wd);
+ }
+
+ for (FreestyleModuleConfig *fmc = view_layer->freestyle_config.modules.first; fmc; fmc = fmc->next) {
+ writestruct(wd, DATA, FreestyleModuleConfig, 1, fmc);
+ }
+
+ for (FreestyleLineSet *fls = view_layer->freestyle_config.linesets.first; fls; fls = fls->next) {
+ writestruct(wd, DATA, FreestyleLineSet, 1, fls);
+ }
+ write_layer_collections(wd, &view_layer->layer_collections);
+}
+
static void write_scene(WriteData *wd, Scene *sce)
{
/* write LibData */
@@ -2795,26 +2822,7 @@ static void write_scene(WriteData *wd, Scene *sce)
write_scene_collection(wd, sce->collection);
for (ViewLayer *view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) {
- writestruct(wd, DATA, ViewLayer, 1, view_layer);
- writelist(wd, DATA, Base, &view_layer->object_bases);
-
- if (view_layer->properties) {
- IDP_WriteProperty(view_layer->properties, wd);
- }
-
- if (view_layer->id_properties) {
- IDP_WriteProperty(view_layer->id_properties, wd);
- }
-
- for (FreestyleModuleConfig *fmc = view_layer->freestyle_config.modules.first; fmc; fmc = fmc->next) {
- writestruct(wd, DATA, FreestyleModuleConfig, 1, fmc);
- }
-
- for (FreestyleLineSet *fls = view_layer->freestyle_config.linesets.first; fls; fls = fls->next) {
- writestruct(wd, DATA, FreestyleLineSet, 1, fls);
- }
-
- write_layer_collections(wd, &view_layer->layer_collections);
+ write_view_layer(wd, view_layer);
}
if (sce->layer_properties) {
@@ -3233,10 +3241,8 @@ static void write_group(WriteData *wd, Group *group)
write_iddata(wd, &group->id);
write_previews(wd, group->preview);
-
- for (GroupObject *go = group->gobject.first; go; go = go->next) {
- writestruct(wd, DATA, GroupObject, 1, go);
- }
+ write_scene_collection(wd, group->collection);
+ write_view_layer(wd, group->view_layer);
}
}
diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp
index 8908d0e603f..d3e23f740c8 100644
--- a/source/blender/collada/DocumentImporter.cpp
+++ b/source/blender/collada/DocumentImporter.cpp
@@ -267,7 +267,7 @@ void DocumentImporter::finish()
std::vector<Object *>::iterator it;
for (it = libnode_ob.begin(); it != libnode_ob.end(); it++) {
Object *ob = *it;
- BKE_collections_object_remove(G.main, sce, ob, true);
+ BKE_collections_object_remove(G.main, &sce->id, ob, true);
}
libnode_ob.clear();
diff --git a/source/blender/collada/SceneExporter.cpp b/source/blender/collada/SceneExporter.cpp
index aa98f2ee96c..c375c09d869 100644
--- a/source/blender/collada/SceneExporter.cpp
+++ b/source/blender/collada/SceneExporter.cpp
@@ -26,6 +26,7 @@
extern "C" {
#include "BLI_utildefines.h"
+ #include "BKE_group.h"
#include "BKE_object.h"
#include "BLI_listbase.h"
}
@@ -177,12 +178,13 @@ void SceneExporter::writeNodes(const EvaluationContext *eval_ctx, Object *ob, Sc
// empty object
else if (ob->type == OB_EMPTY) { // TODO: handle groups (OB_DUPLIGROUP
if ((ob->transflag & OB_DUPLIGROUP) == OB_DUPLIGROUP && ob->dup_group) {
- GroupObject *go = NULL;
- Group *gr = ob->dup_group;
- /* printf("group detected '%s'\n", gr->id.name + 2); */
- for (go = (GroupObject *)(gr->gobject.first); go; go = go->next) {
- printf("\t%s\n", go->ob->id.name);
+ Group *group = ob->dup_group;
+ /* printf("group detected '%s'\n", group->id.name + 2); */
+ FOREACH_GROUP_OBJECT(group, object)
+ {
+ printf("\t%s\n", object->id.name);
}
+ FOREACH_GROUP_OBJECT_END
}
}
diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp
index 1a6f2675cc7..6a52027fb47 100644
--- a/source/blender/collada/collada_utils.cpp
+++ b/source/blender/collada/collada_utils.cpp
@@ -147,7 +147,7 @@ Object *bc_add_object(Scene *scene, int type, const char *name)
ViewLayer *view_layer = BKE_view_layer_context_active_PLACEHOLDER(scene);
LayerCollection *layer_collection = BKE_layer_collection_get_active_ensure(scene, view_layer);
- BKE_collection_object_add(scene, layer_collection->scene_collection, ob);
+ BKE_collection_object_add(&scene->id, layer_collection->scene_collection, ob);
Base *base = BKE_view_layer_base_find(view_layer, ob);
BKE_view_layer_base_select(view_layer, base);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index 18e9c01113d..d9634b525e1 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -428,9 +428,11 @@ void DepsgraphNodeBuilder::build_group(Group *group)
}
group_id->tag |= LIB_TAG_DOIT;
- LINKLIST_FOREACH (GroupObject *, go, &group->gobject) {
- build_object(NULL, go->ob, DEG_ID_LINKED_INDIRECTLY);
+ LINKLIST_FOREACH(Base *, base, &group->view_layer->object_bases) {
+ build_object(NULL, base->object, DEG_ID_LINKED_INDIRECTLY);
}
+
+ build_view_layer_collections(&group->id, group->view_layer);
}
void DepsgraphNodeBuilder::build_object(Base *base,
@@ -802,8 +804,8 @@ void DepsgraphNodeBuilder::build_rigidbody(Scene *scene)
/* objects - simulation participants */
if (rbw->group) {
- LINKLIST_FOREACH (GroupObject *, go, &rbw->group->gobject) {
- Object *object = go->ob;
+ LINKLIST_FOREACH (Base *, base, &rbw->group->view_layer->object_bases) {
+ Object *object = base->object;
if (!object || (object->type != OB_MESH))
continue;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
index 5c0a5054590..c9bdd194227 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
@@ -208,11 +208,13 @@ struct DepsgraphNodeBuilder {
int index;
LayerCollection *parent;
};
- void build_layer_collection(LayerCollection *layer_collection,
+ void build_layer_collection(ID *owner_id,
+ LayerCollection *layer_collection,
LayerCollectionState *state);
- void build_layer_collections(ListBase *layer_collections,
+ void build_layer_collections(ID *owner_id,
+ ListBase *layer_collections,
LayerCollectionState *state);
- void build_view_layer_collections(Scene *scene, ViewLayer *view_layer);
+ void build_view_layer_collections(ID *owner_id, ViewLayer *view_layer);
protected:
struct SavedEntryTag {
ID *id;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer_collection.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer_collection.cc
index 4d4bf2e4ffe..b34395e8a9a 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer_collection.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_layer_collection.cc
@@ -62,6 +62,7 @@ extern "C" {
namespace DEG {
void DepsgraphNodeBuilder::build_layer_collection(
+ ID *owner_id,
LayerCollection *layer_collection,
LayerCollectionState *state)
{
@@ -69,7 +70,7 @@ void DepsgraphNodeBuilder::build_layer_collection(
* Harmless but could be optimized.
*/
ComponentDepsNode *comp = add_component_node(
- &scene_->id,
+ owner_id,
DEG_NODE_TYPE_LAYER_COLLECTIONS);
add_operation_node(comp,
@@ -85,31 +86,32 @@ void DepsgraphNodeBuilder::build_layer_collection(
/* Recurs into nested layer collections. */
LayerCollection *parent = state->parent;
state->parent = layer_collection;
- build_layer_collections(&layer_collection->layer_collections, state);
+ build_layer_collections(owner_id, &layer_collection->layer_collections, state);
state->parent = parent;
}
-void DepsgraphNodeBuilder::build_layer_collections(ListBase *layer_collections,
+void DepsgraphNodeBuilder::build_layer_collections(ID *owner_id,
+ ListBase *layer_collections,
LayerCollectionState *state)
{
LINKLIST_FOREACH (LayerCollection *, layer_collection, layer_collections) {
- build_layer_collection(layer_collection, state);
+ build_layer_collection(owner_id, layer_collection, state);
}
}
void DepsgraphNodeBuilder::build_view_layer_collections(
- Scene *scene,
+ ID *owner_id,
ViewLayer *view_layer)
{
LayerCollectionState state;
state.index = 0;
ComponentDepsNode *comp = add_component_node(
- &scene_->id,
+ owner_id,
DEG_NODE_TYPE_LAYER_COLLECTIONS);
add_operation_node(comp,
function_bind(BKE_layer_eval_layer_collection_pre,
_1,
- scene,
+ owner_id,
view_layer),
DEG_OPCODE_VIEW_LAYER_INIT);
add_operation_node(comp,
@@ -118,7 +120,7 @@ void DepsgraphNodeBuilder::build_view_layer_collections(
view_layer),
DEG_OPCODE_VIEW_LAYER_DONE);
state.parent = NULL;
- build_layer_collections(&view_layer->layer_collections, &state);
+ build_layer_collections(owner_id, &view_layer->layer_collections, &state);
}
} // namespace DEG
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
index cf77b859b5c..a8325d34a27 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_view_layer.cc
@@ -157,7 +157,7 @@ void DepsgraphNodeBuilder::build_view_layer(
build_movieclip(clip);
}
/* Collections. */
- build_view_layer_collections(scene_cow, view_layer_cow);
+ build_view_layer_collections(&scene_cow->id, view_layer_cow);
/* Parameters evaluation for scene relations mainly. */
add_operation_node(&scene->id,
DEG_NODE_TYPE_PARAMETERS,
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index f2805cc9a7c..1b9f27932f5 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -413,14 +413,20 @@ void DepsgraphRelationBuilder::build_group(Object *object, Group *group)
OperationKey object_local_transform_key(&object->id,
DEG_NODE_TYPE_TRANSFORM,
DEG_OPCODE_TRANSFORM_LOCAL);
- LINKLIST_FOREACH (GroupObject *, go, &group->gobject) {
- if (!group_done) {
- build_object(NULL, go->ob);
+
+ if (!group_done) {
+ LINKLIST_FOREACH(Base *, base, &group->view_layer->object_bases) {
+ build_object(NULL, base->object);
}
- ComponentKey dupli_transform_key(&go->ob->id, DEG_NODE_TYPE_TRANSFORM);
+
+ build_view_layer_collections(&group->id, group->view_layer);
+ group_id->tag |= LIB_TAG_DOIT;
+ }
+
+ LINKLIST_FOREACH (Base *, base, &group->view_layer->object_bases) {
+ ComponentKey dupli_transform_key(&base->object->id, DEG_NODE_TYPE_TRANSFORM);
add_relation(dupli_transform_key, object_local_transform_key, "Dupligroup");
}
- group_id->tag |= LIB_TAG_DOIT;
}
void DepsgraphRelationBuilder::build_object(Base *base, Object *object)
@@ -1285,8 +1291,8 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene)
/* objects - simulation participants */
if (rbw->group) {
- LINKLIST_FOREACH (GroupObject *, go, &rbw->group->gobject) {
- Object *object = go->ob;
+ LINKLIST_FOREACH (Base *, base, &rbw->group->view_layer->object_bases) {
+ Object *object = base->object;
if (object == NULL || object->type != OB_MESH) {
continue;
}
@@ -1339,8 +1345,8 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene)
/* constraints */
if (rbw->constraints) {
- LINKLIST_FOREACH (GroupObject *, go, &rbw->constraints->gobject) {
- Object *object = go->ob;
+ LINKLIST_FOREACH (Base *, base, &rbw->constraints->view_layer->object_bases) {
+ Object *object = base->object;
if (object == NULL || !object->rigidbody_constraint) {
continue;
}
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
index 8fe98ae9901..569383fe479 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
@@ -249,11 +249,13 @@ struct DepsgraphRelationBuilder
OperationKey done_key;
OperationKey prev_key;
};
- void build_layer_collection(LayerCollection *layer_collection,
+ void build_layer_collection(ID *owner_id,
+ LayerCollection *layer_collection,
LayerCollectionState *state);
- void build_layer_collections(ListBase *layer_collections,
+ void build_layer_collections(ID *owner_id,
+ ListBase *layer_collections,
LayerCollectionState *state);
- void build_view_layer_collections(ViewLayer *view_layer);
+ void build_view_layer_collections(struct ID *owner_id, ViewLayer *view_layer);
void build_copy_on_write_relations();
void build_copy_on_write_relations(IDDepsNode *id_node);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_layer_collection.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_layer_collection.cc
index a7c70bfc098..0a8552ba747 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_layer_collection.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_layer_collection.cc
@@ -69,10 +69,11 @@ extern "C" {
namespace DEG {
void DepsgraphRelationBuilder::build_layer_collection(
+ ID *owner_id,
LayerCollection *layer_collection,
LayerCollectionState *state)
{
- OperationKey layer_key(&scene_->id,
+ OperationKey layer_key(owner_id,
DEG_NODE_TYPE_LAYER_COLLECTIONS,
DEG_OPCODE_VIEW_LAYER_EVAL,
layer_collection->scene_collection->name,
@@ -83,29 +84,31 @@ void DepsgraphRelationBuilder::build_layer_collection(
state->prev_key = layer_key;
/* Recurs into nested layer collections. */
- build_layer_collections(&layer_collection->layer_collections, state);
+ build_layer_collections(owner_id, &layer_collection->layer_collections, state);
}
void DepsgraphRelationBuilder::build_layer_collections(
+ ID *owner_id,
ListBase *layer_collections,
LayerCollectionState *state)
{
LINKLIST_FOREACH (LayerCollection *, layer_collection, layer_collections) {
/* Recurs into the layer. */
- build_layer_collection(layer_collection, state);
+ build_layer_collection(owner_id, layer_collection, state);
}
}
void DepsgraphRelationBuilder::build_view_layer_collections(
+ ID *owner_id,
ViewLayer *view_layer)
{
LayerCollectionState state;
state.index = 0;
- OperationKey init_key(&scene_->id,
+ OperationKey init_key(owner_id,
DEG_NODE_TYPE_LAYER_COLLECTIONS,
DEG_OPCODE_VIEW_LAYER_INIT);
- OperationKey done_key(&scene_->id,
+ OperationKey done_key(owner_id,
DEG_NODE_TYPE_LAYER_COLLECTIONS,
DEG_OPCODE_VIEW_LAYER_DONE);
@@ -113,7 +116,7 @@ void DepsgraphRelationBuilder::build_view_layer_collections(
state.done_key = done_key;
state.prev_key = init_key;
- build_layer_collections(&view_layer->layer_collections, &state);
+ build_layer_collections(owner_id, &view_layer->layer_collections, &state);
add_relation(state.prev_key, done_key, "Layer collection order");
}
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
index fe7ccf6a24c..1f105ee0823 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_view_layer.cc
@@ -112,7 +112,7 @@ void DepsgraphRelationBuilder::build_view_layer(Scene *scene, ViewLayer *view_la
build_movieclip(clip);
}
/* Collections. */
- build_view_layer_collections(view_layer);
+ build_view_layer_collections(&scene_->id, view_layer);
/* TODO(sergey): Do this flush on CoW object? */
foreach (OperationDepsNode *node, graph_->operations) {
IDDepsNode *id_node = node->owner->owner;
diff --git a/source/blender/depsgraph/intern/depsgraph_query_iter.cc b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
index d764ea47fea..d8a54642a85 100644
--- a/source/blender/depsgraph/intern/depsgraph_query_iter.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
@@ -36,6 +36,7 @@ extern "C" {
#include "BLI_utildefines.h"
#include "BLI_math.h"
#include "BKE_anim.h"
+#include "BKE_idprop.h"
#include "BKE_layer.h"
} /* extern "C" */
@@ -82,10 +83,10 @@ static bool deg_objects_dupli_iterator_next(BLI_Iterator *iter)
*temp_dupli_object = *dob->ob;
temp_dupli_object->select_color = dupli_parent->select_color;
temp_dupli_object->base_flag = dupli_parent->base_flag | BASE_FROMDUPLI;
- temp_dupli_object->base_collection_properties =
- dupli_parent->base_collection_properties;
+ BLI_assert(dob->collection_properties != NULL);
+ temp_dupli_object->base_collection_properties = dob->collection_properties;
+ IDP_MergeGroup(temp_dupli_object->base_collection_properties, dupli_parent->base_collection_properties, false);
copy_m4_m4(data->temp_dupli_object.obmat, dob->mat);
-
iter->current = &data->temp_dupli_object;
BLI_assert(
DEG::deg_validate_copy_on_write_datablock(
diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c
index fc3116d9bd2..1a210f071e0 100644
--- a/source/blender/editors/gpencil/gpencil_convert.c
+++ b/source/blender/editors/gpencil/gpencil_convert.c
@@ -1156,7 +1156,7 @@ static void gp_layer_to_curve(bContext *C, ReportList *reports, bGPdata *gpd, bG
*/
ob = BKE_object_add_only_object(bmain, OB_CURVE, gpl->info);
cu = ob->data = BKE_curve_add(bmain, gpl->info, OB_CURVE);
- BKE_collection_object_add(scene, sc, ob);
+ BKE_collection_object_add(&scene->id, sc, ob);
base_new = BKE_view_layer_base_find(view_layer, ob);
cu->flag |= CU_3D;
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 649e4c7f221..e8807432328 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -1221,7 +1221,7 @@ void ED_object_base_free_and_unlink(Main *bmain, Scene *scene, Object *ob)
DEG_id_tag_update_ex(bmain, &ob->id, DEG_TAG_BASE_FLAGS_UPDATE);
object_delete_check_glsl_update(ob);
- BKE_collections_object_remove(bmain, scene, ob, true);
+ BKE_collections_object_remove(bmain, &scene->id, ob, true);
}
static int object_delete_exec(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index fb1c7f04a95..8848b69a927 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -342,17 +342,15 @@ static int make_proxy_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Object *ob, *gob = ED_object_active_context(C);
- GroupObject *go;
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
if (gob->dup_group != NULL) {
- go = BLI_findlink(&gob->dup_group->gobject, RNA_enum_get(op->ptr, "object"));
- ob = go->ob;
+ Base *base = BLI_findlink(&gob->dup_group->view_layer->object_bases, RNA_enum_get(op->ptr, "object"));
+ ob = base->object;
}
else {
ob = gob;
- gob = NULL;
}
if (ob) {
@@ -397,17 +395,18 @@ static const EnumPropertyItem *proxy_group_object_itemf(bContext *C, PointerRNA
int totitem = 0;
int i = 0;
Object *ob = ED_object_active_context(C);
- GroupObject *go;
if (!ob || !ob->dup_group)
return DummyRNA_DEFAULT_items;
/* find the object to affect */
- for (go = ob->dup_group->gobject.first; go; go = go->next) {
- item_tmp.identifier = item_tmp.name = go->ob->id.name + 2;
+ FOREACH_GROUP_OBJECT(ob->dup_group, object)
+ {
+ item_tmp.identifier = item_tmp.name = object->id.name + 2;
item_tmp.value = i++;
RNA_enum_item_add(&item, &totitem, &item_tmp);
}
+ FOREACH_GROUP_OBJECT_END
RNA_enum_item_end(&item, &totitem);
*r_free = true;
@@ -1368,10 +1367,10 @@ static int make_links_scene_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- SceneCollection *sc_to = BKE_collection_master(scene_to);
+ SceneCollection *sc_to = BKE_collection_master(&scene_to->id);
CTX_DATA_BEGIN (C, Base *, base, selected_bases)
{
- BKE_collection_object_add(scene_to, sc_to, base->object);
+ BKE_collection_object_add(&scene_to->id, sc_to, base->object);
}
CTX_DATA_END;
@@ -1691,12 +1690,11 @@ static void single_object_users_scene_collection(Main *bmain, Scene *scene, Scen
static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const int flag, const bool copy_groups)
{
Group *group, *groupn;
- GroupObject *go;
clear_sca_new_poins(); /* BGE logic */
/* duplicate all the objects of the scene */
- SceneCollection *msc = BKE_collection_master(scene);
+ SceneCollection *msc = BKE_collection_master(&scene->id);
single_object_users_scene_collection(bmain, scene, msc, flag, copy_groups);
/* loop over ViewLayers and assign the pointers accordingly */
@@ -1708,22 +1706,26 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in
/* duplicate groups that consist entirely of duplicated objects */
for (group = bmain->group.first; group; group = group->id.next) {
- if (copy_groups && group->gobject.first) {
+ if (copy_groups && group->view_layer->object_bases.first) {
bool all_duplicated = true;
- for (go = group->gobject.first; go; go = go->next) {
- if (!(go->ob && (go->ob->id.newid))) {
+ FOREACH_GROUP_OBJECT(group, object)
+ {
+ if (object->id.newid == NULL) {
all_duplicated = false;
break;
}
}
+ FOREACH_GROUP_OBJECT_END
if (all_duplicated) {
groupn = ID_NEW_SET(group, BKE_group_copy(bmain, group));
- for (go = groupn->gobject.first; go; go = go->next) {
- go->ob = (Object *)go->ob->id.newid;
+ FOREACH_GROUP_BASE(groupn, base)
+ {
+ base->object = (Object *)base->object->id.newid;
}
+ FOREACH_GROUP_BASE_END
}
}
}
@@ -2151,7 +2153,7 @@ static bool make_local_all__instance_indirect_unused(Main *bmain, Scene *scene,
id_us_plus(&ob->id);
- BKE_collection_object_add(scene, sc, ob);
+ BKE_collection_object_add(&scene->id, sc, ob);
base = BKE_view_layer_base_find(view_layer, ob);
base->flag |= BASE_SELECTED;
BKE_scene_object_base_flag_sync_from_base(base);
diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c
index 53709e4cea7..3cf833756ef 100644
--- a/source/blender/editors/space_info/info_stats.c
+++ b/source/blender/editors/space_info/info_stats.c
@@ -270,6 +270,39 @@ static void stats_object_sculpt_dynamic_topology(Object *ob, SceneStats *stats)
stats->tottri = ob->sculpt->bm->totface;
}
+static void stats_dupli_object_group_count(SceneCollection *scene_collection, int *count)
+{
+ for (LinkData *link = scene_collection->objects.first; link; link = link->next) {
+ (*count)++;
+ }
+
+ SceneCollection *scene_collection_nested;
+ for (scene_collection_nested = scene_collection->scene_collections.first;
+ scene_collection_nested;
+ scene_collection_nested = scene_collection_nested->next)
+ {
+ stats_dupli_object_group_count(scene_collection_nested, count);
+ }
+}
+
+static void stats_dupli_object_group_doit(SceneCollection *scene_collection, SceneStats *stats, ParticleSystem *psys,
+ const int totgroup, int *cur)
+{
+ for (LinkData *link = scene_collection->objects.first; link; link = link->next) {
+ int tot = count_particles_mod(psys, totgroup, *cur);
+ stats_object(link->data, 0, tot, stats);
+ (*cur)++;
+ }
+
+ SceneCollection *scene_collection_nested;
+ for (scene_collection_nested = scene_collection->scene_collections.first;
+ scene_collection_nested;
+ scene_collection_nested = scene_collection_nested->next)
+ {
+ stats_dupli_object_group_doit(scene_collection_nested, stats, psys, totgroup, cur);
+ }
+}
+
static void stats_dupli_object(Base *base, Object *ob, SceneStats *stats)
{
if (base->flag & BASE_SELECTED) stats->totobjsel++;
@@ -287,17 +320,11 @@ static void stats_dupli_object(Base *base, Object *ob, SceneStats *stats)
stats_object(part->dup_ob, 0, tot, stats);
}
else if (part->draw_as == PART_DRAW_GR && part->dup_group) {
- GroupObject *go;
- int tot, totgroup = 0, cur = 0;
-
- for (go = part->dup_group->gobject.first; go; go = go->next)
- totgroup++;
-
- for (go = part->dup_group->gobject.first; go; go = go->next) {
- tot = count_particles_mod(psys, totgroup, cur);
- stats_object(go->ob, 0, tot, stats);
- cur++;
- }
+ int totgroup = 0, cur = 0;
+
+ SceneCollection *scene_collection = part->dup_group->collection;
+ stats_dupli_object_group_count(scene_collection, &totgroup);
+ stats_dupli_object_group_doit(scene_collection, stats, psys, totgroup, &cur);
}
}
diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c
index adf7e1dc5d3..a32a9c5f523 100644
--- a/source/blender/editors/space_outliner/outliner_collections.c
+++ b/source/blender/editors/space_outliner/outliner_collections.c
@@ -36,6 +36,8 @@
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
+#include "DNA_group_types.h"
+
#include "ED_screen.h"
#include "WM_api.h"
@@ -110,7 +112,7 @@ static int collection_link_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
- SceneCollection *sc_master = BKE_collection_master(scene);
+ SceneCollection *sc_master = BKE_collection_master(&scene->id);
SceneCollection *sc;
int scene_collection_index = RNA_enum_get(op->ptr, "scene_collection");
@@ -136,7 +138,9 @@ static int collection_link_exec(bContext *C, wmOperator *op)
static int collection_link_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (BKE_collection_master(CTX_data_scene(C))->scene_collections.first == NULL) {
+ Scene *scene = CTX_data_scene(C);
+ SceneCollection *master_collection = BKE_collection_master(&scene->id);
+ if (master_collection->scene_collections.first == NULL) {
RNA_enum_set(op->ptr, "scene_collection", 0);
return collection_link_exec(C, op);
}
@@ -169,7 +173,7 @@ static const EnumPropertyItem *collection_scene_collection_itemf(
int value = 0, totitem = 0;
Scene *scene = CTX_data_scene(C);
- SceneCollection *sc = BKE_collection_master(scene);
+ SceneCollection *sc = BKE_collection_master(&scene->id);
collection_scene_collection_itemf_recursive(&tmp, &item, &totitem, &value, sc);
RNA_enum_item_end(&item, &totitem);
@@ -257,15 +261,18 @@ void OUTLINER_OT_collection_unlink(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/**********************************************************************************/
+/* Add new collection. */
+
static int collection_new_exec(bContext *C, wmOperator *UNUSED(op))
{
+ Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
+ SceneCollection *scene_collection = BKE_collection_add(&scene->id, NULL, COLLECTION_TYPE_NONE, NULL);
+ BKE_collection_link(view_layer, scene_collection);
- SceneCollection *sc = BKE_collection_add(scene, NULL, NULL);
- BKE_collection_link(view_layer, sc);
-
- DEG_relations_tag_update(CTX_data_main(C));
+ DEG_relations_tag_update(bmain);
WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
return OPERATOR_FINISHED;
}
@@ -275,7 +282,7 @@ void OUTLINER_OT_collection_new(wmOperatorType *ot)
/* identifiers */
ot->name = "New Collection";
ot->idname = "OUTLINER_OT_collection_new";
- ot->description = "Add a new collection to the scene, and link it to the active layer";
+ ot->description = "Add a new collection to the scene";
/* api callbacks */
ot->exec = collection_new_exec;
@@ -284,6 +291,8 @@ void OUTLINER_OT_collection_new(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/**********************************************************************************/
+
/**
* Returns true is selected element is a collection
*/
@@ -336,12 +345,12 @@ static TreeTraversalAction collection_delete_cb(TreeElement *te, void *customdat
return TRAVERSE_SKIP_CHILDS;
}
- if (scene_collection == BKE_collection_master(data->scene)) {
+ if (scene_collection == BKE_collection_master(&data->scene->id)) {
/* skip - showing warning/error message might be missleading
* when deleting multiple collections, so just do nothing */
}
else {
- BKE_collection_remove(data->scene, scene_collection);
+ BKE_collection_remove(&data->scene->id, scene_collection);
}
return TRAVERSE_CONTINUE;
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 8b4ed61f148..4ac5ad6e8d2 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -250,9 +250,16 @@ static void restrictbutton_gp_layer_flag_cb(bContext *C, void *UNUSED(poin), voi
static void enablebutton_collection_flag_cb(bContext *C, void *poin, void *poin2)
{
Main *bmain = CTX_data_main(C);
- Scene *scene = poin;
+ Scene *scene = CTX_data_scene(C);
+ ID *id = poin;
LayerCollection *layer_collection = poin2;
- ViewLayer *view_layer = BKE_view_layer_find_from_collection(scene, layer_collection);
+ ViewLayer *view_layer = BKE_view_layer_find_from_collection(id, layer_collection);
+
+ /* TODO: This breaks when you see the collections of a group. (dfelinto) */
+ if (view_layer == NULL) {
+ WM_reportf(RPT_INFO, "Enable/disable of group collections disabled for now");
+ return;
+ }
/* We need to toggle the flag since this is called after the flag is already set. */
layer_collection->flag ^= COLLECTION_DISABLED;
@@ -273,11 +280,16 @@ static void enablebutton_collection_flag_cb(bContext *C, void *poin, void *poin2
static void restrictbutton_collection_flag_cb(bContext *C, void *poin, void *UNUSED(poin2))
{
- Scene *scene = poin;
+ ID *id = (ID *)poin;
+
/* hide and deselect bases that are directly influenced by this LayerCollection */
/* TODO(sergey): Use proper flag for tagging here. */
- DEG_id_tag_update(&scene->id, 0);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ DEG_id_tag_update(id, 0);
+
+ if (GS(id->name) == ID_SCE) {
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, id);
+ }
+
WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, NULL);
}
@@ -595,22 +607,24 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_ENABLEX), te->ys, UI_UNIT_X,
UI_UNIT_Y, &collection->flag, 0, 0, 0, 0,
TIP_("Enable/Disable collection from depsgraph"));
- UI_but_func_set(bt, enablebutton_collection_flag_cb, scene, collection);
+ UI_but_func_set(bt, enablebutton_collection_flag_cb, tselem->id, collection);
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
bt = uiDefIconButBitS(block, UI_BTYPE_ICON_TOGGLE_N, COLLECTION_VISIBLE, 0, ICON_RESTRICT_VIEW_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X,
UI_UNIT_Y, &collection->flag, 0, 0, 0, 0,
TIP_("Restrict/Allow 3D View visibility of objects in the collection"));
- UI_but_func_set(bt, restrictbutton_collection_flag_cb, scene, collection);
+ UI_but_func_set(bt, restrictbutton_collection_flag_cb, tselem->id, collection);
UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
- bt = uiDefIconButBitS(block, UI_BTYPE_ICON_TOGGLE_N, COLLECTION_SELECTABLE, 0, ICON_RESTRICT_SELECT_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X,
- UI_UNIT_Y, &collection->flag, 0, 0, 0, 0,
- TIP_("Restrict/Allow 3D View selection of objects in the collection"));
- UI_but_func_set(bt, restrictbutton_collection_flag_cb, scene, collection);
- UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ if (collection->scene_collection->type == COLLECTION_TYPE_NONE) {
+ bt = uiDefIconButBitS(block, UI_BTYPE_ICON_TOGGLE_N, COLLECTION_SELECTABLE, 0, ICON_RESTRICT_SELECT_OFF,
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X,
+ UI_UNIT_Y, &collection->flag, 0, 0, 0, 0,
+ TIP_("Restrict/Allow 3D View selection of objects in the collection"));
+ UI_but_func_set(bt, restrictbutton_collection_flag_cb, scene, collection);
+ UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK);
+ }
UI_block_emboss_set(block, UI_EMBOSS);
}
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index 4858b6cb120..8cd76179f23 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -274,7 +274,7 @@ static void do_item_rename(const Scene *scene, ARegion *ar, TreeElement *te, Tre
BKE_report(reports, RPT_WARNING, "Cannot edit sequence name");
}
else if (ELEM(tselem->type, TSE_LAYER_COLLECTION, TSE_SCENE_COLLECTION)) {
- SceneCollection *master = BKE_collection_master(scene);
+ SceneCollection *master = BKE_collection_master(&scene->id);
if ((tselem->type == TSE_SCENE_COLLECTION && te->directdata == master) ||
(((LayerCollection *)te->directdata)->scene_collection == master))
@@ -1940,7 +1940,7 @@ static int parent_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
BLI_assert(scene);
RNA_string_get(op->ptr, "child", childname);
ob = (Object *)BKE_libblock_find_name(ID_OB, childname);
- BKE_collection_object_add(scene, sc, ob);
+ BKE_collection_object_add(&scene->id, sc, ob);
DEG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
@@ -2166,13 +2166,13 @@ static int scene_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
SceneCollection *sc;
if (scene != CTX_data_scene(C)) {
/* when linking to an inactive scene link to the master collection */
- sc = BKE_collection_master(scene);
+ sc = BKE_collection_master(&scene->id);
}
else {
sc = CTX_data_scene_collection(C);
}
- BKE_collection_object_add(scene, sc, ob);
+ BKE_collection_object_add(&scene->id, sc, ob);
for (ViewLayer *view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
Base *base = BKE_view_layer_base_find(view_layer, ob);
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index 23e1b766891..f69eb9af1bf 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -67,9 +67,8 @@ typedef enum TreeTraversalAction {
/**
* Callback type for reinserting elements at a different position, used to allow user customizable element order.
- * Passing scene right now, may be better to allow some custom data.
*/
-typedef void (*TreeElementReinsertFunc)(struct Main *bmain, const struct Scene *scene,
+typedef void (*TreeElementReinsertFunc)(struct Main *bmain,
struct TreeElement *insert_element,
struct TreeElement *insert_handle, TreeElementInsertType action);
/**
@@ -77,7 +76,7 @@ typedef void (*TreeElementReinsertFunc)(struct Main *bmain, const struct Scene *
* if reinserting insert_element before/after/into insert_handle would be allowed.
* It's allowed to change the reinsert info here for non const pointers.
*/
-typedef bool (*TreeElementReinsertPollFunc)(const struct Scene *scene, const struct TreeElement *insert_element,
+typedef bool (*TreeElementReinsertPollFunc)(const struct TreeElement *insert_element,
struct TreeElement **io_insert_handle, TreeElementInsertType *io_action);
typedef TreeTraversalAction (*TreeTraversalFunc)(struct TreeElement *te, void *customdata);
diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c
index aa6a5dba6a7..856dd022c14 100644
--- a/source/blender/editors/space_outliner/outliner_ops.c
+++ b/source/blender/editors/space_outliner/outliner_ops.c
@@ -58,7 +58,7 @@ static int outliner_item_drag_drop_poll(bContext *C)
SpaceOops *soops = CTX_wm_space_outliner(C);
return ED_operator_outliner_active(C) &&
/* Only collection display modes supported for now. Others need more design work */
- ELEM(soops->outlinevis, SO_ACT_LAYER, SO_COLLECTIONS);
+ ELEM(soops->outlinevis, SO_ACT_LAYER, SO_COLLECTIONS, SO_GROUPS);
}
static TreeElement *outliner_item_drag_element_find(SpaceOops *soops, ARegion *ar, const wmEvent *event)
@@ -138,7 +138,7 @@ static void outliner_item_drag_get_insert_data(
}
static void outliner_item_drag_handle(
- const Scene *scene, SpaceOops *soops, ARegion *ar, const wmEvent *event, TreeElement *te_dragged)
+ SpaceOops *soops, ARegion *ar, const wmEvent *event, TreeElement *te_dragged)
{
TreeElement *te_insert_handle;
TreeElementInsertType insert_type;
@@ -156,7 +156,7 @@ static void outliner_item_drag_handle(
/* nothing will happen anyway, no need to do poll check */
}
else if (!te_dragged->reinsert_poll ||
- !te_dragged->reinsert_poll(scene, te_dragged, &te_insert_handle, &insert_type))
+ !te_dragged->reinsert_poll(te_dragged, &te_insert_handle, &insert_type))
{
te_insert_handle = NULL;
}
@@ -164,7 +164,7 @@ static void outliner_item_drag_handle(
te_dragged->drag_data->insert_handle = te_insert_handle;
}
-static bool outliner_item_drag_drop_apply(Main *bmain, const Scene *scene, TreeElement *dragged_te)
+static bool outliner_item_drag_drop_apply(Main *bmain, TreeElement *dragged_te)
{
TreeElement *insert_handle = dragged_te->drag_data->insert_handle;
TreeElementInsertType insert_type = dragged_te->drag_data->insert_type;
@@ -173,12 +173,12 @@ static bool outliner_item_drag_drop_apply(Main *bmain, const Scene *scene, TreeE
/* No need to do anything */
}
else if (dragged_te->reinsert) {
- BLI_assert(!dragged_te->reinsert_poll || dragged_te->reinsert_poll(scene, dragged_te, &insert_handle,
+ BLI_assert(!dragged_te->reinsert_poll || dragged_te->reinsert_poll(dragged_te, &insert_handle,
&insert_type));
/* call of assert above should not have changed insert_handle and insert_type at this point */
BLI_assert(dragged_te->drag_data->insert_handle == insert_handle &&
dragged_te->drag_data->insert_type == insert_type);
- dragged_te->reinsert(bmain, scene, dragged_te, insert_handle, insert_type);
+ dragged_te->reinsert(bmain, dragged_te, insert_handle, insert_type);
return true;
}
@@ -188,7 +188,6 @@ static bool outliner_item_drag_drop_apply(Main *bmain, const Scene *scene, TreeE
static int outliner_item_drag_drop_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
ARegion *ar = CTX_wm_region(C);
SpaceOops *soops = CTX_wm_space_outliner(C);
TreeElement *te_dragged = op->customdata;
@@ -199,7 +198,7 @@ static int outliner_item_drag_drop_modal(bContext *C, wmOperator *op, const wmEv
switch (event->type) {
case EVT_MODAL_MAP:
if (event->val == OUTLINER_ITEM_DRAG_CONFIRM) {
- if (outliner_item_drag_drop_apply(bmain, scene, te_dragged)) {
+ if (outliner_item_drag_drop_apply(bmain, te_dragged)) {
skip_rebuild = false;
}
retval = OPERATOR_FINISHED;
@@ -215,7 +214,7 @@ static int outliner_item_drag_drop_modal(bContext *C, wmOperator *op, const wmEv
redraw = true;
break;
case MOUSEMOVE:
- outliner_item_drag_handle(scene, soops, ar, event, te_dragged);
+ outliner_item_drag_handle(soops, ar, event, te_dragged);
redraw = true;
break;
}
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index 5215efaa05c..70d01007d89 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -44,6 +44,7 @@
#include "BLI_listbase.h"
#include "BKE_context.h"
+#include "BKE_group.h"
#include "BKE_object.h"
#include "BKE_layer.h"
#include "BKE_scene.h"
@@ -784,9 +785,11 @@ static eOLDrawState tree_element_active_collection(
LayerCollection *lc = te->directdata;
const int collection_index = BKE_layer_collection_findindex(view_layer, lc);
- BLI_assert(collection_index >= 0);
- view_layer->active_collection = collection_index;
- WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+ /* If the collection is part of a group we don't change active collection. */
+ if (collection_index > -1) {
+ view_layer->active_collection = collection_index;
+ WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
+ }
}
return OL_DRAWSEL_NONE;
@@ -906,26 +909,30 @@ static void do_outliner_item_activate_tree_element(
}
else if (te->idcode == ID_GR) {
Group *gr = (Group *)tselem->id;
- GroupObject *gob;
if (extend) {
int sel = BA_SELECT;
- for (gob = gr->gobject.first; gob; gob = gob->next) {
- if (gob->ob->flag & SELECT) {
+ FOREACH_GROUP_BASE(gr, base)
+ {
+ if (base->flag & BASE_SELECTED) {
sel = BA_DESELECT;
break;
}
}
+ FOREACH_GROUP_BASE_END
- for (gob = gr->gobject.first; gob; gob = gob->next) {
- ED_object_base_select(BKE_view_layer_base_find(view_layer, gob->ob), sel);
+ FOREACH_GROUP_OBJECT(gr, object)
+ {
+ ED_object_base_select(BKE_view_layer_base_find(view_layer, object), sel);
}
+ FOREACH_GROUP_OBJECT_END
}
else {
BKE_view_layer_base_deselect_all(view_layer);
- for (gob = gr->gobject.first; gob; gob = gob->next) {
- Base *base = BKE_view_layer_base_find(view_layer, gob->ob);
+ FOREACH_GROUP_OBJECT(gr, object)
+ {
+ Base *base = BKE_view_layer_base_find(view_layer, object);
/* Object may not be in this scene */
if (base != NULL) {
if ((base->flag & BASE_SELECTED) == 0) {
@@ -933,6 +940,7 @@ static void do_outliner_item_activate_tree_element(
}
}
}
+ FOREACH_GROUP_OBJECT_END
}
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index 63e1a527138..203942b3c9b 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -525,20 +525,21 @@ static void group_linkobs2scene_cb(
ViewLayer *view_layer = CTX_data_view_layer(C);
SceneCollection *sc = CTX_data_scene_collection(C);
Group *group = (Group *)tselem->id;
- GroupObject *gob;
Base *base;
- for (gob = group->gobject.first; gob; gob = gob->next) {
- base = BKE_view_layer_base_find(view_layer, gob->ob);
+ FOREACH_GROUP_OBJECT(group, object)
+ {
+ base = BKE_view_layer_base_find(view_layer, object);
if (!base) {
/* link to scene */
- BKE_collection_object_add(scene, sc, gob->ob);
- base = BKE_view_layer_base_find(view_layer, gob->ob);
- id_us_plus(&gob->ob->id);
+ BKE_collection_object_add(&scene->id, sc, object);
+ base = BKE_view_layer_base_find(view_layer, object);
+ id_us_plus(&object->id);
}
base->flag |= BASE_SELECTED;
}
+ FOREACH_GROUP_OBJECT_END
}
static void group_instance_cb(
@@ -820,12 +821,13 @@ static void collection_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tsel
bContext *C = (bContext *)Carg;
Scene *scene = CTX_data_scene(C);
LayerCollection *lc = te->directdata;
+ ID *id = te->store_elem->id;
SceneCollection *sc = lc->scene_collection;
if (event == OL_COLLECTION_OP_OBJECTS_ADD) {
CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
{
- BKE_collection_object_add(scene, sc, ob);
+ BKE_collection_object_add(id, sc, ob);
}
CTX_DATA_END;
@@ -836,7 +838,7 @@ static void collection_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tsel
CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
{
- BKE_collection_object_remove(bmain, scene, sc, ob, true);
+ BKE_collection_object_remove(bmain, id, sc, ob, true);
}
CTX_DATA_END;
@@ -844,7 +846,13 @@ static void collection_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tsel
te->store_elem->flag &= ~TSE_SELECTED;
}
else if (event == OL_COLLECTION_OP_COLLECTION_NEW) {
- BKE_collection_add(scene, sc, NULL);
+ if (GS(id->name) == ID_GR) {
+ BKE_collection_add(id, sc, COLLECTION_TYPE_GROUP_INTERNAL, NULL);
+ }
+ else {
+ BLI_assert(GS(id->name) == ID_SCE);
+ BKE_collection_add(id, sc, COLLECTION_TYPE_NONE, NULL);
+ }
WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
}
else if (event == OL_COLLECTION_OP_COLLECTION_UNLINK) {
@@ -861,7 +869,7 @@ static void collection_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tsel
}
}
else if (event == OL_COLLECTION_OP_COLLECTION_DEL) {
- if (BKE_collection_remove(scene, sc)) {
+ if (BKE_collection_remove(id, sc)) {
DEG_relations_tag_update(CTX_data_main(C));
WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
}
@@ -1794,15 +1802,38 @@ void OUTLINER_OT_modifier_operation(wmOperatorType *ot)
/* ******************** */
-static EnumPropertyItem prop_collection_op_types[] = {
- {OL_COLLECTION_OP_OBJECTS_ADD, "OBJECTS_ADD", ICON_ZOOMIN, "Add Selected", "Add selected objects to collection"},
- {OL_COLLECTION_OP_OBJECTS_REMOVE, "OBJECTS_REMOVE", ICON_X, "Remove Selected", "Remove selected objects from collection"},
- {OL_COLLECTION_OP_COLLECTION_NEW, "COLLECTION_NEW", ICON_NEW, "New Collection", "Add a new nested collection"},
- {OL_COLLECTION_OP_COLLECTION_UNLINK, "COLLECTION_UNLINK", ICON_UNLINKED, "Unlink", "Unlink collection"},
- {OL_COLLECTION_OP_COLLECTION_DEL, "COLLECTION_DEL", ICON_X, "Delete Collection", "Delete the collection"},
- {0, NULL, 0, NULL, NULL}
+static EnumPropertyItem prop_collection_op_none_types[] = {
+ {OL_COLLECTION_OP_OBJECTS_ADD, "OBJECTS_ADD", ICON_ZOOMIN, "Add Selected", "Add selected objects to collection"},
+ {OL_COLLECTION_OP_OBJECTS_REMOVE, "OBJECTS_REMOVE", ICON_X, "Remove Selected", "Remove selected objects from collection"},
+ {OL_COLLECTION_OP_COLLECTION_NEW, "COLLECTION_NEW", ICON_NEW, "New Collection", "Add a new nested collection"},
+ {OL_COLLECTION_OP_COLLECTION_UNLINK, "COLLECTION_UNLINK", ICON_UNLINKED, "Unlink", "Unlink collection"},
+ {OL_COLLECTION_OP_COLLECTION_DEL, "COLLECTION_DEL", ICON_X, "Delete Collection", "Delete the collection"},
+ {0, NULL, 0, NULL, NULL}
};
+static EnumPropertyItem prop_collection_op_group_internal_types[] = {
+ {OL_COLLECTION_OP_OBJECTS_ADD, "OBJECTS_ADD", ICON_ZOOMIN, "Add Selected", "Add selected objects to collection"},
+ {OL_COLLECTION_OP_OBJECTS_REMOVE, "OBJECTS_REMOVE", ICON_X, "Remove Selected", "Remove selected objects from collection"},
+ {OL_COLLECTION_OP_COLLECTION_NEW, "COLLECTION_NEW", ICON_NEW, "New Collection", "Add a new nested collection"},
+ {OL_COLLECTION_OP_COLLECTION_DEL, "COLLECTION_DEL", ICON_X, "Delete Collection", "Delete the collection"},
+ {0, NULL, 0, NULL, NULL}
+};
+
+static const EnumPropertyItem *outliner_collection_operation_type_itemf(
+ bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
+{
+ *r_free = false;
+ SpaceOops *soops = CTX_wm_space_outliner(C);
+
+ switch (soops->outlinevis) {
+ case SO_GROUPS:
+ return prop_collection_op_group_internal_types;
+ case SO_ACT_LAYER:
+ return prop_collection_op_none_types;
+ }
+ return NULL;
+}
+
static int outliner_collection_operation_exec(bContext *C, wmOperator *op)
{
SpaceOops *soops = CTX_wm_space_outliner(C);
@@ -1823,6 +1854,8 @@ static int outliner_collection_operation_exec(bContext *C, wmOperator *op)
void OUTLINER_OT_collection_operation(wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Outliner Collection Operation";
ot->idname = "OUTLINER_OT_collection_operation";
@@ -1835,7 +1868,10 @@ void OUTLINER_OT_collection_operation(wmOperatorType *ot)
ot->flag = 0;
- ot->prop = RNA_def_enum(ot->srna, "type", prop_collection_op_types, 0, "Collection Operation", "");
+ prop = RNA_def_enum(ot->srna, "type", DummyRNA_NULL_items, 0, "Collection Operation", "");
+ RNA_def_enum_funcs(prop, outliner_collection_operation_type_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
+ ot->prop = prop;
}
/* ******************** */
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index 1ab715d0246..a9c9ab74970 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -88,6 +88,8 @@
#endif
/* prototypes */
+static void outliner_add_layer_collections_recursive(
+ SpaceOops *soops, ListBase *tree, ID *id, ListBase *layer_collections, TreeElement *parent_ten);
static void outliner_make_hierarchy(ListBase *lb);
/* ********************************************************* */
@@ -386,13 +388,14 @@ static void outliner_add_scene_contents(SpaceOops *soops, ListBase *lb, Scene *s
}
static void outliner_object_reorder(
- Main *UNUSED(bmain), const Scene *scene,
+ Main *UNUSED(bmain),
TreeElement *insert_element, TreeElement *insert_handle, TreeElementInsertType action)
{
TreeStoreElem *tselem_insert = TREESTORE(insert_element);
Object *ob = (Object *)tselem_insert->id;
SceneCollection *sc = outliner_scene_collection_from_tree_element(insert_handle);
SceneCollection *sc_ob_parent = NULL;
+ ID *id = insert_handle->store_elem->id;
BLI_assert(action == TE_INSERT_INTO);
UNUSED_VARS_NDEBUG(action);
@@ -407,13 +410,13 @@ static void outliner_object_reorder(
}
}
else {
- sc_ob_parent = BKE_collection_master(scene);
+ sc_ob_parent = BKE_collection_master(id);
}
- BKE_collection_object_move(scene, sc, sc_ob_parent, ob);
+ BKE_collection_object_move(id, sc, sc_ob_parent, ob);
}
static bool outliner_object_reorder_poll(
- const Scene *UNUSED(scene), const TreeElement *insert_element,
+ const TreeElement *insert_element,
TreeElement **io_insert_handle, TreeElementInsertType *io_action)
{
TreeStoreElem *tselem_handle = TREESTORE(*io_insert_handle);
@@ -861,7 +864,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
}
/* exceptions */
- if (ELEM(type, TSE_ID_BASE, TSE_LAYER_COLLECTION)) {
+ if (type == TSE_ID_BASE) {
/* pass */
}
else if (id == NULL) {
@@ -1199,6 +1202,11 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
te->flag |= TE_LAZY_CLOSED;
}
+ if ((type != TSE_LAYER_COLLECTION) && GS(id->name) == ID_GR) {
+ Group *group = (Group *)id;
+ outliner_add_layer_collections_recursive(soops, &te->subtree, id, &group->view_layer->layer_collections, NULL);
+ }
+
return te;
}
@@ -1349,20 +1357,21 @@ static void outliner_add_orphaned_datablocks(Main *mainvar, SpaceOops *soops)
}
static void outliner_layer_collections_reorder(
- Main *bmain, const Scene *scene,
+ Main *bmain,
TreeElement *insert_element, TreeElement *insert_handle, TreeElementInsertType action)
{
LayerCollection *lc_insert = insert_element->directdata;
LayerCollection *lc_handle = insert_handle->directdata;
+ ID *id = insert_element->store_elem->id;
if (action == TE_INSERT_BEFORE) {
- BKE_layer_collection_move_above(scene, lc_handle, lc_insert);
+ BKE_layer_collection_move_above(id, lc_handle, lc_insert);
}
else if (action == TE_INSERT_AFTER) {
- BKE_layer_collection_move_below(scene, lc_handle, lc_insert);
+ BKE_layer_collection_move_below(id, lc_handle, lc_insert);
}
else if (action == TE_INSERT_INTO) {
- BKE_layer_collection_move_into(scene, lc_handle, lc_insert);
+ BKE_layer_collection_move_into(id, lc_handle, lc_insert);
}
else {
BLI_assert(0);
@@ -1371,25 +1380,30 @@ static void outliner_layer_collections_reorder(
DEG_relations_tag_update(bmain);
}
static bool outliner_layer_collections_reorder_poll(
- const Scene *UNUSED(scene), const TreeElement *UNUSED(insert_element),
+ const TreeElement *insert_element,
TreeElement **io_insert_handle, TreeElementInsertType *UNUSED(io_action))
{
const TreeStoreElem *tselem_handle = TREESTORE(*io_insert_handle);
+
+ if (tselem_handle->id != insert_element->store_elem->id) {
+ return false;
+ }
+
return ELEM(tselem_handle->type, TSE_LAYER_COLLECTION);
}
static void outliner_add_layer_collections_recursive(
- SpaceOops *soops, ListBase *tree, ListBase *layer_collections, TreeElement *parent_ten)
+ SpaceOops *soops, ListBase *tree, ID *id, ListBase *layer_collections, TreeElement *parent_ten)
{
for (LayerCollection *collection = layer_collections->first; collection; collection = collection->next) {
- TreeElement *ten = outliner_add_element(soops, tree, collection, parent_ten, TSE_LAYER_COLLECTION, 0);
+ TreeElement *ten = outliner_add_element(soops, tree, id, parent_ten, TSE_LAYER_COLLECTION, 0);
ten->name = collection->scene_collection->name;
ten->directdata = collection;
ten->reinsert = outliner_layer_collections_reorder;
ten->reinsert_poll = outliner_layer_collections_reorder_poll;
- outliner_add_layer_collections_recursive(soops, &ten->subtree, &collection->layer_collections, ten);
+ outliner_add_layer_collections_recursive(soops, &ten->subtree, id, &collection->layer_collections, ten);
for (LinkData *link = collection->object_bases.first; link; link = link->next) {
Base *base = (Base *)link->data;
TreeElement *te_object = outliner_add_element(soops, &ten->subtree, base->object, ten, 0, 0);
@@ -1398,27 +1412,29 @@ static void outliner_add_layer_collections_recursive(
outliner_make_hierarchy(&ten->subtree);
}
}
-static void outliner_add_collections_act_layer(SpaceOops *soops, ViewLayer *layer)
+static void outliner_add_collections_act_layer(SpaceOops *soops, Scene *scene, ViewLayer *layer)
{
- outliner_add_layer_collections_recursive(soops, &soops->tree, &layer->layer_collections, NULL);
+ outliner_add_layer_collections_recursive(soops, &soops->tree, &scene->id, &layer->layer_collections, NULL);
}
static void outliner_scene_collections_reorder(
- Main *bmain, const Scene *scene,
+ Main *bmain,
TreeElement *insert_element, TreeElement *insert_handle, TreeElementInsertType action)
{
SceneCollection *sc_insert = insert_element->directdata;
SceneCollection *sc_handle = insert_handle->directdata;
+ ID *id = insert_handle->store_elem->id;
+ BLI_assert(id == insert_element->store_elem->id);
- BLI_assert((action == TE_INSERT_INTO) || (sc_handle != BKE_collection_master(scene)));
+ BLI_assert((action == TE_INSERT_INTO) || (sc_handle != BKE_collection_master(id)));
if (action == TE_INSERT_BEFORE) {
- BKE_collection_move_above(scene, sc_handle, sc_insert);
+ BKE_collection_move_above(id, sc_handle, sc_insert);
}
else if (action == TE_INSERT_AFTER) {
- BKE_collection_move_below(scene, sc_handle, sc_insert);
+ BKE_collection_move_below(id, sc_handle, sc_insert);
}
else if (action == TE_INSERT_INTO) {
- BKE_collection_move_into(scene, sc_handle, sc_insert);
+ BKE_collection_move_into(id, sc_handle, sc_insert);
}
else {
BLI_assert(0);
@@ -1427,17 +1443,23 @@ static void outliner_scene_collections_reorder(
DEG_relations_tag_update(bmain);
}
static bool outliner_scene_collections_reorder_poll(
- const Scene *scene, const TreeElement *UNUSED(insert_element),
+ const TreeElement *insert_element,
TreeElement **io_insert_handle, TreeElementInsertType *io_action)
{
const TreeStoreElem *tselem_handle = TREESTORE(*io_insert_handle);
- SceneCollection *sc_master = BKE_collection_master(scene);
- SceneCollection *sc_handle = (*io_insert_handle)->directdata;
+ ID *id = tselem_handle->id;
+
+ if (id != insert_element->store_elem->id) {
+ return false;
+ }
if (!ELEM(tselem_handle->type, TSE_SCENE_COLLECTION)) {
return false;
}
+ SceneCollection *sc_master = BKE_collection_master(id);
+ SceneCollection *sc_handle = (*io_insert_handle)->directdata;
+
if (sc_handle == sc_master) {
/* exception: Can't insert before/after master selection, has to be one of its childs */
TreeElement *te_master = *io_insert_handle;
@@ -1478,7 +1500,7 @@ static void outliner_add_scene_collections_recursive(
}
static void outliner_add_collections_master(SpaceOops *soops, Scene *scene)
{
- SceneCollection *master = BKE_collection_master(scene);
+ SceneCollection *master = BKE_collection_master(&scene->id);
outliner_add_scene_collections_recursive(soops, &soops->tree, &master->scene_collections, NULL);
outliner_add_scene_collection_objects(soops, &soops->tree, master, NULL);
}
@@ -1851,19 +1873,9 @@ void outliner_build_tree(Main *mainvar, Scene *scene, ViewLayer *view_layer, Spa
}
else if (soops->outlinevis == SO_GROUPS) {
Group *group;
- GroupObject *go;
-
for (group = mainvar->group.first; group; group = group->id.next) {
- if (group->gobject.first) {
- te = outliner_add_element(soops, &soops->tree, group, NULL, 0, 0);
-
- for (go = group->gobject.first; go; go = go->next) {
- outliner_add_element(soops, &te->subtree, go->ob, te, 0, 0);
- }
- outliner_make_hierarchy(&te->subtree);
- /* clear id.newid, to prevent objects be inserted in wrong scenes (parent in other scene) */
- for (go = group->gobject.first; go; go = go->next) go->ob->id.newid = NULL;
- }
+ te = outliner_add_element(soops, &soops->tree, group, NULL, 0, 0);
+ outliner_make_hierarchy(&te->subtree);
}
}
else if (soops->outlinevis == SO_SAME_TYPE) {
@@ -1940,7 +1952,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, ViewLayer *view_layer, Spa
outliner_add_orphaned_datablocks(mainvar, soops);
}
else if (soops->outlinevis == SO_ACT_LAYER) {
- outliner_add_collections_act_layer(soops, view_layer);
+ outliner_add_collections_act_layer(soops, scene, view_layer);
}
else if (soops->outlinevis == SO_COLLECTIONS) {
outliner_add_collections_master(soops, scene);
diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c
index 568343f8ec8..79fa9e14dc1 100644
--- a/source/blender/editors/space_view3d/view3d_ops.c
+++ b/source/blender/editors/space_view3d/view3d_ops.c
@@ -46,6 +46,7 @@
#include "BKE_appdir.h"
#include "BKE_blender_copybuffer.h"
#include "BKE_context.h"
+#include "BKE_group.h"
#include "BKE_main.h"
#include "BKE_report.h"
@@ -81,14 +82,16 @@ static int view3d_copybuffer_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
for (Group *group = bmain->group.first; group; group = group->id.next) {
- for (GroupObject *go = group->gobject.first; go; go = go->next) {
- if (go->ob && (go->ob->id.tag & LIB_TAG_DOIT)) {
+ FOREACH_GROUP_OBJECT(group, object)
+ {
+ if (object && (object->id.tag & LIB_TAG_DOIT)) {
BKE_copybuffer_tag_ID(&group->id);
/* don't expand out to all other objects */
group->id.tag &= ~LIB_TAG_NEED_EXPAND;
break;
}
}
+ FOREACH_GROUP_OBJECT_END
}
BLI_make_file_string("/", str, BKE_tempdir_base(), "copybuffer.blend");
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
index 6122ef99964..79f17756ca6 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
+++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
@@ -945,8 +945,8 @@ Object *BlenderStrokeRenderer::NewMesh() const
ob->data = BKE_mesh_add(freestyle_bmain, name);
ob->lay = 1;
- SceneCollection *sc_master = BKE_collection_master(freestyle_scene);
- BKE_collection_object_add(freestyle_scene, sc_master, ob);
+ SceneCollection *sc_master = BKE_collection_master(&freestyle_scene->id);
+ BKE_collection_object_add(&freestyle_scene->id, sc_master, ob);
DEG_graph_tag_relations_update(freestyle_depsgraph);
DEG_graph_id_tag_update(freestyle_bmain,
diff --git a/source/blender/makesdna/DNA_group_types.h b/source/blender/makesdna/DNA_group_types.h
index 45dd0cb9ff2..8f15aa85e97 100644
--- a/source/blender/makesdna/DNA_group_types.h
+++ b/source/blender/makesdna/DNA_group_types.h
@@ -60,6 +60,13 @@ typedef struct Group {
* on the last used scene */
unsigned int layer;
float dupli_ofs[3];
+
+ struct SceneCollection *collection;
+ struct ViewLayer *view_layer;
} Group;
+
+#define GROUP_MASTER_COLLECTION(_group) \
+ (((LayerCollection *)(_group)->view_layer->layer_collections.first)->scene_collection)
+
#endif /* __DNA_GROUP_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_layer_types.h b/source/blender/makesdna/DNA_layer_types.h
index 3eac7f0aab3..c677383cb6e 100644
--- a/source/blender/makesdna/DNA_layer_types.h
+++ b/source/blender/makesdna/DNA_layer_types.h
@@ -104,7 +104,8 @@ typedef struct SceneCollection {
char name[64]; /* MAX_NAME */
char filter[64]; /* MAX_NAME */
int active_object_index; /* for UI */
- int pad;
+ char type;
+ char pad[3];
ListBase objects; /* (Object *)LinkData->data */
ListBase filter_objects; /* (Object *)LinkData->data */
ListBase scene_collections; /* nested collections */
@@ -134,6 +135,11 @@ enum {
VIEW_LAYER_FREESTYLE = (1 << 2),
};
+/* SceneCollection->type */
+enum {
+ COLLECTION_TYPE_NONE = 0,
+ COLLECTION_TYPE_GROUP_INTERNAL = 1,
+};
/* *************************************************************** */
/* Engine Settings */
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index a706ea50ebd..78c623f6408 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -371,6 +371,7 @@ typedef struct DupliObject {
struct ParticleSystem *particle_system;
unsigned int random_id;
unsigned int pad;
+ struct IDProperty *collection_properties;
} DupliObject;
/* **************** OBJECT ********************* */
diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h
index 155c82bbbc3..345c47ae1bf 100644
--- a/source/blender/makesrna/RNA_enum_types.h
+++ b/source/blender/makesrna/RNA_enum_types.h
@@ -61,6 +61,8 @@ extern const EnumPropertyItem rna_enum_object_modifier_type_items[];
extern const EnumPropertyItem rna_enum_constraint_type_items[];
extern const EnumPropertyItem rna_enum_boidrule_type_items[];
extern const EnumPropertyItem rna_enum_sequence_modifier_type_items[];
+
+extern const EnumPropertyItem rna_enum_collection_type_items[];
extern const EnumPropertyItem rna_enum_layer_collection_mode_settings_type_items[];
extern const EnumPropertyItem rna_enum_modifier_triangulate_quad_method_items[];
diff --git a/source/blender/makesrna/intern/rna_group.c b/source/blender/makesrna/intern/rna_group.c
index 2a5a0011279..ec67370b14f 100644
--- a/source/blender/makesrna/intern/rna_group.c
+++ b/source/blender/makesrna/intern/rna_group.c
@@ -49,8 +49,9 @@ static PointerRNA rna_Group_objects_get(CollectionPropertyIterator *iter)
{
ListBaseIterator *internal = &iter->internal.listbase;
- /* we are actually iterating a GroupObject list, so override get */
- return rna_pointer_inherit_refine(&iter->parent, &RNA_Object, ((GroupObject *)internal->link)->ob);
+ /* we are actually iterating a ObjectBase list, so override get */
+ Base *base = (Base *)internal->link;
+ return rna_pointer_inherit_refine(&iter->parent, &RNA_Object, base->object);
}
static void rna_Group_objects_link(Group *group, ReportList *reports, Object *object)
@@ -124,20 +125,17 @@ void RNA_def_group(BlenderRNA *brna)
RNA_def_property_ui_range(prop, -10000.0, 10000.0, 10, RNA_TRANSLATION_PREC_DEFAULT);
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
- prop = RNA_def_property(srna, "layers", PROP_BOOLEAN, PROP_LAYER);
- RNA_def_property_boolean_sdna(prop, NULL, "layer", 1);
- RNA_def_property_array(prop, 20);
- RNA_def_property_ui_text(prop, "Dupli Layers", "Layers visible when this group is instanced as a dupli");
- RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
-
prop = RNA_def_property(srna, "objects", PROP_COLLECTION, PROP_NONE);
- RNA_def_property_collection_sdna(prop, NULL, "gobject", NULL);
+ RNA_def_property_collection_sdna(prop, NULL, "view_layer->object_bases", NULL);
RNA_def_property_struct_type(prop, "Object");
RNA_def_property_ui_text(prop, "Objects", "A collection of this groups objects");
RNA_def_property_collection_funcs(prop, NULL, NULL, NULL, "rna_Group_objects_get", NULL, NULL, NULL, NULL);
-
rna_def_group_objects(brna, prop);
+ prop = RNA_def_property(srna, "collections", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "view_layer->layer_collections", NULL);
+ RNA_def_property_struct_type(prop, "LayerCollection");
+ RNA_def_property_ui_text(prop, "Layer Collections", "");
}
#endif
diff --git a/source/blender/makesrna/intern/rna_layer.c b/source/blender/makesrna/intern/rna_layer.c
index 2bdb3035073..df6c2188799 100644
--- a/source/blender/makesrna/intern/rna_layer.c
+++ b/source/blender/makesrna/intern/rna_layer.c
@@ -54,8 +54,15 @@ const EnumPropertyItem rna_enum_layer_collection_mode_settings_type_items[] = {
{0, NULL, 0, NULL, NULL}
};
+const EnumPropertyItem rna_enum_collection_type_items[] = {
+ {COLLECTION_TYPE_NONE, "NONE", 0, "Normal", ""},
+ {COLLECTION_TYPE_GROUP_INTERNAL, "GROUP_INTERNAL", 0, "Group Internal", ""},
+ {0, NULL, 0, NULL, NULL}
+};
+
#ifdef RNA_RUNTIME
+#include "DNA_group_types.h"
#include "DNA_object_types.h"
#include "RNA_access.h"
@@ -69,6 +76,20 @@ const EnumPropertyItem rna_enum_layer_collection_mode_settings_type_items[] = {
#include "DEG_depsgraph_build.h"
#include "DEG_depsgraph_query.h"
+static StructRNA *rna_SceneCollection_refine(PointerRNA *ptr)
+{
+ SceneCollection *scene_collection = (SceneCollection *)ptr->data;
+ switch (scene_collection->type) {
+ case COLLECTION_TYPE_GROUP_INTERNAL:
+ case COLLECTION_TYPE_NONE:
+ return &RNA_SceneCollection;
+ default:
+ BLI_assert(!"Collection type not fully implemented");
+ break;
+ }
+ return &RNA_SceneCollection;
+}
+
static void rna_SceneCollection_name_set(PointerRNA *ptr, const char *value)
{
Scene *scene = (Scene *)ptr->id.data;
@@ -96,9 +117,7 @@ static PointerRNA rna_SceneCollection_objects_get(CollectionPropertyIterator *it
static int rna_SceneCollection_move_above(ID *id, SceneCollection *sc_src, Main *bmain, SceneCollection *sc_dst)
{
- Scene *scene = (Scene *)id;
-
- if (!BKE_collection_move_above(scene, sc_dst, sc_src)) {
+ if (!BKE_collection_move_above(id, sc_dst, sc_src)) {
return 0;
}
@@ -110,9 +129,7 @@ static int rna_SceneCollection_move_above(ID *id, SceneCollection *sc_src, Main
static int rna_SceneCollection_move_below(ID *id, SceneCollection *sc_src, Main *bmain, SceneCollection *sc_dst)
{
- Scene *scene = (Scene *)id;
-
- if (!BKE_collection_move_below(scene, sc_dst, sc_src)) {
+ if (!BKE_collection_move_below(id, sc_dst, sc_src)) {
return 0;
}
@@ -124,9 +141,7 @@ static int rna_SceneCollection_move_below(ID *id, SceneCollection *sc_src, Main
static int rna_SceneCollection_move_into(ID *id, SceneCollection *sc_src, Main *bmain, SceneCollection *sc_dst)
{
- Scene *scene = (Scene *)id;
-
- if (!BKE_collection_move_into(scene, sc_dst, sc_src)) {
+ if (!BKE_collection_move_into(id, sc_dst, sc_src)) {
return 0;
}
@@ -139,8 +154,7 @@ static int rna_SceneCollection_move_into(ID *id, SceneCollection *sc_src, Main *
static SceneCollection *rna_SceneCollection_new(
ID *id, SceneCollection *sc_parent, Main *bmain, const char *name)
{
- Scene *scene = (Scene *)id;
- SceneCollection *sc = BKE_collection_add(scene, sc_parent, name);
+ SceneCollection *sc = BKE_collection_add(id, sc_parent, COLLECTION_TYPE_NONE, name);
DEG_relations_tag_update(bmain);
WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
@@ -151,7 +165,6 @@ static SceneCollection *rna_SceneCollection_new(
static void rna_SceneCollection_remove(
ID *id, SceneCollection *sc_parent, Main *bmain, ReportList *reports, PointerRNA *sc_ptr)
{
- Scene *scene = (Scene *)id;
SceneCollection *sc = sc_ptr->data;
const int index = BLI_findindex(&sc_parent->scene_collections, sc);
@@ -161,7 +174,7 @@ static void rna_SceneCollection_remove(
return;
}
- if (!BKE_collection_remove(scene, sc)) {
+ if (!BKE_collection_remove(id, sc)) {
BKE_reportf(reports, RPT_ERROR, "Collection '%s' could not be removed from collection '%s'",
sc->name, sc_parent->name);
return;
@@ -203,7 +216,7 @@ void rna_SceneCollection_object_link(
return;
}
- BKE_collection_object_add(scene, sc, ob);
+ BKE_collection_object_add(&scene->id, sc, ob);
/* TODO(sergey): Only update relations for the current scene. */
DEG_relations_tag_update(bmain);
@@ -226,7 +239,7 @@ static void rna_SceneCollection_object_unlink(
return;
}
- BKE_collection_object_remove(bmain, scene, sc, ob, false);
+ BKE_collection_object_remove(bmain, &scene->id, sc, ob, false);
/* needed otherwise the depgraph will contain freed objects which can crash, see [#20958] */
DEG_relations_tag_update(bmain);
@@ -417,11 +430,11 @@ static void rna_ViewLayerEngineSettings_update(bContext *C, PointerRNA *UNUSED(p
DEG_id_tag_update(&scene->id, 0);
}
-static void rna_LayerCollectionEngineSettings_update(bContext *C, PointerRNA *UNUSED(ptr))
+static void rna_LayerCollectionEngineSettings_update(bContext *UNUSED(C), PointerRNA *ptr)
{
- Scene *scene = CTX_data_scene(C);
+ ID *id = ptr->id.data;
/* TODO(sergey): Use proper flag for tagging here. */
- DEG_id_tag_update(&scene->id, 0);
+ DEG_id_tag_update(id, 0);
}
static void rna_LayerCollectionEngineSettings_wire_update(bContext *C, PointerRNA *UNUSED(ptr))
@@ -641,9 +654,7 @@ static PointerRNA rna_LayerCollection_objects_get(CollectionPropertyIterator *it
static int rna_LayerCollection_move_above(ID *id, LayerCollection *lc_src, Main *bmain, LayerCollection *lc_dst)
{
- Scene *scene = (Scene *)id;
-
- if (!BKE_layer_collection_move_above(scene, lc_dst, lc_src)) {
+ if (!BKE_layer_collection_move_above(id, lc_dst, lc_src)) {
return 0;
}
@@ -655,9 +666,7 @@ static int rna_LayerCollection_move_above(ID *id, LayerCollection *lc_src, Main
static int rna_LayerCollection_move_below(ID *id, LayerCollection *lc_src, Main *bmain, LayerCollection *lc_dst)
{
- Scene *scene = (Scene *)id;
-
- if (!BKE_layer_collection_move_below(scene, lc_dst, lc_src)) {
+ if (!BKE_layer_collection_move_below(id, lc_dst, lc_src)) {
return 0;
}
@@ -669,9 +678,7 @@ static int rna_LayerCollection_move_below(ID *id, LayerCollection *lc_src, Main
static int rna_LayerCollection_move_into(ID *id, LayerCollection *lc_src, Main *bmain, LayerCollection *lc_dst)
{
- Scene *scene = (Scene *)id;
-
- if (!BKE_layer_collection_move_into(scene, lc_dst, lc_src)) {
+ if (!BKE_layer_collection_move_into(id, lc_dst, lc_src)) {
return 0;
}
@@ -681,19 +688,27 @@ static int rna_LayerCollection_move_into(ID *id, LayerCollection *lc_src, Main *
return 1;
}
-static void rna_LayerCollection_flag_update(bContext *C, PointerRNA *UNUSED(ptr))
+static void rna_LayerCollection_flag_update(bContext *C, PointerRNA *ptr)
{
- Scene *scene = CTX_data_scene(C);
+ ID *id = ptr->id.data;
/* TODO(sergey): Use proper flag for tagging here. */
- DEG_id_tag_update(&scene->id, 0);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ DEG_id_tag_update(id, 0);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, CTX_data_scene(C));
}
static void rna_LayerCollection_enable_set(
ID *id, LayerCollection *layer_collection, Main *bmain, bContext *C, ReportList *reports, int value)
{
- Scene *scene = (Scene *)id;
- ViewLayer *view_layer = BKE_view_layer_find_from_collection(scene, layer_collection);
+ ViewLayer *view_layer;
+ if (GS(id->name) == ID_SCE) {
+ Scene *scene = (Scene *)id;
+ view_layer = BKE_view_layer_find_from_collection(&scene->id, layer_collection);
+ }
+ else {
+ BLI_assert(GS(id->name) == ID_GR);
+ Group *group = (Group *)id;
+ view_layer = group->view_layer;
+ }
if (layer_collection->flag & COLLECTION_DISABLED) {
if (value == 1) {
@@ -715,6 +730,7 @@ static void rna_LayerCollection_enable_set(
}
}
+ Scene *scene = CTX_data_scene(C);
DEG_relations_tag_update(bmain);
/* TODO(sergey): Use proper flag for tagging here. */
DEG_id_tag_update(&scene->id, 0);
@@ -1034,6 +1050,7 @@ static void rna_def_scene_collection(BlenderRNA *brna)
srna = RNA_def_struct(brna, "SceneCollection", NULL);
RNA_def_struct_ui_text(srna, "Scene Collection", "Collection");
+ RNA_def_struct_refine_func(srna, "rna_SceneCollection_refine");
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SceneCollection_name_set");
@@ -1041,6 +1058,11 @@ static void rna_def_scene_collection(BlenderRNA *brna)
RNA_def_struct_name_property(srna, prop);
RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, NULL);
+ prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, rna_enum_collection_type_items);
+ RNA_def_property_ui_text(prop, "Type", "Type of collection");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
prop = RNA_def_property(srna, "filter", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SceneCollection_filter_set");
RNA_def_property_ui_text(prop, "Filter", "Filter to dynamically include objects based on their names (e.g., CHAR_*)");
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 81ed4c71b17..74de3fcded6 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -68,6 +68,7 @@
#include "BKE_displist.h"
#include "BKE_DerivedMesh.h"
#include "BKE_global.h"
+#include "BKE_group.h"
#include "BKE_key.h"
#include "BKE_image.h"
#include "BKE_lattice.h"
@@ -3979,28 +3980,32 @@ static bool is_object_hidden(Render *re, Object *ob)
/* layflag: allows material group to ignore layerflag */
static void add_lightgroup(Render *re, Group *group, int exclusive)
{
- GroupObject *go, *gol;
-
group->id.tag &= ~LIB_TAG_DOIT;
+#if 0
/* it's a bit too many loops in loops... but will survive */
/* note that 'exclusive' will remove it from the global list */
- for (go= group->gobject.first; go; go= go->next) {
- go->lampren= NULL;
+ FOREACH_GROUP_BASE(group, base)
+ {
+ Object *object = base->object;
- if (is_object_hidden(re, go->ob))
+ if (is_object_hidden(re, object)) {
continue;
-
- if (go->ob->lay & re->lay) {
- if (go->ob && go->ob->type==OB_LAMP) {
- for (gol= re->lights.first; gol; gol= gol->next) {
- if (gol->ob==go->ob) {
- go->lampren= gol->lampren;
+ }
+
+ if (base->flag & BASE_VISIBLED) {
+ if (object && object->type == OB_LAMP) {
+ for (GroupObject *gol = re->lights.first; gol; gol = gol->next) {
+ if (gol->ob == object) {
+ go->lampren = gol->lampren;
break;
}
}
- if (go->lampren==NULL)
- gol= add_render_lamp(re, go->ob);
+
+ if (go->lampren == NULL) {
+ gol= add_render_lamp(re, object);
+ }
+
if (gol && exclusive) {
BLI_remlink(&re->lights, gol);
MEM_freeN(gol);
@@ -4008,6 +4013,10 @@ static void add_lightgroup(Render *re, Group *group, int exclusive)
}
}
}
+ FOREACH_GROUP_BASE_END
+#else
+ UNUSED_VARS(re, exclusive);
+#endif
}
static void set_material_lightgroups(Render *re)
@@ -4899,8 +4908,6 @@ static void dupli_render_particle_set(Render *re, Object *ob, int timeoffset, in
{
/* ugly function, but we need to set particle systems to their render
* settings before calling object_duplilist, to get render level duplis */
- Group *group;
- GroupObject *go;
ParticleSystem *psys;
DerivedMesh *dm;
@@ -4932,11 +4939,13 @@ static void dupli_render_particle_set(Render *re, Object *ob, int timeoffset, in
}
}
- if (ob->dup_group==NULL) return;
- group= ob->dup_group;
+ if (ob->dup_group == NULL) return;
- for (go= group->gobject.first; go; go= go->next)
- dupli_render_particle_set(re, go->ob, timeoffset, level+1, enable);
+ FOREACH_GROUP_OBJECT(ob->dup_group, object)
+ {
+ dupli_render_particle_set(re, object, timeoffset, level+1, enable);
+ }
+ FOREACH_GROUP_OBJECT_END
}
static int get_vector_viewlayers(Scene *UNUSED(sce))
@@ -4946,29 +4955,27 @@ static int get_vector_viewlayers(Scene *UNUSED(sce))
static void add_group_render_dupli_obs(Render *re, Group *group, int nolamps, int onlyselected, Object *actob, int timeoffset, int level)
{
- GroupObject *go;
- Object *ob;
-
- /* simple preventing of too deep nested groups */
- if (level>MAX_DUPLI_RECUR) return;
-
- /* recursively go into dupligroups to find objects with OB_RENDER_DUPLI
- * that were not created yet */
- for (go= group->gobject.first; go; go= go->next) {
- ob= go->ob;
+ /* Simple preventing of too deep nested groups. */
+ if (level > MAX_DUPLI_RECUR) return;
+ /* Recursively go into dupligroups to find objects with OB_RENDER_DUPLI
+ * that were not created yet. */
+ FOREACH_GROUP_OBJECT(group, ob)
+ {
if (ob->flag & OB_DONE) {
if (ob->transflag & OB_RENDER_DUPLI) {
if (allow_render_object(re, ob, nolamps, onlyselected, actob)) {
init_render_object(re, ob, NULL, NULL, NULL, timeoffset);
ob->transflag &= ~OB_RENDER_DUPLI;
- if (ob->dup_group)
+ if (ob->dup_group) {
add_group_render_dupli_obs(re, ob->dup_group, nolamps, onlyselected, actob, timeoffset, level+1);
+ }
}
}
}
}
+ FOREACH_GROUP_OBJECT_END
}
static void database_init_objects(Render *re, unsigned int UNUSED(renderlay), int nolamps, int onlyselected, Object *actob, int timeoffset)
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index ad9855586ee..acd425e788a 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -147,6 +147,7 @@ extern "C" {
#include "BKE_customdata.h"
#include "BKE_cdderivedmesh.h"
#include "BKE_DerivedMesh.h"
+#include "BKE_group.h"
#include "BKE_layer.h"
#include "BKE_material.h" /* give_current_material */
#include "BKE_image.h"
@@ -2052,10 +2053,8 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
for (git=tempglist.begin(); git!=tempglist.end(); git++)
{
Group* group = *git;
- GroupObject* go;
- for (go=(GroupObject*)group->gobject.first; go; go=(GroupObject*)go->next)
+ FOREACH_GROUP_OBJECT(group, blenderobject)
{
- Object* blenderobject = go->ob;
if (converter->FindGameObject(blenderobject) == NULL)
{
allblobj.insert(blenderobject);
@@ -2090,6 +2089,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
}
}
}
+ FOREACH_GROUP_OBJECT_END
}
}
}
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index b3061087344..48b50d24975 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -105,6 +105,7 @@
#include "KX_Light.h"
+#include "BKE_group.h"
#include "BLI_task.h"
static void *KX_SceneReplicationFunc(SG_IObject* node,void* gameobj,void* scene)
@@ -720,7 +721,6 @@ void KX_Scene::DupliGroupRecurse(CValue* obj, int level)
KX_GameObject* gameobj;
Object* blgroupobj = groupobj->GetBlenderObject();
Group* group;
- GroupObject *go;
vector<KX_GameObject*> duplilist;
if (!groupobj->GetSGNode() ||
@@ -738,9 +738,9 @@ void KX_Scene::DupliGroupRecurse(CValue* obj, int level)
m_groupGameObjects.clear();
group = blgroupobj->dup_group;
- for (go=(GroupObject*)group->gobject.first; go; go=(GroupObject*)go->next)
+ FOREACH_GROUP_BASE(group, base)
{
- Object* blenderobj = go->ob;
+ Object *blenderobj = base->object;
if (blgroupobj == blenderobj)
// this check is also in group_duplilist()
continue;
@@ -755,13 +755,13 @@ void KX_Scene::DupliGroupRecurse(CValue* obj, int level)
gameobj->SetBlenderGroupObject(blgroupobj);
- if ((blenderobj->lay & group->layer)==0)
- {
+ if ((base->flag & BASE_VISIBLED) == 0) {
// object is not visible in the 3D view, will not be instantiated
continue;
}
m_groupGameObjects.insert(gameobj);
}
+ FOREACH_GROUP_BASE_END
set<CValue*>::iterator oit;
for (oit=m_groupGameObjects.begin(); oit != m_groupGameObjects.end(); oit++)