DNA: move Collection members into their own Runtime struct
Also add static assert that COLLECTION_COLOR_TOT has the correct number of items in the enum.
This commit is contained in:
parent
9179362e7b
commit
44dd3308a5
|
@ -574,7 +574,8 @@ static void loose_data_instantiate_obdata_preprocess(
|
||||||
* (return false). */
|
* (return false). */
|
||||||
static bool loose_data_instantiate_collection_parents_check_recursive(Collection *collection)
|
static bool loose_data_instantiate_collection_parents_check_recursive(Collection *collection)
|
||||||
{
|
{
|
||||||
for (CollectionParent *parent_collection = collection->parents.first; parent_collection != NULL;
|
for (CollectionParent *parent_collection = collection->runtime.parents.first;
|
||||||
|
parent_collection != NULL;
|
||||||
parent_collection = parent_collection->next) {
|
parent_collection = parent_collection->next) {
|
||||||
if ((parent_collection->collection->id.tag & LIB_TAG_DOIT) != 0) {
|
if ((parent_collection->collection->id.tag & LIB_TAG_DOIT) != 0) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -114,12 +114,12 @@ static void collection_copy_data(Main *bmain, ID *id_dst, const ID *id_src, cons
|
||||||
|
|
||||||
collection_dst->flag &= ~COLLECTION_HAS_OBJECT_CACHE;
|
collection_dst->flag &= ~COLLECTION_HAS_OBJECT_CACHE;
|
||||||
collection_dst->flag &= ~COLLECTION_HAS_OBJECT_CACHE_INSTANCED;
|
collection_dst->flag &= ~COLLECTION_HAS_OBJECT_CACHE_INSTANCED;
|
||||||
BLI_listbase_clear(&collection_dst->object_cache);
|
BLI_listbase_clear(&collection_dst->runtime.object_cache);
|
||||||
BLI_listbase_clear(&collection_dst->object_cache_instanced);
|
BLI_listbase_clear(&collection_dst->runtime.object_cache_instanced);
|
||||||
|
|
||||||
BLI_listbase_clear(&collection_dst->gobject);
|
BLI_listbase_clear(&collection_dst->gobject);
|
||||||
BLI_listbase_clear(&collection_dst->children);
|
BLI_listbase_clear(&collection_dst->children);
|
||||||
BLI_listbase_clear(&collection_dst->parents);
|
BLI_listbase_clear(&collection_dst->runtime.parents);
|
||||||
|
|
||||||
LISTBASE_FOREACH (CollectionChild *, child, &collection_src->children) {
|
LISTBASE_FOREACH (CollectionChild *, child, &collection_src->children) {
|
||||||
collection_child_add(collection_dst, child->collection, flag, false);
|
collection_child_add(collection_dst, child->collection, flag, false);
|
||||||
|
@ -138,7 +138,7 @@ static void collection_free_data(ID *id)
|
||||||
|
|
||||||
BLI_freelistN(&collection->gobject);
|
BLI_freelistN(&collection->gobject);
|
||||||
BLI_freelistN(&collection->children);
|
BLI_freelistN(&collection->children);
|
||||||
BLI_freelistN(&collection->parents);
|
BLI_freelistN(&collection->runtime.parents);
|
||||||
|
|
||||||
BKE_collection_object_cache_free(collection);
|
BKE_collection_object_cache_free(collection);
|
||||||
}
|
}
|
||||||
|
@ -148,7 +148,7 @@ static void collection_foreach_id(ID *id, LibraryForeachIDData *data)
|
||||||
Collection *collection = (Collection *)id;
|
Collection *collection = (Collection *)id;
|
||||||
|
|
||||||
BKE_LIB_FOREACHID_PROCESS_ID(
|
BKE_LIB_FOREACHID_PROCESS_ID(
|
||||||
data, collection->owner_id, IDWALK_CB_LOOPBACK | IDWALK_CB_NEVER_SELF);
|
data, collection->runtime.owner_id, IDWALK_CB_LOOPBACK | IDWALK_CB_NEVER_SELF);
|
||||||
|
|
||||||
LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) {
|
LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) {
|
||||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, cob->ob, IDWALK_CB_USER);
|
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, cob->ob, IDWALK_CB_USER);
|
||||||
|
@ -157,7 +157,7 @@ static void collection_foreach_id(ID *id, LibraryForeachIDData *data)
|
||||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(
|
BKE_LIB_FOREACHID_PROCESS_IDSUPER(
|
||||||
data, child->collection, IDWALK_CB_NEVER_SELF | IDWALK_CB_USER);
|
data, child->collection, IDWALK_CB_NEVER_SELF | IDWALK_CB_USER);
|
||||||
}
|
}
|
||||||
LISTBASE_FOREACH (CollectionParent *, parent, &collection->parents) {
|
LISTBASE_FOREACH (CollectionParent *, parent, &collection->runtime.parents) {
|
||||||
/* XXX This is very weak. The whole idea of keeping pointers to private IDs is very bad
|
/* XXX This is very weak. The whole idea of keeping pointers to private IDs is very bad
|
||||||
* anyway... */
|
* anyway... */
|
||||||
const int cb_flag = ((parent->collection != NULL &&
|
const int cb_flag = ((parent->collection != NULL &&
|
||||||
|
@ -178,11 +178,12 @@ static ID **collection_owner_pointer_get(ID *id)
|
||||||
|
|
||||||
Collection *master_collection = (Collection *)id;
|
Collection *master_collection = (Collection *)id;
|
||||||
BLI_assert((master_collection->flag & COLLECTION_IS_MASTER) != 0);
|
BLI_assert((master_collection->flag & COLLECTION_IS_MASTER) != 0);
|
||||||
BLI_assert(master_collection->owner_id != NULL);
|
BLI_assert(master_collection->runtime.owner_id != NULL);
|
||||||
BLI_assert(GS(master_collection->owner_id->name) == ID_SCE);
|
BLI_assert(GS(master_collection->runtime.owner_id->name) == ID_SCE);
|
||||||
BLI_assert(((Scene *)master_collection->owner_id)->master_collection == master_collection);
|
BLI_assert(((Scene *)master_collection->runtime.owner_id)->master_collection ==
|
||||||
|
master_collection);
|
||||||
|
|
||||||
return &master_collection->owner_id;
|
return &master_collection->runtime.owner_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BKE_collection_blend_write_nolib(BlendWriter *writer, Collection *collection)
|
void BKE_collection_blend_write_nolib(BlendWriter *writer, Collection *collection)
|
||||||
|
@ -208,10 +209,10 @@ static void collection_blend_write(BlendWriter *writer, ID *id, const void *id_a
|
||||||
/* Clean up, important in undo case to reduce false detection of changed data-blocks. */
|
/* Clean up, important in undo case to reduce false detection of changed data-blocks. */
|
||||||
collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE;
|
collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE;
|
||||||
collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE_INSTANCED;
|
collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE_INSTANCED;
|
||||||
collection->tag = 0;
|
collection->runtime.tag = 0;
|
||||||
BLI_listbase_clear(&collection->object_cache);
|
BLI_listbase_clear(&collection->runtime.object_cache);
|
||||||
BLI_listbase_clear(&collection->object_cache_instanced);
|
BLI_listbase_clear(&collection->runtime.object_cache_instanced);
|
||||||
BLI_listbase_clear(&collection->parents);
|
BLI_listbase_clear(&collection->runtime.parents);
|
||||||
|
|
||||||
/* write LibData */
|
/* write LibData */
|
||||||
BLO_write_id_struct(writer, Collection, id_address, &collection->id);
|
BLO_write_id_struct(writer, Collection, id_address, &collection->id);
|
||||||
|
@ -258,7 +259,7 @@ void BKE_collection_blend_read_data(BlendDataReader *reader, Collection *collect
|
||||||
}
|
}
|
||||||
collection->id.flag |= LIB_EMBEDDED_DATA;
|
collection->id.flag |= LIB_EMBEDDED_DATA;
|
||||||
}
|
}
|
||||||
collection->owner_id = owner_id;
|
collection->runtime.owner_id = owner_id;
|
||||||
|
|
||||||
BLO_read_list(reader, &collection->gobject);
|
BLO_read_list(reader, &collection->gobject);
|
||||||
BLO_read_list(reader, &collection->children);
|
BLO_read_list(reader, &collection->children);
|
||||||
|
@ -268,10 +269,10 @@ void BKE_collection_blend_read_data(BlendDataReader *reader, Collection *collect
|
||||||
|
|
||||||
collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE;
|
collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE;
|
||||||
collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE_INSTANCED;
|
collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE_INSTANCED;
|
||||||
collection->tag = 0;
|
collection->runtime.tag = 0;
|
||||||
BLI_listbase_clear(&collection->object_cache);
|
BLI_listbase_clear(&collection->runtime.object_cache);
|
||||||
BLI_listbase_clear(&collection->object_cache_instanced);
|
BLI_listbase_clear(&collection->runtime.object_cache_instanced);
|
||||||
BLI_listbase_clear(&collection->parents);
|
BLI_listbase_clear(&collection->runtime.parents);
|
||||||
|
|
||||||
#ifdef USE_COLLECTION_COMPAT_28
|
#ifdef USE_COLLECTION_COMPAT_28
|
||||||
/* This runs before the very first doversion. */
|
/* This runs before the very first doversion. */
|
||||||
|
@ -543,7 +544,7 @@ bool BKE_collection_delete(Main *bmain, Collection *collection, bool hierarchy)
|
||||||
else {
|
else {
|
||||||
/* Link child collections into parent collection. */
|
/* Link child collections into parent collection. */
|
||||||
LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
|
LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
|
||||||
LISTBASE_FOREACH (CollectionParent *, cparent, &collection->parents) {
|
LISTBASE_FOREACH (CollectionParent *, cparent, &collection->runtime.parents) {
|
||||||
Collection *parent = cparent->collection;
|
Collection *parent = cparent->collection;
|
||||||
collection_child_add(parent, child->collection, 0, true);
|
collection_child_add(parent, child->collection, 0, true);
|
||||||
}
|
}
|
||||||
|
@ -552,7 +553,7 @@ bool BKE_collection_delete(Main *bmain, Collection *collection, bool hierarchy)
|
||||||
CollectionObject *cob = collection->gobject.first;
|
CollectionObject *cob = collection->gobject.first;
|
||||||
while (cob != NULL) {
|
while (cob != NULL) {
|
||||||
/* Link child object into parent collections. */
|
/* Link child object into parent collections. */
|
||||||
LISTBASE_FOREACH (CollectionParent *, cparent, &collection->parents) {
|
LISTBASE_FOREACH (CollectionParent *, cparent, &collection->runtime.parents) {
|
||||||
Collection *parent = cparent->collection;
|
Collection *parent = cparent->collection;
|
||||||
collection_object_add(bmain, parent, cob->ob, 0, true);
|
collection_object_add(bmain, parent, cob->ob, 0, true);
|
||||||
}
|
}
|
||||||
|
@ -816,13 +817,13 @@ ListBase BKE_collection_object_cache_get(Collection *collection)
|
||||||
|
|
||||||
BLI_mutex_lock(&cache_lock);
|
BLI_mutex_lock(&cache_lock);
|
||||||
if (!(collection->flag & COLLECTION_HAS_OBJECT_CACHE)) {
|
if (!(collection->flag & COLLECTION_HAS_OBJECT_CACHE)) {
|
||||||
collection_object_cache_fill(&collection->object_cache, collection, 0, false);
|
collection_object_cache_fill(&collection->runtime.object_cache, collection, 0, false);
|
||||||
collection->flag |= COLLECTION_HAS_OBJECT_CACHE;
|
collection->flag |= COLLECTION_HAS_OBJECT_CACHE;
|
||||||
}
|
}
|
||||||
BLI_mutex_unlock(&cache_lock);
|
BLI_mutex_unlock(&cache_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
return collection->object_cache;
|
return collection->runtime.object_cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
ListBase BKE_collection_object_cache_instanced_get(Collection *collection)
|
ListBase BKE_collection_object_cache_instanced_get(Collection *collection)
|
||||||
|
@ -832,13 +833,14 @@ ListBase BKE_collection_object_cache_instanced_get(Collection *collection)
|
||||||
|
|
||||||
BLI_mutex_lock(&cache_lock);
|
BLI_mutex_lock(&cache_lock);
|
||||||
if (!(collection->flag & COLLECTION_HAS_OBJECT_CACHE_INSTANCED)) {
|
if (!(collection->flag & COLLECTION_HAS_OBJECT_CACHE_INSTANCED)) {
|
||||||
collection_object_cache_fill(&collection->object_cache_instanced, collection, 0, true);
|
collection_object_cache_fill(
|
||||||
|
&collection->runtime.object_cache_instanced, collection, 0, true);
|
||||||
collection->flag |= COLLECTION_HAS_OBJECT_CACHE_INSTANCED;
|
collection->flag |= COLLECTION_HAS_OBJECT_CACHE_INSTANCED;
|
||||||
}
|
}
|
||||||
BLI_mutex_unlock(&cache_lock);
|
BLI_mutex_unlock(&cache_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
return collection->object_cache_instanced;
|
return collection->runtime.object_cache_instanced;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void collection_object_cache_free(Collection *collection)
|
static void collection_object_cache_free(Collection *collection)
|
||||||
|
@ -846,10 +848,10 @@ static void collection_object_cache_free(Collection *collection)
|
||||||
/* Clear own cache an for all parents, since those are affected by changes as well. */
|
/* Clear own cache an for all parents, since those are affected by changes as well. */
|
||||||
collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE;
|
collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE;
|
||||||
collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE_INSTANCED;
|
collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE_INSTANCED;
|
||||||
BLI_freelistN(&collection->object_cache);
|
BLI_freelistN(&collection->runtime.object_cache);
|
||||||
BLI_freelistN(&collection->object_cache_instanced);
|
BLI_freelistN(&collection->runtime.object_cache_instanced);
|
||||||
|
|
||||||
LISTBASE_FOREACH (CollectionParent *, parent, &collection->parents) {
|
LISTBASE_FOREACH (CollectionParent *, parent, &collection->runtime.parents) {
|
||||||
collection_object_cache_free(parent->collection);
|
collection_object_cache_free(parent->collection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -884,7 +886,7 @@ Collection *BKE_collection_master_add(Scene *scene)
|
||||||
Collection *master_collection = BKE_libblock_alloc(
|
Collection *master_collection = BKE_libblock_alloc(
|
||||||
NULL, ID_GR, BKE_SCENE_COLLECTION_NAME, LIB_ID_CREATE_NO_MAIN);
|
NULL, ID_GR, BKE_SCENE_COLLECTION_NAME, LIB_ID_CREATE_NO_MAIN);
|
||||||
master_collection->id.flag |= LIB_EMBEDDED_DATA;
|
master_collection->id.flag |= LIB_EMBEDDED_DATA;
|
||||||
master_collection->owner_id = &scene->id;
|
master_collection->runtime.owner_id = &scene->id;
|
||||||
master_collection->flag |= COLLECTION_IS_MASTER;
|
master_collection->flag |= COLLECTION_IS_MASTER;
|
||||||
master_collection->color_tag = COLLECTION_COLOR_NONE;
|
master_collection->color_tag = COLLECTION_COLOR_NONE;
|
||||||
|
|
||||||
|
@ -1024,7 +1026,7 @@ static void collection_tag_update_parent_recursive(Main *bmain,
|
||||||
|
|
||||||
DEG_id_tag_update_ex(bmain, &collection->id, flag);
|
DEG_id_tag_update_ex(bmain, &collection->id, flag);
|
||||||
|
|
||||||
LISTBASE_FOREACH (CollectionParent *, collection_parent, &collection->parents) {
|
LISTBASE_FOREACH (CollectionParent *, collection_parent, &collection->runtime.parents) {
|
||||||
if (collection_parent->collection->flag & COLLECTION_IS_MASTER) {
|
if (collection_parent->collection->flag & COLLECTION_IS_MASTER) {
|
||||||
/* We don't care about scene/master collection here. */
|
/* We don't care about scene/master collection here. */
|
||||||
continue;
|
continue;
|
||||||
|
@ -1045,7 +1047,7 @@ static Collection *collection_parent_editable_find_recursive(const ViewLayer *vi
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
LISTBASE_FOREACH (CollectionParent *, collection_parent, &collection->parents) {
|
LISTBASE_FOREACH (CollectionParent *, collection_parent, &collection->runtime.parents) {
|
||||||
if (!ID_IS_LINKED(collection_parent->collection) &&
|
if (!ID_IS_LINKED(collection_parent->collection) &&
|
||||||
!ID_IS_OVERRIDE_LIBRARY(collection_parent->collection)) {
|
!ID_IS_OVERRIDE_LIBRARY(collection_parent->collection)) {
|
||||||
if (view_layer != NULL &&
|
if (view_layer != NULL &&
|
||||||
|
@ -1344,9 +1346,9 @@ static void collection_null_children_remove(Collection *collection)
|
||||||
|
|
||||||
static void collection_missing_parents_remove(Collection *collection)
|
static void collection_missing_parents_remove(Collection *collection)
|
||||||
{
|
{
|
||||||
LISTBASE_FOREACH_MUTABLE (CollectionParent *, parent, &collection->parents) {
|
LISTBASE_FOREACH_MUTABLE (CollectionParent *, parent, &collection->runtime.parents) {
|
||||||
if ((parent->collection == NULL) || !collection_find_child(parent->collection, collection)) {
|
if ((parent->collection == NULL) || !collection_find_child(parent->collection, collection)) {
|
||||||
BLI_freelinkN(&collection->parents, parent);
|
BLI_freelinkN(&collection->runtime.parents, parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1380,11 +1382,11 @@ void BKE_collections_child_remove_nulls(Main *bmain,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LISTBASE_FOREACH_MUTABLE (CollectionParent *, parent, &child_collection->parents) {
|
LISTBASE_FOREACH_MUTABLE (CollectionParent *, parent, &child_collection->runtime.parents) {
|
||||||
collection_null_children_remove(parent->collection);
|
collection_null_children_remove(parent->collection);
|
||||||
|
|
||||||
if (!collection_find_child(parent->collection, child_collection)) {
|
if (!collection_find_child(parent->collection, child_collection)) {
|
||||||
BLI_freelinkN(&child_collection->parents, parent);
|
BLI_freelinkN(&child_collection->runtime.parents, parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1420,7 +1422,7 @@ bool BKE_collection_is_in_scene(Collection *collection)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
LISTBASE_FOREACH (CollectionParent *, cparent, &collection->parents) {
|
LISTBASE_FOREACH (CollectionParent *, cparent, &collection->runtime.parents) {
|
||||||
if (BKE_collection_is_in_scene(cparent->collection)) {
|
if (BKE_collection_is_in_scene(cparent->collection)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1474,7 +1476,7 @@ bool BKE_collection_cycle_find(Collection *new_ancestor, Collection *collection)
|
||||||
collection = new_ancestor;
|
collection = new_ancestor;
|
||||||
}
|
}
|
||||||
|
|
||||||
LISTBASE_FOREACH (CollectionParent *, parent, &new_ancestor->parents) {
|
LISTBASE_FOREACH (CollectionParent *, parent, &new_ancestor->runtime.parents) {
|
||||||
if (BKE_collection_cycle_find(parent->collection, collection)) {
|
if (BKE_collection_cycle_find(parent->collection, collection)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1514,7 +1516,7 @@ static bool collection_cycle_fix_recursive(Main *bmain,
|
||||||
{
|
{
|
||||||
bool cycles_found = false;
|
bool cycles_found = false;
|
||||||
|
|
||||||
LISTBASE_FOREACH_MUTABLE (CollectionParent *, parent, &parent_collection->parents) {
|
LISTBASE_FOREACH_MUTABLE (CollectionParent *, parent, &parent_collection->runtime.parents) {
|
||||||
if (BKE_collection_cycle_find(parent->collection, collection)) {
|
if (BKE_collection_cycle_find(parent->collection, collection)) {
|
||||||
BKE_collection_child_remove(bmain, parent->collection, parent_collection);
|
BKE_collection_child_remove(bmain, parent->collection, parent_collection);
|
||||||
cycles_found = true;
|
cycles_found = true;
|
||||||
|
@ -1560,7 +1562,7 @@ bool BKE_collection_has_collection(const Collection *parent, const Collection *c
|
||||||
|
|
||||||
static CollectionParent *collection_find_parent(Collection *child, Collection *collection)
|
static CollectionParent *collection_find_parent(Collection *child, Collection *collection)
|
||||||
{
|
{
|
||||||
return BLI_findptr(&child->parents, collection, offsetof(CollectionParent, collection));
|
return BLI_findptr(&child->runtime.parents, collection, offsetof(CollectionParent, collection));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool collection_child_add(Collection *parent,
|
static bool collection_child_add(Collection *parent,
|
||||||
|
@ -1584,7 +1586,7 @@ static bool collection_child_add(Collection *parent,
|
||||||
if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) {
|
if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) {
|
||||||
CollectionParent *cparent = MEM_callocN(sizeof(CollectionParent), "CollectionParent");
|
CollectionParent *cparent = MEM_callocN(sizeof(CollectionParent), "CollectionParent");
|
||||||
cparent->collection = parent;
|
cparent->collection = parent;
|
||||||
BLI_addtail(&collection->parents, cparent);
|
BLI_addtail(&collection->runtime.parents, cparent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (add_us) {
|
if (add_us) {
|
||||||
|
@ -1604,7 +1606,7 @@ static bool collection_child_remove(Collection *parent, Collection *collection)
|
||||||
}
|
}
|
||||||
|
|
||||||
CollectionParent *cparent = collection_find_parent(collection, parent);
|
CollectionParent *cparent = collection_find_parent(collection, parent);
|
||||||
BLI_freelinkN(&collection->parents, cparent);
|
BLI_freelinkN(&collection->runtime.parents, cparent);
|
||||||
BLI_freelinkN(&parent->children, child);
|
BLI_freelinkN(&parent->children, child);
|
||||||
|
|
||||||
id_us_min(&collection->id);
|
id_us_min(&collection->id);
|
||||||
|
@ -1664,19 +1666,19 @@ void BKE_collection_parent_relations_rebuild(Collection *collection)
|
||||||
BLI_assert(collection_find_parent(child->collection, collection) == NULL);
|
BLI_assert(collection_find_parent(child->collection, collection) == NULL);
|
||||||
CollectionParent *cparent = MEM_callocN(sizeof(CollectionParent), __func__);
|
CollectionParent *cparent = MEM_callocN(sizeof(CollectionParent), __func__);
|
||||||
cparent->collection = collection;
|
cparent->collection = collection;
|
||||||
BLI_addtail(&child->collection->parents, cparent);
|
BLI_addtail(&child->collection->runtime.parents, cparent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void collection_parents_rebuild_recursive(Collection *collection)
|
static void collection_parents_rebuild_recursive(Collection *collection)
|
||||||
{
|
{
|
||||||
/* A same collection may be child of several others, no need to process it more than once. */
|
/* A same collection may be child of several others, no need to process it more than once. */
|
||||||
if ((collection->tag & COLLECTION_TAG_RELATION_REBUILD) == 0) {
|
if ((collection->runtime.tag & COLLECTION_TAG_RELATION_REBUILD) == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BKE_collection_parent_relations_rebuild(collection);
|
BKE_collection_parent_relations_rebuild(collection);
|
||||||
collection->tag &= ~COLLECTION_TAG_RELATION_REBUILD;
|
collection->runtime.tag &= ~COLLECTION_TAG_RELATION_REBUILD;
|
||||||
|
|
||||||
LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
|
LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
|
||||||
/* See comment above in `BKE_collection_parent_relations_rebuild`. */
|
/* See comment above in `BKE_collection_parent_relations_rebuild`. */
|
||||||
|
@ -1691,9 +1693,9 @@ void BKE_main_collections_parent_relations_rebuild(Main *bmain)
|
||||||
{
|
{
|
||||||
/* Only collections not in bmain (master ones in scenes) have no parent... */
|
/* Only collections not in bmain (master ones in scenes) have no parent... */
|
||||||
LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
|
LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
|
||||||
BLI_freelistN(&collection->parents);
|
BLI_freelistN(&collection->runtime.parents);
|
||||||
|
|
||||||
collection->tag |= COLLECTION_TAG_RELATION_REBUILD;
|
collection->runtime.tag |= COLLECTION_TAG_RELATION_REBUILD;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Scene's master collections will be 'root' parent of most of our collections, so start with
|
/* Scene's master collections will be 'root' parent of most of our collections, so start with
|
||||||
|
@ -1702,8 +1704,8 @@ void BKE_main_collections_parent_relations_rebuild(Main *bmain)
|
||||||
/* This function can be called from readfile.c, when this pointer is not guaranteed to be NULL.
|
/* This function can be called from readfile.c, when this pointer is not guaranteed to be NULL.
|
||||||
*/
|
*/
|
||||||
if (scene->master_collection != NULL) {
|
if (scene->master_collection != NULL) {
|
||||||
BLI_assert(BLI_listbase_is_empty(&scene->master_collection->parents));
|
BLI_assert(BLI_listbase_is_empty(&scene->master_collection->runtime.parents));
|
||||||
scene->master_collection->tag |= COLLECTION_TAG_RELATION_REBUILD;
|
scene->master_collection->runtime.tag |= COLLECTION_TAG_RELATION_REBUILD;
|
||||||
collection_parents_rebuild_recursive(scene->master_collection);
|
collection_parents_rebuild_recursive(scene->master_collection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1711,7 +1713,7 @@ void BKE_main_collections_parent_relations_rebuild(Main *bmain)
|
||||||
/* We may have parent chains outside of scene's master_collection context? At least, readfile's
|
/* We may have parent chains outside of scene's master_collection context? At least, readfile's
|
||||||
* lib_link_collection_data() seems to assume that, so do the same here. */
|
* lib_link_collection_data() seems to assume that, so do the same here. */
|
||||||
LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
|
LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
|
||||||
if (collection->tag & COLLECTION_TAG_RELATION_REBUILD) {
|
if (collection->runtime.tag & COLLECTION_TAG_RELATION_REBUILD) {
|
||||||
/* NOTE: we do not have easy access to 'which collections is root' info in that case, which
|
/* NOTE: we do not have easy access to 'which collections is root' info in that case, which
|
||||||
* means test for cycles in collection relationships may fail here. I don't think that is an
|
* means test for cycles in collection relationships may fail here. I don't think that is an
|
||||||
* issue in practice here, but worth keeping in mind... */
|
* issue in practice here, but worth keeping in mind... */
|
||||||
|
|
|
@ -626,7 +626,8 @@ static bool layer_collection_hidden(ViewLayer *view_layer, LayerCollection *lc)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restriction flags stay set, so we need to check parents */
|
/* Restriction flags stay set, so we need to check parents */
|
||||||
CollectionParent *parent = static_cast<CollectionParent *>(lc->collection->parents.first);
|
CollectionParent *parent = static_cast<CollectionParent *>(
|
||||||
|
lc->collection->runtime.parents.first);
|
||||||
|
|
||||||
if (parent) {
|
if (parent) {
|
||||||
lc = BKE_layer_collection_first_from_scene_collection(view_layer, parent->collection);
|
lc = BKE_layer_collection_first_from_scene_collection(view_layer, parent->collection);
|
||||||
|
@ -662,7 +663,8 @@ bool BKE_layer_collection_activate(ViewLayer *view_layer, LayerCollection *lc)
|
||||||
|
|
||||||
LayerCollection *BKE_layer_collection_activate_parent(ViewLayer *view_layer, LayerCollection *lc)
|
LayerCollection *BKE_layer_collection_activate_parent(ViewLayer *view_layer, LayerCollection *lc)
|
||||||
{
|
{
|
||||||
CollectionParent *parent = static_cast<CollectionParent *>(lc->collection->parents.first);
|
CollectionParent *parent = static_cast<CollectionParent *>(
|
||||||
|
lc->collection->runtime.parents.first);
|
||||||
|
|
||||||
if (parent) {
|
if (parent) {
|
||||||
lc = BKE_layer_collection_first_from_scene_collection(view_layer, parent->collection);
|
lc = BKE_layer_collection_first_from_scene_collection(view_layer, parent->collection);
|
||||||
|
|
|
@ -277,7 +277,7 @@ static void scene_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int
|
||||||
(ID *)scene_src->master_collection,
|
(ID *)scene_src->master_collection,
|
||||||
(ID **)&scene_dst->master_collection,
|
(ID **)&scene_dst->master_collection,
|
||||||
flag_private_id_data);
|
flag_private_id_data);
|
||||||
scene_dst->master_collection->owner_id = &scene_dst->id;
|
scene_dst->master_collection->runtime.owner_id = &scene_dst->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* View Layers */
|
/* View Layers */
|
||||||
|
|
|
@ -609,7 +609,7 @@ static void template_id_liboverride_hierarchy_collection_root_find_recursive(
|
||||||
*r_collection_parent_best = collection;
|
*r_collection_parent_best = collection;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (CollectionParent *iter = static_cast<CollectionParent *>(collection->parents.first);
|
for (CollectionParent *iter = static_cast<CollectionParent *>(collection->runtime.parents.first);
|
||||||
iter != nullptr;
|
iter != nullptr;
|
||||||
iter = iter->next) {
|
iter = iter->next) {
|
||||||
if (iter->collection->id.lib != collection->id.lib && ID_IS_LINKED(iter->collection)) {
|
if (iter->collection->id.lib != collection->id.lib && ID_IS_LINKED(iter->collection)) {
|
||||||
|
@ -628,7 +628,8 @@ static void template_id_liboverride_hierarchy_collections_tag_recursive(
|
||||||
/* Tag all local parents of the root collection, so that usages of the root collection and other
|
/* Tag all local parents of the root collection, so that usages of the root collection and other
|
||||||
* linked ones can be replaced by the local overrides in those parents too. */
|
* linked ones can be replaced by the local overrides in those parents too. */
|
||||||
if (do_parents) {
|
if (do_parents) {
|
||||||
for (CollectionParent *iter = static_cast<CollectionParent *>(root_collection->parents.first);
|
for (CollectionParent *iter =
|
||||||
|
static_cast<CollectionParent *>(root_collection->runtime.parents.first);
|
||||||
iter != nullptr;
|
iter != nullptr;
|
||||||
iter = iter->next) {
|
iter = iter->next) {
|
||||||
if (ID_IS_LINKED(iter->collection)) {
|
if (ID_IS_LINKED(iter->collection)) {
|
||||||
|
|
|
@ -2435,7 +2435,7 @@ static int make_override_library_exec(bContext *C, wmOperator *op)
|
||||||
case ID_GR: {
|
case ID_GR: {
|
||||||
Collection *collection_root = (Collection *)id_root;
|
Collection *collection_root = (Collection *)id_root;
|
||||||
LISTBASE_FOREACH_MUTABLE (
|
LISTBASE_FOREACH_MUTABLE (
|
||||||
CollectionParent *, collection_parent, &collection_root->parents) {
|
CollectionParent *, collection_parent, &collection_root->runtime.parents) {
|
||||||
if (ID_IS_LINKED(collection_parent->collection) ||
|
if (ID_IS_LINKED(collection_parent->collection) ||
|
||||||
!BKE_view_layer_has_collection(view_layer, collection_parent->collection)) {
|
!BKE_view_layer_has_collection(view_layer, collection_parent->collection)) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -368,7 +368,7 @@ void outliner_collection_delete(
|
||||||
skip = true;
|
skip = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LISTBASE_FOREACH (CollectionParent *, cparent, &collection->parents) {
|
LISTBASE_FOREACH (CollectionParent *, cparent, &collection->runtime.parents) {
|
||||||
Collection *parent = cparent->collection;
|
Collection *parent = cparent->collection;
|
||||||
if (ID_IS_LINKED(parent) || ID_IS_OVERRIDE_LIBRARY(parent)) {
|
if (ID_IS_LINKED(parent) || ID_IS_OVERRIDE_LIBRARY(parent)) {
|
||||||
skip = true;
|
skip = true;
|
||||||
|
|
|
@ -1235,7 +1235,7 @@ static char *collection_drop_tooltip(bContext *C,
|
||||||
|
|
||||||
/* Test if we are moving within same parent collection. */
|
/* Test if we are moving within same parent collection. */
|
||||||
bool same_level = false;
|
bool same_level = false;
|
||||||
LISTBASE_FOREACH (CollectionParent *, parent, &data.to->parents) {
|
LISTBASE_FOREACH (CollectionParent *, parent, &data.to->runtime.parents) {
|
||||||
if (data.from == parent->collection) {
|
if (data.from == parent->collection) {
|
||||||
same_level = true;
|
same_level = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -560,7 +560,7 @@ void outliner_collection_isolate_flag(Scene *scene,
|
||||||
else {
|
else {
|
||||||
CollectionParent *parent;
|
CollectionParent *parent;
|
||||||
Collection *child = collection;
|
Collection *child = collection;
|
||||||
while ((parent = static_cast<CollectionParent *>(child->parents.first))) {
|
while ((parent = static_cast<CollectionParent *>(child->runtime.parents.first))) {
|
||||||
if (parent->collection->flag & COLLECTION_IS_MASTER) {
|
if (parent->collection->flag & COLLECTION_IS_MASTER) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,7 +189,7 @@ bool TreeDisplayLibraries::library_id_filter_poll(const Library *lib, ID *id) co
|
||||||
Collection *collection = (Collection *)id;
|
Collection *collection = (Collection *)id;
|
||||||
bool has_non_scene_parent = false;
|
bool has_non_scene_parent = false;
|
||||||
|
|
||||||
for (CollectionParent *cparent : List<CollectionParent>(collection->parents)) {
|
for (CollectionParent *cparent : List<CollectionParent>(collection->runtime.parents)) {
|
||||||
if (!(cparent->collection->flag & COLLECTION_IS_MASTER)) {
|
if (!(cparent->collection->flag & COLLECTION_IS_MASTER)) {
|
||||||
has_non_scene_parent = true;
|
has_non_scene_parent = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,12 +44,31 @@ enum eCollectionLineArt_Flags {
|
||||||
COLLECTION_LRT_USE_INTERSECTION_PRIORITY = (1 << 1),
|
COLLECTION_LRT_USE_INTERSECTION_PRIORITY = (1 << 1),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct Collection_Runtime {
|
||||||
|
/** The ID owning this collection, in case it is an embedded one. */
|
||||||
|
ID *owner_id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cache of objects in this collection and all its children.
|
||||||
|
* This is created on demand when e.g. some physics simulation needs it,
|
||||||
|
* we don't want to have it for every collections due to memory usage reasons.
|
||||||
|
*/
|
||||||
|
ListBase object_cache;
|
||||||
|
|
||||||
|
/** Need this for line art sub-collection selections. */
|
||||||
|
ListBase object_cache_instanced;
|
||||||
|
|
||||||
|
/** List of collections that are a parent of this data-block. */
|
||||||
|
ListBase parents;
|
||||||
|
|
||||||
|
uint8_t tag;
|
||||||
|
|
||||||
|
char _pad0[7];
|
||||||
|
} Collection_Runtime;
|
||||||
|
|
||||||
typedef struct Collection {
|
typedef struct Collection {
|
||||||
ID id;
|
ID id;
|
||||||
|
|
||||||
/** The ID owning this node tree, in case it is an embedded one. */
|
|
||||||
ID *owner_id;
|
|
||||||
|
|
||||||
/** CollectionObject. */
|
/** CollectionObject. */
|
||||||
ListBase gobject;
|
ListBase gobject;
|
||||||
/** CollectionChild. */
|
/** CollectionChild. */
|
||||||
|
@ -60,56 +79,51 @@ typedef struct Collection {
|
||||||
unsigned int layer DNA_DEPRECATED;
|
unsigned int layer DNA_DEPRECATED;
|
||||||
float instance_offset[3];
|
float instance_offset[3];
|
||||||
|
|
||||||
short flag;
|
uint8_t flag;
|
||||||
/* Runtime-only, always cleared on file load. */
|
int8_t color_tag;
|
||||||
short tag;
|
|
||||||
|
|
||||||
short lineart_usage; /* eCollectionLineArt_Usage */
|
char _pad0[2];
|
||||||
unsigned char lineart_flags; /* eCollectionLineArt_Flags */
|
|
||||||
unsigned char lineart_intersection_mask;
|
|
||||||
unsigned char lineart_intersection_priority;
|
|
||||||
char _pad[5];
|
|
||||||
|
|
||||||
int16_t color_tag;
|
uint8_t lineart_usage; /* #eCollectionLineArt_Usage */
|
||||||
|
uint8_t lineart_flags; /* #eCollectionLineArt_Flags */
|
||||||
|
uint8_t lineart_intersection_mask;
|
||||||
|
uint8_t lineart_intersection_priority;
|
||||||
|
|
||||||
/* Runtime. Cache of objects in this collection and all its
|
|
||||||
* children. This is created on demand when e.g. some physics
|
|
||||||
* simulation needs it, we don't want to have it for every
|
|
||||||
* collections due to memory usage reasons. */
|
|
||||||
ListBase object_cache;
|
|
||||||
|
|
||||||
/* Need this for line art sub-collection selections. */
|
|
||||||
ListBase object_cache_instanced;
|
|
||||||
|
|
||||||
/* Runtime. List of collections that are a parent of this
|
|
||||||
* datablock. */
|
|
||||||
ListBase parents;
|
|
||||||
|
|
||||||
/* Deprecated */
|
|
||||||
struct SceneCollection *collection DNA_DEPRECATED;
|
struct SceneCollection *collection DNA_DEPRECATED;
|
||||||
struct ViewLayer *view_layer DNA_DEPRECATED;
|
struct ViewLayer *view_layer DNA_DEPRECATED;
|
||||||
|
|
||||||
|
/* Keep last. */
|
||||||
|
Collection_Runtime runtime;
|
||||||
} Collection;
|
} Collection;
|
||||||
|
|
||||||
/* Collection->flag */
|
/** #Collection.flag */
|
||||||
enum {
|
enum {
|
||||||
COLLECTION_HIDE_VIEWPORT = (1 << 0), /* Disable in viewports. */
|
/** Disable in viewports. */
|
||||||
COLLECTION_HIDE_SELECT = (1 << 1), /* Not selectable in viewport. */
|
COLLECTION_HIDE_VIEWPORT = (1 << 0),
|
||||||
/* COLLECTION_DISABLED_DEPRECATED = (1 << 2), */ /* Not used anymore */
|
/** Not selectable in viewport. */
|
||||||
COLLECTION_HIDE_RENDER = (1 << 3), /* Disable in renders. */
|
COLLECTION_HIDE_SELECT = (1 << 1),
|
||||||
COLLECTION_HAS_OBJECT_CACHE = (1 << 4), /* Runtime: object_cache is populated. */
|
// COLLECTION_DISABLED_DEPRECATED = (1 << 2), /* DIRTY */
|
||||||
COLLECTION_IS_MASTER = (1 << 5), /* Is master collection embedded in the scene. */
|
/** Disable in renders. */
|
||||||
COLLECTION_HAS_OBJECT_CACHE_INSTANCED = (1 << 6), /* for object_cache_instanced. */
|
COLLECTION_HIDE_RENDER = (1 << 3),
|
||||||
|
/** Runtime: object_cache is populated. */
|
||||||
|
COLLECTION_HAS_OBJECT_CACHE = (1 << 4),
|
||||||
|
/** Is master collection embedded in the scene. */
|
||||||
|
COLLECTION_IS_MASTER = (1 << 5),
|
||||||
|
/** for object_cache_instanced. */
|
||||||
|
COLLECTION_HAS_OBJECT_CACHE_INSTANCED = (1 << 6),
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Collection->tag */
|
/** #Collection_Runtime.tag */
|
||||||
enum {
|
enum {
|
||||||
/* That code (BKE_main_collections_parent_relations_rebuild and the like)
|
/**
|
||||||
|
* That code (#BKE_main_collections_parent_relations_rebuild and the like)
|
||||||
* is called from very low-level places, like e.g ID remapping...
|
* is called from very low-level places, like e.g ID remapping...
|
||||||
* Using a generic tag like LIB_TAG_DOIT for this is just impossible, we need our very own. */
|
* Using a generic tag like #LIB_TAG_DOIT for this is just impossible, we need our very own.
|
||||||
|
*/
|
||||||
COLLECTION_TAG_RELATION_REBUILD = (1 << 0),
|
COLLECTION_TAG_RELATION_REBUILD = (1 << 0),
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Collection->color_tag. */
|
/** #Collection.color_tag */
|
||||||
typedef enum CollectionColorTag {
|
typedef enum CollectionColorTag {
|
||||||
COLLECTION_COLOR_NONE = -1,
|
COLLECTION_COLOR_NONE = -1,
|
||||||
COLLECTION_COLOR_01,
|
COLLECTION_COLOR_01,
|
||||||
|
|
|
@ -31,6 +31,9 @@ const EnumPropertyItem rna_enum_collection_color_items[] = {
|
||||||
{COLLECTION_COLOR_08, "COLOR_08", ICON_COLLECTION_COLOR_08, "Color 08", ""},
|
{COLLECTION_COLOR_08, "COLOR_08", ICON_COLLECTION_COLOR_08, "Color 08", ""},
|
||||||
{0, NULL, 0, NULL, NULL},
|
{0, NULL, 0, NULL, NULL},
|
||||||
};
|
};
|
||||||
|
/* Minus 1 for NONE & 1 for the NULL sentinel. */
|
||||||
|
BLI_STATIC_ASSERT(ARRAY_SIZE(rna_enum_collection_color_items) - 2 == COLLECTION_COLOR_TOT,
|
||||||
|
"Collection color total is an invalid size");
|
||||||
|
|
||||||
#ifdef RNA_RUNTIME
|
#ifdef RNA_RUNTIME
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue