Cheat Sheet
Print this out and keep it handy. Probably.
Primitives
3D
| Function | Arguments | Example |
|---|---|---|
box |
w h d | box 80 60 10 |
cylinder |
r h | cylinder 5 10 |
sphere |
r | sphere 10 |
cone |
r1 r2 h | cone 10 0 20 |
torus |
r1 r2 | torus 20 5 |
wedge |
dx dy dz ltx | wedge 20 10 15 5 |
Position convention:
box/cylinder/sphere/cone/torusare centered at the origin.extrude his bottom-aligned (z=0..h). When mixing both, use| floor/translate/center:(true,true,false)to align them.
2D
| Function | Arguments | Example |
|---|---|---|
rect |
w h | rect 50 30 |
circle |
r | circle 10 |
ellipse |
rx ry | ellipse 10 5 |
polygon |
n r | polygon 6 10 |
polyline |
points | polyline [(0,0), (10,0), (5,10)] |
text |
content size | text "ABC" 10 |
sketch |
[segments] | sketch [(5,0), arc (5,0) (0,-5) (-5,0), (0,7), (5,0)] |
sketch segments: tuple = line, arc start through end = 3-point arc, arc start end center:(cx,cy) = center arc, arc start end radius:radius = radius arc, bezier [control points] = Bezier (start point is implicit from the preceding segment; list contains control points and the end point), spline [through points] = spline (likewise). First element is the start point; auto-close.
Paths
| Function | Arguments | Example |
|---|---|---|
line |
start end | line (0,0,0) (10,0,10) |
arc |
start through end / start end center:(cx,cy) / start end radius:radius | arc (0,0,0) (5,5,0) (10,0,0), arc (0,0) (0,$r) center:(0,0), arc (0,0) (5,3) radius:2 |
bezier |
points | bezier [(0,0,0), (5,10,0), (10,0,0)] |
helix |
pitch h r | helix 5 30 10 |
spline |
points | spline [(0,0,0), (10,5,5), (20,0,10)] |
wire |
[segments] | wire [(0,0), (10,0), arc (10,0) (15,5) radius:5] |
wire is the open version of sketch (no auto-close). Joins multiple segments into an open wire. Supports both 2D and 3D coordinates. Ideal as the spine (upstream) of sweep. Its type is Wire (a curve): it never becomes a face even when closed, so extrude/cut/2D booleans reject it; offset d turns it into a Face of width 2|d|. sketch, rect and the other 2D primitives are Faces:
wire [(0,0), (10,0), arc (10,0) (15,5) radius:5] | sweep (circle 5)
Like sketch, wire works with workplane to draw on any plane:
workplane XZ | wire [(0,0),(10,0),(10,10),(0,10),(0,0)] | sweep (circle 2)
Pipe Operations
Modifiers
| Operation | Description | Example |
|---|---|---|
fillet r |
Round edges | fillet 2 |
chamfer r |
Chamfer edges | chamfer 1 |
shell t |
Hollow out | faces >Z | shell 2 |
offset d |
Face: scale the outline (+out, -in; a face with holes will not). Wire: make a band (open) / ring (closed) of width 2|d|, as a Face |
rect 80 60 | offset -10 |
offset d cap:"square" |
End an open wire square rather than rounded (default "round") |
wire [(0,0),(40,0),(40,30)] | offset 2 cap:"square" |
offset d join:"miter" |
Meet corners at a point rather than an arc (default "round", also "tangent") |
offset 2 join:"miter" |
A
wireof one straight segment (two points) cannot be offset. It fails withoffsetWire2D: operation failed. Add a midpoint to make it two segments and it works:wire [(0,0),(20,0),(40,0)].
Boolean
| Operation | Description | Example |
|---|---|---|
diff shape |
Subtract | diff cylinder 5 10 |
union shape |
Add | union sphere 5 |
inter shape |
Intersect | inter box 20 20 20 |
Pipe operation: box 10 10 10 | diff (sphere 7)
Source command: union [box 10 10 10, sphere 7] / diff [...] / inter [...]
Shape operators: a + b (union) / a - b (diff) / a * b (inter). Only between variables or parentheses: (box 10 10 10) - (cylinder 3 20) works, box 10 10 10 - cylinder 3 20 is a parse error (it collides with argument arithmetic). base - holes | fillet 2 is (base - holes) | fillet 2. Parenthesise when mixing * with +/-
Place
| Operation | Description | Example |
|---|---|---|
place shape |
Place a 2D shape | place $profile, place (circle 3) |
Place a 2D shape stored in a variable onto a face, then cut or extrude:
$s = sketch [(5,0), arc (5,0) (0,-5) (-5,0), (0,7), (5,0)]
box 10 10 10 | faces >Z | place $s | cut
2D → 3D
| Operation | Description | Example |
|---|---|---|
extrude h |
Extrude | extrude 10 draft:5 |
revolve axis [deg] |
Revolve (axis: X/Y/Z, deg defaults to 360) | revolve Y, revolve X 180 |
sweep profile |
Sweep profile along the upstream wire (spine). Spine and profile are both wires; either may be open or closed | helix 5 30 10 | sweep (circle 2) |
loft [sections] h |
Loft between sections | loft [rect 8 8] 10 |
Machining
| Operation | Description | Example |
|---|---|---|
cut |
Cut (omit depth for through) | `circle 5 |
hole r |
Drill hole (at face center or each point; omit depth for through) | `faces top |
Transform
| Operation | Description | Example |
|---|---|---|
floor |
Align bottom to z=0 | box 10 10 10 | floor |
translate x y z |
Translate (solids, point/vertex selections; not 2D shapes) | translate 0 0 5 |
rotate rx ry rz |
Rotate a solid (about the world X, Y and Z axes, exactly three) | rotate 0 0 45 |
rotate a |
Rotate a 2D shape (Face / Wire) in its plane (about the workplane normal, exactly one). It cannot stand a shape up off a face | rect 10 10 | rotate 45 | extrude 5 |
scale s / scale sx sy sz |
Scale (uniform/non-uniform) | scale 2, scale 2 1 0.5 |
mirror "axis" |
Mirror | mirror "X" |
move dx dy |
Move the drawing cursor (not a drawn shape) | move 10 10 | circle 5 | cut |
moveto x y |
Move the drawing cursor to a point | moveto 30 20 | rect 5 5 | cut |
color name |
Apply color | color "red", color 0.8 0.2 0.1 |
translate, rotate, scale accept origin: keyword: "world" (default), "local" (bbox center), or (x,y,z).
A 2D shape cannot leave the workplane it was drawn on. To put a path or an
outline on a vertical plane (XZ / YZ), draw it there to begin with, or write
it in 3D coordinates – do not try to stand it up with rotate:
workplane XZ | wire [arc (0,-25) (25,0) center:(0,0)] | sweep (circle 5) # arc on the XZ plane
arc (0,0,-25) (25,0,0) center:(0,0,0) | sweep (circle 5) # the same path in 3D
rotate 0 0 45 origin:"local" # rotate around object center
scale 2 origin:(10, 0, 0) # scale from arbitrary point
Selection and Workplane
Selection
| faces sel # select faces
| edges sel # select edges
| verts sel # select vertices (in 2D, returns shape vertices; can place 2D/3D primitives)
| verts | translate x y z # offset vertex positions (stays in selection)
| points [...] # specify points by coordinates
| points (polar n r) # circular arrangement
| points (grid nx ny p) # grid arrangement
| points ... | translate x y z # offset point positions (stays in selection)
After face selection, polar / grid can be written directly (omitting points):
| faces top | polar 6 20 | hole 3 # same as points (polar 6 20)
| faces top | grid 2 3 20 | hole 3 # same as points (grid 2 3 20)
Selector symbols
| Symbol | Meaning | Example |
|---|---|---|
> |
Maximum direction | faces >Z — top face |
< |
Minimum direction | faces <Z — bottom face |
= |
Normal/direction parallel to the axis | edges =Z — the 4 vertical edges / faces =Z — top + bottom |
+ |
Normal/direction perpendicular to the axis | faces +Z — the 4 side faces / edges +Z — the 8 horizontal edges |
Only >Z selects a single face. =Z and +Z come back as two faces and four
(for a 60x40x30 box, areas 4800 and 6000).
Name aliases
| Alias | Equivalent |
|---|---|
top |
>Z |
bottom |
<Z |
right |
>X |
left |
<X |
front |
<Y |
back |
>Y |
Compound selectors
| edges >Z >X # AND: Z-max AND X-max
| edges [>Z, <Z] # OR: Z-max OR Z-min
Tagging (as)
| faces <X as $left # name a face for later reference
| edges =Z as $top_edges
Workplane
| faces top | rect 50 30 # draw 2D directly from face selection (implicit workplane)
| faces top | workplane XZ # use workplane only when you need a specific axis
Placement at:
at: is a named argument. Omit parentheses for simple coordinates. Parentheses are required for expressions.
cylinder 2.5 10 at:20 10 # single position (omit parentheses)
cylinder 2.5 10 at:(20, 10) # parenthesized form also valid
cylinder 2.5 10 at:[(0,0), (20,10)] # list (brackets required)
rect 10 5 angle:45 # rotation (angle: named argument)
box 10 10 3 | polar 6 20 # circular array (3D context)
box 10 10 3 | grid 4 3 20 # grid array (3D context)
In a face selection context, polar/grid are interpreted as points:
box 10 10 10 | faces top | polar 6 20 | circle 3 | cut # circular point arrangement
box 10 10 10 | faces top | grid 2 3 20 | circle 3 | cut # grid point arrangement
Syntax
Variables
$w = 80
box $w $w/2 10
Function definition
def name($args) = pipeline
Import
import "gear"
Conditional expression
if $x > 0 then $x else -$x
List comprehension
[$i * 10 for $i in range(6)]
Operators (highest to lowest precedence)
** → * / // % → + - → comparison → and → or → |
CLI
The common ones. Every subcommand and option is in the CLI reference.
| Option | Description | Example |
|---|---|---|
-o file |
Output file (.stl / .step / .glb / .svg / .png) | poly build m.poly -o out.step |
--view names |
SVG/PNG viewpoints (front/back/top/bottom/left/right/iso, comma-separated). Default front,top,right,iso | poly build m.poly -o v.png --view iso |
--view-size px |
SVG/PNG panel size (default 240) | poly build m.poly -o v.svg --view-size 480 |
--no-hidden |
Omit occluded edges instead of dashing them | poly build m.poly -o v.svg --no-hidden |
-D key=value |
Override a parameter (repeatable) | poly build m.poly -D width=100 |
--params-file file |
Load parameters from a JSON file | poly build m.poly --params-file p.json |
--mesh-deflection val |
Mesh precision for STL/glTF (default 0.1; higher = coarser) | poly build m.poly --mesh-deflection 0.05 |
-D type inference: 100 -> int, 1.5 -> float, true/false -> bool, anything else -> string
When -D and --params-file are combined, -D wins. Precedence: -D > --params-file > @param defaults
poly build box.poly -D width=100 -D height=50
poly build box.poly --params-file presets/small.json -D width=120
Sections: poly section
Cut the model with a plane and report the contours. This is for checking a shape by numbers rather than by looking at a picture.
poly section m.poly # default xz,yz (through the bbox centre)
poly section m.poly --plane Z=10 # an explicit position
poly section m.poly --plane xz,yz,Z=10 # several
poly section m.poly --plane Y=0 -o cut.svg
Name a plane by the two axes it contains (xz has a Y normal). Omit the
position and it passes through the centre of the bounding box.
section XY @ Z=20: 2 loops
loop 0: closed bbox 39.999x39.9995 at (...) area 1256.6371 length 125.6637 points 315
loop 1: closed bbox 15.999x15.9995 at (...) area 201.0619 length 50.2655 points 199
Two loops mean hollow, one means solid. area and length are exact,
measured off the analytic curves (above is a 40mm cylinder with a 16mm bore,
matching pir^2 and 2pi*r to the digit). bbox and points come from the
sampled drawing path, so on a curved face they sit fractionally inside. An
area prefixed with ~ means no face could be built and the polygon area was
returned instead.
The SVG written by -o has path coordinates in millimetres, with the
display scale kept in a group transform. A 2mm floor and 2mm wall can be read
straight out of d="M 45.25 0 L 15 0 L 15 2 ...".
Context Transitions
3D ─→ faces/edges ─→ 2D ─→ extrude/cut ─→ 3D
│ │
│ └── hole ──→ 3D (hole at face center)
│
└── fillet/chamfer ──→ 3D
Face/Wire ─→ verts ──→ 2D primitive ─→ Face/Wire
│ └─→ 3D primitive ─→ 3D
│ └─→ translate ─→ verts (offset and stay in selection)
│
points ──→ hole ──→ 3D (hole at each point)
└─→ translate ─→ points (offset and stay in selection)
Remember: create → select → draw → return (workplane is optional – just select a face and draw directly)
With verts, both 2D and 3D primitives can be placed at each vertex.
Use translate to offset positions before placement:
rect 100 100 | verts | circle 1 # place circles at each vertex → 2D
rect 100 100 | verts | box 1 1 1 # place boxes at each vertex → 3D
rect 80 60 | verts | translate 10 10 10 | cone 2 0 6 # offset vertices then place