docs / Curves & surfaces
Curves & surfaces
NURBS curves and surfaces, plus the evaluators for measuring them before they become solids.
Curves and surfaces are measurable before they become solids. pointAt() reads a point off the curve; thicken() turns the surface into one.
const rail = nurbsCurve([
[0, 0, 0],
[30, 0, 20],
[60, 20, 20],
[80, 40, 0],
]);
const mid = rail.pointAt(0.5);
if (mid.length !== 3) {
throw new Error('pointAt should return a 3D point');
}
const panel = nurbsSurface({
controls: [
[[0, 0, 0], [0, 30, 10], [0, 60, 0]],
[[30, 0, 12], [30, 30, 26], [30, 60, 12]],
[[60, 0, 0], [60, 30, 10], [60, 60, 0]],
],
degree: { u: 2, v: 2 },
});
return panel.thicken(2).color('beam');Calls
| Call | What it does |
|---|---|
nurbsCurve(controlPoints: Vec3[], opts?: { degree?: number; weights?: number[]; knots?: number[]; closed?: boolean }) => Curve3D | 3D parametric NURBS curve specified by an explicit Geom_BSplineCurve control net. |
spline3d(points: Vec3[], opts?: { tension?: number; closed?: boolean }) => Curve3D | Catmull-Rom-to-cubic-Bezier convenience that interpolates the supplied points through a cubic NURBS curve. |
hermiteG2(a: { point: Vec3; tangent: Vec3; curvature?: Vec3 }, b: { point: Vec3; tangent: Vec3; curvature?: Vec3 }) => Curve3D | Quintic Hermite Curve3D that interpolates the two endpoints with matching positions, first derivatives (tangents), and second derivatives (curvatures). |
PathBuilder.hermiteG2(a: HermiteEndpoint2D, b: HermiteEndpoint2D) => PathBuilder | NURBS Slice D — 2D quintic-Hermite transition between two endpoints, each with prescribed point + first derivative (tangent) + optional second derivative (curvature). |
nurbsSurface({ controls, degree, weights?, knots?, periodic? }) => Surface | Build a NURBS surface from an explicit control net + degree. |
surfaceFromCurves(sections: Sketch[]) => Surface | Skin a NURBS surface through 2+ closed Sketch cross-sections in declaration order. |
surfaceFromBoundary(curves: [Curve3D, Curve3D, Curve3D, Curve3D], opts?: { continuity?: "C0" | "C1" | "C2" | ("C0" | "C1" | "C2")[]; sampling?: number }) => Surface | Build the shipped filling surface: one NURBS face through 4 boundary curves. |
sew(surfaces: Surface[], opts?: { tolerance?: number; requireClosed?: boolean }) => Shape | Stitch N surfaces into a shell or closed solid via OCCT BRepBuilderAPI_Sewing. |
Surface.thicken(t: Editable<number>) => Shape | Offset both sides of this surface by t mm and return the closed solid Shape. |
Surface.toShape() => Shape | Wrap this surface as a single-face zero-volume Shape (TopoDS_Shell). |
Surface.trimTo(by: Surface) => Surface | Trim this surface at its intersection with by (a Surface cutter) and return a new Surface representing the kept half. |
Surface.split(by: Surface) => [Surface, Surface] | Split this surface at its intersection with by (a Surface cutter) and return both resulting Surface halves as [first, second], ordered by descending face area. |
Shape.projectCurve(opts: { source: ProjectCurveSource; face: FaceSelector | string; scaleMode?: 'original' | 'native' | 'bounds'; asEdge?: boolean }) => Sketch | Wrap a 2D closed curve onto a 3D face along the face normal. |
Curve3D.sample(n: number) => [number, number, number][] | Sample n + 1 evenly-spaced points along the curve in the public [0, 1] parameter domain. |
Curve3D.pointAt(t: number) => [number, number, number] | World-space point on the curve at parameter t ∈ [0, 1] (clamped). |
Curve3D.tangentAt(t: number) => [number, number, number] | Unit tangent vector at parameter t ∈ [0, 1] (clamped). |
Curve3D.domain() => [number, number] | Parametric domain. |
Curve3D.analytics.closestPoint(pt: Vec3, opts?: { tolerance?: number }) => Vec3 | World-space closest point on the curve to the query pt (Newton-Raphson). |
Curve3D.analytics.closestParam(pt: Vec3, opts?: { tolerance?: number }) => number | Parametric coordinate t ∈ [0, 1] of the closest point on the curve to pt. |
Curve3D.analytics.divideByEqualArcLength(n: number) => CurveLengthSample[] | Divide the curve into n equal-arc-length segments; returns n + 1 { t, pt, arcLength } samples covering both endpoints. |
Curve3D.analytics.divideByArcLength(arcLength: number) => CurveLengthSample[] | Sample the curve every arcLength mm starting from t = 0. |
Curve3D.analytics.derivatives(t: number, numDerivs?: number) => Vec3[] | Evaluate the curve and its first numDerivs derivatives at t ∈ [0, 1]. |
Curve3D.analytics.tessellate(opts?: { tolerance?: number }) => Vec3[] | Adaptive polyline approximation of the curve at the given tolerance (mm). |
Shape.intersect(...others) => Shape | Boolean intersection. |
Curve3D.analytics.intersect(other: Curve3D | Surface, opts?: { tolerance?: number }) => CurveCurveIntersection[] | CurveSurfaceIntersection[] | Geometric intersection of this curve with another Curve3D (returns { tA, tB, ptA, ptB, distance } records) or with a Surface from nurbsSurface() (returns { tCurve, uv, pt } records). |