brepjs 18.84.0 → 18.85.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 (91) hide show
  1. package/README.md +13 -3
  2. package/dist/2d/lib/definitions.d.ts +4 -1
  3. package/dist/2d.cjs +6 -6
  4. package/dist/2d.js +6 -6
  5. package/dist/{blueprint-krPp-yxy.js → blueprint-BL2TdtBX.js} +5 -5
  6. package/dist/{blueprint-TE6QbbrL.cjs → blueprint-KrNFTiyX.cjs} +5 -5
  7. package/dist/{blueprintFns-Cnx8Pwsc.js → blueprintFns-DCA97w4C.js} +2 -2
  8. package/dist/{blueprintFns-BHzvNR9P.cjs → blueprintFns-Dp0_BOuL.cjs} +2 -2
  9. package/dist/{blueprintSketcher-BgQ4HUQS.cjs → blueprintSketcher-ChpPo7tq.cjs} +3 -3
  10. package/dist/{blueprintSketcher-BgJ92ofq.js → blueprintSketcher-CxFmYBvh.js} +3 -3
  11. package/dist/{boolean2D-C5RQKxsG.js → boolean2D-CIohnI9l.js} +4 -4
  12. package/dist/{boolean2D-Bm57seK7.cjs → boolean2D-RC6jXv4x.cjs} +4 -4
  13. package/dist/brepjs.cjs +40 -26
  14. package/dist/brepjs.js +45 -31
  15. package/dist/{cameraFns-Dr6husIP.js → cameraFns-BA7CVtWJ.js} +2 -2
  16. package/dist/{cameraFns-CyH0eFkv.cjs → cameraFns-IL7qYFaG.cjs} +2 -2
  17. package/dist/core/kernelBoundary.d.ts +12 -3
  18. package/dist/core/planeOps.d.ts +4 -1
  19. package/dist/core/shapeTypeCache.d.ts +8 -2
  20. package/dist/core/typeDiscriminants.d.ts +1 -0
  21. package/dist/core.cjs +1 -1
  22. package/dist/core.js +1 -1
  23. package/dist/{cornerFinder-CEbdh48G.js → cornerFinder-7M1wdtcY.js} +1 -1
  24. package/dist/{cornerFinder-DXhDNSVO.cjs → cornerFinder-DKyR_u8g.cjs} +1 -1
  25. package/dist/{curveFns-ZfGUUd8h.cjs → curveFns-D3k8aHIE.cjs} +1 -1
  26. package/dist/{curveFns-BMvOjgAe.js → curveFns-DT1yMgBI.js} +1 -1
  27. package/dist/{drawFns-NN_2dIb7.js → drawFns-C63kOWvC.js} +12 -12
  28. package/dist/{drawFns-DwxukBbB.cjs → drawFns-C766Umy1.cjs} +12 -12
  29. package/dist/{faceFns-CfCwtCKM.js → faceFns-CmhEEB-L.js} +2 -2
  30. package/dist/{faceFns-CEhhzLpI.cjs → faceFns-DSdVqqVP.cjs} +2 -2
  31. package/dist/{healingFns-4FJFU89Q.cjs → healingFns-B1axWCr3.cjs} +5 -5
  32. package/dist/{healingFns-Db0sWtJD.js → healingFns-Cxi24K_n.js} +5 -5
  33. package/dist/{helpers-BMg3VK6f.js → helpers-CKjmUSf0.js} +6 -6
  34. package/dist/{helpers-BsPWHGEz.cjs → helpers-Cvrmxw4s.cjs} +6 -6
  35. package/dist/{importFns-DAxR2wFw.js → importFns-CDaNqu4H.js} +2 -2
  36. package/dist/{importFns-YD2jjXSP.cjs → importFns-D09lb1dB.cjs} +2 -2
  37. package/dist/index.d.ts +2 -2
  38. package/dist/io.cjs +2 -2
  39. package/dist/io.js +2 -2
  40. package/dist/kernel/brepkit/kernel2dOps.d.ts +1 -1
  41. package/dist/{loftFns-D4xbMwPh.cjs → loftFns-C664R57e.cjs} +1 -1
  42. package/dist/{loftFns-BLwuVjwA.js → loftFns-C8Ep9McS.js} +1 -1
  43. package/dist/{measureFns-Bsu3HKAh.cjs → measureFns-BtPAmRfH.cjs} +3 -3
  44. package/dist/{measureFns-DcU_ZNtw.js → measureFns-D0e8tGSP.js} +3 -3
  45. package/dist/measurement/measureCache.d.ts +1 -0
  46. package/dist/measurement.cjs +1 -1
  47. package/dist/measurement.js +1 -1
  48. package/dist/{meshFns-C_r1wsG-.cjs → meshFns-7IXB_Bua.cjs} +3 -3
  49. package/dist/{meshFns-4yXoFw_7.js → meshFns-CtchqgDR.js} +3 -3
  50. package/dist/operations/exporters.d.ts +1 -0
  51. package/dist/operations.cjs +2 -2
  52. package/dist/operations.js +2 -2
  53. package/dist/{primitiveFns-CdBx3Q-K.cjs → primitiveFns-Bdqm8wjI.cjs} +4 -4
  54. package/dist/{primitiveFns-Cbg94cAE.js → primitiveFns-D7R24hoz.js} +4 -4
  55. package/dist/projection.cjs +1 -1
  56. package/dist/projection.js +1 -1
  57. package/dist/query.cjs +2 -2
  58. package/dist/query.js +2 -2
  59. package/dist/{shapeFns-C0K2yQlH.js → shapeFns-B0lN3o3r.js} +2 -2
  60. package/dist/{shapeFns-C00nTg4m.cjs → shapeFns-CeSEceUG.cjs} +2 -2
  61. package/dist/shapeRef.cjs +1 -1
  62. package/dist/shapeRef.js +1 -1
  63. package/dist/{shapeRefFns-DuGh1xIA.cjs → shapeRefFns-BsX2j-n3.cjs} +4 -4
  64. package/dist/{shapeRefFns-BEm9-eG3.js → shapeRefFns-C4JSc_jF.js} +4 -4
  65. package/dist/{shapeTypes-CL5wYLDw.js → shapeTypes-BIcALNFv.js} +50 -4
  66. package/dist/{shapeTypes-BHoIVN7I.cjs → shapeTypes-DwNTiXjG.cjs} +50 -4
  67. package/dist/sketching/compoundSketch.d.ts +8 -2
  68. package/dist/sketching/sketch.d.ts +8 -3
  69. package/dist/sketching/sketchFns.d.ts +12 -4
  70. package/dist/sketching/sketches.d.ts +24 -5
  71. package/dist/sketching.cjs +3 -3
  72. package/dist/sketching.js +3 -3
  73. package/dist/{solidBuilders-C73RAr6j.cjs → solidBuilders-B_5FgvuK.cjs} +5 -5
  74. package/dist/{solidBuilders-Bp_Gf3y_.js → solidBuilders-Bb5_uC7F.js} +5 -5
  75. package/dist/{surfaceBuilders-DObQZa60.js → surfaceBuilders-BQx3TjMH.js} +2 -2
  76. package/dist/{surfaceBuilders-7QLWQwje.cjs → surfaceBuilders-DvpxHHIm.cjs} +2 -2
  77. package/dist/text.cjs +2 -2
  78. package/dist/text.js +2 -2
  79. package/dist/{textBlueprints-FGsoRUZ4.cjs → textBlueprints-CKFmYJHD.cjs} +70 -19
  80. package/dist/{textBlueprints-Dvp_j93V.js → textBlueprints-CU7MHMR8.js} +70 -19
  81. package/dist/{textMetrics-rFF3uFYC.js → textMetrics-BDTWvvyd.js} +1 -1
  82. package/dist/{textMetrics-BZbM75gl.cjs → textMetrics-BYHtOFYW.cjs} +1 -1
  83. package/dist/{threadFns-CYXs_rE1.js → threadFns-BWAL8cAZ.js} +6 -6
  84. package/dist/{threadFns-BNidejyc.cjs → threadFns-BsRDNoSm.cjs} +6 -6
  85. package/dist/topology/api.d.ts +4 -0
  86. package/dist/topology.cjs +8 -8
  87. package/dist/topology.js +8 -8
  88. package/dist/{topologyQueryFns-BtyNquQX.js → topologyQueryFns-0BIOC7YH.js} +1 -1
  89. package/dist/{topologyQueryFns-CJYc4A0j.cjs → topologyQueryFns-a2i0YhGF.cjs} +1 -1
  90. package/dist/utils/vec2d.d.ts +4 -1
  91. package/package.json +3 -1
@@ -8545,11 +8545,16 @@ function makeEllipse2d(cx, cy, major, minor, xDirX, xDirY, sense) {
8545
8545
  return require_occtWasmAdapter.makeEllipse2d(cx, cy, major, minor, xDirX, xDirY, sense);
8546
8546
  }
8547
8547
  function makeEllipseArc2d(cx, cy, major, minor, start, end, xDirX, xDirY, sense) {
8548
+ const ellipse = require_occtWasmAdapter.makeEllipse2d(cx, cy, major, minor, xDirX, xDirY, sense);
8549
+ const ccw = sense !== false;
8550
+ const tStart = ccw ? start : -start;
8551
+ let tEnd = ccw ? end : -end;
8552
+ if (tEnd < tStart - 1e-9) tEnd += 2 * Math.PI;
8548
8553
  return {
8549
8554
  __bk2d: "trimmed",
8550
- basis: require_occtWasmAdapter.makeEllipse2d(cx, cy, major, minor, xDirX, xDirY, sense),
8551
- tStart: start,
8552
- tEnd: end
8555
+ basis: ellipse,
8556
+ tStart,
8557
+ tEnd
8553
8558
  };
8554
8559
  }
8555
8560
  function makeBezier2d(points) {
@@ -8601,6 +8606,45 @@ function trimCurve2d(curve, start, end) {
8601
8606
  tEnd: end
8602
8607
  };
8603
8608
  }
8609
+ function reverseCurve2d(curve) {
8610
+ const c = curve;
8611
+ switch (c.__bk2d) {
8612
+ case "line": {
8613
+ const m = c;
8614
+ m.ox += m.dx * m.len;
8615
+ m.oy += m.dy * m.len;
8616
+ m.dx = -m.dx;
8617
+ m.dy = -m.dy;
8618
+ break;
8619
+ }
8620
+ case "circle":
8621
+ case "ellipse": {
8622
+ const m = c;
8623
+ m.sense = !m.sense;
8624
+ break;
8625
+ }
8626
+ case "trimmed": {
8627
+ const m = c;
8628
+ [m.tStart, m.tEnd] = [m.tEnd, m.tStart];
8629
+ break;
8630
+ }
8631
+ case "bezier": {
8632
+ const m = c;
8633
+ m.poles = [...m.poles].reverse();
8634
+ break;
8635
+ }
8636
+ case "bspline": {
8637
+ const m = c;
8638
+ m.poles = [...m.poles].reverse();
8639
+ const lo = m.knots[0];
8640
+ const hi = m.knots[m.knots.length - 1];
8641
+ if (lo !== void 0 && hi !== void 0) m.knots = m.knots.map((k) => lo + hi - k).reverse();
8642
+ if (Array.isArray(m.weights)) m.weights = [...m.weights].reverse();
8643
+ break;
8644
+ }
8645
+ default: break;
8646
+ }
8647
+ }
8604
8648
  function copyCurve2d(curve) {
8605
8649
  return JSON.parse(JSON.stringify(curve));
8606
8650
  }
@@ -9272,7 +9316,9 @@ function makeKernel2dOps(bk) {
9272
9316
  getCurve2dBounds: (curve) => getCurve2dBounds(curve),
9273
9317
  getCurve2dType: (curve) => getCurve2dType(curve),
9274
9318
  trimCurve2d: (curve, start, end) => trimCurve2d(curve, start, end),
9275
- reverseCurve2d: (curve) => {},
9319
+ reverseCurve2d: (curve) => {
9320
+ reverseCurve2d(curve);
9321
+ },
9276
9322
  copyCurve2d: (curve) => copyCurve2d(curve),
9277
9323
  offsetCurve2d: (curve, off) => offsetCurve2d(curve, off),
9278
9324
  translateCurve2d: (curve, dx, dy) => translateCurve2d(curve, dx, dy),
@@ -49,6 +49,12 @@ export default class CompoundSketch implements SketchInterface {
49
49
  revolve(revolutionAxis?: PointInput, config?: {
50
50
  origin?: PointInput;
51
51
  }): Shape3D;
52
- /** Loft between this compound sketch and another with matching sub-sketch counts. */
53
- loftWith(otherCompound: this, loftConfig: LoftOptions): Shape3D;
52
+ /**
53
+ * Loft between this compound sketch and another with matching sub-sketch
54
+ * counts. The target must itself be a compound sketch — lofting a
55
+ * face-with-holes profile to a single-wire one has no defined meaning.
56
+ */
57
+ loftWith(otherCompound: SketchInterface | SketchInterface[], loftConfig?: LoftOptions): Shape3D;
58
+ /** Sweeping a face-with-holes profile has no single well-defined spine. */
59
+ sweepSketch(): Shape3D;
54
60
  }
@@ -41,7 +41,12 @@ export interface SketchInterface {
41
41
  *
42
42
  * Note that all sketches will be deleted by this operation
43
43
  */
44
- loftWith(otherSketches: this | this[], loftConfig: LoftOptions, returnShell?: boolean): Shape3D;
44
+ loftWith(otherSketches: SketchInterface | SketchInterface[], loftConfig?: LoftOptions, returnShell?: boolean): Shape3D;
45
+ /**
46
+ * Sweep a profile sketch (built by the `sketchOnPlane` callback) along this
47
+ * sketch's wire path.
48
+ */
49
+ sweepSketch(sketchOnPlane: (plane: Plane, origin: Vec3) => SketchInterface, sweepConfig?: SweepOptions): Shape3D;
45
50
  }
46
51
  /**
47
52
  * Represent a closed or open wire profile with a default extrusion origin and direction.
@@ -137,7 +142,7 @@ export default class Sketch implements SketchInterface {
137
142
  * @remarks Consumes both this sketch and the one returned by `sketchOnPlane` —
138
143
  * calling either consumer twice throws on the second call.
139
144
  */
140
- sweepSketch(sketchOnPlane: (plane: Plane, origin: Vec3) => this, sweepConfig?: SweepOptions): Shape3D;
145
+ sweepSketch(sketchOnPlane: (plane: Plane, origin: Vec3) => SketchInterface, sweepConfig?: SweepOptions): Shape3D;
141
146
  /** Loft between this sketch and another sketch (or an array of them)
142
147
  *
143
148
  * You can also define a `startPoint` for the loft (that will be placed
@@ -147,5 +152,5 @@ export default class Sketch implements SketchInterface {
147
152
  *
148
153
  * Note that all sketches will be deleted by this operation
149
154
  */
150
- loftWith(otherSketches: this | this[], loftConfig?: LoftOptions, returnShell?: boolean): Shape3D;
155
+ loftWith(otherSketches: SketchInterface | SketchInterface[], loftConfig?: LoftOptions, returnShell?: boolean): Shape3D;
151
156
  }
@@ -5,12 +5,20 @@ import { LoftOptions } from '../operations/loftFns.js';
5
5
  import { OrientedFace, Shape3D, Wire } from '../core/shapeTypes.js';
6
6
  import { PlanarFace } from '../core/validityTypes.js';
7
7
  import { SketchData } from '../2d/blueprints/lib.js';
8
- import { default as Sketch } from './sketch.js';
8
+ import { default as Sketch, SketchInterface } from './sketch.js';
9
9
  import { default as CompoundSketch } from './compoundSketch.js';
10
10
  /** Wrap SketchData into a Sketch instance. */
11
11
  export declare function wrapSketchData(data: SketchData): Sketch;
12
12
  /** Wrap an array of SketchData into a CompoundSketch. */
13
13
  export declare function wrapSketchDataArray(dataArr: SketchData[]): CompoundSketch;
14
+ /**
15
+ * Collapse a sketch-like (the `SketchInterface | Sketches` union that
16
+ * `Drawing.sketchOnPlane` can return) to a single {@link Sketch} for use as a
17
+ * loft or sweep section. A single-wire profile passes through; a multi-piece
18
+ * profile keeps its first wire and disposes the rest, since loft/sweep sections
19
+ * are single wires.
20
+ */
21
+ export declare function asSketch(sketchLike: SketchInterface): Sketch;
14
22
  /** Build a face from a sketch's closed planar wire. */
15
23
  export declare function sketchFace(sketch: Sketch): OrientedFace & PlanarFace;
16
24
  /** Return an independent clone of the sketch's wire. */
@@ -43,13 +51,13 @@ export declare function sketchExtrude(sketch: Sketch, extrusionDistance: number,
43
51
  * @remarks Consumes both this sketch and the one returned by `sketchOnPlane` —
44
52
  * calling either twice throws on the second call.
45
53
  */
46
- export declare function sketchSweep(sketch: Sketch, sketchOnPlane: (plane: Plane, origin: Vec3) => Sketch, sweepConfig?: SweepOptions): Shape3D;
54
+ export declare function sketchSweep(sketch: Sketch, sketchOnPlane: (plane: Plane, origin: Vec3) => SketchInterface, sweepConfig?: SweepOptions): Shape3D;
47
55
  /**
48
56
  * Loft between this sketch and one or more other sketches.
49
57
  *
50
58
  * @remarks Consumes all input sketches — calling twice throws on the second call.
51
59
  */
52
- export declare function sketchLoft(sketch: Sketch, otherSketches: Sketch | Sketch[], loftConfig?: LoftOptions, returnShell?: boolean): Shape3D;
60
+ export declare function sketchLoft(sketch: Sketch, otherSketches: SketchInterface | SketchInterface[], loftConfig?: LoftOptions, returnShell?: boolean): Shape3D;
53
61
  /** Build a face from a compound sketch (outer boundary with holes). */
54
62
  export declare function compoundSketchFace(sketch: CompoundSketch): OrientedFace & PlanarFace;
55
63
  /** Return all wires (outer + holes) combined into a compound shape. */
@@ -71,4 +79,4 @@ export declare function compoundSketchRevolve(sketch: CompoundSketch, revolution
71
79
  origin?: PointInput;
72
80
  }): Shape3D;
73
81
  /** Loft between two compound sketches with matching sub-sketch counts. */
74
- export declare function compoundSketchLoft(sketch: CompoundSketch, other: CompoundSketch, loftConfig: LoftOptions): Shape3D;
82
+ export declare function compoundSketchLoft(sketch: CompoundSketch, other: CompoundSketch, loftConfig?: LoftOptions): Shape3D;
@@ -1,19 +1,38 @@
1
- import { PointInput } from '../core/types.js';
2
- import { ExtrusionProfile } from '../operations/extrudeUtils.js';
3
- import { Compound } from '../core/shapeTypes.js';
1
+ import { PointInput, Vec3 } from '../core/types.js';
2
+ import { ExtrusionProfile, SweepOptions } from '../operations/extrudeUtils.js';
3
+ import { LoftOptions } from '../operations/loftFns.js';
4
+ import { Plane } from '../core/planeTypes.js';
5
+ import { Compound, Face, Shape3D } from '../core/shapeTypes.js';
4
6
  import { default as CompoundSketch } from './compoundSketch.js';
5
- import { default as Sketch } from './sketch.js';
7
+ import { default as Sketch, SketchInterface } from './sketch.js';
6
8
  /**
7
9
  * Batch wrapper around multiple {@link Sketch} or {@link CompoundSketch} instances.
8
10
  *
9
11
  * Applies the same operation (extrude, revolve, etc.) to every contained sketch
10
12
  * and returns the results combined into a single compound shape.
11
13
  *
14
+ * Implements {@link SketchInterface} so it is interchangeable with a single
15
+ * {@link Sketch} in the chained `Drawing.sketchOnPlane(...).extrude()` style.
16
+ * Operations with no per-profile batch meaning (`face`, `loftWith`,
17
+ * `sweepSketch`) require a single contained profile and otherwise throw.
18
+ *
12
19
  * @category Sketching
13
20
  */
14
- export default class Sketches {
21
+ export default class Sketches implements SketchInterface {
15
22
  sketches: Array<Sketch | CompoundSketch>;
16
23
  constructor(sketches: Array<Sketch | CompoundSketch>);
24
+ /**
25
+ * The sole contained {@link Sketch}, for operations that have no
26
+ * multi-profile meaning. Throws when there is more than one profile, or when
27
+ * the single profile is a compound (face-with-holes) sketch.
28
+ */
29
+ private soleSketch;
30
+ /** Build a face from the sole contained profile (see {@link Sketches.faces}). */
31
+ face(): Face;
32
+ /** Loft from the sole contained profile to one or more other sketches. */
33
+ loftWith(otherSketches: SketchInterface | SketchInterface[], loftConfig?: LoftOptions, returnShell?: boolean): Shape3D;
34
+ /** Sweep a profile along the sole contained sketch's wire. */
35
+ sweepSketch(sketchOnPlane: (plane: Plane, origin: Vec3) => SketchInterface, sweepConfig?: SweepOptions): Shape3D;
17
36
  /** Return all wires combined into a single compound shape. */
18
37
  wires(): Compound;
19
38
  /** Return all sketch faces combined into a single compound shape. */
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_textBlueprints = require("./textBlueprints-FGsoRUZ4.cjs");
3
- const require_blueprintSketcher = require("./blueprintSketcher-BgQ4HUQS.cjs");
4
- const require_drawFns = require("./drawFns-DwxukBbB.cjs");
2
+ const require_textBlueprints = require("./textBlueprints-CKFmYJHD.cjs");
3
+ const require_blueprintSketcher = require("./blueprintSketcher-ChpPo7tq.cjs");
4
+ const require_drawFns = require("./drawFns-C766Umy1.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-BgJ92ofq.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-NN_2dIb7.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-Dvp_j93V.js";
1
+ import { n as BaseSketcher2d, t as BlueprintSketcher } from "./blueprintSketcher-CxFmYBvh.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-C63kOWvC.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-CU7MHMR8.js";
4
4
  //#region src/sketching.ts
5
5
  /**
6
6
  * brepjs/sketching — Sketcher, Drawing, and sketch-to-shape operations.
@@ -1,13 +1,13 @@
1
- const require_shapeTypes = require("./shapeTypes-BHoIVN7I.cjs");
1
+ const require_shapeTypes = require("./shapeTypes-DwNTiXjG.cjs");
2
2
  const require_errors = require("./errors-CXJtc4I7.cjs");
3
- const require_topologyQueryFns = require("./topologyQueryFns-CJYc4A0j.cjs");
3
+ const require_topologyQueryFns = require("./topologyQueryFns-a2i0YhGF.cjs");
4
4
  const require_constants = require("./constants-BOVyEYGH.cjs");
5
5
  const require_vecOps = require("./vecOps-CCnJt-yH.cjs");
6
6
  const require_planeOps = require("./planeOps-BA4HfgQu.cjs");
7
- const require_faceFns = require("./faceFns-CEhhzLpI.cjs");
8
- const require_shapeFns = require("./shapeFns-C00nTg4m.cjs");
7
+ const require_faceFns = require("./faceFns-DSdVqqVP.cjs");
8
+ const require_shapeFns = require("./shapeFns-CeSEceUG.cjs");
9
9
  const require_arrayAccess = require("./arrayAccess-e4H9cBfh.cjs");
10
- const require_surfaceBuilders = require("./surfaceBuilders-7QLWQwje.cjs");
10
+ const require_surfaceBuilders = require("./surfaceBuilders-DvpxHHIm.cjs");
11
11
  //#region src/topology/booleanFns.ts
12
12
  /**
13
13
  * Boolean and compound operations — functional replacements for _3DShape boolean methods.
@@ -1,13 +1,13 @@
1
- import { Z as getKernel, _ as isSolid, c as createSolid, g as isShell, h as isShape3D, i as createCompound, l as createVertex, t as castShape } from "./shapeTypes-CL5wYLDw.js";
1
+ import { Z as getKernel, _ as isSolid, c as createSolid, g as isShell, h as isShape3D, i as createCompound, l as createVertex, t as castShape } from "./shapeTypes-BIcALNFv.js";
2
2
  import { A as ok, R as unwrap, b as err, d as validationError, i as kernelError, l as typeCastError, t as BrepErrorCode, v as andThen, w as isErr } from "./errors-DNWJsfVU.js";
3
- import { f as getVertices, p as getWires, s as getEdges } from "./topologyQueryFns-BtyNquQX.js";
3
+ import { f as getVertices, p as getWires, s as getEdges } from "./topologyQueryFns-0BIOC7YH.js";
4
4
  import { n as HASH_CODE_MAX } from "./constants-ITRzCnCp.js";
5
5
  import { h as vecScale, t as vecAdd } from "./vecOps-SKPRvPH-.js";
6
6
  import { o as resolvePlane } from "./planeOps-DSjjtrjg.js";
7
- import { _ as cast, v as downcast } from "./faceFns-CfCwtCKM.js";
8
- import { _ as propagateAllMetadata, g as collectInputFaceHashes, v as propagateMetadataByHash } from "./shapeFns-C0K2yQlH.js";
7
+ import { _ as cast, v as downcast } from "./faceFns-CmhEEB-L.js";
8
+ import { _ as propagateAllMetadata, g as collectInputFaceHashes, v as propagateMetadataByHash } from "./shapeFns-B0lN3o3r.js";
9
9
  import { n as getAtOrThrow, t as firstOrThrow } from "./arrayAccess-DrUGPADn.js";
10
- import { r as makeFace } from "./surfaceBuilders-DObQZa60.js";
10
+ import { r as makeFace } from "./surfaceBuilders-BQx3TjMH.js";
11
11
  //#region src/topology/booleanFns.ts
12
12
  /**
13
13
  * Boolean and compound operations — functional replacements for _3DShape boolean methods.
@@ -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-CL5wYLDw.js";
1
+ import { Z as getKernel, a as createEdge, o as createFace, p as isFace, u as createWire, w as isPlanarFace } from "./shapeTypes-BIcALNFv.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 { _ as cast, u as outerWire } from "./faceFns-CfCwtCKM.js";
3
+ import { _ as cast, u as outerWire } from "./faceFns-CmhEEB-L.js";
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
- const require_shapeTypes = require("./shapeTypes-BHoIVN7I.cjs");
1
+ const require_shapeTypes = require("./shapeTypes-DwNTiXjG.cjs");
2
2
  const require_errors = require("./errors-CXJtc4I7.cjs");
3
- const require_faceFns = require("./faceFns-CEhhzLpI.cjs");
3
+ const require_faceFns = require("./faceFns-DSdVqqVP.cjs");
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-FGsoRUZ4.cjs");
3
- const require_textMetrics = require("./textMetrics-BZbM75gl.cjs");
2
+ const require_textBlueprints = require("./textBlueprints-CKFmYJHD.cjs");
3
+ const require_textMetrics = require("./textMetrics-BYHtOFYW.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-Dvp_j93V.js";
2
- import { n as textMetrics, r as sketchText, t as fontMetrics } from "./textMetrics-rFF3uFYC.js";
1
+ import { n as getFont, r as loadFont, t as textBlueprints } from "./textBlueprints-CU7MHMR8.js";
2
+ import { n as textMetrics, r as sketchText, t as fontMetrics } from "./textMetrics-BDTWvvyd.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-BHoIVN7I.cjs");
32
+ const require_shapeTypes = require("./shapeTypes-DwNTiXjG.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-CEhhzLpI.cjs");
38
- const require_curveFns = require("./curveFns-ZfGUUd8h.cjs");
37
+ const require_faceFns = require("./faceFns-DSdVqqVP.cjs");
38
+ const require_curveFns = require("./curveFns-D3k8aHIE.cjs");
39
39
  const require_arrayAccess = require("./arrayAccess-e4H9cBfh.cjs");
40
- const require_surfaceBuilders = require("./surfaceBuilders-7QLWQwje.cjs");
41
- const require_solidBuilders = require("./solidBuilders-C73RAr6j.cjs");
42
- const require_blueprintSketcher = require("./blueprintSketcher-BgQ4HUQS.cjs");
43
- const require_loftFns = require("./loftFns-D4xbMwPh.cjs");
40
+ const require_surfaceBuilders = require("./surfaceBuilders-DvpxHHIm.cjs");
41
+ const require_solidBuilders = require("./solidBuilders-B_5FgvuK.cjs");
42
+ const require_blueprintSketcher = require("./blueprintSketcher-ChpPo7tq.cjs");
43
+ const require_loftFns = require("./loftFns-C664R57e.cjs");
44
44
  let opentype_js = require("opentype.js");
45
45
  opentype_js = __toESM(opentype_js, 1);
46
46
  //#region src/sketching/compoundSketch.ts
@@ -58,7 +58,7 @@ opentype_js = __toESM(opentype_js, 1);
58
58
  * @see {@link Sketch} for single-wire profiles without holes.
59
59
  * @category Sketching
60
60
  */
61
- var CompoundSketch = class {
61
+ var CompoundSketch = class CompoundSketch {
62
62
  sketches;
63
63
  constructor(sketches) {
64
64
  if (sketches.length === 0) require_errors.bug("CompoundSketch", "Cannot create CompoundSketch with an empty array of sketches");
@@ -102,10 +102,19 @@ var CompoundSketch = class {
102
102
  revolve(revolutionAxis, config = {}) {
103
103
  return compoundSketchRevolve(this, revolutionAxis, config);
104
104
  }
105
- /** Loft between this compound sketch and another with matching sub-sketch counts. */
106
- loftWith(otherCompound, loftConfig) {
105
+ /**
106
+ * Loft between this compound sketch and another with matching sub-sketch
107
+ * counts. The target must itself be a compound sketch — lofting a
108
+ * face-with-holes profile to a single-wire one has no defined meaning.
109
+ */
110
+ loftWith(otherCompound, loftConfig = {}) {
111
+ if (Array.isArray(otherCompound) || !(otherCompound instanceof CompoundSketch)) return require_errors.bug("CompoundSketch.loftWith", "A compound (face-with-holes) sketch can only loft to another compound sketch with the same number of sub-sketches.");
107
112
  return compoundSketchLoft(this, otherCompound, loftConfig);
108
113
  }
114
+ /** Sweeping a face-with-holes profile has no single well-defined spine. */
115
+ sweepSketch() {
116
+ return require_errors.bug("CompoundSketch.sweepSketch", "Sweeping a compound (face-with-holes) profile is not supported — sweep its outer Sketch instead.");
117
+ }
109
118
  };
110
119
  //#endregion
111
120
  //#region src/sketching/sketchFns.ts
@@ -122,6 +131,25 @@ function wrapSketchData(data) {
122
131
  function wrapSketchDataArray(dataArr) {
123
132
  return new CompoundSketch(dataArr.map(wrapSketchData));
124
133
  }
134
+ /**
135
+ * Collapse a sketch-like (the `SketchInterface | Sketches` union that
136
+ * `Drawing.sketchOnPlane` can return) to a single {@link Sketch} for use as a
137
+ * loft or sweep section. A single-wire profile passes through; a multi-piece
138
+ * profile keeps its first wire and disposes the rest, since loft/sweep sections
139
+ * are single wires.
140
+ */
141
+ function asSketch(sketchLike) {
142
+ if (sketchLike instanceof Sketch) return sketchLike;
143
+ const pieces = sketchLike.sketches;
144
+ if (Array.isArray(pieces)) {
145
+ const [first, ...rest] = pieces;
146
+ if (first instanceof Sketch) {
147
+ for (const extra of rest) extra.delete();
148
+ return first;
149
+ }
150
+ }
151
+ require_errors.bug("asSketch", "Expected a single-wire profile to loft or sweep.");
152
+ }
125
153
  /** Build a face from a sketch's closed planar wire. */
126
154
  function sketchFace(sketch) {
127
155
  let face;
@@ -185,13 +213,7 @@ function sketchSweep(sketch, sketchOnPlane, sweepConfig = {}) {
185
213
  const normal = require_vecOps.vecNormalize(require_vecOps.vecScale(require_curveFns.curveTangentAt(sketch.wire, 1e-9), -1));
186
214
  const defaultDir = sketch.defaultDirection;
187
215
  const xDir = require_vecOps.vecScale(require_vecOps.vecCross(normal, defaultDir), -1);
188
- const result = sketchOnPlane(require_planeOps.createPlane([...startPoint], [...xDir], [...normal]), [...startPoint]);
189
- let profile;
190
- if ("sketches" in result && Array.isArray(result.sketches)) {
191
- const pieces = result.sketches;
192
- profile = pieces[0];
193
- for (let i = 1; i < pieces.length; i++) pieces[i]?.delete();
194
- } else profile = result;
216
+ const profile = asSketch(sketchOnPlane(require_planeOps.createPlane([...startPoint], [...xDir], [...normal]), [...startPoint]));
195
217
  const config = {
196
218
  forceProfileSpineOthogonality: true,
197
219
  ...sweepConfig
@@ -207,7 +229,7 @@ function sketchSweep(sketch, sketchOnPlane, sweepConfig = {}) {
207
229
  * @remarks Consumes all input sketches — calling twice throws on the second call.
208
230
  */
209
231
  function sketchLoft(sketch, otherSketches, loftConfig = {}, returnShell = false) {
210
- const sketchArray = Array.isArray(otherSketches) ? [sketch, ...otherSketches] : [sketch, otherSketches];
232
+ const sketchArray = [sketch, ...(Array.isArray(otherSketches) ? otherSketches : [otherSketches]).map(asSketch)];
211
233
  const shape = require_errors.unwrap(require_loftFns.loft(sketchArray.map((s) => s.wire), loftConfig, returnShell));
212
234
  sketchArray.forEach((s) => {
213
235
  s.delete();
@@ -268,7 +290,7 @@ function compoundSketchRevolve(sketch, revolutionAxis, { origin } = {}) {
268
290
  return require_errors.unwrap(require_loftFns.revolve(compoundSketchFace(sketch), center, dir));
269
291
  }
270
292
  /** Loft between two compound sketches with matching sub-sketch counts. */
271
- function compoundSketchLoft(sketch, other, loftConfig) {
293
+ function compoundSketchLoft(sketch, other, loftConfig = {}) {
272
294
  if (sketch.sketches.length !== other.sketches.length) require_errors.bug("CompoundSketch.loftWith", "You need to loft with another compound with the same number of sketches");
273
295
  const shells = sketch.sketches.map((base, cIndex) => {
274
296
  const outer = require_arrayAccess.getAtOrThrow(other.sketches, cIndex);
@@ -436,6 +458,11 @@ var Sketch = class Sketch {
436
458
  * Applies the same operation (extrude, revolve, etc.) to every contained sketch
437
459
  * and returns the results combined into a single compound shape.
438
460
  *
461
+ * Implements {@link SketchInterface} so it is interchangeable with a single
462
+ * {@link Sketch} in the chained `Drawing.sketchOnPlane(...).extrude()` style.
463
+ * Operations with no per-profile batch meaning (`face`, `loftWith`,
464
+ * `sweepSketch`) require a single contained profile and otherwise throw.
465
+ *
439
466
  * @category Sketching
440
467
  */
441
468
  var Sketches = class {
@@ -443,6 +470,30 @@ var Sketches = class {
443
470
  constructor(sketches) {
444
471
  this.sketches = sketches;
445
472
  }
473
+ /**
474
+ * The sole contained {@link Sketch}, for operations that have no
475
+ * multi-profile meaning. Throws when there is more than one profile, or when
476
+ * the single profile is a compound (face-with-holes) sketch.
477
+ */
478
+ soleSketch(op) {
479
+ if (this.sketches.length !== 1) require_errors.bug(`Sketches.${op}`, `Multiple profiles — ${op} each sub-sketch individually.`);
480
+ const only = require_arrayAccess.firstOrThrow(this.sketches);
481
+ if (!(only instanceof Sketch)) require_errors.bug(`Sketches.${op}`, `${op} is only supported on single-wire profiles.`);
482
+ return only;
483
+ }
484
+ /** Build a face from the sole contained profile (see {@link Sketches.faces}). */
485
+ face() {
486
+ if (this.sketches.length !== 1) require_errors.bug("Sketches.face", "Multiple profiles — use faces() to combine them.");
487
+ return require_arrayAccess.firstOrThrow(this.sketches).face();
488
+ }
489
+ /** Loft from the sole contained profile to one or more other sketches. */
490
+ loftWith(otherSketches, loftConfig, returnShell) {
491
+ return this.soleSketch("loftWith").loftWith(otherSketches, loftConfig, returnShell);
492
+ }
493
+ /** Sweep a profile along the sole contained sketch's wire. */
494
+ sweepSketch(sketchOnPlane, sweepConfig) {
495
+ return this.soleSketch("sweepSketch").sweepSketch(sketchOnPlane, sweepConfig);
496
+ }
446
497
  /** Return all wires combined into a single compound shape. */
447
498
  wires() {
448
499
  return require_solidBuilders.makeCompound(this.sketches.map((s) => s instanceof Sketch ? s.wire : s.wires));
@@ -1,15 +1,15 @@
1
- import { o as createFace, u as createWire } from "./shapeTypes-CL5wYLDw.js";
1
+ import { o as createFace, u as createWire } from "./shapeTypes-BIcALNFv.js";
2
2
  import { A as ok, R as unwrap, b as err, h as bug, 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 { v as downcast } from "./faceFns-CfCwtCKM.js";
7
- import { l as curveStartPoint, u as curveTangentAt } from "./curveFns-BMvOjgAe.js";
6
+ import { v as downcast } from "./faceFns-CmhEEB-L.js";
7
+ import { l as curveStartPoint, u as curveTangentAt } from "./curveFns-DT1yMgBI.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-DObQZa60.js";
10
- import { o as makeSolid, p as cutAll, t as makeCompound } from "./solidBuilders-Bp_Gf3y_.js";
11
- import { r as organiseBlueprints, t as BlueprintSketcher } from "./blueprintSketcher-BgJ92ofq.js";
12
- import { a as revolve, d as twistExtrude, o as complexExtrude, r as extrude, t as loft, u as sweep } from "./loftFns-BLwuVjwA.js";
9
+ import { i as makeNewFaceWithinFace, r as makeFace, t as addHolesInFace } from "./surfaceBuilders-BQx3TjMH.js";
10
+ import { o as makeSolid, p as cutAll, t as makeCompound } from "./solidBuilders-Bb5_uC7F.js";
11
+ import { r as organiseBlueprints, t as BlueprintSketcher } from "./blueprintSketcher-CxFmYBvh.js";
12
+ import { a as revolve, d as twistExtrude, o as complexExtrude, r as extrude, t as loft, u as sweep } from "./loftFns-C8Ep9McS.js";
13
13
  import opentype from "opentype.js";
14
14
  //#region src/sketching/compoundSketch.ts
15
15
  /**
@@ -26,7 +26,7 @@ import opentype from "opentype.js";
26
26
  * @see {@link Sketch} for single-wire profiles without holes.
27
27
  * @category Sketching
28
28
  */
29
- var CompoundSketch = class {
29
+ var CompoundSketch = class CompoundSketch {
30
30
  sketches;
31
31
  constructor(sketches) {
32
32
  if (sketches.length === 0) bug("CompoundSketch", "Cannot create CompoundSketch with an empty array of sketches");
@@ -70,10 +70,19 @@ var CompoundSketch = class {
70
70
  revolve(revolutionAxis, config = {}) {
71
71
  return compoundSketchRevolve(this, revolutionAxis, config);
72
72
  }
73
- /** Loft between this compound sketch and another with matching sub-sketch counts. */
74
- loftWith(otherCompound, loftConfig) {
73
+ /**
74
+ * Loft between this compound sketch and another with matching sub-sketch
75
+ * counts. The target must itself be a compound sketch — lofting a
76
+ * face-with-holes profile to a single-wire one has no defined meaning.
77
+ */
78
+ loftWith(otherCompound, loftConfig = {}) {
79
+ if (Array.isArray(otherCompound) || !(otherCompound instanceof CompoundSketch)) return bug("CompoundSketch.loftWith", "A compound (face-with-holes) sketch can only loft to another compound sketch with the same number of sub-sketches.");
75
80
  return compoundSketchLoft(this, otherCompound, loftConfig);
76
81
  }
82
+ /** Sweeping a face-with-holes profile has no single well-defined spine. */
83
+ sweepSketch() {
84
+ return bug("CompoundSketch.sweepSketch", "Sweeping a compound (face-with-holes) profile is not supported — sweep its outer Sketch instead.");
85
+ }
77
86
  };
78
87
  //#endregion
79
88
  //#region src/sketching/sketchFns.ts
@@ -90,6 +99,25 @@ function wrapSketchData(data) {
90
99
  function wrapSketchDataArray(dataArr) {
91
100
  return new CompoundSketch(dataArr.map(wrapSketchData));
92
101
  }
102
+ /**
103
+ * Collapse a sketch-like (the `SketchInterface | Sketches` union that
104
+ * `Drawing.sketchOnPlane` can return) to a single {@link Sketch} for use as a
105
+ * loft or sweep section. A single-wire profile passes through; a multi-piece
106
+ * profile keeps its first wire and disposes the rest, since loft/sweep sections
107
+ * are single wires.
108
+ */
109
+ function asSketch(sketchLike) {
110
+ if (sketchLike instanceof Sketch) return sketchLike;
111
+ const pieces = sketchLike.sketches;
112
+ if (Array.isArray(pieces)) {
113
+ const [first, ...rest] = pieces;
114
+ if (first instanceof Sketch) {
115
+ for (const extra of rest) extra.delete();
116
+ return first;
117
+ }
118
+ }
119
+ bug("asSketch", "Expected a single-wire profile to loft or sweep.");
120
+ }
93
121
  /** Build a face from a sketch's closed planar wire. */
94
122
  function sketchFace(sketch) {
95
123
  let face;
@@ -153,13 +181,7 @@ function sketchSweep(sketch, sketchOnPlane, sweepConfig = {}) {
153
181
  const normal = vecNormalize(vecScale(curveTangentAt(sketch.wire, 1e-9), -1));
154
182
  const defaultDir = sketch.defaultDirection;
155
183
  const xDir = vecScale(vecCross(normal, defaultDir), -1);
156
- const result = sketchOnPlane(createPlane([...startPoint], [...xDir], [...normal]), [...startPoint]);
157
- let profile;
158
- if ("sketches" in result && Array.isArray(result.sketches)) {
159
- const pieces = result.sketches;
160
- profile = pieces[0];
161
- for (let i = 1; i < pieces.length; i++) pieces[i]?.delete();
162
- } else profile = result;
184
+ const profile = asSketch(sketchOnPlane(createPlane([...startPoint], [...xDir], [...normal]), [...startPoint]));
163
185
  const config = {
164
186
  forceProfileSpineOthogonality: true,
165
187
  ...sweepConfig
@@ -175,7 +197,7 @@ function sketchSweep(sketch, sketchOnPlane, sweepConfig = {}) {
175
197
  * @remarks Consumes all input sketches — calling twice throws on the second call.
176
198
  */
177
199
  function sketchLoft(sketch, otherSketches, loftConfig = {}, returnShell = false) {
178
- const sketchArray = Array.isArray(otherSketches) ? [sketch, ...otherSketches] : [sketch, otherSketches];
200
+ const sketchArray = [sketch, ...(Array.isArray(otherSketches) ? otherSketches : [otherSketches]).map(asSketch)];
179
201
  const shape = unwrap(loft(sketchArray.map((s) => s.wire), loftConfig, returnShell));
180
202
  sketchArray.forEach((s) => {
181
203
  s.delete();
@@ -236,7 +258,7 @@ function compoundSketchRevolve(sketch, revolutionAxis, { origin } = {}) {
236
258
  return unwrap(revolve(compoundSketchFace(sketch), center, dir));
237
259
  }
238
260
  /** Loft between two compound sketches with matching sub-sketch counts. */
239
- function compoundSketchLoft(sketch, other, loftConfig) {
261
+ function compoundSketchLoft(sketch, other, loftConfig = {}) {
240
262
  if (sketch.sketches.length !== other.sketches.length) bug("CompoundSketch.loftWith", "You need to loft with another compound with the same number of sketches");
241
263
  const shells = sketch.sketches.map((base, cIndex) => {
242
264
  const outer = getAtOrThrow(other.sketches, cIndex);
@@ -404,6 +426,11 @@ var Sketch = class Sketch {
404
426
  * Applies the same operation (extrude, revolve, etc.) to every contained sketch
405
427
  * and returns the results combined into a single compound shape.
406
428
  *
429
+ * Implements {@link SketchInterface} so it is interchangeable with a single
430
+ * {@link Sketch} in the chained `Drawing.sketchOnPlane(...).extrude()` style.
431
+ * Operations with no per-profile batch meaning (`face`, `loftWith`,
432
+ * `sweepSketch`) require a single contained profile and otherwise throw.
433
+ *
407
434
  * @category Sketching
408
435
  */
409
436
  var Sketches = class {
@@ -411,6 +438,30 @@ var Sketches = class {
411
438
  constructor(sketches) {
412
439
  this.sketches = sketches;
413
440
  }
441
+ /**
442
+ * The sole contained {@link Sketch}, for operations that have no
443
+ * multi-profile meaning. Throws when there is more than one profile, or when
444
+ * the single profile is a compound (face-with-holes) sketch.
445
+ */
446
+ soleSketch(op) {
447
+ if (this.sketches.length !== 1) bug(`Sketches.${op}`, `Multiple profiles — ${op} each sub-sketch individually.`);
448
+ const only = firstOrThrow(this.sketches);
449
+ if (!(only instanceof Sketch)) bug(`Sketches.${op}`, `${op} is only supported on single-wire profiles.`);
450
+ return only;
451
+ }
452
+ /** Build a face from the sole contained profile (see {@link Sketches.faces}). */
453
+ face() {
454
+ if (this.sketches.length !== 1) bug("Sketches.face", "Multiple profiles — use faces() to combine them.");
455
+ return firstOrThrow(this.sketches).face();
456
+ }
457
+ /** Loft from the sole contained profile to one or more other sketches. */
458
+ loftWith(otherSketches, loftConfig, returnShell) {
459
+ return this.soleSketch("loftWith").loftWith(otherSketches, loftConfig, returnShell);
460
+ }
461
+ /** Sweep a profile along the sole contained sketch's wire. */
462
+ sweepSketch(sketchOnPlane, sweepConfig) {
463
+ return this.soleSketch("sweepSketch").sweepSketch(sketchOnPlane, sweepConfig);
464
+ }
414
465
  /** Return all wires combined into a single compound shape. */
415
466
  wires() {
416
467
  return makeCompound(this.sketches.map((s) => s instanceof Sketch ? s.wire : s.wires));
@@ -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-Dvp_j93V.js";
2
+ import { g as wrapSketchData, i as Sketches, n as getFont, t as textBlueprints, v as CompoundSketch } from "./textBlueprints-CU7MHMR8.js";
3
3
  //#region src/text/sketchText.ts
4
4
  /**
5
5
  * Render text as 3D sketch outlines on a plane.
@@ -1,4 +1,4 @@
1
- const require_textBlueprints = require("./textBlueprints-FGsoRUZ4.cjs");
1
+ const require_textBlueprints = require("./textBlueprints-CKFmYJHD.cjs");
2
2
  const require_errors = require("./errors-CXJtc4I7.cjs");
3
3
  //#region src/text/sketchText.ts
4
4
  /**