brepjs 20.12.15 → 20.13.1

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 (99) hide show
  1. package/dist/2d.cjs +6 -6
  2. package/dist/2d.js +6 -6
  3. package/dist/{adjacencyFns-BHdJW5pd.cjs → adjacencyFns-BA9xrrmS.cjs} +3 -3
  4. package/dist/{adjacencyFns-C4yjxKu4.js → adjacencyFns-C4Tui11_.js} +3 -3
  5. package/dist/{blueprint-D4juQWXs.cjs → blueprint-D193PMxX.cjs} +5 -5
  6. package/dist/{blueprint-ku_wYIZl.js → blueprint-DH0H9OWv.js} +5 -5
  7. package/dist/{blueprintFns-B0cqtoFB.js → blueprintFns-Bfiqbmtc.js} +2 -2
  8. package/dist/{blueprintFns-8obtvMEn.cjs → blueprintFns-DYIKTIvJ.cjs} +2 -2
  9. package/dist/{blueprintSketcher-CRFpnZAS.cjs → blueprintSketcher-B1UrnhFt.cjs} +3 -3
  10. package/dist/{blueprintSketcher-Dpdgf5aR.js → blueprintSketcher-RA8ti2Xp.js} +3 -3
  11. package/dist/{boolean2D-CnCDsRJ4.js → boolean2D-CCKUmway.js} +4 -4
  12. package/dist/{boolean2D-D3jxohLZ.cjs → boolean2D-XIehGONX.cjs} +4 -4
  13. package/dist/{booleanFns-CItcObM_.js → booleanFns-CyxmW1pL.js} +5 -5
  14. package/dist/{booleanFns-GBPAGQ5g.cjs → booleanFns-zRlNDHQY.cjs} +5 -5
  15. package/dist/brepjs.cjs +30 -30
  16. package/dist/brepjs.js +30 -30
  17. package/dist/{cameraFns-C2XhSqrr.cjs → cameraFns-BDjt94fY.cjs} +3 -3
  18. package/dist/{cameraFns-B6ujpyKy.js → cameraFns-CtpBKmwD.js} +3 -3
  19. package/dist/core.cjs +2 -2
  20. package/dist/core.js +2 -2
  21. package/dist/{cornerFinder-D3nBhdfi.js → cornerFinder-CIryesVI.js} +1 -1
  22. package/dist/{cornerFinder-CqHx_Itj.cjs → cornerFinder-DWN1Vkea.cjs} +1 -1
  23. package/dist/{curveFns-BQjw0VBB.cjs → curveFns-0vAErrs9.cjs} +1 -1
  24. package/dist/{curveFns-nAwtilbz.js → curveFns-b_C6tBeU.js} +1 -1
  25. package/dist/{drawFns-D9q4Hxc_.js → drawFns--_Bd7ONO.js} +12 -12
  26. package/dist/{drawFns-hFjTvdw4.cjs → drawFns-vcRf5KKV.cjs} +12 -12
  27. package/dist/{faceFns-DdMpocg9.cjs → faceFns-DzNcnzS5.cjs} +2 -2
  28. package/dist/{faceFns-Dodcduw8.js → faceFns-WtnWpVQl.js} +2 -2
  29. package/dist/{healingFns-GNF1rFuw.js → healingFns-B82dNj9P.js} +79 -31
  30. package/dist/{healingFns-Cdpu44d0.cjs → healingFns-D26gj7M5.cjs} +79 -31
  31. package/dist/{helpers-TWIfnyto.cjs → helpers-BO5NktbN.cjs} +6 -6
  32. package/dist/{helpers-CoVtL5c9.js → helpers-C5I0ZqYC.js} +6 -6
  33. package/dist/{importFns-P-TcOJ1G.cjs → importFns-Ceb2VgcK.cjs} +34 -20
  34. package/dist/{importFns-C9TUFscx.js → importFns-sxpO2z86.js} +34 -20
  35. package/dist/io/importFns.d.ts +12 -5
  36. package/dist/io.cjs +2 -2
  37. package/dist/io.js +2 -2
  38. package/dist/kernel/brepkit/igesMerge.d.ts +13 -0
  39. package/dist/kernel/brepkit/stepMerge.d.ts +14 -0
  40. package/dist/kernel/interfaces/evolutionOps.d.ts +8 -0
  41. package/dist/kernel/interfaces/modifierOps.d.ts +17 -8
  42. package/dist/kernel/occtWasm/evolutionOps.d.ts +2 -0
  43. package/dist/kernel/occtWasm/helpers.d.ts +6 -0
  44. package/dist/kernel/occtWasm/modifierOps.d.ts +2 -8
  45. package/dist/kernel/occtWasm/occtWasmAdapter.cjs +1 -1
  46. package/dist/kernel/occtWasm/occtWasmAdapter.d.ts +3 -5
  47. package/dist/kernel/occtWasm/occtWasmAdapter.js +1 -1
  48. package/dist/kernel/occtWasm/occtWasmTypes.d.ts +2 -0
  49. package/dist/{loftFns-Uq6BhPVL.cjs → loftFns-KXrP3aat.cjs} +1 -1
  50. package/dist/{loftFns-DVsWk-9v.js → loftFns-Y-aBF_f7.js} +1 -1
  51. package/dist/{measureFns-DoUWDfAP.js → measureFns-B0PhQ5dY.js} +3 -3
  52. package/dist/{measureFns-B0Cy7GcQ.cjs → measureFns-C8UjdHpB.cjs} +3 -3
  53. package/dist/measurement.cjs +2 -2
  54. package/dist/measurement.js +2 -2
  55. package/dist/{meshFns-BpBgKIIE.js → meshFns-BazHDlpY.js} +4 -4
  56. package/dist/{meshFns-Bz9PPZWP.cjs → meshFns-BnkXZ0Xm.cjs} +4 -4
  57. package/dist/{occtWasmAdapter-DzxyXpLG.cjs → occtWasmAdapter-4YnvqZOW.cjs} +122 -9
  58. package/dist/{occtWasmAdapter-DeVQrL5n.js → occtWasmAdapter-CGsnjMOe.js} +122 -9
  59. package/dist/operations.cjs +2 -2
  60. package/dist/operations.js +2 -2
  61. package/dist/{primitiveFns-DE1RROq-.cjs → primitiveFns-BM709SMs.cjs} +5 -5
  62. package/dist/{primitiveFns-Crqsdby_.js → primitiveFns-BZALpT35.js} +5 -5
  63. package/dist/{principalBoxFns-CzEBI6tC.cjs → principalBoxFns-C_hSxRc7.cjs} +3 -3
  64. package/dist/{principalBoxFns-DwitCsif.js → principalBoxFns-DLOoxmZB.js} +3 -3
  65. package/dist/projection.cjs +1 -1
  66. package/dist/projection.js +1 -1
  67. package/dist/query.cjs +2 -2
  68. package/dist/query.js +2 -2
  69. package/dist/{refResolveFns-BJz9UvXM.js → refResolveFns-BA1ES0sL.js} +6 -6
  70. package/dist/{refResolveFns-DgM_B9WU.cjs → refResolveFns-BkSLmvyY.cjs} +6 -6
  71. package/dist/{shapeFns-B9LB54_t.cjs → shapeFns-Bgql2_E6.cjs} +2 -2
  72. package/dist/{shapeFns-Ddh0M4Iz.js → shapeFns-CSWOXGx9.js} +2 -2
  73. package/dist/shapeRef.cjs +1 -1
  74. package/dist/shapeRef.js +1 -1
  75. package/dist/{shapeTypes-C1Ljs72p.cjs → shapeTypes-BFfnNmzj.cjs} +214 -23
  76. package/dist/{shapeTypes-DiCMRU6Z.js → shapeTypes-C7hqbMwl.js} +214 -23
  77. package/dist/sketching.cjs +3 -3
  78. package/dist/sketching.js +3 -3
  79. package/dist/{solidBuilders-Dzhk5L6w.js → solidBuilders-B01dFnd7.js} +3 -3
  80. package/dist/{solidBuilders-C6_6tZXG.cjs → solidBuilders-CWw3yasa.cjs} +3 -3
  81. package/dist/{surfaceBuilders-Idshk6C3.js → surfaceBuilders-Cn7GIsyR.js} +3 -3
  82. package/dist/{surfaceBuilders-CU_vd71e.cjs → surfaceBuilders-DL7UTpW2.cjs} +3 -3
  83. package/dist/text.cjs +2 -2
  84. package/dist/text.js +2 -2
  85. package/dist/{textBlueprints-DyT-kfxc.js → textBlueprints-B7gDC-aP.js} +8 -8
  86. package/dist/{textBlueprints-BmIxy1fi.cjs → textBlueprints-dOnCv38X.cjs} +8 -8
  87. package/dist/{textMetrics-DuzBLY9z.js → textMetrics-BFzj8Zvn.js} +1 -1
  88. package/dist/{textMetrics-CbDASt0r.cjs → textMetrics-Cqc0xzHC.cjs} +1 -1
  89. package/dist/{threadFns-YPn7KF9u.cjs → threadFns-DwTPnV_1.cjs} +7 -7
  90. package/dist/{threadFns-CN1R3YKa.js → threadFns-M8pqF4TW.js} +7 -7
  91. package/dist/topology/apiTypes.d.ts +9 -0
  92. package/dist/topology/chamferAngleFns.d.ts +18 -9
  93. package/dist/topology.cjs +9 -9
  94. package/dist/topology.js +9 -9
  95. package/dist/{topologyQueryFns-0Ycw298Y.cjs → topologyQueryFns-95FptXtu.cjs} +1 -1
  96. package/dist/{topologyQueryFns-CNOqc1rB.js → topologyQueryFns-C3-_9dFM.js} +1 -1
  97. package/dist/{validityTypes-CXnc46WG.cjs → validityTypes--tgDeAF8.cjs} +1 -1
  98. package/dist/{validityTypes-rUpnumpL.js → validityTypes-C6qOP241.js} +1 -1
  99. package/package.json +2 -2
@@ -1,6 +1,6 @@
1
- const require_shapeTypes = require("./shapeTypes-C1Ljs72p.cjs");
1
+ const require_shapeTypes = require("./shapeTypes-BFfnNmzj.cjs");
2
2
  const require_errors = require("./errors-O_blYTWT.cjs");
3
- const require_topologyQueryFns = require("./topologyQueryFns-0Ycw298Y.cjs");
3
+ const require_topologyQueryFns = require("./topologyQueryFns-95FptXtu.cjs");
4
4
  const require_types = require("./types-CjF9Rofr.cjs");
5
5
  // src/topology/cast.ts
6
6
  var TOPO_ENUM = {
@@ -1,6 +1,6 @@
1
- import { O as getOrQueryType, i as castShape, q as getKernel } from "./shapeTypes-DiCMRU6Z.js";
1
+ import { O as getOrQueryType, i as castShape, q as getKernel } from "./shapeTypes-C7hqbMwl.js";
2
2
  import { E as ok, P as unwrap, g as err, l as typeCastError } from "./errors-BTccWbtE.js";
3
- import { a as getCachedSurfaceType } from "./topologyQueryFns-CNOqc1rB.js";
3
+ import { a as getCachedSurfaceType } from "./topologyQueryFns-C3-_9dFM.js";
4
4
  import { r as toVec3 } from "./types-CKXsIm9-.js";
5
5
  // src/topology/cast.ts
6
6
  var TOPO_ENUM = {
@@ -1,11 +1,13 @@
1
- import { C as isSolid, D as getShapeKind, T as isWire, Y as getKernelCapabilities, h as disposeResultShape, i as castShape, m as disposeDowncastSource, n as castResultShape, q as getKernel, r as castResultShapeWithKnownType, x as isShape3D, y as isFace } from "./shapeTypes-DiCMRU6Z.js";
2
- import { j as isUnsupportedKernelOperationError, n as faultyEdgeIndexesOf } from "./occtWasmAdapter-DeVQrL5n.js";
1
+ import { C as isSolid, D as getShapeKind, T as isWire, Y as getKernelCapabilities, h as disposeResultShape, i as castShape, m as disposeDowncastSource, n as castResultShape, q as getKernel, r as castResultShapeWithKnownType, x as isShape3D, y as isFace } from "./shapeTypes-C7hqbMwl.js";
2
+ import { j as isUnsupportedKernelOperationError, n as faultyEdgeIndexesOf } from "./occtWasmAdapter-CGsnjMOe.js";
3
3
  import { E as ok, b as isErr, d as validationError, g as err, i as kernelError, l as typeCastError, t as BrepErrorCode, u as unsupportedError, x as isOk } from "./errors-BTccWbtE.js";
4
- import { C as subShapeHashes, O as getSuggestionForCode, c as getFaces, i as getCachedIsValid, m as invalidateShapeCache, p as getWires, s as getEdges } from "./topologyQueryFns-CNOqc1rB.js";
4
+ import { C as subShapeHashes, O as getSuggestionForCode, c as getFaces, i as getCachedIsValid, m as invalidateShapeCache, p as getWires, s as getEdges } from "./topologyQueryFns-C3-_9dFM.js";
5
5
  import { n as HASH_CODE_MAX } from "./constants-iraOnb2p.js";
6
- import { y as downcast } from "./faceFns-Dodcduw8.js";
7
- import { a as fuse, f as collectInputFaceHashes, h as propagateMetadataByHash, i as cutAll, m as propagateAllMetadata, n as copyAsBooleanResult, o as fuseAll, r as cut } from "./booleanFns-CItcObM_.js";
6
+ import { y as downcast } from "./faceFns-WtnWpVQl.js";
7
+ import { a as fuse, f as collectInputFaceHashes, h as propagateMetadataByHash, i as cutAll, m as propagateAllMetadata, n as copyAsBooleanResult, o as fuseAll, r as cut } from "./booleanFns-CyxmW1pL.js";
8
+ import { a as isSameShape } from "./shapeFns-CSWOXGx9.js";
8
9
  import { t as firstOrThrow } from "./arrayAccess-BpgouNir.js";
10
+ import { i as facesOfEdge } from "./adjacencyFns-C4Tui11_.js";
9
11
  // src/topology/threeHelpers.ts
10
12
  /**
11
13
  * Convert a ShapeMesh into BufferGeometry-compatible typed arrays.
@@ -729,6 +731,10 @@ function removeFaces(shape, faces) {
729
731
  * Provides chamferDistAngle(), which chamfers edges using one distance
730
732
  * measured along one face and one angle that determines the chamfer on the
731
733
  * other, and chamferDistAngles(), which gives each edge its own pair.
734
+ *
735
+ * Face origins, tags and colors carry over to the faces a chamfer keeps where
736
+ * the kernel reports face history for it (occt-wasm 5.11.0 or later);
737
+ * elsewhere only face origins do.
732
738
  */
733
739
  function validateDistAngle(distance, angleDeg) {
734
740
  if (distance <= 0) return err(validationError("CHAMFER_ANGLE_BAD_DISTANCE", `distance must be positive, got ${distance}`, void 0, { distance }));
@@ -746,10 +752,31 @@ function chamferAngleFailed(operation, e, edges, metadata) {
746
752
  }, failedEdges && failedEdges.length > 0 ? "The chamfer could not be built on metadata.failedEdges: use a smaller distance there, or leave those edges out" : void 0));
747
753
  }
748
754
  /**
755
+ * Chamfer `entries` with the kernel's distance-angle chamfer that reports face
756
+ * history. A kernel without one, or a build that rejects it as unsupported
757
+ * (occt-wasm before 5.11), runs `withoutHistory` instead.
758
+ */
759
+ function buildChamfer(shape, entries, withoutHistory) {
760
+ const kernel = getKernel();
761
+ if (kernel.chamferDistAnglesWithHistory) try {
762
+ const { shape: raw, evolution } = kernel.chamferDistAnglesWithHistory(shape.wrapped, entries, collectInputFaceHashes([shape]), HASH_CODE_MAX);
763
+ return {
764
+ raw,
765
+ evolution
766
+ };
767
+ } catch (e) {
768
+ if (!isUnsupportedKernelOperationError(e)) throw e;
769
+ }
770
+ return {
771
+ raw: withoutHistory(),
772
+ evolution: void 0
773
+ };
774
+ }
775
+ /**
749
776
  * Cast a fresh kernel result to a 3D shape, releasing every intermediate slot,
750
- * and carry the face origins of `input` over to it.
777
+ * and carry the face metadata of `input` over to it.
751
778
  */
752
- function castChamferResult(input, raw) {
779
+ function castChamferResult(input, { raw, evolution }) {
753
780
  const downcastResult = downcast(raw);
754
781
  if (isErr(downcastResult)) {
755
782
  getKernel().dispose(raw);
@@ -761,7 +788,8 @@ function castChamferResult(input, raw) {
761
788
  disposeResultShape(wrapped);
762
789
  return err(typeCastError("CHAMFER_ANGLE_NOT_3D", "chamferDistAngle did not produce a 3D shape"));
763
790
  }
764
- propagateMetadataByHash([input], wrapped);
791
+ if (evolution) propagateAllMetadata(evolution, [input], wrapped);
792
+ else propagateMetadataByHash([input], wrapped);
765
793
  return ok(wrapped);
766
794
  }
767
795
  /**
@@ -785,10 +813,14 @@ function chamferDistAngle(shape, edges, distance, angleDeg) {
785
813
  const invalid = validateDistAngle(distance, angleDeg);
786
814
  if (invalid) return invalid;
787
815
  const kernel = getKernel();
788
- let raw;
816
+ let built;
789
817
  try {
790
818
  const rawEdges = edges.map((e) => e.wrapped);
791
- raw = kernel.chamferDistAngle(shape.wrapped, rawEdges, distance, angleDeg);
819
+ built = buildChamfer(shape, rawEdges.map((edge) => ({
820
+ edge,
821
+ distance,
822
+ angleDeg
823
+ })), () => kernel.chamferDistAngle(shape.wrapped, rawEdges, distance, angleDeg));
792
824
  } catch (e) {
793
825
  if (isUnsupportedKernelOperationError(e)) return err(unsupportedError(BrepErrorCode.UNSUPPORTED_CAPABILITY, `chamferDistAngle: the ${kernel.kernelId} kernel has no distance-angle chamfer`, e, { kernel: kernel.kernelId }, "Chamfer by one symmetric distance instead, or use the occt-wasm kernel"));
794
826
  return chamferAngleFailed("chamferDistAngle", e, edges, {
@@ -797,24 +829,32 @@ function chamferDistAngle(shape, edges, distance, angleDeg) {
797
829
  edgeCount: edges.length
798
830
  });
799
831
  }
800
- return castChamferResult(shape, raw);
832
+ return castChamferResult(shape, built);
801
833
  }
802
- function perEdgeUnsupported(kernelId, cause) {
803
- return err(unsupportedError(BrepErrorCode.UNSUPPORTED_CAPABILITY, `chamferDistAngles: the ${kernelId} kernel cannot give each edge its own distance and angle`, cause, { kernel: kernelId }, "Use the occt-wasm kernel (5.9.0 or later), or give every edge the same { distance, angle } on a kernel that has a distance-angle chamfer"));
834
+ function perEdgeUnsupported(kernelId, cause, facesGiven) {
835
+ return err(unsupportedError(BrepErrorCode.UNSUPPORTED_CAPABILITY, facesGiven ? `chamferDistAngles: the ${kernelId} kernel cannot measure a distance-angle chamfer from a given face` : `chamferDistAngles: the ${kernelId} kernel cannot give each edge its own distance and angle`, cause, { kernel: kernelId }, facesGiven ? "Use the occt-wasm kernel (5.9.0 or later), or leave out face so the kernel picks it" : "Use the occt-wasm kernel (5.9.0 or later), or give every edge the same { distance, angle } on a kernel that has a distance-angle chamfer"));
836
+ }
837
+ /** The first entry whose `face` is not one of the faces of `shape` its edge joins. */
838
+ function entryWithStrayFace(shape, entries) {
839
+ return entries.find(({ edge, face }) => face !== void 0 && !facesOfEdge(shape, edge).some((f) => isSameShape(f, face)));
804
840
  }
805
841
  /**
806
842
  * Chamfer each edge by its own distance and angle, in one operation.
807
843
  *
808
- * Edges that all share one distance and angle go through
809
- * {@link chamferDistAngle}, which every kernel but brepkit provides. Different
810
- * values need a kernel with a per-edge distance-angle chamfer (occt-wasm 5.9.0
811
- * or later); on any other kernel the result is an `UNSUPPORTED_CAPABILITY` error. On
812
- * occt-wasm the edges of one tangent-continuous contour must share their
813
- * distance and angle, or the result is `CHAMFER_ANGLE_FAILED`.
844
+ * Edges that all share one distance and angle, with no reference face given,
845
+ * go through {@link chamferDistAngle}, which every kernel but brepkit provides.
846
+ * Different values, or any `face`, need a kernel with a per-edge distance-angle
847
+ * chamfer (occt-wasm 5.9.0 or later); on any other kernel the result is an
848
+ * `UNSUPPORTED_CAPABILITY` error. On occt-wasm the edges of one
849
+ * tangent-continuous contour must state the same chamfer, or the result is
850
+ * `CHAMFER_ANGLE_FAILED`; from 5.11.0 an edge may state it from the face on
851
+ * the other side of the contour.
814
852
  *
815
853
  * @param shape - The 3D shape to chamfer.
816
- * @param entries - Each edge with its distance and angle (must not be empty).
817
- * @returns Ok with the chamfered shape, or Err on invalid input, an unsupported
854
+ * @param entries - Each edge with its distance, angle and optional reference
855
+ * face (must not be empty).
856
+ * @returns Ok with the chamfered shape, or Err on invalid input (a `face` not
857
+ * adjacent to its edge is `CHAMFER_ANGLE_FACE_NOT_ADJACENT`), an unsupported
818
858
  * kernel, or kernel failure.
819
859
  */
820
860
  function chamferDistAngles(shape, entries) {
@@ -824,23 +864,31 @@ function chamferDistAngles(shape, entries) {
824
864
  const invalid = validateDistAngle(distance, angle);
825
865
  if (invalid) return invalid;
826
866
  }
867
+ const stray = entryWithStrayFace(shape, entries);
868
+ if (stray) return err(validationError("CHAMFER_ANGLE_FACE_NOT_ADJACENT", "chamferDistAngles: a reference face is not one of the two faces its edge joins", void 0, {
869
+ edge: stray.edge,
870
+ face: stray.face
871
+ }, "Pick the face from facesOfEdge(shape, edge) on the shape being chamfered, or leave out face"));
827
872
  const edges = entries.map((e) => e.edge);
828
- if (entries.every((e) => e.distance === first.distance && e.angle === first.angle)) return chamferDistAngle(shape, edges, first.distance, first.angle);
873
+ const facesGiven = entries.some((e) => e.face !== void 0);
874
+ if (entries.every((e) => e.distance === first.distance && e.angle === first.angle) && !facesGiven) return chamferDistAngle(shape, edges, first.distance, first.angle);
829
875
  const kernel = getKernel();
830
876
  const perEdge = kernel.chamferDistAngles?.bind(kernel);
831
- if (!perEdge) return perEdgeUnsupported(kernel.kernelId, void 0);
832
- let raw;
877
+ if (!perEdge) return perEdgeUnsupported(kernel.kernelId, void 0, facesGiven);
878
+ const kernelEntries = entries.map(({ edge, distance, angle, face }) => ({
879
+ edge: edge.wrapped,
880
+ distance,
881
+ angleDeg: angle,
882
+ face: face?.wrapped
883
+ }));
884
+ let built;
833
885
  try {
834
- raw = perEdge(shape.wrapped, entries.map(({ edge, distance, angle }) => ({
835
- edge: edge.wrapped,
836
- distance,
837
- angleDeg: angle
838
- })));
886
+ built = buildChamfer(shape, kernelEntries, () => perEdge(shape.wrapped, kernelEntries));
839
887
  } catch (e) {
840
- if (isUnsupportedKernelOperationError(e)) return perEdgeUnsupported(kernel.kernelId, e);
888
+ if (isUnsupportedKernelOperationError(e)) return perEdgeUnsupported(kernel.kernelId, e, facesGiven);
841
889
  return chamferAngleFailed("chamferDistAngles", e, edges, { edgeCount: entries.length });
842
890
  }
843
- return castChamferResult(shape, raw);
891
+ return castChamferResult(shape, built);
844
892
  }
845
893
  // src/topology/nurbsFns.ts
846
894
  /**
@@ -1,11 +1,13 @@
1
- const require_shapeTypes = require("./shapeTypes-C1Ljs72p.cjs");
2
- const require_occtWasmAdapter = require("./occtWasmAdapter-DzxyXpLG.cjs");
1
+ const require_shapeTypes = require("./shapeTypes-BFfnNmzj.cjs");
2
+ const require_occtWasmAdapter = require("./occtWasmAdapter-4YnvqZOW.cjs");
3
3
  const require_errors = require("./errors-O_blYTWT.cjs");
4
- const require_topologyQueryFns = require("./topologyQueryFns-0Ycw298Y.cjs");
4
+ const require_topologyQueryFns = require("./topologyQueryFns-95FptXtu.cjs");
5
5
  const require_constants = require("./constants-oee0S_x6.cjs");
6
- const require_faceFns = require("./faceFns-DdMpocg9.cjs");
7
- const require_booleanFns = require("./booleanFns-GBPAGQ5g.cjs");
6
+ const require_faceFns = require("./faceFns-DzNcnzS5.cjs");
7
+ const require_booleanFns = require("./booleanFns-zRlNDHQY.cjs");
8
+ const require_shapeFns = require("./shapeFns-Bgql2_E6.cjs");
8
9
  const require_arrayAccess = require("./arrayAccess-DpJYARwv.cjs");
10
+ const require_adjacencyFns = require("./adjacencyFns-BA9xrrmS.cjs");
9
11
  // src/topology/threeHelpers.ts
10
12
  /**
11
13
  * Convert a ShapeMesh into BufferGeometry-compatible typed arrays.
@@ -729,6 +731,10 @@ function removeFaces(shape, faces) {
729
731
  * Provides chamferDistAngle(), which chamfers edges using one distance
730
732
  * measured along one face and one angle that determines the chamfer on the
731
733
  * other, and chamferDistAngles(), which gives each edge its own pair.
734
+ *
735
+ * Face origins, tags and colors carry over to the faces a chamfer keeps where
736
+ * the kernel reports face history for it (occt-wasm 5.11.0 or later);
737
+ * elsewhere only face origins do.
732
738
  */
733
739
  function validateDistAngle(distance, angleDeg) {
734
740
  if (distance <= 0) return require_errors.err(require_errors.validationError("CHAMFER_ANGLE_BAD_DISTANCE", `distance must be positive, got ${distance}`, void 0, { distance }));
@@ -746,10 +752,31 @@ function chamferAngleFailed(operation, e, edges, metadata) {
746
752
  }, failedEdges && failedEdges.length > 0 ? "The chamfer could not be built on metadata.failedEdges: use a smaller distance there, or leave those edges out" : void 0));
747
753
  }
748
754
  /**
755
+ * Chamfer `entries` with the kernel's distance-angle chamfer that reports face
756
+ * history. A kernel without one, or a build that rejects it as unsupported
757
+ * (occt-wasm before 5.11), runs `withoutHistory` instead.
758
+ */
759
+ function buildChamfer(shape, entries, withoutHistory) {
760
+ const kernel = require_shapeTypes.getKernel();
761
+ if (kernel.chamferDistAnglesWithHistory) try {
762
+ const { shape: raw, evolution } = kernel.chamferDistAnglesWithHistory(shape.wrapped, entries, require_booleanFns.collectInputFaceHashes([shape]), require_constants.HASH_CODE_MAX);
763
+ return {
764
+ raw,
765
+ evolution
766
+ };
767
+ } catch (e) {
768
+ if (!require_occtWasmAdapter.isUnsupportedKernelOperationError(e)) throw e;
769
+ }
770
+ return {
771
+ raw: withoutHistory(),
772
+ evolution: void 0
773
+ };
774
+ }
775
+ /**
749
776
  * Cast a fresh kernel result to a 3D shape, releasing every intermediate slot,
750
- * and carry the face origins of `input` over to it.
777
+ * and carry the face metadata of `input` over to it.
751
778
  */
752
- function castChamferResult(input, raw) {
779
+ function castChamferResult(input, { raw, evolution }) {
753
780
  const downcastResult = require_faceFns.downcast(raw);
754
781
  if (require_errors.isErr(downcastResult)) {
755
782
  require_shapeTypes.getKernel().dispose(raw);
@@ -761,7 +788,8 @@ function castChamferResult(input, raw) {
761
788
  require_shapeTypes.disposeResultShape(wrapped);
762
789
  return require_errors.err(require_errors.typeCastError("CHAMFER_ANGLE_NOT_3D", "chamferDistAngle did not produce a 3D shape"));
763
790
  }
764
- require_booleanFns.propagateMetadataByHash([input], wrapped);
791
+ if (evolution) require_booleanFns.propagateAllMetadata(evolution, [input], wrapped);
792
+ else require_booleanFns.propagateMetadataByHash([input], wrapped);
765
793
  return require_errors.ok(wrapped);
766
794
  }
767
795
  /**
@@ -785,10 +813,14 @@ function chamferDistAngle(shape, edges, distance, angleDeg) {
785
813
  const invalid = validateDistAngle(distance, angleDeg);
786
814
  if (invalid) return invalid;
787
815
  const kernel = require_shapeTypes.getKernel();
788
- let raw;
816
+ let built;
789
817
  try {
790
818
  const rawEdges = edges.map((e) => e.wrapped);
791
- raw = kernel.chamferDistAngle(shape.wrapped, rawEdges, distance, angleDeg);
819
+ built = buildChamfer(shape, rawEdges.map((edge) => ({
820
+ edge,
821
+ distance,
822
+ angleDeg
823
+ })), () => kernel.chamferDistAngle(shape.wrapped, rawEdges, distance, angleDeg));
792
824
  } catch (e) {
793
825
  if (require_occtWasmAdapter.isUnsupportedKernelOperationError(e)) return require_errors.err(require_errors.unsupportedError(require_errors.BrepErrorCode.UNSUPPORTED_CAPABILITY, `chamferDistAngle: the ${kernel.kernelId} kernel has no distance-angle chamfer`, e, { kernel: kernel.kernelId }, "Chamfer by one symmetric distance instead, or use the occt-wasm kernel"));
794
826
  return chamferAngleFailed("chamferDistAngle", e, edges, {
@@ -797,24 +829,32 @@ function chamferDistAngle(shape, edges, distance, angleDeg) {
797
829
  edgeCount: edges.length
798
830
  });
799
831
  }
800
- return castChamferResult(shape, raw);
832
+ return castChamferResult(shape, built);
801
833
  }
802
- function perEdgeUnsupported(kernelId, cause) {
803
- return require_errors.err(require_errors.unsupportedError(require_errors.BrepErrorCode.UNSUPPORTED_CAPABILITY, `chamferDistAngles: the ${kernelId} kernel cannot give each edge its own distance and angle`, cause, { kernel: kernelId }, "Use the occt-wasm kernel (5.9.0 or later), or give every edge the same { distance, angle } on a kernel that has a distance-angle chamfer"));
834
+ function perEdgeUnsupported(kernelId, cause, facesGiven) {
835
+ return require_errors.err(require_errors.unsupportedError(require_errors.BrepErrorCode.UNSUPPORTED_CAPABILITY, facesGiven ? `chamferDistAngles: the ${kernelId} kernel cannot measure a distance-angle chamfer from a given face` : `chamferDistAngles: the ${kernelId} kernel cannot give each edge its own distance and angle`, cause, { kernel: kernelId }, facesGiven ? "Use the occt-wasm kernel (5.9.0 or later), or leave out face so the kernel picks it" : "Use the occt-wasm kernel (5.9.0 or later), or give every edge the same { distance, angle } on a kernel that has a distance-angle chamfer"));
836
+ }
837
+ /** The first entry whose `face` is not one of the faces of `shape` its edge joins. */
838
+ function entryWithStrayFace(shape, entries) {
839
+ return entries.find(({ edge, face }) => face !== void 0 && !require_adjacencyFns.facesOfEdge(shape, edge).some((f) => require_shapeFns.isSameShape(f, face)));
804
840
  }
805
841
  /**
806
842
  * Chamfer each edge by its own distance and angle, in one operation.
807
843
  *
808
- * Edges that all share one distance and angle go through
809
- * {@link chamferDistAngle}, which every kernel but brepkit provides. Different
810
- * values need a kernel with a per-edge distance-angle chamfer (occt-wasm 5.9.0
811
- * or later); on any other kernel the result is an `UNSUPPORTED_CAPABILITY` error. On
812
- * occt-wasm the edges of one tangent-continuous contour must share their
813
- * distance and angle, or the result is `CHAMFER_ANGLE_FAILED`.
844
+ * Edges that all share one distance and angle, with no reference face given,
845
+ * go through {@link chamferDistAngle}, which every kernel but brepkit provides.
846
+ * Different values, or any `face`, need a kernel with a per-edge distance-angle
847
+ * chamfer (occt-wasm 5.9.0 or later); on any other kernel the result is an
848
+ * `UNSUPPORTED_CAPABILITY` error. On occt-wasm the edges of one
849
+ * tangent-continuous contour must state the same chamfer, or the result is
850
+ * `CHAMFER_ANGLE_FAILED`; from 5.11.0 an edge may state it from the face on
851
+ * the other side of the contour.
814
852
  *
815
853
  * @param shape - The 3D shape to chamfer.
816
- * @param entries - Each edge with its distance and angle (must not be empty).
817
- * @returns Ok with the chamfered shape, or Err on invalid input, an unsupported
854
+ * @param entries - Each edge with its distance, angle and optional reference
855
+ * face (must not be empty).
856
+ * @returns Ok with the chamfered shape, or Err on invalid input (a `face` not
857
+ * adjacent to its edge is `CHAMFER_ANGLE_FACE_NOT_ADJACENT`), an unsupported
818
858
  * kernel, or kernel failure.
819
859
  */
820
860
  function chamferDistAngles(shape, entries) {
@@ -824,23 +864,31 @@ function chamferDistAngles(shape, entries) {
824
864
  const invalid = validateDistAngle(distance, angle);
825
865
  if (invalid) return invalid;
826
866
  }
867
+ const stray = entryWithStrayFace(shape, entries);
868
+ if (stray) return require_errors.err(require_errors.validationError("CHAMFER_ANGLE_FACE_NOT_ADJACENT", "chamferDistAngles: a reference face is not one of the two faces its edge joins", void 0, {
869
+ edge: stray.edge,
870
+ face: stray.face
871
+ }, "Pick the face from facesOfEdge(shape, edge) on the shape being chamfered, or leave out face"));
827
872
  const edges = entries.map((e) => e.edge);
828
- if (entries.every((e) => e.distance === first.distance && e.angle === first.angle)) return chamferDistAngle(shape, edges, first.distance, first.angle);
873
+ const facesGiven = entries.some((e) => e.face !== void 0);
874
+ if (entries.every((e) => e.distance === first.distance && e.angle === first.angle) && !facesGiven) return chamferDistAngle(shape, edges, first.distance, first.angle);
829
875
  const kernel = require_shapeTypes.getKernel();
830
876
  const perEdge = kernel.chamferDistAngles?.bind(kernel);
831
- if (!perEdge) return perEdgeUnsupported(kernel.kernelId, void 0);
832
- let raw;
877
+ if (!perEdge) return perEdgeUnsupported(kernel.kernelId, void 0, facesGiven);
878
+ const kernelEntries = entries.map(({ edge, distance, angle, face }) => ({
879
+ edge: edge.wrapped,
880
+ distance,
881
+ angleDeg: angle,
882
+ face: face?.wrapped
883
+ }));
884
+ let built;
833
885
  try {
834
- raw = perEdge(shape.wrapped, entries.map(({ edge, distance, angle }) => ({
835
- edge: edge.wrapped,
836
- distance,
837
- angleDeg: angle
838
- })));
886
+ built = buildChamfer(shape, kernelEntries, () => perEdge(shape.wrapped, kernelEntries));
839
887
  } catch (e) {
840
- if (require_occtWasmAdapter.isUnsupportedKernelOperationError(e)) return perEdgeUnsupported(kernel.kernelId, e);
888
+ if (require_occtWasmAdapter.isUnsupportedKernelOperationError(e)) return perEdgeUnsupported(kernel.kernelId, e, facesGiven);
841
889
  return chamferAngleFailed("chamferDistAngles", e, edges, { edgeCount: entries.length });
842
890
  }
843
- return castChamferResult(shape, raw);
891
+ return castChamferResult(shape, built);
844
892
  }
845
893
  // src/topology/nurbsFns.ts
846
894
  /**
@@ -1,12 +1,12 @@
1
- const require_shapeTypes = require("./shapeTypes-C1Ljs72p.cjs");
1
+ const require_shapeTypes = require("./shapeTypes-BFfnNmzj.cjs");
2
2
  const require_errors = require("./errors-O_blYTWT.cjs");
3
- const require_topologyQueryFns = require("./topologyQueryFns-0Ycw298Y.cjs");
3
+ const require_topologyQueryFns = require("./topologyQueryFns-95FptXtu.cjs");
4
4
  const require_constants = require("./constants-oee0S_x6.cjs");
5
5
  const require_vecOps = require("./vecOps-CrGEPPQM.cjs");
6
- const require_faceFns = require("./faceFns-DdMpocg9.cjs");
7
- const require_shapeFns = require("./shapeFns-B9LB54_t.cjs");
8
- const require_curveFns = require("./curveFns-BQjw0VBB.cjs");
9
- const require_measureFns = require("./measureFns-B0Cy7GcQ.cjs");
6
+ const require_faceFns = require("./faceFns-DzNcnzS5.cjs");
7
+ const require_shapeFns = require("./shapeFns-Bgql2_E6.cjs");
8
+ const require_curveFns = require("./curveFns-0vAErrs9.cjs");
9
+ const require_measureFns = require("./measureFns-C8UjdHpB.cjs");
10
10
  // src/utils/vec2d.ts
11
11
  /** Precision for curve intersection and parameter operations. */
12
12
  var PRECISION_INTERSECTION = 1e-9;
@@ -1,12 +1,12 @@
1
- import { q as getKernel, y as isFace } from "./shapeTypes-DiCMRU6Z.js";
1
+ import { q as getKernel, y as isFace } from "./shapeTypes-C7hqbMwl.js";
2
2
  import { E as ok, g as err, o as queryError, x as isOk } from "./errors-BTccWbtE.js";
3
- import { c as getFaces, f as getVertices, p as getWires, s as getEdges } from "./topologyQueryFns-CNOqc1rB.js";
3
+ import { c as getFaces, f as getVertices, p as getWires, s as getEdges } from "./topologyQueryFns-C3-_9dFM.js";
4
4
  import { t as DEG2RAD } from "./constants-iraOnb2p.js";
5
5
  import { a as vecDot, d as vecNormalize } from "./vecOps-S-m9H_fe.js";
6
- import { l as normalAt, s as getSurfaceType } from "./faceFns-Dodcduw8.js";
7
- import { a as isSameShape, n as getHashCode } from "./shapeFns-Ddh0M4Iz.js";
8
- import { f as getCurveType, i as curveIsClosed, o as curveLength } from "./curveFns-nAwtilbz.js";
9
- import { n as measureArea } from "./measureFns-DoUWDfAP.js";
6
+ import { l as normalAt, s as getSurfaceType } from "./faceFns-WtnWpVQl.js";
7
+ import { a as isSameShape, n as getHashCode } from "./shapeFns-CSWOXGx9.js";
8
+ import { f as getCurveType, i as curveIsClosed, o as curveLength } from "./curveFns-b_C6tBeU.js";
9
+ import { n as measureArea } from "./measureFns-B0PhQ5dY.js";
10
10
  // src/utils/vec2d.ts
11
11
  /** Precision for curve intersection and parameter operations. */
12
12
  var PRECISION_INTERSECTION = 1e-9;
@@ -1,12 +1,12 @@
1
- const require_shapeTypes = require("./shapeTypes-C1Ljs72p.cjs");
1
+ const require_shapeTypes = require("./shapeTypes-BFfnNmzj.cjs");
2
2
  const require_bug = require("./bug-CBcpIPuf.cjs");
3
3
  const require_errors = require("./errors-O_blYTWT.cjs");
4
- const require_topologyQueryFns = require("./topologyQueryFns-0Ycw298Y.cjs");
4
+ const require_topologyQueryFns = require("./topologyQueryFns-95FptXtu.cjs");
5
5
  const require_constants = require("./constants-oee0S_x6.cjs");
6
- const require_solidBuilders = require("./solidBuilders-C6_6tZXG.cjs");
7
- const require_meshFns = require("./meshFns-Bz9PPZWP.cjs");
6
+ const require_solidBuilders = require("./solidBuilders-CWw3yasa.cjs");
7
+ const require_meshFns = require("./meshFns-BnkXZ0Xm.cjs");
8
8
  const require_arrayAccess = require("./arrayAccess-DpJYARwv.cjs");
9
- const require_blueprint = require("./blueprint-D4juQWXs.cjs");
9
+ const require_blueprint = require("./blueprint-D193PMxX.cjs");
10
10
  // src/io/objExportFns.ts
11
11
  /** Read a vec3 from a typed array at the given vertex index. */
12
12
  function vec3At(arr, i) {
@@ -1999,15 +1999,33 @@ function binaryPositions(data) {
1999
1999
  * Supports STEP, STL, and IGES formats.
2000
2000
  */
2001
2001
  /**
2002
+ * The whole model a reader returned: its one shape as is, or a compound of
2003
+ * every top-level shape (brepkit returns a solid per part, the OCCT kernels
2004
+ * one shape for the file).
2005
+ */
2006
+ function wholeModel(shapes) {
2007
+ const [only] = shapes;
2008
+ if (shapes.length === 1 && only !== void 0) return require_shapeTypes.castResultShape(only);
2009
+ const parts = shapes.map((s) => require_shapeTypes.castResultShape(s));
2010
+ try {
2011
+ return require_solidBuilders.makeCompound(parts);
2012
+ } finally {
2013
+ for (const part of parts) part[Symbol.dispose]();
2014
+ }
2015
+ }
2016
+ /**
2002
2017
  * Import a STEP file from a Blob.
2003
2018
  *
2004
- * Writes the blob to the WASM virtual filesystem, reads it with
2005
- * `STEPControl_Reader`, and returns the resulting shape.
2019
+ * Reads every part in the file. A file holding one solid comes back as that
2020
+ * solid; an assembly or a file with several parts comes back as a `Compound`
2021
+ * of every part, each at the placement the file gives it.
2006
2022
  *
2007
2023
  * @param blob - A Blob or File containing STEP data (.step / .stp).
2008
- * @returns A `Result` wrapping the imported shape, or an error if parsing fails.
2024
+ * @returns A `Result` wrapping the imported shape (a `Compound` when the file
2025
+ * holds several parts), or an error if parsing fails.
2009
2026
  *
2010
- * @remarks The temporary file on the WASM FS is cleaned up automatically.
2027
+ * @remarks Part names and colors in the file are not read. The temporary file
2028
+ * on the WASM FS is cleaned up automatically.
2011
2029
  *
2012
2030
  * @example
2013
2031
  * ```ts
@@ -2020,11 +2038,7 @@ async function importSTEP(blob) {
2020
2038
  const data = await blob.arrayBuffer();
2021
2039
  const shapes = require_shapeTypes.getKernel().importSTEP(data);
2022
2040
  if (shapes.length === 0) return require_errors.err(require_errors.ioError("STEP_IMPORT_FAILED", "STEP file contains no valid geometry"));
2023
- for (let i = 1; i < shapes.length; i++) {
2024
- const extra = shapes[i];
2025
- if (extra) require_shapeTypes.getKernel().dispose(extra);
2026
- }
2027
- return require_errors.ok(require_shapeTypes.castResultShape(shapes[0]));
2041
+ return require_errors.ok(wholeModel(shapes));
2028
2042
  } catch (e) {
2029
2043
  return require_errors.err(require_errors.ioError("STEP_IMPORT_FAILED", "Failed to load STEP file", e));
2030
2044
  }
@@ -2081,8 +2095,12 @@ async function importSTL(blob) {
2081
2095
  /**
2082
2096
  * Import an IGES file from a Blob.
2083
2097
  *
2098
+ * Reads every part in the file: one solid comes back as that solid, several as
2099
+ * a `Compound` of every part.
2100
+ *
2084
2101
  * @param blob - A Blob or File containing IGES data (.iges / .igs).
2085
- * @returns A `Result` wrapping the imported shape, or an error if parsing fails.
2102
+ * @returns A `Result` wrapping the imported shape (a `Compound` when the file
2103
+ * holds several parts), or an error if parsing fails.
2086
2104
  *
2087
2105
  * @remarks The temporary file on the WASM FS is cleaned up automatically. The
2088
2106
  * default occt-wasm kernel is built without an IGES translator, so there this
@@ -2098,11 +2116,7 @@ async function importIGES(blob) {
2098
2116
  const data = await blob.arrayBuffer();
2099
2117
  const shapes = require_shapeTypes.getKernel().importIGES(data);
2100
2118
  if (shapes.length === 0) return require_errors.err(require_errors.ioError("IGES_IMPORT_FAILED", "IGES file contains no valid geometry"));
2101
- for (let i = 1; i < shapes.length; i++) {
2102
- const extra = shapes[i];
2103
- if (extra) require_shapeTypes.getKernel().dispose(extra);
2104
- }
2105
- return require_errors.ok(require_shapeTypes.castResultShape(shapes[0]));
2119
+ return require_errors.ok(wholeModel(shapes));
2106
2120
  } catch (e) {
2107
2121
  return require_errors.err(require_meshFns.igesUnsupportedError("importIGES", e) ?? require_errors.ioError("IGES_IMPORT_FAILED", "Failed to load IGES file", e));
2108
2122
  }
@@ -1,12 +1,12 @@
1
- import { C as isSolid, G as _usingCtx, S as isShell, _ as isCompound, n as castResultShape, q as getKernel } from "./shapeTypes-DiCMRU6Z.js";
1
+ import { C as isSolid, G as _usingCtx, S as isShell, _ as isCompound, n as castResultShape, q as getKernel } from "./shapeTypes-C7hqbMwl.js";
2
2
  import { i as wasmIndex, r as vec3At$1 } from "./bug-ClMTAJhe.js";
3
3
  import { E as ok, g as err, r as ioError, t as BrepErrorCode } from "./errors-BTccWbtE.js";
4
- import { S as subShapeCount, c as getFaces, u as getShells } from "./topologyQueryFns-CNOqc1rB.js";
4
+ import { S as subShapeCount, c as getFaces, u as getShells } from "./topologyQueryFns-C3-_9dFM.js";
5
5
  import { n as HASH_CODE_MAX } from "./constants-iraOnb2p.js";
6
- import { t as makeCompound } from "./solidBuilders-Dzhk5L6w.js";
7
- import { u as igesUnsupportedError } from "./meshFns-BpBgKIIE.js";
6
+ import { t as makeCompound } from "./solidBuilders-B01dFnd7.js";
7
+ import { u as igesUnsupportedError } from "./meshFns-BazHDlpY.js";
8
8
  import { n as getAtOrThrow } from "./arrayAccess-BpgouNir.js";
9
- import { c as make2dBezierCurve, h as make2dThreePointArc, p as make2dSegmentCurve, t as Blueprint } from "./blueprint-ku_wYIZl.js";
9
+ import { c as make2dBezierCurve, h as make2dThreePointArc, p as make2dSegmentCurve, t as Blueprint } from "./blueprint-DH0H9OWv.js";
10
10
  // src/io/objExportFns.ts
11
11
  /** Read a vec3 from a typed array at the given vertex index. */
12
12
  function vec3At(arr, i) {
@@ -1999,15 +1999,33 @@ function binaryPositions(data) {
1999
1999
  * Supports STEP, STL, and IGES formats.
2000
2000
  */
2001
2001
  /**
2002
+ * The whole model a reader returned: its one shape as is, or a compound of
2003
+ * every top-level shape (brepkit returns a solid per part, the OCCT kernels
2004
+ * one shape for the file).
2005
+ */
2006
+ function wholeModel(shapes) {
2007
+ const [only] = shapes;
2008
+ if (shapes.length === 1 && only !== void 0) return castResultShape(only);
2009
+ const parts = shapes.map((s) => castResultShape(s));
2010
+ try {
2011
+ return makeCompound(parts);
2012
+ } finally {
2013
+ for (const part of parts) part[Symbol.dispose]();
2014
+ }
2015
+ }
2016
+ /**
2002
2017
  * Import a STEP file from a Blob.
2003
2018
  *
2004
- * Writes the blob to the WASM virtual filesystem, reads it with
2005
- * `STEPControl_Reader`, and returns the resulting shape.
2019
+ * Reads every part in the file. A file holding one solid comes back as that
2020
+ * solid; an assembly or a file with several parts comes back as a `Compound`
2021
+ * of every part, each at the placement the file gives it.
2006
2022
  *
2007
2023
  * @param blob - A Blob or File containing STEP data (.step / .stp).
2008
- * @returns A `Result` wrapping the imported shape, or an error if parsing fails.
2024
+ * @returns A `Result` wrapping the imported shape (a `Compound` when the file
2025
+ * holds several parts), or an error if parsing fails.
2009
2026
  *
2010
- * @remarks The temporary file on the WASM FS is cleaned up automatically.
2027
+ * @remarks Part names and colors in the file are not read. The temporary file
2028
+ * on the WASM FS is cleaned up automatically.
2011
2029
  *
2012
2030
  * @example
2013
2031
  * ```ts
@@ -2020,11 +2038,7 @@ async function importSTEP(blob) {
2020
2038
  const data = await blob.arrayBuffer();
2021
2039
  const shapes = getKernel().importSTEP(data);
2022
2040
  if (shapes.length === 0) return err(ioError("STEP_IMPORT_FAILED", "STEP file contains no valid geometry"));
2023
- for (let i = 1; i < shapes.length; i++) {
2024
- const extra = shapes[i];
2025
- if (extra) getKernel().dispose(extra);
2026
- }
2027
- return ok(castResultShape(shapes[0]));
2041
+ return ok(wholeModel(shapes));
2028
2042
  } catch (e) {
2029
2043
  return err(ioError("STEP_IMPORT_FAILED", "Failed to load STEP file", e));
2030
2044
  }
@@ -2081,8 +2095,12 @@ async function importSTL(blob) {
2081
2095
  /**
2082
2096
  * Import an IGES file from a Blob.
2083
2097
  *
2098
+ * Reads every part in the file: one solid comes back as that solid, several as
2099
+ * a `Compound` of every part.
2100
+ *
2084
2101
  * @param blob - A Blob or File containing IGES data (.iges / .igs).
2085
- * @returns A `Result` wrapping the imported shape, or an error if parsing fails.
2102
+ * @returns A `Result` wrapping the imported shape (a `Compound` when the file
2103
+ * holds several parts), or an error if parsing fails.
2086
2104
  *
2087
2105
  * @remarks The temporary file on the WASM FS is cleaned up automatically. The
2088
2106
  * default occt-wasm kernel is built without an IGES translator, so there this
@@ -2098,11 +2116,7 @@ async function importIGES(blob) {
2098
2116
  const data = await blob.arrayBuffer();
2099
2117
  const shapes = getKernel().importIGES(data);
2100
2118
  if (shapes.length === 0) return err(ioError("IGES_IMPORT_FAILED", "IGES file contains no valid geometry"));
2101
- for (let i = 1; i < shapes.length; i++) {
2102
- const extra = shapes[i];
2103
- if (extra) getKernel().dispose(extra);
2104
- }
2105
- return ok(castResultShape(shapes[0]));
2119
+ return ok(wholeModel(shapes));
2106
2120
  } catch (e) {
2107
2121
  return err(igesUnsupportedError("importIGES", e) ?? ioError("IGES_IMPORT_FAILED", "Failed to load IGES file", e));
2108
2122
  }
@@ -3,13 +3,16 @@ import { Result } from '../core/result.js';
3
3
  /**
4
4
  * Import a STEP file from a Blob.
5
5
  *
6
- * Writes the blob to the WASM virtual filesystem, reads it with
7
- * `STEPControl_Reader`, and returns the resulting shape.
6
+ * Reads every part in the file. A file holding one solid comes back as that
7
+ * solid; an assembly or a file with several parts comes back as a `Compound`
8
+ * of every part, each at the placement the file gives it.
8
9
  *
9
10
  * @param blob - A Blob or File containing STEP data (.step / .stp).
10
- * @returns A `Result` wrapping the imported shape, or an error if parsing fails.
11
+ * @returns A `Result` wrapping the imported shape (a `Compound` when the file
12
+ * holds several parts), or an error if parsing fails.
11
13
  *
12
- * @remarks The temporary file on the WASM FS is cleaned up automatically.
14
+ * @remarks Part names and colors in the file are not read. The temporary file
15
+ * on the WASM FS is cleaned up automatically.
13
16
  *
14
17
  * @example
15
18
  * ```ts
@@ -48,8 +51,12 @@ export declare function importSTL(blob: Blob): Promise<Result<UnknownDimShape>>;
48
51
  /**
49
52
  * Import an IGES file from a Blob.
50
53
  *
54
+ * Reads every part in the file: one solid comes back as that solid, several as
55
+ * a `Compound` of every part.
56
+ *
51
57
  * @param blob - A Blob or File containing IGES data (.iges / .igs).
52
- * @returns A `Result` wrapping the imported shape, or an error if parsing fails.
58
+ * @returns A `Result` wrapping the imported shape (a `Compound` when the file
59
+ * holds several parts), or an error if parsing fails.
53
60
  *
54
61
  * @remarks The temporary file on the WASM FS is cleaned up automatically. The
55
62
  * default occt-wasm kernel is built without an IGES translator, so there this