Aixle reference
Generated by npm run docs from the builtin signatures. Do not edit by hand; see docs/language.md for the language itself.
Arguments are positional or by name (cylinder(r=1, h=2)); name=value in a signature is a default. shape is a 3D shape, shape2 a 2D profile, curve a bezier() or curve(). Angles are degrees. a | f(x) means f(a, x).
3D primitives
box
A box centred on the origin. One size makes a cube. round rounds every edge.
box(w, h=?, d=?, round=0) -> shape
w: width along xh: height along y (defaults to w)d: depth along z (defaults to w)round: edge radius
sphere
A sphere of radius r.
sphere(r) -> shape
cylinder
A cylinder standing along y, centred on the origin.
cylinder(r, h, round=0) -> shape
h: heightround: edge radius
cone
A cone or frustum along y: radius r1 at the bottom, r2 at the top (0 for a point).
cone(r1, r2, h) -> shape
capsule
A capsule (a cylinder with hemispherical ends) along y; h is the total height.
capsule(r, h) -> shape
torus
A ring lying flat around y: R to the tube's centre, r the tube's radius.
torus(R, r) -> shape
ellipsoid
An ellipsoid with radii rx, ry, rz.
ellipsoid(rx, ry, rz) -> shape
octahedron
An octahedron with its points s from the centre.
octahedron(s) -> shape
prism
A regular polygon (sides, circumradius r) extruded to height h along y, one flat facing +z.
prism(sides, r, h) -> shape
empty
Nothing. The starting value for building up a shape in a loop.
empty() -> shape
2D profiles
circle
A circle of radius r in the x/y plane.
circle(r) -> shape2
rect
A rectangle w by h, centred; round rounds its corners.
rect(w, h=?, round=0) -> shape2
h: defaults to w
ellipse
An ellipse with radii rx, ry.
ellipse(rx, ry) -> shape2
ngon
A regular polygon with sides sides and circumradius r.
ngon(sides, r) -> shape2
star
A star with points points, outer radius r1 and inner radius r2.
star(points, r1, r2) -> shape2
polygon
A polygon from x, y pairs, either as numbers or one list: polygon(0,0, 2,0, 1,1.5).
polygon(points) -> shape2
polygon(coords...) -> shape2
text
Lettering as a 2D profile from a single-stroke font (A-Z, a-z, 0-9, punctuation), laid out from x = 0 on the baseline y = 0; face="serif" adds slab serifs. size is the cap height, weight the stroke width (the profile's box reaches half the weight past the strokes, so the lettering stands size plus weight tall, and a line of n characters is about 0.8 × n × size wide, 0.93 with serifs); align is "left", "center" or "right". Extrude it for a sign, subtract it for engraving. check warns when the weight is under a grid cell.
text(text, size=1, weight=0.15, align="left", spacing=0, arc=0, face="sans") -> shape2
size: cap heightweight: stroke widthspacing: extra gap between lettersarc: bend onto a circle of this radius, centred on the origin: positive reads over the top, negative under the bottomface: "sans" or "serif" (slab serifs on the same letters, set a little wider)
2D to 3D
extrude
Thicken a profile to height h, centred on its plane. axis="y" (default): the profile lies flat, its x along world x and its y along world -z, thickened up. axis="z": the profile stands facing +z, its x along x and its y along y. axis="x": it stands facing +x, its x along world -z and its y along y.
extrude(profile, h, axis="y") -> shape
revolve
Spin a profile around y; its x is the radius (draw it on x >= 0), pushed out by offset. angle below 360 sweeps only that far, from +z towards +x, with flat ends: an arch, a cutaway.
revolve(profile, offset=0, angle=360) -> shape
angle: degrees swept
Paths
tube
A round tube of radius r along a path of x, y, z points, joins rounded and the ends hemispheres unless cap="flat". smooth > 0 curves the path through the points (8 is plenty); taper is the radius at the end relative to the start.
tube(r, points, smooth=0, taper=1, cap="round") -> shape
tube(r, curve, taper=1, cap="round") -> shape
points: a flat list [x,y,z, x,y,z, ...]taper: end radius / start radiuscap: "round" (hemispheres, reaching r past each end) or "flat" (cut at the ends)curve: a bezier() or curve()cap: "round" or "flat"
sweep
A 2D profile carried along a path of x, y, z points: its x runs across the path, its y up. smooth curves the path; twist turns the profile by that many degrees over the whole path; taper scales it to that factor by the end.
sweep(profile, points, smooth=0, twist=0, taper=1) -> shape
sweep(profile, curve, twist=0, taper=1) -> shape
points: a flat list [x,y,z, x,y,z, ...]twist: degrees over the pathtaper: end scalecurve: a bezier() or curve()twist: degrees over the curve
bezier
An exact curve from cubic Bezier control points: an anchor, then two handles and an anchor for each piece (4, 7, 10, ... points). A tube or sweep along it is the true offset of the curve, with no facets at any grid, and costs about as much per piece as a spline's.
bezier(points) -> curve
points: a flat list [x,y,z, x,y,z, ...]
curve
An exact smooth curve through the points, the same shape spline() draws, for tube() and sweep(): the surface follows the true curve rather than a polyline through it.
curve(points) -> curve
points: a flat list [x,y,z, x,y,z, ...]
helix
A path list for a helix of radius r around y, for tube() or sweep(): it starts at (r, 0, 0) and rises from y = 0 to y = h over turns turns.
helix(r, h, turns, per_turn=16) -> list
per_turn: points per turn
spline
A smooth path through the points, subdivided until no piece turns more than degrees: a curve that shows no faceting in a tube or sweep, however tight.
spline(points, degrees=3) -> list
points: a flat list [x,y,z, x,y,z, ...]degrees: largest turn between pieces
arc
A path list for an arc of radius r on the ground plane from from to to degrees (0 is +z, 90 is +x).
arc(r, from=0, to=90, segments=16) -> list
loft
A solid h tall that is profile a at the bottom and profile b at the top, blending between them; centred on y = 0 like extrude (from -h/2 to h/2), each profile laid flat with its y along -z.
loft(a, b, h) -> shape
Booleans
union
Everything in any of the shapes. k > 0 blends the joins smoothly over about k units. Same as a + b.
union(a, shapes..., k=0) -> shape
union(a, profiles..., k=0) -> shape2
k: blend radius
difference
a with b cut away. Same as a - b. The cut surface keeps a's material.
difference(a, b, k=0) -> shape
difference(a, b, k=0) -> shape2
k: blend radius
intersect
Only where a and b overlap. Same as a & b.
intersect(a, b, k=0) -> shape
intersect(a, b, k=0) -> shape2
k: blend radius
Transforms
move
Translate by x, y, z (a profile takes x, y).
move(shape, x=0, y=0, z=0) -> shape
move(profile, x=0, y=0) -> shape2
rotate
Rotate by degrees about x, then y, then z, around the origin, right-handed: a positive x angle turns +y towards +z, a positive y angle turns +z towards +x, a positive z angle turns +x towards +y. rotate(shape, y=45) is the usual call. A profile takes one angle, counter-clockwise.
rotate(shape, x=0, y=0, z=0) -> shape
rotate(profile, angle) -> shape2
scale
Scale about the origin: one factor for all axes, or one per axis.
scale(shape, x, y=?, z=?) -> shape
scale(profile, x, y=?) -> shape2
y: defaults to xz: defaults to x
mirror
The shape plus its reflection across the plane perpendicular to axis through the origin: model half, mirror the rest.
mirror(shape, axis) -> shape
mirror(profile, axis) -> shape2
flip
Reflect across the plane perpendicular to axis (no copy kept).
flip(shape, axis) -> shape
flip(profile, axis) -> shape2
ground
Move the shape so the lowest point of its surface rests on y = 0 (the surface, found by rays from below, not the bounding box, which a blend or a cut can leave loose).
ground(shape) -> shape
center
Move the shape so its bounding box is centred on the origin; axes picks which of x, y, z.
center(shape, axes="xyz") -> shape
Modifiers
round
Round every edge by growing the surface outward by r (on a number: round to the nearest integer).
round(shape, r) -> shape
round(profile, r) -> shape2
round(x) -> number
offset
Grow (r > 0) or shrink (r < 0) the surface by r.
offset(shape, r) -> shape
offset(profile, r) -> shape2
hollow
Hollow for printing: a shell wall thick with a drain hole of radius r (default the wall) cut through it at the drain point, usually on the bottom, so the void is open and resin or support can escape. hollow(cup, 0.1, 0, 0, 0) drains a model standing on y = 0 through its floor.
hollow(shape, wall, x, y, z, r=?) -> shape
x: the drain pointr: drain radius
shell
Hollow the shape leaving a wall t thick inside its surface. Subtract something to open it up. check warns when t is under a grid cell.
shell(shape, t) -> shape
shell(profile, t) -> shape2
t: wall thickness
twist
Twist around y by degrees for every unit of height.
twist(shape, degrees) -> shape
bend
Bend about z: the shape's x axis becomes an arc of a circle of radius 57.3 / degrees centred above the origin at (0, R), curving up by degrees for every unit along x (negative bends down). A point at height y rides at radius R - y. Exact, so the box check prints is the bent shape's.
bend(shape, degrees) -> shape
wrap
Wrap around y: the shape's x axis goes round a cylinder of radius r, x = 0 landing on +z and reading left to right from the front; depth z rides at radius r + z. Standing lettering (extrude(text(...), h, "z")) wrapped this way is a label round a jar or a name round a rim: wrap(letters, 1.3) | move(0, y, 0).
wrap(shape, r) -> shape
r: the cylinder's radius
displace
Roughen the surface with noise: in and out by up to amp, features about size across.
displace(shape, amp, size=1, seed=0) -> shape
Repetition
array
count copies stepping by dx, dy, dz from the original.
array(shape, count, dx=0, dy=0, dz=0) -> shape
grid
nx by nz copies on the ground plane, dx and dz apart.
grid(shape, nx, nz, dx, dz=?) -> shape
dz: defaults to dx
ring
count copies evenly around axis (default y), each first pushed out to radius along +x.
ring(shape, count, radius=0, axis="y") -> shape
Assembly
place
Copies of a shape at each x, y, z, yaw (degrees about y) in a flat list, optionally x, y, z, yaw, scale with fields=5. Rendered as a union; exported once with a node per copy.
place(shape, placements, fields=4) -> shape
placements: [x,y,z,yaw, x,y,z,yaw, ...]fields: 4 for x,y,z,yaw or 5 to add a scale
Queries
height
The y of the highest surface of the shape above the point (x, z): where to set something down on a blended or roughened surface. An error when nothing is there.
height(shape, x, z) -> number
top
The highest y of a shape's bounds (a bound, not necessarily a surface point); bottom(), left()... are the other faces of the box.
top(shape) -> number
bottom
The lowest y of a shape's bounds.
bottom(shape) -> number
width
The size of a shape's bounds along x.
width(shape) -> number
depth
The size of a shape's bounds along z.
depth(shape) -> number
tall
The size of a shape's bounds along y.
tall(shape) -> number
surface
The point on a shape's surface nearest to (x, y, z), as [x, y, z]: where a rod, a foot or a decal should meet a curved body. Found by sliding along the field, so it is exact on primitives and close on blends and warps.
surface(shape, x, y, z) -> list
angle
The current pose's angles for a joint, as [x, y, z] degrees (all zero at rest, or for a joint the pose does not set): what a member between two moving bodies (a hydraulic cylinder, a strut) needs to work out its end points with sin and cos. Nested joints' angles are relative to their parent.
angle(joint) -> list
joint: the joint's name
Materials
paint
Give the whole shape a material: a preset name, a colour ("#rrggbb" or a name), or material(...). Paint parts before combining them to keep several materials.
paint(shape, material) -> shape
decal
Paint only the part of the surface inside region, adding no geometry: a pupil on an eye (decal(eye, sphere(0.1) | move(...), "black")), a mouth line along a thin tube, a label on a jar. The region is any shape; its inside picks the material.
decal(shape, region, material) -> shape
region: the part of the surface inside this shape gets the material
material
A custom material, from a colour or from a preset with some of its fields changed: material("granite", scale=0.3). Patterns: solid, checker, stripes, wood, marble, noise, speckle, brick, tiles, dots. scale is the feature size in units; metal 0..1; rough 0..1; transmit 0..1 for glass; glow 0..2 for a flame or a lamp. Patterns are laid out in the frame the part is painted in, along axis (default y): stripes are bands stacked along it, wood rings and brick courses go round it, tiles and checks lie in the plane across it (floor tiles with the default y). Paint before moving the part, or set axis="x" for stripes running the other way.
material(color, pattern="", color2="", scale=?, metal=?, rough=?, seed=?, transmit=?, axis="", glow=?) -> material
color: a colour, or a preset name to start fromcolor2: second colour for two-tone patternsscale: feature size in unitstransmit: 0 opaque .. 1 clear glass (beauty render only)axis: the pattern's axis: stripes stack along it, grain runs along itglow: light the surface gives off, 0..2 (unshadowed, for flames and lamps)
rgb
A colour string from red, green, blue in 0..255.
rgb(r, g, b) -> string
hsl
A colour string from hue in degrees, saturation and lightness in 0..1.
hsl(h, s, l) -> string
Numbers
range
A list of integers: range(n) is 0..n-1; range(a, b) is a..b-1; range(a, b, step).
range(a, b=?, step=1) -> list
len
Length of a list.
len(list) -> number
sin
Sine of an angle in degrees.
sin(degrees) -> number
cos
Cosine of an angle in degrees.
cos(degrees) -> number
tan
Tangent of an angle in degrees.
tan(degrees) -> number
asin
Arcsine, in degrees.
asin(x) -> number
acos
Arccosine, in degrees.
acos(x) -> number
atan
Arctangent of y/x, in degrees; atan(y, x) takes the quadrant into account.
atan(y, x=?) -> number
sqrt
Square root.
sqrt(x) -> number
abs
Absolute value.
abs(x) -> number
floor
Round down.
floor(x) -> number
ceil
Round up.
ceil(x) -> number
min
Smallest of the numbers.
min(a, more...) -> number
max
Largest of the numbers.
max(a, more...) -> number
pow
x to the power y (also x ^ y).
pow(x, y) -> number
clamp
x limited to lo..hi.
clamp(x, lo, hi) -> number
lerp
a + (b - a) * t.
lerp(a, b, t) -> number
mod
a modulo b, always in 0..b (also a % b).
mod(a, b) -> number
rand
A repeatable pseudo-random number in 0..1 for an integer seed (use the loop index).
rand(seed) -> number
Anchors
anchor
Name a point on a shape, in the shape's own frame: anchor(post, "top", 0, 1, 0). Every move, rotate, scale, warp and posed joint above it carries the point along, so at() reads it wherever the part ends up, and a union keeps every part's anchors (the first part wins a repeated name).
anchor(shape, name, x, y, z) -> shape
at
The world point of a shape's anchor as [x, y, z]: one named with anchor(), or a free one every shape has from its box: centre, top, bottom, front, back, left, right (the box's face centres). In a pose, a point inside a joint is where the pose put it.
at(shape, name) -> list
attach
Move part so its anchor lands on the target's anchor: attach(arm, "root", post, "top") is a move with no numbers. Either anchor may be a named one or a free one (top, bottom, ...). Rotate the part first, then attach it; the anchors turn with it.
attach(part, anchor, target, targetAnchor) -> shape
anchor: the part's anchortargetAnchor: the target's anchor
Files
import
An existing mesh as a shape: import("part.obj") or a .glb, relative to the program's folder. The mesh is sampled into a distance field over a grid of resolution cells on its longest side (default 96), so it can be cut, blended, hollowed and painted like any shape; size= scales its longest side to that many units. Closed meshes work; an open mesh has no inside and the report says so.
import(path, size=?, resolution=96) -> shape
Poses and animation
joint
Make a part turn about a pivot under poses: joint(part, "elbow", x, y, z) with the pivot in world units, declared once the part is in place; combine it with + and paint afterwards, not move. Nested joints turn with their parent. With axis=[x, y, z] the joint turns about that one direction through the pivot (a raked steering column) and a pose gives it a single angle. Exports get a node per joint and glTF animations from animation().
joint(part, name, x, y, z) -> shape
joint(part, name, x, y, z, axis=[ax, ay, az]) -> shape
pose
Name a set of joint angles: pose("wave", shoulder=[0, 0, 70], elbow=[0, 0, 40]), degrees about x, y, z per joint, or one number for a joint declared with axis=. Joints not named stay at rest. Every pose is drawn on poses.png; set pose wave makes the sheet and exports show it.
pose(name, joint=[x, y, z], ...) -> string
animation
A glTF animation from poses: animation("wave", ["rest", "wave", "rest"], seconds=1.2); keyframes are spaced evenly and interpolate linearly. A rest pose is any pose with no angles, or the name "rest". Each animation gets a frame strip anim_<name>.png.
animation(name, poses, seconds=1, loop=1) -> string
Material presets
Use any of these by name in paint(). A colour name ("red") or hex ("#c8342a") also works.
| Name | Pattern | Feature size | Colours | Notes |
|---|---|---|---|---|
| clay | solid | #c9b8a6 | rough 0.7 | |
| white | solid | #f2f2f0 | rough 0.6 | |
| black | solid | #1a1a1c | rough 0.6 | |
| gray | solid | #8a8a8a | rough 0.6 | |
| red | solid | #c8342a | rough 0.6 | |
| green | solid | #3f9a45 | rough 0.6 | |
| blue | solid | #2f66c4 | rough 0.6 | |
| yellow | solid | #e8c53a | rough 0.6 | |
| orange | solid | #e07a2a | rough 0.6 | |
| purple | solid | #7a4bb0 | rough 0.6 | |
| pink | solid | #e58cb8 | rough 0.6 | |
| brown | solid | #7a4d2b | rough 0.6 | |
| teal | solid | #2a9b8f | rough 0.6 | |
| cream | solid | #f0e6c8 | rough 0.6 | |
| navy | solid | #213a6b | rough 0.6 | |
| tan | solid | #c9a97a | rough 0.6 | |
| olive | solid | #7a7a2e | rough 0.6 | |
| maroon | solid | #6e1f2a | rough 0.6 | |
| sky | solid | #8cc4ea | rough 0.6 | |
| lime | solid | #9ad13a | rough 0.6 | |
| charcoal | solid | #3a3a3e | rough 0.6 | |
| ivory | solid | #f4f0e2 | rough 0.6 | |
| coral | solid | #e8735a | rough 0.6 | |
| gold | solid | #e2b13c | metal, rough 0.3 | |
| silver | solid | #d4d6da | metal, rough 0.25 | |
| copper | solid | #c67a4a | metal, rough 0.35 | |
| bronze | solid | #a5772f | metal, rough 0.4 | |
| steel | solid | #8e949c | metal, rough 0.45 | |
| iron | solid | #5c5e62 | metal, rough 0.6 | |
| brass | solid | #c9a54a | metal, rough 0.35 | |
| chrome | solid | #e8eaee | metal, rough 0.1 | |
| wood | wood | 0.25 units | #b07d4a / #7a4f2a | rough 0.7 |
| oak | wood | 0.3 units | #c69a63 / #8f6539 | rough 0.7 |
| walnut | wood | 0.22 units | #6b4327 / #3e2414 | rough 0.6 |
| pine | wood | 0.35 units | #e0c08a / #b48c55 | rough 0.75 |
| ebony | wood | 0.2 units | #2c2420 / #171210 | rough 0.4 |
| marble | marble | 1.2 units | #ececea / #9a9aa0 | rough 0.3 |
| granite | speckle | 0.05 units | #8e8a86 / #3c3a38 | rough 0.5 |
| stone | noise | 0.5 units | #9a9590 / #6e6a66 | rough 0.9 |
| sandstone | noise | 0.6 units | #d9b98a / #b8945f | rough 0.9 |
| concrete | speckle | 0.03 units | #a9a8a4 / #8c8b87 | rough 0.95 |
| brick | brick | 0.5 units | #b0503a / #d8cbb8 | rough 0.9 |
| tiles | tiles | 0.5 units | #e8e4dc / #7a7670 | rough 0.3 |
| checker | checker | 0.5 units | #f0f0ec / #2a2a2e | rough 0.5 |
| stripes | stripes | 0.25 units | #e8e4dc / #c8342a | rough 0.6 |
| dots | dots | 0.5 units | #f4f0e2 / #2f66c4 | rough 0.6 |
| grass | noise | 0.3 units | #5a9a3a / #3e7228 | rough 0.95 |
| dirt | noise | 0.2 units | #6e4e32 / #4d341f | rough 0.95 |
| sand | speckle | 0.04 units | #e2cf9a / #c8b27a | rough 0.95 |
| water | noise | 0.8 units | #3a8ad8 / #6fb4ee | rough 0.1 |
| glass | solid | #dff0f6 | glass (transmit 0.9), rough 0.05 | |
| amber | solid | #e0a030 | glass (transmit 0.7), rough 0.1 | |
| emerald | solid | #40b070 | glass (transmit 0.7), rough 0.08 | |
| leather | speckle | 0.06 units | #6b3f24 / #4a2a16 | rough 0.7 |
| rubber | solid | #2a2a2c | rough 0.95 | |
| plastic | solid | #e8e8e8 | rough 0.35 | |
| porcelain | solid | #f6f4ee | rough 0.2 | |
| snow | noise | 0.3 units | #f8f9fb / #dfe6ef | rough 0.9 |
| lava | marble | 0.8 units | #f06a1a / #3a1a10 | rough 0.6 |
A pattern's feature size is in model units: a wood ring every 0.25 units suits a table leg, not a 20-unit floor. Use material(color, pattern, color2, scale=) with the two colours from this table for the same look at another size.
Patterns
For material(color, pattern, ...): solid, checker, stripes, wood, marble, noise, speckle, brick, tiles, dots.