Fix T80078: Overrides: Crash with animated IK control on linked armature.
Issue was with our dear posebones again... when applying overrides we keep the same address/pointer for the IDs themselves, (which avoids us the need to remap their usages), but their inner data is often re-allocated. Therefore, we need once again to go over armature objects and invalidate their posebone pointers. This should also be back-ported to Blender LTS 2.83. Maniphest Tasks: T80078 Differential Revision: https://developer.blender.org/D8734
This commit is contained in:
@@ -1475,6 +1475,20 @@ void BKE_lib_override_library_update(Main *bmain, ID *local)
|
||||
/* XXX And crashing in complex cases (e.g. because depsgraph uses same data...). */
|
||||
BKE_id_free_ex(bmain, tmp_id, LIB_ID_FREE_NO_UI_USER, true);
|
||||
|
||||
if (GS(local->name) == ID_AR) {
|
||||
/* Funtime again, thanks to bone pointers in pose data of objects. We keep same ID addresses,
|
||||
* but internal data has changed for sure, so we need to invalidate posebones caches. */
|
||||
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
|
||||
if (ob->pose != NULL && ob->data == local) {
|
||||
BLI_assert(ob->type == OB_ARMATURE);
|
||||
ob->pose->flag |= POSE_RECALC;
|
||||
/* We need to clear pose bone pointers immediately, some code may access those before pose
|
||||
* is actually recomputed, which can lead to segfault. */
|
||||
BKE_pose_clear_pointers(ob->pose);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (local->override_library->storage) {
|
||||
/* We know this datablock is not used anywhere besides local->override->storage. */
|
||||
/* XXX For until we get fully shadow copies, we still need to ensure storage releases
|
||||
|
||||
@@ -244,17 +244,17 @@ static void libblock_remap_data_preprocess(IDRemap *r_id_remap_data)
|
||||
ID *old_id = r_id_remap_data->old_id;
|
||||
if (!old_id || GS(old_id->name) == ID_AR) {
|
||||
Object *ob = (Object *)r_id_remap_data->id_owner;
|
||||
/* Object's pose holds reference to armature bones... sic */
|
||||
/* Note that in theory, we should have to bother about
|
||||
* linked/non-linked/never-null/etc. flags/states.
|
||||
/* Object's pose holds reference to armature bones. sic */
|
||||
/* Note that in theory, we should have to bother about linked/non-linked/never-null/etc.
|
||||
* flags/states.
|
||||
* Fortunately, this is just a tag, so we can accept to 'over-tag' a bit for pose recalc,
|
||||
* and avoid another complex and risky condition nightmare like the one we have in
|
||||
* foreach_libblock_remap_callback()... */
|
||||
* foreach_libblock_remap_callback(). */
|
||||
if (ob->pose && (!old_id || ob->data == old_id)) {
|
||||
BLI_assert(ob->type == OB_ARMATURE);
|
||||
ob->pose->flag |= POSE_RECALC;
|
||||
/* We need to clear pose bone pointers immediately, things like undo writefile may be
|
||||
* called before pose is actually recomputed, can lead to segfault... */
|
||||
/* We need to clear pose bone pointers immediately, some code may access those before
|
||||
* pose is actually recomputed, which can lead to segfault. */
|
||||
BKE_pose_clear_pointers(ob->pose);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user