The layered DXF ships today and works with whatever CAM you already run — VCarve, Aspire, Fusion, EnRoute, your machine's own software. The direct posts write a machine's program straight from the nest, for eight controllers.
Every direct program is simulated and read back before the app will offer it, and no WoodWright program has cut on a machine yet. Below is exactly what each file contains — check it against your own table before the first scrap cut.
design → parts → nest (true-shape, grain-locked)
│
┌─────────────┴─────────────┐
layered DXF direct post
every part of a material one program per nested sheet
↓ ↓
your CAM .xxl .tap .nc .ngc
nests it, toolpaths it, .sbp .cix .mpr
writes your G-code ↓
↓ your controller
your routerCutlist ▸ ⬇ DXF writes one file per material, named WW-<room>-<material>.dxf, into the job's own folder — or into the folder your CAM watches, if you point Settings ▸ Folders at one.
It is ASCII DXF, R2010, in inches. It opens in anything that reads DXF, and it audits clean in an independent DXF library (ezdxf: zero errors).
The DXF is not the nest. It is every cut part of that material, each drawn in its own frame and laid out in tidy rows — 96 inches wide, 1-inch gutters — for your CAM to nest and toolpath.
A DXF of the nested sheet itself is on the bench; the nest reaches a machine through the direct posts today.
Each part sits with its origin at its bottom-left corner, X along the grain (the part's length), Y across it, top face up. Everything the router does to that part is on its own layer, and the layer name is the tool selector:
OUTLINE the through cut — one closed polyline per part; fillets are true arcs
POCKET_0.385 a dado or groove, pocketed 0.385" deep — a closed polyline
POCKET the same with no derived depth — set the depth in your CAM
ROUTE_0.375x0.25 a groove that is not square to an edge: the cutter CENTRELINE as
an open polyline — 0.375 is the bit, 0.25 the depth
BORE_0.197 a drill centre: a POINT and a CIRCLE at true diameter (5 mm here)
BORE_1.378x0.5 a 35 mm hinge cup, 0.5" deep — drill it, or run a hole toolpath on the circle
LABEL the part name as TEXT — never a cut layerThe numbers in a layer name are decimal inches to three places. They are selectors, not measurements — the geometry underneath is exact.
In VCarve terms: OUTLINE is a profile outside the line; POCKET is a pocket to the named depth; ROUTE is a profile on the line with the named bit, to the named depth; BORE is a drill at the point, or a hole toolpath on the circle when the hole is wider than any bit you own; LABEL stays off.
Which face. Everything drawn is on the face that is up.
A part whose machining is all on the far face is drawn mirrored, with · MACHINED-FACE-DOWN in its label — the same flip the direct posts make, so the DXF shows the face the router actually cuts. A part that needs both faces refuses the whole export and says which part.
WoodWright has one toolpath planner. It writes SCM Xilog, because that is the machine it was decoded against: three real jobs' programs off the shop's own N100, every program re-parsed byte-identical and run through an independent dry-run simulator.
Every other post is a translation of that simulated program — move for move, bore for bore — and the translated text is then read back by its own parser and compared to the source before a machine card may offer it.
| Machine | File | How it is spoken | Your choices |
|---|---|---|---|
| SCM N100 · Xilog Plus | .xxl | The source program itself — the dialect decoded from the shop’s own programs, re-parsed byte-identical, dry-run simulated, checked against three real jobs’ goldens. | two-face |
| Generic router · Mach3 / Mach4 | .tap | ISO G-code: T M6 + G43 H, G91.1, G83 pecks. Avid, Laguna, most 4×8 kits. | units · Z zero · tool change · two-face |
| Generic router · GRBL 1.1 | .nc | M0 tool change that names the bit, pecks spelled out (no canned cycles), no G91.1, every line under 80 characters. Onefinity, Shapeoko, LongMill, OpenBuilds. | units · Z zero · two-face |
| Generic router · LinuxCNC | .ngc | RS274/NGC: T M6 + G43 H, G91.1, G83 pecks. | units · Z zero · tool change · two-face |
| Generic router · Masso G3 | .nc | T M06 without G43 — tool geometry lives in Masso’s own table. G83 pecks. | units · Z zero · tool change · two-face |
| ShopBot · PRSalpha / PRSstandard | .sbp | OpenSBP (public domain): a %(25) unit guard that halts on the wrong unit, CG arcs, C6/C7 spindle, &Tool + C9 or a PAUSE for a hand change. Inches by default. | units · Z zero · tool change · two-face |
| Biesse Rover · bSolid / bWorks | .cix | BG bores, ROUT + LINE_EP paths with incremental Z (a misread lifts, never buries), arcs chorded at 0.025 mm. Z is panel-relative, so no Z-zero choice. | two-face |
| Homag / Weeke · woodWOP | .mpr | BohrVert bores by diameter (the control picks the drill), KP/KL contours on the tool centreline with RK=NOWRK, TI=0 so the depth lives in the points. mm only. | two-face |
Tick your machine in Sheets ▸ Machines — the public build starts with none ticked, so nothing posts until you say which controller reads it.
Programs save beside the job (or in the folder the machine reads), one per sheet, named WW-<room>-<material>-S01.<ext>. A SETUP.txt saves beside each one: the origin corner, the face that is up, the Z reference, and every tool with its T number.
A pinned dado bit that is not in the changer cuts with the widest capable bit that fits, and the setup sheet says so.
Mach3/4, GRBL, LinuxCNC and Masso share one emitter; the cards differ only where the controls do. This is the head of a generated program, unedited:
(WoodWright 0.7.0 - WW-Kitchen-Prefinished-S01) (Prefinished 3/4 - sheet 1 of 3 - 2026-09-03) (stock 2451.1 x 1231.9 x DZ 18.923 mm - X along the long axis) (Z0 = TABLE spoilboard top; stock top at Z18.923) (origin front-left corner of the sheet, top face up) (sim-verified translation of the WoodWright toolpath - VERIFY ON SCRAP FIRST) G17 G21 G90 G94 G40 G49 G54 G91.1 G0 Z33.923
The preamble. XY plane, millimetres (or G20 on an inch card — then every word is converted, feeds included), absolute positioning, feed in units per minute, cutter compensation off, tool-length offset cancelled, work offset G54.
G91.1 declares incremental arc centres on Mach and LinuxCNC; GRBL errors on that word and never sees it. Comments are in parentheses, lines end CRLF, there are no line numbers, and on GRBL no line is longer than 78 characters.
The origin is the front-left corner of the sheet, top face up, X along the long axis. By default Z0 is the table — the top of the spoilboard — and the stock top sits at +DZ, the thickness you mic'd and typed into the sheet.
With Z0 at the table a wrong thickness cannot bury a bit: a through cut always ends 0.127 mm into the spoilboard, wherever the stock top really was. The card offers Z0 at the top of the stock instead, for a shop that touches off the sheet.
With 18.923 mm stock the numbers in the program are:
Z33.923 safe height stock top + 15 mm — every rapid rides here Z19.923 hover 1 mm over the stock — the plunge starts here, at plunge feed Z18.923 the stock top DZ, as typed Z-0.127 a through cut 0.127 mm into the spoilboard Z-0.099 a through bore the drill's own through-add
G0 Z33.923 retract to safe G0 X187.3 Y7.938 rapid over the lead-in G0 Z19.923 down to the hover G1 Z18.923 F1778 to the stock top at the tool's plunge feed G1 X212.7 Z-0.127 the ramp the simulator cleared — 25.4 mm long G1 X412.7 F17780 the cut, at the tool's feed (modal — said once) G2 X417.462 Y12.7 I0 J4.762 a filleted corner: incremental I/J from the current point G1 Y312.7
Every path is the tool centreline — the offsets are already in the geometry, which is why the program runs G40 and a control with cutter compensation on would cut it twice.
Feeds are the tool library's (Sheets ▸ Tooling), spindle speed rides S… M3 at each change. Onion-skin tabs every 24 inches are on by default (the G-code modal has the box); the ramps and tab lifts are explicit moves, never a cycle.
Mach / LinuxCNC Masso M5 M5 G0 Z33.923 G0 Z33.923 T1 M6 T1 M6 G43 H1 S24000 M3 S24000 M3 GRBL, or "change by hand" on any card M5 G0 Z33.923 T1 (CHANGE TO T1 3/8 Compression d9.525 then cycle start) M0 S24000 M3
T numbers are the app's own tool-library numbers, and the setup sheet lists each one with its name, diameter, rpm and feed, so the changer or the hand can be checked against the paper. Masso keeps tool geometry in its own table and is correct without G43 — that is deliberate, not an omission.
A router has no drill bank, so the post decides. A bit of the hole's diameter that is marked for drilling pecks — G83 with a 4 mm peck, or the pecks spelled out as G1/G0 pairs on GRBL.
A hole wider than any drill you own is helix-bored with the largest suitable smaller bit: full-circle G2 arcs stepping down 1.5 mm a turn, one flat turn at the bottom. A hole nothing in your library can make refuses the sheet and names the bit to add.
(1 x d5 pecked with 5mm Drill) G83 X1100 Y950 Z-0.099 R19.923 Q4 F1200 G80 (1 x d35 helix-bored with 3/8 Compression) G0 X1012.737 Y900 G0 Z19.923 G1 Z18.923 F1778 G2 X1012.737 Y900 Z17.423 I-12.738 J0 F17780 G2 X1012.737 Y900 Z15.923 I-12.738 J0 … G2 X1012.737 Y900 Z6.223 I-12.738 J0 G2 X1012.737 Y900 I-12.738 J0
The same translation, spoken three other ways. Each was built from the public format description only — no vendor post file was copied — and where the public text leaves a token ambiguous, the conservative reading was taken and the program's own header says which.
ShopBot (.sbp) never sets the control's units — a wrong calibration value would miscalibrate the machine — it guards them and halts:
'stock 96.5 x 48.5 x DZ 0.745 in - X along the long axis 'Z0 = TABLE (spoilboard top); stock top at Z0.745 'units INCHES; speeds in in/sec; the file halts if the control is set to the other unit IF %(25)=1 THEN GOTO UNIT_ERROR SA JZ,1.3356
Cuts are M2/M3/MZ, jogs J2/J3/JZ, arcs CG with the diameter written as well as the centre so either reading of the centre words gives the same circle, spindle TR … C6 … C7, and a hole wider than the bit is stepped — plunge a pitch, one flat circle, again — rather than helixed.
Biesse (.cix) carries the stock in MAINDATA (LPX, LPY, LPZ), Z is the top of the panel, a bore the library can drill is a BG macro, a path is ROUT + LINE_EP elements with incremental Z — the reading under which a misread lifts the bit rather than burying it — and arcs are chorded at 0.025 mm sag because the arc direction word is not corroborated.
Homag / Weeke (.mpr) is woodWOP's own file: the [H header with DX/DY/DZ, a BohrVert macro per bore with the diameter so the control picks its own drill — no peck, no helix, no library lookup — and KP/KL contours on the tool centreline with RK="NOWRK" so woodWOP does not offset a second time. Feeds and rpm are written in each macro's comment and ride your tool database.
The first time a machine saves programs on a device, the app puts this in front of the hand that saves them, and the box has to be ticked. These are its words:
Sheets ▸ Machines ▸ tell us about your machine hands us the maker, model, controller and bed with the details prefilled. A sample program your CAM writes today — any .nc, .sbp, .mpr, .cix — helps most, because a post is built by reading what the machine already eats.
And if you have run a WoodWright program on iron: send the measured first part through support and that machine's card gets a proven-on date. The bench order follows real shops.