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.
@@ -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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"}