brepjs 18.63.0 → 18.65.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 (77) hide show
  1. package/dist/2d.cjs +6 -6
  2. package/dist/2d.js +6 -6
  3. package/dist/{blueprint-DaRszQg-.js → blueprint-1wDhBDmB.js} +5 -5
  4. package/dist/{blueprint-XEJiK6ON.cjs → blueprint-smNMCQA1.cjs} +5 -5
  5. package/dist/{blueprintFns-C0ULkqGT.js → blueprintFns-DeCDdsDz.js} +2 -2
  6. package/dist/{blueprintFns-CTJGTMYw.cjs → blueprintFns-DkHfzzv0.cjs} +2 -2
  7. package/dist/{blueprintSketcher-DHWmjOmJ.js → blueprintSketcher-BL85kdgo.js} +3 -3
  8. package/dist/{blueprintSketcher-r0uUFBZZ.cjs → blueprintSketcher-Bpd7nMHt.cjs} +3 -3
  9. package/dist/{boolean2D-BT3RGDXW.cjs → boolean2D-CHu_3RIB.cjs} +4 -4
  10. package/dist/{boolean2D-BfavHsXe.js → boolean2D-CWgORqab.js} +4 -4
  11. package/dist/{booleanFns-B3vIRhjz.cjs → booleanFns-C9olM-r4.cjs} +4 -4
  12. package/dist/{booleanFns-DNG6xxu8.js → booleanFns-ogc1TMXG.js} +4 -4
  13. package/dist/brepjs.cjs +24 -24
  14. package/dist/brepjs.js +24 -24
  15. package/dist/{cameraFns-CQkS1TSY.js → cameraFns-9SLctf9O.js} +2 -2
  16. package/dist/{cameraFns-CqplcvtL.cjs → cameraFns-Za6Rsnmg.cjs} +2 -2
  17. package/dist/core.cjs +1 -1
  18. package/dist/core.js +1 -1
  19. package/dist/{cornerFinder-ByEss8KB.cjs → cornerFinder-CUhZgX6X.cjs} +1 -1
  20. package/dist/{cornerFinder-CE1b1IMu.js → cornerFinder-Cchldpsv.js} +1 -1
  21. package/dist/{curveFns-vZbW7CVb.js → curveFns-DH5NpaKO.js} +1 -1
  22. package/dist/{curveFns-Dx9ha0n_.cjs → curveFns-DR68aqxR.cjs} +1 -1
  23. package/dist/{drawFns-DiJFFH16.js → drawFns-Cq6bAjFC.js} +12 -12
  24. package/dist/{drawFns-ZPhrUGWl.cjs → drawFns-DPE6EU_v.cjs} +12 -12
  25. package/dist/{extrudeFns-BamV4cSU.js → extrudeFns-DZEN4PPg.js} +1 -1
  26. package/dist/{extrudeFns-DsvQYfqd.cjs → extrudeFns-yfUN1m7e.cjs} +1 -1
  27. package/dist/{faceFns-LJ_lU5IE.js → faceFns-Qrz3lIDv.js} +2 -2
  28. package/dist/{faceFns-DGmQI57P.cjs → faceFns-_m0px2ug.cjs} +2 -2
  29. package/dist/{helpers-B6abm0X7.cjs → helpers-BXiYZ2Dl.cjs} +6 -6
  30. package/dist/{helpers-CxZqc5vt.js → helpers-Bk538__I.js} +6 -6
  31. package/dist/{historyFns-a2plj33G.cjs → historyFns-B-R48Dze.cjs} +4 -4
  32. package/dist/{historyFns-DpHCn1yw.js → historyFns-BJKkvynn.js} +4 -4
  33. package/dist/{importFns-CEz6N0mP.js → importFns-Cid57qQ1.js} +2 -2
  34. package/dist/{importFns-iJZHFevB.cjs → importFns-D8EPeKcC.cjs} +2 -2
  35. package/dist/io.cjs +2 -2
  36. package/dist/io.js +2 -2
  37. package/dist/kernel/manifold/curveDesc.d.ts +54 -0
  38. package/dist/kernel/manifold/profileOps.d.ts +2 -1
  39. package/dist/{measureFns-1vEKylTt.js → measureFns-95m36tbx.js} +3 -3
  40. package/dist/{measureFns-CvAOj_Io.cjs → measureFns-CqSFeI4R.cjs} +3 -3
  41. package/dist/measurement.cjs +1 -1
  42. package/dist/measurement.js +1 -1
  43. package/dist/{meshFns-CoPoc7dh.js → meshFns-BCggXbKk.js} +3 -3
  44. package/dist/{meshFns-D2rlqrTt.cjs → meshFns-CR8dRmoo.cjs} +3 -3
  45. package/dist/operations.cjs +2 -2
  46. package/dist/operations.js +2 -2
  47. package/dist/{primitiveFns-Bi22B25-.cjs → primitiveFns-DFsImECE.cjs} +7 -7
  48. package/dist/{primitiveFns-OuEHerl6.js → primitiveFns-Fy3scr-a.js} +7 -7
  49. package/dist/projection.cjs +1 -1
  50. package/dist/projection.js +1 -1
  51. package/dist/query.cjs +2 -2
  52. package/dist/query.js +2 -2
  53. package/dist/{shapeFns-C3wVDhtn.js → shapeFns-Ct1lekCK.js} +2 -2
  54. package/dist/{shapeFns-n4A9y80v.cjs → shapeFns-DNqkQ2yJ.cjs} +2 -2
  55. package/dist/shapeRef.cjs +1 -1
  56. package/dist/shapeRef.js +1 -1
  57. package/dist/{shapeRefFns-eqCfRF0P.cjs → shapeRefFns-BB9iWqZb.cjs} +4 -4
  58. package/dist/{shapeRefFns-CUt56Cul.js → shapeRefFns-CZqzvMgX.js} +4 -4
  59. package/dist/{shapeTypes-9yfC5Z8_.js → shapeTypes-C-32Klnb.js} +369 -31
  60. package/dist/{shapeTypes-C_liO43e.cjs → shapeTypes-DAhE_41P.cjs} +369 -31
  61. package/dist/sketching.cjs +3 -3
  62. package/dist/sketching.js +3 -3
  63. package/dist/{solidBuilders-DSAmLmHd.js → solidBuilders-B-gb9ZsJ.js} +2 -2
  64. package/dist/{solidBuilders-BtfspzpT.cjs → solidBuilders-iapbn6CO.cjs} +2 -2
  65. package/dist/{surfaceBuilders-6BfGn0MN.cjs → surfaceBuilders-B9kzwe0E.cjs} +2 -2
  66. package/dist/{surfaceBuilders-ChWLM9Io.js → surfaceBuilders-Cwecm13F.js} +2 -2
  67. package/dist/text.cjs +2 -2
  68. package/dist/text.js +2 -2
  69. package/dist/{textBlueprints-DTaz774E.cjs → textBlueprints-7KWxP1zT.cjs} +7 -7
  70. package/dist/{textBlueprints-B_RYPM3J.js → textBlueprints-CyIv54Ac.js} +7 -7
  71. package/dist/{textMetrics-CEBrAzpE.cjs → textMetrics-BXoJfZKn.cjs} +1 -1
  72. package/dist/{textMetrics-RRDn50ym.js → textMetrics-D740OLnV.js} +1 -1
  73. package/dist/topology.cjs +7 -7
  74. package/dist/topology.js +7 -7
  75. package/dist/{topologyQueryFns-nbhh_XJF.js → topologyQueryFns-C0yUIRDE.js} +1 -1
  76. package/dist/{topologyQueryFns-B6BTVGLX.cjs → topologyQueryFns-CBVVRWvE.cjs} +1 -1
  77. package/package.json +1 -1
@@ -10070,8 +10070,8 @@ function translationMatrix(x, y, z) {
10070
10070
  m[14] = z;
10071
10071
  return m;
10072
10072
  }
10073
- function rotationMatrix(angleDeg, axis, center) {
10074
- const rad = angleDeg * Math.PI / 180;
10073
+ function rotationMatrix(angleRad, axis, center) {
10074
+ const rad = angleRad;
10075
10075
  const [ax, ay, az] = normalizeAxis(axis);
10076
10076
  const c = Math.cos(rad);
10077
10077
  const s = Math.sin(rad);
@@ -10301,6 +10301,171 @@ function multiplyMatrix(a, b) {
10301
10301
  return out;
10302
10302
  }
10303
10303
  //#endregion
10304
+ //#region src/kernel/manifold/curveDesc.ts
10305
+ var TAU = 2 * Math.PI;
10306
+ var hypot3 = (a) => Math.hypot(a[0], a[1], a[2]);
10307
+ var sub3 = (a, b) => [
10308
+ a[0] - b[0],
10309
+ a[1] - b[1],
10310
+ a[2] - b[2]
10311
+ ];
10312
+ function lineLen(d) {
10313
+ return hypot3(sub3(d.p2, d.p1));
10314
+ }
10315
+ function bezierAt$1(points, t) {
10316
+ const tmp = points.map((p) => [
10317
+ p[0],
10318
+ p[1],
10319
+ p[2]
10320
+ ]);
10321
+ for (let k = 1; k < tmp.length; k++) for (let i = 0; i < tmp.length - k; i++) {
10322
+ const a = tmp[i] ?? [
10323
+ 0,
10324
+ 0,
10325
+ 0
10326
+ ];
10327
+ const b = tmp[i + 1] ?? [
10328
+ 0,
10329
+ 0,
10330
+ 0
10331
+ ];
10332
+ tmp[i] = [
10333
+ a[0] * (1 - t) + b[0] * t,
10334
+ a[1] * (1 - t) + b[1] * t,
10335
+ a[2] * (1 - t) + b[2] * t
10336
+ ];
10337
+ }
10338
+ return tmp[0] ?? [
10339
+ 0,
10340
+ 0,
10341
+ 0
10342
+ ];
10343
+ }
10344
+ function descType(d) {
10345
+ if (d.k === "line") return "LINE";
10346
+ if (d.k === "bezier") return "BEZIER";
10347
+ if (d.k === "helix") return "BSPLINE";
10348
+ return Math.abs(d.rx - d.ry) < 1e-9 * Math.max(1, d.rx) ? "CIRCLE" : "ELLIPSE";
10349
+ }
10350
+ /** Parameter bounds: line → [0, length]; conic → [a0, a1]; helix → [0, 2π·turns]; bezier → [0, 1]. */
10351
+ function descBounds(d) {
10352
+ if (d.k === "line") return {
10353
+ first: 0,
10354
+ last: lineLen(d)
10355
+ };
10356
+ if (d.k === "conic") return {
10357
+ first: d.a0,
10358
+ last: d.a1
10359
+ };
10360
+ if (d.k === "helix") return {
10361
+ first: 0,
10362
+ last: TAU * d.turns
10363
+ };
10364
+ return {
10365
+ first: 0,
10366
+ last: 1
10367
+ };
10368
+ }
10369
+ function descPointAt(d, param) {
10370
+ if (d.k === "line") {
10371
+ const t = param / (lineLen(d) || 1);
10372
+ return [
10373
+ d.p1[0] + (d.p2[0] - d.p1[0]) * t,
10374
+ d.p1[1] + (d.p2[1] - d.p1[1]) * t,
10375
+ d.p1[2] + (d.p2[2] - d.p1[2]) * t
10376
+ ];
10377
+ }
10378
+ if (d.k === "bezier") return bezierAt$1(d.points, param);
10379
+ if (d.k === "helix") {
10380
+ const ct = Math.cos(param);
10381
+ const st = Math.sin(param);
10382
+ const z = d.pitch * param / TAU;
10383
+ return [
10384
+ d.center[0] + d.radius * (ct * d.x[0] + st * d.y[0]) + z * d.axis[0],
10385
+ d.center[1] + d.radius * (ct * d.x[1] + st * d.y[1]) + z * d.axis[1],
10386
+ d.center[2] + d.radius * (ct * d.x[2] + st * d.y[2]) + z * d.axis[2]
10387
+ ];
10388
+ }
10389
+ const ct = Math.cos(param);
10390
+ const st = Math.sin(param);
10391
+ return [
10392
+ d.center[0] + d.rx * ct * d.x[0] + d.ry * st * d.y[0],
10393
+ d.center[1] + d.rx * ct * d.x[1] + d.ry * st * d.y[1],
10394
+ d.center[2] + d.rx * ct * d.x[2] + d.ry * st * d.y[2]
10395
+ ];
10396
+ }
10397
+ function descTangent(d, param) {
10398
+ let t;
10399
+ if (d.k === "line") t = sub3(d.p2, d.p1);
10400
+ else if (d.k === "bezier") {
10401
+ const a = bezierAt$1(d.points, Math.max(0, param - 1e-4));
10402
+ t = sub3(bezierAt$1(d.points, Math.min(1, param + 1e-4)), a);
10403
+ } else if (d.k === "helix") {
10404
+ const ct = Math.cos(param);
10405
+ const st = Math.sin(param);
10406
+ const k = d.pitch / TAU;
10407
+ t = [
10408
+ d.radius * (-st * d.x[0] + ct * d.y[0]) + k * d.axis[0],
10409
+ d.radius * (-st * d.x[1] + ct * d.y[1]) + k * d.axis[1],
10410
+ d.radius * (-st * d.x[2] + ct * d.y[2]) + k * d.axis[2]
10411
+ ];
10412
+ } else {
10413
+ const ct = Math.cos(param);
10414
+ const st = Math.sin(param);
10415
+ t = [
10416
+ -d.rx * st * d.x[0] + d.ry * ct * d.y[0],
10417
+ -d.rx * st * d.x[1] + d.ry * ct * d.y[1],
10418
+ -d.rx * st * d.x[2] + d.ry * ct * d.y[2]
10419
+ ];
10420
+ }
10421
+ const l = hypot3(t) || 1;
10422
+ return [
10423
+ t[0] / l,
10424
+ t[1] / l,
10425
+ t[2] / l
10426
+ ];
10427
+ }
10428
+ /** Exact length where closed-form exists; Ramanujan for full ellipses; numeric otherwise. */
10429
+ function descLength(d) {
10430
+ if (d.k === "line") return lineLen(d);
10431
+ if (d.k === "helix") {
10432
+ const c = TAU * d.radius;
10433
+ return d.turns * Math.sqrt(c * c + d.pitch * d.pitch);
10434
+ }
10435
+ if (d.k === "conic") {
10436
+ const span = Math.abs(d.a1 - d.a0);
10437
+ if (Math.abs(d.rx - d.ry) < 1e-9 * Math.max(1, d.rx)) return d.rx * span;
10438
+ if (Math.abs(span - TAU) < 1e-9) {
10439
+ const a = d.rx;
10440
+ const b = d.ry;
10441
+ const h = (a - b) * (a - b) / ((a + b) * (a + b));
10442
+ return Math.PI * (a + b) * (1 + 3 * h / (10 + Math.sqrt(4 - 3 * h)));
10443
+ }
10444
+ return numericLength((t) => descPointAt(d, t), d.a0, d.a1, 256);
10445
+ }
10446
+ return numericLength((t) => descPointAt(d, t), 0, 1, 128);
10447
+ }
10448
+ function descIsClosed(d) {
10449
+ if (d.k === "conic") return Math.abs(Math.abs(d.a1 - d.a0) - TAU) < 1e-9;
10450
+ return false;
10451
+ }
10452
+ function descIsPeriodic(d) {
10453
+ return descIsClosed(d);
10454
+ }
10455
+ function descPeriod(d) {
10456
+ return d.k === "conic" ? TAU : 0;
10457
+ }
10458
+ function numericLength(at, t0, t1, n) {
10459
+ let len = 0;
10460
+ let prev = at(t0);
10461
+ for (let i = 1; i <= n; i++) {
10462
+ const p = at(t0 + (t1 - t0) * i / n);
10463
+ len += hypot3(sub3(p, prev));
10464
+ prev = p;
10465
+ }
10466
+ return len;
10467
+ }
10468
+ //#endregion
10304
10469
  //#region src/kernel/manifold/approximations.ts
10305
10470
  function asShape$2(shape) {
10306
10471
  return shape;
@@ -10702,10 +10867,22 @@ function rotationMinimizingFrames(path, seed) {
10702
10867
  }
10703
10868
  //#endregion
10704
10869
  //#region src/kernel/manifold/profileOps.ts
10705
- /** Segments used to approximate a full circle; arcs scale by angle span. */
10870
+ /** Fallback full-circle segment count when the kernel exposes no quality fn. */
10706
10871
  var FULL_CIRCLE_SEGMENTS = 24;
10707
10872
  /** Bezier sampling segments per edge. */
10708
10873
  var BEZIER_SEGMENTS = 24;
10874
+ /**
10875
+ * Full-circle segment count, following the Manifold global quality setting
10876
+ * (`getCircularSegments`) when available so profile-curve fidelity scales with
10877
+ * the kernel's tessellation quality — fine for accuracy-sensitive callers,
10878
+ * coarse for fast preview — instead of a hardcoded constant. Set by
10879
+ * {@link makeProfileBuilders}.
10880
+ */
10881
+ var circularSegmentsFor = null;
10882
+ function fullCircleSegments(radius) {
10883
+ const n = circularSegmentsFor ? circularSegmentsFor(Math.max(Math.abs(radius), 1e-6)) : FULL_CIRCLE_SEGMENTS;
10884
+ return Math.max(FULL_CIRCLE_SEGMENTS, n);
10885
+ }
10709
10886
  var ZERO3 = [
10710
10887
  0,
10711
10888
  0,
@@ -10719,8 +10896,8 @@ var PLACEHOLDER = {
10719
10896
  function at3(pts, i) {
10720
10897
  return pts[i] ?? ZERO3;
10721
10898
  }
10722
- function arcSegments(angleSpan) {
10723
- return Math.max(2, Math.ceil(Math.abs(angleSpan) / (2 * Math.PI) * FULL_CIRCLE_SEGMENTS));
10899
+ function arcSegments(angleSpan, radius = 1) {
10900
+ return Math.max(2, Math.ceil(Math.abs(angleSpan) / (2 * Math.PI) * fullCircleSegments(radius)));
10724
10901
  }
10725
10902
  function pickPerp(n) {
10726
10903
  return normalize3(cross(n, Math.abs(n[0]) < .9 ? [
@@ -10739,7 +10916,7 @@ function sampleArc(center, normal, radius, startAngle, endAngle, xDir) {
10739
10916
  const x = xDir ? normalize3(xDir) : pickPerp(n);
10740
10917
  const y = normalize3(cross(n, x));
10741
10918
  const span = endAngle - startAngle;
10742
- const segs = arcSegments(span);
10919
+ const segs = arcSegments(span, radius);
10743
10920
  const pts = [];
10744
10921
  for (let i = 0; i <= segs; i++) {
10745
10922
  const a = startAngle + span * i / segs;
@@ -10875,9 +11052,54 @@ function sampleOcctEdge(occt, edge) {
10875
11052
  function discretizeOcctWire(occt, wire) {
10876
11053
  return chainEdges(occt.iterShapes(wire, "edge").map((e) => sampleOcctEdge(occt, e)));
10877
11054
  }
10878
- function makeProfileBuilders(_module) {
10879
- function edge(pts) {
10880
- return wrap(PLACEHOLDER, makeNode("profileEdge", { pts }, []));
11055
+ function makeProfileBuilders(module) {
11056
+ const getSegs = module.getCircularSegments;
11057
+ if (typeof getSegs === "function") circularSegmentsFor = (r) => getSegs(r);
11058
+ function edge(pts, curve) {
11059
+ return wrap(PLACEHOLDER, makeNode("profileEdge", curve ? {
11060
+ pts,
11061
+ curve
11062
+ } : { pts }, []));
11063
+ }
11064
+ /** In-plane orthonormal frame (x, y) for a conic on a plane with the given normal. */
11065
+ function conicFrame(normal, xDir) {
11066
+ const n = normalize3(normal);
11067
+ const x = xDir ? normalize3(xDir) : pickPerp(n);
11068
+ return {
11069
+ x,
11070
+ y: normalize3(cross(n, x))
11071
+ };
11072
+ }
11073
+ /** Analytic conic descriptor for the circle through three points (or null if collinear). */
11074
+ function conicDescFrom3(p1, p2, p3) {
11075
+ const v1 = sub(p2, p1);
11076
+ const v2 = sub(p3, p1);
11077
+ const n = cross(v1, v2);
11078
+ if (length3(n) < 1e-12) return void 0;
11079
+ const nn = normalize3(n);
11080
+ const b = dot(v1, v1);
11081
+ const c = dot(v2, v2);
11082
+ const dd = dot(v1, v2);
11083
+ const denom = 2 * (b * c - dd * dd);
11084
+ if (Math.abs(denom) < 1e-18) return void 0;
11085
+ const s = c * (b - dd) / denom;
11086
+ const t = b * (c - dd) / denom;
11087
+ const center = add(p1, add(scaleVec(v1, s), scaleVec(v2, t)));
11088
+ const radius = length3(sub(p1, center));
11089
+ const x = normalize3(sub(p1, center));
11090
+ const y = normalize3(cross(nn, x));
11091
+ let a1 = Math.atan2(dot(sub(p3, center), y), dot(sub(p3, center), x));
11092
+ if (a1 < 0) a1 += 2 * Math.PI;
11093
+ return {
11094
+ k: "conic",
11095
+ center,
11096
+ x,
11097
+ y,
11098
+ rx: radius,
11099
+ ry: radius,
11100
+ a0: 0,
11101
+ a1
11102
+ };
10881
11103
  }
10882
11104
  function ringOrPts(shape) {
10883
11105
  const ms = asManifoldShape(shape);
@@ -10965,8 +11187,9 @@ function makeProfileBuilders(_module) {
10965
11187
  const x = xDir ? normalize3(xDir) : pickPerp(n);
10966
11188
  const y = normalize3(cross(n, x));
10967
11189
  const pts = [];
10968
- for (let i = 0; i <= FULL_CIRCLE_SEGMENTS; i++) {
10969
- const a = 2 * Math.PI * i / FULL_CIRCLE_SEGMENTS;
11190
+ const segs = fullCircleSegments(Math.max(majorRadius, minorRadius));
11191
+ for (let i = 0; i <= segs; i++) {
11192
+ const a = 2 * Math.PI * i / segs;
10970
11193
  pts.push(add(center, add(scaleVec(x, majorRadius * Math.cos(a)), scaleVec(y, minorRadius * Math.sin(a)))));
10971
11194
  }
10972
11195
  return pts;
@@ -10977,13 +11200,89 @@ function makeProfileBuilders(_module) {
10977
11200
  y,
10978
11201
  z
10979
11202
  ]]),
10980
- makeLineEdge: (p1, p2) => edge([p1, p2]),
10981
- makeCircleEdge: (center, normal, radius) => edge(sampleArc(center, normal, radius, 0, 2 * Math.PI)),
10982
- makeCircleArc: (center, normal, radius, startAngle, endAngle) => edge(sampleArc(center, normal, radius, startAngle, endAngle)),
10983
- makeArcEdge: (p1, p2, p3) => edge(circleFrom3(p1, p2, p3)),
10984
- makeEllipseEdge: (center, normal, majorRadius, minorRadius, xDir) => edge(ellipsePts(center, normal, majorRadius, minorRadius, xDir)),
10985
- makeBezierEdge: (points) => edge(sampleBezier(points)),
10986
- makeTangentArc: (startPoint, _startTangent, endPoint) => edge([startPoint, endPoint]),
11203
+ makeLineEdge: (p1, p2) => edge([p1, p2], {
11204
+ k: "line",
11205
+ p1,
11206
+ p2
11207
+ }),
11208
+ makeCircleEdge: (center, normal, radius) => {
11209
+ const { x, y } = conicFrame(normal);
11210
+ return edge(sampleArc(center, normal, radius, 0, 2 * Math.PI), {
11211
+ k: "conic",
11212
+ center,
11213
+ x,
11214
+ y,
11215
+ rx: radius,
11216
+ ry: radius,
11217
+ a0: 0,
11218
+ a1: 2 * Math.PI
11219
+ });
11220
+ },
11221
+ makeCircleArc: (center, normal, radius, startAngle, endAngle) => {
11222
+ const { x, y } = conicFrame(normal);
11223
+ return edge(sampleArc(center, normal, radius, startAngle, endAngle), {
11224
+ k: "conic",
11225
+ center,
11226
+ x,
11227
+ y,
11228
+ rx: radius,
11229
+ ry: radius,
11230
+ a0: startAngle,
11231
+ a1: endAngle
11232
+ });
11233
+ },
11234
+ makeArcEdge: (p1, p2, p3) => edge(circleFrom3(p1, p2, p3), conicDescFrom3(p1, p2, p3)),
11235
+ makeEllipseEdge: (center, normal, majorRadius, minorRadius, xDir) => {
11236
+ const { x, y } = conicFrame(normal, xDir);
11237
+ return edge(ellipsePts(center, normal, majorRadius, minorRadius, xDir), {
11238
+ k: "conic",
11239
+ center,
11240
+ x,
11241
+ y,
11242
+ rx: majorRadius,
11243
+ ry: minorRadius,
11244
+ a0: 0,
11245
+ a1: 2 * Math.PI
11246
+ });
11247
+ },
11248
+ makeBezierEdge: (points) => edge(sampleBezier(points), {
11249
+ k: "bezier",
11250
+ points: points.map((p) => [...p])
11251
+ }),
11252
+ makeTangentArc: (startPoint, _startTangent, endPoint) => edge([startPoint, endPoint], {
11253
+ k: "line",
11254
+ p1: startPoint,
11255
+ p2: endPoint
11256
+ }),
11257
+ makeHelixWire: (pitch, height, radius, center = [
11258
+ 0,
11259
+ 0,
11260
+ 0
11261
+ ], direction = [
11262
+ 0,
11263
+ 0,
11264
+ 1
11265
+ ], leftHanded = false) => {
11266
+ const axis = normalize3(direction);
11267
+ const x = pickPerp(axis);
11268
+ const y0 = normalize3(cross(axis, x));
11269
+ const y = leftHanded ? scaleVec(y0, -1) : y0;
11270
+ const turns = pitch !== 0 ? height / pitch : 0;
11271
+ const desc = {
11272
+ k: "helix",
11273
+ center,
11274
+ axis,
11275
+ x,
11276
+ y,
11277
+ radius,
11278
+ pitch,
11279
+ turns
11280
+ };
11281
+ const segs = Math.max(8, Math.ceil(turns * FULL_CIRCLE_SEGMENTS));
11282
+ const pts = [];
11283
+ for (let i = 0; i <= segs; i++) pts.push(descPointAt(desc, 2 * Math.PI * turns * i / segs));
11284
+ return edge(pts, desc);
11285
+ },
10987
11286
  makeWire: (edges) => wireFrom(edges),
10988
11287
  makeWireFromMixed: (items) => wireFrom(items),
10989
11288
  makeFace,
@@ -11029,7 +11328,7 @@ function makeBuilderOps(module) {
11029
11328
  makeEllipseArc: () => notImplemented("makeEllipseArc"),
11030
11329
  makeBezierEdge: (points) => profile.makeBezierEdge(points),
11031
11330
  makeTangentArc: (startPoint, startTangent, endPoint) => profile.makeTangentArc(startPoint, startTangent, endPoint),
11032
- makeHelixWire: () => notImplemented("makeHelixWire"),
11331
+ makeHelixWire: (pitch, height, radius, center, direction, leftHanded) => profile.makeHelixWire(pitch, height, radius, center, direction, leftHanded),
11033
11332
  makeWireFromMixed: (items) => profile.makeWireFromMixed(items),
11034
11333
  makeCompound: () => notImplemented("makeCompound"),
11035
11334
  solidFromShell: () => notImplemented("solidFromShell"),
@@ -12621,6 +12920,8 @@ function makeMeasureOps(_module) {
12621
12920
  length: (shape) => {
12622
12921
  const e = shape;
12623
12922
  if (e && e.__nativeEdge && typeof e.length === "number") return e.length;
12923
+ const node = asManifoldShape(shape)?.node;
12924
+ if (node?.op === "profileEdge" && node.params?.curve) return descLength(node.params.curve);
12624
12925
  return notImplemented("length");
12625
12926
  },
12626
12927
  centerOfMass: (shape) => centerOfMass(shape),
@@ -13127,8 +13428,7 @@ function hashCode(shape, upperBound) {
13127
13428
  function isNull(shape) {
13128
13429
  const s = asManifoldShape(shape);
13129
13430
  if (!s) return true;
13130
- const solid = unwrap(s);
13131
- return !solid || typeof solid.isEmpty === "function" && solid.isEmpty();
13431
+ return !unwrap(s);
13132
13432
  }
13133
13433
  function iterShapes(shape, type) {
13134
13434
  const s = asManifoldShape(shape);
@@ -13785,18 +14085,56 @@ function viaOcct(shape, query) {
13785
14085
  }
13786
14086
  return query(occtShape, occt);
13787
14087
  }
14088
+ /** The analytic curve descriptor of a standalone profile edge, if it has one. */
14089
+ function descOf(shape) {
14090
+ const ms = asManifoldShape(shape);
14091
+ if (!ms) return void 0;
14092
+ const node = ms.node;
14093
+ return node.op === "profileEdge" ? node.params?.curve : void 0;
14094
+ }
13788
14095
  function makeGeometryOps(_module) {
13789
14096
  return {
13790
- curveType: (shape) => isNativeEdge(shape) ? shape.curveType : viaOcct(shape, (s, occt) => occt.curveType(s)),
13791
- curveParameters: (shape) => isNativeEdge(shape) ? [0, shape.length] : viaOcct(shape, (s, occt) => occt.curveParameters(s)),
13792
- curvePointAtParam: (shape, param) => isNativeEdge(shape) ? edgePointAt(shape, param) : viaOcct(shape, (s, occt) => occt.curvePointAtParam(s, param)),
13793
- curveTangent: (shape, param) => isNativeEdge(shape) ? {
13794
- point: edgePointAt(shape, param),
13795
- tangent: edgeTangentAt(shape, param)
13796
- } : viaOcct(shape, (s, occt) => occt.curveTangent(s, param)),
13797
- curveIsClosed: (shape) => viaOcct(shape, (s, occt) => occt.curveIsClosed(s)),
13798
- curveIsPeriodic: (shape) => viaOcct(shape, (s, occt) => occt.curveIsPeriodic(s)),
13799
- curvePeriod: (shape) => viaOcct(shape, (s, occt) => occt.curvePeriod(s)),
14097
+ curveType: (shape) => {
14098
+ const d = descOf(shape);
14099
+ if (d) return descType(d);
14100
+ return isNativeEdge(shape) ? shape.curveType : viaOcct(shape, (s, occt) => occt.curveType(s));
14101
+ },
14102
+ curveParameters: (shape) => {
14103
+ const d = descOf(shape);
14104
+ if (d) {
14105
+ const b = descBounds(d);
14106
+ return [b.first, b.last];
14107
+ }
14108
+ return isNativeEdge(shape) ? [0, shape.length] : viaOcct(shape, (s, occt) => occt.curveParameters(s));
14109
+ },
14110
+ curvePointAtParam: (shape, param) => {
14111
+ const d = descOf(shape);
14112
+ if (d) return descPointAt(d, param);
14113
+ return isNativeEdge(shape) ? edgePointAt(shape, param) : viaOcct(shape, (s, occt) => occt.curvePointAtParam(s, param));
14114
+ },
14115
+ curveTangent: (shape, param) => {
14116
+ const d = descOf(shape);
14117
+ if (d) return {
14118
+ point: descPointAt(d, param),
14119
+ tangent: descTangent(d, param)
14120
+ };
14121
+ return isNativeEdge(shape) ? {
14122
+ point: edgePointAt(shape, param),
14123
+ tangent: edgeTangentAt(shape, param)
14124
+ } : viaOcct(shape, (s, occt) => occt.curveTangent(s, param));
14125
+ },
14126
+ curveIsClosed: (shape) => {
14127
+ const d = descOf(shape);
14128
+ return d ? descIsClosed(d) : viaOcct(shape, (s, occt) => occt.curveIsClosed(s));
14129
+ },
14130
+ curveIsPeriodic: (shape) => {
14131
+ const d = descOf(shape);
14132
+ return d ? descIsPeriodic(d) : viaOcct(shape, (s, occt) => occt.curveIsPeriodic(s));
14133
+ },
14134
+ curvePeriod: (shape) => {
14135
+ const d = descOf(shape);
14136
+ return d ? descPeriod(d) : viaOcct(shape, (s, occt) => occt.curvePeriod(s));
14137
+ },
13800
14138
  interpolatePoints: (points, options) => occtOrThrow("interpolatePoints").interpolatePoints(points, options),
13801
14139
  approximatePoints: (points, options) => occtOrThrow("approximatePoints").approximatePoints(points, options),
13802
14140
  curveDegreeElevate: (edge, elevateBy) => viaOcct(edge, (s, occt) => occt.curveDegreeElevate(s, elevateBy)),
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_textBlueprints = require("./textBlueprints-DTaz774E.cjs");
3
- const require_blueprintSketcher = require("./blueprintSketcher-r0uUFBZZ.cjs");
4
- const require_drawFns = require("./drawFns-ZPhrUGWl.cjs");
2
+ const require_textBlueprints = require("./textBlueprints-7KWxP1zT.cjs");
3
+ const require_blueprintSketcher = require("./blueprintSketcher-Bpd7nMHt.cjs");
4
+ const require_drawFns = require("./drawFns-DPE6EU_v.cjs");
5
5
  //#region src/sketching.ts
6
6
  /**
7
7
  * brepjs/sketching — Sketcher, Drawing, and sketch-to-shape operations.
package/dist/sketching.js CHANGED
@@ -1,6 +1,6 @@
1
- import { n as BaseSketcher2d, t as BlueprintSketcher } from "./blueprintSketcher-DHWmjOmJ.js";
2
- import { A as sketchEllipse, C as DrawingPen, D as makeBaseBox, E as deserializeDrawing, F as sketchRectangle, I as sketchRoundedRectangle, L as FaceSketcher, M as sketchHelix, N as sketchParametricFunction, O as polysideInnerRadius, P as sketchPolysides, R as Sketcher, S as drawText, T as Drawing, _ as drawPolysides, a as drawingIntersect, b as drawSingleCircle, c as rotateDrawing, d as drawFaceOutline, f as drawProjection, g as drawPointsInterpolation, h as drawParametricFunction, i as drawingFuse, j as sketchFaceOffset, k as sketchCircle, l as scaleDrawing, m as drawEllipse, n as drawingCut, o as drawingToSketchOnPlane, p as drawCircle, r as drawingFillet, s as mirrorDrawing, t as drawingChamfer, u as translateDrawing, v as drawRectangle, w as draw, x as drawSingleEllipse, y as drawRoundedRectangle } from "./drawFns-DiJFFH16.js";
3
- import { a as Sketch, c as compoundSketchLoft, d as sketchFace, f as sketchLoft, h as sketchWires, i as Sketches, l as compoundSketchRevolve, m as sketchSweep, o as compoundSketchExtrude, p as sketchRevolve, s as compoundSketchFace, u as sketchExtrude, v as CompoundSketch } from "./textBlueprints-B_RYPM3J.js";
1
+ import { n as BaseSketcher2d, t as BlueprintSketcher } from "./blueprintSketcher-BL85kdgo.js";
2
+ import { A as sketchEllipse, C as DrawingPen, D as makeBaseBox, E as deserializeDrawing, F as sketchRectangle, I as sketchRoundedRectangle, L as FaceSketcher, M as sketchHelix, N as sketchParametricFunction, O as polysideInnerRadius, P as sketchPolysides, R as Sketcher, S as drawText, T as Drawing, _ as drawPolysides, a as drawingIntersect, b as drawSingleCircle, c as rotateDrawing, d as drawFaceOutline, f as drawProjection, g as drawPointsInterpolation, h as drawParametricFunction, i as drawingFuse, j as sketchFaceOffset, k as sketchCircle, l as scaleDrawing, m as drawEllipse, n as drawingCut, o as drawingToSketchOnPlane, p as drawCircle, r as drawingFillet, s as mirrorDrawing, t as drawingChamfer, u as translateDrawing, v as drawRectangle, w as draw, x as drawSingleEllipse, y as drawRoundedRectangle } from "./drawFns-Cq6bAjFC.js";
3
+ import { a as Sketch, c as compoundSketchLoft, d as sketchFace, f as sketchLoft, h as sketchWires, i as Sketches, l as compoundSketchRevolve, m as sketchSweep, o as compoundSketchExtrude, p as sketchRevolve, s as compoundSketchFace, u as sketchExtrude, v as CompoundSketch } from "./textBlueprints-CyIv54Ac.js";
4
4
  //#region src/sketching.ts
5
5
  /**
6
6
  * brepjs/sketching — Sketcher, Drawing, and sketch-to-shape operations.
@@ -1,6 +1,6 @@
1
- import { Z as getKernel, _ as isSolid, c as createSolid, g as isShell, h as isShape3D, i as createCompound, l as createVertex } from "./shapeTypes-9yfC5Z8_.js";
1
+ import { Z as getKernel, _ as isSolid, c as createSolid, g as isShell, h as isShape3D, i as createCompound, l as createVertex } from "./shapeTypes-C-32Klnb.js";
2
2
  import { A as ok, R as unwrap, b as err, l as typeCastError, v as andThen } from "./errors-DNWJsfVU.js";
3
- import { _ as downcast, g as cast } from "./faceFns-LJ_lU5IE.js";
3
+ import { _ as downcast, g as cast } from "./faceFns-Qrz3lIDv.js";
4
4
  //#region src/topology/shapeUtils.ts
5
5
  /**
6
6
  * Shape assembly utilities — welding and sewing operations.
@@ -1,6 +1,6 @@
1
- const require_shapeTypes = require("./shapeTypes-C_liO43e.cjs");
1
+ const require_shapeTypes = require("./shapeTypes-DAhE_41P.cjs");
2
2
  const require_errors = require("./errors-CXJtc4I7.cjs");
3
- const require_faceFns = require("./faceFns-DGmQI57P.cjs");
3
+ const require_faceFns = require("./faceFns-_m0px2ug.cjs");
4
4
  //#region src/topology/shapeUtils.ts
5
5
  /**
6
6
  * Shape assembly utilities — welding and sewing operations.
@@ -1,6 +1,6 @@
1
- const require_shapeTypes = require("./shapeTypes-C_liO43e.cjs");
1
+ const require_shapeTypes = require("./shapeTypes-DAhE_41P.cjs");
2
2
  const require_errors = require("./errors-CXJtc4I7.cjs");
3
- const require_faceFns = require("./faceFns-DGmQI57P.cjs");
3
+ const require_faceFns = require("./faceFns-_m0px2ug.cjs");
4
4
  //#region src/utils/range.ts
5
5
  /** Generate an array of integers `[0, 1, …, len - 1]`. */
6
6
  function range(len) {
@@ -1,6 +1,6 @@
1
- import { Z as getKernel, a as createEdge, o as createFace, p as isFace, u as createWire, w as isPlanarFace } from "./shapeTypes-9yfC5Z8_.js";
1
+ import { Z as getKernel, a as createEdge, o as createFace, p as isFace, u as createWire, w as isPlanarFace } from "./shapeTypes-C-32Klnb.js";
2
2
  import { A as ok, b as err, d as validationError, i as kernelError, v as andThen } from "./errors-DNWJsfVU.js";
3
- import { g as cast, l as outerWire } from "./faceFns-LJ_lU5IE.js";
3
+ import { g as cast, l as outerWire } from "./faceFns-Qrz3lIDv.js";
4
4
  //#region src/utils/range.ts
5
5
  /** Generate an array of integers `[0, 1, …, len - 1]`. */
6
6
  function range(len) {
package/dist/text.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_textBlueprints = require("./textBlueprints-DTaz774E.cjs");
3
- const require_textMetrics = require("./textMetrics-CEBrAzpE.cjs");
2
+ const require_textBlueprints = require("./textBlueprints-7KWxP1zT.cjs");
3
+ const require_textMetrics = require("./textMetrics-BXoJfZKn.cjs");
4
4
  exports.fontMetrics = require_textMetrics.fontMetrics;
5
5
  exports.getFont = require_textBlueprints.getFont;
6
6
  exports.loadFont = require_textBlueprints.loadFont;
package/dist/text.js CHANGED
@@ -1,3 +1,3 @@
1
- import { n as getFont, r as loadFont, t as textBlueprints } from "./textBlueprints-B_RYPM3J.js";
2
- import { n as textMetrics, r as sketchText, t as fontMetrics } from "./textMetrics-RRDn50ym.js";
1
+ import { n as getFont, r as loadFont, t as textBlueprints } from "./textBlueprints-CyIv54Ac.js";
2
+ import { n as textMetrics, r as sketchText, t as fontMetrics } from "./textMetrics-D740OLnV.js";
3
3
  export { fontMetrics, getFont, loadFont, sketchText, textBlueprints, textMetrics };
@@ -29,18 +29,18 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
29
29
  enumerable: true
30
30
  }) : target, mod));
31
31
  //#endregion
32
- const require_shapeTypes = require("./shapeTypes-C_liO43e.cjs");
32
+ const require_shapeTypes = require("./shapeTypes-DAhE_41P.cjs");
33
33
  const require_errors = require("./errors-CXJtc4I7.cjs");
34
34
  const require_types = require("./types-KjA8tY4Y.cjs");
35
35
  const require_vecOps = require("./vecOps-CCnJt-yH.cjs");
36
36
  const require_planeOps = require("./planeOps-BA4HfgQu.cjs");
37
- const require_faceFns = require("./faceFns-DGmQI57P.cjs");
38
- const require_curveFns = require("./curveFns-Dx9ha0n_.cjs");
37
+ const require_faceFns = require("./faceFns-_m0px2ug.cjs");
38
+ const require_curveFns = require("./curveFns-DR68aqxR.cjs");
39
39
  const require_arrayAccess = require("./arrayAccess-e4H9cBfh.cjs");
40
- const require_surfaceBuilders = require("./surfaceBuilders-6BfGn0MN.cjs");
41
- const require_blueprintSketcher = require("./blueprintSketcher-r0uUFBZZ.cjs");
42
- const require_solidBuilders = require("./solidBuilders-BtfspzpT.cjs");
43
- const require_extrudeFns = require("./extrudeFns-DsvQYfqd.cjs");
40
+ const require_surfaceBuilders = require("./surfaceBuilders-B9kzwe0E.cjs");
41
+ const require_blueprintSketcher = require("./blueprintSketcher-Bpd7nMHt.cjs");
42
+ const require_solidBuilders = require("./solidBuilders-iapbn6CO.cjs");
43
+ const require_extrudeFns = require("./extrudeFns-yfUN1m7e.cjs");
44
44
  let opentype_js = require("opentype.js");
45
45
  opentype_js = __toESM(opentype_js, 1);
46
46
  //#region src/operations/loftFns.ts
@@ -1,15 +1,15 @@
1
- import { Z as getKernel, h as isShape3D, o as createFace, p as isFace, t as castShape, u as createWire } from "./shapeTypes-9yfC5Z8_.js";
1
+ import { Z as getKernel, h as isShape3D, o as createFace, p as isFace, t as castShape, u as createWire } from "./shapeTypes-C-32Klnb.js";
2
2
  import { A as ok, R as unwrap, T as isOk, b as err, d as validationError, h as bug, i as kernelError, l as typeCastError, r as ioError, t as BrepErrorCode } from "./errors-DNWJsfVU.js";
3
3
  import { r as toVec3 } from "./types-D24Y27N0.js";
4
4
  import { d as vecNormalize, h as vecScale, r as vecCross } from "./vecOps-SKPRvPH-.js";
5
5
  import { n as createPlane } from "./planeOps-DSjjtrjg.js";
6
- import { _ as downcast, g as cast } from "./faceFns-LJ_lU5IE.js";
7
- import { c as curveStartPoint, l as curveTangentAt } from "./curveFns-vZbW7CVb.js";
6
+ import { _ as downcast, g as cast } from "./faceFns-Qrz3lIDv.js";
7
+ import { c as curveStartPoint, l as curveTangentAt } from "./curveFns-DH5NpaKO.js";
8
8
  import { n as getAtOrThrow, t as firstOrThrow } from "./arrayAccess-DrUGPADn.js";
9
- import { i as makeNewFaceWithinFace, r as makeFace, t as addHolesInFace } from "./surfaceBuilders-ChWLM9Io.js";
10
- import { r as organiseBlueprints, t as BlueprintSketcher } from "./blueprintSketcher-DHWmjOmJ.js";
11
- import { o as makeSolid, t as makeCompound } from "./solidBuilders-DSAmLmHd.js";
12
- import { c as sweep, i as complexExtrude, l as twistExtrude, r as revolve, t as extrude } from "./extrudeFns-BamV4cSU.js";
9
+ import { i as makeNewFaceWithinFace, r as makeFace, t as addHolesInFace } from "./surfaceBuilders-Cwecm13F.js";
10
+ import { r as organiseBlueprints, t as BlueprintSketcher } from "./blueprintSketcher-BL85kdgo.js";
11
+ import { o as makeSolid, t as makeCompound } from "./solidBuilders-B-gb9ZsJ.js";
12
+ import { c as sweep, i as complexExtrude, l as twistExtrude, r as revolve, t as extrude } from "./extrudeFns-DZEN4PPg.js";
13
13
  import opentype from "opentype.js";
14
14
  //#region src/operations/loftFns.ts
15
15
  /**
@@ -1,4 +1,4 @@
1
- const require_textBlueprints = require("./textBlueprints-DTaz774E.cjs");
1
+ const require_textBlueprints = require("./textBlueprints-7KWxP1zT.cjs");
2
2
  const require_errors = require("./errors-CXJtc4I7.cjs");
3
3
  //#region src/text/sketchText.ts
4
4
  /**
@@ -1,5 +1,5 @@
1
1
  import { A as ok, b as err, d as validationError, t as BrepErrorCode } from "./errors-DNWJsfVU.js";
2
- import { g as wrapSketchData, i as Sketches, n as getFont, t as textBlueprints, v as CompoundSketch } from "./textBlueprints-B_RYPM3J.js";
2
+ import { g as wrapSketchData, i as Sketches, n as getFont, t as textBlueprints, v as CompoundSketch } from "./textBlueprints-CyIv54Ac.js";
3
3
  //#region src/text/sketchText.ts
4
4
  /**
5
5
  * Render text as 3D sketch outlines on a plane.
package/dist/topology.cjs CHANGED
@@ -1,11 +1,11 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_topologyQueryFns = require("./topologyQueryFns-B6BTVGLX.cjs");
3
- const require_faceFns = require("./faceFns-DGmQI57P.cjs");
4
- const require_shapeFns = require("./shapeFns-n4A9y80v.cjs");
5
- const require_curveFns = require("./curveFns-Dx9ha0n_.cjs");
6
- const require_meshFns = require("./meshFns-D2rlqrTt.cjs");
7
- const require_booleanFns = require("./booleanFns-B3vIRhjz.cjs");
8
- const require_primitiveFns = require("./primitiveFns-Bi22B25-.cjs");
2
+ const require_topologyQueryFns = require("./topologyQueryFns-CBVVRWvE.cjs");
3
+ const require_faceFns = require("./faceFns-_m0px2ug.cjs");
4
+ const require_shapeFns = require("./shapeFns-DNqkQ2yJ.cjs");
5
+ const require_curveFns = require("./curveFns-DR68aqxR.cjs");
6
+ const require_meshFns = require("./meshFns-CR8dRmoo.cjs");
7
+ const require_booleanFns = require("./booleanFns-C9olM-r4.cjs");
8
+ const require_primitiveFns = require("./primitiveFns-DFsImECE.cjs");
9
9
  exports.addHoles = require_primitiveFns.addHoles;
10
10
  exports.adjacentFaces = require_primitiveFns.adjacentFaces;
11
11
  exports.approximateCurve = require_curveFns.approximateCurve;