Components, parameters & pins
A design is a set of component definitions, one of which is the root — the design’s top-level component, and the one the file opens at. Everything you draw lands in the body of some definition, so a chip authored as a single flat drawing is one definition whose body holds all of its channels, points and regions.
Export fabricates whichever component is open, not the root, so a subassembly opened on its own exports as a device in its own right. See Export for the dialog and what its files are named.
Component definitions and placements
A component definition is a template. Placing it inside another definition’s body creates a child that refers back to it, so editing the definition updates every placement of it at once.
Two placements of one definition are independent children. Position (pos), rotation (rot)
and layer belong to the placement; the shape belongs to the definition. The viewport marks a
placement’s position with an amber diamond while you hover or select it. Each placement also
sets its own args: one value for each parameter of the definition. An argument you leave
unset falls back to the parameter’s default.
Composition runs one way: a component cannot place itself, directly or through a chain of others. A placement that would close such a loop is refused at the moment you make it.
Deleting a definition is refused while it is the root, and while another definition places it.
Parameters
A parameter is an input to the definition — what someone placing it can set. It has a name, a type, and usually a default.
There are four types:
- Number — a plain real value; where one is a length it is micrometres, and where one is an angle it is radians.
- Int — a whole number, for counts such as the turns in a meander.
- Vec2 — a pair, read with
.xand.y. - Bool — true or false.
A parameter with no default reads (required), and every placement of the definition must supply an argument for it.
Computed values
A computed value is a name bound to an expression over the component’s parameters and its other computed values. Use one to state a relationship once — a chamber’s area from its width and length, a meander’s total length from its pitch and turn count — instead of repeating the arithmetic at every child that needs it.
Its type follows from the expression rather than being declared, so you never set it.
The expression language
An expression computes a value and does nothing else. There is nothing to assign, no loops, and no functions of your own.
Numbers carry units. 250um, 0.5mm, 2cm, 800nm, 45deg and 1.2rad are all
literals; the suffix folds to micrometres or radians, so 0.5mm and 500um are the same
value. pi, tau and e are constants.
Operators are arithmetic (+, -, *, /, %), comparison (==, !=, <, <=,
>, >=) and boolean (&&, ||, !). Division always produces a Number, so 3 / 2 is
1.5.
Conditionals are written if cond then a else b, and both arms must have the same type.
Functions are a fixed set: vec2, min, max, abs, clamp, sqrt, pow, floor,
ceil, round, sin, cos, tan, atan2. A name counts as a function only when a (
follows it, so a parameter may be called min without shadowing anything.
An expression sees the parameters and computed values of the component it is written in, and nothing else — not a child, not a sibling, not the component that placed this one. Values travel downward, through arguments.
An expression that does not parse never takes effect. One that parses but does not type-check leaves the component unresolvable until you fix it. See Inspector for where the reason is shown.
Pins
A pin is a connection point a component exposes to whoever places it, and pins are the only part of it another component can attach to. A channel in the parent attaches to a pin; everything behind the pin stays inside the definition and changes with it.
A pin is made by exposing a terminal — a point, or a pin of a component you placed. Exposing a point in the body publishes that point; exposing a placed component’s pin forwards that pin outward under the same name. Every terminal draws as an amber circle, a point and a placed component’s pin alike, and an exposed one takes a sky-blue ring around that circle. Unexpose removes one. See Inspector for the controls.
A pin’s name is separate from the label of the point behind it. The two start equal and the inspector shows one name while they are, so they diverge only when you rename the pin deliberately. Renaming or deleting a pin is refused while another component refers to it.
World ports
A terminal marked world port is open to the outside: an inlet or an outlet. The viewport badges one with a burst of short rays around its circle. Every other terminal is an interior connection, sealed inside the assembled chip.
The mark sits on the terminal, not on a pin, so a point does not have to be exposed to be a port — select it and tick world port in its detail. Beside the tick you choose which face of the chip it comes out of, down by default. The port takes the terminal’s own name, so renaming the point renames the port.
The same tick is there on a terminal inside a component you placed, reached from the Body tree, which is how you open a port on a library part without editing the part.
The built-in components mark nothing. Whether a given inlet reaches the outside is decided by the design that places them, so it is a setting you make on your own top-level component.
Connections between components
Two pins never merge into one point. To join two placed components you draw a channel between their pins, however short.
A pin named by two or more channel ends is a shared junction, so you make a fan-in by pointing several channel ends at one pin.
Built-in components
Three components ship with the app:
- Serpentine — a square meander for mixing or delay, with
inletandoutletpins and a computedlength. - FlowFocusing — a droplet-forming junction:
dispersed,sheath_a,sheath_bandoutletarms meeting at a narrowed orifice. - Chamber — a rounded reservoir whose
corner_radiustakes it from a sharp rectangle through a stadium to a circle, withinletandoutlettaps on its wall.
Any .exw file that declares a library identity and sits beside the design you opened is a
library, and its components can be placed like any other. A library component is
read-only: you set its arguments at each placement as for a component you authored, but you
cannot edit the definition. See
Components & Libraries for what opening one shows.
See also
- Inspector — the Params, Computed, Pins and Body tabs that edit everything on this page.
- Channels & points — the terminals a pin is exposed from.
- Components & Libraries — the browser the built-ins and library components are placed from.