brepjs 20.13.5 → 20.14.0

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 (94) hide show
  1. package/dist/2d.cjs +6 -6
  2. package/dist/2d.js +6 -6
  3. package/dist/{adjacencyFns-B1ZWTkxw.cjs → adjacencyFns-B6fMyAj0.cjs} +3 -3
  4. package/dist/{adjacencyFns-XdjXKCXE.js → adjacencyFns-n6XWEyj1.js} +3 -3
  5. package/dist/{blueprint-WAucCqwY.js → blueprint-2j8szIQ6.js} +5 -5
  6. package/dist/{blueprint-DzhzGFy2.cjs → blueprint-Cfj9EupK.cjs} +5 -5
  7. package/dist/{blueprintFns-DnzHyTjv.cjs → blueprintFns-7SWJcrSi.cjs} +2 -2
  8. package/dist/{blueprintFns-C8gt4OYm.js → blueprintFns-C4VacaAG.js} +2 -2
  9. package/dist/{blueprintSketcher-CeMrC8k-.js → blueprintSketcher-D81yS5Em.js} +3 -3
  10. package/dist/{blueprintSketcher-JoLn4vSB.cjs → blueprintSketcher-zx0yhxOF.cjs} +3 -3
  11. package/dist/{boolean2D-Cwc_4mU8.cjs → boolean2D-BMfzZ4n8.cjs} +4 -4
  12. package/dist/{boolean2D-D8_6vKh_.js → boolean2D-DhW8iZoR.js} +4 -4
  13. package/dist/{booleanFns-BhW5eybV.cjs → booleanFns-CaHF13T-.cjs} +5 -5
  14. package/dist/{booleanFns-aGRfk4ud.js → booleanFns-DIqS3nBK.js} +5 -5
  15. package/dist/brepjs.cjs +30 -30
  16. package/dist/brepjs.js +30 -30
  17. package/dist/{cameraFns-CBc6tpRl.js → cameraFns-DB_nPXR7.js} +3 -3
  18. package/dist/{cameraFns-DhgM5-Nl.cjs → cameraFns-T60Qk0tk.cjs} +3 -3
  19. package/dist/core.cjs +2 -2
  20. package/dist/core.js +2 -2
  21. package/dist/{cornerFinder-xI6O0ZCv.cjs → cornerFinder-CNuTBfRo.cjs} +1 -1
  22. package/dist/{cornerFinder-ChkO3EOO.js → cornerFinder-GtiadLBr.js} +1 -1
  23. package/dist/{curveFns-Cnh0Hljx.js → curveFns-CGQCy_D5.js} +1 -1
  24. package/dist/{curveFns-Dz36SOE6.cjs → curveFns-m73YVbFb.cjs} +1 -1
  25. package/dist/{drawFns-RuUOUlSC.js → drawFns-D9GuLtRK.js} +12 -12
  26. package/dist/{drawFns-BrRyiHKp.cjs → drawFns-DCY1v4nI.cjs} +12 -12
  27. package/dist/{faceFns-Dz3eRgNR.js → faceFns-BNv6thpF.js} +2 -2
  28. package/dist/{faceFns-DfEUZlnf.cjs → faceFns-CPGJ_cx6.cjs} +2 -2
  29. package/dist/{healingFns-D7LTrPO8.cjs → healingFns-D33MBaNA.cjs} +41 -28
  30. package/dist/{healingFns-CCRPtrvE.js → healingFns-w-PHd-Lj.js} +41 -28
  31. package/dist/{helpers-C0MoldOO.cjs → helpers-CCnN8-PY.cjs} +6 -6
  32. package/dist/{helpers-D3oo0Zfs.js → helpers-Ci_WZ5ou.js} +6 -6
  33. package/dist/{importFns-BVcmm3T0.js → importFns-DQgcQQCb.js} +5 -5
  34. package/dist/{importFns-Sp5phi5Y.cjs → importFns-zfbC3bIK.cjs} +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/helpers.d.ts +12 -2
  41. package/dist/kernel/occtWasm/occtWasmAdapter.cjs +1 -1
  42. package/dist/kernel/occtWasm/occtWasmAdapter.js +1 -1
  43. package/dist/{loftFns-BoGWrMPg.cjs → loftFns-DQJM-35I.cjs} +4 -4
  44. package/dist/{loftFns-oH6dldzO.js → loftFns-mrTzIf4_.js} +4 -4
  45. package/dist/{measureFns-CmKNZ0gC.cjs → measureFns-CpoPgAZt.cjs} +4 -4
  46. package/dist/{measureFns-6mHYvqUc.js → measureFns-MSr05_kf.js} +4 -4
  47. package/dist/measurement.cjs +2 -2
  48. package/dist/measurement.js +2 -2
  49. package/dist/{meshFns-D29JHTr6.js → meshFns-BIWD7IFN.js} +4 -4
  50. package/dist/{meshFns-BFgQZGty.cjs → meshFns-BxRKwY5z.cjs} +4 -4
  51. package/dist/{occtWasmAdapter-4YnvqZOW.cjs → occtWasmAdapter-BH1JcAgl.cjs} +13 -5
  52. package/dist/{occtWasmAdapter-CGsnjMOe.js → occtWasmAdapter-DD_6IAVj.js} +13 -5
  53. package/dist/operations/sweepFns.d.ts +3 -3
  54. package/dist/operations.cjs +2 -2
  55. package/dist/operations.js +2 -2
  56. package/dist/{primitiveFns-uywjJ06V.js → primitiveFns-BaYEo9qN.js} +5 -5
  57. package/dist/{primitiveFns-Dovused4.cjs → primitiveFns-D8D9dI_P.cjs} +5 -5
  58. package/dist/{principalBoxFns-CTVc4f8W.js → principalBoxFns-CBWLch1h.js} +3 -3
  59. package/dist/{principalBoxFns-KvlaTxMs.cjs → principalBoxFns-CNSK-z3k.cjs} +3 -3
  60. package/dist/projection.cjs +1 -1
  61. package/dist/projection.js +1 -1
  62. package/dist/query.cjs +2 -2
  63. package/dist/query.js +2 -2
  64. package/dist/{refResolveFns-BFws5K2t.cjs → refResolveFns-CuewCIRB.cjs} +6 -6
  65. package/dist/{refResolveFns-DZoPfglj.js → refResolveFns-DaZPev13.js} +6 -6
  66. package/dist/{shapeFns-CHsoXWeu.js → shapeFns-3NzCE2kz.js} +2 -2
  67. package/dist/{shapeFns-C9P1KmqH.cjs → shapeFns-Cklw3p3S.cjs} +2 -2
  68. package/dist/shapeRef.cjs +1 -1
  69. package/dist/shapeRef.js +1 -1
  70. package/dist/{shapeTypes-BK53GmLC.cjs → shapeTypes-CgayxMvX.cjs} +195 -37
  71. package/dist/{shapeTypes-Ckz9bpYW.js → shapeTypes-qhs8f2zx.js} +195 -37
  72. package/dist/sketching.cjs +3 -3
  73. package/dist/sketching.js +3 -3
  74. package/dist/{solidBuilders-CETSjBW2.cjs → solidBuilders-BvIdZUkI.cjs} +3 -3
  75. package/dist/{solidBuilders-DMfqtfIG.js → solidBuilders-DhDGnOTQ.js} +3 -3
  76. package/dist/{surfaceBuilders-vKXtKSqY.cjs → surfaceBuilders-BPAW6RbN.cjs} +3 -3
  77. package/dist/{surfaceBuilders-BeHgAqDx.js → surfaceBuilders-D9WX9gHX.js} +3 -3
  78. package/dist/text.cjs +2 -2
  79. package/dist/text.js +2 -2
  80. package/dist/{textBlueprints-DSiQKpe8.cjs → textBlueprints-CTMykb_E.cjs} +8 -8
  81. package/dist/{textBlueprints-CLwy1uWM.js → textBlueprints-CxufM4VF.js} +8 -8
  82. package/dist/{textMetrics-1e-VHhTX.js → textMetrics-CdvERXfK.js} +1 -1
  83. package/dist/{textMetrics-CzSpui4K.cjs → textMetrics-D51K9Ddx.cjs} +1 -1
  84. package/dist/{threadFns-DveRUJwK.js → threadFns-BUy4gIG3.js} +7 -7
  85. package/dist/{threadFns-BEopBSv3.cjs → threadFns-zNevH3kU.cjs} +7 -7
  86. package/dist/topology/apiTypes.d.ts +2 -4
  87. package/dist/topology/modifierFns.d.ts +15 -6
  88. package/dist/topology.cjs +9 -9
  89. package/dist/topology.js +9 -9
  90. package/dist/{topologyQueryFns-SINsBrMe.js → topologyQueryFns-CArmw9sE.js} +1 -1
  91. package/dist/{topologyQueryFns--p_-tywe.cjs → topologyQueryFns-EI-aso9K.cjs} +1 -1
  92. package/dist/{validityTypes-DPAkV5rC.cjs → validityTypes-DFEPeAkV.cjs} +1 -1
  93. package/dist/{validityTypes-BCZ8XRzO.js → validityTypes-DiOmm0sf.js} +1 -1
  94. package/package.json +2 -2
@@ -1,6 +1,6 @@
1
- import { O as getOrQueryType, i as castShape, q as getKernel } from "./shapeTypes-Ckz9bpYW.js";
1
+ import { O as getOrQueryType, i as castShape, q as getKernel } from "./shapeTypes-qhs8f2zx.js";
2
2
  import { E as ok, P as unwrap, g as err, l as typeCastError } from "./errors-BTccWbtE.js";
3
- import { a as getCachedSurfaceType } from "./topologyQueryFns-SINsBrMe.js";
3
+ import { a as getCachedSurfaceType } from "./topologyQueryFns-CArmw9sE.js";
4
4
  import { r as toVec3 } from "./types-CKXsIm9-.js";
5
5
  // src/topology/cast.ts
6
6
  var TOPO_ENUM = {
@@ -1,6 +1,6 @@
1
- const require_shapeTypes = require("./shapeTypes-BK53GmLC.cjs");
1
+ const require_shapeTypes = require("./shapeTypes-CgayxMvX.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-EI-aso9K.cjs");
4
4
  const require_types = require("./types-CjF9Rofr.cjs");
5
5
  // src/topology/cast.ts
6
6
  var TOPO_ENUM = {
@@ -1,13 +1,13 @@
1
- const require_shapeTypes = require("./shapeTypes-BK53GmLC.cjs");
2
- const require_occtWasmAdapter = require("./occtWasmAdapter-4YnvqZOW.cjs");
1
+ const require_shapeTypes = require("./shapeTypes-CgayxMvX.cjs");
2
+ const require_occtWasmAdapter = require("./occtWasmAdapter-BH1JcAgl.cjs");
3
3
  const require_errors = require("./errors-O_blYTWT.cjs");
4
- const require_topologyQueryFns = require("./topologyQueryFns--p_-tywe.cjs");
4
+ const require_topologyQueryFns = require("./topologyQueryFns-EI-aso9K.cjs");
5
5
  const require_constants = require("./constants-oee0S_x6.cjs");
6
- const require_faceFns = require("./faceFns-DfEUZlnf.cjs");
7
- const require_booleanFns = require("./booleanFns-BhW5eybV.cjs");
8
- const require_shapeFns = require("./shapeFns-C9P1KmqH.cjs");
6
+ const require_faceFns = require("./faceFns-CPGJ_cx6.cjs");
7
+ const require_booleanFns = require("./booleanFns-CaHF13T-.cjs");
8
+ const require_shapeFns = require("./shapeFns-Cklw3p3S.cjs");
9
9
  const require_arrayAccess = require("./arrayAccess-DpJYARwv.cjs");
10
- const require_adjacencyFns = require("./adjacencyFns-B1ZWTkxw.cjs");
10
+ const require_adjacencyFns = require("./adjacencyFns-B6fMyAj0.cjs");
11
11
  // src/topology/threeHelpers.ts
12
12
  /**
13
13
  * Convert a ShapeMesh into BufferGeometry-compatible typed arrays.
@@ -213,28 +213,41 @@ function validateNotNull$1(shape, label) {
213
213
  if (require_shapeTypes.getKernel().isNull(shape.wrapped)) return require_errors.err(require_errors.validationError(require_errors.BrepErrorCode.NULL_SHAPE_INPUT, `${label} is a null shape`));
214
214
  return require_errors.ok(void 0);
215
215
  }
216
+ function isPositivePair([a, b]) {
217
+ return a > 0 && b > 0;
218
+ }
216
219
  /**
217
- * Validate that a scalar or `[a, b]` pair is positive.
220
+ * A fillet's start and end radius: one may be 0, so the fillet runs out to
221
+ * nothing at that end of the edge, but not both, and neither below 0.
222
+ */
223
+ function isFilletRadiusPair([start, end]) {
224
+ return start >= 0 && end >= 0 && (start > 0 || end > 0);
225
+ }
226
+ var FILLET_PAIR_MESSAGE = "Fillet radii must not be negative, and one must be positive";
227
+ var FILLET_PAIR_HINT = "A radius may run to 0 at one end of the edge, but the other must be greater than 0";
228
+ /**
229
+ * Validate that a scalar is positive and that an `[a, b]` pair passes
230
+ * `isValidPair` (both positive by default).
218
231
  * Returns an Err Result on failure, `undefined` on success.
219
232
  *
220
233
  * Function-type values (per-edge callbacks) are intentionally skipped here --
221
234
  * they are validated lazily in {@link resolveEdgeCallback} when each edge is processed.
222
235
  */
223
- function validatePositiveParam(value, msgs) {
236
+ function validatePositiveParam(value, msgs, isValidPair = isPositivePair) {
224
237
  if (typeof value === "number" && value <= 0) return require_errors.err(require_errors.validationError(msgs.code, msgs.scalar, void 0, void 0, msgs.scalarHint));
225
- if (Array.isArray(value) && (value[0] <= 0 || value[1] <= 0)) return require_errors.err(require_errors.validationError(msgs.code, msgs.pair, void 0, void 0, msgs.pairHint));
238
+ if (Array.isArray(value) && !isValidPair(value)) return require_errors.err(require_errors.validationError(msgs.code, msgs.pair, void 0, void 0, msgs.pairHint));
226
239
  }
227
240
  /**
228
241
  * When the user supplies a per-edge callback, pre-filter edges and build a
229
242
  * hash-indexed lookup for the kernel. Returns `null` if no edges survive.
230
243
  */
231
- function resolveEdgeCallback$1(selectedEdges, callbackFn) {
244
+ function resolveEdgeCallback$1(selectedEdges, callbackFn, isValidPair = isPositivePair) {
232
245
  const filteredEdges = [];
233
246
  const hashToValue = /* @__PURE__ */ new Map();
234
247
  for (const edge of selectedEdges) {
235
248
  const val = callbackFn(edge) ?? 0;
236
249
  if (typeof val === "number" && val <= 0) continue;
237
- if (Array.isArray(val) && (val[0] <= 0 || val[1] <= 0)) continue;
250
+ if (Array.isArray(val) && !isValidPair(val)) continue;
238
251
  filteredEdges.push(edge);
239
252
  hashToValue.set(require_shapeTypes.getKernel().hashCode(edge.wrapped, require_constants.HASH_CODE_MAX), val);
240
253
  }
@@ -320,15 +333,15 @@ function normalizeFilletInputs(shape, edges, radius) {
320
333
  const paramErr = validatePositiveParam(radius, {
321
334
  code: "INVALID_FILLET_RADIUS",
322
335
  scalar: "Fillet radius must be positive",
323
- pair: "Fillet radii must both be positive",
336
+ pair: FILLET_PAIR_MESSAGE,
324
337
  scalarHint: "Provide a positive radius value greater than 0",
325
- pairHint: "Both radius values must be greater than 0"
326
- });
338
+ pairHint: FILLET_PAIR_HINT
339
+ }, isFilletRadiusPair);
327
340
  if (paramErr) return paramErr;
328
341
  const selectedEdges = edges ?? require_topologyQueryFns.getEdges(shape);
329
342
  if (selectedEdges.length === 0) return require_errors.err(require_errors.validationError(require_errors.BrepErrorCode.FILLET_NO_EDGES, "No edges found for fillet", void 0, void 0, "Check that the shape has edges, or adjust your edge finder criteria"));
330
343
  if (typeof radius === "function") {
331
- const resolved = resolveEdgeCallback$1(selectedEdges, radius);
344
+ const resolved = resolveEdgeCallback$1(selectedEdges, radius, isFilletRadiusPair);
332
345
  if (!resolved) return require_errors.err(require_errors.validationError(require_errors.BrepErrorCode.FILLET_NO_EDGES, "No edges with positive radius for fillet", void 0, void 0, "Check that the radius callback returns positive values"));
333
346
  return require_errors.ok({
334
347
  filteredEdges: resolved.edges,
@@ -377,8 +390,7 @@ function fillet(shape, edges, radius, { trackEvolution = true } = {}) {
377
390
  }
378
391
  /**
379
392
  * `UNSUPPORTED_CAPABILITY` for a fillet the kernel cannot build as asked (a
380
- * radius that varies along an edge on brepkit), from its
381
- * `UnsupportedKernelOperationError`.
393
+ * multi-point variable radius), from its `UnsupportedKernelOperationError`.
382
394
  */
383
395
  function filletUnsupportedError(e) {
384
396
  const kernelId = require_shapeTypes.getKernel().kernelId;
@@ -386,7 +398,7 @@ function filletUnsupportedError(e) {
386
398
  return require_errors.unsupportedError(require_errors.BrepErrorCode.UNSUPPORTED_CAPABILITY, `fillet: the ${kernelId} kernel cannot build this fillet (${raw})`, e, {
387
399
  kernel: kernelId,
388
400
  operation: "fillet"
389
- }, "Use one constant radius per edge, or use the occt-wasm kernel");
401
+ }, "Use a constant or linear (start, end) radius per edge");
390
402
  }
391
403
  /**
392
404
  * `FILLET_FAILED` / `CHAMFER_FAILED`, with `metadata.failedEdges` set to the
@@ -595,15 +607,16 @@ function draft(shape, faces, pullDirection, neutralPlane, angle) {
595
607
  *
596
608
  * The radius varies along the edge according to the provided spec points.
597
609
  * Each point specifies a normalized parameter (0 = start, 1 = end) and radius.
610
+ * A radius may be 0, so the fillet runs out to nothing there, as long as one
611
+ * is positive.
598
612
  *
599
- * **Cross-kernel note:** occt-wasm supports a linear (start/end, <=2-point)
600
- * profile; brepkit supports only a constant radius. Either returns
601
- * `UNSUPPORTED_CAPABILITY` for a profile it cannot build. The opencascade.js
602
- * kernel does not implement it.
613
+ * **Cross-kernel note:** occt-wasm and brepkit build a constant or linear
614
+ * (start/end, <=2-point) profile and return `UNSUPPORTED_CAPABILITY` for one of
615
+ * more points. The opencascade.js kernel does not implement it.
603
616
  */
604
617
  function variableFillet(shape, edge, radii) {
605
618
  if (radii.length === 0) return require_errors.err(require_errors.validationError(require_errors.BrepErrorCode.VARIABLE_FILLET_FAILED, "radii must contain at least one radius spec"));
606
- for (const r of radii) if (r.radius <= 0) return require_errors.err(require_errors.validationError(require_errors.BrepErrorCode.VARIABLE_FILLET_FAILED, "All radius values must be positive"));
619
+ if (radii.some((r) => r.radius < 0) || radii.every((r) => r.radius === 0)) return require_errors.err(require_errors.validationError(require_errors.BrepErrorCode.VARIABLE_FILLET_FAILED, "Radius values must not be negative, and one must be positive"));
607
620
  const kernel = require_shapeTypes.getKernel();
608
621
  try {
609
622
  const spec = JSON.stringify({
@@ -1155,13 +1168,13 @@ function castToShape3D(shape, errorCode, errorMsg, suggestion) {
1155
1168
  require_shapeTypes.disposeDowncastSource(shape, wrapped);
1156
1169
  return require_errors.ok(wrapped);
1157
1170
  }
1158
- function resolveEdgeCallback(selectedEdges, callbackFn) {
1171
+ function resolveEdgeCallback(selectedEdges, callbackFn, isValidPair = ([a, b]) => a > 0 && b > 0) {
1159
1172
  const filteredEdges = [];
1160
1173
  const hashToValue = /* @__PURE__ */ new Map();
1161
1174
  for (const edge of selectedEdges) {
1162
1175
  const val = callbackFn(edge) ?? 0;
1163
1176
  if (typeof val === "number" && val <= 0) continue;
1164
- if (Array.isArray(val) && (val[0] <= 0 || val[1] <= 0)) continue;
1177
+ if (Array.isArray(val) && !isValidPair(val)) continue;
1165
1178
  filteredEdges.push(edge);
1166
1179
  hashToValue.set(require_shapeTypes.getKernel().hashCode(edge.wrapped, require_constants.HASH_CODE_MAX), val);
1167
1180
  }
@@ -1251,14 +1264,14 @@ function filletWithEvolution(shape, edges, radius) {
1251
1264
  const check = validateNotNull(shape, "filletWithEvolution: shape");
1252
1265
  if (require_errors.isErr(check)) return check;
1253
1266
  if (typeof radius === "number" && radius <= 0) return require_errors.err(require_errors.validationError("INVALID_FILLET_RADIUS", "Fillet radius must be positive", void 0, void 0, "Provide a positive radius value greater than 0"));
1254
- if (Array.isArray(radius) && (radius[0] <= 0 || radius[1] <= 0)) return require_errors.err(require_errors.validationError("INVALID_FILLET_RADIUS", "Fillet radii must both be positive", void 0, void 0, "Both radius values must be greater than 0"));
1267
+ if (Array.isArray(radius) && !isFilletRadiusPair(radius)) return require_errors.err(require_errors.validationError("INVALID_FILLET_RADIUS", FILLET_PAIR_MESSAGE, void 0, void 0, FILLET_PAIR_HINT));
1255
1268
  const selectedEdges = edges ?? require_topologyQueryFns.getEdges(shape);
1256
1269
  if (selectedEdges.length === 0) return require_errors.err(require_errors.validationError(require_errors.BrepErrorCode.FILLET_NO_EDGES, "No edges found for fillet", void 0, void 0, "Check that the shape has edges, or adjust your edge finder criteria"));
1257
1270
  try {
1258
1271
  let filteredEdges;
1259
1272
  let kernelRadius;
1260
1273
  if (typeof radius === "function") {
1261
- const resolved = resolveEdgeCallback(selectedEdges, radius);
1274
+ const resolved = resolveEdgeCallback(selectedEdges, radius, isFilletRadiusPair);
1262
1275
  if (!resolved) return require_errors.err(require_errors.validationError(require_errors.BrepErrorCode.FILLET_NO_EDGES, "No edges with positive radius for fillet", void 0, void 0, "Check that the radius callback returns positive values"));
1263
1276
  filteredEdges = resolved.edges;
1264
1277
  kernelRadius = resolved.kernelParam;
@@ -1,13 +1,13 @@
1
- import { C as isSolid, D as getShapeKind, T as isWire, Y as getKernelCapabilities, h as disposeResultShape, i as castShape, m as disposeDowncastSource, n as castResultShape, q as getKernel, r as castResultShapeWithKnownType, x as isShape3D, y as isFace } from "./shapeTypes-Ckz9bpYW.js";
2
- import { j as isUnsupportedKernelOperationError, n as faultyEdgeIndexesOf } from "./occtWasmAdapter-CGsnjMOe.js";
1
+ import { C as isSolid, D as getShapeKind, T as isWire, Y as getKernelCapabilities, h as disposeResultShape, i as castShape, m as disposeDowncastSource, n as castResultShape, q as getKernel, r as castResultShapeWithKnownType, x as isShape3D, y as isFace } from "./shapeTypes-qhs8f2zx.js";
2
+ import { j as isUnsupportedKernelOperationError, n as faultyEdgeIndexesOf } from "./occtWasmAdapter-DD_6IAVj.js";
3
3
  import { E as ok, b as isErr, d as validationError, g as err, i as kernelError, l as typeCastError, t as BrepErrorCode, u as unsupportedError, x as isOk } from "./errors-BTccWbtE.js";
4
- import { C as subShapeHashes, O as getSuggestionForCode, c as getFaces, i as getCachedIsValid, m as invalidateShapeCache, p as getWires, s as getEdges } from "./topologyQueryFns-SINsBrMe.js";
4
+ import { C as subShapeHashes, O as getSuggestionForCode, c as getFaces, i as getCachedIsValid, m as invalidateShapeCache, p as getWires, s as getEdges } from "./topologyQueryFns-CArmw9sE.js";
5
5
  import { n as HASH_CODE_MAX } from "./constants-iraOnb2p.js";
6
- import { y as downcast } from "./faceFns-Dz3eRgNR.js";
7
- import { a as fuse, f as collectInputFaceHashes, h as propagateMetadataByHash, i as cutAll, m as propagateAllMetadata, n as copyAsBooleanResult, o as fuseAll, r as cut } from "./booleanFns-aGRfk4ud.js";
8
- import { a as isSameShape } from "./shapeFns-CHsoXWeu.js";
6
+ import { y as downcast } from "./faceFns-BNv6thpF.js";
7
+ import { a as fuse, f as collectInputFaceHashes, h as propagateMetadataByHash, i as cutAll, m as propagateAllMetadata, n as copyAsBooleanResult, o as fuseAll, r as cut } from "./booleanFns-DIqS3nBK.js";
8
+ import { a as isSameShape } from "./shapeFns-3NzCE2kz.js";
9
9
  import { t as firstOrThrow } from "./arrayAccess-BpgouNir.js";
10
- import { i as facesOfEdge } from "./adjacencyFns-XdjXKCXE.js";
10
+ import { i as facesOfEdge } from "./adjacencyFns-n6XWEyj1.js";
11
11
  // src/topology/threeHelpers.ts
12
12
  /**
13
13
  * Convert a ShapeMesh into BufferGeometry-compatible typed arrays.
@@ -213,28 +213,41 @@ function validateNotNull$1(shape, label) {
213
213
  if (getKernel().isNull(shape.wrapped)) return err(validationError(BrepErrorCode.NULL_SHAPE_INPUT, `${label} is a null shape`));
214
214
  return ok(void 0);
215
215
  }
216
+ function isPositivePair([a, b]) {
217
+ return a > 0 && b > 0;
218
+ }
216
219
  /**
217
- * Validate that a scalar or `[a, b]` pair is positive.
220
+ * A fillet's start and end radius: one may be 0, so the fillet runs out to
221
+ * nothing at that end of the edge, but not both, and neither below 0.
222
+ */
223
+ function isFilletRadiusPair([start, end]) {
224
+ return start >= 0 && end >= 0 && (start > 0 || end > 0);
225
+ }
226
+ var FILLET_PAIR_MESSAGE = "Fillet radii must not be negative, and one must be positive";
227
+ var FILLET_PAIR_HINT = "A radius may run to 0 at one end of the edge, but the other must be greater than 0";
228
+ /**
229
+ * Validate that a scalar is positive and that an `[a, b]` pair passes
230
+ * `isValidPair` (both positive by default).
218
231
  * Returns an Err Result on failure, `undefined` on success.
219
232
  *
220
233
  * Function-type values (per-edge callbacks) are intentionally skipped here --
221
234
  * they are validated lazily in {@link resolveEdgeCallback} when each edge is processed.
222
235
  */
223
- function validatePositiveParam(value, msgs) {
236
+ function validatePositiveParam(value, msgs, isValidPair = isPositivePair) {
224
237
  if (typeof value === "number" && value <= 0) return err(validationError(msgs.code, msgs.scalar, void 0, void 0, msgs.scalarHint));
225
- if (Array.isArray(value) && (value[0] <= 0 || value[1] <= 0)) return err(validationError(msgs.code, msgs.pair, void 0, void 0, msgs.pairHint));
238
+ if (Array.isArray(value) && !isValidPair(value)) return err(validationError(msgs.code, msgs.pair, void 0, void 0, msgs.pairHint));
226
239
  }
227
240
  /**
228
241
  * When the user supplies a per-edge callback, pre-filter edges and build a
229
242
  * hash-indexed lookup for the kernel. Returns `null` if no edges survive.
230
243
  */
231
- function resolveEdgeCallback$1(selectedEdges, callbackFn) {
244
+ function resolveEdgeCallback$1(selectedEdges, callbackFn, isValidPair = isPositivePair) {
232
245
  const filteredEdges = [];
233
246
  const hashToValue = /* @__PURE__ */ new Map();
234
247
  for (const edge of selectedEdges) {
235
248
  const val = callbackFn(edge) ?? 0;
236
249
  if (typeof val === "number" && val <= 0) continue;
237
- if (Array.isArray(val) && (val[0] <= 0 || val[1] <= 0)) continue;
250
+ if (Array.isArray(val) && !isValidPair(val)) continue;
238
251
  filteredEdges.push(edge);
239
252
  hashToValue.set(getKernel().hashCode(edge.wrapped, HASH_CODE_MAX), val);
240
253
  }
@@ -320,15 +333,15 @@ function normalizeFilletInputs(shape, edges, radius) {
320
333
  const paramErr = validatePositiveParam(radius, {
321
334
  code: "INVALID_FILLET_RADIUS",
322
335
  scalar: "Fillet radius must be positive",
323
- pair: "Fillet radii must both be positive",
336
+ pair: FILLET_PAIR_MESSAGE,
324
337
  scalarHint: "Provide a positive radius value greater than 0",
325
- pairHint: "Both radius values must be greater than 0"
326
- });
338
+ pairHint: FILLET_PAIR_HINT
339
+ }, isFilletRadiusPair);
327
340
  if (paramErr) return paramErr;
328
341
  const selectedEdges = edges ?? getEdges(shape);
329
342
  if (selectedEdges.length === 0) return err(validationError(BrepErrorCode.FILLET_NO_EDGES, "No edges found for fillet", void 0, void 0, "Check that the shape has edges, or adjust your edge finder criteria"));
330
343
  if (typeof radius === "function") {
331
- const resolved = resolveEdgeCallback$1(selectedEdges, radius);
344
+ const resolved = resolveEdgeCallback$1(selectedEdges, radius, isFilletRadiusPair);
332
345
  if (!resolved) return err(validationError(BrepErrorCode.FILLET_NO_EDGES, "No edges with positive radius for fillet", void 0, void 0, "Check that the radius callback returns positive values"));
333
346
  return ok({
334
347
  filteredEdges: resolved.edges,
@@ -377,8 +390,7 @@ function fillet(shape, edges, radius, { trackEvolution = true } = {}) {
377
390
  }
378
391
  /**
379
392
  * `UNSUPPORTED_CAPABILITY` for a fillet the kernel cannot build as asked (a
380
- * radius that varies along an edge on brepkit), from its
381
- * `UnsupportedKernelOperationError`.
393
+ * multi-point variable radius), from its `UnsupportedKernelOperationError`.
382
394
  */
383
395
  function filletUnsupportedError(e) {
384
396
  const kernelId = getKernel().kernelId;
@@ -386,7 +398,7 @@ function filletUnsupportedError(e) {
386
398
  return unsupportedError(BrepErrorCode.UNSUPPORTED_CAPABILITY, `fillet: the ${kernelId} kernel cannot build this fillet (${raw})`, e, {
387
399
  kernel: kernelId,
388
400
  operation: "fillet"
389
- }, "Use one constant radius per edge, or use the occt-wasm kernel");
401
+ }, "Use a constant or linear (start, end) radius per edge");
390
402
  }
391
403
  /**
392
404
  * `FILLET_FAILED` / `CHAMFER_FAILED`, with `metadata.failedEdges` set to the
@@ -595,15 +607,16 @@ function draft(shape, faces, pullDirection, neutralPlane, angle) {
595
607
  *
596
608
  * The radius varies along the edge according to the provided spec points.
597
609
  * Each point specifies a normalized parameter (0 = start, 1 = end) and radius.
610
+ * A radius may be 0, so the fillet runs out to nothing there, as long as one
611
+ * is positive.
598
612
  *
599
- * **Cross-kernel note:** occt-wasm supports a linear (start/end, <=2-point)
600
- * profile; brepkit supports only a constant radius. Either returns
601
- * `UNSUPPORTED_CAPABILITY` for a profile it cannot build. The opencascade.js
602
- * kernel does not implement it.
613
+ * **Cross-kernel note:** occt-wasm and brepkit build a constant or linear
614
+ * (start/end, <=2-point) profile and return `UNSUPPORTED_CAPABILITY` for one of
615
+ * more points. The opencascade.js kernel does not implement it.
603
616
  */
604
617
  function variableFillet(shape, edge, radii) {
605
618
  if (radii.length === 0) return err(validationError(BrepErrorCode.VARIABLE_FILLET_FAILED, "radii must contain at least one radius spec"));
606
- for (const r of radii) if (r.radius <= 0) return err(validationError(BrepErrorCode.VARIABLE_FILLET_FAILED, "All radius values must be positive"));
619
+ if (radii.some((r) => r.radius < 0) || radii.every((r) => r.radius === 0)) return err(validationError(BrepErrorCode.VARIABLE_FILLET_FAILED, "Radius values must not be negative, and one must be positive"));
607
620
  const kernel = getKernel();
608
621
  try {
609
622
  const spec = JSON.stringify({
@@ -1155,13 +1168,13 @@ function castToShape3D(shape, errorCode, errorMsg, suggestion) {
1155
1168
  disposeDowncastSource(shape, wrapped);
1156
1169
  return ok(wrapped);
1157
1170
  }
1158
- function resolveEdgeCallback(selectedEdges, callbackFn) {
1171
+ function resolveEdgeCallback(selectedEdges, callbackFn, isValidPair = ([a, b]) => a > 0 && b > 0) {
1159
1172
  const filteredEdges = [];
1160
1173
  const hashToValue = /* @__PURE__ */ new Map();
1161
1174
  for (const edge of selectedEdges) {
1162
1175
  const val = callbackFn(edge) ?? 0;
1163
1176
  if (typeof val === "number" && val <= 0) continue;
1164
- if (Array.isArray(val) && (val[0] <= 0 || val[1] <= 0)) continue;
1177
+ if (Array.isArray(val) && !isValidPair(val)) continue;
1165
1178
  filteredEdges.push(edge);
1166
1179
  hashToValue.set(getKernel().hashCode(edge.wrapped, HASH_CODE_MAX), val);
1167
1180
  }
@@ -1251,14 +1264,14 @@ function filletWithEvolution(shape, edges, radius) {
1251
1264
  const check = validateNotNull(shape, "filletWithEvolution: shape");
1252
1265
  if (isErr(check)) return check;
1253
1266
  if (typeof radius === "number" && radius <= 0) return err(validationError("INVALID_FILLET_RADIUS", "Fillet radius must be positive", void 0, void 0, "Provide a positive radius value greater than 0"));
1254
- if (Array.isArray(radius) && (radius[0] <= 0 || radius[1] <= 0)) return err(validationError("INVALID_FILLET_RADIUS", "Fillet radii must both be positive", void 0, void 0, "Both radius values must be greater than 0"));
1267
+ if (Array.isArray(radius) && !isFilletRadiusPair(radius)) return err(validationError("INVALID_FILLET_RADIUS", FILLET_PAIR_MESSAGE, void 0, void 0, FILLET_PAIR_HINT));
1255
1268
  const selectedEdges = edges ?? getEdges(shape);
1256
1269
  if (selectedEdges.length === 0) return err(validationError(BrepErrorCode.FILLET_NO_EDGES, "No edges found for fillet", void 0, void 0, "Check that the shape has edges, or adjust your edge finder criteria"));
1257
1270
  try {
1258
1271
  let filteredEdges;
1259
1272
  let kernelRadius;
1260
1273
  if (typeof radius === "function") {
1261
- const resolved = resolveEdgeCallback(selectedEdges, radius);
1274
+ const resolved = resolveEdgeCallback(selectedEdges, radius, isFilletRadiusPair);
1262
1275
  if (!resolved) return err(validationError(BrepErrorCode.FILLET_NO_EDGES, "No edges with positive radius for fillet", void 0, void 0, "Check that the radius callback returns positive values"));
1263
1276
  filteredEdges = resolved.edges;
1264
1277
  kernelRadius = resolved.kernelParam;
@@ -1,12 +1,12 @@
1
- const require_shapeTypes = require("./shapeTypes-BK53GmLC.cjs");
1
+ const require_shapeTypes = require("./shapeTypes-CgayxMvX.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-EI-aso9K.cjs");
4
4
  const require_constants = require("./constants-oee0S_x6.cjs");
5
5
  const require_vecOps = require("./vecOps-CrGEPPQM.cjs");
6
- const require_faceFns = require("./faceFns-DfEUZlnf.cjs");
7
- const require_shapeFns = require("./shapeFns-C9P1KmqH.cjs");
8
- const require_curveFns = require("./curveFns-Dz36SOE6.cjs");
9
- const require_measureFns = require("./measureFns-CmKNZ0gC.cjs");
6
+ const require_faceFns = require("./faceFns-CPGJ_cx6.cjs");
7
+ const require_shapeFns = require("./shapeFns-Cklw3p3S.cjs");
8
+ const require_curveFns = require("./curveFns-m73YVbFb.cjs");
9
+ const require_measureFns = require("./measureFns-CpoPgAZt.cjs");
10
10
  // src/utils/vec2d.ts
11
11
  /** Precision for curve intersection and parameter operations. */
12
12
  var PRECISION_INTERSECTION = 1e-9;
@@ -1,12 +1,12 @@
1
- import { q as getKernel, y as isFace } from "./shapeTypes-Ckz9bpYW.js";
1
+ import { q as getKernel, y as isFace } from "./shapeTypes-qhs8f2zx.js";
2
2
  import { E as ok, g as err, o as queryError, x as isOk } from "./errors-BTccWbtE.js";
3
- import { c as getFaces, f as getVertices, p as getWires, s as getEdges } from "./topologyQueryFns-SINsBrMe.js";
3
+ import { c as getFaces, f as getVertices, p as getWires, s as getEdges } from "./topologyQueryFns-CArmw9sE.js";
4
4
  import { t as DEG2RAD } from "./constants-iraOnb2p.js";
5
5
  import { a as vecDot, d as vecNormalize } from "./vecOps-S-m9H_fe.js";
6
- import { l as normalAt, s as getSurfaceType } from "./faceFns-Dz3eRgNR.js";
7
- import { a as isSameShape, n as getHashCode } from "./shapeFns-CHsoXWeu.js";
8
- import { f as getCurveType, i as curveIsClosed, o as curveLength } from "./curveFns-Cnh0Hljx.js";
9
- import { r as measureArea } from "./measureFns-6mHYvqUc.js";
6
+ import { l as normalAt, s as getSurfaceType } from "./faceFns-BNv6thpF.js";
7
+ import { a as isSameShape, n as getHashCode } from "./shapeFns-3NzCE2kz.js";
8
+ import { f as getCurveType, i as curveIsClosed, o as curveLength } from "./curveFns-CGQCy_D5.js";
9
+ import { r as measureArea } from "./measureFns-MSr05_kf.js";
10
10
  // src/utils/vec2d.ts
11
11
  /** Precision for curve intersection and parameter operations. */
12
12
  var PRECISION_INTERSECTION = 1e-9;
@@ -1,12 +1,12 @@
1
- import { C as isSolid, G as _usingCtx, S as isShell, _ as isCompound, n as castResultShape, q as getKernel } from "./shapeTypes-Ckz9bpYW.js";
1
+ import { C as isSolid, G as _usingCtx, S as isShell, _ as isCompound, n as castResultShape, q as getKernel } from "./shapeTypes-qhs8f2zx.js";
2
2
  import { i as wasmIndex, r as vec3At$1 } from "./bug-ClMTAJhe.js";
3
3
  import { E as ok, g as err, r as ioError, t as BrepErrorCode } from "./errors-BTccWbtE.js";
4
- import { S as subShapeCount, c as getFaces, u as getShells } from "./topologyQueryFns-SINsBrMe.js";
4
+ import { S as subShapeCount, c as getFaces, u as getShells } from "./topologyQueryFns-CArmw9sE.js";
5
5
  import { n as HASH_CODE_MAX } from "./constants-iraOnb2p.js";
6
- import { t as makeCompound } from "./solidBuilders-DMfqtfIG.js";
7
- import { u as igesUnsupportedError } from "./meshFns-D29JHTr6.js";
6
+ import { t as makeCompound } from "./solidBuilders-DhDGnOTQ.js";
7
+ import { u as igesUnsupportedError } from "./meshFns-BIWD7IFN.js";
8
8
  import { n as getAtOrThrow } from "./arrayAccess-BpgouNir.js";
9
- import { c as make2dBezierCurve, h as make2dThreePointArc, p as make2dSegmentCurve, t as Blueprint } from "./blueprint-WAucCqwY.js";
9
+ import { c as make2dBezierCurve, h as make2dThreePointArc, p as make2dSegmentCurve, t as Blueprint } from "./blueprint-2j8szIQ6.js";
10
10
  // src/io/objExportFns.ts
11
11
  /** Read a vec3 from a typed array at the given vertex index. */
12
12
  function vec3At(arr, i) {
@@ -1,12 +1,12 @@
1
- const require_shapeTypes = require("./shapeTypes-BK53GmLC.cjs");
1
+ const require_shapeTypes = require("./shapeTypes-CgayxMvX.cjs");
2
2
  const require_bug = require("./bug-CBcpIPuf.cjs");
3
3
  const require_errors = require("./errors-O_blYTWT.cjs");
4
- const require_topologyQueryFns = require("./topologyQueryFns--p_-tywe.cjs");
4
+ const require_topologyQueryFns = require("./topologyQueryFns-EI-aso9K.cjs");
5
5
  const require_constants = require("./constants-oee0S_x6.cjs");
6
- const require_solidBuilders = require("./solidBuilders-CETSjBW2.cjs");
7
- const require_meshFns = require("./meshFns-BFgQZGty.cjs");
6
+ const require_solidBuilders = require("./solidBuilders-BvIdZUkI.cjs");
7
+ const require_meshFns = require("./meshFns-BxRKwY5z.cjs");
8
8
  const require_arrayAccess = require("./arrayAccess-DpJYARwv.cjs");
9
- const require_blueprint = require("./blueprint-DzhzGFy2.cjs");
9
+ const require_blueprint = require("./blueprint-Cfj9EupK.cjs");
10
10
  // src/io/objExportFns.ts
11
11
  /** Read a vec3 from a typed array at the given vertex index. */
12
12
  function vec3At(arr, i) {
package/dist/io.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_meshFns = require("./meshFns-BFgQZGty.cjs");
3
- const require_importFns = require("./importFns-Sp5phi5Y.cjs");
2
+ const require_meshFns = require("./meshFns-BxRKwY5z.cjs");
3
+ const require_importFns = require("./importFns-zfbC3bIK.cjs");
4
4
  exports.blueprintToDXF = require_importFns.blueprintToDXF;
5
5
  exports.exportDXF = require_importFns.exportDXF;
6
6
  exports.exportGlb = require_importFns.exportGlb;
package/dist/io.js CHANGED
@@ -1,3 +1,3 @@
1
- import { n as exportSTEP, r as exportSTL, t as exportIGES } from "./meshFns-D29JHTr6.js";
2
- import { a as exportSTEPConfigured, c as exportThreeMF, d as exportGlb, f as exportGltf, l as blueprintToDXF, n as importSTEP, o as importSVG, p as exportOBJ, r as importSTL, s as importSVGPathD, t as importIGES, u as exportDXF } from "./importFns-BVcmm3T0.js";
1
+ import { n as exportSTEP, r as exportSTL, t as exportIGES } from "./meshFns-BIWD7IFN.js";
2
+ import { a as exportSTEPConfigured, c as exportThreeMF, d as exportGlb, f as exportGltf, l as blueprintToDXF, n as importSTEP, o as importSVG, p as exportOBJ, r as importSTL, s as importSVGPathD, t as importIGES, u as exportDXF } from "./importFns-DQgcQQCb.js";
3
3
  export { blueprintToDXF, exportDXF, exportGlb, exportGltf, exportIGES, exportOBJ, exportSTEP, exportSTEPConfigured, exportSTL, exportThreeMF, importIGES, importSTEP, importSTL, importSVG, importSVGPathD };
@@ -2,7 +2,7 @@
2
2
  * Type-safe interface for the brepkit WASM kernel (`BrepKernel`).
3
3
  *
4
4
  * AUTO-GENERATED by `npm run sync:brepkit-types`.
5
- * Synced against `brepkit-wasm@4.6.7`.
5
+ * Synced against `brepkit-wasm@4.6.9`.
6
6
  *
7
7
  * Methods not yet referenced in the adapter layer are tagged `@unwired`.
8
8
  *
@@ -109,7 +109,6 @@ export interface BrepkitKernel {
109
109
  fillet(solid: number, edgeHandles: Uint32Array | number[], radius: number): number;
110
110
  /** @unwired */
111
111
  filletV2(solid: number, edgeHandles: Uint32Array | number[], radius: number): number;
112
- /** @unwired */
113
112
  filletVariable(solid: number, json: string): number;
114
113
  chamfer(solid: number, edgeHandles: Uint32Array | number[], distance: number): number;
115
114
  chamferV2(solid: number, edgeHandles: Uint32Array | number[], d1: number, d2: number): number;
@@ -309,10 +308,8 @@ export interface BrepkitKernel {
309
308
  getNurbsSurfaceDataParity(face: number): string;
310
309
  /** @unwired */
311
310
  getNurbsSurfaceData(face: number): string;
312
- /** @unwired */
313
311
  getSolidPieces(solid: number): Uint32Array;
314
312
  getSolidShells(solid: number): Uint32Array;
315
- /** @unwired */
316
313
  guidedSweep(face: number, spineDegree: number, spineKnots: Float64Array | number[], spineControlPoints: Float64Array | number[], spineWeights: Float64Array | number[], auxDegree: number, auxKnots: Float64Array | number[], auxControlPoints: Float64Array | number[], auxWeights: Float64Array | number[]): number;
317
314
  intersectWithOptions(a: number, b: number, simplify: boolean): number;
318
315
  /** @unwired */
@@ -330,7 +327,6 @@ export interface BrepkitKernel {
330
327
  multiSectionSweep(faceHandles: Uint32Array | number[], params: Float64Array | number[], spineDegree: number, spineKnots: Float64Array | number[], spineControlPoints: Float64Array | number[], spineWeights: Float64Array | number[], ruled: boolean): number;
331
328
  offsetWire2DWithJoin(wire: number, distance: number, joinType: string): number;
332
329
  projectEdges(solid: number, originX: number, originY: number, originZ: number, dirX: number, dirY: number, dirZ: number, xAxisX: number, xAxisY: number, xAxisZ: number, hiddenLines: boolean, deflection: number): string;
333
- /** @unwired */
334
330
  projectSolidsEdges(solids: Uint32Array | number[], originX: number, originY: number, originZ: number, dirX: number, dirY: number, dirZ: number, xAxisX: number, xAxisY: number, xAxisZ: number, hiddenLines: boolean, deflection: number): string;
335
331
  /** @unwired */
336
332
  serializeSolid(solid: number): Uint8Array;
@@ -339,11 +335,11 @@ export interface BrepkitKernel {
339
335
  /** @unwired */
340
336
  toBrepJson(solid: number): string;
341
337
  transformFace(face: number, matrix: Float64Array | number[]): void;
342
- /** @future Not in brepkit-wasm 4.6.7. Referenced with feature detection in adapter. */
338
+ /** @future Not in brepkit-wasm 4.6.9. Referenced with feature detection in adapter. */
343
339
  copyEdge?(edge: number): number;
344
- /** @future Not in brepkit-wasm 4.6.7. Referenced with feature detection in adapter. */
340
+ /** @future Not in brepkit-wasm 4.6.9. Referenced with feature detection in adapter. */
345
341
  transformEdge?(edge: number, matrix: Float64Array | number[]): void;
346
- /** @future Not in brepkit-wasm 4.6.7. Referenced with feature detection in adapter. */
342
+ /** @future Not in brepkit-wasm 4.6.9. Referenced with feature detection in adapter. */
347
343
  validateSolidDetails?(solid: number): string;
348
344
  /** Release the entire arena. */
349
345
  free(): void;
@@ -25,7 +25,7 @@ export declare function makeEllipseEdge(bk: BrepkitKernel, center: [number, numb
25
25
  export declare function makeEllipseArc(bk: BrepkitKernel, center: [number, number, number], normal: [number, number, number], majorRadius: number, minorRadius: number, startAngle: number, endAngle: number, xDir?: [number, number, number]): KernelShape;
26
26
  export declare function makeBezierEdge(bk: BrepkitKernel, points: [number, number, number][]): KernelShape;
27
27
  export declare function makeTangentArc(bk: BrepkitKernel, startPoint: [number, number, number], startTangent: [number, number, number], endPoint: [number, number, number]): KernelShape;
28
- export declare function makeHelixWire(bk: BrepkitKernel, pitch: number, height: number, radius: number, center?: [number, number, number], _direction?: [number, number, number], leftHanded?: boolean): KernelShape;
28
+ export declare function makeHelixWire(bk: BrepkitKernel, pitch: number, height: number, radius: number, center?: [number, number, number], direction?: [number, number, number], leftHanded?: boolean): KernelShape;
29
29
  export declare function makeWireFromMixed(bk: BrepkitKernel, items: KernelShape[]): KernelShape;
30
30
  export declare function makeCompound(bk: BrepkitKernel, shapes: KernelShape[]): KernelShape;
31
31
  export declare function makeBoxFromCorners(bk: BrepkitKernel, p1: [number, number, number], p2: [number, number, number]): KernelShape;
@@ -3,9 +3,9 @@ import { KernelShape } from '../types.js';
3
3
  export declare function fillet(bk: BrepkitKernel, shape: KernelShape, edges: KernelShape[], radius: number | [number, number] | ((edge: KernelShape) => number | [number, number])): KernelShape;
4
4
  /**
5
5
  * A variable fillet spec on one edge: `{ edge: hashCode, radii: [{ param, radius }] }`
6
- * from variableFillet, or `{ edgeId, startRadius, endRadius }`. A constant radius is
7
- * an ordinary fillet; a radius that varies is unsupported (see
8
- * {@link varyingFilletUnsupported}).
6
+ * from variableFillet, or `{ edgeId, startRadius, endRadius }`. Like occt-wasm, a
7
+ * profile runs linearly from its first radius to its last, so one of more than two
8
+ * points is unsupported rather than flattened to a line.
9
9
  */
10
10
  export declare function filletVariable(bk: BrepkitKernel, shape: KernelShape, spec: string): KernelShape;
11
11
  export declare function chamfer(bk: BrepkitKernel, shape: KernelShape, edges: KernelShape[], distance: number | [number, number] | ((edge: KernelShape) => number | [number, number])): KernelShape;
@@ -28,13 +28,23 @@ export declare function multiplyMatrices4x4(a: number[], b: number[]): number[];
28
28
  /** A fillet's start and end radius, or a chamfer's two setbacks. A number is both. */
29
29
  type EdgeValue = number | [number, number];
30
30
  export type EdgeValueSpec = EdgeValue | ((edge: KernelShape) => EdgeValue);
31
+ /** Per-edge values as parallel arrays, one entry per edge. */
32
+ interface EdgeValues {
33
+ readonly first: number[];
34
+ readonly second: number[];
35
+ }
36
+ /**
37
+ * occt-wasm's fillet entry points take only positive radii, though its
38
+ * single-edge filletVariable builds a fillet that runs out to a radius of 0.
39
+ */
40
+ export declare function refuseVanishingFilletRadius({ first, second }: EdgeValues): void;
31
41
  /**
32
42
  * Run a fillet or chamfer over `edges`, naming the edges it fails on. Edges
33
43
  * that all take one value go to `uniform`, the single-value entry point every
34
44
  * occt-wasm build has; otherwise `perEdge` gets each edge's pair as `first`
35
- * and `second`.
45
+ * and `second`. `check` sees the resolved values first and throws to refuse them.
36
46
  */
37
- export declare function runEdgeTreatment<T>(Module: OcctWasmModule, edges: KernelShape[], value: EdgeValueSpec, uniform: (edgeVec: EmVectorUint32, value: number) => T, perEdge: (edgeVec: EmVectorUint32, first: EmVectorDouble, second: EmVectorDouble) => T): T;
47
+ export declare function runEdgeTreatment<T>(Module: OcctWasmModule, edges: KernelShape[], value: EdgeValueSpec, uniform: (edgeVec: EmVectorUint32, value: number) => T, perEdge: (edgeVec: EmVectorUint32, first: EmVectorDouble, second: EmVectorDouble) => T, check?: (values: EdgeValues) => void): T;
38
48
  /**
39
49
  * A per-edge chamfer's `referenceFaceIds`: empty when no edge names its
40
50
  * reference face, else one id per edge, 0 where the facade picks the face.
@@ -1,3 +1,3 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_occtWasmAdapter = require("../../occtWasmAdapter-4YnvqZOW.cjs");
2
+ const require_occtWasmAdapter = require("../../occtWasmAdapter-BH1JcAgl.cjs");
3
3
  exports.OcctWasmAdapter = require_occtWasmAdapter.OcctWasmAdapter;
@@ -1 +1 @@
1
- export { t as OcctWasmAdapter } from "../../occtWasmAdapter-CGsnjMOe.js";
1
+ export { t as OcctWasmAdapter } from "../../occtWasmAdapter-DD_6IAVj.js";
@@ -1,5 +1,5 @@
1
- const require_shapeTypes = require("./shapeTypes-BK53GmLC.cjs");
2
- const require_occtWasmAdapter = require("./occtWasmAdapter-4YnvqZOW.cjs");
1
+ const require_shapeTypes = require("./shapeTypes-CgayxMvX.cjs");
2
+ const require_occtWasmAdapter = require("./occtWasmAdapter-BH1JcAgl.cjs");
3
3
  const require_errors = require("./errors-O_blYTWT.cjs");
4
4
  const require_types = require("./types-CjF9Rofr.cjs");
5
5
  const require_vecOps = require("./vecOps-CrGEPPQM.cjs");
@@ -82,13 +82,13 @@ function castSweepShellTuple(result) {
82
82
  endWire
83
83
  ]);
84
84
  }
85
- /** `UNSUPPORTED_CAPABILITY` for a sweep option the kernel cannot build (a twist or a scaling law on brepkit). */
85
+ /** `UNSUPPORTED_CAPABILITY` for a sweep option the kernel cannot build (a scaling law on brepkit). */
86
86
  function sweepUnsupportedError(kernelId, e) {
87
87
  const raw = e instanceof Error ? e.message : String(e);
88
88
  return require_errors.unsupportedError(require_errors.BrepErrorCode.UNSUPPORTED_CAPABILITY, `sweep: the ${kernelId} kernel cannot build this sweep (${raw})`, e, {
89
89
  kernel: kernelId,
90
90
  operation: "sweep"
91
- }, "Drop the twist or scaling law, or use the occt-wasm kernel");
91
+ }, "Drop the scaling law, or use the occt-wasm kernel");
92
92
  }
93
93
  function sweep(wire, spine, config = {}, shellMode = false) {
94
94
  if (config.mode === "simple" && !shellMode) {
@@ -1,5 +1,5 @@
1
- import { G as _usingCtx, T as isWire, h as disposeResultShape, n as castResultShape, q as getKernel, x as isShape3D } from "./shapeTypes-Ckz9bpYW.js";
2
- import { j as isUnsupportedKernelOperationError } from "./occtWasmAdapter-CGsnjMOe.js";
1
+ import { G as _usingCtx, T as isWire, h as disposeResultShape, n as castResultShape, q as getKernel, x as isShape3D } from "./shapeTypes-qhs8f2zx.js";
2
+ import { j as isUnsupportedKernelOperationError } from "./occtWasmAdapter-DD_6IAVj.js";
3
3
  import { E as ok, b as isErr, d as validationError, g as err, i as kernelError, l as typeCastError, t as BrepErrorCode, u as unsupportedError } from "./errors-BTccWbtE.js";
4
4
  import { r as toVec3 } from "./types-CKXsIm9-.js";
5
5
  import { c as vecLength, t as vecAdd } from "./vecOps-S-m9H_fe.js";
@@ -82,13 +82,13 @@ function castSweepShellTuple(result) {
82
82
  endWire
83
83
  ]);
84
84
  }
85
- /** `UNSUPPORTED_CAPABILITY` for a sweep option the kernel cannot build (a twist or a scaling law on brepkit). */
85
+ /** `UNSUPPORTED_CAPABILITY` for a sweep option the kernel cannot build (a scaling law on brepkit). */
86
86
  function sweepUnsupportedError(kernelId, e) {
87
87
  const raw = e instanceof Error ? e.message : String(e);
88
88
  return unsupportedError(BrepErrorCode.UNSUPPORTED_CAPABILITY, `sweep: the ${kernelId} kernel cannot build this sweep (${raw})`, e, {
89
89
  kernel: kernelId,
90
90
  operation: "sweep"
91
- }, "Drop the twist or scaling law, or use the occt-wasm kernel");
91
+ }, "Drop the scaling law, or use the occt-wasm kernel");
92
92
  }
93
93
  function sweep(wire, spine, config = {}, shellMode = false) {
94
94
  if (config.mode === "simple" && !shellMode) {