brepjs 20.0.1 → 20.1.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.
Files changed (91) hide show
  1. package/dist/2d.cjs +6 -6
  2. package/dist/2d.js +6 -6
  3. package/dist/{adjacencyFns-BOBaGnQ-.js → adjacencyFns-Uvm9NynL.js} +3 -3
  4. package/dist/{adjacencyFns-lCrjQUQr.cjs → adjacencyFns-jii1IFIG.cjs} +3 -3
  5. package/dist/{blueprint-C8-OnlmZ.cjs → blueprint-D9ZlqUeK.cjs} +5 -5
  6. package/dist/{blueprint-DlFhP2Qh.js → blueprint-DILaxgJO.js} +5 -5
  7. package/dist/{blueprintFns-CnbCEsbH.cjs → blueprintFns-D4TEbdWz.cjs} +2 -2
  8. package/dist/{blueprintFns-BniwPQ5Y.js → blueprintFns-bY8kvY4_.js} +2 -2
  9. package/dist/{blueprintSketcher-kSDNNuEJ.js → blueprintSketcher-DQ8_jTjB.js} +3 -3
  10. package/dist/{blueprintSketcher-DooDamYd.cjs → blueprintSketcher-Dzt1t42w.cjs} +3 -3
  11. package/dist/{boolean2D-DWWRN2RX.cjs → boolean2D-B1mwRBqn.cjs} +4 -4
  12. package/dist/{boolean2D-B7qLwMXL.js → boolean2D-Ez4nai3v.js} +4 -4
  13. package/dist/brepjs.cjs +29 -29
  14. package/dist/brepjs.js +29 -29
  15. package/dist/{cameraFns-DHCT80lC.cjs → cameraFns-BPPUjCnt.cjs} +3 -3
  16. package/dist/{cameraFns-npky8h1N.js → cameraFns-DVsDrWgy.js} +3 -3
  17. package/dist/core.cjs +2 -2
  18. package/dist/core.js +2 -2
  19. package/dist/{cornerFinder-Dy1lzQTB.cjs → cornerFinder-CbsBCk55.cjs} +1 -1
  20. package/dist/{cornerFinder-CEarkgO9.js → cornerFinder-D_9RMx6b.js} +1 -1
  21. package/dist/{curveFns-qVcljEvc.cjs → curveFns-0ka_F1Qt.cjs} +1 -1
  22. package/dist/{curveFns-n7htUStC.js → curveFns-Ci1fc5gO.js} +1 -1
  23. package/dist/{drawFns-CBSjbn4X.js → drawFns-ClJ3JEQN.js} +12 -12
  24. package/dist/{drawFns-VAreKNtB.cjs → drawFns-D9MEpXRq.cjs} +12 -12
  25. package/dist/{faceFns-CQyNJard.js → faceFns-DCmUSP5s.js} +2 -2
  26. package/dist/{faceFns-s7QRCW8A.cjs → faceFns-DeJ6KX-t.cjs} +2 -2
  27. package/dist/{healingFns-CDmIZyqk.cjs → healingFns-DKA7ZP2T.cjs} +4 -4
  28. package/dist/{healingFns-C1Vwru9B.js → healingFns-DLTUch-a.js} +4 -4
  29. package/dist/{helpers-BSo7hpSE.cjs → helpers-C7Dc2kHH.cjs} +6 -6
  30. package/dist/{helpers-DVdxPyq2.js → helpers-DptAa1BD.js} +6 -6
  31. package/dist/{importFns-BU_WjaNS.js → importFns-BPFSXV6z.js} +2 -2
  32. package/dist/{importFns-BjV9G5z6.cjs → importFns-CFIKCNNb.cjs} +2 -2
  33. package/dist/io.cjs +2 -2
  34. package/dist/io.js +2 -2
  35. package/dist/kernel/interfaces/evolutionOps.d.ts +7 -0
  36. package/dist/kernel/occtWasm/booleanOps.d.ts +38 -6
  37. package/dist/kernel/occtWasm/evolutionOps.d.ts +11 -3
  38. package/dist/kernel/occtWasm/helpers.d.ts +7 -2
  39. package/dist/kernel/occtWasm/occtWasmAdapter.cjs +1 -1
  40. package/dist/kernel/occtWasm/occtWasmAdapter.d.ts +4 -0
  41. package/dist/kernel/occtWasm/occtWasmAdapter.js +1 -1
  42. package/dist/kernel/occtWasm/occtWasmTypes.d.ts +2 -0
  43. package/dist/{loftFns-suyWruNr.cjs → loftFns-IB4K_Dzv.cjs} +1 -1
  44. package/dist/{loftFns-DDdoMjxj.js → loftFns-IzkWwK0P.js} +1 -1
  45. package/dist/{measureFns-DLTeuGwQ.cjs → measureFns-Cxk116Fv.cjs} +3 -3
  46. package/dist/{measureFns-DMr_rq2J.js → measureFns-HcH4fJJE.js} +3 -3
  47. package/dist/measurement.cjs +1 -1
  48. package/dist/measurement.js +1 -1
  49. package/dist/{meshFns-qV2fL7DY.js → meshFns-CvqS6edU.js} +3 -3
  50. package/dist/{meshFns-Crgr_uib.cjs → meshFns-zlx99xbI.cjs} +3 -3
  51. package/dist/{occtWasmAdapter-CIc9I87_.js → occtWasmAdapter-BYziKlFk.js} +215 -76
  52. package/dist/{occtWasmAdapter-y21xnRNM.cjs → occtWasmAdapter-D6-CUP2V.cjs} +215 -76
  53. package/dist/operations.cjs +2 -2
  54. package/dist/operations.js +2 -2
  55. package/dist/{originTrackingFns-BbRMIrPd.js → originTrackingFns-B_VM7fiP.js} +2 -2
  56. package/dist/{originTrackingFns-CIXgTLuX.cjs → originTrackingFns-PUTN7amf.cjs} +2 -2
  57. package/dist/{primitiveFns-DHTDymOR.cjs → primitiveFns-C109FiCa.cjs} +4 -4
  58. package/dist/{primitiveFns-CM-WtrDU.js → primitiveFns-DbZD1Zqf.js} +4 -4
  59. package/dist/projection.cjs +1 -1
  60. package/dist/projection.js +1 -1
  61. package/dist/query.cjs +2 -2
  62. package/dist/query.js +2 -2
  63. package/dist/{refResolveFns-Caq9pEFX.js → refResolveFns-Cr_obR-4.js} +6 -6
  64. package/dist/{refResolveFns-W0eI7vrV.cjs → refResolveFns-DtU3S0qY.cjs} +6 -6
  65. package/dist/{shapeFns-DnTR5fGL.cjs → shapeFns-BPBLbDjd.cjs} +2 -2
  66. package/dist/{shapeFns-abxGUiRi.js → shapeFns-Dpa19NyE.js} +2 -2
  67. package/dist/shapeRef.cjs +1 -1
  68. package/dist/shapeRef.js +1 -1
  69. package/dist/{shapeTypes-DgcXaWoK.js → shapeTypes-B_ogF-B7.js} +1 -1
  70. package/dist/{shapeTypes-D6N6FPC9.cjs → shapeTypes-DwrDUQPZ.cjs} +1 -1
  71. package/dist/sketching.cjs +3 -3
  72. package/dist/sketching.js +3 -3
  73. package/dist/{solidBuilders-DnUQIIh-.cjs → solidBuilders-BNsIlURc.cjs} +31 -7
  74. package/dist/{solidBuilders-DCVpjCr4.js → solidBuilders-pibEpGVS.js} +31 -7
  75. package/dist/{surfaceBuilders-wEh6hNcZ.js → surfaceBuilders-COXjNT6b.js} +3 -3
  76. package/dist/{surfaceBuilders-DZ4qaEMP.cjs → surfaceBuilders-DZU1ttYY.cjs} +3 -3
  77. package/dist/text.cjs +2 -2
  78. package/dist/text.js +2 -2
  79. package/dist/{textBlueprints-Cx7nEADC.cjs → textBlueprints-CpPDmfyT.cjs} +7 -7
  80. package/dist/{textBlueprints-CJyJx8VV.js → textBlueprints-CzC9BOgL.js} +7 -7
  81. package/dist/{textMetrics-C7yaPJuS.cjs → textMetrics-Bjm9jybe.cjs} +1 -1
  82. package/dist/{textMetrics-ZDLgofee.js → textMetrics-IF9ktcEi.js} +1 -1
  83. package/dist/{threadFns-xQF8IS-h.cjs → threadFns-BRB6cpKI.cjs} +7 -7
  84. package/dist/{threadFns-Dnr7QEbq.js → threadFns-nkBUo5vX.js} +7 -7
  85. package/dist/topology.cjs +9 -9
  86. package/dist/topology.js +9 -9
  87. package/dist/{topologyQueryFns-gVaVV1Nt.js → topologyQueryFns-DPrHRCrr.js} +1 -1
  88. package/dist/{topologyQueryFns-DhWju_Rg.cjs → topologyQueryFns-YGvGdGCr.cjs} +1 -1
  89. package/dist/{validityTypes-swMGQ5f2.js → validityTypes-CBK24R8q.js} +1 -1
  90. package/dist/{validityTypes-Bh3tqEzS.cjs → validityTypes-DUed50G5.cjs} +1 -1
  91. package/package.json +3 -3
@@ -1327,6 +1327,37 @@ function rotateZToDirection(k, shapeId, dir) {
1327
1327
  const angle = Math.acos(Math.max(-1, Math.min(1, nz)));
1328
1328
  return k.rotate(shapeId, 0, 0, 0, ax / axLen, ay / axLen, 0, angle);
1329
1329
  }
1330
+ /** Read an evolution result into a shape id and maps, releasing the Embind object. */
1331
+ function parseEvolution(evo) {
1332
+ try {
1333
+ const modifiedRaw = readVecInt(evo.modified);
1334
+ const generatedRaw = readVecInt(evo.generated);
1335
+ const deletedRaw = readVecInt(evo.deleted);
1336
+ const parseMap = (raw) => {
1337
+ const map = /* @__PURE__ */ new Map();
1338
+ let i = 0;
1339
+ while (i + 1 < raw.length) {
1340
+ const inputHash = raw[i] ?? 0;
1341
+ const count = raw[i + 1] ?? 0;
1342
+ i += 2;
1343
+ const outputs = [];
1344
+ for (let j = 0; j < count && i < raw.length; j++, i++) outputs.push(raw[i] ?? 0);
1345
+ map.set(inputHash, outputs);
1346
+ }
1347
+ return map;
1348
+ };
1349
+ return {
1350
+ id: evo.resultId,
1351
+ evolution: {
1352
+ modified: parseMap(modifiedRaw),
1353
+ generated: parseMap(generatedRaw),
1354
+ deleted: new Set(deletedRaw)
1355
+ }
1356
+ };
1357
+ } finally {
1358
+ evo.delete();
1359
+ }
1360
+ }
1330
1361
  //#endregion
1331
1362
  //#region src/kernel/occtWasm/adapterShims.ts
1332
1363
  function wrapKernelExceptions(kernel, mod) {
@@ -1382,6 +1413,89 @@ function buildOcShim(module, k) {
1382
1413
  }
1383
1414
  //#endregion
1384
1415
  //#region src/kernel/occtWasm/booleanOps.ts
1416
+ var BOOLEAN_OP_CODE = {
1417
+ fuse: 0,
1418
+ cut: 1,
1419
+ common: 2
1420
+ };
1421
+ /** Same angular tolerance the opencascade.js adapter hands SimplifyResult. */
1422
+ var SIMPLIFY_ANGULAR_TOLERANCE = .001;
1423
+ /** Whether this occt-wasm build has the general `booleanOp`. */
1424
+ function hasBooleanOp(k) {
1425
+ return typeof k.booleanOp === "function";
1426
+ }
1427
+ /** Whether `options` asks for anything only `booleanOp` can honor. */
1428
+ function needsBooleanOptions(options) {
1429
+ if (!options) return false;
1430
+ return options.optimisation !== void 0 && options.optimisation !== "none" || (options.fuzzyValue ?? 0) > 0 || options.simplify === true;
1431
+ }
1432
+ function glueCode(optimisation) {
1433
+ if (optimisation === "commonFace") return 1;
1434
+ if (optimisation === "sameFace") return 2;
1435
+ return 0;
1436
+ }
1437
+ /**
1438
+ * Run `booleanOp` on raw shape ids, collecting face history when hashes are
1439
+ * given. The caller owns the returned id.
1440
+ */
1441
+ function runBooleanOp(k, Module, kind, argIds, toolIds, options = {}, inputFaceHashes = [], hashUpperBound = 0) {
1442
+ if (!k.booleanOp) throw new Error("occt-wasm: booleanOp is not available in this build");
1443
+ let args;
1444
+ let tools;
1445
+ let hashes;
1446
+ try {
1447
+ args = makeVecU32(Module, argIds);
1448
+ tools = makeVecU32(Module, toolIds);
1449
+ hashes = makeVecInt(Module, inputFaceHashes);
1450
+ return parseEvolution(k.booleanOp(BOOLEAN_OP_CODE[kind], args, tools, glueCode(options.optimisation), options.fuzzyValue ?? 0, options.simplify === true ? SIMPLIFY_ANGULAR_TOLERANCE : 0, hashes, hashUpperBound));
1451
+ } finally {
1452
+ args?.delete();
1453
+ tools?.delete();
1454
+ hashes?.delete();
1455
+ }
1456
+ }
1457
+ /**
1458
+ * Call `fn` with a tool's solids as separate ids, or with the tool alone when
1459
+ * it holds at most one solid, and report whether it was split. Solids are
1460
+ * handed to an n-way boolean as separate tools, which OCCT allows to overlap,
1461
+ * where one compound of overlapping solids is invalid input.
1462
+ */
1463
+ function withToolIds(k, tool, fn) {
1464
+ return withSolidIds(k, [tool], fn);
1465
+ }
1466
+ /**
1467
+ * {@link withToolIds} over several shapes: each multi-solid shape contributes
1468
+ * its solids, every other shape its own id, in order. `split` reports whether
1469
+ * any shape was expanded.
1470
+ */
1471
+ function withSolidIds(k, shapes, fn) {
1472
+ const ids = [];
1473
+ const extracted = [];
1474
+ try {
1475
+ for (const shape of shapes) pushSolidIds(k, unwrap(shape), ids, extracted);
1476
+ return fn(ids, ids.length > shapes.length);
1477
+ } finally {
1478
+ for (const id of extracted) k.release(id);
1479
+ }
1480
+ }
1481
+ /**
1482
+ * Append `id`'s solids to `ids`, or `id` itself when it holds at most one.
1483
+ * Every solid copy the query allocated goes on `extracted` for release.
1484
+ */
1485
+ function pushSolidIds(k, id, ids, extracted) {
1486
+ const solids = k.getSubShapes(id, "solid");
1487
+ try {
1488
+ const n = solids.size();
1489
+ for (let i = 0; i < n; i++) {
1490
+ const solidId = solids.get(i);
1491
+ if (solidId !== id) extracted.push(solidId);
1492
+ if (n > 1) ids.push(solidId);
1493
+ }
1494
+ if (n <= 1) ids.push(id);
1495
+ } finally {
1496
+ solids.delete();
1497
+ }
1498
+ }
1385
1499
  /**
1386
1500
  * Normalize a boolean tool to a single fused solid when it is a compound of
1387
1501
  * multiple solids (e.g. engraved text — one solid per glyph). occt-wasm's
@@ -1414,29 +1528,33 @@ function resolveBooleanTool(k, tool) {
1414
1528
  solids.delete();
1415
1529
  }
1416
1530
  }
1417
- function fuse(k, shape, tool, _options) {
1531
+ function fuse(k, Module, shape, tool, options) {
1532
+ if (hasBooleanOp(k) && needsBooleanOptions(options)) return wrapResult(k, runBooleanOp(k, Module, "fuse", [unwrap(shape)], [unwrap(tool)], options).id);
1418
1533
  return wrapResult(k, k.fuse(unwrap(shape), unwrap(tool)));
1419
1534
  }
1420
- function cut(k, shape, tool, _options) {
1421
- const resolved = resolveBooleanTool(k, tool);
1422
- try {
1423
- return wrapResult(k, k.cut(unwrap(shape), resolved.id));
1424
- } finally {
1425
- resolved.dispose();
1535
+ function subtractOrCommon(k, Module, kind, shape, tool, options) {
1536
+ if (hasBooleanOp(k)) {
1537
+ const id = withToolIds(k, tool, (toolIds, split) => split || needsBooleanOptions(options) ? runBooleanOp(k, Module, kind, [unwrap(shape)], toolIds, options).id : null);
1538
+ if (id !== null) return wrapResult(k, id);
1426
1539
  }
1427
- }
1428
- function intersect(k, shape, tool, _options) {
1429
1540
  const resolved = resolveBooleanTool(k, tool);
1430
1541
  try {
1431
- return wrapResult(k, k.intersect(unwrap(shape), resolved.id));
1542
+ return wrapResult(k, kind === "cut" ? k.cut(unwrap(shape), resolved.id) : k.intersect(unwrap(shape), resolved.id));
1432
1543
  } finally {
1433
1544
  resolved.dispose();
1434
1545
  }
1435
1546
  }
1547
+ function cut(k, Module, shape, tool, options) {
1548
+ return subtractOrCommon(k, Module, "cut", shape, tool, options);
1549
+ }
1550
+ function intersect(k, Module, shape, tool, options) {
1551
+ return subtractOrCommon(k, Module, "common", shape, tool, options);
1552
+ }
1436
1553
  function section(k, shape, plane, _approximation) {
1437
1554
  return wrapResult(k, k.section(unwrap(shape), unwrap(plane)));
1438
1555
  }
1439
- function fuseAll(k, Module, shapes, _options) {
1556
+ function fuseAll(k, Module, shapes, options) {
1557
+ if (shapes.length > 1 && hasBooleanOp(k) && needsBooleanOptions(options)) return withSolidIds(k, shapes, ([first, ...rest]) => wrapResult(k, runBooleanOp(k, Module, "fuse", first === void 0 ? [] : [first], rest, options).id));
1440
1558
  const vec = makeVecU32(Module, shapes.map(unwrap));
1441
1559
  try {
1442
1560
  return wrapResult(k, k.fuseAll(vec));
@@ -1444,7 +1562,8 @@ function fuseAll(k, Module, shapes, _options) {
1444
1562
  vec.delete();
1445
1563
  }
1446
1564
  }
1447
- function cutAll(k, Module, shape, tools, _options) {
1565
+ function cutAll(k, Module, shape, tools, options) {
1566
+ if (tools.length > 0 && hasBooleanOp(k) && needsBooleanOptions(options)) return withSolidIds(k, [shape], (argIds) => withSolidIds(k, tools, (toolIds) => wrapResult(k, runBooleanOp(k, Module, "cut", argIds, toolIds, options).id)));
1448
1567
  const vec = makeVecU32(Module, tools.map(unwrap));
1449
1568
  try {
1450
1569
  return wrapResult(k, k.cutAll(unwrap(shape), vec));
@@ -4518,36 +4637,6 @@ function fixWireOnFace(k, wire, face, tolerance) {
4518
4637
  * Parse an EvolutionData result from the WASM kernel into a ShapeEvolution.
4519
4638
  * The C++ facade returns flat vectors of [inputHash, count, out1, out2, ..., inputHash, count, ...].
4520
4639
  */
4521
- function parseEvolution(evo) {
4522
- try {
4523
- const modifiedRaw = readVecInt(evo.modified);
4524
- const generatedRaw = readVecInt(evo.generated);
4525
- const deletedRaw = readVecInt(evo.deleted);
4526
- const parseMap = (raw) => {
4527
- const map = /* @__PURE__ */ new Map();
4528
- let i = 0;
4529
- while (i + 1 < raw.length) {
4530
- const inputHash = raw[i] ?? 0;
4531
- const count = raw[i + 1] ?? 0;
4532
- i += 2;
4533
- const outputs = [];
4534
- for (let j = 0; j < count && i < raw.length; j++, i++) outputs.push(raw[i] ?? 0);
4535
- map.set(inputHash, outputs);
4536
- }
4537
- return map;
4538
- };
4539
- return {
4540
- id: evo.resultId,
4541
- evolution: {
4542
- modified: parseMap(modifiedRaw),
4543
- generated: parseMap(generatedRaw),
4544
- deleted: new Set(deletedRaw)
4545
- }
4546
- };
4547
- } finally {
4548
- evo.delete();
4549
- }
4550
- }
4551
4640
  function translateWithHistory(k, Module, shape, x, y, z, inputFaceHashes, hashUpperBound) {
4552
4641
  const hashVec = makeVecInt(Module, inputFaceHashes);
4553
4642
  try {
@@ -4619,62 +4708,104 @@ function generalTransformWithHistory(generalTransformFn, shape, linear, translat
4619
4708
  }
4620
4709
  };
4621
4710
  }
4622
- function fuseWithHistory(k, Module, shape, tool, inputFaceHashes, hashUpperBound, _options) {
4711
+ var NO_DIAGNOSTICS = {
4712
+ hasErrors: false,
4713
+ hasWarnings: false,
4714
+ messages: []
4715
+ };
4716
+ function viaBooleanOp(k, Module, kind, argIds, toolIds, inputFaceHashes, hashUpperBound, options) {
4717
+ const { id, evolution } = runBooleanOp(k, Module, kind, argIds, toolIds, options, inputFaceHashes, hashUpperBound);
4718
+ return {
4719
+ shape: wrapResult(k, id),
4720
+ evolution,
4721
+ diagnostics: NO_DIAGNOSTICS
4722
+ };
4723
+ }
4724
+ function fuseWithHistory(k, Module, shape, tool, inputFaceHashes, hashUpperBound, options) {
4725
+ if (hasBooleanOp(k) && needsBooleanOptions(options)) return viaBooleanOp(k, Module, "fuse", [unwrap(shape)], [unwrap(tool)], inputFaceHashes, hashUpperBound, options);
4623
4726
  const hashVec = makeVecInt(Module, inputFaceHashes);
4624
4727
  try {
4625
4728
  const { id, evolution } = parseEvolution(k.fuseWithHistory(unwrap(shape), unwrap(tool), hashVec, hashUpperBound));
4626
4729
  return {
4627
4730
  shape: wrapResult(k, id),
4628
4731
  evolution,
4629
- diagnostics: {
4630
- hasErrors: false,
4631
- hasWarnings: false,
4632
- messages: []
4633
- }
4732
+ diagnostics: NO_DIAGNOSTICS
4634
4733
  };
4635
4734
  } finally {
4636
4735
  hashVec.delete();
4637
4736
  }
4638
4737
  }
4639
- function cutWithHistory(k, Module, shape, tool, inputFaceHashes, hashUpperBound, _options) {
4738
+ function subtractOrCommonWithHistory(k, Module, kind, shape, tool, inputFaceHashes, hashUpperBound, options) {
4739
+ if (hasBooleanOp(k)) {
4740
+ const result = withToolIds(k, tool, (toolIds, split) => split || needsBooleanOptions(options) ? viaBooleanOp(k, Module, kind, [unwrap(shape)], toolIds, inputFaceHashes, hashUpperBound, options) : null);
4741
+ if (result) return result;
4742
+ }
4640
4743
  const hashVec = makeVecInt(Module, inputFaceHashes);
4641
4744
  let resolved;
4642
4745
  try {
4643
4746
  resolved = resolveBooleanTool(k, tool);
4644
- const { id, evolution } = parseEvolution(k.cutWithHistory(unwrap(shape), resolved.id, hashVec, hashUpperBound));
4747
+ const { id, evolution } = parseEvolution(kind === "cut" ? k.cutWithHistory(unwrap(shape), resolved.id, hashVec, hashUpperBound) : k.intersectWithHistory(unwrap(shape), resolved.id, hashVec, hashUpperBound));
4645
4748
  return {
4646
4749
  shape: wrapResult(k, id),
4647
4750
  evolution,
4648
- diagnostics: {
4649
- hasErrors: false,
4650
- hasWarnings: false,
4651
- messages: []
4652
- }
4751
+ diagnostics: NO_DIAGNOSTICS
4653
4752
  };
4654
4753
  } finally {
4655
4754
  hashVec.delete();
4656
4755
  resolved?.dispose();
4657
4756
  }
4658
4757
  }
4659
- function intersectWithHistory(k, Module, shape, tool, inputFaceHashes, hashUpperBound, _options) {
4660
- const hashVec = makeVecInt(Module, inputFaceHashes);
4661
- let resolved;
4662
- try {
4663
- resolved = resolveBooleanTool(k, tool);
4664
- const { id, evolution } = parseEvolution(k.intersectWithHistory(unwrap(shape), resolved.id, hashVec, hashUpperBound));
4665
- return {
4666
- shape: wrapResult(k, id),
4667
- evolution,
4668
- diagnostics: {
4669
- hasErrors: false,
4670
- hasWarnings: false,
4671
- messages: []
4672
- }
4673
- };
4674
- } finally {
4675
- hashVec.delete();
4676
- resolved?.dispose();
4758
+ function cutWithHistory(k, Module, shape, tool, inputFaceHashes, hashUpperBound, options) {
4759
+ return subtractOrCommonWithHistory(k, Module, "cut", shape, tool, inputFaceHashes, hashUpperBound, options);
4760
+ }
4761
+ function intersectWithHistory(k, Module, shape, tool, inputFaceHashes, hashUpperBound, options) {
4762
+ return subtractOrCommonWithHistory(k, Module, "common", shape, tool, inputFaceHashes, hashUpperBound, options);
4763
+ }
4764
+ /**
4765
+ * History for a result that is its input re-stored: `fuseAll` of one solid and
4766
+ * `cutAll` with no tools keep the same TShape, so every face keeps its hash.
4767
+ */
4768
+ function identityEvolution(inputFaceHashes) {
4769
+ const modified = /* @__PURE__ */ new Map();
4770
+ for (const h of inputFaceHashes) modified.set(h, [h]);
4771
+ return {
4772
+ modified,
4773
+ generated: /* @__PURE__ */ new Map(),
4774
+ deleted: /* @__PURE__ */ new Set()
4775
+ };
4776
+ }
4777
+ /** N-way fuse with face history over every input. Needs `booleanOp`. */
4778
+ function fuseAllWithHistory(k, Module, shapes, inputFaceHashes, hashUpperBound, options) {
4779
+ return withSolidIds(k, shapes, (ids) => {
4780
+ const [first, ...rest] = ids;
4781
+ if (first !== void 0 && rest.length > 0) return viaBooleanOp(k, Module, "fuse", [first], rest, inputFaceHashes, hashUpperBound, options);
4782
+ const vec = makeVecU32(Module, ids);
4783
+ try {
4784
+ return {
4785
+ shape: wrapResult(k, k.fuseAll(vec)),
4786
+ evolution: identityEvolution(inputFaceHashes),
4787
+ diagnostics: NO_DIAGNOSTICS
4788
+ };
4789
+ } finally {
4790
+ vec.delete();
4791
+ }
4792
+ });
4793
+ }
4794
+ /** N-way cut with face history over the base and every tool. Needs `booleanOp`. */
4795
+ function cutAllWithHistory(k, Module, shape, tools, inputFaceHashes, hashUpperBound, options) {
4796
+ if (tools.length === 0) {
4797
+ const vec = makeVecU32(Module, []);
4798
+ try {
4799
+ return {
4800
+ shape: wrapResult(k, k.cutAll(unwrap(shape), vec)),
4801
+ evolution: identityEvolution(inputFaceHashes),
4802
+ diagnostics: NO_DIAGNOSTICS
4803
+ };
4804
+ } finally {
4805
+ vec.delete();
4806
+ }
4677
4807
  }
4808
+ return withSolidIds(k, [shape], (argIds) => withSolidIds(k, tools, (toolIds) => viaBooleanOp(k, Module, "cut", argIds, toolIds, inputFaceHashes, hashUpperBound, options)));
4678
4809
  }
4679
4810
  function filletWithHistory(k, Module, shape, edges, radius, inputFaceHashes, hashUpperBound) {
4680
4811
  const r = resolveUniformRadius(edges, radius);
@@ -4835,11 +4966,19 @@ var OcctWasmAdapter = class OcctWasmAdapter {
4835
4966
  Module;
4836
4967
  k;
4837
4968
  owner;
4969
+ /** Present when this occt-wasm build has `booleanOp`. */
4970
+ fuseAllWithHistory;
4971
+ /** Present when this occt-wasm build has `booleanOp`. */
4972
+ cutAllWithHistory;
4838
4973
  constructor(module, kernel, owner) {
4839
4974
  this.Module = module;
4840
4975
  this.k = wrapKernelExceptions(kernel, module);
4841
4976
  this.oc = buildOcShim(module, this.k);
4842
4977
  this.owner = owner;
4978
+ if (hasBooleanOp(this.k)) {
4979
+ this.fuseAllWithHistory = (shapes, inputFaceHashes, hashUpperBound, options) => fuseAllWithHistory(this.k, this.Module, shapes, inputFaceHashes, hashUpperBound, options);
4980
+ this.cutAllWithHistory = (shape, tools, inputFaceHashes, hashUpperBound, options) => cutAllWithHistory(this.k, this.Module, shape, tools, inputFaceHashes, hashUpperBound, options);
4981
+ }
4843
4982
  }
4844
4983
  /**
4845
4984
  * Build an adapter from occt-wasm's `OcctKernel` wrapper, retaining it for the
@@ -4911,13 +5050,13 @@ var OcctWasmAdapter = class OcctWasmAdapter {
4911
5050
  return makeRectangle(this.k, width, height);
4912
5051
  }
4913
5052
  fuse(shape, tool, options) {
4914
- return fuse(this.k, shape, tool, options);
5053
+ return fuse(this.k, this.Module, shape, tool, options);
4915
5054
  }
4916
5055
  cut(shape, tool, options) {
4917
- return cut(this.k, shape, tool, options);
5056
+ return cut(this.k, this.Module, shape, tool, options);
4918
5057
  }
4919
5058
  intersect(shape, tool, options) {
4920
- return intersect(this.k, shape, tool, options);
5059
+ return intersect(this.k, this.Module, shape, tool, options);
4921
5060
  }
4922
5061
  section(shape, plane, approximation) {
4923
5062
  return section(this.k, shape, plane, approximation);