Undo - Current Status and Important Fixes Needed #83806
Labels
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
11 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: blender/blender#83806
Loading…
Reference in New Issue
No description provided.
Delete Branch "%!s(<nil>)"
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?
While investigating #82851 (Undo bug while sculpting) I realized that current general undo code has several issues, some being fairly critical and not trivial to solve (as is, too involved for a mere bugfix).
Here is current view of the situation (as I understand it), and some draft proposals to fix things and hopefully reach a better general state for undo code.
Current Status and Issues
1- Some undo steps will never be undone
Some undo modes (Sculpt and Image ones afaict) have a specific way to store and process their undo steps, which results in the fact that when undoing, they actually need to process the
next
step, and not the one that is passed to them (seesculpt_undosys_step_decode_undo
e.g.).This is all good as long as we stay in a same undo step type, but as soon as the step is from another type (like a global memfile one e.g.), its apply function is fully unaware of this, and therefore that first sculpt undo step never gets processed (undone).
2 - Some undo modes have useless redundant and critically buggy code
Again, Sculpt and Image undo code has loops over previous/next steps that are both useless, and critically buggy as they assume said previous/next steps are of the same undotype.
I'd assume this is inherited from the time where undo stacks where separated, but in a single common undo stack this is both useless (since main undo code like
BKE_undosys_step_undo_with_data_ex
already ensures that all previous/next steps have been processed in proper order), and obviously broken (due to lack of undo step type checking).3 - Unclear half-not-implemented fully-not-working support of 'absolute' undo steps
Definition:
Currently, general undo system (in
undo_system.c
) assumes all steps to be relative (see e.g. the first loop inBKE_undosys_step_undo_with_data_ex
). There are comments and pieces of code that seem to hint that absolute steps were supported, or intended to be supported at some point.In addition, while memfile steps used to be absolute, it's no longer the case with new system for them either.
4 - Apparently unused GPencil undo code
GPencil undo code is tagged in
ed_undo_step_impl
as needing update to be properly integrated in new general undo stack, however it seems to never be used effectively. See #84703 (Modernize (or Remove) GPencil Undo System) for details....And more?
There are probably more issues more or less related to issues mentioned above (did not check our reports related to edits/memfile undos mismatches e.g.), but I think addressing those three points would already bring things to a saner state.
Proposals
1 - Some undo steps will never be undone
Think main undo system should deal with those cases. Would do it that way:
step_decode
callbacks should only ever process the step that is given to them.** E.g. when you undo from a sculpt step to a memfile one, you actually need to process both the sculpt undo step (exception case) and the memfile one.
2 - Some undo modes have useless redundant and critically buggy code
Those extra looping pieces of code should simply be removed imho. Afaict they are dead code from earlier versions of undo system?
Tried to get them actually do something in
sculpt_undosys_step_decode_undo()
in debug session, and in all cases those actually never do anything, besides setting step-to-be-processed as the next one instead of the target one e.g.3 - Unclear half-not-implemented fully-not-working support of 'absolute' undo steps
Suggestion is to simply always assume all steps are relative ones. This will simplify logic and make code easier to follow.
This does imply some extra work when undoing a lot of steps at once (through the undo history menu e.g.), however I think this situation is not that common? And one could argue that on very heavy files like production ones, doing fifty relative undo steps affecting only a few data-blocks may very well be much quicker than re-reading the whole .blend file from memory, with all the implied depsgraph rebuild, updates, etc.
Changed status from 'Needs Triage' to: 'Confirmed'
Added subscribers: @mont29, @brecht, @ideasman42, @dfelinto
This task is mainly to see if other devs having some good knowledge of undo area see missing issues, or invalid analysis of those, and/or have other ideas about how to address them, before I start spending time in actual code refactor...
@ideasman42 am especially eager to have your feedback here, since iirc you were the last one to work on general undo system (among other things, merging all stacks into a single one?). ;)
Added subscriber: @TheRedWaxPolice
Clarifications
151cc02b6f
should have resolved the kinds of problems that still exist in sculpt mode.Regarding Proposal
This is fuzzy to me, if we need to handle special cases, OK, but I'm not sure which steps are not undone and the kinds of bugs this is causing currently.
Can we confirm that this is only sculpt mode? - if that's the case. Then we're on the same page. Getting sculpt modes undo working at all was quite difficult given how it handles undo steps internally.
+1 to remove absolute undo steps. There are times speed things up, but my sense is that undo-history is not a common way to access undo. And we can accept some performance loss to keep the internal logic stable + working.
Note that we could always support ways of skipping some undo steps as an optimization later (if we want). For example - loading undo steps into the same edit-mesh is not very useful. However I dont see this as a priority... having working predictable undo is so much more important.
Comments...
Generally the proposal seems fine, although I'd like to be aware of bugs. In general my impression is undo is working well in that it's not crashing and users are not regularly running into problems. That's not to say there are no problems, just that overall it's reliable. OTOH, it's possible I miss some issues and am unaware of some bugs/problems.
I'd highly recommend using tests for any development in this area. It's far too easy to accidentally break things and not realize, especially when this is interactions with different undo systems.
Double check the current tests cover the areas you intend to change/develop.
Create tests that expose existing bugs these changes intend to fix (handy for TDD too)
I can help with these tests if needed, if you can point me to bugs in undo, I don't mind to turn them into tests we can use to resolve issues, or if you want a hand in getting them setup, that's fine too.
I can mostly only repeat why I already say in task itself...
No open bug afaik, but image undo code seems to use the exact same 'use next step instead of given one' process as sculpt mode, so would expect exact same issue of missing first undo step...
Again, why are internal undo/redo code of image and sculpt (
sculpt_undosys_step_decode_undo
etc.) looping over undo steps, when main system (BKE_undosys_step_undo_with_data_ex
) already does it? Looks like dead code from before merge of the different undo stacks to me?See #82851: Undo bug while sculpting. First sculpt step stored after a Memfile one will never be undone. This is not visible from user most of the time since switching to Sculpt mode generates it's own, initial 'do nothing' sculpt step, but if there are memfile undo steps within a sculpt session e.g., then you'll have that bug.
That's why I want to make main
BKE_undosys_step_undo_with_data_ex
aware of this requirement instead, so that it can deal properly with this case, and mode-specific undo code can just blindly always process the step passed to it, and nothing else. This is the only safe way to handle an heterogeneous undo stack imho. mode-specific callbacks should never have to access any other step than the one they are given.Again, think this is at least sculpt and image. At the very least, they both share the same process in
sculpt_undosys_step_decode_undo
andimage_undosys_step_decode_undo
, iterating over undo steps blindly assuming those are of their own type, without any checks (and afaict without any valid reason to do so anymore).Indeed, starting with new tests seems the best thing to do here, will do that first.
Added new
view3d_sculpt_with_memfile_step
test demonstrating issue from #82532/T82851 in rBL62534Added subscriber: @NoBlahBlah
I can assure you guys that using undo history menu to undo multiple steps at once is an extremely common use case. Why? Because of 2 reasons
1). Undoing and then redoing between the same steps to check whether a change you made is a good one is pretty much a universal workflow, no one teaches you to work like this you learn this yourself, given just how universal this is you can almost call it human nature.
2). Sometimes or rather most of the times comparing the state of something (be it a mesh or scene etc etc...) immediately before and after a change is just not a fair comparison to make, it's like comparing apples to oranges , to make it a more fair comparison you need to make more than one change possibly even 10 to 20 changes before you can finally compare the current state with what it was many, many undo steps ago.
Added subscriber: @ckohl_art
Added subscriber: @oweissbarth
@NoBlahBlah it's not about removing ability to undo multiple steps at once, it's about removing half-finished, not-really-working that tries to optimize that specific scenario, but is not really working anyway currently.
FYI, quick-slapped a (horrible!) investigating patch to address the sculpt-step-not-properly-undone case, P1858: (An Untitled Masterwork)
.
It does fix the sculpt issue, but is obviously not a proper clean solution at all, and also break some other tests on the road... But think it demonstrate the problem on a code side of things.
Added subscriber: @kursadk
I have had a case with undoing text edits inside the text editor also causes massive wait times with heavy scenes. I am wondering if it is possible to decouple the text editor changes from the actual scenes. This kind of slow down is extra unproductive.
Thanks
Added subscriber: @Pipeliner
This comment isn't valid, added comment + assertion that this never happens, see:
ab6e67767e
Added subscriber: @Jenny-Brown
Added subscriber: @Gilberto.R
Added subscriber: @RedMser
Changed status from 'Confirmed' to: 'Archived'
Archiving this for now, it is no longer really relevant and have no time to update it to current status of undo code.