@snaptrude/plugin-core 0.0.0-dev-20260708130115 → 0.0.0-dev-20260827194031

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 (261) hide show
  1. package/CHANGELOG.md +152 -1
  2. package/api-manifest.json +3643 -276
  3. package/dist/api/analysis/daylight.d.ts +603 -0
  4. package/dist/api/analysis/daylight.d.ts.map +1 -0
  5. package/dist/api/analysis/heatmaps.d.ts +658 -0
  6. package/dist/api/analysis/heatmaps.d.ts.map +1 -0
  7. package/dist/api/analysis/illuminance.d.ts +145 -0
  8. package/dist/api/analysis/illuminance.d.ts.map +1 -0
  9. package/dist/api/analysis/index.d.ts +59 -0
  10. package/dist/api/analysis/index.d.ts.map +1 -0
  11. package/dist/api/analysis/shadows.d.ts +165 -0
  12. package/dist/api/analysis/shadows.d.ts.map +1 -0
  13. package/dist/api/analysis/solar.d.ts +249 -0
  14. package/dist/api/analysis/solar.d.ts.map +1 -0
  15. package/dist/api/analysis/sunlightHours.d.ts +208 -0
  16. package/dist/api/analysis/sunlightHours.d.ts.map +1 -0
  17. package/dist/api/analysis/sunpath.d.ts +80 -0
  18. package/dist/api/analysis/sunpath.d.ts.map +1 -0
  19. package/dist/api/analysis/weather.d.ts +193 -0
  20. package/dist/api/analysis/weather.d.ts.map +1 -0
  21. package/dist/api/core/camera/index.d.ts +261 -0
  22. package/dist/api/core/camera/index.d.ts.map +1 -0
  23. package/dist/api/core/comment/index.d.ts +105 -2
  24. package/dist/api/core/comment/index.d.ts.map +1 -1
  25. package/dist/api/core/geom/create/index.d.ts +840 -14
  26. package/dist/api/core/geom/create/index.d.ts.map +1 -1
  27. package/dist/api/core/geom/delete/index.d.ts +8 -2
  28. package/dist/api/core/geom/delete/index.d.ts.map +1 -1
  29. package/dist/api/core/geom/query/arc.d.ts +5 -5
  30. package/dist/api/core/geom/query/brep.d.ts +130 -18
  31. package/dist/api/core/geom/query/brep.d.ts.map +1 -1
  32. package/dist/api/core/geom/query/circle.d.ts +18 -18
  33. package/dist/api/core/geom/query/contour.d.ts +20 -20
  34. package/dist/api/core/geom/query/curve.d.ts +49 -49
  35. package/dist/api/core/geom/query/edge.d.ts +5 -5
  36. package/dist/api/core/geom/query/face.d.ts +16 -16
  37. package/dist/api/core/geom/query/halfedge.d.ts +8 -8
  38. package/dist/api/core/geom/query/profile.d.ts +19 -19
  39. package/dist/api/core/geom/query/vertex.d.ts +8 -8
  40. package/dist/api/core/geom/update/contour.d.ts +14 -14
  41. package/dist/api/core/geom/update/curve.d.ts +7 -7
  42. package/dist/api/core/geom/update/profile.d.ts +16 -16
  43. package/dist/api/core/handles/index.d.ts +210 -0
  44. package/dist/api/core/handles/index.d.ts.map +1 -0
  45. package/dist/api/core/index.d.ts +34 -0
  46. package/dist/api/core/index.d.ts.map +1 -1
  47. package/dist/api/core/io/export/index.d.ts +134 -0
  48. package/dist/api/core/io/export/index.d.ts.map +1 -0
  49. package/dist/api/core/io/import/index.d.ts +453 -0
  50. package/dist/api/core/io/import/index.d.ts.map +1 -0
  51. package/dist/api/core/io/index.d.ts +40 -0
  52. package/dist/api/core/io/index.d.ts.map +1 -0
  53. package/dist/api/core/io/job/index.d.ts +139 -0
  54. package/dist/api/core/io/job/index.d.ts.map +1 -0
  55. package/dist/api/core/io/query/index.d.ts +74 -0
  56. package/dist/api/core/io/query/index.d.ts.map +1 -0
  57. package/dist/api/core/io/terrain/index.d.ts +341 -0
  58. package/dist/api/core/io/terrain/index.d.ts.map +1 -0
  59. package/dist/api/core/io/underlay/index.d.ts +805 -0
  60. package/dist/api/core/io/underlay/index.d.ts.map +1 -0
  61. package/dist/api/core/layers.d.ts +7 -7
  62. package/dist/api/core/mode/index.d.ts +99 -0
  63. package/dist/api/core/mode/index.d.ts.map +1 -0
  64. package/dist/api/core/project/index.d.ts +68 -1
  65. package/dist/api/core/project/index.d.ts.map +1 -1
  66. package/dist/api/core/proposals/index.d.ts +531 -0
  67. package/dist/api/core/proposals/index.d.ts.map +1 -0
  68. package/dist/api/core/storeys/index.d.ts +265 -0
  69. package/dist/api/core/storeys/index.d.ts.map +1 -0
  70. package/dist/api/core/tags.d.ts +24 -0
  71. package/dist/api/core/tags.d.ts.map +1 -1
  72. package/dist/api/core/user.d.ts +44 -0
  73. package/dist/api/core/user.d.ts.map +1 -0
  74. package/dist/api/core/zoom/index.d.ts +4 -0
  75. package/dist/api/core/zoom/index.d.ts.map +1 -1
  76. package/dist/api/design/boolean/index.d.ts +4 -4
  77. package/dist/api/design/create/index.d.ts +568 -45
  78. package/dist/api/design/create/index.d.ts.map +1 -1
  79. package/dist/api/design/delete/index.d.ts +3 -0
  80. package/dist/api/design/delete/index.d.ts.map +1 -1
  81. package/dist/api/design/doors/index.d.ts +195 -0
  82. package/dist/api/design/doors/index.d.ts.map +1 -1
  83. package/dist/api/design/edit/index.d.ts +1 -1
  84. package/dist/api/design/erase/index.d.ts +2 -2
  85. package/dist/api/design/family.d.ts +493 -0
  86. package/dist/api/design/family.d.ts.map +1 -0
  87. package/dist/api/design/furniture/index.d.ts +181 -8
  88. package/dist/api/design/furniture/index.d.ts.map +1 -1
  89. package/dist/api/design/index.d.ts +98 -0
  90. package/dist/api/design/index.d.ts.map +1 -1
  91. package/dist/api/design/lock.d.ts +26 -0
  92. package/dist/api/design/lock.d.ts.map +1 -1
  93. package/dist/api/design/materials/index.d.ts +270 -16
  94. package/dist/api/design/materials/index.d.ts.map +1 -1
  95. package/dist/api/design/query/geometry/index.d.ts +112 -0
  96. package/dist/api/design/query/geometry/index.d.ts.map +1 -1
  97. package/dist/api/design/query/index.d.ts +289 -11
  98. package/dist/api/design/query/index.d.ts.map +1 -1
  99. package/dist/api/design/query/referenceLines.d.ts +45 -0
  100. package/dist/api/design/query/referenceLines.d.ts.map +1 -0
  101. package/dist/api/design/query/spaces.d.ts +181 -8
  102. package/dist/api/design/query/spaces.d.ts.map +1 -1
  103. package/dist/api/design/selection/index.d.ts +144 -0
  104. package/dist/api/design/selection/index.d.ts.map +1 -1
  105. package/dist/api/design/transform/index.d.ts +172 -10
  106. package/dist/api/design/transform/index.d.ts.map +1 -1
  107. package/dist/api/design/types/index.d.ts +181 -0
  108. package/dist/api/design/types/index.d.ts.map +1 -0
  109. package/dist/api/design/update/index.d.ts +553 -2
  110. package/dist/api/design/update/index.d.ts.map +1 -1
  111. package/dist/api/design/visibility.d.ts +126 -0
  112. package/dist/api/design/visibility.d.ts.map +1 -0
  113. package/dist/api/design/windows/index.d.ts +113 -2
  114. package/dist/api/design/windows/index.d.ts.map +1 -1
  115. package/dist/api/entity/buildableEnvelope.d.ts +4 -0
  116. package/dist/api/entity/buildableEnvelope.d.ts.map +1 -1
  117. package/dist/api/entity/referenceLine.d.ts +10 -2
  118. package/dist/api/entity/referenceLine.d.ts.map +1 -1
  119. package/dist/api/entity/space.d.ts +21 -21
  120. package/dist/api/entity/story.d.ts +242 -15
  121. package/dist/api/entity/story.d.ts.map +1 -1
  122. package/dist/api/index.d.ts +10 -0
  123. package/dist/api/index.d.ts.map +1 -1
  124. package/dist/api/presentation/aiInspiration.d.ts +25 -25
  125. package/dist/api/presentation/annotate.d.ts +467 -0
  126. package/dist/api/presentation/annotate.d.ts.map +1 -0
  127. package/dist/api/presentation/diagrams.d.ts +111 -8
  128. package/dist/api/presentation/diagrams.d.ts.map +1 -1
  129. package/dist/api/presentation/export.d.ts +108 -0
  130. package/dist/api/presentation/export.d.ts.map +1 -0
  131. package/dist/api/presentation/import.d.ts +55 -4
  132. package/dist/api/presentation/import.d.ts.map +1 -1
  133. package/dist/api/presentation/index.d.ts +58 -1
  134. package/dist/api/presentation/index.d.ts.map +1 -1
  135. package/dist/api/presentation/placedViews.d.ts +1139 -0
  136. package/dist/api/presentation/placedViews.d.ts.map +1 -0
  137. package/dist/api/presentation/shapes.d.ts +481 -0
  138. package/dist/api/presentation/shapes.d.ts.map +1 -0
  139. package/dist/api/presentation/sheets.d.ts +452 -13
  140. package/dist/api/presentation/sheets.d.ts.map +1 -1
  141. package/dist/api/presentation/slideshow.d.ts +125 -0
  142. package/dist/api/presentation/slideshow.d.ts.map +1 -0
  143. package/dist/api/presentation/tables.d.ts +81 -0
  144. package/dist/api/presentation/tables.d.ts.map +1 -0
  145. package/dist/api/presentation/views.d.ts +367 -7
  146. package/dist/api/presentation/views.d.ts.map +1 -1
  147. package/dist/api/program/areas.d.ts +102 -12
  148. package/dist/api/program/areas.d.ts.map +1 -1
  149. package/dist/api/program/cores.d.ts +3 -99
  150. package/dist/api/program/cores.d.ts.map +1 -1
  151. package/dist/api/program/index.d.ts +7 -15
  152. package/dist/api/program/index.d.ts.map +1 -1
  153. package/dist/api/program/layout.d.ts +346 -11
  154. package/dist/api/program/layout.d.ts.map +1 -1
  155. package/dist/api/program/site.d.ts +469 -13
  156. package/dist/api/program/site.d.ts.map +1 -1
  157. package/dist/api/program/spreadsheet.d.ts +365 -41
  158. package/dist/api/program/spreadsheet.d.ts.map +1 -1
  159. package/dist/api/workspace/index.d.ts +505 -0
  160. package/dist/api/workspace/index.d.ts.map +1 -0
  161. package/dist/errors/codes.d.ts +34 -0
  162. package/dist/errors/codes.d.ts.map +1 -0
  163. package/dist/errors/envelope.d.ts +56 -0
  164. package/dist/errors/envelope.d.ts.map +1 -0
  165. package/dist/errors/index.d.ts +6 -0
  166. package/dist/errors/index.d.ts.map +1 -0
  167. package/dist/errors/plugin-error.d.ts +69 -0
  168. package/dist/errors/plugin-error.d.ts.map +1 -0
  169. package/dist/handles.d.ts +97 -25
  170. package/dist/handles.d.ts.map +1 -1
  171. package/dist/host-utils.d.ts +4 -0
  172. package/dist/host-utils.d.ts.map +1 -1
  173. package/dist/index.cjs +4605 -1423
  174. package/dist/index.cjs.map +1 -1
  175. package/dist/index.d.ts +1 -0
  176. package/dist/index.d.ts.map +1 -1
  177. package/dist/index.js +4191 -1412
  178. package/dist/index.js.map +1 -1
  179. package/package.json +4 -2
  180. package/scripts/generate-manifest.mjs +45 -0
  181. package/scripts/generate-manifest.test.mjs +103 -4
  182. package/src/api/analysis/daylight.ts +470 -0
  183. package/src/api/analysis/heatmaps.ts +683 -0
  184. package/src/api/analysis/illuminance.ts +155 -0
  185. package/src/api/analysis/index.ts +61 -0
  186. package/src/api/analysis/shadows.ts +183 -0
  187. package/src/api/analysis/solar.ts +237 -0
  188. package/src/api/analysis/sunlightHours.ts +211 -0
  189. package/src/api/analysis/sunpath.ts +83 -0
  190. package/src/api/analysis/weather.ts +179 -0
  191. package/src/api/core/camera/index.ts +268 -0
  192. package/src/api/core/comment/index.ts +120 -2
  193. package/src/api/core/geom/create/index.ts +912 -1
  194. package/src/api/core/geom/delete/index.ts +6 -0
  195. package/src/api/core/geom/query/brep.ts +119 -0
  196. package/src/api/core/handles/index.ts +233 -0
  197. package/src/api/core/index.ts +34 -0
  198. package/src/api/core/io/export/index.ts +126 -0
  199. package/src/api/core/io/import/index.ts +496 -0
  200. package/src/api/core/io/index.ts +42 -0
  201. package/src/api/core/io/job/index.ts +140 -0
  202. package/src/api/core/io/query/index.ts +71 -0
  203. package/src/api/core/io/terrain/index.ts +360 -0
  204. package/src/api/core/io/underlay/index.ts +705 -0
  205. package/src/api/core/mode/index.ts +96 -0
  206. package/src/api/core/project/index.ts +62 -1
  207. package/src/api/core/proposals/index.ts +569 -0
  208. package/src/api/core/storeys/index.ts +294 -0
  209. package/src/api/core/tags.ts +27 -0
  210. package/src/api/core/user.ts +46 -0
  211. package/src/api/core/zoom/index.ts +4 -0
  212. package/src/api/design/create/index.ts +670 -30
  213. package/src/api/design/delete/index.ts +3 -0
  214. package/src/api/design/doors/index.ts +208 -0
  215. package/src/api/design/erase/index.ts +1 -1
  216. package/src/api/design/family.ts +544 -0
  217. package/src/api/design/furniture/index.ts +197 -8
  218. package/src/api/design/index.ts +102 -0
  219. package/src/api/design/lock.ts +27 -0
  220. package/src/api/design/materials/index.ts +334 -27
  221. package/src/api/design/query/geometry/index.ts +125 -3
  222. package/src/api/design/query/index.ts +219 -7
  223. package/src/api/design/query/referenceLines.ts +52 -0
  224. package/src/api/design/query/spaces.ts +143 -0
  225. package/src/api/design/selection/index.ts +129 -0
  226. package/src/api/design/transform/index.ts +170 -9
  227. package/src/api/design/types/index.ts +156 -0
  228. package/src/api/design/update/index.ts +631 -3
  229. package/src/api/design/visibility.ts +143 -0
  230. package/src/api/design/windows/index.ts +128 -2
  231. package/src/api/entity/buildableEnvelope.ts +4 -0
  232. package/src/api/entity/referenceLine.ts +8 -0
  233. package/src/api/entity/story.ts +259 -15
  234. package/src/api/index.ts +10 -0
  235. package/src/api/presentation/annotate.ts +385 -0
  236. package/src/api/presentation/diagrams.ts +118 -8
  237. package/src/api/presentation/export.ts +108 -0
  238. package/src/api/presentation/import.ts +51 -4
  239. package/src/api/presentation/index.ts +66 -1
  240. package/src/api/presentation/placedViews.ts +1120 -0
  241. package/src/api/presentation/shapes.ts +274 -0
  242. package/src/api/presentation/sheets.ts +400 -13
  243. package/src/api/presentation/slideshow.ts +134 -0
  244. package/src/api/presentation/tables.ts +84 -0
  245. package/src/api/presentation/views.ts +376 -8
  246. package/src/api/program/areas.ts +88 -15
  247. package/src/api/program/cores.ts +3 -91
  248. package/src/api/program/index.ts +7 -15
  249. package/src/api/program/layout.ts +365 -11
  250. package/src/api/program/site.ts +435 -13
  251. package/src/api/program/spreadsheet.ts +376 -35
  252. package/src/api/workspace/index.ts +563 -0
  253. package/src/errors/codes.ts +136 -0
  254. package/src/errors/envelope.ts +75 -0
  255. package/src/errors/index.ts +21 -0
  256. package/src/errors/plugin-error.ts +134 -0
  257. package/src/handles.ts +123 -13
  258. package/src/host-utils.ts +4 -0
  259. package/src/index.ts +1 -0
  260. package/test/errors.test.mjs +184 -0
  261. package/tsconfig.json +7 -2
@@ -7,8 +7,10 @@ import {
7
7
  PluginDepartmentId,
8
8
  PluginAreaClass,
9
9
  } from "../../entity/space"
10
+ import { PluginStaircasePreset } from "../create"
10
11
  import { PluginDesignQueryGeometryApi } from "./geometry"
11
12
  import { PluginDesignQuerySpacesApi } from "./spaces"
13
+ import { PluginDesignQueryReferenceLinesApi } from "./referenceLines"
12
14
 
13
15
  // ---------------------------------------------------------------------------
14
16
  // Entity type vocabulary
@@ -39,6 +41,7 @@ import { PluginDesignQuerySpacesApi } from "./spaces"
39
41
  * | `"curtainWall"` | Parametric curtain wall |
40
42
  * | `"mullion"` | Curtain-wall mullion |
41
43
  * | `"panel"` | Curtain-wall panel |
44
+ * | `"parametricComponent"` | A placed parametric family instance (native or Revit-imported). Its geometry is rebuilt from `design.family` parameters, so read and drive it through `design.family.getParameters` / `setParameters` rather than editing its meshes. |
42
45
  */
43
46
  export const PluginEntityType = z.enum([
44
47
  "wall",
@@ -58,6 +61,7 @@ export const PluginEntityType = z.enum([
58
61
  "curtainWall",
59
62
  "mullion",
60
63
  "panel",
64
+ "parametricComponent",
61
65
  ])
62
66
  export type PluginEntityType = z.infer<typeof PluginEntityType>
63
67
 
@@ -167,6 +171,7 @@ export type PluginDesignQueryComponentsArgs = z.infer<
167
171
  * | `spaceType` | {@linkcode PluginSpaceType} | Space-type (spaces only) |
168
172
  * | `areaClass` | {@linkcode PluginAreaClass} | Area classification (spaces only) |
169
173
  * | `departmentId` | `string` | Department (masses only) |
174
+ * | `buildingType` | `string` | Assigned building type NAME (walls / slabs / floors / roofs / ceilings only) — the Object Properties panel's Wall/Slab/Floor/Roof/Ceiling Type dropdown value, matching the names from `design.types.list(kind)` |
170
175
  * | `isLocked` | `boolean` | Lock flag |
171
176
  * | `isHidden` | `boolean` | User-hidden flag |
172
177
  * | `isSelected` | `boolean` | Current selection state |
@@ -185,6 +190,7 @@ export const PluginEntityProperties = z
185
190
  spaceType: PluginSpaceType,
186
191
  areaClass: PluginAreaClass,
187
192
  departmentId: z.string(),
193
+ buildingType: z.string(),
188
194
  isLocked: z.boolean(),
189
195
  isHidden: z.boolean(),
190
196
  isSelected: z.boolean(),
@@ -200,21 +206,82 @@ export type PluginEntityProperties = z.infer<typeof PluginEntityProperties>
200
206
  * entity's type computes them (area: floors/masses/slabs/roofs/beams/columns;
201
207
  * volume: all; length: walls/beams).
202
208
  *
209
+ * `thickness` and `height` are the Object Properties panel's dimension reads
210
+ * (the same engine source `design.update.wall` / `design.update.slab` etc.
211
+ * write through), in engine units. `thickness`: walls (the plan thickness —
212
+ * present only for straight orthogonal walls, exactly when the panel shows it)
213
+ * and slabs/floors/roofs/ceilings (the vertical extent the panel calls
214
+ * Thickness). `height`: walls only.
215
+ *
203
216
  * | Property | Type | Description |
204
217
  * |---|---|---|
205
218
  * | `area` | `number`? | Bottom-face area |
206
219
  * | `volume` | `number`? | Solid volume |
207
220
  * | `length` | `number`? | Running length (linear elements) |
221
+ * | `thickness` | `number`? | Panel Thickness — walls (straight orthogonal only) and the slab family |
222
+ * | `height` | `number`? | Panel Height — walls only |
208
223
  * | `boundingBox` | {@linkcode BBoxComponents} | World-space AABB (always present) |
209
224
  */
210
225
  export const PluginEntityMeasurements = z.object({
211
226
  area: z.number().optional(),
212
227
  volume: z.number().optional(),
213
228
  length: z.number().optional(),
229
+ thickness: z.number().optional(),
230
+ height: z.number().optional(),
214
231
  boundingBox: BBoxComponents,
215
232
  })
216
233
  export type PluginEntityMeasurements = z.infer<typeof PluginEntityMeasurements>
217
234
 
235
+ /**
236
+ * The parametric properties of a staircase — the same editable fields the
237
+ * staircase properties panel exposes. Returned by
238
+ * {@linkcode PluginDesignQueryApi.getStaircaseParams}; the write side is
239
+ * `design.update.staircase`. Engine internals (block schema, min well size,
240
+ * square-well padding) are deliberately excluded.
241
+ *
242
+ * All dimensions are in **engine units** (the same convention as
243
+ * `design.doors.getWidth`); `steps` is a unitless count. The invariant
244
+ * `staircaseHeight = steps × riser` is governed by the two lock booleans — see
245
+ * `design.update.staircase`. Type-specific fields (`wellSize`, `landingWidth`,
246
+ * `flightStartDistAfterTurn`) are present only when the preset uses them.
247
+ *
248
+ * | Property | Type | Description |
249
+ * |---|---|---|
250
+ * | `staircaseType` | {@linkcode PluginStaircasePreset} | Base staircase type |
251
+ * | `staircasePreset` | {@linkcode PluginStaircasePreset} | Named parametric preset |
252
+ * | `staircaseHeight` | `number` | Total rise (engine units) |
253
+ * | `steps` | `number` | Step count (unitless) |
254
+ * | `riser` | `number` | Riser height (engine units) |
255
+ * | `tread` | `number` | Tread depth (engine units) |
256
+ * | `width` | `number` | Flight width (engine units) |
257
+ * | `depth` | `number` | Slab/waist thickness (engine units) |
258
+ * | `wellSize` | `number`? | Stairwell gap (dogLegged / openWell / square) |
259
+ * | `landingWidth` | `number`? | Landing depth (straight / dogLegged) |
260
+ * | `flightStartDistAfterTurn` | `number`? | Flight offset after a turn (dogLegged / lShaped / square) |
261
+ * | `baseOffset` | `number` | Vertical offset from the storey base (engine units) |
262
+ * | `isStoreyHeightUnlocked` | `boolean` | When `false`, height is tied to the storey height |
263
+ * | `isStaircaseHeightUnlocked` | `boolean` | When `false`, height recomputes from steps × riser |
264
+ * | `storey` | `number` | Storey/floor level the staircase sits on |
265
+ */
266
+ export const PluginStaircaseParams = z.object({
267
+ staircaseType: PluginStaircasePreset,
268
+ staircasePreset: PluginStaircasePreset,
269
+ staircaseHeight: z.number(),
270
+ steps: z.number(),
271
+ riser: z.number(),
272
+ tread: z.number(),
273
+ width: z.number(),
274
+ depth: z.number(),
275
+ wellSize: z.number().optional(),
276
+ landingWidth: z.number().optional(),
277
+ flightStartDistAfterTurn: z.number().optional(),
278
+ baseOffset: z.number(),
279
+ isStoreyHeightUnlocked: z.boolean(),
280
+ isStaircaseHeightUnlocked: z.boolean(),
281
+ storey: z.number(),
282
+ })
283
+ export type PluginStaircaseParams = z.infer<typeof PluginStaircaseParams>
284
+
218
285
  // ---------------------------------------------------------------------------
219
286
  // The query API
220
287
  // ---------------------------------------------------------------------------
@@ -237,6 +304,8 @@ export abstract class PluginDesignQueryApi {
237
304
  public abstract geometry: PluginDesignQueryGeometryApi
238
305
  /** Space-specific reads (footprint, …). See {@linkcode PluginDesignQuerySpacesApi}. */
239
306
  public abstract spaces: PluginDesignQuerySpacesApi
307
+ /** Reference-line-specific reads. See {@linkcode PluginDesignQueryReferenceLinesApi}. */
308
+ public abstract referenceLines: PluginDesignQueryReferenceLinesApi
240
309
 
241
310
  constructor() {}
242
311
 
@@ -704,9 +773,7 @@ export abstract class PluginDesignQueryApi {
704
773
  * }
705
774
  * ```
706
775
  */
707
- public abstract exists(
708
- id: ComponentHandle,
709
- ): PluginApiReturn<boolean>
776
+ public abstract exists(id: ComponentHandle): PluginApiReturn<boolean>
710
777
 
711
778
  /**
712
779
  * Get the kind of BIM entity a handle refers to — wall, door, space, slab,
@@ -760,9 +827,7 @@ export abstract class PluginDesignQueryApi {
760
827
  * }
761
828
  * ```
762
829
  */
763
- public abstract getLabel(
764
- component: ComponentHandle,
765
- ): PluginApiReturn<string>
830
+ public abstract getLabel(component: ComponentHandle): PluginApiReturn<string>
766
831
 
767
832
  /**
768
833
  * Get a serializable, persistable reference to an entity. Under the all-handle
@@ -846,13 +911,16 @@ export abstract class PluginDesignQueryApi {
846
911
  * Read an entity's common properties as a {@linkcode PluginEntityProperties}
847
912
  * record (only applicable fields are present). For spaces/masses this includes
848
913
  * `adjacency` — the per-entity adjacency read (bulk form:
849
- * `program.adjacency.getMatrix`).
914
+ * `program.adjacency.getMatrix`). For walls and the slab family (slab / floor
915
+ * / roof / ceiling) this includes `buildingType` — the assigned building type
916
+ * NAME the panel's type dropdown shows, matching `design.types.list(kind)`.
850
917
  *
851
918
  * @param component - the entity's {@linkcode ComponentHandle}
852
919
  * @returns the property record
853
920
  *
854
921
  * @examplePrompt Show me all the details of the selected object
855
922
  * @examplePrompt What storey is this wall on?
923
+ * @examplePrompt Which wall type is assigned to this wall?
856
924
  * @examplePrompt Which department does this room belong to?
857
925
  * @examplePrompt Is this element locked or hidden?
858
926
  * @examplePrompt Get the adjacencies of this space
@@ -882,11 +950,20 @@ export abstract class PluginDesignQueryApi {
882
950
  * Measure an entity — read its area, volume, and/or running length (whichever
883
951
  * its type supports) together with its world-space bounding box in one call.
884
952
  *
953
+ * For walls and the slab family this also carries the Object Properties
954
+ * panel's dimension reads in engine units: `thickness` (walls — straight
955
+ * orthogonal only, exactly when the panel shows it; slabs / floors / roofs /
956
+ * ceilings — the vertical extent the panel calls Thickness) and `height`
957
+ * (walls). These are the read side of `design.update.wall` /
958
+ * `design.update.slab` / `.floor` / `.roof` / `.ceiling`.
959
+ *
885
960
  * @param component - the entity's {@linkcode ComponentHandle}
886
961
  * @returns a {@linkcode PluginEntityMeasurements}, or `null` if the entity is gone
887
962
  *
888
963
  * @examplePrompt What's the area of this room?
889
964
  * @examplePrompt How long is the selected wall?
965
+ * @examplePrompt How thick is this wall?
966
+ * @examplePrompt Get the thickness of the slab on level 2
890
967
  * @examplePrompt Get the volume of this mass
891
968
  * @examplePrompt Give me the dimensions of the selected element
892
969
  * @examplePrompt What's the floor area of the kitchen?
@@ -896,12 +973,47 @@ export abstract class PluginDesignQueryApi {
896
973
  * const [space] = await snaptrude.design.query.listSpaces()
897
974
  * const m = await snaptrude.design.query.measure(space)
898
975
  * console.log(m?.area, m?.volume)
976
+ *
977
+ * // wall dimensions — the panel's Thickness / Height, in engine units
978
+ * const [wall] = await snaptrude.design.query.listWalls()
979
+ * const wm = await snaptrude.design.query.measure(wall)
980
+ * console.log(wm?.thickness, wm?.height)
899
981
  * ```
900
982
  */
901
983
  public abstract measure(
902
984
  component: ComponentHandle,
903
985
  ): PluginApiReturn<PluginEntityMeasurements | null>
904
986
 
987
+ /**
988
+ * Read a staircase's parametric properties — its preset, dimensions, step
989
+ * count, base offset, and height-lock state — as a
990
+ * {@linkcode PluginStaircaseParams} record. The paired write is
991
+ * `design.update.staircase`.
992
+ *
993
+ * All dimensions are in **engine units** (the same convention as
994
+ * `design.doors.getWidth`); `steps` is a unitless count. A read — never
995
+ * throws: returns `null` for a handle that is not a staircase or no longer
996
+ * resolves.
997
+ *
998
+ * @param staircase - the staircase's {@linkcode ComponentHandle}
999
+ * @returns the {@linkcode PluginStaircaseParams} record, or `null`
1000
+ *
1001
+ * @examplePrompt What's the riser height of this staircase?
1002
+ * @examplePrompt How many steps does the selected stair have?
1003
+ * @examplePrompt Show me the tread and width of this staircase
1004
+ * @examplePrompt Read all the parameters of the stairs on level 1
1005
+ *
1006
+ * # Example
1007
+ * ```ts
1008
+ * const [stair] = await snaptrude.design.query.listStaircases({ isSelected: true })
1009
+ * const params = stair ? await snaptrude.design.query.getStaircaseParams(stair) : null
1010
+ * if (params) console.log(params.steps, params.riser, params.tread)
1011
+ * ```
1012
+ */
1013
+ public abstract getStaircaseParams(
1014
+ staircase: ComponentHandle,
1015
+ ): PluginApiReturn<PluginStaircaseParams | null>
1016
+
905
1017
  /**
906
1018
  * Get the **union** axis-aligned bounding box enclosing a set of entities.
907
1019
  *
@@ -931,7 +1043,107 @@ export abstract class PluginDesignQueryApi {
931
1043
  public abstract getBoundingBox(
932
1044
  components: ComponentHandle[],
933
1045
  ): PluginApiReturn<BBoxComponents | null>
1046
+
1047
+ /**
1048
+ * Compute the plan **outline of what is built on a storey** — the union of
1049
+ * the storey's wall (by default) footprints as polygons-with-holes. This is
1050
+ * the footprint-from-the-built-model query: by the time slabs are needed the
1051
+ * walls exist, and the engine's own solids (snapped, joined and mitred at
1052
+ * creation) are the cleanest wall network available — no CAD re-tracing.
1053
+ *
1054
+ * Semantics: the union of wall solids is the wall *material* — a ring-shaped
1055
+ * polygon. The **outer ring is the OUTSIDE wall face** (the slab boundary);
1056
+ * every enclosed region — rooms AND courtyards — appears as a hole. When the
1057
+ * largest hole is ~zero the walls don't enclose anything: the footprint
1058
+ * reports `enclosed: false` (an open wall network), never a garbage outline.
1059
+ * Detached buildings come back as separate footprints.
1060
+ *
1061
+ * A read — nothing is created. Feed a footprint's `outline` to
1062
+ * `core.geom.create.profileFromLinePoints` → `design.create.slab` to build
1063
+ * the floor/roof plate. Coordinates are world-space plan (x, z) in Snaptrude
1064
+ * internal units; `areaSq` values are in squared internal units.
1065
+ *
1066
+ * @param options - storey / included kinds / debris filter; see
1067
+ * {@linkcode PluginStoreyOutlineOptions}.
1068
+ * @returns the storey's footprints (possibly several for detached buildings)
1069
+ * plus pieces discarded by `minArea` (`footprints: []` when nothing matches).
1070
+ *
1071
+ * @examplePrompt What is the building footprint on the ground floor?
1072
+ * @examplePrompt Create a floor slab covering the whole storey
1073
+ * @examplePrompt Get the outline of the walls on storey 1
1074
+ * @examplePrompt How much area do the ground-floor walls enclose?
1075
+ *
1076
+ * # Example
1077
+ * ```ts
1078
+ * const r = await snaptrude.design.query.storeyOutline({ storey: 1 })
1079
+ * const main = r.footprints.find((f) => f.enclosed)
1080
+ * if (main) {
1081
+ * const profile = await snaptrude.core.geom.create.profileFromLinePoints(
1082
+ * main.outline.map((p) => ({ x: p.x, y: 0, z: p.z })),
1083
+ * )
1084
+ * // → design.create.slab with the profile's contour
1085
+ * }
1086
+ * ```
1087
+ */
1088
+ public abstract storeyOutline(
1089
+ options?: PluginStoreyOutlineOptions,
1090
+ ): PluginApiReturn<PluginStoreyOutlineResult>
934
1091
  }
935
1092
 
1093
+
1094
+ /** A point in the world-space plan (x, z) projection, Snaptrude internal units. */
1095
+ export const PluginOutlinePlanPoint = z.object({ x: z.number(), z: z.number() })
1096
+ export type PluginOutlinePlanPoint = z.infer<typeof PluginOutlinePlanPoint>
1097
+
1098
+ /**
1099
+ * Options for {@link PluginDesignQueryApi.storeyOutline}.
1100
+ *
1101
+ * | Property | Type | Description |
1102
+ * |---|---|---|
1103
+ * | `storey` | `number`? | Only components on this storey (default: all storeys) |
1104
+ * | `include` | {@link PluginEntityType}`[]`? | Component kinds to union (default `["wall"]`) |
1105
+ * | `minArea` | `number`? | Drop union pieces below this plan area, squared internal units (default `1`) |
1106
+ */
1107
+ export const PluginStoreyOutlineOptions = z.object({
1108
+ storey: z.number().int().optional(),
1109
+ include: z.array(PluginEntityType).nonempty().default(["wall"]),
1110
+ minArea: z.number().nonnegative().default(1),
1111
+ })
1112
+ export type PluginStoreyOutlineOptions = z.input<
1113
+ typeof PluginStoreyOutlineOptions
1114
+ >
1115
+
1116
+ /**
1117
+ * One connected footprint from {@link PluginDesignQueryApi.storeyOutline}.
1118
+ * `outline` traces the OUTSIDE wall face; `holes` are the enclosed regions
1119
+ * (rooms and courtyards). `enclosed` is `false` when the wall network does not
1120
+ * close around any region (open C-shape) — don't slab an unenclosed outline
1121
+ * without checking it.
1122
+ */
1123
+ export const PluginStoreyFootprint = z.object({
1124
+ outline: z.array(PluginOutlinePlanPoint),
1125
+ holes: z.array(
1126
+ z.object({
1127
+ ring: z.array(PluginOutlinePlanPoint),
1128
+ areaSq: z.number().nonnegative(),
1129
+ }),
1130
+ ),
1131
+ areaSq: z.number().nonnegative(),
1132
+ enclosed: z.boolean(),
1133
+ })
1134
+ export type PluginStoreyFootprint = z.infer<typeof PluginStoreyFootprint>
1135
+
1136
+ /** Result of {@link PluginDesignQueryApi.storeyOutline}. */
1137
+ export const PluginStoreyOutlineResult = z.object({
1138
+ footprints: z.array(PluginStoreyFootprint),
1139
+ discarded: z.array(
1140
+ z.object({ areaSq: z.number().nonnegative(), reason: z.string() }),
1141
+ ),
1142
+ })
1143
+ export type PluginStoreyOutlineResult = z.infer<
1144
+ typeof PluginStoreyOutlineResult
1145
+ >
1146
+
936
1147
  export * from "./geometry"
937
1148
  export * from "./spaces"
1149
+ export * from "./referenceLines"
@@ -0,0 +1,52 @@
1
+ import * as z from "zod"
2
+ import { PluginApiReturn } from "../../../types"
3
+ import {
4
+ PluginReferenceLineGetProperty,
5
+ PluginReferenceLineGetResult,
6
+ } from "../../entity/referenceLine"
7
+
8
+ /**
9
+ * `design.query.referenceLines.*` — reference-line-specific reads.
10
+ *
11
+ * A **reference line** is a 2D guide line (or arc) in the scene, typically used
12
+ * for grid lines and alignment guides. Enumerate reference lines with
13
+ * `design.query.listReferenceLines`; read an individual line's properties here.
14
+ * This is the canonical home of the read formerly at `entity.referenceLine.get`
15
+ * (now deprecated).
16
+ *
17
+ * Accessed via `snaptrude.design.query.referenceLines`.
18
+ */
19
+ export abstract class PluginDesignQueryReferenceLinesApi {
20
+ constructor() {}
21
+
22
+ /**
23
+ * Get properties of a reference line by its ID.
24
+ *
25
+ * Only the properties listed in `properties` are returned — unlisted
26
+ * properties will be `undefined` in the result.
27
+ *
28
+ * @param referenceLineId - The unique reference line ID
29
+ * @param properties - Array of property names to retrieve. See
30
+ * {@linkcode PluginReferenceLineGetProperty}.
31
+ * @returns A partial {@linkcode PluginReferenceLineGetResult} containing only the
32
+ * requested properties
33
+ * @throws If the reference line does not exist
34
+ *
35
+ * @examplePrompt Get the curve geometry of this reference line
36
+ * @examplePrompt Where does this grid line run?
37
+ * @examplePrompt Read the geometry of a guide line by its id
38
+ * @examplePrompt Look up the curve of the selected reference line
39
+ *
40
+ * # Example
41
+ * ```ts
42
+ * const [refLine] = await snaptrude.design.query.listReferenceLines()
43
+ * const result = await snaptrude.design.query.referenceLines.get(refLine, ["curve"])
44
+ * // result.curve is an opaque CurveHandle; read its coordinates via
45
+ * // `snaptrude.core.geom.curve`.
46
+ * ```
47
+ */
48
+ public abstract get(
49
+ referenceLineId: string,
50
+ properties: z.infer<typeof PluginReferenceLineGetProperty>[],
51
+ ): PluginApiReturn<PluginReferenceLineGetResult>
52
+ }
@@ -75,6 +75,55 @@ export abstract class PluginDesignQuerySpacesApi {
75
75
  public abstract getFootprint(
76
76
  space: ComponentHandle,
77
77
  ): PluginApiReturn<ContourHandle | null>
78
+
79
+ /**
80
+ * Get the **enclosure** of a space — the floor and ceiling that cap it, the
81
+ * bounding walls around it (with each wall's door/window openings), and the
82
+ * neighbouring spaces it shares a boundary with.
83
+ *
84
+ * **Geometric v1 — best effort.** The engine has no persisted space→surface
85
+ * topology, so this read is derived purely from *plan geometry*: the space
86
+ * footprint is matched against the plan footprints/baselines of the slabs and
87
+ * walls on the same storey. Consequences a caller must account for:
88
+ *
89
+ * - `faceIndices` is **always `[]`**. The triangle→B-rep-face provenance that
90
+ * would populate it is a separate engine capability that does not exist yet;
91
+ * read a surface's full geometry via
92
+ * {@linkcode PluginDesignQueryGeometryApi.getBrep} on its `component` instead.
93
+ * - After heavy edits (move / stretch / boolean) or on imported models the plan
94
+ * match can miss or mis-attribute a surface — treat the result as advisory,
95
+ * not authoritative.
96
+ * - `adjacentSpaces` comes from the same adjacency data as
97
+ * {@linkcode PluginProgramAdjacencyApi.getMatrix} (so the two agree on which
98
+ * spaces neighbour). `sharedEdgeLength` is `0` because that data exposes no
99
+ * edge length, and `sharedSurface` is the common boundary wall only when one
100
+ * is found geometrically (else `null`).
101
+ *
102
+ * Read-only; never mutates the model.
103
+ *
104
+ * @param space - The space (room mass) to read
105
+ * @returns the {@linkcode PluginSpaceEnclosure}, or `null` when `space` is not a
106
+ * space (room mass) or has no extractable plan footprint
107
+ *
108
+ * @examplePrompt What walls, floor and ceiling enclose this room?
109
+ * @examplePrompt Which of this room's walls are external?
110
+ * @examplePrompt List the doors and windows around the selected space
111
+ * @examplePrompt Which spaces are adjacent to this room, and through which wall?
112
+ *
113
+ * # Example
114
+ * ```ts
115
+ * const [space] = await snaptrude.design.query.listSpaces()
116
+ * const enclosure = await snaptrude.design.query.spaces.getEnclosure(space)
117
+ * if (enclosure) {
118
+ * const walls = enclosure.surfaces.filter((s) => s.role === "wall")
119
+ * const external = walls.filter((s) => s.isExternal)
120
+ * console.log(`${walls.length} walls, ${external.length} external`)
121
+ * }
122
+ * ```
123
+ */
124
+ public abstract getEnclosure(
125
+ space: ComponentHandle,
126
+ ): PluginApiReturn<PluginSpaceEnclosure | null>
78
127
  }
79
128
 
80
129
  /**
@@ -130,3 +179,97 @@ export const PluginDesignQuerySpacesGetResult = PluginSpaceGetResult.omit({
130
179
  export type PluginDesignQuerySpacesGetResult = z.infer<
131
180
  typeof PluginDesignQuerySpacesGetResult
132
181
  >
182
+
183
+ /**
184
+ * Arguments for {@linkcode PluginDesignQuerySpacesApi.getEnclosure}.
185
+ *
186
+ * | Property | Type | Description |
187
+ * |---|---|---|
188
+ * | `space` | {@linkcode ComponentHandle} | The space (room mass) to read |
189
+ */
190
+ export const PluginDesignQuerySpacesGetEnclosureArgs = z.object({
191
+ space: ComponentHandle,
192
+ })
193
+ export type PluginDesignQuerySpacesGetEnclosureArgs = z.infer<
194
+ typeof PluginDesignQuerySpacesGetEnclosureArgs
195
+ >
196
+
197
+ /**
198
+ * The role a bounding surface plays in a {@linkcode PluginSpaceEnclosure}:
199
+ * `"floor"` (slab below), `"ceiling"` (slab/roof above), or `"wall"`.
200
+ */
201
+ export const PluginEnclosureRole = z.enum(["floor", "ceiling", "wall"])
202
+ export type PluginEnclosureRole = z.infer<typeof PluginEnclosureRole>
203
+
204
+ /** The kind of opening hosted in a bounding wall. */
205
+ export const PluginEnclosureOpeningKind = z.enum(["door", "window", "void"])
206
+ export type PluginEnclosureOpeningKind = z.infer<
207
+ typeof PluginEnclosureOpeningKind
208
+ >
209
+
210
+ /**
211
+ * One opening (door / window / void) in a bounding wall.
212
+ *
213
+ * | Property | Type | Description |
214
+ * |---|---|---|
215
+ * | `kind` | {@linkcode PluginEnclosureOpeningKind} | `"door"`, `"window"`, or `"void"` |
216
+ * | `component` | {@linkcode ComponentHandle} | The opening entity |
217
+ */
218
+ export const PluginEnclosureOpening = z.object({
219
+ kind: PluginEnclosureOpeningKind,
220
+ component: ComponentHandle,
221
+ })
222
+ export type PluginEnclosureOpening = z.infer<typeof PluginEnclosureOpening>
223
+
224
+ /**
225
+ * One bounding surface of a space's enclosure.
226
+ *
227
+ * | Property | Type | Description |
228
+ * |---|---|---|
229
+ * | `role` | {@linkcode PluginEnclosureRole} | `"floor"`, `"ceiling"`, or `"wall"` |
230
+ * | `component` | {@linkcode ComponentHandle} | The wall / slab / roof entity |
231
+ * | `faceIndices` | `number[]` | B-rep face indices facing the space. **Always `[]` in geometric v1** (no triangle→face provenance yet) |
232
+ * | `isExternal` | `boolean` | No space on the other side — for a wall, no other room bounds it; for a floor/ceiling, no room caps the storey below/above |
233
+ * | `openings` | {@linkcode PluginEnclosureOpening}`[]` | Doors/windows/voids in the surface (walls only; `[]` for floor/ceiling in v1) |
234
+ */
235
+ export const PluginEnclosureSurface = z.object({
236
+ role: PluginEnclosureRole,
237
+ component: ComponentHandle,
238
+ faceIndices: z.array(z.number()),
239
+ isExternal: z.boolean(),
240
+ openings: z.array(PluginEnclosureOpening),
241
+ })
242
+ export type PluginEnclosureSurface = z.infer<typeof PluginEnclosureSurface>
243
+
244
+ /**
245
+ * A space that neighbours the queried space.
246
+ *
247
+ * | Property | Type | Description |
248
+ * |---|---|---|
249
+ * | `space` | {@linkcode ComponentHandle} | The neighbouring space |
250
+ * | `sharedSurface` | {@linkcode ComponentHandle}` \| null` | The common boundary wall when one is found geometrically, else `null` (e.g. an open-plan or non-physical adjacency) |
251
+ * | `sharedEdgeLength` | `number` | Plan-unit length of the shared boundary — **always `0` in geometric v1** (the adjacency data exposes no edge length) |
252
+ */
253
+ export const PluginAdjacentSpace = z.object({
254
+ space: ComponentHandle,
255
+ sharedSurface: ComponentHandle.nullable(),
256
+ sharedEdgeLength: z.number(),
257
+ })
258
+ export type PluginAdjacentSpace = z.infer<typeof PluginAdjacentSpace>
259
+
260
+ /**
261
+ * Result of {@linkcode PluginDesignQuerySpacesApi.getEnclosure} — the geometric
262
+ * v1 enclosure of a space.
263
+ *
264
+ * | Property | Type | Description |
265
+ * |---|---|---|
266
+ * | `space` | {@linkcode ComponentHandle} | The queried space |
267
+ * | `surfaces` | {@linkcode PluginEnclosureSurface}`[]` | Floor + ceiling + bounding walls, as a flat list (any of the three may be absent when no plan match is found) |
268
+ * | `adjacentSpaces` | {@linkcode PluginAdjacentSpace}`[]` | Neighbouring spaces from the adjacency data (`[]` when adjacency was never computed) |
269
+ */
270
+ export const PluginSpaceEnclosure = z.object({
271
+ space: ComponentHandle,
272
+ surfaces: z.array(PluginEnclosureSurface),
273
+ adjacentSpaces: z.array(PluginAdjacentSpace),
274
+ })
275
+ export type PluginSpaceEnclosure = z.infer<typeof PluginSpaceEnclosure>