brepjs 20.13.5 → 20.13.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 (93) hide show
  1. package/dist/2d.cjs +6 -6
  2. package/dist/2d.js +6 -6
  3. package/dist/{adjacencyFns-B1ZWTkxw.cjs → adjacencyFns-BLtq-nUN.cjs} +3 -3
  4. package/dist/{adjacencyFns-XdjXKCXE.js → adjacencyFns-C1Hxy0tk.js} +3 -3
  5. package/dist/{blueprint-WAucCqwY.js → blueprint-BzI6waZa.js} +5 -5
  6. package/dist/{blueprint-DzhzGFy2.cjs → blueprint-DlpFhHbU.cjs} +5 -5
  7. package/dist/{blueprintFns-DnzHyTjv.cjs → blueprintFns-Cc9OyvKE.cjs} +2 -2
  8. package/dist/{blueprintFns-C8gt4OYm.js → blueprintFns-HFd0lu9A.js} +2 -2
  9. package/dist/{blueprintSketcher-CeMrC8k-.js → blueprintSketcher-BrQee61I.js} +3 -3
  10. package/dist/{blueprintSketcher-JoLn4vSB.cjs → blueprintSketcher-DUT3-Cuo.cjs} +3 -3
  11. package/dist/{boolean2D-Cwc_4mU8.cjs → boolean2D-BC0TwxyB.cjs} +4 -4
  12. package/dist/{boolean2D-D8_6vKh_.js → boolean2D-CvBeghsg.js} +4 -4
  13. package/dist/{booleanFns-aGRfk4ud.js → booleanFns-Dtg2jqzi.js} +5 -5
  14. package/dist/{booleanFns-BhW5eybV.cjs → booleanFns-Dti1CK1F.cjs} +5 -5
  15. package/dist/brepjs.cjs +30 -30
  16. package/dist/brepjs.js +30 -30
  17. package/dist/{cameraFns-DhgM5-Nl.cjs → cameraFns--Ab792oE.cjs} +3 -3
  18. package/dist/{cameraFns-CBc6tpRl.js → cameraFns-CXONX5Da.js} +3 -3
  19. package/dist/core.cjs +2 -2
  20. package/dist/core.js +2 -2
  21. package/dist/{cornerFinder-ChkO3EOO.js → cornerFinder-C7f43oKE.js} +1 -1
  22. package/dist/{cornerFinder-xI6O0ZCv.cjs → cornerFinder-DUzrQsfW.cjs} +1 -1
  23. package/dist/{curveFns-Cnh0Hljx.js → curveFns-Dzgl3_MC.js} +1 -1
  24. package/dist/{curveFns-Dz36SOE6.cjs → curveFns-QaNfJzko.cjs} +1 -1
  25. package/dist/{drawFns-BrRyiHKp.cjs → drawFns-BRXk9fLg.cjs} +12 -12
  26. package/dist/{drawFns-RuUOUlSC.js → drawFns-WvF0fehK.js} +12 -12
  27. package/dist/{faceFns-Dz3eRgNR.js → faceFns-BG1CBQUM.js} +2 -2
  28. package/dist/{faceFns-DfEUZlnf.cjs → faceFns-dj_c8LVc.cjs} +2 -2
  29. package/dist/{healingFns-D7LTrPO8.cjs → healingFns-BSNNLyXP.cjs} +12 -14
  30. package/dist/{healingFns-CCRPtrvE.js → healingFns-CfkUEqcL.js} +12 -14
  31. package/dist/{helpers-C0MoldOO.cjs → helpers-6Emek9dE.cjs} +6 -6
  32. package/dist/{helpers-D3oo0Zfs.js → helpers-DolHn2_s.js} +6 -6
  33. package/dist/{importFns-Sp5phi5Y.cjs → importFns-CZb21dj7.cjs} +5 -5
  34. package/dist/{importFns-BVcmm3T0.js → importFns-D1AxkVC3.js} +5 -5
  35. package/dist/io.cjs +2 -2
  36. package/dist/io.js +2 -2
  37. package/dist/kernel/brepkit/brepkitWasmTypes.d.ts +4 -8
  38. package/dist/kernel/brepkit/constructionOps.d.ts +1 -1
  39. package/dist/kernel/brepkit/modifierOps.d.ts +3 -3
  40. package/dist/kernel/occtWasm/occtWasmAdapter.cjs +1 -1
  41. package/dist/kernel/occtWasm/occtWasmAdapter.js +1 -1
  42. package/dist/{loftFns-BoGWrMPg.cjs → loftFns-BD0na-M4.cjs} +4 -4
  43. package/dist/{loftFns-oH6dldzO.js → loftFns-Cua-MamP.js} +4 -4
  44. package/dist/{measureFns-CmKNZ0gC.cjs → measureFns-FrNeGmXh.cjs} +4 -4
  45. package/dist/{measureFns-6mHYvqUc.js → measureFns-WGYWWnQ1.js} +4 -4
  46. package/dist/measurement.cjs +2 -2
  47. package/dist/measurement.js +2 -2
  48. package/dist/{meshFns-BFgQZGty.cjs → meshFns-Dy1a9wl_.cjs} +4 -4
  49. package/dist/{meshFns-D29JHTr6.js → meshFns-Lie8oAac.js} +4 -4
  50. package/dist/{occtWasmAdapter-4YnvqZOW.cjs → occtWasmAdapter-B9ZXx36v.cjs} +1 -1
  51. package/dist/{occtWasmAdapter-CGsnjMOe.js → occtWasmAdapter-CGkZIHyM.js} +1 -1
  52. package/dist/operations/sweepFns.d.ts +3 -3
  53. package/dist/operations.cjs +2 -2
  54. package/dist/operations.js +2 -2
  55. package/dist/{primitiveFns-Dovused4.cjs → primitiveFns-Dpn3ZtUE.cjs} +5 -5
  56. package/dist/{primitiveFns-uywjJ06V.js → primitiveFns-w-ST-RDJ.js} +5 -5
  57. package/dist/{principalBoxFns-KvlaTxMs.cjs → principalBoxFns-3ZURcOFP.cjs} +3 -3
  58. package/dist/{principalBoxFns-CTVc4f8W.js → principalBoxFns-CjfJnZfH.js} +3 -3
  59. package/dist/projection.cjs +1 -1
  60. package/dist/projection.js +1 -1
  61. package/dist/query.cjs +2 -2
  62. package/dist/query.js +2 -2
  63. package/dist/{refResolveFns-BFws5K2t.cjs → refResolveFns-ROMmhWfH.cjs} +6 -6
  64. package/dist/{refResolveFns-DZoPfglj.js → refResolveFns-Yy1n2BHJ.js} +6 -6
  65. package/dist/{shapeFns-CHsoXWeu.js → shapeFns-BRRrZc1X.js} +2 -2
  66. package/dist/{shapeFns-C9P1KmqH.cjs → shapeFns-CljM3iMI.cjs} +2 -2
  67. package/dist/shapeRef.cjs +1 -1
  68. package/dist/shapeRef.js +1 -1
  69. package/dist/{shapeTypes-BK53GmLC.cjs → shapeTypes-DEe6gtTR.cjs} +195 -37
  70. package/dist/{shapeTypes-Ckz9bpYW.js → shapeTypes-w2wyXEis.js} +195 -37
  71. package/dist/sketching.cjs +3 -3
  72. package/dist/sketching.js +3 -3
  73. package/dist/{solidBuilders-DMfqtfIG.js → solidBuilders-BxIYXIv-.js} +3 -3
  74. package/dist/{solidBuilders-CETSjBW2.cjs → solidBuilders-yQFZe6jf.cjs} +3 -3
  75. package/dist/{surfaceBuilders-BeHgAqDx.js → surfaceBuilders-BZ7BW8I0.js} +3 -3
  76. package/dist/{surfaceBuilders-vKXtKSqY.cjs → surfaceBuilders-dWcQ_BpM.cjs} +3 -3
  77. package/dist/text.cjs +2 -2
  78. package/dist/text.js +2 -2
  79. package/dist/{textBlueprints-CLwy1uWM.js → textBlueprints-CxhhPEaF.js} +8 -8
  80. package/dist/{textBlueprints-DSiQKpe8.cjs → textBlueprints-Tx73Xex5.cjs} +8 -8
  81. package/dist/{textMetrics-CzSpui4K.cjs → textMetrics-9q5S5II9.cjs} +1 -1
  82. package/dist/{textMetrics-1e-VHhTX.js → textMetrics-B5dKPalE.js} +1 -1
  83. package/dist/{threadFns-BEopBSv3.cjs → threadFns-BnNo5eND.cjs} +7 -7
  84. package/dist/{threadFns-DveRUJwK.js → threadFns-Dfu2jV41.js} +7 -7
  85. package/dist/topology/apiTypes.d.ts +0 -3
  86. package/dist/topology/modifierFns.d.ts +4 -6
  87. package/dist/topology.cjs +9 -9
  88. package/dist/topology.js +9 -9
  89. package/dist/{topologyQueryFns-SINsBrMe.js → topologyQueryFns-CTl4cWYD.js} +1 -1
  90. package/dist/{topologyQueryFns--p_-tywe.cjs → topologyQueryFns-I_m8o-s7.cjs} +1 -1
  91. package/dist/{validityTypes-BCZ8XRzO.js → validityTypes-C2K0Eepw.js} +1 -1
  92. package/dist/{validityTypes-DPAkV5rC.cjs → validityTypes-DgknRAAp.cjs} +1 -1
  93. package/package.json +2 -2
package/dist/query.js CHANGED
@@ -1,3 +1,3 @@
1
- import { n as edgeFinder, r as faceFinder, t as getSingleFace } from "./helpers-D3oo0Zfs.js";
2
- import { t as cornerFinder } from "./cornerFinder-ChkO3EOO.js";
1
+ import { n as edgeFinder, r as faceFinder, t as getSingleFace } from "./helpers-DolHn2_s.js";
2
+ import { t as cornerFinder } from "./cornerFinder-C7f43oKE.js";
3
3
  export { cornerFinder, edgeFinder, faceFinder, getSingleFace };
@@ -1,10 +1,10 @@
1
- const require_shapeTypes = require("./shapeTypes-BK53GmLC.cjs");
2
- const require_topologyQueryFns = require("./topologyQueryFns--p_-tywe.cjs");
3
- const require_faceFns = require("./faceFns-DfEUZlnf.cjs");
1
+ const require_shapeTypes = require("./shapeTypes-DEe6gtTR.cjs");
2
+ const require_topologyQueryFns = require("./topologyQueryFns-I_m8o-s7.cjs");
3
+ const require_faceFns = require("./faceFns-dj_c8LVc.cjs");
4
4
  const require_faceRoleFns = require("./faceRoleFns-Db5bYj4Q.cjs");
5
- const require_shapeFns = require("./shapeFns-C9P1KmqH.cjs");
6
- const require_measureFns = require("./measureFns-CmKNZ0gC.cjs");
7
- const require_adjacencyFns = require("./adjacencyFns-B1ZWTkxw.cjs");
5
+ const require_shapeFns = require("./shapeFns-CljM3iMI.cjs");
6
+ const require_measureFns = require("./measureFns-FrNeGmXh.cjs");
7
+ const require_adjacencyFns = require("./adjacencyFns-BLtq-nUN.cjs");
8
8
  // src/topology/shapeRef/scoring.ts
9
9
  /**
10
10
  * Default face scorer combining surface type, normal alignment, centroid proximity,
@@ -1,10 +1,10 @@
1
- import { g as disposeTransientSubShape, o as castShapeWithKnownType, q as getKernel } from "./shapeTypes-Ckz9bpYW.js";
2
- import { c as getFaces, w as vertexPosition } from "./topologyQueryFns-SINsBrMe.js";
3
- import { i as faceGeomType, l as normalAt, r as faceCenter } from "./faceFns-Dz3eRgNR.js";
1
+ import { g as disposeTransientSubShape, o as castShapeWithKnownType, q as getKernel } from "./shapeTypes-w2wyXEis.js";
2
+ import { c as getFaces, w as vertexPosition } from "./topologyQueryFns-CTl4cWYD.js";
3
+ import { i as faceGeomType, l as normalAt, r as faceCenter } from "./faceFns-BG1CBQUM.js";
4
4
  import { t as getFaceRoles } from "./faceRoleFns-BPxzQF-n.js";
5
- import { n as getHashCode } from "./shapeFns-CHsoXWeu.js";
6
- import { c as measureLength, r as measureArea } from "./measureFns-6mHYvqUc.js";
7
- import { a as facesOfVertex, c as verticesOfFace, i as facesOfEdge, o as sharedEdges, s as verticesOfEdge, t as adjacentFaceHashes } from "./adjacencyFns-XdjXKCXE.js";
5
+ import { n as getHashCode } from "./shapeFns-BRRrZc1X.js";
6
+ import { c as measureLength, r as measureArea } from "./measureFns-WGYWWnQ1.js";
7
+ import { a as facesOfVertex, c as verticesOfFace, i as facesOfEdge, o as sharedEdges, s as verticesOfEdge, t as adjacentFaceHashes } from "./adjacencyFns-C1Hxy0tk.js";
8
8
  // src/topology/shapeRef/scoring.ts
9
9
  /**
10
10
  * Default face scorer combining surface type, normal alignment, centroid proximity,
@@ -1,6 +1,6 @@
1
- import { q as getKernel } from "./shapeTypes-Ckz9bpYW.js";
1
+ import { q as getKernel } from "./shapeTypes-w2wyXEis.js";
2
2
  import { t as BrepErrorCode } from "./errors-BTccWbtE.js";
3
- import { E as kernelCallRaw, T as kernelCall } from "./topologyQueryFns-SINsBrMe.js";
3
+ import { E as kernelCallRaw, T as kernelCall } from "./topologyQueryFns-CTl4cWYD.js";
4
4
  import { n as HASH_CODE_MAX } from "./constants-iraOnb2p.js";
5
5
  // src/topology/shapeFns.ts
6
6
  /**
@@ -1,6 +1,6 @@
1
- const require_shapeTypes = require("./shapeTypes-BK53GmLC.cjs");
1
+ const require_shapeTypes = require("./shapeTypes-DEe6gtTR.cjs");
2
2
  const require_errors = require("./errors-O_blYTWT.cjs");
3
- const require_topologyQueryFns = require("./topologyQueryFns--p_-tywe.cjs");
3
+ const require_topologyQueryFns = require("./topologyQueryFns-I_m8o-s7.cjs");
4
4
  const require_constants = require("./constants-oee0S_x6.cjs");
5
5
  // src/topology/shapeFns.ts
6
6
  /**
package/dist/shapeRef.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_refResolveFns = require("./refResolveFns-BFws5K2t.cjs");
2
+ const require_refResolveFns = require("./refResolveFns-ROMmhWfH.cjs");
3
3
  exports.assignRoles = require_refResolveFns.assignRoles;
4
4
  exports.captureHint = require_refResolveFns.captureHint;
5
5
  exports.createDerivedFaceRef = require_refResolveFns.createDerivedFaceRef;
package/dist/shapeRef.js CHANGED
@@ -1 +1 @@
1
- export { h as assignRoles, g as captureHint, l as createDerivedFaceRef, p as createEdgeRef, _ as createRef, d as createVertexRef, b as defaultScorer, t as isDerivedFaceRef, n as isEdgeRef, r as isFaceRef, i as isLineageRef, a as isVertexRef, u as resolveDerivedFaceRef, m as resolveEdgeRef, o as resolveLineageRef, v as resolveRef, s as resolveRefIn, c as resolveRefParams, f as resolveVertexRef, y as updateRoles } from "./refResolveFns-DZoPfglj.js";
1
+ export { h as assignRoles, g as captureHint, l as createDerivedFaceRef, p as createEdgeRef, _ as createRef, d as createVertexRef, b as defaultScorer, t as isDerivedFaceRef, n as isEdgeRef, r as isFaceRef, i as isLineageRef, a as isVertexRef, u as resolveDerivedFaceRef, m as resolveEdgeRef, o as resolveLineageRef, v as resolveRef, s as resolveRefIn, c as resolveRefParams, f as resolveVertexRef, y as updateRoles } from "./refResolveFns-Yy1n2BHJ.js";
@@ -1,4 +1,4 @@
1
- const require_occtWasmAdapter = require("./occtWasmAdapter-4YnvqZOW.cjs");
1
+ const require_occtWasmAdapter = require("./occtWasmAdapter-B9ZXx36v.cjs");
2
2
  const require_bug = require("./bug-CBcpIPuf.cjs");
3
3
  // src/kernel/quality.ts
4
4
  /**
@@ -7278,21 +7278,85 @@ function makeBezierEdge(bk, points) {
7278
7278
  function makeTangentArc(bk, startPoint, startTangent, endPoint) {
7279
7279
  return edgeHandle(bk.makeTangentArc3d(startPoint[0], startPoint[1], startPoint[2], startTangent[0], startTangent[1], startTangent[2], endPoint[0], endPoint[1], endPoint[2]));
7280
7280
  }
7281
- function makeHelixWire(bk, pitch, height, radius, center, _direction, leftHanded) {
7281
+ /** The X axis occt's `gp_Ax3(P, V)` picks when given only a direction, so a helix starts where occt-wasm's does. */
7282
+ function occtDefaultXDir(a, b, c) {
7283
+ const [aa, ba, ca] = [
7284
+ Math.abs(a),
7285
+ Math.abs(b),
7286
+ Math.abs(c)
7287
+ ];
7288
+ let x;
7289
+ if (ba <= aa && ba <= ca) x = aa > ca ? [
7290
+ -c,
7291
+ 0,
7292
+ a
7293
+ ] : [
7294
+ c,
7295
+ 0,
7296
+ -a
7297
+ ];
7298
+ else if (aa <= ba && aa <= ca) x = ba > ca ? [
7299
+ 0,
7300
+ -c,
7301
+ b
7302
+ ] : [
7303
+ 0,
7304
+ c,
7305
+ -b
7306
+ ];
7307
+ else x = aa > ba ? [
7308
+ -b,
7309
+ a,
7310
+ 0
7311
+ ] : [
7312
+ b,
7313
+ -a,
7314
+ 0
7315
+ ];
7316
+ const len = Math.hypot(x[0], x[1], x[2]);
7317
+ return [
7318
+ x[0] / len,
7319
+ x[1] / len,
7320
+ x[2] / len
7321
+ ];
7322
+ }
7323
+ function makeHelixWire(bk, pitch, height, radius, center, direction, leftHanded) {
7282
7324
  const turns = height / pitch;
7283
7325
  const nSamples = Math.max(4, Math.ceil(turns * 16));
7284
- const cx = center?.[0] ?? 0;
7285
- const cy = center?.[1] ?? 0;
7286
- const cz = center?.[2] ?? 0;
7326
+ const [cx, cy, cz] = center ?? [
7327
+ 0,
7328
+ 0,
7329
+ 0
7330
+ ];
7331
+ const [dx, dy, dz] = direction ?? [
7332
+ 0,
7333
+ 0,
7334
+ 1
7335
+ ];
7336
+ const dLen = Math.hypot(dx, dy, dz);
7337
+ const z = [
7338
+ dx / dLen,
7339
+ dy / dLen,
7340
+ dz / dLen
7341
+ ];
7342
+ const x = occtDefaultXDir(z[0], z[1], z[2]);
7343
+ const y = [
7344
+ z[1] * x[2] - z[2] * x[1],
7345
+ z[2] * x[0] - z[0] * x[2],
7346
+ z[0] * x[1] - z[1] * x[0]
7347
+ ];
7287
7348
  const sign = leftHanded ? -1 : 1;
7288
7349
  const points = [];
7289
7350
  for (let i = 0; i <= nSamples; i++) {
7290
7351
  const t = i / nSamples;
7291
7352
  const angle = sign * 2 * Math.PI * turns * t;
7353
+ const u = radius * Math.cos(angle);
7354
+ const v = radius * Math.sin(angle);
7355
+ const h = height * t;
7292
7356
  points.push([
7293
- cx + radius * Math.cos(angle),
7294
- cy + radius * Math.sin(angle),
7295
- cz + height * t
7357
+ cx + u * x[0] + v * y[0] + h * z[0],
7358
+ cy + u * x[1] + v * y[1] + h * z[1],
7359
+ cz + u * x[2] + v * y[2] + h * z[2]
7296
7360
  ]);
7297
7361
  }
7298
7362
  return makeWire(bk, [interpolatePoints(bk, points)]);
@@ -7934,45 +7998,80 @@ function fillet(bk, shape, edges, radius) {
7934
7998
  const solidId = unwrapSolidOrThrow(shape, "fillet");
7935
7999
  const edgeIds = edges.map((e) => unwrap$1(e, "edge"));
7936
8000
  if (typeof radius === "number") return solidHandle(bk.fillet(solidId, edgeIds, radius));
7937
- const radii = /* @__PURE__ */ new Set();
7938
- for (const edge of edges) {
8001
+ const laws = edges.map((edge, i) => {
7939
8002
  const r = typeof radius === "function" ? radius(edge) : radius;
7940
8003
  const [start, end] = Array.isArray(r) ? r : [r, r];
7941
- if (start !== end) throw varyingFilletUnsupported();
7942
- radii.add(start);
8004
+ return {
8005
+ edge: require_bug.wasmIndex(edgeIds, i),
8006
+ start,
8007
+ end
8008
+ };
8009
+ });
8010
+ const [first] = laws;
8011
+ if (!first) throw new Error("brepkit: fillet needs at least one edge");
8012
+ if (laws.every((l) => l.start === first.start && l.end === first.start)) return solidHandle(bk.fillet(solidId, edgeIds, first.start));
8013
+ return filletAlongLaws(bk, solidId, laws);
8014
+ }
8015
+ var lawProbes = /* @__PURE__ */ new WeakMap();
8016
+ /**
8017
+ * brepkit-wasm before 4.6.9 cuts a flat bevel along a radius law, and the peer
8018
+ * range still admits those builds. Rounding a 10 mm cube edge from 1 to 2 tells
8019
+ * them apart: a round removes 5.0 mm3 and a bevel 11.7. The probe runs once per
8020
+ * kernel, inside a checkpoint it restores and discards, so it leaves nothing behind.
8021
+ */
8022
+ function roundsAlongLaws(bk) {
8023
+ const known = lawProbes.get(bk);
8024
+ if (known !== void 0) return known;
8025
+ let rounds;
8026
+ const mark = bk.checkpoint();
8027
+ try {
8028
+ const cube = bk.makeBox(10, 10, 10);
8029
+ const edge = require_bug.wasmIndex(bk.getSolidEdges(cube), 0);
8030
+ const spec = JSON.stringify([{
8031
+ edge,
8032
+ law: "linear",
8033
+ start: 1,
8034
+ end: 2
8035
+ }]);
8036
+ rounds = 1e3 - bk.volume(bk.filletVariable(cube, spec), DEFAULT_DEFLECTION) < 8;
8037
+ } catch {
8038
+ rounds = false;
8039
+ } finally {
8040
+ bk.restore(mark);
8041
+ bk.discardCheckpoint(mark);
7943
8042
  }
7944
- if (radii.size > 1) throw perEdgeUnsupported("fillet radii");
7945
- const [only] = radii;
7946
- if (only === void 0) throw new Error("brepkit: fillet needs at least one edge");
7947
- return solidHandle(bk.fillet(solidId, edgeIds, only));
8043
+ lawProbes.set(bk, rounds);
8044
+ return rounds;
7948
8045
  }
7949
8046
  /**
7950
- * brepkit takes one value for every edge of a fillet or chamfer call, and a
7951
- * second call on the first one's result cannot name the input's other edges:
7952
- * a chamfer fails on them ("no manifold edges to chamfer"), and a fillet builds
7953
- * the right body but leaves the input solid corrupt, so that filleting the
7954
- * input's four vertical cube edges at 2 mm afterwards cuts a flat chamfer.
8047
+ * One filletVariable call for every edge, each along its own constant or
8048
+ * linear law, running from the edge's start vertex to its end.
7955
8049
  */
7956
- function perEdgeUnsupported(what) {
7957
- return new require_occtWasmAdapter.UnsupportedKernelOperationError(`brepkit: different ${what} on different edges in one call is not supported`);
8050
+ function filletAlongLaws(bk, solidId, laws) {
8051
+ if (!roundsAlongLaws(bk)) throw new require_occtWasmAdapter.UnsupportedKernelOperationError("brepkit: a fillet along a radius law needs brepkit-wasm 4.6.9 or newer");
8052
+ const spec = laws.map(({ edge, start, end }) => ({
8053
+ edge,
8054
+ law: start === end ? "constant" : "linear",
8055
+ start,
8056
+ end
8057
+ }));
8058
+ return solidHandle(bk.filletVariable(solidId, JSON.stringify(spec)));
7958
8059
  }
7959
8060
  /**
7960
- * brepkit-wasm's filletVariable does not build a rolling-ball blend: on the
7961
- * 40 mm top edge of a 40 x 30 x 20 box, a radius running 2 to 5 removes 260 mm3
7962
- * where the blend removes about 113, and even a constant law of 3 removes 180
7963
- * (the flat chamfer) where fillet removes 77.26. A radius that varies along an
7964
- * edge is refused rather than built that way.
8061
+ * brepkit takes one distance for every edge of a chamfer call, and a second
8062
+ * call on the first one's result cannot name the input's other edges: it fails
8063
+ * on them ("no manifold edges to chamfer").
7965
8064
  */
7966
- function varyingFilletUnsupported() {
7967
- return new require_occtWasmAdapter.UnsupportedKernelOperationError("brepkit: a fillet radius that varies along an edge is not supported");
8065
+ function perEdgeUnsupported(what) {
8066
+ return new require_occtWasmAdapter.UnsupportedKernelOperationError(`brepkit: different ${what} on different edges in one call is not supported`);
7968
8067
  }
7969
8068
  /** occt's hashCode upper bound, which the kernel-agnostic filletVariable spec hashes edges with. */
7970
8069
  var HASH_UPPER_BOUND = 2147483647;
7971
8070
  /**
7972
8071
  * A variable fillet spec on one edge: `{ edge: hashCode, radii: [{ param, radius }] }`
7973
- * from variableFillet, or `{ edgeId, startRadius, endRadius }`. A constant radius is
7974
- * an ordinary fillet; a radius that varies is unsupported (see
7975
- * {@link varyingFilletUnsupported}).
8072
+ * from variableFillet, or `{ edgeId, startRadius, endRadius }`. Like occt-wasm, a
8073
+ * profile runs linearly from its first radius to its last, so one of more than two
8074
+ * points is unsupported rather than flattened to a line.
7976
8075
  */
7977
8076
  function filletVariable$1(bk, shape, spec) {
7978
8077
  const solidId = unwrapSolidOrThrow(shape, "filletVariable");
@@ -7988,9 +8087,15 @@ function filletVariable$1(bk, shape, spec) {
7988
8087
  radii = [parsed.startRadius, parsed.endRadius];
7989
8088
  } else throw new require_occtWasmAdapter.UnsupportedKernelOperationError("brepkit: filletVariable: unrecognized spec");
7990
8089
  if (edgeId === void 0) throw new Error("brepkit: filletVariable: the edge is not an edge of the shape");
7991
- const [first = 0] = radii;
7992
- if (radii.some((r) => r !== first)) throw varyingFilletUnsupported();
7993
- return solidHandle(bk.fillet(solidId, [edgeId], first));
8090
+ if (radii.length > 2) throw new require_occtWasmAdapter.UnsupportedKernelOperationError("brepkit: filletVariable supports only a linear (<=2-point) radius profile");
8091
+ const start = require_bug.wasmIndex(radii, 0);
8092
+ const end = require_bug.wasmIndex(radii, radii.length - 1);
8093
+ if (start === end) return solidHandle(bk.fillet(solidId, [edgeId], start));
8094
+ return filletAlongLaws(bk, solidId, [{
8095
+ edge: edgeId,
8096
+ start,
8097
+ end
8098
+ }]);
7994
8099
  }
7995
8100
  /**
7996
8101
  * A symmetric chamfer for two equal distances, brepkit's two-distance chamfer
@@ -10967,12 +11072,65 @@ function trySmoothPipeShell(bk, faceId, spine) {
10967
11072
  return;
10968
11073
  }
10969
11074
  }
11075
+ /**
11076
+ * The curve a guided sweep runs along: one line, or one edge brepkit stores
11077
+ * as NURBS. brepkit gives no NURBS for a circle or an ellipse, and reading one
11078
+ * by its end points would sweep along the chord.
11079
+ */
11080
+ function guideCurve(bk, shape, role) {
11081
+ const edges = shape.type === "edge" ? [shape] : iterShapes$1(bk, shape, "edge");
11082
+ const [edge] = edges;
11083
+ if (edges.length !== 1 || !edge) throw new require_occtWasmAdapter.UnsupportedKernelOperationError(`brepkit: a guided sweep takes a single-edge ${role}, got ${edges.length} edges`);
11084
+ const edgeId = unwrap$1(edge, "edge");
11085
+ const curveType = bk.getEdgeCurveType(edgeId);
11086
+ if (curveType !== "LINE" && bk.getEdgeNurbsData(edgeId) === null) throw new require_occtWasmAdapter.UnsupportedKernelOperationError(`brepkit: a guided sweep takes a line or NURBS ${role}, got ${curveType}`);
11087
+ const data = extractNurbsFromEdge(bk, edge);
11088
+ if (!data) throw new Error(`brepkit: guided sweep could not read the ${role}`);
11089
+ return data;
11090
+ }
11091
+ /**
11092
+ * brepkit places a guided sweep's sections at twice the spine's control points
11093
+ * (at least 4) and rules flat between them, so a straight spine twists through
11094
+ * 4 segments whatever the guide does: a square turned 90° comes out 2.5% light.
11095
+ * Splitting a straight spine into twice as many collinear spans as the guide
11096
+ * has control points samples the twist more finely than the guide is drawn.
11097
+ */
11098
+ function densifyStraightSpine(path, spans) {
11099
+ if (path.degree !== 1 || path.controlPoints.length !== 6 || spans <= 1) return path;
11100
+ const start = require_bug.vec3At(path.controlPoints, 0);
11101
+ const end = require_bug.vec3At(path.controlPoints, 3);
11102
+ const controlPoints = [];
11103
+ const interior = [];
11104
+ for (let i = 0; i <= spans; i++) {
11105
+ const t = i / spans;
11106
+ controlPoints.push(...start.map((s, k) => s + (require_bug.wasmIndex(end, k) - s) * t));
11107
+ if (i > 0 && i < spans) interior.push(t);
11108
+ }
11109
+ return {
11110
+ degree: 1,
11111
+ knots: [
11112
+ 0,
11113
+ 0,
11114
+ ...interior,
11115
+ 1,
11116
+ 1
11117
+ ],
11118
+ controlPoints,
11119
+ weights: new Array(spans + 1).fill(1)
11120
+ };
11121
+ }
11122
+ function guidedPipeShell(bk, faceId, spine, auxiliary) {
11123
+ const aux = guideCurve(bk, auxiliary, "auxiliary spine");
11124
+ const path = densifyStraightSpine(guideCurve(bk, spine, "spine"), 2 * (aux.controlPoints.length / 3));
11125
+ return solidHandle(bk.guidedSweep(faceId, path.degree, path.knots, path.controlPoints, path.weights, aux.degree, aux.knots, aux.controlPoints, aux.weights));
11126
+ }
10970
11127
  function sweepPipeShell(bk, profile, spine, options) {
10971
- if (options?.["auxiliary"] !== void 0) throw new require_occtWasmAdapter.UnsupportedKernelOperationError("brepkit: sweepPipeShell has no auxiliary spine (twist or guided sweep)");
10972
11128
  if (options?.["law"] !== void 0) throw new require_occtWasmAdapter.UnsupportedKernelOperationError("brepkit: sweepPipeShell has no scaling law");
10973
11129
  const profileHandle = profile;
10974
11130
  const faceId = profileHandle.type === "wire" ? bk.makeFaceFromWire(profileHandle.id) : unwrap$1(profile, "face");
10975
11131
  const shellMode = !!(options && options["shellMode"]);
11132
+ const auxiliary = options?.["auxiliary"];
11133
+ if (auxiliary !== void 0) return wrapPipeShellResult(guidedPipeShell(bk, faceId, spine, auxiliary), profile, shellMode);
10976
11134
  const transitionMode = options?.["transitionMode"];
10977
11135
  const contactMode = transitionMode ? mapStringTransitionMode(transitionMode) : void 0;
10978
11136
  if (contactMode) {