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

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 (51) hide show
  1. package/api-manifest.json +177 -15
  2. package/dist/api/core/geom/create/index.d.ts +559 -86
  3. package/dist/api/core/geom/create/index.d.ts.map +1 -1
  4. package/dist/api/core/geom/query/brep.d.ts +50 -0
  5. package/dist/api/core/geom/query/brep.d.ts.map +1 -1
  6. package/dist/api/core/geom/query/curve.d.ts +58 -35
  7. package/dist/api/core/geom/query/curve.d.ts.map +1 -1
  8. package/dist/api/core/geom/query/edge.d.ts +2 -2
  9. package/dist/api/core/geom/query/face.d.ts +45 -0
  10. package/dist/api/core/geom/query/face.d.ts.map +1 -1
  11. package/dist/api/core/geom/update/curve.d.ts +5 -5
  12. package/dist/api/core/geom/update/profile.d.ts +1 -1
  13. package/dist/api/design/family.d.ts +152 -8
  14. package/dist/api/design/family.d.ts.map +1 -1
  15. package/dist/api/design/query/geometry/index.d.ts +27 -1
  16. package/dist/api/design/query/geometry/index.d.ts.map +1 -1
  17. package/dist/api/design/query/index.d.ts +54 -0
  18. package/dist/api/design/query/index.d.ts.map +1 -1
  19. package/dist/api/design/query/spaces.d.ts +5 -5
  20. package/dist/api/design/update/index.d.ts +87 -0
  21. package/dist/api/design/update/index.d.ts.map +1 -1
  22. package/dist/api/entity/referenceLine.d.ts +2 -2
  23. package/dist/api/entity/referenceLine.d.ts.map +1 -1
  24. package/dist/api/entity/space.d.ts +5 -4
  25. package/dist/api/entity/space.d.ts.map +1 -1
  26. package/dist/api/entity/story.d.ts +4 -4
  27. package/dist/api/program/spreadsheet.d.ts +4 -4
  28. package/dist/handles.d.ts +12 -3
  29. package/dist/handles.d.ts.map +1 -1
  30. package/dist/index.cjs +3044 -2707
  31. package/dist/index.cjs.map +1 -1
  32. package/dist/index.d.ts +1 -0
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +3007 -2707
  35. package/dist/index.js.map +1 -1
  36. package/dist/massParameters.d.ts +319 -0
  37. package/dist/massParameters.d.ts.map +1 -0
  38. package/package.json +1 -1
  39. package/src/api/core/geom/create/index.ts +588 -84
  40. package/src/api/core/geom/query/brep.ts +51 -0
  41. package/src/api/core/geom/query/curve.ts +25 -2
  42. package/src/api/core/geom/query/edge.ts +2 -2
  43. package/src/api/core/geom/query/face.ts +49 -0
  44. package/src/api/design/family.ts +164 -8
  45. package/src/api/design/query/geometry/index.ts +29 -0
  46. package/src/api/design/query/index.ts +52 -0
  47. package/src/api/design/update/index.ts +94 -0
  48. package/src/handles.ts +15 -3
  49. package/src/index.ts +1 -0
  50. package/src/massParameters.ts +472 -0
  51. package/test/massParameters.test.mjs +500 -0
package/api-manifest.json CHANGED
@@ -729,8 +729,9 @@
729
729
  {
730
730
  "path": "core.geom.create.brepFromChamfer",
731
731
  "namespace": "core.geom.create",
732
- "summary": "Bevels the given straight edges of a solid with a symmetric planar cut. Host API call — returns a new {@linkcode BrepHandle}; the input brep is read-only.",
732
+ "summary": "Bevels the given edges of a solid with a symmetric planar cut. Host API call — returns a new {@linkcode BrepHandle}; the input brep is read-only.",
733
733
  "examplePrompts": [
734
+ "Chamfer the top edge of the cylinder",
734
735
  "Bevel these edges by 100mm",
735
736
  "Chamfer the top edges of the plinth",
736
737
  "Cut a 45-degree flat along the corners of this mass\n\n# Example\n```ts\nconst brep = await snaptrude.core.geom.create.brepFromExtrusion(contour, { x: 0, y: 1, z: 0 }, 3)\nconst edges = await snaptrude.core.geom.query.brep.listEdges(brep)\nconst beveled = await snaptrude.core.geom.create.brepFromChamfer(brep, [edges[0]], 0.1)\n```"
@@ -738,6 +739,28 @@
738
739
  "argsType": "BrepHandle",
739
740
  "resultType": "BrepHandle"
740
741
  },
742
+ {
743
+ "path": "core.geom.create.brepFromCone",
744
+ "namespace": "core.geom.create",
745
+ "summary": "Create a solid **cone or frustum** B-rep: bottom-cap centre, axis, base radius, height, and an optional top radius (default 0 — a full cone to a point; > 0 — a frustum / tapered column). Host API call — returns a {@linkcode BrepHandle}; commit with `design.create.massFromBrep`. Carries a creation recipe (radii + height), editable through `design.update.parameters`.",
746
+ "examplePrompts": [
747
+ "Create a cone roof 4m wide and 3m tall",
748
+ "Make a tapered column narrowing from 1m to 0.6m\n\n# Example\n```ts\nconst roof = await snaptrude.core.geom.create.brepFromCone(\n{ x: 0, y: 9, z: 0 },\n{ x: 0, y: 1, z: 0 },\n2,\n3,\n)\n```"
749
+ ],
750
+ "argsType": "Vec3Components",
751
+ "resultType": "BrepHandle"
752
+ },
753
+ {
754
+ "path": "core.geom.create.brepFromCylinder",
755
+ "namespace": "core.geom.create",
756
+ "summary": "Create a solid **cylinder** B-rep from its bottom-cap centre, axis direction, radius and height. Host API call — returns a {@linkcode BrepHandle}; commit with `design.create.massFromBrep`. The bottom cap sits AT `base` and the solid extends `height` along `axis` — place `base` on the floor and use axis `{x: 0, y: 1, z: 0}` for an upright column. Carries a creation recipe (radius, height), editable through `design.update.parameters`.",
757
+ "examplePrompts": [
758
+ "Create a cylinder 2m across and 4m tall",
759
+ "Add a circular column here\n\n# Example\n```ts\nconst brep = await snaptrude.core.geom.create.brepFromCylinder(\n{ x: 0, y: 0, z: 0 },\n{ x: 0, y: 1, z: 0 },\n1,\n4,\n)\nconst column = await snaptrude.design.create.massFromBrep(brep, \"Column\")\n```"
760
+ ],
761
+ "argsType": "Vec3Components",
762
+ "resultType": "BrepHandle"
763
+ },
741
764
  {
742
765
  "path": "core.geom.create.brepFromExtrusion",
743
766
  "namespace": "core.geom.create",
@@ -765,11 +788,12 @@
765
788
  {
766
789
  "path": "core.geom.create.brepFromFillet",
767
790
  "namespace": "core.geom.create",
768
- "summary": "Rounds the given straight edges of a solid with a constant radius. Host API call — returns a new {@linkcode BrepHandle}; the input brep is read-only.",
791
+ "summary": "Rounds the given edges of a solid with a constant radius. Host API call — returns a new {@linkcode BrepHandle}; the input brep is read-only.",
769
792
  "examplePrompts": [
770
- "Round the edges of this mass",
793
+ "Round the rim of the column with 200 mm",
794
+ "Soften where the dome meets the wall",
771
795
  "Fillet the corners of the podium with a 0.5m radius",
772
- "Soften the vertical edges of this tower\n\n# Example\n```ts\nconst brep = await snaptrude.core.geom.create.brepFromExtrusion(contour, { x: 0, y: 1, z: 0 }, 3)\nconst edges = await snaptrude.core.geom.query.brep.listEdges(brep)\nconst rounded = await snaptrude.core.geom.create.brepFromFillet(brep, [edges[0]], 0.3)\n```"
796
+ "Soften the vertical edges of this tower\n\n# Example\n```ts\n// Rim = every edge between the cylinder side and a plane cap\nconst edges = await snaptrude.core.geom.query.brep.listEdges(column)\nconst rim = []\nfor (const edge of edges) {\nconst faces = await snaptrude.core.geom.query.edge.listFaces(edge)\nconst kinds = await Promise.all(\nfaces.map((f) => snaptrude.core.geom.query.face.getSurfaceKind(f)),\n)\nif (kinds.includes(\"cylinder\") && kinds.includes(\"plane\")) rim.push(edge)\n}\nconst rounded = await snaptrude.core.geom.create.brepFromFillet(column, rim, 0.787) // 200 mm\n```"
773
797
  ],
774
798
  "argsType": "BrepHandle",
775
799
  "resultType": "BrepHandle"
@@ -820,6 +844,7 @@
820
844
  "namespace": "core.geom.create",
821
845
  "summary": "Grows or shrinks a solid by offsetting every face — positive distance moves faces outward, negative moves them inward. Host API call — returns a new {@linkcode BrepHandle}; the input brep is read-only.",
822
846
  "examplePrompts": [
847
+ "Thicken the torus ring by 100 mm",
823
848
  "Grow this solid by 0.5m in every direction",
824
849
  "Shrink this mass by 200mm",
825
850
  "Offset the building envelope outward by 1m\n\n# Example\n```ts\nconst brep = await snaptrude.core.geom.create.brepFromExtrusion(contour, { x: 0, y: 1, z: 0 }, 3)\nconst grown = await snaptrude.core.geom.create.brepFromOffset(brep, 0.5)\n```"
@@ -830,11 +855,13 @@
830
855
  {
831
856
  "path": "core.geom.create.brepFromRevolution",
832
857
  "namespace": "core.geom.create",
833
- "summary": "Revolves a planar profile about an axis to make a solid of revolution — a full turn by default. Host API call — returns a new {@linkcode BrepHandle}; the input contour is read-only. Holes in the profile are allowed. Profile segments must stay parallel or perpendicular to the axis inclined or arc segments would revolve into surfaces Snaptrude cannot represent.",
858
+ "summary": "Revolves a planar profile about an axis to make a solid of revolution — a full turn by default. Host API call — returns a new {@linkcode BrepHandle}; the input contour is read-only. Holes in the profile are allowed, and segments may run at any angle to the axis: an inclined segment revolves into a cone, an arc into a sphere or torus section. This is the general route to domes, vases, columns and rotundas.",
834
859
  "examplePrompts": [
835
860
  "Create a dome from this section",
836
861
  "Revolve this profile 360 degrees around the vertical axis",
837
- "Build a rotunda by revolving this wall section\n\n# Example\n```ts\n// A cylinder: revolve a 2m-wide, 3m-tall rectangle about the Y axis at its edge\nconst rect = await snaptrude.core.geom.create.profileFromLinePoints([\nawait snaptrude.core.math.vec3.new(0, 0, 0),\nawait snaptrude.core.math.vec3.new(2, 0, 0),\nawait snaptrude.core.math.vec3.new(2, 3, 0),\nawait snaptrude.core.math.vec3.new(0, 3, 0),\n])\nconst profile = await snaptrude.core.geom.create.contourFromProfile(rect)\nconst cylinder = await snaptrude.core.geom.create.brepFromRevolution(\nprofile,\n{ x: 0, y: 0, z: 0 },\n{ x: 0, y: 1, z: 0 },\n)\n```"
862
+ "Build a rotunda by revolving this wall section",
863
+ "Make a dome by revolving a quarter-circle about the vertical axis",
864
+ "Turn this curved outline into a vase\n\n# Example\n```ts\n// A cylinder: revolve a 2m-wide, 3m-tall rectangle about the Y axis at\n// its edge — the left edge sits ON the axis, which is legal.\nconst rect = await snaptrude.core.geom.create.profileFromLinePoints([\nawait snaptrude.core.math.vec3.new(0, 0, 0),\nawait snaptrude.core.math.vec3.new(2, 0, 0),\nawait snaptrude.core.math.vec3.new(2, 3, 0),\nawait snaptrude.core.math.vec3.new(0, 3, 0),\n])\nconst profile = await snaptrude.core.geom.create.contourFromProfile(rect)\nconst cylinder = await snaptrude.core.geom.create.brepFromRevolution(\nprofile,\n{ x: 0, y: 0, z: 0 },\n{ x: 0, y: 1, z: 0 },\n)\n```"
838
865
  ],
839
866
  "argsType": "ContourHandle",
840
867
  "resultType": "BrepHandle"
@@ -844,13 +871,25 @@
844
871
  "namespace": "core.geom.create",
845
872
  "summary": "Hollows a solid into constant-thickness walls, removing the given faces as openings. Host API call — returns a new {@linkcode BrepHandle}; the input brep is read-only. The outer surface is kept and the walls grow inward.",
846
873
  "examplePrompts": [
874
+ "Hollow the dome into a 300 mm shell, open at the base",
847
875
  "Hollow this mass into 200mm walls",
848
876
  "Shell this form with the top face open",
849
- "Turn this solid tower into a tube open at both ends\n\n# Example\n```ts\nconst brep = await snaptrude.core.geom.create.brepFromExtrusion(contour, { x: 0, y: 1, z: 0 }, 3)\nconst faces = await snaptrude.core.geom.query.brep.listFaces(brep)\nconst hollow = await snaptrude.core.geom.create.brepFromShell(brep, [faces[0]], 0.2)\n```"
877
+ "Turn this solid tower into a tube open at both ends\n\n# Example\n```ts\n// Open the dome at its flat base: the one face whose surface is a plane\nconst faces = await snaptrude.core.geom.query.brep.listFaces(dome)\nconst base = []\nfor (const face of faces) {\nif ((await snaptrude.core.geom.query.face.getSurfaceKind(face)) === \"plane\") base.push(face)\n}\nconst hollow = await snaptrude.core.geom.create.brepFromShell(dome, base, 1.181) // 300 mm\n```"
850
878
  ],
851
879
  "argsType": "BrepHandle",
852
880
  "resultType": "BrepHandle"
853
881
  },
882
+ {
883
+ "path": "core.geom.create.brepFromSphere",
884
+ "namespace": "core.geom.create",
885
+ "summary": "Create a solid **sphere** B-rep from a centre and radius. Host API call — returns a {@linkcode BrepHandle}; commit it to the scene with `design.create.massFromBrep`. The result carries an exact spherical surface (not a faceted approximation) and a creation recipe — read the committed mass's parameters back with `design.query.getParameters` and edit them with `design.update.parameters`.",
886
+ "examplePrompts": [
887
+ "Create a sphere of radius 5 at the origin",
888
+ "Add a 3m ball on top of the tower\n\n# Example\n```ts\nconst brep = await snaptrude.core.geom.create.brepFromSphere({ x: 0, y: 5, z: 0 }, 5)\nconst mass = await snaptrude.design.create.massFromBrep(brep, \"Sphere\")\n```"
889
+ ],
890
+ "argsType": "Vec3Components",
891
+ "resultType": "BrepHandle"
892
+ },
854
893
  {
855
894
  "path": "core.geom.create.brepFromSubtraction",
856
895
  "namespace": "core.geom.create",
@@ -866,7 +905,7 @@
866
905
  {
867
906
  "path": "core.geom.create.brepFromSweep",
868
907
  "namespace": "core.geom.create",
869
- "summary": "Sweeps a planar profile along a polyline path, with mitred corners at each bend. Host API call — returns a new {@linkcode BrepHandle}; the input contour is read-only. The profile must be hole-free and must not lie in a plane containing the first path segment's direction. Repeating the first point as the last closes the path into a ring solid (a picture frame): closed paths must be flat and straight-segmented and take a straight-edged (arc-free) profile — the ring's cross-section is the authored profile projected along the first leg onto the first mitre plane, so a profile not perpendicular to the first leg appears sheared. An optional scale law tapers the sweep: `startScale`/`endScale` interpolate linearly by arc length, or `scales` gives one factor per path point (scaling is about the profile centroid). A uniform scale (all factors equal) works on any path today's sweep accepts; a varying scale takes straight (collinear) open paths with straight-edged profiles — tapering across a bend or along an arc edge would create faces Snaptrude cannot represent and throws (sweep each straight run separately and union the results instead). An optional `transition` picks the corner treatment: `\"miter\"` (default) is today's sharp mitred bend; `{ bevel: b }` chamfers each turning corner by cutting `b` back along both adjacent legs (works on open and closed paths — each leg must be long enough for its cuts). On a corner-less path `transition` has no effect, and the varying-scale lane takes straight paths, so it never sees a corner.",
908
+ "summary": "Sweeps a planar profile along a polyline path, with mitred corners at each bend. Host API call — returns a new {@linkcode BrepHandle}; the input contour is read-only. The profile must be hole-free and must not lie in a plane containing the first path segment's direction. Repeating the first point as the last closes the path into a ring solid (a picture frame): closed paths must be flat and straight-segmented and take a straight-edged (arc-free) profile — the ring's cross-section is the authored profile projected along the first leg onto the first mitre plane, so a profile not perpendicular to the first leg appears sheared. An optional scale law tapers the sweep: `startScale`/`endScale` interpolate linearly by arc length, or `scales` gives one factor per path point (scaling is about the profile centroid). A uniform scale (all factors equal) works on any path today's sweep accepts; a varying scale takes straight (collinear) open paths with straight-edged profiles — tapering across a bend or along an arc edge would create faces Snaptrude cannot represent and throws (sweep each straight run separately and union the results instead). An optional `transition` picks the corner treatment: `\"miter\"` (default) is today's sharp mitred bend; `\"round\"` carries the section around each turning corner on a tangent circular arc, so the corner patch is a real curved (cylindrical) surface rather than a flat cut (open paths only — `\"round\"` on a closed ring path is refused); `{ bevel: b }` chamfers each turning corner by cutting `b` back along both adjacent legs (works on open and closed paths — each leg must be long enough for its cuts). On a corner-less path `transition` has no effect, and the varying-scale lane takes straight paths, so it never sees a corner.",
870
909
  "examplePrompts": [
871
910
  "Sweep this profile along the corridor path",
872
911
  "Extrude the railing section along this route",
@@ -874,11 +913,23 @@
874
913
  "Sweep a frame profile around a closed rectangular loop",
875
914
  "Taper this duct from 1x1 to 2x2 along its run",
876
915
  "Sweep a column section that narrows toward the top",
877
- "Chamfer the corners of this swept frame by 200mm\n\n# Example\n```ts\nconst rect = await snaptrude.core.geom.create.profileRect(0.4, 0.4)\nconst profile = await snaptrude.core.geom.create.contourFromProfile(rect)\n// profileRect lies in the XZ plane, so the path must START out of that\n// plane (here: straight up), then it can run horizontally.\nconst duct = await snaptrude.core.geom.create.brepFromSweep(profile, [\n{ x: 0, y: 0, z: 0 },\n{ x: 0, y: 2.8, z: 0 },\n{ x: 10, y: 2.8, z: 0 },\n])\n// A closed ring (picture frame): repeat the first point as the last\nconst frame = await snaptrude.core.geom.create.brepFromSweep(profile, [\n{ x: 0, y: 0, z: 0 },\n{ x: 0, y: 3, z: 0 },\n{ x: 4, y: 3, z: 0 },\n{ x: 4, y: 0, z: 0 },\n{ x: 0, y: 0, z: 0 },\n])\n// A tapered straight run: 0.4x0.4 at the start, 0.8x0.8 at the end\nconst flue = await snaptrude.core.geom.create.brepFromSweep(\nprofile,\n[\n{ x: 0, y: 0, z: 0 },\n{ x: 0, y: 10, z: 0 },\n],\n{ startScale: 1, endScale: 2 },\n)\n```"
916
+ "Chamfer the corners of this swept frame by 200mm",
917
+ "Sweep this handrail with rounded corners at the bends\n\n# Example\n```ts\nconst rect = await snaptrude.core.geom.create.profileRect(0.4, 0.4)\nconst profile = await snaptrude.core.geom.create.contourFromProfile(rect)\n// profileRect lies in the XZ plane, so the path must START out of that\n// plane (here: straight up), then it can run horizontally.\nconst duct = await snaptrude.core.geom.create.brepFromSweep(profile, [\n{ x: 0, y: 0, z: 0 },\n{ x: 0, y: 2.8, z: 0 },\n{ x: 10, y: 2.8, z: 0 },\n])\n// A closed ring (picture frame): repeat the first point as the last\nconst frame = await snaptrude.core.geom.create.brepFromSweep(profile, [\n{ x: 0, y: 0, z: 0 },\n{ x: 0, y: 3, z: 0 },\n{ x: 4, y: 3, z: 0 },\n{ x: 4, y: 0, z: 0 },\n{ x: 0, y: 0, z: 0 },\n])\n// A tapered straight run: 0.4x0.4 at the start, 0.8x0.8 at the end\nconst flue = await snaptrude.core.geom.create.brepFromSweep(\nprofile,\n[\n{ x: 0, y: 0, z: 0 },\n{ x: 0, y: 10, z: 0 },\n],\n{ startScale: 1, endScale: 2 },\n)\n```"
878
918
  ],
879
919
  "argsType": "ContourHandle",
880
920
  "resultType": "BrepHandle"
881
921
  },
922
+ {
923
+ "path": "core.geom.create.brepFromTorus",
924
+ "namespace": "core.geom.create",
925
+ "summary": "Create a solid **torus** (ring / donut) B-rep from its centre, plane normal, ring radius and tube radius. Host API call — returns a {@linkcode BrepHandle}; commit with `design.create.massFromBrep`. `majorRadius` is centre-to-tube-centre; `minorRadius` is the tube's own radius and must be strictly smaller. Carries a creation recipe, editable through `design.update.parameters`.",
926
+ "examplePrompts": [
927
+ "Create a donut-shaped ring 10m across with a 1m tube",
928
+ "Add a torus canopy around the tower\n\n# Example\n```ts\nconst ring = await snaptrude.core.geom.create.brepFromTorus(\n{ x: 0, y: 6, z: 0 },\n{ x: 0, y: 1, z: 0 },\n5,\n1,\n)\n```"
929
+ ],
930
+ "argsType": "Vec3Components",
931
+ "resultType": "BrepHandle"
932
+ },
882
933
  {
883
934
  "path": "core.geom.create.brepFromUnion",
884
935
  "namespace": "core.geom.create",
@@ -965,6 +1016,18 @@
965
1016
  "argsType": "Vec3Handle[]",
966
1017
  "resultType": "ProfileHandle"
967
1018
  },
1019
+ {
1020
+ "path": "core.geom.create.profileFromSplinePoints",
1021
+ "namespace": "core.geom.create",
1022
+ "summary": "Create a CLOSED smooth profile passing through each point, in order, with the loop closed smoothly back from the last point to the first (do NOT repeat the first point). Host API call — returns a handle. This is the closed counterpart of {@linkcode PluginGeomCreateApi.splineFromPoints} and the one-call route from points to an extrudable outline: wrap in `contourFromProfile` and extrude/loft/sweep as usual.",
1023
+ "examplePrompts": [
1024
+ "Make a blob-shaped floor plate through these points",
1025
+ "Organic curved outline through these corners",
1026
+ "Freeform podium profile\n\n# Example\n```ts\nconst profile = await snaptrude.core.geom.create.profileFromSplinePoints([p0, p1, p2, p3, p4])\nconst contour = await snaptrude.core.geom.create.contourFromProfile(profile)\nconst brep = await snaptrude.core.geom.create.brepFromExtrusion(contour, { x: 0, y: 1, z: 0 }, 3)\nconst podium = await snaptrude.design.create.massFromBrep(brep, \"Podium\")\n```"
1027
+ ],
1028
+ "argsType": "Vec3Handle[]",
1029
+ "resultType": "ProfileHandle"
1030
+ },
968
1031
  {
969
1032
  "path": "core.geom.create.profileRect",
970
1033
  "namespace": "core.geom.create",
@@ -976,6 +1039,29 @@
976
1039
  "argsType": "number",
977
1040
  "resultType": "ProfileHandle"
978
1041
  },
1042
+ {
1043
+ "path": "core.geom.create.splineFromControlPoints",
1044
+ "namespace": "core.geom.create",
1045
+ "summary": "Create an open NURBS curve DEFINED BY control points — the curve is pulled TOWARD the interior points, not through them; it starts at the first point and ends at the last. Knots are computed for you (clamped, uniform) — there is no knot-vector argument. For a curve that must pass THROUGH given points use {@linkcode PluginGeomCreateApi.splineFromPoints}.",
1046
+ "examplePrompts": [
1047
+ "Draw a smooth curve controlled by these four points",
1048
+ "Rebuild this edge from its control polygon\n\n# Example\n```ts\nconst curve = await snaptrude.core.geom.create.splineFromControlPoints([p0, p1, p2, p3])\n// Quadratic instead of the default cubic\nconst tighter = await snaptrude.core.geom.create.splineFromControlPoints(\n[p0, p1, p2, p3],\n{ degree: 2 },\n)\n```"
1049
+ ],
1050
+ "argsType": "Vec3Handle[]",
1051
+ "resultType": "SplineHandle"
1052
+ },
1053
+ {
1054
+ "path": "core.geom.create.splineFromPoints",
1055
+ "namespace": "core.geom.create",
1056
+ "summary": "Create an open NURBS curve passing exactly THROUGH each point, in order (centripetal Catmull-Rom fit → clamped cubic B-spline; C1-smooth, no cusps on uneven spacing). Host API call — returns a handle. The points are interpolated, NOT control points. For a CLOSED smooth loop use {@linkcode PluginGeomCreateApi.profileFromSplinePoints} — closed splines exist only as profiles, never as a single curve handle.",
1057
+ "examplePrompts": [
1058
+ "Draw a smooth curve through these points",
1059
+ "Make a wavy edge that passes through A, B, C and D",
1060
+ "Freeform curved wall path through these clicks\n\n# Example\n```ts\nconst spline = await snaptrude.core.geom.create.splineFromPoints([p0, p1, p2, p3])\n// Mixed profile: smooth top, straight closing base\nconst base = await snaptrude.core.geom.create.line(p3, p0)\nconst profile = await snaptrude.core.geom.create.profileFromCurves([spline, base])\n```"
1061
+ ],
1062
+ "argsType": "Vec3Handle[]",
1063
+ "resultType": "SplineHandle"
1064
+ },
979
1065
  {
980
1066
  "path": "core.geom.delete.contour",
981
1067
  "namespace": "core.geom.delete",
@@ -1101,10 +1187,11 @@
1101
1187
  "Read the radius of this curved edge",
1102
1188
  "Is this edge straight or an arc?",
1103
1189
  "Get the exact start and end points of this edge",
1104
- "Measure the length of each edge of this mass\n\n# Example\n```ts\nconst [mass] = await snaptrude.design.query.listMasses()\nconst brep = await snaptrude.design.query.geometry.getBrep(mass)\nif (brep) {\nconst edges = await snaptrude.core.geom.query.brep.listEdges(brep)\nfor (const edge of edges) {\nconst curve = await snaptrude.core.geom.query.brep.getEdgeCurve(brep, edge)\nif (curve.type === \"arc\") console.log(\"arc radius:\", curve.radius)\n}\n}\n```"
1190
+ "Measure the length of each edge of this mass",
1191
+ "Read the control points of this curved edge\n\n# Example\n```ts\nconst [mass] = await snaptrude.design.query.listMasses()\nconst brep = await snaptrude.design.query.geometry.getBrep(mass)\nif (brep) {\nconst edges = await snaptrude.core.geom.query.brep.listEdges(brep)\nfor (const edge of edges) {\nconst curve = await snaptrude.core.geom.query.brep.getEdgeCurve(brep, edge)\nif (curve.type === \"arc\") console.log(\"arc radius:\", curve.radius)\n}\n}\n```"
1105
1192
  ],
1106
1193
  "argsType": "BrepHandle",
1107
- "resultType": "| { type: \"line\"; startPoint: Vec3Components; endPoint: Vec3Components; length: number }\n | {\n type: \"arc\"\n startPoint: Vec3Components\n endPoint: Vec3Components\n centre: Vec3Components\n axis: Vec3Components\n radius: number\n length: number\n }\n | {\n type: \"circle\"\n centre: Vec3Components\n axis: Vec3Components\n radius: number\n length: number\n }"
1194
+ "resultType": "| { type: \"line\"; startPoint: Vec3Components; endPoint: Vec3Components; length: number }\n | {\n type: \"arc\"\n startPoint: Vec3Components\n endPoint: Vec3Components\n centre: Vec3Components\n axis: Vec3Components\n radius: number\n length: number\n }\n | {\n type: \"circle\"\n centre: Vec3Components\n axis: Vec3Components\n radius: number\n length: number\n }\n | {\n type: \"spline\"\n startPoint: Vec3Components\n endPoint: Vec3Components\n degree: number\n controlPoints: Vec3Components[]\n /** Expanded by multiplicity: `controlPoints.length + degree + 1` entries. */\n knots: number[]\n length: number\n }"
1108
1195
  },
1109
1196
  {
1110
1197
  "path": "core.geom.query.brep.getFaceCount",
@@ -1138,6 +1225,18 @@
1138
1225
  "argsType": "BrepHandle",
1139
1226
  "resultType": "Vec3Components"
1140
1227
  },
1228
+ {
1229
+ "path": "core.geom.query.brep.getVolume",
1230
+ "namespace": "core.geom.query.brep",
1231
+ "summary": "Get the enclosed **volume** of a closed solid, integrated from its exact surfaces. Curved faces are measured analytically, not from their tessellation — a real sphere of radius 5 reports 523.6, whatever its triangle count. That makes this the reliable way to confirm a solid is the shape you intended (a torus should measure 2·π²·R·r²).",
1232
+ "examplePrompts": [
1233
+ "What is the volume of this mass?",
1234
+ "How much concrete is in this shape?",
1235
+ "Check the volume of the dome I just made\n\n# Example\n```ts\nconst [mass] = await snaptrude.design.query.listMasses()\nconst brep = await snaptrude.design.query.geometry.getBrep(mass)\nif (brep) {\nconst volume = await snaptrude.core.geom.query.brep.getVolume(brep)\nconsole.log(\"volume:\", volume)\n}\n```"
1236
+ ],
1237
+ "argsType": "BrepHandle",
1238
+ "resultType": "number"
1239
+ },
1141
1240
  {
1142
1241
  "path": "core.geom.query.brep.hasEdge",
1143
1242
  "namespace": "core.geom.query.brep",
@@ -1742,7 +1841,7 @@
1742
1841
  {
1743
1842
  "path": "core.geom.query.edge.getCurve",
1744
1843
  "namespace": "core.geom.query.edge",
1745
- "summary": "Get the underlying curve geometry of an edge (a line or arc).",
1844
+ "summary": "Get the underlying curve geometry of an edge (a line, arc or spline).",
1746
1845
  "examplePrompts": [],
1747
1846
  "argsType": "EdgeHandle",
1748
1847
  "resultType": "CurveHandle | null"
@@ -1819,6 +1918,19 @@
1819
1918
  "argsType": "FaceHandle",
1820
1919
  "resultType": "number"
1821
1920
  },
1921
+ {
1922
+ "path": "core.geom.query.face.getSurfaceKind",
1923
+ "namespace": "core.geom.query.face",
1924
+ "summary": "Read what KIND of surface a face lies on. This is the one read that tells a genuinely curved face from a faceted approximation of one: every face of a 200-triangle \"dome\" answers `\"plane\"`, while a real dome has faces answering `\"sphere\"`. Use it to confirm a curved solid actually came out curved.",
1925
+ "examplePrompts": [
1926
+ "Is this face flat or curved?",
1927
+ "Check that this dome is a real sphere, not a faceted approximation",
1928
+ "What kind of surface is this face?",
1929
+ "How many curved faces does this mass have?\n\n# Example\n```ts\nconst [mass] = await snaptrude.design.query.listMasses()\nconst brep = await snaptrude.design.query.geometry.getBrep(mass)\nif (brep) {\nconst faces = await snaptrude.core.geom.query.brep.listFaces(brep)\nconst kinds = []\nfor (const face of faces) kinds.push(await snaptrude.core.geom.query.face.getSurfaceKind(face))\nconsole.log(\"spherical faces:\", kinds.filter((k) => k === \"sphere\").length)\n}\n```"
1930
+ ],
1931
+ "argsType": "FaceHandle",
1932
+ "resultType": "\"plane\" | \"cylinder\" | \"cone\" | \"sphere\" | \"torus\" | \"spline\" | null"
1933
+ },
1822
1934
  {
1823
1935
  "path": "core.geom.query.face.hasHoles",
1824
1936
  "namespace": "core.geom.query.face",
@@ -4769,6 +4881,17 @@
4769
4881
  "argsType": null,
4770
4882
  "resultType": "PluginFamilyBundle | null"
4771
4883
  },
4884
+ {
4885
+ "path": "design.family.getParameters",
4886
+ "namespace": "design.family",
4887
+ "summary": "Read a placed component's current parameter values and its sheet.",
4888
+ "examplePrompts": [
4889
+ "What size is that table?",
4890
+ "Show me the parameters on this partition\n\n# Example\n```ts\nconst { values, parameters } = await snaptrude.design.family.getParameters({ component })\n```"
4891
+ ],
4892
+ "argsType": "PluginDesignFamilyGetParametersArgs",
4893
+ "resultType": "PluginFamilyInstanceParameters | null"
4894
+ },
4772
4895
  {
4773
4896
  "path": "design.family.getReference",
4774
4897
  "namespace": "design.family",
@@ -4793,12 +4916,13 @@
4793
4916
  {
4794
4917
  "path": "design.family.place",
4795
4918
  "namespace": "design.family",
4796
- "summary": "Arm placement with the prepared family.",
4919
+ "summary": "Put a family into the model — either the prepared draft or any family from {@linkcode PluginDesignFamilyApi.list}.",
4797
4920
  "examplePrompts": [
4798
4921
  "Place it in the model",
4799
- "Let me put this on the facade\n\n# Example\n```ts\nawait snaptrude.design.family.place()\n```"
4922
+ "Put a louvre screen at the origin",
4923
+ "Copy that table two metres to the right\n\n# Example\n```ts\n// positioned — geometry exists when this resolves\nconst { component } = await snaptrude.design.family.place({\nid: \"revit:gypsum-stud-partition~90ad72\",\nposition: { x: 0, y: 0, z: 0 },\nrotation: 90,\n})\nawait snaptrude.design.transform.move([component], { x: 2, y: 0, z: 0 })\n\n// interactive — the user clicks\nawait snaptrude.design.family.place()\n```"
4800
4924
  ],
4801
- "argsType": null,
4925
+ "argsType": "PluginDesignFamilyPlaceArgs",
4802
4926
  "resultType": "PluginFamilyPlaceResult"
4803
4927
  },
4804
4928
  {
@@ -4813,6 +4937,17 @@
4813
4937
  "argsType": "PluginDesignFamilyPrepareArgs",
4814
4938
  "resultType": "PluginFamilyPrepareResult"
4815
4939
  },
4940
+ {
4941
+ "path": "design.family.setParameters",
4942
+ "namespace": "design.family",
4943
+ "summary": "Change a placed component's parameters and rebuild its geometry in place.",
4944
+ "examplePrompts": [
4945
+ "Make that table seat 8",
4946
+ "Change the stud spacing to 400\n\n# Example\n```ts\nawait snaptrude.design.family.setParameters({ component, values: { seats: 8 } })\n```"
4947
+ ],
4948
+ "argsType": "PluginDesignFamilySetParametersArgs",
4949
+ "resultType": "PluginFamilyInstanceParameters"
4950
+ },
4816
4951
  {
4817
4952
  "path": "design.furniture.exists",
4818
4953
  "namespace": "design.furniture",
@@ -5207,6 +5342,7 @@
5207
5342
  "summary": "Get the boundary representation (B-rep) of a scene component — the solid geometry (faces, edges, vertices) behind a wall, slab, room or any other scene entity, as a reusable {@linkcode BrepHandle} for the `core.geom.query.brep.*` reads.",
5208
5343
  "examplePrompts": [
5209
5344
  "Get the 3D solid geometry of the selected wall",
5345
+ "Round the top rim of this column and put it back where it is",
5210
5346
  "How many faces does this mass have?",
5211
5347
  "Inspect the mesh of this slab so I can look at its faces and edges",
5212
5348
  "Read the vertices of the selected column's geometry"
@@ -5318,6 +5454,19 @@
5318
5454
  "argsType": "ComponentHandle",
5319
5455
  "resultType": "string"
5320
5456
  },
5457
+ {
5458
+ "path": "design.query.getParameters",
5459
+ "namespace": "design.query",
5460
+ "summary": "Read a mass's creation-parameter record — the recipe it was built from (`kind` plus the values that constructor was called with). Present on masses committed from a `core.geom.create` brep constructor that carries a recipe: {@linkcode MassParametersRecord} covers the four primitives (sphere, cylinder, cone, torus), extrusions, revolutions, lofts and sweeps.",
5461
+ "examplePrompts": [
5462
+ "What radius is this sphere?",
5463
+ "Is this mass parametric?",
5464
+ "Read back the dome's creation parameters",
5465
+ "How tall was this cylinder made?\n\n# Example\n```ts\nconst [mass] = await snaptrude.design.query.listMasses({ isSelected: true })\nconst params = await snaptrude.design.query.getParameters(mass)\nif (params?.kind === \"sphere\") console.log(\"radius:\", params.values.radius)\n```"
5466
+ ],
5467
+ "argsType": "ComponentHandle",
5468
+ "resultType": "MassParametersRecord | null"
5469
+ },
5321
5470
  {
5322
5471
  "path": "design.query.getProperties",
5323
5472
  "namespace": "design.query",
@@ -5895,6 +6044,19 @@
5895
6044
  "argsType": "ComponentHandle",
5896
6045
  "resultType": "PluginDesignChangeResult"
5897
6046
  },
6047
+ {
6048
+ "path": "design.update.parameters",
6049
+ "namespace": "design.update",
6050
+ "summary": "Edit a parametric mass by patching its creation recipe and rebuilding the solid in place — the mass keeps its id, storey, materials, position and linked copies; only the geometry changes. Read the current record with `design.query.getParameters` first.",
6051
+ "examplePrompts": [
6052
+ "Make the dome's radius 8 metres",
6053
+ "Raise the podium to 5 m",
6054
+ "Widen the vase — move its profile points 20 cm outward",
6055
+ "Change the fillet on the rounded column to 300 mm\n\n# Example\n```ts\n// { kind: \"sphere\", values: { centre, radius: 19.685 }, … }\nconst before = await snaptrude.design.query.getParameters(dome)\nconst after = await snaptrude.design.update.parameters(dome, { radius: 31.496 }) // 8 m in internal units\n\n// Fillet radius on a recorded result: read → edit → send the array back\nconst rec = await snaptrude.design.query.getParameters(column)\nconst operations = rec?.operations ?? []\nif (operations[0]?.op === \"fillet\") {\noperations[0].radius = 1.181\nawait snaptrude.design.update.parameters(column, { operations })\n}\n```"
6056
+ ],
6057
+ "argsType": "ComponentHandle",
6058
+ "resultType": "MassParametersRecord"
6059
+ },
5898
6060
  {
5899
6061
  "path": "design.update.roof",
5900
6062
  "namespace": "design.update",