brepjs 20.12.8 → 20.12.9

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 (93) hide show
  1. package/dist/2d.cjs +6 -6
  2. package/dist/2d.js +6 -6
  3. package/dist/{adjacencyFns-Bl109A3Z.js → adjacencyFns-1Cmjb2ot.js} +3 -3
  4. package/dist/{adjacencyFns-BfgFo-Rh.cjs → adjacencyFns-CfhGIMeR.cjs} +3 -3
  5. package/dist/{blueprint-RqemOtg5.js → blueprint-BVcuEefs.js} +5 -5
  6. package/dist/{blueprint-DTDSztfd.cjs → blueprint-DbJVzU9F.cjs} +5 -5
  7. package/dist/{blueprintFns-C7E5R89N.cjs → blueprintFns-DePTHG1I.cjs} +2 -2
  8. package/dist/{blueprintFns-B9_PhTr8.js → blueprintFns-mD4pDyFP.js} +2 -2
  9. package/dist/{blueprintSketcher-Brj4lXjj.cjs → blueprintSketcher-B5CFmhjg.cjs} +3 -3
  10. package/dist/{blueprintSketcher-B15522Kr.js → blueprintSketcher-BrGmq-65.js} +3 -3
  11. package/dist/{boolean2D-_eiIiNw1.js → boolean2D-BrHrY60M.js} +4 -4
  12. package/dist/{boolean2D-DZ8aJbI-.cjs → boolean2D-CFKg1FJ_.cjs} +4 -4
  13. package/dist/{booleanFns-D5nQ1nWS.cjs → booleanFns-C640CeaY.cjs} +4 -4
  14. package/dist/{booleanFns-cNfXGqMX.js → booleanFns-CKDyqKz0.js} +4 -4
  15. package/dist/brepjs.cjs +30 -30
  16. package/dist/brepjs.js +30 -30
  17. package/dist/{cameraFns-YhB7A_Zc.js → cameraFns-DIbua1lC.js} +3 -3
  18. package/dist/{cameraFns-6Er2lhp5.cjs → cameraFns-hXUKJkLg.cjs} +3 -3
  19. package/dist/core.cjs +2 -2
  20. package/dist/core.js +2 -2
  21. package/dist/{cornerFinder-G1WkSkVl.js → cornerFinder-BYDkloVc.js} +1 -1
  22. package/dist/{cornerFinder-D9Wx3DWu.cjs → cornerFinder-ByBGU0r7.cjs} +1 -1
  23. package/dist/{curveFns-B5_N-gMj.cjs → curveFns-Cqgtmhr0.cjs} +1 -1
  24. package/dist/{curveFns-C4CqthJp.js → curveFns-DphpaoQ4.js} +1 -1
  25. package/dist/{drawFns-DU5fewKl.js → drawFns-Ch3ah8K9.js} +12 -12
  26. package/dist/{drawFns-UPbO2heB.cjs → drawFns-GwVZX47o.cjs} +12 -12
  27. package/dist/{faceFns-C4NOGZBg.cjs → faceFns-BDqVGEoB.cjs} +2 -2
  28. package/dist/{faceFns-BgRNa5vx.js → faceFns-D4cDeMRf.js} +2 -2
  29. package/dist/{healingFns-BzOo0yyz.js → healingFns--vBKh5pa.js} +5 -5
  30. package/dist/{healingFns-i5gV3BMG.cjs → healingFns-Fu7Xl8fu.cjs} +5 -5
  31. package/dist/{helpers-DPHQt2Kr.js → helpers-CroIo2SI.js} +6 -6
  32. package/dist/{helpers-DJQeDf_5.cjs → helpers-Wnq-YPWv.cjs} +6 -6
  33. package/dist/{importFns-CwrJsNvg.js → importFns-D5Bt_44J.js} +5 -5
  34. package/dist/{importFns-BiRpt227.cjs → importFns-tHr15Lhm.cjs} +5 -5
  35. package/dist/io.cjs +2 -2
  36. package/dist/io.js +2 -2
  37. package/dist/kernel/occtWasm/evolutionOps.d.ts +4 -3
  38. package/dist/kernel/occtWasm/helpers.d.ts +14 -3
  39. package/dist/kernel/occtWasm/ioOps.d.ts +13 -13
  40. package/dist/kernel/occtWasm/modifierOps.d.ts +5 -3
  41. package/dist/kernel/occtWasm/occtWasmAdapter.cjs +1 -1
  42. package/dist/kernel/occtWasm/occtWasmAdapter.d.ts +1 -1
  43. package/dist/kernel/occtWasm/occtWasmAdapter.js +1 -1
  44. package/dist/kernel/occtWasm/occtWasmTypes.d.ts +33 -0
  45. package/dist/{loftFns-lwzTh1fI.js → loftFns-Bh_RuF7a.js} +1 -1
  46. package/dist/{loftFns-DgkK4Kj_.cjs → loftFns-T0GxcPlB.cjs} +1 -1
  47. package/dist/{measureFns-Q3K25IfN.js → measureFns-C3TZ5Fj9.js} +3 -3
  48. package/dist/{measureFns-D_RRjCZg.cjs → measureFns-DGm6ndQY.cjs} +3 -3
  49. package/dist/measurement.cjs +2 -2
  50. package/dist/measurement.js +2 -2
  51. package/dist/{meshFns-Djbb4PUC.cjs → meshFns-DDgZ3vpr.cjs} +4 -4
  52. package/dist/{meshFns-BGoJU6_P.js → meshFns-Go1XSyUh.js} +4 -4
  53. package/dist/{occtWasmAdapter-UcYZRi-w.cjs → occtWasmAdapter-CZPZnpCe.cjs} +290 -80
  54. package/dist/{occtWasmAdapter-BCCwaYkq.js → occtWasmAdapter-EM3EhKwk.js} +290 -80
  55. package/dist/operations.cjs +2 -2
  56. package/dist/operations.js +2 -2
  57. package/dist/{primitiveFns-D-aYcwt2.js → primitiveFns-CeRc4Sls.js} +5 -5
  58. package/dist/{primitiveFns-CfSnex9P.cjs → primitiveFns-Dg_XWYtp.cjs} +5 -5
  59. package/dist/{principalBoxFns-IY8FfPVj.cjs → principalBoxFns-B5zdek3y.cjs} +3 -3
  60. package/dist/{principalBoxFns-Dcp9gg5e.js → principalBoxFns-BuK-ueAB.js} +3 -3
  61. package/dist/projection.cjs +1 -1
  62. package/dist/projection.js +1 -1
  63. package/dist/query.cjs +2 -2
  64. package/dist/query.js +2 -2
  65. package/dist/{refResolveFns-gZQ1o5XK.cjs → refResolveFns-CFwsYCKA.cjs} +6 -6
  66. package/dist/{refResolveFns-BPge7T5w.js → refResolveFns-WRcvVhV-.js} +6 -6
  67. package/dist/{shapeFns-TWdr4Dv4.js → shapeFns-CYjU8PsF.js} +2 -2
  68. package/dist/{shapeFns-Bs92VrZh.cjs → shapeFns-DuxfaqTw.cjs} +2 -2
  69. package/dist/shapeRef.cjs +1 -1
  70. package/dist/shapeRef.js +1 -1
  71. package/dist/{shapeTypes-DmThK_oa.cjs → shapeTypes--7XBFlOD.cjs} +1 -1
  72. package/dist/{shapeTypes-CIH-8d_a.js → shapeTypes-DvzbSivn.js} +1 -1
  73. package/dist/sketching.cjs +3 -3
  74. package/dist/sketching.js +3 -3
  75. package/dist/{solidBuilders-q_hwYsdo.js → solidBuilders-BqSVC4cB.js} +3 -3
  76. package/dist/{solidBuilders-DGskMugU.cjs → solidBuilders-D0bIZX9K.cjs} +3 -3
  77. package/dist/{surfaceBuilders-DXo4N7wQ.js → surfaceBuilders--HOoTQad.js} +3 -3
  78. package/dist/{surfaceBuilders-DeSLKg73.cjs → surfaceBuilders-CPQHyL_5.cjs} +3 -3
  79. package/dist/text.cjs +2 -2
  80. package/dist/text.js +2 -2
  81. package/dist/{textBlueprints-Dz6wNgve.cjs → textBlueprints-B4HzJzZM.cjs} +8 -8
  82. package/dist/{textBlueprints-BYWZho_c.js → textBlueprints-plsbHqiI.js} +8 -8
  83. package/dist/{textMetrics-bKoFTj3m.cjs → textMetrics-CBwUIDI7.cjs} +1 -1
  84. package/dist/{textMetrics-k_rGqib2.js → textMetrics-IIS6DUTr.js} +1 -1
  85. package/dist/{threadFns-BeB8s0tA.js → threadFns-CmZFykpi.js} +7 -7
  86. package/dist/{threadFns-CoGAFHHt.cjs → threadFns-e8_26ZYw.cjs} +7 -7
  87. package/dist/topology.cjs +9 -9
  88. package/dist/topology.js +9 -9
  89. package/dist/{topologyQueryFns-Cp0yekBh.js → topologyQueryFns-BUzMuIs5.js} +1 -1
  90. package/dist/{topologyQueryFns-CXbCFaU2.cjs → topologyQueryFns-NszVx8a0.cjs} +1 -1
  91. package/dist/{validityTypes-DlrWkrSR.js → validityTypes-CdY06B8c.js} +1 -1
  92. package/dist/{validityTypes-m6eLRTYE.cjs → validityTypes-Ds4zNICF.cjs} +1 -1
  93. package/package.json +2 -2
@@ -2299,16 +2299,56 @@ function multiplyMatrices4x4(a, b) {
2299
2299
  for (let i = 0; i < 4; i++) for (let j = 0; j < 4; j++) for (let k = 0; k < 4; k++) result[i * 4 + j] = result[i * 4 + j] + a[i * 4 + k] * b[k * 4 + j];
2300
2300
  return result;
2301
2301
  }
2302
+ function resolveEdgeValues(edges, value) {
2303
+ const first = [];
2304
+ const second = [];
2305
+ for (const edge of edges) {
2306
+ const v = typeof value === "function" ? value(edge) : value;
2307
+ first.push(typeof v === "number" ? v : v[0]);
2308
+ second.push(typeof v === "number" ? v : v[1]);
2309
+ }
2310
+ return {
2311
+ first,
2312
+ second
2313
+ };
2314
+ }
2315
+ /** The value every edge takes on both sides, or `undefined` when they differ. */
2316
+ function uniformEdgeValue({ first, second }) {
2317
+ const [value] = first;
2318
+ if (value === void 0) return void 0;
2319
+ return first.every((v) => v === value) && second.every((v) => v === value) ? value : void 0;
2320
+ }
2302
2321
  /**
2303
- * Resolve a callback-style radius/distance to a uniform number.
2304
- * occt-wasm's fillet/chamfer take a single radius — uniform per call.
2322
+ * Run a fillet or chamfer over `edges`, naming the edges it fails on. Edges
2323
+ * that all take one value go to `uniform`, the single-value entry point every
2324
+ * occt-wasm build has; otherwise `perEdge` gets each edge's pair as `first`
2325
+ * and `second`.
2305
2326
  */
2306
- function resolveUniformRadius(edges, radius) {
2307
- if (typeof radius === "number") return radius;
2308
- if (Array.isArray(radius)) return radius[0];
2309
- if (edges.length === 0) throw new Error("occt-wasm: no edges provided");
2310
- const val = radius(edges[0]);
2311
- return typeof val === "number" ? val : val[0];
2327
+ function runEdgeTreatment(Module, edges, value, uniform, perEdge) {
2328
+ const values = resolveEdgeValues(edges, value);
2329
+ const shared = uniformEdgeValue(values);
2330
+ const edgeVec = makeVecU32(Module, edges.map(unwrap));
2331
+ try {
2332
+ if (shared !== void 0) return reportingFaultyEdges(edges, () => uniform(edgeVec, shared));
2333
+ const first = makeVecDouble(Module, values.first);
2334
+ const second = makeVecDouble(Module, values.second);
2335
+ try {
2336
+ return reportingFaultyEdges(edges, () => perEdge(edgeVec, first, second));
2337
+ } finally {
2338
+ first.delete();
2339
+ second.delete();
2340
+ }
2341
+ } finally {
2342
+ edgeVec.delete();
2343
+ }
2344
+ }
2345
+ /** Each face's draft angle, in radians. */
2346
+ function draftAnglesRad(faces, angleDeg) {
2347
+ return faces.map((face) => (typeof angleDeg === "function" ? angleDeg(face) : angleDeg) * Math.PI / 180);
2348
+ }
2349
+ /** The peer range still admits older builds, which lack the per-edge and unit entry points. */
2350
+ function needsOcctWasm59(what) {
2351
+ return new UnsupportedKernelOperationError(`occt-wasm: ${what} requires occt-wasm >= 5.9.0`);
2312
2352
  }
2313
2353
  /**
2314
2354
  * Rotate a shape from the kernel's default Z-axis to an arbitrary direction.
@@ -3754,29 +3794,42 @@ function surfaceCurvature(k, face, u, v) {
3754
3794
  // src/kernel/occtWasm/modifierOps.ts
3755
3795
  var HASH_UPPER_BOUND = 2147483647;
3756
3796
  function fillet(k, Module, shape, edges, radius) {
3757
- const r = resolveUniformRadius(edges, radius);
3758
- const vec = makeVecU32(Module, edges.map(unwrap));
3759
- try {
3760
- return wrapResult(k, reportingFaultyEdges(edges, () => k.fillet(unwrap(shape), vec, r)));
3761
- } finally {
3762
- vec.delete();
3763
- }
3797
+ const id = unwrap(shape);
3798
+ return wrapResult(k, runEdgeTreatment(Module, edges, radius, (edgeVec, r) => k.fillet(id, edgeVec, r), (edgeVec, startRadii, endRadii) => {
3799
+ if (!k.filletRadii) throw needsOcctWasm59("per-edge or tapered fillet radii");
3800
+ return k.filletRadii(id, edgeVec, startRadii, endRadii);
3801
+ }));
3764
3802
  }
3765
3803
  function chamfer(k, Module, shape, edges, distance) {
3766
- const d = resolveUniformRadius(edges, distance);
3767
- const vec = makeVecU32(Module, edges.map(unwrap));
3804
+ const id = unwrap(shape);
3805
+ const faceVec = makeVecU32(Module, []);
3768
3806
  try {
3769
- return wrapResult(k, reportingFaultyEdges(edges, () => k.chamfer(unwrap(shape), vec, d)));
3807
+ return wrapResult(k, runEdgeTreatment(Module, edges, distance, (edgeVec, d) => k.chamfer(id, edgeVec, d), (edgeVec, distances1, distances2) => {
3808
+ if (!k.chamferDistances) throw needsOcctWasm59("per-edge or asymmetric chamfer distances");
3809
+ return k.chamferDistances(id, edgeVec, distances1, distances2, faceVec);
3810
+ }));
3770
3811
  } finally {
3771
- vec.delete();
3812
+ faceVec.delete();
3772
3813
  }
3773
3814
  }
3774
3815
  function chamferDistAngle(k, Module, shape, edges, distance, angleDeg) {
3775
- const vec = makeVecU32(Module, edges.map(unwrap));
3816
+ const id = unwrap(shape);
3817
+ const edgeVec = makeVecU32(Module, edges.map(unwrap));
3776
3818
  try {
3777
- return wrapResult(k, k.chamferDistAngle(unwrap(shape), vec, distance, angleDeg));
3819
+ if (!k.chamferDistAngles) return wrapResult(k, k.chamferDistAngle(id, edgeVec, distance, angleDeg));
3820
+ const chamferDistAngles = k.chamferDistAngles.bind(k);
3821
+ const distanceVec = makeVecDouble(Module, Array(edges.length).fill(distance));
3822
+ const angleVec = makeVecDouble(Module, Array(edges.length).fill(angleDeg));
3823
+ const faceVec = makeVecU32(Module, []);
3824
+ try {
3825
+ return wrapResult(k, reportingFaultyEdges(edges, () => chamferDistAngles(id, edgeVec, distanceVec, angleVec, faceVec)));
3826
+ } finally {
3827
+ distanceVec.delete();
3828
+ angleVec.delete();
3829
+ faceVec.delete();
3830
+ }
3778
3831
  } finally {
3779
- vec.delete();
3832
+ edgeVec.delete();
3780
3833
  }
3781
3834
  }
3782
3835
  function shell(k, Module, shape, faces, thickness, tolerance) {
@@ -3858,13 +3911,30 @@ function filletVariable(k, shape, spec) {
3858
3911
  }
3859
3912
  throw new UnsupportedKernelOperationError("occt-wasm: filletVariable: unrecognized spec");
3860
3913
  }
3861
- function draft(k, shape, faces, pullDirection, _neutralPlane, angleDeg) {
3862
- let currentId = unwrap(shape);
3863
- for (const face of faces) {
3864
- const angleRad = (typeof angleDeg === "function" ? angleDeg(face) : angleDeg) * Math.PI / 180;
3865
- currentId = k.draft(currentId, unwrap(face), angleRad, pullDirection[0], pullDirection[1], pullDirection[2]);
3914
+ /**
3915
+ * Before 5.9 occt-wasm drafts one face per call about the XY plane through the
3916
+ * origin. That is the caller's plane (through `neutralPlane`, normal to the
3917
+ * pull) only for a pull along Z and a point at z = 0.
3918
+ */
3919
+ function legacyDraft(k, shape, faces, pullDirection, neutralPlane, anglesRad) {
3920
+ const [face] = faces;
3921
+ const [angle] = anglesRad;
3922
+ const [dx, dy, dz] = pullDirection;
3923
+ if (!(faces.length === 1 && dx === 0 && dy === 0 && neutralPlane[2] === 0) || face === void 0 || angle === void 0) throw needsOcctWasm59("drafting several faces, or about a neutral plane off z = 0,");
3924
+ return wrapResult(k, k.draft(unwrap(shape), unwrap(face), angle, dx, dy, dz));
3925
+ }
3926
+ /** Draft every face in one operation about the plane through `neutralPlane` normal to the pull. */
3927
+ function draft(k, Module, shape, faces, pullDirection, neutralPlane, angleDeg) {
3928
+ const anglesRad = draftAnglesRad(faces, angleDeg);
3929
+ if (!k.draftFaces) return legacyDraft(k, shape, faces, pullDirection, neutralPlane, anglesRad);
3930
+ const faceVec = makeVecU32(Module, faces.map(unwrap));
3931
+ const angleVec = makeVecDouble(Module, anglesRad);
3932
+ try {
3933
+ return wrapResult(k, k.draftFaces(unwrap(shape), faceVec, angleVec, ...pullDirection, ...neutralPlane, ...pullDirection));
3934
+ } finally {
3935
+ faceVec.delete();
3936
+ angleVec.delete();
3866
3937
  }
3867
- return wrapResult(k, currentId);
3868
3938
  }
3869
3939
  function defeature(k, Module, shape, faces) {
3870
3940
  const vec = makeVecU32(Module, faces.map(unwrap));
@@ -4480,10 +4550,85 @@ function buildGltfManifest(vCount, nCount, iCount, posBytes, nrmBytes, idxBytes,
4480
4550
  ]
4481
4551
  };
4482
4552
  }
4553
+ var MM_PER_UNIT = {
4554
+ mm: 1,
4555
+ millimeter: 1,
4556
+ millimetre: 1,
4557
+ cm: 10,
4558
+ centimeter: 10,
4559
+ centimetre: 10,
4560
+ m: 1e3,
4561
+ meter: 1e3,
4562
+ metre: 1e3,
4563
+ km: 1e6,
4564
+ kilometer: 1e6,
4565
+ kilometre: 1e6,
4566
+ in: 25.4,
4567
+ inch: 25.4,
4568
+ ft: 304.8,
4569
+ foot: 304.8,
4570
+ feet: 304.8,
4571
+ mi: 1609344,
4572
+ mile: 1609344,
4573
+ mil: .0254,
4574
+ thou: .0254,
4575
+ um: .001,
4576
+ micron: .001,
4577
+ micrometer: .001,
4578
+ micrometre: .001,
4579
+ uin: 254e-7,
4580
+ microinch: 254e-7
4581
+ };
4582
+ function mmPerUnit(unit) {
4583
+ const mm = MM_PER_UNIT[unit.toLowerCase()];
4584
+ if (mm === void 0) throw new Error(`occt-wasm: unknown STEP length unit '${unit}'`);
4585
+ return mm;
4586
+ }
4587
+ /**
4588
+ * brepjs writes lengths in `unit` and reads the shapes as `modelUnit`, which
4589
+ * defaults to `unit` (so `unit` alone relabels and does not scale). occt-wasm
4590
+ * reads shapes as millimeters and scales them into the unit written, so a
4591
+ * model in another unit is scaled to millimeters first.
4592
+ */
4593
+ function resolveStepUnits(options) {
4594
+ const write = options?.unit ?? options?.modelUnit ?? "mm";
4595
+ return {
4596
+ write,
4597
+ modelScale: mmPerUnit(options?.modelUnit ?? write)
4598
+ };
4599
+ }
4600
+ /**
4601
+ * The writer for `units`: the 5.9 unit-aware one, else the millimeter-only
4602
+ * one when the file is in millimeters anyway.
4603
+ */
4604
+ function stepWriter(withUnit, inMillimeters, units) {
4605
+ if (withUnit) return (id) => withUnit(id, units.write);
4606
+ if (mmPerUnit(units.write) === 1) return inMillimeters;
4607
+ throw needsOcctWasm59(`STEP export in '${units.write}'`);
4608
+ }
4609
+ /** Run `use` on `id` scaled by `factor` about the origin, releasing the scaled copy. */
4610
+ function withScaled(k, id, factor, use) {
4611
+ if (factor === 1) return use(id);
4612
+ const scaled = k.scale(id, 0, 0, 0, factor);
4613
+ try {
4614
+ return use(scaled);
4615
+ } finally {
4616
+ k.release(scaled);
4617
+ }
4618
+ }
4619
+ /** One STEP file holding every shape (as a compound when there are several). */
4620
+ function writeStepShapes(k, makeCompound, shapes, units) {
4621
+ const write = stepWriter(k.exportStepWithUnit?.bind(k), (id) => k.exportStep(id), units);
4622
+ if (shapes.length === 1) return withScaled(k, unwrap(shapes[0]), units.modelScale, write);
4623
+ const compoundId = unwrap(makeCompound(shapes));
4624
+ try {
4625
+ return withScaled(k, compoundId, units.modelScale, write);
4626
+ } finally {
4627
+ k.release(compoundId);
4628
+ }
4629
+ }
4483
4630
  function exportSTEP(k, makeCompound, shapes) {
4484
- if (shapes.length === 1) return k.exportStep(unwrap(shapes[0]));
4485
- const compound = makeCompound(shapes);
4486
- return k.exportStep(unwrap(compound));
4631
+ return writeStepShapes(k, makeCompound, shapes, resolveStepUnits(void 0));
4487
4632
  }
4488
4633
  function exportSTL(mesh, shape, binary, tolerance = DEFAULT_STL_TOLERANCE, angularTolerance = DEFAULT_STL_ANGULAR_TOLERANCE) {
4489
4634
  const { vertices, triangles } = mesh(shape, {
@@ -4518,14 +4663,9 @@ function importIGES(k, data) {
4518
4663
  if (!importIges) throw new UnsupportedKernelOperationError("occt-wasm: importIGES is unsupported");
4519
4664
  return [wrapResult(k, importIges(typeof data === "string" ? data : new TextDecoder().decode(data)))];
4520
4665
  }
4521
- function exportSTEPAssembly(k, Module, parts, _options) {
4666
+ function exportSTEPAssembly(k, parts, options) {
4522
4667
  if (parts.length === 0) return "";
4523
- const doc = createXCAFDocument(k, Module, parts);
4524
- try {
4525
- return writeXCAFToSTEP(k, doc);
4526
- } finally {
4527
- doc.delete();
4528
- }
4668
+ return writeXcafParts(k, parts, resolveStepUnits(options));
4529
4669
  }
4530
4670
  function exportGLB(mesh, shape, tolerance) {
4531
4671
  const result = mesh(shape, {
@@ -4653,9 +4793,9 @@ function toBREP(k, shape) {
4653
4793
  function fromBREP(k, data) {
4654
4794
  return wrapResult(k, k.fromBREP(data));
4655
4795
  }
4656
- function createXCAFDocument(k, _Module, shapes) {
4796
+ function addXcafParts(k, parts) {
4657
4797
  const docId = k.xcafNewDocument();
4658
- for (const entry of shapes) {
4798
+ for (const entry of parts) {
4659
4799
  const labelId = k.xcafAddShape(docId, unwrap(entry.shape));
4660
4800
  if (entry.name) k.xcafSetName(docId, labelId, entry.name);
4661
4801
  if (entry.color) {
@@ -4663,37 +4803,94 @@ function createXCAFDocument(k, _Module, shapes) {
4663
4803
  k.xcafSetColor(docId, labelId, r / 255, g / 255, b / 255);
4664
4804
  }
4665
4805
  }
4666
- return handle("compound", docId);
4806
+ return docId;
4667
4807
  }
4668
- function writeXCAFToSTEP(k, doc, _options) {
4669
- const docId = unwrap(doc);
4808
+ function writeXcafDoc(k, docId, units) {
4670
4809
  const roots = k.xcafGetRootLabels(docId);
4671
- const hasShapes = (() => {
4810
+ try {
4811
+ if (roots.size() === 0) return "";
4812
+ } finally {
4813
+ roots.delete();
4814
+ }
4815
+ return stepWriter(k.xcafExportSTEPWithUnit?.bind(k), (id) => k.xcafExportSTEP(id), units)(docId);
4816
+ }
4817
+ /** Write `parts` as one XCAF STEP file, scaling each into millimeters first if needed. */
4818
+ function writeXcafParts(k, parts, units) {
4819
+ const scaled = [];
4820
+ try {
4821
+ const docId = addXcafParts(k, parts.map((part) => {
4822
+ if (units.modelScale === 1) return part;
4823
+ const id = k.scale(unwrap(part.shape), 0, 0, 0, units.modelScale);
4824
+ scaled.push(id);
4825
+ return {
4826
+ ...part,
4827
+ shape: id
4828
+ };
4829
+ }));
4672
4830
  try {
4673
- return roots.size() > 0;
4831
+ return writeXcafDoc(k, docId, units);
4674
4832
  } finally {
4675
- roots.delete();
4833
+ k.xcafClose(docId);
4676
4834
  }
4677
- })();
4835
+ } finally {
4836
+ for (const id of scaled) k.release(id);
4837
+ }
4838
+ }
4839
+ function createXCAFDocument(k, makeCompound, shapes) {
4840
+ const retainedId = unwrap(makeCompound(shapes.map((s) => s.shape)));
4841
+ try {
4842
+ return {
4843
+ ...handle("compound", addXcafParts(k, shapes)),
4844
+ retainedId,
4845
+ labels: shapes.map(({ name, color }) => ({
4846
+ name,
4847
+ color
4848
+ }))
4849
+ };
4850
+ } catch (e) {
4851
+ k.release(retainedId);
4852
+ throw e;
4853
+ }
4854
+ }
4855
+ function writeXCAFToSTEP(k, doc, options) {
4856
+ const docId = unwrap(doc);
4857
+ const { retainedId, labels } = doc;
4678
4858
  try {
4679
- return hasShapes ? k.xcafExportSTEP(docId) : "";
4859
+ const units = resolveStepUnits(options);
4860
+ if (units.modelScale === 1) return writeXcafDoc(k, docId, units);
4861
+ if (retainedId === void 0 || labels === void 0) throw new Error("occt-wasm: this XCAF document does not record its parts");
4862
+ return writeScaledXcafParts(k, retainedId, labels, units);
4680
4863
  } finally {
4681
4864
  k.xcafClose(docId);
4865
+ if (retainedId !== void 0) k.release(retainedId);
4682
4866
  }
4683
4867
  }
4684
- function exportSTEPConfigured(k, Module, shapes, _options) {
4685
- if (shapes.length === 0) return "";
4686
- const doc = createXCAFDocument(k, Module, shapes.map((s) => ({
4687
- shape: s.shape,
4688
- name: s.name ?? "",
4689
- color: s.color
4690
- })));
4868
+ /** Scale the retained compound once and write its children as the labeled parts. */
4869
+ function writeScaledXcafParts(k, retainedId, labels, units) {
4870
+ const scaledId = k.scale(retainedId, 0, 0, 0, units.modelScale);
4871
+ const children = k.iterShapes(scaledId);
4872
+ const childIds = [];
4691
4873
  try {
4692
- return writeXCAFToSTEP(k, doc);
4874
+ for (let i = 0; i < children.size(); i++) childIds.push(children.get(i));
4875
+ return writeXcafParts(k, labels.map((label, i) => ({
4876
+ ...label,
4877
+ shape: handle("compound", childIds[i] ?? 0)
4878
+ })), {
4879
+ ...units,
4880
+ modelScale: 1
4881
+ });
4693
4882
  } finally {
4694
- doc.delete();
4883
+ children.delete();
4884
+ for (const id of childIds) k.release(id);
4885
+ k.release(scaledId);
4695
4886
  }
4696
4887
  }
4888
+ function exportSTEPConfigured(k, makeCompound, shapes, options) {
4889
+ if (shapes.length === 0) return "";
4890
+ const units = resolveStepUnits(options);
4891
+ if (!shapes.some((s) => s.name || s.color)) return writeStepShapes(k, makeCompound, shapes.map((s) => s.shape), units);
4892
+ return writeXcafParts(k, shapes, units);
4893
+ }
4697
4894
  // src/kernel/occtWasm/constructionOps.ts
4698
4895
  function makeVertex(k, x, y, z) {
4699
4896
  return handle("vertex", k.makeVertex(x, y, z));
@@ -5926,32 +6123,36 @@ function cutAllWithHistory(k, Module, shape, tools, inputFaceHashes, hashUpperBo
5926
6123
  return withSolidIds(k, [shape], (argIds) => withSolidIds(k, tools, (toolIds) => viaBooleanOp(k, Module, "cut", argIds, toolIds, inputFaceHashes, hashUpperBound, options)));
5927
6124
  }
5928
6125
  function filletWithHistory(k, Module, shape, edges, radius, inputFaceHashes, hashUpperBound) {
5929
- const r = resolveUniformRadius(edges, radius);
5930
- const edgeVec = makeVecU32(Module, edges.map(unwrap));
6126
+ const shapeId = unwrap(shape);
5931
6127
  const hashVec = makeVecInt(Module, inputFaceHashes);
5932
6128
  try {
5933
- const { id, evolution } = parseEvolution(reportingFaultyEdges(edges, () => k.filletWithHistory(unwrap(shape), edgeVec, r, hashVec, hashUpperBound)));
6129
+ const { id, evolution } = parseEvolution(runEdgeTreatment(Module, edges, radius, (edgeVec, r) => k.filletWithHistory(shapeId, edgeVec, r, hashVec, hashUpperBound), (edgeVec, startRadii, endRadii) => {
6130
+ if (!k.filletRadiiWithHistory) throw needsOcctWasm59("per-edge or tapered fillet radii");
6131
+ return k.filletRadiiWithHistory(shapeId, edgeVec, startRadii, endRadii, hashVec, hashUpperBound);
6132
+ }));
5934
6133
  return {
5935
6134
  shape: wrapResult(k, id),
5936
6135
  evolution
5937
6136
  };
5938
6137
  } finally {
5939
- edgeVec.delete();
5940
6138
  hashVec.delete();
5941
6139
  }
5942
6140
  }
5943
6141
  function chamferWithHistory(k, Module, shape, edges, distance, inputFaceHashes, hashUpperBound) {
5944
- const d = resolveUniformRadius(edges, distance);
5945
- const edgeVec = makeVecU32(Module, edges.map(unwrap));
6142
+ const shapeId = unwrap(shape);
6143
+ const faceVec = makeVecU32(Module, []);
5946
6144
  const hashVec = makeVecInt(Module, inputFaceHashes);
5947
6145
  try {
5948
- const { id, evolution } = parseEvolution(reportingFaultyEdges(edges, () => k.chamferWithHistory(unwrap(shape), edgeVec, d, hashVec, hashUpperBound)));
6146
+ const { id, evolution } = parseEvolution(runEdgeTreatment(Module, edges, distance, (edgeVec, d) => k.chamferWithHistory(shapeId, edgeVec, d, hashVec, hashUpperBound), (edgeVec, distances1, distances2) => {
6147
+ if (!k.chamferDistancesWithHistory) throw needsOcctWasm59("per-edge or asymmetric chamfer distances");
6148
+ return k.chamferDistancesWithHistory(shapeId, edgeVec, distances1, distances2, faceVec, hashVec, hashUpperBound);
6149
+ }));
5949
6150
  return {
5950
6151
  shape: wrapResult(k, id),
5951
6152
  evolution
5952
6153
  };
5953
6154
  } finally {
5954
- edgeVec.delete();
6155
+ faceVec.delete();
5955
6156
  hashVec.delete();
5956
6157
  }
5957
6158
  }
@@ -5993,21 +6194,30 @@ function offsetWithHistory(k, Module, shape, distance, inputFaceHashes, hashUppe
5993
6194
  hashVec.delete();
5994
6195
  }
5995
6196
  }
5996
- function draftWithHistory(k, shape, faces, pullDirection, angleDeg) {
5997
- const [dx, dy, dz] = pullDirection;
5998
- let currentId = unwrap(shape);
5999
- for (const face of faces) {
6000
- const angleRad = (typeof angleDeg === "number" ? angleDeg : angleDeg(face)) * Math.PI / 180;
6001
- currentId = k.draft(currentId, unwrap(face), angleRad, dx, dy, dz);
6002
- }
6003
- return {
6004
- shape: wrapResult(k, currentId),
6197
+ function draftWithHistory(k, Module, shape, faces, pullDirection, neutralPlane, angleDeg, inputFaceHashes, hashUpperBound) {
6198
+ if (!k.draftFacesWithHistory) return {
6199
+ shape: draft(k, Module, shape, faces, pullDirection, neutralPlane, angleDeg),
6005
6200
  evolution: {
6006
6201
  modified: /* @__PURE__ */ new Map(),
6007
6202
  generated: /* @__PURE__ */ new Map(),
6008
6203
  deleted: /* @__PURE__ */ new Set()
6009
6204
  }
6010
6205
  };
6206
+ const anglesRad = draftAnglesRad(faces, angleDeg);
6207
+ const faceVec = makeVecU32(Module, faces.map(unwrap));
6208
+ const angleVec = makeVecDouble(Module, anglesRad);
6209
+ const hashVec = makeVecInt(Module, inputFaceHashes);
6210
+ try {
6211
+ const { id, evolution } = parseEvolution(k.draftFacesWithHistory(unwrap(shape), faceVec, angleVec, ...pullDirection, ...neutralPlane, ...pullDirection, hashVec, hashUpperBound));
6212
+ return {
6213
+ shape: wrapResult(k, id),
6214
+ evolution
6215
+ };
6216
+ } finally {
6217
+ faceVec.delete();
6218
+ angleVec.delete();
6219
+ hashVec.delete();
6220
+ }
6011
6221
  }
6012
6222
  function applyComposedTransformWithHistory(transformFn, iterShapesFn, hashCodeFn, shape, transformHandle, inputFaceHashes, hashUpperBound) {
6013
6223
  const result = transformFn(shape, transformHandle);
@@ -6369,7 +6579,7 @@ var OcctWasmAdapter = class OcctWasmAdapter {
6369
6579
  return filletVariable(this.k, shape, spec);
6370
6580
  }
6371
6581
  draft(shape, faces, pullDirection, neutralPlane, angleDeg) {
6372
- return draft(this.k, shape, faces, pullDirection, neutralPlane, angleDeg);
6582
+ return draft(this.k, this.Module, shape, faces, pullDirection, neutralPlane, angleDeg);
6373
6583
  }
6374
6584
  defeature(shape, faces) {
6375
6585
  return defeature(this.k, this.Module, shape, faces);
@@ -6461,8 +6671,8 @@ var OcctWasmAdapter = class OcctWasmAdapter {
6461
6671
  offsetWithHistory(shape, distance, inputFaceHashes, hashUpperBound, tolerance) {
6462
6672
  return offsetWithHistory(this.k, this.Module, shape, distance, inputFaceHashes, hashUpperBound, tolerance);
6463
6673
  }
6464
- draftWithHistory(shape, faces, pullDirection, _neutralPlane, angleDeg, _inputFaceHashes, _hashUpperBound) {
6465
- return draftWithHistory(this.k, shape, faces, pullDirection, angleDeg);
6674
+ draftWithHistory(shape, faces, pullDirection, neutralPlane, angleDeg, inputFaceHashes, hashUpperBound) {
6675
+ return draftWithHistory(this.k, this.Module, shape, faces, pullDirection, neutralPlane, angleDeg, inputFaceHashes, hashUpperBound);
6466
6676
  }
6467
6677
  applyComposedTransformWithHistory(shape, transformHandle, inputFaceHashes, hashUpperBound) {
6468
6678
  return applyComposedTransformWithHistory((s, t) => this.transform(s, t), (s, t) => this.iterShapes(s, t), (s, ub) => this.hashCode(s, ub), shape, transformHandle, inputFaceHashes, hashUpperBound);
@@ -6498,7 +6708,7 @@ var OcctWasmAdapter = class OcctWasmAdapter {
6498
6708
  return importIGES(this.k, data);
6499
6709
  }
6500
6710
  exportSTEPAssembly(parts, options) {
6501
- return exportSTEPAssembly(this.k, this.Module, parts, options);
6711
+ return exportSTEPAssembly(this.k, parts, options);
6502
6712
  }
6503
6713
  export3MF(_shape, _tolerance) {
6504
6714
  throw new Error("export3MF is only available with the brepkit kernel");
@@ -6528,13 +6738,13 @@ var OcctWasmAdapter = class OcctWasmAdapter {
6528
6738
  return fromBREP(this.k, data);
6529
6739
  }
6530
6740
  createXCAFDocument(shapes) {
6531
- return createXCAFDocument(this.k, this.Module, shapes);
6741
+ return createXCAFDocument(this.k, this.makeCompound.bind(this), shapes);
6532
6742
  }
6533
6743
  writeXCAFToSTEP(doc, options) {
6534
6744
  return writeXCAFToSTEP(this.k, doc, options);
6535
6745
  }
6536
6746
  exportSTEPConfigured(shapes, options) {
6537
- return exportSTEPConfigured(this.k, this.Module, shapes, options);
6747
+ return exportSTEPConfigured(this.k, this.makeCompound.bind(this), shapes, options);
6538
6748
  }
6539
6749
  volume(shape) {
6540
6750
  return volume(this.k, shape);