@metamesh/modeling 0.8.0 → 0.9.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.
@@ -520,6 +520,39 @@ export declare interface ArcCurve3 {
520
520
  */
521
521
  export declare const cross3: (a: Vec3, b: Vec3) => Vec3;
522
522
 
523
+ /** One explicitly closed planar contour, independent of editor metadata and parameter contracts. */
524
+ export declare interface CrossSectionCurve {
525
+ /** Initial anchor; coordinates may be any finite value. */
526
+ readonly start: CrossSectionPoint;
527
+ /** Ordered chain of 2–32 segments; the final end must exactly match start. */
528
+ readonly segments: readonly CrossSectionSegment[];
529
+ }
530
+
531
+ /** Planar X and upward Y in millimetres, or in units converted by sampling scales. */
532
+ export declare interface CrossSectionPoint {
533
+ /** Horizontal coordinate; physical scaling does not center the contour. */
534
+ readonly x: number;
535
+ /** Upward planar coordinate. */
536
+ readonly y: number;
537
+ }
538
+
539
+ /** Straight or cubic Bézier segment in one closed planar contour. */
540
+ export declare type CrossSectionSegment = {
541
+ /** Straight segment discriminator. */
542
+ readonly type: "line";
543
+ /** Next anchor; the final anchor repeats the curve start. */
544
+ readonly end: CrossSectionPoint;
545
+ } | {
546
+ /** Cubic Bézier segment discriminator. */
547
+ readonly type: "cubic";
548
+ /** Outgoing control from the previous anchor. */
549
+ readonly control1: CrossSectionPoint;
550
+ /** Incoming control at the next anchor. */
551
+ readonly control2: CrossSectionPoint;
552
+ /** Next anchor; the final anchor repeats the curve start. */
553
+ readonly end: CrossSectionPoint;
554
+ };
555
+
523
556
  /** Planar cubic Bézier with explicit endpoint and control coordinates. */
524
557
  export declare interface CubicBezierCurve2 {
525
558
  /** Selects a cubic Bézier through two endpoints and two controls. */
@@ -2195,1027 +2228,1068 @@ export declare interface ArcCurve3 {
2195
2228
  readonly radius: number;
2196
2229
  }
2197
2230
 
2198
- /** Samples a planar curve with the same guarantees and policy as spatial sampling.
2199
- * @remarks Private spatial scratch math is shared, while only final planar vectors are copied and
2200
- * frozen. At stationary tangents, outgoing secants are preferred and endpoints use a backward fallback.
2201
- * @example
2202
- * ```ts
2203
- * const turn = sampleCurve2({kind: "arc", center: [0,0], radius: 10, sweepDegrees: 90});
2204
- * ```
2205
- */
2206
- export declare function sampleCurve2(curve: Curve2, options?: CurveSamplingOptions): SampledCurve2;
2207
-
2208
2231
  /**
2209
- * Samples a spatial curve, preserving endpoints and directed unit tangents.
2210
- * @remarks Exact counts use uniform curve parameters, not equal physical distances. Adaptive cubics
2211
- * bound the full control hull. Full-circle arcs repeat their endpoint; closed polylines do not.
2212
- * @example
2213
- * ```ts
2214
- * const path = sampleCurve3({kind: "cubic", start: [0,0,0], control1: [5,0,0], control2: [5,5,5], end: [10,5,5]});
2215
- * ```
2216
- */
2217
- export declare function sampleCurve3(curve: Curve3, options?: CurveSamplingOptions): SampledCurve3;
2218
-
2219
- /**
2220
- * Samples a complete external involute gear boundary in the XY plane.
2232
+ * Samples 2–32 connected line/cubic segments into a simple, nonzero-area, immutable CCW XY loop.
2233
+ * Physical scaling precedes adaptive curve sampling; the final end must repeat start exactly.
2234
+ * Shared anchors and the closing seam are emitted once. Winding normalization may change the
2235
+ * starting vertex. The sampled loop is checked for self-intersection and degeneracy by
2236
+ * `normalizeLoop2`; this is a single contour without holes. No editor modes or normalized
2237
+ * coordinate range are required. No native engine, SDK, or ambient resolution is used.
2221
2238
  *
2222
- * The returned loop is counter-clockwise, closed implicitly without a repeated
2223
- * seam point, and contains no holes. Its center is the origin and its axis is
2224
- * +Z. Bore, hub, keyway, twist, and face-width choices remain generator-owned.
2225
- */
2226
- export declare function sampleCylindricalGearOutline(spec: CylindricalGearSpec, options?: CylindricalGearOutlineOptions): Loop2;
2227
-
2228
- /** Immutable planar points and corresponding directed unit tangents. */
2229
- export declare interface SampledCurve2 {
2230
- /** Curves retain both endpoints, including full-circle seams; closed resampling omits its seam. */
2231
- readonly points: readonly Vec2[];
2232
- /** Directed unit vectors; stationary derivatives use the nearest usable direction. */
2233
- readonly tangents: readonly Vec2[];
2234
- }
2235
-
2236
- /**
2237
- * Immutable spatial points and corresponding directed unit tangents.
2238
- */
2239
- export declare interface SampledCurve3 {
2240
- /** Curves retain both endpoints, including full-circle seams; closed resampling omits its seam. */
2241
- readonly points: readonly Vec3[];
2242
- /** Directed unit vectors; stationary derivatives use the nearest usable direction. */
2243
- readonly tangents: readonly Vec3[];
2244
- }
2245
-
2246
- /** Sampled paths plus conventional pitch and lead measurements. */
2247
- export declare interface SampledThreadHelices {
2248
- /** Axial advance over one revolution, equal to `pitch * starts`. */
2249
- readonly lead: number;
2250
- /** One immutable sampled path for each thread start. */
2251
- readonly paths: readonly Path3[];
2252
- /** Adjacent axial thread spacing in millimetres. */
2253
- readonly pitch: number;
2254
- /** Number of revolutions represented by each path. */
2255
- readonly turns: number;
2256
- }
2257
-
2258
- /**
2259
- * Creates `segments + 1` points including exact helix endpoints from finite positive dimensions.
2260
- * Integrated weights must remain finite. The maxPathPoints ceiling defaults to 100000; excessive
2261
- * exact counts reject before evaluating axial weights or allocating sample arrays.
2262
- */
2263
- export declare const sampleHelix: ({ turns, radius, height, segments, limits, axialWeight, }: SampleHelixOptions) => readonly Vec3[];
2264
-
2265
- /** Options for a sampled +Z helix with millimetre dimensions. */
2266
- export declare interface SampleHelixOptions {
2267
- /** Number of complete rotations around +Z. */
2268
- readonly turns: number;
2269
- /** Explicit output allocation ceilings. */
2270
- readonly limits?: Partial<GeometrySamplingLimits>;
2271
- /** Constant radial distance from the +Z axis. */
2272
- readonly radius: number;
2273
- /** Total axial advance from the first point to the last. */
2274
- readonly height: number;
2275
- /** Number of sampled line segments; the result contains one additional endpoint. */
2276
- readonly segments: number;
2277
- /**
2278
- * Relative axial advance at a normalized turn position. Values are integrated
2279
- * and normalized, so the final endpoint is always exactly `height`.
2280
- */
2281
- readonly axialWeight?: (t: number) => number;
2282
- }
2283
-
2284
- /**
2285
- * Samples the center opening and tooth spaces used to subtract an internal ring gear.
2286
- *
2287
- * Internal tooth tips lie one addendum below the pitch radius and their roots lie one
2288
- * dedendum above it. At the pitch circle, positive backlash widens each sampled space
2289
- * tangentially. The returned CCW loop encloses the center and is intended to be reversed
2290
- * when used as a region hole.
2291
- */
2292
- export declare function sampleInternalCylindricalGearSpaceOutline(spec: CylindricalGearSpec, options?: CylindricalGearOutlineOptions): Loop2;
2293
-
2294
- /**
2295
- * Samples 1–31 line/cubic segments into a deeply immutable open [radius,height] polyline.
2296
- * Anchors must progress strictly upward; nonnegative-radius cubic controls must have ordered
2297
- * heights between their endpoints. Cubics use de Casteljau subdivision with a conservative
2298
- * control-hull chord-error bound. Lines also obey the optional physical edge-length ceiling.
2299
- * Neither normalized coordinates nor editor metadata are required. Endpoints are retained once;
2300
- * no axis closure, winding normalization, or manufacturing repair is performed.
2301
- *
2302
- * @param curve - Open outline in millimetres unless the positive scales convert its coordinates.
2303
- * @param options - Physical resolution and output budget; defaults to 4096 vertices.
2304
- * @returns Frozen open polyline in millimetres, ordered from lowest to highest anchor.
2305
- * @throws {@link GeometryError} for invalid coordinates, order, scale, or exceeded subdivision budget.
2239
+ * @param curve - Closed contour in millimetres unless positive scales convert its coordinates.
2240
+ * @param options - Physical resolution and unique vertex budget; defaults to 4096 vertices.
2241
+ * @returns Frozen counterclockwise loop in millimetres, without a repeated seam endpoint.
2242
+ * @throws {@link GeometryError} for invalid data, topology, scale, or exceeded sampling budgets.
2306
2243
  *
2307
2244
  * @example
2308
2245
  * ```ts
2309
- * const side = sampleOpenProfile({
2310
- * start: { radius: 0.5, height: 0 },
2311
- * segments: [{ type: "line", end: { radius: 1, height: 1 } }],
2312
- * }, { radiusScale: 12, heightScale: 30 });
2246
+ * const section = sampleCrossSection({
2247
+ * start: { x: 0, y: 0 },
2248
+ * segments: [
2249
+ * { type: "line", end: { x: 1, y: 0 } },
2250
+ * { type: "line", end: { x: 0.5, y: 1 } },
2251
+ * { type: "line", end: { x: 0, y: 0 } },
2252
+ * ],
2253
+ * }, { widthScale: 20, heightScale: 12 });
2313
2254
  * ```
2314
2255
  */
2315
- export declare function sampleOpenProfile(curve: OpenProfileCurve, options?: SampleOpenProfileOptions): readonly Vec2[];
2256
+ export declare function sampleCrossSection(curve: CrossSectionCurve, options?: SampleCrossSectionOptions): Loop2;
2316
2257
 
2317
- /** Physical scaling and bounded adaptive subdivision for an open profile. */
2318
- export declare interface SampleOpenProfileOptions {
2319
- /** Positive radius scale; use the desired maximum radius for normalized coordinates. Defaults to 1. */
2320
- readonly radiusScale?: number;
2321
- /** Positive height scale; use the desired total height for normalized coordinates. Defaults to 1. */
2258
+ /** Physical scaling, subdivision policy, and output ceilings for one closed contour. */
2259
+ export declare interface SampleCrossSectionOptions {
2260
+ /** Positive horizontal scale; normalized inputs span this width envelope. Defaults to 1. */
2261
+ readonly widthScale?: number;
2262
+ /** Positive vertical scale; normalized inputs span this height envelope. Defaults to 1. */
2322
2263
  readonly heightScale?: number;
2323
- /** Shared physical policy, evaluated after scaling; exact circular counts do not affect curves. */
2264
+ /** Physical policy evaluated after scaling, using the shared curve sampler. */
2324
2265
  readonly resolution?: GeometryResolution;
2325
- /** Maximum output vertex count within maxProfilePoints. Defaults to the smaller of 4096 and that ceiling. */
2266
+ /** Unique output vertex ceiling, at least three, within maxProfilePoints. Defaults to min(4096, maxProfilePoints). */
2326
2267
  readonly maximumVertices?: number;
2327
- /** Explicit profile and circular allocation ceilings. */
2268
+ /** Selected profile and per-segment path ceilings; omitted values use package defaults. */
2328
2269
  readonly limits?: Partial<GeometrySamplingLimits>;
2329
2270
  }
2330
2271
 
2331
- /**
2332
- * Samples the open top boundary of a finite rack in its XY pitch plane.
2333
- *
2334
- * X follows rack travel, Y is tooth height, and the pitch line is `Y = 0`.
2335
- * The path begins and ends on the root line, omits duplicate adjacent points,
2336
- * and leaves base thickness, mounting features, extrusion, and helical sweep to
2337
- * the owning generator.
2338
- */
2339
- export declare function sampleRackToothPath(spec: RackPitchSpec, limits?: Partial<GeometrySamplingLimits>): Path2;
2340
-
2341
- /**
2342
- * Samples a prepared text layout without shaping text again or loading a font.
2343
- *
2344
- * @param layout - Immutable millimetre paths and measurements retained from text preparation.
2345
- * @param resolution - Explicit curve sampling policy; omitted uses the pure default policy.
2346
- * @param limits - Explicit profile and circular allocation ceilings.
2347
- * @returns Frozen contours with original glyph winding and no repeated closing vertex.
2348
- * @throws GeometryError for empty outlines, invalid paths or policies, over 1000 paths or selected sampling ceilings.
2349
- */
2350
- export declare function sampleTextContours(layout: VectorTextLayout, resolution?: GeometryResolution, limits?: Partial<GeometrySamplingLimits>): readonly Loop2[];
2351
-
2352
- /**
2353
- * Samples evenly phased thread helices with finite `lead = pitch * starts`.
2354
- * All starts together respect maxPathPoints (default 100000); excessive counts fail before allocation.
2272
+ /** Samples a planar curve with the same guarantees and policy as spatial sampling.
2273
+ * @remarks Private spatial scratch math is shared, while only final planar vectors are copied and
2274
+ * frozen. At stationary tangents, outgoing secants are preferred and endpoints use a backward fallback.
2275
+ * @example
2276
+ * ```ts
2277
+ * const turn = sampleCurve2({kind: "arc", center: [0,0], radius: 10, sweepDegrees: 90});
2278
+ * ```
2355
2279
  */
2356
- export declare function sampleThreadHelices(options: ThreadHelixOptions): SampledThreadHelices;
2280
+ export declare function sampleCurve2(curve: Curve2, options?: CurveSamplingOptions): SampledCurve2;
2357
2281
 
2358
2282
  /**
2359
- * Multiplies a vector by a dimensionless scalar.
2283
+ * Samples a spatial curve, preserving endpoints and directed unit tangents.
2284
+ * @remarks Exact counts use uniform curve parameters, not equal physical distances. Adaptive cubics
2285
+ * bound the full control hull. Full-circle arcs repeat their endpoint; closed polylines do not.
2360
2286
  * @example
2361
2287
  * ```ts
2362
- * scale3([1, 2, 3], 2); // [2, 4, 6]
2288
+ * const path = sampleCurve3({kind: "cubic", start: [0,0,0], control1: [5,0,0], control2: [5,5,5], end: [10,5,5]});
2363
2289
  * ```
2364
2290
  */
2365
- export declare const scale3: (vector: Vec3, scale: number) => Vec3;
2291
+ export declare function sampleCurve3(curve: Curve3, options?: CurveSamplingOptions): SampledCurve3;
2366
2292
 
2367
2293
  /**
2368
- * Creates an immutable axis-aligned scale transform.
2369
- *
2370
- * Negative components are reflections. Zero components are rejected because
2371
- * they collapse volume and cannot be inverted.
2294
+ * Samples a complete external involute gear boundary in the XY plane.
2372
2295
  *
2373
- * @param factors - Finite, non-zero XYZ scale factors.
2374
- * @returns A frozen row-major transform.
2296
+ * The returned loop is counter-clockwise, closed implicitly without a repeated
2297
+ * seam point, and contains no holes. Its center is the origin and its axis is
2298
+ * +Z. Bore, hub, keyway, twist, and face-width choices remain generator-owned.
2375
2299
  */
2376
- export declare function scaleTransform3(factors: Vec3): Transform3;
2377
-
2378
- /** Returns the signed area of a non-duplicated loop; positive means CCW. */
2379
- export declare function signedAreaLoop2(loop: Loop2): number;
2380
-
2381
- /** A cubic corner transition with zero curvature at its straight tangent joins. */
2382
- export declare interface SmoothEdgeTreatment {
2383
- /** Selects continuous-curvature cubic rounding, rather than a circular radius. */
2384
- readonly kind: "smooth";
2385
- /** Positive tangent setbacks, equal or [first, second], in millimetres. */
2386
- readonly distance: number | readonly [first: number, second: number];
2387
- /** Exact cubic interval count, positive; overrides physical sampling. */
2388
- readonly segments?: number;
2389
- /** Physical chord/edge-length sampling; circularSegments does not describe a cubic. */
2390
- readonly resolution?: GeometryResolution;
2391
- /** Explicit sampling ceilings, bounded by the host policy. */
2392
- readonly limits?: Partial<GeometrySamplingLimits>;
2393
- }
2300
+ export declare function sampleCylindricalGearOutline(spec: CylindricalGearSpec, options?: CylindricalGearOutlineOptions): Loop2;
2394
2301
 
2395
- /** Bounded floating-point intersection and shell-orientation validation settings. */
2396
- export declare interface SolidMeshValidationOptions {
2397
- /** Work ceiling for spatial comparisons and containment tests; defaults to 2,000,000 and may only lower it. */
2398
- readonly maximumTests?: number;
2399
- /** Distance comparison policy in millimetres; near contacts reject conservatively. */
2400
- readonly tolerance?: GeometryToleranceOptions;
2302
+ /** Immutable planar points and corresponding directed unit tangents. */
2303
+ export declare interface SampledCurve2 {
2304
+ /** Curves retain both endpoints, including full-circle seams; closed resampling omits its seam. */
2305
+ readonly points: readonly Vec2[];
2306
+ /** Directed unit vectors; stationary derivatives use the nearest usable direction. */
2307
+ readonly tangents: readonly Vec2[];
2401
2308
  }
2402
2309
 
2403
2310
  /**
2404
- * Exactly one radius or diameter, placement, and tessellation for an origin-centered sphere.
2311
+ * Immutable spatial points and corresponding directed unit tangents.
2405
2312
  */
2406
- export declare type SphereOptions = CircularPrimitiveOptions & PrimitivePlacement & ({
2407
- /** Positive radius in millimetres; mutually exclusive with diameter. */
2408
- readonly radius: number;
2409
- /** Full diameter is unavailable when radius is supplied. */
2410
- readonly diameter?: never;
2411
- } | {
2412
- /** Positive full diameter in millimetres; mutually exclusive with radius. */
2413
- readonly diameter: number;
2414
- /** Radius is unavailable when diameter is supplied. */
2415
- readonly radius?: never;
2416
- });
2417
-
2418
- /** Square profile with equal crest and root widths. */
2419
- export declare interface SquareThreadProfileSpec extends ThreadProfileBaseSpec {
2420
- /** Selects the square profile family. */
2421
- readonly kind: "square";
2422
- /**
2423
- * Radial depth in millimetres.
2424
- * @defaultValue `pitch / 2`
2425
- */
2426
- readonly depth?: number;
2313
+ export declare interface SampledCurve3 {
2314
+ /** Curves retain both endpoints, including full-circle seams; closed resampling omits its seam. */
2315
+ readonly points: readonly Vec3[];
2316
+ /** Directed unit vectors; stationary derivatives use the nearest usable direction. */
2317
+ readonly tangents: readonly Vec3[];
2427
2318
  }
2428
2319
 
2429
- /**
2430
- * Creates a centered CCW alternating-radius star within the selected profile sampling ceiling.
2431
- *
2432
- * @example Five-point outline
2433
- * ```ts
2434
- * starLoop(12, 5, 6);
2435
- * ```
2436
- */
2437
- export declare const starLoop: (outerRadius: number, points: number, innerRadius?: number, limits?: Partial<GeometrySamplingLimits>) => readonly Vec2[];
2438
-
2439
- /** End-cap treatment for an open stroked path. */
2440
- export declare type StrokePathCap = "butt" | "round" | "square";
2441
-
2442
- /** Join treatment where adjacent stroked path segments meet. */
2443
- export declare type StrokePathJoin = "bevel" | "miter" | "round";
2444
-
2445
- /**
2446
- * Converts a sampled millimetre path into the filled region covered by a centered stroke.
2447
- *
2448
- * Closed paths omit a duplicated seam point. Zero-length sampled segments are ignored, while the
2449
- * effective path must still contain visible length. Round caps and joins use deterministic physical
2450
- * resolution. Bevels fill the outer corner triangle; miters extend the outer edges to their
2451
- * intersection, falling back to bevels above SVG's default miter limit of 4.
2452
- */
2453
- export declare function strokePathRegion(path: Path2, options: StrokePathRegionOptions): Region2;
2454
-
2455
- /** Physical stroke and topology controls for {@link strokePathRegion}. */
2456
- export declare interface StrokePathRegionOptions {
2457
- /** Explicit path, circular and expanded-profile allocation ceilings. */
2458
- readonly limits?: Partial<GeometrySamplingLimits>;
2459
- /** Treat the path as a closed non-duplicated loop. Default: `false`. */
2460
- readonly closed?: boolean;
2461
- /** End-cap treatment for an open path. Ignored for closed paths. Default: `butt`. */
2462
- readonly cap?: StrokePathCap;
2463
- /** Corner treatment; miters exceeding SVG's default limit of 4 become bevels. Default: `miter`. */
2464
- readonly join?: StrokePathJoin;
2465
- /** Physical tessellation policy for round caps and joins. */
2466
- readonly resolution?: GeometryResolution;
2467
- /** Positive total stroke width in millimetres, centered on the sampled path. */
2468
- readonly width: number;
2320
+ /** Sampled paths plus conventional pitch and lead measurements. */
2321
+ export declare interface SampledThreadHelices {
2322
+ /** Axial advance over one revolution, equal to `pitch * starts`. */
2323
+ readonly lead: number;
2324
+ /** One immutable sampled path for each thread start. */
2325
+ readonly paths: readonly Path3[];
2326
+ /** Adjacent axial thread spacing in millimetres. */
2327
+ readonly pitch: number;
2328
+ /** Number of revolutions represented by each path. */
2329
+ readonly turns: number;
2469
2330
  }
2470
2331
 
2471
2332
  /**
2472
- * Subtracts `b` from `a`.
2473
- * @example
2474
- * ```ts
2475
- * subtract3([4, 5, 6], [1, 2, 3]); // [3, 3, 3]
2476
- * ```
2333
+ * Creates `segments + 1` points including exact helix endpoints from finite positive dimensions.
2334
+ * Integrated weights must remain finite. The maxPathPoints ceiling defaults to 100000; excessive
2335
+ * exact counts reject before evaluating axial weights or allocating sample arrays.
2477
2336
  */
2478
- export declare const subtract3: (a: Vec3, b: Vec3) => Vec3;
2337
+ export declare const sampleHelix: ({ turns, radius, height, segments, limits, axialWeight, }: SampleHelixOptions) => readonly Vec3[];
2479
2338
 
2480
- /** Sampling controls for deterministic SVG-to-region conversion. */
2481
- export declare interface SvgImportOptions {
2482
- /** Explicit profile and circular allocation ceilings; bounded SVG source/work limits remain fixed. */
2339
+ /** Options for a sampled +Z helix with millimetre dimensions. */
2340
+ export declare interface SampleHelixOptions {
2341
+ /** Number of complete rotations around +Z. */
2342
+ readonly turns: number;
2343
+ /** Explicit output allocation ceilings. */
2483
2344
  readonly limits?: Partial<GeometrySamplingLimits>;
2484
- /** Exact segments for a complete ellipse or round stroke feature. */
2485
- readonly circularSegments?: number;
2486
- /** Operation-level physical tessellation policy over the active model-wide policy. */
2487
- readonly resolution?: GeometryResolution;
2345
+ /** Constant radial distance from the +Z axis. */
2346
+ readonly radius: number;
2347
+ /** Total axial advance from the first point to the last. */
2348
+ readonly height: number;
2349
+ /** Number of sampled line segments; the result contains one additional endpoint. */
2350
+ readonly segments: number;
2488
2351
  /**
2489
- * `"center"` places the viewport center at the origin. `"document"` places its converted
2490
- * lower-left corner at the origin. Default: `"center"`.
2352
+ * Relative axial advance at a normalized turn position. Values are integrated
2353
+ * and normalized, so the final endpoint is always exactly `height`.
2491
2354
  */
2492
- readonly origin?: "center" | "document";
2493
- }
2494
-
2495
- /** Exact normalized SVG region plus bounded source, geometry, and safe-repair diagnostics. */
2496
- export declare interface SvgRegionPreflight {
2497
- /** Physical and final-topology measurements of `region`. */
2498
- readonly geometry: SvgRegionPreflightGeometryMetrics;
2499
- /** Appearance-preserving cleanup observed during parsing and normalization. */
2500
- readonly repairs: SvgRegionPreflightRepairs;
2501
- /** Canonical millimetre, Y-up geometry. */
2502
- readonly region: Region2;
2503
- /** Bounded source and flattening complexity measurements. */
2504
- readonly source: SvgRegionPreflightSourceMetrics;
2505
- }
2506
-
2507
- /** Physical and final-topology facts for a normalized imported SVG region. */
2508
- export declare interface SvgRegionPreflightGeometryMetrics {
2509
- /** Filled area in square millimetres. */
2510
- readonly area: number;
2511
- /** Millimetre bounds, or `null` when no painted region remains. */
2512
- readonly bounds: Bounds2 | null;
2513
- /** Disconnected filled polygons in the final region. */
2514
- readonly components: number;
2515
- /** Exterior and hole boundary count in the final region. */
2516
- readonly contours: number;
2517
- /** Interior boundary count in the final region. */
2518
- readonly holes: number;
2519
- /** Shortest final boundary edge in millimetres, or `null` for an empty region. */
2520
- readonly minEdgeLength: number | null;
2521
- /** Final boundary edges shorter than the conservative 0.01 mm indicator. */
2522
- readonly shortEdges: number;
2523
- /** Components with less than 0.01 square millimetres of filled area. */
2524
- readonly tinyIslands: number;
2525
- /** Non-duplicated boundary vertices in the final normalized region. */
2526
- readonly vertices: number;
2527
- }
2528
-
2529
- /** Visible, appearance-preserving cleanup counters from bounded SVG import. */
2530
- export declare interface SvgRegionPreflightRepairs {
2531
- /** Graphics elements with neither a visible fill nor a positive-width visible stroke. */
2532
- readonly invisibleElements: number;
2533
- /** Open filled subpaths closed by SVG fill semantics without closing their strokes. */
2534
- readonly implicitFilledClosures: number;
2535
- /** Visibly painted elements whose fill and stroke both resolved to empty geometry. */
2536
- readonly emptyElements: number;
2537
- /** Consecutive repeated flattened vertices discarded before topology resolution. */
2538
- readonly removedDuplicateVertices: number;
2539
- /** Explicit repeated seam vertices removed from otherwise closed contours. */
2540
- readonly removedSeamVertices: number;
2541
- }
2542
-
2543
- /** Bounded source-complexity facts collected while parsing one SVG document. */
2544
- export declare interface SvgRegionPreflightSourceMetrics {
2545
- /** UTF-8 source size, capped at 256 KiB before parsing. */
2546
- readonly bytes: number;
2547
- /** Renderable shape elements, capped at 500; containers and metadata are excluded. */
2548
- readonly elements: number;
2549
- /** Flattened vertices emitted before fill, stroke, and clipping operations. */
2550
- readonly emittedVertices: number;
2551
- /** Path endpoints and control vertices parsed before adaptive flattening. */
2552
- readonly parsedVertices: number;
2355
+ readonly axialWeight?: (t: number) => number;
2553
2356
  }
2554
2357
 
2555
2358
  /**
2556
- * Sweeps one explicitly ordered point loop, with caps or a geometrically matching closed seam.
2359
+ * Samples the center opening and tooth spaces used to subtract an internal ring gear.
2557
2360
  *
2558
- * @example Sweep point data along a bent path
2559
- * ```ts
2560
- * const profile = rectangleLoop({ size: [6, 3] });
2561
- * sweepMesh(profile, [[0, 0, 0], [0, 0, 15], [10, 0, 25]], {
2562
- * orientation: { kind: "transport", initialNormal: [0, 1, 0] },
2563
- * });
2564
- * ```
2361
+ * Internal tooth tips lie one addendum below the pitch radius and their roots lie one
2362
+ * dedendum above it. At the pitch circle, positive backlash widens each sampled space
2363
+ * tangentially. The returned CCW loop encloses the center and is intended to be reversed
2364
+ * when used as a region hole.
2565
2365
  */
2566
- export declare function sweepMesh(profile: Loop2, path: readonly Vec3[], options?: SweepOptions): TriangleMesh;
2366
+ export declare function sampleInternalCylindricalGearSpaceOutline(spec: CylindricalGearSpec, options?: CylindricalGearOutlineOptions): Loop2;
2567
2367
 
2568
2368
  /**
2569
- * Controls shared by pure mesh construction and filled modeling sweeps.
2570
- */
2571
- export declare interface SweepOptions {
2572
- /** Join the path's last station to its first. Open paths retain watertight end caps. */
2573
- readonly closed?: boolean;
2574
- /** Explicit output and sampling allocation ceilings. */
2575
- readonly limits?: Partial<ModelingLimits>;
2576
- /** Explicit frame policy; default transport minimizes rotations, initially projecting +X then +Y then +Z. */
2577
- readonly orientation?: SweepOrientation;
2578
- /** Physical sampling of nonzero twist; inserted stations retain authored station controls. */
2579
- readonly resolution?: GeometryResolution;
2580
- /** Total additional profile rotation in degrees, with progression selected by twistBy. */
2581
- readonly twistDegrees?: number;
2582
- /** Twist advances by physical path length (default), or normalized authored station position, including a closed seam gap. */
2583
- readonly twistBy?: "length" | "stations";
2584
- /** Positive uniform/XY scale, or one XY pair per path station. Defaults to one. */
2585
- readonly scale?: number | Vec2 | readonly Vec2[];
2586
- /** Corresponding point-index advance at a rotationally equivalent closed seam. */
2587
- readonly seamProfileOffset?: number;
2588
- }
2589
-
2590
- /**
2591
- * Explicit profile-X frame policy; all normals are directed, and selected singular policies reject.
2592
- */
2593
- export declare type SweepOrientation = {
2594
- /** Minimizes frame rotation by parallel transport. */
2595
- readonly kind: "transport";
2596
- /** Initial profile +X guide, projected perpendicular to the first tangent. */
2597
- readonly initialNormal?: Vec3;
2598
- } | {
2599
- /** Projects one fixed world-space normal at every path station. */
2600
- readonly kind: "fixed-normal";
2601
- /** Directed profile +X guide; must not be parallel to any local tangent. */
2602
- readonly normal: Vec3;
2603
- } | {
2604
- /** Uses an explicitly directed normal callback at each original normalized station. */
2605
- readonly kind: "guide";
2606
- /** Finite profile +X guide callback, evaluated once per original path station. */
2607
- readonly normal: PathNormalGuide;
2608
- } | {
2609
- /** Uses sampled curvature normals; zero-curvature stations reject. */
2610
- readonly kind: "frenet";
2611
- };
2612
-
2613
- /** End bevel controls shared by threaded rods and cutters. */
2614
- export declare interface ThreadBevelOptions {
2615
- /** Apply a 45-degree bevel at Z=0. */
2616
- readonly bevelBottom?: boolean;
2617
- /**
2618
- * Axial bevel extent in millimetres. Active blunt ends default to one sixth of the compensated
2619
- * male minor radius or female major radius; other ends default to the profile depth.
2620
- */
2621
- readonly bevelSize?: number;
2622
- /** Apply a 45-degree bevel at Z=length. */
2623
- readonly bevelTop?: boolean;
2624
- }
2625
-
2626
- /** Inputs for resolving one shared circular facet count for a mating thread pair. */
2627
- export declare interface ThreadCircularSegmentsOptions {
2628
- /** Explicit circular allocation ceiling for the shared mating grid. */
2629
- readonly limits?: Partial<GeometrySamplingLimits>;
2630
- /** Printable fit whose larger compensated female envelope governs tessellation. */
2631
- readonly fit?: PrintableThreadFit | PrintableThreadFitPolicy;
2632
- /** Nominal major diameter before role-specific compensation. */
2633
- readonly nominalMajorDiameter: number;
2634
- /**
2635
- * Maximum active female face outset beyond the compensated major envelope, in millimetres.
2636
- * This keeps a compensated male/female pair on one role-independent grid when an internal
2637
- * cutter has an enlarged entrance bevel. Default: `0`.
2369
+ * Samples 1–31 line/cubic segments into a deeply immutable open [radius,height] polyline.
2370
+ * Anchors must progress strictly upward; nonnegative-radius cubic controls must have ordered
2371
+ * heights between their endpoints. Cubics use de Casteljau subdivision with a conservative
2372
+ * control-hull chord-error bound. Lines also obey the optional physical edge-length ceiling.
2373
+ * Neither normalized coordinates nor editor metadata are required. Endpoints are retained once;
2374
+ * no axis closure, winding normalization, or manufacturing repair is performed.
2375
+ *
2376
+ * @param curve - Open outline in millimetres unless the positive scales convert its coordinates.
2377
+ * @param options - Physical resolution and output budget; defaults to 4096 vertices.
2378
+ * @returns Frozen open polyline in millimetres, ordered from lowest to highest anchor.
2379
+ * @throws {@link GeometryError} for invalid coordinates, order, scale, or exceeded subdivision budget.
2380
+ *
2381
+ * @example
2382
+ * ```ts
2383
+ * const side = sampleOpenProfile({
2384
+ * start: { radius: 0.5, height: 0 },
2385
+ * segments: [{ type: "line", end: { radius: 1, height: 1 } }],
2386
+ * }, { radiusScale: 12, heightScale: 30 });
2387
+ * ```
2638
2388
  */
2639
- readonly maximumRadialOutset?: number;
2640
- /** Validated mating profile whose pitch and flank capacities govern tessellation. */
2641
- readonly profile: ThreadProfile;
2642
- /** Physical or exact circular resolution policy. */
2643
- readonly resolution?: GeometryResolution;
2644
- /** Number of phased starts. Default: `1`. */
2645
- readonly starts?: number;
2646
- }
2647
-
2648
- /** Options for compensating nominal male or female thread diameters. */
2649
- export declare interface ThreadCompensationOptions {
2650
- /** Named policy or explicit caller-calibrated allowances. */
2651
- readonly fit?: PrintableThreadFit | PrintableThreadFitPolicy;
2652
- /** Nominal sharp or truncated major diameter in millimetres. */
2653
- readonly nominalMajorDiameter: number;
2654
- /** Male or female geometry being compensated. */
2655
- readonly role: ThreadRole;
2656
- /** Radial depth from major to minor envelope in millimetres. */
2657
- readonly threadDepth: number;
2658
- /** Optional numerical tolerance overrides. */
2659
- readonly tolerance?: GeometryToleranceOptions;
2660
- }
2661
-
2662
- /** Nut-edge bevel selection. */
2663
- export declare type ThreadedNutBevel = "automatic" | "both" | "inside" | "none" | "outside";
2664
-
2665
- /**
2666
- * Options for a compensated nut with an internal thread.
2667
- */
2668
- export declare interface ThreadedNutOptions extends Omit<InternalThreadCutterOptions, "bevelBottom" | "bevelSize" | "bevelTop" | "length"> {
2669
- /** Nut body bevel selection. Default: `automatic`. */
2670
- readonly bevel?: ThreadedNutBevel;
2671
- /** Optional physical policy for a round body, independent of the thread's matched facet grid. */
2672
- readonly bodyResolution?: GeometryResolution;
2673
- /** 45-degree body chamfer extent. Default: `min(profile.depth, thickness/4)`. */
2674
- readonly chamferSize?: number;
2675
- /** Leave the bottom outside edge flat for build-plate adhesion. Default: `false`. */
2676
- readonly flushBuildPlateBottom?: boolean;
2677
- /** Nut body shape. */
2678
- readonly shape: ThreadedNutShape;
2679
- /** Nut thickness along +Z in millimetres. */
2680
- readonly thickness: number;
2681
- /** Across-flats width for hex/square or diameter for round, in millimetres. */
2682
- readonly width: number;
2683
- }
2389
+ export declare function sampleOpenProfile(curve: OpenProfileCurve, options?: SampleOpenProfileOptions): readonly Vec2[];
2390
+
2391
+ /** Physical scaling and bounded adaptive subdivision for an open profile. */
2392
+ export declare interface SampleOpenProfileOptions {
2393
+ /** Positive radius scale; use the desired maximum radius for normalized coordinates. Defaults to 1. */
2394
+ readonly radiusScale?: number;
2395
+ /** Positive height scale; use the desired total height for normalized coordinates. Defaults to 1. */
2396
+ readonly heightScale?: number;
2397
+ /** Shared physical policy, evaluated after scaling; exact circular counts do not affect curves. */
2398
+ readonly resolution?: GeometryResolution;
2399
+ /** Maximum output vertex count within maxProfilePoints. Defaults to the smaller of 4096 and that ceiling. */
2400
+ readonly maximumVertices?: number;
2401
+ /** Explicit profile and circular allocation ceilings. */
2402
+ readonly limits?: Partial<GeometrySamplingLimits>;
2403
+ }
2684
2404
 
2685
- /** Allocation-free body, cutter, and end-face facts resolved for a threaded nut. */
2686
- export declare interface ThreadedNutPreflight {
2687
- /** Polygon segment count used by the nut body. */
2688
- readonly bodySegments: number;
2689
- /** Shared 45-degree chamfer size applied to the selected body and cutter edges. */
2690
- readonly chamferSize: number;
2691
- /** Maximum compensated cutter radius at either requested face. */
2692
- readonly cutterFaceRadius: number;
2693
- /** Minimum nut-body inradius across the requested top and bottom faces. */
2694
- readonly minimumBodyFaceInradius: number;
2695
- /** Smallest radial wall left between the body and cutter at either requested face. */
2696
- readonly minimumFaceWall: number;
2697
- /** Conservative allocation facts for the exact extended internal-thread cutter mesh. */
2698
- readonly thread: HelicalThreadSolidMeshPreflight;
2699
- /** Start-aligned circular facet count used by the compensated thread cutter. */
2700
- readonly threadCircularSegments: number;
2701
- }
2702
-
2703
- /**
2704
- * Supported printable nut body shapes.
2705
- */
2706
- export declare type ThreadedNutShape = "hex" | "round" | "square";
2405
+ /**
2406
+ * Samples the open top boundary of a finite rack in its XY pitch plane.
2407
+ *
2408
+ * X follows rack travel, Y is tooth height, and the pitch line is `Y = 0`.
2409
+ * The path begins and ends on the root line, omits duplicate adjacent points,
2410
+ * and leaves base thickness, mounting features, extrusion, and helical sweep to
2411
+ * the owning generator.
2412
+ */
2413
+ export declare function sampleRackToothPath(spec: RackPitchSpec, limits?: Partial<GeometrySamplingLimits>): Path2;
2707
2414
 
2708
- /**
2709
- * Options for a compensated external threaded rod along +Z.
2710
- */
2711
- export declare interface ThreadedRodOptions extends Omit<HelicalThreadRidgeMeshOptions, "majorDiameter">, ThreadBevelOptions {
2712
- /** Printable fit or caller-calibrated allowances. Default: `normal`. */
2713
- readonly fit?: PrintableThreadFit | PrintableThreadFitPolicy;
2714
- /** Nominal major diameter before male compensation. */
2715
- readonly nominalMajorDiameter: number;
2716
- }
2415
+ /**
2416
+ * Samples a prepared text layout without shaping text again or loading a font.
2417
+ *
2418
+ * @param layout - Immutable millimetre paths and measurements retained from text preparation.
2419
+ * @param resolution - Explicit curve sampling policy; omitted uses the pure default policy.
2420
+ * @param limits - Explicit profile and circular allocation ceilings.
2421
+ * @returns Frozen contours with original glyph winding and no repeated closing vertex.
2422
+ * @throws GeometryError for empty outlines, invalid paths or policies, over 1000 paths or selected sampling ceilings.
2423
+ */
2424
+ export declare function sampleTextContours(layout: VectorTextLayout, resolution?: GeometryResolution, limits?: Partial<GeometrySamplingLimits>): readonly Loop2[];
2717
2425
 
2718
- /** End shape of a generated helical ridge. */
2719
- export declare type ThreadEndStyle = "blunt" | "standard" | "tapered";
2426
+ /**
2427
+ * Samples evenly phased thread helices with finite `lead = pitch * starts`.
2428
+ * All starts together respect maxPathPoints (default 100000); excessive counts fail before allocation.
2429
+ */
2430
+ export declare function sampleThreadHelices(options: ThreadHelixOptions): SampledThreadHelices;
2720
2431
 
2721
- /** Axial end controls for a generated ridge. */
2722
- export declare interface ThreadEndTreatmentOptions {
2723
- /**
2724
- * Ridge shape at the lower working boundary. `blunt` ends at full profile height, `standard`
2725
- * clips the periodic profile at the face, and `tapered` ramps out from the minor envelope.
2726
- * @defaultValue `"blunt"`
2727
- */
2728
- readonly bottom?: ThreadEndStyle;
2729
- /**
2730
- * Non-negative unthreaded envelope length reserved at each non-standard end, in millimetres.
2731
- * Active blunt bevels may raise this reservation to the effective bevel size.
2732
- * @defaultValue `0`
2733
- */
2734
- readonly endLength?: number;
2735
- /**
2736
- * Radial envelope toward which a blunt lead-in collapses.
2737
- * @defaultValue `"minor"`
2738
- */
2739
- readonly leadInEnvelope?: ThreadLeadInEnvelope;
2740
- /**
2741
- * Physical circumferential lead-in length in millimetres.
2742
- * @defaultValue The profile depth.
2743
- */
2744
- readonly leadInLength?: number;
2745
- /**
2746
- * Cross-section scaling curve used by blunt ends. `cut` switches abruptly to the full profile.
2747
- * @defaultValue `"cut"`
2748
- */
2749
- readonly leadInShape?: ThreadLeadInShape;
2750
- /**
2751
- * Ridge shape at the upper working boundary. `blunt` ends at full profile height, `standard`
2752
- * clips the periodic profile at the face, and `tapered` ramps into the minor envelope.
2753
- * @defaultValue `"blunt"`
2754
- */
2755
- readonly top?: ThreadEndStyle;
2756
- }
2432
+ /**
2433
+ * Multiplies a vector by a dimensionless scalar.
2434
+ * @example
2435
+ * ```ts
2436
+ * scale3([1, 2, 3], 2); // [2, 4, 6]
2437
+ * ```
2438
+ */
2439
+ export declare const scale3: (vector: Vec3, scale: number) => Vec3;
2757
2440
 
2758
- /**
2759
- * Direction in which a conventional helical thread advances around +Z.
2760
- */
2761
- export declare type ThreadHandedness = "left" | "right";
2441
+ /**
2442
+ * Creates an immutable axis-aligned scale transform.
2443
+ *
2444
+ * Negative components are reflections. Zero components are rejected because
2445
+ * they collapse volume and cannot be inverted.
2446
+ *
2447
+ * @param factors - Finite, non-zero XYZ scale factors.
2448
+ * @returns A frozen row-major transform.
2449
+ */
2450
+ export declare function scaleTransform3(factors: Vec3): Transform3;
2451
+
2452
+ /** Returns the signed area of a non-duplicated loop; positive means CCW. */
2453
+ export declare function signedAreaLoop2(loop: Loop2): number;
2454
+
2455
+ /** A cubic corner transition with zero curvature at its straight tangent joins. */
2456
+ export declare interface SmoothEdgeTreatment {
2457
+ /** Selects continuous-curvature cubic rounding, rather than a circular radius. */
2458
+ readonly kind: "smooth";
2459
+ /** Positive tangent setbacks, equal or [first, second], in millimetres. */
2460
+ readonly distance: number | readonly [first: number, second: number];
2461
+ /** Exact cubic interval count, positive; overrides physical sampling. */
2462
+ readonly segments?: number;
2463
+ /** Physical chord/edge-length sampling; circularSegments does not describe a cubic. */
2464
+ readonly resolution?: GeometryResolution;
2465
+ /** Explicit sampling ceilings, bounded by the host policy. */
2466
+ readonly limits?: Partial<GeometrySamplingLimits>;
2467
+ }
2468
+
2469
+ /** Bounded floating-point intersection and shell-orientation validation settings. */
2470
+ export declare interface SolidMeshValidationOptions {
2471
+ /** Work ceiling for spatial comparisons and containment tests; defaults to 2,000,000 and may only lower it. */
2472
+ readonly maximumTests?: number;
2473
+ /** Distance comparison policy in millimetres; near contacts reject conservatively. */
2474
+ readonly tolerance?: GeometryToleranceOptions;
2475
+ }
2762
2476
 
2763
- /** Conventional helix options: `pitch` is adjacent spacing and lead is `pitch * starts`. */
2764
- export declare interface ThreadHelixOptions {
2765
- /** Helix direction. Default: `right`. */
2766
- readonly handedness?: ThreadHandedness;
2767
- /** Explicit aggregate path allocation ceilings across all starts. */
2768
- readonly limits?: Partial<GeometrySamplingLimits>;
2769
- /** Total sampled axial length in millimetres. */
2770
- readonly length: number;
2771
- /** Angular offset of the first start in degrees. Default: `0`. */
2772
- readonly phaseDegrees?: number;
2773
- /** Adjacent axial thread spacing in millimetres. */
2774
- readonly pitch: number;
2775
- /** Radial distance from the +Z axis in millimetres. */
2776
- readonly radius: number;
2777
- /** Angular sampling density for each revolution. Default: `32`. */
2778
- readonly segmentsPerTurn?: number;
2779
- /** Number of evenly phased helices. Default: `1`. */
2780
- readonly starts?: number;
2781
- /** Optional numerical tolerance overrides. */
2782
- readonly tolerance?: GeometryToleranceOptions;
2783
- }
2477
+ /**
2478
+ * Exactly one radius or diameter, placement, and tessellation for an origin-centered sphere.
2479
+ */
2480
+ export declare type SphereOptions = CircularPrimitiveOptions & PrimitivePlacement & ({
2481
+ /** Positive radius in millimetres; mutually exclusive with diameter. */
2482
+ readonly radius: number;
2483
+ /** Full diameter is unavailable when radius is supplied. */
2484
+ readonly diameter?: never;
2485
+ } | {
2486
+ /** Positive full diameter in millimetres; mutually exclusive with radius. */
2487
+ readonly diameter: number;
2488
+ /** Radius is unavailable when diameter is supplied. */
2489
+ readonly radius?: never;
2490
+ });
2491
+
2492
+ /** Square profile with equal crest and root widths. */
2493
+ export declare interface SquareThreadProfileSpec extends ThreadProfileBaseSpec {
2494
+ /** Selects the square profile family. */
2495
+ readonly kind: "square";
2496
+ /**
2497
+ * Radial depth in millimetres.
2498
+ * @defaultValue `pitch / 2`
2499
+ */
2500
+ readonly depth?: number;
2501
+ }
2784
2502
 
2785
- /** Radial envelope toward which a blunt lead-in collapses. */
2786
- export declare type ThreadLeadInEnvelope = "major" | "minor";
2503
+ /**
2504
+ * Creates a centered CCW alternating-radius star within the selected profile sampling ceiling.
2505
+ *
2506
+ * @example Five-point outline
2507
+ * ```ts
2508
+ * starLoop(12, 5, 6);
2509
+ * ```
2510
+ */
2511
+ export declare const starLoop: (outerRadius: number, points: number, innerRadius?: number, limits?: Partial<GeometrySamplingLimits>) => readonly Vec2[];
2787
2512
 
2788
- /** BOSL2-compatible cross-section scaling curve for a blunt thread lead-in. */
2789
- export declare type ThreadLeadInShape = "cut" | "linear" | "smooth" | "sqrt";
2513
+ /** End-cap treatment for an open stroked path. */
2514
+ export declare type StrokePathCap = "butt" | "round" | "square";
2790
2515
 
2791
- /**
2792
- * A validated immutable periodic thread profile in `[axial, radial]` millimetres.
2793
- */
2794
- export declare interface ThreadProfile {
2795
- /** Axial width of the flat at the major envelope. */
2796
- readonly crestFlatWidth: number;
2797
- /** Radial distance from the major envelope to the root. */
2798
- readonly depth: number;
2799
- /** Profile family that produced this validated profile. */
2800
- readonly kind: ThreadProfileSpec["kind"];
2801
- /** Adjacent axial thread spacing in millimetres. */
2802
- readonly pitch: number;
2803
- /** Immutable open `[axial, radial]` path spanning one pitch. */
2804
- readonly points: readonly Vec2[];
2805
- /** Axial width of the flat at the minor envelope. */
2806
- readonly rootFlatWidth: number;
2807
- }
2516
+ /** Join treatment where adjacent stroked path segments meet. */
2517
+ export declare type StrokePathJoin = "bevel" | "miter" | "round";
2808
2518
 
2809
- /** Fields shared by all thread profile specifications. */
2810
- export declare interface ThreadProfileBaseSpec {
2811
- /** Adjacent axial thread spacing in millimetres. */
2812
- readonly pitch: number;
2813
- /** Optional numerical tolerance overrides. */
2814
- readonly tolerance?: GeometryToleranceOptions;
2815
- }
2519
+ /**
2520
+ * Converts a sampled millimetre path into the filled region covered by a centered stroke.
2521
+ *
2522
+ * Closed paths omit a duplicated seam point. Zero-length sampled segments are ignored, while the
2523
+ * effective path must still contain visible length. Round caps and joins use deterministic physical
2524
+ * resolution. Bevels fill the outer corner triangle; miters extend the outer edges to their
2525
+ * intersection, falling back to bevels above SVG's default miter limit of 4.
2526
+ */
2527
+ export declare function strokePathRegion(path: Path2, options: StrokePathRegionOptions): Region2;
2528
+
2529
+ /** Physical stroke and topology controls for {@link strokePathRegion}. */
2530
+ export declare interface StrokePathRegionOptions {
2531
+ /** Explicit path, circular and expanded-profile allocation ceilings. */
2532
+ readonly limits?: Partial<GeometrySamplingLimits>;
2533
+ /** Treat the path as a closed non-duplicated loop. Default: `false`. */
2534
+ readonly closed?: boolean;
2535
+ /** End-cap treatment for an open path. Ignored for closed paths. Default: `butt`. */
2536
+ readonly cap?: StrokePathCap;
2537
+ /** Corner treatment; miters exceeding SVG's default limit of 4 become bevels. Default: `miter`. */
2538
+ readonly join?: StrokePathJoin;
2539
+ /** Physical tessellation policy for round caps and joins. */
2540
+ readonly resolution?: GeometryResolution;
2541
+ /** Positive total stroke width in millimetres, centered on the sampled path. */
2542
+ readonly width: number;
2543
+ }
2816
2544
 
2817
- /**
2818
- * Supported built-in and caller-defined thread profiles.
2819
- */
2820
- export declare type ThreadProfileSpec = AcmeThreadProfileSpec | ButtressThreadProfileSpec | CustomThreadProfileSpec | SquareThreadProfileSpec | TrapezoidalThreadProfileSpec | TriangularThreadProfileSpec;
2545
+ /**
2546
+ * Subtracts `b` from `a`.
2547
+ * @example
2548
+ * ```ts
2549
+ * subtract3([4, 5, 6], [1, 2, 3]); // [3, 3, 3]
2550
+ * ```
2551
+ */
2552
+ export declare const subtract3: (a: Vec3, b: Vec3) => Vec3;
2553
+
2554
+ /** Sampling controls for deterministic SVG-to-region conversion. */
2555
+ export declare interface SvgImportOptions {
2556
+ /** Explicit profile and circular allocation ceilings; bounded SVG source/work limits remain fixed. */
2557
+ readonly limits?: Partial<GeometrySamplingLimits>;
2558
+ /** Exact segments for a complete ellipse or round stroke feature. */
2559
+ readonly circularSegments?: number;
2560
+ /** Operation-level physical tessellation policy over the active model-wide policy. */
2561
+ readonly resolution?: GeometryResolution;
2562
+ /**
2563
+ * `"center"` places the viewport center at the origin. `"document"` places its converted
2564
+ * lower-left corner at the origin. Default: `"center"`.
2565
+ */
2566
+ readonly origin?: "center" | "document";
2567
+ }
2568
+
2569
+ /** Exact normalized SVG region plus bounded source, geometry, and safe-repair diagnostics. */
2570
+ export declare interface SvgRegionPreflight {
2571
+ /** Physical and final-topology measurements of `region`. */
2572
+ readonly geometry: SvgRegionPreflightGeometryMetrics;
2573
+ /** Appearance-preserving cleanup observed during parsing and normalization. */
2574
+ readonly repairs: SvgRegionPreflightRepairs;
2575
+ /** Canonical millimetre, Y-up geometry. */
2576
+ readonly region: Region2;
2577
+ /** Bounded source and flattening complexity measurements. */
2578
+ readonly source: SvgRegionPreflightSourceMetrics;
2579
+ }
2580
+
2581
+ /** Physical and final-topology facts for a normalized imported SVG region. */
2582
+ export declare interface SvgRegionPreflightGeometryMetrics {
2583
+ /** Filled area in square millimetres. */
2584
+ readonly area: number;
2585
+ /** Millimetre bounds, or `null` when no painted region remains. */
2586
+ readonly bounds: Bounds2 | null;
2587
+ /** Disconnected filled polygons in the final region. */
2588
+ readonly components: number;
2589
+ /** Exterior and hole boundary count in the final region. */
2590
+ readonly contours: number;
2591
+ /** Interior boundary count in the final region. */
2592
+ readonly holes: number;
2593
+ /** Shortest final boundary edge in millimetres, or `null` for an empty region. */
2594
+ readonly minEdgeLength: number | null;
2595
+ /** Final boundary edges shorter than the conservative 0.01 mm indicator. */
2596
+ readonly shortEdges: number;
2597
+ /** Components with less than 0.01 square millimetres of filled area. */
2598
+ readonly tinyIslands: number;
2599
+ /** Non-duplicated boundary vertices in the final normalized region. */
2600
+ readonly vertices: number;
2601
+ }
2602
+
2603
+ /** Visible, appearance-preserving cleanup counters from bounded SVG import. */
2604
+ export declare interface SvgRegionPreflightRepairs {
2605
+ /** Graphics elements with neither a visible fill nor a positive-width visible stroke. */
2606
+ readonly invisibleElements: number;
2607
+ /** Open filled subpaths closed by SVG fill semantics without closing their strokes. */
2608
+ readonly implicitFilledClosures: number;
2609
+ /** Visibly painted elements whose fill and stroke both resolved to empty geometry. */
2610
+ readonly emptyElements: number;
2611
+ /** Consecutive repeated flattened vertices discarded before topology resolution. */
2612
+ readonly removedDuplicateVertices: number;
2613
+ /** Explicit repeated seam vertices removed from otherwise closed contours. */
2614
+ readonly removedSeamVertices: number;
2615
+ }
2616
+
2617
+ /** Bounded source-complexity facts collected while parsing one SVG document. */
2618
+ export declare interface SvgRegionPreflightSourceMetrics {
2619
+ /** UTF-8 source size, capped at 256 KiB before parsing. */
2620
+ readonly bytes: number;
2621
+ /** Renderable shape elements, capped at 500; containers and metadata are excluded. */
2622
+ readonly elements: number;
2623
+ /** Flattened vertices emitted before fill, stroke, and clipping operations. */
2624
+ readonly emittedVertices: number;
2625
+ /** Path endpoints and control vertices parsed before adaptive flattening. */
2626
+ readonly parsedVertices: number;
2627
+ }
2821
2628
 
2822
- /** Whether compensation is being applied to an external or internal thread. */
2823
- export declare type ThreadRole = "male" | "female";
2629
+ /**
2630
+ * Sweeps one explicitly ordered point loop, with caps or a geometrically matching closed seam.
2631
+ *
2632
+ * @example Sweep point data along a bent path
2633
+ * ```ts
2634
+ * const profile = rectangleLoop({ size: [6, 3] });
2635
+ * sweepMesh(profile, [[0, 0, 0], [0, 0, 15], [10, 0, 25]], {
2636
+ * orientation: { kind: "transport", initialNormal: [0, 1, 0] },
2637
+ * });
2638
+ * ```
2639
+ */
2640
+ export declare function sweepMesh(profile: Loop2, path: readonly Vec3[], options?: SweepOptions): TriangleMesh;
2824
2641
 
2825
- /**
2826
- * Dimensions and independent ring/profile tessellation for a torus around the Z axis.
2827
- */
2828
- export declare interface TorusOptions extends PrimitivePlacement {
2829
- /** Explicit sampling ceilings, bounded by the host policy. */
2830
- readonly limits?: Partial<GeometrySamplingLimits>;
2831
- /** Radius from the Z axis to the profile center, in millimetres; greater than `minorRadius`. */
2832
- readonly majorRadius: number;
2833
- /** Exact segment count around the Z axis; omitted uses adaptive resolution. */
2834
- readonly majorSegments?: number;
2835
- /** Radius of the swept circular profile in millimetres. */
2836
- readonly minorRadius: number;
2837
- /** Exact segment count around the swept profile; omitted uses adaptive resolution. */
2838
- readonly minorSegments?: number;
2839
- /** Operation-level physical tessellation policy over the active model-wide policy. */
2840
- readonly resolution?: GeometryResolution;
2841
- }
2642
+ /**
2643
+ * Controls shared by pure mesh construction and filled modeling sweeps.
2644
+ */
2645
+ export declare interface SweepOptions {
2646
+ /** Join the path's last station to its first. Open paths retain watertight end caps. */
2647
+ readonly closed?: boolean;
2648
+ /** Explicit output and sampling allocation ceilings. */
2649
+ readonly limits?: Partial<ModelingLimits>;
2650
+ /** Explicit frame policy; default transport minimizes rotations, initially projecting +X then +Y then +Z. */
2651
+ readonly orientation?: SweepOrientation;
2652
+ /** Physical sampling of nonzero twist; inserted stations retain authored station controls. */
2653
+ readonly resolution?: GeometryResolution;
2654
+ /** Total additional profile rotation in degrees, with progression selected by twistBy. */
2655
+ readonly twistDegrees?: number;
2656
+ /** Twist advances by physical path length (default), or normalized authored station position, including a closed seam gap. */
2657
+ readonly twistBy?: "length" | "stations";
2658
+ /** Positive uniform/XY scale, or one XY pair per path station. Defaults to one. */
2659
+ readonly scale?: number | Vec2 | readonly Vec2[];
2660
+ /** Corresponding point-index advance at a rotationally equivalent closed seam. */
2661
+ readonly seamProfileOffset?: number;
2662
+ }
2842
2663
 
2843
- /**
2844
- * A row-major affine 4x4 matrix applied to column vectors.
2845
- *
2846
- * Translation occupies indices 3, 7, and 11. The final row must be
2847
- * `[0, 0, 0, 1]` within the active geometry tolerance.
2848
- */
2849
- export declare type Transform3 = readonly [
2850
- m00: number,
2851
- m01: number,
2852
- m02: number,
2853
- m03: number,
2854
- m10: number,
2855
- m11: number,
2856
- m12: number,
2857
- m13: number,
2858
- m20: number,
2859
- m21: number,
2860
- m22: number,
2861
- m23: number,
2862
- m30: number,
2863
- m31: number,
2864
- m32: number,
2865
- m33: number
2866
- ];
2664
+ /**
2665
+ * Explicit profile-X frame policy; all normals are directed, and selected singular policies reject.
2666
+ */
2667
+ export declare type SweepOrientation = {
2668
+ /** Minimizes frame rotation by parallel transport. */
2669
+ readonly kind: "transport";
2670
+ /** Initial profile +X guide, projected perpendicular to the first tangent. */
2671
+ readonly initialNormal?: Vec3;
2672
+ } | {
2673
+ /** Projects one fixed world-space normal at every path station. */
2674
+ readonly kind: "fixed-normal";
2675
+ /** Directed profile +X guide; must not be parallel to any local tangent. */
2676
+ readonly normal: Vec3;
2677
+ } | {
2678
+ /** Uses an explicitly directed normal callback at each original normalized station. */
2679
+ readonly kind: "guide";
2680
+ /** Finite profile +X guide callback, evaluated once per original path station. */
2681
+ readonly normal: PathNormalGuide;
2682
+ } | {
2683
+ /** Uses sampled curvature normals; zero-curvature stations reject. */
2684
+ readonly kind: "frenet";
2685
+ };
2686
+
2687
+ /** End bevel controls shared by threaded rods and cutters. */
2688
+ export declare interface ThreadBevelOptions {
2689
+ /** Apply a 45-degree bevel at Z=0. */
2690
+ readonly bevelBottom?: boolean;
2691
+ /**
2692
+ * Axial bevel extent in millimetres. Active blunt ends default to one sixth of the compensated
2693
+ * male minor radius or female major radius; other ends default to the profile depth.
2694
+ */
2695
+ readonly bevelSize?: number;
2696
+ /** Apply a 45-degree bevel at Z=length. */
2697
+ readonly bevelTop?: boolean;
2698
+ }
2699
+
2700
+ /** Inputs for resolving one shared circular facet count for a mating thread pair. */
2701
+ export declare interface ThreadCircularSegmentsOptions {
2702
+ /** Explicit circular allocation ceiling for the shared mating grid. */
2703
+ readonly limits?: Partial<GeometrySamplingLimits>;
2704
+ /** Printable fit whose larger compensated female envelope governs tessellation. */
2705
+ readonly fit?: PrintableThreadFit | PrintableThreadFitPolicy;
2706
+ /** Nominal major diameter before role-specific compensation. */
2707
+ readonly nominalMajorDiameter: number;
2708
+ /**
2709
+ * Maximum active female face outset beyond the compensated major envelope, in millimetres.
2710
+ * This keeps a compensated male/female pair on one role-independent grid when an internal
2711
+ * cutter has an enlarged entrance bevel. Default: `0`.
2712
+ */
2713
+ readonly maximumRadialOutset?: number;
2714
+ /** Validated mating profile whose pitch and flank capacities govern tessellation. */
2715
+ readonly profile: ThreadProfile;
2716
+ /** Physical or exact circular resolution policy. */
2717
+ readonly resolution?: GeometryResolution;
2718
+ /** Number of phased starts. Default: `1`. */
2719
+ readonly starts?: number;
2720
+ }
2721
+
2722
+ /** Options for compensating nominal male or female thread diameters. */
2723
+ export declare interface ThreadCompensationOptions {
2724
+ /** Named policy or explicit caller-calibrated allowances. */
2725
+ readonly fit?: PrintableThreadFit | PrintableThreadFitPolicy;
2726
+ /** Nominal sharp or truncated major diameter in millimetres. */
2727
+ readonly nominalMajorDiameter: number;
2728
+ /** Male or female geometry being compensated. */
2729
+ readonly role: ThreadRole;
2730
+ /** Radial depth from major to minor envelope in millimetres. */
2731
+ readonly threadDepth: number;
2732
+ /** Optional numerical tolerance overrides. */
2733
+ readonly tolerance?: GeometryToleranceOptions;
2734
+ }
2735
+
2736
+ /** Nut-edge bevel selection. */
2737
+ export declare type ThreadedNutBevel = "automatic" | "both" | "inside" | "none" | "outside";
2867
2738
 
2868
- /**
2869
- * Returns the determinant of a transform's linear 3x3 component.
2870
- *
2871
- * A negative result identifies a reflection; zero is rejected as singular.
2872
- *
2873
- * @param transform - Valid affine transform.
2874
- * @returns Signed linear determinant.
2875
- */
2876
- export declare function transformDeterminant3(transform: Transform3): number;
2739
+ /**
2740
+ * Options for a compensated nut with an internal thread.
2741
+ */
2742
+ export declare interface ThreadedNutOptions extends Omit<InternalThreadCutterOptions, "bevelBottom" | "bevelSize" | "bevelTop" | "length"> {
2743
+ /** Nut body bevel selection. Default: `automatic`. */
2744
+ readonly bevel?: ThreadedNutBevel;
2745
+ /** Optional physical policy for a round body, independent of the thread's matched facet grid. */
2746
+ readonly bodyResolution?: GeometryResolution;
2747
+ /** 45-degree body chamfer extent. Default: `min(profile.depth, thickness/4)`. */
2748
+ readonly chamferSize?: number;
2749
+ /** Leave the bottom outside edge flat for build-plate adhesion. Default: `false`. */
2750
+ readonly flushBuildPlateBottom?: boolean;
2751
+ /** Nut body shape. */
2752
+ readonly shape: ThreadedNutShape;
2753
+ /** Nut thickness along +Z in millimetres. */
2754
+ readonly thickness: number;
2755
+ /** Across-flats width for hex/square or diameter for round, in millimetres. */
2756
+ readonly width: number;
2757
+ }
2758
+
2759
+ /** Allocation-free body, cutter, and end-face facts resolved for a threaded nut. */
2760
+ export declare interface ThreadedNutPreflight {
2761
+ /** Polygon segment count used by the nut body. */
2762
+ readonly bodySegments: number;
2763
+ /** Shared 45-degree chamfer size applied to the selected body and cutter edges. */
2764
+ readonly chamferSize: number;
2765
+ /** Maximum compensated cutter radius at either requested face. */
2766
+ readonly cutterFaceRadius: number;
2767
+ /** Minimum nut-body inradius across the requested top and bottom faces. */
2768
+ readonly minimumBodyFaceInradius: number;
2769
+ /** Smallest radial wall left between the body and cutter at either requested face. */
2770
+ readonly minimumFaceWall: number;
2771
+ /** Conservative allocation facts for the exact extended internal-thread cutter mesh. */
2772
+ readonly thread: HelicalThreadSolidMeshPreflight;
2773
+ /** Start-aligned circular facet count used by the compensated thread cutter. */
2774
+ readonly threadCircularSegments: number;
2775
+ }
2877
2776
 
2878
- /**
2879
- * Transforms a closed loop and preserves its original winding convention.
2880
- *
2881
- * Reflections reverse the point order automatically through normalization.
2882
- */
2883
- export declare function transformLoop2(loop: Loop2, transform: Transform3, tolerance?: GeometryToleranceOptions): Loop2;
2777
+ /**
2778
+ * Supported printable nut body shapes.
2779
+ */
2780
+ export declare type ThreadedNutShape = "hex" | "round" | "square";
2884
2781
 
2885
- /** Applies an XY-plane-preserving affine transform to a 2D path. */
2886
- export declare function transformPath2(path: Path2, transform: Transform3, tolerance?: GeometryToleranceOptions): Path2;
2782
+ /**
2783
+ * Options for a compensated external threaded rod along +Z.
2784
+ */
2785
+ export declare interface ThreadedRodOptions extends Omit<HelicalThreadRidgeMeshOptions, "majorDiameter">, ThreadBevelOptions {
2786
+ /** Printable fit or caller-calibrated allowances. Default: `normal`. */
2787
+ readonly fit?: PrintableThreadFit | PrintableThreadFitPolicy;
2788
+ /** Nominal major diameter before male compensation. */
2789
+ readonly nominalMajorDiameter: number;
2790
+ }
2791
+
2792
+ /** End shape of a generated helical ridge. */
2793
+ export declare type ThreadEndStyle = "blunt" | "standard" | "tapered";
2794
+
2795
+ /** Axial end controls for a generated ridge. */
2796
+ export declare interface ThreadEndTreatmentOptions {
2797
+ /**
2798
+ * Ridge shape at the lower working boundary. `blunt` ends at full profile height, `standard`
2799
+ * clips the periodic profile at the face, and `tapered` ramps out from the minor envelope.
2800
+ * @defaultValue `"blunt"`
2801
+ */
2802
+ readonly bottom?: ThreadEndStyle;
2803
+ /**
2804
+ * Non-negative unthreaded envelope length reserved at each non-standard end, in millimetres.
2805
+ * Active blunt bevels may raise this reservation to the effective bevel size.
2806
+ * @defaultValue `0`
2807
+ */
2808
+ readonly endLength?: number;
2809
+ /**
2810
+ * Radial envelope toward which a blunt lead-in collapses.
2811
+ * @defaultValue `"minor"`
2812
+ */
2813
+ readonly leadInEnvelope?: ThreadLeadInEnvelope;
2814
+ /**
2815
+ * Physical circumferential lead-in length in millimetres.
2816
+ * @defaultValue The profile depth.
2817
+ */
2818
+ readonly leadInLength?: number;
2819
+ /**
2820
+ * Cross-section scaling curve used by blunt ends. `cut` switches abruptly to the full profile.
2821
+ * @defaultValue `"cut"`
2822
+ */
2823
+ readonly leadInShape?: ThreadLeadInShape;
2824
+ /**
2825
+ * Ridge shape at the upper working boundary. `blunt` ends at full profile height, `standard`
2826
+ * clips the periodic profile at the face, and `tapered` ramps into the minor envelope.
2827
+ * @defaultValue `"blunt"`
2828
+ */
2829
+ readonly top?: ThreadEndStyle;
2830
+ }
2887
2831
 
2888
- /** Applies an affine transform to a 3D path without mutating its points. */
2889
- export declare function transformPath3(path: Path3, transform: Transform3): Path3;
2832
+ /**
2833
+ * Direction in which a conventional helical thread advances around +Z.
2834
+ */
2835
+ export declare type ThreadHandedness = "left" | "right";
2836
+
2837
+ /** Conventional helix options: `pitch` is adjacent spacing and lead is `pitch * starts`. */
2838
+ export declare interface ThreadHelixOptions {
2839
+ /** Helix direction. Default: `right`. */
2840
+ readonly handedness?: ThreadHandedness;
2841
+ /** Explicit aggregate path allocation ceilings across all starts. */
2842
+ readonly limits?: Partial<GeometrySamplingLimits>;
2843
+ /** Total sampled axial length in millimetres. */
2844
+ readonly length: number;
2845
+ /** Angular offset of the first start in degrees. Default: `0`. */
2846
+ readonly phaseDegrees?: number;
2847
+ /** Adjacent axial thread spacing in millimetres. */
2848
+ readonly pitch: number;
2849
+ /** Radial distance from the +Z axis in millimetres. */
2850
+ readonly radius: number;
2851
+ /** Angular sampling density for each revolution. Default: `32`. */
2852
+ readonly segmentsPerTurn?: number;
2853
+ /** Number of evenly phased helices. Default: `1`. */
2854
+ readonly starts?: number;
2855
+ /** Optional numerical tolerance overrides. */
2856
+ readonly tolerance?: GeometryToleranceOptions;
2857
+ }
2858
+
2859
+ /** Radial envelope toward which a blunt lead-in collapses. */
2860
+ export declare type ThreadLeadInEnvelope = "major" | "minor";
2861
+
2862
+ /** BOSL2-compatible cross-section scaling curve for a blunt thread lead-in. */
2863
+ export declare type ThreadLeadInShape = "cut" | "linear" | "smooth" | "sqrt";
2890
2864
 
2891
- /** Transforms an explicit outer/hole region with reflection-safe winding correction. */
2892
- export declare function transformRegion2(region: Region2, transform: Transform3, tolerance?: GeometryToleranceOptions): Region2;
2865
+ /**
2866
+ * A validated immutable periodic thread profile in `[axial, radial]` millimetres.
2867
+ */
2868
+ export declare interface ThreadProfile {
2869
+ /** Axial width of the flat at the major envelope. */
2870
+ readonly crestFlatWidth: number;
2871
+ /** Radial distance from the major envelope to the root. */
2872
+ readonly depth: number;
2873
+ /** Profile family that produced this validated profile. */
2874
+ readonly kind: ThreadProfileSpec["kind"];
2875
+ /** Adjacent axial thread spacing in millimetres. */
2876
+ readonly pitch: number;
2877
+ /** Immutable open `[axial, radial]` path spanning one pitch. */
2878
+ readonly points: readonly Vec2[];
2879
+ /** Axial width of the flat at the minor envelope. */
2880
+ readonly rootFlatWidth: number;
2881
+ }
2882
+
2883
+ /** Fields shared by all thread profile specifications. */
2884
+ export declare interface ThreadProfileBaseSpec {
2885
+ /** Adjacent axial thread spacing in millimetres. */
2886
+ readonly pitch: number;
2887
+ /** Optional numerical tolerance overrides. */
2888
+ readonly tolerance?: GeometryToleranceOptions;
2889
+ }
2893
2890
 
2894
- /**
2895
- * Applies an affine transform to a mesh and preserves outward face orientation.
2896
- *
2897
- * A transform with a negative linear determinant reflects space, so this helper
2898
- * automatically reverses every triangle. Singular transforms are rejected.
2899
- *
2900
- * @param mesh - Mesh to transform without mutation.
2901
- * @param transform - Row-major affine transform.
2902
- * @returns A mesh with fresh transformed positions and copied or reversed indices.
2903
- */
2904
- export declare function transformTriangleMesh(mesh: TriangleMesh, transform: Transform3): TriangleMesh;
2891
+ /**
2892
+ * Supported built-in and caller-defined thread profiles.
2893
+ */
2894
+ export declare type ThreadProfileSpec = AcmeThreadProfileSpec | ButtressThreadProfileSpec | CustomThreadProfileSpec | SquareThreadProfileSpec | TrapezoidalThreadProfileSpec | TriangularThreadProfileSpec;
2905
2895
 
2906
- /**
2907
- * Creates an immutable translation transform.
2908
- *
2909
- * @param offset - Finite XYZ translation in model units.
2910
- * @returns A frozen row-major transform.
2911
- */
2912
- export declare function translationTransform3(offset: Vec3): Transform3;
2896
+ /** Whether compensation is being applied to an external or internal thread. */
2897
+ export declare type ThreadRole = "male" | "female";
2913
2898
 
2914
- /** Trapezoidal thread profile with a configurable included angle. */
2915
- export declare interface TrapezoidalThreadProfileSpec extends ThreadProfileBaseSpec {
2916
- /** Selects the trapezoidal profile family. */
2917
- readonly kind: "trapezoidal";
2918
- /**
2919
- * Radial depth in millimetres.
2920
- * @defaultValue `pitch / 2`
2921
- */
2922
- readonly depth?: number;
2923
- /**
2924
- * Included flank angle in degrees. Use `90` for printable 45-degree slopes.
2925
- * @defaultValue `30`
2926
- */
2927
- readonly threadAngle?: number;
2928
- }
2899
+ /**
2900
+ * Dimensions and independent ring/profile tessellation for a torus around the Z axis.
2901
+ */
2902
+ export declare interface TorusOptions extends PrimitivePlacement {
2903
+ /** Explicit sampling ceilings, bounded by the host policy. */
2904
+ readonly limits?: Partial<GeometrySamplingLimits>;
2905
+ /** Radius from the Z axis to the profile center, in millimetres; greater than `minorRadius`. */
2906
+ readonly majorRadius: number;
2907
+ /** Exact segment count around the Z axis; omitted uses adaptive resolution. */
2908
+ readonly majorSegments?: number;
2909
+ /** Radius of the swept circular profile in millimetres. */
2910
+ readonly minorRadius: number;
2911
+ /** Exact segment count around the swept profile; omitted uses adaptive resolution. */
2912
+ readonly minorSegments?: number;
2913
+ /** Operation-level physical tessellation policy over the active model-wide policy. */
2914
+ readonly resolution?: GeometryResolution;
2915
+ }
2929
2916
 
2930
- /**
2931
- * A topology-preserving indexed triangle mesh with XYZ vertex positions.
2932
- */
2933
- export declare interface TriangleMesh {
2934
- /** Three unsigned vertex indices per triangle. */
2935
- readonly indices: Uint32Array;
2936
- /** Flat XYZ coordinates, three finite values per vertex. */
2937
- readonly positions: Float32Array;
2938
- }
2917
+ /**
2918
+ * A row-major affine 4x4 matrix applied to column vectors.
2919
+ *
2920
+ * Translation occupies indices 3, 7, and 11. The final row must be
2921
+ * `[0, 0, 0, 1]` within the active geometry tolerance.
2922
+ */
2923
+ export declare type Transform3 = readonly [
2924
+ m00: number,
2925
+ m01: number,
2926
+ m02: number,
2927
+ m03: number,
2928
+ m10: number,
2929
+ m11: number,
2930
+ m12: number,
2931
+ m13: number,
2932
+ m20: number,
2933
+ m21: number,
2934
+ m22: number,
2935
+ m23: number,
2936
+ m30: number,
2937
+ m31: number,
2938
+ m32: number,
2939
+ m33: number
2940
+ ];
2939
2941
 
2940
- /**
2941
- * Measurements and optional edge-connected topology from one validated mesh traversal.
2942
- */
2943
- export declare interface TriangleMeshAnalysis extends TriangleMeshMeasurements {
2944
- /** Number of referenced edge-connected components when `includeTopology` is requested. */
2945
- readonly connectedComponentCount?: number;
2946
- /** Number of distinct indexed undirected edges when `includeTopology` is requested. */
2947
- readonly edgeCount?: number;
2948
- }
2942
+ /**
2943
+ * Returns the determinant of a transform's linear 3x3 component.
2944
+ *
2945
+ * A negative result identifies a reflection; zero is rejected as singular.
2946
+ *
2947
+ * @param transform - Valid affine transform.
2948
+ * @returns Signed linear determinant.
2949
+ */
2950
+ export declare function transformDeterminant3(transform: Transform3): number;
2949
2951
 
2950
- /**
2951
- * Validation and optional connectivity controls for a shared mesh analysis.
2952
- */
2953
- export declare interface TriangleMeshAnalysisOptions extends TriangleMeshValidationOptions {
2954
- /** Compute indexed edge/component counts and reject unreferenced vertices; defaults to false. */
2955
- readonly includeTopology?: boolean;
2956
- }
2952
+ /**
2953
+ * Transforms a closed loop and preserves its original winding convention.
2954
+ *
2955
+ * Reflections reverse the point order automatically through normalization.
2956
+ */
2957
+ export declare function transformLoop2(loop: Loop2, transform: Transform3, tolerance?: GeometryToleranceOptions): Loop2;
2957
2958
 
2958
- /**
2959
- * Geometric measurements derived from a validated, non-empty triangle mesh.
2960
- */
2961
- export declare interface TriangleMeshMeasurements {
2962
- /** Axis-aligned bounds. */
2963
- readonly bounds: MeshBounds;
2964
- /** Signed enclosed volume; positive values correspond to outward winding. */
2965
- readonly signedVolume: number;
2966
- /** Sum of all triangle areas in squared model units. */
2967
- readonly surfaceArea: number;
2968
- /** Number of indexed triangles. */
2969
- readonly triangleCount: number;
2970
- /** Number of distinct entries in the position buffer. */
2971
- readonly vertexCount: number;
2972
- }
2959
+ /** Applies an XY-plane-preserving affine transform to a 2D path. */
2960
+ export declare function transformPath2(path: Path2, transform: Transform3, tolerance?: GeometryToleranceOptions): Path2;
2973
2961
 
2974
- /** Options controlling bounded triangle-mesh quality analysis. */
2975
- export declare interface TriangleMeshQualityOptions {
2976
- /** Maximum number of triangles inspected. Defaults to `200000`. */
2977
- readonly maximumTriangleCount?: number;
2978
- /** Numeric comparison overrides; model coordinates are interpreted in their existing units. */
2979
- readonly tolerance?: GeometryToleranceOptions;
2980
- }
2962
+ /** Applies an affine transform to a 3D path without mutating its points. */
2963
+ export declare function transformPath3(path: Path3, transform: Transform3): Path3;
2981
2964
 
2982
- /** Structural, topological, and planar-patch measurements for one indexed triangle mesh. */
2983
- export declare interface TriangleMeshQualityReport {
2984
- /** Number of duplicate triangles beyond their first unordered occurrence. */
2985
- readonly duplicateTriangleCount: number;
2986
- /** Number of two-face edges whose incident triangles use the same direction. */
2987
- readonly inconsistentWindingEdgeCount: number;
2988
- /** Whether the mesh has valid faces and exactly two oppositely wound faces at every edge. */
2989
- readonly isClosedOrientedManifold: boolean;
2990
- /** Largest normalized triangle aspect ratio; an equilateral triangle has ratio `1`. */
2991
- readonly maximumTriangleAspectRatio: number;
2992
- /** Largest number of triangles incident to one indexed vertex. */
2993
- readonly maximumVertexTriangleIncidence: number;
2994
- /** Largest number of distinct neighbours connected to one indexed vertex. */
2995
- readonly maximumVertexValence: number;
2996
- /** Smallest interior triangle angle in degrees. */
2997
- readonly minimumTriangleAngleDegrees: number;
2998
- /** Number of triangles at or below the scale-aware zero-area threshold. */
2999
- readonly nearZeroAreaTriangleCount: number;
3000
- /** Number of edges with more than two incident triangles. */
3001
- readonly nonManifoldEdgeCount: number;
3002
- /** Number of edges with exactly one incident triangle. */
3003
- readonly openEdgeCount: number;
3004
- /** Edge-connected coplanar patches in deterministic first-triangle order. */
3005
- readonly planarPatches: readonly PlanarPatchQuality[];
3006
- /** Signed enclosed volume in cubic model units; positive values indicate outward winding. */
3007
- readonly signedVolume: number;
3008
- /** Total triangle area in squared model units. */
3009
- readonly surfaceArea: number;
3010
- /** Number of indexed triangles. */
3011
- readonly triangleCount: number;
3012
- /** Number of entries in the position buffer. */
3013
- readonly vertexCount: number;
3014
- }
2965
+ /** Transforms an explicit outer/hole region with reflection-safe winding correction. */
2966
+ export declare function transformRegion2(region: Region2, transform: Transform3, tolerance?: GeometryToleranceOptions): Region2;
3015
2967
 
3016
- /** Immutable deterministic measurements for a closed, oriented triangle mesh. */
3017
- export declare interface TriangleMeshSignature {
3018
- /** Axis-aligned bounds quantized by `tolerances.position`. */
3019
- readonly bounds: MeshBounds;
3020
- /** Number of edge-connected closed components. */
3021
- readonly connectedComponentCount: number;
3022
- /** Total orientable genus across all connected components. */
3023
- readonly genus: number;
3024
- /** Order-independent hash of quantized vertices and oriented triangles. */
3025
- readonly fingerprint: string;
3026
- /** Signed enclosed volume quantized by `tolerances.signedVolume`. */
3027
- readonly signedVolume: number;
3028
- /** Quantization used to make the signature stable across insignificant numeric drift. */
3029
- readonly tolerances: TriangleMeshSignatureTolerances;
3030
- /** Number of indexed triangles. */
3031
- readonly triangleCount: number;
3032
- /** Number of referenced position-buffer vertices. */
3033
- readonly vertexCount: number;
3034
- }
2968
+ /**
2969
+ * Applies an affine transform to a mesh and preserves outward face orientation.
2970
+ *
2971
+ * A transform with a negative linear determinant reflects space, so this helper
2972
+ * automatically reverses every triangle. Singular transforms are rejected.
2973
+ *
2974
+ * @param mesh - Mesh to transform without mutation.
2975
+ * @param transform - Row-major affine transform.
2976
+ * @returns A mesh with fresh transformed positions and copied or reversed indices.
2977
+ */
2978
+ export declare function transformTriangleMesh(mesh: TriangleMesh, transform: Transform3): TriangleMesh;
3035
2979
 
3036
- /** Options controlling deterministic triangle-mesh regression signatures. */
3037
- export declare interface TriangleMeshSignatureOptions {
3038
- /** Maximum accepted triangle count. Defaults to 200,000. */
3039
- readonly maximumTriangleCount?: number;
3040
- /** Position and bounds quantization in model units. Defaults to `1e-5`. */
3041
- readonly positionTolerance?: number;
3042
- /** Signed-volume quantization in cubic model units. Defaults to `1e-4`. */
3043
- readonly volumeTolerance?: number;
3044
- }
2980
+ /**
2981
+ * Creates an immutable translation transform.
2982
+ *
2983
+ * @param offset - Finite XYZ translation in model units.
2984
+ * @returns A frozen row-major transform.
2985
+ */
2986
+ export declare function translationTransform3(offset: Vec3): Transform3;
2987
+
2988
+ /** Trapezoidal thread profile with a configurable included angle. */
2989
+ export declare interface TrapezoidalThreadProfileSpec extends ThreadProfileBaseSpec {
2990
+ /** Selects the trapezoidal profile family. */
2991
+ readonly kind: "trapezoidal";
2992
+ /**
2993
+ * Radial depth in millimetres.
2994
+ * @defaultValue `pitch / 2`
2995
+ */
2996
+ readonly depth?: number;
2997
+ /**
2998
+ * Included flank angle in degrees. Use `90` for printable 45-degree slopes.
2999
+ * @defaultValue `30`
3000
+ */
3001
+ readonly threadAngle?: number;
3002
+ }
3045
3003
 
3046
- /** Absolute tolerances recorded in a triangle-mesh regression signature. */
3047
- export declare interface TriangleMeshSignatureTolerances {
3048
- /** Position and bounds quantization in model units. */
3049
- readonly position: number;
3050
- /** Signed-volume quantization in cubic model units. */
3051
- readonly signedVolume: number;
3052
- }
3004
+ /**
3005
+ * A topology-preserving indexed triangle mesh with XYZ vertex positions.
3006
+ */
3007
+ export declare interface TriangleMesh {
3008
+ /** Three unsigned vertex indices per triangle. */
3009
+ readonly indices: Uint32Array;
3010
+ /** Flat XYZ coordinates, three finite values per vertex. */
3011
+ readonly positions: Float32Array;
3012
+ }
3053
3013
 
3054
- /** Options controlling structural and manufacturing validation of a mesh. */
3055
- export declare interface TriangleMeshValidationOptions {
3056
- /** Permit an empty position and index buffer. Defaults to `false`. */
3057
- readonly allowEmpty?: boolean;
3058
- /** Require two oppositely wound faces per edge; geometric self-intersections are not detected. */
3059
- readonly requireClosed?: boolean;
3060
- /** Numeric comparison overrides used for zero-area triangle detection. */
3061
- readonly tolerance?: GeometryToleranceOptions;
3062
- }
3014
+ /**
3015
+ * Measurements and optional edge-connected topology from one validated mesh traversal.
3016
+ */
3017
+ export declare interface TriangleMeshAnalysis extends TriangleMeshMeasurements {
3018
+ /** Number of referenced edge-connected components when `includeTopology` is requested. */
3019
+ readonly connectedComponentCount?: number;
3020
+ /** Number of distinct indexed undirected edges when `includeTopology` is requested. */
3021
+ readonly edgeCount?: number;
3022
+ }
3063
3023
 
3064
- /**
3065
- * ISO/UTS-like 60-degree truncated triangular profile.
3066
- */
3067
- export declare interface TriangularThreadProfileSpec extends ThreadProfileBaseSpec {
3068
- /** Selects the 60-degree triangular profile family. */
3069
- readonly kind: "triangular";
3070
- /**
3071
- * Crest width divided by pitch.
3072
- * @defaultValue `1 / 8`
3073
- */
3074
- readonly crestFlatRatio?: number;
3075
- /**
3076
- * Root width divided by pitch.
3077
- * @defaultValue `1 / 4`
3078
- */
3079
- readonly rootFlatRatio?: number;
3080
- }
3024
+ /**
3025
+ * Validation and optional connectivity controls for a shared mesh analysis.
3026
+ */
3027
+ export declare interface TriangleMeshAnalysisOptions extends TriangleMeshValidationOptions {
3028
+ /** Compute indexed edge/component counts and reject unreferenced vertices; defaults to false. */
3029
+ readonly includeTopology?: boolean;
3030
+ }
3081
3031
 
3082
- /** Ear-clips one normalized simple CCW loop into stable local vertex indices. */
3083
- export declare function triangulateLoop2(loop: Loop2): Uint32Array;
3032
+ /**
3033
+ * Geometric measurements derived from a validated, non-empty triangle mesh.
3034
+ */
3035
+ export declare interface TriangleMeshMeasurements {
3036
+ /** Axis-aligned bounds. */
3037
+ readonly bounds: MeshBounds;
3038
+ /** Signed enclosed volume; positive values correspond to outward winding. */
3039
+ readonly signedVolume: number;
3040
+ /** Sum of all triangle areas in squared model units. */
3041
+ readonly surfaceArea: number;
3042
+ /** Number of indexed triangles. */
3043
+ readonly triangleCount: number;
3044
+ /** Number of distinct entries in the position buffer. */
3045
+ readonly vertexCount: number;
3046
+ }
3047
+
3048
+ /** Options controlling bounded triangle-mesh quality analysis. */
3049
+ export declare interface TriangleMeshQualityOptions {
3050
+ /** Maximum number of triangles inspected. Defaults to `200000`. */
3051
+ readonly maximumTriangleCount?: number;
3052
+ /** Numeric comparison overrides; model coordinates are interpreted in their existing units. */
3053
+ readonly tolerance?: GeometryToleranceOptions;
3054
+ }
3055
+
3056
+ /** Structural, topological, and planar-patch measurements for one indexed triangle mesh. */
3057
+ export declare interface TriangleMeshQualityReport {
3058
+ /** Number of duplicate triangles beyond their first unordered occurrence. */
3059
+ readonly duplicateTriangleCount: number;
3060
+ /** Number of two-face edges whose incident triangles use the same direction. */
3061
+ readonly inconsistentWindingEdgeCount: number;
3062
+ /** Whether the mesh has valid faces and exactly two oppositely wound faces at every edge. */
3063
+ readonly isClosedOrientedManifold: boolean;
3064
+ /** Largest normalized triangle aspect ratio; an equilateral triangle has ratio `1`. */
3065
+ readonly maximumTriangleAspectRatio: number;
3066
+ /** Largest number of triangles incident to one indexed vertex. */
3067
+ readonly maximumVertexTriangleIncidence: number;
3068
+ /** Largest number of distinct neighbours connected to one indexed vertex. */
3069
+ readonly maximumVertexValence: number;
3070
+ /** Smallest interior triangle angle in degrees. */
3071
+ readonly minimumTriangleAngleDegrees: number;
3072
+ /** Number of triangles at or below the scale-aware zero-area threshold. */
3073
+ readonly nearZeroAreaTriangleCount: number;
3074
+ /** Number of edges with more than two incident triangles. */
3075
+ readonly nonManifoldEdgeCount: number;
3076
+ /** Number of edges with exactly one incident triangle. */
3077
+ readonly openEdgeCount: number;
3078
+ /** Edge-connected coplanar patches in deterministic first-triangle order. */
3079
+ readonly planarPatches: readonly PlanarPatchQuality[];
3080
+ /** Signed enclosed volume in cubic model units; positive values indicate outward winding. */
3081
+ readonly signedVolume: number;
3082
+ /** Total triangle area in squared model units. */
3083
+ readonly surfaceArea: number;
3084
+ /** Number of indexed triangles. */
3085
+ readonly triangleCount: number;
3086
+ /** Number of entries in the position buffer. */
3087
+ readonly vertexCount: number;
3088
+ }
3089
+
3090
+ /** Immutable deterministic measurements for a closed, oriented triangle mesh. */
3091
+ export declare interface TriangleMeshSignature {
3092
+ /** Axis-aligned bounds quantized by `tolerances.position`. */
3093
+ readonly bounds: MeshBounds;
3094
+ /** Number of edge-connected closed components. */
3095
+ readonly connectedComponentCount: number;
3096
+ /** Total orientable genus across all connected components. */
3097
+ readonly genus: number;
3098
+ /** Order-independent hash of quantized vertices and oriented triangles. */
3099
+ readonly fingerprint: string;
3100
+ /** Signed enclosed volume quantized by `tolerances.signedVolume`. */
3101
+ readonly signedVolume: number;
3102
+ /** Quantization used to make the signature stable across insignificant numeric drift. */
3103
+ readonly tolerances: TriangleMeshSignatureTolerances;
3104
+ /** Number of indexed triangles. */
3105
+ readonly triangleCount: number;
3106
+ /** Number of referenced position-buffer vertices. */
3107
+ readonly vertexCount: number;
3108
+ }
3109
+
3110
+ /** Options controlling deterministic triangle-mesh regression signatures. */
3111
+ export declare interface TriangleMeshSignatureOptions {
3112
+ /** Maximum accepted triangle count. Defaults to 200,000. */
3113
+ readonly maximumTriangleCount?: number;
3114
+ /** Position and bounds quantization in model units. Defaults to `1e-5`. */
3115
+ readonly positionTolerance?: number;
3116
+ /** Signed-volume quantization in cubic model units. Defaults to `1e-4`. */
3117
+ readonly volumeTolerance?: number;
3118
+ }
3119
+
3120
+ /** Absolute tolerances recorded in a triangle-mesh regression signature. */
3121
+ export declare interface TriangleMeshSignatureTolerances {
3122
+ /** Position and bounds quantization in model units. */
3123
+ readonly position: number;
3124
+ /** Signed-volume quantization in cubic model units. */
3125
+ readonly signedVolume: number;
3126
+ }
3127
+
3128
+ /** Options controlling structural and manufacturing validation of a mesh. */
3129
+ export declare interface TriangleMeshValidationOptions {
3130
+ /** Permit an empty position and index buffer. Defaults to `false`. */
3131
+ readonly allowEmpty?: boolean;
3132
+ /** Require two oppositely wound faces per edge; geometric self-intersections are not detected. */
3133
+ readonly requireClosed?: boolean;
3134
+ /** Numeric comparison overrides used for zero-area triangle detection. */
3135
+ readonly tolerance?: GeometryToleranceOptions;
3136
+ }
3084
3137
 
3085
- /**
3086
- * Dimensions, placement, and tessellation for a hollow Z-axis tube.
3087
- */
3088
- export declare interface TubeOptions extends CircularPrimitiveOptions, PrimitivePlacement {
3089
- /**
3090
- * Centers the tube on the Z origin when `true`; otherwise its bottom is at `Z = 0`.
3091
- * @defaultValue `true`
3092
- */
3093
- readonly center?: boolean;
3094
- /** Total height along Z in millimetres. */
3095
- readonly height: number;
3096
- /** Positive inner radius in millimetres. */
3097
- readonly innerRadius: number;
3098
- /** Outer radius in millimetres; greater than {@link TubeOptions.innerRadius}. */
3099
- readonly outerRadius: number;
3100
- }
3138
+ /**
3139
+ * ISO/UTS-like 60-degree truncated triangular profile.
3140
+ */
3141
+ export declare interface TriangularThreadProfileSpec extends ThreadProfileBaseSpec {
3142
+ /** Selects the 60-degree triangular profile family. */
3143
+ readonly kind: "triangular";
3144
+ /**
3145
+ * Crest width divided by pitch.
3146
+ * @defaultValue `1 / 8`
3147
+ */
3148
+ readonly crestFlatRatio?: number;
3149
+ /**
3150
+ * Root width divided by pitch.
3151
+ * @defaultValue `1 / 4`
3152
+ */
3153
+ readonly rootFlatRatio?: number;
3154
+ }
3101
3155
 
3102
- /**
3103
- * Checks closed indexed topology, triangle intersections, and alternating nested shell orientation.
3104
- * Outward exterior shells and inward cavity shells are accepted. Separate shells must not touch,
3105
- * intersect, or overlap as material. Indexed neighbours may share their own vertex or edge.
3106
- *
3107
- * Uses bounded floating-point tests, not exact predicates or repair. Contacts within the selected
3108
- * tolerance reject conservatively. At most 200,000 triangles and 2,000,000 spatial/containment tests
3109
- * are supported; exhausting a ceiling throws COMPLEXITY_LIMIT rather than claiming validity.
3110
- * Input buffers are freshly inspected and never modified; units are millimetres.
3111
- *
3112
- * @param mesh - Closed triangle mesh to inspect.
3113
- * @param options - Optional lower work ceiling and numeric comparison policy.
3114
- * @returns The original mesh after every requested check succeeds.
3115
- */
3116
- export declare function validateSolidMesh(mesh: TriangleMesh, options?: SolidMeshValidationOptions): TriangleMesh;
3156
+ /** Ear-clips one normalized simple CCW loop into stable local vertex indices. */
3157
+ export declare function triangulateLoop2(loop: Loop2): Uint32Array;
3117
3158
 
3118
- /**
3119
- * Validates that a transform is finite, affine, and non-singular.
3120
- *
3121
- * @param transform - Row-major matrix to validate.
3122
- * @param tolerance - Optional comparison overrides.
3123
- * @returns The original transform after successful validation.
3124
- * @throws {@link GeometryError} For non-finite, non-affine, or singular matrices.
3125
- */
3126
- export declare function validateTransform3(transform: Transform3, tolerance?: GeometryToleranceOptions): Transform3;
3159
+ /**
3160
+ * Dimensions, placement, and tessellation for a hollow Z-axis tube.
3161
+ */
3162
+ export declare interface TubeOptions extends CircularPrimitiveOptions, PrimitivePlacement {
3163
+ /**
3164
+ * Centers the tube on the Z origin when `true`; otherwise its bottom is at `Z = 0`.
3165
+ * @defaultValue `true`
3166
+ */
3167
+ readonly center?: boolean;
3168
+ /** Total height along Z in millimetres. */
3169
+ readonly height: number;
3170
+ /** Positive inner radius in millimetres. */
3171
+ readonly innerRadius: number;
3172
+ /** Outer radius in millimetres; greater than {@link TubeOptions.innerRadius}. */
3173
+ readonly outerRadius: number;
3174
+ }
3127
3175
 
3128
3176
  /**
3129
- * Validates mesh buffers, indices, triangle area, and optionally closed topology.
3177
+ * Checks closed indexed topology, triangle intersections, and alternating nested shell orientation.
3178
+ * Outward exterior shells and inward cavity shells are accepted. Separate shells must not touch,
3179
+ * intersect, or overlap as material. Indexed neighbours may share their own vertex or edge.
3130
3180
  *
3131
- * Closed validation requires each edge to occur exactly twice with opposite
3132
- * directions, rejecting boundary and non-manifold edges. Validation does not
3133
- * mutate or copy the mesh. This establishes edge connectivity, not the absence
3134
- * of geometric self-intersections between faces.
3181
+ * Uses bounded floating-point tests, not exact predicates or repair. Contacts within the selected
3182
+ * tolerance reject conservatively. At most 200,000 triangles and 2,000,000 spatial/containment tests
3183
+ * are supported; exhausting a ceiling throws COMPLEXITY_LIMIT rather than claiming validity.
3184
+ * Input buffers are freshly inspected and never modified; units are millimetres.
3185
+ *
3186
+ * @param mesh - Closed triangle mesh to inspect.
3187
+ * @param options - Optional lower work ceiling and numeric comparison policy.
3188
+ * @returns The original mesh after every requested check succeeds.
3189
+ */
3190
+ export declare function validateSolidMesh(mesh: TriangleMesh, options?: SolidMeshValidationOptions): TriangleMesh;
3191
+
3192
+ /**
3193
+ * Validates that a transform is finite, affine, and non-singular.
3135
3194
  *
3136
- * @param mesh - Mesh to inspect.
3137
- * @param options - Empty-mesh, topology, and tolerance policy.
3138
- * @returns The original mesh after successful validation.
3139
- * @throws {@link GeometryError} When any requested invariant fails.
3195
+ * @param transform - Row-major matrix to validate.
3196
+ * @param tolerance - Optional comparison overrides.
3197
+ * @returns The original transform after successful validation.
3198
+ * @throws {@link GeometryError} For non-finite, non-affine, or singular matrices.
3140
3199
  */
3141
- export declare function validateTriangleMesh(mesh: TriangleMesh, options?: TriangleMeshValidationOptions): TriangleMesh;
3142
-
3143
- /** A two-dimensional Cartesian vector or point. */
3144
- export declare type Vec2 = readonly [x: number, y: number];
3145
-
3146
- /** A three-dimensional Cartesian vector or point. */
3147
- export declare type Vec3 = readonly [x: number, y: number, z: number];
3148
-
3149
- /** A circular baseline centered at the XY origin, with rigid shaped glyph groups. */
3150
- export declare interface VectorTextArcBaseline {
3151
- /** Selects a circular baseline; glyph outlines rotate without bending or stretching. */
3152
- readonly kind: "arc";
3153
- /** Baseline radius in millimetres, greater than zero and at most 10000. */
3154
- readonly radius: number;
3155
- /** Alignment datum in degrees counterclockwise from +X; defaults to 90. */
3156
- readonly centerAngleDegrees?: number;
3157
- /** Reading direction around the circle; defaults to clockwise. */
3158
- readonly direction?: "clockwise" | "counterclockwise";
3159
- }
3160
-
3161
- /** Exact curve bounds in millimetres; positive Y points upward. */
3162
- export declare interface VectorTextBounds {
3163
- /** Minimum X and Y of visible outlines, including accents, descenders, and overhangs. */
3164
- readonly min: readonly [number, number];
3165
- /** Maximum X and Y of visible outlines. */
3166
- readonly max: readonly [number, number];
3167
- }
3200
+ export declare function validateTransform3(transform: Transform3, tolerance?: GeometryToleranceOptions): Transform3;
3168
3201
 
3169
3202
  /**
3170
- * Immutable vector layout with no browser, font parser, or kernel ownership.
3171
- */
3172
- export declare interface VectorTextLayout {
3173
- /** Nonzero-filled path data in millimetres, positive Y upward; empty for text with no ink. */
3174
- readonly paths: readonly string[];
3175
- /** Exact measurements of these paths and their logical text layout. */
3176
- readonly metrics: VectorTextMetrics;
3177
- }
3203
+ * Validates mesh buffers, indices, triangle area, and optionally closed topology.
3204
+ *
3205
+ * Closed validation requires each edge to occur exactly twice with opposite
3206
+ * directions, rejecting boundary and non-manifold edges. Validation does not
3207
+ * mutate or copy the mesh. This establishes edge connectivity, not the absence
3208
+ * of geometric self-intersections between faces.
3209
+ *
3210
+ * @param mesh - Mesh to inspect.
3211
+ * @param options - Empty-mesh, topology, and tolerance policy.
3212
+ * @returns The original mesh after successful validation.
3213
+ * @throws {@link GeometryError} When any requested invariant fails.
3214
+ */
3215
+ export declare function validateTriangleMesh(mesh: TriangleMesh, options?: TriangleMeshValidationOptions): TriangleMesh;
3216
+
3217
+ /** A two-dimensional Cartesian vector or point. */
3218
+ export declare type Vec2 = readonly [x: number, y: number];
3219
+
3220
+ /** A three-dimensional Cartesian vector or point. */
3221
+ export declare type Vec3 = readonly [x: number, y: number, z: number];
3222
+
3223
+ /** A circular baseline centered at the XY origin, with rigid shaped glyph groups. */
3224
+ export declare interface VectorTextArcBaseline {
3225
+ /** Selects a circular baseline; glyph outlines rotate without bending or stretching. */
3226
+ readonly kind: "arc";
3227
+ /** Baseline radius in millimetres, greater than zero and at most 10000. */
3228
+ readonly radius: number;
3229
+ /** Alignment datum in degrees counterclockwise from +X; defaults to 90. */
3230
+ readonly centerAngleDegrees?: number;
3231
+ /** Reading direction around the circle; defaults to clockwise. */
3232
+ readonly direction?: "clockwise" | "counterclockwise";
3233
+ }
3234
+
3235
+ /** Exact curve bounds in millimetres; positive Y points upward. */
3236
+ export declare interface VectorTextBounds {
3237
+ /** Minimum X and Y of visible outlines, including accents, descenders, and overhangs. */
3238
+ readonly min: readonly [number, number];
3239
+ /** Maximum X and Y of visible outlines. */
3240
+ readonly max: readonly [number, number];
3241
+ }
3178
3242
 
3179
- /**
3180
- * Text bounded to 512 UTF-16 units: horizontal lines or one circular line without wrapping.
3181
- */
3182
- export declare interface VectorTextLayoutOptions extends VectorTextOptions {
3183
- /** Place the advance's start, midpoint or end at the datum; defaults to center on arcs, otherwise left. */
3184
- readonly align?: "left" | "center" | "right";
3185
- /** Omitted uses horizontal lines. Arcs require one line and baseline vertical alignment. */
3186
- readonly baseline?: VectorTextArcBaseline;
3187
- /** Baseline spacing in ems, 0.5–5; omitted uses the selected face's natural vertical metrics. */
3188
- readonly lineHeight?: number;
3189
- /** Place the first baseline or complete ink bounds at Y=0; arcs only accept baseline. */
3190
- readonly verticalAlign?: "baseline" | "top" | "center" | "bottom";
3191
- }
3192
-
3193
- /** Text measurements from the same immutable layout that supplies geometry and SVG outlines. */
3194
- export declare interface VectorTextMetrics {
3195
- /** Visible curve bounds after alignment, or null when the text has no ink. */
3196
- readonly bounds: VectorTextBounds | null;
3197
- /** Unaligned logical advance and negative baseline displacement in mm; arcs retain [arc length, 0]. */
3198
- readonly advance: readonly [number, number];
3199
- /** Maximum logical line advance in millimetres, including spaces; arc length on circular baselines. */
3200
- readonly logicalWidth: number;
3201
- /** Selected font's ascender distance above a baseline in millimetres, independent of the text. */
3202
- readonly ascent: number;
3203
- /** Selected font's descender distance below a baseline in millimetres, a non-negative value. */
3204
- readonly descent: number;
3205
- /** Actual distance between baselines in millimetres. */
3206
- readonly lineHeight: number;
3207
- /** Number of lines, including empty and trailing lines; empty text occupies one line. */
3208
- readonly lineCount: number;
3209
- }
3210
-
3211
- /** Shaping controls for a prepared exact font face; all lengths are in millimetres. */
3212
- export declare interface VectorTextOptions {
3213
- /** Em size in millimetres, greater than zero and at most 10000; not the visible glyph height. */
3214
- readonly fontSize: number;
3215
- /** Actual static or variable weight, 1–1000; defaults to the prepared face's static weight. */
3216
- readonly fontWeight?: number;
3217
- /** Tracking between glyph clusters in millimetres, -100–100; defaults to zero. */
3218
- readonly letterSpacing?: number;
3219
- }
3220
-
3221
- export { }
3243
+ /**
3244
+ * Immutable vector layout with no browser, font parser, or kernel ownership.
3245
+ */
3246
+ export declare interface VectorTextLayout {
3247
+ /** Nonzero-filled path data in millimetres, positive Y upward; empty for text with no ink. */
3248
+ readonly paths: readonly string[];
3249
+ /** Exact measurements of these paths and their logical text layout. */
3250
+ readonly metrics: VectorTextMetrics;
3251
+ }
3252
+
3253
+ /**
3254
+ * Text bounded to 512 UTF-16 units: horizontal lines or one circular line without wrapping.
3255
+ */
3256
+ export declare interface VectorTextLayoutOptions extends VectorTextOptions {
3257
+ /** Place the advance's start, midpoint or end at the datum; defaults to center on arcs, otherwise left. */
3258
+ readonly align?: "left" | "center" | "right";
3259
+ /** Omitted uses horizontal lines. Arcs require one line and baseline vertical alignment. */
3260
+ readonly baseline?: VectorTextArcBaseline;
3261
+ /** Baseline spacing in ems, 0.5–5; omitted uses the selected face's natural vertical metrics. */
3262
+ readonly lineHeight?: number;
3263
+ /** Place the first baseline or complete ink bounds at Y=0; arcs only accept baseline. */
3264
+ readonly verticalAlign?: "baseline" | "top" | "center" | "bottom";
3265
+ }
3266
+
3267
+ /** Text measurements from the same immutable layout that supplies geometry and SVG outlines. */
3268
+ export declare interface VectorTextMetrics {
3269
+ /** Visible curve bounds after alignment, or null when the text has no ink. */
3270
+ readonly bounds: VectorTextBounds | null;
3271
+ /** Unaligned logical advance and negative baseline displacement in mm; arcs retain [arc length, 0]. */
3272
+ readonly advance: readonly [number, number];
3273
+ /** Maximum logical line advance in millimetres, including spaces; arc length on circular baselines. */
3274
+ readonly logicalWidth: number;
3275
+ /** Selected font's ascender distance above a baseline in millimetres, independent of the text. */
3276
+ readonly ascent: number;
3277
+ /** Selected font's descender distance below a baseline in millimetres, a non-negative value. */
3278
+ readonly descent: number;
3279
+ /** Actual distance between baselines in millimetres. */
3280
+ readonly lineHeight: number;
3281
+ /** Number of lines, including empty and trailing lines; empty text occupies one line. */
3282
+ readonly lineCount: number;
3283
+ }
3284
+
3285
+ /** Shaping controls for a prepared exact font face; all lengths are in millimetres. */
3286
+ export declare interface VectorTextOptions {
3287
+ /** Em size in millimetres, greater than zero and at most 10000; not the visible glyph height. */
3288
+ readonly fontSize: number;
3289
+ /** Actual static or variable weight, 1–1000; defaults to the prepared face's static weight. */
3290
+ readonly fontWeight?: number;
3291
+ /** Tracking between glyph clusters in millimetres, -100–100; defaults to zero. */
3292
+ readonly letterSpacing?: number;
3293
+ }
3294
+
3295
+ export { }