Comb brush improvements #105722

Open
opened 2023-03-13 15:11:13 +01:00 by Hans Goudey · 6 comments
Member

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.
image

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.
image

Code: #105769

A few further improvements should be considered for a full feature:

  • The constraint solver should be generalized to support additional constraints in the future.
  • Length constraints should apply to both sides of a segment equally instead of the follow-the-leader approach (solving from the root up). This will require more iterations but make it more compatible with other constraints. Zero weights for root points ensure pinning to the surface.
  • Some simplified stiffness constraints for segment angles can help avoid the "floppiness" of curves.
  • Better collision handling is needed. Collision constraints should not attempt to solve length constraints simultaneously, since that only works for the last-solved segment and makes the solution very non-linear.
  • The comb constraint is solved with a linear projection. A few iterations of gradient descent or a similar method for just this constraint type might improve convergence.
  • Currently 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.
# 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. ![image](/attachments/f97b70fd-0461-4032-82cb-2203fb478e3c) 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. <img src=/attachments/a536da74-18fb-499f-9963-6ace3147d310 width="300"> 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. ![image](/attachments/1cfd44c8-a6a6-40bb-9e9d-f7686e82e031) Code: https://projects.blender.org/blender/blender/pulls/105769 A few further improvements should be considered for a full feature: * The constraint solver should be generalized to support additional constraints in the future. * Length constraints should apply to both sides of a segment equally instead of the follow-the-leader approach (solving from the root up). This will require more iterations but make it more compatible with other constraints. Zero weights for root points ensure pinning to the surface. * Some simplified stiffness constraints for segment angles can help avoid the "floppiness" of curves. * Better collision handling is needed. Collision constraints should not attempt to solve length constraints simultaneously, since that only works for the last-solved segment and makes the solution very non-linear. * The comb constraint is solved with a linear projection. A few iterations of gradient descent or a similar method for just this constraint type might improve convergence. * Currently `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.
Hans Goudey added the
Type
To Do
label 2023-03-13 15:11:13 +01:00
Hans Goudey added this to the Nodes & Physics project 2023-03-13 15:11:14 +01:00
Lukas Tönne self-assigned this 2023-03-13 15:52:16 +01:00
Member

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.

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](/attachments/bea64ab3-3591-41df-af16-822a59f2edf6) 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.
Member

Moved the main description to Hans' first comment.

Moved the main description to Hans' first comment.
Member

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.

Testing a bending constraint based on Bergou, Miklós, et al. "Discrete elastic rods." <video controls src="/attachments/612883c5-8a9d-4667-a6ba-c00bbe9e231d"></video> 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?

This woulde be a fantastic improvment! Any news on this?
Member

@LukasTonne I think I missed your update on this. What is the status here? Should it be tested?

@LukasTonne I think I missed your update on this. What is the status here? Should it be tested?
Member

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

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
Sign in to join this conversation.
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 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
No description provided.