@metamesh/modeling 0.9.0 → 0.11.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 (42) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/README.md +66 -422
  3. package/THIRD_PARTY_NOTICES.md +4 -148
  4. package/dist/api/engine.d.ts +105 -8
  5. package/dist/api/geometry.d.ts +95 -83
  6. package/dist/api/index.d.ts +767 -772
  7. package/dist/engine/construction-operations.js +3 -1
  8. package/dist/engine/deferred-context.js +182 -0
  9. package/dist/engine/execution.js +38 -4
  10. package/dist/engine/finalization.js +65 -133
  11. package/dist/engine/geometry-recipes.js +12 -0
  12. package/dist/engine/immutable-generation-data.js +186 -0
  13. package/dist/engine/index.js +57 -35
  14. package/dist/engine/kernel/manifold.wasm +0 -0
  15. package/dist/engine/model-dependencies.js +46 -0
  16. package/dist/engine/model-summary.js +43 -0
  17. package/dist/engine/native/ownership.js +11 -5
  18. package/dist/engine/placement.js +24 -0
  19. package/dist/engine/recipe-realization.js +119 -0
  20. package/dist/engine/session-graph.js +442 -0
  21. package/dist/engine/session-native.js +90 -0
  22. package/dist/engine/session-snapshot.js +153 -0
  23. package/dist/engine/session.js +184 -0
  24. package/dist/engine/shape-anchors.js +5 -0
  25. package/dist/geometry/index.js +2 -2
  26. package/dist/geometry/mesh-centroid.js +7 -6
  27. package/dist/geometry/mesh-planar.js +11 -10
  28. package/dist/geometry/mesh-quality.js +15 -14
  29. package/dist/geometry/mesh-signature.js +8 -7
  30. package/dist/geometry/mesh-solid.js +10 -4
  31. package/dist/geometry/mesh.js +36 -31
  32. package/dist/geometry/profiles/{cross-section.js → contour.js} +3 -3
  33. package/dist/geometry/profiles/{open-profile.js → side-profile.js} +3 -3
  34. package/dist/geometry/svg-import.js +1 -16
  35. package/dist/index.js +2 -0
  36. package/dist/model/execution-binding.js +5 -5
  37. package/dist/model/generation.js +27 -0
  38. package/dist/model/immutable-buffer.js +111 -0
  39. package/dist/model/modeling-context.js +1 -0
  40. package/dist/model/operations.js +521 -160
  41. package/dist/model/shape-handles.js +44 -0
  42. package/package.json +4 -4
@@ -11,8 +11,16 @@ declare interface AcmeThreadProfileSpec extends ThreadProfileBaseSpec {
11
11
  readonly depth?: number;
12
12
  }
13
13
 
14
- /** Reads one immutable named anchor from a shape in the active build. */
15
- export declare const anchor: ModelingContext["anchor"];
14
+ /**
15
+ * Reads a copied, immutable named anchor from this exact active generation.
16
+ *
17
+ * @example Read the top datum
18
+ * ```ts
19
+ * const plate = box({ size: [30, 20, 6] });
20
+ * anchor(plate, "top"); // position [0, 0, 3], direction [0, 0, 1]
21
+ * ```
22
+ */
23
+ export declare function anchor(shape: Solid | Section, name: string): Anchor3;
16
24
 
17
25
  /**
18
26
  * An attachment pose on a solid or assembly.
@@ -29,9 +37,6 @@ export declare interface Anchor3 {
29
37
  readonly up: Vec3;
30
38
  }
31
39
 
32
- /** Host-bound attach operation. Valid only during a synchronous build. */
33
- export declare const attach: ModelingContext["attach"];
34
-
35
40
  /**
36
41
  * Degree-based anchor attachment controls for a scoped solid.
37
42
  */
@@ -46,8 +51,15 @@ export declare interface AttachOptions {
46
51
  readonly tolerance?: GeometryToleranceOptions;
47
52
  }
48
53
 
49
- /** Host-bound box operation. Valid only during a synchronous build. */
50
- export declare const box: ModelingContext["box"];
54
+ /**
55
+ * Axis-aligned box with uniform or disjoint named edge/group treatments.
56
+ *
57
+ * @example Rounded box
58
+ * ```ts
59
+ * box({ size: [30, 20, 8], treatment: { kind: "round", radius: 2 } });
60
+ * ```
61
+ */
62
+ export declare function box(options: BoxOptions): Solid;
51
63
 
52
64
  /** Box edges use +Z top, +Y front and +X right; vertical names list front/back first. */
53
65
  export declare type BoxEdge = "top-front" | "top-back" | "top-left" | "top-right" | "bottom-front" | "bottom-back" | "bottom-left" | "bottom-right" | "front-left" | "front-right" | "back-left" | "back-right";
@@ -75,9 +87,6 @@ export declare interface BoxOptions extends PrimitivePlacement {
75
87
  readonly treatment?: EdgeTreatment | BoxEdgeTreatments;
76
88
  }
77
89
 
78
- /** A bare solid receives the semantic part ID `model`. Explicit parts preserve their IDs. */
79
- export declare type BuildOutput = Solid | readonly ModelPart[];
80
-
81
90
  /** Axial side carrying the near-normal pressure flank of a buttress thread. */
82
91
  declare type ButtressPressureFlankSide = "negative" | "positive";
83
92
 
@@ -108,8 +117,15 @@ export declare interface ChamferedEdgeTreatment {
108
117
  readonly distance: number | readonly [first: number, second: number];
109
118
  }
110
119
 
111
- /** Host-bound circle operation. Valid only during a synchronous build. */
112
- export declare const circle: ModelingContext["circle"];
120
+ /**
121
+ * Centered circular section.
122
+ *
123
+ * @example Size to polygon faces
124
+ * ```ts
125
+ * circle({ diameter: 12, sizing: "face" });
126
+ * ```
127
+ */
128
+ export declare function circle(options: CircleOptions): Section;
113
129
 
114
130
  /**
115
131
  * Circular profile dimensions with exactly one radius or diameter and explicit sampling.
@@ -148,11 +164,41 @@ export declare interface CircularPrimitiveOptions {
148
164
  readonly resolution?: GeometryResolution;
149
165
  }
150
166
 
151
- /** Host-bound components operation. Valid only during a synchronous build. */
152
- export declare const components: ModelingContext["components"];
167
+ /**
168
+ * Separates a solid's disconnected surface shells into same-session solid handles.
169
+ *
170
+ * For solids without enclosed cavities, these shells are the disconnected material islands.
171
+ * Enclosed cavities produce separate inward shells with negative signed volume; these cannot
172
+ * be finalized alone as manufacturing parts. This does not cut connected geometry.
173
+ *
174
+ * @example Move disconnected pieces independently
175
+ * ```ts
176
+ * const islands = union([box({ size: 8 }), box({ size: 8 }).translate([12, 0, 0])]);
177
+ * const pieces = components(islands);
178
+ * // Component order is unspecified; the index only sets a display height here.
179
+ * union(pieces.map((piece, index) => piece.translate([0, 0, index * 6])));
180
+ * ```
181
+ */
182
+ export declare function components(solid: Solid): readonly Solid[];
183
+
184
+ /** Separates filled 2D islands into sections, retaining each island's holes; empty gives []. */
185
+ export declare function components(section: Section): readonly Section[];
186
+
187
+ /** Combines disjoint components without resolving overlap. */
188
+ export declare function compose(solids: readonly Solid[]): Solid;
189
+
190
+ /** A lazy session-owned reader. Calling it tracks its output in the current computation. */
191
+ export declare interface Computed<T> {
192
+ /** Compile-time ownership brand; readers are created by the engine's context helper. */
193
+ readonly [computedBrand]: "Computed";
194
+ /** Reads immutable data or a deferred recipe; evaluation is synchronous and cached. */
195
+ (): T;
196
+ }
197
+
198
+ declare const computedBrand: unique symbol;
153
199
 
154
- /** Host-bound compose operation. Valid only during a synchronous build. */
155
- export declare const compose: ModelingContext["compose"];
200
+ /** A value supplied immediately or by a lazy computed reader. */
201
+ export declare type ComputedValue<T> = T | Computed<T>;
156
202
 
157
203
  /** One sampled component retaining contour identities and logical point correspondence. */
158
204
  export declare interface CorrespondingComponent {
@@ -197,8 +243,20 @@ declare interface CustomThreadProfileSpec extends ThreadProfileBaseSpec {
197
243
  readonly points: readonly Vec2[];
198
244
  }
199
245
 
200
- /** Host-bound cylinder operation. Valid only during a synchronous build. */
201
- export declare const cylinder: ModelingContext["cylinder"];
246
+ /**
247
+ * +Z cylinder or frustum. Face sizing compensates polygon faceting.
248
+ *
249
+ * @example Cylinder
250
+ * ```ts
251
+ * cylinder({ height: 20, radius: 10 });
252
+ * ```
253
+ *
254
+ * @example Cone
255
+ * ```ts
256
+ * cylinder({ height: 20, radius: [10, 0] });
257
+ * ```
258
+ */
259
+ export declare function cylinder(options: CylinderOptions): Solid;
202
260
 
203
261
  /**
204
262
  * Dimensions, placement, independent end finishing, and tessellation for a Z-axis cylinder or frustum.
@@ -225,16 +283,43 @@ export declare type CylinderOptions = CircularPrimitiveOptions & RadialSizingOpt
225
283
  readonly radius?: never;
226
284
  });
227
285
 
228
- /** Measures the minimum separation between two nonempty solids in millimetres. */
229
- export declare const distance: ModelingContext["distance"];
286
+ /** Typed parameter association for an assertion or warning. */
287
+ export declare interface DiagnosticOptions<P> {
288
+ /** Existing top-level parameter key. */
289
+ readonly parameterId?: Extract<keyof P, string> | undefined;
290
+ }
291
+
292
+ /**
293
+ * Measures the minimum separation between two nonempty solids in millimetres.
294
+ *
295
+ * Uses actual geometry, not bounding-box separation or distance between object origins.
296
+ * Contact or overlapping material returns zero, including one solid inside another.
297
+ * The kernel's search range is managed internally; the result is not capped at a caller limit.
298
+ * Empty, expired or foreign-build handles reject. Results follow native numeric precision.
299
+ *
300
+ * @example Measure the gap between two blocks
301
+ * ```ts
302
+ * const left = box({ size: 10 });
303
+ * const right = box({ size: 10 }).translate([13, 0, 0]);
304
+ * const gap = distance(left, right); // 3 mm
305
+ * ```
306
+ */
307
+ export declare function distance(solid: Solid, other: Solid): number;
230
308
 
231
309
  /**
232
310
  * Uniform finishing vocabulary shared by applicable solid edges and profile corners.
233
311
  */
234
312
  export declare type EdgeTreatment = ChamferedEdgeTreatment | RoundedEdgeTreatment | SmoothEdgeTreatment | ProfiledEdgeTreatment;
235
313
 
236
- /** Host-bound ellipse operation. Valid only during a synchronous build. */
237
- export declare const ellipse: ModelingContext["ellipse"];
314
+ /**
315
+ * Centered elliptical section.
316
+ *
317
+ * @example Ellipse by full dimensions
318
+ * ```ts
319
+ * ellipse({ size: [30, 20] });
320
+ * ```
321
+ */
322
+ export declare function ellipse(options: EllipseOptions): Section;
238
323
 
239
324
  /**
240
325
  * Ellipse dimensions with exactly one XY radii or full-size tuple and explicit sampling.
@@ -266,8 +351,20 @@ export declare interface EndTreatments {
266
351
  readonly top?: EdgeTreatment;
267
352
  }
268
353
 
269
- /** Host-bound extrude operation. Valid only during a synchronous build. */
270
- export declare const extrude: ModelingContext["extrude"];
354
+ /**
355
+ * Extrudes explicit corresponding contours along +Z with degree twist and top scaling.
356
+ * Filled Sections use `section.extrude(options)`.
357
+ *
358
+ * @example Extrude
359
+ * ```ts
360
+ * import { extrude, matchProfiles } from "@metamesh/modeling";
361
+ * import { rectangleProfile } from "@metamesh/modeling/geometry";
362
+ *
363
+ * const [profile] = matchProfiles([rectangleProfile({ size: [30, 20] })]);
364
+ * extrude(profile!, { height: 8 });
365
+ * ```
366
+ */
367
+ export declare function extrude(shape: CorrespondingProfile, options: ExtrudeOptions): Solid;
271
368
 
272
369
  /**
273
370
  * Dimensions and sampling shared by native and pure +Z extrusion.
@@ -342,8 +439,73 @@ export declare interface Frame3 {
342
439
  readonly zAxis: Vec3;
343
440
  }
344
441
 
345
- /** Host-bound fromRegion operation. Valid only during a synchronous build. */
346
- export declare const fromRegion: ModelingContext["fromRegion"];
442
+ /** Imports explicit region topology once. */
443
+ export declare function fromRegion(region: Region2): Section;
444
+
445
+ /**
446
+ * Defines a typed model without executing it. Use `computed` only for work worth reusing.
447
+ *
448
+ * @example A simple model
449
+ * ```ts
450
+ * const model = generate<{ height: number }>(({ params, part, assert }) => {
451
+ * assert(params.height > 0, "Height must be positive.");
452
+ * return [part("body", box({ size: [10, 10, params.height] }))];
453
+ * });
454
+ * ```
455
+ */
456
+ export declare function generate<P, S = Record<never, never>>(callback: GenerateCallback<P, S>): ModelProgram<P, S>;
457
+
458
+ /** Pure synchronous generation callback; caches are an optional performance optimization. */
459
+ export declare type GenerateCallback<P, S = Record<never, never>> = (context: GenerateContext<P, S>) => readonly GeneratedPart[];
460
+
461
+ /** The sole synchronous authoring context, supplied independently of Studio. */
462
+ export declare interface GenerateContext<P, S = Record<never, never>> {
463
+ /** Frozen ordinary parameter values; synchronous top-level reads are tracked. */
464
+ readonly params: Readonly<P>;
465
+ /** Host-prepared readonly synchronous capabilities, fixed for the session. */
466
+ readonly services: Readonly<S>;
467
+ /** Registers a lazy pure calculation; capture changing locals through explicit bindings. */
468
+ readonly computed: {
469
+ <T>(id: string, callback: () => T): Computed<T>;
470
+ <B extends Readonly<Record<string, unknown>>, T>(id: string, bindings: B, callback: (bindings: B) => T): Computed<T>;
471
+ };
472
+ /** Declares a semantic part with identity placement, or explicit placement and appearance. */
473
+ readonly part: {
474
+ (id: string, geometry: ComputedValue<PartGeometry>): GeneratedPart;
475
+ (id: string, options: PartOptions): GeneratedPart;
476
+ };
477
+ /** Immediately aborts on false; geometry observations in the condition run first. */
478
+ readonly assert: {
479
+ (condition: false, message: string, options?: DiagnosticOptions<P>): never;
480
+ (condition: boolean, message: string, options?: DiagnosticOptions<P>): void;
481
+ };
482
+ /** Records a nonblocking issue; call only in the outer generation callback. */
483
+ readonly warn: (message: string, options?: DiagnosticOptions<P>) => void;
484
+ }
485
+
486
+ /** One declared output part. Construct with the context's `part` helper. */
487
+ export declare interface GeneratedPart extends PartOptions {
488
+ /** Unique canonical lowercase hyphen-separated identity, at most 64 characters. */
489
+ readonly id: string;
490
+ }
491
+
492
+ /** Structured user-facing issue associated with the attempted revision. */
493
+ export declare interface GenerationDiagnostic {
494
+ /** An error aborts generation; a warning allows generation to continue. */
495
+ readonly severity: "error" | "warning";
496
+ /** Human-readable corrective guidance. */
497
+ readonly message: string;
498
+ /** Optional control identity, validated against the supplied parameters. */
499
+ readonly parameterId?: string | undefined;
500
+ }
501
+
502
+ /** A user-correctable assertion failure. Successful computation caches never retain failures. */
503
+ export declare class GenerationError extends Error {
504
+ /** Issues reached in normal JavaScript order, ending with the first failed assertion. */
505
+ readonly diagnostics: readonly GenerationDiagnostic[];
506
+ /** Captures immutable diagnostics; unexpected author errors retain their original type. */
507
+ constructor(diagnostics: readonly GenerationDiagnostic[]);
508
+ }
347
509
 
348
510
  /**
349
511
  * Tessellation policy for sampled geometry measured in millimetres.
@@ -383,8 +545,15 @@ export declare interface GeometryToleranceOptions {
383
545
  readonly relative?: number;
384
546
  }
385
547
 
386
- /** Host-bound gridPattern operation. Valid only during a synchronous build. */
387
- export declare const gridPattern: ModelingContext["gridPattern"];
548
+ /**
549
+ * XY or XYZ copies, optionally centered or placed in an explicit frame.
550
+ *
551
+ * @example Centered XY grid
552
+ * ```ts
553
+ * gridPattern(box({ size: 4 }), { count: [3, 2], spacing: [10, 10], center: true });
554
+ * ```
555
+ */
556
+ export declare function gridPattern(source: PatternSource, options: GridPatternOptions): readonly Solid[];
388
557
 
389
558
  /**
390
559
  * XY or XYZ grid with X varying fastest. The first item starts at the local origin.
@@ -406,8 +575,19 @@ export declare type GridPatternOptions = {
406
575
  readonly spacing: Vec3;
407
576
  });
408
577
 
409
- /** Constructs a closed rectilinear heightfield during the active synchronous build. */
410
- export declare const heightfield: ModelingContext["heightfield"];
578
+ /**
579
+ * Closed rectilinear top above a flat base, with uniform or explicit XY coordinates.
580
+ * Samples each grid height once; center-error triangulation also samples each cell centre.
581
+ *
582
+ * @example Heightfield
583
+ * ```ts
584
+ * heightfield({
585
+ * size: [30, 20], segments: [24, 16],
586
+ * height: ([x, y]) => 3 + Math.cos(x / 5) * Math.cos(y / 5),
587
+ * });
588
+ * ```
589
+ */
590
+ export declare function heightfield(options: HeightfieldOptions): Solid;
411
591
 
412
592
  /**
413
593
  * A closed rectilinear heightfield above a flat base, with uniform or explicit XY samples in millimetres.
@@ -497,10 +677,22 @@ export declare interface HelicalThreadSolidMeshPreflight {
497
677
  readonly estimatedTriangles: number;
498
678
  }
499
679
 
500
- /** Host-bound hull operation. Valid only during a synchronous build. */
501
- export declare const hull: ModelingContext["hull"];
680
+ /**
681
+ * Convex hull of points or solids.
682
+ *
683
+ * @example Hull
684
+ * ```ts
685
+ * const left = sphere({ radius: 5 }).translate([-10, 0, 0]);
686
+ * const right = sphere({ radius: 5 }).translate([10, 0, 0]);
687
+ * hull({ solids: [left, right] });
688
+ * ```
689
+ */
690
+ export declare function hull(options: HullOptions): Solid;
691
+
692
+ /** Convex filled XY hull of finite points or same-session sections. */
693
+ export declare function hull(options: SectionHullOptions): Section;
502
694
 
503
- /** Hull inputs are either finite points or same-build solids. */
695
+ /** Hull inputs are either finite points or same-session solids. */
504
696
  export declare type HullOptions = {
505
697
  /** Finite millimetre XYZ points to include in the convex hull. */
506
698
  readonly points: readonly Vec3[];
@@ -513,8 +705,60 @@ export declare type HullOptions = {
513
705
  readonly points?: never;
514
706
  };
515
707
 
516
- /** Host-bound implicit operation. Valid only during a synchronous build. */
517
- export declare const implicit: ModelingContext["implicit"];
708
+ /** Owned immutable numeric data. Use copy() to obtain mutable storage for numerical work. */
709
+ export declare interface ImmutableBuffer<T extends NumericArray> {
710
+ /** Opaque element-storage brand; construct buffers with immutableBuffer(). */
711
+ readonly [immutableBufferBrand]: T;
712
+ /** Number of numeric elements, independent of their byte width. */
713
+ readonly length: number;
714
+ /** Reads an integer offset; negative offsets count from the end. Invalid offsets return undefined. */
715
+ at(this: void, index: number): number | undefined;
716
+ /** Returns a fresh mutable array of the original numeric type; never exposes cached storage. */
717
+ copy(this: void): T;
718
+ }
719
+
720
+ /**
721
+ * Copies numeric data once into private storage. This pure helper needs no active generation.
722
+ * @example
723
+ * ```ts
724
+ * import { immutableBuffer } from "@metamesh/modeling";
725
+ * const heights = immutableBuffer(new Float32Array([2, 4, 6]));
726
+ * const count = heights.length;
727
+ * const first = heights.at(0);
728
+ * const editable = heights.copy();
729
+ * editable[0] = 8; // heights still contains 2, 4, 6.
730
+ * ```
731
+ */
732
+ export declare function immutableBuffer<T extends NumericArray>(source: T): ImmutableBuffer<T>;
733
+
734
+ declare const immutableBufferBrand: unique symbol;
735
+
736
+ /**
737
+ * Copies mesh buffers into immutable data; geometric validation still occurs when modeling or finalizing.
738
+ * @example
739
+ * ```ts
740
+ * import { generate, immutableMesh } from "@metamesh/modeling";
741
+ * import { heightfieldMesh } from "@metamesh/modeling/geometry";
742
+ * const model = generate(({ computed, part }) => {
743
+ * const surface = computed("surface", () => immutableMesh(heightfieldMesh({
744
+ * size: [10, 10], segments: [8, 8], height: () => 2,
745
+ * })));
746
+ * return [part("surface", surface)];
747
+ * });
748
+ * ```
749
+ */
750
+ export declare function immutableMesh(mesh: TriangleMesh): ImmutableTriangleMesh;
751
+
752
+ /** Immutable local XYZ positions and triangle indices, suitable for a computed value or part. */
753
+ export declare interface ImmutableTriangleMesh {
754
+ /** Packed XYZ coordinates in millimetres. */
755
+ readonly positions: ImmutableBuffer<Float32Array>;
756
+ /** Zero-based vertex indices, three per triangle. */
757
+ readonly indices: ImmutableBuffer<Uint32Array>;
758
+ }
759
+
760
+ /** Bounded positive-inside implicit field constructor. */
761
+ export declare function implicit(options: ImplicitOptions): Solid;
518
762
 
519
763
  /** Positive-inside sampling, bounded to 4M native BCC grid slots and 8M field calls. */
520
764
  export declare interface ImplicitOptions {
@@ -530,14 +774,42 @@ export declare interface ImplicitOptions {
530
774
  readonly tolerance?: number;
531
775
  }
532
776
 
533
- /** Host-bound inspectSection operation. Valid only during a synchronous build. */
534
- export declare const inspectSection: ModelingContext["inspectSection"];
777
+ /**
778
+ * Copies lightweight section measurements.
779
+ *
780
+ * @example Check filled area
781
+ * ```ts
782
+ * const facts = inspectSection(rectangle({ size: [20, 10] }));
783
+ * facts.area; // 200 mm²
784
+ * ```
785
+ */
786
+ export declare function inspectSection(section: Section): SectionInspection;
535
787
 
536
- /** Host-bound inspectSolid operation. Valid only during a synchronous build. */
537
- export declare const inspectSolid: ModelingContext["inspectSolid"];
788
+ /**
789
+ * Reads immutable native facts once per solid; temporary components are owned by the build.
790
+ *
791
+ * @example Check dimensions and volume
792
+ * ```ts
793
+ * const facts = inspectSolid(box({ size: [30, 20, 6] }));
794
+ * facts.volume; // 3600 mm³
795
+ * ```
796
+ */
797
+ export declare function inspectSolid(solid: Solid): SolidInspection;
538
798
 
539
- /** Host-bound internalThreadCutter operation. Valid only during a synchronous build. */
540
- export declare const internalThreadCutter: ModelingContext["internalThreadCutter"];
799
+ /**
800
+ * Compensated internal threaded cutter.
801
+ *
802
+ * @example Internal thread
803
+ * ```ts
804
+ * import { cylinder, internalThreadCutter } from "@metamesh/modeling";
805
+ * import { createThreadProfile } from "@metamesh/modeling/geometry";
806
+ * const profile = createThreadProfile({ kind: "triangular", pitch: 1.75 });
807
+ * const body = cylinder({ diameter: 20, height: 12, center: false });
808
+ * const cutter = internalThreadCutter({ nominalMajorDiameter: 12, length: 12, profile });
809
+ * body.subtract([cutter]);
810
+ * ```
811
+ */
812
+ export declare function internalThreadCutter(options: InternalThreadCutterOptions): Solid;
541
813
 
542
814
  /** Options for a compensated internal-thread subtraction tool along +Z. */
543
815
  export declare interface InternalThreadCutterOptions extends Omit<HelicalThreadRidgeMeshOptions, "majorDiameter">, ThreadBevelOptions {
@@ -547,14 +819,44 @@ export declare interface InternalThreadCutterOptions extends Omit<HelicalThreadR
547
819
  readonly nominalMajorDiameter: number;
548
820
  }
549
821
 
550
- /** Host-bound intersect operation. Valid only during a synchronous build. */
551
- export declare const intersect: ModelingContext["intersect"];
822
+ /**
823
+ * Robust intersection.
824
+ *
825
+ * @example Intersect
826
+ * ```ts
827
+ * intersect([box({ size: 20 }), sphere({ radius: 12 })]);
828
+ * ```
829
+ */
830
+ export declare function intersect(solids: readonly Solid[]): Solid;
552
831
 
553
- /** Tests a solid or filled section in the active build, including expected empty Boolean results. */
554
- export declare const isEmpty: ModelingContext["isEmpty"];
832
+ /** Native filled section intersection; dimensions cannot be mixed. */
833
+ export declare function intersect(sections: readonly Section[]): Section;
834
+
835
+ /**
836
+ * Checks whether a same-session solid or filled section contains no geometry.
837
+ *
838
+ * Accepts a 3D Solid or 2D Section handle, not a finalized model or raw triangle mesh.
839
+ * Useful after a Boolean operation whose inputs may not overlap; no mesh is extracted.
840
+ *
841
+ * @example Check a missed intersection
842
+ * ```ts
843
+ * const body = box({ size: 10 });
844
+ * const distant = box({ size: 10 }).translate([30, 0, 0]);
845
+ * const empty = intersect([body, distant]);
846
+ * const missed = isEmpty(empty); // true
847
+ * ```
848
+ */
849
+ export declare function isEmpty(shape: Solid | Section): boolean;
555
850
 
556
- /** Host-bound linearPattern operation. Valid only during a synchronous build. */
557
- export declare const linearPattern: ModelingContext["linearPattern"];
851
+ /**
852
+ * Repeats one solid along a normalized direction.
853
+ *
854
+ * @example Three copies along X
855
+ * ```ts
856
+ * linearPattern(box({ size: 4 }), { count: 3, spacing: 10 });
857
+ * ```
858
+ */
859
+ export declare function linearPattern(source: PatternSource, options: LinearPatternOptions): readonly Solid[];
558
860
 
559
861
  /**
560
862
  * Equal linear intervals determined by exactly two of count, spacing and total length.
@@ -585,10 +887,35 @@ export declare type LinearPatternOptions = {
585
887
  readonly count?: never;
586
888
  });
587
889
 
588
- /** Host-bound loft operation. Valid only during a synchronous build. */
589
- export declare const loft: ModelingContext["loft"];
890
+ /**
891
+ * Lofts primitive Sections at z heights or frames; arbitrary Sections and loops require an explicit correspondence method.
892
+ *
893
+ * @example Loft
894
+ * ```ts
895
+ * loft([
896
+ * { profile: circle({ diameter: 16 }), z: 0 },
897
+ * { profile: rectangle({ size: [30, 20], treatment: { kind: "round", radius: 3 } }), z: 30 },
898
+ * ]);
899
+ * ```
900
+ */
901
+ export declare function loft(stations: readonly LoftStation[], options?: LoftOptions): Solid;
902
+
903
+ /** Lofts explicit corresponding contours, including holes and collapsed logical slots. */
904
+ export declare function loft(stations: readonly CorrespondingProfileStation[], options?: LoftOptions): Solid;
590
905
 
591
- /** Deterministic ordered edge subdivision or bounded geometric vertex association. */
906
+ /**
907
+ * Associates ordered loft contours without inferring component identities or repairing topology.
908
+ *
909
+ * - `direct` preserves seams and subdivides edges to a common count without dropping vertices.
910
+ * - `reindex` applies direct subdivision, then selects the next contour's cyclic phase with the
911
+ * least total world-space connection length.
912
+ * - `fast-distance` preserves supplied seams and minimizes connection length over ordered closed
913
+ * vertex associations, repeating vertices for triangular fans.
914
+ * - `distance` runs the same ordered optimization over every cyclic phase of the next contour.
915
+ *
916
+ * Components and holes are paired by their existing order. Use identified profiles when semantic
917
+ * correspondence must remain authoritative.
918
+ */
592
919
  export declare type LoftCorrespondence = "direct" | "reindex" | "fast-distance" | "distance";
593
920
 
594
921
  /**
@@ -640,8 +967,8 @@ export declare type LoftStation = LoftPlacement & {
640
967
  */
641
968
  export declare type Loop2 = readonly Vec2[];
642
969
 
643
- /** Matches an explicit profile family using the current build's physical resolution. */
644
- export declare const matchProfiles: ModelingContext["matchProfiles"];
970
+ /** Explicit family matching on a shared physical span grid using session or operation resolution. */
971
+ export declare function matchProfiles(profiles: readonly Profile[], options?: MatchProfilesOptions): readonly CorrespondingProfile[];
645
972
 
646
973
  /** Explicit family sampling settings; omitted values use physical package defaults. */
647
974
  export declare interface MatchProfilesOptions {
@@ -661,615 +988,8 @@ export declare interface MeshBounds {
661
988
  readonly max: Vec3;
662
989
  }
663
990
 
664
- /** Named direct mesh part. Input is copied, validated, and bounded by the host. */
665
- export declare interface MeshPart {
666
- /** Stable canonical lowercase identity; unique within the containing topology or output. */
667
- readonly id: string;
668
- /** Optional six-digit hex RGB display color. */
669
- readonly color?: string;
670
- /** Direct manufacturing mesh; mutually exclusive with a solid handle. */
671
- readonly mesh: TriangleMesh;
672
- /** Same-build solid handle; mutually exclusive with a direct mesh. */
673
- readonly solid?: never;
674
- }
675
-
676
- /** Host-bound minkowskiSum operation. Valid only during a synchronous build. */
677
- export declare const minkowskiSum: ModelingContext["minkowskiSum"];
678
-
679
- /** Host-bound mirror operation. Valid only during a synchronous build. */
680
- export declare const mirror: ModelingContext["mirror"];
681
-
682
- /** The sole modeling facade used by compiled and authored generators.
683
- * Methods are bound to the host execution and can be destructured safely. Angles are degrees;
684
- * lengths are millimetres. Handles cannot outlive this build or cross into a different build.
685
- */
686
- export declare interface ModelingContext {
687
- /** Derives a context with explicit physical sampling defaults in the same execution. */
688
- withResolution(this: void, resolution: GeometryResolution): ModelingContext;
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
- */
697
- box(this: void, options: BoxOptions): Solid;
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
- */
711
- cylinder(this: void, options: CylinderOptions): Solid;
712
- /**
713
- * Hollow +Z tube.
714
- *
715
- * @example Tube
716
- * ```ts
717
- * tube({ height: 20, outerRadius: 10, innerRadius: 6 });
718
- * ```
719
- */
720
- tube(this: void, options: TubeOptions): Solid;
721
- /**
722
- * Origin-centered sphere.
723
- *
724
- * @example Sphere
725
- * ```ts
726
- * sphere({ diameter: 20 });
727
- * ```
728
- */
729
- sphere(this: void, options: SphereOptions): Solid;
730
- /**
731
- * Torus around +Z.
732
- *
733
- * @example Torus
734
- * ```ts
735
- * torus({ majorRadius: 12, minorRadius: 3 });
736
- * ```
737
- */
738
- torus(this: void, options: TorusOptions): Solid;
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
- */
749
- union(this: void, solids: readonly Solid[]): Solid;
750
- /** Native filled section union; dimensions cannot be mixed. */
751
- union(this: void, sections: readonly Section[]): Section;
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
- */
763
- subtract(this: void, solid: Solid, cutters: readonly Solid[]): Solid;
764
- /** Native section difference; an empty cutter array preserves the source. */
765
- subtract(this: void, section: Section, cutters: readonly Section[]): Section;
766
- /**
767
- * Robust intersection.
768
- *
769
- * @example Intersect
770
- * ```ts
771
- * intersect([box({ size: 20 }), sphere({ radius: 12 })]);
772
- * ```
773
- */
774
- intersect(this: void, solids: readonly Solid[]): Solid;
775
- /** Native filled section intersection; dimensions cannot be mixed. */
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];
815
- /** Combines disjoint components without resolving overlap. */
816
- compose(this: void, solids: readonly Solid[]): Solid;
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
- */
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;
830
- /** Three-dimensional Minkowski sum. */
831
- minkowskiSum(this: void, a: Solid, b: Solid): Solid;
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
- */
844
- solidFromMesh(this: void, mesh: TriangleMesh): Solid;
845
- /** Copies a handle to manufacturing mesh buffers. */
846
- toTriangleMesh(this: void, solid: Solid): TriangleMesh;
847
- /** Translation preserving dimensionality. */
848
- translate(this: void, section: Section, offset: Vec2): Section;
849
- /**
850
- * Translation preserving dimensionality.
851
- *
852
- * @example Translate
853
- * ```ts
854
- * translate(box({ size: [12, 8, 4] }), [15, 0, 0]);
855
- * ```
856
- */
857
- translate(this: void, solid: Solid, offset: Vec3): Solid;
858
- /** Degree rotation; scalar XY rotation or XYZ solid Euler angles. */
859
- rotate(this: void, section: Section, degrees: number): Section;
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
- */
868
- rotate(this: void, solid: Solid, degrees: Vec3): Solid;
869
- /**
870
- * Nonsingular scaling about the origin.
871
- */
872
- scale(this: void, section: Section, factors: number | Vec2): Section;
873
- /**
874
- * Nonsingular scaling about the origin.
875
- *
876
- * @example Scale
877
- * ```ts
878
- * scale(sphere({ radius: 8 }), [2, 1, 1]);
879
- * ```
880
- */
881
- scale(this: void, solid: Solid, factors: number | Vec3): Solid;
882
- /** Reflection across an origin line/plane. */
883
- mirror(this: void, section: Section, normal: Vec2): Section;
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
- */
893
- mirror(this: void, solid: Solid, normal: Vec3): Solid;
894
- /** Row-major affine transform preserving dimensionality. */
895
- transform(this: void, section: Section, matrix: Transform2): Section;
896
- /** Row-major affine transform preserving dimensionality. */
897
- transform(this: void, solid: Solid, matrix: Transform3): Solid;
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
- */
907
- anchor(this: void, shape: Solid | Section, name: string): Anchor3;
908
- /**
909
- * Returns a new same-build handle with copied named anchors; existing names may be replaced.
910
- */
911
- withAnchors<T extends Solid | Section>(this: void, shape: T, anchors: Readonly<Record<string, Anchor3>>): T;
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
- */
922
- attach(this: void, solid: Solid, source: Anchor3 | string, target: Anchor3, options?: AttachOptions): Solid;
923
- /**
924
- * Creates a native filled section without an intermediate Region2 conversion.
925
- */
926
- sectionFromContours(this: void, contours: readonly Loop2[], options?: SectionFromContoursOptions): Section;
927
- /** Imports explicit region topology once. */
928
- fromRegion(this: void, region: Region2): Section;
929
- /** Explicit copied topology inspection; not needed for section operations. */
930
- toRegion(this: void, section: Section): Region2;
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
- */
939
- rectangle(this: void, options: RectangleOptions): Section;
940
- /**
941
- * Centered circular section.
942
- *
943
- * @example Size to polygon faces
944
- * ```ts
945
- * circle({ diameter: 12, sizing: "face" });
946
- * ```
947
- */
948
- circle(this: void, options: CircleOptions): Section;
949
- /**
950
- * Centered elliptical section.
951
- *
952
- * @example Ellipse by full dimensions
953
- * ```ts
954
- * ellipse({ size: [30, 20] });
955
- * ```
956
- */
957
- ellipse(this: void, options: EllipseOptions): Section;
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
- */
966
- regularPolygon(this: void, options: RegularPolygonOptions): Section;
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
- */
975
- star(this: void, options: StarOptions): Section;
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
- */
985
- offset(this: void, section: Section, distance: number, options?: RegionOffsetOptions): Section;
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
- */
995
- extrude(this: void, shape: ModelingShape, options: ExtrudeOptions): Solid;
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
- */
1006
- revolve(this: void, shape: ModelingShape, options?: RevolveOptions): Solid;
1007
- /** Filled XY projection. */
1008
- projectSection(this: void, solid: Solid): Section;
1009
- /** Horizontal filled slice. */
1010
- sliceSection(this: void, solid: Solid, z: number): Section;
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
- */
1022
- loft(this: void, stations: readonly LoftStation[], options?: LoftOptions): Solid;
1023
- /** Lofts explicit corresponding contours, including holes and collapsed logical slots. */
1024
- loft(this: void, stations: readonly CorrespondingProfileStation[], options?: LoftOptions): Solid;
1025
- /** Explicit family matching on a shared physical span grid using context resolution. */
1026
- matchProfiles(this: void, profiles: readonly Profile[], options?: MatchProfilesOptions): readonly CorrespondingProfile[];
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
- */
1038
- sweep(this: void, shape: ModelingShape, path: readonly Vec3[], options?: SweepOptions): Solid;
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
- */
1048
- inspectSection(this: void, section: Section): SectionInspection;
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
- */
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;
1090
- /** Copies intersections along the finite directed origin-to-endpoint segment. */
1091
- rayCast(this: void, solid: Solid, origin: Vec3, endpoint: Vec3): readonly SolidRayHit[];
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
- */
1107
- components(this: void, solid: Solid): readonly Solid[];
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
- */
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;
1131
- /** Bounded positive-inside implicit field constructor. */
1132
- implicit(this: void, options: ImplicitOptions): Solid;
1133
- /** Replaces native tolerance on an immutable copy; zero selects the kernel minimum. */
1134
- setTolerance(this: void, solid: Solid, tolerance: number): Solid;
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
- */
1147
- heightfield(this: void, options: HeightfieldOptions): Solid;
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
- */
1156
- linearPattern(this: void, source: PatternSource, options: LinearPatternOptions): readonly Solid[];
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
- */
1166
- radialPattern(this: void, source: PatternSource, options: RadialPatternOptions): readonly Solid[];
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
- */
1175
- gridPattern(this: void, source: PatternSource, options: GridPatternOptions): readonly Solid[];
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
- */
1184
- pathPattern(this: void, source: PatternSource, path: readonly Vec3[], options: PathPatternOptions): readonly Solid[];
1185
- /** Helical ridge mesh construction. */
1186
- threadRidge(this: void, options: ThreadRidgeOptions): Solid;
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
- */
1199
- threadedRod(this: void, options: ThreadedRodOptions): Solid;
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
- */
1214
- internalThreadCutter(this: void, options: InternalThreadCutterOptions): Solid;
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
- */
1227
- threadedNut(this: void, options: ThreadedNutOptions): Solid;
1228
- /** Allocation-free external-thread facts. */
1229
- preflightThreadedRod(this: void, options: ThreadedRodOptions): HelicalThreadSolidMeshPreflight;
1230
- /** Allocation-free internal-thread facts. */
1231
- preflightInternalThreadCutter(this: void, options: InternalThreadCutterOptions): HelicalThreadSolidMeshPreflight;
1232
- /** Allocation-free nut/cutter facts. */
1233
- preflightThreadedNut(this: void, options: ThreadedNutOptions): ThreadedNutPreflight;
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
- */
1245
- textSection(this: void, layout: VectorTextLayout, options?: TextSectionOptions): Section;
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
- */
1257
- svgSection(this: void, svg: string, options?: SvgSectionOptions): Section;
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
- */
1266
- svgPathSection(this: void, path: string, options?: SvgPathSectionOptions): Section;
1267
- }
1268
-
1269
- /**
1270
- * Returns bound local operations, optionally with derived resolution, without changing imported operations.
1271
- */
1272
- export declare function modelingFunctions(resolution?: GeometryResolution): ModelingContext;
991
+ /** Three-dimensional Minkowski sum. */
992
+ export declare function minkowskiSum(a: Solid, b: Solid): Solid;
1273
993
 
1274
994
  /** Aggregate manufacturing output ceilings selected by a trusted host. */
1275
995
  export declare interface ModelingLimits extends GeometrySamplingLimits {
@@ -1283,14 +1003,31 @@ export declare interface ModelingLimits extends GeometrySamplingLimits {
1283
1003
  readonly maxBytes: number;
1284
1004
  }
1285
1005
 
1286
- /** A native filled shape or sampled profile with explicit contour identities. */
1287
- export declare type ModelingShape = Section | CorrespondingProfile;
1006
+ /** Stateless portable program descriptor. Execution and caches belong to an engine session. */
1007
+ export declare interface ModelProgram<P, S = Record<never, never>> {
1008
+ /** Exact generation protocol discriminator. */
1009
+ readonly kind: "metamesh-model";
1010
+ /** Typed synchronous declaration callback. */
1011
+ readonly generate: GenerateCallback<P, S>;
1012
+ }
1288
1013
 
1289
- /** Named manufacturing output containing exactly one solid or direct mesh. */
1290
- export declare type ModelPart = SolidPart | MeshPart;
1014
+ /** Numeric storage supported by immutable generation buffers. */
1015
+ export declare type NumericArray = Float32Array | Float64Array | Uint32Array | Uint8Array | Int32Array;
1291
1016
 
1292
- /** Host-bound offset operation. Valid only during a synchronous build. */
1293
- export declare const offset: ModelingContext["offset"];
1017
+ /** Manufacturing geometry; filled sections are intermediate construction values. */
1018
+ export declare type PartGeometry = Solid | TriangleMesh | ImmutableTriangleMesh;
1019
+
1020
+ /** Appearance and rigid placement of a finished local manufacturing part. */
1021
+ export declare interface PartOptions {
1022
+ /** Local geometry or a lazy reader; native objects never cross a revision. */
1023
+ readonly geometry: ComputedValue<PartGeometry>;
1024
+ /** XYZ translation in millimetres, applied after rotation; defaults to zero. */
1025
+ readonly position?: ComputedValue<Vec3>;
1026
+ /** Fixed global X, Y, Z rotations in degrees; defaults to zero. */
1027
+ readonly rotation?: ComputedValue<Vec3>;
1028
+ /** Optional six-digit hexadecimal semantic part color. */
1029
+ readonly color?: string;
1030
+ }
1294
1031
 
1295
1032
  /**
1296
1033
  * Supplies a profile-X orientation guide for each original normalized sweep station.
@@ -1301,8 +1038,15 @@ export declare const offset: ModelingContext["offset"];
1301
1038
  */
1302
1039
  export declare type PathNormalGuide = (point: Vec3, index: number) => Vec3;
1303
1040
 
1304
- /** Host-bound pathPattern operation. Valid only during a synchronous build. */
1305
- export declare const pathPattern: ModelingContext["pathPattern"];
1041
+ /**
1042
+ * Physical arc-length copies along a sampled path, with optional tangent orientation.
1043
+ *
1044
+ * @example Copies along a bent path
1045
+ * ```ts
1046
+ * pathPattern(box({ size: 4 }), [[0, 0, 0], [20, 0, 0], [20, 20, 0]], { count: 5 });
1047
+ * ```
1048
+ */
1049
+ export declare function pathPattern(source: PatternSource, path: readonly Vec3[], options: PathPatternOptions): readonly Solid[];
1306
1050
 
1307
1051
  /** Equal physical arc-length placements along an open or implicitly closed sampled path. */
1308
1052
  export declare interface PathPatternOptions {
@@ -1315,7 +1059,7 @@ export declare interface PathPatternOptions {
1315
1059
  }
1316
1060
 
1317
1061
  /**
1318
- * One same-build shape, or a synchronous factory called once per copy in index order.
1062
+ * One same-session shape, or a synchronous factory called once per copy in index order.
1319
1063
  */
1320
1064
  export declare type PatternSource = Solid | ((index: number) => Solid);
1321
1065
 
@@ -1341,14 +1085,14 @@ export declare interface Polygon2 {
1341
1085
  readonly outer: Loop2;
1342
1086
  }
1343
1087
 
1344
- /** Host-bound preflightInternalThreadCutter operation. Valid only during a synchronous build. */
1345
- export declare const preflightInternalThreadCutter: ModelingContext["preflightInternalThreadCutter"];
1088
+ /** Allocation-free internal-thread facts. */
1089
+ export declare function preflightInternalThreadCutter(options: InternalThreadCutterOptions): HelicalThreadSolidMeshPreflight;
1346
1090
 
1347
- /** Host-bound preflightThreadedNut operation. Valid only during a synchronous build. */
1348
- export declare const preflightThreadedNut: ModelingContext["preflightThreadedNut"];
1091
+ /** Allocation-free nut/cutter facts. */
1092
+ export declare function preflightThreadedNut(options: ThreadedNutOptions): ThreadedNutPreflight;
1349
1093
 
1350
- /** Host-bound preflightThreadedRod operation. Valid only during a synchronous build. */
1351
- export declare const preflightThreadedRod: ModelingContext["preflightThreadedRod"];
1094
+ /** Allocation-free external-thread facts. */
1095
+ export declare function preflightThreadedRod(options: ThreadedRodOptions): HelicalThreadSolidMeshPreflight;
1352
1096
 
1353
1097
  /** Placement shared by solid and filled-section factories. */
1354
1098
  export declare interface PrimitivePlacement {
@@ -1468,11 +1212,16 @@ export declare type ProfileSpan2 = {
1468
1212
  readonly end: Vec2;
1469
1213
  });
1470
1214
 
1471
- /** Host-bound projectSection operation. Valid only during a synchronous build. */
1472
- export declare const projectSection: ModelingContext["projectSection"];
1473
-
1474
- /** Host-bound radialPattern operation. Valid only during a synchronous build. */
1475
- export declare const radialPattern: ModelingContext["radialPattern"];
1215
+ /**
1216
+ * Repeats one solid about an axis.
1217
+ *
1218
+ * @example Six copies around Z
1219
+ * ```ts
1220
+ * const pin = cylinder({ height: 6, radius: 2 }).translate([12, 0, 0]);
1221
+ * radialPattern(pin, { count: 6, axis: [0, 0, 1], angleDegrees: 60 });
1222
+ * ```
1223
+ */
1224
+ export declare function radialPattern(source: PatternSource, options: RadialPatternOptions): readonly Solid[];
1476
1225
 
1477
1226
  /**
1478
1227
  * Options for repeating one solid around an axis through a center point.
@@ -1503,11 +1252,18 @@ export declare interface RadialSizingOptions {
1503
1252
  readonly sizing?: RadialSizing;
1504
1253
  }
1505
1254
 
1506
- /** Copies intersections along a finite directed ray segment during the active build. */
1507
- export declare const rayCast: ModelingContext["rayCast"];
1255
+ /** Copies intersections along the finite directed origin-to-endpoint segment. */
1256
+ export declare function rayCast(solid: Solid, origin: Vec3, endpoint: Vec3): readonly SolidRayHit[];
1508
1257
 
1509
- /** Host-bound rectangle operation. Valid only during a synchronous build. */
1510
- export declare const rectangle: ModelingContext["rectangle"];
1258
+ /**
1259
+ * Filled rectangular section with uniform or independently treated corners.
1260
+ *
1261
+ * @example Round the corners
1262
+ * ```ts
1263
+ * rectangle({ size: [30, 20], treatment: { kind: "round", radius: 3 } });
1264
+ * ```
1265
+ */
1266
+ export declare function rectangle(options: RectangleOptions): Section;
1511
1267
 
1512
1268
  /** A rectangle corner, including an explicitly untreated corner in a treatment tuple. */
1513
1269
  export declare type RectangleCornerTreatment = EdgeTreatment | {
@@ -1561,8 +1317,15 @@ export declare interface RegionOffsetOptions {
1561
1317
  readonly resolution?: GeometryResolution;
1562
1318
  }
1563
1319
 
1564
- /** Host-bound regularPolygon operation. Valid only during a synchronous build. */
1565
- export declare const regularPolygon: ModelingContext["regularPolygon"];
1320
+ /**
1321
+ * Regular polygon with a vertex on +X.
1322
+ *
1323
+ * @example Hexagonal section
1324
+ * ```ts
1325
+ * regularPolygon({ radius: 10, sides: 6, sizing: "face" });
1326
+ * ```
1327
+ */
1328
+ export declare function regularPolygon(options: RegularPolygonOptions): Section;
1566
1329
 
1567
1330
  /**
1568
1331
  * Regular polygon dimensions, radial convention and degree rotation.
@@ -1576,8 +1339,21 @@ export declare type RegularPolygonOptions = RadialSizingOptions & PrimitivePlace
1576
1339
  readonly rotationDegrees?: number;
1577
1340
  };
1578
1341
 
1579
- /** Host-bound revolve operation. Valid only during a synchronous build. */
1580
- export declare const revolve: ModelingContext["revolve"];
1342
+ /**
1343
+ * Revolves explicit corresponding radial/Z contours around +Z, with caps for partial sweeps.
1344
+ * Filled Sections use `section.revolve(options)`.
1345
+ *
1346
+ * @example Revolve
1347
+ * ```ts
1348
+ * import { matchProfiles, revolve } from "@metamesh/modeling";
1349
+ * import { rectangleProfile } from "@metamesh/modeling/geometry";
1350
+ *
1351
+ * // Contour coordinates are [radius, Z].
1352
+ * const [profile] = matchProfiles([rectangleProfile({ size: [4, 16], center: false })]);
1353
+ * revolve(profile!, { revolveDegrees: 270 });
1354
+ * ```
1355
+ */
1356
+ export declare function revolve(shape: CorrespondingProfile, options?: RevolveOptions): Solid;
1581
1357
 
1582
1358
  /**
1583
1359
  * Circumferential sampling and degree sweep shared by pure and filled revolution.
@@ -1594,9 +1370,6 @@ export declare interface RevolveOptions extends CircularPrimitiveOptions {
1594
1370
  readonly limits?: Partial<ModelingLimits>;
1595
1371
  }
1596
1372
 
1597
- /** Host-bound rotate operation. Valid only during a synchronous build. */
1598
- export declare const rotate: ModelingContext["rotate"];
1599
-
1600
1373
  /**
1601
1374
  * A circular edge or corner roundover with explicit physical sampling.
1602
1375
  */
@@ -1607,19 +1380,72 @@ export declare interface RoundedEdgeTreatment extends CircularPrimitiveOptions {
1607
1380
  readonly radius: number;
1608
1381
  }
1609
1382
 
1610
- /** Host-bound scale operation. Valid only during a synchronous build. */
1611
- export declare const scale: ModelingContext["scale"];
1612
-
1613
- /** Immutable native filled XY section belonging to exactly one synchronous engine build. */
1383
+ /**
1384
+ * Immutable deferred filled XY section recipe belonging to exactly one model session.
1385
+ * Methods run during synchronous generation and preserve their receiver.
1386
+ * Distances use millimetres; rotations are counterclockwise degrees about the origin.
1387
+ * Construction uses the session resolution unless the operation supplies explicit options.
1388
+ *
1389
+ * @example Extrude an outline with a border
1390
+ * ```ts
1391
+ * const body = rectangle({ size: [20, 12] })
1392
+ * .subtract([rectangle({ size: [16, 8] })])
1393
+ * .offset(0.5)
1394
+ * .extrude({ height: 4 });
1395
+ * ```
1396
+ */
1614
1397
  export declare interface Section {
1615
- /** Compile-time ownership brand for a same-build section. */
1398
+ /** Compile-time ownership brand for a same-session section. */
1616
1399
  readonly [sectionBrand]: "Section";
1400
+ /** Translates XY coordinates in millimetres. */
1401
+ translate(this: Section, offset: Vec2): Section;
1402
+ /** Rotates counterclockwise about the origin by a scalar angle in degrees. */
1403
+ rotate(this: Section, degrees: number): Section;
1404
+ /**
1405
+ * Nonsingular scaling about the origin.
1406
+ */
1407
+ scale(this: Section, factors: number | Vec2): Section;
1408
+ /** Reflection across an origin line/plane. */
1409
+ mirror(this: Section, normal: Vec2): Section;
1410
+ /** Row-major affine transform preserving dimensionality. */
1411
+ transform(this: Section, matrix: Transform2): Section;
1412
+ /** Native section difference; an empty cutter array preserves the source. */
1413
+ subtract(this: Section, cutters: readonly Section[]): Section;
1414
+ /**
1415
+ * Simplifies filled 2D contours using an explicit positive millimetre tolerance.
1416
+ *
1417
+ * Useful for dense imported outlines before extrusion. This changes the outline rather
1418
+ * than selecting a lower rendering quality; fine features may be removed.
1419
+ */
1420
+ simplify(this: Section, tolerance: number): Section;
1421
+ /**
1422
+ * Returns a new same-session handle with copied named anchors; existing names may be replaced.
1423
+ */
1424
+ withAnchors(this: Section, anchors: Readonly<Record<string, Anchor3>>): Section;
1425
+ /**
1426
+ * Native millimetre offset preserving holes.
1427
+ */
1428
+ offset(this: Section, distance: number, options?: RegionOffsetOptions): Section;
1429
+ /**
1430
+ * Extrudes along +Z with degree twist and top scaling.
1431
+ */
1432
+ extrude(this: Section, options: ExtrudeOptions): Solid;
1433
+ /**
1434
+ * Revolves a filled radial/Z shape around +Z, with caps for partial sweeps.
1435
+ */
1436
+ revolve(this: Section, options?: RevolveOptions): Solid;
1437
+ /**
1438
+ * Sweeps this filled section using the selected frame policy and degree twist.
1439
+ */
1440
+ sweep(this: Section, path: readonly Vec3[], options?: SweepOptions): Solid;
1617
1441
  }
1618
1442
 
1619
1443
  declare const sectionBrand: unique symbol;
1620
1444
 
1621
- /** Host-bound sectionFromContours operation. Valid only during a synchronous build. */
1622
- export declare const sectionFromContours: ModelingContext["sectionFromContours"];
1445
+ /**
1446
+ * Creates a native filled section without an intermediate Region2 conversion.
1447
+ */
1448
+ export declare function sectionFromContours(contours: readonly Loop2[], options?: SectionFromContoursOptions): Section;
1623
1449
 
1624
1450
  /**
1625
1451
  * Filled-contour resolution. Closing vertices are implicit.
@@ -1629,14 +1455,14 @@ export declare interface SectionFromContoursOptions {
1629
1455
  readonly fillRule?: "nonzero" | "evenodd";
1630
1456
  }
1631
1457
 
1632
- /** Planar convex hull inputs are finite XY points or same-build filled sections. */
1458
+ /** Planar convex hull inputs are finite XY points or same-session filled sections. */
1633
1459
  export declare type SectionHullOptions = {
1634
1460
  /** At least three finite millimetre XY points spanning positive area. */
1635
1461
  readonly points: readonly Vec2[];
1636
1462
  /** Point input excludes section input. */
1637
1463
  readonly sections?: never;
1638
1464
  } | {
1639
- /** One through 1000 same-build sections to include in the convex hull. */
1465
+ /** One through 1000 same-session sections to include in the convex hull. */
1640
1466
  readonly sections: readonly Section[];
1641
1467
  /** Section input excludes point input. */
1642
1468
  readonly points?: never;
@@ -1644,7 +1470,7 @@ export declare type SectionHullOptions = {
1644
1470
 
1645
1471
  /**
1646
1472
  * Immutable native filled section facts in millimetres and square millimetres.
1647
- * Repeated inspections of the same native shape share these facts within one build.
1473
+ * Repeated inspections of the same native shape share these facts within one revision.
1648
1474
  */
1649
1475
  export declare interface SectionInspection {
1650
1476
  /** Whether this filled section has no area or boundary. */
@@ -1663,15 +1489,6 @@ export declare interface SectionInspection {
1663
1489
  readonly vertices: number;
1664
1490
  }
1665
1491
 
1666
- /** Returns an immutable copy with the explicit native millimetre tolerance. */
1667
- export declare const setTolerance: ModelingContext["setTolerance"];
1668
-
1669
- /** Host-bound simplify operation. Valid only during a synchronous build. */
1670
- export declare const simplify: ModelingContext["simplify"];
1671
-
1672
- /** Host-bound sliceSection operation. Valid only during a synchronous build. */
1673
- export declare const sliceSection: ModelingContext["sliceSection"];
1674
-
1675
1492
  /** A cubic corner transition with zero curvature at its straight tangent joins. */
1676
1493
  export declare interface SmoothEdgeTreatment {
1677
1494
  /** Selects continuous-curvature cubic rounding, rather than a circular radius. */
@@ -1686,20 +1503,85 @@ export declare interface SmoothEdgeTreatment {
1686
1503
  readonly limits?: Partial<GeometrySamplingLimits>;
1687
1504
  }
1688
1505
 
1689
- /** Immutable solid handle belonging to exactly one synchronous engine build. */
1506
+ /**
1507
+ * Immutable deferred solid recipe belonging to exactly one model session.
1508
+ * Methods run during synchronous generation, preserve their receiver, and use millimetres and degrees.
1509
+ * A no-op may reuse the receiver; final part placement belongs in `part` options.
1510
+ *
1511
+ * @example Shape a body with a through bore
1512
+ * ```ts
1513
+ * const body = box({ size: [30, 20, 6] })
1514
+ * .subtract([cylinder({ height: 8, radius: 3 })])
1515
+ * .rotate([0, 0, 45]);
1516
+ * ```
1517
+ */
1690
1518
  export declare interface Solid {
1691
- /** Compile-time ownership brand for a same-build solid. */
1519
+ /** Compile-time ownership brand for a same-session solid. */
1692
1520
  readonly [solidBrand]: "Solid";
1521
+ /**
1522
+ * Translates XYZ coordinates in millimetres.
1523
+ */
1524
+ translate(this: Solid, offset: Vec3): Solid;
1525
+ /**
1526
+ * Rotates about the origin using XYZ Euler angles in degrees.
1527
+ */
1528
+ rotate(this: Solid, degrees: Vec3): Solid;
1529
+ /**
1530
+ * Nonsingular scaling about the origin.
1531
+ */
1532
+ scale(this: Solid, factors: number | Vec3): Solid;
1533
+ /**
1534
+ * Reflection across an origin line/plane.
1535
+ */
1536
+ mirror(this: Solid, normal: Vec3): Solid;
1537
+ /** Row-major affine transform preserving dimensionality. */
1538
+ transform(this: Solid, matrix: Transform3): Solid;
1539
+ /**
1540
+ * Robust difference; an empty cutter array preserves the source.
1541
+ */
1542
+ subtract(this: Solid, cutters: readonly Solid[]): Solid;
1543
+ /**
1544
+ * Simplifies a solid using an explicit positive millimetre tolerance.
1545
+ *
1546
+ * Removes redundant vertices while keeping surfaces within the greater of this tolerance
1547
+ * and the solid's existing native tolerance. Choose it from the detail you can afford to lose.
1548
+ */
1549
+ simplify(this: Solid, tolerance: number): Solid;
1550
+ /**
1551
+ * Returns a new same-session handle with copied named anchors; existing names may be replaced.
1552
+ */
1553
+ withAnchors(this: Solid, anchors: Readonly<Record<string, Anchor3>>): Solid;
1554
+ /**
1555
+ * Places an explicit or named source anchor against an explicit target anchor.
1556
+ */
1557
+ attach(this: Solid, source: Anchor3 | string, target: Anchor3, options?: AttachOptions): Solid;
1558
+ /** Replaces native tolerance on an immutable copy; zero selects the kernel minimum. */
1559
+ setTolerance(this: Solid, tolerance: number): Solid;
1560
+ /** Projects this solid into a filled XY section. */
1561
+ projectSection(this: Solid): Section;
1562
+ /** Takes a filled horizontal slice at Z millimetres. */
1563
+ sliceSection(this: Solid, z: number): Section;
1693
1564
  }
1694
1565
 
1695
1566
  declare const solidBrand: unique symbol;
1696
1567
 
1697
- /** Host-bound solidFromMesh operation. Valid only during a synchronous build. */
1698
- export declare const solidFromMesh: ModelingContext["solidFromMesh"];
1568
+ /**
1569
+ * Imports a bounded closed indexed mesh.
1570
+ *
1571
+ * @example Mesh import
1572
+ * ```ts
1573
+ * import { solidFromMesh } from "@metamesh/modeling";
1574
+ * import { extrudeMesh, rectangleLoop } from "@metamesh/modeling/geometry";
1575
+ *
1576
+ * const mesh = extrudeMesh(rectangleLoop({ size: [20, 12] }), { height: 6 });
1577
+ * solidFromMesh(mesh);
1578
+ * ```
1579
+ */
1580
+ export declare function solidFromMesh(mesh: TriangleMesh | ImmutableTriangleMesh): Solid;
1699
1581
 
1700
1582
  /**
1701
1583
  * 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.
1584
+ * Repeated inspections of the same native shape share these facts within one revision.
1703
1585
  */
1704
1586
  export declare interface SolidInspection {
1705
1587
  /** Whether this native solid contains no material. */
@@ -1718,18 +1600,6 @@ export declare interface SolidInspection {
1718
1600
  readonly tolerance: number;
1719
1601
  }
1720
1602
 
1721
- /** Named same-build solid manufacturing part. */
1722
- export declare interface SolidPart {
1723
- /** Stable canonical lowercase identity; unique within the containing topology or output. */
1724
- readonly id: string;
1725
- /** Optional six-digit hex RGB display color. */
1726
- readonly color?: string;
1727
- /** Same-build solid handle; mutually exclusive with a direct mesh. */
1728
- readonly solid: Solid;
1729
- /** Direct manufacturing mesh; mutually exclusive with a solid handle. */
1730
- readonly mesh?: never;
1731
- }
1732
-
1733
1603
  /** Copied surface intersection from a finite directed segment. Distance is in millimetres. */
1734
1604
  export declare interface SolidRayHit {
1735
1605
  /** Copied numeric native face identity. */
@@ -1742,8 +1612,15 @@ export declare interface SolidRayHit {
1742
1612
  readonly normal: Vec3;
1743
1613
  }
1744
1614
 
1745
- /** Host-bound sphere operation. Valid only during a synchronous build. */
1746
- export declare const sphere: ModelingContext["sphere"];
1615
+ /**
1616
+ * Origin-centered sphere.
1617
+ *
1618
+ * @example Sphere
1619
+ * ```ts
1620
+ * sphere({ diameter: 20 });
1621
+ * ```
1622
+ */
1623
+ export declare function sphere(options: SphereOptions): Solid;
1747
1624
 
1748
1625
  /**
1749
1626
  * Exactly one radius or diameter, placement, and tessellation for an origin-centered sphere.
@@ -1760,11 +1637,45 @@ export declare type SphereOptions = CircularPrimitiveOptions & PrimitivePlacemen
1760
1637
  readonly radius?: never;
1761
1638
  });
1762
1639
 
1763
- /** Returns intersection and difference with a same-build cutter, including empty results. */
1764
- export declare const split: ModelingContext["split"];
1640
+ /**
1641
+ * Splits a solid into [inside the cutter, outside the cutter].
1642
+ *
1643
+ * The first result is the intersection; the second is the subtraction. The cutter itself
1644
+ * is not returned. Either result may be empty or contain multiple disconnected components.
1645
+ *
1646
+ * @example Keep the plug and the surrounding body
1647
+ * ```ts
1648
+ * const body = box({ size: [30, 20, 8] });
1649
+ * const cutter = cylinder({ height: 10, diameter: 8 });
1650
+ * const [plug, remainder] = split(body, cutter);
1651
+ * // Move the plug beside the body to show both results.
1652
+ * union([plug.translate([0, -20, 0]), remainder]);
1653
+ * ```
1654
+ */
1655
+ export declare function split(solid: Solid, cutter: Solid): readonly [Solid, Solid];
1765
1656
 
1766
- /** Splits a solid into the normal-side and opposite-side halves of a world-space plane. */
1767
- export declare const splitByPlane: ModelingContext["splitByPlane"];
1657
+ /**
1658
+ * Splits a solid into [positive-normal side, negative side] at a world-space plane.
1659
+ *
1660
+ * The nonzero normal is normalized; offset is the signed distance from the origin in
1661
+ * millimetres, defaulting to zero. Both cut faces are closed. Select either tuple result
1662
+ * to retain one side; either result may be empty.
1663
+ *
1664
+ * @example Separate two halves at X = 0
1665
+ * ```ts
1666
+ * const body = box({ size: [30, 20, 8] });
1667
+ * const [right, left] = splitByPlane(body, { normal: [1, 0, 0] });
1668
+ * // The gap is only for display; the cut itself removes no material.
1669
+ * union([right.translate([4, 0, 0]), left.translate([-4, 0, 0])]);
1670
+ * ```
1671
+ *
1672
+ * @example Keep only the positive half
1673
+ * ```ts
1674
+ * const [right] = splitByPlane(box({ size: [30, 20, 8] }), { normal: [1, 0, 0] });
1675
+ * right;
1676
+ * ```
1677
+ */
1678
+ export declare function splitByPlane(solid: Solid, plane: PlaneOptions): readonly [Solid, Solid];
1768
1679
 
1769
1680
  /** Square profile with equal crest and root widths. */
1770
1681
  declare interface SquareThreadProfileSpec extends ThreadProfileBaseSpec {
@@ -1777,8 +1688,15 @@ declare interface SquareThreadProfileSpec extends ThreadProfileBaseSpec {
1777
1688
  readonly depth?: number;
1778
1689
  }
1779
1690
 
1780
- /** Host-bound star operation. Valid only during a synchronous build. */
1781
- export declare const star: ModelingContext["star"];
1691
+ /**
1692
+ * Alternating outer/inner star vertices.
1693
+ *
1694
+ * @example Five-point section
1695
+ * ```ts
1696
+ * star({ outerRadius: 12, innerRadius: 6, points: 5 });
1697
+ * ```
1698
+ */
1699
+ export declare function star(options: StarOptions): Section;
1782
1700
 
1783
1701
  /**
1784
1702
  * Alternating outer and inner vertices, centered on the XY origin.
@@ -1796,14 +1714,18 @@ export declare interface StarOptions extends PrimitivePlacement {
1796
1714
  readonly rotationDegrees?: number;
1797
1715
  }
1798
1716
 
1799
- /** Host-bound subtract operation. Valid only during a synchronous build. */
1800
- export declare const subtract: ModelingContext["subtract"];
1801
-
1802
1717
  /** Placement of painted SVG geometry after SVG Y-axis inversion. */
1803
1718
  export declare type SvgOrigin = "center" | "document";
1804
1719
 
1805
- /** Host-bound svgPathSection operation. Valid only during a synchronous build. */
1806
- export declare const svgPathSection: ModelingContext["svgPathSection"];
1720
+ /**
1721
+ * Imports bounded filled SVG path data.
1722
+ *
1723
+ * @example Fill an SVG path in millimetres
1724
+ * ```ts
1725
+ * svgPathSection("M0 0H20V12H0Z", { origin: "center", scale: 1 });
1726
+ * ```
1727
+ */
1728
+ export declare function svgPathSection(path: string, options?: SvgPathSectionOptions): Section;
1807
1729
 
1808
1730
  /** Bounded filled SVG path sampling. Path scale converts user units to millimetres. */
1809
1731
  export declare interface SvgPathSectionOptions {
@@ -1819,8 +1741,18 @@ export declare interface SvgPathSectionOptions {
1819
1741
  readonly scale?: number;
1820
1742
  }
1821
1743
 
1822
- /** Host-bound svgSection operation. Valid only during a synchronous build. */
1823
- export declare const svgSection: ModelingContext["svgSection"];
1744
+ /**
1745
+ * Imports bounded painted SVG document geometry.
1746
+ *
1747
+ * @example Import a physical SVG rectangle
1748
+ * ```ts
1749
+ * svgSection(
1750
+ * '<svg xmlns="http://www.w3.org/2000/svg" width="30mm" height="20mm" viewBox="0 0 30 20"><rect width="30" height="20"/></svg>',
1751
+ * { origin: "center" },
1752
+ * );
1753
+ * ```
1754
+ */
1755
+ export declare function svgSection(svg: string, options?: SvgSectionOptions): Section;
1824
1756
 
1825
1757
  /**
1826
1758
  * Bounded SVG document sampling. Center origin uses the final painted bounds.
@@ -1836,8 +1768,22 @@ export declare interface SvgSectionOptions {
1836
1768
  readonly origin?: SvgOrigin;
1837
1769
  }
1838
1770
 
1839
- /** Host-bound sweep operation. Valid only during a synchronous build. */
1840
- export declare const sweep: ModelingContext["sweep"];
1771
+ /**
1772
+ * Sweeps explicit corresponding contours using the selected frame policy.
1773
+ * Filled Sections use `section.sweep(path, options)`.
1774
+ *
1775
+ * @example Sweep
1776
+ * ```ts
1777
+ * import { matchProfiles, sweep } from "@metamesh/modeling";
1778
+ * import { rectangleProfile } from "@metamesh/modeling/geometry";
1779
+ *
1780
+ * const [profile] = matchProfiles([rectangleProfile({ size: [6, 3] })]);
1781
+ * sweep(profile!, [[0, 0, 0], [0, 0, 15], [10, 0, 25]], {
1782
+ * orientation: { kind: "transport", initialNormal: [0, 1, 0] },
1783
+ * });
1784
+ * ```
1785
+ */
1786
+ export declare function sweep(shape: CorrespondingProfile, path: readonly Vec3[], options?: SweepOptions): Solid;
1841
1787
 
1842
1788
  /**
1843
1789
  * Controls shared by pure mesh construction and filled modeling sweeps.
@@ -1884,8 +1830,18 @@ export declare type SweepOrientation = {
1884
1830
  readonly kind: "frenet";
1885
1831
  };
1886
1832
 
1887
- /** Host-bound textSection operation. Valid only during a synchronous build. */
1888
- export declare const textSection: ModelingContext["textSection"];
1833
+ /**
1834
+ * Consumes a previously prepared layout; never shapes or fetches a font.
1835
+ *
1836
+ * @example Use a prepared text layout
1837
+ * ```ts
1838
+ * // Prepare the exact font and layout before entering build.
1839
+ * function labelSection(layout: VectorTextLayout) {
1840
+ * return textSection(layout);
1841
+ * }
1842
+ * ```
1843
+ */
1844
+ export declare function textSection(layout: VectorTextLayout, options?: TextSectionOptions): Section;
1889
1845
 
1890
1846
  /**
1891
1847
  * Physical curve sampling applied to already prepared vector text.
@@ -1910,8 +1866,19 @@ declare interface ThreadBevelOptions {
1910
1866
  readonly bevelTop?: boolean;
1911
1867
  }
1912
1868
 
1913
- /** Host-bound threadedNut operation. Valid only during a synchronous build. */
1914
- export declare const threadedNut: ModelingContext["threadedNut"];
1869
+ /**
1870
+ * Compensated threaded nut.
1871
+ *
1872
+ * @example Threaded nut
1873
+ * ```ts
1874
+ * import { threadedNut } from "@metamesh/modeling";
1875
+ * import { createThreadProfile } from "@metamesh/modeling/geometry";
1876
+ *
1877
+ * const profile = createThreadProfile({ kind: "triangular", pitch: 1.75 });
1878
+ * threadedNut({ nominalMajorDiameter: 12, thickness: 8, width: 20, shape: "hex", profile, fit: "normal" });
1879
+ * ```
1880
+ */
1881
+ export declare function threadedNut(options: ThreadedNutOptions): Solid;
1915
1882
 
1916
1883
  /** Nut-edge bevel selection. */
1917
1884
  export declare type ThreadedNutBevel = "automatic" | "both" | "inside" | "none" | "outside";
@@ -1959,8 +1926,19 @@ export declare interface ThreadedNutPreflight {
1959
1926
  */
1960
1927
  export declare type ThreadedNutShape = "hex" | "round" | "square";
1961
1928
 
1962
- /** Host-bound threadedRod operation. Valid only during a synchronous build. */
1963
- export declare const threadedRod: ModelingContext["threadedRod"];
1929
+ /**
1930
+ * Compensated external threaded rod.
1931
+ *
1932
+ * @example Threaded rod
1933
+ * ```ts
1934
+ * import { threadedRod } from "@metamesh/modeling";
1935
+ * import { createThreadProfile } from "@metamesh/modeling/geometry";
1936
+ *
1937
+ * const profile = createThreadProfile({ kind: "triangular", pitch: 1.75 });
1938
+ * threadedRod({ nominalMajorDiameter: 12, length: 24, profile, fit: "normal" });
1939
+ * ```
1940
+ */
1941
+ export declare function threadedRod(options: ThreadedRodOptions): Solid;
1964
1942
 
1965
1943
  /**
1966
1944
  * Options for a compensated external threaded rod along +Z.
@@ -2054,17 +2032,24 @@ declare interface ThreadProfileBaseSpec {
2054
2032
  */
2055
2033
  declare type ThreadProfileSpec = AcmeThreadProfileSpec | ButtressThreadProfileSpec | CustomThreadProfileSpec | SquareThreadProfileSpec | TrapezoidalThreadProfileSpec | TriangularThreadProfileSpec;
2056
2034
 
2057
- /** Host-bound threadRidge operation. Valid only during a synchronous build. */
2058
- export declare const threadRidge: ModelingContext["threadRidge"];
2035
+ /** Helical ridge mesh construction. */
2036
+ export declare function threadRidge(options: ThreadRidgeOptions): Solid;
2059
2037
 
2060
2038
  /** Parameters for a helical ridge before solid construction. */
2061
2039
  export declare type ThreadRidgeOptions = HelicalThreadRidgeMeshOptions;
2062
2040
 
2063
- /** Host-bound toRegion operation. Valid only during a synchronous build. */
2064
- export declare const toRegion: ModelingContext["toRegion"];
2041
+ /** Explicit copied topology inspection; not needed for section operations. */
2042
+ export declare function toRegion(section: Section): Region2;
2065
2043
 
2066
- /** Host-bound torus operation. Valid only during a synchronous build. */
2067
- export declare const torus: ModelingContext["torus"];
2044
+ /**
2045
+ * Torus around +Z.
2046
+ *
2047
+ * @example Torus
2048
+ * ```ts
2049
+ * torus({ majorRadius: 12, minorRadius: 3 });
2050
+ * ```
2051
+ */
2052
+ export declare function torus(options: TorusOptions): Solid;
2068
2053
 
2069
2054
  /**
2070
2055
  * Dimensions and independent ring/profile tessellation for a torus around the Z axis.
@@ -2084,11 +2069,8 @@ export declare interface TorusOptions extends PrimitivePlacement {
2084
2069
  readonly resolution?: GeometryResolution;
2085
2070
  }
2086
2071
 
2087
- /** Host-bound toTriangleMesh operation. Valid only during a synchronous build. */
2088
- export declare const toTriangleMesh: ModelingContext["toTriangleMesh"];
2089
-
2090
- /** Host-bound transform operation. Valid only during a synchronous build. */
2091
- export declare const transform: ModelingContext["transform"];
2072
+ /** Copies a handle to manufacturing mesh buffers. */
2073
+ export declare function toTriangleMesh(solid: Solid): TriangleMesh;
2092
2074
 
2093
2075
  /** Row-major affine XY matrix. Translation occupies m02/m12; final row is [0, 0, 1]. */
2094
2076
  export declare type Transform2 = readonly [
@@ -2128,9 +2110,6 @@ m32: number,
2128
2110
  m33: number
2129
2111
  ];
2130
2112
 
2131
- /** Host-bound translate operation. Valid only during a synchronous build. */
2132
- export declare const translate: ModelingContext["translate"];
2133
-
2134
2113
  /** Trapezoidal thread profile with a configurable included angle. */
2135
2114
  declare interface TrapezoidalThreadProfileSpec extends ThreadProfileBaseSpec {
2136
2115
  /** Selects the trapezoidal profile family. */
@@ -2201,8 +2180,15 @@ declare interface TriangularThreadProfileSpec extends ThreadProfileBaseSpec {
2201
2180
  readonly rootFlatRatio?: number;
2202
2181
  }
2203
2182
 
2204
- /** Host-bound tube operation. Valid only during a synchronous build. */
2205
- export declare const tube: ModelingContext["tube"];
2183
+ /**
2184
+ * Hollow +Z tube.
2185
+ *
2186
+ * @example Tube
2187
+ * ```ts
2188
+ * tube({ height: 20, outerRadius: 10, innerRadius: 6 });
2189
+ * ```
2190
+ */
2191
+ export declare function tube(options: TubeOptions): Solid;
2206
2192
 
2207
2193
  /**
2208
2194
  * Dimensions, placement, and tessellation for a hollow Z-axis tube.
@@ -2221,8 +2207,20 @@ export declare interface TubeOptions extends CircularPrimitiveOptions, Primitive
2221
2207
  readonly outerRadius: number;
2222
2208
  }
2223
2209
 
2224
- /** Host-bound union operation. Valid only during a synchronous build. */
2225
- export declare const union: ModelingContext["union"];
2210
+ /**
2211
+ * Robust union.
2212
+ *
2213
+ * @example Union
2214
+ * ```ts
2215
+ * const block = box({ size: 20 });
2216
+ * const cap = sphere({ radius: 10 }).translate([0, 0, 10]);
2217
+ * union([block, cap]);
2218
+ * ```
2219
+ */
2220
+ export declare function union(solids: readonly Solid[]): Solid;
2221
+
2222
+ /** Native filled section union; dimensions cannot be mixed. */
2223
+ export declare function union(sections: readonly Section[]): Section;
2226
2224
 
2227
2225
  /** A two-dimensional Cartesian vector or point. */
2228
2226
  export declare type Vec2 = readonly [x: number, y: number];
@@ -2266,7 +2264,4 @@ export declare interface VectorTextMetrics {
2266
2264
  readonly lineCount: number;
2267
2265
  }
2268
2266
 
2269
- /** Returns a new same-build shape handle with explicit copied named anchors. */
2270
- export declare const withAnchors: ModelingContext["withAnchors"];
2271
-
2272
2267
  export { }