brepjs 18.119.2 → 18.119.4

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 (100) hide show
  1. package/dist/2d/blueprints/blueprints.d.ts +3 -0
  2. package/dist/2d/blueprints/compoundBlueprint.d.ts +3 -0
  3. package/dist/2d/blueprints/lib.d.ts +6 -0
  4. package/dist/2d/lib/curve2D.d.ts +6 -1
  5. package/dist/2d/lib/curve2dFns.d.ts +6 -1
  6. package/dist/2d.cjs +7 -7
  7. package/dist/2d.js +7 -7
  8. package/dist/{adjacencyFns-BdM5p58J.js → adjacencyFns-DLityMyV.js} +2 -2
  9. package/dist/{adjacencyFns-Brrc7jlS.cjs → adjacencyFns-DSxuQYnb.cjs} +2 -2
  10. package/dist/{blueprint-DJJo8WkI.js → blueprint-DEMSX-hc.js} +37 -10
  11. package/dist/{blueprint-DTNT4qYJ.cjs → blueprint-DUnNPwQL.cjs} +43 -10
  12. package/dist/{blueprintFns-CcpboZ80.js → blueprintFns-DSj4RTjU.js} +9 -4
  13. package/dist/{blueprintFns-2XDZfCxX.cjs → blueprintFns-Dg8V99O9.cjs} +9 -4
  14. package/dist/{blueprintSketcher-DDPyypmC.js → blueprintSketcher-gMuUUPb-.js} +185 -54
  15. package/dist/{blueprintSketcher-C0EXFVb2.cjs → blueprintSketcher-gXVPrPlj.cjs} +192 -61
  16. package/dist/{boolean2D-Ddfo_dd0.cjs → boolean2D-BpmxQ1AH.cjs} +5 -5
  17. package/dist/{boolean2D-C_PVz8xT.js → boolean2D-DKT0BgZs.js} +5 -5
  18. package/dist/brepjs.cjs +105 -92
  19. package/dist/brepjs.js +39 -27
  20. package/dist/{cameraFns-Czr5vABD.cjs → cameraFns-2-haLzLi.cjs} +4 -4
  21. package/dist/{cameraFns-D9tdBYLM.js → cameraFns-CG_J66Hl.js} +4 -4
  22. package/dist/core.cjs +12 -11
  23. package/dist/core.js +4 -3
  24. package/dist/{cornerFinder-Cqg-Dz74.js → cornerFinder-CPFM7bA0.js} +1 -1
  25. package/dist/{cornerFinder-DETRDOMz.cjs → cornerFinder-mfsUMi5g.cjs} +1 -1
  26. package/dist/{curveFns-RENXKp64.js → curveFns-DX13KRh2.js} +2 -2
  27. package/dist/{curveFns-D7utcbnf.cjs → curveFns-GmFnqNo3.cjs} +2 -2
  28. package/dist/{drawFns-D9Rf4foW.cjs → drawFns-CI6CpqO8.cjs} +35 -16
  29. package/dist/{drawFns-B9HbtAoc.js → drawFns-CrfBz_wj.js} +35 -16
  30. package/dist/{errors-B3CDG537.js → errors-MHLiNE-C.js} +1 -92
  31. package/dist/{errors-CJU8CHng.cjs → errors-RHkKO5bZ.cjs} +0 -103
  32. package/dist/{faceFns-CPswi9Cm.cjs → faceFns-BK4r7Dxk.cjs} +3 -3
  33. package/dist/{faceFns-CB6uzvOg.js → faceFns-DJj9Nb6T.js} +3 -3
  34. package/dist/{healingFns-BFTYLiAm.js → healingFns-DxcRyVCG.js} +5 -6
  35. package/dist/{healingFns-bhMxTTqw.cjs → healingFns-Hx4oTlq8.cjs} +27 -28
  36. package/dist/{helpers-Cu4ag5bh.cjs → helpers-BfkBvokP.cjs} +8 -24
  37. package/dist/{helpers-BiN4qQZP.js → helpers-Du_OdHuy.js} +9 -25
  38. package/dist/{importFns-X8vBhZI2.js → importFns-DqxAZFb-.js} +3 -3
  39. package/dist/{importFns-DS4J1xLv.cjs → importFns-pr-r5qiV.cjs} +3 -3
  40. package/dist/io.cjs +2 -2
  41. package/dist/io.js +2 -2
  42. package/dist/{loftFns-ChHjzUK-.cjs → loftFns-BdpZ8FMN.cjs} +2 -125
  43. package/dist/{loftFns-BF5X7ltI.js → loftFns-BeGJ6dxx.js} +4 -109
  44. package/dist/{measureFns-B5Zzg1qM.cjs → measureFns-CJGrmhHT.cjs} +4 -4
  45. package/dist/{measureFns-CC7HhAH3.js → measureFns-CMnbcUZC.js} +4 -4
  46. package/dist/measurement.cjs +1 -1
  47. package/dist/measurement.js +1 -1
  48. package/dist/{meshFns-D57Fyqyf.js → meshFns-Cs5EBsf7.js} +4 -4
  49. package/dist/{meshFns-CaXmWmhe.cjs → meshFns-Dqf5QBhQ.cjs} +5 -5
  50. package/dist/operations.cjs +2 -2
  51. package/dist/operations.js +2 -2
  52. package/dist/originTrackingFns-DZmdiQ-O.js +203 -0
  53. package/dist/originTrackingFns-fpEgTIwV.cjs +226 -0
  54. package/dist/{planeOps-Cp6GQ23-.js → planeOps-CQahLrCx.js} +1 -1
  55. package/dist/{planeOps-Cr25KWWA.cjs → planeOps-VlFxtvzY.cjs} +1 -1
  56. package/dist/primitiveFns-B_rflH83.cjs +773 -0
  57. package/dist/primitiveFns-Cxo3xDKY.js +558 -0
  58. package/dist/projection.cjs +1 -1
  59. package/dist/projection.js +1 -1
  60. package/dist/query.cjs +2 -2
  61. package/dist/query.js +2 -2
  62. package/dist/{refResolveFns-3bw9-U-e.js → refResolveFns-BbRLD8LA.js} +6 -6
  63. package/dist/{refResolveFns-BxmgIhQM.cjs → refResolveFns-CVDLwh12.cjs} +6 -6
  64. package/dist/result.cjs +1 -1
  65. package/dist/result.js +1 -1
  66. package/dist/rolldown-runtime-DakpK96I.cjs +43 -0
  67. package/dist/shapeFns-BTFx-os7.js +43 -0
  68. package/dist/shapeFns-D_5TgiUi.cjs +84 -0
  69. package/dist/shapeRef.cjs +1 -1
  70. package/dist/shapeRef.js +1 -1
  71. package/dist/{shapeTypes-Bpsu5KJO.cjs → shapeTypes-CkcIL7zv.cjs} +1 -222
  72. package/dist/{shapeTypes-CnKFSfDT.js → shapeTypes-t49f64Dx.js} +2 -139
  73. package/dist/sketching/drawing.d.ts +9 -1
  74. package/dist/sketching.cjs +3 -3
  75. package/dist/sketching.js +3 -3
  76. package/dist/{solidBuilders-I8_V8qqU.js → solidBuilders-DTgqQC3W.js} +310 -8
  77. package/dist/{solidBuilders-Bp7lQW62.cjs → solidBuilders-IiIzjKAr.cjs} +401 -15
  78. package/dist/{surfaceBuilders-D8_08oOR.cjs → surfaceBuilders-Biqx51el.cjs} +6 -5
  79. package/dist/{surfaceBuilders-BNR7yMQO.js → surfaceBuilders-BryY-i0F.js} +4 -3
  80. package/dist/text.cjs +2 -2
  81. package/dist/text.js +2 -2
  82. package/dist/{textBlueprints-B5zcLGvJ.cjs → textBlueprints-BY0FEg59.cjs} +138 -51
  83. package/dist/{textBlueprints-igbNvKcd.js → textBlueprints-ZzYg3XTS.js} +116 -11
  84. package/dist/{textMetrics-CJvtpbc3.js → textMetrics-Diakbtem.js} +2 -2
  85. package/dist/{textMetrics-08fF0QNf.cjs → textMetrics-f5yXR4OG.cjs} +2 -2
  86. package/dist/{threadFns-CqSMNyTZ.js → threadFns-BOtXTHZ9.js} +8 -8
  87. package/dist/{threadFns-Co6vWEWx.cjs → threadFns-DRrk9Qod.cjs} +8 -8
  88. package/dist/topology.cjs +9 -9
  89. package/dist/topology.js +9 -9
  90. package/dist/{topologyQueryFns-C3fhJndG.cjs → topologyQueryFns-Bia7o8l_.cjs} +97 -6
  91. package/dist/{topologyQueryFns-DNqT88yx.js → topologyQueryFns-BkQ6Q7gN.js} +93 -2
  92. package/dist/validityTypes-DiTgeCD9.js +129 -0
  93. package/dist/validityTypes-ZGMVlv7b.cjs +200 -0
  94. package/dist/vectors.cjs +1 -1
  95. package/dist/vectors.js +1 -1
  96. package/package.json +8 -8
  97. package/dist/primitiveFns-CRy_CUVg.cjs +0 -492
  98. package/dist/primitiveFns-DCIH-SBm.js +0 -331
  99. package/dist/shapeFns-BrHFNLMA.js +0 -771
  100. package/dist/shapeFns-qm9VRo4i.cjs +0 -962
@@ -1,10 +1,10 @@
1
- import { at as getKernel2D, it as getKernel } from "./shapeTypes-CnKFSfDT.js";
1
+ import { K as getKernel, q as getKernel2D } from "./shapeTypes-t49f64Dx.js";
2
2
  import { i as wasmIndex, n as bug } from "./bug-BdOHwn_e.js";
3
- import { C as isOk, I as unwrap, O as ok, n as computationError, s as safeIndex, v as err } from "./errors-B3CDG537.js";
3
+ import { E as ok, P as unwrap, g as err, n as computationError, s as safeIndex, x as isOk } from "./errors-MHLiNE-C.js";
4
4
  import { r as RAD2DEG, t as DEG2RAD } from "./constants-ITRzCnCp.js";
5
5
  import { t as firstOrThrow } from "./arrayAccess-DrUGPADn.js";
6
- import { _ as samePoint, b as subtract2d, d as cartesianToPolar, f as crossProduct2d, g as rotate2d, h as polarToCartesian, l as add2d, m as polarAngle2d, o as normalize2d, p as distance2d, v as scalarMultiply2d } from "./helpers-BiN4qQZP.js";
7
- import { _ as Curve2D, c as make2dCircle, f as make2dSegmentCurve, h as approximateAsBSpline, m as make2dThreePointArc, n as asSVG, o as make2dArcFromCenter, p as make2dTangentArc, r as viewbox, s as make2dBezierCurve, t as Blueprint, u as make2dEllipseArc, x as isPoint2D, y as BoundingBox2d } from "./blueprint-DJJo8WkI.js";
6
+ import { _ as samePoint, b as subtract2d, c as add2d, d as crossProduct2d, f as distance2d, g as rotate2d, h as polarToCartesian, m as polarAngle2d, u as cartesianToPolar, v as scalarMultiply2d } from "./helpers-Du_OdHuy.js";
7
+ import { S as isPoint2D, _ as Curve2D, b as BoundingBox2d, c as make2dCircle, f as make2dSegmentCurve, h as approximateAsBSpline, m as make2dThreePointArc, n as asSVG, o as make2dArcFromCenter, p as make2dTangentArc, r as viewbox, s as make2dBezierCurve, t as Blueprint, u as make2dEllipseArc, y as normalize2d } from "./blueprint-DEMSX-hc.js";
8
8
  //#region node_modules/flatqueue/index.js
9
9
  /**
10
10
  * @typedef {Float64ArrayConstructor | Float32ArrayConstructor |
@@ -668,32 +668,99 @@ var make2dOffset = (curve, offset) => {
668
668
  };
669
669
  //#endregion
670
670
  //#region src/2d/lib/customCorners.ts
671
+ /** Unwrap an intersection, discarding the common-segment curves the caller does not use. */
672
+ function intersectionPoints(first, second) {
673
+ const result = unwrap(intersectCurves(first, second));
674
+ result.commonSegments.forEach((c) => {
675
+ c.delete();
676
+ });
677
+ return result.intersections;
678
+ }
679
+ /**
680
+ * Delete the split pieces the caller is discarding. `splitAt` returns the curve
681
+ * itself when there is nothing to split, so the source is never deleted here.
682
+ */
683
+ function disposeSplitPieces(pieces, source, kept) {
684
+ pieces.forEach((piece) => {
685
+ if (piece !== source && piece !== kept) piece.delete();
686
+ });
687
+ }
688
+ /**
689
+ * Run `split` and, if it throws, dispose the pieces an earlier split already
690
+ * produced. Splitting the second curve of a corner can fail (its parameter may
691
+ * not project onto the offset), stranding the first curve's pieces.
692
+ */
693
+ function splitOrDiscard(split, earlier) {
694
+ try {
695
+ return split();
696
+ } catch (e) {
697
+ disposeSplitPieces(earlier.pieces, earlier.source);
698
+ throw e;
699
+ }
700
+ }
701
+ /**
702
+ * Build the corner result, disposing the trimmed halves if the connecting curve
703
+ * cannot be built. They are unreachable once the error propagates.
704
+ */
705
+ function discardTrimsOnError(firstCurve, secondCurve, first, second, build) {
706
+ try {
707
+ return build();
708
+ } catch (e) {
709
+ if (first !== firstCurve) first.delete();
710
+ if (second !== secondCurve) second.delete();
711
+ throw e;
712
+ }
713
+ }
671
714
  function removeCorner(firstCurve, secondCurve, radius) {
672
715
  const sinAngle = crossProduct2d(firstCurve.tangentAt(1), secondCurve.tangentAt(0));
673
716
  if (Math.abs(sinAngle) < 1e-10) return null;
674
717
  const offset = Math.abs(radius) * (sinAngle > 0 ? -1 : 1);
675
- const firstOffset = make2dOffset(firstCurve, offset);
676
- const secondOffset = make2dOffset(secondCurve, offset);
677
- if (!(firstOffset instanceof Curve2D) || !(secondOffset instanceof Curve2D)) return null;
678
- const intersectionResult = intersectCurves(firstOffset, secondOffset, 1e-9);
679
- if (!isOk(intersectionResult)) return null;
680
- const potentialCenter = intersectionResult.value.intersections.at(-1);
681
- if (!isPoint2D(potentialCenter)) return null;
682
- const center = potentialCenter;
683
- const splitForFillet = (curve, offsetCurve) => {
684
- const [x, y] = offsetCurve.tangentAt(center);
685
- const normal = normalize2d([-y, x]);
686
- const splitPoint = add2d(center, scalarMultiply2d(normal, offset));
687
- const splitParam = unwrap(curve.parameter(splitPoint, 1e-6));
688
- return curve.splitAt([splitParam]);
689
- };
690
- const firstSplit = splitForFillet(firstCurve, firstOffset);
691
- const secondSplit = splitForFillet(secondCurve, secondOffset);
692
- return {
693
- first: wasmIndex(firstSplit, 0),
694
- second: wasmIndex(secondSplit, 1),
695
- center
696
- };
718
+ let firstOffset = null;
719
+ let secondOffset = null;
720
+ try {
721
+ firstOffset = make2dOffset(firstCurve, offset);
722
+ secondOffset = make2dOffset(secondCurve, offset);
723
+ if (!(firstOffset instanceof Curve2D) || !(secondOffset instanceof Curve2D)) return null;
724
+ const firstOffsetCurve = firstOffset;
725
+ const secondOffsetCurve = secondOffset;
726
+ const intersectionResult = intersectCurves(firstOffsetCurve, secondOffsetCurve, 1e-9);
727
+ if (!isOk(intersectionResult)) return null;
728
+ intersectionResult.value.commonSegments.forEach((c) => {
729
+ c.delete();
730
+ });
731
+ const potentialCenter = intersectionResult.value.intersections.at(-1);
732
+ if (!isPoint2D(potentialCenter)) return null;
733
+ const center = potentialCenter;
734
+ const splitForFillet = (curve, offsetCurve) => {
735
+ const [x, y] = offsetCurve.tangentAt(center);
736
+ const normal = normalize2d([-y, x]);
737
+ const splitPoint = add2d(center, scalarMultiply2d(normal, offset));
738
+ const splitParam = unwrap(curve.parameter(splitPoint, 1e-6));
739
+ return curve.splitAt([splitParam]);
740
+ };
741
+ const firstSplit = splitForFillet(firstCurve, firstOffsetCurve);
742
+ const secondSplit = splitOrDiscard(() => splitForFillet(secondCurve, secondOffsetCurve), {
743
+ pieces: firstSplit,
744
+ source: firstCurve
745
+ });
746
+ const first = firstSplit[0];
747
+ const second = secondSplit[1];
748
+ if (!first || !second) {
749
+ disposeSplitPieces(firstSplit, firstCurve);
750
+ disposeSplitPieces(secondSplit, secondCurve);
751
+ return null;
752
+ }
753
+ disposeSplitPieces(firstSplit, firstCurve, first);
754
+ disposeSplitPieces(secondSplit, secondCurve, second);
755
+ return {
756
+ first,
757
+ second,
758
+ center
759
+ };
760
+ } finally {
761
+ if (firstOffset instanceof Curve2D) firstOffset.delete();
762
+ if (secondOffset instanceof Curve2D) secondOffset.delete();
763
+ }
697
764
  }
698
765
  /**
699
766
  * Insert a circular fillet arc at the corner between two curves.
@@ -711,11 +778,11 @@ function filletCurves(firstCurve, secondCurve, radius) {
711
778
  const cornerRemoved = removeCorner(firstCurve, secondCurve, radius);
712
779
  if (!cornerRemoved) return [firstCurve, secondCurve];
713
780
  const { first, second, center } = cornerRemoved;
714
- return [
781
+ return discardTrimsOnError(firstCurve, secondCurve, first, second, () => [
715
782
  first,
716
783
  make2dArcFromCenter(first.lastPoint, second.firstPoint, center),
717
784
  second
718
- ];
785
+ ]);
719
786
  }
720
787
  /**
721
788
  * Insert a straight chamfer segment at the corner between two curves.
@@ -727,11 +794,11 @@ function chamferCurves(firstCurve, secondCurve, radius) {
727
794
  const cornerRemoved = removeCorner(firstCurve, secondCurve, radius);
728
795
  if (!cornerRemoved) return [firstCurve, secondCurve];
729
796
  const { first, second } = cornerRemoved;
730
- return [
797
+ return discardTrimsOnError(firstCurve, secondCurve, first, second, () => [
731
798
  first,
732
799
  make2dSegmentCurve(first.lastPoint, second.firstPoint),
733
800
  second
734
- ];
801
+ ]);
735
802
  }
736
803
  /**
737
804
  * Insert a dogbone fillet at an inner corner for CNC milling clearance.
@@ -745,29 +812,53 @@ function dogboneFilletCurves(firstCurve, secondCurve, radius) {
745
812
  if (Math.abs(sinAngle) < 1e-10) return [firstCurve, secondCurve];
746
813
  const orientationCorrection = sinAngle > 0 ? -1 : 1;
747
814
  const offset = Math.abs(radius) * Math.sin(a / 2) * orientationCorrection;
748
- const firstOffset = make2dOffset(firstCurve, offset);
749
- const secondOffset = make2dOffset(secondCurve, offset);
750
- if (!(firstOffset instanceof Curve2D) || !(secondOffset instanceof Curve2D)) return [firstCurve, secondCurve];
751
- const intersectionResult2 = intersectCurves(firstOffset, secondOffset, 1e-9);
752
- if (!isOk(intersectionResult2)) return [firstCurve, secondCurve];
753
- const potentialCenter = intersectionResult2.value.intersections.at(-1);
754
- if (!isPoint2D(potentialCenter)) return [firstCurve, secondCurve];
755
- const circle = make2dCircle(radius, potentialCenter);
756
- const firstInt = unwrap(intersectCurves(firstCurve, circle)).intersections[0];
757
- const secondInt = unwrap(intersectCurves(secondCurve, circle)).intersections.at(-1);
758
- if (!firstInt || !secondInt) return [firstCurve, secondCurve];
759
- const firstSplit = firstCurve.splitAt([firstInt]);
760
- const secondSplit = secondCurve.splitAt([secondInt]);
761
- const firstPart = wasmIndex(firstSplit, 0);
762
- const secondPart = wasmIndex(secondSplit, secondSplit.length - 1);
815
+ let firstOffset = null;
816
+ let secondOffset = null;
817
+ let circle = null;
763
818
  try {
764
- return [
765
- firstPart,
766
- make2dThreePointArc(firstPart.lastPoint, firstCurve.lastPoint, secondPart.firstPoint),
767
- secondPart
768
- ];
769
- } catch {
770
- return [firstCurve, secondCurve];
819
+ firstOffset = make2dOffset(firstCurve, offset);
820
+ secondOffset = make2dOffset(secondCurve, offset);
821
+ if (!(firstOffset instanceof Curve2D) || !(secondOffset instanceof Curve2D)) return [firstCurve, secondCurve];
822
+ const intersectionResult2 = intersectCurves(firstOffset, secondOffset, 1e-9);
823
+ if (!isOk(intersectionResult2)) return [firstCurve, secondCurve];
824
+ intersectionResult2.value.commonSegments.forEach((c) => {
825
+ c.delete();
826
+ });
827
+ const potentialCenter = intersectionResult2.value.intersections.at(-1);
828
+ if (!isPoint2D(potentialCenter)) return [firstCurve, secondCurve];
829
+ circle = make2dCircle(radius, potentialCenter);
830
+ const firstInt = intersectionPoints(firstCurve, circle)[0];
831
+ const secondInt = intersectionPoints(secondCurve, circle).at(-1);
832
+ if (!firstInt || !secondInt) return [firstCurve, secondCurve];
833
+ const firstSplit = firstCurve.splitAt([firstInt]);
834
+ const secondSplit = splitOrDiscard(() => secondCurve.splitAt([secondInt]), {
835
+ pieces: firstSplit,
836
+ source: firstCurve
837
+ });
838
+ const firstPart = firstSplit[0];
839
+ const secondPart = secondSplit[secondSplit.length - 1];
840
+ if (!firstPart || !secondPart) {
841
+ disposeSplitPieces(firstSplit, firstCurve);
842
+ disposeSplitPieces(secondSplit, secondCurve);
843
+ return [firstCurve, secondCurve];
844
+ }
845
+ disposeSplitPieces(firstSplit, firstCurve, firstPart);
846
+ disposeSplitPieces(secondSplit, secondCurve, secondPart);
847
+ try {
848
+ return [
849
+ firstPart,
850
+ make2dThreePointArc(firstPart.lastPoint, firstCurve.lastPoint, secondPart.firstPoint),
851
+ secondPart
852
+ ];
853
+ } catch {
854
+ if (firstPart !== firstCurve) firstPart.delete();
855
+ if (secondPart !== secondCurve) secondPart.delete();
856
+ return [firstCurve, secondCurve];
857
+ }
858
+ } finally {
859
+ if (firstOffset instanceof Curve2D) firstOffset.delete();
860
+ if (secondOffset instanceof Curve2D) secondOffset.delete();
861
+ circle?.delete();
771
862
  }
772
863
  }
773
864
  //#endregion
@@ -791,6 +882,19 @@ var Blueprints = class Blueprints {
791
882
  this.blueprints = blueprints;
792
883
  this._boundingBox = null;
793
884
  }
885
+ /** Release the resources held by every child blueprint and the cached bounding box. */
886
+ delete() {
887
+ this.blueprints.forEach((bp) => {
888
+ bp.delete();
889
+ });
890
+ if (this._boundingBox) {
891
+ this._boundingBox.delete();
892
+ this._boundingBox = null;
893
+ }
894
+ }
895
+ [Symbol.dispose]() {
896
+ this.delete();
897
+ }
794
898
  /** Return a multi-line debug representation of every child blueprint. */
795
899
  get repr() {
796
900
  return ["Blueprints", ...this.blueprints.map((b) => b.repr)].join("\n");
@@ -898,6 +1002,19 @@ var CompoundBlueprint = class CompoundBlueprint {
898
1002
  this.blueprints = blueprints;
899
1003
  this._boundingBox = null;
900
1004
  }
1005
+ /** Release the resources held by every child blueprint and the cached bounding box. */
1006
+ delete() {
1007
+ this.blueprints.forEach((bp) => {
1008
+ bp.delete();
1009
+ });
1010
+ if (this._boundingBox) {
1011
+ this._boundingBox.delete();
1012
+ this._boundingBox = null;
1013
+ }
1014
+ }
1015
+ [Symbol.dispose]() {
1016
+ this.delete();
1017
+ }
901
1018
  /** Return a deep copy of this compound blueprint and all its children. */
902
1019
  clone() {
903
1020
  return new CompoundBlueprint(this.blueprints.map((bp) => bp.clone()));
@@ -1213,6 +1330,16 @@ var cornerModeFns = {
1213
1330
  dogbone: dogboneFilletCurves,
1214
1331
  fillet: filletCurves
1215
1332
  };
1333
+ /**
1334
+ * Delete the curves a corner function consumed. Corner functions return their
1335
+ * inputs untouched when they bail (collinear curves, failed offset), so only
1336
+ * the ones absent from the result are ours to free.
1337
+ */
1338
+ function disposeConsumedCurves(consumed, produced) {
1339
+ consumed.forEach((curve) => {
1340
+ if (!produced.includes(curve)) curve.delete();
1341
+ });
1342
+ }
1216
1343
  function buildCornerFunction(radius, mode) {
1217
1344
  if (typeof radius === "function") return radius;
1218
1345
  const makeFn = cornerModeFns[mode];
@@ -1295,7 +1422,9 @@ var BaseSketcher2d = class {
1295
1422
  }
1296
1423
  const previousCurve = this.pendingCurves.pop();
1297
1424
  if (!previousCurve) bug("Sketcher2d.saveCurve", "No previous curve available for custom corner");
1298
- this.pendingCurves.push(...this._nextCorner(previousCurve, curve));
1425
+ const cornered = this._nextCorner(previousCurve, curve);
1426
+ disposeConsumedCurves([previousCurve, curve], cornered);
1427
+ this.pendingCurves.push(...cornered);
1299
1428
  this._nextCorner = null;
1300
1429
  }
1301
1430
  /** Draw a straight line to an absolute 2D point. */
@@ -1469,7 +1598,9 @@ var BaseSketcher2d = class {
1469
1598
  const previousCurve = this.pendingCurves.pop();
1470
1599
  const curve = this.pendingCurves.shift();
1471
1600
  if (!previousCurve || !curve) bug("Sketcher2d._customCornerLastWithFirst", "Not enough curves to close and fillet");
1472
- this.pendingCurves.push(...buildCornerFunction(radius, mode)(previousCurve, curve));
1601
+ const cornered = buildCornerFunction(radius, mode)(previousCurve, curve);
1602
+ disposeConsumedCurves([previousCurve, curve], cornered);
1603
+ this.pendingCurves.push(...cornered);
1473
1604
  }
1474
1605
  _closeSketch() {
1475
1606
  if (!samePoint(this.pointer, this.firstPoint)) this.lineTo(this.firstPoint);