brepjs 20.12.4 → 20.12.6

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 (102) hide show
  1. package/dist/2d/lib/offset.d.ts +1 -1
  2. package/dist/2d.cjs +6 -6
  3. package/dist/2d.js +6 -6
  4. package/dist/{adjacencyFns-54UTqtan.js → adjacencyFns--KmBIKYJ.js} +3 -3
  5. package/dist/{adjacencyFns-C_Vb1AeW.cjs → adjacencyFns-BFJfaUwX.cjs} +3 -3
  6. package/dist/{blueprint-DFpjcrlm.js → blueprint-BhIk9Pvm.js} +7 -8
  7. package/dist/{blueprint-D0VEeTzJ.cjs → blueprint-D83DDDPb.cjs} +7 -8
  8. package/dist/{blueprintFns-Douf5ZdX.cjs → blueprintFns-C4TQn-x_.cjs} +2 -2
  9. package/dist/{blueprintFns-Dye1jezD.js → blueprintFns-eULVgkq9.js} +2 -2
  10. package/dist/{blueprintSketcher-Cr0Lr1Dq.js → blueprintSketcher-D_Faf0GO.js} +32 -14
  11. package/dist/{blueprintSketcher-W9yON-UC.cjs → blueprintSketcher-Di376t-0.cjs} +32 -14
  12. package/dist/{boolean2D-C9VghXHG.cjs → boolean2D-CNZFI_y8.cjs} +4 -4
  13. package/dist/{boolean2D-CCV3R6lN.js → boolean2D-DqpCF72W.js} +4 -4
  14. package/dist/brepjs.cjs +128 -100
  15. package/dist/brepjs.js +128 -100
  16. package/dist/{cameraFns-DZOI_ewG.js → cameraFns-CrClIkmV.js} +3 -3
  17. package/dist/{cameraFns-x3L6dtA8.cjs → cameraFns-RqraCXIc.cjs} +3 -3
  18. package/dist/core.cjs +2 -2
  19. package/dist/core.js +2 -2
  20. package/dist/{cornerFinder-BY10jciz.js → cornerFinder-BZuQkRp2.js} +1 -1
  21. package/dist/{cornerFinder-B8PqO4um.cjs → cornerFinder-CdOe1Wrb.cjs} +1 -1
  22. package/dist/{curveFns-B4308HNM.js → curveFns-BP3srCfK.js} +1 -1
  23. package/dist/{curveFns-8lUhNquZ.cjs → curveFns-CyIvQNYT.cjs} +1 -1
  24. package/dist/{drawFns-C7zAvera.cjs → drawFns-71cOhWD-.cjs} +29 -16
  25. package/dist/{drawFns-DjnU3fEd.js → drawFns-DxDwJ5zZ.js} +29 -16
  26. package/dist/{faceFns-BjmlYcc9.cjs → faceFns-B7MiDYj1.cjs} +2 -2
  27. package/dist/{faceFns-7eHqNM0P.js → faceFns-iVPbTxki.js} +2 -2
  28. package/dist/{healingFns-BW7mZ_SW.js → healingFns-BhP8zfp1.js} +5 -5
  29. package/dist/{healingFns-CYLIcIWv.cjs → healingFns-DWljGTNR.cjs} +5 -5
  30. package/dist/{helpers-BQ6XMFcm.js → helpers-D2hANLRu.js} +14 -10
  31. package/dist/{helpers-De0Z_6iV.cjs → helpers-DKEVm6Hu.cjs} +14 -10
  32. package/dist/{importFns-BCL4-H8e.js → importFns-DUzIkns7.js} +2 -2
  33. package/dist/{importFns-3IMBHQrQ.cjs → importFns-KEPAgbjj.cjs} +2 -2
  34. package/dist/index.d.ts +2 -2
  35. package/dist/io.cjs +2 -2
  36. package/dist/io.js +2 -2
  37. package/dist/kernel/bspline2dFit.d.ts +42 -0
  38. package/dist/kernel/geometry2d.d.ts +45 -0
  39. package/dist/kernel/occt/kernel2dOps.d.ts +1 -1
  40. package/dist/kernel/occtWasm/constructionOps.d.ts +1 -1
  41. package/dist/kernel/occtWasm/kernel2dOps.d.ts +7 -4
  42. package/dist/kernel/occtWasm/occtWasmAdapter.cjs +1 -1
  43. package/dist/kernel/occtWasm/occtWasmAdapter.d.ts +3 -3
  44. package/dist/kernel/occtWasm/occtWasmAdapter.js +1 -1
  45. package/dist/kernel/occtWasm/occtWasmTypes.d.ts +7 -0
  46. package/dist/{loftFns-DlG5oR0X.cjs → loftFns-D5AvfCGG.cjs} +17 -2
  47. package/dist/{loftFns-H4ZOpRAk.js → loftFns-D5NJpHLZ.js} +17 -2
  48. package/dist/{measureFns-Ce01LVwq.cjs → measureFns-CZHNWkiA.cjs} +102 -35
  49. package/dist/{measureFns-1IfNe629.js → measureFns-mxBdPiWa.js} +102 -35
  50. package/dist/measurement/measureFns.d.ts +3 -2
  51. package/dist/measurement.cjs +2 -2
  52. package/dist/measurement.js +2 -2
  53. package/dist/{meshFns-nEvfwNRF.cjs → meshFns-Czlt-GBJ.cjs} +3 -3
  54. package/dist/{meshFns-DaRZxa7B.js → meshFns-DmjMzNbH.js} +3 -3
  55. package/dist/{occtWasmAdapter-ipKUdNLN.js → occtWasmAdapter-B9d0Q0Vl.js} +1160 -261
  56. package/dist/{occtWasmAdapter-CRd9RFEu.cjs → occtWasmAdapter-DVxLkjlJ.cjs} +1171 -260
  57. package/dist/operations/patternFns.d.ts +6 -1
  58. package/dist/operations.cjs +2 -2
  59. package/dist/operations.js +2 -2
  60. package/dist/{originTrackingFns-zrksCJTa.js → originTrackingFns-CBnyKLm7.js} +2 -2
  61. package/dist/{originTrackingFns-9gyCMFFQ.cjs → originTrackingFns-CHymOLLm.cjs} +2 -2
  62. package/dist/{primitiveFns-BRXZ7jnP.cjs → primitiveFns-BVeBEaa4.cjs} +7 -14
  63. package/dist/{primitiveFns-ClQP6zMQ.js → primitiveFns-DeNl60Rw.js} +7 -14
  64. package/dist/{principalBoxFns-DsfWOoXg.js → principalBoxFns-3mW_hA6z.js} +3 -3
  65. package/dist/{principalBoxFns-tIv-crMB.cjs → principalBoxFns-CG6kG7vT.cjs} +3 -3
  66. package/dist/projection.cjs +1 -1
  67. package/dist/projection.js +1 -1
  68. package/dist/query/finderCore.d.ts +7 -7
  69. package/dist/query.cjs +2 -2
  70. package/dist/query.js +2 -2
  71. package/dist/{refResolveFns-BZdUlv9f.cjs → refResolveFns-BAs4p9z7.cjs} +6 -6
  72. package/dist/{refResolveFns-BG3JGs--.js → refResolveFns-DHx1Y3GG.js} +6 -6
  73. package/dist/{shapeFns-BbXqiNqY.cjs → shapeFns-C0w8vvfb.cjs} +2 -2
  74. package/dist/{shapeFns-BCgegapL.js → shapeFns-CgqKICF_.js} +2 -2
  75. package/dist/shapeRef.cjs +1 -1
  76. package/dist/shapeRef.js +1 -1
  77. package/dist/{shapeTypes-DJT3SnGK.cjs → shapeTypes-Dc7j-MYg.cjs} +10 -16
  78. package/dist/{shapeTypes-DAz6aAnJ.js → shapeTypes-DwvQUp9M.js} +10 -16
  79. package/dist/sketching/sketches.d.ts +2 -0
  80. package/dist/sketching.cjs +3 -3
  81. package/dist/sketching.js +3 -3
  82. package/dist/{solidBuilders-8xytLt8-.js → solidBuilders-DT1gpVWM.js} +5 -5
  83. package/dist/{solidBuilders-BWbqhbyv.cjs → solidBuilders-iS5DDwg8.cjs} +5 -5
  84. package/dist/{surfaceBuilders-CwG_RPdZ.cjs → surfaceBuilders-BvwSgD3C.cjs} +3 -3
  85. package/dist/{surfaceBuilders-BO96DMCH.js → surfaceBuilders-CPLe0bbk.js} +3 -3
  86. package/dist/text.cjs +2 -2
  87. package/dist/text.js +2 -2
  88. package/dist/{textBlueprints-Dhe8_Uvc.js → textBlueprints-BU0Rhk54.js} +19 -11
  89. package/dist/{textBlueprints-DHfYmLtP.cjs → textBlueprints-CNPCPJix.cjs} +19 -11
  90. package/dist/{textMetrics-CwYDH9js.cjs → textMetrics-C71g4TmO.cjs} +1 -1
  91. package/dist/{textMetrics-Bbf-Dllw.js → textMetrics-Df9aLYK2.js} +1 -1
  92. package/dist/{threadFns-B23RqugN.cjs → threadFns-CzXEnnmo.cjs} +37 -29
  93. package/dist/{threadFns-Cn7_bmux.js → threadFns-DESH7lcs.js} +36 -28
  94. package/dist/topology/apiTypes.d.ts +13 -7
  95. package/dist/topology.cjs +9 -9
  96. package/dist/topology.d.ts +1 -1
  97. package/dist/topology.js +9 -9
  98. package/dist/{topologyQueryFns-xh11vEQw.cjs → topologyQueryFns-5Frx8Y-0.cjs} +1 -1
  99. package/dist/{topologyQueryFns-BfYdGOJc.js → topologyQueryFns-LXV1nTaS.js} +1 -1
  100. package/dist/{validityTypes-CXkecqMw.cjs → validityTypes-C6rROGTP.cjs} +1 -1
  101. package/dist/{validityTypes-BfOuvfyp.js → validityTypes-DM-Iwe8N.js} +1 -1
  102. package/package.json +2 -1
@@ -1,19 +1,19 @@
1
1
  const require_rolldown_runtime = require("./rolldown-runtime-BW-eSwOZ.cjs");
2
- const require_shapeTypes = require("./shapeTypes-DJT3SnGK.cjs");
2
+ const require_shapeTypes = require("./shapeTypes-Dc7j-MYg.cjs");
3
3
  const require_bug = require("./bug-CBcpIPuf.cjs");
4
4
  const require_errors = require("./errors-O_blYTWT.cjs");
5
5
  const require_constants = require("./constants-oee0S_x6.cjs");
6
6
  const require_types = require("./types-CjF9Rofr.cjs");
7
7
  const require_vecOps = require("./vecOps-CrGEPPQM.cjs");
8
8
  const require_planeOps = require("./planeOps-DZfLToKZ.cjs");
9
- const require_faceFns = require("./faceFns-BjmlYcc9.cjs");
10
- const require_solidBuilders = require("./solidBuilders-BWbqhbyv.cjs");
9
+ const require_faceFns = require("./faceFns-B7MiDYj1.cjs");
10
+ const require_solidBuilders = require("./solidBuilders-iS5DDwg8.cjs");
11
11
  const require_faceRoleFns = require("./faceRoleFns-Db5bYj4Q.cjs");
12
- const require_curveFns = require("./curveFns-8lUhNquZ.cjs");
12
+ const require_curveFns = require("./curveFns-CyIvQNYT.cjs");
13
13
  const require_arrayAccess = require("./arrayAccess-DpJYARwv.cjs");
14
- const require_surfaceBuilders = require("./surfaceBuilders-CwG_RPdZ.cjs");
15
- const require_blueprintSketcher = require("./blueprintSketcher-W9yON-UC.cjs");
16
- const require_loftFns = require("./loftFns-DlG5oR0X.cjs");
14
+ const require_surfaceBuilders = require("./surfaceBuilders-BvwSgD3C.cjs");
15
+ const require_blueprintSketcher = require("./blueprintSketcher-Di376t-0.cjs");
16
+ const require_loftFns = require("./loftFns-D5AvfCGG.cjs");
17
17
  let opentype_js = require("opentype.js");
18
18
  opentype_js = require_rolldown_runtime.__toESM(opentype_js, 1);
19
19
  // src/topology/shapeRef/extrudeRoleFns.ts
@@ -486,9 +486,13 @@ function sketchSweep(sketch, sketchOnPlane, sweepConfig = {}) {
486
486
  ...sweepConfig
487
487
  };
488
488
  if (sketch.baseFace) config.support = sketch.baseFace.wrapped;
489
- const shape = require_errors.unwrap(require_loftFns.sweep(profile.wire, sketch.wire, config));
490
- sketch.delete();
491
- return shape;
489
+ try {
490
+ const shape = require_errors.unwrap(require_loftFns.sweep(profile.wire, sketch.wire, config));
491
+ sketch.delete();
492
+ return shape;
493
+ } finally {
494
+ profile.delete();
495
+ }
492
496
  }
493
497
  /**
494
498
  * Loft between this sketch and one or more other sketches.
@@ -763,6 +767,10 @@ var Sketches = class {
763
767
  if (!(only instanceof Sketch)) require_bug.bug(`Sketches.${op}`, `${op} is only supported on single-wire profiles.`);
764
768
  return only;
765
769
  }
770
+ /** Release the kernel resources of every contained sketch. */
771
+ delete() {
772
+ for (const s of this.sketches) s.delete();
773
+ }
766
774
  /** Build a face from the sole contained profile (see {@link Sketches.faces}). */
767
775
  face() {
768
776
  if (this.sketches.length !== 1) require_bug.bug("Sketches.face", "Multiple profiles — use faces() to combine them.");
@@ -930,7 +938,7 @@ function textBlueprints(text, { startX = 0, startY = 0, fontSize = 16, fontFamil
930
938
  let font = getFont(fontFamily);
931
939
  if (!font) font = getFont();
932
940
  if (!font) require_bug.bug("text", "No fonts loaded. Call loadFont() before using text functions.");
933
- const writtenText = font.getPath(text, -startX, -startY, fontSize);
941
+ const writtenText = font.getPath(text, startX, -startY, fontSize);
934
942
  const blueprints = Array.from(sketchFontCommands(writtenText.commands));
935
943
  return require_blueprintSketcher.organiseBlueprints(blueprints).mirror([0, 0]);
936
944
  }
@@ -1,5 +1,5 @@
1
1
  const require_errors = require("./errors-O_blYTWT.cjs");
2
- const require_textBlueprints = require("./textBlueprints-DHfYmLtP.cjs");
2
+ const require_textBlueprints = require("./textBlueprints-CNPCPJix.cjs");
3
3
  // src/text/sketchText.ts
4
4
  /**
5
5
  * Render text as 3D sketch outlines on a plane.
@@ -1,5 +1,5 @@
1
1
  import { E as ok, d as validationError, g as err, t as BrepErrorCode } from "./errors-BTccWbtE.js";
2
- import { _ as wrapSketchData, a as Sketches, n as getFont, t as textBlueprints, y as CompoundSketch } from "./textBlueprints-Dhe8_Uvc.js";
2
+ import { _ as wrapSketchData, a as Sketches, n as getFont, t as textBlueprints, y as CompoundSketch } from "./textBlueprints-BU0Rhk54.js";
3
3
  // src/text/sketchText.ts
4
4
  /**
5
5
  * Render text as 3D sketch outlines on a plane.
@@ -1,12 +1,12 @@
1
- const require_shapeTypes = require("./shapeTypes-DJT3SnGK.cjs");
1
+ const require_shapeTypes = require("./shapeTypes-Dc7j-MYg.cjs");
2
2
  const require_errors = require("./errors-O_blYTWT.cjs");
3
3
  const require_vecOps = require("./vecOps-CrGEPPQM.cjs");
4
- const require_faceFns = require("./faceFns-BjmlYcc9.cjs");
5
- const require_solidBuilders = require("./solidBuilders-BWbqhbyv.cjs");
6
- const require_primitiveFns = require("./primitiveFns-BRXZ7jnP.cjs");
7
- const require_shapeFns = require("./shapeFns-BbXqiNqY.cjs");
8
- const require_loftFns = require("./loftFns-DlG5oR0X.cjs");
9
- const require_refResolveFns = require("./refResolveFns-BZdUlv9f.cjs");
4
+ const require_faceFns = require("./faceFns-B7MiDYj1.cjs");
5
+ const require_solidBuilders = require("./solidBuilders-iS5DDwg8.cjs");
6
+ const require_primitiveFns = require("./primitiveFns-BVeBEaa4.cjs");
7
+ const require_shapeFns = require("./shapeFns-C0w8vvfb.cjs");
8
+ const require_loftFns = require("./loftFns-D5AvfCGG.cjs");
9
+ const require_refResolveFns = require("./refResolveFns-BAs4p9z7.cjs");
10
10
  // src/utils/uuid.ts
11
11
  /** Generate a v4-style UUID string using `crypto.getRandomValues`. */
12
12
  function uuidv() {
@@ -147,7 +147,7 @@ function quatMultiply(a, b) {
147
147
  */
148
148
  function linearPattern(shape, direction, count, spacing, options) {
149
149
  if (count < 1) return require_errors.err(require_errors.validationError("PATTERN_INVALID_COUNT", "Pattern count must be at least 1"));
150
- if (count === 1) return require_errors.ok(shape);
150
+ if (count === 1) return require_shapeFns.clone(shape);
151
151
  if (require_vecOps.vecIsZero(direction)) return require_errors.err(require_errors.validationError("PATTERN_ZERO_DIRECTION", "Pattern direction cannot be zero"));
152
152
  const dir = require_vecOps.vecNormalize(direction);
153
153
  const copies = require_shapeTypes.getKernel().linearPattern(shape.wrapped, [...dir], spacing, count).map((s) => require_shapeTypes.castResultShape(s));
@@ -163,10 +163,15 @@ function linearPattern(shape, direction, count, spacing, options) {
163
163
  /**
164
164
  * Create a circular pattern of a shape around an axis.
165
165
  *
166
+ * A full turn (`fullAngle` of ±360) spaces the copies `fullAngle / count`
167
+ * apart, so the last copy does not land on the first. Any other angle is an
168
+ * open arc: the first copy stays in place, the last lands at `fullAngle`, and
169
+ * they are spaced `fullAngle / (count - 1)` apart.
170
+ *
166
171
  * @param shape - The shape to replicate
167
172
  * @param axis - Rotation axis direction
168
173
  * @param count - Total number of copies (including the original)
169
- * @param fullAngle - Total angle to spread copies over in degrees (default: 360)
174
+ * @param fullAngle - Angle in degrees the copies span (default: 360)
170
175
  * @param center - Center point of rotation (default: [0,0,0])
171
176
  * @param options - Boolean options for the fuse operation
172
177
  * @returns Fused shape of all copies
@@ -177,9 +182,9 @@ function circularPattern(shape, axis, count, fullAngle = 360, center = [
177
182
  0
178
183
  ], options) {
179
184
  if (count < 1) return require_errors.err(require_errors.validationError("PATTERN_INVALID_COUNT", "Pattern count must be at least 1"));
180
- if (count === 1) return require_errors.ok(shape);
185
+ if (count === 1) return require_shapeFns.clone(shape);
181
186
  if (require_vecOps.vecIsZero(axis)) return require_errors.err(require_errors.validationError("PATTERN_ZERO_AXIS", "Pattern axis cannot be zero"));
182
- const angleStep = fullAngle / count;
187
+ const angleStep = fullAngle / (Math.abs(Math.abs(fullAngle) - 360) < 1e-9 ? count : count - 1);
183
188
  const copies = require_shapeTypes.getKernel().circularPattern(shape.wrapped, [...center], [...axis], angleStep, count).map((s) => require_shapeTypes.castResultShape(s));
184
189
  try {
185
190
  return require_solidBuilders.fuseAll(copies, {
@@ -204,24 +209,27 @@ function circularPattern(shape, axis, count, fullAngle = 360, center = [
204
209
  * @returns Compound shape containing all copies, or fused result
205
210
  */
206
211
  function gridPattern(shape, directionX, directionY, countX, countY, spacingX, spacingY, options) {
207
- if (countX < 1 || countY < 1) return require_errors.err(require_errors.validationError("PATTERN_INVALID_COUNT", "Grid pattern counts must be at least 1"));
208
- if (countX === 1 && countY === 1) return require_errors.ok(shape);
209
- if (require_vecOps.vecIsZero(directionX)) return require_errors.err(require_errors.validationError("PATTERN_ZERO_DIRECTION", "Grid directionX cannot be zero"));
210
- if (require_vecOps.vecIsZero(directionY)) return require_errors.err(require_errors.validationError("PATTERN_ZERO_DIRECTION", "Grid directionY cannot be zero"));
211
- const kernel = require_shapeTypes.getKernel();
212
- const dirX = require_vecOps.vecNormalize(directionX);
213
- const dirY = require_vecOps.vecNormalize(directionY);
214
- if (typeof kernel.gridPattern === "function") {
215
- const compound = kernel.gridPattern(shape.wrapped, [...dirX], [...dirY], spacingX, spacingY, countX, countY);
216
- return require_errors.ok(require_shapeTypes.castResultShape(compound));
217
- }
218
- const rowResult = linearPattern(shape, directionX, countX, spacingX, options);
219
- if (!rowResult.ok) return rowResult;
220
- const row = rowResult.value;
221
- const out = linearPattern(row, directionY, countY, spacingY, options);
222
- const passthrough = out.ok && out.value === row;
223
- if (row !== shape && !passthrough) row[Symbol.dispose]();
224
- return out;
212
+ try {
213
+ var _usingCtx$2 = require_shapeTypes._usingCtx();
214
+ if (countX < 1 || countY < 1) return require_errors.err(require_errors.validationError("PATTERN_INVALID_COUNT", "Grid pattern counts must be at least 1"));
215
+ if (countX === 1 && countY === 1) return require_shapeFns.clone(shape);
216
+ if (require_vecOps.vecIsZero(directionX)) return require_errors.err(require_errors.validationError("PATTERN_ZERO_DIRECTION", "Grid directionX cannot be zero"));
217
+ if (require_vecOps.vecIsZero(directionY)) return require_errors.err(require_errors.validationError("PATTERN_ZERO_DIRECTION", "Grid directionY cannot be zero"));
218
+ const kernel = require_shapeTypes.getKernel();
219
+ const dirX = require_vecOps.vecNormalize(directionX);
220
+ const dirY = require_vecOps.vecNormalize(directionY);
221
+ if (typeof kernel.gridPattern === "function") {
222
+ const compound = kernel.gridPattern(shape.wrapped, [...dirX], [...dirY], spacingX, spacingY, countX, countY);
223
+ return require_errors.ok(require_shapeTypes.castResultShape(compound));
224
+ }
225
+ const rowResult = linearPattern(shape, directionX, countX, spacingX, options);
226
+ if (!rowResult.ok) return rowResult;
227
+ return linearPattern(_usingCtx$2.u(rowResult.value), directionY, countY, spacingY, options);
228
+ } catch (_) {
229
+ _usingCtx$2.e = _;
230
+ } finally {
231
+ _usingCtx$2.d();
232
+ }
225
233
  }
226
234
  // src/operations/exporterFns.ts
227
235
  /**
@@ -1,12 +1,12 @@
1
- import { F as createKernelHandle, G as _usingCtx, N as DisposalScope, n as castResultShape, q as getKernel, x as isShape3D } from "./shapeTypes-DAz6aAnJ.js";
1
+ import { F as createKernelHandle, G as _usingCtx, N as DisposalScope, n as castResultShape, q as getKernel, x as isShape3D } from "./shapeTypes-DwvQUp9M.js";
2
2
  import { E as ok, d as validationError, g as err, n as computationError, r as ioError, t as BrepErrorCode, x as isOk } from "./errors-BTccWbtE.js";
3
3
  import { d as vecNormalize, s as vecIsZero } from "./vecOps-S-m9H_fe.js";
4
- import { b as fromBREP } from "./faceFns-7eHqNM0P.js";
5
- import { h as fuseAll } from "./solidBuilders-8xytLt8-.js";
6
- import { E as wire, h as line } from "./primitiveFns-ClQP6zMQ.js";
7
- import { s as toBREP } from "./shapeFns-BCgegapL.js";
8
- import { t as loft } from "./loftFns-H4ZOpRAk.js";
9
- import { c as resolveRefParams } from "./refResolveFns-BG3JGs--.js";
4
+ import { b as fromBREP } from "./faceFns-iVPbTxki.js";
5
+ import { h as fuseAll } from "./solidBuilders-DT1gpVWM.js";
6
+ import { E as wire, h as line } from "./primitiveFns-DeNl60Rw.js";
7
+ import { s as toBREP, t as clone } from "./shapeFns-CgqKICF_.js";
8
+ import { t as loft } from "./loftFns-D5NJpHLZ.js";
9
+ import { c as resolveRefParams } from "./refResolveFns-DHx1Y3GG.js";
10
10
  // src/utils/uuid.ts
11
11
  /** Generate a v4-style UUID string using `crypto.getRandomValues`. */
12
12
  function uuidv() {
@@ -147,7 +147,7 @@ function quatMultiply(a, b) {
147
147
  */
148
148
  function linearPattern(shape, direction, count, spacing, options) {
149
149
  if (count < 1) return err(validationError("PATTERN_INVALID_COUNT", "Pattern count must be at least 1"));
150
- if (count === 1) return ok(shape);
150
+ if (count === 1) return clone(shape);
151
151
  if (vecIsZero(direction)) return err(validationError("PATTERN_ZERO_DIRECTION", "Pattern direction cannot be zero"));
152
152
  const dir = vecNormalize(direction);
153
153
  const copies = getKernel().linearPattern(shape.wrapped, [...dir], spacing, count).map((s) => castResultShape(s));
@@ -163,10 +163,15 @@ function linearPattern(shape, direction, count, spacing, options) {
163
163
  /**
164
164
  * Create a circular pattern of a shape around an axis.
165
165
  *
166
+ * A full turn (`fullAngle` of ±360) spaces the copies `fullAngle / count`
167
+ * apart, so the last copy does not land on the first. Any other angle is an
168
+ * open arc: the first copy stays in place, the last lands at `fullAngle`, and
169
+ * they are spaced `fullAngle / (count - 1)` apart.
170
+ *
166
171
  * @param shape - The shape to replicate
167
172
  * @param axis - Rotation axis direction
168
173
  * @param count - Total number of copies (including the original)
169
- * @param fullAngle - Total angle to spread copies over in degrees (default: 360)
174
+ * @param fullAngle - Angle in degrees the copies span (default: 360)
170
175
  * @param center - Center point of rotation (default: [0,0,0])
171
176
  * @param options - Boolean options for the fuse operation
172
177
  * @returns Fused shape of all copies
@@ -177,9 +182,9 @@ function circularPattern(shape, axis, count, fullAngle = 360, center = [
177
182
  0
178
183
  ], options) {
179
184
  if (count < 1) return err(validationError("PATTERN_INVALID_COUNT", "Pattern count must be at least 1"));
180
- if (count === 1) return ok(shape);
185
+ if (count === 1) return clone(shape);
181
186
  if (vecIsZero(axis)) return err(validationError("PATTERN_ZERO_AXIS", "Pattern axis cannot be zero"));
182
- const angleStep = fullAngle / count;
187
+ const angleStep = fullAngle / (Math.abs(Math.abs(fullAngle) - 360) < 1e-9 ? count : count - 1);
183
188
  const copies = getKernel().circularPattern(shape.wrapped, [...center], [...axis], angleStep, count).map((s) => castResultShape(s));
184
189
  try {
185
190
  return fuseAll(copies, {
@@ -204,24 +209,27 @@ function circularPattern(shape, axis, count, fullAngle = 360, center = [
204
209
  * @returns Compound shape containing all copies, or fused result
205
210
  */
206
211
  function gridPattern(shape, directionX, directionY, countX, countY, spacingX, spacingY, options) {
207
- if (countX < 1 || countY < 1) return err(validationError("PATTERN_INVALID_COUNT", "Grid pattern counts must be at least 1"));
208
- if (countX === 1 && countY === 1) return ok(shape);
209
- if (vecIsZero(directionX)) return err(validationError("PATTERN_ZERO_DIRECTION", "Grid directionX cannot be zero"));
210
- if (vecIsZero(directionY)) return err(validationError("PATTERN_ZERO_DIRECTION", "Grid directionY cannot be zero"));
211
- const kernel = getKernel();
212
- const dirX = vecNormalize(directionX);
213
- const dirY = vecNormalize(directionY);
214
- if (typeof kernel.gridPattern === "function") {
215
- const compound = kernel.gridPattern(shape.wrapped, [...dirX], [...dirY], spacingX, spacingY, countX, countY);
216
- return ok(castResultShape(compound));
212
+ try {
213
+ var _usingCtx$2 = _usingCtx();
214
+ if (countX < 1 || countY < 1) return err(validationError("PATTERN_INVALID_COUNT", "Grid pattern counts must be at least 1"));
215
+ if (countX === 1 && countY === 1) return clone(shape);
216
+ if (vecIsZero(directionX)) return err(validationError("PATTERN_ZERO_DIRECTION", "Grid directionX cannot be zero"));
217
+ if (vecIsZero(directionY)) return err(validationError("PATTERN_ZERO_DIRECTION", "Grid directionY cannot be zero"));
218
+ const kernel = getKernel();
219
+ const dirX = vecNormalize(directionX);
220
+ const dirY = vecNormalize(directionY);
221
+ if (typeof kernel.gridPattern === "function") {
222
+ const compound = kernel.gridPattern(shape.wrapped, [...dirX], [...dirY], spacingX, spacingY, countX, countY);
223
+ return ok(castResultShape(compound));
224
+ }
225
+ const rowResult = linearPattern(shape, directionX, countX, spacingX, options);
226
+ if (!rowResult.ok) return rowResult;
227
+ return linearPattern(_usingCtx$2.u(rowResult.value), directionY, countY, spacingY, options);
228
+ } catch (_) {
229
+ _usingCtx$2.e = _;
230
+ } finally {
231
+ _usingCtx$2.d();
217
232
  }
218
- const rowResult = linearPattern(shape, directionX, countX, spacingX, options);
219
- if (!rowResult.ok) return rowResult;
220
- const row = rowResult.value;
221
- const out = linearPattern(row, directionY, countY, spacingY, options);
222
- const passthrough = out.ok && out.value === row;
223
- if (row !== shape && !passthrough) row[Symbol.dispose]();
224
- return out;
225
233
  }
226
234
  // src/operations/exporterFns.ts
227
235
  /**
@@ -2,13 +2,14 @@ import { Vec2, Vec3 } from '../core/types.js';
2
2
  import { AnyShape, Dimension, Edge, Face, Wire, Shape3D } from '../core/shapeTypes.js';
3
3
  import { EdgeFinderFn, FaceFinderFn, ShapeFinder } from '../query/finderFns.js';
4
4
  /**
5
- * Structural type matching a Drawing's wire-producing interface.
6
- * Used in place of importing the actual Drawing class to avoid
7
- * Layer 2 → Layer 3 boundary violations.
5
+ * Structural type matching a Drawing: it sketches onto a plane as something
6
+ * that builds a face (holes included). Used in place of importing the actual
7
+ * Drawing class to avoid Layer 2 → Layer 3 boundary violations.
8
8
  */
9
9
  export interface DrawingLike {
10
- sketchOnPlane(plane: string): {
11
- wire: Wire;
10
+ sketchOnPlane(plane: 'XY'): {
11
+ face(): Face;
12
+ delete?(): void;
12
13
  };
13
14
  }
14
15
  type FinderFor<T extends AnyShape<Dimension>> = T extends Edge ? EdgeFinderFn : T extends Face ? FaceFinderFn : ShapeFinder<T>;
@@ -66,7 +67,12 @@ export interface DrillOptions {
66
67
  }
67
68
  /** Options for the pocket() compound operation. */
68
69
  export interface PocketOptions {
69
- /** 2D profile shape to cut into the face. */
70
+ /**
71
+ * 2D profile to cut into the face, drawn in XY with its origin at the face
72
+ * centre. On faces parallel to XY it keeps the world X and Y axes; on any
73
+ * other face its Y axis runs up the face and its X axis points right as seen
74
+ * from outside.
75
+ */
70
76
  profile: DrawingLike | Wire;
71
77
  /** Which face to pocket. Default: top face. */
72
78
  face?: Face | FinderFn<Face>;
@@ -75,7 +81,7 @@ export interface PocketOptions {
75
81
  }
76
82
  /** Options for the boss() compound operation. */
77
83
  export interface BossOptions {
78
- /** 2D profile shape to extrude onto the face. */
84
+ /** 2D profile to extrude from the face, placed as for {@link PocketOptions.profile}. */
79
85
  profile: DrawingLike | Wire;
80
86
  /** Which face to add onto. Default: top face. */
81
87
  face?: Face | FinderFn<Face>;
package/dist/topology.cjs CHANGED
@@ -1,13 +1,13 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_topologyQueryFns = require("./topologyQueryFns-xh11vEQw.cjs");
3
- const require_faceFns = require("./faceFns-BjmlYcc9.cjs");
4
- const require_solidBuilders = require("./solidBuilders-BWbqhbyv.cjs");
5
- const require_primitiveFns = require("./primitiveFns-BRXZ7jnP.cjs");
6
- const require_shapeFns = require("./shapeFns-BbXqiNqY.cjs");
7
- const require_curveFns = require("./curveFns-8lUhNquZ.cjs");
8
- const require_meshFns = require("./meshFns-nEvfwNRF.cjs");
9
- const require_healingFns = require("./healingFns-CYLIcIWv.cjs");
10
- const require_adjacencyFns = require("./adjacencyFns-C_Vb1AeW.cjs");
2
+ const require_topologyQueryFns = require("./topologyQueryFns-5Frx8Y-0.cjs");
3
+ const require_faceFns = require("./faceFns-B7MiDYj1.cjs");
4
+ const require_solidBuilders = require("./solidBuilders-iS5DDwg8.cjs");
5
+ const require_primitiveFns = require("./primitiveFns-BVeBEaa4.cjs");
6
+ const require_shapeFns = require("./shapeFns-C0w8vvfb.cjs");
7
+ const require_curveFns = require("./curveFns-CyIvQNYT.cjs");
8
+ const require_meshFns = require("./meshFns-Czlt-GBJ.cjs");
9
+ const require_healingFns = require("./healingFns-DWljGTNR.cjs");
10
+ const require_adjacencyFns = require("./adjacencyFns-BFJfaUwX.cjs");
11
11
  exports.addHoles = require_primitiveFns.addHoles;
12
12
  exports.adjacentFaces = require_adjacencyFns.adjacentFaces;
13
13
  exports.approximateCurve = require_curveFns.approximateCurve;
@@ -17,7 +17,7 @@ export { chamferDistAngle as chamferDistAngleShape } from './topology/chamferAng
17
17
  export { variableFillet, type VariableFilletRadius } from './topology/modifierFns.js';
18
18
  export { getCurveType, curveStartPoint, curveEndPoint, curvePointAt, curveTangentAt, curveAxis, curveLength, curveIsClosed, curveIsPeriodic, curvePeriod, getOrientation, flipOrientation, offsetWire2D, interpolateCurve, approximateCurve, type InterpolateCurveOptions, type ApproximateCurveOptions, } from './topology/curveFns.js';
19
19
  export { getNurbsCurveData, getNurbsSurfaceData } from './topology/nurbsFns.js';
20
- export { getSurfaceType, faceGeomType, faceOrientation, flipFaceOrientation, uvBounds, pointOnSurface, uvCoordinates, normalAt, faceCenter, faceAxis, classifyPointOnFace, outerWire, innerWires, projectPointOnFace, type UVBounds, type PointProjectionResult, } from './topology/faceFns.js';
20
+ export { getSurfaceType, faceGeomType, faceOrientation, flipFaceOrientation, uvBounds, pointOnSurface, uvCoordinates, normalAt, faceCenter, faceAxis, classifyPointOnFace, outerWire, innerWires, projectPointOnFace, type SurfaceType, type UVBounds, type PointProjectionResult, } from './topology/faceFns.js';
21
21
  export { facesOfEdge, edgesOfFace, wiresOfFace, verticesOfEdge, adjacentFaces, sharedEdges, } from './topology/adjacencyFns.js';
22
22
  export { exportSTEP, exportSTL, exportIGES, type ShapeMesh, type EdgeMesh, type MeshOptions, } from './topology/meshFns.js';
23
23
  export { clearMeshCache, createMeshCache, type MeshCacheContext } from './topology/meshCache.js';
package/dist/topology.js CHANGED
@@ -1,10 +1,10 @@
1
- import { _ as iterFaces, b as iterVertices, c as getFaces, f as getVertices, g as iterEdges, m as invalidateShapeCache, n as getBounds, p as getWires, s as getEdges, w as vertexPosition, x as iterWires } from "./topologyQueryFns-BfYdGOJc.js";
2
- import { C as shapeType, S as iterTopo, _ as cast, a as faceOrientation, b as fromBREP, c as innerWires, d as pointOnSurface, f as projectPointOnFace, g as asTopo, h as uvCoordinates, i as faceGeomType, l as normalAt, m as uvBounds, n as faceAxis, o as flipFaceOrientation, r as faceCenter, s as getSurfaceType, t as classifyPointOnFace, u as outerWire, x as isCompSolid, y as downcast } from "./faceFns-7eHqNM0P.js";
3
- import { h as fuseAll, p as cutAll } from "./solidBuilders-8xytLt8-.js";
4
- import { C as threePointArc, D as wireLoop, E as wire, S as tangentArc, T as vertex, _ as polygon, a as circle, b as sphere, c as cylinder, d as ellipsoid, f as face, g as offsetFace, h as line, i as bsplineApprox, l as ellipse, m as helix, n as bezier, o as compound, p as filledFace, r as box, s as cone, t as addHoles, u as ellipseArc, v as sewShells, w as torus, x as subFace, y as solid } from "./primitiveFns-ClQP6zMQ.js";
5
- import { a as isSameShape, i as isEqualShape, n as getHashCode } from "./shapeFns-BCgegapL.js";
6
- import { a as curveIsPeriodic, c as curvePointAt, d as flipOrientation, f as getCurveType, h as offsetWire2D, i as curveIsClosed, l as curveStartPoint, m as interpolateCurve, n as curveAxis, o as curveLength, p as getOrientation, r as curveEndPoint, s as curvePeriod, t as approximateCurve, u as curveTangentAt } from "./curveFns-B4308HNM.js";
7
- import { d as clearMeshCache, f as createMeshCache, n as exportSTEP, r as exportSTL, t as exportIGES } from "./meshFns-DaRZxa7B.js";
8
- import { A as variableFillet, F as toLineGeometryData, M as toGroupedBufferGeometryData, S as chamferDistAngle, _ as checkBoolean, a as healFace, b as getNurbsCurveData, d as chamferWithEvolution, f as cutWithEvolution, g as shellWithEvolution, h as intersectWithEvolution, j as toBufferGeometryData, l as solidFromShell, m as fuseWithEvolution, n as fixSelfIntersection, o as healSolid, p as filletWithEvolution, r as fixShape, s as healWire, t as autoHeal, u as positionOnCurve, v as cutAllBisect, x as getNurbsSurfaceData, y as fuseAllBisect } from "./healingFns-BW7mZ_SW.js";
9
- import { i as facesOfEdge, l as wiresOfFace, n as adjacentFaces, o as sharedEdges, r as edgesOfFace, s as verticesOfEdge } from "./adjacencyFns-54UTqtan.js";
1
+ import { _ as iterFaces, b as iterVertices, c as getFaces, f as getVertices, g as iterEdges, m as invalidateShapeCache, n as getBounds, p as getWires, s as getEdges, w as vertexPosition, x as iterWires } from "./topologyQueryFns-LXV1nTaS.js";
2
+ import { C as shapeType, S as iterTopo, _ as cast, a as faceOrientation, b as fromBREP, c as innerWires, d as pointOnSurface, f as projectPointOnFace, g as asTopo, h as uvCoordinates, i as faceGeomType, l as normalAt, m as uvBounds, n as faceAxis, o as flipFaceOrientation, r as faceCenter, s as getSurfaceType, t as classifyPointOnFace, u as outerWire, x as isCompSolid, y as downcast } from "./faceFns-iVPbTxki.js";
3
+ import { h as fuseAll, p as cutAll } from "./solidBuilders-DT1gpVWM.js";
4
+ import { C as threePointArc, D as wireLoop, E as wire, S as tangentArc, T as vertex, _ as polygon, a as circle, b as sphere, c as cylinder, d as ellipsoid, f as face, g as offsetFace, h as line, i as bsplineApprox, l as ellipse, m as helix, n as bezier, o as compound, p as filledFace, r as box, s as cone, t as addHoles, u as ellipseArc, v as sewShells, w as torus, x as subFace, y as solid } from "./primitiveFns-DeNl60Rw.js";
5
+ import { a as isSameShape, i as isEqualShape, n as getHashCode } from "./shapeFns-CgqKICF_.js";
6
+ import { a as curveIsPeriodic, c as curvePointAt, d as flipOrientation, f as getCurveType, h as offsetWire2D, i as curveIsClosed, l as curveStartPoint, m as interpolateCurve, n as curveAxis, o as curveLength, p as getOrientation, r as curveEndPoint, s as curvePeriod, t as approximateCurve, u as curveTangentAt } from "./curveFns-BP3srCfK.js";
7
+ import { d as clearMeshCache, f as createMeshCache, n as exportSTEP, r as exportSTL, t as exportIGES } from "./meshFns-DmjMzNbH.js";
8
+ import { A as variableFillet, F as toLineGeometryData, M as toGroupedBufferGeometryData, S as chamferDistAngle, _ as checkBoolean, a as healFace, b as getNurbsCurveData, d as chamferWithEvolution, f as cutWithEvolution, g as shellWithEvolution, h as intersectWithEvolution, j as toBufferGeometryData, l as solidFromShell, m as fuseWithEvolution, n as fixSelfIntersection, o as healSolid, p as filletWithEvolution, r as fixShape, s as healWire, t as autoHeal, u as positionOnCurve, v as cutAllBisect, x as getNurbsSurfaceData, y as fuseAllBisect } from "./healingFns-BhP8zfp1.js";
9
+ import { i as facesOfEdge, l as wiresOfFace, n as adjacentFaces, o as sharedEdges, r as edgesOfFace, s as verticesOfEdge } from "./adjacencyFns--KmBIKYJ.js";
10
10
  export { addHoles, adjacentFaces, approximateCurve, asTopo, autoHeal, bezier, box, bsplineApprox, cast, chamferDistAngle as chamferDistAngleShape, chamferWithEvolution, checkBoolean, circle, classifyPointOnFace, clearMeshCache, compound, cone, createMeshCache, curveAxis, curveEndPoint, curveIsClosed, curveIsPeriodic, curveLength, curvePeriod, curvePointAt, curveStartPoint, curveTangentAt, cutAll, cutAllBisect, cutWithEvolution, cylinder, fromBREP as deserializeShape, downcast, edgesOfFace, ellipse, ellipseArc, ellipsoid, exportIGES, exportSTEP, exportSTL, face, faceAxis, faceCenter, faceGeomType, faceOrientation, facesOfEdge, filledFace, filletWithEvolution, fixSelfIntersection, fixShape, flipFaceOrientation, flipOrientation, fuseAll, fuseAllBisect, fuseWithEvolution, getBounds, getCurveType, getEdges, getFaces, getHashCode, getNurbsCurveData, getNurbsSurfaceData, getOrientation, getSurfaceType, getVertices, getWires, healFace, healSolid, healWire, helix, innerWires, interpolateCurve, intersectWithEvolution, invalidateShapeCache, isCompSolid, isEqualShape, isSameShape, iterEdges, iterFaces, iterTopo, iterVertices, iterWires, line, normalAt, offsetFace, offsetWire2D, outerWire, pointOnSurface, polygon, positionOnCurve, projectPointOnFace, sewShells, shapeType, sharedEdges, shellWithEvolution, solid, solidFromShell, sphere, subFace, tangentArc, threePointArc, toBufferGeometryData, toGroupedBufferGeometryData, toLineGeometryData, torus, uvBounds, uvCoordinates, variableFillet, vertex, vertexPosition, verticesOfEdge, wire, wireLoop, wiresOfFace };
@@ -1,4 +1,4 @@
1
- const require_shapeTypes = require("./shapeTypes-DJT3SnGK.cjs");
1
+ const require_shapeTypes = require("./shapeTypes-Dc7j-MYg.cjs");
2
2
  const require_errors = require("./errors-O_blYTWT.cjs");
3
3
  const require_constants = require("./constants-oee0S_x6.cjs");
4
4
  // src/core/kernelErrorTranslation.ts
@@ -1,4 +1,4 @@
1
- import { G as _usingCtx, N as DisposalScope, O as getOrQueryType, n as castResultShape, q as getKernel, r as castResultShapeWithKnownType } from "./shapeTypes-DAz6aAnJ.js";
1
+ import { G as _usingCtx, N as DisposalScope, O as getOrQueryType, n as castResultShape, q as getKernel, r as castResultShapeWithKnownType } from "./shapeTypes-DwvQUp9M.js";
2
2
  import { E as ok, g as err } from "./errors-BTccWbtE.js";
3
3
  import { n as HASH_CODE_MAX } from "./constants-iraOnb2p.js";
4
4
  // src/core/kernelErrorTranslation.ts
@@ -1,4 +1,4 @@
1
- const require_shapeTypes = require("./shapeTypes-DJT3SnGK.cjs");
1
+ const require_shapeTypes = require("./shapeTypes-Dc7j-MYg.cjs");
2
2
  const require_errors = require("./errors-O_blYTWT.cjs");
3
3
  // src/core/validityTypes.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { q as getKernel } from "./shapeTypes-DAz6aAnJ.js";
1
+ import { q as getKernel } from "./shapeTypes-DwvQUp9M.js";
2
2
  import { E as ok, g as err } from "./errors-BTccWbtE.js";
3
3
  // src/core/validityTypes.ts
4
4
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brepjs",
3
- "version": "20.12.4",
3
+ "version": "20.12.6",
4
4
  "description": "Exact B-Rep CAD in TypeScript on OpenCascade WebAssembly, with a pluggable geometry kernel",
5
5
  "keywords": [
6
6
  "cad",
@@ -223,6 +223,7 @@
223
223
  "prepublishOnly": "npm run build",
224
224
  "prepack": "bash scripts/validate-pack.sh",
225
225
  "typecheck": "tsgo --noEmit",
226
+ "typecheck:tests": "tsgo --noEmit -p tsconfig.typecheck-tests.json",
226
227
  "typecheck:tsc": "tsc --noEmit",
227
228
  "lint": "eslint src/",
228
229
  "lint:fix": "eslint src/ --fix",