CNC / CAM Export — DXF Layer Convention

Convention version: TC-DXF-1

Every DXF TimberCloud exports follows the layer convention on this page. It is published, versioned and stable: we will add layers, but we will not change what an existing layer name means without changing the version tag.

Give this page to whoever runs your CNC. It is the reference for writing a post-processor, an import template or a machine setup sheet against our files.

Note: By default, TimberCloud's CAM export produces these neutral DXF files — not machine G-code. There is also an opt-in, Beta path that can emit real Grbl .nc G-code once your shop turns it on, configures a machine and tool, and accepts a responsibility notice. It's off by default and covered under CNC / CAM Settings. Everything on this page describes the neutral DXF files.


Read this first

Important:

These DXF files are neutral CAM data. They are not G-code.

Import them into your own validated CAM, assign your tools, feeds and speeds, and simulate before cutting. Kerf, grain direction and material allowances in our nests are assumptions — confirm them against your stock.

(If your shop has enabled the Beta G-code path, the export instead hands you posted .nc — but the same rule applies even harder: dry-run and simulate before you cut. See CNC / CAM Settings.)

What is in a TimberCloud DXF: through-cut profile geometry only.

What is not in it: dados, grooves, rabbets, pockets, bores, hinge cups, shelf-pin holes, edge profiles, or any other joinery.

Those operations are not represented in the file at all — not as empty layers, not as zero-depth geometry. Their absence is not a statement that the part has none. Take joinery from the cut sheet or the shop drawing.

This is stated so bluntly because DXF cannot say it for us. A quarter-inch dado and a cut clean through three-quarter plywood are the same closed polyline in a DXF — the format has no depth, no tool and no operation. If an exporter emits both without saying which is which, you get a part with a hole where a groove should be, and nothing anywhere disagrees.

Our answer is the two halves of this page: the operation lives in the layer name, and the operations we do not emit are named out loud so you never have to guess whether a file is complete.


Units and orientation

UnitsInches. Declared in the file header as $INSUNITS = 1.
CoordinatesReal size. A 34.5" shelf is 34.5 units long — nothing is scaled.
OriginBottom-left corner of the sheet, for nested files.
Depth referenceMeasured from the face presented to the spindle, as the part is laid out in the file.

The namespace rule

Every layer this convention governs starts with TC-.

A layer that does not start with TC- is not ours and carries no promise from us — treat it as reference and do not cut it. (This matters when our file has been merged into a larger drawing.)


Cutting layers

Only these layers describe material removal. Everything else is reference.

LayerOperationWaste sideEmitted today
TC-CUT-THRUThrough cut of a part profile, full stock thicknessOutside the boundary✅ Yes
TC-CUT-INNERThrough cut of an interior boundary (a cutout)Inside the boundary⛔ Reserved
TC-POCKET-D####Flat-bottom pocket to the named depth; the polyline is the pocket wallInside⛔ Reserved
TC-GROOVE-D####-W####Groove / dado / rabbet; the polyline is the centreline, not the wallAlong the centreline⛔ Reserved
TC-BORE-D####Bore to the named depth; emitted as a CIRCLE whose radius is the hole radiusInside⛔ Reserved

"Waste side" is the question a closed polyline cannot answer. TC-CUT-THRU means the shape is the part. TC-CUT-INNER means the shape is the hole.

Reserved is not the same as missing

The four reserved layers are published now and not written yet. Joinery output does not exist in TimberCloud today, and emitting an empty TC-POCKET-D0250 layer would read as "this part has no pockets" — a claim we cannot make. The same holds for TC-CUT-INNER: today's export writes the outer profile of each part and no interior boundary, so the layer stays reserved rather than declaring cutouts that are not in the file. Naming them now means the day joinery ships, your post-processor gains layers instead of having them renamed underneath it.


Depth encoding

DXF has nowhere to put a depth, so depth is in the layer name.

D#### and W#### are thousandths of an inch, zero-padded to four digits.

TokenInchesFraction
D01250.125"1/8"
D02500.250"1/4"
D03750.375"3/8"
D05000.500"1/2"
D07500.750"3/4"
D10001.000"1"

Fixed width keeps the names sorted correctly in a CAM layer list. The maximum a four-digit token can carry is 9.999" — a deeper operation is rejected by the exporter rather than silently truncated.

Face qualifier

A trailing -B means the operation is machined from the back face of the part as laid out in the file. No suffix means the front (up) face.

TC-POCKET-D0250        1/4" pocket, front face
TC-POCKET-D0375-B      3/8" pocket, back face
TC-GROOVE-D0250-W0500  1/4" deep, 1/2" wide groove on the centreline
TC-BORE-D0500-B        1/2" deep bore from the back

Reference layers — never cut these

LayerWhat it is
TC-STOCKThe sheet-stock boundary. Cutting it means running the tool around the outside of a full sheet.
TC-LABELPart identification text.
TC-GRAINGrain-direction indicator on grain-locked parts. The line runs along the grain.
TC-OFFCUTThe usable remnant left after nesting. Cutting it turns a usable offcut into scrap.
TC-NOTELegend and safety text.

Rule of thumb for a post-processor: cut only layers matching TC-CUT-*, TC-POCKET-*, TC-GROOVE-* and TC-BORE-*. Ignore everything else.


One nest, one material

Parts are grouped by (material, thickness) before anything is nested, and each DXF is a nest of one stock only. A 3/4" plywood carcass side and a 1/4" back panel will never appear on the same sheet — that would be a file describing a sheet that does not exist, and again, nothing in DXF could object.

Each file's header states which stock it was nested for:

999
MATERIAL: Maple Ply
999
STOCK THICKNESS: 0.75"
999
NESTED ON: 96" x 48" Maple Ply (0.75") [match: exact]

The [match: …] tag tells you how confident that is:

MatchMeaning
exactMaterial and thickness matched an entry in your sheet-stock library.
materialThe material matched, but that stock entry declares no thickness.
thicknessOnly one stock has this thickness, so it was used. Confirm the material.
fallbackNothing matched. The nest is still cuttable geometry, but the sheet size and material are an assumption.
defaultNo stock library is configured, so the default 96" × 48" sheet was used.

Anything other than exact also appears as a STOCK NOTE: line in the file and as a warning in the export.

Parts with no material or thickness

If a part does not declare a material or a thickness, it goes into its own nest, flagged as unspecified — never merged into a nest of known stock.

We deliberately do not infer thickness from a part's smallest dimension. That guess is right most of the time and wrong on exactly the parts you cannot afford it to be: on a 3/4" × 2" × 30" face-frame stile the smallest dimension is the width.

Fix it by filling in the material and thickness on the product's parts.


Large jobs are split into chunks

A very large nest is split into several files of a few hundred parts each, named …-part1-sheet-1.dxf, …-part2-sheet-1.dxf and so on, with a CHUNK 1 of 3 line in the header.

Sheets in different chunks were nested independently, so they could not share offcuts — expect a slightly higher sheet count than a single nest would give. The trade is deliberate: it keeps a whole-kitchen export from stalling.


The header block

Every file starts with 999 comments carrying the safety notice, the convention version, the completeness statement, the stock the file was nested for, and a legend covering exactly the layers present in that file.

Warning:

Many CAM importers discard 999 comments on read. That is precisely why the operation lives in the layer name — the name survives every importer that supports layers at all. Treat the header as a courtesy and the layer name as the contract.

The same header block is included as cam/LAYER-CONVENTION.txt in the full design export, so it survives the DXFs being copied, renamed or emailed on.