56 #include "RNA_prototypes.h"
61 #define OVERRIDE_AUTO_CHECK_DELAY 0.2
64 #ifdef DEBUG_OVERRIDE_TIMEIT
97 const ID *owner_id_hint,
98 const ID **r_owner_id)
100 if (r_owner_id !=
nullptr) {
109 const_cast<Main *
>(bmain),
const_cast<ID *
>(
id),
const_cast<ID *
>(owner_id_hint));
110 if (r_owner_id !=
nullptr) {
111 *r_owner_id = owner_id;
115 BLI_assert_msg(0,
"IDTypeInfo of liboverride-embedded ID with no owner getter");
117 return id->override_library;
129 const_cast<const ID *
>(
id),
130 const_cast<const ID *
>(owner_id_hint),
131 const_cast<const ID **
>(r_owner_id)));
142 for (ancestor_id = reference_id;
196 const_cast<ID *
>(src_id);
210 op_dst = op_dst->
next, op_src = op_src->
next) {
241 if ((*override)->runtime !=
nullptr) {
242 if ((*override)->runtime->rna_path_to_override_properties !=
nullptr) {
243 BLI_ghash_free((*override)->runtime->rna_path_to_override_properties,
nullptr,
nullptr);
256 const int lib_id_copy_flags)
266 if (local_id ==
nullptr) {
274 local_id->
lib = owner_library;
327 const ID *override_owner_id;
338 const int rnaprop_index)
341 if (anim_data !=
nullptr) {
343 char *index_token_start =
const_cast<char *
>(
345 if (index_token_start !=
nullptr) {
346 const char index_token_start_backup = *index_token_start;
347 *index_token_start =
'\0';
349 anim_data, override_prop->
rna_path, rnaprop_index,
nullptr,
nullptr);
350 *index_token_start = index_token_start_backup;
354 anim_data, override_prop->
rna_path, 0,
nullptr,
nullptr);
356 if (fcurve !=
nullptr) {
367 bool *is_leaf =
static_cast<bool *
>(cb_data->
user_data);
395 const bool do_tagged_remap)
408 if (do_tagged_remap) {
409 Key *reference_key, *local_key =
nullptr;
425 if (reference_key !=
nullptr) {
446 id =
reinterpret_cast<Key *
>(id_iter)->
from;
451 id->override_library->reference->newid =
id;
454 if (reference_key !=
nullptr) {
455 reference_key->
id.
newid = id_iter;
469 Key *reference_key, *local_key =
nullptr;
471 if (reference_id->
newid !=
nullptr) {
484 const ID *id_root_reference,
485 ID *id_hierarchy_root,
486 const ID *id_hierarchy_root_reference,
487 const bool do_no_main,
488 const bool do_fully_editable)
493 BLI_assert(id_hierarchy_root !=
nullptr || id_hierarchy_root_reference !=
nullptr ||
497 BLI_assert(
ELEM(
nullptr, id_hierarchy_root, id_hierarchy_root_reference));
499 if (id_hierarchy_root !=
nullptr) {
512 if (!
ELEM(id_hierarchy_root_reference,
nullptr, id_root_reference)) {
519 const Library *reference_library = id_root_reference->
lib;
529 if ((reference_id->
tag &
LIB_TAG_DOIT) != 0 && reference_id->
lib == reference_library &&
531 todo_id_iter = MEM_cnew<LinkData>(__func__);
532 todo_id_iter->
data = reference_id;
539 for (todo_id_iter =
static_cast<LinkData *
>(todo_ids.
first); todo_id_iter !=
nullptr;
540 todo_id_iter = todo_id_iter->
next) {
541 reference_id =
static_cast<ID *
>(todo_id_iter->
data);
545 if (reference_id->
newid ==
nullptr) {
551 if (reference_id->
newid ==
nullptr) {
555 if (do_fully_editable) {
568 reference_key->
id.
newid = &local_key->
id;
577 if (id_hierarchy_root_reference !=
nullptr) {
578 id_hierarchy_root = id_hierarchy_root_reference->
newid;
580 else if (id_root_reference->
newid !=
nullptr &&
581 (id_hierarchy_root ==
nullptr ||
583 id_hierarchy_root = id_root_reference->
newid;
596 if (do_no_main &&
id->
lib == id_root_reference->
lib &&
id->
newid !=
nullptr) {
597 other_id =
id->
newid;
603 other_id->
lib =
nullptr;
616 ID *local_id = reference_id->
newid;
617 if (other_id == local_id) {
622 if (other_id !=
id) {
623 other_id->
lib = id_root_reference->
lib;
628 for (todo_id_iter =
static_cast<LinkData *
>(todo_ids.
first); todo_id_iter !=
nullptr;
629 todo_id_iter = todo_id_iter->
next) {
630 reference_id =
static_cast<ID *
>(todo_id_iter->
data);
631 ID *local_id = reference_id->
newid;
633 if (local_id ==
nullptr) {
653 for (todo_id_iter =
static_cast<LinkData *
>(todo_ids.
first); todo_id_iter !=
nullptr;
654 todo_id_iter = todo_id_iter->
next) {
655 reference_id =
static_cast<ID *
>(todo_id_iter->
data);
657 reference_id->
newid =
nullptr;
688 Object *ob = collection_object->ob;
696 reinterpret_cast<void ***
>(&collections_linkedlist_p))) {
697 *collections_linkedlist_p =
static_cast<LinkNodePair *
>(
715 if (
data->scene !=
nullptr) {
717 data,
data->scene->master_collection);
735 const bool is_override =
data->is_override;
737 if ((*
reinterpret_cast<uint *
>(&
id->
tag) &
data->tag) == 0) {
755 from_id_entry = from_id_entry->
next) {
762 ID *from_id = from_id_entry->id_pointer.from;
763 if (from_id ==
nullptr || from_id->
lib !=
id->
lib ||
786 const bool is_override =
data->is_override;
787 const bool is_resync =
data->is_resync;
795 return (*
reinterpret_cast<uint *
>(&
id->
tag) &
data->tag) != 0;
802 to_id_entry = to_id_entry->
next) {
809 ID *to_id = *to_id_entry->id_pointer.to;
810 if (to_id ==
nullptr || to_id->
lib !=
id->
lib ||
828 if ((*
reinterpret_cast<uint *
>(&
id->
tag) &
data->tag) != 0 && !is_resync) {
832 return (*
reinterpret_cast<uint *
>(&
id->
tag) &
data->tag) != 0;
838 ID *id_owner =
data->id_root;
842 const uint missing_tag =
data->missing_tag;
857 to_id_entry = to_id_entry->
next) {
863 ID *to_id = *to_id_entry->id_pointer.to;
864 if (
ELEM(to_id,
nullptr, id_owner)) {
868 if (to_id->
lib != id_owner->
lib) {
878 to_id->
tag |= missing_tag;
901 collection_object !=
nullptr;
902 collection_object = collection_object->
next) {
903 Object *
object = collection_object->ob;
904 if (
object ==
nullptr) {
914 collection_child !=
nullptr;
915 collection_child = collection_child->
next) {
917 data, collection_child->collection)) {
928 ID *id_root =
data->id_root;
933 if (ob->type ==
OB_ARMATURE && ob->pose !=
nullptr && (ob->id.tag &
data->tag)) {
936 pchan = pchan->
next) {
937 if (pchan->custom !=
nullptr && &pchan->custom->id != id_root) {
938 pchan->custom->id.tag &= ~
data->tag;
947 if ((collection->id.tag &
data->tag) == 0 || &collection->id == id_root) {
952 collection->id.tag &= ~
data->tag;
970 ID *id_root =
data->id_root;
971 const bool is_resync =
data->is_resync;
975 id_root->
tag |=
data->missing_tag;
1009 Collection *instantiating_collection =
nullptr;
1010 Collection *instantiating_collection_override_candidate =
nullptr;
1015 if (instantiating_collection_linklist !=
nullptr) {
1016 for (
LinkNode *instantiating_collection_linknode = instantiating_collection_linklist->
list;
1017 instantiating_collection_linknode !=
nullptr;
1018 instantiating_collection_linknode = instantiating_collection_linknode->
next) {
1019 instantiating_collection =
static_cast<Collection *
>(
1020 instantiating_collection_linknode->link);
1026 if (instantiating_collection->
id.
tag &
data->tag) {
1031 instantiating_collection_override_candidate = instantiating_collection;
1032 instantiating_collection =
nullptr;
1036 if (instantiating_collection ==
nullptr &&
1037 instantiating_collection_override_candidate !=
nullptr) {
1039 instantiating_collection_override_candidate->
id.
tag |=
data->missing_tag;
1042 instantiating_collection_override_candidate->
id.
tag |=
data->tag;
1052 ID *id_owner =
data->id_root;
1056 ID *id_hierarchy_root =
data->hierarchy_root_id;
1064 const uint missing_tag =
data->missing_tag;
1079 to_id_entry = to_id_entry->
next) {
1085 ID *to_id = *to_id_entry->id_pointer.to;
1086 if (
ELEM(to_id,
nullptr, id_owner)) {
1099 const Library *reference_lib =
1101 const ID *to_id_reference =
1103 if (to_id_reference->
lib != reference_lib) {
1109 to_id->
tag |= missing_tag;
1125 ID *id_root =
data->id_root;
1129 ID *id_hierarchy_root =
data->hierarchy_root_id;
1135 id_root->
tag |=
data->missing_tag;
1148 ID *id_root_reference,
1149 ID *id_hierarchy_root_reference,
1150 const bool do_fully_editable)
1156 data.id_root = id_root_reference;
1159 data.is_override =
false;
1160 data.is_resync =
false;
1170 if (id_hierarchy_root_reference->
lib != id_root_reference->
lib) {
1173 id_root_reference->
lib);
1176 data.hierarchy_root_id = id_hierarchy_root_reference;
1177 data.id_root = id_hierarchy_root_reference;
1178 data.is_override =
true;
1185 bool success =
false;
1186 if (id_hierarchy_root_reference->
lib != id_root_reference->
lib) {
1190 id_hierarchy_root_reference,
1200 id_hierarchy_root_reference,
1213 ID *id_instance_hint,
1215 const Object *old_active_object,
1216 const bool is_resync)
1219 BLI_assert(old_active_object ==
nullptr || view_layer !=
nullptr);
1237 if (!is_resync && id_root !=
nullptr && id_root->
newid !=
nullptr &&
1239 switch (
GS(id_root->
name)) {
1241 Object *ob_reference = id_instance_hint !=
nullptr &&
GS(id_instance_hint->
name) ==
ID_OB ?
1242 reinterpret_cast<Object *
>(id_instance_hint) :
1248 if (ob_reference !=
nullptr) {
1251 else if (id_instance_hint !=
nullptr) {
1254 bmain,
scene, (
reinterpret_cast<Collection *
>(id_instance_hint)), collection_new);
1258 bmain,
scene, (
reinterpret_cast<Collection *
>(id_root)), collection_new);
1270 bmain,
scene,
reinterpret_cast<Object *
>(id_root), ob_new);
1281 Collection *default_instantiating_collection = residual_storage;
1283 Object *ob_new =
reinterpret_cast<Object *
>(ob->id.newid);
1284 if (ob_new ==
nullptr || (
ID_IS_LINKED(ob_new) && ob_new->
id.
lib != owner_library)) {
1291 if (old_active_object == ob) {
1293 if (basact !=
nullptr) {
1294 view_layer->
basact = basact;
1300 if (id_root !=
nullptr && default_instantiating_collection ==
nullptr) {
1301 ID *id_ref = id_root->
newid !=
nullptr ? id_root->
newid : id_root;
1302 switch (
GS(id_ref->
name)) {
1314 default_instantiating_collection =
static_cast<Collection *
>(
1328 (view_layer !=
nullptr ?
1332 default_instantiating_collection = collection;
1341 if (default_instantiating_collection ==
nullptr) {
1350 if (id_root !=
nullptr &&
1352 ID *id_ref = id_root->
newid !=
nullptr ? id_root->
newid : id_root;
1353 switch (
GS(id_ref->
name)) {
1358 default_instantiating_collection);
1363 bmain,
scene,
nullptr, default_instantiating_collection);
1375 ID *id_root_reference,
1376 ID *id_hierarchy_root_reference,
1377 ID *id_instance_hint,
1378 ID **r_id_root_override,
1379 const bool do_fully_editable)
1381 if (r_id_root_override !=
nullptr) {
1382 *r_id_root_override =
nullptr;
1385 if (id_hierarchy_root_reference ==
nullptr) {
1386 id_hierarchy_root_reference = id_root_reference;
1389 const Object *old_active_object = (view_layer !=
nullptr) ?
OBACT(view_layer) :
nullptr;
1395 id_hierarchy_root_reference,
1402 if (r_id_root_override !=
nullptr) {
1403 *r_id_root_override = id_root_reference->
newid;
1441 if (curr_level > 1000) {
1443 "Levels of dependency relationships between library overrides IDs is way too high, "
1444 "skipping further processing loops (involves at least '%s')",
1461 *r_best_level = curr_level;
1462 return id->override_library->hierarchy_root;
1467 int best_level_placeholder = 0;
1475 int best_level_candidate = curr_level;
1476 ID *best_root_id_candidate =
id;
1479 from_id_entry = from_id_entry->
next) {
1485 ID *from_id = from_id_entry->id_pointer.from;
1486 if (
ELEM(from_id,
nullptr,
id)) {
1493 int level_candidate = curr_level + 1;
1496 bmain, from_id, curr_level + 1, &level_candidate);
1497 if (level_candidate > best_level_candidate && root_id_candidate !=
nullptr) {
1498 best_root_id_candidate = root_id_candidate;
1499 best_level_candidate = level_candidate;
1506 int best_level_placeholder = 0;
1509 bmain, id_owner, curr_level + 1, &best_level_placeholder);
1512 BLI_assert(best_root_id_candidate !=
nullptr);
1515 *r_best_level = best_level_candidate;
1516 return best_root_id_candidate;
1540 "Inconsistency in library override hierarchy of ID '%s'.\n"
1541 "\tNot enough data to verify validity of current proposed root '%s', assuming "
1542 "already set one '%s' is valid.",
1554 bool do_replace_root =
false;
1556 from_id_entry = from_id_entry->
next) {
1562 if (id_from_ref == from_id_entry->id_pointer.from) {
1565 do_replace_root =
true;
1568 "Inconsistency in library override hierarchy of ID '%s'.\n"
1569 "\tCurrent proposed root '%s' detected as valid, will replace already set one '%s'.",
1577 if (!do_replace_root) {
1580 "Inconsistency in library override hierarchy of ID '%s'.\n"
1581 "\tCurrent proposed root '%s' not detected as valid, keeping already set one '%s'.",
1589 id->override_library->hierarchy_root = id_root;
1597 to_id_entry = to_id_entry->
next) {
1603 ID *to_id = *to_id_entry->id_pointer.to;
1604 if (
ELEM(to_id,
nullptr,
id)) {
1631 "Existing override hierarchy root ('%s') for ID '%s' is invalid, will try to find a "
1637 id->override_library->hierarchy_root =
nullptr;
1651 "Potential inconsistency in library override hierarchy of ID '%s', detected as "
1652 "part of the hierarchy of '%s', which has a different root '%s'",
1669 const ID *id_root_reference,
1670 GHash *linkedref_to_old_override)
1678 ID *id_override_new =
id->
newid;
1680 if (id_override_old ==
nullptr) {
1691 GHASH_ITER (linkedref_to_old_override_iter, linkedref_to_old_override) {
1692 ID *id_override_old_iter =
static_cast<ID *
>(
1718 Collection *override_resync_residual_storage,
1719 const bool do_hierarchy_enforce,
1720 const bool do_post_process,
1727 const Object *old_active_object = view_layer ?
OBACT(view_layer) :
nullptr;
1732 "Impossible to resync data-block %s and its dependencies, as its linked reference "
1742 data.id_root = id_root;
1746 data.is_override =
true;
1747 data.is_resync =
true;
1757 for (
LinkNode *resync_root_link = id_resync_roots; resync_root_link !=
nullptr;
1758 resync_root_link = resync_root_link->
next) {
1759 ID *id_resync_root =
static_cast<ID *
>(resync_root_link->link);
1764 "While dealing with root '%s', resync root ID '%s' (%p) found to be alreaady "
1767 id_resync_root->
name,
1781 reports !=
nullptr ? reports->
reports :
nullptr,
1783 "Impossible to resync data-block %s and its dependencies, as its linked reference "
1794 data.id_root = id_resync_root;
1795 data.is_override =
true;
1801 data.is_override =
false;
1829 bmain,
id,
nullptr,
nullptr);
1835 ID *reference_id = id_override_library->
reference;
1843 reference_id =
reinterpret_cast<ID *
>(
1844 reinterpret_cast<Scene *
>(reference_id)->master_collection);
1853 if (reference_id ==
nullptr) {
1875 bool do_break =
false;
1899 data.id_root = id_root;
1900 data.is_override =
true;
1928 id->
lib != id_root_reference->
lib) {
1931 ID *id_override_new =
id->
newid;
1940 BLI_assert(id_override_old ==
nullptr || id_override_old->
lib == id_root->
lib);
1941 id_override_new->
lib = id_root->
lib;
1947 if (id_override_old !=
nullptr) {
1950 memcpy(id_name_buf, id_override_old->
name,
sizeof(id_name_buf));
1951 memcpy(id_override_old->
name, id_override_new->
name,
sizeof(id_override_old->
name));
1952 memcpy(id_override_new->
name, id_name_buf,
sizeof(id_override_new->
name));
1972 for (; op_new; op_new = op_new->
next, op_old = op_old->
next) {
1995 LinkNode *id_override_old_list =
nullptr;
2002 id->
lib != id_root_reference->
lib) {
2006 ID *id_override_new =
id->
newid;
2012 if (id_override_old ==
nullptr) {
2059 id_override_old_list,
2063 for (
LinkNode *ln_iter = id_override_old_list; ln_iter !=
nullptr; ln_iter = ln_iter->
next) {
2064 ID *id_override_old =
static_cast<ID *
>(ln_iter->link);
2073 int user_edited_overrides_deletion_count = 0;
2082 if (id_override_old !=
nullptr) {
2112 CLOG_INFO(&
LOG, 2,
"Old override %s is being kept around as it was user-edited",
id->
name);
2121 &
LOG,
"Old override %s is being deleted even though it was user-edited",
id->
name);
2122 user_edited_overrides_deletion_count++;
2137 if (id_root_reference->
newid !=
nullptr) {
2138 id_root = id_root_reference->
newid;
2141 if (user_edited_overrides_deletion_count > 0) {
2144 "During resync of data-block %s, %d obsolete overrides were deleted, that had "
2145 "local changes defined by user",
2147 user_edited_overrides_deletion_count);
2150 if (do_post_process) {
2162 override_resync_residual_storage,
2178 Collection *override_resync_residual_storage,
2179 const bool do_hierarchy_enforce,
2182 ListBase no_main_ids_list = {
nullptr};
2184 id_resync_roots.
link = id_root;
2185 id_resync_roots.
next =
nullptr;
2193 override_resync_residual_storage,
2194 do_hierarchy_enforce,
2206 const int library_indirect_level,
2207 const bool do_strict_equal)
2209 const int id_lib_level = (
ID_IS_LINKED(
id) ?
id->lib->temp_index : 0);
2210 return do_strict_equal ? id_lib_level == library_indirect_level :
2211 id_lib_level <= library_indirect_level;
2220 id = id_type->
owner_get(bmain,
id,
nullptr);
2228 return hierarchy_root_id;
2243 Main *bmain,
ID *
id,
GHash *id_roots,
const int library_indirect_level,
const bool check_only)
2251 "While processing indirect level %d, ID %s from lib %s of indirect level %d detected "
2252 "as needing resync, skipping.",
2253 library_indirect_level,
2296 bool is_ancestor_tagged_for_resync =
false;
2298 entry_item = entry_item->
next) {
2299 if (entry_item->usage_flag &
2304 ID *id_from = entry_item->id_pointer.from;
2309 const bool is_ancestor_tagged_for_resync_prev = is_ancestor_tagged_for_resync;
2311 bmain, id_from, id_roots, library_indirect_level, check_only);
2313 if (!check_only && is_ancestor_tagged_for_resync && !is_ancestor_tagged_for_resync_prev) {
2316 "ID %s (%p) now tagged as needing resync because they are used by %s (%p) "
2317 "that needs to be resynced",
2327 id->tag |= id_tag_need_resync;
2330 return is_ancestor_tagged_for_resync;
2333 if (is_ancestor_tagged_for_resync) {
2341 "ID %s (%p) is tagged as needing resync, but none of its override hierarchy "
2342 "ancestors are tagged for resync, so it is a partial resync root",
2357 if (!
BLI_ghash_ensure_p(id_roots, id_root,
reinterpret_cast<void ***
>(&id_resync_roots_p))) {
2358 *id_resync_roots_p = MEM_cnew<LinkNodePair>(__func__);
2362 is_ancestor_tagged_for_resync =
true;
2365 return is_ancestor_tagged_for_resync;
2377 Collection *override_resync_residual_storage,
2378 const int library_indirect_level,
2381 const bool do_reports_recursive_resync_timing = (library_indirect_level != 0);
2396 data.id_root =
nullptr;
2399 data.is_override =
false;
2400 data.is_resync =
true;
2427 data.id_root =
id->override_library->reference;
2464 bmain,
id, id_roots, library_indirect_level,
false);
2473 entry_item = entry_item->
next) {
2477 ID *id_to = *entry_item->id_pointer.to;
2484 "ID %s (%p) now tagged as needing resync because they use linked %s (%p) that "
2485 "now needs to be overridden",
2491 bmain,
id, id_roots, library_indirect_level,
false);
2509 &
LOG, 2,
"Checking validity of computed TODO data for root '%s'... \n", id_root->
name);
2510 for (
LinkNode *id_resync_root_iter = id_resync_roots->
list; id_resync_root_iter !=
nullptr;
2511 id_resync_root_iter = id_resync_root_iter->
next) {
2512 ID *id_resync_root =
static_cast<ID *
>(id_resync_root_iter->link);
2514 if (id_resync_root == id_root) {
2516 id_resync_root_iter == id_resync_roots->
last_node);
2519 bmain, id_resync_root, id_roots, library_indirect_level,
true));
2530 ListBase no_main_ids_list = {
nullptr};
2545 "Resyncing all dependencies under root %s (%p), first one being '%s'...",
2547 reinterpret_cast<void *
>(
library),
2553 id_resync_roots->
list,
2555 override_resync_residual_storage,
2593 id, library_indirect_level - 1,
false));
2594 if (!is_valid_tagged_need_resync) {
2596 "ID override %s from library level %d still found as needing resync, when all "
2597 "IDs from that level should have been processed after tackling library level %d",
2600 library_indirect_level);
2612 if (do_reports_recursive_resync_timing) {
2627 if (owner_library_indirect_level > 100) {
2629 "Levels of indirect usages of libraries is way too high, there are most likely "
2630 "dependency loops, skipping further building loops (involves at least '%s' from "
2631 "'%s' and '%s' from '%s')",
2638 if (owner_library_indirect_level > 90) {
2641 "Levels of indirect usages of libraries is suspiciously too high, there are most likely "
2642 "dependency loops (involves at least '%s' from '%s' and '%s' from '%s')",
2650 id->lib->temp_index = owner_library_indirect_level + 1;
2651 *
reinterpret_cast<bool *
>(cb_data->
user_data) =
true;
2667 bool do_continue =
true;
2668 while (do_continue) {
2669 do_continue =
false;
2678 int library_indirect_level_max = 0;
2680 if (
library->temp_index > library_indirect_level_max) {
2681 library_indirect_level_max =
library->temp_index;
2684 return library_indirect_level_max;
2694 #define OVERRIDE_RESYNC_RESIDUAL_STORAGE_NAME "OVERRIDE_RESYNC_LEFTOVERS"
2697 if (override_resync_residual_storage !=
nullptr &&
2699 override_resync_residual_storage =
nullptr;
2701 if (override_resync_residual_storage ==
nullptr) {
2708 const Object *old_active_object =
OBACT(view_layer);
2716 while (library_indirect_level >= 0) {
2721 override_resync_residual_storage,
2722 library_indirect_level,
2724 library_indirect_level--;
2736 override_resync_residual_storage,
2748 "library '%s' contains some linked overrides that required recursive resync, "
2749 "consider updating it",
2765 data.scene =
nullptr;
2766 data.id_root = id_root;
2770 data.is_override =
true;
2771 data.is_resync =
false;
2813 if (shape_key !=
nullptr) {
2818 Collection *master_collection =
reinterpret_cast<Scene *
>(
id)->master_collection;
2819 if (master_collection !=
nullptr) {
2833 if (
override->runtime ==
nullptr) {
2834 override->runtime = MEM_cnew<IDOverrideLibraryRuntime>(__func__);
2836 return override->runtime;
2858 const char *rna_path)
2865 const char *rna_path,
2870 if (op ==
nullptr) {
2871 op = MEM_cnew<IDOverrideLibraryProperty>(__func__);
2882 else if (r_created) {
2897 idpoin, library_prop->
rna_path, r_override_poin, r_override_prop, r_index);
2910 opop_dst = opop_dst->
next, opop_src = opop_src->
next) {
2942 const char *subitem_refname,
2943 const char *subitem_locname,
2944 const int subitem_refindex,
2945 const int subitem_locindex,
2950 const int subitem_defindex = -1;
2956 if (subitem_locname !=
nullptr) {
2962 if (opop ==
nullptr) {
2975 if (subitem_refname !=
nullptr) {
2981 if (opop ==
nullptr) {
2997 sizeof(subitem_locindex),
3005 sizeof(subitem_refindex),
3012 if (!strict && (subitem_locindex != subitem_defindex) &&
3016 sizeof(subitem_defindex),
3029 const short operation,
3030 const char *subitem_refname,
3031 const char *subitem_locname,
3032 const int subitem_refindex,
3033 const int subitem_locindex,
3047 if (opop ==
nullptr) {
3048 opop = MEM_cnew<IDOverrideLibraryPropertyOperation>(__func__);
3050 if (subitem_locname) {
3053 if (subitem_refname) {
3065 else if (r_created) {
3110 switch (override_property_operation->
operation) {
3118 if (ptr_storage ==
nullptr || ptr_storage->
data ==
nullptr || prop_storage ==
nullptr) {
3119 BLI_assert_msg(0,
"Missing data to apply differential override operation.");
3128 if ((ptr_dst ==
nullptr || ptr_dst->
data ==
nullptr || prop_dst ==
nullptr) ||
3129 (ptr_src ==
nullptr || ptr_src->
data ==
nullptr || prop_src ==
nullptr)) {
3144 ID *liboverride_id =
id;
3163 if (liboverride->
reference ==
nullptr) {
3167 "Library override templates have been removed: removing all override data from "
3168 "the data-block '%s'",
3169 liboverride_id->
name);
3173 if (liboverride->
reference == liboverride_id) {
3178 "Data corruption: data-block '%s' is using itself as library override reference, "
3179 "removing all override data",
3180 liboverride_id->
name);
3189 "Data corruption: data-block '%s' is using another local data-block ('%s') as "
3190 "library override reference, removing all override data",
3191 liboverride_id->
name,
3216 if (reference ==
nullptr) {
3266 if (reference ==
nullptr) {
3321 bool created =
false;
3365 CLOG_INFO(&
LOG, 2,
"We did restore some properties of %s from its reference", local->
name);
3368 CLOG_INFO(&
LOG, 2,
"We did generate library override rules for %s", local->
name);
3386 ID *
id =
static_cast<ID *
>(taskdata);
3399 #ifdef DEBUG_OVERRIDE_TIMEIT
3421 create_pool_data.
bmain = bmain;
3422 create_pool_data.changed =
false;
3466 #ifdef DEBUG_OVERRIDE_TIMEIT
3470 return create_pool_data.changed;
3475 const bool do_reset_system_override)
3477 bool was_op_deleted =
false;
3479 if (do_reset_system_override) {
3485 bool do_op_delete =
true;
3487 if (is_collection || op->rna_prop_type ==
PROP_POINTER) {
3504 if (is_collection) {
3524 was_op_deleted =
true;
3528 if (was_op_deleted) {
3535 return was_op_deleted;
3540 const bool do_reset_system_override)
3558 const bool do_reset_system_override)
3565 if (entry_vp ==
nullptr) {
3584 to_id_entry = to_id_entry->
next) {
3591 if (*to_id_entry->id_pointer.to !=
nullptr) {
3592 ID *to_id = *to_id_entry->id_pointer.to;
3602 const bool do_reset_system_override)
3626 if (override_property !=
nullptr) {
3628 override_property->
tag |= tag;
3631 override_property->
tag &= ~tag;
3649 if (
override !=
nullptr) {
3746 if (tmp_id ==
nullptr) {
3753 tmp_id->
lib = local->
lib;
3765 if (local_key !=
nullptr && tmp_key !=
nullptr) {
3772 PointerRNA rnaptr_src, rnaptr_dst, rnaptr_storage_stack, *rnaptr_storage =
nullptr;
3776 rnaptr_storage = &rnaptr_storage_stack;
3793 if (local_key !=
nullptr && tmp_key !=
nullptr) {
3801 local_key->
from = local;
3802 tmp_key->
from = tmp_id;
3815 if (ob->pose !=
nullptr && ob->data == local) {
3927 #ifdef DEBUG_OVERRIDE_TIMEIT
3946 storage_id =
BKE_id_copy(
reinterpret_cast<Main *
>(override_storage), local);
3948 if (storage_id !=
nullptr) {
3949 PointerRNA rnaptr_reference, rnaptr_final, rnaptr_storage;
3955 bmain, &rnaptr_final, &rnaptr_reference, &rnaptr_storage, local->
override_library)) {
3957 storage_id =
nullptr;
3961 storage_id =
nullptr;
3966 #ifdef DEBUG_OVERRIDE_TIMEIT
struct AnimData * BKE_animdata_from_id(const struct ID *id)
void BKE_pose_ensure(struct Main *bmain, struct Object *ob, struct bArmature *arm, bool do_id_user)
void BKE_pose_clear_pointers(struct bPose *pose)
struct Collection * BKE_collection_add(struct Main *bmain, struct Collection *parent, const char *name)
void BKE_collection_object_add_from(struct Main *bmain, struct Scene *scene, struct Object *ob_src, struct Object *ob_dst)
bool BKE_collection_object_add(struct Main *bmain, struct Collection *collection, struct Object *ob)
struct GSet * BKE_scene_objects_as_gset(struct Scene *scene, struct GSet *objects_gset)
void BKE_collection_add_from_object(struct Main *bmain, struct Scene *scene, const struct Object *ob_src, struct Collection *collection_dst)
bool BKE_collection_has_object(struct Collection *collection, const struct Object *ob)
bool BKE_collection_has_collection(const struct Collection *parent, const struct Collection *collection)
void BKE_collection_add_from_collection(struct Main *bmain, struct Scene *scene, struct Collection *collection_src, struct Collection *collection_dst)
bool BKE_collection_is_in_scene(struct Collection *collection)
bool BKE_collection_is_empty(const struct Collection *collection)
bool BKE_collection_delete(struct Main *bmain, struct Collection *collection, bool hierarchy)
struct FCurve * BKE_animadata_fcurve_find_by_rna_path(struct AnimData *animdata, const char *rna_path, const int rna_index, struct bAction **r_action, bool *r_driven)
bool BKE_idtype_idcode_is_linkable(short idcode)
const struct IDTypeInfo * BKE_idtype_get_info_from_id(const struct ID *id)
struct Key * BKE_key_from_id(struct ID *id)
struct Key ** BKE_key_from_id_p(struct ID *id)
void BKE_main_collection_sync(const struct Main *bmain)
bool BKE_view_layer_has_collection(const struct ViewLayer *view_layer, const struct Collection *collection)
void BKE_layer_collection_resync_allow(void)
struct Base * BKE_view_layer_base_find(struct ViewLayer *view_layer, struct Object *ob)
void BKE_layer_collection_resync_forbid(void)
void BKE_main_collection_sync_remap(const struct Main *bmain)
struct ID * BKE_id_copy(struct Main *bmain, const struct ID *id)
@ LIB_ID_COPY_NO_LIB_OVERRIDE
@ LIB_ID_COPY_NO_LIB_OVERRIDE_LOCAL_DATA_FLAG
void BKE_libblock_management_main_add(struct Main *bmain, void *idv)
void BKE_main_id_newptr_and_tag_clear(struct Main *bmain)
struct ID * BKE_id_copy_ex(struct Main *bmain, const struct ID *id, struct ID **r_newid, int flag)
void BKE_main_id_tag_all(struct Main *mainvar, int tag, bool value)
void id_us_min(struct ID *id)
void id_fake_user_set(struct ID *id)
@ LIB_ID_FREE_NO_NAMEMAP_REMOVE
void BKE_id_free(struct Main *bmain, void *idv)
void id_us_plus(struct ID *id)
void BKE_id_free_ex(struct Main *bmain, void *idv, int flag, bool use_flag_from_idtag)
void * BKE_id_new(struct Main *bmain, short type, const char *name)
void BKE_id_delete(struct Main *bmain, void *idv) ATTR_NONNULL()
size_t BKE_id_multi_tagged_delete(struct Main *bmain) ATTR_NONNULL()
void BKE_lib_id_swap(struct Main *bmain, struct ID *id_a, struct ID *id_b)
void BKE_library_foreach_ID_link(struct Main *bmain, struct ID *id, LibraryIDLinkCallback callback, void *user_data, int flag)
@ IDWALK_CB_OVERRIDE_LIBRARY_NOT_OVERRIDABLE
@ ID_REMAP_SKIP_OVERRIDE_LIBRARY
@ ID_REMAP_FORCE_USER_REFCOUNT
@ ID_REMAP_SKIP_INDIRECT_USAGE
@ ID_REMAP_FORCE_NEVER_NULL_USAGE
void void BKE_libblock_remap(struct Main *bmain, void *old_idv, void *new_idv, short remap_flags) ATTR_NONNULL(1
void BKE_id_remapper_add(struct IDRemapper *id_remapper, struct ID *old_id, struct ID *new_id)
void BKE_libblock_relink_ex(struct Main *bmain, void *idv, void *old_idv, void *new_idv, short remap_flags) ATTR_NONNULL(1
struct IDRemapper * BKE_id_remapper_create(void)
void BKE_id_remapper_free(struct IDRemapper *id_remapper)
void void BKE_libblock_relink_multiple(struct Main *bmain, struct LinkNode *ids, eIDRemapType remap_type, struct IDRemapper *id_remapper, short remap_flags)
void BKE_libblock_remap_multiple(struct Main *bmain, struct IDRemapper *mappings, short remap_flags)
#define FOREACH_MAIN_ID_END
struct Main * BKE_main_new(void)
#define FOREACH_MAIN_LISTBASE_ID_END
void BKE_main_relations_tag_set(struct Main *bmain, eMainIDRelationsEntryTags tag, bool value)
#define FOREACH_MAIN_LISTBASE_ID_BEGIN(_lb, _id)
#define FOREACH_MAIN_LISTBASE_END
@ MAINIDRELATIONS_ENTRY_TAGS_PROCESSED_TO
@ MAINIDRELATIONS_ENTRY_TAGS_PROCESSED
@ MAINIDRELATIONS_ENTRY_TAGS_PROCESSED_FROM
void BKE_main_relations_create(struct Main *bmain, short flag)
void BKE_main_relations_free(struct Main *bmain)
#define FOREACH_MAIN_LISTBASE_BEGIN(_bmain, _lb)
#define FOREACH_MAIN_ID_BEGIN(_bmain, _id)
void BKE_main_free(struct Main *mainvar)
void BKE_main_namemap_remove_name(struct Main *bmain, struct ID *id, const char *name) ATTR_NONNULL()
bool BKE_main_namemap_validate(struct Main *bmain) ATTR_NONNULL()
struct bNodeTree * ntreeFromID(struct ID *id)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
#define BLI_assert_unreachable()
#define BLI_assert_msg(a, msg)
bool BLI_ghashutil_strcmp(const void *a, const void *b)
BLI_INLINE void * BLI_ghashIterator_getKey(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
bool BLI_ghash_haskey(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
void BLI_ghashIterator_step(GHashIterator *ghi)
void BLI_ghash_clear(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
unsigned int BLI_ghashutil_ptrhash(const void *key)
void BLI_ghashIterator_free(GHashIterator *ghi)
BLI_INLINE void * BLI_ghashIterator_getValue(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
#define GHASH_ITER(gh_iter_, ghash_)
GHash * BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void * BLI_gset_lookup(const GSet *gs, const void *key) ATTR_WARN_UNUSED_RESULT
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
bool BLI_ghashutil_ptrcmp(const void *a, const void *b)
unsigned int BLI_ghashutil_strhash_p_murmur(const void *ptr)
GHashIterator * BLI_ghashIterator_new(GHash *gh) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
bool BLI_ghash_remove(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
void BLI_ghash_insert(GHash *gh, void *key, void *val)
void ** BLI_ghash_lookup_p(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
GHash * BLI_ghash_ptr_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
bool BLI_ghash_ensure_p(GHash *gh, void *key, void ***r_val) ATTR_WARN_UNUSED_RESULT
BLI_INLINE bool BLI_ghashIterator_done(const GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
void BLI_linklist_append_arena(LinkNodePair *list_pair, void *ptr, struct MemArena *ma) ATTR_NONNULL(1
void BLI_linklist_free(LinkNode *list, LinkNodeFreeFP freefunc)
void void void void BLI_linklist_append(LinkNodePair *list_pair, void *ptr) ATTR_NONNULL(1)
void void BLI_linklist_prepend(LinkNode **listp, void *ptr) ATTR_NONNULL(1)
int BLI_linklist_index(const LinkNode *list, void *ptr) ATTR_WARN_UNUSED_RESULT
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
#define LISTBASE_FOREACH(type, var, list)
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void * BLI_findstring_ptr(const struct ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_insertlinkreplace(ListBase *listbase, void *vreplacelink, void *vnewlink) ATTR_NONNULL(1
void void void void void BLI_duplicatelist(struct ListBase *dst, const struct ListBase *src) ATTR_NONNULL(1
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
void * BLI_listbase_bytes_find(const ListBase *listbase, const void *bytes, size_t bytes_size, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void * BLI_findstring(const struct ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_memarena_free(struct MemArena *ma) ATTR_NONNULL(1)
struct MemArena * BLI_memarena_new(size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(2) ATTR_MALLOC
#define BLI_MEMARENA_STD_BUFSIZE
void * BLI_memarena_calloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
void * BLI_task_pool_user_data(TaskPool *pool)
void BLI_task_pool_work_and_wait(TaskPool *pool)
TaskPool * BLI_task_pool_create(void *userdata, eTaskPriority priority)
void BLI_task_pool_free(TaskPool *pool)
void BLI_task_pool_push(TaskPool *pool, TaskRunFunction run, void *taskdata, bool free_taskdata, TaskFreeFunction freedata)
#define UNUSED_VARS_NDEBUG(...)
external readfile function prototypes.
#define CLOG_ERROR(clg_ref,...)
#define CLOG_WARN(clg_ref,...)
#define CLOG_INFO(clg_ref, level,...)
void DEG_id_tag_update_ex(struct Main *bmain, struct ID *id, int flag)
void DEG_id_tag_update(struct ID *id, int flag)
void DEG_relations_tag_update(struct Main *bmain)
ID and Library types, which are fundamental for sdna.
#define ID_IS_OVERRIDE_LIBRARY_VIRTUAL(_id)
@ IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE
@ ID_RECALC_COPY_ON_WRITE
#define ID_IS_OVERRIDE_LIBRARY_REAL(_id)
#define ID_IS_LINKED(_id)
@ IDOVERRIDE_LIBRARY_OP_MULTIPLY
@ IDOVERRIDE_LIBRARY_OP_INSERT_AFTER
@ IDOVERRIDE_LIBRARY_OP_NOOP
@ IDOVERRIDE_LIBRARY_OP_SUBTRACT
@ IDOVERRIDE_LIBRARY_OP_ADD
@ IDOVERRIDE_LIBRARY_OP_INSERT_BEFORE
@ IDOVERRIDE_LIBRARY_OP_REPLACE
@ LIB_TAG_NO_USER_REFCOUNT
@ LIB_TAG_OVERRIDE_LIBRARY_REFOK
@ LIB_TAG_LIB_OVERRIDE_NEED_RESYNC
@ LIB_TAG_OVERRIDE_LIBRARY_AUTOREFRESH
@ LIB_LIB_OVERRIDE_RESYNC_LEFTOVER
@ LIB_EMBEDDED_DATA_LIB_OVERRIDE
#define ID_REAL_USERS(id)
@ IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RELOAD
#define ID_IS_OVERRIDE_LIBRARY(_id)
@ LIBRARY_TAG_RESYNC_REQUIRED
@ IDOVERRIDE_LIBRARY_TAG_UNUSED
#define ID_IS_OVERRIDE_LIBRARY_TEMPLATE(_id)
@ IDOVERRIDE_LIBRARY_FLAG_NO_HIERARCHY
@ IDOVERRIDE_LIBRARY_FLAG_SYSTEM_DEFINED
Object groups, one object can be in many groups at once.
@ COLLECTION_HIDE_VIEWPORT
Object is a sort of wrapper for general info.
#define OB_DATA_SUPPORT_ID(_id_type)
#define OBACT(_view_layer)
Read Guarded memory(de)allocation.
Platform independent time functions.
Utility defines for timing/benchmarks.
#define TIMEIT_START_AVERAGED(var)
#define TIMEIT_END_AVERAGED(var)
@ RNA_OVERRIDE_APPLY_FLAG_IGNORE_ID_POINTERS
@ RNA_OVERRIDE_APPLY_FLAG_NOP
@ RNA_OVERRIDE_COMPARE_IGNORE_OVERRIDDEN
@ RNA_OVERRIDE_COMPARE_CREATE
@ RNA_OVERRIDE_COMPARE_IGNORE_NON_OVERRIDABLE
@ RNA_OVERRIDE_COMPARE_RESTORE
@ RNA_OVERRIDE_MATCH_RESULT_RESTORED
@ RNA_OVERRIDE_MATCH_RESULT_CREATED
Provides wrapper around system-specific atomic primitives, and some extensions (faked-atomic operatio...
ATOMIC_INLINE uint8_t atomic_fetch_and_or_uint8(uint8_t *p, uint8_t b)
static void lib_override_remapper_overrides_add(IDRemapper *id_remapper, ID *reference_id, ID *local_id)
void BKE_lib_override_library_main_hierarchy_root_ensure(Main *bmain)
void BKE_lib_override_library_main_tag(Main *bmain, const short tag, const bool do_set)
static bool lib_override_hierarchy_dependencies_recursive_tag(LibOverrideGroupTagData *data)
static void lib_override_library_create_post_process(Main *bmain, Scene *scene, ViewLayer *view_layer, const Library *owner_library, ID *id_root, ID *id_instance_hint, Collection *residual_storage, const Object *old_active_object, const bool is_resync)
void BKE_lib_override_library_operations_store_finalize(OverrideLibraryStorage *override_storage)
static bool lib_override_resync_id_lib_level_is_valid(ID *id, const int library_indirect_level, const bool do_strict_equal)
static void lib_override_library_property_clear(IDOverrideLibraryProperty *op)
static void lib_override_group_tag_data_object_to_collection_init_collection_process(LibOverrideGroupTagData *data, Collection *collection)
static void lib_override_group_tag_data_object_to_collection_init(LibOverrideGroupTagData *data)
static void lib_override_hierarchy_dependencies_recursive_tag_from(LibOverrideGroupTagData *data)
ID * BKE_lib_override_library_create_from_id(Main *bmain, ID *reference_id, const bool do_tagged_remap)
void BKE_lib_override_library_free(IDOverrideLibrary **override, const bool do_id_user)
void BKE_lib_override_library_main_validate(Main *bmain, ReportList *reports)
static void lib_override_overrides_group_tag_recursive(LibOverrideGroupTagData *data)
void BKE_lib_override_library_operations_tag(IDOverrideLibraryProperty *override_property, const short tag, const bool do_set)
static void lib_override_root_hierarchy_set(Main *bmain, ID *id_root, ID *id, ID *id_from)
bool BKE_lib_override_library_id_is_user_deletable(Main *bmain, ID *id)
static void lib_override_linked_group_tag(LibOverrideGroupTagData *data)
IDOverrideLibraryProperty * BKE_lib_override_library_property_get(IDOverrideLibrary *override, const char *rna_path, bool *r_created)
bool BKE_lib_override_library_is_system_defined(const Main *bmain, const ID *id)
ID * BKE_lib_override_library_operations_store_start(Main *bmain, OverrideLibraryStorage *override_storage, ID *local)
void BKE_lib_override_library_properties_tag(IDOverrideLibrary *override, const short tag, const bool do_set)
bool BKE_lib_override_library_property_operation_operands_validate(IDOverrideLibraryPropertyOperation *override_property_operation, PointerRNA *ptr_dst, PointerRNA *ptr_src, PointerRNA *ptr_storage, PropertyRNA *prop_dst, PropertyRNA *prop_src, PropertyRNA *prop_storage)
#define OVERRIDE_RESYNC_RESIDUAL_STORAGE_NAME
BLI_INLINE const IDOverrideLibrary * BKE_lib_override_library_get(const Main *bmain, const ID *id, const ID *owner_id_hint, const ID **r_owner_id)
static void lib_override_library_property_operation_copy(IDOverrideLibraryPropertyOperation *opop_dst, IDOverrideLibraryPropertyOperation *opop_src)
void BKE_lib_override_library_clear(IDOverrideLibrary *override, const bool do_id_user)
bool BKE_lib_override_library_status_check_reference(Main *bmain, ID *local)
bool BKE_lib_override_library_operations_create(Main *bmain, ID *local)
void BKE_lib_override_library_update(Main *bmain, ID *local)
static ID * lib_override_root_find(Main *bmain, ID *id, const int curr_level, int *r_best_level)
static void lib_override_id_swap(Main *bmain, ID *id_local, ID *id_temp)
OverrideLibraryStorage * BKE_lib_override_library_operations_store_init(void)
BLI_INLINE GHash * override_library_rna_path_mapping_ensure(IDOverrideLibrary *override)
IDOverrideLibraryPropertyOperation * BKE_lib_override_library_property_operation_get(IDOverrideLibraryProperty *override_property, const short operation, const char *subitem_refname, const char *subitem_locname, const int subitem_refindex, const int subitem_locindex, const bool strict, bool *r_strict, bool *r_created)
IDOverrideLibrary * BKE_lib_override_library_init(ID *local_id, ID *reference_id)
static void lib_override_library_remap(Main *bmain, const ID *id_root_reference, GHash *linkedref_to_old_override)
void BKE_lib_override_library_id_unused_cleanup(ID *local)
static void lib_override_library_operations_create_cb(TaskPool *__restrict pool, void *taskdata)
static bool lib_override_library_create_do(Main *bmain, Scene *scene, Library *owner_library, ID *id_root_reference, ID *id_hierarchy_root_reference, const bool do_fully_editable)
static void lib_override_group_tag_data_clear(LibOverrideGroupTagData *data)
void BKE_lib_override_library_main_resync(Main *bmain, Scene *scene, ViewLayer *view_layer, BlendFileReadReport *reports)
static ID * lib_override_library_main_resync_root_get(Main *bmain, ID *id)
bool BKE_lib_override_library_create(Main *bmain, Scene *scene, ViewLayer *view_layer, Library *owner_library, ID *id_root_reference, ID *id_hierarchy_root_reference, ID *id_instance_hint, ID **r_id_root_override, const bool do_fully_editable)
static bool lib_override_library_id_reset_do(Main *bmain, ID *id_root, const bool do_reset_system_override)
bool BKE_lib_override_library_is_user_edited(const ID *id)
void BKE_lib_override_library_operations_store_end(OverrideLibraryStorage *UNUSED(override_storage), ID *local)
bool BKE_lib_override_library_create_from_tag(Main *bmain, Library *owner_library, const ID *id_root_reference, ID *id_hierarchy_root, const ID *id_hierarchy_root_reference, const bool do_no_main, const bool do_fully_editable)
void BKE_lib_override_library_id_reset(Main *bmain, ID *id_root, const bool do_reset_system_override)
bool BKE_lib_override_rna_property_find(PointerRNA *idpoin, const IDOverrideLibraryProperty *library_prop, PointerRNA *r_override_poin, PropertyRNA **r_override_prop, int *r_index)
bool BKE_lib_override_library_status_check_local(Main *bmain, ID *local)
static void lib_override_linked_group_tag_clear_boneshapes_objects(LibOverrideGroupTagData *data)
static void lib_override_library_id_hierarchy_recursive_reset(Main *bmain, ID *id_root, const bool do_reset_system_override)
static void lib_override_library_main_resync_on_library_indirect_level(Main *bmain, Scene *scene, ViewLayer *view_layer, Collection *override_resync_residual_storage, const int library_indirect_level, BlendFileReadReport *reports)
bool BKE_lib_override_library_resync(Main *bmain, Scene *scene, ViewLayer *view_layer, ID *id_root, Collection *override_resync_residual_storage, const bool do_hierarchy_enforce, BlendFileReadReport *reports)
static ID * lib_override_library_create_from(Main *bmain, Library *owner_library, ID *reference_id, const int lib_id_copy_flags)
static int lib_override_sort_libraries_func(LibraryIDLinkCallbackData *cb_data)
void BKE_lib_override_library_property_delete(IDOverrideLibrary *override, IDOverrideLibraryProperty *override_property)
static bool lib_override_linked_group_tag_collections_keep_tagged_check_recursive(LibOverrideGroupTagData *data, Collection *collection)
static bool lib_override_resync_tagging_finalize_recurse(Main *bmain, ID *id, GHash *id_roots, const int library_indirect_level, const bool check_only)
void BKE_lib_override_library_validate(Main *bmain, ID *id, ReportList *reports)
BLI_INLINE void lib_override_object_posemode_transfer(ID *id_dst, ID *id_src)
static bool lib_override_library_resync(Main *bmain, Scene *scene, ViewLayer *view_layer, ID *id_root, LinkNode *id_resync_roots, ListBase *no_main_ids_list, Collection *override_resync_residual_storage, const bool do_hierarchy_enforce, const bool do_post_process, BlendFileReadReport *reports)
bool BKE_lib_override_library_property_is_animated(const ID *id, const IDOverrideLibraryProperty *override_prop, const PropertyRNA *override_rna_prop, const int rnaprop_index)
void BKE_lib_override_library_delete(Main *bmain, ID *id_root)
bool BKE_lib_override_library_is_hierarchy_leaf(Main *bmain, ID *id)
static void lib_override_linked_group_tag_recursive(LibOverrideGroupTagData *data)
static int foreachid_is_hierarchy_leaf_fn(LibraryIDLinkCallbackData *cb_data)
void BKE_lib_override_library_id_hierarchy_reset(Main *bmain, ID *id_root, const bool do_reset_system_override)
static void lib_override_library_property_operation_clear(IDOverrideLibraryPropertyOperation *opop)
void BKE_lib_override_library_main_update(Main *bmain)
void BKE_lib_override_library_main_unused_cleanup(Main *bmain)
void BKE_lib_override_library_make_local(ID *id)
static void lib_override_overrides_group_tag(LibOverrideGroupTagData *data)
BLI_INLINE IDOverrideLibraryRuntime * override_library_rna_path_runtime_ensure(IDOverrideLibrary *override)
IDOverrideLibraryPropertyOperation * BKE_lib_override_library_property_operation_find(IDOverrideLibraryProperty *override_property, const char *subitem_refname, const char *subitem_locname, const int subitem_refindex, const int subitem_locindex, const bool strict, bool *r_strict)
IDOverrideLibraryProperty * BKE_lib_override_library_property_find(IDOverrideLibrary *override, const char *rna_path)
bool BKE_lib_override_library_main_operations_create(Main *bmain, const bool force_auto)
static void lib_override_prefill_newid_from_existing_overrides(Main *bmain, ID *id_hierarchy_root)
void BKE_lib_override_library_copy(ID *dst_id, const ID *src_id, const bool do_full_copy)
void BKE_lib_override_library_property_operation_delete(IDOverrideLibraryProperty *override_property, IDOverrideLibraryPropertyOperation *override_property_operation)
static int lib_override_libraries_index_define(Main *bmain)
static void lib_override_library_property_copy(IDOverrideLibraryProperty *op_dst, IDOverrideLibraryProperty *op_src)
bool BKE_lib_override_library_template_create(ID *id)
void(* MEM_freeN)(void *vmemh)
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
bool RNA_struct_is_ID(const StructRNA *type)
PropertyType RNA_property_type(PropertyRNA *prop)
PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop)
StructRNA * RNA_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop)
bool RNA_struct_override_store(Main *bmain, PointerRNA *ptr_local, PointerRNA *ptr_reference, PointerRNA *ptr_storage, IDOverrideLibrary *override)
void RNA_struct_override_apply(Main *bmain, PointerRNA *ptr_dst, PointerRNA *ptr_src, PointerRNA *ptr_storage, IDOverrideLibrary *override, const eRNAOverrideApplyFlag flag)
bool RNA_struct_override_matches(Main *bmain, PointerRNA *ptr_local, PointerRNA *ptr_reference, const char *root_path, const size_t root_path_len, IDOverrideLibrary *override, const eRNAOverrideMatch flags, eRNAOverrideMatchResult *r_report_flags)
bool RNA_path_resolve_property(const PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
bool RNA_path_resolve_property_full(const PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index)
const char * RNA_path_array_index_token_find(const char *rna_path, const PropertyRNA *array_prop)
double lib_overrides_recursive_resync
struct ReportList * reports
bool do_resynced_lib_overrides_libraries_list
int resynced_lib_overrides
struct LinkNode * resynced_lib_overrides_libraries
int resynced_lib_overrides_libraries_count
struct BlendFileReadReport::@134 count
struct BlendFileReadReport::@133 duration
struct CollectionChild * next
struct CollectionObject * next
struct IDOverrideLibraryPropertyOperation * next
int subitem_reference_index
char * subitem_local_name
char * subitem_reference_name
struct IDOverrideLibraryProperty * next
struct GHash * rna_path_to_override_properties
struct ID * hierarchy_root
IDOverrideLibraryRuntime * runtime
IDTypeEmbeddedOwnerGetFunction owner_get
IDOverrideLibrary * override_library
GHash * linked_object_to_instantiating_collections
struct MainIDRelationsEntryItem * next
struct MainIDRelationsEntryItem * to_ids
struct MainIDRelationsEntryItem * from_ids
struct GHash * relations_from_pointers
struct MainIDRelations * relations
struct Collection * master_collection
struct bPoseChannel * next
double PIL_check_seconds_timer(void)
static FT_Library library