okgeometry-api 1.2.1 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/NurbsCurve.ts CHANGED
@@ -1,14 +1,14 @@
1
1
  import { ensureInit } from "./engine.js";
2
2
  import { Point } from "./Point.js";
3
- import { Vec3 } from "./Vec3.js";
4
- import { Plane } from "./Plane.js";
5
- import { Mesh } from "./Mesh.js";
6
- import { Polyline } from "./Polyline.js";
7
- import { PolyCurve } from "./PolyCurve.js";
8
- import type { Line } from "./Line.js";
9
- import type { Arc } from "./Arc.js";
10
- import type { CurveOffsetOptions, RotationAxis } from "./types.js";
11
- import * as wasm from "./wasm-bindings.js";
3
+ import { Vec3 } from "./Vec3.js";
4
+ import { Plane } from "./Plane.js";
5
+ import { Mesh } from "./Mesh.js";
6
+ import { Polyline } from "./Polyline.js";
7
+ import { PolyCurve } from "./PolyCurve.js";
8
+ import type { Line } from "./Line.js";
9
+ import type { Arc } from "./Arc.js";
10
+ import type { CurveOffsetOptions, RotationAxis } from "./types.js";
11
+ import * as wasm from "./wasm-bindings.js";
12
12
 
13
13
  /**
14
14
  * Non-Uniform Rational B-Spline (NURBS) curve backed by WASM.
@@ -155,83 +155,129 @@ export class NurbsCurve {
155
155
  );
156
156
  }
157
157
 
158
- /**
159
- * Offset this curve by a distance.
160
- * Note: NURBS offset is approximated by sampling and offsetting as polyline.
161
- * @param distance - Offset distance
162
- * @param normal - Reference normal for determining offset direction
163
- * @param samples - Number of sample points (default 64)
164
- * @param arcSamples - Number of samples per exact arc segment in the returned polyline(s)
165
- * @param options - Offset options such as join style
166
- * @returns Offset polyline approximation
167
- */
168
- offset(
169
- distance: number,
170
- normal?: Vec3,
171
- samples = 64,
172
- arcSamples = 32,
173
- options: CurveOffsetOptions = {},
174
- ): Polyline {
175
- const results = this.offsetAll(distance, normal, samples, arcSamples, options);
176
- if (results.length === 1) return results[0];
177
- if (results.length === 0) {
178
- throw new Error("NurbsCurve.offset() collapsed and produced no valid result polylines");
179
- }
180
- throw new Error(
181
- `NurbsCurve.offset() produced ${results.length} result polylines. Use NurbsCurve.offsetAll() instead.`,
182
- );
183
- }
184
-
185
- /**
186
- * Offset this curve by a distance and return every sampled result polyline.
187
- * Note: NURBS offset is approximated by sampling and offsetting as polyline.
188
- * @param distance - Offset distance
189
- * @param normal - Reference normal for determining offset direction
190
- * @param samples - Number of sample points used to approximate the source curve
191
- * @param arcSamples - Number of samples per exact arc segment in the returned polylines
192
- * @param options - Offset options such as join style
193
- * @returns Every valid offset polyline approximation
194
- */
195
- offsetAll(
196
- distance: number,
197
- normal?: Vec3,
198
- samples = 64,
199
- arcSamples = 32,
200
- options: CurveOffsetOptions = {},
201
- ): Polyline[] {
202
- const pts = this.sample(samples);
203
- const pl = new Polyline(pts);
204
- return pl.offsetAll(distance, normal, arcSamples, options);
205
- }
206
-
207
- /**
208
- * Thicken this curve into a closed PolyCurve.
209
- * Note: this is approximated by sampling the NURBS curve into a polyline first.
210
- *
211
- * When `bothSides` is false, the sampled source curve forms one side of the
212
- * result. When true, the distance is applied on each side of the sampled curve.
213
- */
214
- thicken(
215
- distance: number,
216
- bothSides = false,
217
- normal?: Vec3,
218
- samples = 64,
219
- options: CurveOffsetOptions = {},
220
- ): PolyCurve {
221
- const pts = this.sample(samples);
222
- return new Polyline(pts).thicken(distance, bothSides, normal, options);
223
- }
224
-
225
- /**
226
- * Extrude this closed NURBS curve into a trusted solid suitable for booleans.
227
- * @param direction - Extrusion direction and magnitude
228
- * @param segments - Number of curve samples used for tessellation (default 64)
158
+ /**
159
+ * Offset this curve by a distance.
160
+ * Note: NURBS offset is approximated by sampling and offsetting as polyline.
161
+ * @param distance - Offset distance
162
+ * @param normal - Reference normal for determining offset direction
163
+ * @param samples - Number of sample points (default 64)
164
+ * @param arcSamples - Number of samples per exact arc segment in the returned polyline(s)
165
+ * @param options - Offset options such as join style
166
+ * @returns Offset polyline approximation
167
+ */
168
+ offset(
169
+ distance: number,
170
+ normal?: Vec3,
171
+ samples = 64,
172
+ arcSamples = 32,
173
+ options: CurveOffsetOptions = {},
174
+ ): Polyline {
175
+ const results = this.offsetAll(distance, normal, samples, arcSamples, options);
176
+ if (results.length === 1) return results[0];
177
+ if (results.length === 0) {
178
+ throw new Error("NurbsCurve.offset() collapsed and produced no valid result polylines");
179
+ }
180
+ throw new Error(
181
+ `NurbsCurve.offset() produced ${results.length} result polylines. Use NurbsCurve.offsetAll() instead.`,
182
+ );
183
+ }
184
+
185
+ /**
186
+ * Offset this curve by a distance and return every sampled result polyline.
187
+ * Note: NURBS offset is approximated by sampling and offsetting as polyline.
188
+ * @param distance - Offset distance
189
+ * @param normal - Reference normal for determining offset direction
190
+ * @param samples - Number of sample points used to approximate the source curve
191
+ * @param arcSamples - Number of samples per exact arc segment in the returned polylines
192
+ * @param options - Offset options such as join style
193
+ * @returns Every valid offset polyline approximation
194
+ */
195
+ offsetAll(
196
+ distance: number,
197
+ normal?: Vec3,
198
+ samples = 64,
199
+ arcSamples = 32,
200
+ options: CurveOffsetOptions = {},
201
+ ): Polyline[] {
202
+ const pts = this.sample(samples);
203
+ const pl = new Polyline(pts);
204
+ return pl.offsetAll(distance, normal, arcSamples, options);
205
+ }
206
+
207
+ /**
208
+ * Thicken this curve into a closed PolyCurve.
209
+ * Note: this is approximated by sampling the NURBS curve into a polyline first.
210
+ *
211
+ * When `bothSides` is false, the sampled source curve forms one side of the
212
+ * result. When true, the distance is applied on each side of the sampled curve.
213
+ */
214
+ thicken(
215
+ distance: number,
216
+ bothSides = false,
217
+ normal?: Vec3,
218
+ samples = 64,
219
+ options: CurveOffsetOptions = {},
220
+ ): PolyCurve {
221
+ const pts = this.sample(samples);
222
+ return new Polyline(pts).thicken(distance, bothSides, normal, options);
223
+ }
224
+
225
+ /**
226
+ * Extrude this curve along a direction vector.
227
+ * Note: this is approximated by sampling the NURBS curve into a polyline
228
+ * first. Open curves produce an open sheet; closed curves an uncapped tube
229
+ * unless `caps` is true (see extrudeAsSolid for a boolean-ready solid).
230
+ * @param direction - Extrusion direction and magnitude
231
+ * @param segments - Number of segments along the extrusion (default 1)
232
+ * @param caps - Whether to cap the ends of a closed profile (default false)
233
+ * @param samples - Number of curve samples used for tessellation (default 64)
234
+ * @returns Mesh representing the extruded surface
235
+ */
236
+ extrude(direction: Vec3, segments = 1, caps = false, samples = 64): Mesh {
237
+ const pts = this.sample(samples);
238
+ return new Polyline(pts).extrude(direction, segments, caps);
239
+ }
240
+
241
+ /**
242
+ * Extrude this closed NURBS curve into a trusted solid suitable for booleans.
243
+ * @param direction - Extrusion direction and magnitude
244
+ * @param segments - Number of curve samples used for tessellation (default 64)
229
245
  * @returns Closed mesh solid ready for boolean operations
230
246
  */
231
247
  extrudeAsSolid(direction: Vec3, segments = 64): Mesh {
232
248
  return Mesh.extrudeCurveAsSolid(this, direction, segments);
233
249
  }
234
250
 
251
+ /**
252
+ * Build a NURBS curve from raw control points with kernel-managed knots and
253
+ * uniform weights.
254
+ *
255
+ * Open curves use a clamped uniform knot vector (curve interpolates the first
256
+ * and last control points). Closed curves are periodic (C^{degree-1}
257
+ * continuous loops); the first control point must NOT be repeated at the end.
258
+ *
259
+ * @param degree - Requested degree (clamped by the kernel to the valid range)
260
+ * @param controlPoints - Control points (min 2 open / 3 closed)
261
+ * @param closed - Build a periodic closed loop (default false)
262
+ * @returns New NurbsCurve instance
263
+ */
264
+ static fromPoints(degree: number, controlPoints: Point[], closed = false): NurbsCurve {
265
+ ensureInit();
266
+ const coords = new Float64Array(controlPoints.length * 3);
267
+ for (let i = 0; i < controlPoints.length; i++) {
268
+ coords[i * 3] = controlPoints[i].x;
269
+ coords[i * 3 + 1] = controlPoints[i].y;
270
+ coords[i * 3 + 2] = controlPoints[i].z;
271
+ }
272
+ const buf = wasm.build_nurbs_curve(degree, coords, closed);
273
+ if (buf.length < 2) {
274
+ throw new Error(
275
+ `NurbsCurve.fromPoints failed (degree ${degree}, ${controlPoints.length} points, closed=${closed})`,
276
+ );
277
+ }
278
+ return NurbsCurve.fromData(buf);
279
+ }
280
+
235
281
  /**
236
282
  * Decode a NurbsCurve from WASM flat buffer.
237
283
  * @param data - Buffer in format [degree, num_cp, xyz..., w..., k...]