docs / Script API / KernelCadApi
KernelCadApi methods
69 unique methods generated from the typed runtime interface. Overloaded methods list each signature.
Task-based script API · Capability coverage inventory
angle
angle(a: unknown, b: unknown): RequirementPredicate
Angle between two selections' directions, degrees.
animationView
animationView(spec: AnimationViewSpec): AnimationViewHandle
Declare an animation timeline for offline MP4 capture. Two forms: - Legacy sweep: `{ param, from, to, durationMs, fps? }` — ONE previously-declared `param()` swept linearly. - Keyframe tracks: `{ name?, tracks, fps? }` — several params on one shared timeline, each track a list of `{ atMs, value, ease? }` keys. `ease` applies to the segment ENDING at that key (default 'linear'); outside the keyed span the value holds. Either way the stored metadata is normalized to the track shape (`AnimationViewMetadata`): keys sorted by atMs, ease defaulted, and `durationMs` = max atMs across all tracks. `scripts/captureAnimationView.mjs` reads the resulting `animationView` virtual record and renders an MP4 by sampling `ceil(durationMs / 1000 * fps)` frames across the timeline — leveraging the per-session mesh cache so each frame's recompute is ~5 ms warm. Every animated param must be declared by a prior `param()` call; malformed tracks/keys throw `KernelError` (`animation.*` codes), key values outside the param's declared range are clamped with a warn. Multiple calls register multiple records; the capture script uses the last one (the later record carries an `animation.view.shadowed` warn naming the records it shadows).
assembly
assembly(name?: string): Assembly
Declared on KernelCadApi.
bbox
bbox(selection: unknown): RequirementPredicate
Bounding-box size of a selection in mm; chain `.within({ x, y, z })`.
bezier
bezier(points: Vec3[]): Curve3D
A 3D Bézier curve through its control polygon: 3 points = quadratic, 4 = cubic (up to 26). Returns a `Curve3D` (same as `nurbsCurve(points, { degree: points.length - 1 })`), usable as a `variableSweep` spine or sampled into a sweep rail: `profile.sweep(bezier(pts).sample(64), { spine: 'smooth' })`.
box
box(x: Editable<number>, y: Editable<number>, z: Editable<number>, centered?: boolean, opts?: FaceLabelOpts): Shape
Axis-aligned box. Default (`centered` omitted/false): corner at the origin, spans [0,x]×[0,y]×[0,z]. `centered: true` centres ALL THREE axes on the origin, so Z spans -z/2..+z/2 (unlike `cylinder`, whose bottom stays on z = 0).
centerOfMass
centerOfMass(selection: unknown): RequirementPredicate
Centre of mass in mm; chain `.within(bands)` or `.between(lo, hi)`.
clearance
clearance(a: unknown, b: unknown): RequirementPredicate
Minimum surface-to-surface distance between two selections, mm.
concentric
concentric(a: unknown, b: unknown): RequirementPredicate
Two selections share an axis.
coplanar
coplanar(a: unknown, b: unknown): RequirementPredicate
Two selections are coplanar.
count
count(selection: unknown): RequirementPredicate
Number of resolved faces/edges in a selection.
curveBridge
curveBridge(a: Curve3D, b: Curve3D, opts: {
continuity: 'G1' | 'G2';
ends?: 'end-start' | 'end-end' | 'start-start' | 'start-end';
tension?: number;
}): Curve3D
Infer end frames from two Curve3Ds and emit a degree-5 Hermite blend. Same geometry as `a.bridge(b, opts)`.
cylinder
cylinder(h: Editable<number>, r: Editable<number>, segments?: number, opts?: FaceLabelOpts): Shape
Z-axis cylinder, centred on the Z axis in X/Y, bottom on the XY plane (spans z = 0..h). No `centered` flag: `.translate(0, 0, -h/2)` to centre.
dfmSpec
dfmSpec(spec: DfmSpec): DfmSpecHandle
Declare printability (design-for-manufacture) gates for the model. Declaration-only: this registers a virtual record (no OCCT geometry). Enforcement runs on every `kernelcad evaluate` / `evaluate_script` once a dfmSpec record is present — declared gates (minimum wall thickness, inter-part clearance, internal-channel topology) fail the evaluation when violated. `process: 'fdm'` adds the FDM printability check (overhangs and bridges relative to `buildDirection`, walls and features relative to `nozzleMm`, bed contact, bed fit on `printer`, and the six-orientation ranking); the gcode export slices in the declared `buildDirection`. At least one of `minWall`, `minClearance`, `channels`, or `process` is required. `includeArticulatedMates: true` also measures non-fastened mate pairs at the declared rest pose; fastened mates stay exempt because their contact is checked separately. Malformed declarations THROW `KernelError` (`feature.invalid-args`) rather than stashing diagnostics — dfmSpec is an enforcement gate, and a silently-disabled gate is worse than a build failure. Multiple calls register multiple records; the last record wins (same convention as `setRenderEnvironment`).
distance
distance(a: unknown, b: unknown): RequirementPredicate
Distance between two selections, mm.
edges
edges(shape: Shape, query?: EdgeQuery): RequirementSelectionHandle
Select all edges of `shape` matching `query` (default: every edge).
extrudeCircle
extrudeCircle(r: Editable<number>, height: Editable<number>, opts?: ExtrudeOpts): Shape
Declared on KernelCadApi.
extrudePolygon
extrudePolygon(points: Array<[
Editable<number>,
Editable<number>
]>, depth: Editable<number>, opts?: ExtrudeOpts): Shape
Declared on KernelCadApi.
extrudeRect
extrudeRect(w: Editable<number>, h: Editable<number>, height: Editable<number>, opts?: ExtrudeOpts): Shape
Declared on KernelCadApi.
extrudeRoundedRect
extrudeRoundedRect(width: Editable<number>, height: Editable<number>, radius: Editable<number>, depth: Editable<number>, opts?: ExtrudeOpts): Shape
Declared on KernelCadApi.
faces
faces(shape: Shape, query?: import('../shared/intent/queryTypes').FaceQuery): RequirementSelectionHandle
Select all faces of `shape` matching `query` (default: every face).
filletPolygon
filletPolygon(points: readonly PolygonPoint[], radius: number, opts?: FilletPolygonOptions): [
number,
number
][]
Round every corner of a closed 2D polygon with tangent arcs. Returns points for `extrudePolygon` / the prism helpers. Radius is clamped per corner to half the shorter adjacent edge; CW and CCW winding both work.
fontPath
fontPath(p: string): FontPath
Brand a string as a font filesystem path (TTF). Use with sketch.text({ font: fontPath('/path/to/font.ttf') }).
helix
helix(opts: EditableHelixOptions): RailPoint[]
Helix rail for `Sketch.sweep`. `radius`, `pitch`, `turns` and `startAngle` accept ParamRefs: the points are sampled from the current values and the rail remembers the symbolic dimensions, so a sweep along it follows param changes, and `sweep(rail, { spine: 'helix' })` can build the exact helix.
hermiteG2
hermiteG2(a: HermiteEndpoint, b: HermiteEndpoint): Curve3D
NURBS Slice C: quintic Hermite transition curve between two endpoints with prescribed tangent and (optional) curvature on each side. Returns a degree-5 `Curve3D` (6-control-point Bezier under a clamped-uniform knot vector). Use this to build a G2 blend curve between two existing curves — sample each neighbour's `pointAt(t)`, `tangentAt(t)` (and, if the neighbour is itself a `Curve3D`, its second-derivative for G2; otherwise omit `curvature` to fall back to G1). Throws `KernelError` on non-finite inputs or a zero-magnitude tangent; the curve3d record is not registered in that case.
innerLoops
innerLoops(selection: unknown): RequirementPredicate
Largest inner-loop (hole) count across the selected faces.
internalGear
internalGear(opts: InternalSpurGearOptions): Shape
Declared on KernelCadApi.
internalSpurGear
internalSpurGear(opts: InternalSpurGearOptions): Shape
Build an involute INTERNAL / ring gear as ONE manifold solid: outer rim disk minus a bore whose flanks are the external spur profile mirrored through the pitch circle. Axis +Z, face from z = 0 to z = faceWidth. `rimThickness` (default 2.5·module) is radial stock outside the root. Aliases: `ringGear`, `internalGear`. Pair with external planets at centre distance m(Zring − Zplanet)/2. For a planetary stage enforce `planetaryToothCompatibility({ sunTeeth, planetTeeth, ringTeeth })` so Zring = Zsun + 2·Zplanet.
isoThread
isoThread(spec: string): IsoThreadInfo
Resolve an ISO metric thread designation. `'M6'` takes the ISO 261 coarse pitch (M1–M64 table); `'M6x0.75'` sets the pitch and works for any size (`'M70x4'` for a jar neck). Returns the canonical `spec`, `diameter`, `pitch`, `coarse` / `standard` flags, `pitchDiameter`, `minorDiameter` (D1, the nut bore), `tapDrill` (D − P) and `threadDepth`. Pure data — no geometry.
mass
mass(selection: unknown): RequirementPredicate
Mass of a selection in kg (default 1000 kg/m^3).
meta
meta(metadata: AssetMetadataInput): void
Declare validated content metadata for a catalog asset.
nurbsCurve
nurbsCurve(controlPoints: Vec3[], opts?: {
degree?: number;
weights?: number[];
knots?: number[];
closed?: boolean;
}): Curve3D
NURBS Slice B: a 3D parametric curve specified by an explicit `Geom_BSplineCurve` control net. `degree` defaults to 3 (cubic). Pass `weights` for a rational curve, `knots` for a custom knot vector (otherwise clamped-uniform is generated). Returns a `Curve3D` peer. The curve lowers to a `TopoDS_Edge` and is consumed by `variableSweep` (spine input) and — in later slices — `surfaceFromBoundary`. The proxy also exposes synchronous `sample` / `pointAt` / `tangentAt` / `length`.
nurbsPatchFamily
nurbsPatchFamily(opts: {
controls: Vec3[][];
weights?: number[][];
degree: {
u: number;
v: number;
};
knots?: {
u: number[];
v: number[];
};
periodic?: {
u: boolean;
v: boolean;
};
split: {
direction: 'u' | 'v';
knot?: number;
};
extrusion: Vec3;
tolerance?: number;
}): Shape
Build a solid with degree-5+ NURBS caps split into a shared knot patch family. The lowerer measures the two internal cap seams and emits the achieved class; G4 is reported only when the output passes the common-UV D0–D4 seam instrument.
nurbsSurface
nurbsSurface(opts: {
controls: Vec3[][];
weights?: number[][];
degree: {
u: number;
v: number;
};
knots?: {
u: number[];
v: number[];
};
periodic?: {
u: boolean;
v: boolean;
};
}): SurfaceProxy
W1.3: Build a NURBS surface from an explicit control net + degree. Returns a `Surface` peer to `Shape`. Use `.thicken(t)` to get a closed solid, or `.toShape()` to get a zero-volume single-face shell. `weights` are honored: when supplied, the surface is built rational (OCCT `Geom_BSplineSurface_2`), so exact circles/cylinders/spheres/ conics are representable. Omit `weights` for a non-rational surface.
param
param(name: string, defaultValue: number, meta?: ParamMetadata): ParamRef<number>
param(name: string, defaultValue: boolean, meta?: ParamMetadata): ParamRef<boolean>
param<C extends string>(name: string, defaultValue: C, meta: ParamMetadata & {
choices: readonly C[];
}): TypedParamRef<C>
param(name: string, defaultValue: `#${string}`, meta?: ParamMetadata): TypedParamRef<`#${string}`>
param(name: string, defaultValue: string, meta?: ParamMetadata): TypedParamRef<string>
Declared on KernelCadApi.
params
params<R extends Record<string, number | boolean>>(decl: R): {
[K in keyof R]: ParamRef<R[K]>;
}
Declared on KernelCadApi.
path
path(): PathBuilder
Declared on KernelCadApi.
planeBlendSurface
planeBlendSurface(railA: Curve3D, railB: Curve3D, opts: {
normalA: Vec3;
normalB: Vec3;
handleLengthMm?: number;
}): SurfaceProxy
Build a degree-5 NURBS blend surface between two corresponding straight, parallel rails on planar supports. The two support normals define the support planes; the generated cross-boundary second derivatives are zero at both rails. Sew the result with the two support surfaces, then measure the joined seams before relying on the achieved class. The measured test case reaches G2; this method does not claim G3/G4.
planetaryToothCompatibility
planetaryToothCompatibility(opts: PlanetaryToothCompatibilityOpts): void
Validate coaxial planetary tooth counts: Zring must equal Zsun + 2·Zplanet. Throws `feature.invalid-args` when the pitch circles cannot meet.
presets
presets(presets: AssetPresets): void
Declare named presets for its already-declared parameters.
prismFront
prismFront(points: readonly PolygonPoint[], x0: number, x1: number): Shape
Front-view mask prism: points are (Y, Z), extruded along X from x0..x1.
prismPlan
prismPlan(points: readonly PolygonPoint[], z0: number, z1: number): Shape
Plan-view mask prism: points are (X, Y), extruded along Z from z0..z1.
prismSide
prismSide(points: readonly PolygonPoint[], halfY?: number): Shape
Side-view mask prism: polygon points are (station s, height z), extruded through Y from -halfY to +halfY (default 1200). The polygon lies on the XZ plane, so the shape reads like a side elevation.
prismSideY
prismSideY(points: readonly PolygonPoint[], y0: number, y1: number): Shape
Side-view mask prism on one side only: Y spans y0..y1 (y1 > y0).
referenceImage
referenceImage(path: string, opts: {
plane: PlaneSpec;
anchor?: 'origin' | [
number,
number,
number
];
scale?: ReferenceImageScale;
opacity?: number;
flipU?: boolean;
flipV?: boolean;
}): ReferenceImageHandle
Slice A: overlay a reference image on a plane for tracing or design review. The record is virtual — no OCCT geometry is produced; the renderer reads the image directly from the feature graph. Validation errors (missing file, bad format, invalid plane) are pushed as structured diagnostics on the returned handle's record rather than thrown — so agents can inspect and correct them incrementally.
require
require(name: string, predicate: RequirementPredicate): void
Declare a named, kernel-measured requirement. The predicate is authored with the helper globals below and reports into the same `requirements` ledger as `dfmSpec`, `feaStudy.minSafetyFactor` and mechanical intent. Example: require('bolt-clearance', clearance(faces(bracket, { ofSurfaceType: 'CYLINDER' }), housing).gte(1.0)); require('hole-count', count(faces(plate, { ... })).eq(4)); require('wall-band', volume(body).between(1200, 1800)); A requirement without a comparison THROWS (an enforcement gate must not silently disable itself). Each evaluation returns a `requirements` block with status / measured / limit / margin and the S1 fingerprints of the selections involved.
ringGear
ringGear(opts: InternalSpurGearOptions): Shape
Declared on KernelCadApi.
select
select<T>(items: Iterable<T>): ShapeList<T>
Wrap any array of topology query results in a `ShapeList` so the selector algebra applies — face summaries, `Query.evaluate(scene)` results, or a hand-assembled list. `selectEdges` already returns one.
selectEdge
selectEdge(shape: Shape, query: EdgeQuery): Promise<EdgeSegment>
Declared on KernelCadApi.
selectEdges
selectEdges(shape: Shape, query?: EdgeQuery): Promise<ShapeList<EdgeSegment>>
Pre-select edges by EdgeQuery. Returns a `ShapeList` — still an `EdgeSegment[]` everywhere one is expected, plus the selector algebra (`sortBy` / `groupBy` / `filterBy` / `filterByPosition` / `sortByDistance` and the `first` / `last` / `at` / `take` accessors).
setCameraDistance
setCameraDistance(distance: number): CameraTargetHandle
Override the camera framing distance (mm from target). Convenience wrap over the optional `distance` field on the underlying cameraTarget record — pulls the current camera target (or [0, 0, 0] if no setCameraTarget call has been made) and attaches the supplied distance. Used to push or pull the camera relative to the auto-fit when the extents-projection fit reads too tight or too loose at the chosen pose / aspect.
setCameraTarget
setCameraTarget(x: number, y: number, z: number): CameraTargetHandle
Override the camera look-at target for setRenderPose / engineering-view renders. Default behavior (no call) is to aim the camera at the bbox centroid; that auto-fit skews when geometry is highly asymmetric (tall pendants, off-centre eyepieces). Pass an explicit (x, y, z) to re-aim. Multiple calls register multiple records; the renderer applies the last one at render time. Validation errors (non-finite coords, negative distance) are stashed on `handle.metadata.diagnostics` rather than thrown — a default-safe record (target = bbox centroid axis-by-axis) is still produced.
setRenderEnvironment
setRenderEnvironment(spec: RenderEnvironmentSpec): RenderEnvironmentHandle
Set the HDRI / IBL lighting environment for the rendered scene. Pass either a built-in preset key or a `.hdr` URL; intensity (default 1.0) scales `envMapIntensity` on all PBR materials, and rotation (degrees, default 0) rotates the env map around the world Y axis. Default behavior (script never calls this) is the existing three-light rig — no env map applied. Multiple calls register multiple records; the last one wins at render time.
sew
sew(surfaces: SurfaceProxy[], opts?: {
tolerance?: number;
requireClosed?: boolean;
continuity?: 'G0' | 'G1' | 'G2' | 'G3' | 'G4';
}): Shape
NURBS Slice E: stitch N surfaces into a shell or closed solid. Lowers to OCCT `BRepBuilderAPI_Sewing` (Task 5). Returns a `Shape` so the result flows directly into boolean ops, export, and fillet pipelines. Edges within `opts.tolerance` mm of each other are stitched together. `opts.continuity` requests a minimum G0–G4 class on every shared seam; lowering measures and reports the achieved class and warns if it is below the request. If `opts.requireClosed` is true and the result is still an open shell at lower time, the lowerer emits `feature.surface-sew.open-shell` (severity 'error') instead of returning a partial solid.
sheetMetal
sheetMetal(profile: Sketch, opts: SheetMetalOpts): Shape
W2.2: Build a sheet-metal body from a closed planar Sketch. Reuses the sketch→extrude pipeline at depth = `thickness`; tags the record as `kind: 'sheetMetal'` so the lowerer threads sheet-metal canonical face labels and stores `kFactor` for downstream `.bend()` math. Bend-allowance math (K-factor approximation, used by `.bend()`): `BA = (π · |angle_deg| / 180) · (kFactor · thickness + radius)` Slice-1 limits: planar profile only; `radius >= 0.5 · thickness` for reliable sewing; flatten-pattern supports <= 2 bends.
sphere
sphere(r: Editable<number>, opts?: FaceLabelOpts): Shape
Sphere centred on the origin (all three axes).
spline3d
spline3d(points: Vec3[], opts?: {
tension?: number;
closed?: boolean;
}): Curve3D
NURBS Slice B: Catmull-Rom convenience that interpolates the supplied points through a cubic NURBS curve. Returns a `Curve3D`. Equivalent to `nurbsCurve(controlNet, { degree: 3 })` after a Catmull-Rom-to-Bezier conversion; see implementation comments for the formula.
spring
spring(opts: SpringOptions): Shape
Build a physical helical spring as a swept circular wire along a helix. Default axis is +Z; use axis 'X' for Anglepoise-style balance springs along lamp arms.
spurGear
spurGear(opts: SpurGearOptions): Shape
Build an involute spur gear as ONE manifold solid: the tooth is generated by the standard basic rack (true involute above the base circle, trochoid root fillet, correct undercut below ~17 teeth at 20°). Axis +Z, face from z = 0 to z = faceWidth, tooth 0 centred on +X. Two gears of equal module and pressure angle mesh at centre distance m(z1 + z2)/2. Place the second gear at +X and rotate it by 180/z2 degrees when z2 is even (0 when odd) so a tooth space faces the first gear.
surfaceFromBoundary
surfaceFromBoundary(curves: [
Curve3D,
Curve3D,
Curve3D,
Curve3D
], opts?: {
continuity?: 'C0' | 'C1' | 'C2' | ('C0' | 'C1' | 'C2')[];
sampling?: number;
}): SurfaceProxy
NURBS Slice C: build the shipped filling surface: one NURBS face through 4 boundary curves. The 4 curves must be passed in exact loop order: curves[0] = bottom, curves[1] = right, curves[2] = top, curves[3] = left. Adjacent endpoints must coincide within 1e-6 mm (the kernel emits `feature.surface-from-boundary.corner-mismatch` otherwise). `opts.continuity` defaults to C0. C1/C2 requests fail at capture with `feature.surface-from-boundary.continuity-unverified`: this operation receives boundary curves but no neighboring support surfaces, so it cannot promise continuity across those boundaries. `opts.sampling` controls `NbPtsOnCur` (defaults to 15 at lower time). Returns a `Surface` peer to `Shape`. Use `.thicken(t)` to get a closed solid, or `.toShape()` to wrap as a zero-volume single-face shell.
surfaceFromCurves
surfaceFromCurves(sections: Sketch[]): SurfaceProxy
W1.3: Skin a NURBS surface through a sequence of Sketch sections in order. Each section's lifted profile becomes a transverse cross-section of the resulting surface. Returns a `Surface` peer to `Shape`.
surfaceIntersection
surfaceIntersection(a: Shape | SurfaceProxy, b: Shape | SurfaceProxy): Promise<Curve3D[]>
Exact surface–surface (or face–face) intersection via OCCT `BRepAlgoAPI_Section`. Returns one Curve3D per section edge.
threadedRod
threadedRod(opts: ThreadedRodOptions): Shape
A real ISO metric EXTERNAL thread: 60° basic profile, right-hand, axis +Z from z = 0 to z = `length`, ridge centre crossing +X at every z = k·pitch (so a `threadedHole` whose entry face sits at a whole number of pitches mates in phase). Built as ONE screw sweep of the thread's transverse section, so it is a valid solid that unions, subtracts and exports STEP. `chamfer: true` adds 45° ends down to the root (one extra boolean). `cosmetic: true` returns a plain major-diameter cylinder carrying the thread spec as metadata. `clearance` takes play off the external thread (FDM fits).
torus
torus(majorR: number, minorR: number, segments?: number): Shape
Solid torus centered on world origin, axis along world +Z. Built via `path().circle(majorR, 0, minorR).revolve()` — a polyline approximation of the minor-radius profile revolved 360° about Z. Surfaced 2× in agent-eval (eyebolt + others): there was no convenience primitive for this canonical rotational shape; agents emitted trig in TS to build the polyline circle by hand.
tube
tube(name: string, opts: TubeOptions): Shape
Bent tube between two ends: straight legs joined by constant-radius bends, built as one hollow solid in assembly space. `from` / `to` are `part.port(name)` or `{ point, axis? }`; `via` lists the corner points in order. `bendRadius` is the centreline radius; `od` defaults to the port size. Add the returned Shape to the assembly with `asm.part(name, shape)` and no `at`. Malformed input throws `feature.invalid-args` with a `tube.*` message prefix.
tubeSpec
tubeSpec(spec: TubeSpec): {
id: FeatureId;
metadata: TubeSpecMetadata;
}
Declare the bending and clearance rules every `tube()` in the script must meet. `systems` overrides the bend and straight rules for the tubes of one fluid system. Virtual record; malformed input throws `feature.invalid-args` (an enforcement gate must not be silently disabled).
union
union(...shapes: Shape[]): Shape
Declared on KernelCadApi.
variableSweep
variableSweep(spine: Curve3D | Sketch | Vec3[], sections: Array<{
t: number;
profile: Sketch;
}>, opts?: {
closed?: boolean;
continuity?: 'C0' | 'C1' | 'C2';
}): Shape
NURBS Slice B: multi-section sweep. Sweeps each `section.profile` along the `spine`, blending between sections at the section's `t ∈ [0, 1]` spine parameter. Lowers to `BRepOffsetAPI_MakePipeShell` (direct OCCT — no replicad wrapper). `spine` accepts a `Curve3D`, a planar `Sketch` (its lifted wire is used as the rail), or a `Vec3[]` (auto-converted to a `nurbsCurve` of degree `min(3, points.length - 1)`). Sections must be strictly increasing in `t`; the first section MUST sit at `t = 0` and the last at `t = 1`. Intermediate sections in `(0, 1)` are supported: the lowerer subdivides the spine at each station so the profile anchors to a real spine vertex. `t` is the spine's normalized curve parameter (the same mapping as `Curve3D.pointAt`), not normalized arc length. Continuity defaults to `'C1'`. C1/C2 are mapped to OCCT transition modes, then the lowerer measures NURBS station seams and reports the achieved class; C2 asks for at least measured G2.
volume
volume(selection: unknown): RequirementPredicate
Volume of a selection in mm^3.