@metamesh/modeling 0.6.0 → 0.8.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 (50) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +157 -22
  3. package/dist/api/engine.d.ts +25 -4
  4. package/dist/api/geometry.d.ts +391 -82
  5. package/dist/api/index.d.ts +732 -108
  6. package/dist/api/text.d.ts +40 -10
  7. package/dist/engine/construction-operations.js +52 -10
  8. package/dist/engine/execution.js +55 -2
  9. package/dist/engine/export-3mf.js +17 -1
  10. package/dist/engine/finalization.js +27 -18
  11. package/dist/engine/index.js +12 -1
  12. package/dist/engine/inspection-operations.js +26 -22
  13. package/dist/engine/loft-operations.js +1 -1
  14. package/dist/engine/mechanical-operations.js +5 -8
  15. package/dist/engine/mesh-view-cache.js +23 -0
  16. package/dist/engine/native/adapter.js +2 -4
  17. package/dist/engine/native/distance.js +42 -0
  18. package/dist/engine/native/status.js +16 -0
  19. package/dist/engine/operation-environment.js +2 -1
  20. package/dist/engine/section-operations.js +3 -3
  21. package/dist/geometry/curves/sampling.js +2 -1
  22. package/dist/geometry/heightfield.js +109 -42
  23. package/dist/geometry/index.js +2 -0
  24. package/dist/geometry/loft-simple-mesh.js +2 -3
  25. package/dist/geometry/loft-triangulation.js +12 -9
  26. package/dist/geometry/loft.js +18 -7
  27. package/dist/geometry/math/vector3.js +35 -5
  28. package/dist/geometry/mechanical/standards.js +2 -3
  29. package/dist/geometry/mechanical/thread-profiles.js +5 -0
  30. package/dist/geometry/mechanical/threads.js +2 -3
  31. package/dist/geometry/mesh-centroid.js +36 -0
  32. package/dist/geometry/mesh-edge-table.js +126 -0
  33. package/dist/geometry/mesh-solid-intersections.js +123 -0
  34. package/dist/geometry/mesh-solid.js +284 -0
  35. package/dist/geometry/mesh.js +8 -25
  36. package/dist/geometry/paths/path.js +3 -1
  37. package/dist/geometry/paths/resampling.js +2 -1
  38. package/dist/geometry/profiles/matched.js +8 -0
  39. package/dist/geometry/profiles/profiles.js +24 -3
  40. package/dist/geometry/profiles/rectangle.js +16 -2
  41. package/dist/geometry/profiles/shapes.js +8 -1
  42. package/dist/geometry/revolve/revolve-mesh.js +6 -0
  43. package/dist/geometry/sweeps/sweep-closed.js +4 -4
  44. package/dist/geometry/sweeps/sweep-mesh.js +13 -7
  45. package/dist/geometry/sweeps/sweep-open.js +4 -4
  46. package/dist/geometry/sweeps/validation.js +1 -2
  47. package/dist/model/operations.js +13 -4
  48. package/dist/text/index.js +11 -1
  49. package/dist/text/vector-text-layout.js +46 -3
  50. package/package.json +1 -1
@@ -32,7 +32,9 @@ export declare interface Anchor3 {
32
32
  /** Host-bound attach operation. Valid only during a synchronous build. */
33
33
  export declare const attach: ModelingContext["attach"];
34
34
 
35
- /** Degree-based anchor attachment controls for a scoped solid. */
35
+ /**
36
+ * Degree-based anchor attachment controls for a scoped solid.
37
+ */
36
38
  export declare interface AttachOptions {
37
39
  /** Align outward directions face-to-face (`opposed`) or in parallel (`same`). */
38
40
  readonly alignment?: "opposed" | "same";
@@ -56,7 +58,9 @@ export declare type BoxEdgeSelection = BoxEdge | "top" | "bottom" | "vertical";
56
58
  /** Independent treatments for disjoint named edge selections; overlapping selections fail. */
57
59
  export declare type BoxEdgeTreatments = Readonly<Partial<Record<BoxEdgeSelection, EdgeTreatment>>>;
58
60
 
59
- /** Dimensions, placement, and uniform or independently selected finishing for an axis-aligned box. */
61
+ /**
62
+ * Dimensions, placement, and uniform or independently selected finishing for an axis-aligned box.
63
+ */
60
64
  export declare interface BoxOptions extends PrimitivePlacement {
61
65
  /** Explicit sampling ceilings for edge treatments, bounded by the host policy. */
62
66
  readonly limits?: Partial<GeometrySamplingLimits>;
@@ -94,7 +98,9 @@ declare interface ButtressThreadProfileSpec extends ThreadProfileBaseSpec {
94
98
  readonly pressureFlankSide?: ButtressPressureFlankSide;
95
99
  }
96
100
 
97
- /** A planar edge or corner chamfer with equal or independent surface setbacks. */
101
+ /**
102
+ * A planar edge or corner chamfer with equal or independent surface setbacks.
103
+ */
98
104
  export declare interface ChamferedEdgeTreatment {
99
105
  /** Selects a straight bevel between adjoining surfaces. */
100
106
  readonly kind: "chamfer";
@@ -105,7 +111,9 @@ export declare interface ChamferedEdgeTreatment {
105
111
  /** Host-bound circle operation. Valid only during a synchronous build. */
106
112
  export declare const circle: ModelingContext["circle"];
107
113
 
108
- /** Circular profile dimensions with exactly one radius or diameter and explicit sampling. */
114
+ /**
115
+ * Circular profile dimensions with exactly one radius or diameter and explicit sampling.
116
+ */
109
117
  export declare type CircleLoopOptions = CircularPrimitiveOptions & RadialSizingOptions & ({
110
118
  /** Positive nominal radius in millimetres; mutually exclusive with diameter. */
111
119
  readonly radius: number;
@@ -118,10 +126,14 @@ export declare type CircleLoopOptions = CircularPrimitiveOptions & RadialSizingO
118
126
  readonly radius?: never;
119
127
  });
120
128
 
121
- /** Circular dimensions with exactly one nominal radius or diameter. */
129
+ /**
130
+ * Circular dimensions with exactly one nominal radius or diameter.
131
+ */
122
132
  export declare type CircleOptions = CircleLoopOptions & PrimitivePlacement;
123
133
 
124
- /** Tessellation controls shared by circular primitives across Geometry entry points. */
134
+ /**
135
+ * Tessellation controls shared by circular primitives across Geometry entry points.
136
+ */
125
137
  export declare interface CircularPrimitiveOptions {
126
138
  /** Explicit sampling ceilings; bound modeling operations may only lower the host policy. */
127
139
  readonly limits?: Partial<GeometrySamplingLimits>;
@@ -188,7 +200,9 @@ declare interface CustomThreadProfileSpec extends ThreadProfileBaseSpec {
188
200
  /** Host-bound cylinder operation. Valid only during a synchronous build. */
189
201
  export declare const cylinder: ModelingContext["cylinder"];
190
202
 
191
- /** Dimensions, placement, independent end finishing, and tessellation for a Z-axis cylinder or frustum. */
203
+ /**
204
+ * Dimensions, placement, independent end finishing, and tessellation for a Z-axis cylinder or frustum.
205
+ */
192
206
  export declare type CylinderOptions = CircularPrimitiveOptions & RadialSizingOptions & PrimitivePlacement & {
193
207
  /**
194
208
  * Centers the solid on the Z origin when `true`; otherwise its bottom is at `Z = 0`.
@@ -211,13 +225,20 @@ export declare type CylinderOptions = CircularPrimitiveOptions & RadialSizingOpt
211
225
  readonly radius?: never;
212
226
  });
213
227
 
214
- /** Uniform finishing vocabulary shared by applicable solid edges and profile corners. */
228
+ /** Measures the minimum separation between two nonempty solids in millimetres. */
229
+ export declare const distance: ModelingContext["distance"];
230
+
231
+ /**
232
+ * Uniform finishing vocabulary shared by applicable solid edges and profile corners.
233
+ */
215
234
  export declare type EdgeTreatment = ChamferedEdgeTreatment | RoundedEdgeTreatment | SmoothEdgeTreatment | ProfiledEdgeTreatment;
216
235
 
217
236
  /** Host-bound ellipse operation. Valid only during a synchronous build. */
218
237
  export declare const ellipse: ModelingContext["ellipse"];
219
238
 
220
- /** Ellipse dimensions with exactly one XY radii or full-size tuple and explicit sampling. */
239
+ /**
240
+ * Ellipse dimensions with exactly one XY radii or full-size tuple and explicit sampling.
241
+ */
221
242
  export declare type EllipseLoopOptions = CircularPrimitiveOptions & ({
222
243
  /** Positive XY radii in millimetres; mutually exclusive with size. */
223
244
  readonly radius: Vec2;
@@ -230,10 +251,14 @@ export declare type EllipseLoopOptions = CircularPrimitiveOptions & ({
230
251
  readonly radius?: never;
231
252
  });
232
253
 
233
- /** Ellipse dimensions in local XY, with exactly one radii or full-size tuple. */
254
+ /**
255
+ * Ellipse dimensions in local XY, with exactly one radii or full-size tuple.
256
+ */
234
257
  export declare type EllipseOptions = EllipseLoopOptions & PrimitivePlacement;
235
258
 
236
- /** Independent inward finishing on primitive or straight convex extrusion ends. */
259
+ /**
260
+ * Independent inward finishing on primitive or straight convex extrusion ends.
261
+ */
237
262
  export declare interface EndTreatments {
238
263
  /** Bottom cap and adjoining side; omitted leaves the end untreated. */
239
264
  readonly bottom?: EdgeTreatment;
@@ -244,7 +269,9 @@ export declare interface EndTreatments {
244
269
  /** Host-bound extrude operation. Valid only during a synchronous build. */
245
270
  export declare const extrude: ModelingContext["extrude"];
246
271
 
247
- /** Dimensions and sampling shared by native and pure +Z extrusion. */
272
+ /**
273
+ * Dimensions and sampling shared by native and pure +Z extrusion.
274
+ */
248
275
  export declare interface ExtrudeOptions extends ExtrusionSamplingOptions {
249
276
  /** Positive extrusion height in millimetres. */
250
277
  readonly height: number;
@@ -318,7 +345,9 @@ export declare interface Frame3 {
318
345
  /** Host-bound fromRegion operation. Valid only during a synchronous build. */
319
346
  export declare const fromRegion: ModelingContext["fromRegion"];
320
347
 
321
- /** Tessellation policy for sampled geometry measured in millimetres. */
348
+ /**
349
+ * Tessellation policy for sampled geometry measured in millimetres.
350
+ */
322
351
  export declare interface GeometryResolution {
323
352
  /** Optional exact full-circle segment count, of at least three, bounded by the selected circular ceiling. */
324
353
  readonly circularSegments?: number;
@@ -357,7 +386,9 @@ export declare interface GeometryToleranceOptions {
357
386
  /** Host-bound gridPattern operation. Valid only during a synchronous build. */
358
387
  export declare const gridPattern: ModelingContext["gridPattern"];
359
388
 
360
- /** XY or XYZ grid with X varying fastest. The first item starts at the local origin. */
389
+ /**
390
+ * XY or XYZ grid with X varying fastest. The first item starts at the local origin.
391
+ */
361
392
  export declare type GridPatternOptions = {
362
393
  /** Center the complete distribution around its local origin; defaults to false. */
363
394
  readonly center?: boolean;
@@ -375,22 +406,57 @@ export declare type GridPatternOptions = {
375
406
  readonly spacing: Vec3;
376
407
  });
377
408
 
378
- /** Constructs a closed regularly sampled heightfield during the active synchronous build. */
409
+ /** Constructs a closed rectilinear heightfield during the active synchronous build. */
379
410
  export declare const heightfield: ModelingContext["heightfield"];
380
411
 
381
- /** A regularly sampled, closed heightfield above a flat base, in millimetres. */
382
- export declare interface HeightfieldOptions {
383
- /** Positive XY footprint. */
384
- readonly size: Vec2;
385
- /** Exact positive integer X/Y interval counts. */
386
- readonly segments: readonly [x: number, y: number];
412
+ /**
413
+ * A closed rectilinear heightfield above a flat base, with uniform or explicit XY samples in millimetres.
414
+ *
415
+ * Uniform sampling requires positive `size: [width, depth]` and positive integer `segments: [x, y]`.
416
+ * Optional `origin` sets the lower-left XY corner; omitting it centres the footprint on XY.
417
+ * Alternatively, supply `coordinates: { x, y }` with at least two strictly increasing finite
418
+ * absolute samples per axis, distinct in Float32. This infers the footprint and interval counts;
419
+ * `size`, `segments`, and `origin` cannot be combined with explicit coordinates.
420
+ */
421
+ export declare type HeightfieldOptions = {
387
422
  /** Absolute top Z at the supplied XY point. Every sample must be above baseZ. */
388
423
  readonly height: (point: Vec2) => number;
389
424
  /** Flat bottom Z. Defaults to zero. */
390
425
  readonly baseZ?: number;
426
+ /**
427
+ * Top-cell diagonal policy. Defaults to fixed (lower-left to upper-right).
428
+ * min-edge selects the shorter 3D diagonal; center-error selects the diagonal whose endpoint
429
+ * average is closest to one extra height sample at the physical cell centre. Ties use fixed.
430
+ * All policies retain two triangles per cell; neither estimates error elsewhere in the cell.
431
+ */
432
+ readonly triangulation?: "fixed" | "min-edge" | "center-error";
433
+ } & ({
434
+ /** Positive XY footprint for uniform sampling. */
435
+ readonly size: Vec2;
436
+ /** Exact positive integer X/Y interval counts. */
437
+ readonly segments: readonly [x: number, y: number];
391
438
  /** Lower-left footprint XY. Omitted centers the footprint on XY. */
392
439
  readonly origin?: Vec2;
393
- }
440
+ /** Explicit coordinates cannot be combined with uniform sampling. */
441
+ readonly coordinates?: never;
442
+ } | {
443
+ /**
444
+ * Absolute XY coordinates, each with at least two strictly increasing finite values that
445
+ * remain distinct in Float32. Uneven spacing permits caller-owned local refinement.
446
+ */
447
+ readonly coordinates: {
448
+ /** Absolute X samples in ascending order. */
449
+ readonly x: readonly number[];
450
+ /** Absolute Y samples in ascending order. */
451
+ readonly y: readonly number[];
452
+ };
453
+ /** The footprint is inferred from explicit coordinates. */
454
+ readonly size?: never;
455
+ /** Interval counts are inferred from explicit coordinates. */
456
+ readonly segments?: never;
457
+ /** Explicit coordinates already include their origin. */
458
+ readonly origin?: never;
459
+ });
394
460
 
395
461
  /** Runtime-neutral options for the dedicated helical ridge mesher. */
396
462
  export declare interface HelicalThreadRidgeMeshOptions {
@@ -460,7 +526,7 @@ export declare interface ImplicitOptions {
460
526
  readonly edgeLength: number;
461
527
  /** Field isosurface value; defaults to zero. */
462
528
  readonly level?: number;
463
- /** Explicit nonnegative native geometric tolerance in millimetres. */
529
+ /** Positive native geometric tolerance in millimetres; omitted uses interpolated grid crossings. */
464
530
  readonly tolerance?: number;
465
531
  }
466
532
 
@@ -484,10 +550,15 @@ export declare interface InternalThreadCutterOptions extends Omit<HelicalThreadR
484
550
  /** Host-bound intersect operation. Valid only during a synchronous build. */
485
551
  export declare const intersect: ModelingContext["intersect"];
486
552
 
553
+ /** Tests a solid or filled section in the active build, including expected empty Boolean results. */
554
+ export declare const isEmpty: ModelingContext["isEmpty"];
555
+
487
556
  /** Host-bound linearPattern operation. Valid only during a synchronous build. */
488
557
  export declare const linearPattern: ModelingContext["linearPattern"];
489
558
 
490
- /** Equal linear intervals determined by exactly two of count, spacing and total length. */
559
+ /**
560
+ * Equal linear intervals determined by exactly two of count, spacing and total length.
561
+ */
491
562
  export declare type LinearPatternOptions = {
492
563
  /** Direction of repetition; magnitude is ignored. Defaults to +X. */
493
564
  readonly direction?: Vec3;
@@ -520,7 +591,9 @@ export declare const loft: ModelingContext["loft"];
520
591
  /** Deterministic ordered edge subdivision or bounded geometric vertex association. */
521
592
  export declare type LoftCorrespondence = "direct" | "reindex" | "fast-distance" | "distance";
522
593
 
523
- /** Shared controls for native and pure lofts. Point data and arbitrary Sections require explicit correspondence. */
594
+ /**
595
+ * Shared controls for native and pure lofts. Point data and arbitrary Sections require explicit correspondence.
596
+ */
524
597
  export declare interface LoftOptions {
525
598
  /** One method or one per consecutive station gap. Omitted preserves known landmarks, including circle/ellipse-to-rectangle corners, or maps other unlike primitive seams directly. */
526
599
  readonly correspondence?: LoftCorrespondence | readonly LoftCorrespondence[];
@@ -536,7 +609,9 @@ export declare interface LoftOptions {
536
609
  readonly limits?: Partial<ModelingLimits>;
537
610
  }
538
611
 
539
- /** A horizontal XY station height, or an explicit right-handed spatial frame, never both. */
612
+ /**
613
+ * A horizontal XY station height, or an explicit right-handed spatial frame, never both.
614
+ */
540
615
  export declare type LoftPlacement = {
541
616
  /** Horizontal XY station height in millimetres. */
542
617
  readonly z: number;
@@ -549,7 +624,9 @@ export declare type LoftPlacement = {
549
624
  readonly z?: never;
550
625
  };
551
626
 
552
- /** A Section or point loop at an explicit height or frame. */
627
+ /**
628
+ * A Section or point loop at an explicit height or frame.
629
+ */
553
630
  export declare type LoftStation = LoftPlacement & {
554
631
  /** Same-build filled Section or ordered XY boundary point data. */
555
632
  readonly profile: Section | Loop2;
@@ -574,7 +651,9 @@ export declare interface MatchProfilesOptions {
574
651
  readonly limits?: Partial<GeometrySamplingLimits>;
575
652
  }
576
653
 
577
- /** Axis-aligned bounds of a non-empty triangle mesh. */
654
+ /**
655
+ * Axis-aligned bounds of a non-empty triangle mesh.
656
+ */
578
657
  export declare interface MeshBounds {
579
658
  /** Inclusive minimum XYZ coordinates. */
580
659
  readonly min: Vec3;
@@ -607,129 +686,544 @@ export declare const mirror: ModelingContext["mirror"];
607
686
  export declare interface ModelingContext {
608
687
  /** Derives a context with explicit physical sampling defaults in the same execution. */
609
688
  withResolution(this: void, resolution: GeometryResolution): ModelingContext;
610
- /** Axis-aligned box with uniform or disjoint named edge/group treatments. */
689
+ /**
690
+ * Axis-aligned box with uniform or disjoint named edge/group treatments.
691
+ *
692
+ * @example Rounded box
693
+ * ```ts
694
+ * box({ size: [30, 20, 8], treatment: { kind: "round", radius: 2 } });
695
+ * ```
696
+ */
611
697
  box(this: void, options: BoxOptions): Solid;
612
- /** +Z cylinder or frustum. Face sizing compensates polygon faceting. */
698
+ /**
699
+ * +Z cylinder or frustum. Face sizing compensates polygon faceting.
700
+ *
701
+ * @example Cylinder
702
+ * ```ts
703
+ * cylinder({ height: 20, radius: 10 });
704
+ * ```
705
+ *
706
+ * @example Cone
707
+ * ```ts
708
+ * cylinder({ height: 20, radius: [10, 0] });
709
+ * ```
710
+ */
613
711
  cylinder(this: void, options: CylinderOptions): Solid;
614
- /** Hollow +Z tube. */
712
+ /**
713
+ * Hollow +Z tube.
714
+ *
715
+ * @example Tube
716
+ * ```ts
717
+ * tube({ height: 20, outerRadius: 10, innerRadius: 6 });
718
+ * ```
719
+ */
615
720
  tube(this: void, options: TubeOptions): Solid;
616
- /** Origin-centered sphere. */
721
+ /**
722
+ * Origin-centered sphere.
723
+ *
724
+ * @example Sphere
725
+ * ```ts
726
+ * sphere({ diameter: 20 });
727
+ * ```
728
+ */
617
729
  sphere(this: void, options: SphereOptions): Solid;
618
- /** Torus around +Z. */
730
+ /**
731
+ * Torus around +Z.
732
+ *
733
+ * @example Torus
734
+ * ```ts
735
+ * torus({ majorRadius: 12, minorRadius: 3 });
736
+ * ```
737
+ */
619
738
  torus(this: void, options: TorusOptions): Solid;
620
- /** Robust union. */
739
+ /**
740
+ * Robust union.
741
+ *
742
+ * @example Union
743
+ * ```ts
744
+ * const block = box({ size: 20 });
745
+ * const cap = translate(sphere({ radius: 10 }), [0, 0, 10]);
746
+ * union([block, cap]);
747
+ * ```
748
+ */
621
749
  union(this: void, solids: readonly Solid[]): Solid;
622
750
  /** Native filled section union; dimensions cannot be mixed. */
623
751
  union(this: void, sections: readonly Section[]): Section;
624
- /** Robust difference; an empty cutter array preserves the source. */
752
+ /**
753
+ * Robust difference; an empty cutter array preserves the source.
754
+ *
755
+ * @example Subtract
756
+ * ```ts
757
+ * const plate = box({ size: [30, 20, 6] });
758
+ * // Extend the cutter beyond both faces.
759
+ * const bore = cylinder({ height: 8, radius: 3, sizing: "face" });
760
+ * subtract(plate, [bore]);
761
+ * ```
762
+ */
625
763
  subtract(this: void, solid: Solid, cutters: readonly Solid[]): Solid;
626
764
  /** Native section difference; an empty cutter array preserves the source. */
627
765
  subtract(this: void, section: Section, cutters: readonly Section[]): Section;
628
- /** Robust intersection. */
766
+ /**
767
+ * Robust intersection.
768
+ *
769
+ * @example Intersect
770
+ * ```ts
771
+ * intersect([box({ size: 20 }), sphere({ radius: 12 })]);
772
+ * ```
773
+ */
629
774
  intersect(this: void, solids: readonly Solid[]): Solid;
630
775
  /** Native filled section intersection; dimensions cannot be mixed. */
631
776
  intersect(this: void, sections: readonly Section[]): Section;
777
+ /**
778
+ * Splits a solid into [inside the cutter, outside the cutter].
779
+ *
780
+ * The first result is the intersection; the second is the subtraction. The cutter itself
781
+ * is not returned. Either result may be empty or contain multiple disconnected components.
782
+ *
783
+ * @example Keep the plug and the surrounding body
784
+ * ```ts
785
+ * const body = box({ size: [30, 20, 8] });
786
+ * const cutter = cylinder({ height: 10, diameter: 8 });
787
+ * const [plug, remainder] = split(body, cutter);
788
+ * // Move the plug beside the body to show both results.
789
+ * union([translate(plug, [0, -20, 0]), remainder]);
790
+ * ```
791
+ */
792
+ split(this: void, solid: Solid, cutter: Solid): readonly [Solid, Solid];
793
+ /**
794
+ * Splits a solid into [positive-normal side, negative side] at a world-space plane.
795
+ *
796
+ * The nonzero normal is normalized; offset is the signed distance from the origin in
797
+ * millimetres, defaulting to zero. Both cut faces are closed. Select either tuple result
798
+ * to retain one side; either result may be empty.
799
+ *
800
+ * @example Separate two halves at X = 0
801
+ * ```ts
802
+ * const body = box({ size: [30, 20, 8] });
803
+ * const [right, left] = splitByPlane(body, { normal: [1, 0, 0] });
804
+ * // The gap is only for display; the cut itself removes no material.
805
+ * union([translate(right, [4, 0, 0]), translate(left, [-4, 0, 0])]);
806
+ * ```
807
+ *
808
+ * @example Keep only the positive half
809
+ * ```ts
810
+ * const [right] = splitByPlane(box({ size: [30, 20, 8] }), { normal: [1, 0, 0] });
811
+ * right;
812
+ * ```
813
+ */
814
+ splitByPlane(this: void, solid: Solid, plane: PlaneOptions): readonly [Solid, Solid];
632
815
  /** Combines disjoint components without resolving overlap. */
633
816
  compose(this: void, solids: readonly Solid[]): Solid;
634
- /** Convex hull of points or solids. */
817
+ /**
818
+ * Convex hull of points or solids.
819
+ *
820
+ * @example Hull
821
+ * ```ts
822
+ * const left = translate(sphere({ radius: 5 }), [-10, 0, 0]);
823
+ * const right = translate(sphere({ radius: 5 }), [10, 0, 0]);
824
+ * hull({ solids: [left, right] });
825
+ * ```
826
+ */
635
827
  hull(this: void, options: HullOptions): Solid;
828
+ /** Convex filled XY hull of finite points or same-build sections. */
829
+ hull(this: void, options: SectionHullOptions): Section;
636
830
  /** Three-dimensional Minkowski sum. */
637
831
  minkowskiSum(this: void, a: Solid, b: Solid): Solid;
638
- /** Imports a bounded closed indexed mesh. */
832
+ /**
833
+ * Imports a bounded closed indexed mesh.
834
+ *
835
+ * @example Mesh import
836
+ * ```ts
837
+ * import { solidFromMesh } from "@metamesh/modeling";
838
+ * import { extrudeMesh, rectangleLoop } from "@metamesh/modeling/geometry";
839
+ *
840
+ * const mesh = extrudeMesh(rectangleLoop({ size: [20, 12] }), { height: 6 });
841
+ * solidFromMesh(mesh);
842
+ * ```
843
+ */
639
844
  solidFromMesh(this: void, mesh: TriangleMesh): Solid;
640
845
  /** Copies a handle to manufacturing mesh buffers. */
641
846
  toTriangleMesh(this: void, solid: Solid): TriangleMesh;
642
847
  /** Translation preserving dimensionality. */
643
848
  translate(this: void, section: Section, offset: Vec2): Section;
644
- /** Translation preserving dimensionality. */
849
+ /**
850
+ * Translation preserving dimensionality.
851
+ *
852
+ * @example Translate
853
+ * ```ts
854
+ * translate(box({ size: [12, 8, 4] }), [15, 0, 0]);
855
+ * ```
856
+ */
645
857
  translate(this: void, solid: Solid, offset: Vec3): Solid;
646
858
  /** Degree rotation; scalar XY rotation or XYZ solid Euler angles. */
647
859
  rotate(this: void, section: Section, degrees: number): Section;
648
- /** Degree rotation; scalar XY rotation or XYZ solid Euler angles. */
860
+ /**
861
+ * Degree rotation; scalar XY rotation or XYZ solid Euler angles.
862
+ *
863
+ * @example Rotate
864
+ * ```ts
865
+ * rotate(box({ size: [20, 10, 6] }), [0, 0, 30]);
866
+ * ```
867
+ */
649
868
  rotate(this: void, solid: Solid, degrees: Vec3): Solid;
650
- /** Nonsingular scaling about the origin. */
869
+ /**
870
+ * Nonsingular scaling about the origin.
871
+ */
651
872
  scale(this: void, section: Section, factors: number | Vec2): Section;
652
- /** Nonsingular scaling about the origin. */
873
+ /**
874
+ * Nonsingular scaling about the origin.
875
+ *
876
+ * @example Scale
877
+ * ```ts
878
+ * scale(sphere({ radius: 8 }), [2, 1, 1]);
879
+ * ```
880
+ */
653
881
  scale(this: void, solid: Solid, factors: number | Vec3): Solid;
654
882
  /** Reflection across an origin line/plane. */
655
883
  mirror(this: void, section: Section, normal: Vec2): Section;
656
- /** Reflection across an origin line/plane. */
884
+ /**
885
+ * Reflection across an origin line/plane.
886
+ *
887
+ * @example Mirror
888
+ * ```ts
889
+ * const block = translate(box({ size: [12, 8, 4] }), [10, 0, 0]);
890
+ * mirror(block, [1, 0, 0]);
891
+ * ```
892
+ */
657
893
  mirror(this: void, solid: Solid, normal: Vec3): Solid;
658
894
  /** Row-major affine transform preserving dimensionality. */
659
895
  transform(this: void, section: Section, matrix: Transform2): Section;
660
896
  /** Row-major affine transform preserving dimensionality. */
661
897
  transform(this: void, solid: Solid, matrix: Transform3): Solid;
662
- /** Reads a copied, immutable named anchor from this exact active build. */
898
+ /**
899
+ * Reads a copied, immutable named anchor from this exact active build.
900
+ *
901
+ * @example Read the top datum
902
+ * ```ts
903
+ * const plate = box({ size: [30, 20, 6] });
904
+ * anchor(plate, "top"); // position [0, 0, 3], direction [0, 0, 1]
905
+ * ```
906
+ */
663
907
  anchor(this: void, shape: Solid | Section, name: string): Anchor3;
664
- /** Returns a new same-build handle with copied named anchors; existing names may be replaced. */
908
+ /**
909
+ * Returns a new same-build handle with copied named anchors; existing names may be replaced.
910
+ */
665
911
  withAnchors<T extends Solid | Section>(this: void, shape: T, anchors: Readonly<Record<string, Anchor3>>): T;
666
- /** Places an explicit or named source anchor against an explicit target anchor. */
912
+ /**
913
+ * Places an explicit or named source anchor against an explicit target anchor.
914
+ *
915
+ * @example Anchor attachment
916
+ * ```ts
917
+ * const plate = box({ size: [30, 20, 6] });
918
+ * const pin = cylinder({ height: 12, radius: 3 });
919
+ * attach(pin, "bottom", anchor(plate, "top"), { gap: 1 });
920
+ * ```
921
+ */
667
922
  attach(this: void, solid: Solid, source: Anchor3 | string, target: Anchor3, options?: AttachOptions): Solid;
668
- /** Creates a native filled section without an intermediate Region2 conversion. */
923
+ /**
924
+ * Creates a native filled section without an intermediate Region2 conversion.
925
+ */
669
926
  sectionFromContours(this: void, contours: readonly Loop2[], options?: SectionFromContoursOptions): Section;
670
927
  /** Imports explicit region topology once. */
671
928
  fromRegion(this: void, region: Region2): Section;
672
929
  /** Explicit copied topology inspection; not needed for section operations. */
673
930
  toRegion(this: void, section: Section): Region2;
674
- /** Filled rectangular section with uniform or independently treated corners. */
931
+ /**
932
+ * Filled rectangular section with uniform or independently treated corners.
933
+ *
934
+ * @example Round the corners
935
+ * ```ts
936
+ * rectangle({ size: [30, 20], treatment: { kind: "round", radius: 3 } });
937
+ * ```
938
+ */
675
939
  rectangle(this: void, options: RectangleOptions): Section;
676
- /** Centered circular section. */
940
+ /**
941
+ * Centered circular section.
942
+ *
943
+ * @example Size to polygon faces
944
+ * ```ts
945
+ * circle({ diameter: 12, sizing: "face" });
946
+ * ```
947
+ */
677
948
  circle(this: void, options: CircleOptions): Section;
678
- /** Centered elliptical section. */
949
+ /**
950
+ * Centered elliptical section.
951
+ *
952
+ * @example Ellipse by full dimensions
953
+ * ```ts
954
+ * ellipse({ size: [30, 20] });
955
+ * ```
956
+ */
679
957
  ellipse(this: void, options: EllipseOptions): Section;
680
- /** Regular polygon with a vertex on +X. */
958
+ /**
959
+ * Regular polygon with a vertex on +X.
960
+ *
961
+ * @example Hexagonal section
962
+ * ```ts
963
+ * regularPolygon({ radius: 10, sides: 6, sizing: "face" });
964
+ * ```
965
+ */
681
966
  regularPolygon(this: void, options: RegularPolygonOptions): Section;
682
- /** Alternating outer/inner star vertices. */
967
+ /**
968
+ * Alternating outer/inner star vertices.
969
+ *
970
+ * @example Five-point section
971
+ * ```ts
972
+ * star({ outerRadius: 12, innerRadius: 6, points: 5 });
973
+ * ```
974
+ */
683
975
  star(this: void, options: StarOptions): Section;
684
- /** Native millimetre offset preserving holes. */
976
+ /**
977
+ * Native millimetre offset preserving holes.
978
+ *
979
+ * @example Add a 2 mm margin
980
+ * ```ts
981
+ * const outline = rectangle({ size: [20, 12] });
982
+ * offset(outline, 2, { join: "round" });
983
+ * ```
984
+ */
685
985
  offset(this: void, section: Section, distance: number, options?: RegionOffsetOptions): Section;
686
- /** Extrudes along +Z with degree twist and top scaling. */
986
+ /**
987
+ * Extrudes along +Z with degree twist and top scaling.
988
+ *
989
+ * @example Extrude
990
+ * ```ts
991
+ * const outline = rectangle({ size: [30, 20], treatment: { kind: "round", radius: 3 } });
992
+ * extrude(outline, { height: 8 });
993
+ * ```
994
+ */
687
995
  extrude(this: void, shape: ModelingShape, options: ExtrudeOptions): Solid;
688
- /** Revolves a filled radial/Z shape around +Z, with caps for partial sweeps. */
996
+ /**
997
+ * Revolves a filled radial/Z shape around +Z, with caps for partial sweeps.
998
+ *
999
+ * @example Revolve
1000
+ * ```ts
1001
+ * // Contour coordinates are [radius, Z].
1002
+ * const profile = sectionFromContours([[[8, 0], [12, 0], [12, 16], [8, 16]]]);
1003
+ * revolve(profile, { revolveDegrees: 270 });
1004
+ * ```
1005
+ */
689
1006
  revolve(this: void, shape: ModelingShape, options?: RevolveOptions): Solid;
690
1007
  /** Filled XY projection. */
691
1008
  projectSection(this: void, solid: Solid): Section;
692
1009
  /** Horizontal filled slice. */
693
1010
  sliceSection(this: void, solid: Solid, z: number): Section;
694
- /** Lofts primitive Sections at z heights or frames; arbitrary Sections and loops require an explicit correspondence method. */
1011
+ /**
1012
+ * Lofts primitive Sections at z heights or frames; arbitrary Sections and loops require an explicit correspondence method.
1013
+ *
1014
+ * @example Loft
1015
+ * ```ts
1016
+ * loft([
1017
+ * { profile: circle({ diameter: 16 }), z: 0 },
1018
+ * { profile: rectangle({ size: [30, 20], treatment: { kind: "round", radius: 3 } }), z: 30 },
1019
+ * ]);
1020
+ * ```
1021
+ */
695
1022
  loft(this: void, stations: readonly LoftStation[], options?: LoftOptions): Solid;
696
1023
  /** Lofts explicit corresponding contours, including holes and collapsed logical slots. */
697
1024
  loft(this: void, stations: readonly CorrespondingProfileStation[], options?: LoftOptions): Solid;
698
1025
  /** Explicit family matching on a shared physical span grid using context resolution. */
699
1026
  matchProfiles(this: void, profiles: readonly Profile[], options?: MatchProfilesOptions): readonly CorrespondingProfile[];
700
- /** Sweeps filled or explicitly corresponding contours using the selected frame policy. */
1027
+ /**
1028
+ * Sweeps filled or explicitly corresponding contours using the selected frame policy.
1029
+ *
1030
+ * @example Sweep
1031
+ * ```ts
1032
+ * const profile = rectangle({ size: [6, 3], treatment: { kind: "round", radius: 1 } });
1033
+ * sweep(profile, [[0, 0, 0], [0, 0, 15], [10, 0, 25]], {
1034
+ * orientation: { kind: "transport", initialNormal: [0, 1, 0] },
1035
+ * });
1036
+ * ```
1037
+ */
701
1038
  sweep(this: void, shape: ModelingShape, path: readonly Vec3[], options?: SweepOptions): Solid;
702
- /** Copies lightweight section measurements. */
1039
+ /**
1040
+ * Copies lightweight section measurements.
1041
+ *
1042
+ * @example Check filled area
1043
+ * ```ts
1044
+ * const facts = inspectSection(rectangle({ size: [20, 10] }));
1045
+ * facts.area; // 200 mm²
1046
+ * ```
1047
+ */
703
1048
  inspectSection(this: void, section: Section): SectionInspection;
704
- /** Copies solid bounds and volume; temporary components are owned by the build. */
1049
+ /**
1050
+ * Reads immutable native facts once per solid; temporary components are owned by the build.
1051
+ *
1052
+ * @example Check dimensions and volume
1053
+ * ```ts
1054
+ * const facts = inspectSolid(box({ size: [30, 20, 6] }));
1055
+ * facts.volume; // 3600 mm³
1056
+ * ```
1057
+ */
705
1058
  inspectSolid(this: void, solid: Solid): SolidInspection;
1059
+ /**
1060
+ * Checks whether a same-build solid or filled section contains no geometry.
1061
+ *
1062
+ * Accepts a 3D Solid or 2D Section handle, not a finalized model or raw triangle mesh.
1063
+ * Useful after a Boolean operation whose inputs may not overlap; no mesh is extracted.
1064
+ *
1065
+ * @example Check a missed intersection
1066
+ * ```ts
1067
+ * const body = box({ size: 10 });
1068
+ * const distant = translate(box({ size: 10 }), [30, 0, 0]);
1069
+ * const empty = intersect([body, distant]);
1070
+ * const missed = isEmpty(empty); // true
1071
+ * ```
1072
+ */
1073
+ isEmpty(this: void, shape: Solid | Section): boolean;
1074
+ /**
1075
+ * Measures the minimum separation between two nonempty solids in millimetres.
1076
+ *
1077
+ * Uses actual geometry, not bounding-box separation or distance between object origins.
1078
+ * Contact or overlapping material returns zero, including one solid inside another.
1079
+ * The kernel's search range is managed internally; the result is not capped at a caller limit.
1080
+ * Empty, expired or foreign-build handles reject. Results follow native numeric precision.
1081
+ *
1082
+ * @example Measure the gap between two blocks
1083
+ * ```ts
1084
+ * const left = box({ size: 10 });
1085
+ * const right = translate(box({ size: 10 }), [13, 0, 0]);
1086
+ * const gap = distance(left, right); // 3 mm
1087
+ * ```
1088
+ */
1089
+ distance(this: void, solid: Solid, other: Solid): number;
706
1090
  /** Copies intersections along the finite directed origin-to-endpoint segment. */
707
1091
  rayCast(this: void, solid: Solid, origin: Vec3, endpoint: Vec3): readonly SolidRayHit[];
708
- /** Returns same-build disconnected solid handles. */
1092
+ /**
1093
+ * Separates a solid's disconnected surface shells into same-build solid handles.
1094
+ *
1095
+ * For solids without enclosed cavities, these shells are the disconnected material islands.
1096
+ * Enclosed cavities produce separate inward shells with negative signed volume; these cannot
1097
+ * be finalized alone as manufacturing parts. This does not cut connected geometry.
1098
+ *
1099
+ * @example Move disconnected pieces independently
1100
+ * ```ts
1101
+ * const islands = union([box({ size: 8 }), translate(box({ size: 8 }), [12, 0, 0])]);
1102
+ * const pieces = components(islands);
1103
+ * // Component order is unspecified; the index only sets a display height here.
1104
+ * union(pieces.map((piece, index) => translate(piece, [0, 0, index * 6])));
1105
+ * ```
1106
+ */
709
1107
  components(this: void, solid: Solid): readonly Solid[];
710
- /** Removes features within the explicit millimetre tolerance. */
1108
+ /** Separates filled 2D islands into sections, retaining each island's holes; empty gives []. */
1109
+ components(this: void, section: Section): readonly Section[];
1110
+ /**
1111
+ * Simplifies a solid using an explicit positive millimetre tolerance.
1112
+ *
1113
+ * Removes redundant vertices while keeping surfaces within the greater of this tolerance
1114
+ * and the solid's existing native tolerance. Choose it from the detail you can afford to lose.
1115
+ */
711
1116
  simplify(this: void, solid: Solid, tolerance: number): Solid;
1117
+ /**
1118
+ * Simplifies filled 2D contours using an explicit positive millimetre tolerance.
1119
+ *
1120
+ * Useful for dense imported outlines before extrusion. This changes the outline rather
1121
+ * than selecting a lower rendering quality; fine features may be removed.
1122
+ *
1123
+ * @example Clean a dense outline before extrusion
1124
+ * ```ts
1125
+ * const outline = circle({ diameter: 20, segments: 256 });
1126
+ * const cleaned = simplify(outline, 0.05); // 0.05 mm cleanup tolerance
1127
+ * const body = extrude(cleaned, { height: 3 });
1128
+ * ```
1129
+ */
1130
+ simplify(this: void, section: Section, tolerance: number): Section;
712
1131
  /** Bounded positive-inside implicit field constructor. */
713
1132
  implicit(this: void, options: ImplicitOptions): Solid;
714
1133
  /** Replaces native tolerance on an immutable copy; zero selects the kernel minimum. */
715
1134
  setTolerance(this: void, solid: Solid, tolerance: number): Solid;
716
- /** Closed regular-grid top above a flat base; every height is sampled once. */
1135
+ /**
1136
+ * Closed rectilinear top above a flat base, with uniform or explicit XY coordinates.
1137
+ * Samples each grid height once; center-error triangulation also samples each cell centre.
1138
+ *
1139
+ * @example Heightfield
1140
+ * ```ts
1141
+ * heightfield({
1142
+ * size: [30, 20], segments: [24, 16],
1143
+ * height: ([x, y]) => 3 + Math.cos(x / 5) * Math.cos(y / 5),
1144
+ * });
1145
+ * ```
1146
+ */
717
1147
  heightfield(this: void, options: HeightfieldOptions): Solid;
718
- /** Repeats one solid along a normalized direction. */
1148
+ /**
1149
+ * Repeats one solid along a normalized direction.
1150
+ *
1151
+ * @example Three copies along X
1152
+ * ```ts
1153
+ * linearPattern(box({ size: 4 }), { count: 3, spacing: 10 });
1154
+ * ```
1155
+ */
719
1156
  linearPattern(this: void, source: PatternSource, options: LinearPatternOptions): readonly Solid[];
720
- /** Repeats one solid about an axis. */
1157
+ /**
1158
+ * Repeats one solid about an axis.
1159
+ *
1160
+ * @example Six copies around Z
1161
+ * ```ts
1162
+ * const pin = translate(cylinder({ height: 6, radius: 2 }), [12, 0, 0]);
1163
+ * radialPattern(pin, { count: 6, axis: [0, 0, 1], angleDegrees: 60 });
1164
+ * ```
1165
+ */
721
1166
  radialPattern(this: void, source: PatternSource, options: RadialPatternOptions): readonly Solid[];
722
- /** XY or XYZ copies, optionally centered or placed in an explicit frame. */
1167
+ /**
1168
+ * XY or XYZ copies, optionally centered or placed in an explicit frame.
1169
+ *
1170
+ * @example Centered XY grid
1171
+ * ```ts
1172
+ * gridPattern(box({ size: 4 }), { count: [3, 2], spacing: [10, 10], center: true });
1173
+ * ```
1174
+ */
723
1175
  gridPattern(this: void, source: PatternSource, options: GridPatternOptions): readonly Solid[];
724
- /** Physical arc-length copies along a sampled path, with optional tangent orientation. */
1176
+ /**
1177
+ * Physical arc-length copies along a sampled path, with optional tangent orientation.
1178
+ *
1179
+ * @example Copies along a bent path
1180
+ * ```ts
1181
+ * pathPattern(box({ size: 4 }), [[0, 0, 0], [20, 0, 0], [20, 20, 0]], { count: 5 });
1182
+ * ```
1183
+ */
725
1184
  pathPattern(this: void, source: PatternSource, path: readonly Vec3[], options: PathPatternOptions): readonly Solid[];
726
1185
  /** Helical ridge mesh construction. */
727
1186
  threadRidge(this: void, options: ThreadRidgeOptions): Solid;
728
- /** Compensated external threaded rod. */
1187
+ /**
1188
+ * Compensated external threaded rod.
1189
+ *
1190
+ * @example Threaded rod
1191
+ * ```ts
1192
+ * import { threadedRod } from "@metamesh/modeling";
1193
+ * import { createThreadProfile } from "@metamesh/modeling/geometry";
1194
+ *
1195
+ * const profile = createThreadProfile({ kind: "triangular", pitch: 1.75 });
1196
+ * threadedRod({ nominalMajorDiameter: 12, length: 24, profile, fit: "normal" });
1197
+ * ```
1198
+ */
729
1199
  threadedRod(this: void, options: ThreadedRodOptions): Solid;
730
- /** Compensated internal threaded cutter. */
1200
+ /**
1201
+ * Compensated internal threaded cutter.
1202
+ *
1203
+ * @example Internal thread
1204
+ * ```ts
1205
+ * import { cylinder, internalThreadCutter, subtract } from "@metamesh/modeling";
1206
+ * import { createThreadProfile } from "@metamesh/modeling/geometry";
1207
+ *
1208
+ * const profile = createThreadProfile({ kind: "triangular", pitch: 1.75 });
1209
+ * const body = cylinder({ diameter: 20, height: 12, center: false });
1210
+ * const cutter = internalThreadCutter({ nominalMajorDiameter: 12, length: 12, profile });
1211
+ * subtract(body, [cutter]);
1212
+ * ```
1213
+ */
731
1214
  internalThreadCutter(this: void, options: InternalThreadCutterOptions): Solid;
732
- /** Compensated threaded nut. */
1215
+ /**
1216
+ * Compensated threaded nut.
1217
+ *
1218
+ * @example Threaded nut
1219
+ * ```ts
1220
+ * import { threadedNut } from "@metamesh/modeling";
1221
+ * import { createThreadProfile } from "@metamesh/modeling/geometry";
1222
+ *
1223
+ * const profile = createThreadProfile({ kind: "triangular", pitch: 1.75 });
1224
+ * threadedNut({ nominalMajorDiameter: 12, thickness: 8, width: 20, shape: "hex", profile, fit: "normal" });
1225
+ * ```
1226
+ */
733
1227
  threadedNut(this: void, options: ThreadedNutOptions): Solid;
734
1228
  /** Allocation-free external-thread facts. */
735
1229
  preflightThreadedRod(this: void, options: ThreadedRodOptions): HelicalThreadSolidMeshPreflight;
@@ -737,15 +1231,44 @@ export declare interface ModelingContext {
737
1231
  preflightInternalThreadCutter(this: void, options: InternalThreadCutterOptions): HelicalThreadSolidMeshPreflight;
738
1232
  /** Allocation-free nut/cutter facts. */
739
1233
  preflightThreadedNut(this: void, options: ThreadedNutOptions): ThreadedNutPreflight;
740
- /** Consumes a previously prepared layout; never shapes or fetches a font. */
1234
+ /**
1235
+ * Consumes a previously prepared layout; never shapes or fetches a font.
1236
+ *
1237
+ * @example Use a prepared text layout
1238
+ * ```ts
1239
+ * // Prepare the exact font and layout before entering build.
1240
+ * function labelSection(layout: VectorTextLayout) {
1241
+ * return textSection(layout);
1242
+ * }
1243
+ * ```
1244
+ */
741
1245
  textSection(this: void, layout: VectorTextLayout, options?: TextSectionOptions): Section;
742
- /** Imports bounded painted SVG document geometry. */
1246
+ /**
1247
+ * Imports bounded painted SVG document geometry.
1248
+ *
1249
+ * @example Import a physical SVG rectangle
1250
+ * ```ts
1251
+ * svgSection(
1252
+ * '<svg xmlns="http://www.w3.org/2000/svg" width="30mm" height="20mm" viewBox="0 0 30 20"><rect width="30" height="20"/></svg>',
1253
+ * { origin: "center" },
1254
+ * );
1255
+ * ```
1256
+ */
743
1257
  svgSection(this: void, svg: string, options?: SvgSectionOptions): Section;
744
- /** Imports bounded filled SVG path data. */
1258
+ /**
1259
+ * Imports bounded filled SVG path data.
1260
+ *
1261
+ * @example Fill an SVG path in millimetres
1262
+ * ```ts
1263
+ * svgPathSection("M0 0H20V12H0Z", { origin: "center", scale: 1 });
1264
+ * ```
1265
+ */
745
1266
  svgPathSection(this: void, path: string, options?: SvgPathSectionOptions): Section;
746
1267
  }
747
1268
 
748
- /** Returns bound local operations, optionally with derived resolution, without changing imported operations. */
1269
+ /**
1270
+ * Returns bound local operations, optionally with derived resolution, without changing imported operations.
1271
+ */
749
1272
  export declare function modelingFunctions(resolution?: GeometryResolution): ModelingContext;
750
1273
 
751
1274
  /** Aggregate manufacturing output ceilings selected by a trusted host. */
@@ -791,9 +1314,19 @@ export declare interface PathPatternOptions {
791
1314
  readonly orientation?: "fixed" | "tangent";
792
1315
  }
793
1316
 
794
- /** One same-build shape, or a synchronous factory called once per copy in index order. */
1317
+ /**
1318
+ * One same-build shape, or a synchronous factory called once per copy in index order.
1319
+ */
795
1320
  export declare type PatternSource = Solid | ((index: number) => Solid);
796
1321
 
1322
+ /** A world-space cutting plane, retaining the half-space in the normal's direction. */
1323
+ export declare interface PlaneOptions {
1324
+ /** Finite nonzero plane normal; magnitude does not affect the plane. */
1325
+ readonly normal: Vec3;
1326
+ /** Signed millimetre distance from the origin along the unit normal. Defaults to zero. */
1327
+ readonly offset?: number;
1328
+ }
1329
+
797
1330
  /**
798
1331
  * One bounded two-dimensional polygon.
799
1332
  *
@@ -839,7 +1372,9 @@ export declare interface PrimitivePlacementOptions {
839
1372
  readonly tolerance?: GeometryToleranceOptions;
840
1373
  }
841
1374
 
842
- /** Named baseline fit policies for calibrated FDM-style printed threads. */
1375
+ /**
1376
+ * Named baseline fit policies for calibrated FDM-style printed threads.
1377
+ */
843
1378
  export declare type PrintableThreadFit = "tight" | "normal" | "loose";
844
1379
 
845
1380
  /**
@@ -939,7 +1474,9 @@ export declare const projectSection: ModelingContext["projectSection"];
939
1474
  /** Host-bound radialPattern operation. Valid only during a synchronous build. */
940
1475
  export declare const radialPattern: ModelingContext["radialPattern"];
941
1476
 
942
- /** Options for repeating one solid around an axis through a center point. */
1477
+ /**
1478
+ * Options for repeating one solid around an axis through a center point.
1479
+ */
943
1480
  export declare interface RadialPatternOptions {
944
1481
  /** Number of solids to return, including the original. */
945
1482
  readonly count: number;
@@ -951,10 +1488,14 @@ export declare interface RadialPatternOptions {
951
1488
  readonly center?: Vec3;
952
1489
  }
953
1490
 
954
- /** Radial dimensions refer to polygon vertices or compensate faceting to meet polygon faces. */
1491
+ /**
1492
+ * Radial dimensions refer to polygon vertices or compensate faceting to meet polygon faces.
1493
+ */
955
1494
  export declare type RadialSizing = "vertex" | "face";
956
1495
 
957
- /** Nominal radial sizing shared by circular and regular polygon construction. */
1496
+ /**
1497
+ * Nominal radial sizing shared by circular and regular polygon construction.
1498
+ */
958
1499
  export declare interface RadialSizingOptions {
959
1500
  /** Explicit sampling ceilings; bound modeling operations may only lower the host policy. */
960
1501
  readonly limits?: Partial<GeometrySamplingLimits>;
@@ -982,7 +1523,9 @@ bottomLeft: RectangleCornerTreatment,
982
1523
  bottomRight: RectangleCornerTreatment
983
1524
  ];
984
1525
 
985
- /** Shared rectangle dimensions, origin and uniform or per-corner treatment. */
1526
+ /**
1527
+ * Shared rectangle dimensions, origin and uniform or per-corner treatment.
1528
+ */
986
1529
  export declare interface RectangleLoopOptions {
987
1530
  /** Positive uniform size or explicit XY extents in millimetres. */
988
1531
  readonly size: number | Vec2;
@@ -994,7 +1537,9 @@ export declare interface RectangleLoopOptions {
994
1537
  readonly limits?: Partial<GeometrySamplingLimits>;
995
1538
  }
996
1539
 
997
- /** Rectangle dimensions, placement and uniform or per-corner treatment. */
1540
+ /**
1541
+ * Rectangle dimensions, placement and uniform or per-corner treatment.
1542
+ */
998
1543
  export declare interface RectangleOptions extends RectangleLoopOptions, PrimitivePlacement {
999
1544
  }
1000
1545
 
@@ -1019,7 +1564,9 @@ export declare interface RegionOffsetOptions {
1019
1564
  /** Host-bound regularPolygon operation. Valid only during a synchronous build. */
1020
1565
  export declare const regularPolygon: ModelingContext["regularPolygon"];
1021
1566
 
1022
- /** Regular polygon dimensions, radial convention and degree rotation. */
1567
+ /**
1568
+ * Regular polygon dimensions, radial convention and degree rotation.
1569
+ */
1023
1570
  export declare type RegularPolygonOptions = RadialSizingOptions & PrimitivePlacement & {
1024
1571
  /** Positive nominal radius in millimetres, interpreted according to sizing. */
1025
1572
  readonly radius: number;
@@ -1032,7 +1579,9 @@ export declare type RegularPolygonOptions = RadialSizingOptions & PrimitivePlace
1032
1579
  /** Host-bound revolve operation. Valid only during a synchronous build. */
1033
1580
  export declare const revolve: ModelingContext["revolve"];
1034
1581
 
1035
- /** Circumferential sampling and degree sweep shared by pure and filled revolution. */
1582
+ /**
1583
+ * Circumferential sampling and degree sweep shared by pure and filled revolution.
1584
+ */
1036
1585
  export declare interface RevolveOptions extends CircularPrimitiveOptions {
1037
1586
  /**
1038
1587
  * Positive angular sweep no greater than 360 degrees; partial revolutions have end caps.
@@ -1048,7 +1597,9 @@ export declare interface RevolveOptions extends CircularPrimitiveOptions {
1048
1597
  /** Host-bound rotate operation. Valid only during a synchronous build. */
1049
1598
  export declare const rotate: ModelingContext["rotate"];
1050
1599
 
1051
- /** A circular edge or corner roundover with explicit physical sampling. */
1600
+ /**
1601
+ * A circular edge or corner roundover with explicit physical sampling.
1602
+ */
1052
1603
  export declare interface RoundedEdgeTreatment extends CircularPrimitiveOptions {
1053
1604
  /** Selects circular corners or spherical all-edge roundovers. */
1054
1605
  readonly kind: "round";
@@ -1070,14 +1621,34 @@ declare const sectionBrand: unique symbol;
1070
1621
  /** Host-bound sectionFromContours operation. Valid only during a synchronous build. */
1071
1622
  export declare const sectionFromContours: ModelingContext["sectionFromContours"];
1072
1623
 
1073
- /** Filled-contour resolution. Closing vertices are implicit. */
1624
+ /**
1625
+ * Filled-contour resolution. Closing vertices are implicit.
1626
+ */
1074
1627
  export declare interface SectionFromContoursOptions {
1075
1628
  /** Nonzero or even-odd filled-contour rule; defaults to nonzero. */
1076
1629
  readonly fillRule?: "nonzero" | "evenodd";
1077
1630
  }
1078
1631
 
1079
- /** Copied native filled section facts in millimetres and square millimetres. */
1632
+ /** Planar convex hull inputs are finite XY points or same-build filled sections. */
1633
+ export declare type SectionHullOptions = {
1634
+ /** At least three finite millimetre XY points spanning positive area. */
1635
+ readonly points: readonly Vec2[];
1636
+ /** Point input excludes section input. */
1637
+ readonly sections?: never;
1638
+ } | {
1639
+ /** One through 1000 same-build sections to include in the convex hull. */
1640
+ readonly sections: readonly Section[];
1641
+ /** Section input excludes point input. */
1642
+ readonly points?: never;
1643
+ };
1644
+
1645
+ /**
1646
+ * Immutable native filled section facts in millimetres and square millimetres.
1647
+ * Repeated inspections of the same native shape share these facts within one build.
1648
+ */
1080
1649
  export declare interface SectionInspection {
1650
+ /** Whether this filled section has no area or boundary. */
1651
+ readonly isEmpty: boolean;
1081
1652
  /** Filled section area in square millimetres. */
1082
1653
  readonly area: number;
1083
1654
  /** Number of extracted outer and hole contours. */
@@ -1126,16 +1697,25 @@ declare const solidBrand: unique symbol;
1126
1697
  /** Host-bound solidFromMesh operation. Valid only during a synchronous build. */
1127
1698
  export declare const solidFromMesh: ModelingContext["solidFromMesh"];
1128
1699
 
1129
- /** Copied solid bounds, connected component count, and cubic millimetre volume. */
1700
+ /**
1701
+ * Immutable solid bounds, emptiness, component count, volume, surface area and native tolerance.
1702
+ * Repeated inspections of the same native shape share these facts within one build.
1703
+ */
1130
1704
  export declare interface SolidInspection {
1705
+ /** Whether this native solid contains no material. */
1706
+ readonly isEmpty: boolean;
1131
1707
  /** Inclusive maximum coordinates in millimetres. */
1132
1708
  readonly max: Vec3;
1133
1709
  /** Inclusive minimum coordinates in millimetres. */
1134
1710
  readonly min: Vec3;
1135
- /** Number of connected native solid components. */
1711
+ /** Number of connected surface shells; inward cavity shells count separately. */
1136
1712
  readonly parts: number;
1137
1713
  /** Enclosed native solid volume in cubic millimetres. */
1138
1714
  readonly volume: number;
1715
+ /** Total native surface area in square millimetres. */
1716
+ readonly surfaceArea: number;
1717
+ /** Effective native geometric tolerance in millimetres. */
1718
+ readonly tolerance: number;
1139
1719
  }
1140
1720
 
1141
1721
  /** Named same-build solid manufacturing part. */
@@ -1165,7 +1745,9 @@ export declare interface SolidRayHit {
1165
1745
  /** Host-bound sphere operation. Valid only during a synchronous build. */
1166
1746
  export declare const sphere: ModelingContext["sphere"];
1167
1747
 
1168
- /** Exactly one radius or diameter, placement, and tessellation for an origin-centered sphere. */
1748
+ /**
1749
+ * Exactly one radius or diameter, placement, and tessellation for an origin-centered sphere.
1750
+ */
1169
1751
  export declare type SphereOptions = CircularPrimitiveOptions & PrimitivePlacement & ({
1170
1752
  /** Positive radius in millimetres; mutually exclusive with diameter. */
1171
1753
  readonly radius: number;
@@ -1178,6 +1760,12 @@ export declare type SphereOptions = CircularPrimitiveOptions & PrimitivePlacemen
1178
1760
  readonly radius?: never;
1179
1761
  });
1180
1762
 
1763
+ /** Returns intersection and difference with a same-build cutter, including empty results. */
1764
+ export declare const split: ModelingContext["split"];
1765
+
1766
+ /** Splits a solid into the normal-side and opposite-side halves of a world-space plane. */
1767
+ export declare const splitByPlane: ModelingContext["splitByPlane"];
1768
+
1181
1769
  /** Square profile with equal crest and root widths. */
1182
1770
  declare interface SquareThreadProfileSpec extends ThreadProfileBaseSpec {
1183
1771
  /** Selects the square profile family. */
@@ -1192,7 +1780,9 @@ declare interface SquareThreadProfileSpec extends ThreadProfileBaseSpec {
1192
1780
  /** Host-bound star operation. Valid only during a synchronous build. */
1193
1781
  export declare const star: ModelingContext["star"];
1194
1782
 
1195
- /** Alternating outer and inner vertices, centered on the XY origin. */
1783
+ /**
1784
+ * Alternating outer and inner vertices, centered on the XY origin.
1785
+ */
1196
1786
  export declare interface StarOptions extends PrimitivePlacement {
1197
1787
  /** Explicit sampling ceilings, bounded by the host policy. */
1198
1788
  readonly limits?: Partial<GeometrySamplingLimits>;
@@ -1232,7 +1822,9 @@ export declare interface SvgPathSectionOptions {
1232
1822
  /** Host-bound svgSection operation. Valid only during a synchronous build. */
1233
1823
  export declare const svgSection: ModelingContext["svgSection"];
1234
1824
 
1235
- /** Bounded SVG document sampling. Center origin uses the final painted bounds. */
1825
+ /**
1826
+ * Bounded SVG document sampling. Center origin uses the final painted bounds.
1827
+ */
1236
1828
  export declare interface SvgSectionOptions {
1237
1829
  /** Local allocation ceilings may only lower the configured engine policy. */
1238
1830
  readonly limits?: Partial<GeometrySamplingLimits>;
@@ -1247,7 +1839,9 @@ export declare interface SvgSectionOptions {
1247
1839
  /** Host-bound sweep operation. Valid only during a synchronous build. */
1248
1840
  export declare const sweep: ModelingContext["sweep"];
1249
1841
 
1250
- /** Controls shared by pure mesh construction and filled modeling sweeps. */
1842
+ /**
1843
+ * Controls shared by pure mesh construction and filled modeling sweeps.
1844
+ */
1251
1845
  export declare interface SweepOptions {
1252
1846
  /** Join the path's last station to its first. Open paths retain watertight end caps. */
1253
1847
  readonly closed?: boolean;
@@ -1267,7 +1861,9 @@ export declare interface SweepOptions {
1267
1861
  readonly seamProfileOffset?: number;
1268
1862
  }
1269
1863
 
1270
- /** Explicit profile-X frame policy; all normals are directed, and selected singular policies reject. */
1864
+ /**
1865
+ * Explicit profile-X frame policy; all normals are directed, and selected singular policies reject.
1866
+ */
1271
1867
  export declare type SweepOrientation = {
1272
1868
  /** Minimizes frame rotation by parallel transport. */
1273
1869
  readonly kind: "transport";
@@ -1291,7 +1887,9 @@ export declare type SweepOrientation = {
1291
1887
  /** Host-bound textSection operation. Valid only during a synchronous build. */
1292
1888
  export declare const textSection: ModelingContext["textSection"];
1293
1889
 
1294
- /** Physical curve sampling applied to already prepared vector text. */
1890
+ /**
1891
+ * Physical curve sampling applied to already prepared vector text.
1892
+ */
1295
1893
  export declare interface TextSectionOptions {
1296
1894
  /** Local allocation ceilings may only lower the configured engine policy. */
1297
1895
  readonly limits?: Partial<GeometrySamplingLimits>;
@@ -1318,7 +1916,9 @@ export declare const threadedNut: ModelingContext["threadedNut"];
1318
1916
  /** Nut-edge bevel selection. */
1319
1917
  export declare type ThreadedNutBevel = "automatic" | "both" | "inside" | "none" | "outside";
1320
1918
 
1321
- /** Options for a compensated nut with an internal thread. */
1919
+ /**
1920
+ * Options for a compensated nut with an internal thread.
1921
+ */
1322
1922
  export declare interface ThreadedNutOptions extends Omit<InternalThreadCutterOptions, "bevelBottom" | "bevelSize" | "bevelTop" | "length"> {
1323
1923
  /** Nut body bevel selection. Default: `automatic`. */
1324
1924
  readonly bevel?: ThreadedNutBevel;
@@ -1354,13 +1954,17 @@ export declare interface ThreadedNutPreflight {
1354
1954
  readonly threadCircularSegments: number;
1355
1955
  }
1356
1956
 
1357
- /** Supported printable nut body shapes. */
1957
+ /**
1958
+ * Supported printable nut body shapes.
1959
+ */
1358
1960
  export declare type ThreadedNutShape = "hex" | "round" | "square";
1359
1961
 
1360
1962
  /** Host-bound threadedRod operation. Valid only during a synchronous build. */
1361
1963
  export declare const threadedRod: ModelingContext["threadedRod"];
1362
1964
 
1363
- /** Options for a compensated external threaded rod along +Z. */
1965
+ /**
1966
+ * Options for a compensated external threaded rod along +Z.
1967
+ */
1364
1968
  export declare interface ThreadedRodOptions extends Omit<HelicalThreadRidgeMeshOptions, "majorDiameter">, ThreadBevelOptions {
1365
1969
  /** Printable fit or caller-calibrated allowances. Default: `normal`. */
1366
1970
  readonly fit?: PrintableThreadFit | PrintableThreadFitPolicy;
@@ -1408,7 +2012,9 @@ export declare interface ThreadEndTreatmentOptions {
1408
2012
  readonly top?: ThreadEndStyle;
1409
2013
  }
1410
2014
 
1411
- /** Direction in which a conventional helical thread advances around +Z. */
2015
+ /**
2016
+ * Direction in which a conventional helical thread advances around +Z.
2017
+ */
1412
2018
  export declare type ThreadHandedness = "left" | "right";
1413
2019
 
1414
2020
  /** Radial envelope toward which a blunt lead-in collapses. */
@@ -1417,7 +2023,9 @@ export declare type ThreadLeadInEnvelope = "major" | "minor";
1417
2023
  /** BOSL2-compatible cross-section scaling curve for a blunt thread lead-in. */
1418
2024
  export declare type ThreadLeadInShape = "cut" | "linear" | "smooth" | "sqrt";
1419
2025
 
1420
- /** A validated immutable periodic thread profile in `[axial, radial]` millimetres. */
2026
+ /**
2027
+ * A validated immutable periodic thread profile in `[axial, radial]` millimetres.
2028
+ */
1421
2029
  export declare interface ThreadProfile {
1422
2030
  /** Axial width of the flat at the major envelope. */
1423
2031
  readonly crestFlatWidth: number;
@@ -1441,7 +2049,9 @@ declare interface ThreadProfileBaseSpec {
1441
2049
  readonly tolerance?: GeometryToleranceOptions;
1442
2050
  }
1443
2051
 
1444
- /** Supported built-in and caller-defined thread profiles. */
2052
+ /**
2053
+ * Supported built-in and caller-defined thread profiles.
2054
+ */
1445
2055
  declare type ThreadProfileSpec = AcmeThreadProfileSpec | ButtressThreadProfileSpec | CustomThreadProfileSpec | SquareThreadProfileSpec | TrapezoidalThreadProfileSpec | TriangularThreadProfileSpec;
1446
2056
 
1447
2057
  /** Host-bound threadRidge operation. Valid only during a synchronous build. */
@@ -1456,7 +2066,9 @@ export declare const toRegion: ModelingContext["toRegion"];
1456
2066
  /** Host-bound torus operation. Valid only during a synchronous build. */
1457
2067
  export declare const torus: ModelingContext["torus"];
1458
2068
 
1459
- /** Dimensions and independent ring/profile tessellation for a torus around the Z axis. */
2069
+ /**
2070
+ * Dimensions and independent ring/profile tessellation for a torus around the Z axis.
2071
+ */
1460
2072
  export declare interface TorusOptions extends PrimitivePlacement {
1461
2073
  /** Explicit sampling ceilings, bounded by the host policy. */
1462
2074
  readonly limits?: Partial<GeometrySamplingLimits>;
@@ -1535,7 +2147,9 @@ declare interface TrapezoidalThreadProfileSpec extends ThreadProfileBaseSpec {
1535
2147
  readonly threadAngle?: number;
1536
2148
  }
1537
2149
 
1538
- /** A topology-preserving indexed triangle mesh with XYZ vertex positions. */
2150
+ /**
2151
+ * A topology-preserving indexed triangle mesh with XYZ vertex positions.
2152
+ */
1539
2153
  export declare interface TriangleMesh {
1540
2154
  /** Three unsigned vertex indices per triangle. */
1541
2155
  readonly indices: Uint32Array;
@@ -1543,7 +2157,9 @@ export declare interface TriangleMesh {
1543
2157
  readonly positions: Float32Array;
1544
2158
  }
1545
2159
 
1546
- /** Measurements and optional edge-connected topology from one validated mesh traversal. */
2160
+ /**
2161
+ * Measurements and optional edge-connected topology from one validated mesh traversal.
2162
+ */
1547
2163
  export declare interface TriangleMeshAnalysis extends TriangleMeshMeasurements {
1548
2164
  /** Number of referenced edge-connected components when `includeTopology` is requested. */
1549
2165
  readonly connectedComponentCount?: number;
@@ -1551,7 +2167,9 @@ export declare interface TriangleMeshAnalysis extends TriangleMeshMeasurements {
1551
2167
  readonly edgeCount?: number;
1552
2168
  }
1553
2169
 
1554
- /** Geometric measurements derived from a validated, non-empty triangle mesh. */
2170
+ /**
2171
+ * Geometric measurements derived from a validated, non-empty triangle mesh.
2172
+ */
1555
2173
  export declare interface TriangleMeshMeasurements {
1556
2174
  /** Axis-aligned bounds. */
1557
2175
  readonly bounds: MeshBounds;
@@ -1565,7 +2183,9 @@ export declare interface TriangleMeshMeasurements {
1565
2183
  readonly vertexCount: number;
1566
2184
  }
1567
2185
 
1568
- /** ISO/UTS-like 60-degree truncated triangular profile. */
2186
+ /**
2187
+ * ISO/UTS-like 60-degree truncated triangular profile.
2188
+ */
1569
2189
  declare interface TriangularThreadProfileSpec extends ThreadProfileBaseSpec {
1570
2190
  /** Selects the 60-degree triangular profile family. */
1571
2191
  readonly kind: "triangular";
@@ -1584,7 +2204,9 @@ declare interface TriangularThreadProfileSpec extends ThreadProfileBaseSpec {
1584
2204
  /** Host-bound tube operation. Valid only during a synchronous build. */
1585
2205
  export declare const tube: ModelingContext["tube"];
1586
2206
 
1587
- /** Dimensions, placement, and tessellation for a hollow Z-axis tube. */
2207
+ /**
2208
+ * Dimensions, placement, and tessellation for a hollow Z-axis tube.
2209
+ */
1588
2210
  export declare interface TubeOptions extends CircularPrimitiveOptions, PrimitivePlacement {
1589
2211
  /**
1590
2212
  * Centers the tube on the Z origin when `true`; otherwise its bottom is at `Z = 0`.
@@ -1616,7 +2238,9 @@ export declare interface VectorTextBounds {
1616
2238
  readonly max: readonly [number, number];
1617
2239
  }
1618
2240
 
1619
- /** Immutable vector layout with no browser, font parser, or kernel ownership. */
2241
+ /**
2242
+ * Immutable vector layout with no browser, font parser, or kernel ownership.
2243
+ */
1620
2244
  export declare interface VectorTextLayout {
1621
2245
  /** Nonzero-filled path data in millimetres, positive Y upward; empty for text with no ink. */
1622
2246
  readonly paths: readonly string[];
@@ -1628,9 +2252,9 @@ export declare interface VectorTextLayout {
1628
2252
  export declare interface VectorTextMetrics {
1629
2253
  /** Visible curve bounds after alignment, or null when the text has no ink. */
1630
2254
  readonly bounds: VectorTextBounds | null;
1631
- /** Unaligned pen displacement: final line advance and negative baseline displacement, in mm. */
2255
+ /** Unaligned logical advance and negative baseline displacement in mm; arcs retain [arc length, 0]. */
1632
2256
  readonly advance: readonly [number, number];
1633
- /** Maximum line advance in millimetres, including spaces; distinct from visible ink width. */
2257
+ /** Maximum logical line advance in millimetres, including spaces; arc length on circular baselines. */
1634
2258
  readonly logicalWidth: number;
1635
2259
  /** Selected font's ascender distance above a baseline in millimetres, independent of the text. */
1636
2260
  readonly ascent: number;