Studio Matrx Monthly · Volume 1 · Issue 3 · August 2026
Amogh N P
 In loving memory of Amogh N P — Architect · Designer · Visionary 
Tree Matching & GraftingLesson 3.3
CPD for Architecture, Planning & Urban Design/Module 3 · Data Trees & List Management

Lesson 3.3 · Data Trees & List Management

Tree Matching & Grafting

Graft, Flatten, Simplify - and the data-matching rules behind '400 lines instead of 20'

13 min Interactive lessonFree · open lessonByAmogh N P· Architect & interior designer
The hook

You expected 20 lines. Grasshopper gave you 400. Nothing is broken - your two inputs just matched every-with-every.

This is the lesson that stops the tears. Almost every 'Grasshopper is doing something insane' moment - duplicated geometry, a count that exploded, lines connecting to the wrong things - traces back to how two inputs got matched.

Once you understand Graft, Flatten and Simplify, and the three matching rules that govern how components pair up their inputs, these mysteries turn into one-move fixes. This is the single most practical skill in the whole module.

Diagnose first: Param Viewer on BOTH inputs. Then reshape. Graft to separate, Flatten to merge, Simplify to tidy.

Graft, Flatten, Simplify: your three everyday moves

Three components reshape trees, and you will use them constantly. Learn what each does to the structure, not just its name.

Graft pushes every item onto its own new branch. A single list of 20 points becomes a tree of 20 branches, one point each. Why would you want that? Because it changes how the data matches downstream - grafting is how you say 'treat each of these separately, and pair each one against the whole of that other input'. It is the go-to move for making a list behave like a set of independent cases.

Flatten does the opposite: it collapses every branch back into one single list, discarding the path structure entirely. All items, one branch, in order. Flatten is the sledgehammer - wonderfully effective for forcing everything into one clean stream, and dangerous precisely because it throws away the grouping you may have needed. Reach for it deliberately, never reflexively.

Simplify is the gentle one: it removes redundant, shared levels from the paths without moving any item. If every branch is buried under a common prefix like {0;0;0;...}, Simplify strips the parts that don't distinguish anything, turning unreadable deep paths into clean {0}, {1} - while the data stays exactly where it was. It tidies labels, not contents. Together these three - split, merge, tidy - are the vocabulary of every tree fix you will make.

THREE MOVES THAT RESHAPE A TREE GRAFT every item -> own branch {0} a b c -> {0;0} a {0;1} b {0;2} c FLATTEN all items -> one branch {0} a b {1} c d -> {0} a b c d SIMPLIFY strip shared path prefixes {0;0;0} a {0;0;1} b -> {0} a {1} b Graft splits, Flatten merges, Simplify tidies the path names without moving any item.
Zoom
Three moves that reshape a tree. Graft splits every item onto its own branch; Flatten merges every branch into one list; Simplify strips shared, redundant path levels so labels read cleanly - without moving any item. Split, merge, tidy: the vocabulary of every tree fix.

Graft = split every item onto its own branch. Flatten = dump all into one list. Simplify = clean the path labels only.

Data matching: how components pair their inputs

Now the heart of it. When a component has two or more inputs of different lengths - say 3 points and 5 circles - it has to decide how to pair them. Grasshopper follows a data-matching rule, and knowing which rule is in play explains nearly every surprising result.

The default is longest-list: Grasshopper walks the longest input and reuses the last item of the shorter ones to keep up. Pair 3 planes with 5 radii and you get 5 circles - the last plane repeated to cover the extra radii. Usually sensible, occasionally surprising.

Shortest-list matching stops at the end of the shortest input: 3 planes and 5 radii give only 3 circles, and the two extra radii are simply dropped. You opt into this (via the Shortest List component or a component option) when you want strict, one-to-one pairing with no reused leftovers.

Cross reference is the dramatic one: it pairs every item of one input with every item of the other. 3 points crossed with 5 points produces 15 combinations - the full grid. This is enormously useful when you genuinely want all combinations (every column position against every row position to build a grid), and it is the usual culprit when a count explodes far beyond what you expected. If you asked for 20 and got 400, a cross reference - deliberate or accidental - almost certainly happened.

WHY 20 x 20 CAN BECOME 400 LINES A: [p0 p1 p2] B: [q0 q1 q2] LONGEST / DEFAULT p0-q0p1-q1p2-q2 3 pairs, in step SHORTEST stops at theshorter list leftovers dropped CROSS REFERENCE p0-q0 p0-q1 p0-q2 p1-q0 p1-q1 p1-q2 p2-q0 p2-q1 p2-q2 every-with-every = 3 x 3 = 9 Got far too many results? A tree probably met a list and matched every-with-every. Fix by grafting the OTHER input to align, or flattening to force one long list.
Zoom
How components pair unequal inputs. Longest-list (the default) reuses the last item to keep the streams in step; shortest-list stops at the shorter input and drops the leftovers; cross reference pairs every item with every item - which is how 3 x 3 becomes 9, and how an unintended tree-meets-list match turns 20 into 400.

'Why 400 lines instead of 20?' - the classic, explained

Let's solve the archetypal disaster properly, because understanding it once immunises you. You have 20 points on one wire and 20 points on another, and you feed both into a Line component expecting 20 lines - one connecting each pair. Instead you get 400. What happened?

One of your inputs is a tree and the other is a flat list - and when a tree meets a list, the component often matches the flat list against each branch of the tree, which multiplies. Twenty branches each matched against a 20-item list gives 20 x 20 = 400. Grasshopper didn't misbehave; it faithfully paired every branch with the whole other input. Your two inputs simply had mismatched structures.

The fix is to make the structures agree. If both should be simple parallel lists, Flatten both inputs so each is one 20-item list, and you'll get the 20 one-to-one lines you wanted. If you meant for the pairing to be per-branch, Graft the flat input so it, too, has one item per branch and the branches align one-to-one. The move is always the same diagnosis: open the Param Viewer on both inputs, compare their shapes, and use Graft or Flatten to bring them into alignment. The geometry was never the problem - the data structures were.

WHY 20 x 20 CAN BECOME 400 LINES A: [p0 p1 p2] B: [q0 q1 q2] LONGEST / DEFAULT p0-q0p1-q1p2-q2 3 pairs, in step SHORTEST stops at theshorter list leftovers dropped CROSS REFERENCE p0-q0 p0-q1 p0-q2 p1-q0 p1-q1 p1-q2 p2-q0 p2-q1 p2-q2 every-with-every = 3 x 3 = 9 Got far too many results? A tree probably met a list and matched every-with-every. Fix by grafting the OTHER input to align, or flattening to force one long list.
Zoom
How components pair unequal inputs. Longest-list (the default) reuses the last item to keep the streams in step; shortest-list stops at the shorter input and drops the leftovers; cross reference pairs every item with every item - which is how 3 x 3 becomes 9, and how an unintended tree-meets-list match turns 20 into 400.

400 = 20 x 20. A tree met a flat list and matched branch-by-list. Flatten both, or graft to align.

Trim Tree, Prune and matching with intent

A few more tools round out the kit. Trim Tree removes the last N levels of a path, merging the deepest branches back together - the surgical opposite of Graft when you've branched one level too far and want to fold it back without flattening everything. Think of it as 'undo one level of nesting' rather than the total collapse Flatten performs.

Prune Tree (and related tools like Clean Tree) remove empty branches or null items that quietly accumulate and cause off-by-one mismatches later - a good habit before a tricky match. And the Path Mapper is the power tool for those who need to rewrite path structure explicitly, remapping {A;B} to {B} or {A} with a rule; you won't need it often, but it's there when Graft and Flatten aren't precise enough.

The deeper point is to work with intent. Before wiring two things together, ask: what shape is each input, and what pairing do I actually want - one-to-one, one-to-many, or all-combinations? Then set the structures to make that happen: Flatten for one clean stream, Graft to separate cases, Simplify to keep paths readable, Trim to fold a level back. Most 'Grasshopper is fighting me' sessions are really just a mismatch between the pairing you imagined and the one the data structures dictated. Name the pairing you want, shape the trees to match, and the fight ends.

THREE MOVES THAT RESHAPE A TREE GRAFT every item -> own branch {0} a b c -> {0;0} a {0;1} b {0;2} c FLATTEN all items -> one branch {0} a b {1} c d -> {0} a b c d SIMPLIFY strip shared path prefixes {0;0;0} a {0;0;1} b -> {0} a {1} b Graft splits, Flatten merges, Simplify tidies the path names without moving any item.
Zoom
Three moves that reshape a tree. Graft splits every item onto its own branch; Flatten merges every branch into one list; Simplify strips shared, redundant path levels so labels read cleanly - without moving any item. Split, merge, tidy: the vocabulary of every tree fix.

A field guide: which move for which pairing

Let's turn all of this into a decision you can make in seconds at the canvas, because in practice the whole skill collapses to one question asked before you wire two things together: what pairing do I actually want?

One-to-one - each item of A with the matching item of B, same count out. Make both inputs the same shape: if both are flat lists of equal length, you're done (longest-list keeps them in step); if one is a tree, Flatten both or Graft both so their branch structures agree. This is the everyday case - 20 planes with 20 radii giving 20 circles.

One-to-many - each item of A combined with the whole of B. Graft A so each of its items sits alone on its own branch; each branch then matches against the entire list B. This is how you say 'for each attractor point, measure the distance to every grid point' - graft the attractors, leave the grid flat.

All-combinations - every item of A with every item of B, N times M results. Use a cross reference (or the grafting that induces one). This is a grid generator: every X coordinate against every Y coordinate. Expect and want the count to multiply here.

Carry a tiny pre-flight checklist: (1) Param Viewer on both inputs - list or tree, how long? (2) name the pairing I want in words; (3) reshape to make the structures deliver it; (4) Simplify to keep paths readable. Four beats, every time. Do this and the 'Grasshopper is fighting me' feeling essentially disappears - you'll have replaced surprise with a deliberate choice, which is exactly what separates someone who uses trees from someone who is used by them.

Components & rules you'll meet in this lesson

Graft

Puts every item onto its own new branch

Turns a list of N into a tree of N single-item branches. Used to make items match as independent cases.

Flatten

Collapses all branches into one flat list

Discards path structure entirely. Powerful and blunt - use deliberately, because it destroys grouping you might need.

Simplify

Removes redundant shared levels from paths

Tidies path labels without moving any item. Turns unreadable deep paths into clean {0}, {1}.

Trim Tree

Removes the last N levels of the path

Folds the deepest branches back together. The surgical 'undo one graft' rather than a full flatten.

Data matching (longest / shortest / cross reference)

The rules for pairing inputs of different length

Longest reuses the last item; shortest drops leftovers; cross reference pairs every-with-every. Explains almost every surprising count.

Hands-on workshop

Workshop — cause the 400-line explosion, then fix it

The best way to never fear this bug again is to create it on purpose, diagnose it with the Param Viewer, and fix it two different ways. You'll come away able to control matching with intent.

Rhino + Grasshopper. Param Viewer and Panel on both inputs. Series, Construct Point, Line, Graft, Flatten.

Given & goal
Goal: reproduce and fix a data-matching explosion
Inputs: Rhino + Grasshopper
Time: ~40 minutes
  1. 1Make two point lists: use two Series/Construct Point setups to place 5 points along X and 5 points along Y (both flat lists of 5).
  2. 2Wire both into a Line component and read the output count. With both flat and equal length you'll get 5 lines (longest-list, in step). Confirm in a Panel.
  3. 3Now Graft the X points and re-wire. Read the count - it jumps to 25, because each grafted X branch now matches against the whole 5-item Y list (a cross reference in disguise). Param-View both inputs and see the structural mismatch.
  4. 4Fix it two ways and compare: (a) Flatten both inputs to get back the 5 one-to-one lines; (b) Graft the other input too so the branches align one-to-one. Note which fix preserves the grouping you'd want for a grid versus a fan.
  5. 5Write the diagnosis in one sentence, in the form: 'Input A was a tree of 5 branches, input B a flat list of 5, so the component matched branch-by-list = 25; flattening both restored one-to-one.'

You’ll walk away with
One definition that demonstrates the explosion and both fixes side by side, plus your one-sentence diagnosis. Being able to _state_ the mismatch is the real deliverable - it's the sentence you'll reuse on every future bug.

The worked example

Three altitudes on the same idea

Read the band that fits you — or all three.

For the architectDesign intent, geometry & delivery

This is the skill that makes big facades behave. Panelising a tower means constantly deciding whether a shading rule applies per-panel, per-floor, or across the whole surface - which is entirely a matching-and-grafting decision. Master Graft, Flatten and cross reference and you can direct exactly how a rule propagates through thousands of elements instead of fighting mysterious multiplications.

For the interior designerParametric interiors, pattern & furniture

When a pattern suddenly repeats too many times, this lesson is the cure. A tiling that should map one motif per cell but instead stamps every motif in every cell is a cross-reference match - and a Flatten or Graft fixes it in one move. Controlling how your data pairs up is what keeps a decorative system producing the count and arrangement you actually drew.

For the studentSkills, portfolio & jobs

Learn to read the Param Viewer on _both_ inputs before you panic - that single habit is worth more than memorising components. Almost every 'my definition is broken' moment in your first year is a matching mismatch. Being the person who calmly says 'one input is a tree, the other's a list - flatten both' will make you look far more experienced than you are.

Misconception check

When I get way too many results, some component must be bugged or duplicating my geometry.

Almost never. Grasshopper is deterministic and its components are heavily used and reliable - an explosion from 20 to 400 is essentially always a data-matching outcome, not a bug. What happened is that two inputs with mismatched structures got paired every-with-every (a cross reference) or a tree got matched branch-by-branch against a flat list. The multiplication is the software faithfully following its matching rules on the structures you gave it. The fix is never to hunt for a broken node; it's to open the Param Viewer on each input, see that their shapes disagree, and Graft or Flatten to align them. Once you internalise that surprising counts are structure problems, you stop blaming the tool and start reading the data.
Try it

Do it yourself

Predict the count before you check.

  1. 13 planes and 5 radii into a Circle component with default matching - how many circles, and why?
  2. 2Same inputs with shortest-list matching - how many now, and what happened to the extras?
  3. 3In one sentence, what does Graft do to a flat list of 12 items?
  4. 4You got 400 lines from two 20-item inputs. What's the most likely structural cause?
  5. 5Which reshaping component tidies path labels without moving any data?
Take this with you

The one line to carry out

Surprising counts are structure problems: Graft splits items onto their own branches, Flatten merges everything into one list, and the matching rule - longest, shortest or cross reference - decides how inputs pair - so diagnose with the Param Viewer and reshape the trees to match the pairing you actually want.
Take it further
References & further reading

Peer-reviewed journals & authoritative standards

  1. 01Rhino Developer — Grasshopper Data TreesRobert McNeel & Associates, 2026.
  2. 02Mode Lab — The Grasshopper Primer (Third Edition)grasshopperprimer.com (free online edition), 2020.
  3. 03Grasshopper Docs — component referencegrasshopperdocs.com, 2026.
  4. 04Rutten, D. — The Guide to Grasshopper (community)grasshopper3d.com, 2026.
Related lessons
Recap
Graft pushes every item onto its own branch, Flatten collapses everything into one list, Simplify tidies path labels, and Trim Tree folds the deepest level back. Components pair unequal inputs by longest-list (reuse the last), shortest-list (drop leftovers) or cross reference (every-with-every). The classic '400 instead of 20' is a tree meeting a flat list; the cure is to align their structures with Graft or Flatten.
Carry forward →

You can now read and reshape trees fluently - which means your definitions are about to get bigger and more ambitious. The final lesson of this module is about keeping that growing complexity legible: groups, scribbles, clusters, colour, naming, and a real debugging strategy so large definitions stay understandable.

A

The author

Amogh N P

Architect, interior designer, and creative polymath. Studio Matrx began in his notebooks — his vision of design made honest, useful, and open to everyone. Its Academy is written and taught in his memory, and free, forever.

More about Amogh →