brepjs 13.4.0 → 14.1.2

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 (125) hide show
  1. package/dist/2d.cjs +15 -14
  2. package/dist/2d.js +6 -5
  3. package/dist/arrayAccess-CmulMesb.cjs +40 -0
  4. package/dist/arrayAccess-xxcB3YNq.js +23 -0
  5. package/dist/{blueprint-CB_85Lz_.js → blueprint-B3A5x7P9.js} +9 -9
  6. package/dist/{blueprint-CDnBM-tA.cjs → blueprint-D0XChcek.cjs} +13 -13
  7. package/dist/{blueprintFns-DVDommWB.js → blueprintFns-BwAMXY3t.js} +4 -125
  8. package/dist/{blueprintFns-D4YucGaQ.cjs → blueprintFns-COrEYX29.cjs} +3 -142
  9. package/dist/{boolean2D-lqfKJKUY.cjs → boolean2D-BPsyKImE.cjs} +19 -18
  10. package/dist/{boolean2D-Mzp-0g7o.js → boolean2D-D_Te-6N6.js} +12 -11
  11. package/dist/{booleanFns-Bw8sAMgI.cjs → booleanFns-B6M6Lm0V.cjs} +24 -22
  12. package/dist/{booleanFns-B46fgObh.js → booleanFns-CgsaJFBf.js} +8 -6
  13. package/dist/brepjs.cjs +301 -90
  14. package/dist/brepjs.js +189 -26
  15. package/dist/constants-B9u763C3.js +9 -0
  16. package/dist/constants-unWN8k4c.cjs +26 -0
  17. package/dist/core/errors.d.ts +5 -1
  18. package/dist/core/errors.d.ts.map +1 -1
  19. package/dist/core/kernelCall.d.ts.map +1 -1
  20. package/dist/core/kernelErrorTranslation.d.ts +2 -0
  21. package/dist/core/kernelErrorTranslation.d.ts.map +1 -1
  22. package/dist/core.cjs +8 -7
  23. package/dist/core.js +5 -4
  24. package/dist/{cornerFinder-aBLykolI.js → cornerFinder-AEFnAxt4.js} +3 -3
  25. package/dist/{cornerFinder-BszIcLqj.cjs → cornerFinder-DTt_SvtC.cjs} +4 -4
  26. package/dist/{curveFns-DY4dFcP-.js → curveFns-CcInoOEA.js} +2 -2
  27. package/dist/{curveFns-CZszKLQB.cjs → curveFns-DCEcwcpd.cjs} +2 -2
  28. package/dist/{drawFns-BHNDF8hb.cjs → drawFns-BOwBIzPa.cjs} +34 -17
  29. package/dist/{drawFns-l5CY2s-l.js → drawFns-n9qif7QN.js} +16 -14
  30. package/dist/{errors-BlC5ZWv4.cjs → errors-9zQcQK1H.cjs} +28 -0
  31. package/dist/{errors-BVOlxlIA.js → errors-C-cgQA3w.js} +23 -1
  32. package/dist/{extrudeFns-b0uLn4E4.js → extrudeFns-DrDr9-nU.js} +3 -3
  33. package/dist/{extrudeFns-GpCB_Uzs.cjs → extrudeFns-Rcut7h8S.cjs} +3 -3
  34. package/dist/{faceFns-Cat-4X74.js → faceFns-TSH54pPQ.js} +93 -3
  35. package/dist/{faceFns-BywUjlJ7.cjs → faceFns-cE2WxY6I.cjs} +110 -2
  36. package/dist/{helpers-1iCCEElA.cjs → helpers-DZje6XWE.cjs} +18 -17
  37. package/dist/{helpers-DgX1UucG.js → helpers-XrXlKm8D.js} +8 -7
  38. package/dist/{historyFns-BFwp8NLX.js → historyFns-2hCWrX_X.js} +10 -10
  39. package/dist/{historyFns-DqxDtXIZ.cjs → historyFns-BiQ9dmzp.cjs} +10 -10
  40. package/dist/{importFns-ChXEJAvu.cjs → importFns-DGE5nCSW.cjs} +4 -4
  41. package/dist/{importFns-Cb8fcldB.js → importFns-m0xyj0Zt.js} +4 -4
  42. package/dist/index.d.ts +11 -0
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/io.cjs +2 -2
  45. package/dist/io.js +2 -2
  46. package/dist/kernel/brepkit/brepkitAdapter.d.ts +149 -242
  47. package/dist/kernel/brepkit/brepkitAdapter.d.ts.map +1 -1
  48. package/dist/kernel/brepkit/evolutionOps.d.ts +1 -0
  49. package/dist/kernel/brepkit/evolutionOps.d.ts.map +1 -1
  50. package/dist/kernel/index.d.ts +1 -1
  51. package/dist/kernel/index.d.ts.map +1 -1
  52. package/dist/{measureFns-D3rAp1X1.js → measureFns-DHByqdmn.js} +9 -16
  53. package/dist/{measureFns-Bx-kl7_g.cjs → measureFns-D_QKZ5yg.cjs} +9 -16
  54. package/dist/measurement/measureFns.d.ts.map +1 -1
  55. package/dist/measurement.cjs +1 -1
  56. package/dist/measurement.js +1 -1
  57. package/dist/{meshFns-D3KAZ_ma.cjs → meshFns-CVe3Kc77.cjs} +4 -4
  58. package/dist/{meshFns-BPi0bhm9.js → meshFns-DL4Djz3w.js} +3 -3
  59. package/dist/ns/booleans.d.ts +10 -0
  60. package/dist/ns/booleans.d.ts.map +1 -0
  61. package/dist/ns/construction.d.ts +10 -0
  62. package/dist/ns/construction.d.ts.map +1 -0
  63. package/dist/ns/ioNs.d.ts +18 -0
  64. package/dist/ns/ioNs.d.ts.map +1 -0
  65. package/dist/ns/measurement.d.ts +6 -0
  66. package/dist/ns/measurement.d.ts.map +1 -0
  67. package/dist/ns/modifiers.d.ts +6 -0
  68. package/dist/ns/modifiers.d.ts.map +1 -0
  69. package/dist/ns/patterns.d.ts +5 -0
  70. package/dist/ns/patterns.d.ts.map +1 -0
  71. package/dist/ns/primitives.d.ts +7 -0
  72. package/dist/ns/primitives.d.ts.map +1 -0
  73. package/dist/ns/query.d.ts +6 -0
  74. package/dist/ns/query.d.ts.map +1 -0
  75. package/dist/ns/transforms.d.ts +5 -0
  76. package/dist/ns/transforms.d.ts.map +1 -0
  77. package/dist/operations.cjs +2 -2
  78. package/dist/operations.js +2 -2
  79. package/dist/{planeOps-BqLav0Ir.cjs → planeOps-6Wu7dMDN.cjs} +4 -3
  80. package/dist/{planeOps-D88tfyJs.js → planeOps-gTOEarV2.js} +3 -2
  81. package/dist/{primitiveFns-BGh9A9jR.cjs → primitiveFns-CRPGjIFg.cjs} +69 -69
  82. package/dist/{primitiveFns-CnZkW6Bi.js → primitiveFns-CeKiYSSW.js} +7 -7
  83. package/dist/query.cjs +2 -2
  84. package/dist/query.js +2 -2
  85. package/dist/result.cjs +1 -1
  86. package/dist/result.js +1 -1
  87. package/dist/{arrayAccess-B5LgmXBo.js → shapeFns-DCi9O27X.js} +8 -30
  88. package/dist/{arrayAccess-t2dlxGSK.cjs → shapeFns-aEeSHNqX.cjs} +24 -64
  89. package/dist/shapeRef.cjs +8 -0
  90. package/dist/shapeRef.d.ts +5 -0
  91. package/dist/shapeRef.d.ts.map +1 -0
  92. package/dist/shapeRef.js +2 -0
  93. package/dist/shapeRefFns-B1TODUMl.js +194 -0
  94. package/dist/shapeRefFns-CVdS6jWS.cjs +229 -0
  95. package/dist/{shapeTypes-Di6GlhPk.js → shapeTypes-BO1aiDhi.js} +2642 -2546
  96. package/dist/{shapeTypes-8eK48l-X.cjs → shapeTypes-BqWQlrYE.cjs} +2642 -2546
  97. package/dist/sketching.cjs +2 -2
  98. package/dist/sketching.js +2 -2
  99. package/dist/{solidBuilders-D9KYP9sL.cjs → solidBuilders-0iVdiZUw.cjs} +3 -3
  100. package/dist/{solidBuilders-ctO_wFrm.js → solidBuilders-jk7HfWs8.js} +3 -3
  101. package/dist/{surfaceBuilders-CZzipftq.cjs → surfaceBuilders-C_8rs79F.cjs} +3 -3
  102. package/dist/{surfaceBuilders-BaqeZa0x.js → surfaceBuilders-DE5e6bp8.js} +3 -3
  103. package/dist/topology/api.d.ts +3 -3
  104. package/dist/topology/api.d.ts.map +1 -1
  105. package/dist/topology/shapeFns.d.ts +4 -3
  106. package/dist/topology/shapeFns.d.ts.map +1 -1
  107. package/dist/topology/shapeRef/index.d.ts +7 -0
  108. package/dist/topology/shapeRef/index.d.ts.map +1 -0
  109. package/dist/topology/shapeRef/scoring.d.ts +16 -0
  110. package/dist/topology/shapeRef/scoring.d.ts.map +1 -0
  111. package/dist/topology/shapeRef/shapeRefFns.d.ts +47 -0
  112. package/dist/topology/shapeRef/shapeRefFns.d.ts.map +1 -0
  113. package/dist/topology/shapeRef/shapeRefTypes.d.ts +40 -0
  114. package/dist/topology/shapeRef/shapeRefTypes.d.ts.map +1 -0
  115. package/dist/topology.cjs +20 -20
  116. package/dist/topology.js +6 -6
  117. package/dist/{vecOps-DKGelwGL.cjs → vecOps-BXvBYIor.cjs} +0 -26
  118. package/dist/{vecOps-DFfUfsmc.js → vecOps-D9etjPgV.js} +1 -9
  119. package/dist/vectors.cjs +5 -4
  120. package/dist/vectors.js +3 -2
  121. package/dist/worker.cjs +1 -1
  122. package/dist/worker.js +1 -1
  123. package/package.json +14 -4
  124. /package/dist/{workerHandler-nLkvSOKX.cjs → workerHandler-C-7OUJsa.cjs} +0 -0
  125. /package/dist/{workerHandler-BrOTzYRI.js → workerHandler-o2xzAfFk.js} +0 -0
@@ -1,7 +1,7 @@
1
- const require_shapeTypes = require("./shapeTypes-8eK48l-X.cjs");
2
- const require_errors = require("./errors-BlC5ZWv4.cjs");
3
- const require_vecOps = require("./vecOps-DKGelwGL.cjs");
4
- const require_faceFns = require("./faceFns-BywUjlJ7.cjs");
1
+ const require_shapeTypes = require("./shapeTypes-BqWQlrYE.cjs");
2
+ const require_errors = require("./errors-9zQcQK1H.cjs");
3
+ const require_faceFns = require("./faceFns-cE2WxY6I.cjs");
4
+ const require_constants = require("./constants-unWN8k4c.cjs");
5
5
  //#region src/topology/topologyQueryFns.ts
6
6
  /**
7
7
  * Topology query functions — extract sub-shapes, compute bounds, and
@@ -145,7 +145,7 @@ function vertexPosition(vertex) {
145
145
  function setShapeOrigin(shape, origin) {
146
146
  const cache = getOrCreateCache(shape);
147
147
  const map = /* @__PURE__ */ new Map();
148
- for (const f of getFaces(shape)) map.set(require_shapeTypes.getKernel().hashCode(f.wrapped, require_vecOps.HASH_CODE_MAX), origin);
148
+ for (const f of getFaces(shape)) map.set(require_shapeTypes.getKernel().hashCode(f.wrapped, require_constants.HASH_CODE_MAX), origin);
149
149
  cache.faceOrigins = map;
150
150
  }
151
151
  /**
@@ -222,7 +222,7 @@ function propagateOriginsByHash(inputs, result) {
222
222
  const resultMap = /* @__PURE__ */ new Map();
223
223
  const resultFaces = getFaces(result);
224
224
  for (const f of resultFaces) {
225
- const hash = kernel.hashCode(f.wrapped, require_vecOps.HASH_CODE_MAX);
225
+ const hash = kernel.hashCode(f.wrapped, require_constants.HASH_CODE_MAX);
226
226
  const origin = lookup.get(hash);
227
227
  if (origin !== void 0) resultMap.set(hash, origin);
228
228
  }
@@ -233,7 +233,7 @@ function propagateOriginsByHash(inputs, result) {
233
233
  const origins = getFaceOrigins(input);
234
234
  if (!origins) continue;
235
235
  for (const f of getFaces(input)) {
236
- const hash = kernel.hashCode(f.wrapped, require_vecOps.HASH_CODE_MAX);
236
+ const hash = kernel.hashCode(f.wrapped, require_constants.HASH_CODE_MAX);
237
237
  const origin = origins.get(hash);
238
238
  if (origin === void 0) continue;
239
239
  try {
@@ -249,7 +249,7 @@ function propagateOriginsByHash(inputs, result) {
249
249
  }
250
250
  }
251
251
  if (inputSigs.length > 0) for (const f of resultFaces) {
252
- const hash = kernel.hashCode(f.wrapped, require_vecOps.HASH_CODE_MAX);
252
+ const hash = kernel.hashCode(f.wrapped, require_constants.HASH_CODE_MAX);
253
253
  try {
254
254
  const outBounds = kernel.uvBounds(f.wrapped);
255
255
  const bestOrigin = findBestOriginMatch(kernel.surfaceNormal(f.wrapped, .5 * (outBounds.uMin + outBounds.uMax), .5 * (outBounds.vMin + outBounds.vMax)), kernel.surfaceCenterOfMass(f.wrapped), inputSigs);
@@ -299,7 +299,7 @@ function tagFaces(shape, selector, tag) {
299
299
  const faces = Array.isArray(selector) ? selector : getFaces(shape).filter(selector);
300
300
  const tagMap = getTagMap(shape);
301
301
  const existing = tagMap.get(tag) ?? /* @__PURE__ */ new Set();
302
- for (const face of faces) existing.add(require_shapeTypes.getKernel().hashCode(face.wrapped, require_vecOps.HASH_CODE_MAX));
302
+ for (const face of faces) existing.add(require_shapeTypes.getKernel().hashCode(face.wrapped, require_constants.HASH_CODE_MAX));
303
303
  tagMap.set(tag, existing);
304
304
  return shape;
305
305
  }
@@ -316,7 +316,7 @@ function findFacesByTag(shape, tag) {
316
316
  if (!hashes || hashes.size === 0) return [];
317
317
  const result = [];
318
318
  for (const face of getFaces(shape)) {
319
- const hash = require_shapeTypes.getKernel().hashCode(face.wrapped, require_vecOps.HASH_CODE_MAX);
319
+ const hash = require_shapeTypes.getKernel().hashCode(face.wrapped, require_constants.HASH_CODE_MAX);
320
320
  if (hashes.has(hash)) result.push(face);
321
321
  }
322
322
  return result;
@@ -330,7 +330,7 @@ function getFaceTags(shape) {
330
330
  if (!tagMap) return result;
331
331
  const faces = getFaces(shape);
332
332
  const faceByHash = /* @__PURE__ */ new Map();
333
- for (const face of faces) faceByHash.set(require_shapeTypes.getKernel().hashCode(face.wrapped, require_vecOps.HASH_CODE_MAX), face);
333
+ for (const face of faces) faceByHash.set(require_shapeTypes.getKernel().hashCode(face.wrapped, require_constants.HASH_CODE_MAX), face);
334
334
  for (const [tag, hashes] of tagMap) {
335
335
  const taggedFaces = [];
336
336
  for (const hash of hashes) {
@@ -442,7 +442,7 @@ function colorShape(shape, color) {
442
442
  function colorFaces(shape, faces, color) {
443
443
  const parsed = parseColor(color);
444
444
  const map = getFaceColorMap(shape);
445
- for (const face of faces) map.set(require_shapeTypes.getKernel().hashCode(face.wrapped, require_vecOps.HASH_CODE_MAX), parsed);
445
+ for (const face of faces) map.set(require_shapeTypes.getKernel().hashCode(face.wrapped, require_constants.HASH_CODE_MAX), parsed);
446
446
  return shape;
447
447
  }
448
448
  /**
@@ -457,7 +457,7 @@ function getShapeColor(shape) {
457
457
  function getFaceColor(shape, face) {
458
458
  const map = faceColorStore.get(shape.wrapped);
459
459
  if (!map) return void 0;
460
- return map.get(require_shapeTypes.getKernel().hashCode(face.wrapped, require_vecOps.HASH_CODE_MAX));
460
+ return map.get(require_shapeTypes.getKernel().hashCode(face.wrapped, require_constants.HASH_CODE_MAX));
461
461
  }
462
462
  /**
463
463
  * Propagate colors from input shapes to a result shape using a
@@ -497,7 +497,7 @@ function collectInputFaceHashes(inputs) {
497
497
  const hashes = [];
498
498
  for (const input of inputs) {
499
499
  const faces = kernel.iterShapes(input.wrapped, "face");
500
- for (const face of faces) hashes.push(kernel.hashCode(face, require_vecOps.HASH_CODE_MAX));
500
+ for (const face of faces) hashes.push(kernel.hashCode(face, require_constants.HASH_CODE_MAX));
501
501
  }
502
502
  return hashes;
503
503
  }
@@ -536,7 +536,7 @@ function propagateMetadataByHash(inputs, result) {
536
536
  /** Translate a shape by a vector. Returns a new shape. */
537
537
  function translate(shape, v) {
538
538
  const inputFaceHashes = collectInputFaceHashes([shape]);
539
- const { shape: resultShape, evolution } = require_shapeTypes.getKernel().translateWithHistory(shape.wrapped, v[0], v[1], v[2], inputFaceHashes, require_vecOps.HASH_CODE_MAX);
539
+ const { shape: resultShape, evolution } = require_shapeTypes.getKernel().translateWithHistory(shape.wrapped, v[0], v[1], v[2], inputFaceHashes, require_constants.HASH_CODE_MAX);
540
540
  const result = require_shapeTypes.castShape(resultShape);
541
541
  propagateAllMetadata(evolution, [shape], result);
542
542
  return result;
@@ -552,7 +552,7 @@ function rotate(shape, angle, position = [
552
552
  1
553
553
  ]) {
554
554
  const inputFaceHashes = collectInputFaceHashes([shape]);
555
- const { shape: resultShape, evolution } = require_shapeTypes.getKernel().rotateWithHistory(shape.wrapped, angle * require_vecOps.DEG2RAD, inputFaceHashes, require_vecOps.HASH_CODE_MAX, direction, position);
555
+ const { shape: resultShape, evolution } = require_shapeTypes.getKernel().rotateWithHistory(shape.wrapped, angle * require_constants.DEG2RAD, inputFaceHashes, require_constants.HASH_CODE_MAX, direction, position);
556
556
  const result = require_shapeTypes.castShape(resultShape);
557
557
  propagateAllMetadata(evolution, [shape], result);
558
558
  return result;
@@ -568,7 +568,7 @@ function mirror(shape, planeNormal = [
568
568
  0
569
569
  ]) {
570
570
  const inputFaceHashes = collectInputFaceHashes([shape]);
571
- const { shape: resultShape, evolution } = require_shapeTypes.getKernel().mirrorWithHistory(shape.wrapped, planeOrigin, planeNormal, inputFaceHashes, require_vecOps.HASH_CODE_MAX);
571
+ const { shape: resultShape, evolution } = require_shapeTypes.getKernel().mirrorWithHistory(shape.wrapped, planeOrigin, planeNormal, inputFaceHashes, require_constants.HASH_CODE_MAX);
572
572
  const result = require_shapeTypes.castShape(resultShape);
573
573
  propagateAllMetadata(evolution, [shape], result);
574
574
  return result;
@@ -580,7 +580,7 @@ function scale(shape, factor, center = [
580
580
  0
581
581
  ]) {
582
582
  const inputFaceHashes = collectInputFaceHashes([shape]);
583
- const { shape: resultShape, evolution } = require_shapeTypes.getKernel().scaleWithHistory(shape.wrapped, center, factor, inputFaceHashes, require_vecOps.HASH_CODE_MAX);
583
+ const { shape: resultShape, evolution } = require_shapeTypes.getKernel().scaleWithHistory(shape.wrapped, center, factor, inputFaceHashes, require_constants.HASH_CODE_MAX);
584
584
  const result = require_shapeTypes.castShape(resultShape);
585
585
  propagateAllMetadata(evolution, [shape], result);
586
586
  return result;
@@ -682,7 +682,7 @@ function applyMatrix(shape, matrix) {
682
682
  if (Math.abs(d) < 1e-12) return require_errors.err(require_errors.validationError(require_errors.BrepErrorCode.VALIDATION_FAILED, "applyMatrix: singular matrix (determinant ≈ 0). Cannot apply a non-invertible transform."));
683
683
  if (isOrthogonalMatrix(linear)) {
684
684
  const inputFaceHashes = collectInputFaceHashes([shape]);
685
- const { shape: resultShape, evolution } = require_shapeTypes.getKernel().generalTransformWithHistory(shape.wrapped, linear, translation, true, inputFaceHashes, require_vecOps.HASH_CODE_MAX);
685
+ const { shape: resultShape, evolution } = require_shapeTypes.getKernel().generalTransformWithHistory(shape.wrapped, linear, translation, true, inputFaceHashes, require_constants.HASH_CODE_MAX);
686
686
  const result = require_shapeTypes.castShape(resultShape);
687
687
  propagateAllMetadata(evolution, [shape], result);
688
688
  return require_errors.ok(result);
@@ -724,7 +724,7 @@ function composeTransforms(ops) {
724
724
  */
725
725
  function transformCopy(shape, composed) {
726
726
  const inputFaceHashes = collectInputFaceHashes([shape]);
727
- const { shape: resultShape, evolution } = require_shapeTypes.getKernel().applyComposedTransformWithHistory(shape.wrapped, composed.trsf, inputFaceHashes, require_vecOps.HASH_CODE_MAX);
727
+ const { shape: resultShape, evolution } = require_shapeTypes.getKernel().applyComposedTransformWithHistory(shape.wrapped, composed.trsf, inputFaceHashes, require_constants.HASH_CODE_MAX);
728
728
  const result = require_shapeTypes.castShape(resultShape);
729
729
  propagateAllMetadata(evolution, [shape], result);
730
730
  return result;
@@ -741,15 +741,15 @@ function transformCopy(shape, composed) {
741
741
  */
742
742
  /** Clone a shape (deep copy via kernel topology downcast). */
743
743
  function clone(shape) {
744
- return require_shapeTypes.castShape(require_errors.unwrap(require_faceFns.downcast(shape.wrapped)));
744
+ return require_faceFns.kernelCall(() => require_shapeTypes.getKernel().downcast(shape.wrapped), require_errors.BrepErrorCode.CLONE_FAILED, "Failed to clone shape");
745
745
  }
746
746
  /** Serialize a shape to BREP string format. */
747
747
  function toBREP(shape) {
748
- return require_shapeTypes.getKernel().toBREP(shape.wrapped);
748
+ return require_faceFns.kernelCallRaw(() => require_shapeTypes.getKernel().toBREP(shape.wrapped), require_errors.BrepErrorCode.TO_BREP_FAILED, "Failed to serialize shape to BREP");
749
749
  }
750
750
  /** Get the topology hash code of a shape. */
751
751
  function getHashCode(shape) {
752
- return require_shapeTypes.getKernel().hashCode(shape.wrapped, require_vecOps.HASH_CODE_MAX);
752
+ return require_shapeTypes.getKernel().hashCode(shape.wrapped, require_constants.HASH_CODE_MAX);
753
753
  }
754
754
  /** Check if a shape is null. */
755
755
  function isEmpty(shape) {
@@ -765,29 +765,7 @@ function isEqualShape(a, b) {
765
765
  }
766
766
  /** Simplify a shape by merging same-domain faces/edges. Returns a new shape. */
767
767
  function simplify(shape) {
768
- return require_shapeTypes.castShape(require_shapeTypes.getKernel().simplify(shape.wrapped));
769
- }
770
- //#endregion
771
- //#region src/utils/arrayAccess.ts
772
- /**
773
- * Safe array access utilities.
774
- * Replaces `arr[i]!` patterns where TypeScript's `noUncheckedIndexedAccess` requires
775
- * a non-null assertion but bounds are proven by surrounding code.
776
- */
777
- /** Access element by index, throwing if out of bounds. Use when bounds are logically guaranteed. */
778
- function getAtOrThrow(arr, index, msg) {
779
- if (index < 0 || index >= arr.length) throw new Error(msg ?? `Index ${index} out of bounds (length ${arr.length})`);
780
- return arr[index];
781
- }
782
- /** Get the first element of a non-empty array, throwing if empty. */
783
- function firstOrThrow(arr, msg) {
784
- if (arr.length === 0) throw new Error(msg ?? "Expected non-empty array");
785
- return arr[0];
786
- }
787
- /** Get the last element of a non-empty array, throwing if empty. */
788
- function lastOrThrow(arr, msg) {
789
- if (arr.length === 0) throw new Error(msg ?? "Expected non-empty array");
790
- return arr[arr.length - 1];
768
+ return require_faceFns.kernelCall(() => require_shapeTypes.getKernel().simplify(shape.wrapped), require_errors.BrepErrorCode.SIMPLIFY_FAILED, "Failed to simplify shape");
791
769
  }
792
770
  //#endregion
793
771
  Object.defineProperty(exports, "applyMatrix", {
@@ -838,18 +816,6 @@ Object.defineProperty(exports, "findFacesByTag", {
838
816
  return findFacesByTag;
839
817
  }
840
818
  });
841
- Object.defineProperty(exports, "firstOrThrow", {
842
- enumerable: true,
843
- get: function() {
844
- return firstOrThrow;
845
- }
846
- });
847
- Object.defineProperty(exports, "getAtOrThrow", {
848
- enumerable: true,
849
- get: function() {
850
- return getAtOrThrow;
851
- }
852
- });
853
819
  Object.defineProperty(exports, "getBounds", {
854
820
  enumerable: true,
855
821
  get: function() {
@@ -970,12 +936,6 @@ Object.defineProperty(exports, "iterWires", {
970
936
  return iterWires;
971
937
  }
972
938
  });
973
- Object.defineProperty(exports, "lastOrThrow", {
974
- enumerable: true,
975
- get: function() {
976
- return lastOrThrow;
977
- }
978
- });
979
939
  Object.defineProperty(exports, "mirror", {
980
940
  enumerable: true,
981
941
  get: function() {
@@ -0,0 +1,8 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_shapeRefFns = require("./shapeRefFns-CVdS6jWS.cjs");
3
+ exports.assignRoles = require_shapeRefFns.assignRoles;
4
+ exports.captureHint = require_shapeRefFns.captureHint;
5
+ exports.createRef = require_shapeRefFns.createRef;
6
+ exports.defaultScorer = require_shapeRefFns.defaultScorer;
7
+ exports.resolveRef = require_shapeRefFns.resolveRef;
8
+ exports.updateRoles = require_shapeRefFns.updateRoles;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * brepjs/shapeRef — Stable face references for parametric replay.
3
+ */
4
+ export { type GeometricHint, type ShapeRef, type RoleTable, type ResolvedRef, type BrokenRef, type FaceScorer, defaultScorer, captureHint, assignRoles, createRef, updateRoles, resolveRef, } from './topology/shapeRef/index.js';
5
+ //# sourceMappingURL=shapeRef.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shapeRef.d.ts","sourceRoot":"","sources":["../src/shapeRef.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,UAAU,EACf,aAAa,EACb,WAAW,EACX,WAAW,EACX,SAAS,EACT,WAAW,EACX,UAAU,GACX,MAAM,8BAA8B,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { a as updateRoles, i as resolveRef, n as captureHint, o as defaultScorer, r as createRef, t as assignRoles } from "./shapeRefFns-B1TODUMl.js";
2
+ export { assignRoles, captureHint, createRef, defaultScorer, resolveRef, updateRoles };
@@ -0,0 +1,194 @@
1
+ import { c as normalAt, n as faceCenter, r as faceGeomType } from "./faceFns-TSH54pPQ.js";
2
+ import { N as getFaces, n as getHashCode } from "./shapeFns-DCi9O27X.js";
3
+ import { n as measureArea } from "./measureFns-DHByqdmn.js";
4
+ //#region src/topology/shapeRef/scoring.ts
5
+ /**
6
+ * Default face scorer combining surface type, normal alignment, centroid proximity,
7
+ * and area similarity.
8
+ *
9
+ * Scoring breakdown:
10
+ * - Surface type match: +1.0 (mismatch when both defined: -Infinity)
11
+ * - Normal dot product: weighted contribution (rejected if < 0.707)
12
+ * - Centroid distance: quadratic penalty (rejected if distSq > 100)
13
+ * - Area ratio: penalized if |log(hintArea / faceArea)| > 1.0
14
+ */
15
+ function defaultScorer(hint, face) {
16
+ let score = 0;
17
+ const faceType = faceGeomType(face);
18
+ if (hint.surfaceType !== void 0) if (faceType === hint.surfaceType) score += 1;
19
+ else return -Infinity;
20
+ if (hint.normal !== void 0) {
21
+ const faceNormal = normalAt(face);
22
+ const dot = hint.normal[0] * faceNormal[0] + hint.normal[1] * faceNormal[1] + hint.normal[2] * faceNormal[2];
23
+ if (dot < .707) return -Infinity;
24
+ score += dot;
25
+ }
26
+ if (hint.centroid !== void 0) {
27
+ const faceCentroid = faceCenter(face);
28
+ const dx = hint.centroid[0] - faceCentroid[0];
29
+ const dy = hint.centroid[1] - faceCentroid[1];
30
+ const dz = hint.centroid[2] - faceCentroid[2];
31
+ const distSq = dx * dx + dy * dy + dz * dz;
32
+ if (distSq > 100) return -Infinity;
33
+ score -= distSq / 100;
34
+ }
35
+ if (hint.area !== void 0 && hint.area > 0) {
36
+ const areaResult = measureArea(face);
37
+ if (areaResult.ok && areaResult.value > 0) {
38
+ const logRatio = Math.abs(Math.log(hint.area / areaResult.value));
39
+ if (logRatio > 1) score -= logRatio;
40
+ }
41
+ }
42
+ return score;
43
+ }
44
+ //#endregion
45
+ //#region src/topology/shapeRef/shapeRefFns.ts
46
+ /** Snapshot the geometric properties of a face for later matching. */
47
+ function captureHint(face) {
48
+ const surfaceType = faceGeomType(face);
49
+ const normal = normalAt(face);
50
+ const centroid = faceCenter(face);
51
+ const areaResult = measureArea(face);
52
+ return {
53
+ entityType: "face",
54
+ surfaceType,
55
+ normal,
56
+ centroid,
57
+ area: areaResult.ok ? areaResult.value : void 0
58
+ };
59
+ }
60
+ /** Threshold for dominant-axis detection (abs(component) > 0.9). */
61
+ var AXIS_THRESHOLD = .9;
62
+ /** Determine the cardinal role name for a box face from its outward normal. */
63
+ function boxRoleFromNormal(n) {
64
+ if (n[2] > AXIS_THRESHOLD) return "box:top";
65
+ if (n[2] < -AXIS_THRESHOLD) return "box:bottom";
66
+ if (n[1] > AXIS_THRESHOLD) return "box:back";
67
+ if (n[1] < -AXIS_THRESHOLD) return "box:front";
68
+ if (n[0] > AXIS_THRESHOLD) return "box:right";
69
+ if (n[0] < -AXIS_THRESHOLD) return "box:left";
70
+ }
71
+ /**
72
+ * Auto-assign role names to the faces of a shape based on operation type.
73
+ *
74
+ * For 'box': uses face normals to assign cardinal names
75
+ * ('box:top', 'box:bottom', 'box:front', 'box:back', 'box:left', 'box:right').
76
+ * **Note:** Box role detection assumes axis-aligned faces (normal within 0.9 of
77
+ * a cardinal axis). Rotated boxes may receive fewer than 6 named roles; remaining
78
+ * faces fall through to sequential naming.
79
+ *
80
+ * For other types: sequential naming ('opType:face_0', 'opType:face_1', ...).
81
+ *
82
+ * @returns Map from role name to face hash code
83
+ */
84
+ function assignRoles(shape, operationType) {
85
+ const faces = getFaces(shape);
86
+ const roles = /* @__PURE__ */ new Map();
87
+ if (operationType === "box") {
88
+ for (const face of faces) {
89
+ const role = boxRoleFromNormal(normalAt(face));
90
+ if (role !== void 0 && !roles.has(role)) roles.set(role, getHashCode(face));
91
+ }
92
+ return roles;
93
+ }
94
+ let index = 0;
95
+ for (const face of faces) {
96
+ roles.set(`${operationType}:face_${index}`, getHashCode(face));
97
+ index++;
98
+ }
99
+ return roles;
100
+ }
101
+ /** Create a ShapeRef from an origin ID, role name, and face. */
102
+ function createRef(origin, role, face) {
103
+ return {
104
+ origin,
105
+ role,
106
+ hint: captureHint(face)
107
+ };
108
+ }
109
+ /**
110
+ * Propagate a role table through a ShapeEvolution record.
111
+ * Returns a new RoleTable with hashes updated according to the evolution.
112
+ *
113
+ * - Deleted faces: role removed
114
+ * - Modified faces: hash updated to first result hash
115
+ * - Unchanged faces: hash preserved
116
+ *
117
+ * **Limitation:** When a face splits (1→many in `evolution.modified`), only the
118
+ * first successor hash is tracked. The geometric fallback in `resolveRef` handles
119
+ * cases where this picks the "wrong" successor. A future version may return
120
+ * multi-hash mappings for split-aware resolution.
121
+ */
122
+ function updateRoles(roles, origin, evolution) {
123
+ const originRoles = roles.get(origin);
124
+ if (!originRoles) return roles;
125
+ const updatedOriginRoles = /* @__PURE__ */ new Map();
126
+ for (const [role, hash] of originRoles) {
127
+ if (evolution.deleted.has(hash)) continue;
128
+ const modifiedHashes = evolution.modified.get(hash);
129
+ if (modifiedHashes && modifiedHashes.length > 0) updatedOriginRoles.set(role, modifiedHashes[0]);
130
+ else updatedOriginRoles.set(role, hash);
131
+ }
132
+ const newRoles = /* @__PURE__ */ new Map();
133
+ for (const [key, value] of roles) if (key === origin) newRoles.set(key, updatedOriginRoles);
134
+ else newRoles.set(key, value);
135
+ return newRoles;
136
+ }
137
+ /** Ambiguity threshold: if two scores are within this range, it's ambiguous. */
138
+ var AMBIGUITY_THRESHOLD = .1;
139
+ /** Minimum score for geometric fallback to accept a match. */
140
+ var MIN_SCORE = .5;
141
+ /**
142
+ * Resolve a ShapeRef to a face in the current shape.
143
+ *
144
+ * Resolution strategy:
145
+ * 1. Exact lookup via role table hash match
146
+ * 2. Geometric fallback using scorer against all faces
147
+ * 3. Ambiguous if multiple faces score within threshold
148
+ * 4. Not-found if no match above minimum score
149
+ */
150
+ function resolveRef(ref, roles, currentShape, scorer) {
151
+ const faces = getFaces(currentShape);
152
+ const scoreFn = scorer ?? defaultScorer;
153
+ const targetHash = roles.get(ref.origin)?.get(ref.role);
154
+ if (targetHash !== void 0) {
155
+ for (const face of faces) if (getHashCode(face) === targetHash) return {
156
+ face,
157
+ confidence: "exact"
158
+ };
159
+ return {
160
+ ref,
161
+ reason: "deleted"
162
+ };
163
+ }
164
+ let bestScore = -Infinity;
165
+ let bestFace;
166
+ let secondBestScore = -Infinity;
167
+ const scored = [];
168
+ for (const face of faces) {
169
+ const score = scoreFn(ref.hint, face);
170
+ if (score > MIN_SCORE) scored.push([face, score]);
171
+ if (score > bestScore) {
172
+ secondBestScore = bestScore;
173
+ bestScore = score;
174
+ bestFace = face;
175
+ } else if (score > secondBestScore) secondBestScore = score;
176
+ }
177
+ if (bestFace !== void 0 && bestScore > MIN_SCORE) {
178
+ if (bestScore - secondBestScore < AMBIGUITY_THRESHOLD && scored.length > 1) return {
179
+ ref,
180
+ reason: "ambiguous",
181
+ candidates: scored.filter(([, s]) => s >= bestScore - AMBIGUITY_THRESHOLD).map(([f]) => f)
182
+ };
183
+ return {
184
+ face: bestFace,
185
+ confidence: "geometric-fallback"
186
+ };
187
+ }
188
+ return {
189
+ ref,
190
+ reason: "not-found"
191
+ };
192
+ }
193
+ //#endregion
194
+ export { updateRoles as a, resolveRef as i, captureHint as n, defaultScorer as o, createRef as r, assignRoles as t };
@@ -0,0 +1,229 @@
1
+ const require_faceFns = require("./faceFns-cE2WxY6I.cjs");
2
+ const require_shapeFns = require("./shapeFns-aEeSHNqX.cjs");
3
+ const require_measureFns = require("./measureFns-D_QKZ5yg.cjs");
4
+ //#region src/topology/shapeRef/scoring.ts
5
+ /**
6
+ * Default face scorer combining surface type, normal alignment, centroid proximity,
7
+ * and area similarity.
8
+ *
9
+ * Scoring breakdown:
10
+ * - Surface type match: +1.0 (mismatch when both defined: -Infinity)
11
+ * - Normal dot product: weighted contribution (rejected if < 0.707)
12
+ * - Centroid distance: quadratic penalty (rejected if distSq > 100)
13
+ * - Area ratio: penalized if |log(hintArea / faceArea)| > 1.0
14
+ */
15
+ function defaultScorer(hint, face) {
16
+ let score = 0;
17
+ const faceType = require_faceFns.faceGeomType(face);
18
+ if (hint.surfaceType !== void 0) if (faceType === hint.surfaceType) score += 1;
19
+ else return -Infinity;
20
+ if (hint.normal !== void 0) {
21
+ const faceNormal = require_faceFns.normalAt(face);
22
+ const dot = hint.normal[0] * faceNormal[0] + hint.normal[1] * faceNormal[1] + hint.normal[2] * faceNormal[2];
23
+ if (dot < .707) return -Infinity;
24
+ score += dot;
25
+ }
26
+ if (hint.centroid !== void 0) {
27
+ const faceCentroid = require_faceFns.faceCenter(face);
28
+ const dx = hint.centroid[0] - faceCentroid[0];
29
+ const dy = hint.centroid[1] - faceCentroid[1];
30
+ const dz = hint.centroid[2] - faceCentroid[2];
31
+ const distSq = dx * dx + dy * dy + dz * dz;
32
+ if (distSq > 100) return -Infinity;
33
+ score -= distSq / 100;
34
+ }
35
+ if (hint.area !== void 0 && hint.area > 0) {
36
+ const areaResult = require_measureFns.measureArea(face);
37
+ if (areaResult.ok && areaResult.value > 0) {
38
+ const logRatio = Math.abs(Math.log(hint.area / areaResult.value));
39
+ if (logRatio > 1) score -= logRatio;
40
+ }
41
+ }
42
+ return score;
43
+ }
44
+ //#endregion
45
+ //#region src/topology/shapeRef/shapeRefFns.ts
46
+ /** Snapshot the geometric properties of a face for later matching. */
47
+ function captureHint(face) {
48
+ const surfaceType = require_faceFns.faceGeomType(face);
49
+ const normal = require_faceFns.normalAt(face);
50
+ const centroid = require_faceFns.faceCenter(face);
51
+ const areaResult = require_measureFns.measureArea(face);
52
+ return {
53
+ entityType: "face",
54
+ surfaceType,
55
+ normal,
56
+ centroid,
57
+ area: areaResult.ok ? areaResult.value : void 0
58
+ };
59
+ }
60
+ /** Threshold for dominant-axis detection (abs(component) > 0.9). */
61
+ var AXIS_THRESHOLD = .9;
62
+ /** Determine the cardinal role name for a box face from its outward normal. */
63
+ function boxRoleFromNormal(n) {
64
+ if (n[2] > AXIS_THRESHOLD) return "box:top";
65
+ if (n[2] < -AXIS_THRESHOLD) return "box:bottom";
66
+ if (n[1] > AXIS_THRESHOLD) return "box:back";
67
+ if (n[1] < -AXIS_THRESHOLD) return "box:front";
68
+ if (n[0] > AXIS_THRESHOLD) return "box:right";
69
+ if (n[0] < -AXIS_THRESHOLD) return "box:left";
70
+ }
71
+ /**
72
+ * Auto-assign role names to the faces of a shape based on operation type.
73
+ *
74
+ * For 'box': uses face normals to assign cardinal names
75
+ * ('box:top', 'box:bottom', 'box:front', 'box:back', 'box:left', 'box:right').
76
+ * **Note:** Box role detection assumes axis-aligned faces (normal within 0.9 of
77
+ * a cardinal axis). Rotated boxes may receive fewer than 6 named roles; remaining
78
+ * faces fall through to sequential naming.
79
+ *
80
+ * For other types: sequential naming ('opType:face_0', 'opType:face_1', ...).
81
+ *
82
+ * @returns Map from role name to face hash code
83
+ */
84
+ function assignRoles(shape, operationType) {
85
+ const faces = require_shapeFns.getFaces(shape);
86
+ const roles = /* @__PURE__ */ new Map();
87
+ if (operationType === "box") {
88
+ for (const face of faces) {
89
+ const role = boxRoleFromNormal(require_faceFns.normalAt(face));
90
+ if (role !== void 0 && !roles.has(role)) roles.set(role, require_shapeFns.getHashCode(face));
91
+ }
92
+ return roles;
93
+ }
94
+ let index = 0;
95
+ for (const face of faces) {
96
+ roles.set(`${operationType}:face_${index}`, require_shapeFns.getHashCode(face));
97
+ index++;
98
+ }
99
+ return roles;
100
+ }
101
+ /** Create a ShapeRef from an origin ID, role name, and face. */
102
+ function createRef(origin, role, face) {
103
+ return {
104
+ origin,
105
+ role,
106
+ hint: captureHint(face)
107
+ };
108
+ }
109
+ /**
110
+ * Propagate a role table through a ShapeEvolution record.
111
+ * Returns a new RoleTable with hashes updated according to the evolution.
112
+ *
113
+ * - Deleted faces: role removed
114
+ * - Modified faces: hash updated to first result hash
115
+ * - Unchanged faces: hash preserved
116
+ *
117
+ * **Limitation:** When a face splits (1→many in `evolution.modified`), only the
118
+ * first successor hash is tracked. The geometric fallback in `resolveRef` handles
119
+ * cases where this picks the "wrong" successor. A future version may return
120
+ * multi-hash mappings for split-aware resolution.
121
+ */
122
+ function updateRoles(roles, origin, evolution) {
123
+ const originRoles = roles.get(origin);
124
+ if (!originRoles) return roles;
125
+ const updatedOriginRoles = /* @__PURE__ */ new Map();
126
+ for (const [role, hash] of originRoles) {
127
+ if (evolution.deleted.has(hash)) continue;
128
+ const modifiedHashes = evolution.modified.get(hash);
129
+ if (modifiedHashes && modifiedHashes.length > 0) updatedOriginRoles.set(role, modifiedHashes[0]);
130
+ else updatedOriginRoles.set(role, hash);
131
+ }
132
+ const newRoles = /* @__PURE__ */ new Map();
133
+ for (const [key, value] of roles) if (key === origin) newRoles.set(key, updatedOriginRoles);
134
+ else newRoles.set(key, value);
135
+ return newRoles;
136
+ }
137
+ /** Ambiguity threshold: if two scores are within this range, it's ambiguous. */
138
+ var AMBIGUITY_THRESHOLD = .1;
139
+ /** Minimum score for geometric fallback to accept a match. */
140
+ var MIN_SCORE = .5;
141
+ /**
142
+ * Resolve a ShapeRef to a face in the current shape.
143
+ *
144
+ * Resolution strategy:
145
+ * 1. Exact lookup via role table hash match
146
+ * 2. Geometric fallback using scorer against all faces
147
+ * 3. Ambiguous if multiple faces score within threshold
148
+ * 4. Not-found if no match above minimum score
149
+ */
150
+ function resolveRef(ref, roles, currentShape, scorer) {
151
+ const faces = require_shapeFns.getFaces(currentShape);
152
+ const scoreFn = scorer ?? defaultScorer;
153
+ const targetHash = roles.get(ref.origin)?.get(ref.role);
154
+ if (targetHash !== void 0) {
155
+ for (const face of faces) if (require_shapeFns.getHashCode(face) === targetHash) return {
156
+ face,
157
+ confidence: "exact"
158
+ };
159
+ return {
160
+ ref,
161
+ reason: "deleted"
162
+ };
163
+ }
164
+ let bestScore = -Infinity;
165
+ let bestFace;
166
+ let secondBestScore = -Infinity;
167
+ const scored = [];
168
+ for (const face of faces) {
169
+ const score = scoreFn(ref.hint, face);
170
+ if (score > MIN_SCORE) scored.push([face, score]);
171
+ if (score > bestScore) {
172
+ secondBestScore = bestScore;
173
+ bestScore = score;
174
+ bestFace = face;
175
+ } else if (score > secondBestScore) secondBestScore = score;
176
+ }
177
+ if (bestFace !== void 0 && bestScore > MIN_SCORE) {
178
+ if (bestScore - secondBestScore < AMBIGUITY_THRESHOLD && scored.length > 1) return {
179
+ ref,
180
+ reason: "ambiguous",
181
+ candidates: scored.filter(([, s]) => s >= bestScore - AMBIGUITY_THRESHOLD).map(([f]) => f)
182
+ };
183
+ return {
184
+ face: bestFace,
185
+ confidence: "geometric-fallback"
186
+ };
187
+ }
188
+ return {
189
+ ref,
190
+ reason: "not-found"
191
+ };
192
+ }
193
+ //#endregion
194
+ Object.defineProperty(exports, "assignRoles", {
195
+ enumerable: true,
196
+ get: function() {
197
+ return assignRoles;
198
+ }
199
+ });
200
+ Object.defineProperty(exports, "captureHint", {
201
+ enumerable: true,
202
+ get: function() {
203
+ return captureHint;
204
+ }
205
+ });
206
+ Object.defineProperty(exports, "createRef", {
207
+ enumerable: true,
208
+ get: function() {
209
+ return createRef;
210
+ }
211
+ });
212
+ Object.defineProperty(exports, "defaultScorer", {
213
+ enumerable: true,
214
+ get: function() {
215
+ return defaultScorer;
216
+ }
217
+ });
218
+ Object.defineProperty(exports, "resolveRef", {
219
+ enumerable: true,
220
+ get: function() {
221
+ return resolveRef;
222
+ }
223
+ });
224
+ Object.defineProperty(exports, "updateRoles", {
225
+ enumerable: true,
226
+ get: function() {
227
+ return updateRoles;
228
+ }
229
+ });