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--source/blender/blenkernel/intern/lib_override.c99
-rw-r--r--source/blender/makesdna/DNA_ID.h4
2 files changed, 91 insertions, 12 deletions
diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c
index 0f753018c46..63709080b5c 100644
--- a/source/blender/blenkernel/intern/lib_override.c
+++ b/source/blender/blenkernel/intern/lib_override.c
@@ -423,6 +423,8 @@ static void lib_override_linked_group_tag_recursive(LibOverrideGroupTagData *dat
Main *bmain = data->bmain;
ID *id_owner = data->id_root;
BLI_assert(ID_IS_LINKED(id_owner));
+ const uint tag = data->tag;
+ const uint missing_tag = data->missing_tag;
MainIDRelationsEntry *entry = BLI_ghash_lookup(bmain->relations->relations_from_pointers,
id_owner);
@@ -430,7 +432,6 @@ static void lib_override_linked_group_tag_recursive(LibOverrideGroupTagData *dat
if (entry->tags & MAINIDRELATIONS_ENTRY_TAGS_PROCESSED) {
/* This ID has already been processed. */
- printf("%s already processed\n", id_owner->name);
return;
}
/* This way we won't process again that ID, should we encounter it again through another
@@ -439,9 +440,10 @@ static void lib_override_linked_group_tag_recursive(LibOverrideGroupTagData *dat
for (MainIDRelationsEntryItem *to_id_entry = entry->to_ids; to_id_entry != NULL;
to_id_entry = to_id_entry->next) {
- if ((to_id_entry->usage_flag & IDWALK_CB_LOOPBACK) != 0) {
- /* Never consider 'loop back' relationships ('from', 'parents', 'owner' etc. pointers) as
- * actual dependencies. */
+ if ((to_id_entry->usage_flag &
+ (IDWALK_CB_EMBEDDED | IDWALK_CB_LOOPBACK | IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE)) != 0) {
+ /* Never consider 'loop back' relationships ('from', 'parents', 'owner' etc. pointers), nor
+ * override references or embedded ID pointers, as actual dependencies. */
continue;
}
@@ -460,10 +462,10 @@ static void lib_override_linked_group_tag_recursive(LibOverrideGroupTagData *dat
* Note: missing IDs (aka placeholders) are never overridden. */
if (ELEM(GS(to_id->name), ID_OB, ID_GR)) {
if ((to_id->tag & LIB_TAG_MISSING)) {
- to_id->tag |= data->missing_tag;
+ to_id->tag |= missing_tag;
}
else {
- to_id->tag |= data->tag;
+ to_id->tag |= tag;
}
}
@@ -570,23 +572,93 @@ static int lib_override_local_group_tag_cb(LibraryIDLinkCallbackData *cb_data)
return IDWALK_RET_NOP;
}
+static void lib_override_local_group_tag_recursive(LibOverrideGroupTagData *data)
+{
+ Main *bmain = data->bmain;
+ ID *id_owner = data->id_root;
+ BLI_assert(ID_IS_OVERRIDE_LIBRARY(id_owner));
+ const uint tag = data->tag;
+ const uint missing_tag = data->missing_tag;
+
+ MainIDRelationsEntry *entry = BLI_ghash_lookup(bmain->relations->relations_from_pointers,
+ id_owner);
+ BLI_assert(entry != NULL);
+
+ if (entry->tags & MAINIDRELATIONS_ENTRY_TAGS_PROCESSED) {
+ /* This ID has already been processed. */
+ return;
+ }
+ /* This way we won't process again that ID, should we encounter it again through another
+ * relationship hierarchy. */
+ entry->tags |= MAINIDRELATIONS_ENTRY_TAGS_PROCESSED;
+
+ for (MainIDRelationsEntryItem *to_id_entry = entry->to_ids; to_id_entry != NULL;
+ to_id_entry = to_id_entry->next) {
+ if ((to_id_entry->usage_flag &
+ (IDWALK_CB_EMBEDDED | IDWALK_CB_LOOPBACK | IDWALK_CB_OVERRIDE_LIBRARY_REFERENCE)) != 0) {
+ /* Never consider 'loop back' relationships ('from', 'parents', 'owner' etc. pointers), nor
+ * override references or embedded ID pointers, as actual dependencies. */
+ continue;
+ }
+
+ ID *to_id = *to_id_entry->id_pointer.to;
+ if (ELEM(to_id, NULL, id_owner)) {
+ continue;
+ }
+ if (!ID_IS_OVERRIDE_LIBRARY(to_id) || ID_IS_LINKED(to_id)) {
+ continue;
+ }
+
+ /* Do not tag 'virtual' overrides (shape keys here, as we already rejected embedded case
+ * above). */
+ if (ID_IS_OVERRIDE_LIBRARY_REAL(to_id)) {
+ ID *reference_lib = NULL;
+ if (GS(id_owner->name) == ID_KE) {
+ reference_lib = ((Key *)id_owner)->from->override_library->reference->lib;
+ }
+ else {
+ reference_lib = id_owner->override_library->reference->lib;
+ }
+ if (to_id->override_library->reference->lib != reference_lib) {
+ /* We do not override data-blocks from other libraries, nor do we process them. */
+ continue;
+ }
+
+ if (to_id->override_library->reference->tag & LIB_TAG_MISSING) {
+ to_id->tag |= missing_tag;
+ }
+ else {
+ to_id->tag |= tag;
+ }
+ }
+
+ /* Recursively process the dependencies. */
+ LibOverrideGroupTagData sub_data = *data;
+ sub_data.id_root = to_id;
+ lib_override_local_group_tag_recursive(&sub_data);
+ }
+}
+
/* This will tag all override IDs of an override group defined by the given `id_root`. */
static void lib_override_local_group_tag(LibOverrideGroupTagData *data)
{
- Main *bmain = data->bmain;
ID *id_root = data->id_root;
+ BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_root) && !ID_IS_LINKED(id_root));
- id_root->tag |= data->tag;
+ if ((id_root->override_library->reference->tag & LIB_TAG_MISSING)) {
+ id_root->tag |= data->missing_tag;
+ }
+ else {
+ id_root->tag |= data->tag;
+ }
/* Tag all local overrides in id_root's group. */
- BKE_library_foreach_ID_link(
- bmain, id_root, lib_override_local_group_tag_cb, data, IDWALK_READONLY | IDWALK_RECURSE);
+ lib_override_local_group_tag_recursive(data);
}
static bool lib_override_library_create_do(Main *bmain, ID *id_root)
{
BKE_main_relations_create(bmain, 0);
-
LibOverrideGroupTagData data = {
.bmain = bmain, .id_root = id_root, .tag = LIB_TAG_DOIT, .missing_tag = LIB_TAG_MISSING};
lib_override_linked_group_tag(&data);
@@ -790,11 +862,11 @@ bool BKE_lib_override_library_resync(Main *bmain, Scene *scene, ViewLayer *view_
ID *id_root_reference = id_root->override_library->reference;
BKE_main_relations_create(bmain, 0);
-
LibOverrideGroupTagData data = {
.bmain = bmain, .id_root = id_root, .tag = LIB_TAG_DOIT, .missing_tag = LIB_TAG_MISSING};
lib_override_local_group_tag(&data);
+ BKE_main_relations_tag_set(bmain, MAINIDRELATIONS_ENTRY_TAGS_PROCESSED, false);
data.id_root = id_root_reference;
lib_override_linked_group_tag(&data);
@@ -999,10 +1071,13 @@ void BKE_lib_override_library_delete(Main *bmain, ID *id_root)
BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_root));
/* Tag all library overrides in the chains of dependencies from the given root one. */
+ BKE_main_relations_create(bmain, 0);
LibOverrideGroupTagData data = {
.bmain = bmain, .id_root = id_root, .tag = LIB_TAG_DOIT, .missing_tag = LIB_TAG_MISSING};
lib_override_local_group_tag(&data);
+ BKE_main_relations_free(bmain);
+
ID *id;
FOREACH_MAIN_ID_BEGIN (bmain, id) {
if (id->tag & LIB_TAG_DOIT) {
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index d9c821d3ba7..00d0d4e3626 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -427,6 +427,10 @@ typedef struct PreviewImage {
(ID_IS_LINKED(_id) && !ID_MISSING(_id) && (((const ID *)(_id))->tag & LIB_TAG_EXTERN) != 0 && \
(BKE_idtype_get_info_from_id((const ID *)(_id))->flags & IDTYPE_FLAGS_NO_LIBLINKING) == 0)
+/* NOTE: The three checks below do not take into account whether given ID is linked or not (when
+ * chaining overrides over several libraries). User must ensure the ID is not linked itself
+ * currently. */
+/* TODO: add `_EDITABLE` versions of those macros (that would check if ID is linked or not)? */
#define ID_IS_OVERRIDE_LIBRARY_REAL(_id) \
(((const ID *)(_id))->override_library != NULL && \
((const ID *)(_id))->override_library->reference != NULL)