Skip to content

Latest commit

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

shopbot-toolpaths

Verified CNC toolpath strategies and the small motion IR they compose onto — the reusable core extracted from the ShopBot Labs step-toolpath app.

Each strategy is a self-contained function that turns a geometric feature (a pocket, a profile, an edge chamfer, a bored hole, a 3D relief surface) into machine moves on a shared rail, checked by an independent verifier before it becomes G-code or ShopBot SBP. The idea is that you can lift one file — say the chamfer strategy — understand it on its own, and reuse the concept in your own CAM code.

Grab a strategy. Want the chamfer logic? It's strategies/chamfer.js. The strategies depend only on each other, the ir/ rail, and a bundled copy of Clipper — no framework, no build step.

The shape of it (fabrication hourglass)

feature (pocket / profile / chamfer / bore / relief)
│
strategies/*.js ← the "how to cut it" — geometry → toolpath
▼
ir/moves.js ← the canonical motion rail (the neck): every
strategy emits the SAME move vocabulary
│
ir/job.js ← compose ops into one multi-tool job
ir/verify.js ← admission gate: refuses gouges / cut-throughs /
bad plunges BEFORE anything posts
▼
G-code · ShopBot SBP

Strategies never post directly and never trust themselves — they emit moves, and ir/verify.js re-derives the safety constraints independently. That separation (a wide set of strategies above a narrow verified rail) is the whole point.

What's here

strategies/ — the toolpath generators:

filewhat it does
chamfer.jsEdge-break / bevel along a feature edge with a V-bit.
pocket.jsPocket clearing — the core area-clearing primitive.
profile.jsCut the part free (profile/perimeter, with tabs).
bore.jsA circular hole cut by a bit near its own diameter.
rest.jsRest machining — a smaller bit cleans what the bulk bit couldn't reach.
surface-raster.jsBallnose-compensated 3D raster over a heightmap (reliefs, dishes, textures).
tool-select.jsWhich bit machines which feature, and when to add a smaller one.

ir/ — the composition IR the strategies share:

filewhat it does
moves.jsThe canonical motion rail — the common move vocabulary.
job.jsCompose ops into one multi-tool job.
verify.jsThe verifier — the admission gate (gouge / depth / plunge checks).
tools.jsShared tool drawer + a deterministic feeds/speeds engine.
placement.jsTransform op-local moves into job coordinates.
arc-fit.jsOptional arc-fitting pass on the moves rail.

vendor/clipper.jsClipper 6.4.2 (Angus Johnson), polygon offsetting/clipping, wrapped as an ES module. Boost Software License; see NOTICE.

Quickstart

Pure ES modules — browser or Node, no build step, no dependencies to install (Clipper is vendored). Clone it and run the example below with node.

This cuts a rectangular part free from a board and posts ShopBot .sbp. The shape of every job is the same: run a strategy → compose → verify → post.

import{generateProfile}from'./strategies/profile.js';import{composeJob,postJobToSbp}from'./ir/job.js';import{verifyJob}from'./ir/verify.js';// 1. A feature — a 3" x 2" part outline. Points are { x, y } in inches, placed// with clearance inside the stock so an outside cut stays on the board.constregion={outer: [{x: 0.5,y: 0.5},{x: 3.5,y: 0.5},{x: 3.5,y: 2.5},{x: 0.5,y: 2.5}]};// 2. A tool — a 1/4" flat endmill, carrying the machine's real &Tool number.consttool={number: 1,diameter: 0.25,kind: 'flat',flutes: 2};// 3. Run a strategy — profile-cut the part free, tool OUTSIDE the line, with// hold-down tabs so the part doesn't break loose mid-cut.constprof=generateProfile(region,tool,{side: 'outside',totalDepth: 0.5,depthPerPass: 0.25,safeZ: 0.25,tabs: {height: 0.08,length: 0.3},});// 4. Wrap it as a one-operation job over a piece of stock.constjob={units: 'in',stock: {w: 4,h: 3,thickness: 0.5},safeZ: 0.25,spindleSpeed: 16000,tools: {1: {name: '1/4" endmill',diameter: 0.25,kind: 'flat',rpm: 16000}},operations: [{name: 'Cut out',tool: 1,feedRate: 120,plungeRate: 40,moves: prof.moves},],};// 5. Compose → verify → post. verifyJob MEASURES the real motion (stock// envelope, cut depth, plunge) and refuses anything unsafe before it// becomes machine code — the strategy is never trusted to police itself.constmoves=composeJob(job);constreport=verifyJob(job,moves);if(!report.ok)thrownewError('refused: '+report.errors.join('; '));constsbp=postJobToSbp(job,moves,{title: 'quickstart'});// ShopBot .sbp// const gcode = postJobToGcode(job, moves, { title: 'quickstart' }); // or G-codeconsole.log(sbp);

The verifier is real. Move the part flush to the corner — { x: 0, y: 0 } — and verifyJob returns ok: false, because an outside cut with a 1/4" tool would run off the stock. Nothing posts until the motion checks out.

Swap generateProfile for generatePocket, generateChamfer, generateBore, or generateSurfaceRaster to cut a different feature — same compose/verify/post loop, same job shape.

The strategies are written to be read, not just called — each file opens with a comment explaining the geometry and the reasoning, because the goal is to share the toolpathing concepts, not just an API.

Status & scope

This is an extracted, reusable subset — the strategy + IR core. The surrounding application (STEP-file feature detection, the UI, the LLM intent layer, the hosting) is not included here. Interfaces may still change; treat it as a reference and a starting point rather than a frozen library.

License

Apache License 2.0 — permissive, with an explicit patent grant. See NOTICE for third-party attributions.

About

Verified CNC toolpath strategies + motion IR, extracted from the ShopBot step-toolpath app

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages