okgeometry-api 1.1.13 → 1.1.15
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/dist/Circle.d.ts +7 -0
- package/dist/Circle.d.ts.map +1 -1
- package/dist/Circle.js +9 -0
- package/dist/Circle.js.map +1 -1
- package/dist/Mesh.d.ts +8 -0
- package/dist/Mesh.d.ts.map +1 -1
- package/dist/Mesh.js +61 -0
- package/dist/Mesh.js.map +1 -1
- package/dist/NurbsCurve.d.ts +14 -0
- package/dist/NurbsCurve.d.ts.map +1 -1
- package/dist/NurbsCurve.js +18 -0
- package/dist/NurbsCurve.js.map +1 -1
- package/dist/PolyCurve.d.ts +19 -0
- package/dist/PolyCurve.d.ts.map +1 -1
- package/dist/PolyCurve.js +27 -0
- package/dist/PolyCurve.js.map +1 -1
- package/dist/Polyline.d.ts +6 -0
- package/dist/Polyline.d.ts.map +1 -1
- package/dist/Polyline.js +8 -0
- package/dist/Polyline.js.map +1 -1
- package/dist/wasm-base64.d.ts +1 -1
- package/dist/wasm-base64.js +1 -1
- package/dist/wasm-bindings.js +1 -1
- package/package.json +1 -1
- package/src/Circle.ts +19 -9
- package/src/Mesh.ts +83 -13
- package/src/NurbsCurve.ts +43 -23
- package/src/PolyCurve.ts +52 -20
- package/src/Polyline.ts +21 -12
- package/src/wasm-base64.ts +1 -1
- package/src/wasm-bindings.js +1 -1
package/dist/wasm-bindings.js
CHANGED
|
@@ -1688,7 +1688,7 @@ export function version() {
|
|
|
1688
1688
|
function __wbg_get_imports() {
|
|
1689
1689
|
const import0 = {
|
|
1690
1690
|
__proto__: null,
|
|
1691
|
-
|
|
1691
|
+
__wbg___okgeometry_boolean_should_cancel_18de25279e7a7d72: function () {
|
|
1692
1692
|
const ret = globalThis.__okgeometry_boolean_should_cancel();
|
|
1693
1693
|
return ret;
|
|
1694
1694
|
},
|
package/package.json
CHANGED
package/src/Circle.ts
CHANGED
|
@@ -139,15 +139,25 @@ export class Circle {
|
|
|
139
139
|
* @param caps - Whether to cap the ends (default true)
|
|
140
140
|
* @returns Mesh representing the extruded cylinder
|
|
141
141
|
*/
|
|
142
|
-
extrude(direction: Vec3, segments = 16, caps = true): Mesh {
|
|
143
|
-
ensureInit();
|
|
144
|
-
const buf = wasm.extrude_circle(
|
|
145
|
-
this.center.x, this.center.y, this.center.z,
|
|
146
|
-
this.normal.x, this.normal.y, this.normal.z,
|
|
142
|
+
extrude(direction: Vec3, segments = 16, caps = true): Mesh {
|
|
143
|
+
ensureInit();
|
|
144
|
+
const buf = wasm.extrude_circle(
|
|
145
|
+
this.center.x, this.center.y, this.center.z,
|
|
146
|
+
this.normal.x, this.normal.y, this.normal.z,
|
|
147
147
|
this.radius,
|
|
148
148
|
direction.x, direction.y, direction.z,
|
|
149
149
|
segments, caps
|
|
150
|
-
);
|
|
151
|
-
return Mesh.fromBuffer(buf);
|
|
152
|
-
}
|
|
153
|
-
|
|
150
|
+
);
|
|
151
|
+
return Mesh.fromBuffer(buf);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Extrude this closed circle into a trusted solid suitable for booleans.
|
|
156
|
+
* @param direction - Extrusion direction and magnitude
|
|
157
|
+
* @param segments - Number of boundary samples used for tessellation (default 32)
|
|
158
|
+
* @returns Closed mesh solid ready for boolean operations
|
|
159
|
+
*/
|
|
160
|
+
extrudeAsSolid(direction: Vec3, segments = 32): Mesh {
|
|
161
|
+
return Mesh.extrudeCurveAsSolid(this, direction, segments);
|
|
162
|
+
}
|
|
163
|
+
}
|
package/src/Mesh.ts
CHANGED
|
@@ -1192,21 +1192,91 @@ export class Mesh {
|
|
|
1192
1192
|
* Extrude a planar curve along a direction.
|
|
1193
1193
|
* Open curves return an uncapped polysurface; closed curves are capped solids.
|
|
1194
1194
|
*/
|
|
1195
|
-
static extrudePlanarCurve(points: Point[], normal: Vec3, height: number, closed: boolean): Mesh {
|
|
1196
|
-
ensureInit();
|
|
1197
|
-
const buf = wasm.mesh_extrude_planar_curve(
|
|
1198
|
-
pointsToCoords(points),
|
|
1199
|
-
normal.x, normal.y, normal.z,
|
|
1195
|
+
static extrudePlanarCurve(points: Point[], normal: Vec3, height: number, closed: boolean): Mesh {
|
|
1196
|
+
ensureInit();
|
|
1197
|
+
const buf = wasm.mesh_extrude_planar_curve(
|
|
1198
|
+
pointsToCoords(points),
|
|
1199
|
+
normal.x, normal.y, normal.z,
|
|
1200
1200
|
height,
|
|
1201
1201
|
closed,
|
|
1202
|
-
);
|
|
1203
|
-
return Mesh.fromTrustedBuffer(buf);
|
|
1204
|
-
}
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1202
|
+
);
|
|
1203
|
+
return Mesh.fromTrustedBuffer(buf);
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
private static normalizeClosedCurvePoints(points: Point[], eps = 1e-10): Point[] {
|
|
1207
|
+
const normalized: Point[] = [];
|
|
1208
|
+
for (const point of points) {
|
|
1209
|
+
if (normalized.length > 0 && normalized[normalized.length - 1].equals(point, eps)) continue;
|
|
1210
|
+
normalized.push(point);
|
|
1211
|
+
}
|
|
1212
|
+
if (normalized.length > 1 && normalized[0].equals(normalized[normalized.length - 1], eps)) {
|
|
1213
|
+
normalized.pop();
|
|
1214
|
+
}
|
|
1215
|
+
return normalized;
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
private static getClosedCurveLoopPoints(curve: SweepableCurve, segments: number): Point[] {
|
|
1219
|
+
const closureEps = 1e-6;
|
|
1220
|
+
const sampleCount = Number.isFinite(segments) ? Math.max(3, Math.floor(segments)) : 32;
|
|
1221
|
+
|
|
1222
|
+
if (curve instanceof Circle) {
|
|
1223
|
+
return Mesh.normalizeClosedCurvePoints(curve.sample(sampleCount), closureEps);
|
|
1224
|
+
}
|
|
1225
|
+
if (curve instanceof Polygon || curve instanceof Polyline) {
|
|
1226
|
+
if (!curve.isClosed(closureEps)) {
|
|
1227
|
+
throw new Error("Mesh.extrudeCurveAsSolid() requires a closed polyline or polygon.");
|
|
1228
|
+
}
|
|
1229
|
+
return Mesh.normalizeClosedCurvePoints(curve.points, closureEps);
|
|
1230
|
+
}
|
|
1231
|
+
if (curve instanceof PolyCurve) {
|
|
1232
|
+
if (!curve.isClosed(closureEps)) {
|
|
1233
|
+
throw new Error("Mesh.extrudeCurveAsSolid() requires a closed polycurve.");
|
|
1234
|
+
}
|
|
1235
|
+
return Mesh.normalizeClosedCurvePoints(curve.sample(Math.max(2, sampleCount)), closureEps);
|
|
1236
|
+
}
|
|
1237
|
+
if (curve instanceof NurbsCurve) {
|
|
1238
|
+
if (!curve.isClosed(closureEps)) {
|
|
1239
|
+
throw new Error("Mesh.extrudeCurveAsSolid() requires a closed NURBS curve.");
|
|
1240
|
+
}
|
|
1241
|
+
return Mesh.normalizeClosedCurvePoints(curve.sample(sampleCount), closureEps);
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
throw new Error(
|
|
1245
|
+
"Mesh.extrudeCurveAsSolid() requires a closed curve "
|
|
1246
|
+
+ "(Circle, closed Polyline/Polygon, closed PolyCurve, or closed NurbsCurve).",
|
|
1247
|
+
);
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
/**
|
|
1251
|
+
* Extrude a closed planar curve into a trusted closed solid suitable for booleans.
|
|
1252
|
+
* Curved inputs are sampled first, so `segments` controls tessellation density
|
|
1253
|
+
* for circles, polycurves, and NURBS curves.
|
|
1254
|
+
*/
|
|
1255
|
+
static extrudeCurveAsSolid(curve: SweepableCurve, direction: Vec3, segments = 32): Mesh {
|
|
1256
|
+
ensureInit();
|
|
1257
|
+
|
|
1258
|
+
const height = direction.length();
|
|
1259
|
+
if (!Number.isFinite(height) || height < 1e-10) {
|
|
1260
|
+
throw new Error("Mesh.extrudeCurveAsSolid() requires a non-zero extrusion direction.");
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1263
|
+
const points = Mesh.getClosedCurveLoopPoints(curve, segments);
|
|
1264
|
+
if (points.length < 3) {
|
|
1265
|
+
throw new Error("Mesh.extrudeCurveAsSolid() requires at least 3 unique boundary points.");
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
const normal = direction.scale(1 / height);
|
|
1269
|
+
const mesh = Mesh.extrudePlanarCurve(points, normal, height, true);
|
|
1270
|
+
if (mesh.vertexCount === 0) {
|
|
1271
|
+
throw new Error("Mesh.extrudeCurveAsSolid() failed. Ensure the curve is planar and closed.");
|
|
1272
|
+
}
|
|
1273
|
+
return mesh;
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
/**
|
|
1277
|
+
* Shift a closed cutter profile slightly opposite to travel direction and
|
|
1278
|
+
* compensate height so the distal end remains at the user-intended depth.
|
|
1279
|
+
*/
|
|
1210
1280
|
static prepareBooleanCutterCurve(
|
|
1211
1281
|
points: Point[],
|
|
1212
1282
|
closed: boolean,
|
package/src/NurbsCurve.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
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 {
|
|
6
|
-
import
|
|
7
|
-
import type {
|
|
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 type { Line } from "./Line.js";
|
|
8
|
+
import type { Arc } from "./Arc.js";
|
|
8
9
|
import type { RotationAxis } from "./types.js";
|
|
9
10
|
import { parseIntersectionPoints } from "./BufferCodec.js";
|
|
10
11
|
import * as wasm from "./wasm-bindings.js";
|
|
@@ -50,15 +51,24 @@ export class NurbsCurve {
|
|
|
50
51
|
* @param n - Number of points to generate
|
|
51
52
|
* @returns Array of n points along the curve
|
|
52
53
|
*/
|
|
53
|
-
sample(n: number): Point[] {
|
|
54
|
-
ensureInit();
|
|
55
|
-
const buf = wasm.sample_nurbs_curve(this._data, n);
|
|
56
|
-
const pts: Point[] = [];
|
|
57
|
-
for (let i = 0; i < buf.length; i += 3) {
|
|
58
|
-
pts.push(new Point(buf[i], buf[i + 1], buf[i + 2]));
|
|
59
|
-
}
|
|
60
|
-
return pts;
|
|
61
|
-
}
|
|
54
|
+
sample(n: number): Point[] {
|
|
55
|
+
ensureInit();
|
|
56
|
+
const buf = wasm.sample_nurbs_curve(this._data, n);
|
|
57
|
+
const pts: Point[] = [];
|
|
58
|
+
for (let i = 0; i < buf.length; i += 3) {
|
|
59
|
+
pts.push(new Point(buf[i], buf[i + 1], buf[i + 2]));
|
|
60
|
+
}
|
|
61
|
+
return pts;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Check if this NURBS curve is closed.
|
|
66
|
+
* @param eps - Tolerance for comparing start and end points
|
|
67
|
+
* @returns True if the curve closes on itself
|
|
68
|
+
*/
|
|
69
|
+
isClosed(eps = 1e-10): boolean {
|
|
70
|
+
return this.pointAt(0).equals(this.pointAt(1), eps);
|
|
71
|
+
}
|
|
62
72
|
|
|
63
73
|
/**
|
|
64
74
|
* Find intersection points with a plane.
|
|
@@ -153,15 +163,25 @@ export class NurbsCurve {
|
|
|
153
163
|
* @param samples - Number of sample points (default 64)
|
|
154
164
|
* @returns Offset polyline approximation
|
|
155
165
|
*/
|
|
156
|
-
offset(distance: number, normal?: Vec3, samples = 64): Polyline {
|
|
157
|
-
const pts = this.sample(samples);
|
|
158
|
-
const pl = new Polyline(pts);
|
|
159
|
-
return pl.offset(distance, normal);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
*
|
|
164
|
-
* @param
|
|
166
|
+
offset(distance: number, normal?: Vec3, samples = 64): Polyline {
|
|
167
|
+
const pts = this.sample(samples);
|
|
168
|
+
const pl = new Polyline(pts);
|
|
169
|
+
return pl.offset(distance, normal);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Extrude this closed NURBS curve into a trusted solid suitable for booleans.
|
|
174
|
+
* @param direction - Extrusion direction and magnitude
|
|
175
|
+
* @param segments - Number of curve samples used for tessellation (default 64)
|
|
176
|
+
* @returns Closed mesh solid ready for boolean operations
|
|
177
|
+
*/
|
|
178
|
+
extrudeAsSolid(direction: Vec3, segments = 64): Mesh {
|
|
179
|
+
return Mesh.extrudeCurveAsSolid(this, direction, segments);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Decode a NurbsCurve from WASM flat buffer.
|
|
184
|
+
* @param data - Buffer in format [degree, num_cp, xyz..., w..., k...]
|
|
165
185
|
* @returns New NurbsCurve instance
|
|
166
186
|
*/
|
|
167
187
|
static fromData(data: Float64Array | number[]): NurbsCurve {
|
package/src/PolyCurve.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { ensureInit } from "./engine.js";
|
|
2
2
|
import { Point } from "./Point.js";
|
|
3
3
|
import { Line } from "./Line.js";
|
|
4
|
-
import { Arc } from "./Arc.js";
|
|
5
|
-
import { Vec3 } from "./Vec3.js";
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
8
|
-
import type {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import
|
|
4
|
+
import { Arc } from "./Arc.js";
|
|
5
|
+
import { Vec3 } from "./Vec3.js";
|
|
6
|
+
import { Mesh } from "./Mesh.js";
|
|
7
|
+
import { NurbsCurve } from "./NurbsCurve.js";
|
|
8
|
+
import type { Plane } from "./Plane.js";
|
|
9
|
+
import type { CurveSegment, RotationAxis } from "./types.js";
|
|
10
|
+
import { SegmentTypeCode } from "./types.js";
|
|
11
|
+
import { pointsToCoords } from "./BufferCodec.js";
|
|
12
|
+
import * as wasm from "./wasm-bindings.js";
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Composite curve made of sequential Line and Arc segments.
|
|
@@ -108,10 +109,10 @@ export class PolyCurve {
|
|
|
108
109
|
return new PolyCurve(this.segments.map(s => s.translate(offset)));
|
|
109
110
|
}
|
|
110
111
|
|
|
111
|
-
projectOntoPlane(plane: Plane, direction?: Vec3, arcSamples = 32): PolyCurve {
|
|
112
|
-
const proj = (p: Point) => direction ? plane.projectPointAlongDirection(p, direction) : plane.projectPoint(p);
|
|
113
|
-
const segs: CurveSegment[] = [];
|
|
114
|
-
for (const s of this.segments) {
|
|
112
|
+
projectOntoPlane(plane: Plane, direction?: Vec3, arcSamples = 32): PolyCurve {
|
|
113
|
+
const proj = (p: Point) => direction ? plane.projectPointAlongDirection(p, direction) : plane.projectPoint(p);
|
|
114
|
+
const segs: CurveSegment[] = [];
|
|
115
|
+
for (const s of this.segments) {
|
|
115
116
|
if (s instanceof Line) {
|
|
116
117
|
segs.push(new Line(proj(s.start), proj(s.end)));
|
|
117
118
|
} else {
|
|
@@ -121,14 +122,45 @@ export class PolyCurve {
|
|
|
121
122
|
segs.push(new Line(proj(pts[i]), proj(pts[i + 1])));
|
|
122
123
|
}
|
|
123
124
|
}
|
|
124
|
-
}
|
|
125
|
-
return new PolyCurve(segs);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
|
|
125
|
+
}
|
|
126
|
+
return new PolyCurve(segs);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Extrude this polycurve along a direction vector.
|
|
131
|
+
* Curved segments are sampled to a polyline first, so `segments` controls
|
|
132
|
+
* the tessellation density used for arc segments before extrusion.
|
|
133
|
+
* @param direction - Extrusion direction and magnitude
|
|
134
|
+
* @param segments - Number of samples per arc segment (default 32)
|
|
135
|
+
* @param caps - Whether to cap closed profiles (default false)
|
|
136
|
+
* @returns Mesh representing the extruded surface
|
|
137
|
+
*/
|
|
138
|
+
extrude(direction: Vec3, segments = 32, caps = false): Mesh {
|
|
139
|
+
ensureInit();
|
|
140
|
+
const arcSamples = Number.isFinite(segments) ? Math.max(2, Math.floor(segments)) : 32;
|
|
141
|
+
const buf = wasm.extrude_polyline(
|
|
142
|
+
pointsToCoords(this.sample(arcSamples)),
|
|
143
|
+
direction.x, direction.y, direction.z,
|
|
144
|
+
arcSamples, caps,
|
|
145
|
+
);
|
|
146
|
+
return Mesh.fromBuffer(buf);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Extrude this closed polycurve into a trusted solid suitable for booleans.
|
|
151
|
+
* Curved segments are sampled first, so `segments` controls tessellation density.
|
|
152
|
+
* @param direction - Extrusion direction and magnitude
|
|
153
|
+
* @param segments - Number of samples per curved segment (default 32)
|
|
154
|
+
* @returns Closed mesh solid ready for boolean operations
|
|
155
|
+
*/
|
|
156
|
+
extrudeAsSolid(direction: Vec3, segments = 32): Mesh {
|
|
157
|
+
return Mesh.extrudeCurveAsSolid(this, direction, segments);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Fillet corners of this PolyCurve with arcs of the given radius.
|
|
162
|
+
* Extracts the vertex points, calls WASM fillet_corners, returns a new PolyCurve.
|
|
163
|
+
*/
|
|
132
164
|
fillet(radius: number, normal?: Vec3): PolyCurve {
|
|
133
165
|
ensureInit();
|
|
134
166
|
if (this.segments.length < 2) {
|
package/src/Polyline.ts
CHANGED
|
@@ -57,19 +57,28 @@ export class Polyline {
|
|
|
57
57
|
* @param caps - Whether to cap the ends (default false)
|
|
58
58
|
* @returns Mesh representing the extruded surface
|
|
59
59
|
*/
|
|
60
|
-
extrude(direction: Vec3, segments = 1, caps = false): Mesh {
|
|
61
|
-
ensureInit();
|
|
62
|
-
const buf = wasm.extrude_polyline(
|
|
63
|
-
this.toCoords(),
|
|
64
|
-
direction.x, direction.y, direction.z,
|
|
60
|
+
extrude(direction: Vec3, segments = 1, caps = false): Mesh {
|
|
61
|
+
ensureInit();
|
|
62
|
+
const buf = wasm.extrude_polyline(
|
|
63
|
+
this.toCoords(),
|
|
64
|
+
direction.x, direction.y, direction.z,
|
|
65
65
|
segments, caps
|
|
66
|
-
);
|
|
67
|
-
return Mesh.fromBuffer(buf);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
*
|
|
72
|
-
* @param
|
|
66
|
+
);
|
|
67
|
+
return Mesh.fromBuffer(buf);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Extrude this closed polyline into a trusted solid suitable for booleans.
|
|
72
|
+
* @param direction - Extrusion direction and magnitude
|
|
73
|
+
* @returns Closed mesh solid ready for boolean operations
|
|
74
|
+
*/
|
|
75
|
+
extrudeAsSolid(direction: Vec3): Mesh {
|
|
76
|
+
return Mesh.extrudeCurveAsSolid(this, direction);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Translate this polyline by an offset vector.
|
|
81
|
+
* @param offset - Translation vector
|
|
73
82
|
* @returns New translated polyline
|
|
74
83
|
*/
|
|
75
84
|
translate(offset: Vec3): Polyline {
|