okgeometry-api 1.15.0 → 1.17.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/dist/Brep.d.ts +95 -6
- package/dist/Brep.d.ts.map +1 -1
- package/dist/Brep.js +114 -5
- package/dist/Brep.js.map +1 -1
- package/dist/GeometryBoolean.d.ts +136 -0
- package/dist/GeometryBoolean.d.ts.map +1 -0
- package/dist/GeometryBoolean.js +632 -0
- package/dist/GeometryBoolean.js.map +1 -0
- package/dist/Mesh.d.ts +21 -1
- package/dist/Mesh.d.ts.map +1 -1
- package/dist/Mesh.js +66 -4
- package/dist/Mesh.js.map +1 -1
- package/dist/NurbsCurve.d.ts +66 -0
- package/dist/NurbsCurve.d.ts.map +1 -1
- package/dist/NurbsCurve.js +101 -0
- package/dist/NurbsCurve.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/wasm-base64.d.ts +1 -1
- package/dist/wasm-base64.d.ts.map +1 -1
- package/dist/wasm-base64.js +1 -1
- package/dist/wasm-base64.js.map +1 -1
- package/dist/wasm-bindings.d.ts +123 -1
- package/dist/wasm-bindings.d.ts.map +1 -1
- package/dist/wasm-bindings.js +193 -1
- package/dist/wasm-bindings.js.map +1 -1
- package/package.json +58 -54
- package/src/Brep.ts +147 -10
- package/src/GeometryBoolean.ts +863 -0
- package/src/Mesh.ts +3804 -3730
- package/src/NurbsCurve.ts +110 -0
- package/src/index.ts +88 -79
- package/src/wasm-base64.ts +1 -1
- package/src/wasm-bindings.d.ts +110 -1
- package/src/wasm-bindings.js +197 -1
|
@@ -0,0 +1,632 @@
|
|
|
1
|
+
import { Mesh } from "./Mesh.js";
|
|
2
|
+
import { Brep } from "./Brep.js";
|
|
3
|
+
import { NurbsSurface } from "./NurbsSurface.js";
|
|
4
|
+
import { NurbsCurve } from "./NurbsCurve.js";
|
|
5
|
+
import { Polyline } from "./Polyline.js";
|
|
6
|
+
import { PolyCurve } from "./PolyCurve.js";
|
|
7
|
+
import { Arc } from "./Arc.js";
|
|
8
|
+
import { Circle } from "./Circle.js";
|
|
9
|
+
import { Line } from "./Line.js";
|
|
10
|
+
/** Fallback tessellation tolerance when no operand yields usable bounds. */
|
|
11
|
+
const DEFAULT_TESS_TOLERANCE = 0.005;
|
|
12
|
+
/** Scale-relative default: bounds diagonal × this (render pipeline recipe). */
|
|
13
|
+
const MESH_TOLERANCE_DIAG_FACTOR = 2e-3;
|
|
14
|
+
/** Absolute floor for the scale-relative default. */
|
|
15
|
+
const MESH_TOLERANCE_FLOOR = 1e-6;
|
|
16
|
+
/** Coarse probe tolerance for BREP bounds estimation (minimal tessellation). */
|
|
17
|
+
const BOUNDS_PROBE_TOLERANCE = 1e6;
|
|
18
|
+
function cached(build) {
|
|
19
|
+
let value = null;
|
|
20
|
+
return () => {
|
|
21
|
+
if (value === null)
|
|
22
|
+
value = build();
|
|
23
|
+
return value;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
const TAU = Math.PI * 2;
|
|
27
|
+
function classifyOperand(operand, label) {
|
|
28
|
+
if (operand instanceof Brep) {
|
|
29
|
+
return { kind: "brep", closed: operand.isClosed(), brep: operand };
|
|
30
|
+
}
|
|
31
|
+
if (operand instanceof NurbsSurface) {
|
|
32
|
+
// A surface is an (untrimmed) sheet; the sheet BREP carries the exact
|
|
33
|
+
// surface so the parametric paths stay exact.
|
|
34
|
+
return { kind: "brep", closed: false, brep: Brep.fromSurface(operand) };
|
|
35
|
+
}
|
|
36
|
+
if (operand instanceof Mesh) {
|
|
37
|
+
return { kind: "mesh", closed: operand.isClosedVolume(), mesh: operand };
|
|
38
|
+
}
|
|
39
|
+
if (operand instanceof NurbsCurve) {
|
|
40
|
+
return {
|
|
41
|
+
kind: "curve",
|
|
42
|
+
raw: operand,
|
|
43
|
+
closed: operand.isClosed(),
|
|
44
|
+
polyline: null,
|
|
45
|
+
nurbs: () => operand,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
if (operand instanceof Polyline) {
|
|
49
|
+
// Polygon extends Polyline with automatic closure, so it lands here and
|
|
50
|
+
// classifies as a CLOSED polyline (region-boolean capable).
|
|
51
|
+
return {
|
|
52
|
+
kind: "curve",
|
|
53
|
+
raw: operand,
|
|
54
|
+
closed: operand.isClosed(),
|
|
55
|
+
polyline: operand,
|
|
56
|
+
nurbs: cached(() => NurbsCurve.fromPoints(1, operand.points)),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
if (operand instanceof Line) {
|
|
60
|
+
const polyline = new Polyline([operand.start, operand.end]);
|
|
61
|
+
return {
|
|
62
|
+
kind: "curve",
|
|
63
|
+
raw: operand,
|
|
64
|
+
closed: false,
|
|
65
|
+
polyline,
|
|
66
|
+
nurbs: cached(() => NurbsCurve.fromLine(operand)),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
if (operand instanceof Arc) {
|
|
70
|
+
const closed = Math.abs(operand.endAngle - operand.startAngle) >= TAU - 1e-9;
|
|
71
|
+
return {
|
|
72
|
+
kind: "curve",
|
|
73
|
+
raw: operand,
|
|
74
|
+
closed,
|
|
75
|
+
polyline: null,
|
|
76
|
+
nurbs: cached(() => NurbsCurve.fromArc(operand)),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
if (operand instanceof Circle) {
|
|
80
|
+
return {
|
|
81
|
+
kind: "curve",
|
|
82
|
+
raw: operand,
|
|
83
|
+
closed: true,
|
|
84
|
+
polyline: null,
|
|
85
|
+
nurbs: cached(() => NurbsCurve.fromArc(new Arc(operand.center, operand.radius, 0, TAU, operand.normal))),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
if (operand instanceof PolyCurve) {
|
|
89
|
+
return {
|
|
90
|
+
kind: "curve",
|
|
91
|
+
raw: operand,
|
|
92
|
+
closed: operand.isClosed(),
|
|
93
|
+
polyline: null,
|
|
94
|
+
nurbs: cached(() => operand.toNurbs()),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
throw new Error(`geometryBoolean operand ${label} has an unsupported type, expected `
|
|
98
|
+
+ "Mesh, Brep, NurbsSurface, NurbsCurve, Polyline, Polygon, PolyCurve, "
|
|
99
|
+
+ "Arc, Circle, or Line");
|
|
100
|
+
}
|
|
101
|
+
function operandMesh(operand, tolerance) {
|
|
102
|
+
if (operand.mesh)
|
|
103
|
+
return operand.mesh;
|
|
104
|
+
return operand.brep.toMesh(tolerance);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Accumulate an operand's world bounds for the scale-relative default
|
|
108
|
+
* tessellation tolerance. Mesh operands use their exact vertex bounds; BREP
|
|
109
|
+
* operands use a MINIMAL probe tessellation (huge chordal tolerance → one
|
|
110
|
+
* segment per knot span — cheap, and adequate for a scale estimate); curve
|
|
111
|
+
* operands use their polyline points or NURBS control points (a convex-hull
|
|
112
|
+
* bound). Operands that fail to yield bounds are skipped.
|
|
113
|
+
*/
|
|
114
|
+
function accumulateOperandBounds(operand, acc) {
|
|
115
|
+
const add = (x, y, z) => {
|
|
116
|
+
acc.minX = Math.min(acc.minX, x);
|
|
117
|
+
acc.minY = Math.min(acc.minY, y);
|
|
118
|
+
acc.minZ = Math.min(acc.minZ, z);
|
|
119
|
+
acc.maxX = Math.max(acc.maxX, x);
|
|
120
|
+
acc.maxY = Math.max(acc.maxY, y);
|
|
121
|
+
acc.maxZ = Math.max(acc.maxZ, z);
|
|
122
|
+
};
|
|
123
|
+
try {
|
|
124
|
+
if (operand.kind === "curve") {
|
|
125
|
+
const points = operand.polyline
|
|
126
|
+
? operand.polyline.points
|
|
127
|
+
: operand.nurbs().controlPoints;
|
|
128
|
+
for (const p of points)
|
|
129
|
+
add(p.x, p.y, p.z);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
const mesh = operand.mesh ?? operand.brep.tessellate(BOUNDS_PROBE_TOLERANCE);
|
|
133
|
+
const bounds = mesh.getBounds();
|
|
134
|
+
add(bounds.min.x, bounds.min.y, bounds.min.z);
|
|
135
|
+
add(bounds.max.x, bounds.max.y, bounds.max.z);
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
// Bounds are a scale ESTIMATE — a failing operand is skipped, never fatal.
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Resolve the tessellation tolerance: an explicit `meshTolerance` wins;
|
|
143
|
+
* otherwise combined-operand bounds diagonal × 2e-3 (floored at 1e-6), so
|
|
144
|
+
* mm-scale models get mm-scale probe tessellations and 100 m models don't
|
|
145
|
+
* over-tessellate. Falls back to the legacy 0.005 when no operand yields
|
|
146
|
+
* bounds.
|
|
147
|
+
*/
|
|
148
|
+
function resolveMeshTolerance(options, ...operands) {
|
|
149
|
+
if (options?.meshTolerance !== undefined)
|
|
150
|
+
return options.meshTolerance;
|
|
151
|
+
const acc = {
|
|
152
|
+
minX: Infinity,
|
|
153
|
+
minY: Infinity,
|
|
154
|
+
minZ: Infinity,
|
|
155
|
+
maxX: -Infinity,
|
|
156
|
+
maxY: -Infinity,
|
|
157
|
+
maxZ: -Infinity,
|
|
158
|
+
};
|
|
159
|
+
for (const operand of operands)
|
|
160
|
+
accumulateOperandBounds(operand, acc);
|
|
161
|
+
if (!Number.isFinite(acc.minX) || !Number.isFinite(acc.maxX)) {
|
|
162
|
+
return DEFAULT_TESS_TOLERANCE;
|
|
163
|
+
}
|
|
164
|
+
const diag = Math.hypot(acc.maxX - acc.minX, acc.maxY - acc.minY, acc.maxZ - acc.minZ);
|
|
165
|
+
if (!(diag > 0))
|
|
166
|
+
return DEFAULT_TESS_TOLERANCE;
|
|
167
|
+
return Math.max(diag * MESH_TOLERANCE_DIAG_FACTOR, MESH_TOLERANCE_FLOOR);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Try to view a surface-like operand as a BREP for the parametric paths.
|
|
171
|
+
* Mesh operands convert via Brep.fromMesh with a 512-face guard (planar
|
|
172
|
+
* faceted solids only, densely tessellated curved meshes fall back to the
|
|
173
|
+
* mesh path instead of producing a pathological per-triangle BREP).
|
|
174
|
+
*
|
|
175
|
+
* Facet-planarity heuristic: fromMesh can "succeed" on a curved closed mesh
|
|
176
|
+
* under the face guard by emitting nearly one BREP face per triangle. A BREP
|
|
177
|
+
* face count CLOSE TO the mesh triangle count means barely any coplanar
|
|
178
|
+
* clustering happened — reject it (mesh path) instead of running the exact
|
|
179
|
+
* pipeline on a per-facet pseudo-BREP. The threshold is tris × 0.55: a
|
|
180
|
+
* quad-faceted planar solid legitimately has faces ≈ tris / 2 (every planar
|
|
181
|
+
* face triangulated as one quad), so a tris / 3 cutoff wrongly rejected it,
|
|
182
|
+
* while a per-facet pseudo-BREP (faces ≈ tris) still lands far above 0.55.
|
|
183
|
+
*/
|
|
184
|
+
function tryOperandBrep(operand) {
|
|
185
|
+
if (operand.brep)
|
|
186
|
+
return { brep: operand.brep, coercedFromMesh: false };
|
|
187
|
+
if (!operand.closed)
|
|
188
|
+
return null; // Brep.fromMesh rejects open meshes.
|
|
189
|
+
try {
|
|
190
|
+
const mesh = operand.mesh;
|
|
191
|
+
const brep = Brep.fromMesh(mesh, { maxFaces: 512 });
|
|
192
|
+
if (brep.faceCount > Math.max(32, mesh.faceCount * 0.55)) {
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
return { brep, coercedFromMesh: true };
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* The parametric BREP pipeline runs only when at least one operand arrived
|
|
203
|
+
* as exact geometry (Brep or NurbsSurface); mesh x mesh pairs always use the
|
|
204
|
+
* mesh kernel directly.
|
|
205
|
+
*/
|
|
206
|
+
function shouldTryParametric(a, b) {
|
|
207
|
+
return a.kind === "brep" || b.kind === "brep";
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Sample a curve operand into a polyline with KNOWN uniform parameters:
|
|
211
|
+
* point i sits at curve parameter i / segmentCount (closed) or
|
|
212
|
+
* i / (sampleCount - 1) (open), so mesh-side hits map back to curve
|
|
213
|
+
* parameters via (segmentIndex + segmentT) / segmentCount.
|
|
214
|
+
*
|
|
215
|
+
* Polyline-NATIVE operands never reach this sampler — every dispatch row
|
|
216
|
+
* handles `operand.polyline` on a native path first; a polyline that did
|
|
217
|
+
* arrive here would simply sample its exact degree-1 NURBS coercion.
|
|
218
|
+
*/
|
|
219
|
+
function sampleCurveOperand(operand, samples = 128) {
|
|
220
|
+
const curve = operand.nurbs();
|
|
221
|
+
const points = [];
|
|
222
|
+
if (operand.closed) {
|
|
223
|
+
// Closed sampling omits the duplicate seam point and flags closedness
|
|
224
|
+
// explicitly; segment i runs i/n to (i+1)/n with the wrap segment last.
|
|
225
|
+
for (let i = 0; i < samples; i++)
|
|
226
|
+
points.push(curve.pointAt(i / samples));
|
|
227
|
+
return { points, closed: true, segmentCount: samples };
|
|
228
|
+
}
|
|
229
|
+
for (let i = 0; i < samples; i++)
|
|
230
|
+
points.push(curve.pointAt(i / (samples - 1)));
|
|
231
|
+
return { points, closed: false, segmentCount: samples - 1 };
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Which side of an oriented sheet mesh a crossing-free curve piece lies on.
|
|
235
|
+
*
|
|
236
|
+
* Classifies probe POINTS — interior parameter samples of the piece — by
|
|
237
|
+
* their signed side against the sheet, each through a tiny 2-point probe
|
|
238
|
+
* polyline (a crossing-free micro-span classifies by its midpoint's signed
|
|
239
|
+
* side, i.e. a point probe). Points are used instead of clipping whole
|
|
240
|
+
* probe CHORDS between distant samples: a chord can shortcut across a
|
|
241
|
+
* curved sheet (crossing it even though the curve piece does not) and
|
|
242
|
+
* misclassify, and a degenerate micro-piece chord probe can throw and abort
|
|
243
|
+
* the whole operation.
|
|
244
|
+
*
|
|
245
|
+
* Robustness contract: a sample whose probe fails (degenerate span) is
|
|
246
|
+
* skipped; a piece with no classifiable samples, or an exact tie, defaults
|
|
247
|
+
* to "front" — the documented ON convention (a sheet's material is the
|
|
248
|
+
* CLOSED front half-space, so on-sheet pieces belong to the front and are
|
|
249
|
+
* dropped by subtract). This function never throws.
|
|
250
|
+
*/
|
|
251
|
+
function pieceSideOfSheet(piece, sheetMesh) {
|
|
252
|
+
let front = 0;
|
|
253
|
+
let back = 0;
|
|
254
|
+
for (let i = 1; i <= 5; i++) {
|
|
255
|
+
const t = i / 6;
|
|
256
|
+
const p = piece.pointAt(t);
|
|
257
|
+
// Tiny tangent-direction partner keeps the probe span on the sample's
|
|
258
|
+
// side of the sheet (the piece is crossing-free).
|
|
259
|
+
const q = piece.pointAt(Math.min(1, t + 1e-3));
|
|
260
|
+
try {
|
|
261
|
+
const groups = sheetMesh.clipPolylineBySheet([p, q], false);
|
|
262
|
+
const total = (list) => list.reduce((sum, pl) => sum + pl.length(), 0);
|
|
263
|
+
const inside = total(groups.inside);
|
|
264
|
+
const outside = total(groups.outside);
|
|
265
|
+
if (inside > outside)
|
|
266
|
+
front++;
|
|
267
|
+
else if (outside > inside)
|
|
268
|
+
back++;
|
|
269
|
+
}
|
|
270
|
+
catch {
|
|
271
|
+
// Degenerate probe: skip this sample, never abort the operation.
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return back > front ? "back" : "front";
|
|
275
|
+
}
|
|
276
|
+
// ── result assembly ─────────────────────────────────────────────────
|
|
277
|
+
function brepResult(pieces) {
|
|
278
|
+
const breps = pieces.filter((piece) => piece != null);
|
|
279
|
+
return {
|
|
280
|
+
kind: "brep",
|
|
281
|
+
breps,
|
|
282
|
+
brep: breps.length === 1 ? breps[0] : undefined,
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
function meshResult(pieces) {
|
|
286
|
+
if (pieces.length === 0)
|
|
287
|
+
return { kind: "mesh", meshes: [] };
|
|
288
|
+
const mesh = pieces.length === 1 ? pieces[0] : Mesh.mergeMeshes(pieces);
|
|
289
|
+
return { kind: "mesh", mesh, meshes: pieces };
|
|
290
|
+
}
|
|
291
|
+
function curvesResult(curves) {
|
|
292
|
+
return { kind: "curves", curves };
|
|
293
|
+
}
|
|
294
|
+
function pointsResult(points) {
|
|
295
|
+
return { kind: "points", points };
|
|
296
|
+
}
|
|
297
|
+
// ── curve x curve region booleans ───────────────────────────────────
|
|
298
|
+
/**
|
|
299
|
+
* 2D region boolean between two CLOSED coplanar curve operands (Rhino
|
|
300
|
+
* CurveBoolean). Both operands are coerced to exact NURBS; the kernel fits a
|
|
301
|
+
* common plane, verifies coplanarity, and returns the result region boundary
|
|
302
|
+
* loops (polyline fidelity — outer CCW, holes CW). Throws with a clear message
|
|
303
|
+
* when the curves are not coplanar.
|
|
304
|
+
*/
|
|
305
|
+
function regionBoolean(a, b, op) {
|
|
306
|
+
const na = a.nurbs();
|
|
307
|
+
const nb = b.nurbs();
|
|
308
|
+
switch (op) {
|
|
309
|
+
case "union":
|
|
310
|
+
return na.regionUnion(nb);
|
|
311
|
+
case "subtract":
|
|
312
|
+
return na.regionSubtract(nb);
|
|
313
|
+
case "intersect":
|
|
314
|
+
return na.regionIntersect(nb);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
// ── surface-like x surface-like ─────────────────────────────────────
|
|
318
|
+
function meshBoolean(a, b, op, tolerance) {
|
|
319
|
+
const meshA = operandMesh(a, tolerance);
|
|
320
|
+
const meshB = operandMesh(b, tolerance);
|
|
321
|
+
if (a.closed && !b.closed) {
|
|
322
|
+
// solid x sheet: cut the solid along the oriented sheet and keep the
|
|
323
|
+
// CAPPED half, matching the parametric solid/sheet convention
|
|
324
|
+
// (subtract keeps the half behind the sheet normal, intersect the front).
|
|
325
|
+
const split = meshA.splitSolidBySurface(meshB);
|
|
326
|
+
return meshResult(op === "subtract" ? split.outside : split.inside);
|
|
327
|
+
}
|
|
328
|
+
if (!a.closed && (b.closed || op !== "union")) {
|
|
329
|
+
// sheet x solid trims by containment; sheet x sheet subtract/intersect
|
|
330
|
+
// classify by the other sheet's signed side (back/front).
|
|
331
|
+
const split = meshA.split(meshB);
|
|
332
|
+
return meshResult(op === "subtract" ? split.outside : split.inside);
|
|
333
|
+
}
|
|
334
|
+
if (op === "union") {
|
|
335
|
+
// closed x closed volumetric union, or open x open sheet union
|
|
336
|
+
// (mutual trim + join) — Mesh.union dispatches on closedness.
|
|
337
|
+
return meshResult([meshA.union(meshB)]);
|
|
338
|
+
}
|
|
339
|
+
return meshResult([op === "subtract" ? meshA.subtract(meshB) : meshA.intersect(meshB)]);
|
|
340
|
+
}
|
|
341
|
+
function surfaceBoolean(a, b, op, options) {
|
|
342
|
+
// Union of a solid and a sheet is not defined in ANY representation, and
|
|
343
|
+
// this is a semantic error, never a fallback trigger.
|
|
344
|
+
if (op === "union" && a.closed !== b.closed) {
|
|
345
|
+
throw new Error("Union of a solid and a sheet is not defined, trim the sheet with "
|
|
346
|
+
+ "subtract or intersect, or close the sheet into a solid first");
|
|
347
|
+
}
|
|
348
|
+
if (shouldTryParametric(a, b)) {
|
|
349
|
+
const brepA = tryOperandBrep(a);
|
|
350
|
+
const brepB = tryOperandBrep(b);
|
|
351
|
+
if (brepA && brepB) {
|
|
352
|
+
try {
|
|
353
|
+
const parametricOptions = options?.tolerance !== undefined ? { tolerance: options.tolerance } : undefined;
|
|
354
|
+
const result = op === "union"
|
|
355
|
+
? brepA.brep.unionBrep(brepB.brep, parametricOptions)
|
|
356
|
+
: op === "subtract"
|
|
357
|
+
? brepA.brep.subtractBrep(brepB.brep, parametricOptions)
|
|
358
|
+
: brepA.brep.intersectBrep(brepB.brep, parametricOptions);
|
|
359
|
+
// Validation gate for COERCED mesh operands: fromMesh conversion can
|
|
360
|
+
// hand the exact pipeline a borderline pseudo-BREP; when both inputs
|
|
361
|
+
// are closed, the boolean of two solids must come back closed —
|
|
362
|
+
// otherwise reject the parametric result and use the mesh path.
|
|
363
|
+
if ((brepA.coercedFromMesh || brepB.coercedFromMesh)
|
|
364
|
+
&& a.closed && b.closed
|
|
365
|
+
&& result.faceCount > 0
|
|
366
|
+
&& !result.isClosed()) {
|
|
367
|
+
throw new Error("parametric result of coerced mesh operand is not closed");
|
|
368
|
+
}
|
|
369
|
+
return brepResult([result]);
|
|
370
|
+
}
|
|
371
|
+
catch {
|
|
372
|
+
// Documented downgrade: the parametric pipeline failed, fall back to
|
|
373
|
+
// the tessellated mesh path below.
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
return meshBoolean(a, b, op, resolveMeshTolerance(options, a, b));
|
|
378
|
+
}
|
|
379
|
+
// ── curve x surface-like ────────────────────────────────────────────
|
|
380
|
+
function curveSolidPieces(curve, solid) {
|
|
381
|
+
if (solid.kind === "brep") {
|
|
382
|
+
// Exact: knot-insertion split + containment classification.
|
|
383
|
+
return curve.nurbs().clipByBrep(solid.brep);
|
|
384
|
+
}
|
|
385
|
+
if (curve.polyline) {
|
|
386
|
+
return solid.mesh.clipPolyline(curve.polyline);
|
|
387
|
+
}
|
|
388
|
+
// Exact curve against a mesh solid: tessellated clip (documented
|
|
389
|
+
// approximation, pieces come back as Polylines). Pass the solid as a Brep
|
|
390
|
+
// for the exact path instead.
|
|
391
|
+
const sampled = sampleCurveOperand(curve);
|
|
392
|
+
return solid.mesh.clipPolyline(sampled.points, sampled.closed);
|
|
393
|
+
}
|
|
394
|
+
function curveSheetCrossings(curve, sheet) {
|
|
395
|
+
if (sheet.kind === "brep") {
|
|
396
|
+
return sheet.brep.intersectCurve(curve.nurbs()).map((hit) => hit.point);
|
|
397
|
+
}
|
|
398
|
+
const sampled = curve.polyline
|
|
399
|
+
? { points: curve.polyline.points, closed: curve.closed }
|
|
400
|
+
: sampleCurveOperand(curve);
|
|
401
|
+
return sheet
|
|
402
|
+
.mesh.intersectPolyline(sampled.points, sampled.closed)
|
|
403
|
+
.map((hit) => hit.point);
|
|
404
|
+
}
|
|
405
|
+
function curveMinusSheet(curve, sheet, tolerance) {
|
|
406
|
+
if (sheet.kind === "brep") {
|
|
407
|
+
// Exact split parameters from the trim-checked curve x BREP hits, then
|
|
408
|
+
// exact knot-insertion splitting; side classification uses the
|
|
409
|
+
// tessellated sheet (no exact open-sheet clip exists, clipCurve
|
|
410
|
+
// requires a closed solid).
|
|
411
|
+
const hits = sheet.brep.intersectCurve(curve.nurbs());
|
|
412
|
+
const pieces = curve
|
|
413
|
+
.nurbs()
|
|
414
|
+
.splitAtParams(hits.map((hit) => hit.curveParam), curve.closed);
|
|
415
|
+
const sheetMesh = sheet.brep.toMesh(tolerance);
|
|
416
|
+
return pieces.filter((piece) => pieceSideOfSheet(piece, sheetMesh) === "back");
|
|
417
|
+
}
|
|
418
|
+
if (curve.polyline) {
|
|
419
|
+
return sheet.mesh.clipPolylineBySheet(curve.polyline).outside;
|
|
420
|
+
}
|
|
421
|
+
// Exact curve against a mesh sheet: exact split at sampled-hit parameters
|
|
422
|
+
// (hit parameters are exact in parameter space up to chord deviation),
|
|
423
|
+
// then signed-side classification per piece.
|
|
424
|
+
const sampled = sampleCurveOperand(curve);
|
|
425
|
+
const hits = sheet.mesh.intersectPolyline(sampled.points, sampled.closed);
|
|
426
|
+
const params = hits.map((hit) => (hit.segmentIndex + hit.segmentT) / sampled.segmentCount);
|
|
427
|
+
const pieces = curve.nurbs().splitAtParams(params, curve.closed);
|
|
428
|
+
return pieces.filter((piece) => pieceSideOfSheet(piece, sheet.mesh) === "back");
|
|
429
|
+
}
|
|
430
|
+
function curveSurfaceBoolean(curve, other, op, curveIsFirst, options) {
|
|
431
|
+
if (op === "union") {
|
|
432
|
+
throw new Error("Union with a curve operand is not defined, curves have no area or volume");
|
|
433
|
+
}
|
|
434
|
+
if (op === "subtract" && !curveIsFirst) {
|
|
435
|
+
throw new Error("Subtracting a curve from a solid or sheet is not defined, curves have "
|
|
436
|
+
+ "no volume or area to remove");
|
|
437
|
+
}
|
|
438
|
+
if (other.closed) {
|
|
439
|
+
// curve x solid: intersect keeps the inside pieces, subtract the outside.
|
|
440
|
+
const pieces = curveSolidPieces(curve, other);
|
|
441
|
+
return curvesResult(op === "intersect" ? pieces.inside : pieces.outside);
|
|
442
|
+
}
|
|
443
|
+
// curve x sheet: the intersection set is the crossing POINTS; subtract
|
|
444
|
+
// keeps the pieces behind the sheet normal. The tessellation tolerance is
|
|
445
|
+
// resolved LAZILY here — the exact paths above never pay the bounds probe.
|
|
446
|
+
if (op === "intersect") {
|
|
447
|
+
return pointsResult(curveSheetCrossings(curve, other));
|
|
448
|
+
}
|
|
449
|
+
return curvesResult(curveMinusSheet(curve, other, resolveMeshTolerance(options, curve, other)));
|
|
450
|
+
}
|
|
451
|
+
// ── public API: boolean ─────────────────────────────────────────────
|
|
452
|
+
/**
|
|
453
|
+
* Boolean of any two geometries, dispatched by effective dimension.
|
|
454
|
+
*
|
|
455
|
+
* Dispatch matrix (A x B):
|
|
456
|
+
* - brep x brep (any closedness) — parametric unionBrep/subtractBrep/
|
|
457
|
+
* intersectBrep (sheet-capable) returning kind 'brep'; parametric failures
|
|
458
|
+
* fall back to the tessellated mesh path (kind 'mesh').
|
|
459
|
+
* - brep x mesh — the closed mesh side is converted with Brep.fromMesh
|
|
460
|
+
* (planar-faceted) for the parametric path; otherwise tessellated mesh ops.
|
|
461
|
+
* - mesh x mesh — solid x solid runs CSG; a sheet operand uses the
|
|
462
|
+
* split-based trim semantics (subtract keeps outside/back, intersect keeps
|
|
463
|
+
* inside/front; solid x sheet returns the CAPPED clicked-side halves);
|
|
464
|
+
* sheet union sheet runs the kernel mutual trim + join. A sheet's material
|
|
465
|
+
* is its FRONT half-space, so the sheet union keeps each sheet's pieces
|
|
466
|
+
* BEHIND the other (front pieces are interior to the union material);
|
|
467
|
+
* uncut regions are kept, coincident overlaps keep A's copy.
|
|
468
|
+
* - union of a solid and a sheet (any representation) throws.
|
|
469
|
+
* - curve x solid — intersect keeps the inside clip pieces, subtract the
|
|
470
|
+
* outside pieces (kind 'curves'); union throws.
|
|
471
|
+
* - curve x sheet — intersect returns the crossing points (kind 'points');
|
|
472
|
+
* subtract keeps the pieces behind the sheet normal (kind 'curves').
|
|
473
|
+
* - curve x curve — when BOTH curves are closed and coplanar, union /
|
|
474
|
+
* subtract / intersect are 2D REGION booleans (Rhino CurveBoolean): the
|
|
475
|
+
* result is the region boundary CURVES (kind 'curves', outer CCW / holes
|
|
476
|
+
* CW, polyline fidelity). For open curves, intersect returns the crossing
|
|
477
|
+
* POINTS (kind 'points') and union / subtract throw (open curves bound no
|
|
478
|
+
* region). Note: region-intersect returns the overlapping region's
|
|
479
|
+
* BOUNDARY, distinct from the point-set intersection of the open case.
|
|
480
|
+
*/
|
|
481
|
+
export function geometryBoolean(a, b, op, options) {
|
|
482
|
+
const oa = classifyOperand(a, "A");
|
|
483
|
+
const ob = classifyOperand(b, "B");
|
|
484
|
+
if (oa.kind === "curve" && ob.kind === "curve") {
|
|
485
|
+
// Two CLOSED coplanar curves bound 2D regions, so union / subtract /
|
|
486
|
+
// intersect are the REGION booleans (Rhino CurveBoolean). The region
|
|
487
|
+
// op returns the boundary CURVES (outer CCW, holes CW). Coplanarity is
|
|
488
|
+
// verified kernel-side; a non-coplanar pair throws with a clear message.
|
|
489
|
+
if (oa.closed && ob.closed) {
|
|
490
|
+
return curvesResult(regionBoolean(oa, ob, op));
|
|
491
|
+
}
|
|
492
|
+
// Open curves cannot bound a region. Intersect still returns the crossing
|
|
493
|
+
// POINTS (the meaningful lower-dimensional result); union / subtract of an
|
|
494
|
+
// open curve is undefined.
|
|
495
|
+
if (op !== "intersect") {
|
|
496
|
+
throw new Error(`Boolean ${op} of two curves requires BOTH curves to be closed and `
|
|
497
|
+
+ "coplanar (open curves bound no region)");
|
|
498
|
+
}
|
|
499
|
+
const hits = oa.nurbs().intersectCurveParams(ob.nurbs());
|
|
500
|
+
return pointsResult(hits.map((hit) => hit.point));
|
|
501
|
+
}
|
|
502
|
+
if (oa.kind === "curve") {
|
|
503
|
+
return curveSurfaceBoolean(oa, ob, op, true, options);
|
|
504
|
+
}
|
|
505
|
+
if (ob.kind === "curve") {
|
|
506
|
+
return curveSurfaceBoolean(ob, oa, op, false, options);
|
|
507
|
+
}
|
|
508
|
+
return surfaceBoolean(oa, ob, op, options);
|
|
509
|
+
}
|
|
510
|
+
// ── public API: split ───────────────────────────────────────────────
|
|
511
|
+
function splitCurveByOperand(curve, blade) {
|
|
512
|
+
if (blade.kind === "curve") {
|
|
513
|
+
// Two CLOSED coplanar curves → REGION split (Rhino "region split"): the
|
|
514
|
+
// arrangement of the two loops partitions the plane into all its regions,
|
|
515
|
+
// returned as closed boundary curves (outer CCW, holes CW).
|
|
516
|
+
if (curve.closed && blade.closed) {
|
|
517
|
+
return curvesResult(curve.nurbs().regionSplit(blade.nurbs()));
|
|
518
|
+
}
|
|
519
|
+
// Otherwise split THIS curve exactly at every crossing parameter (the
|
|
520
|
+
// blade is untouched), the pre-region behavior.
|
|
521
|
+
const hits = curve.nurbs().intersectCurveParams(blade.nurbs());
|
|
522
|
+
return curvesResult(curve.nurbs().splitAtParams(hits.map((hit) => hit.paramA), curve.closed));
|
|
523
|
+
}
|
|
524
|
+
if (blade.kind === "brep") {
|
|
525
|
+
if (blade.closed) {
|
|
526
|
+
// Exact containment clip, all pieces (inside then outside).
|
|
527
|
+
const clipped = curve.nurbs().clipByBrep(blade.brep);
|
|
528
|
+
return curvesResult([...clipped.inside, ...clipped.outside]);
|
|
529
|
+
}
|
|
530
|
+
const hits = blade.brep.intersectCurve(curve.nurbs());
|
|
531
|
+
return curvesResult(curve.nurbs().splitAtParams(hits.map((hit) => hit.curveParam), curve.closed));
|
|
532
|
+
}
|
|
533
|
+
// Mesh blade (open or closed): polyline-native input splits natively;
|
|
534
|
+
// exact curves split EXACTLY at the sampled-hit parameters so the pieces
|
|
535
|
+
// stay on the curve.
|
|
536
|
+
if (curve.polyline) {
|
|
537
|
+
return curvesResult(blade.mesh.splitPolyline(curve.polyline));
|
|
538
|
+
}
|
|
539
|
+
const sampled = sampleCurveOperand(curve);
|
|
540
|
+
const hits = blade.mesh.intersectPolyline(sampled.points, sampled.closed);
|
|
541
|
+
const params = hits.map((hit) => (hit.segmentIndex + hit.segmentT) / sampled.segmentCount);
|
|
542
|
+
return curvesResult(curve.nurbs().splitAtParams(params, curve.closed));
|
|
543
|
+
}
|
|
544
|
+
function splitSurfaceByOperand(a, blade, options) {
|
|
545
|
+
if (blade.kind === "curve") {
|
|
546
|
+
if (!blade.closed) {
|
|
547
|
+
throw new Error("geometrySplit: an OPEN curve cannot cut a solid or sheet — only a "
|
|
548
|
+
+ "CLOSED planar curve acts as a through-cut blade; close the curve "
|
|
549
|
+
+ "(or use a Polygon), or split with a sheet or solid blade instead");
|
|
550
|
+
}
|
|
551
|
+
// Closed planar blade curves become through-cut cutter solids
|
|
552
|
+
// (Mesh.split's curve mode). BREP hosts tessellate first (documented
|
|
553
|
+
// downgrade).
|
|
554
|
+
const hostMesh = operandMesh(a, resolveMeshTolerance(options, a, blade));
|
|
555
|
+
const split = hostMesh.split(blade.raw);
|
|
556
|
+
return meshResult([...split.outside, ...split.inside]);
|
|
557
|
+
}
|
|
558
|
+
const parametricOptions = options?.tolerance !== undefined ? { tolerance: options.tolerance } : undefined;
|
|
559
|
+
// Parametric splits where an exact pipeline exists (only when at least one
|
|
560
|
+
// side arrived as exact geometry, mesh x mesh always splits in the mesh
|
|
561
|
+
// kernel).
|
|
562
|
+
if (shouldTryParametric(a, blade)) {
|
|
563
|
+
const brepA = tryOperandBrep(a);
|
|
564
|
+
const brepB = tryOperandBrep(blade);
|
|
565
|
+
if (brepA && brepB) {
|
|
566
|
+
try {
|
|
567
|
+
if (a.closed && !blade.closed) {
|
|
568
|
+
const halves = brepA.brep.splitBySheet(brepB.brep, parametricOptions);
|
|
569
|
+
// Validation gate for coerced-mesh hosts: a genuine cut of a closed
|
|
570
|
+
// solid must yield closed halves, else use the mesh path.
|
|
571
|
+
if (brepA.coercedFromMesh
|
|
572
|
+
&& [halves.negative, halves.positive].some((h) => h != null && h.faceCount > 0 && !h.isClosed())) {
|
|
573
|
+
throw new Error("parametric split of coerced mesh host is not closed");
|
|
574
|
+
}
|
|
575
|
+
return brepResult([halves.negative, halves.positive]);
|
|
576
|
+
}
|
|
577
|
+
if (!a.closed && blade.closed) {
|
|
578
|
+
const sides = brepA.brep.splitSheetBySolid(brepB.brep, parametricOptions);
|
|
579
|
+
return brepResult([sides.outside, sides.inside]);
|
|
580
|
+
}
|
|
581
|
+
if (!a.closed && !blade.closed) {
|
|
582
|
+
const sides = brepA.brep.splitSheetBySheet(brepB.brep, parametricOptions);
|
|
583
|
+
return brepResult([sides.outside, sides.inside]);
|
|
584
|
+
}
|
|
585
|
+
// solid / solid has no parametric split pipeline, use the mesh path.
|
|
586
|
+
}
|
|
587
|
+
catch {
|
|
588
|
+
// Documented downgrade: fall through to the tessellated mesh path.
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
// Tessellated fallback: the tolerance is resolved LAZILY here so the
|
|
593
|
+
// parametric success paths above never pay the bounds probe.
|
|
594
|
+
const tolerance = resolveMeshTolerance(options, a, blade);
|
|
595
|
+
const hostMesh = operandMesh(a, tolerance);
|
|
596
|
+
const bladeMesh = operandMesh(blade, tolerance);
|
|
597
|
+
if (a.closed && !blade.closed) {
|
|
598
|
+
// Capped halves on both sides of the oriented sheet.
|
|
599
|
+
const split = hostMesh.splitSolidBySurface(bladeMesh);
|
|
600
|
+
return meshResult([...split.outside, ...split.inside]);
|
|
601
|
+
}
|
|
602
|
+
const split = hostMesh.split(bladeMesh);
|
|
603
|
+
return meshResult([...split.outside, ...split.inside]);
|
|
604
|
+
}
|
|
605
|
+
/**
|
|
606
|
+
* Split geometry A by blade B, returning ALL pieces of A (the blade is
|
|
607
|
+
* untouched). Dispatch mirrors {@link geometryBoolean}:
|
|
608
|
+
* - brep solid / sheet blades use the parametric splitBySheet /
|
|
609
|
+
* splitSheetBySolid / splitSheetBySheet pipelines (kind 'brep', both
|
|
610
|
+
* sides); failures fall back to the tessellated mesh path.
|
|
611
|
+
* - mesh hosts use Mesh.split / Mesh.splitSolidBySurface (kind 'mesh',
|
|
612
|
+
* outside pieces then inside pieces).
|
|
613
|
+
* - curve hosts split exactly: clipByBrep (closed BREP blade), exact
|
|
614
|
+
* parameters from trim-checked BREP hits (sheet BREP blade),
|
|
615
|
+
* splitPolyline or exact splitAtParams (mesh blade). For a closed curve
|
|
616
|
+
* host split by a closed coplanar curve blade → 2D REGION split (all region
|
|
617
|
+
* boundaries, Rhino "region split"); an open host splits at
|
|
618
|
+
* intersectCurveParams hits (curve blade). Kind 'curves'.
|
|
619
|
+
* - a closed planar curve blade cuts mesh and BREP hosts through
|
|
620
|
+
* Mesh.split's curve mode (through-cut cutter); an OPEN curve blade
|
|
621
|
+
* against a solid/sheet host throws a typed error (an open curve cannot
|
|
622
|
+
* bound a through-cut).
|
|
623
|
+
*/
|
|
624
|
+
export function geometrySplit(a, b, options) {
|
|
625
|
+
const oa = classifyOperand(a, "A");
|
|
626
|
+
const ob = classifyOperand(b, "B");
|
|
627
|
+
if (oa.kind === "curve") {
|
|
628
|
+
return splitCurveByOperand(oa, ob);
|
|
629
|
+
}
|
|
630
|
+
return splitSurfaceByOperand(oa, ob, options);
|
|
631
|
+
}
|
|
632
|
+
//# sourceMappingURL=GeometryBoolean.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GeometryBoolean.js","sourceRoot":"","sources":["../src/GeometryBoolean.ts"],"names":[],"mappings":"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"}
|