ParaShape

Compute

The standalone compute substrate: 133 pure geometry/value functions exported by @parashape/parametric/compute — value in, value out, no engine coupling (no registry, no Store, no node classes). This is the surface a node registry wires into its definitions (@parashape/parametric/nodes does exactly that) and the surface another project reuses without adopting the node catalog. Namespaced per domain module — function names are only unique WITHIN a module.

axis · 5

import { axis } from "@parashape/parametric/compute" // axis.direction(…)
FunctionSignatureDescription
directiondirection(axis: Axis): Vector3DThe axis's unit direction vector.
fromPointDirectionfromPointDirection(origin: Point3D, direction: Vector3D): Axis── Constructors ─────────────────────────────────────────────────── Build an axis from an origin point and a direction; the direction is normalized.
fromTwoPointsfromTwoPoints(from: Point3D, to: Point3D): AxisBuild an axis from a start point through a second point; direction = (to−from) normalized.
originorigin(axis: Axis): Point3D── Accessors ────────────────────────────────────────────────────── The axis's origin point.
pointAtpointAt(axis: Axis, distance: number): Point3DThe point on the axis at an arc-length distance from the origin.

curve · 28

import { curve } from "@parashape/parametric/compute" // curve.arcCenterStartEnd(…)
FunctionSignatureDescription
arcCenterStartEndarcCenterStartEnd(center: number[], start: number[], end: number[]): CurveJSON
arcTangentEndarcTangentEnd(axis: Axis, end: number[]): CurveJSONArc defined by a start axis (origin = start point, direction = leaving tangent) and an end point.
arcThreePointsarcThreePoints(start: number[], middle: number[], end: number[]): CurveJSON
circlecircle(center: number[], radius: number): CurveJSON
closestPointclosestPoint(curve: CurveLike, point: Point3D): Point3D
cubicBeziercubicBezier(start: number[], control1: number[], control2: number[], end: number[]): CurveJSON
curveChamfercurveChamfer(curve: CurveJSON, distance: number, vertexFilter?: (p: Point3D, i: number) => boolean): CurveJSONBevel selected polyline corners with a straight setback.
curveFilletcurveFillet(curve: CurveJSON, radius: number, vertexFilter?: (p: Point3D, i: number) => boolean): CurveJSONRound selected polyline corners with an arc of the given radius.
curveIntersectcurveIntersect(self: unknown, curve: unknown): CurveJSON[]
curveSelfUnionImplcurveSelfUnionImpl(curves: unknown): CurveJSON[]Self-union (reduce n→m): fold the OWN closed curves/regions into merged region boundary loop(s).
curveSplitcurveSplit(curve: CurveJSON, parameter: number): CurveJSON[]Split a curve at param t (0–1) → two curves.
curveSubtractcurveSubtract(self: unknown, curve: unknown): CurveJSON[]
curveUnioncurveUnion(self: unknown, curve: unknown): CurveJSON[]
dividedivide(curve: CurveLike, count: number): Point3D[]
ellipseArcellipseArc(center: number[], xAxis: number[] | number, yAxis: number[] | number, angle?: unknown): CurveJSONElliptical arc — angle = 360 → full closed ellipse, < 360 → open arc.
endPointendPoint(curve: CurveLike): Point3D
lengthlength(curve: CurveLike): number
nurbsCurvenurbsCurve(points: number[][], degree?: unknown, knots?: number[], weights?: number[]): CurveJSON
pointAtpointAt(curve: CurveLike, parameter: number): Point3D
pointAtLengthpointAtLength(curve: CurveLike, distance: number): Point3D
polygonpolygon(center: number[], radius: number, sides: number): CurveJSON
polylinepolyline(points: number[][], closed?: unknown): CurveJSON── Generators (open/closed 1D wires → CurveJSON) ──────────────────
quadraticBezierquadraticBezier(start: number[], control: number[], end: number[]): CurveJSON
rectanglerectangle(point1: number[], point2: number[]): CurveJSONClosed planar loops — fill them with `face.fill` (or feed straight into extrude/loft, which auto-fill a closed curve).
splinespline(points: number[][], degree?: unknown): CurveJSON
startPointstartPoint(curve: CurveLike): Point3D
tangentAttangentAt(curve: CurveLike, parameter: number): Vector3D
textCurvetextCurve(font: FontData | null | undefined, content: string, fontSize: number): CurveJSON[]Text → outline loops (one curve per letter contour, holes as separate loops).

entities · 3

import { entities } from "@parashape/parametric/compute" // entities.addMesh(…)
FunctionSignatureDescription
addMeshaddMesh(faces: EntityJSON | EntityJSON[] | null | undefined): EntityJSON[]── Mesh (baked entities literal → renderable, transformable) ───── A generator (return "entity") whose `faces` arg is a LITERAL baked entity array (NOT a node ref): the entities travel in the expression itself (`[{geo…
cloneclone(source: EntityJSON | EntityJSON[] | null | undefined): EntityJSON[]── Clone (another node → independent deep copy) ────────────────── A generator (return "entity") whose `source` arg references ANOTHER node's output.
placeModelplaceModel(source: EntityJSON | EntityJSON[] | string | null | undefined): EntityJSON[]── placeModel (string model ID → placed, independent copy) ────── A `placeModel` GENERATOR's `source` arg is a STRING model ID.

entity · 13

import { entity } from "@parashape/parametric/compute" // entity.entitiesBoundingBox(…)
FunctionSignatureDescription
entitiesBoundingBoxentitiesBoundingBox(entities: EntityJSON[]): BoundingBox | nullShared bbox utility — reused by `resize` here and by the lengthX/Y/Z auto-seed helper (Model.ts) and hosts that need a world-space envelope (apps/sketchup's SketchUpHost) instead of each hand-rolling a min/max loop.
flipflip(entity: EntityJSON, plane: Plane): EntityJSONReflect an entity across a plane (Hessian [nx,ny,nz,d]).
layerlayer(entity: EntityJSON, name: string): EntityJSON
materialmaterial(entity: EntityJSON, name: string): EntityJSON── Properties (immutable apply) ───────────────────────────────────
movemove(entity: EntityJSON, vector: Vector3D): EntityJSON
moveMatrixmoveMatrix(vector: Vector3D): Transformation── Transforms (per-entity) ──────────────────────────────────────── Matrix builders — the single source of truth for the move/rotate transforms, reused both as per-entity ops (below) and as whole-array transforms (tra…
namename(entity: EntityJSON, text: string): EntityJSON
reflectionMatrixreflectionMatrix(plane: Plane): TransformationReflect-across-a-plane matrix builder — the SSOT for both the per-entity `flip` (below) and the Instance-placement `mirror` (entities.ts).
reversereverse(entity: EntityJSON, enabled?: number | boolean): EntityJSONReverse a single entity's direction/winding (1→1), flipping its outward normal.
rotaterotate(entity: EntityJSON, axis: Axis, degree: number): EntityJSONRotate about an axis (origin = pivot point, direction = rotation axis).
rotateMatrixrotateMatrix(axis: Axis, degree: number): Transformation
transformEntitytransformEntity(e: EntityJSON, tr: Transformation): EntityJSON
visiblevisible(entity: EntityJSON, enabled: number | boolean): EntityJSON

face · 19

import { face } from "@parashape/parametric/compute" // face.asPathShapes(…)
FunctionSignatureDescription
asPathShapesasPathShapes(input: unknown): FaceJSON[]Like asShapes(), but curves keep their own open/closed topology (via asOpenPath) instead of being force-closed — curveThicken strokes a path, it doesn't fill a boundary.
asShapesasShapes(input: unknown): FaceJSON[]
bakedPathbakedPath(face: FaceJSON): PolyShapeThe 2D PolyShape of a face in its own plane coords.
coplanarGroupscoplanarGroups(regions: FaceJSON[]): FaceJSON[][]Partition regions into coplanar groups (first member = the group's plane representative).
faceOffsetfaceOffset(face: FaceJSON, distance: number): FaceJSONInset (positive distance) or outset (negative distance) a planar face's boundary.
fillfill(curve: CurveJSON | CurveJSON[]): FaceJSON── Generators ───────────────────────────────────────────────────── Fill a closed curve loop (or curves forming a loop) into a planar region.
fromPolyShapefromPolyShape(shapes2d: Shape2d[], uvMatrix?: Transformation): FaceGeometryFor each result Shape2d, sample its boundary to polygon VERTICES (any arc segment is tessellated at a sane chord tolerance), unproject 2D→3D via the frame, producing 3D world loops.
newellNormalnewellNormal(loop: Point3D[]): Point3D── Plane fitting (when uvMatrix is absent) ────────────────────────
planarIntersectplanarIntersect(a: FaceJSON, other: unknown): FaceJSON
planarOffsetAllplanarOffsetAll(faces: FaceJSON[], distance: number): FaceJSONOffset ALL coplanar faces together, in ONE combined PolyShape (the group's shared frame) — same "process the coplanar group as one unit" principle as planarUnionAll: disjoint shapes that grow into overlap after offset…
planarSubtractplanarSubtract(a: FaceJSON, other: unknown): FaceJSON── Modifiers (per-entity) ─────────────────────────────────────────
planarThickenAllplanarThickenAll(faces: FaceJSON[], distance: number, joinType: OffsetJoinType, endType: OffsetEndType): FaceJSONThicken ALL coplanar paths together into one combined closed-strip outline — same grouping principle as planarOffsetAll/planarUnionAll.
planarUnionplanarUnion(a: FaceJSON, other: unknown): FaceJSON
planarUnionAllplanarUnionAll(faces: FaceJSON[]): FaceJSONUnion of MANY coplanar faces in ONE Clipper call (NonZero fill — see normalizedPathIn).
planeMatrixplaneMatrix(face: FaceJSON): TransformationThe face's frame, as a uvMatrix (used to place boolean results back in 3D).
planeNormalplaneNormal(face: FaceJSON): Point3D
reverseShapereverseShape(e: FaceJSON): FaceJSONReverse loop winding/direction.
toPolylines3DtoPolylines3D(s: FaceJSON): Ring3D[]
toPolyShapetoPolyShape(face: FaceJSON): PolyShapeBuild a 2D PolyShape from a face: project each 3D loop to 2D via the face frame (drop z).

faceValue · 4

import { faceValue } from "@parashape/parametric/compute" // faceValue.area(…)
FunctionSignatureDescription
areaarea(face: FaceGeometry): numberArea of the face (outer loop minus holes).
centroidcentroid(face: FaceGeometry): Point3DCentroid of the outer loop vertices.
containscontains(face: FaceGeometry, point: Point3D): booleanTrue if a point lies inside the face (within the outer loop, outside holes), projected onto the face's plane.
normalnormal(face: FaceGeometry): Vector3DUnit outward normal of the face's plane (from the outer loop).

font · 4

import { font } from "@parashape/parametric/compute" // font.getFallbackFont(…)
FunctionSignatureDescription
getFallbackFontgetFallbackFont(): FontData | null
parseparse(buffer: ArrayBuffer): FontData
setFallbackFontsetFallbackFont(font: FontData): void
textCleantextClean(font: FontData, content: string, fontSize: number): Shape2d[]Convert text to clean (boolean-unioned) Shape2d subpaths.

layer · 1

import { layer } from "@parashape/parametric/compute" // layer.createLayer(…)
FunctionSignatureDescription
createLayercreateLayer(name: string): LayerJSON── Generators ─────────────────────────────────────────────────────

material · 1

import { material } from "@parashape/parametric/compute" // material.createMaterial(…)
FunctionSignatureDescription
createMaterialcreateMaterial(name: string, baseColor?: string, opacity?: unknown, texture?: string | null, colorFactor?: unknown): MaterialJSON── Generators ─────────────────────────────────────────────────────

parameter · 16

import { parameter } from "@parashape/parametric/compute" // parameter.angle(…)
FunctionSignatureDescription
angleangle(v: unknown): number
areaarea(v: unknown): number
booleanboolean(v: unknown): boolean
colorcolor(v: unknown): string── Color ────────────────────────────────────────────────────────── Color is stored as a hex string (#rrggbb).
currencycurrency(v: unknown): number
fnfn(v: unknown): unknown── Pass-through (handled by ParameterNode async) ──────────────────
fontfont(v: unknown): unknown
groupgroup(v: unknown): unknown
lengthlength(v: unknown): number
massmass(v: unknown): number
modelmodel(v: unknown): unknown
numbernumber(v: unknown): number── Scalar ─────────────────────────────────────────────────────────
objectobject(v: unknown): unknown
stringstring(v: unknown): string
texttext(v: unknown): string
volumevolume(v: unknown): number

plane · 4

import { plane } from "@parashape/parametric/compute" // plane.distance(…)
FunctionSignatureDescription
distancedistance(plane: Plane, query: Point3D): numberSigned distance from the plane to a query point (positive = normal side).
fromPointNormalfromPointNormal(point: Point3D, normal: Vector3D): Plane── Constructors ─────────────────────────────────────────────────── Build a plane from a point on it and its normal.
normalnormal(plane: Plane): Vector3D── Accessors ────────────────────────────────────────────────────── The unit normal of the plane.
pointpoint(plane: Plane): Point3DA point on the plane (the one passed to fromPointNormal).

point · 5

import { point } from "@parashape/parametric/compute" // point.distance(…)
FunctionSignatureDescription
distancedistance(from: Point3D, to: Point3D): numberPoint math (Point.* expression namespace) + a render generator that emits Point marker entities for visualizing positions.
interpolateinterpolate(from: Point3D, to: Point3D, fraction: number): Point3D
midpointmidpoint(from: Point3D, to: Point3D): Point3D
pointEntitypointEntity(positions: Point3D[]): PointJSON[]── Generators (primitive → renderable marker entity) ──────────────
translatetranslate(point: Point3D, offset: Vector3D): Point3D

solid · 8

import { solid } from "@parashape/parametric/compute" // solid.asFaces(…)
FunctionSignatureDescription
asFacesasFaces(input: unknown): FaceJSON[]Collect the Face faces from a value (single, array, or nested).
facesToMeshfacesToMesh(faces: FaceJSON[]): MeshA solid's faces → a welded half-edge Mesh — the EXPENSIVE promotion (`toMesh()` = toJSON's 1e-6 vertex weld + fromPolygonMesh's T-junction stitch + half-edge build), required by the topology ops below.
facesToPolygonMeshfacesToPolygonMesh(faces: FaceJSON[]): PolygonMeshA solid's faces → a PolygonMesh, constructed DIRECTLY (Point loops, no index pool, no weld — PolygonMesh 0.10 stores faces independently).
markWholeArraymarkWholeArray(fn: T): T & { wholeArray: true }── Whole-array modifiers (operate on the parent's whole face-set) ── Marked `.wholeArray` so the engine passes the entire array (one solid) at once instead of mapping per-face.
meshToFacesmeshToFaces(mesh: Mesh): FaceJSON[]A Mesh → its faces as Face[].
nurbsToFacesnurbsToFaces(nurbs: NurbsSurfaceJSON): FaceJSON[]Tessellate a kernel NurbsSurface to a triangle mesh, then emit one planar face per triangle.
solidSelfUnionImplsolidSelfUnionImpl(faces: FaceJSON[]): FaceJSON[]Fold all solids in one Face[] into a single fused solid (n→1).
sweepsweep(pathArg: unknown, profileArg: unknown, caps?: unknown): FaceJSON[]

surface · 6

import { surface } from "@parashape/parametric/compute" // surface.asPaths(…)
FunctionSignatureDescription
asPathsasPaths(input: unknown): CurveJSON[]
hydrateCurveshydrateCurves(input: unknown): NurbsCurve[]
loftloft(curves: unknown, degree?: unknown): FaceJSON[]── Generators ───────────────────────────────────────────────────── NurbsSurface is no longer a scene entity.
patchFromCornerspatchFromCorners(corner0: Point3D, corner1: Point3D, corner2: Point3D, corner3: Point3D): FaceJSON[]
patchFromCurvepatchFromCurve(curves: unknown): FaceJSON[]
revolverevolve(curves: unknown, axis: Axis, angle: number): FaceJSON[]Revolve profile curve(s) about an axis (origin = a point on it, direction = spin axis).

surfaceValue · 5

import { surfaceValue } from "@parashape/parametric/compute" // surfaceValue.area(…)
FunctionSignatureDescription
areaarea(surface: NurbsSurfaceJSON): numberTotal surface area.
curvaturecurvature(surface: NurbsSurfaceJSON, u: number, v: number): numberMean curvature of the surface at (u, v).
isocurveisocurve(surface: NurbsSurfaceJSON, parameter: number, direction: "u" | "v"): CurveJSONIsocurve at `parameter` (0..1) in the given direction ("u" | "v") → a curve.
normalAtnormalAt(surface: NurbsSurfaceJSON, u: number, v: number): Vector3DUnit normal of the surface at (u, v).
pointAtpointAt(surface: NurbsSurfaceJSON, u: number, v: number): Point3DPoint on the surface at parameters (u, v) ∈ [0,1]².

vector · 9

import { vector } from "@parashape/parametric/compute" // vector.add(…)
FunctionSignatureDescription
addadd(left: Vector3D, right: Vector3D): Vector3D
angleangle(from: Vector3D, to: Vector3D): number
betweenbetween(from: Point3D, to: Point3D): Vector3D
crosscross(left: Vector3D, right: Vector3D): Vector3D
dotdot(left: Vector3D, right: Vector3D): number
lengthlength(vector: Vector3D): numberVector math (Vector.* expression namespace) — pure value→value, clear arg names (no a/b/v).
normalizenormalize(vector: Vector3D): Vector3D
scalescale(vector: Vector3D, factor: number): Vector3D
subtractsubtract(left: Vector3D, right: Vector3D): Vector3D

root exports · 2

import { bakeGroup, render } from "@parashape/parametric/compute"
FunctionSignatureDescription
bakeGroupbakeGroup(entity: EntityJSON, definitions?: DefinitionMap, inherited?: Inherited, deep?: unknown): EntityJSON[]Bake a (possibly nested) entity into a flat list of renderable leaf entities by exploding every groupEntity (resolving its definition from `definitions`).
renderrender(e: EntityJSON): SceneEntity