Skip to content
CADCAMFUN
Docs

Documentation

Setups and saved programs

Capture the stock, work frame, cutter assignments, ordered operations, and source evidence used to produce a program.

A setup is manufacturing context

A manufacturing setup defines how a part sits relative to stock, fixtures, and tools. cam.ManufacturingSetup records an identifier, revision, rigid work frame, world-coordinate stock and fixture envelopes, and tool assemblies. The native kernel accepts a CAD snapshot and resources and produces ordered operation results and one posted program.

Saved application programs use CamProgramDocument, the portable document also stored in Toolpath.data. This contract retains NC and its program representation together with the settings, stock, and drawing snapshot needed to reopen the workspace. Optional operations preserve separate operation identities; optional kernel data retains native source evidence.

Portable document contract

A document identifies itself with format: "cadcamfun-cam" and version: 1. Required fields are gcode, program, generator settings, printer extras, stock, and a free-form drawing snapshot. Optional fields are operations, kernelArtifact, and kernelRequest.

Each stored operation has a unique id, name, gcode, and program, with optional tool, settings, and source element identifiers. Keeping its NC and identity makes an operation round-trip independently of its display label.

Operation order and composition

combineCamOperations preserves operation order. It namespaces toolpath identifiers with the operation identifier, uses an explicit operation tool when supplied, and prefixes display names when there is more than one operation. The combined program takes units and work offset from the first operation.

For a single operation, combined NC is the original text. For multiple operations, the helper joins their existing NC sections with operation comments. This helper does not re-post all sections into a single controller program. The native kernel is the route that generates ordered operations and emits one integrated program.

Callers composing pre-generated sections must ensure compatible units, work offsets, tool numbering, headers, and program endings. A successful document composition proves ordering and consistency with its stored sections; it does not add machine-clearance evidence.

Generate and save

  1. Capture the drawing elements and stock to be machined. Choose a material, machine, tools, work offset, and quality controls.
  2. Call POST /api/toolpaths/manufacture with schemaVersion: 1, job identity, name, and the captured elements. Supply operations explicitly in machining order or allow the kernel to plan them.
  3. Inspect the returned result, issues, individual claims, and release. An artifact can be a preview or blocked; receiving a result does not imply verified output.
  4. Build a CamProgramDocument whose G-code, program, artifact, and captured request describe the same result. Save it through a toolpath create or update endpoint, together with that G-code.

The manufacture endpoint evaluates the supplied snapshot without writing the drawing or creating a toolpath. Generator /generate is a separate settings-driven route and can also supply NC for a portable document.

Persistence validation

The sidecar recognizes portable documents by their format and decodes the full schema before saving. The document's G-code must match the toolpath row's G-code. Operation identifiers must be unique, and their ordered composition must reproduce the saved text. The sidecar reparses operation NC to reconstruct program moves rather than trusting client-provided move data.

For a new native artifact with a captured request, the sidecar reruns that request and compares the resulting artifact, program, and original NC. Failed or blocked results, altered artifacts, and mismatched text are rejected. A newly supplied artifact without its captured request is removed unless it is an unchanged artifact already retained on the row.

When the supplied source elements and stock match the associated stored drawing, the service computes a drawing revision digest. Clients cannot provide a trusted sourceRevision or arbitrary verification claim. The saved revision is derived by the service or retained only for the same existing artifact.

Editing NC and retaining evidence

An update can replace NC while sending the unchanged prior portable document. The service recognizes that case, rebuilds the parsed program from the new text, and removes operations and native source evidence that no longer match. An inconsistent new document is rejected instead of silently combining unrelated programs.

Ordinary free-form toolpath data remains supported. A change to NC removes stale native artifact metadata where it no longer matches. Client-supplied verification and response fields do not become trusted native evidence.

The validation implementation is apps/sidecar/src/services/cam-program.ts; runKernelRequest, prepareCamProgramData, and drawingRevision share the same request adapter and identity logic used by generation and saves.

A saved program can contain subprograms generated from repeated toolpaths. The rules for which toolpaths may share a subprogram are described on the CAM page.

Rigid work frames

A WorkFrame has an origin and X/Y/Z axes. validateWorkFrame requires finite coordinates, unit axes, pairwise orthogonality, and right-handed orientation within its numerical tolerance. workToWorld applies the frame; worldToWork projects back. Invalid frames, invalid points, and numeric overflow produce a range error.

validateSetup also checks a non-empty setup identifier, non-negative safe-integer revision, positive-volume finite envelopes, unique fixture/tool identifiers, and positive finite cutter and holder dimensions. Cutting length must not exceed stickout. Validation returns field-specific issues so the caller can identify the value that needs correction.

Indexed table machining

cam/indexing.ts solves indexed orientations for table-AC and table-BC layouts. It rotates the selected work-plane normal onto machine +Z, respects rotary limits, and prefers the smaller reachable tilt. Program points pass through the work frame and table rotation about the machine pivot.

This adapter models table indexing with a fixed tool axis. Tilting heads, controller tilted-plane cycles, and simultaneous five-axis motion are separate capabilities. Rotary positions are degrees; frame axes remain unit vectors.

Shared setup types

ManufacturingSetup, WorkFrame, ToolAssembly, validateSetup, validateWorkFrame, workToWorld, and worldToWork are exported through cam. Portable operation and document schemas are exported from @cadcamfun/api, which makes them available to both sidecar persistence and desktop restore logic.

Reopening in the desktop

saved-program.ts captures current settings, stock, drawing, and the exact NC being saved. It retains a kernel artifact only when its NC and hash match those bytes. On restore, it checks the stored artifact and release, restores compatible operation results, resets replay verification, loads the editor, and restores generator and stock controls from the snapshot.

When only ordinary G-code is available, the desktop parses it for display. Opening text successfully does not recreate a missing generation request or upgrade the program's evidence level.

Keep source and result together

Regenerate after changing geometry, stock, tool dimensions, work frame, machine, material, or operation order. Preserve source snapshots for reproducibility, and treat a changed NC file as new output requiring its own analysis. Source revision checks and artifact replay prevent an earlier result from being presented as evidence for different program bytes.

Evaluate a captured setup

The snapshot adapter is the common boundary for the native manufacture request. This self-contained example captures a polymer blank and a slightly larger stock box, then returns the artifact's actual release level. It writes neither a drawing nor a toolpath.

From editor coordinates to a native job
import { cam } from "@cadcamfun/core"

const prepared = cam.kernel.jobOfSnapshot({
  schemaVersion: 1, id: "blank-job", name: "Blank", material: "POM",
  elements: [{ id: "blank", type: "cube", x: 20, y: 20, z: 5,
    width: 40, height: 40, depth: 10 }],
  stock: { x: 20, y: 20, width: 44, height: 44, depth: 11 },
  resolution: 0.5
})
if (prepared.status === "failed") throw new Error(JSON.stringify(prepared.issues))
const result = cam.kernel.runJob(prepared.value)
if (result.status === "failed") throw new Error(JSON.stringify(result.issues))
console.log(result.value.release)
console.log(result.value.claims)
console.log(result.value.identity.nc)

The cube position is its center; its bottom is Z0. Snapshot stock X/Y are its center and width/height are full dimensions. The adapter places the stock bottom at the selected part's lowest Z, then adds the declared depth. Kernel work origin defaults to stock-center at the stock top; stock-corner selects its minimum X/Y and top Z instead.

Source: packages/core/src/cam/kernel/snapshot.ts, execute.ts, and kernel.test.ts.

Snapshot options and bounds

The HTTP native request requires 1–2,000 elements, a version of 1, non-empty job ID/name, and a material name up to 80 characters. It accepts up to 500 explicit operations and, when supplied, 1–200 cutters. Omitting operations invokes the planner; an explicit empty operation list is not a request to invent operations.

finishAllowance accepts 0–5 mm; scallop is positive and at most 1 mm; deburr is positive and at most 5 mm. Native defaults use the material's finish allowance, 0.01 mm scallop, and 0.01 mm path tolerance. Replay resolution can be supplied separately. Optional subprograms: true requests translated repeat emission only where the selected dialect supports it.

A snapshot machine field names a registered preset. The lower-level ManufacturingJob can carry a full machine record, including explicit travel and table geometry; the public snapshot machine string does not itself accept an arbitrary machine record.

Source: packages/api/src/cam-kernel.ts, ai-cam.ts, and packages/core/src/cam/kernel/contracts.ts.

Resolve rejected saves

Response messageCause and remedy
Invalid CADCAMFUN toolpath documentThe recognized portable format failed its schema. Preserve all required settings, printer, stock, drawing, program, and G-code fields.
Toolpath document and G-code must contain the same programThe row NC and new document NC differ. Rebuild the snapshot from the exact bytes being saved.
Saved operations must have unique IDs and compose the stored G-code in orderOperation identity or ordering no longer reproduces the document. Recompose after editing, reordering, or deleting operations.
The saved kernel artifact does not match its source request and original NCReplaying the captured request failed, returned blocked output, or differed from the claimed artifact/program/NC. Regenerate rather than editing the evidence fields.

A valid native artifact may be retained without a source drawing revision when its source selection/stock does not match the associated stored drawing. That absence does not imply the saved NC was regenerated against the current drawing. Read the drawing revision and source snapshot independently when reporting freshness.

Source: apps/sidecar/src/services/cam-program.ts and apps/sidecar/test/cam-program.test.ts.

See a native job in 3D

Native job: POM blank, three operations Drag to orbit · scroll to zoom · right-drag to pan
The real program generated by the native kernel for the snapshot below, drawn in world millimetres. Purple: face mill Ø50 at Z10. Green: Ø16 adaptive roughing. Blue: Ø10 ball finishing. Dashed: rapids. Translucent boxes: the 44 × 44 × 11 stock and the 40 × 40 × 10 part. The program is in work coordinates; the work origin is the stock-center top, world (20, 20, 11), so every move here is the program move plus that origin.
OpStrategyToolCut lengthTimeRemoved
Face stock topfacefacemill-50334.0 mm12.4 s1936 mm³
3D adaptive roughingsurfaceflat-16472.2 mm5.3 s3360 mm³
3D steep and shallow finishingsurfaceball-105660.6 mm113.4 s0 mm³

Machine vmc-standard (Vertical machining centre (BT40, 12 000 rpm, 11 kW), post fanuc), material pom-c (Acetal POM-C (Delrin)). Stock volume 21296 mm³, final 16000 mm³, equal to the part volume, so remaining volume is 0. Estimated cycle time 149 s. Release: verified-program. The NC is 3071 lines long.

ClaimStatus
cutting-datapassed
machine-limitspassed
operations-completepassed
no-rapid-in-stockpassed
holder-clearancepassed
no-gougepassed
material-removedpassed
nc-replaypassed
machine-travelunsupported
machine-clearancepassed
machine-travel is unsupported here because the preset has no explicit travel envelope to check against. An unsupported claim is not a failure, but it is also not evidence; the verified-program release covers the claims that passed.

Work frame math, worked through

z = (0.707, 0, 0.707)x = (0.707, 0, −0.707) origin (40, 0, 10)world Xworld Z
Build, check and use a 45° frame
import { cam } from "@cadcamfun/core"

const frame = cam.frameFromNormal({ x: 40, y: 0, z: 10 }, { x: 1, y: 0, z: 1 })
// xAxis (0.707, 0, -0.707)  yAxis (0, 1, 0)  zAxis (0.707, 0, 0.707)
cam.validateWorkFrame(frame)                     // []

const world = cam.workToWorld(frame, { x: 10, y: 5, z: 0 })   // (47.071, 5, 2.929)
cam.worldToWork(frame, world)                    // (10, 5, 0)

cam.validateWorkFrame({ origin: { x: 0, y: 0, z: 0 },
  xAxis: { x: 1, y: 0, z: 0 }, yAxis: { x: 0, y: 0, z: 1 }, zAxis: { x: 0, y: 1, z: 0 } })
// [{ field: "frame", message: "Work frame axes must be orthonormal and right-handed" }]
frameFromNormal takes the normal as Z and projects the X hint (world X by default) onto the plane. When the hint is parallel to the normal it picks another perpendicular. Y is always Z × X, so the result is right-handed by construction.

Rotary solutions for common faces

anglesFor(normal, layout, limits) returns every way the table can bring a part direction to machine +Z, smallest tilt first, with the tilt inside the limits (default −120° to 120°). C is wrapped into (−180°, 180°]. These are real outputs:
Part normaltable-ACtable-BC
(1, 0, 1), 45° sideA45 C90, then A−45 C−90B−45 C0, then B45 C180
(1, 0, 0), +X faceA90 C90, then A−90 C−90B−90 C0, then B90 C180
(0, −1, 0), front faceA90 C180, then A−90 C0B−90 C90, then B90 C−90
(0, 0, −1), undersidenone (empty array)none (empty array)

An underside needs a 180° tilt, outside the default limits, so the list is empty and indexToolpath throws "The machine's rotary axes cannot reach this work plane within their limits". Machine the underside in a second setup instead.

Where the frame origin lands after indexing
const [angles] = cam.anglesFor({ x: 1, y: 0, z: 1 }, "table-BC")   // { b: -45, c: 0 }
cam.partToMachine({ x: 40, y: 0, z: 10 }, angles, "table-BC", { x: 0, y: 0, z: 0 })
// (21.213, 0, 35.355): the origin rotated -45° about Y around the pivot

Setup validation messages

Everything wrong at once
cam.validateSetup({
  id: "", revision: -1, frame,
  stock: { min: { x: 0, y: 0, z: 0 }, max: { x: 0, y: 10, z: 10 } },
  fixtures: [],
  tools: [{ toolId: "t", cuttingDiameter: 6, cuttingLength: 30, stickout: 20,
            holderDiameter: 32, holderLength: 40 }],
})
fieldmessage
idSetup ID must not be empty
revisionSetup revision must be a non-negative safe integer
stockEnvelope must have finite coordinates and positive volume
tools.tCutting length must not exceed stickout

Issues are returned, not thrown, and all are reported in one pass, so a form can mark every bad field together.