Skip to main content
  1. Hair Tools/
  2. Hair Tools Documentation/

Hair Tools - Extract Clumps

Table of Contents

force_table_of_contents
#

Builds guide curves from a dense groom. First it finds clumps, which are groups of strands that travel together. Then for each clump it either picks the existing strand that best represents it, or builds a new average strand down its center. Strands are grouped by the path they follow rather than how close their roots are, so hairs that sweep together land in the same clump even when they start far apart on the skin.

If you already have clump IDs from elsewhere, you can feed them in and skip the automatic clumping.

By default, the input groom is shown as a guide, with color coding to identify the clumps.

See also: hair_select to select a subset of representative guides with an even mesh distribution.

Clump Identification
#

This stage decides which strands belong together. It looks for places where strands bunch up, finds the dense core of each clump, and grows the clump outward from there. That keeps clumps apart inside a thick coat instead of merging the whole groom into one blob. Any strand that doesn’t fit a clump is marked as noise, with a clumpid of -1.

Strands are compared by the path they travel, not just where they start. Each pair is measured along the shorter strand and compared against the longer one, so a short strand and a long strand that lie together still count as neighbors. Two strands join the same clump when they stay closer than clump_scale times the local root spacing. Since the spacing is measured locally, one value of clump_scale works across both the dense and sparse parts of the groom.

A group with fewer than min_clump_size strands is too small to be a real clump, so it’s left as noise instead of being forced into one. This keeps stray hairs from forming junk clumps.

The clustering can split one clump into several, which shows up as a single clump painted in a few colors. merge_clumps joins those pieces back up. It looks at the dip in strand density between two clumps: a clump that got split has only a shallow dip between its halves, while separate clumps have a deep gap between them. The value sets how deep a dip it will merge across, as a fraction of how dense the smaller of the two clumps gets at its core. At 0 only clumps with no dip at all merge, so every split is kept. At 1 all touching clumps merge. A higher value merges across deeper dips. Raise it if one clump comes out as several colors, lower it if separate clumps are merging.

A single strand that strays from its neighbors can get dropped as noise even when it clearly sits inside a clump. To catch this, any noise strand whose root is surrounded by a clump’s roots gets pulled back into that clump. A strand only stays noise if there’s no clump near its root.

Some areas read as clumps without really gathering, like a flat patch of evenly planted strands that all run parallel. Turn on cull_loose_clumps to drop these. A real clump pulls in along its length, while a loose one stays parallel from root to tip. min_convergence sets how much a clump has to pull in to survive. At 0 it only drops clumps that splay apart, and raising it also clears the flatter, more parallel ones while keeping the tight clumps.

sample_start skips the root area when comparing strands, so hairs that share a base but fan apart higher up aren’t grouped together just because of that shared base.

Quick tuning:

  • clump_scale sets the overall clump size. Smaller values give more, finer clumps. Larger values give fewer, broader ones.
  • min_clump_size is the smallest group that counts as a clump. Raise it to push more borderline groups into noise.
  • merge_clumps joins over-split clumps by merging across the density dip between them. Higher values merge across deeper dips. Raise it if one clump shows several colors, lower it if separate clumps merge.
  • cull_loose_clumps removes flat, parallel areas that never really clump. Turn it on and raise min_convergence to drop more of them.
  • sample_start is how much of the root to ignore when matching strands.

External Clump IDs
#

If another tool already provides clumps as a clumpid attribute on each strand, the node skips its own clumping and uses those IDs directly.

Guide Selection
#

For each clump, this picks the existing strand that best represents the group. It builds an average path down the clump, then scores every strand by how closely it follows that path, favoring strands that are straighter and longer. A higher bias value pushes that preference further.

Strands shorter than the minimum length ratio are left out of the running. That ratio is measured against the longest strand in the clump. If a strand ends partway up the clump, the rest of its score uses the distance from its tip, which penalizes short strands.

The chosen strand is added to the guide group, and every strand in its clump gets that guide’s number written to guideid. Noise strands (clump -1) are skipped. They get a guideid of -1 and aren’t turned into guides.

Guide Generation
#

Instead of picking an existing strand, this builds a new guide down the center of each clump. The clump is sliced crossways along its overall direction, and the strand points that fall in each slice are averaged to place that point of the guide.

Point attributes like width, pscale, and Cd are averaged within each slice. Primitive attributes are averaged across the whole clump. The finished guide is smoothed a little to take out jitter.

Clump Width
#

After a guide is selected or generated, the node measures how wide its clump is at each point along the guide. At each point it gathers the clump’s strand points in a thin slab across the guide and averages their distance to the guide. When a slab catches no strand points, the width holds its last measured value instead of dropping to zero. That usually happens past the tip of a selected guide that runs longer than the rest of its clump.

The slab fraction sets how thick that slab is, as a fraction of the guide’s length. Smaller values measure more locally. Larger values average over more of the clump.

The width is written per point, so you can use it later for clump shaping, width-based effects, or just to visualize the clumps.