[Bf-blender-cvs] [8790b55730c] override-recursive-resync: LibOverride: proper order of resync in recursive case.
Bastien Montagne
noreply at git.blender.org
Tue May 25 17:54:02 CEST 2021
Commit: 8790b55730cee8a6681908a4695d41e29a2fe8ac
Author: Bastien Montagne
Date: Tue May 25 17:52:48 2021 +0200
Branches: override-recursive-resync
https://developer.blender.org/rB8790b55730cee8a6681908a4695d41e29a2fe8ac
LibOverride: proper order of resync in recursive case.
When doing recursive resync, one wants to resync first the most
indirectly linked overrides.
===================================================================
M source/blender/blenkernel/intern/lib_override.c
M source/blender/makesdna/DNA_ID.h
===================================================================
diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c
index e858f7e39ac..3694bafe43d 100644
--- a/source/blender/blenkernel/intern/lib_override.c
+++ b/source/blender/blenkernel/intern/lib_override.c
@@ -1260,6 +1260,50 @@ bool BKE_lib_override_library_resync(Main *bmain,
return success;
}
+static int lib_override_sort_libraries_func(LibraryIDLinkCallbackData *cb_data)
+{
+ ID *id_owner = cb_data->id_owner;
+ ID *id = *cb_data->id_pointer;
+ if (id != NULL && ID_IS_LINKED(id) && id->lib != id_owner->lib) {
+ const int owner_library_indirect_level = id_owner->lib != NULL ? id_owner->lib->temp_index : 0;
+ if (owner_library_indirect_level >= id->lib->temp_index) {
+ id->lib->temp_index = owner_library_indirect_level + 1;
+ *(bool *)cb_data->user_data = true;
+ }
+ }
+ return IDWALK_RET_NOP;
+}
+
+/** Define the `temp_index` of libraries from their highest level of indirect usage.
+ *
+ * E.g. if lib_a uses lib_b, lib_c and lib_d, and lib_b also uses lib_d, then lib_a has an index of
+ * 1, lib_b and lib_c an index of 2, and lib_d an index of 3. */
+static int lib_override_libraries_index_define(Main *bmain)
+{
+ LISTBASE_FOREACH (Library *, library, &bmain->libraries) {
+ /* index 0 is reserved for local data. */
+ library->temp_index = 1;
+ }
+ bool do_continue = true;
+ while (do_continue) {
+ do_continue = false;
+ ID *id;
+ FOREACH_MAIN_ID_BEGIN (bmain, id) {
+ BKE_library_foreach_ID_link(
+ bmain, id, lib_override_sort_libraries_func, &do_continue, IDWALK_READONLY);
+ }
+ FOREACH_MAIN_ID_END;
+ }
+
+ int library_indirect_level_max = 0;
+ LISTBASE_FOREACH (Library *, library, &bmain->libraries) {
+ if (library->temp_index > library_indirect_level_max) {
+ library_indirect_level_max = library->temp_index;
+ }
+ }
+ return library_indirect_level_max;
+}
+
/**
* Detect and handle required resync of overrides data, when relations between reference linked IDs
* have changed.
@@ -1368,6 +1412,8 @@ void BKE_lib_override_library_main_resync(Main *bmain,
BKE_main_relations_free(bmain);
BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
+ int library_indirect_level = lib_override_libraries_index_define(bmain);
+
/* And do the actual resync for all IDs detected as needing it.
* NOTE: Since this changes `bmain` (adding **and** removing IDs), we cannot use
* `FOREACH_MAIN_ID_BEGIN/END` here, and need special multi-loop processing. */
@@ -1377,7 +1423,9 @@ void BKE_lib_override_library_main_resync(Main *bmain,
do_continue = false;
FOREACH_MAIN_LISTBASE_BEGIN (bmain, lb) {
FOREACH_MAIN_LISTBASE_ID_BEGIN (lb, id) {
- if ((id->tag & LIB_TAG_LIB_OVERRIDE_NEED_RESYNC) == 0) {
+ if ((id->tag & LIB_TAG_LIB_OVERRIDE_NEED_RESYNC) == 0 ||
+ (ID_IS_LINKED(id) && id->lib->temp_index < library_indirect_level) ||
+ (!ID_IS_LINKED(id) && library_indirect_level != 0)) {
continue;
}
BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id));
@@ -1402,6 +1450,13 @@ void BKE_lib_override_library_main_resync(Main *bmain,
}
}
FOREACH_MAIN_LISTBASE_END;
+
+ if (!do_continue && library_indirect_level != 0) {
+ /* We are done with overrides from that level of indirect linking, we can keep going with
+ * those 'less' indirectly linked now. */
+ library_indirect_level--;
+ do_continue = true;
+ }
}
/* Essentially ensures that potentially new overrides of new objects will be instantiated. */
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index 8bf9afafa1b..dd262f78f6b 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -366,7 +366,7 @@ typedef struct Library {
struct PackedFile *packedfile;
- /* Temp data needed by read/write code. */
+ /* Temp data needed by read/write code, and liboverride recursive resync. */
int temp_index;
/** See BLENDER_FILE_VERSION, BLENDER_FILE_SUBVERSION, needed for do_versions. */
short versionfile, subversionfile;
More information about the Bf-blender-cvs
mailing list