Bone collections and bone collection membership are not handled properly when undoing in armature edit mode #111780
Short description of error
When you undo in armature edit mode, all bones lose their bone collection memberships, and adding/removing bone collections is not undone.
Exact steps for others to reproduce the error
- Create an armature.
- Enter edit mode.
- Add some bones and collections, and assign some bones to some collections.
- Repeatedly undo, and see that bone collection membership is lost on all bones, and the operations adding bone collections don't get undone.
This is due to bone collections not being handled at all in the armature undo code.
In order to initially land bone collections, I added the following code as a stop-gap to avoid crashes due to accessing invalid memory:
It does indeed eliminate the crashes, but also causes undo to work incorrectly. To fix this issue, that code must be removed, and all crashes and misbehavior resulting from that need to be addressed.
Further investigation into the crashes revealed that there are multiple underlying issues, any of which can cause crashes:
- The armature undo code in
editors/armature/editarmature_undo.cccopies the edit bones to the undo stack, for later restoration. However, it doesn't copy the collection membership listbase, so the undo copy of an edit bone points to the same listbase memory as the edit bone still in the armature. If the latter gets deleted, the collection membership listbase also gets deleted, and the undo edit bone is then pointing at invalid memory. This issue is relatively straightforward to address, by simply doing proper copy of that membership listbase... except that will still interact badly with the remaining issues.
- The armature undo code in
editors/armature/editarmature_undo.ccdoesn't handle bone collections at all. This means that adding/removing collections while in armature edit mode doesn't get undone. That on its own needs to get fixed just because it's faulty undo behavior. But it also can result in invalid memory access, due to the collection membership listbase stored in the undo edit bones. If a collection is removed, and then you undo, one of the edit bones may still be pointing to the removed collection. But even after fixing things to restore removed collections on undo, they presumably will not have the same memory address, so the undo edit bones will still point to invalid memory.
- Outside of edit mode, undo is handled by copying data from a memory file. So even if we fix both of the above issues to work properly within edit mode, undoing outside of edit mode frees and recreates the bone collections, so the edit-mode undo stack will again have edit bones pointing at invalid memory via their collection membership listbase. And this also leads to crashes when object-mode undo and edit-mode undo interact, which is fairly easy to trigger.
No due date set.
No dependencies set.
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?