Comb brush improvements #105722
Open
opened 2023-03-13 15:11:13 +01:00 by Hans Goudey
·
6 comments
No Branch/Tag Specified
main
blender-v4.0-release
temp-sculpt-dyntopo
blender-v3.6-release
universal-scene-description
blender-v3.3-release
asset-browser-frontend-split
brush-assets-project
asset-shelf
anim/armature-drawing-refactor-3
temp-sculpt-dyntopo-hive-alloc
tmp-usd-python-mtl
tmp-usd-3.6
blender-v3.5-release
blender-projects-basics
blender-v2.93-release
temp-sculpt-attr-api
realtime-clock
sculpt-dev
gpencil-next
bevelv2
microfacet_hair
xr-dev
principled-v2
v3.6.4
v3.6.3
v3.3.11
v3.6.2
v3.3.10
v3.6.1
v3.3.9
v3.6.0
v3.3.8
v3.3.7
v2.93.18
v3.5.1
v3.3.6
v2.93.17
v3.5.0
v2.93.16
v3.3.5
v3.3.4
v2.93.15
v2.93.14
v3.3.3
v2.93.13
v2.93.12
v3.4.1
v3.3.2
v3.4.0
v3.3.1
v2.93.11
v3.3.0
v3.2.2
v2.93.10
v3.2.1
v3.2.0
v2.83.20
v2.93.9
v3.1.2
v3.1.1
v3.1.0
v2.83.19
v2.93.8
v3.0.1
v2.93.7
v3.0.0
v2.93.6
v2.93.5
v2.83.18
v2.93.4
v2.93.3
v2.83.17
v2.93.2
v2.93.1
v2.83.16
v2.93.0
v2.83.15
v2.83.14
v2.83.13
v2.92.0
v2.83.12
v2.91.2
v2.83.10
v2.91.0
v2.83.9
v2.83.8
v2.83.7
v2.90.1
v2.83.6.1
v2.83.6
v2.90.0
v2.83.5
v2.83.4
v2.83.3
v2.83.2
v2.83.1
v2.83
v2.82a
v2.82
v2.81a
v2.81
v2.80
v2.80-rc3
v2.80-rc2
v2.80-rc1
v2.79b
v2.79a
v2.79
v2.79-rc2
v2.79-rc1
v2.78c
v2.78b
v2.78a
v2.78
v2.78-rc2
v2.78-rc1
v2.77a
v2.77
v2.77-rc2
v2.77-rc1
v2.76b
v2.76a
v2.76
v2.76-rc3
v2.76-rc2
v2.76-rc1
v2.75a
v2.75
v2.75-rc2
v2.75-rc1
v2.74
v2.74-rc4
v2.74-rc3
v2.74-rc2
v2.74-rc1
v2.73a
v2.73
v2.73-rc1
v2.72b
2.72b
v2.72a
v2.72
v2.72-rc1
v2.71
v2.71-rc2
v2.71-rc1
v2.70a
v2.70
v2.70-rc2
v2.70-rc
v2.69
v2.68a
v2.68
v2.67b
v2.67a
v2.67
v2.66a
v2.66
v2.65a
v2.65
v2.64a
v2.64
v2.63a
v2.63
v2.61
v2.60a
v2.60
v2.59
v2.58a
v2.58
v2.57b
v2.57a
v2.57
v2.56a
v2.56
v2.55
v2.54
v2.53
v2.52
v2.51
v2.50
v2.49b
v2.49a
v2.49
v2.48a
v2.48
v2.47
v2.46
v2.45
v2.44
v2.43
v2.42a
v2.42
v2.41
v2.40
v2.37a
v2.37
v2.36
v2.35a
v2.35
v2.34
v2.33a
v2.33
v2.32
v2.31a
v2.31
v2.30
v2.28c
v2.28a
v2.28
v2.27
v2.26
v2.25
Labels
Clear labels
This issue affects/is about backward or forward compatibility
Issues relating to security: https://wiki.blender.org/wiki/Process/Vulnerability_Reports
Apply labels
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
This issue affects/is about backward or forward compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
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
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
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
Issues relating to security: https://wiki.blender.org/wiki/Process/Vulnerability_Reports
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 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 & 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
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
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
Milestone
Set milestone
Clear milestone
No items
No Milestone
Projects
Set Project
Clear projects
No project
Assignees
Assign users
Clear assignees
No Assignees
4 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.
No due date set.
Dependencies
No dependencies set.
Reference: blender/blender#105722
Reference in New Issue
There is no content yet.
Delete Branch "%!s(<nil>)"
Deleting a branch is permanent. Although the deleted branch may exist for a short time before cleaning up, in most cases it CANNOT be undone. Continue?
Motivation
Comb brushes currently don't work all that well. It takes several brush strokes to push hair into a different direction and align it. Curves tend to drift away from the brush, especially close to the tips.
A good combing brush should feel almost like a real, physical hair comb. It should "grip" the hair without letting it drift out of the brush region, while allowing slippage in the hair direction.
Current problems
Goal positions for vertices are correctly computed by the brush and initially applied. But then segment length and collision constraints get solved, which moves points away from initial positions. Large brush strokes in particular cause large corrections for length constraints, which diminishes the brush effect.

Especially points at the tip tend get corrected so much that the initial displacement of the comb brush is quickly lost. That is because the length constraint works from the root upwards and only moves the end point of each segment. This "follow the leader" solution has the advantage that it only requires one iteration for a perfect length constraint, but the downside is that it artificially overcorrects curve tips. This issue has been described in section 3.1 of "Fast Simulation of Inextensible Hair and Fur." (Müller et al.).
https://matthias-research.github.io/pages/publications/FTLHairFur.pdf
Recently a correction factor was introduced (#104589) to make curve tips more responsive, but only partially solves the problem.
What is the desired behavior?
Combing should feel like a physical comb. Hairs between the teeth of a comb are constrained in their lateral movement, but can move (with some friction) along the direction of the hair.

This suggests that, rather than just an initial point offset, combing should be implemented as a constraint itself. This gives greater control over the priority and weighting of brush influence relative to other constraints. The solver can then try to satisfy segment lengths, collisions, and brush constraints at the same time, rather than overriding brush goals immediately.
Irrelevant aspects of real combs
Real physical combs are open to one side to make inserting hair easier. If that side faces down the hair will fall out. This is not a feature we need to replicate. Instead the hair should generally be restrained laterally, but move freely in the longitudinal direction.
Real combs also only work if held at a right angle to the hair direction. Brushes in Blender don’t usually have an orientation, so we can assume that this is always the case.
Combs are also generally planar, while Blender brushes are spheres or cylinders (depending on projection mode). We don’t need all hair constraints to lie in the same plane.
Real hair has some friction when dragged through a comb. This is a useful feature because it extends the influence of the brush beyond the immediate brush position. But we can simplify the brush and assume a moderate constant amount of friction with a simple tool setting (or disable friction altogether).
Formulating a comb brush constraint
All existing curve editing features can be understood as a simplified position-based constraint system. The goal now is to define an objective function that describes a suitable "comb constraint" and improve the curve constraint solver so that it supports this new constraint in addition to existing length and collision constraints.
An formulation of such a constraint can be found in section 5.1 Keyhole Constraint of "A robust and efficient Lagrangian Constraint Toolkit for the Simulation of 1D Structures" by Adrien Theetten.
http://adrien.theetten.free.fr/lifl/simulation/Theetten-2009-JCAD.pdf
The constraint minimizes the distance to a goal point. The goal is found at the beginning of the stroke by looking on each curve for the closest point to the brush center. The key difference to a simple "grab" constraint is that the point parameter
u
along the curve is also a variable, meaning that the point can slide along the curve to minimize deformation, as long as the deformed curve still goes through the goal point.It must be noted that the curve has to be differentiable for this to work properly. A simple cubic spline interpolation helps generate a smooth gradient to move the keyhole point in the right direction along the spline.
Test implementation
A test implementation shows the improved behavior of the constraint-based brush: The curves are following the brush much more strictly and it only takes a single stroke to align curves.

Code: #105769
A few further improvements should be considered for a full feature:
segment_length
and similar constraint constants are recomputed at the start of each brush stroke. This is susceptible to drift over multiple brush strokes, as any residual error of the solver is carried over into the next stroke. While improving convergence of the solver alleviates this issue it shouldn't be expected to get a totally accurate solution every time.segment_length
and other (supposed) constants should be persistent as attributes and only change when e.g. grow/shrink brushes modify them.Here's another test after replacing the root-first length constraints (aka. "follow-the-leader" method) with a more balanced length constraint implementation. Now points closer to the root are also reacting to the combing action, instead of just the tips.
2023-03-15 11-41-38.mp4
The relative strength of constraints should become adjustable eventually, so the brush might have more or less "friction". Currently the brush falloff is also not taken into account.
Moved the main description to Hans' first comment.
Testing a bending constraint based on Bergou, Miklós, et al. "Discrete elastic rods."
Currently has unstable corner cases that need to be fixed. Especially when the brush affects the root points it tends to flip some segments and subsequently takes many iterations to solve.
This feature might be used in combination with the brush falloff, keeping the curves stiff outside of the comb brush influence. More experiments needed.
This woulde be a fantastic improvment! Any news on this?
@LukasTonne I think I missed your update on this. What is the status here? Should it be tested?
It's on hold, there were other priorities. Might come back to this or it might become part of the node tools project, no clear plans atm.
@SimonThommes no testing at this point, not sure if it still works at all