brepjs 20.12.11 → 20.12.12

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 (59) hide show
  1. package/dist/2d.cjs +4 -4
  2. package/dist/2d.js +4 -4
  3. package/dist/{blueprint-DbNFPHzC.js → blueprint-BYXwa2cF.js} +1 -1
  4. package/dist/{blueprint-BY2aygt_.cjs → blueprint-DtPRNDEu.cjs} +1 -1
  5. package/dist/{blueprintFns-dU5V5WcD.js → blueprintFns-YuJQgywS.js} +2 -2
  6. package/dist/{blueprintFns-AfHtvBKP.cjs → blueprintFns-y2oH3LOO.cjs} +2 -2
  7. package/dist/{blueprintSketcher-nBI9PlsW.js → blueprintSketcher-DPP1g95U.js} +2 -2
  8. package/dist/{blueprintSketcher-DHp6AeEM.cjs → blueprintSketcher-zQgjgodb.cjs} +2 -2
  9. package/dist/{boolean2D-C6TS6oFP.cjs → boolean2D-BJFpEXix.cjs} +3 -3
  10. package/dist/{boolean2D-DuWgyjOR.js → boolean2D-CNf7lVXV.js} +3 -3
  11. package/dist/{booleanFns-BwzBRGqj.js → booleanFns-B9RvEpHB.js} +55 -29
  12. package/dist/{booleanFns-D0qfjH0a.cjs → booleanFns-CkcJ8WB7.cjs} +60 -28
  13. package/dist/brepjs.cjs +18 -18
  14. package/dist/brepjs.js +18 -18
  15. package/dist/{cornerFinder-CeyQ5JMA.js → cornerFinder-DgVMDBCo.js} +1 -1
  16. package/dist/{cornerFinder-Da8Dv4bp.cjs → cornerFinder-Dzsi68w-.cjs} +1 -1
  17. package/dist/{drawFns-BQIHgHQg.js → drawFns-Bht1ceeH.js} +6 -6
  18. package/dist/{drawFns-JZV96JGO.cjs → drawFns-CLJog-Xp.cjs} +6 -6
  19. package/dist/{healingFns-qioD81Of.cjs → healingFns-DGc2hk9z.cjs} +76 -16
  20. package/dist/{healingFns-D6mUhe0Z.js → healingFns-DvuJr4RS.js} +76 -16
  21. package/dist/{helpers-CsHdKbfF.js → helpers-BuI9lh-t.js} +1 -1
  22. package/dist/{helpers-BvYkHZK7.cjs → helpers-D7Y4Vxhf.cjs} +1 -1
  23. package/dist/{importFns-BzzUvnKA.cjs → importFns-Dwlc0KtB.cjs} +1 -1
  24. package/dist/{importFns-C8yUNPzJ.js → importFns-TKzj4FaZ.js} +1 -1
  25. package/dist/io.cjs +1 -1
  26. package/dist/io.js +1 -1
  27. package/dist/{measureFns-D3egqKcW.js → measureFns--UKrACtx.js} +12 -6
  28. package/dist/{measureFns-R85865k9.cjs → measureFns-D8uSDn-8.cjs} +23 -5
  29. package/dist/measurement/measureFns.d.ts +18 -3
  30. package/dist/measurement/principalBoxFns.d.ts +2 -1
  31. package/dist/measurement.cjs +2 -2
  32. package/dist/measurement.js +2 -2
  33. package/dist/operations.cjs +1 -1
  34. package/dist/operations.js +1 -1
  35. package/dist/{primitiveFns-eiM6OjWU.cjs → primitiveFns-CZqSRhm8.cjs} +1 -1
  36. package/dist/{primitiveFns-NxbTqKy7.js → primitiveFns-DPqHA3sX.js} +1 -1
  37. package/dist/{principalBoxFns-BgetPvvQ.js → principalBoxFns-C3SQMyG5.js} +28 -19
  38. package/dist/{principalBoxFns-DepJW5im.cjs → principalBoxFns-Cozj46sS.cjs} +27 -18
  39. package/dist/query.cjs +2 -2
  40. package/dist/query.js +2 -2
  41. package/dist/{refResolveFns-DpWvqRm0.cjs → refResolveFns-DBY8yC6n.cjs} +1 -1
  42. package/dist/{refResolveFns-Bl10yOGJ.js → refResolveFns-DtztzO1g.js} +1 -1
  43. package/dist/shapeRef.cjs +1 -1
  44. package/dist/shapeRef.js +1 -1
  45. package/dist/sketching.cjs +3 -3
  46. package/dist/sketching.js +3 -3
  47. package/dist/text.cjs +2 -2
  48. package/dist/text.js +2 -2
  49. package/dist/{textBlueprints-D3XhH1kb.cjs → textBlueprints-BPrPhg5b.cjs} +2 -2
  50. package/dist/{textBlueprints-BvZNjVwM.js → textBlueprints-Dq3pUNSr.js} +2 -2
  51. package/dist/{textMetrics-zk48vXsM.cjs → textMetrics-4xkjKmD1.cjs} +1 -1
  52. package/dist/{textMetrics-BGPUxjiq.js → textMetrics-JN70dV5x.js} +1 -1
  53. package/dist/{threadFns-CEr8JDsu.js → threadFns-D7D_qR7t.js} +3 -3
  54. package/dist/{threadFns-DNFoBBrH.cjs → threadFns-Dq_Gff0C.cjs} +3 -3
  55. package/dist/topology/booleanFns.d.ts +15 -3
  56. package/dist/topology/metadata/metadataPropagation.d.ts +4 -1
  57. package/dist/topology.cjs +3 -3
  58. package/dist/topology.js +3 -3
  59. package/package.json +1 -1
@@ -10,12 +10,12 @@ import { d as pointOnSurface, l as normalAt, m as uvBounds, r as faceCenter, u a
10
10
  import { h as offsetWire2D, i as curveIsClosed, l as curveStartPoint } from "./curveFns-EsJgIpc6.js";
11
11
  import { n as getAtOrThrow, r as lastOrThrow, t as firstOrThrow } from "./arrayAccess-BpgouNir.js";
12
12
  import { c as makeBSplineApproximation, d as makeCircle, f as makeEllipse, m as makeHelix, r as makeFace, s as assembleWire } from "./surfaceBuilders-BBs6D6Km.js";
13
- import { a as Blueprints, c as make2dOffset, i as CompoundBlueprint, l as intersectCurves, n as BaseSketcher2d, o as chamferCurves, s as filletCurves, u as Flatbush } from "./blueprintSketcher-nBI9PlsW.js";
14
- import { b as squareDistance2d, l as add2d, s as PRECISION_OFFSET, v as samePoint$1, x as subtract2d } from "./helpers-CsHdKbfF.js";
15
- import { _ as approximateAsSvgCompatibleCurve, a as edgeToCurve, f as make2dInerpolatedBSplineCurve, i as curvesAsEdgesOnPlane, l as make2dCircle, p as make2dSegmentCurve, s as make2dArcFromCenter, t as Blueprint, u as make2dEllipse, v as Curve2D, x as BoundingBox2d, y as deserializeCurve2D } from "./blueprint-DbNFPHzC.js";
16
- import { t as cornerFinder } from "./cornerFinder-CeyQ5JMA.js";
17
- import { c as roundedRectangleBlueprint, n as fuse2D, r as intersect2D, s as polysidesBlueprint, t as cut2D } from "./boolean2D-DuWgyjOR.js";
18
- import { _ as wrapSketchData, a as Sketches, o as Sketch, t as textBlueprints, v as wrapSketchDataArray } from "./textBlueprints-BvZNjVwM.js";
13
+ import { a as Blueprints, c as make2dOffset, i as CompoundBlueprint, l as intersectCurves, n as BaseSketcher2d, o as chamferCurves, s as filletCurves, u as Flatbush } from "./blueprintSketcher-DPP1g95U.js";
14
+ import { b as squareDistance2d, l as add2d, s as PRECISION_OFFSET, v as samePoint$1, x as subtract2d } from "./helpers-BuI9lh-t.js";
15
+ import { _ as approximateAsSvgCompatibleCurve, a as edgeToCurve, f as make2dInerpolatedBSplineCurve, i as curvesAsEdgesOnPlane, l as make2dCircle, p as make2dSegmentCurve, s as make2dArcFromCenter, t as Blueprint, u as make2dEllipse, v as Curve2D, x as BoundingBox2d, y as deserializeCurve2D } from "./blueprint-BYXwa2cF.js";
16
+ import { t as cornerFinder } from "./cornerFinder-DgVMDBCo.js";
17
+ import { c as roundedRectangleBlueprint, n as fuse2D, r as intersect2D, s as polysidesBlueprint, t as cut2D } from "./boolean2D-CNf7lVXV.js";
18
+ import { _ as wrapSketchData, a as Sketches, o as Sketch, t as textBlueprints, v as wrapSketchDataArray } from "./textBlueprints-Dq3pUNSr.js";
19
19
  import { i as projectEdges, t as cameraFromPlane } from "./cameraFns-CLkNCsYU.js";
20
20
  // src/2d/lib/stitching.ts
21
21
  /**
@@ -10,12 +10,12 @@ const require_faceFns = require("./faceFns-Jo9hMVqL.cjs");
10
10
  const require_curveFns = require("./curveFns-B8mm5cou.cjs");
11
11
  const require_arrayAccess = require("./arrayAccess-DpJYARwv.cjs");
12
12
  const require_surfaceBuilders = require("./surfaceBuilders-D5kFAV1i.cjs");
13
- const require_blueprintSketcher = require("./blueprintSketcher-DHp6AeEM.cjs");
14
- const require_helpers = require("./helpers-BvYkHZK7.cjs");
15
- const require_blueprint = require("./blueprint-BY2aygt_.cjs");
16
- const require_cornerFinder = require("./cornerFinder-Da8Dv4bp.cjs");
17
- const require_boolean2D = require("./boolean2D-C6TS6oFP.cjs");
18
- const require_textBlueprints = require("./textBlueprints-D3XhH1kb.cjs");
13
+ const require_blueprintSketcher = require("./blueprintSketcher-zQgjgodb.cjs");
14
+ const require_helpers = require("./helpers-D7Y4Vxhf.cjs");
15
+ const require_blueprint = require("./blueprint-DtPRNDEu.cjs");
16
+ const require_cornerFinder = require("./cornerFinder-Dzsi68w-.cjs");
17
+ const require_boolean2D = require("./boolean2D-BJFpEXix.cjs");
18
+ const require_textBlueprints = require("./textBlueprints-BPrPhg5b.cjs");
19
19
  const require_cameraFns = require("./cameraFns-B9xKg36U.cjs");
20
20
  // src/2d/lib/stitching.ts
21
21
  /**
@@ -4,7 +4,7 @@ const require_errors = require("./errors-O_blYTWT.cjs");
4
4
  const require_topologyQueryFns = require("./topologyQueryFns-BUhKY2Kj.cjs");
5
5
  const require_constants = require("./constants-oee0S_x6.cjs");
6
6
  const require_faceFns = require("./faceFns-Jo9hMVqL.cjs");
7
- const require_booleanFns = require("./booleanFns-D0qfjH0a.cjs");
7
+ const require_booleanFns = require("./booleanFns-CkcJ8WB7.cjs");
8
8
  const require_arrayAccess = require("./arrayAccess-DpJYARwv.cjs");
9
9
  // src/topology/threeHelpers.ts
10
10
  /**
@@ -855,6 +855,22 @@ function freezeTelemetry(t) {
855
855
  failedInputs: [...t.failedInputs].sort((a, b) => a - b)
856
856
  };
857
857
  }
858
+ function releaseOwned(node) {
859
+ if (node.owned) require_shapeTypes.disposeResultShape(node.shape);
860
+ }
861
+ /** If the run was cancelled, release the `held` nodes this frame owns and throw. */
862
+ function throwIfAborted(options, ...held) {
863
+ if (!options.signal?.aborted) return;
864
+ for (const node of held) releaseOwned(node);
865
+ throw options.signal.reason;
866
+ }
867
+ /**
868
+ * The caller's copy of the final node. A caller's own input can survive to the
869
+ * top (nothing combined, or every step failed), so it comes back as a copy.
870
+ */
871
+ function ownedResult(node, options) {
872
+ return node.owned ? require_errors.ok(node.shape) : require_booleanFns.copyAsBooleanResult(node.shape, options.trackEvolution ?? true);
873
+ }
858
874
  function cutAllBisect(base, tools, options = {}) {
859
875
  return cutAllBisectWith(REAL_OPS, base, tools, options);
860
876
  }
@@ -868,23 +884,36 @@ function cutAllBisectWith(ops, base, tools, options = {}) {
868
884
  singletonFallbacks: 0,
869
885
  failedInputs: /* @__PURE__ */ new Set()
870
886
  };
871
- const result = bisectCut(ops, base, tools, 0, options, telemetry);
887
+ const result = bisectCut(ops, {
888
+ shape: base,
889
+ owned: false
890
+ }, tools, 0, options, telemetry);
872
891
  if (require_errors.isErr(result)) return result;
892
+ const shape = ownedResult(result.value, options);
893
+ if (require_errors.isErr(shape)) return shape;
873
894
  return require_errors.ok({
874
- shape: result.value,
895
+ shape: shape.value,
875
896
  telemetry: freezeTelemetry(telemetry)
876
897
  });
877
898
  }
899
+ /**
900
+ * Cut `tools` from `base`. An owned base is consumed: it comes back as the
901
+ * result when nothing was cut, and is released otherwise, on a throw included.
902
+ */
878
903
  function bisectCut(ops, base, tools, startIdx, options, telemetry) {
879
904
  if (tools.length === 0) return require_errors.ok(base);
880
905
  if (tools.length === 1) return applySingletonCut(ops, base, tools, startIdx, options, telemetry);
881
906
  telemetry.batchAttempts++;
882
- const batchResult = tryBatch(() => ops.cutAll(base, tools, options));
907
+ const batchResult = tryBatch(() => ops.cutAll(base.shape, tools, options));
883
908
  if (batchResult && batchResult.ok) {
884
909
  telemetry.batchSucceeded++;
885
- return batchResult;
910
+ releaseOwned(base);
911
+ return require_errors.ok({
912
+ shape: batchResult.value,
913
+ owned: true
914
+ });
886
915
  }
887
- if (options.signal?.aborted) throw options.signal.reason;
916
+ throwIfAborted(options, base);
888
917
  const mid = Math.floor(tools.length / 2);
889
918
  const left = bisectCut(ops, base, tools.slice(0, mid), startIdx, options, telemetry);
890
919
  if (!left.ok) return left;
@@ -893,9 +922,15 @@ function bisectCut(ops, base, tools, startIdx, options, telemetry) {
893
922
  function applySingletonCut(ops, base, tools, startIdx, options, telemetry) {
894
923
  telemetry.singletonFallbacks++;
895
924
  const tool = require_arrayAccess.firstOrThrow(tools);
896
- const pairResult = tryBatch(() => ops.cut(base, tool, options));
897
- if (pairResult && pairResult.ok) return pairResult;
898
- if (options.signal?.aborted) throw options.signal.reason;
925
+ const pairResult = tryBatch(() => ops.cut(base.shape, tool, options));
926
+ if (pairResult && pairResult.ok) {
927
+ releaseOwned(base);
928
+ return require_errors.ok({
929
+ shape: pairResult.value,
930
+ owned: true
931
+ });
932
+ }
933
+ throwIfAborted(options, base);
899
934
  telemetry.failedInputs.add(startIdx);
900
935
  return require_errors.ok(base);
901
936
  }
@@ -915,29 +950,54 @@ function fuseAllBisectWith(ops, shapes, options = {}) {
915
950
  };
916
951
  const result = bisectFuse(ops, shapes, 0, options, telemetry);
917
952
  if (require_errors.isErr(result)) return result;
953
+ const shape = ownedResult(result.value, options);
954
+ if (require_errors.isErr(shape)) return shape;
918
955
  return require_errors.ok({
919
- shape: result.value,
956
+ shape: shape.value,
920
957
  telemetry: freezeTelemetry(telemetry)
921
958
  });
922
959
  }
923
960
  function bisectFuse(ops, shapes, startIdx, options, telemetry) {
924
- if (shapes.length === 1) return require_errors.ok(require_arrayAccess.firstOrThrow(shapes));
961
+ if (shapes.length === 1) return require_errors.ok({
962
+ shape: require_arrayAccess.firstOrThrow(shapes),
963
+ owned: false
964
+ });
925
965
  telemetry.batchAttempts++;
926
966
  const batchResult = tryBatch(() => ops.fuseAll(shapes, options));
927
967
  if (batchResult && batchResult.ok) {
928
968
  telemetry.batchSucceeded++;
929
- return batchResult;
969
+ return require_errors.ok({
970
+ shape: batchResult.value,
971
+ owned: true
972
+ });
930
973
  }
931
- if (options.signal?.aborted) throw options.signal.reason;
974
+ throwIfAborted(options);
932
975
  const mid = Math.floor(shapes.length / 2);
933
- return combineFuseHalves(ops, bisectFuse(ops, shapes.slice(0, mid), startIdx, options, telemetry), bisectFuse(ops, shapes.slice(mid), startIdx + mid, options, telemetry), shapes, startIdx, mid, options, telemetry);
976
+ const left = bisectFuse(ops, shapes.slice(0, mid), startIdx, options, telemetry);
977
+ let right;
978
+ try {
979
+ right = bisectFuse(ops, shapes.slice(mid), startIdx + mid, options, telemetry);
980
+ } catch (cause) {
981
+ if (left.ok) releaseOwned(left.value);
982
+ throw cause;
983
+ }
984
+ return combineFuseHalves(ops, left, right, shapes, startIdx, mid, options, telemetry);
934
985
  }
935
986
  function combineFuseHalves(ops, left, right, shapes, startIdx, mid, options, telemetry) {
936
987
  if (left.ok && right.ok) {
937
988
  telemetry.singletonFallbacks++;
938
- const merged = tryBatch(() => ops.fuse(left.value, right.value, options));
939
- if (merged && merged.ok) return merged;
989
+ const merged = tryBatch(() => ops.fuse(left.value.shape, right.value.shape, options));
990
+ if (merged && merged.ok) {
991
+ releaseOwned(left.value);
992
+ releaseOwned(right.value);
993
+ return require_errors.ok({
994
+ shape: merged.value,
995
+ owned: true
996
+ });
997
+ }
998
+ throwIfAborted(options, left.value, right.value);
940
999
  for (let i = mid; i < shapes.length; i++) telemetry.failedInputs.add(startIdx + i);
1000
+ releaseOwned(right.value);
941
1001
  return left;
942
1002
  }
943
1003
  if (left.ok) {
@@ -4,7 +4,7 @@ import { E as ok, b as isErr, d as validationError, g as err, i as kernelError,
4
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-yOGEI9hO.js";
5
5
  import { n as HASH_CODE_MAX } from "./constants-iraOnb2p.js";
6
6
  import { y as downcast } from "./faceFns-2jGPfqvB.js";
7
- import { a as fuseAll, d as collectInputFaceHashes, i as fuse, m as propagateMetadataByHash, n as cut, p as propagateAllMetadata, r as cutAll } from "./booleanFns-BwzBRGqj.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-B9RvEpHB.js";
8
8
  import { t as firstOrThrow } from "./arrayAccess-BpgouNir.js";
9
9
  // src/topology/threeHelpers.ts
10
10
  /**
@@ -855,6 +855,22 @@ function freezeTelemetry(t) {
855
855
  failedInputs: [...t.failedInputs].sort((a, b) => a - b)
856
856
  };
857
857
  }
858
+ function releaseOwned(node) {
859
+ if (node.owned) disposeResultShape(node.shape);
860
+ }
861
+ /** If the run was cancelled, release the `held` nodes this frame owns and throw. */
862
+ function throwIfAborted(options, ...held) {
863
+ if (!options.signal?.aborted) return;
864
+ for (const node of held) releaseOwned(node);
865
+ throw options.signal.reason;
866
+ }
867
+ /**
868
+ * The caller's copy of the final node. A caller's own input can survive to the
869
+ * top (nothing combined, or every step failed), so it comes back as a copy.
870
+ */
871
+ function ownedResult(node, options) {
872
+ return node.owned ? ok(node.shape) : copyAsBooleanResult(node.shape, options.trackEvolution ?? true);
873
+ }
858
874
  function cutAllBisect(base, tools, options = {}) {
859
875
  return cutAllBisectWith(REAL_OPS, base, tools, options);
860
876
  }
@@ -868,23 +884,36 @@ function cutAllBisectWith(ops, base, tools, options = {}) {
868
884
  singletonFallbacks: 0,
869
885
  failedInputs: /* @__PURE__ */ new Set()
870
886
  };
871
- const result = bisectCut(ops, base, tools, 0, options, telemetry);
887
+ const result = bisectCut(ops, {
888
+ shape: base,
889
+ owned: false
890
+ }, tools, 0, options, telemetry);
872
891
  if (isErr(result)) return result;
892
+ const shape = ownedResult(result.value, options);
893
+ if (isErr(shape)) return shape;
873
894
  return ok({
874
- shape: result.value,
895
+ shape: shape.value,
875
896
  telemetry: freezeTelemetry(telemetry)
876
897
  });
877
898
  }
899
+ /**
900
+ * Cut `tools` from `base`. An owned base is consumed: it comes back as the
901
+ * result when nothing was cut, and is released otherwise, on a throw included.
902
+ */
878
903
  function bisectCut(ops, base, tools, startIdx, options, telemetry) {
879
904
  if (tools.length === 0) return ok(base);
880
905
  if (tools.length === 1) return applySingletonCut(ops, base, tools, startIdx, options, telemetry);
881
906
  telemetry.batchAttempts++;
882
- const batchResult = tryBatch(() => ops.cutAll(base, tools, options));
907
+ const batchResult = tryBatch(() => ops.cutAll(base.shape, tools, options));
883
908
  if (batchResult && batchResult.ok) {
884
909
  telemetry.batchSucceeded++;
885
- return batchResult;
910
+ releaseOwned(base);
911
+ return ok({
912
+ shape: batchResult.value,
913
+ owned: true
914
+ });
886
915
  }
887
- if (options.signal?.aborted) throw options.signal.reason;
916
+ throwIfAborted(options, base);
888
917
  const mid = Math.floor(tools.length / 2);
889
918
  const left = bisectCut(ops, base, tools.slice(0, mid), startIdx, options, telemetry);
890
919
  if (!left.ok) return left;
@@ -893,9 +922,15 @@ function bisectCut(ops, base, tools, startIdx, options, telemetry) {
893
922
  function applySingletonCut(ops, base, tools, startIdx, options, telemetry) {
894
923
  telemetry.singletonFallbacks++;
895
924
  const tool = firstOrThrow(tools);
896
- const pairResult = tryBatch(() => ops.cut(base, tool, options));
897
- if (pairResult && pairResult.ok) return pairResult;
898
- if (options.signal?.aborted) throw options.signal.reason;
925
+ const pairResult = tryBatch(() => ops.cut(base.shape, tool, options));
926
+ if (pairResult && pairResult.ok) {
927
+ releaseOwned(base);
928
+ return ok({
929
+ shape: pairResult.value,
930
+ owned: true
931
+ });
932
+ }
933
+ throwIfAborted(options, base);
899
934
  telemetry.failedInputs.add(startIdx);
900
935
  return ok(base);
901
936
  }
@@ -915,29 +950,54 @@ function fuseAllBisectWith(ops, shapes, options = {}) {
915
950
  };
916
951
  const result = bisectFuse(ops, shapes, 0, options, telemetry);
917
952
  if (isErr(result)) return result;
953
+ const shape = ownedResult(result.value, options);
954
+ if (isErr(shape)) return shape;
918
955
  return ok({
919
- shape: result.value,
956
+ shape: shape.value,
920
957
  telemetry: freezeTelemetry(telemetry)
921
958
  });
922
959
  }
923
960
  function bisectFuse(ops, shapes, startIdx, options, telemetry) {
924
- if (shapes.length === 1) return ok(firstOrThrow(shapes));
961
+ if (shapes.length === 1) return ok({
962
+ shape: firstOrThrow(shapes),
963
+ owned: false
964
+ });
925
965
  telemetry.batchAttempts++;
926
966
  const batchResult = tryBatch(() => ops.fuseAll(shapes, options));
927
967
  if (batchResult && batchResult.ok) {
928
968
  telemetry.batchSucceeded++;
929
- return batchResult;
969
+ return ok({
970
+ shape: batchResult.value,
971
+ owned: true
972
+ });
930
973
  }
931
- if (options.signal?.aborted) throw options.signal.reason;
974
+ throwIfAborted(options);
932
975
  const mid = Math.floor(shapes.length / 2);
933
- return combineFuseHalves(ops, bisectFuse(ops, shapes.slice(0, mid), startIdx, options, telemetry), bisectFuse(ops, shapes.slice(mid), startIdx + mid, options, telemetry), shapes, startIdx, mid, options, telemetry);
976
+ const left = bisectFuse(ops, shapes.slice(0, mid), startIdx, options, telemetry);
977
+ let right;
978
+ try {
979
+ right = bisectFuse(ops, shapes.slice(mid), startIdx + mid, options, telemetry);
980
+ } catch (cause) {
981
+ if (left.ok) releaseOwned(left.value);
982
+ throw cause;
983
+ }
984
+ return combineFuseHalves(ops, left, right, shapes, startIdx, mid, options, telemetry);
934
985
  }
935
986
  function combineFuseHalves(ops, left, right, shapes, startIdx, mid, options, telemetry) {
936
987
  if (left.ok && right.ok) {
937
988
  telemetry.singletonFallbacks++;
938
- const merged = tryBatch(() => ops.fuse(left.value, right.value, options));
939
- if (merged && merged.ok) return merged;
989
+ const merged = tryBatch(() => ops.fuse(left.value.shape, right.value.shape, options));
990
+ if (merged && merged.ok) {
991
+ releaseOwned(left.value);
992
+ releaseOwned(right.value);
993
+ return ok({
994
+ shape: merged.value,
995
+ owned: true
996
+ });
997
+ }
998
+ throwIfAborted(options, left.value, right.value);
940
999
  for (let i = mid; i < shapes.length; i++) telemetry.failedInputs.add(startIdx + i);
1000
+ releaseOwned(right.value);
941
1001
  return left;
942
1002
  }
943
1003
  if (left.ok) {
@@ -6,7 +6,7 @@ import { a as vecDot, d as vecNormalize } from "./vecOps-S-m9H_fe.js";
6
6
  import { l as normalAt, s as getSurfaceType } from "./faceFns-2jGPfqvB.js";
7
7
  import { a as isSameShape, n as getHashCode } from "./shapeFns-kFm-m8jh.js";
8
8
  import { f as getCurveType, i as curveIsClosed, o as curveLength } from "./curveFns-EsJgIpc6.js";
9
- import { n as measureArea } from "./measureFns-D3egqKcW.js";
9
+ import { n as measureArea } from "./measureFns--UKrACtx.js";
10
10
  // src/utils/vec2d.ts
11
11
  /** Precision for curve intersection and parameter operations. */
12
12
  var PRECISION_INTERSECTION = 1e-9;
@@ -6,7 +6,7 @@ const require_vecOps = require("./vecOps-CrGEPPQM.cjs");
6
6
  const require_faceFns = require("./faceFns-Jo9hMVqL.cjs");
7
7
  const require_shapeFns = require("./shapeFns-D47cmLG8.cjs");
8
8
  const require_curveFns = require("./curveFns-B8mm5cou.cjs");
9
- const require_measureFns = require("./measureFns-R85865k9.cjs");
9
+ const require_measureFns = require("./measureFns-D8uSDn-8.cjs");
10
10
  // src/utils/vec2d.ts
11
11
  /** Precision for curve intersection and parameter operations. */
12
12
  var PRECISION_INTERSECTION = 1e-9;
@@ -6,7 +6,7 @@ const require_constants = require("./constants-oee0S_x6.cjs");
6
6
  const require_solidBuilders = require("./solidBuilders-Dwm0hXn5.cjs");
7
7
  const require_meshFns = require("./meshFns-Cs_qrlXI.cjs");
8
8
  const require_arrayAccess = require("./arrayAccess-DpJYARwv.cjs");
9
- const require_blueprint = require("./blueprint-BY2aygt_.cjs");
9
+ const require_blueprint = require("./blueprint-DtPRNDEu.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) {
@@ -6,7 +6,7 @@ import { n as HASH_CODE_MAX } from "./constants-iraOnb2p.js";
6
6
  import { t as makeCompound } from "./solidBuilders-ZDGdvaTU.js";
7
7
  import { u as igesUnsupportedError } from "./meshFns-Bo4EQJFO.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-DbNFPHzC.js";
9
+ import { c as make2dBezierCurve, h as make2dThreePointArc, p as make2dSegmentCurve, t as Blueprint } from "./blueprint-BYXwa2cF.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) {
package/dist/io.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_meshFns = require("./meshFns-Cs_qrlXI.cjs");
3
- const require_importFns = require("./importFns-BzzUvnKA.cjs");
3
+ const require_importFns = require("./importFns-Dwlc0KtB.cjs");
4
4
  exports.blueprintToDXF = require_importFns.blueprintToDXF;
5
5
  exports.exportDXF = require_importFns.exportDXF;
6
6
  exports.exportGlb = require_importFns.exportGlb;
package/dist/io.js CHANGED
@@ -1,3 +1,3 @@
1
1
  import { n as exportSTEP, r as exportSTL, t as exportIGES } from "./meshFns-Bo4EQJFO.js";
2
- import { a as exportSTEPConfigured, c as exportThreeMF, d as exportGlb, f as exportGltf, l as blueprintToDXF, n as importSTEP, o as importSVG, p as exportOBJ, r as importSTL, s as importSVGPathD, t as importIGES, u as exportDXF } from "./importFns-C8yUNPzJ.js";
2
+ import { a as exportSTEPConfigured, c as exportThreeMF, d as exportGlb, f as exportGltf, l as blueprintToDXF, n as importSTEP, o as importSVG, p as exportOBJ, r as importSTL, s as importSVGPathD, t as importIGES, u as exportDXF } from "./importFns-TKzj4FaZ.js";
3
3
  export { blueprintToDXF, exportDXF, exportGlb, exportGltf, exportIGES, exportOBJ, exportSTEP, exportSTEPConfigured, exportSTL, exportThreeMF, importIGES, importSTEP, importSTL, importSVG, importSVGPathD };
@@ -30,6 +30,8 @@ function nullShapeErr(fn) {
30
30
  * Run `fn` on fresh handles to the distinct sub-shapes of `type`, releasing them
31
31
  * afterwards. Unlike getFaces and friends this leaves the shape's topology cache
32
32
  * alone, so a measurement allocates nothing that outlives it.
33
+ *
34
+ * @internal
33
35
  */
34
36
  function withSubShapes(shape, type, fn) {
35
37
  const kernel = getKernel();
@@ -40,7 +42,11 @@ function withSubShapes(shape, type, fn) {
40
42
  for (const item of items) kernel.dispose(item);
41
43
  }
42
44
  }
43
- /** Run `fn` on a throwaway compound of `parts`, releasing the compound afterwards. */
45
+ /**
46
+ * Run `fn` on a throwaway compound of `parts`, releasing the compound afterwards.
47
+ *
48
+ * @internal
49
+ */
44
50
  function withCompoundOf(parts, fn) {
45
51
  const kernel = getKernel();
46
52
  const c = kernel.makeCompound(parts);
@@ -141,9 +147,9 @@ function measureSurfaceProps(shape) {
141
147
  /**
142
148
  * Measure linear properties of any shape.
143
149
  *
144
- * For edges this is the arc length; for wires and faces it is the total length
145
- * of their edges; for shells, solids, and compounds it is the total length of
146
- * their distinct edges, each counted once.
150
+ * For edges this is the arc length; for wires it is the total length of their
151
+ * edges; for faces, shells, solids, and compounds it is the total length of
152
+ * their distinct edges, each counted once (a face's seam edge included).
147
153
  *
148
154
  * @param shape - Any shape whose linear extent is to be measured.
149
155
  * @returns `Result` containing length, center of mass, and raw mass property.
@@ -164,7 +170,7 @@ function measureLinearProps(shape) {
164
170
  };
165
171
  };
166
172
  let result;
167
- if (type === "vertex" || type === "edge" || type === "wire" || type === "face") result = linearOf(shape.wrapped);
173
+ if (type === "vertex" || type === "edge" || type === "wire") result = linearOf(shape.wrapped);
168
174
  else result = withSubShapes(shape, "edge", (edges) => edges.length === 0 ? {
169
175
  mass: 0,
170
176
  length: 0,
@@ -289,4 +295,4 @@ function measureCurvatureAtMid(face) {
289
295
  minDirection: result.minDirection
290
296
  });
291
297
  }
292
- export { measureDistance as a, measureLinearProps as c, measureVolumeProps as d, getCachedMeasurement as f, measureCurvatureAtMid as i, measureSurfaceProps as l, measureArea as n, measureDistanceProps as o, setCachedMeasurement as p, measureCurvatureAt as r, measureLength as s, createDistanceQuery as t, measureVolume as u };
298
+ export { measureDistance as a, measureLinearProps as c, measureVolumeProps as d, withCompoundOf as f, setCachedMeasurement as h, measureCurvatureAtMid as i, measureSurfaceProps as l, getCachedMeasurement as m, measureArea as n, measureDistanceProps as o, withSubShapes as p, measureCurvatureAt as r, measureLength as s, createDistanceQuery as t, measureVolume as u };
@@ -30,6 +30,8 @@ function nullShapeErr(fn) {
30
30
  * Run `fn` on fresh handles to the distinct sub-shapes of `type`, releasing them
31
31
  * afterwards. Unlike getFaces and friends this leaves the shape's topology cache
32
32
  * alone, so a measurement allocates nothing that outlives it.
33
+ *
34
+ * @internal
33
35
  */
34
36
  function withSubShapes(shape, type, fn) {
35
37
  const kernel = require_shapeTypes.getKernel();
@@ -40,7 +42,11 @@ function withSubShapes(shape, type, fn) {
40
42
  for (const item of items) kernel.dispose(item);
41
43
  }
42
44
  }
43
- /** Run `fn` on a throwaway compound of `parts`, releasing the compound afterwards. */
45
+ /**
46
+ * Run `fn` on a throwaway compound of `parts`, releasing the compound afterwards.
47
+ *
48
+ * @internal
49
+ */
44
50
  function withCompoundOf(parts, fn) {
45
51
  const kernel = require_shapeTypes.getKernel();
46
52
  const c = kernel.makeCompound(parts);
@@ -141,9 +147,9 @@ function measureSurfaceProps(shape) {
141
147
  /**
142
148
  * Measure linear properties of any shape.
143
149
  *
144
- * For edges this is the arc length; for wires and faces it is the total length
145
- * of their edges; for shells, solids, and compounds it is the total length of
146
- * their distinct edges, each counted once.
150
+ * For edges this is the arc length; for wires it is the total length of their
151
+ * edges; for faces, shells, solids, and compounds it is the total length of
152
+ * their distinct edges, each counted once (a face's seam edge included).
147
153
  *
148
154
  * @param shape - Any shape whose linear extent is to be measured.
149
155
  * @returns `Result` containing length, center of mass, and raw mass property.
@@ -164,7 +170,7 @@ function measureLinearProps(shape) {
164
170
  };
165
171
  };
166
172
  let result;
167
- if (type === "vertex" || type === "edge" || type === "wire" || type === "face") result = linearOf(shape.wrapped);
173
+ if (type === "vertex" || type === "edge" || type === "wire") result = linearOf(shape.wrapped);
168
174
  else result = withSubShapes(shape, "edge", (edges) => edges.length === 0 ? {
169
175
  mass: 0,
170
176
  length: 0,
@@ -367,3 +373,15 @@ Object.defineProperty(exports, "setCachedMeasurement", {
367
373
  return setCachedMeasurement;
368
374
  }
369
375
  });
376
+ Object.defineProperty(exports, "withCompoundOf", {
377
+ enumerable: true,
378
+ get: function() {
379
+ return withCompoundOf;
380
+ }
381
+ });
382
+ Object.defineProperty(exports, "withSubShapes", {
383
+ enumerable: true,
384
+ get: function() {
385
+ return withSubShapes;
386
+ }
387
+ });
@@ -1,8 +1,23 @@
1
+ import { KernelShape, ShapeType } from '../kernel/types.js';
1
2
  import { AnyShape, Dimension, Face, OrientedFace, Shape3D } from '../core/shapeTypes.js';
2
3
  import { Result } from '../core/result.js';
3
4
  import { CurvatureResult } from '../kernel/occt/measureOps.js';
4
5
  import { PhysicalProps, VolumeProps, SurfaceProps, LinearProps, DistanceProps } from './measureTypes.js';
5
6
  export type { PhysicalProps, VolumeProps, SurfaceProps, LinearProps, DistanceProps };
7
+ /**
8
+ * Run `fn` on fresh handles to the distinct sub-shapes of `type`, releasing them
9
+ * afterwards. Unlike getFaces and friends this leaves the shape's topology cache
10
+ * alone, so a measurement allocates nothing that outlives it.
11
+ *
12
+ * @internal
13
+ */
14
+ export declare function withSubShapes<R>(shape: AnyShape<Dimension>, type: ShapeType, fn: (items: KernelShape[]) => R): R;
15
+ /**
16
+ * Run `fn` on a throwaway compound of `parts`, releasing the compound afterwards.
17
+ *
18
+ * @internal
19
+ */
20
+ export declare function withCompoundOf<R>(parts: KernelShape[], fn: (c: KernelShape) => R): R;
6
21
  /**
7
22
  * Measure volume properties of a 3D shape.
8
23
  *
@@ -22,9 +37,9 @@ export declare function measureSurfaceProps(shape: Face<Dimension> | Shape3D): R
22
37
  /**
23
38
  * Measure linear properties of any shape.
24
39
  *
25
- * For edges this is the arc length; for wires and faces it is the total length
26
- * of their edges; for shells, solids, and compounds it is the total length of
27
- * their distinct edges, each counted once.
40
+ * For edges this is the arc length; for wires it is the total length of their
41
+ * edges; for faces, shells, solids, and compounds it is the total length of
42
+ * their distinct edges, each counted once (a face's seam edge included).
28
43
  *
29
44
  * @param shape - Any shape whose linear extent is to be measured.
30
45
  * @returns `Result` containing length, center of mass, and raw mass property.
@@ -16,7 +16,8 @@ export type { PrincipalBoundingBox };
16
16
  * Z reports 136.6 x 136.6 x 2, because any in-plane pair of axes is principal
17
17
  * for a square plate.
18
18
  *
19
- * @param shape - A solid, compsolid, or compound containing solids.
19
+ * @param shape - A solid, compsolid, or compound containing solids. A compound
20
+ * is measured by its solids alone: loose faces, shells, or wires in it are ignored.
20
21
  * @returns `Result` with the box center in world coordinates, orthonormal
21
22
  * right-handed axes ordered by decreasing extent, and the full edge lengths
22
23
  * along those axes. Fails with `NOT_A_SOLID` for any other shape type
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_measureFns = require("./measureFns-R85865k9.cjs");
3
- const require_principalBoxFns = require("./principalBoxFns-DepJW5im.cjs");
2
+ const require_measureFns = require("./measureFns-D8uSDn-8.cjs");
3
+ const require_principalBoxFns = require("./principalBoxFns-Cozj46sS.cjs");
4
4
  exports.createDistanceQuery = require_measureFns.createDistanceQuery;
5
5
  exports.measureArea = require_measureFns.measureArea;
6
6
  exports.measureDistance = require_measureFns.measureDistance;
@@ -1,3 +1,3 @@
1
- import { a as measureDistance, c as measureLinearProps, d as measureVolumeProps, l as measureSurfaceProps, n as measureArea, o as measureDistanceProps, s as measureLength, t as createDistanceQuery, u as measureVolume } from "./measureFns-D3egqKcW.js";
2
- import { t as principalBoundingBox } from "./principalBoxFns-BgetPvvQ.js";
1
+ import { a as measureDistance, c as measureLinearProps, d as measureVolumeProps, l as measureSurfaceProps, n as measureArea, o as measureDistanceProps, s as measureLength, t as createDistanceQuery, u as measureVolume } from "./measureFns--UKrACtx.js";
2
+ import { t as principalBoundingBox } from "./principalBoxFns-C3SQMyG5.js";
3
3
  export { createDistanceQuery, measureArea, measureDistance, measureDistanceProps, measureLength, measureLinearProps, measureSurfaceProps, measureVolume, measureVolumeProps, principalBoundingBox };
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_threadFns = require("./threadFns-DNFoBBrH.cjs");
2
+ const require_threadFns = require("./threadFns-Dq_Gff0C.cjs");
3
3
  const require_loftFns = require("./loftFns-CnerVgTM.cjs");
4
4
  exports.addChild = require_threadFns.addChild;
5
5
  exports.addJoint = require_threadFns.addJoint;
@@ -1,3 +1,3 @@
1
- import { A as setJointValue, B as walkAssembly, C as cylindricalJoint, D as planarJoint, E as mechanismDOF, F as countNodes, H as circularPattern, I as createAssemblyNode, L as findNode, M as sphericalJoint, N as addChild, O as prismaticJoint, P as collectShapes, R as removeChild, S as addJoint, T as jointTransform, U as gridPattern, V as exportAssemblySTEP, W as linearPattern, Y as createAssembly, _ as exportURDF, b as inverseKinematics, c as modifyStep, d as replayFrom, f as replayHistory, g as undoLast, h as stepsFrom, i as createRegistry, j as setJointValues, k as revoluteJoint, l as registerOperation, m as stepCount, n as addStep, o as findStep, r as createHistory, s as getShape, t as thread, u as registerShape, v as importURDF, w as forwardKinematics, x as jointTrajectory, y as jointsFromDH, z as updateNode } from "./threadFns-CEr8JDsu.js";
1
+ import { A as setJointValue, B as walkAssembly, C as cylindricalJoint, D as planarJoint, E as mechanismDOF, F as countNodes, H as circularPattern, I as createAssemblyNode, L as findNode, M as sphericalJoint, N as addChild, O as prismaticJoint, P as collectShapes, R as removeChild, S as addJoint, T as jointTransform, U as gridPattern, V as exportAssemblySTEP, W as linearPattern, Y as createAssembly, _ as exportURDF, b as inverseKinematics, c as modifyStep, d as replayFrom, f as replayHistory, g as undoLast, h as stepsFrom, i as createRegistry, j as setJointValues, k as revoluteJoint, l as registerOperation, m as stepCount, n as addStep, o as findStep, r as createHistory, s as getShape, t as thread, u as registerShape, v as importURDF, w as forwardKinematics, x as jointTrajectory, y as jointsFromDH, z as updateNode } from "./threadFns-D7D_qR7t.js";
2
2
  import { c as twistExtrude, o as supportExtrude, r as complexExtrude, s as sweep } from "./loftFns-jnQL_zpD.js";
3
3
  export { addChild, addJoint, addStep, circularPattern, collectShapes, complexExtrude, countNodes, createAssembly, createAssemblyNode, createHistory, createRegistry, cylindricalJoint, exportAssemblySTEP, exportURDF, findNode, findStep, forwardKinematics, getShape as getHistoryShape, gridPattern, importURDF, inverseKinematics, jointTrajectory, jointTransform, jointsFromDH, linearPattern, mechanismDOF, modifyStep, planarJoint, prismaticJoint, registerOperation, registerShape, removeChild, replayFrom, replayHistory, revoluteJoint, setJointValue, setJointValues, sphericalJoint, stepCount, stepsFrom, supportExtrude, sweep, thread, twistExtrude, undoLast, updateNode, walkAssembly };
@@ -4,7 +4,7 @@ const require_validityTypes = require("./validityTypes-lfyOkCQm.cjs");
4
4
  const require_constants = require("./constants-oee0S_x6.cjs");
5
5
  const require_vecOps = require("./vecOps-CrGEPPQM.cjs");
6
6
  const require_solidBuilders = require("./solidBuilders-Dwm0hXn5.cjs");
7
- const require_booleanFns = require("./booleanFns-D0qfjH0a.cjs");
7
+ const require_booleanFns = require("./booleanFns-CkcJ8WB7.cjs");
8
8
  const require_surfaceBuilders = require("./surfaceBuilders-D5kFAV1i.cjs");
9
9
  // src/topology/transformFns.ts
10
10
  /**
@@ -4,7 +4,7 @@ import { n as isClosedWire } from "./validityTypes-CGrEOscY.js";
4
4
  import { n as HASH_CODE_MAX, t as DEG2RAD } from "./constants-iraOnb2p.js";
5
5
  import { d as vecNormalize, h as vecScale } from "./vecOps-S-m9H_fe.js";
6
6
  import { a as makeOffset, c as makeTorus, i as makeEllipsoid, l as makeVertex, n as makeCone, o as makeSolid, r as makeCylinder, s as makeSphere, t as makeCompound, u as weldShellsAndFaces } from "./solidBuilders-ZDGdvaTU.js";
7
- import { d as collectInputFaceHashes, f as hasAnyMetadata, h as propagateMetadataThroughRelocation, m as propagateMetadataByHash, p as propagateAllMetadata } from "./booleanFns-BwzBRGqj.js";
7
+ import { f as collectInputFaceHashes, g as propagateMetadataThroughRelocation, h as propagateMetadataByHash, m as propagateAllMetadata, p as hasAnyMetadata } from "./booleanFns-B9RvEpHB.js";
8
8
  import { _ as makeThreePointArc, a as makeNonPlanarFace, c as makeBSplineApproximation, d as makeCircle, f as makeEllipse, g as makeTangentArc, h as makeLine, i as makeNewFaceWithinFace, m as makeHelix, o as makePolygon, p as makeEllipseArc, r as makeFace, s as assembleWire, t as addHolesInFace, u as makeBezierCurve } from "./surfaceBuilders-BBs6D6Km.js";
9
9
  // src/topology/transformFns.ts
10
10
  /**