Kerfwise CNC G-code Generator
Nest parts and get CNC router G-code: compensated profiles, tabs, ramps, drilling cycles, time.
Try an example: Wardrobe side panels with shelf-pin rows (GRBL) · Doors with Ø35 hinge cups (LinuxCNC, G81 cycles) · L-shaped desk top and corner shelves (Fanuc-style)
How it works
Turns a part list into a CNC router program: parts (rectangles, L-shapes, corner cuts, quarter rounds) are nested with a gap of one cutter diameter, then every part gets an outside profile with the tool-radius offset already in the path (arcs around corners), multiple depth passes with a ramped entry, holding tabs or an onion skin, and the cut order small parts first. Holes become drilling cycles (G81, or G83 peck for deep holes) for LinuxCNC / Fanuc-style controls, or expanded moves for GRBL. You get the G-code, a toolpath preview, a DXF per sheet and the estimated machining time.
- Nesting: the kerfwise sheet nesting optimiser (MaxRects) with the kerf set to the cutter diameter, so the slots of neighbouring parts never overlap; the margin to the sheet edge must be ≥ the cutter radius.
- Tool-radius compensation in the path: each outside profile is the part outline offset outward by the radius — straight edges shifted along their outward normal, an arc (G2/G3, centre = part corner) around every convex corner and a line intersection at inside corners of L-shapes. Inner contours are offset inward. The controller runs with G40 (no G41/G42).
- Passes: n = ⌈(thickness + 0.3 mm overcut) / depth per pass⌉, equal steps. Entry ramps down along the first edge (40 mm), the ramp wedge is cleaned at the end of each pass. Tabs: 2–6 per part on the longest edges, raised to 2 mm above the spoilboard in the passes below that height. Onion skin: the last pass stops 0.3 mm above the bottom.
- Climb milling: outside profiles run clockwise, inner contours counter-clockwise (conventional = reversed). Order: drilling (one tool at a time, nearest-neighbour tour), helical bores, inner contours, outside profiles from the smallest part to the largest.
- Drilling: holes go to the drill whose diameter matches (±0.25 mm) — G98 G81 (G83 peck for holes deeper than 3 × Ø) on LinuxCNC/Fanuc, expanded G0/G1 plunges on GRBL. Holes without a matching drill are helically bored with the end mill. Rapids (G0) are only used at or above the clearance height (3 mm) once over the material.
- Time = feed moves ÷ their feed rate + rapids ÷ 10 m/min + 22 s per tool change; acceleration is ignored, so real machines take longer (add 20–40 %).
Simulate every program in your CAM or controller before running it. Check work zero, tool lengths, feeds and speeds for your machine and material. Kerfwise is not responsible for crashes, broken tools or scrapped material.
Sources
- LinuxCNC G-code reference (G0/G1, G2/G3 arcs, G81/G83 drilling cycles, G98/G99, G40/G43) (LinuxCNC)
- Grbl v1.1 commands — supported G-codes (no canned drilling cycles) (gnea/grbl wiki)
- Climb milling vs. conventional milling (Wikipedia)
- A Thousand Ways to Pack the Bin – A Practical Approach to Two-Dimensional Rectangle Bin Packing (J. Jylänki) (GitHub juj/RectangleBinPack)
Part of Kerfwise
-
Kerfwise Cabinet & furniture CAD
Design cabinets and furniture, get cut lists, optimised sheet layouts, costs and drawings.
Related tools
- Kerfwise Sheet Nesting Optimizer – Nest rectangular and shaped parts on sheets: kerf, grain, yield, lower bound, offcuts, SVG + DXF.
- Kerfwise Cut List & Cost – Cabinets or a Kerfwise project → cut list, edge banding, hardware, sheets and costs.
- Kerfwise Cabinet Builder – Parametric cabinet → every part with cut sizes, edge banding, drilling and hardware.
How to use the Kerfwise CNC G-code Generator
Turn a part list with holes into CNC router G-code for GRBL, LinuxCNC or Fanuc-style controls, with nesting, compensated profiles, tabs, drilling cycles and time estimate.
What it is for
Cutting cabinet parts on a CNC router usually means a CAM package, yet for panel furniture the steps are almost always the same. This generator does them from a simple part list. Rectangles, L-shapes, corner cuts and quarter rounds are nested with a one-cutter gap, each part gets an outside profile with the tool radius already in the path, the depth is split into passes with a ramped entry, tabs or an onion skin hold the parts, and holes become drilling cycles.
You get the G-code for your controller dialect (GRBL, LinuxCNC or Fanuc-style), a toolpath preview, a DXF per sheet, an operations list and an estimated machining time. Always simulate the program in your controller or CAM first, and check work zero, tool lengths, feeds and speeds for your machine and material.
Worked example
Four doors 716 × 446 mm in 19 mm board, each with two Ø35 hinge-cup holes 13 mm deep, 22.5 mm from the edge and 100 mm from each end. Sheet 2440 × 1220, LinuxCNC:
4 parts on 1 sheet; sheet 1: 293 lines of LinuxCNC G-code, 16 profile passes, 8 holes, about 8 min 22 s.
The operations list shows the order. First the Ø35 Forstner bit (T4) drills all 8 cups with a G98 G81 … Z-13 R3 canned cycle. Then the 6 mm end mill (T1) cuts each door in 4 passes of 4.825 mm, which is 19 mm + 0.3 mm overcut split equally, with 3 tabs of 8 × 2 mm and climb milling. The path includes G2 arcs around each corner, because the radius offset is built in and the control runs with G40.
Two wardrobe sides and three shelves with shelf-pin holes in 18 mm board on GRBL: 370 lines, 20 passes (4 × 4.575 mm), 8 holes and about 14 min 23 s. GRBL has no canned drilling cycles, so each hole is written out as plunge-and-retract moves, and tool changes pause with M0 so you can swap the bit and re-zero Z.
How to read the result
- Machining time: the sum of feed moves and rapids plus 22 s per tool change. Acceleration is ignored, so add 20–40 % for a real machine.
- Passes, cutting path, tool changes, lines: a quick plausibility check.
- Operations in machining order: drilling first, then inner contours, then outside profiles from the smallest part to the largest, so small parts are cut while the sheet is still rigid.
- Downloads: the G-code file per sheet and a DXF with outlines, holes and toolpaths.
Tips and common mistakes
- Enter finished cut sizes. The tool adds the cutter offset itself, so don't add the tool radius to your parts.
- Hole x runs along the part length and y across it, from the part's first corner. Part is the row number, and the holes apply to every copy of that row.
- Z0 is the material top. Zero Z on the board, not the spoilboard, or every pass will be off by the thickness.
- The margin to the sheet edge must be at least the cutter radius, otherwise the outer profiles leave the sheet.
- Use tabs or onion skin unless you have strong vacuum, or small parts get thrown on the last pass.
- The tool nests parts one cutter diameter apart, also small parts placed in the notch of an L-shape, measured between the real outlines. If the result still warns that parts are closer than the cutter diameter, don't run the program.
FAQ
Which controllers are supported?
GRBL (no canned cycles, manual tool change with M0), LinuxCNC (G81/G83, T… M6) and Fanuc-style programs with N numbers and an O program number.
Does it use cutter compensation (G41/G42)?
No. The offset is calculated into the path and the program runs with G40. That keeps it portable between controllers.
How are holes drilled?
With a drill whose diameter matches (±0.25 mm), as a G81 or peck G83 cycle, or as expanded moves on GRBL. Holes without a matching drill are helically bored with the end mill.
Guide last updated:
For scripts and AI agents
- JSON API:
POST https://kerfwisecncgcode.usefulweb.app/api/v1/calculate(same calculation as this page) - Interface description: OpenAPI 3.1 · AI guide: llms.txt
- MCP server (Streamable HTTP):
https://kerfwisecncgcode.usefulweb.app/mcp· tool namekerfwise_cnc_gcode
Example request
curl -s -X POST https://kerfwisecncgcode.usefulweb.app/api/v1/calculate \
-H 'content-type: application/json' \
-d '{"parts":[{"name":"Side","length":2000,"width":580,"qty":2},{"name":"Shelf","length":764,"width":560,"qty":3}],"holes":[{"part":1,"x":300,"y":37,"diameter":5,"depth":12},{"part":1,"x":332,"y":37,"diameter":5,"depth":12},{"part":1,"x":300,"y":543,"diameter":5,"depth":12},{"part":1,"x":332,"y":543,"diameter":5,"depth":12}],"sheetLength":2800,"sheetWidth":2070,"thickness":18,"dialect":"grbl"}'