Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--release/scripts/startup/bl_ui/properties_object.py9
-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
58 files changed, 1373 insertions, 944 deletions
diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py
index 49ecb94248e..23787756121 100644
--- a/release/scripts/startup/bl_ui/properties_object.py
+++ b/release/scripts/startup/bl_ui/properties_object.py
@@ -219,13 +219,8 @@ class OBJECT_PT_groups(ObjectButtonsPanel, Panel):
row.operator("object.group_remove", text="", icon='X', emboss=False)
row.menu("GROUP_MT_specials", icon='DOWNARROW_HLT', text="")
- split = col.box().split()
-
- col = split.column()
- col.prop(group, "layers", text="Dupli Visibility")
-
- col = split.column()
- col.prop(group, "dupli_offset", text="")
+ row = col.box().row()
+ row.prop(group, "dupli_offset", text="")
class OBJECT_PT_display(ObjectButtonsPanel, Panel):
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++)