#
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**

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 functionthat 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 Constraintof "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.output.gifimage.pngoutput2.gifNodes & PhysicsprojectWIP: Test implementation of a constraint-based combing brush#105769Here'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.

2023-03-15 11-41-38.mp4Moved 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.

2023-03-20 17-46-22.mp4This 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