Regression: Ctrl+Z breaks vertex paint #116029
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
6 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: blender/blender#116029
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?
System Information
Operating system: Windows-10-10.0.22631-SP0 64 Bits
Graphics card: NVIDIA GeForce RTX 3060 Ti/PCIe/SSE2 NVIDIA Corporation 4.6.0 NVIDIA 546.17
Blender Version
Broken: version: 4.0.2, branch: blender-v4.0-release, commit date: 2023-12-05 07:41, hash:
9be62e85b727
Worked: 3.6
This changed in
94e6ab6d71
Short description of error
When I press Ctrl+Z several times in vertex paint mode, in some point it returns to object mode. Than when i go in vertex paint and tryin to paint nothing happens, the vertices are not painted no matter what I do. If you create a new mash in the same scene, the vertices are not painted on it either. If I create a new file and Ctrl+V broken object from previous file the vertices are not painted over either.
Exact steps for others to reproduce the error
New file, default cube or any created mash
Hi, thanks for the report. Can confirm. This appears to be broke between 3.6 - 4.0 release
This seems to happen when existing color attribute is deleted during undo
Ctrl+Z breaks vertex paintto Regression: Ctrl+Z breaks vertex paintBroke between good
cc5f666672
& bad9cbe156d6a
Will bisect in a bit...
This changed in
94e6ab6d71
@mont29 : mind checking?
Paint is still working fine, the problem is that the paint settings are reset (brush goes back to 'Add' e.g.).
Think it happened to work before
94e6ab6d71
by mere accident (issue fixed by94e6ab6d71
hiding the one revealed here).Checking further.
The problem comes from the tool system resetting the active tool (and brush) from the content of the relevant
tool_slots
. For some reasons, on startup, the first tool slot is set toAdd
brush (at least for me), instead of matching the defaultDraw
brush.I'm lost here...
The active scene's vpaint brush is reset to
Add
one (i.e. the one in thetool_slots[0]
) in theWM_toolsystem_refresh_active
call part of theed_undo_step_post
function. This happens when iterating over all tool references in the workspace, and callingtoolsystem_refresh_ref
on them.From my understanding, in
toolsystem_ref_link
, there is a mismatch between the 'active'slot_index
, and the 'active' tool stored in the Brush ID itself? And why do we store the active tool in the brush ID????This function also seems to be the only one calling
BKE_brush_tool_set
, even though it first uses the result ofBKE_brush_tool_get
to decide whether it needs to re-assign a brush or not (which is what if causing theDraw
brush to be replaced by theAdd
one here). So how is that 'active tool' returned byBKE_brush_tool_get
supposed to be set and valid in the first place?It seems that the
tool_slots
used for a brush is defined by its assigned byBKE_paint_brush_set
(through call toBKE_paint_toolslots_brush_update_ex
).NOTE: Ended up finding 'something' that 'fixes' the reported issue: !116197 . It seems to be a valid change looking at the code... But I have zero idea whether this double brush setting call is actually needed for something else, nor why it was added in the first place (comes from
a90bcdf93d
).I am not familiar enough with the Tool system to go further am afraid, not without spending days trying to understand it. @ideasman42, mind taking over?
@ideasman42 Hey. Any news here?
Edit these findings look to be flawed & don't take into account undo-restore logic (
SCENE_FOREACH_UNDO_RESTORE
), keeping for completeness.As I understand it the root cause is as follows.
Point 3 is the cause of the problem.
So as far as I can see the fix for this is to always tag the scene
ID_RECALC_COPY_ON_WRITE
when it's tool settings are modified, otherwise undo might not include the changes.There are many places that set the brush and they don't always have the owner ID available (the scene in this case). This PR !117055 is an ensures the scene is tagged which AFAICS is correct but could be re-thought or refactored to avoid similar accidents in the future.
While tagging an ID when its data is modified is for sure required, I fail to understand why it solves this issue currently. To me this sounds more like another 'magic fix that happens to work'. I would expect the tool system to work with the original Scene data, not with some evaluated one from depsgraph...
As a reminder, I do not think that
4
is correct? The whole toolsettings are skipped on undo, it's always re-using the current (before undo step loading) data (seescene_undo_preserve
). At least afair when investigating this last month, the brush was the expected 'Draw' one in scene's toolsettings after undo step reading. As said in my previous comment, it's the call totoolsystem_ref_link
that ends up resetting that brush to theAdd
one. Could it be that this is actually working with evaluated Scene data???Although this is definitely not a correct solution, I would be curious to know if replacing
ID_RECALC_COPY_ON_WRITE
byID_RECALC_TAG_FOR_UNDO
in your patch also does solve the issue? That later tag should have no effect on depsgraph/evaluation, and only enforces the ID to be detected as modified by the undo system.It seems my initial findings were flawed because tagging
ID_RECALC_COPY_ON_WRITE
does NOT fix the bug, although when testing an earlier version of the patch I somehow managed to fix the issue, the final patch didn't.After some more discussion, my understanding is that SCENE_FOREACH_UNDO_RESTORE should keep the paint-brush at it's current value (where possible) even if the undo step stores a different value (this part threw me).
Updated findings:
scene_undo_preserve
runs.scene_new->toolsettings->vpaint->paint.tool_slots[0].brush
points to the "Add" brush.scene_old->toolsettings->vpaint->paint.tool_slots[0].brush
points to the "Draw" brush.... Reading
scene_foreach_paint
there is an attempt to keep the values of the old brushes. ...BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER_P
macro runs on the brush pointer, callingscene_foreach_toolsettings_id_pointer_process
.SCENE_FOREACH_UNDO_RESTORE
case is used.BLO_read_get_new_id_address_from_session_uuid
lookup succeeds, but the pointer returned is the same asid_old
,(id_old_new == id_old)
.if (!ELEM(id_old_new, id_old, nullptr)) {...}
block to fail which is needed for the previous pointer to be restored.std::swap(*id_p, *id_old_p);
writes the "Add" brush into the "Draw" brushes ID, causing the brush to be "Add".It seems
BLO_read_get_new_id_address_from_session_uuid(..)
should return a new pointer that doesn't match the existing pointer but I don't know how this would be done.Eeeeeh reading at code in
scene_foreach_toolsettings_id_pointer_process
, there is indeed one critical issue when bothid_old
andid_old_new
pointers are the same! Then the code should essentially do nothing.