Fix assert in BKE_main_namemap when reusing brush assets on fileload.

Code in readfile that copies over brush assets (and related data) from
the old Main to the new one cannot use the namemap reliably, due to how
the linked IDs of the library get temporarily spread between both Mains.

Since in theory there should be no need for name uniqueness processing
in this case anyway, for now disable the relevant code when the library
is re-used.

NOTE: Issue reported in #135315, revealed by recent refactor in
00f406c34c and 16e552298c.

NOTE: This fix is a bit hackish, but seems to be the simplest most
straight-forward way to address the problem. More invasive solution can
be investigated if this proves to still be problematic.

NOTE: While 4.4 also has the same invalid handling, this PR should
likely not be ported to it, as previous BKE_main_namemap code was more
permissive with such invalid behaviors, and there is no known bad
consequences in practice.

Pull Request: https://projects.blender.org/blender/blender/pulls/135362
This commit is contained in:
Bastien Montagne
2025-03-03 11:34:48 +01:00
committed by Bastien Montagne
parent 4a6e73c3e6
commit 666267ef40

View File

@@ -353,12 +353,31 @@ static bool reuse_bmain_move_id(ReuseOldBMainData *reuse_data,
/* Move from one list to another, and ensure name is valid. */
BLI_remlink_safe(old_lb, id);
BKE_main_namemap_remove_id(*old_bmain, *id);
/* In case the ID is linked and its library ID is re-used from the old Main, it is not possible
* to handle name_map (and ensure name uniqueness).
* This is because IDs are moved one by one from old Main's lists to new ones, while the re-used
* library's name_map would be built only from IDs in the new list, leading to incomplete/invalid
* states.
* Currently, such name uniqueness checks should not be needed, as no new name would be expected
* in the re-used library. Should this prove to be wrong at some point, the name check will have
* to happen at the end of #reuse_editable_asset_bmain_data_for_blendfile, in a separate loop
* over Main IDs.
*/
const bool handle_name_map_updates = !ID_IS_LINKED(id) || id->lib != lib;
if (handle_name_map_updates) {
BKE_main_namemap_remove_id(*old_bmain, *id);
}
id->lib = lib;
BLI_addtail(new_lb, id);
BKE_id_new_name_validate(
*new_bmain, *new_lb, *id, nullptr, IDNewNameMode::RenameExistingNever, true);
if (handle_name_map_updates) {
BKE_id_new_name_validate(
*new_bmain, *new_lb, *id, nullptr, IDNewNameMode::RenameExistingNever, true);
}
else {
id_sort_by_name(new_lb, id, nullptr);
}
BKE_lib_libblock_session_uid_renew(id);
/* Remap to itself, to avoid re-processing this ID again. */
@@ -380,6 +399,10 @@ static Library *reuse_bmain_data_dependencies_new_library_get(ReuseOldBMainData
* There should be no filepath conflicts, as #reuse_bmain_data_remapper_ensure has
* already remapped existing libraries with matching filepath. */
reuse_bmain_move_id(reuse_data, &old_lib->id, nullptr, false);
/* Clear the name_map of the library, as not all of its IDs are guaranteed reused. The name
* map cannot be used/kept in valid state while some IDs are moved from old to new main. See
* also #reuse_bmain_move_id code. */
BKE_main_namemap_destroy(&old_lib->runtime->name_map);
return old_lib;
}
case ID_REMAP_RESULT_SOURCE_NOT_MAPPABLE: {