diff options
Diffstat (limited to 'source/blender/blenkernel/intern/group.c')
-rw-r--r-- | source/blender/blenkernel/intern/group.c | 195 |
1 files changed, 115 insertions, 80 deletions
diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c index 6dc8cc5aff1..8295fafba56 100644 --- a/source/blender/blenkernel/intern/group.c +++ b/source/blender/blenkernel/intern/group.c @@ -45,34 +45,51 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" - -#include "BKE_depsgraph.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" /* BKE_scene_base_find */ +#include "BKE_scene.h" -static void free_group_object(GroupObject *go) -{ - MEM_freeN(go); -} +#define DEBUG_PRINT if (G.debug & G_DEBUG_DEPSGRAPH) printf /** 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 = 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, NULL); + BKE_collection_link(group->view_layer, defaut_collection); } Group *BKE_group_add(Main *bmain, const char *name) @@ -85,7 +102,7 @@ Group *BKE_group_add(Main *bmain, const char *name) group->layer = (1 << 20) - 1; group->preview = NULL; - + BKE_group_init(group); return group; } @@ -99,7 +116,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 */ @@ -108,6 +126,19 @@ 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); + + group_dst->view_layer = MEM_dupallocN(group_src->view_layer); + 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) @@ -125,38 +156,27 @@ 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; } -bool BKE_group_object_add(Group *group, Object *object, Scene *scene, Base *base) +bool BKE_group_object_add(Group *group, Object *object) { if (group_object_add_internal(group, object)) { if ((object->flag & OB_FROMGROUP) == 0) { - - if (scene && base == NULL) - base = BKE_scene_base_find(scene, object); - object->flag |= OB_FROMGROUP; - - if (base) - base->flag |= OB_FROMGROUP; } return true; } @@ -166,24 +186,17 @@ bool BKE_group_object_add(Group *group, Object *object, Scene *scene, Base *base } /* 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) @@ -200,12 +213,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 */ @@ -223,18 +237,12 @@ bool BKE_group_object_cyclic_check(Main *bmain, Object *object, Group *group) return group_object_cyclic_check_internal(object, group); } -bool BKE_group_object_unlink(Group *group, Object *object, Scene *scene, Base *base) +bool BKE_group_object_unlink(Group *group, Object *object) { if (group_object_unlink_internal(group, object)) { /* object can be NULL */ if (object && BKE_group_object_find(NULL, object) == NULL) { - if (scene && base == NULL) - base = BKE_scene_base_find(scene, object); - object->flag &= ~OB_FROMGROUP; - - if (base) - base->flag &= ~OB_FROMGROUP; } return true; } @@ -249,7 +257,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))); } } @@ -270,17 +278,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; } @@ -330,10 +334,8 @@ static void group_replaces_nla(Object *parent, Object *target, char mode) * you can draw everything, leaves tags in objects to signal it needs further updating */ /* note: does not work for derivedmesh and render... it recreates all again in convertblender.c */ -void BKE_group_handle_recalc_and_update(EvaluationContext *eval_ctx, Scene *scene, Object *UNUSED(parent), Group *group) +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 @@ -367,12 +369,45 @@ void BKE_group_handle_recalc_and_update(EvaluationContext *eval_ctx, Scene *scen #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->recalc) { - BKE_object_handle_update(eval_ctx, scene, go->ob); - } + FOREACH_GROUP_OBJECT(group, object) + { + if (object->id.recalc & ID_RECALC_ALL) { + BKE_object_handle_update(eval_ctx, scene, object); } } + FOREACH_GROUP_OBJECT_END + } +} + +/* ******** Dependency graph evaluation ******** */ + +static void group_eval_layer_collections( + const struct EvaluationContext *eval_ctx, + Group *group, + ListBase *layer_collections, + LayerCollection *parent_layer_collection) +{ + LINKLIST_FOREACH (LayerCollection *, layer_collection, layer_collections) { + /* Evaluate layer collection itself. */ + BKE_layer_eval_layer_collection(eval_ctx, + layer_collection, + parent_layer_collection); + /* Evaluate nested collections. */ + group_eval_layer_collections(eval_ctx, + group, + &layer_collection->layer_collections, + layer_collection); } } + +void BKE_group_eval_view_layers(const struct EvaluationContext *eval_ctx, + Group *group) +{ + DEBUG_PRINT("%s on %s (%p)\n", __func__, group->id.name, group); + BKE_layer_eval_layer_collection_pre(eval_ctx, &group->id, group->view_layer); + group_eval_layer_collections(eval_ctx, + group, + &group->view_layer->layer_collections, + NULL); + BKE_layer_eval_layer_collection_post(eval_ctx, group->view_layer); +} |