diff options
author | Bastien Montagne <bastien@blender.org> | 2020-11-03 14:09:00 +0300 |
---|---|---|
committer | Bastien Montagne <bastien@blender.org> | 2020-11-03 14:09:00 +0300 |
commit | bc0a6b0400ceeda971384bd88014ea7eb6007ad0 (patch) | |
tree | 2e3bfdf0b76b6a57cf9ce7dcb0700a0c2923e533 /source/blender/blenkernel/intern/brush.c | |
parent | 5610ccdc080497042a24592432ade575e2fab489 (diff) |
Fix T71759: Sculpt/Vertex/Weight Paint Brush Size Gets Undone After Undoing a Stroke.
Add code preserving scene's toolsettings accross undo.
IDPointers are dealt with special care, we try to keep existing ones for
some (like brushes) when possible.
Note that this covers ToolSettings, Brushes and Palettes currently.
I'm not especially happy about how this new code mixes with existing
'foreach_id' one, in particular in scene. But cannot think of a better,
more generic way to do it currently.
Maniphest Tasks: T71759
Differential Revision: https://developer.blender.org/D9311
Diffstat (limited to 'source/blender/blenkernel/intern/brush.c')
-rw-r--r-- | source/blender/blenkernel/intern/brush.c | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index d62ccf794f3..806b9ca1416 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -355,6 +355,37 @@ static void brush_blend_read_expand(BlendExpander *expander, ID *id) } } +static int brush_undo_preserve_cb(LibraryIDLinkCallbackData *cb_data) +{ + BlendLibReader *reader = cb_data->user_data; + ID *id_old = *cb_data->id_pointer; + /* Old data has not been remapped to new values of the pointers, if we want to keep the old + * pointer here we need its new address. */ + ID *id_old_new = id_old != NULL ? BLO_read_get_new_id_address(reader, id_old->lib, id_old) : + NULL; + BLI_assert(id_old_new == NULL || ELEM(id_old, id_old_new, id_old_new->orig_id)); + if (cb_data->cb_flag & IDWALK_CB_USER) { + id_us_plus_no_lib(id_old_new); + id_us_min(id_old); + } + *cb_data->id_pointer = id_old_new; + return IDWALK_RET_NOP; +} + +static void brush_undo_preserve(BlendLibReader *reader, ID *id_new, ID *id_old) +{ + /* Whole Brush is preserved accross undo's. */ + BKE_lib_id_swap(NULL, id_new, id_old); + + /* `id_new` now has content from `id_old`, we need to ensure those old ID pointers are valid. + * Note: Since we want to re-use all old pointers here, code is much simpler than for Scene. */ + BKE_library_foreach_ID_link(NULL, id_new, brush_undo_preserve_cb, reader, IDWALK_NOP); + + /* Note: We do not swap IDProperties, as dealing with potential ID pointers in those would be + * fairly delicate. */ + SWAP(IDProperty *, id_new->properties, id_old->properties); +} + IDTypeInfo IDType_ID_BR = { .id_code = ID_BR, .id_filter = FILTER_ID_BR, @@ -377,7 +408,7 @@ IDTypeInfo IDType_ID_BR = { .blend_read_lib = brush_blend_read_lib, .blend_read_expand = brush_blend_read_expand, - .blend_read_undo_preserve = NULL, + .blend_read_undo_preserve = brush_undo_preserve, }; static RNG *brush_rng; |