Key concepts
Three ideas carry the whole app: what flows on the wires, how nodes connect, and how one value resolves differently for every element.
Everything else in DNA is a variation on these three.
1. Collections
Almost everything that travels between nodes is a collection: a spreadsheet of things. Each row is one item, and each column is an attribute those items carry.
| @P (position) | @Cd (colour) | @pscale (size) |
|---|---|---|
| 0, 0, 0 | red | 1.0 |
| 1, 0, 0 | green | 0.5 |
Points, mesh vertices, shape outlines and plain rows of numbers all share this row-and-column shape. Every node adds rows, removes rows, or edits a column. Open the spreadsheet view on any node to see what is flowing through it.
Attribute names take an @ prefix when you reference them. @P is position, @Cd is colour, @id is each row's unique number.
Read more in Collections.
2. Connections
Drag a wire from one node's output into another node's input. The downstream node reads the incoming collection and passes a new one out.
A Points node takes geometry in and sends points out.
A colour node reads the rows, writes the
@Cdcolumn, and passes the same rows along.A merge node stacks the rows of two collections into one.
Because every collection is the same underlying table, steps mix freely: scatter points on a shape, colour them from a table, then turn them into curves. Mismatched inputs convert automatically where a conversion exists.
When a node misbehaves, check the kind of its input, whether points, geometry, curves or a table. Hover a socket to read the kind on the wire, or open the spreadsheet.
3. Context
A node does not hold a single value. Where it feeds many elements (many points, many copies, many loop passes), a value can resolve differently for each one.
Scatter 200 points with a Points node, add an The Expression language node, and write one rule:
float t = float(@ptnum) / float(@numpt - 1);
@Cd = {t, t, t, 1.0};
Each point reads its own ordinal, 0 through 199, divides by the count, and gets a brightness from 0 to 1. That is a smooth ramp across 200 points from two lines, with no loop written. You describe what happens to one element, and it is applied to every row.
@ptnum and @numpt are the ordinal and the count. They are worth learning first because they come from the loop rather than from a column, so they are available on any collection whatever attributes it carries.
Copies and loops work the same way. Iterator writes an @index column onto every copy, and For Start gives each pass its number on an output pin called $index, which you wire wherever it is needed. You author the relationship once, and every element, copy or pass fills in its own number.
A value varies per element only if it is a per-element attribute. A plain number typed into a parameter is one value shared by everything. To get variety, read an attribute (@ptnum, @id, @index) or feed a list instead of a single value.
Read more in Context: per-element values.