Fix (unreported) liboverride: Hierarchy corruption when making some override local.
Making some liboverride local will break/corrupt liboverride hierarchies in many cases. So that function (or its caller, in some cases) need to call #BKE_lib_override_library_main_hierarchy_root_ensure to re-validate (and re-generate if needed) the liboverride hierarchy roots.
This commit is contained in:
@@ -284,10 +284,14 @@ void BKE_lib_override_library_delete(Main *bmain, ID *id_root);
|
||||
/**
|
||||
* Make given ID fully local.
|
||||
*
|
||||
* \param bmain If given, all liboverrides hierarchy roots will be re-validated/generated after
|
||||
* clearing the liboverride data from given \a id. If nullptr, caller is responsible to perform
|
||||
* this action (call #BKE_lib_override_library_main_hierarchy_root_ensure) itself.
|
||||
*
|
||||
* \note Only differs from lower-level #BKE_lib_override_library_free in infamous embedded ID
|
||||
* cases.
|
||||
*/
|
||||
void BKE_lib_override_library_make_local(ID *id);
|
||||
void BKE_lib_override_library_make_local(Main *bmain, ID *id);
|
||||
|
||||
/**
|
||||
* Find override property from given RNA path, if it exists.
|
||||
|
||||
@@ -506,7 +506,7 @@ void BKE_lib_id_make_local_generic(Main *bmain, ID *id, const int flags)
|
||||
if (force_local) {
|
||||
BKE_lib_id_clear_library_data(bmain, id, flags);
|
||||
if ((flags & LIB_ID_MAKELOCAL_LIBOVERRIDE_CLEAR) != 0) {
|
||||
BKE_lib_override_library_make_local(id);
|
||||
BKE_lib_override_library_make_local(bmain, id);
|
||||
}
|
||||
BKE_lib_id_expand_local(bmain, id, flags);
|
||||
}
|
||||
@@ -1826,7 +1826,9 @@ void BKE_library_make_local(Main *bmain,
|
||||
ELEM(lib, nullptr, id->override_library->reference->lib) &&
|
||||
((untagged_only == false) || !(id->tag & LIB_TAG_PRE_EXISTING)))
|
||||
{
|
||||
BKE_lib_override_library_make_local(id);
|
||||
/* Validating liboverride hierarchy root pointers will happen later in this function,
|
||||
* rather than doing it for each and every localized ID. */
|
||||
BKE_lib_override_library_make_local(nullptr, id);
|
||||
}
|
||||
}
|
||||
/* The check on the fourth line (LIB_TAG_PRE_EXISTING) is done so it's possible to tag data
|
||||
@@ -1966,6 +1968,10 @@ void BKE_library_make_local(Main *bmain,
|
||||
}
|
||||
}
|
||||
|
||||
/* Making some liboverride local may have had some impact on validity of liboverrides hierarchy
|
||||
* roots, these need to be re-validated/re-generated. */
|
||||
BKE_lib_override_library_main_hierarchy_root_ensure(bmain);
|
||||
|
||||
#ifdef DEBUG_TIME
|
||||
printf("Step 4: Remap local usages of old (linked) ID to new (local) ID: Done.\n");
|
||||
TIMEIT_VALUE_PRINT(make_local);
|
||||
|
||||
@@ -3587,7 +3587,7 @@ void BKE_lib_override_library_delete(Main *bmain, ID *id_root)
|
||||
BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
|
||||
}
|
||||
|
||||
void BKE_lib_override_library_make_local(ID *id)
|
||||
void BKE_lib_override_library_make_local(Main *bmain, ID *id)
|
||||
{
|
||||
if (!ID_IS_OVERRIDE_LIBRARY(id)) {
|
||||
return;
|
||||
@@ -3617,6 +3617,10 @@ void BKE_lib_override_library_make_local(ID *id)
|
||||
if (node_tree != nullptr) {
|
||||
node_tree->id.flag &= ~LIB_EMBEDDED_DATA_LIB_OVERRIDE;
|
||||
}
|
||||
|
||||
/* In case a liboverride hierarchy root is 'made local', i.e. is not a liboverride anymore, all
|
||||
* hierarchy roots of all liboverrides need to be validated/re-generated again. */
|
||||
BKE_lib_override_library_main_hierarchy_root_ensure(bmain);
|
||||
}
|
||||
|
||||
/* We only build override GHash on request. */
|
||||
|
||||
@@ -1017,7 +1017,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
|
||||
template_id_liboverride_hierarchy_make(C, bmain, template_ui, &idptr, &undo_push_label);
|
||||
}
|
||||
else {
|
||||
BKE_lib_override_library_make_local(id);
|
||||
BKE_lib_override_library_make_local(bmain, id);
|
||||
/* Reassign to get proper updates/notifiers. */
|
||||
idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop);
|
||||
RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr, nullptr);
|
||||
|
||||
@@ -1002,7 +1002,7 @@ static void id_local_fn(bContext *C,
|
||||
}
|
||||
}
|
||||
else if (ID_IS_OVERRIDE_LIBRARY_REAL(tselem->id)) {
|
||||
BKE_lib_override_library_make_local(tselem->id);
|
||||
BKE_lib_override_library_make_local(CTX_data_main(C), tselem->id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1095,7 +1095,7 @@ static ID *rna_ID_make_local(ID *self, Main *bmain, bool /*clear_proxy*/)
|
||||
BKE_lib_id_make_local(bmain, self, 0);
|
||||
}
|
||||
else if (ID_IS_OVERRIDE_LIBRARY_REAL(self)) {
|
||||
BKE_lib_override_library_make_local(self);
|
||||
BKE_lib_override_library_make_local(bmain, self);
|
||||
}
|
||||
|
||||
ID *ret_id = self->newid ? self->newid : self;
|
||||
|
||||
Reference in New Issue
Block a user