@snaptrude/plugin-core 0.0.0-dev-20260907135026 → 0.0.0-dev-20260911064951

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/api-manifest.json +12 -151
  3. package/dist/api/core/geom/create/index.d.ts +86 -559
  4. package/dist/api/core/geom/create/index.d.ts.map +1 -1
  5. package/dist/api/core/geom/query/brep.d.ts +0 -50
  6. package/dist/api/core/geom/query/brep.d.ts.map +1 -1
  7. package/dist/api/core/geom/query/curve.d.ts +35 -58
  8. package/dist/api/core/geom/query/curve.d.ts.map +1 -1
  9. package/dist/api/core/geom/query/edge.d.ts +2 -2
  10. package/dist/api/core/geom/query/face.d.ts +0 -45
  11. package/dist/api/core/geom/query/face.d.ts.map +1 -1
  12. package/dist/api/core/geom/update/curve.d.ts +5 -5
  13. package/dist/api/core/geom/update/profile.d.ts +1 -1
  14. package/dist/api/core/io/import/index.d.ts +3 -1
  15. package/dist/api/core/io/import/index.d.ts.map +1 -1
  16. package/dist/api/design/create/bulk-items.d.ts +185 -0
  17. package/dist/api/design/create/bulk-items.d.ts.map +1 -0
  18. package/dist/api/design/create/index.d.ts +310 -22
  19. package/dist/api/design/create/index.d.ts.map +1 -1
  20. package/dist/api/design/create/opening-fields.d.ts +37 -0
  21. package/dist/api/design/create/opening-fields.d.ts.map +1 -0
  22. package/dist/api/design/delete/index.d.ts +4 -0
  23. package/dist/api/design/delete/index.d.ts.map +1 -1
  24. package/dist/api/design/dimensions.d.ts +427 -0
  25. package/dist/api/design/dimensions.d.ts.map +1 -0
  26. package/dist/api/design/doors/index.d.ts +20 -13
  27. package/dist/api/design/doors/index.d.ts.map +1 -1
  28. package/dist/api/design/index.d.ts +5 -0
  29. package/dist/api/design/index.d.ts.map +1 -1
  30. package/dist/api/design/query/geometry/index.d.ts +1 -27
  31. package/dist/api/design/query/geometry/index.d.ts.map +1 -1
  32. package/dist/api/design/query/index.d.ts +0 -47
  33. package/dist/api/design/query/index.d.ts.map +1 -1
  34. package/dist/api/design/query/spaces.d.ts +5 -5
  35. package/dist/api/design/update/index.d.ts +0 -87
  36. package/dist/api/design/update/index.d.ts.map +1 -1
  37. package/dist/api/entity/referenceLine.d.ts +2 -2
  38. package/dist/api/entity/referenceLine.d.ts.map +1 -1
  39. package/dist/api/entity/space.d.ts +4 -5
  40. package/dist/api/entity/space.d.ts.map +1 -1
  41. package/dist/api/entity/story.d.ts +4 -4
  42. package/dist/api/presentation/annotate.d.ts +2 -2
  43. package/dist/api/presentation/shapes.d.ts +2 -2
  44. package/dist/api/program/spreadsheet.d.ts +4 -4
  45. package/dist/handles.d.ts +22 -12
  46. package/dist/handles.d.ts.map +1 -1
  47. package/dist/index.cjs +2867 -3040
  48. package/dist/index.cjs.map +1 -1
  49. package/dist/index.d.ts +0 -1
  50. package/dist/index.d.ts.map +1 -1
  51. package/dist/index.js +2844 -3006
  52. package/dist/index.js.map +1 -1
  53. package/package.json +1 -1
  54. package/src/api/core/geom/create/index.ts +84 -588
  55. package/src/api/core/geom/query/brep.ts +0 -51
  56. package/src/api/core/geom/query/curve.ts +2 -25
  57. package/src/api/core/geom/query/edge.ts +2 -2
  58. package/src/api/core/geom/query/face.ts +0 -49
  59. package/src/api/core/io/import/index.ts +11 -3
  60. package/src/api/design/create/bulk-items.ts +186 -0
  61. package/src/api/design/create/index.ts +335 -38
  62. package/src/api/design/create/opening-fields.ts +37 -0
  63. package/src/api/design/delete/index.ts +4 -0
  64. package/src/api/design/dimensions.ts +453 -0
  65. package/src/api/design/doors/index.ts +20 -13
  66. package/src/api/design/index.ts +5 -0
  67. package/src/api/design/query/geometry/index.ts +0 -29
  68. package/src/api/design/query/index.ts +0 -50
  69. package/src/api/design/update/index.ts +0 -94
  70. package/src/handles.ts +27 -15
  71. package/src/index.ts +0 -1
  72. package/dist/massParameters.d.ts +0 -319
  73. package/dist/massParameters.d.ts.map +0 -1
  74. package/src/massParameters.ts +0 -472
  75. package/test/massParameters.test.mjs +0 -500
@@ -1,17 +1,15 @@
1
1
  import * as z from "zod"
2
2
  import { PluginApiReturn } from "../../../../types"
3
- import { MAX_SPLINE_THROUGH_POINTS, MAX_SPLINE_POLES } from "../../../../massParameters"
4
- import { Vec3Handle, LineHandle, ArcHandle, SplineHandle, CircleHandle, CurveHandle, ProfileHandle, ContourHandle, BrepHandle, FaceHandle, EdgeHandle, Vec3Components } from "../../../../handles"
3
+ import { Vec3Handle, LineHandle, ArcHandle, CircleHandle, CurveHandle, ProfileHandle, ContourHandle, BrepHandle, FaceHandle, EdgeHandle, Vec3Components } from "../../../../handles"
5
4
 
6
5
  /**
7
6
  * Curve creation — construct new geometric curves from point handles (all-handle
8
7
  * model, §11).
9
8
  *
10
9
  * Each method takes point handles ({@linkcode Vec3Handle}) and returns an opaque
11
- * curve handle ({@linkcode LineHandle}, {@linkcode ArcHandle}, or
12
- * {@linkcode SplineHandle}) that you pass to query, update, or entity-creation
13
- * methods. Read geometry back as plain values via the
14
- * `snaptrude.core.geom.query.*` methods.
10
+ * curve handle ({@linkcode LineHandle} or {@linkcode ArcHandle}) that you pass to
11
+ * query, update, or entity-creation methods. Read geometry back as plain values
12
+ * via the `snaptrude.core.geom.query.*` methods.
15
13
  *
16
14
  * Accessed via `snaptrude.core.geom.create`.
17
15
  */
@@ -85,75 +83,6 @@ export abstract class PluginGeomCreateApi {
85
83
  radius: number,
86
84
  ): PluginApiReturn<CircleHandle>
87
85
 
88
- /**
89
- * Create an open NURBS curve passing exactly THROUGH each point, in order
90
- * (centripetal Catmull-Rom fit → clamped cubic B-spline; C1-smooth, no cusps
91
- * on uneven spacing). Host API call — returns a handle. The points are
92
- * interpolated, NOT control points. For a CLOSED smooth loop use
93
- * {@linkcode PluginGeomCreateApi.profileFromSplinePoints} — closed splines
94
- * exist only as profiles, never as a single curve handle.
95
- *
96
- * Pure host-side math — the geometry kernel is not loaded. The result is a
97
- * {@linkcode CurveHandle}: pass it to `profileFromCurves` alongside lines and
98
- * arcs, or read it back via `core.geom.query.curve.*`.
99
- *
100
- * @param points 3..256 ordered through-points; consecutive points must be distinct
101
- * @returns The new open curve as a {@linkcode SplineHandle}
102
- * @throws VALIDATION if fewer than 3 points (2 points are a straight line —
103
- * use {@linkcode PluginGeomCreateApi.line}), more than 256 points, or two
104
- * consecutive points coincide
105
- *
106
- * @examplePrompt Draw a smooth curve through these points
107
- * @examplePrompt Make a wavy edge that passes through A, B, C and D
108
- * @examplePrompt Freeform curved wall path through these clicks
109
- *
110
- * # Example
111
- * ```ts
112
- * const spline = await snaptrude.core.geom.create.splineFromPoints([p0, p1, p2, p3])
113
- * // Mixed profile: smooth top, straight closing base
114
- * const base = await snaptrude.core.geom.create.line(p3, p0)
115
- * const profile = await snaptrude.core.geom.create.profileFromCurves([spline, base])
116
- * ```
117
- */
118
- public abstract splineFromPoints(points: Vec3Handle[]): PluginApiReturn<SplineHandle>
119
-
120
- /**
121
- * Create an open NURBS curve DEFINED BY control points — the curve is pulled
122
- * TOWARD the interior points, not through them; it starts at the first point
123
- * and ends at the last. Knots are computed for you (clamped, uniform) —
124
- * there is no knot-vector argument. For a curve that must pass THROUGH given
125
- * points use {@linkcode PluginGeomCreateApi.splineFromPoints}.
126
- *
127
- * A curve made here records as `splinePoles` in a mass recipe and is
128
- * re-minted verbatim on edit — so an agent that read a `splinePoles` curve
129
- * back off a mass can move its poles and rebuild the mass with
130
- * `design.update.parameters`. Pure host-side math — the geometry kernel is
131
- * not loaded, and nothing is created in the scene.
132
- *
133
- * @param controlPoints 3..512 control points ({@linkcode Vec3Handle}s), in order
134
- * @param options.degree 2 or 3; default `min(3, controlPoints.length - 1)`
135
- * @returns The new open curve as a {@linkcode SplineHandle}
136
- * @throws VALIDATION when fewer than `degree + 1` points are given, two
137
- * consecutive points coincide, or `degree` is not 2 or 3
138
- *
139
- * @examplePrompt Draw a smooth curve controlled by these four points
140
- * @examplePrompt Rebuild this edge from its control polygon
141
- *
142
- * # Example
143
- * ```ts
144
- * const curve = await snaptrude.core.geom.create.splineFromControlPoints([p0, p1, p2, p3])
145
- * // Quadratic instead of the default cubic
146
- * const tighter = await snaptrude.core.geom.create.splineFromControlPoints(
147
- * [p0, p1, p2, p3],
148
- * { degree: 2 },
149
- * )
150
- * ```
151
- */
152
- public abstract splineFromControlPoints(
153
- controlPoints: Vec3Handle[],
154
- options?: { degree?: number },
155
- ): PluginApiReturn<SplineHandle>
156
-
157
86
  /**
158
87
  * Create a closed profile from an ordered list of point handles connected by
159
88
  * line segments (last auto-connected to first). Host API call — returns a handle.
@@ -187,39 +116,6 @@ export abstract class PluginGeomCreateApi {
187
116
  */
188
117
  public abstract profileFromCurves(curves: CurveHandle[]): PluginApiReturn<ProfileHandle>
189
118
 
190
- /**
191
- * Create a CLOSED smooth profile passing through each point, in order, with
192
- * the loop closed smoothly back from the last point to the first (do NOT
193
- * repeat the first point). Host API call — returns a handle. This is the
194
- * closed counterpart of {@linkcode PluginGeomCreateApi.splineFromPoints} and
195
- * the one-call route from points to an extrudable outline: wrap in
196
- * `contourFromProfile` and extrude/loft/sweep as usual.
197
- *
198
- * The whole loop is smooth — v1 takes no mixed straight/spline input. For a
199
- * profile that is part curve and part straight, build the pieces with
200
- * `splineFromPoints` + `line` and join them with
201
- * {@linkcode PluginGeomCreateApi.profileFromCurves}.
202
- *
203
- * @param points 3..256 ordered through-points of the loop (first point NOT repeated)
204
- * @returns The new closed profile as a {@linkcode ProfileHandle}
205
- * @throws VALIDATION if fewer than 3 points, more than 256 points,
206
- * consecutive points coincide (including last→first), or the loop
207
- * self-intersects
208
- *
209
- * @examplePrompt Make a blob-shaped floor plate through these points
210
- * @examplePrompt Organic curved outline through these corners
211
- * @examplePrompt Freeform podium profile
212
- *
213
- * # Example
214
- * ```ts
215
- * const profile = await snaptrude.core.geom.create.profileFromSplinePoints([p0, p1, p2, p3, p4])
216
- * const contour = await snaptrude.core.geom.create.contourFromProfile(profile)
217
- * const brep = await snaptrude.core.geom.create.brepFromExtrusion(contour, { x: 0, y: 1, z: 0 }, 3)
218
- * const podium = await snaptrude.design.create.massFromBrep(brep, "Podium")
219
- * ```
220
- */
221
- public abstract profileFromSplinePoints(points: Vec3Handle[]): PluginApiReturn<ProfileHandle>
222
-
223
119
  /**
224
120
  * Create an axis-aligned **rectangle** profile (XZ plane) of `width` × `depth`,
225
121
  * centred at `center` (defaults to the origin). Host API call — returns a handle.
@@ -393,9 +289,7 @@ export abstract class PluginGeomCreateApi {
393
289
  * bottom — sections are auto-matched)
394
290
  * @param intermediateContours Optional in-between cross-sections, ordered
395
291
  * bottom to top (hole-free; edge counts may differ — every section is
396
- * normalized to the largest). Any count is accepted; a loft of more
397
- * than 32 sections counting the bottom and the top still builds but
398
- * carries no parameter record (records are capped, calls are not)
292
+ * normalized to the largest)
399
293
  * @param options Optional behavior switches. `compatibility` — `"auto"`
400
294
  * (default) inserts vertices to match differing edge counts; `"strict"`
401
295
  * skips normalization and throws VALIDATION when outer edge counts (or,
@@ -580,66 +474,38 @@ export abstract class PluginGeomCreateApi {
580
474
  public abstract brepFromIntersection(a: BrepHandle, b: BrepHandle): PluginApiReturn<BrepHandle>
581
475
 
582
476
  /**
583
- * Rounds the given edges of a solid with a constant radius. Host API call —
584
- * returns a new {@linkcode BrepHandle}; the input brep is read-only.
585
- *
586
- * Works on curved solids: edges may be straight, circular or spline, and
587
- * adjacent edges (corner blends) are allowed. To pick a **rim** the circle
588
- * where a cylinder meets a flat cap walk the edges and keep the ones whose
589
- * two faces are a `cylinder` and a `plane`:
590
- * `core.geom.query.brep.listEdges(brep)` per edge
591
- * `core.geom.query.edge.listFaces(edge)` → `core.geom.query.face.getSurfaceKind`
592
- * on both faces. (`core.geom.query.brep.listEdgesBetween` takes two VERTEX
593
- * indices — it is NOT a face-pair lookup.) For one cap's rim only,
594
- * `core.geom.query.face.listEdges(capFace)` after a `getSurfaceKind` census of
595
- * `brep.listFaces` is the shorter walk.
596
- *
597
- * When the input brep carries a creation recipe, the result carries it too,
598
- * with this operation appended to `operations`; `design.create.massFromBrep`
599
- * then keeps the mass editable through `design.update.parameters`.
600
- *
601
- * Runs on the OpenCascade kernel (the first kernel call loads a wasm of tens
602
- * of MB — expect a pause of seconds).
477
+ * Rounds the given straight edges of a solid with a constant radius. Host
478
+ * API call — returns a new {@linkcode BrepHandle}; the input brep is
479
+ * read-only.
480
+ *
481
+ * v1 fillets straight edges only, and no two filleted edges may share a
482
+ * vertexcorner blends produce spherical patches Snaptrude cannot
483
+ * represent. Runs on the OpenCascade kernel (the first kernel call loads a
484
+ * wasm of tens of MB — expect a pause of seconds).
603
485
  *
604
486
  * Inspect the result via `core.geom.query.brep.*`, or commit it to the scene
605
487
  * with `design.create.massFromBrep`.
606
488
  *
607
489
  * @param brep The solid whose edges to round
608
- * @param edges The edges to fillet (one or more, all on `brep`, no
609
- * duplicates; more than 64 still fillets but the result carries no
610
- * parameter record)
490
+ * @param edges The straight edges to fillet (≥1, all on `brep`, no two sharing a vertex)
611
491
  * @param radius Fillet radius (positive, finite)
612
492
  * @returns The filleted solid as a new {@linkcode BrepHandle}
613
- * @throws VALIDATION if `edges` is empty or holds a duplicate, `radius` is
614
- * not a positive finite number, an edge is not on `brep`, or an edge has no
615
- * crease to round it is a seam of a closed face, or it lies between two
616
- * patches of one smooth surface
617
- * @throws PRECONDITION_FAILED if an edge could not be located on the kernel
618
- * solid after healing (select a different edge, or fillet before the
619
- * operation that curved the solid), or the kernel could not blend the edge
620
- * named in the message (reduce the radius or drop that edge)
621
- * @throws OPERATION_FAILED if the kernel or the translation fails, or the
622
- * result is non-manifold, splits into several solids, or contains a surface
623
- * Snaptrude cannot represent
624
- *
625
- * @examplePrompt Round the rim of the column with 200 mm
626
- * @examplePrompt Soften where the dome meets the wall
493
+ * @throws VALIDATION if `edges` is empty, `radius` is not a positive finite
494
+ * number, an edge is not on `brep`, an edge is an arc (v1 fillets straight
495
+ * edges only), or two edges share a vertex (fillet non-adjacent edges)
496
+ * @throws OPERATION_FAILED if the kernel cannot build the fillet (the radius
497
+ * likely exceeds the adjacent face size reduce it) or the result
498
+ * contains curved surfaces Snaptrude cannot represent
499
+ *
500
+ * @examplePrompt Round the edges of this mass
627
501
  * @examplePrompt Fillet the corners of the podium with a 0.5m radius
628
502
  * @examplePrompt Soften the vertical edges of this tower
629
503
  *
630
504
  * # Example
631
505
  * ```ts
632
- * // Rim = every edge between the cylinder side and a plane cap
633
- * const edges = await snaptrude.core.geom.query.brep.listEdges(column)
634
- * const rim = []
635
- * for (const edge of edges) {
636
- * const faces = await snaptrude.core.geom.query.edge.listFaces(edge)
637
- * const kinds = await Promise.all(
638
- * faces.map((f) => snaptrude.core.geom.query.face.getSurfaceKind(f)),
639
- * )
640
- * if (kinds.includes("cylinder") && kinds.includes("plane")) rim.push(edge)
641
- * }
642
- * const rounded = await snaptrude.core.geom.create.brepFromFillet(column, rim, 0.787) // 200 mm
506
+ * const brep = await snaptrude.core.geom.create.brepFromExtrusion(contour, { x: 0, y: 1, z: 0 }, 3)
507
+ * const edges = await snaptrude.core.geom.query.brep.listEdges(brep)
508
+ * const rounded = await snaptrude.core.geom.create.brepFromFillet(brep, [edges[0]], 0.3)
643
509
  * ```
644
510
  */
645
511
  public abstract brepFromFillet(
@@ -653,14 +519,6 @@ export abstract class PluginGeomCreateApi {
653
519
  * moves faces outward, negative moves them inward. Host API call — returns
654
520
  * a new {@linkcode BrepHandle}; the input brep is read-only.
655
521
  *
656
- * Works on curved solids: a sphere offsets to a sphere, a torus to a torus,
657
- * a cylinder to a cylinder. There is nothing to select — the whole solid is
658
- * offset.
659
- *
660
- * When the input brep carries a creation recipe, the result carries it too,
661
- * with this operation appended to `operations`; `design.create.massFromBrep`
662
- * then keeps the mass editable through `design.update.parameters`.
663
- *
664
522
  * Runs on the OpenCascade kernel (the first kernel call loads a wasm of
665
523
  * tens of MB — expect a pause of seconds).
666
524
  *
@@ -672,15 +530,9 @@ export abstract class PluginGeomCreateApi {
672
530
  * @returns The offset solid as a new {@linkcode BrepHandle}
673
531
  * @throws VALIDATION if `distance` is not finite, is too small to offset
674
532
  * anything, or an inward distance consumes the solid entirely
675
- * @throws OPERATION_FAILED if the kernel or the translation fails, or the
676
- * result is non-manifold, splits into several solids, or contains a surface
677
- * Snaptrude cannot represent (an offset free-form NURBS surface may have no
678
- * exact representation — the model is left unchanged). A distance the
679
- * solid cannot carry surfaces here, with a hint asking for a smaller one;
680
- * there is no per-face refusal — the kernel's per-face history verdict
681
- * ("this face was not offset") is logged, never raised (P4-D57)
682
- *
683
- * @examplePrompt Thicken the torus ring by 100 mm
533
+ * @throws OPERATION_FAILED if the kernel cannot build the offset or the
534
+ * result contains curved surfaces Snaptrude cannot represent
535
+ *
684
536
  * @examplePrompt Grow this solid by 0.5m in every direction
685
537
  * @examplePrompt Shrink this mass by 200mm
686
538
  * @examplePrompt Offset the building envelope outward by 1m
@@ -699,17 +551,6 @@ export abstract class PluginGeomCreateApi {
699
551
  * input brep is read-only. The outer surface is kept and the walls grow
700
552
  * inward.
701
553
  *
702
- * Works on curved solids: the open faces may be spherical, cylindrical,
703
- * conical, toroidal or free-form patches, not only flat ones. To open the
704
- * flat base of a dome, census the faces first — `core.geom.query.brep.listFaces`
705
- * then `core.geom.query.face.getSurfaceKind` on each — and keep the `"plane"`
706
- * one. A closed curved surface is stored as several patches (a sphere as
707
- * lunes), so opening "the sphere" may mean passing several faces.
708
- *
709
- * When the input brep carries a creation recipe, the result carries it too,
710
- * with this operation appended to `operations`; `design.create.massFromBrep`
711
- * then keeps the mass editable through `design.update.parameters`.
712
- *
713
554
  * Runs on the OpenCascade kernel (the first kernel call loads a wasm of
714
555
  * tens of MB — expect a pause of seconds).
715
556
  *
@@ -717,36 +558,24 @@ export abstract class PluginGeomCreateApi {
717
558
  * with `design.create.massFromBrep`.
718
559
  *
719
560
  * @param brep The solid to hollow
720
- * @param openFaces The faces to remove as openings (one or more, all on
721
- * `brep`, no duplicates; more than 32 still shells but the result carries
722
- * no parameter record)
561
+ * @param openFaces The faces to remove as openings (≥1, all on `brep`)
723
562
  * @param thickness Wall thickness (positive, finite, smaller than half the solid's smallest span)
724
563
  * @returns The hollowed solid as a new {@linkcode BrepHandle}
725
- * @throws VALIDATION if `openFaces` is empty or holds a duplicate, a face is
726
- * not on `brep`, `thickness` is not a positive finite number, or the
727
- * thickness is too large (it must be smaller than half the solid's smallest
728
- * span)
729
- * @throws OPERATION_FAILED if the kernel or the translation fails, or the
730
- * result is non-manifold, splits into several solids, or contains a surface
731
- * Snaptrude cannot represent. A thickness the solid cannot carry surfaces
732
- * here, with a hint asking for one below half the smallest span; there is
733
- * no per-face refusal — the kernel's per-face history verdict ("this kept
734
- * face was not thickened") is logged, never raised (P4-D57)
735
- *
736
- * @examplePrompt Hollow the dome into a 300 mm shell, open at the base
564
+ * @throws VALIDATION if `openFaces` is empty, a face is not on `brep`,
565
+ * `thickness` is not a positive finite number, or the thickness is too
566
+ * large (it must be smaller than half the solid's smallest span)
567
+ * @throws OPERATION_FAILED if the kernel cannot build the shell or the
568
+ * result contains curved surfaces Snaptrude cannot represent
569
+ *
737
570
  * @examplePrompt Hollow this mass into 200mm walls
738
571
  * @examplePrompt Shell this form with the top face open
739
572
  * @examplePrompt Turn this solid tower into a tube open at both ends
740
573
  *
741
574
  * # Example
742
575
  * ```ts
743
- * // Open the dome at its flat base: the one face whose surface is a plane
744
- * const faces = await snaptrude.core.geom.query.brep.listFaces(dome)
745
- * const base = []
746
- * for (const face of faces) {
747
- * if ((await snaptrude.core.geom.query.face.getSurfaceKind(face)) === "plane") base.push(face)
748
- * }
749
- * const hollow = await snaptrude.core.geom.create.brepFromShell(dome, base, 1.181) // 300 mm
576
+ * const brep = await snaptrude.core.geom.create.brepFromExtrusion(contour, { x: 0, y: 1, z: 0 }, 3)
577
+ * const faces = await snaptrude.core.geom.query.brep.listFaces(brep)
578
+ * const hollow = await snaptrude.core.geom.create.brepFromShell(brep, [faces[0]], 0.2)
750
579
  * ```
751
580
  */
752
581
  public abstract brepFromShell(
@@ -796,48 +625,28 @@ export abstract class PluginGeomCreateApi {
796
625
  ): PluginApiReturn<BrepHandle[]>
797
626
 
798
627
  /**
799
- * Bevels the given edges of a solid with a symmetric planar cut. Host API
800
- * call — returns a new {@linkcode BrepHandle}; the input brep is read-only.
801
- *
802
- * Works on curved solids: edges may be straight, circular or spline, and
803
- * adjacent edges are allowed. Pick edges the same way as for
804
- * {@linkcode PluginGeomCreateApi.brepFromFillet} — `brep.listEdges`, then
805
- * `core.geom.query.edge.listFaces` and `core.geom.query.face.getSurfaceKind`
806
- * on both faces of each edge. (`core.geom.query.brep.listEdgesBetween` takes
807
- * two VERTEX indices — it is NOT a face-pair lookup.) Chamfering a cylinder's
808
- * rim yields a cone patch where a fillet would yield a torus patch.
809
- *
810
- * When the input brep carries a creation recipe, the result carries it too,
811
- * with this operation appended to `operations`; `design.create.massFromBrep`
812
- * then keeps the mass editable through `design.update.parameters`.
628
+ * Bevels the given straight edges of a solid with a symmetric planar cut.
629
+ * Host API call — returns a new {@linkcode BrepHandle}; the input brep is
630
+ * read-only.
813
631
  *
814
- * Runs on the OpenCascade kernel (the first kernel call loads a wasm of tens
815
- * of MB expect a pause of seconds).
632
+ * v1 chamfers straight edges only, and no two chamfered edges may share a
633
+ * vertex. Runs on the OpenCascade kernel (the first kernel call loads a
634
+ * wasm of tens of MB — expect a pause of seconds).
816
635
  *
817
636
  * Inspect the result via `core.geom.query.brep.*`, or commit it to the scene
818
637
  * with `design.create.massFromBrep`.
819
638
  *
820
639
  * @param brep The solid whose edges to bevel
821
- * @param edges The edges to chamfer (one or more, all on `brep`, no
822
- * duplicates; more than 64 still chamfers but the result carries no
823
- * parameter record)
640
+ * @param edges The straight edges to chamfer (≥1, all on `brep`, no two sharing a vertex)
824
641
  * @param distance Chamfer distance from the edge on each adjacent face (positive, finite)
825
642
  * @returns The chamfered solid as a new {@linkcode BrepHandle}
826
- * @throws VALIDATION if `edges` is empty or holds a duplicate, `distance` is
827
- * not a positive finite number, an edge is not on `brep`, or an edge has no
828
- * crease to cut it is a seam of a closed face, or it lies between two
829
- * patches of one smooth surface
830
- * @throws PRECONDITION_FAILED if an edge could not be located on the kernel
831
- * solid after healing (select a different edge, or chamfer before the
832
- * operation that curved the solid)
833
- * @throws OPERATION_FAILED if the kernel or the translation fails, or the
834
- * result is non-manifold, splits into several solids, or contains a surface
835
- * Snaptrude cannot represent. A distance larger than an adjacent face
836
- * surfaces here, with a hint asking for a smaller one: unlike
837
- * {@linkcode PluginGeomCreateApi.brepFromFillet}, a chamfer has no
838
- * per-edge kernel verdict, so the failure names no edge (P4-D59)
839
- *
840
- * @examplePrompt Chamfer the top edge of the cylinder
643
+ * @throws VALIDATION if `edges` is empty, `distance` is not a positive
644
+ * finite number, an edge is not on `brep`, an edge is an arc (v1 chamfers
645
+ * straight edges only), or two edges share a vertex (chamfer non-adjacent
646
+ * edges)
647
+ * @throws OPERATION_FAILED if the kernel cannot build the chamfer (the
648
+ * distance likely exceeds the adjacent face size reduce it)
649
+ *
841
650
  * @examplePrompt Bevel these edges by 100mm
842
651
  * @examplePrompt Chamfer the top edges of the plinth
843
652
  * @examplePrompt Cut a 45-degree flat along the corners of this mass
@@ -873,15 +682,11 @@ export abstract class PluginGeomCreateApi {
873
682
  * tapering across a bend or along an arc edge would create faces Snaptrude
874
683
  * cannot represent and throws (sweep each straight run separately and union
875
684
  * the results instead). An optional `transition` picks the corner
876
- * treatment: `"miter"` (default) is today's sharp mitred bend; `"round"`
877
- * carries the section around each turning corner on a tangent circular arc,
878
- * so the corner patch is a real curved (cylindrical) surface rather than a
879
- * flat cut (open paths only — `"round"` on a closed ring path is refused);
685
+ * treatment: `"miter"` (default) is today's sharp mitred bend;
880
686
  * `{ bevel: b }` chamfers each turning corner by cutting `b` back along
881
687
  * both adjacent legs (works on open and closed paths — each leg must be
882
- * long enough for its cuts). On a corner-less path `transition` has no
883
- * effect, and the varying-scale lane takes straight paths, so it never sees
884
- * a corner.
688
+ * long enough for its cuts). On a corner-less path `transition` has no effect, and the
689
+ * varying-scale lane takes straight paths, so it never sees a corner.
885
690
  *
886
691
  * Open paths run on the OpenCascade kernel (the first kernel call loads a
887
692
  * wasm of tens of MB — expect a pause of seconds); closed paths are
@@ -891,22 +696,19 @@ export abstract class PluginGeomCreateApi {
891
696
  * with `design.create.massFromBrep`.
892
697
  *
893
698
  * @param profile The cross-section to sweep (hole-free contour)
894
- * @param path The polyline path as plain `{x, y, z}` points (2 or more;
895
- * repeat the first point as the last to close the path into a ring; more
896
- * than 512 points still sweeps but the result carries no parameter record)
699
+ * @param path The polyline path as plain `{x, y, z}` points (2; repeat the
700
+ * first point as the last to close the path into a ring)
897
701
  * @param options Optional scale law and corner transition. Scale law:
898
702
  * `startScale`/`endScale` (linear taper by arc length) or `scales` (one
899
703
  * factor per path point; mutually exclusive with
900
704
  * `startScale`/`endScale`); every factor must be finite and within
901
- * 1e-3..1e3. `transition`: `"miter"` (default, sharp corners),
902
- * `"round"` (arc-carried corners curved corner patches; open paths
903
- * only) or `{ bevel: b }` (chamfered corners, `b` finite within
904
- * 1e-3..1e3; open and closed paths)
705
+ * 1e-3..1e3. `transition`: `"miter"` (default, sharp corners) or
706
+ * `{ bevel: b }` (chamfered corners, `b` finite within 1e-3..1e3; open
707
+ * and closed paths)
905
708
  * @returns The swept solid as a new {@linkcode BrepHandle}
906
709
  * @throws VALIDATION if the profile has holes, the path has fewer than 2
907
- * points, consecutive path points coincide, a
908
- * coordinate is not finite, or the profile plane contains the first
909
- * path segment's direction
710
+ * points, consecutive path points coincide, a coordinate is not finite,
711
+ * or the profile plane contains the first path segment's direction
910
712
  * (degenerate sweep); for closed paths, if the ring has fewer than 3
911
713
  * distinct corners, the path is non-planar, a corner doubles back, the
912
714
  * profile has an arc edge, or the profile is too large for a mitred
@@ -914,14 +716,11 @@ export abstract class PluginGeomCreateApi {
914
716
  * is combined with `startScale`/`endScale`, `scales` does not match the
915
717
  * path length, or a varying scale is used on a bent or closed path or
916
718
  * with an arc-edged profile; for `{ bevel }`, if a leg is too short for
917
- * the cuts its bevelled corners take from it or a corner nearly doubles
918
- * back so its bevel collapses (the errors name the corner)
919
- * @throws PRECONDITION_FAILED if `transition` is `"round"` and the path is
920
- * closed — round corners are an open-path lane; use `"miter"` or
921
- * `{ bevel }` on a ring
719
+ * the cuts its beveled corners take from it or a corner nearly doubles
720
+ * back so its chamfer collapses (the errors name the corner)
922
721
  * @throws OPERATION_FAILED if the kernel cannot sweep the profile into a
923
- * valid solid including a `"round"` corner whose arc does not fit its
924
- * legs, which is not pre-checked and so is not named per corner
722
+ * valid solid or a transition patch is a curved surface Snaptrude cannot
723
+ * represent
925
724
  *
926
725
  * @examplePrompt Sweep this profile along the corridor path
927
726
  * @examplePrompt Extrude the railing section along this route
@@ -930,7 +729,6 @@ export abstract class PluginGeomCreateApi {
930
729
  * @examplePrompt Taper this duct from 1x1 to 2x2 along its run
931
730
  * @examplePrompt Sweep a column section that narrows toward the top
932
731
  * @examplePrompt Chamfer the corners of this swept frame by 200mm
933
- * @examplePrompt Sweep this handrail with rounded corners at the bends
934
732
  *
935
733
  * # Example
936
734
  * ```ts
@@ -969,7 +767,7 @@ export abstract class PluginGeomCreateApi {
969
767
  startScale?: number
970
768
  endScale?: number
971
769
  scales?: number[]
972
- transition?: "miter" | "round" | { bevel: number }
770
+ transition?: "miter" | { bevel: number }
973
771
  },
974
772
  ): PluginApiReturn<BrepHandle>
975
773
 
@@ -977,19 +775,9 @@ export abstract class PluginGeomCreateApi {
977
775
  * Revolves a planar profile about an axis to make a solid of revolution — a
978
776
  * full turn by default. Host API call — returns a new
979
777
  * {@linkcode BrepHandle}; the input contour is read-only. Holes in the
980
- * profile are allowed, and segments may run at any angle to the axis: an
981
- * inclined segment revolves into a cone, an arc into a sphere or torus
982
- * section. This is the general route to domes, vases, columns and rotundas.
983
- *
984
- * Two rules bind the axis to the profile. First, the axis line must lie IN
985
- * the profile's plane — a revolution turns a planar section about a line
986
- * drawn in that same plane. An axis that misses the plane (skew to it, or
987
- * parallel but offset out of it) is refused: move the axis into the
988
- * profile's plane, or move the profile onto the axis's plane. Second,
989
- * within that plane the whole profile stays on ONE side of the axis.
990
- * Vertices and whole segments may lie ON the axis — that is how a dome's
991
- * pole and a cylinder's inner edge are authored — but no part of the profile
992
- * may cross to the other side, which would sweep a self-intersecting solid.
778
+ * profile are allowed. Profile segments must stay parallel or perpendicular
779
+ * to the axis inclined or arc segments would revolve into surfaces
780
+ * Snaptrude cannot represent.
993
781
  *
994
782
  * Runs on the OpenCascade kernel (the first kernel call loads a wasm of
995
783
  * tens of MB — expect a pause of seconds).
@@ -1003,25 +791,19 @@ export abstract class PluginGeomCreateApi {
1003
791
  * @param angleInDegrees Optional revolution angle in degrees (0 < angle ≤ 360; default 360)
1004
792
  * @returns The revolved solid as a new {@linkcode BrepHandle}
1005
793
  * @throws VALIDATION if `axisDirection` is zero-length, `angleInDegrees` is
1006
- * not in (0, 360], a coordinate is not finite, or the profile crosses the
1007
- * axis (the message names the offending segment — keep the whole profile
1008
- * on one side; points may touch the axis but not cross it)
1009
- * @throws PRECONDITION_FAILED if the axis does not lie in the profile's
1010
- * plane skew to it, or parallel but offset out of it (the message asks
1011
- * you to move the axis into that plane)
1012
- * @throws OPERATION_FAILED if the kernel cannot revolve the profile into a
1013
- * valid solid
794
+ * not in (0, 360], the axis passes through the profile interior, or a
795
+ * coordinate is not finite
796
+ * @throws OPERATION_FAILED if the kernel cannot revolve the profile or the
797
+ * result contains curved surfaces Snaptrude cannot represent (keep
798
+ * profile segments parallel or perpendicular to the axis)
1014
799
  *
1015
800
  * @examplePrompt Create a dome from this section
1016
801
  * @examplePrompt Revolve this profile 360 degrees around the vertical axis
1017
802
  * @examplePrompt Build a rotunda by revolving this wall section
1018
- * @examplePrompt Make a dome by revolving a quarter-circle about the vertical axis
1019
- * @examplePrompt Turn this curved outline into a vase
1020
803
  *
1021
804
  * # Example
1022
805
  * ```ts
1023
- * // A cylinder: revolve a 2m-wide, 3m-tall rectangle about the Y axis at
1024
- * // its edge — the left edge sits ON the axis, which is legal.
806
+ * // A cylinder: revolve a 2m-wide, 3m-tall rectangle about the Y axis at its edge
1025
807
  * const rect = await snaptrude.core.geom.create.profileFromLinePoints([
1026
808
  * await snaptrude.core.math.vec3.new(0, 0, 0),
1027
809
  * await snaptrude.core.math.vec3.new(2, 0, 0),
@@ -1042,158 +824,6 @@ export abstract class PluginGeomCreateApi {
1042
824
  axisDirection: Vec3Components,
1043
825
  angleInDegrees?: number,
1044
826
  ): PluginApiReturn<BrepHandle>
1045
-
1046
- /**
1047
- * Create a solid **sphere** B-rep from a centre and radius. Host API call —
1048
- * returns a {@linkcode BrepHandle}; commit it to the scene with
1049
- * `design.create.massFromBrep`. The result carries an exact spherical
1050
- * surface (not a faceted approximation) and a creation recipe — read the
1051
- * committed mass's parameters back with `design.query.getParameters` and edit
1052
- * them with `design.update.parameters`.
1053
- *
1054
- * Runs on the OpenCascade kernel (the first kernel call loads a wasm of tens
1055
- * of MB — expect a pause of seconds).
1056
- *
1057
- * @param centre Sphere centre as plain `{x, y, z}` components (raw Babylon units)
1058
- * @param radius Sphere radius (> 0, raw Babylon units)
1059
- * @returns The new solid as a {@linkcode BrepHandle}
1060
- * @throws VALIDATION if `radius` is not a positive finite number or a
1061
- * coordinate is not finite
1062
- *
1063
- * @examplePrompt Create a sphere of radius 5 at the origin
1064
- * @examplePrompt Add a 3m ball on top of the tower
1065
- *
1066
- * # Example
1067
- * ```ts
1068
- * const brep = await snaptrude.core.geom.create.brepFromSphere({ x: 0, y: 5, z: 0 }, 5)
1069
- * const mass = await snaptrude.design.create.massFromBrep(brep, "Sphere")
1070
- * ```
1071
- */
1072
- public abstract brepFromSphere(
1073
- centre: Vec3Components,
1074
- radius: number,
1075
- ): PluginApiReturn<BrepHandle>
1076
-
1077
- /**
1078
- * Create a solid **cylinder** B-rep from its bottom-cap centre, axis
1079
- * direction, radius and height. Host API call — returns a
1080
- * {@linkcode BrepHandle}; commit with `design.create.massFromBrep`. The
1081
- * bottom cap sits AT `base` and the solid extends `height` along `axis` —
1082
- * place `base` on the floor and use axis `{x: 0, y: 1, z: 0}` for an upright
1083
- * column. Carries a creation recipe (radius, height), editable through
1084
- * `design.update.parameters`.
1085
- *
1086
- * Runs on the OpenCascade kernel (the first kernel call loads a wasm of tens
1087
- * of MB — expect a pause of seconds).
1088
- *
1089
- * @param base Centre of the bottom cap as plain `{x, y, z}` components
1090
- * @param axis Axis direction as plain `{x, y, z}` components (non-zero, normalised by the host)
1091
- * @param radius Cylinder radius (> 0)
1092
- * @param height Cylinder height along `axis` (> 0)
1093
- * @returns The new solid as a {@linkcode BrepHandle}
1094
- * @throws VALIDATION if `radius`/`height` are not positive finite numbers or
1095
- * `axis` is zero-length
1096
- *
1097
- * @examplePrompt Create a cylinder 2m across and 4m tall
1098
- * @examplePrompt Add a circular column here
1099
- *
1100
- * # Example
1101
- * ```ts
1102
- * const brep = await snaptrude.core.geom.create.brepFromCylinder(
1103
- * { x: 0, y: 0, z: 0 },
1104
- * { x: 0, y: 1, z: 0 },
1105
- * 1,
1106
- * 4,
1107
- * )
1108
- * const column = await snaptrude.design.create.massFromBrep(brep, "Column")
1109
- * ```
1110
- */
1111
- public abstract brepFromCylinder(
1112
- base: Vec3Components,
1113
- axis: Vec3Components,
1114
- radius: number,
1115
- height: number,
1116
- ): PluginApiReturn<BrepHandle>
1117
-
1118
- /**
1119
- * Create a solid **cone or frustum** B-rep: bottom-cap centre, axis, base
1120
- * radius, height, and an optional top radius (default 0 — a full cone to a
1121
- * point; > 0 — a frustum / tapered column). Host API call — returns a
1122
- * {@linkcode BrepHandle}; commit with `design.create.massFromBrep`. Carries
1123
- * a creation recipe (radii + height), editable through `design.update.parameters`.
1124
- *
1125
- * Runs on the OpenCascade kernel (the first kernel call loads a wasm of tens
1126
- * of MB — expect a pause of seconds).
1127
- *
1128
- * @param base Centre of the bottom cap as plain `{x, y, z}` components
1129
- * @param axis Axis direction as plain `{x, y, z}` components (non-zero, normalised by the host)
1130
- * @param baseRadius Radius at the base (> 0)
1131
- * @param height Height along `axis` (> 0)
1132
- * @param topRadius Optional radius at the top (≥ 0, ≠ `baseRadius`; default 0 = apex)
1133
- * @returns The new solid as a {@linkcode BrepHandle}
1134
- * @throws VALIDATION if radii/height are invalid, `topRadius === baseRadius`
1135
- * (that is a cylinder — use {@linkcode PluginGeomCreateApi.brepFromCylinder}),
1136
- * or `axis` is zero-length
1137
- *
1138
- * @examplePrompt Create a cone roof 4m wide and 3m tall
1139
- * @examplePrompt Make a tapered column narrowing from 1m to 0.6m
1140
- *
1141
- * # Example
1142
- * ```ts
1143
- * const roof = await snaptrude.core.geom.create.brepFromCone(
1144
- * { x: 0, y: 9, z: 0 },
1145
- * { x: 0, y: 1, z: 0 },
1146
- * 2,
1147
- * 3,
1148
- * )
1149
- * ```
1150
- */
1151
- public abstract brepFromCone(
1152
- base: Vec3Components,
1153
- axis: Vec3Components,
1154
- baseRadius: number,
1155
- height: number,
1156
- topRadius?: number,
1157
- ): PluginApiReturn<BrepHandle>
1158
-
1159
- /**
1160
- * Create a solid **torus** (ring / donut) B-rep from its centre, plane
1161
- * normal, ring radius and tube radius. Host API call — returns a
1162
- * {@linkcode BrepHandle}; commit with `design.create.massFromBrep`.
1163
- * `majorRadius` is centre-to-tube-centre; `minorRadius` is the tube's own
1164
- * radius and must be strictly smaller. Carries a creation recipe, editable
1165
- * through `design.update.parameters`.
1166
- *
1167
- * Runs on the OpenCascade kernel (the first kernel call loads a wasm of tens
1168
- * of MB — expect a pause of seconds).
1169
- *
1170
- * @param centre Torus centre as plain `{x, y, z}` components
1171
- * @param axis Plane normal of the ring as plain `{x, y, z}` components (non-zero)
1172
- * @param majorRadius Ring radius, centre to tube centre (> 0)
1173
- * @param minorRadius Tube radius (> 0 and < `majorRadius` — a self-intersecting torus is rejected)
1174
- * @returns The new solid as a {@linkcode BrepHandle}
1175
- * @throws VALIDATION if a radius is invalid, `minorRadius >= majorRadius`,
1176
- * or `axis` is zero-length
1177
- *
1178
- * @examplePrompt Create a donut-shaped ring 10m across with a 1m tube
1179
- * @examplePrompt Add a torus canopy around the tower
1180
- *
1181
- * # Example
1182
- * ```ts
1183
- * const ring = await snaptrude.core.geom.create.brepFromTorus(
1184
- * { x: 0, y: 6, z: 0 },
1185
- * { x: 0, y: 1, z: 0 },
1186
- * 5,
1187
- * 1,
1188
- * )
1189
- * ```
1190
- */
1191
- public abstract brepFromTorus(
1192
- centre: Vec3Components,
1193
- axis: Vec3Components,
1194
- majorRadius: number,
1195
- minorRadius: number,
1196
- ): PluginApiReturn<BrepHandle>
1197
827
  }
1198
828
 
1199
829
  /**
@@ -1247,38 +877,6 @@ export const PluginGeomCreateCircleArgs = z.object({
1247
877
 
1248
878
  export type PluginGeomCreateCircleArgs = z.infer<typeof PluginGeomCreateCircleArgs>
1249
879
 
1250
- /**
1251
- * Arguments for {@linkcode PluginGeomCreateApi.splineFromPoints}.
1252
- *
1253
- * | Property | Type | Description |
1254
- * |---|---|---|
1255
- * | `points` | {@linkcode Vec3Handle}`[]` | 3..256 ordered through-points of the curve |
1256
- */
1257
- export const PluginGeomCreateSplineFromPointsArgs = z.object({
1258
- points: z.array(Vec3Handle).min(3).max(MAX_SPLINE_THROUGH_POINTS),
1259
- })
1260
-
1261
- export type PluginGeomCreateSplineFromPointsArgs = z.infer<
1262
- typeof PluginGeomCreateSplineFromPointsArgs
1263
- >
1264
-
1265
- /**
1266
- * Arguments for {@linkcode PluginGeomCreateApi.splineFromControlPoints}.
1267
- *
1268
- * | Property | Type | Description |
1269
- * |---|---|---|
1270
- * | `controlPoints` | {@linkcode Vec3Handle}`[]` | 3..512 control points of the curve, in order |
1271
- * | `options` | `object`? | `degree`: 2 or 3 (default `min(3, controlPoints.length - 1)`) |
1272
- */
1273
- export const PluginGeomCreateSplineFromControlPointsArgs = z.object({
1274
- controlPoints: z.array(Vec3Handle).min(3).max(MAX_SPLINE_POLES),
1275
- options: z.object({ degree: z.number().int().min(2).max(3).optional() }).optional(),
1276
- })
1277
-
1278
- export type PluginGeomCreateSplineFromControlPointsArgs = z.infer<
1279
- typeof PluginGeomCreateSplineFromControlPointsArgs
1280
- >
1281
-
1282
880
  /**
1283
881
  * Arguments for {@linkcode PluginGeomCreateApi.profileFromLinePoints}.
1284
882
  *
@@ -1309,21 +907,6 @@ export type PluginGeomCreateProfileFromCurvesArgs = z.infer<
1309
907
  typeof PluginGeomCreateProfileFromCurvesArgs
1310
908
  >
1311
909
 
1312
- /**
1313
- * Arguments for {@linkcode PluginGeomCreateApi.profileFromSplinePoints}.
1314
- *
1315
- * | Property | Type | Description |
1316
- * |---|---|---|
1317
- * | `points` | {@linkcode Vec3Handle}`[]` | 3..256 ordered through-points of the closed loop (first point NOT repeated) |
1318
- */
1319
- export const PluginGeomCreateProfileFromSplinePointsArgs = z.object({
1320
- points: z.array(Vec3Handle).min(3).max(MAX_SPLINE_THROUGH_POINTS),
1321
- })
1322
-
1323
- export type PluginGeomCreateProfileFromSplinePointsArgs = z.infer<
1324
- typeof PluginGeomCreateProfileFromSplinePointsArgs
1325
- >
1326
-
1327
910
  /**
1328
911
  * Arguments for {@linkcode PluginGeomCreateApi.contourFromProfile}.
1329
912
  *
@@ -1404,7 +987,7 @@ export type PluginGeomCreateBrepFromExtrusionArgs = z.infer<
1404
987
  * |---|---|---|
1405
988
  * | `bottomContour` | {@linkcode ContourHandle} | The bottom cross-section |
1406
989
  * | `topContour` | {@linkcode ContourHandle} | The top cross-section |
1407
- * | `intermediateContours` | {@linkcode ContourHandle}`[]`? | Optional in-between cross-sections, ordered bottom to top (any count; more than 32 sections in all builds but carries no parameter record) |
990
+ * | `intermediateContours` | {@linkcode ContourHandle}`[]`? | Optional in-between cross-sections, ordered bottom to top |
1408
991
  * | `options` | `object`? | Optional behavior switches: `compatibility` (`"strict"` throws on mismatched edge counts instead of auto-matching; default `"auto"`) and `seamAlignment` (`"authored"` keeps the authored correspondence instead of searching seam rotations; default `"auto"`) |
1409
992
  */
1410
993
  export const PluginGeomCreateBrepFromLoftArgs = z.object({
@@ -1467,7 +1050,7 @@ const FiniteVec3Components = z.object({
1467
1050
  * | Property | Type | Description |
1468
1051
  * |---|---|---|
1469
1052
  * | `brep` | {@linkcode BrepHandle} | The solid whose edges to round |
1470
- * | `edges` | {@linkcode EdgeHandle}`[]` | The edges to fillet (one or more; more than 64 builds but carries no parameter record) |
1053
+ * | `edges` | {@linkcode EdgeHandle}`[]` | The straight edges to fillet (≥1) |
1471
1054
  * | `radius` | `number` | Fillet radius (positive, finite) |
1472
1055
  */
1473
1056
  export const PluginGeomCreateBrepFromFilletArgs = z.object({
@@ -1502,7 +1085,7 @@ export type PluginGeomCreateBrepFromOffsetArgs = z.infer<typeof PluginGeomCreate
1502
1085
  * | Property | Type | Description |
1503
1086
  * |---|---|---|
1504
1087
  * | `brep` | {@linkcode BrepHandle} | The solid to hollow |
1505
- * | `openFaces` | {@linkcode FaceHandle}`[]` | The faces to remove as openings (one or more; more than 32 builds but carries no parameter record) |
1088
+ * | `openFaces` | {@linkcode FaceHandle}`[]` | The faces to remove as openings (≥1) |
1506
1089
  * | `thickness` | `number` | Wall thickness (positive, finite) |
1507
1090
  */
1508
1091
  export const PluginGeomCreateBrepFromShellArgs = z.object({
@@ -1536,7 +1119,7 @@ export type PluginGeomCreateBrepsFromSplitArgs = z.infer<typeof PluginGeomCreate
1536
1119
  * | Property | Type | Description |
1537
1120
  * |---|---|---|
1538
1121
  * | `brep` | {@linkcode BrepHandle} | The solid whose edges to bevel |
1539
- * | `edges` | {@linkcode EdgeHandle}`[]` | The edges to chamfer (one or more; more than 64 builds but carries no parameter record) |
1122
+ * | `edges` | {@linkcode EdgeHandle}`[]` | The straight edges to chamfer (≥1) |
1540
1123
  * | `distance` | `number` | Chamfer distance from the edge on each adjacent face (positive, finite) |
1541
1124
  */
1542
1125
  export const PluginGeomCreateBrepFromChamferArgs = z.object({
@@ -1559,8 +1142,8 @@ const SweepScaleFactor = z.number().finite().min(1e-3).max(1e3)
1559
1142
  * | Property | Type | Description |
1560
1143
  * |---|---|---|
1561
1144
  * | `profile` | {@linkcode ContourHandle} | The cross-section to sweep (hole-free) |
1562
- * | `path` | {@linkcode Vec3Components}`[]` | The polyline path (2 or more points, finite components — more than 512 builds but carries no parameter record; repeating the first point as the last closes it into a ring — closed paths must be flat and straight-segmented and take a straight-edged profile) |
1563
- * | `options` | `object`? | Optional scale law: `startScale`/`endScale` (linear taper by arc length) or per-point `scales` (mutually exclusive; factors finite, 1e-3..1e3; `scales.length` must equal `path.length`). Optional corner `transition`: `"miter"` (default), `"round"` (arc-carried corners) or `{ bevel }` (chamfered corners; finite, 1e-3..1e3) |
1145
+ * | `path` | {@linkcode Vec3Components}`[]` | The polyline path (2 points, finite components; repeating the first point as the last closes it into a ring — closed paths must be flat and straight-segmented and take a straight-edged profile) |
1146
+ * | `options` | `object`? | Optional scale law: `startScale`/`endScale` (linear taper by arc length) or per-point `scales` (mutually exclusive; factors finite, 1e-3..1e3; `scales.length` must equal `path.length`). Optional corner `transition`: `"miter"` (default) or `{ bevel }` (chamfered corners; finite, 1e-3..1e3) |
1564
1147
  */
1565
1148
  export const PluginGeomCreateBrepFromSweepArgs = z
1566
1149
  .object({
@@ -1574,7 +1157,6 @@ export const PluginGeomCreateBrepFromSweepArgs = z
1574
1157
  transition: z
1575
1158
  .union([
1576
1159
  z.literal("miter"),
1577
- z.literal("round"),
1578
1160
  z.object({ bevel: z.number().finite().min(1e-3).max(1e3) }),
1579
1161
  ])
1580
1162
  .optional(),
@@ -1606,8 +1188,8 @@ export type PluginGeomCreateBrepFromSweepArgs = z.infer<typeof PluginGeomCreateB
1606
1188
  * | Property | Type | Description |
1607
1189
  * |---|---|---|
1608
1190
  * | `profile` | {@linkcode ContourHandle} | The cross-section to revolve (holes allowed) |
1609
- * | `axisOrigin` | {@linkcode Vec3Components} | A point on the revolution axis (finite components; the axis must lie in the profile's plane) |
1610
- * | `axisDirection` | {@linkcode Vec3Components} | The axis direction (non-zero, finite components; the axis must lie in the profile's plane) |
1191
+ * | `axisOrigin` | {@linkcode Vec3Components} | A point on the revolution axis (finite components) |
1192
+ * | `axisDirection` | {@linkcode Vec3Components} | The axis direction (non-zero, finite components) |
1611
1193
  * | `angleInDegrees` | `number`? | Revolution angle in degrees (0 < angle ≤ 360; default 360) |
1612
1194
  */
1613
1195
  export const PluginGeomCreateBrepFromRevolutionArgs = z.object({
@@ -1620,89 +1202,3 @@ export const PluginGeomCreateBrepFromRevolutionArgs = z.object({
1620
1202
  export type PluginGeomCreateBrepFromRevolutionArgs = z.infer<
1621
1203
  typeof PluginGeomCreateBrepFromRevolutionArgs
1622
1204
  >
1623
-
1624
- /**
1625
- * Arguments for {@linkcode PluginGeomCreateApi.brepFromSphere}.
1626
- *
1627
- * | Property | Type | Description |
1628
- * |---|---|---|
1629
- * | `centre` | {@linkcode Vec3Components} | Sphere centre (finite components) |
1630
- * | `radius` | `number` | Sphere radius (finite; positivity is checked host-side so the error names the parameter) |
1631
- */
1632
- export const PluginGeomCreateBrepFromSphereArgs = z.object({
1633
- centre: FiniteVec3Components,
1634
- radius: z.number().finite(),
1635
- })
1636
-
1637
- export type PluginGeomCreateBrepFromSphereArgs = z.infer<
1638
- typeof PluginGeomCreateBrepFromSphereArgs
1639
- >
1640
-
1641
- /**
1642
- * Arguments for {@linkcode PluginGeomCreateApi.brepFromCylinder}.
1643
- *
1644
- * | Property | Type | Description |
1645
- * |---|---|---|
1646
- * | `base` | {@linkcode Vec3Components} | Centre of the bottom cap (finite components) |
1647
- * | `axis` | {@linkcode Vec3Components} | Axis direction (non-zero, finite components) |
1648
- * | `radius` | `number` | Cylinder radius (finite, positive) |
1649
- * | `height` | `number` | Height along `axis` (finite, positive) |
1650
- */
1651
- export const PluginGeomCreateBrepFromCylinderArgs = z.object({
1652
- base: FiniteVec3Components,
1653
- axis: FiniteVec3Components,
1654
- radius: z.number().finite(),
1655
- height: z.number().finite(),
1656
- })
1657
-
1658
- export type PluginGeomCreateBrepFromCylinderArgs = z.infer<
1659
- typeof PluginGeomCreateBrepFromCylinderArgs
1660
- >
1661
-
1662
- /**
1663
- * Arguments for {@linkcode PluginGeomCreateApi.brepFromCone}.
1664
- *
1665
- * | Property | Type | Description |
1666
- * |---|---|---|
1667
- * | `base` | {@linkcode Vec3Components} | Centre of the bottom cap (finite components) |
1668
- * | `axis` | {@linkcode Vec3Components} | Axis direction (non-zero, finite components) |
1669
- * | `baseRadius` | `number` | Radius at the base (finite, positive) |
1670
- * | `height` | `number` | Height along `axis` (finite, positive) |
1671
- * | `topRadius` | `number`? | Radius at the top (finite, ≥ 0, ≠ `baseRadius`; default 0 = apex) |
1672
- */
1673
- export const PluginGeomCreateBrepFromConeArgs = z
1674
- .object({
1675
- base: FiniteVec3Components,
1676
- axis: FiniteVec3Components,
1677
- baseRadius: z.number().finite(),
1678
- height: z.number().finite(),
1679
- topRadius: z.number().finite().optional(),
1680
- })
1681
- .refine((a) => (a.topRadius ?? 0) !== a.baseRadius, {
1682
- message: "topRadius must differ from baseRadius — equal radii are a cylinder",
1683
- })
1684
-
1685
- export type PluginGeomCreateBrepFromConeArgs = z.infer<typeof PluginGeomCreateBrepFromConeArgs>
1686
-
1687
- /**
1688
- * Arguments for {@linkcode PluginGeomCreateApi.brepFromTorus}.
1689
- *
1690
- * | Property | Type | Description |
1691
- * |---|---|---|
1692
- * | `centre` | {@linkcode Vec3Components} | Torus centre (finite components) |
1693
- * | `axis` | {@linkcode Vec3Components} | Plane normal of the ring (non-zero, finite components) |
1694
- * | `majorRadius` | `number` | Ring radius, centre to tube centre (finite, positive) |
1695
- * | `minorRadius` | `number` | Tube radius (finite, positive, strictly less than `majorRadius`) |
1696
- */
1697
- export const PluginGeomCreateBrepFromTorusArgs = z
1698
- .object({
1699
- centre: FiniteVec3Components,
1700
- axis: FiniteVec3Components,
1701
- majorRadius: z.number().finite(),
1702
- minorRadius: z.number().finite(),
1703
- })
1704
- .refine((a) => a.minorRadius < a.majorRadius, {
1705
- message: "minorRadius must be smaller than majorRadius — the torus would self-intersect",
1706
- })
1707
-
1708
- export type PluginGeomCreateBrepFromTorusArgs = z.infer<typeof PluginGeomCreateBrepFromTorusArgs>