@snaptrude/plugin-core 0.0.0-bimsvg-20260928124803

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 (383) hide show
  1. package/AGENTS.md +231 -0
  2. package/CHANGELOG.md +341 -0
  3. package/CLAUDE.md +11 -0
  4. package/api-manifest.json +9120 -0
  5. package/dist/api/analysis/daylight.d.ts +603 -0
  6. package/dist/api/analysis/daylight.d.ts.map +1 -0
  7. package/dist/api/analysis/heatmaps.d.ts +658 -0
  8. package/dist/api/analysis/heatmaps.d.ts.map +1 -0
  9. package/dist/api/analysis/illuminance.d.ts +145 -0
  10. package/dist/api/analysis/illuminance.d.ts.map +1 -0
  11. package/dist/api/analysis/index.d.ts +59 -0
  12. package/dist/api/analysis/index.d.ts.map +1 -0
  13. package/dist/api/analysis/shadows.d.ts +165 -0
  14. package/dist/api/analysis/shadows.d.ts.map +1 -0
  15. package/dist/api/analysis/solar.d.ts +249 -0
  16. package/dist/api/analysis/solar.d.ts.map +1 -0
  17. package/dist/api/analysis/sunlightHours.d.ts +208 -0
  18. package/dist/api/analysis/sunlightHours.d.ts.map +1 -0
  19. package/dist/api/analysis/sunpath.d.ts +80 -0
  20. package/dist/api/analysis/sunpath.d.ts.map +1 -0
  21. package/dist/api/analysis/weather.d.ts +193 -0
  22. package/dist/api/analysis/weather.d.ts.map +1 -0
  23. package/dist/api/core/buildings.d.ts +427 -0
  24. package/dist/api/core/buildings.d.ts.map +1 -0
  25. package/dist/api/core/camera/index.d.ts +261 -0
  26. package/dist/api/core/camera/index.d.ts.map +1 -0
  27. package/dist/api/core/comment/index.d.ts +333 -0
  28. package/dist/api/core/comment/index.d.ts.map +1 -0
  29. package/dist/api/core/geom/create/index.d.ts +1073 -0
  30. package/dist/api/core/geom/create/index.d.ts.map +1 -0
  31. package/dist/api/core/geom/delete/index.d.ts +78 -0
  32. package/dist/api/core/geom/delete/index.d.ts.map +1 -0
  33. package/dist/api/core/geom/index.d.ts +33 -0
  34. package/dist/api/core/geom/index.d.ts.map +1 -0
  35. package/dist/api/core/geom/query/arc.d.ts +169 -0
  36. package/dist/api/core/geom/query/arc.d.ts.map +1 -0
  37. package/dist/api/core/geom/query/brep.d.ts +514 -0
  38. package/dist/api/core/geom/query/brep.d.ts.map +1 -0
  39. package/dist/api/core/geom/query/circle.d.ts +378 -0
  40. package/dist/api/core/geom/query/circle.d.ts.map +1 -0
  41. package/dist/api/core/geom/query/contour.d.ts +450 -0
  42. package/dist/api/core/geom/query/contour.d.ts.map +1 -0
  43. package/dist/api/core/geom/query/curve.d.ts +918 -0
  44. package/dist/api/core/geom/query/curve.d.ts.map +1 -0
  45. package/dist/api/core/geom/query/edge.d.ts +128 -0
  46. package/dist/api/core/geom/query/edge.d.ts.map +1 -0
  47. package/dist/api/core/geom/query/face.d.ts +363 -0
  48. package/dist/api/core/geom/query/face.d.ts.map +1 -0
  49. package/dist/api/core/geom/query/halfedge.d.ts +206 -0
  50. package/dist/api/core/geom/query/halfedge.d.ts.map +1 -0
  51. package/dist/api/core/geom/query/index.d.ts +61 -0
  52. package/dist/api/core/geom/query/index.d.ts.map +1 -0
  53. package/dist/api/core/geom/query/profile.d.ts +410 -0
  54. package/dist/api/core/geom/query/profile.d.ts.map +1 -0
  55. package/dist/api/core/geom/query/vertex.d.ts +187 -0
  56. package/dist/api/core/geom/query/vertex.d.ts.map +1 -0
  57. package/dist/api/core/geom/update/contour.d.ts +272 -0
  58. package/dist/api/core/geom/update/contour.d.ts.map +1 -0
  59. package/dist/api/core/geom/update/curve.d.ts +180 -0
  60. package/dist/api/core/geom/update/curve.d.ts.map +1 -0
  61. package/dist/api/core/geom/update/index.d.ts +27 -0
  62. package/dist/api/core/geom/update/index.d.ts.map +1 -0
  63. package/dist/api/core/geom/update/profile.d.ts +329 -0
  64. package/dist/api/core/geom/update/profile.d.ts.map +1 -0
  65. package/dist/api/core/groups.d.ts +485 -0
  66. package/dist/api/core/groups.d.ts.map +1 -0
  67. package/dist/api/core/handles/index.d.ts +210 -0
  68. package/dist/api/core/handles/index.d.ts.map +1 -0
  69. package/dist/api/core/history/index.d.ts +78 -0
  70. package/dist/api/core/history/index.d.ts.map +1 -0
  71. package/dist/api/core/index.d.ts +97 -0
  72. package/dist/api/core/index.d.ts.map +1 -0
  73. package/dist/api/core/io/export/index.d.ts +134 -0
  74. package/dist/api/core/io/export/index.d.ts.map +1 -0
  75. package/dist/api/core/io/import/index.d.ts +455 -0
  76. package/dist/api/core/io/import/index.d.ts.map +1 -0
  77. package/dist/api/core/io/index.d.ts +40 -0
  78. package/dist/api/core/io/index.d.ts.map +1 -0
  79. package/dist/api/core/io/job/index.d.ts +139 -0
  80. package/dist/api/core/io/job/index.d.ts.map +1 -0
  81. package/dist/api/core/io/query/index.d.ts +74 -0
  82. package/dist/api/core/io/query/index.d.ts.map +1 -0
  83. package/dist/api/core/io/terrain/index.d.ts +341 -0
  84. package/dist/api/core/io/terrain/index.d.ts.map +1 -0
  85. package/dist/api/core/io/underlay/index.d.ts +805 -0
  86. package/dist/api/core/io/underlay/index.d.ts.map +1 -0
  87. package/dist/api/core/layers.d.ts +402 -0
  88. package/dist/api/core/layers.d.ts.map +1 -0
  89. package/dist/api/core/math/index.d.ts +18 -0
  90. package/dist/api/core/math/index.d.ts.map +1 -0
  91. package/dist/api/core/math/quat.d.ts +170 -0
  92. package/dist/api/core/math/quat.d.ts.map +1 -0
  93. package/dist/api/core/math/vec3.d.ts +174 -0
  94. package/dist/api/core/math/vec3.d.ts.map +1 -0
  95. package/dist/api/core/mode/index.d.ts +111 -0
  96. package/dist/api/core/mode/index.d.ts.map +1 -0
  97. package/dist/api/core/project/index.d.ts +466 -0
  98. package/dist/api/core/project/index.d.ts.map +1 -0
  99. package/dist/api/core/proposals/index.d.ts +531 -0
  100. package/dist/api/core/proposals/index.d.ts.map +1 -0
  101. package/dist/api/core/storeys/index.d.ts +265 -0
  102. package/dist/api/core/storeys/index.d.ts.map +1 -0
  103. package/dist/api/core/tags.d.ts +860 -0
  104. package/dist/api/core/tags.d.ts.map +1 -0
  105. package/dist/api/core/units/index.d.ts +175 -0
  106. package/dist/api/core/units/index.d.ts.map +1 -0
  107. package/dist/api/core/user.d.ts +44 -0
  108. package/dist/api/core/user.d.ts.map +1 -0
  109. package/dist/api/core/zoom/index.d.ts +49 -0
  110. package/dist/api/core/zoom/index.d.ts.map +1 -0
  111. package/dist/api/design/boolean/index.d.ts +168 -0
  112. package/dist/api/design/boolean/index.d.ts.map +1 -0
  113. package/dist/api/design/create/bulk-items.d.ts +185 -0
  114. package/dist/api/design/create/bulk-items.d.ts.map +1 -0
  115. package/dist/api/design/create/grids.d.ts +132 -0
  116. package/dist/api/design/create/grids.d.ts.map +1 -0
  117. package/dist/api/design/create/index.d.ts +1747 -0
  118. package/dist/api/design/create/index.d.ts.map +1 -0
  119. package/dist/api/design/create/opening-fields.d.ts +37 -0
  120. package/dist/api/design/create/opening-fields.d.ts.map +1 -0
  121. package/dist/api/design/delete/index.d.ts +70 -0
  122. package/dist/api/design/delete/index.d.ts.map +1 -0
  123. package/dist/api/design/dimensions.d.ts +427 -0
  124. package/dist/api/design/dimensions.d.ts.map +1 -0
  125. package/dist/api/design/doors/index.d.ts +470 -0
  126. package/dist/api/design/doors/index.d.ts.map +1 -0
  127. package/dist/api/design/edit/index.d.ts +49 -0
  128. package/dist/api/design/edit/index.d.ts.map +1 -0
  129. package/dist/api/design/erase/index.d.ts +160 -0
  130. package/dist/api/design/erase/index.d.ts.map +1 -0
  131. package/dist/api/design/family.d.ts +611 -0
  132. package/dist/api/design/family.d.ts.map +1 -0
  133. package/dist/api/design/furniture/index.d.ts +296 -0
  134. package/dist/api/design/furniture/index.d.ts.map +1 -0
  135. package/dist/api/design/grids.d.ts +237 -0
  136. package/dist/api/design/grids.d.ts.map +1 -0
  137. package/dist/api/design/index.d.ts +260 -0
  138. package/dist/api/design/index.d.ts.map +1 -0
  139. package/dist/api/design/lock.d.ts +67 -0
  140. package/dist/api/design/lock.d.ts.map +1 -0
  141. package/dist/api/design/materials/index.d.ts +551 -0
  142. package/dist/api/design/materials/index.d.ts.map +1 -0
  143. package/dist/api/design/query/geometry/index.d.ts +252 -0
  144. package/dist/api/design/query/geometry/index.d.ts.map +1 -0
  145. package/dist/api/design/query/grids.d.ts +287 -0
  146. package/dist/api/design/query/grids.d.ts.map +1 -0
  147. package/dist/api/design/query/index.d.ts +1318 -0
  148. package/dist/api/design/query/index.d.ts.map +1 -0
  149. package/dist/api/design/query/referenceLines.d.ts +45 -0
  150. package/dist/api/design/query/referenceLines.d.ts.map +1 -0
  151. package/dist/api/design/query/spaces.d.ts +394 -0
  152. package/dist/api/design/query/spaces.d.ts.map +1 -0
  153. package/dist/api/design/selection/index.d.ts +282 -0
  154. package/dist/api/design/selection/index.d.ts.map +1 -0
  155. package/dist/api/design/shared.d.ts +38 -0
  156. package/dist/api/design/shared.d.ts.map +1 -0
  157. package/dist/api/design/transform/index.d.ts +249 -0
  158. package/dist/api/design/transform/index.d.ts.map +1 -0
  159. package/dist/api/design/types/index.d.ts +181 -0
  160. package/dist/api/design/types/index.d.ts.map +1 -0
  161. package/dist/api/design/update/index.d.ts +803 -0
  162. package/dist/api/design/update/index.d.ts.map +1 -0
  163. package/dist/api/design/visibility.d.ts +126 -0
  164. package/dist/api/design/visibility.d.ts.map +1 -0
  165. package/dist/api/design/windows/index.d.ts +300 -0
  166. package/dist/api/design/windows/index.d.ts.map +1 -0
  167. package/dist/api/entity/buildableEnvelope.d.ts +265 -0
  168. package/dist/api/entity/buildableEnvelope.d.ts.map +1 -0
  169. package/dist/api/entity/department.d.ts +1 -0
  170. package/dist/api/entity/department.d.ts.map +1 -0
  171. package/dist/api/entity/index.d.ts +28 -0
  172. package/dist/api/entity/index.d.ts.map +1 -0
  173. package/dist/api/entity/referenceLine.d.ts +210 -0
  174. package/dist/api/entity/referenceLine.d.ts.map +1 -0
  175. package/dist/api/entity/space.d.ts +846 -0
  176. package/dist/api/entity/space.d.ts.map +1 -0
  177. package/dist/api/entity/story.d.ts +476 -0
  178. package/dist/api/entity/story.d.ts.map +1 -0
  179. package/dist/api/index.d.ts +45 -0
  180. package/dist/api/index.d.ts.map +1 -0
  181. package/dist/api/presentation/aiInspiration.d.ts +2400 -0
  182. package/dist/api/presentation/aiInspiration.d.ts.map +1 -0
  183. package/dist/api/presentation/annotate.d.ts +483 -0
  184. package/dist/api/presentation/annotate.d.ts.map +1 -0
  185. package/dist/api/presentation/diagrams.d.ts +184 -0
  186. package/dist/api/presentation/diagrams.d.ts.map +1 -0
  187. package/dist/api/presentation/drawings.d.ts +2900 -0
  188. package/dist/api/presentation/drawings.d.ts.map +1 -0
  189. package/dist/api/presentation/export.d.ts +126 -0
  190. package/dist/api/presentation/export.d.ts.map +1 -0
  191. package/dist/api/presentation/import.d.ts +164 -0
  192. package/dist/api/presentation/import.d.ts.map +1 -0
  193. package/dist/api/presentation/index.d.ts +114 -0
  194. package/dist/api/presentation/index.d.ts.map +1 -0
  195. package/dist/api/presentation/placedViews.d.ts +1232 -0
  196. package/dist/api/presentation/placedViews.d.ts.map +1 -0
  197. package/dist/api/presentation/shapes.d.ts +481 -0
  198. package/dist/api/presentation/shapes.d.ts.map +1 -0
  199. package/dist/api/presentation/sheets.d.ts +643 -0
  200. package/dist/api/presentation/sheets.d.ts.map +1 -0
  201. package/dist/api/presentation/slideshow.d.ts +125 -0
  202. package/dist/api/presentation/slideshow.d.ts.map +1 -0
  203. package/dist/api/presentation/tables.d.ts +81 -0
  204. package/dist/api/presentation/tables.d.ts.map +1 -0
  205. package/dist/api/presentation/viewPresets.d.ts +70 -0
  206. package/dist/api/presentation/viewPresets.d.ts.map +1 -0
  207. package/dist/api/presentation/views.d.ts +741 -0
  208. package/dist/api/presentation/views.d.ts.map +1 -0
  209. package/dist/api/program/adjacency.d.ts +155 -0
  210. package/dist/api/program/adjacency.d.ts.map +1 -0
  211. package/dist/api/program/areas.d.ts +450 -0
  212. package/dist/api/program/areas.d.ts.map +1 -0
  213. package/dist/api/program/classification.d.ts +135 -0
  214. package/dist/api/program/classification.d.ts.map +1 -0
  215. package/dist/api/program/cores.d.ts +78 -0
  216. package/dist/api/program/cores.d.ts.map +1 -0
  217. package/dist/api/program/departments.d.ts +487 -0
  218. package/dist/api/program/departments.d.ts.map +1 -0
  219. package/dist/api/program/index.d.ts +71 -0
  220. package/dist/api/program/index.d.ts.map +1 -0
  221. package/dist/api/program/labels.d.ts +355 -0
  222. package/dist/api/program/labels.d.ts.map +1 -0
  223. package/dist/api/program/layout.d.ts +398 -0
  224. package/dist/api/program/layout.d.ts.map +1 -0
  225. package/dist/api/program/metadata.d.ts +328 -0
  226. package/dist/api/program/metadata.d.ts.map +1 -0
  227. package/dist/api/program/metrics.d.ts +108 -0
  228. package/dist/api/program/metrics.d.ts.map +1 -0
  229. package/dist/api/program/site.d.ts +823 -0
  230. package/dist/api/program/site.d.ts.map +1 -0
  231. package/dist/api/program/spreadsheet.d.ts +2628 -0
  232. package/dist/api/program/spreadsheet.d.ts.map +1 -0
  233. package/dist/api/workspace/index.d.ts +552 -0
  234. package/dist/api/workspace/index.d.ts.map +1 -0
  235. package/dist/errors/codes.d.ts +34 -0
  236. package/dist/errors/codes.d.ts.map +1 -0
  237. package/dist/errors/envelope.d.ts +56 -0
  238. package/dist/errors/envelope.d.ts.map +1 -0
  239. package/dist/errors/index.d.ts +6 -0
  240. package/dist/errors/index.d.ts.map +1 -0
  241. package/dist/errors/plugin-error.d.ts +69 -0
  242. package/dist/errors/plugin-error.d.ts.map +1 -0
  243. package/dist/handles.d.ts +229 -0
  244. package/dist/handles.d.ts.map +1 -0
  245. package/dist/host-utils.d.ts +47 -0
  246. package/dist/host-utils.d.ts.map +1 -0
  247. package/dist/index.cjs +8836 -0
  248. package/dist/index.cjs.map +1 -0
  249. package/dist/index.d.ts +6 -0
  250. package/dist/index.d.ts.map +1 -0
  251. package/dist/index.js +7568 -0
  252. package/dist/index.js.map +1 -0
  253. package/dist/types.d.ts +16 -0
  254. package/dist/types.d.ts.map +1 -0
  255. package/package.json +41 -0
  256. package/scripts/generate-manifest.mjs +238 -0
  257. package/scripts/generate-manifest.test.mjs +292 -0
  258. package/src/api/analysis/daylight.ts +470 -0
  259. package/src/api/analysis/heatmaps.ts +683 -0
  260. package/src/api/analysis/illuminance.ts +155 -0
  261. package/src/api/analysis/index.ts +61 -0
  262. package/src/api/analysis/shadows.ts +183 -0
  263. package/src/api/analysis/solar.ts +237 -0
  264. package/src/api/analysis/sunlightHours.ts +211 -0
  265. package/src/api/analysis/sunpath.ts +83 -0
  266. package/src/api/analysis/weather.ts +179 -0
  267. package/src/api/core/buildings.ts +485 -0
  268. package/src/api/core/camera/index.ts +268 -0
  269. package/src/api/core/comment/index.ts +376 -0
  270. package/src/api/core/geom/create/index.ts +1204 -0
  271. package/src/api/core/geom/delete/index.ts +84 -0
  272. package/src/api/core/geom/index.ts +35 -0
  273. package/src/api/core/geom/query/arc.ts +169 -0
  274. package/src/api/core/geom/query/brep.ts +563 -0
  275. package/src/api/core/geom/query/circle.ts +404 -0
  276. package/src/api/core/geom/query/contour.ts +540 -0
  277. package/src/api/core/geom/query/curve.ts +1078 -0
  278. package/src/api/core/geom/query/edge.ts +130 -0
  279. package/src/api/core/geom/query/face.ts +403 -0
  280. package/src/api/core/geom/query/halfedge.ts +210 -0
  281. package/src/api/core/geom/query/index.ts +63 -0
  282. package/src/api/core/geom/query/profile.ts +473 -0
  283. package/src/api/core/geom/query/vertex.ts +205 -0
  284. package/src/api/core/geom/update/contour.ts +315 -0
  285. package/src/api/core/geom/update/curve.ts +209 -0
  286. package/src/api/core/geom/update/index.ts +29 -0
  287. package/src/api/core/geom/update/profile.ts +377 -0
  288. package/src/api/core/groups.ts +521 -0
  289. package/src/api/core/handles/index.ts +233 -0
  290. package/src/api/core/history/index.ts +84 -0
  291. package/src/api/core/index.ts +99 -0
  292. package/src/api/core/io/export/index.ts +126 -0
  293. package/src/api/core/io/import/index.ts +504 -0
  294. package/src/api/core/io/index.ts +42 -0
  295. package/src/api/core/io/job/index.ts +140 -0
  296. package/src/api/core/io/query/index.ts +71 -0
  297. package/src/api/core/io/terrain/index.ts +360 -0
  298. package/src/api/core/io/underlay/index.ts +705 -0
  299. package/src/api/core/layers.ts +333 -0
  300. package/src/api/core/math/index.ts +20 -0
  301. package/src/api/core/math/quat.ts +172 -0
  302. package/src/api/core/math/vec3.ts +179 -0
  303. package/src/api/core/mode/index.ts +108 -0
  304. package/src/api/core/project/index.ts +479 -0
  305. package/src/api/core/proposals/index.ts +569 -0
  306. package/src/api/core/storeys/index.ts +294 -0
  307. package/src/api/core/tags.ts +911 -0
  308. package/src/api/core/units/index.ts +164 -0
  309. package/src/api/core/user.ts +46 -0
  310. package/src/api/core/zoom/index.ts +51 -0
  311. package/src/api/design/boolean/index.ts +179 -0
  312. package/src/api/design/create/bulk-items.ts +186 -0
  313. package/src/api/design/create/grids.ts +137 -0
  314. package/src/api/design/create/index.ts +1954 -0
  315. package/src/api/design/create/opening-fields.ts +37 -0
  316. package/src/api/design/delete/index.ts +74 -0
  317. package/src/api/design/dimensions.ts +453 -0
  318. package/src/api/design/doors/index.ts +500 -0
  319. package/src/api/design/edit/index.ts +54 -0
  320. package/src/api/design/erase/index.ts +151 -0
  321. package/src/api/design/family.ts +646 -0
  322. package/src/api/design/furniture/index.ts +319 -0
  323. package/src/api/design/grids.ts +237 -0
  324. package/src/api/design/index.ts +274 -0
  325. package/src/api/design/lock.ts +69 -0
  326. package/src/api/design/materials/index.ts +608 -0
  327. package/src/api/design/query/geometry/index.ts +288 -0
  328. package/src/api/design/query/grids.ts +197 -0
  329. package/src/api/design/query/index.ts +1176 -0
  330. package/src/api/design/query/referenceLines.ts +52 -0
  331. package/src/api/design/query/spaces.ts +275 -0
  332. package/src/api/design/selection/index.ts +273 -0
  333. package/src/api/design/shared.ts +40 -0
  334. package/src/api/design/transform/index.ts +254 -0
  335. package/src/api/design/types/index.ts +156 -0
  336. package/src/api/design/update/index.ts +798 -0
  337. package/src/api/design/visibility.ts +143 -0
  338. package/src/api/design/windows/index.ts +333 -0
  339. package/src/api/entity/buildableEnvelope.ts +322 -0
  340. package/src/api/entity/department.ts +0 -0
  341. package/src/api/entity/index.ts +30 -0
  342. package/src/api/entity/referenceLine.ts +235 -0
  343. package/src/api/entity/space.ts +612 -0
  344. package/src/api/entity/story.ts +517 -0
  345. package/src/api/index.ts +47 -0
  346. package/src/api/presentation/aiInspiration.ts +1116 -0
  347. package/src/api/presentation/annotate.ts +417 -0
  348. package/src/api/presentation/diagrams.ts +194 -0
  349. package/src/api/presentation/drawings.ts +529 -0
  350. package/src/api/presentation/export.ts +133 -0
  351. package/src/api/presentation/import.ts +159 -0
  352. package/src/api/presentation/index.ts +129 -0
  353. package/src/api/presentation/placedViews.ts +1203 -0
  354. package/src/api/presentation/shapes.ts +274 -0
  355. package/src/api/presentation/sheets.ts +616 -0
  356. package/src/api/presentation/slideshow.ts +134 -0
  357. package/src/api/presentation/tables.ts +84 -0
  358. package/src/api/presentation/viewPresets.ts +83 -0
  359. package/src/api/presentation/views.ts +698 -0
  360. package/src/api/program/adjacency.ts +164 -0
  361. package/src/api/program/areas.ts +408 -0
  362. package/src/api/program/classification.ts +138 -0
  363. package/src/api/program/cores.ts +83 -0
  364. package/src/api/program/departments.ts +517 -0
  365. package/src/api/program/index.ts +73 -0
  366. package/src/api/program/labels.ts +332 -0
  367. package/src/api/program/layout.ts +422 -0
  368. package/src/api/program/metadata.ts +364 -0
  369. package/src/api/program/metrics.ts +120 -0
  370. package/src/api/program/site.ts +748 -0
  371. package/src/api/program/spreadsheet.ts +2698 -0
  372. package/src/api/workspace/index.ts +612 -0
  373. package/src/errors/codes.ts +136 -0
  374. package/src/errors/envelope.ts +75 -0
  375. package/src/errors/index.ts +21 -0
  376. package/src/errors/plugin-error.ts +134 -0
  377. package/src/handles.ts +282 -0
  378. package/src/host-utils.ts +68 -0
  379. package/src/index.ts +5 -0
  380. package/src/types.ts +16 -0
  381. package/test/errors.test.mjs +184 -0
  382. package/tsconfig.json +22 -0
  383. package/tsup.config.ts +12 -0
@@ -0,0 +1,1176 @@
1
+ import * as z from "zod"
2
+ import { PluginApiReturn } from "../../../types"
3
+ import { ComponentHandle, BBoxComponents } from "../../../handles"
4
+ import {
5
+ PluginSpaceType,
6
+ PluginMassType,
7
+ PluginDepartmentId,
8
+ PluginAreaClass,
9
+ } from "../../entity/space"
10
+ import { PluginStaircasePreset } from "../create"
11
+ import { PluginDesignQueryGeometryApi } from "./geometry"
12
+ import { PluginDesignQuerySpacesApi } from "./spaces"
13
+ import { PluginDesignQueryReferenceLinesApi } from "./referenceLines"
14
+ import { PluginDesignQueryGridsApi } from "./grids"
15
+
16
+ // ---------------------------------------------------------------------------
17
+ // Entity type vocabulary
18
+ // ---------------------------------------------------------------------------
19
+
20
+ /**
21
+ * The kind of a BIM entity — the discovery/filter vocabulary for the whole
22
+ * `design.query.*` surface. Values are clean `lowerCamel` tokens; the host maps
23
+ * each to the engine's internal type (whose raw strings are case-inconsistent —
24
+ * `"roof"`/`"slab"` lowercase, `"Wall"`/`"Door"` PascalCase — never surfaced here).
25
+ *
26
+ * | Value | Entity |
27
+ * |---|---|
28
+ * | `"wall"` | Wall |
29
+ * | `"space"` | Space (a room mass) |
30
+ * | `"mass"` | Generic mass (non-room) |
31
+ * | `"door"` | Door |
32
+ * | `"window"` | Window |
33
+ * | `"floor"` | Floor |
34
+ * | `"slab"` | Slab |
35
+ * | `"roof"` | Roof |
36
+ * | `"column"` | Column |
37
+ * | `"beam"` | Beam |
38
+ * | `"ceiling"` | Ceiling |
39
+ * | `"staircase"` | Staircase |
40
+ * | `"furniture"` | Furniture |
41
+ * | `"referenceLine"` | Reference line |
42
+ * | `"curtainWall"` | Parametric curtain wall |
43
+ * | `"mullion"` | Curtain-wall mullion |
44
+ * | `"panel"` | Curtain-wall panel |
45
+ * | `"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. |
46
+ * | `"grid"` | Structural grid group |
47
+ */
48
+ export const PluginEntityType = z.enum([
49
+ "wall",
50
+ "space",
51
+ "mass",
52
+ "door",
53
+ "window",
54
+ "floor",
55
+ "slab",
56
+ "roof",
57
+ "column",
58
+ "beam",
59
+ "ceiling",
60
+ "staircase",
61
+ "furniture",
62
+ "referenceLine",
63
+ "curtainWall",
64
+ "mullion",
65
+ "panel",
66
+ "parametricComponent",
67
+ "grid",
68
+ ])
69
+ export type PluginEntityType = z.infer<typeof PluginEntityType>
70
+
71
+ // ---------------------------------------------------------------------------
72
+ // The shared filter — one options object, every list* method
73
+ // ---------------------------------------------------------------------------
74
+
75
+ /**
76
+ * `EntityFilterOptions` — the **single filter** shared by every `design.query.list*`
77
+ * method, so filtering is identical across all BIM object types. Every field is
78
+ * optional and **AND-combined**: a component must satisfy all provided fields.
79
+ * Plural fields are arrays (match any of); singular fields are scalars. A field
80
+ * that names a type-specific dimension (`massTypes`/`spaceTypes`/`departmentId`)
81
+ * excludes components that lack that dimension.
82
+ *
83
+ * | Field | Type | Keeps components where |
84
+ * |---|---|---|
85
+ * | `types` | {@linkcode PluginEntityType}`[]` | entity kind ∈ `types` (ignored by per-type `list*` — the method fixes the kind) |
86
+ * | `storeys` | `number[]` | storey/floor level ∈ `storeys` (negative = basement) |
87
+ * | `buildingIds` | `string[]` | building ∈ `buildingIds` |
88
+ * | `structureIds` | `string[]` | structure ∈ `structureIds` |
89
+ * | `label` | `string` | label (`room_type` ?? mesh label) === `label` |
90
+ * | `massTypes` | {@linkcode PluginMassType}`[]` | mass-type ∈ (masses only) |
91
+ * | `spaceTypes` | {@linkcode PluginSpaceType}`[]` | space-type ∈ (spaces only) |
92
+ * | `departmentId` | {@linkcode PluginDepartmentId} | department === |
93
+ * | `isSelected` | `boolean` | current selection state === |
94
+ * | `isLocked` | `boolean` | lock flag === |
95
+ * | `isHidden` | `boolean` | user-hidden flag === |
96
+ * | `within` | {@linkcode BBoxComponents} | the entity's bounding box intersects the region |
97
+ * | `overlaps` | {@linkcode ComponentHandle} | the entity's plan footprint overlaps the given space's bottom-face footprint — non-zero intersection area, so fully-inside, boundary-nested, and partially-overhanging entities all match; edge-touching with zero interior overlap does not. Exact polygon intersection (holes respected). Tested in plan — storey height is ignored; compose with `storeys` to scope a floor. Hidden entities are excluded by default — pass `isHidden` explicitly to override. The reference space itself is never returned. Throws on an unknown id. Entities without a brep footprint use their bounding-box plan rectangle. |
98
+ * | `ids` | {@linkcode ComponentHandle}`[]` | id ∈ `ids` (restrict to a known set) |
99
+ */
100
+ export const PluginEntityFilter = z.object({
101
+ types: z.array(PluginEntityType).optional(),
102
+ storeys: z.array(z.number()).optional(),
103
+ buildingIds: z.array(z.string()).optional(),
104
+ structureIds: z.array(z.string()).optional(),
105
+ label: z.string().optional(),
106
+ massTypes: z.array(PluginMassType).optional(),
107
+ spaceTypes: z.array(PluginSpaceType).optional(),
108
+ departmentId: PluginDepartmentId.optional(),
109
+ isSelected: z.boolean().optional(),
110
+ isLocked: z.boolean().optional(),
111
+ isHidden: z.boolean().optional(),
112
+ within: BBoxComponents.optional(),
113
+ overlaps: ComponentHandle.optional(),
114
+ ids: z.array(ComponentHandle).optional(),
115
+ })
116
+ export type PluginEntityFilter = z.infer<typeof PluginEntityFilter>
117
+
118
+ /**
119
+ * Arguments for {@linkcode PluginDesignQueryApi.listByType} — a required entity
120
+ * `type` plus every {@linkcode PluginEntityFilter} field.
121
+ */
122
+ export const PluginDesignQueryListByTypeArgs = PluginEntityFilter.extend({
123
+ type: PluginEntityType,
124
+ })
125
+ export type PluginDesignQueryListByTypeArgs = z.infer<
126
+ typeof PluginDesignQueryListByTypeArgs
127
+ >
128
+
129
+ // ---------------------------------------------------------------------------
130
+ // Single-entity argument shapes
131
+ // ---------------------------------------------------------------------------
132
+
133
+ /** Arguments for methods that read one entity by its {@linkcode ComponentHandle}. */
134
+ export const PluginDesignQueryComponentArgs = z.object({
135
+ component: ComponentHandle,
136
+ })
137
+ export type PluginDesignQueryComponentArgs = z.infer<
138
+ typeof PluginDesignQueryComponentArgs
139
+ >
140
+
141
+ /** Arguments for methods that look an entity up by id. */
142
+ export const PluginDesignQueryIdArgs = z.object({
143
+ id: ComponentHandle,
144
+ })
145
+ export type PluginDesignQueryIdArgs = z.infer<typeof PluginDesignQueryIdArgs>
146
+
147
+ /** Arguments for methods over a set of entities (e.g. the union bounding box). */
148
+ export const PluginDesignQueryComponentsArgs = z.object({
149
+ components: z.array(ComponentHandle),
150
+ })
151
+ export type PluginDesignQueryComponentsArgs = z.infer<
152
+ typeof PluginDesignQueryComponentsArgs
153
+ >
154
+
155
+ // ---------------------------------------------------------------------------
156
+ // Read records
157
+ // ---------------------------------------------------------------------------
158
+
159
+ /**
160
+ * The common property record returned by {@linkcode PluginDesignQueryApi.getProperties} —
161
+ * a **partial** object (a field is present only when it applies to the entity).
162
+ * Type-specific and geometry reads live on {@linkcode PluginDesignQueryApi.measure}
163
+ * and `design.query.geometry.*`, keeping this record generic across every type.
164
+ *
165
+ * | Property | Type | Description |
166
+ * |---|---|---|
167
+ * | `id` | `string` | The entity id |
168
+ * | `type` | {@linkcode PluginEntityType} | Entity kind |
169
+ * | `label` | `string` | `room_type` ?? mesh label ?? `""` |
170
+ * | `storey` | `number` | Storey/floor level |
171
+ * | `buildingId` | `string` | Owning building |
172
+ * | `structureId` | `string` | Owning structure |
173
+ * | `massType` | `string` | Mass-type (masses only) |
174
+ * | `spaceType` | {@linkcode PluginSpaceType} | Space-type (spaces only) |
175
+ * | `areaClass` | {@linkcode PluginAreaClass} | Area classification (spaces only) |
176
+ * | `departmentId` | `string` | Department (masses only) |
177
+ * | `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)` |
178
+ * | `isLocked` | `boolean` | Lock flag |
179
+ * | `isHidden` | `boolean` | User-hidden flag |
180
+ * | `isSelected` | `boolean` | Current selection state |
181
+ * | `boundingBox` | {@linkcode BBoxComponents} | World-space AABB |
182
+ * | `adjacency` | `{ spaceId: string; value: number }[]` | Adjacency relationships (spaces/masses only). `value`: `2` = Direct (required), `1` = Indirect or physical contact, `-1` = Restricted; `0` entries are filtered out. `[]` when adjacency has never been computed — see `program.adjacency.compute`. |
183
+ */
184
+ export const PluginEntityProperties = z
185
+ .object({
186
+ id: z.string(),
187
+ type: PluginEntityType,
188
+ label: z.string(),
189
+ storey: z.number(),
190
+ buildingId: z.string(),
191
+ structureId: z.string(),
192
+ massType: z.string(),
193
+ spaceType: PluginSpaceType,
194
+ areaClass: PluginAreaClass,
195
+ departmentId: z.string(),
196
+ buildingType: z.string(),
197
+ isLocked: z.boolean(),
198
+ isHidden: z.boolean(),
199
+ isSelected: z.boolean(),
200
+ boundingBox: BBoxComponents,
201
+ adjacency: z.array(z.object({ spaceId: z.string(), value: z.number() })),
202
+ })
203
+ .partial()
204
+ export type PluginEntityProperties = z.infer<typeof PluginEntityProperties>
205
+
206
+ /**
207
+ * The multi-metric bundle returned by {@linkcode PluginDesignQueryApi.measure}.
208
+ * `boundingBox` is always present; the numeric metrics appear only when the
209
+ * entity's type computes them (area: floors/masses/slabs/roofs/beams/columns;
210
+ * volume: all; length: walls/beams).
211
+ *
212
+ * `thickness` and `height` are the Object Properties panel's dimension reads
213
+ * (the same engine source `design.update.wall` / `design.update.slab` etc.
214
+ * write through), in engine units. `thickness`: walls (the plan thickness —
215
+ * present only for straight orthogonal walls, exactly when the panel shows it)
216
+ * and slabs/floors/roofs/ceilings (the vertical extent the panel calls
217
+ * Thickness). `height`: walls only.
218
+ *
219
+ * | Property | Type | Description |
220
+ * |---|---|---|
221
+ * | `area` | `number`? | Bottom-face area |
222
+ * | `volume` | `number`? | Solid volume |
223
+ * | `length` | `number`? | Running length (linear elements) |
224
+ * | `thickness` | `number`? | Panel Thickness — walls (straight orthogonal only) and the slab family |
225
+ * | `height` | `number`? | Panel Height — walls only |
226
+ * | `boundingBox` | {@linkcode BBoxComponents} | World-space AABB (always present) |
227
+ */
228
+ export const PluginEntityMeasurements = z.object({
229
+ area: z.number().optional(),
230
+ volume: z.number().optional(),
231
+ length: z.number().optional(),
232
+ thickness: z.number().optional(),
233
+ height: z.number().optional(),
234
+ boundingBox: BBoxComponents,
235
+ })
236
+ export type PluginEntityMeasurements = z.infer<typeof PluginEntityMeasurements>
237
+
238
+ /**
239
+ * The parametric properties of a staircase — the same editable fields the
240
+ * staircase properties panel exposes. Returned by
241
+ * {@linkcode PluginDesignQueryApi.getStaircaseParams}; the write side is
242
+ * `design.update.staircase`. Engine internals (block schema, min well size,
243
+ * square-well padding) are deliberately excluded.
244
+ *
245
+ * All dimensions are in **engine units** (the same convention as
246
+ * `design.doors.getWidth`); `steps` is a unitless count. The invariant
247
+ * `staircaseHeight = steps × riser` is governed by the two lock booleans — see
248
+ * `design.update.staircase`. Type-specific fields (`wellSize`, `landingWidth`,
249
+ * `flightStartDistAfterTurn`) are present only when the preset uses them.
250
+ *
251
+ * | Property | Type | Description |
252
+ * |---|---|---|
253
+ * | `staircaseType` | {@linkcode PluginStaircasePreset} | Base staircase type |
254
+ * | `staircasePreset` | {@linkcode PluginStaircasePreset} | Named parametric preset |
255
+ * | `staircaseHeight` | `number` | Total rise (engine units) |
256
+ * | `steps` | `number` | Step count (unitless) |
257
+ * | `riser` | `number` | Riser height (engine units) |
258
+ * | `tread` | `number` | Tread depth (engine units) |
259
+ * | `width` | `number` | Flight width (engine units) |
260
+ * | `depth` | `number` | Slab/waist thickness (engine units) |
261
+ * | `wellSize` | `number`? | Stairwell gap (dogLegged / openWell / square) |
262
+ * | `landingWidth` | `number`? | Landing depth (straight / dogLegged) |
263
+ * | `flightStartDistAfterTurn` | `number`? | Flight offset after a turn (dogLegged / lShaped / square) |
264
+ * | `baseOffset` | `number` | Vertical offset from the storey base (engine units) |
265
+ * | `isStoreyHeightUnlocked` | `boolean` | When `false`, height is tied to the storey height |
266
+ * | `isStaircaseHeightUnlocked` | `boolean` | When `false`, height recomputes from steps × riser |
267
+ * | `storey` | `number` | Storey/floor level the staircase sits on |
268
+ */
269
+ export const PluginStaircaseParams = z.object({
270
+ staircaseType: PluginStaircasePreset,
271
+ staircasePreset: PluginStaircasePreset,
272
+ staircaseHeight: z.number(),
273
+ steps: z.number(),
274
+ riser: z.number(),
275
+ tread: z.number(),
276
+ width: z.number(),
277
+ depth: z.number(),
278
+ wellSize: z.number().optional(),
279
+ landingWidth: z.number().optional(),
280
+ flightStartDistAfterTurn: z.number().optional(),
281
+ baseOffset: z.number(),
282
+ isStoreyHeightUnlocked: z.boolean(),
283
+ isStaircaseHeightUnlocked: z.boolean(),
284
+ storey: z.number(),
285
+ })
286
+ export type PluginStaircaseParams = z.infer<typeof PluginStaircaseParams>
287
+
288
+ // ---------------------------------------------------------------------------
289
+ // The query API
290
+ // ---------------------------------------------------------------------------
291
+
292
+ /**
293
+ * `design.query.*` — read-only enumeration + inspection of scene-committed BIM
294
+ * entities (all-handle model, §11). No query mutates the scene.
295
+ *
296
+ * Every `list*` returns a snapshot {@linkcode ComponentHandle}`[]` (`[]`, never
297
+ * `null`) filtered by the shared {@linkcode PluginEntityFilter}; per-entity reads
298
+ * take a {@linkcode ComponentHandle} and return primitive records / child handles
299
+ * or `null` when the entity is gone. Resolve details of a returned handle with
300
+ * {@linkcode PluginDesignQueryApi.getProperties} / {@linkcode PluginDesignQueryApi.measure}
301
+ * / `design.query.geometry.*`.
302
+ *
303
+ * Accessed via `snaptrude.design.query`.
304
+ */
305
+ export abstract class PluginDesignQueryApi {
306
+ /** Entity-geometry reads (brep, bottom contour). See {@linkcode PluginDesignQueryGeometryApi}. */
307
+ public abstract geometry: PluginDesignQueryGeometryApi
308
+ /** Space-specific reads (footprint, …). See {@linkcode PluginDesignQuerySpacesApi}. */
309
+ public abstract spaces: PluginDesignQuerySpacesApi
310
+ /** Reference-line-specific reads. See {@linkcode PluginDesignQueryReferenceLinesApi}. */
311
+ public abstract referenceLines: PluginDesignQueryReferenceLinesApi
312
+ /** Structural-grid-specific reads. See {@linkcode PluginDesignQueryGridsApi}. */
313
+ public abstract grids: PluginDesignQueryGridsApi
314
+
315
+ constructor() {}
316
+
317
+ // ── enumeration ───────────────────────────────────────────────────────────
318
+
319
+ /**
320
+ * List **all** BIM entities in the project matching the filter.
321
+ *
322
+ * @param filter - an optional {@linkcode PluginEntityFilter}
323
+ * @returns matching entities as {@linkcode ComponentHandle}`[]` (`[]` if none)
324
+ *
325
+ * @examplePrompt Show me everything in the model
326
+ * @examplePrompt How many objects are on the ground floor?
327
+ * @examplePrompt List all the doors and windows on level 2
328
+ * @examplePrompt What elements are currently selected?
329
+ * @examplePrompt Find every hidden object in the project
330
+ *
331
+ * # Example
332
+ * ```ts
333
+ * // Doors and windows on the ground storey (fields AND-combine)
334
+ * const doorsAndWindows = await snaptrude.design.query.listEntities({
335
+ * types: ["door", "window"],
336
+ * storeys: [1],
337
+ * })
338
+ *
339
+ * // Everything the user currently has selected
340
+ * const selected = await snaptrude.design.query.listEntities({ isSelected: true })
341
+ *
342
+ * // Everything inside a world-space region (axis-aligned box, Snaptrude units)
343
+ * const inRegion = await snaptrude.design.query.listEntities({
344
+ * within: { min: { x: 0, y: 0, z: 0 }, max: { x: 10, y: 4, z: 8 } },
345
+ * })
346
+ * ```
347
+ */
348
+ public abstract listEntities(
349
+ filter?: PluginEntityFilter,
350
+ ): PluginApiReturn<ComponentHandle[]>
351
+
352
+ /**
353
+ * List all entities of one BIM object type — wall, door, slab, panel, and so
354
+ * on — optionally narrowed by the shared filter.
355
+ *
356
+ * @param type - the {@linkcode PluginEntityType} to list
357
+ * @param filter - an optional {@linkcode PluginEntityFilter}
358
+ * @returns matching entities as {@linkcode ComponentHandle}`[]`
359
+ *
360
+ * @examplePrompt List all the curtain walls in the project
361
+ * @examplePrompt Show every curtain wall panel on this storey
362
+ * @examplePrompt Get all the elements of a single type, like columns
363
+ * @examplePrompt Find all the locked slabs in the model
364
+ *
365
+ * # Example
366
+ * ```ts
367
+ * const lockedSlabs = await snaptrude.design.query.listByType("slab", { isLocked: true })
368
+ *
369
+ * // Curtain-wall panels on storeys 2-3 of one building
370
+ * const panels = await snaptrude.design.query.listByType("panel", {
371
+ * storeys: [2, 3],
372
+ * buildingIds: ["bld_1"],
373
+ * })
374
+ * ```
375
+ */
376
+ public abstract listByType(
377
+ type: PluginEntityType,
378
+ filter?: PluginEntityFilter,
379
+ ): PluginApiReturn<ComponentHandle[]>
380
+
381
+ /**
382
+ * List all the walls in the project, optionally filtered by storey, building,
383
+ * label, selection state, or region.
384
+ *
385
+ * The `types` field of the filter is ignored (this method fixes the kind).
386
+ *
387
+ * @param filter - an optional {@linkcode PluginEntityFilter}
388
+ * @returns wall {@linkcode ComponentHandle}`[]`
389
+ *
390
+ * @examplePrompt How many walls are in the project?
391
+ * @examplePrompt List all the walls on the ground floor
392
+ * @examplePrompt Which walls are currently selected?
393
+ * @examplePrompt Find the walls on level 2 of building A
394
+ * @examplePrompt Show me every hidden wall
395
+ *
396
+ * # Example
397
+ * ```ts
398
+ * const groundFloorWalls = await snaptrude.design.query.listWalls({ storeys: [1] })
399
+ * ```
400
+ */
401
+ public abstract listWalls(
402
+ filter?: PluginEntityFilter,
403
+ ): PluginApiReturn<ComponentHandle[]>
404
+
405
+ /**
406
+ * List all the spaces (rooms) in the project, optionally filtered by storey,
407
+ * department, space type, label, selection state, or region.
408
+ *
409
+ * @param filter - an optional {@linkcode PluginEntityFilter}
410
+ * @returns space {@linkcode ComponentHandle}`[]`
411
+ *
412
+ * @examplePrompt How many rooms are in this project?
413
+ * @examplePrompt List all the spaces on the second storey
414
+ * @examplePrompt Which rooms are in the Bedrooms department?
415
+ * @examplePrompt Find every room labelled Kitchen
416
+ * @examplePrompt Show the spaces that are currently selected
417
+ *
418
+ * # Example
419
+ * ```ts
420
+ * // Balconies and decks on storey 2 (`label` is an exact match on room_type)
421
+ * const outdoor = await snaptrude.design.query.listSpaces({
422
+ * storeys: [2],
423
+ * spaceTypes: ["Balcony", "Deck"],
424
+ * })
425
+ *
426
+ * // Rooms in a department: resolve its id first, then filter and total the area
427
+ * const { departments } = await snaptrude.program.departments.list()
428
+ * const bedrooms = departments.find((d) => d.name === "Bedrooms")
429
+ * if (bedrooms) {
430
+ * const rooms = await snaptrude.design.query.listSpaces({ departmentId: bedrooms.id })
431
+ * let total = 0
432
+ * for (const room of rooms) {
433
+ * const m = await snaptrude.design.query.measure(room)
434
+ * total += m?.area ?? 0
435
+ * }
436
+ * }
437
+ * ```
438
+ */
439
+ public abstract listSpaces(
440
+ filter?: PluginEntityFilter,
441
+ ): PluginApiReturn<ComponentHandle[]>
442
+
443
+ /**
444
+ * List all the generic masses (non-room massing volumes) in the project,
445
+ * optionally filtered by storey, building, label, mass type, or region.
446
+ *
447
+ * @param filter - an optional {@linkcode PluginEntityFilter}
448
+ * @returns mass {@linkcode ComponentHandle}`[]`
449
+ *
450
+ * @examplePrompt List all the masses in the model
451
+ * @examplePrompt How many massing blocks are on the site?
452
+ * @examplePrompt Show the generic masses on level 1
453
+ * @examplePrompt Find every mass that isn't a room
454
+ *
455
+ * # Example
456
+ * ```ts
457
+ * // Only certain mass kinds — massTypes matches any of the given values
458
+ * const massing = await snaptrude.design.query.listMasses({
459
+ * massTypes: ["Generic mass", "Plinth"],
460
+ * })
461
+ * ```
462
+ */
463
+ public abstract listMasses(
464
+ filter?: PluginEntityFilter,
465
+ ): PluginApiReturn<ComponentHandle[]>
466
+
467
+ /**
468
+ * List all the doors in the project, optionally filtered by storey, building,
469
+ * selection state, or region.
470
+ *
471
+ * @param filter - an optional {@linkcode PluginEntityFilter}
472
+ * @returns door {@linkcode ComponentHandle}`[]`
473
+ *
474
+ * @examplePrompt How many doors are in the project?
475
+ * @examplePrompt List all the doors on the ground floor
476
+ * @examplePrompt Which doors are currently selected?
477
+ * @examplePrompt Find every door in building B
478
+ *
479
+ * # Example
480
+ * ```ts
481
+ * // Ground-floor doors, then read each one's width via design.doors.*
482
+ * const doors = await snaptrude.design.query.listDoors({ storeys: [1] })
483
+ * for (const door of doors) {
484
+ * const width = await snaptrude.design.doors.getWidth(door)
485
+ * }
486
+ * ```
487
+ */
488
+ public abstract listDoors(
489
+ filter?: PluginEntityFilter,
490
+ ): PluginApiReturn<ComponentHandle[]>
491
+
492
+ /**
493
+ * List all the windows in the project, optionally filtered by storey,
494
+ * building, selection state, or region.
495
+ *
496
+ * @param filter - an optional {@linkcode PluginEntityFilter}
497
+ * @returns window {@linkcode ComponentHandle}`[]`
498
+ *
499
+ * @examplePrompt How many windows does this building have?
500
+ * @examplePrompt List every window on level 3
501
+ * @examplePrompt Which windows are on the ground floor?
502
+ * @examplePrompt Show all the windows that are currently selected
503
+ *
504
+ * # Example
505
+ * ```ts
506
+ * const level3Windows = await snaptrude.design.query.listWindows({ storeys: [3] })
507
+ * ```
508
+ */
509
+ public abstract listWindows(
510
+ filter?: PluginEntityFilter,
511
+ ): PluginApiReturn<ComponentHandle[]>
512
+
513
+ /**
514
+ * List all the floor elements (floor plates / finishes) in the project,
515
+ * optionally filtered by storey, building, lock state, or region.
516
+ *
517
+ * @param filter - an optional {@linkcode PluginEntityFilter}
518
+ * @returns floor {@linkcode ComponentHandle}`[]`
519
+ *
520
+ * @examplePrompt List all the floor elements in the model
521
+ * @examplePrompt How many floor plates are on the second storey?
522
+ * @examplePrompt Which floors are locked?
523
+ * @examplePrompt Show the floor finishes on level 0
524
+ *
525
+ * # Example
526
+ * ```ts
527
+ * const lockedFloors = await snaptrude.design.query.listFloors({ isLocked: true })
528
+ * ```
529
+ */
530
+ public abstract listFloors(
531
+ filter?: PluginEntityFilter,
532
+ ): PluginApiReturn<ComponentHandle[]>
533
+
534
+ /**
535
+ * List all the slabs in the project, optionally filtered by storey, building,
536
+ * lock state, or region.
537
+ *
538
+ * @param filter - an optional {@linkcode PluginEntityFilter}
539
+ * @returns slab {@linkcode ComponentHandle}`[]`
540
+ *
541
+ * @examplePrompt List all the slabs in the project
542
+ * @examplePrompt How many slabs are on level 2?
543
+ * @examplePrompt Which slabs are locked?
544
+ * @examplePrompt Show the slabs in the selected building
545
+ *
546
+ * # Example
547
+ * ```ts
548
+ * const storey2Slabs = await snaptrude.design.query.listSlabs({ storeys: [2] })
549
+ * ```
550
+ */
551
+ public abstract listSlabs(
552
+ filter?: PluginEntityFilter,
553
+ ): PluginApiReturn<ComponentHandle[]>
554
+
555
+ /**
556
+ * List all the roofs in the project, optionally filtered by storey, building,
557
+ * visibility, or region.
558
+ *
559
+ * @param filter - an optional {@linkcode PluginEntityFilter}
560
+ * @returns roof {@linkcode ComponentHandle}`[]`
561
+ *
562
+ * @examplePrompt How many roofs does the model have?
563
+ * @examplePrompt List all the roof elements
564
+ * @examplePrompt Show the roofs on the top storey
565
+ * @examplePrompt Find every hidden roof
566
+ *
567
+ * # Example
568
+ * ```ts
569
+ * const hiddenRoofs = await snaptrude.design.query.listRoofs({ isHidden: true })
570
+ * ```
571
+ */
572
+ public abstract listRoofs(
573
+ filter?: PluginEntityFilter,
574
+ ): PluginApiReturn<ComponentHandle[]>
575
+
576
+ /**
577
+ * List all the columns in the project, optionally filtered by storey,
578
+ * building, selection state, or region.
579
+ *
580
+ * @param filter - an optional {@linkcode PluginEntityFilter}
581
+ * @returns column {@linkcode ComponentHandle}`[]`
582
+ *
583
+ * @examplePrompt How many columns are on the ground floor?
584
+ * @examplePrompt List all the columns in building A
585
+ * @examplePrompt Show every column on level 3
586
+ * @examplePrompt Which columns are currently selected?
587
+ *
588
+ * # Example
589
+ * ```ts
590
+ * const groundFloorColumns = await snaptrude.design.query.listColumns({ storeys: [1] })
591
+ * ```
592
+ */
593
+ public abstract listColumns(
594
+ filter?: PluginEntityFilter,
595
+ ): PluginApiReturn<ComponentHandle[]>
596
+
597
+ /**
598
+ * List all the beams in the project, optionally filtered by storey, building,
599
+ * lock state, or region.
600
+ *
601
+ * @param filter - an optional {@linkcode PluginEntityFilter}
602
+ * @returns beam {@linkcode ComponentHandle}`[]`
603
+ *
604
+ * @examplePrompt List all the beams in the project
605
+ * @examplePrompt How many beams are on the second storey?
606
+ * @examplePrompt Show the beams in this structure
607
+ * @examplePrompt Find every locked beam
608
+ *
609
+ * # Example
610
+ * ```ts
611
+ * const storey2Beams = await snaptrude.design.query.listBeams({ storeys: [2] })
612
+ * ```
613
+ */
614
+ public abstract listBeams(
615
+ filter?: PluginEntityFilter,
616
+ ): PluginApiReturn<ComponentHandle[]>
617
+
618
+ /**
619
+ * List all the ceilings in the project, optionally filtered by storey,
620
+ * building, visibility, or region.
621
+ *
622
+ * @param filter - an optional {@linkcode PluginEntityFilter}
623
+ * @returns ceiling {@linkcode ComponentHandle}`[]`
624
+ *
625
+ * @examplePrompt List all the ceilings in the model
626
+ * @examplePrompt How many ceilings are on level 1?
627
+ * @examplePrompt Which ceilings are hidden?
628
+ * @examplePrompt Show the ceilings in building B
629
+ *
630
+ * # Example
631
+ * ```ts
632
+ * const hiddenCeilings = await snaptrude.design.query.listCeilings({ isHidden: true })
633
+ * ```
634
+ */
635
+ public abstract listCeilings(
636
+ filter?: PluginEntityFilter,
637
+ ): PluginApiReturn<ComponentHandle[]>
638
+
639
+ /**
640
+ * List all the staircases in the project, optionally filtered by storey,
641
+ * building, selection state, or region.
642
+ *
643
+ * @param filter - an optional {@linkcode PluginEntityFilter}
644
+ * @returns staircase {@linkcode ComponentHandle}`[]`
645
+ *
646
+ * @examplePrompt How many staircases are in the building?
647
+ * @examplePrompt List all the stairs in the project
648
+ * @examplePrompt Show the staircases on the ground floor
649
+ * @examplePrompt Which stairs are currently selected?
650
+ *
651
+ * # Example
652
+ * ```ts
653
+ * const groundFloorStairs = await snaptrude.design.query.listStaircases({ storeys: [1] })
654
+ * ```
655
+ */
656
+ public abstract listStaircases(
657
+ filter?: PluginEntityFilter,
658
+ ): PluginApiReturn<ComponentHandle[]>
659
+
660
+ /**
661
+ * List all the furniture in the project, optionally filtered by storey,
662
+ * building, label, selection state, or region.
663
+ *
664
+ * @param filter - an optional {@linkcode PluginEntityFilter}
665
+ * @returns furniture {@linkcode ComponentHandle}`[]`
666
+ *
667
+ * @examplePrompt List all the furniture in the project
668
+ * @examplePrompt How many furniture items are on this floor?
669
+ * @examplePrompt Show the furniture inside the selected room
670
+ * @examplePrompt Which furniture is on storey 2?
671
+ *
672
+ * # Example
673
+ * ```ts
674
+ * // Furniture whose plan footprint overlaps a room (`overlaps` is plan-only —
675
+ * // scope the storey too, or furniture stacked on other floors matches)
676
+ * const [kitchen] = await snaptrude.design.query.listSpaces({ label: "Kitchen" })
677
+ * if (kitchen) {
678
+ * const inKitchen = await snaptrude.design.query.listFurniture({
679
+ * overlaps: kitchen,
680
+ * storeys: [1],
681
+ * })
682
+ * }
683
+ * ```
684
+ */
685
+ public abstract listFurniture(
686
+ filter?: PluginEntityFilter,
687
+ ): PluginApiReturn<ComponentHandle[]>
688
+
689
+ /**
690
+ * List all the reference lines in the project, optionally filtered by storey,
691
+ * building, or region.
692
+ *
693
+ * @param filter - an optional {@linkcode PluginEntityFilter}
694
+ * @returns reference-line {@linkcode ComponentHandle}`[]`
695
+ *
696
+ * @examplePrompt List all the reference lines in the model
697
+ * @examplePrompt Show the guide lines on the ground floor
698
+ * @examplePrompt How many reference lines are on this storey?
699
+ * @examplePrompt Find the setting-out lines in building A
700
+ *
701
+ * # Example
702
+ * ```ts
703
+ * const groundFloorRefLines = await snaptrude.design.query.listReferenceLines({ storeys: [1] })
704
+ * ```
705
+ */
706
+ public abstract listReferenceLines(
707
+ filter?: PluginEntityFilter,
708
+ ): PluginApiReturn<ComponentHandle[]>
709
+
710
+ /**
711
+ * List all the curtain-wall mullions in the project, optionally filtered by
712
+ * storey, building, selection state, or region.
713
+ *
714
+ * @param filter - an optional {@linkcode PluginEntityFilter}
715
+ * @returns mullion {@linkcode ComponentHandle}`[]`
716
+ *
717
+ * @examplePrompt List all the mullions in the curtain wall
718
+ * @examplePrompt How many mullions are on the facade?
719
+ * @examplePrompt Show every curtain wall mullion on level 5
720
+ * @examplePrompt Which mullions are currently selected?
721
+ *
722
+ * # Example
723
+ * ```ts
724
+ * const level5Mullions = await snaptrude.design.query.listMullions({ storeys: [5] })
725
+ * ```
726
+ */
727
+ public abstract listMullions(
728
+ filter?: PluginEntityFilter,
729
+ ): PluginApiReturn<ComponentHandle[]>
730
+
731
+ /**
732
+ * List all the structural grids (grid groups) in the project, optionally
733
+ * filtered by storey, building, selection state, or region.
734
+ *
735
+ * @param filter - an optional {@linkcode PluginEntityFilter}
736
+ * @returns grid-group {@linkcode ComponentHandle}`[]`
737
+ *
738
+ * @examplePrompt List all the structural grids in the model
739
+ * @examplePrompt How many grids are on the ground floor?
740
+ * @examplePrompt Show the grids on this storey
741
+ * @examplePrompt Which grids are currently selected?
742
+ *
743
+ * # Example
744
+ * ```ts
745
+ * const groundFloorGrids = await snaptrude.design.query.listGrids({ storeys: [1] })
746
+ * ```
747
+ */
748
+ public abstract listGrids(
749
+ filter?: PluginEntityFilter,
750
+ ): PluginApiReturn<ComponentHandle[]>
751
+
752
+ // ── single-entity access & identity ─────────────────────────────────────────
753
+
754
+ /**
755
+ * Look an entity up by id — returns the same handle if it still resolves live,
756
+ * else `null`. A cheap validity probe (distinct from {@linkcode PluginDesignQueryApi.exists}).
757
+ *
758
+ * @param id - the entity id ({@linkcode ComponentHandle}) to look up
759
+ * @returns the {@linkcode ComponentHandle}, or `null` if it no longer resolves
760
+ *
761
+ * @examplePrompt Look up an object by its id
762
+ * @examplePrompt Does id cmp_42 still point to something in the model?
763
+ * @examplePrompt Fetch the element with this id
764
+ * @examplePrompt Check if this saved element id is still valid
765
+ *
766
+ * # Example
767
+ * ```ts
768
+ * // Persistence round-trip: save a ref now, revalidate it in a later run
769
+ * const [wall] = await snaptrude.design.query.listWalls()
770
+ * const savedRef = await snaptrude.design.query.getEntityRef(wall)
771
+ *
772
+ * // ...later (savedRef restored from plugin storage)...
773
+ * const stillThere = await snaptrude.design.query.getById(savedRef)
774
+ * if (stillThere) {
775
+ * const props = await snaptrude.design.query.getProperties(stillThere)
776
+ * }
777
+ * ```
778
+ */
779
+ public abstract getById(
780
+ id: ComponentHandle,
781
+ ): PluginApiReturn<ComponentHandle | null>
782
+
783
+ /**
784
+ * Test whether an entity id resolves to a live scene entity.
785
+ * @param id - the entity id ({@linkcode ComponentHandle}) to look up
786
+ * @returns `true` if it exists, otherwise `false`
787
+ *
788
+ * @examplePrompt Does this element still exist in the scene?
789
+ * @examplePrompt Check whether the wall I stored earlier is still there
790
+ * @examplePrompt Is id cmp_42 still valid?
791
+ * @examplePrompt Verify the object wasn't deleted
792
+ *
793
+ * # Example
794
+ * ```ts
795
+ * // Guard before acting on a handle that may have been deleted or undone
796
+ * if (await snaptrude.design.query.exists(wall)) {
797
+ * const dx = await snaptrude.core.math.vec3.new(5, 0, 0)
798
+ * await snaptrude.design.transform.move([wall], dx)
799
+ * }
800
+ * ```
801
+ */
802
+ public abstract exists(id: ComponentHandle): PluginApiReturn<boolean>
803
+
804
+ /**
805
+ * Get the kind of BIM entity a handle refers to — wall, door, space, slab,
806
+ * and so on (its {@linkcode PluginEntityType}).
807
+ * @param component - the entity's {@linkcode ComponentHandle}
808
+ * @returns the kind, or `null` if the entity is gone / its type is unknown
809
+ *
810
+ * @examplePrompt What kind of element is this?
811
+ * @examplePrompt Is the selected object a wall or a mass?
812
+ * @examplePrompt Tell me the type of this component
813
+ * @examplePrompt What am I looking at — a door, a window, or a panel?
814
+ *
815
+ * # Example
816
+ * ```ts
817
+ * // Dispatch on what the user selected
818
+ * const selection = await snaptrude.design.selection.get()
819
+ * for (const component of selection) {
820
+ * const kind = await snaptrude.design.query.getEntityType(component)
821
+ * if (kind === "wall") {
822
+ * // wall-specific handling
823
+ * } else if (kind === "space") {
824
+ * // room-specific handling
825
+ * }
826
+ * }
827
+ * ```
828
+ */
829
+ public abstract getEntityType(
830
+ component: ComponentHandle,
831
+ ): PluginApiReturn<PluginEntityType | null>
832
+
833
+ /**
834
+ * Get an entity's human label (`room_type` for spaces/masses, else the mesh
835
+ * label; `""` when unlabelled). The write side is `design.update` (`setLabel`).
836
+ * @param component - the entity's {@linkcode ComponentHandle}
837
+ * @returns the label string
838
+ *
839
+ * @examplePrompt What is this room called?
840
+ * @examplePrompt Get the name of the selected object
841
+ * @examplePrompt Show the label on this wall
842
+ * @examplePrompt What's the room type of this space?
843
+ *
844
+ * # Example
845
+ * ```ts
846
+ * // Fuzzy label search (the `label` filter field is exact-match; for
847
+ * // case-insensitive or partial matches, read labels and compare yourself)
848
+ * const spaces = await snaptrude.design.query.listSpaces()
849
+ * const kitchens: typeof spaces = []
850
+ * for (const space of spaces) {
851
+ * const label = await snaptrude.design.query.getLabel(space)
852
+ * if (label.toLowerCase().includes("kitchen")) kitchens.push(space)
853
+ * }
854
+ * ```
855
+ */
856
+ public abstract getLabel(component: ComponentHandle): PluginApiReturn<string>
857
+
858
+ /**
859
+ * Get a serializable, persistable reference to an entity. Under the all-handle
860
+ * model a {@linkcode ComponentHandle} already IS the ref (raw `Component.id`),
861
+ * so this is the identity passthrough — provided for API completeness.
862
+ * @param component - the entity's {@linkcode ComponentHandle}
863
+ * @returns the entity's {@linkcode ComponentHandle}
864
+ *
865
+ * @examplePrompt Give me a reference I can save for this element
866
+ * @examplePrompt Get a persistent id for the selected wall
867
+ * @examplePrompt Store a handle to this room so I can find it later
868
+ *
869
+ * # Example
870
+ * ```ts
871
+ * const [wall] = await snaptrude.design.query.listWalls()
872
+ * const savedRef = await snaptrude.design.query.getEntityRef(wall)
873
+ * // savedRef is a plain string — persist it, then revalidate in a later run
874
+ * // with snaptrude.design.query.getById(savedRef)
875
+ * ```
876
+ */
877
+ public abstract getEntityRef(
878
+ component: ComponentHandle,
879
+ ): PluginApiReturn<ComponentHandle>
880
+
881
+ /**
882
+ * List an entity's direct child entities — for example the doors and windows
883
+ * hosted in a wall.
884
+ * @param component - the entity's {@linkcode ComponentHandle}
885
+ * @returns child {@linkcode ComponentHandle}`[]` (`[]` if none)
886
+ *
887
+ * @examplePrompt What's inside this wall — list its doors and windows
888
+ * @examplePrompt Show the child elements of the selected object
889
+ * @examplePrompt Which openings belong to this wall?
890
+ * @examplePrompt List everything nested under this mass
891
+ *
892
+ * # Example
893
+ * ```ts
894
+ * // Count the openings hosted in a wall, split by kind
895
+ * const children = await snaptrude.design.query.listChildren(wall)
896
+ * let doors = 0
897
+ * let windows = 0
898
+ * for (const child of children) {
899
+ * const kind = await snaptrude.design.query.getEntityType(child)
900
+ * if (kind === "door") doors++
901
+ * if (kind === "window") windows++
902
+ * }
903
+ * ```
904
+ */
905
+ public abstract listChildren(
906
+ component: ComponentHandle,
907
+ ): PluginApiReturn<ComponentHandle[]>
908
+
909
+ /**
910
+ * Get an entity's host/parent entity (e.g. the wall a door is cut into).
911
+ * @param component - the entity's {@linkcode ComponentHandle}
912
+ * @returns the host {@linkcode ComponentHandle}, or `null` if top-level
913
+ *
914
+ * @examplePrompt Which wall is this door in?
915
+ * @examplePrompt Find the parent of the selected window
916
+ * @examplePrompt What is this element attached to?
917
+ * @examplePrompt Which wall hosts this window?
918
+ *
919
+ * # Example
920
+ * ```ts
921
+ * // From a door up to its host wall, then measure the wall
922
+ * const [door] = await snaptrude.design.query.listDoors({ isSelected: true })
923
+ * const hostWall = door ? await snaptrude.design.query.getHost(door) : null
924
+ * if (hostWall) {
925
+ * const m = await snaptrude.design.query.measure(hostWall)
926
+ * console.log("wall length:", m?.length)
927
+ * }
928
+ * ```
929
+ */
930
+ public abstract getHost(
931
+ component: ComponentHandle,
932
+ ): PluginApiReturn<ComponentHandle | null>
933
+
934
+ // ── property & metric reads ─────────────────────────────────────────────────
935
+
936
+ /**
937
+ * Read an entity's common properties as a {@linkcode PluginEntityProperties}
938
+ * record (only applicable fields are present). For spaces/masses this includes
939
+ * `adjacency` — the per-entity adjacency read (bulk form:
940
+ * `program.adjacency.getMatrix`). For walls and the slab family (slab / floor
941
+ * / roof / ceiling) this includes `buildingType` — the assigned building type
942
+ * NAME the panel's type dropdown shows, matching `design.types.list(kind)`.
943
+ *
944
+ * @param component - the entity's {@linkcode ComponentHandle}
945
+ * @returns the property record
946
+ *
947
+ * @examplePrompt Show me all the details of the selected object
948
+ * @examplePrompt What storey is this wall on?
949
+ * @examplePrompt Which wall type is assigned to this wall?
950
+ * @examplePrompt Which department does this room belong to?
951
+ * @examplePrompt Is this element locked or hidden?
952
+ * @examplePrompt Get the adjacencies of this space
953
+ *
954
+ * # Example
955
+ * ```ts
956
+ * const [wall] = await snaptrude.design.query.listWalls()
957
+ * const props = await snaptrude.design.query.getProperties(wall)
958
+ * console.log(props.type, props.storey, props.boundingBox)
959
+ *
960
+ * // The record is partial — type-specific fields exist only where they apply
961
+ * const [room] = await snaptrude.design.query.listSpaces()
962
+ * const p = await snaptrude.design.query.getProperties(room)
963
+ * if (p.spaceType === "Room" && p.areaClass === "NET") {
964
+ * for (const adj of p.adjacency ?? []) {
965
+ * // adj.value: 2 = direct, 1 = indirect/contact, -1 = restricted
966
+ * console.log(adj.spaceId, adj.value)
967
+ * }
968
+ * }
969
+ * ```
970
+ */
971
+ public abstract getProperties(
972
+ component: ComponentHandle,
973
+ ): PluginApiReturn<PluginEntityProperties>
974
+
975
+ /**
976
+ * Measure an entity — read its area, volume, and/or running length (whichever
977
+ * its type supports) together with its world-space bounding box in one call.
978
+ *
979
+ * For walls and the slab family this also carries the Object Properties
980
+ * panel's dimension reads in engine units: `thickness` (walls — straight
981
+ * orthogonal only, exactly when the panel shows it; slabs / floors / roofs /
982
+ * ceilings — the vertical extent the panel calls Thickness) and `height`
983
+ * (walls). These are the read side of `design.update.wall` /
984
+ * `design.update.slab` / `.floor` / `.roof` / `.ceiling`.
985
+ *
986
+ * @param component - the entity's {@linkcode ComponentHandle}
987
+ * @returns a {@linkcode PluginEntityMeasurements}, or `null` if the entity is gone
988
+ *
989
+ * @examplePrompt What's the area of this room?
990
+ * @examplePrompt How long is the selected wall?
991
+ * @examplePrompt How thick is this wall?
992
+ * @examplePrompt Get the thickness of the slab on level 2
993
+ * @examplePrompt Get the volume of this mass
994
+ * @examplePrompt Give me the dimensions of the selected element
995
+ * @examplePrompt What's the floor area of the kitchen?
996
+ *
997
+ * # Example
998
+ * ```ts
999
+ * const [space] = await snaptrude.design.query.listSpaces()
1000
+ * const m = await snaptrude.design.query.measure(space)
1001
+ * console.log(m?.area, m?.volume)
1002
+ *
1003
+ * // wall dimensions — the panel's Thickness / Height, in engine units
1004
+ * const [wall] = await snaptrude.design.query.listWalls()
1005
+ * const wm = await snaptrude.design.query.measure(wall)
1006
+ * console.log(wm?.thickness, wm?.height)
1007
+ * ```
1008
+ */
1009
+ public abstract measure(
1010
+ component: ComponentHandle,
1011
+ ): PluginApiReturn<PluginEntityMeasurements | null>
1012
+
1013
+ /**
1014
+ * Read a staircase's parametric properties — its preset, dimensions, step
1015
+ * count, base offset, and height-lock state — as a
1016
+ * {@linkcode PluginStaircaseParams} record. The paired write is
1017
+ * `design.update.staircase`.
1018
+ *
1019
+ * All dimensions are in **engine units** (the same convention as
1020
+ * `design.doors.getWidth`); `steps` is a unitless count. A read — never
1021
+ * throws: returns `null` for a handle that is not a staircase or no longer
1022
+ * resolves.
1023
+ *
1024
+ * @param staircase - the staircase's {@linkcode ComponentHandle}
1025
+ * @returns the {@linkcode PluginStaircaseParams} record, or `null`
1026
+ *
1027
+ * @examplePrompt What's the riser height of this staircase?
1028
+ * @examplePrompt How many steps does the selected stair have?
1029
+ * @examplePrompt Show me the tread and width of this staircase
1030
+ * @examplePrompt Read all the parameters of the stairs on level 1
1031
+ *
1032
+ * # Example
1033
+ * ```ts
1034
+ * const [stair] = await snaptrude.design.query.listStaircases({ isSelected: true })
1035
+ * const params = stair ? await snaptrude.design.query.getStaircaseParams(stair) : null
1036
+ * if (params) console.log(params.steps, params.riser, params.tread)
1037
+ * ```
1038
+ */
1039
+ public abstract getStaircaseParams(
1040
+ staircase: ComponentHandle,
1041
+ ): PluginApiReturn<PluginStaircaseParams | null>
1042
+
1043
+ /**
1044
+ * Get the **union** axis-aligned bounding box enclosing a set of entities.
1045
+ *
1046
+ * @param components - the set of entity {@linkcode ComponentHandle}s
1047
+ * @returns the union {@linkcode BBoxComponents}, or `null` if the set is empty /
1048
+ * none resolve
1049
+ *
1050
+ * @examplePrompt Get the bounding box around the selected objects
1051
+ * @examplePrompt What is the overall extent of these walls?
1052
+ * @examplePrompt How big is the region these elements cover together?
1053
+ * @examplePrompt Find the combined extents of everything on level 2
1054
+ *
1055
+ * # Example
1056
+ * ```ts
1057
+ * const walls = await snaptrude.design.query.listWalls()
1058
+ * const box = await snaptrude.design.query.getBoundingBox(walls)
1059
+ *
1060
+ * // Compose with the `within` filter: everything in the selection's extents
1061
+ * const selection = await snaptrude.design.selection.get()
1062
+ * const extents = await snaptrude.design.query.getBoundingBox(selection)
1063
+ * if (extents) {
1064
+ * const nearby = await snaptrude.design.query.listEntities({ within: extents })
1065
+ * const width = extents.max.x - extents.min.x
1066
+ * }
1067
+ * ```
1068
+ */
1069
+ public abstract getBoundingBox(
1070
+ components: ComponentHandle[],
1071
+ ): PluginApiReturn<BBoxComponents | null>
1072
+
1073
+ /**
1074
+ * Compute the plan **outline of what is built on a storey** — the union of
1075
+ * the storey's wall (by default) footprints as polygons-with-holes. This is
1076
+ * the footprint-from-the-built-model query: by the time slabs are needed the
1077
+ * walls exist, and the engine's own solids (snapped, joined and mitred at
1078
+ * creation) are the cleanest wall network available — no CAD re-tracing.
1079
+ *
1080
+ * Semantics: the union of wall solids is the wall *material* — a ring-shaped
1081
+ * polygon. The **outer ring is the OUTSIDE wall face** (the slab boundary);
1082
+ * every enclosed region — rooms AND courtyards — appears as a hole. When the
1083
+ * largest hole is ~zero the walls don't enclose anything: the footprint
1084
+ * reports `enclosed: false` (an open wall network), never a garbage outline.
1085
+ * Detached buildings come back as separate footprints.
1086
+ *
1087
+ * A read — nothing is created. Feed a footprint's `outline` to
1088
+ * `core.geom.create.profileFromLinePoints` → `design.create.slab` to build
1089
+ * the floor/roof plate. Coordinates are world-space plan (x, z) in Snaptrude
1090
+ * internal units; `areaSq` values are in squared internal units.
1091
+ *
1092
+ * @param options - storey / included kinds / debris filter; see
1093
+ * {@linkcode PluginStoreyOutlineOptions}.
1094
+ * @returns the storey's footprints (possibly several for detached buildings)
1095
+ * plus pieces discarded by `minArea` (`footprints: []` when nothing matches).
1096
+ *
1097
+ * @examplePrompt What is the building footprint on the ground floor?
1098
+ * @examplePrompt Create a floor slab covering the whole storey
1099
+ * @examplePrompt Get the outline of the walls on storey 1
1100
+ * @examplePrompt How much area do the ground-floor walls enclose?
1101
+ *
1102
+ * # Example
1103
+ * ```ts
1104
+ * const r = await snaptrude.design.query.storeyOutline({ storey: 1 })
1105
+ * const main = r.footprints.find((f) => f.enclosed)
1106
+ * if (main) {
1107
+ * const profile = await snaptrude.core.geom.create.profileFromLinePoints(
1108
+ * main.outline.map((p) => ({ x: p.x, y: 0, z: p.z })),
1109
+ * )
1110
+ * // → design.create.slab with the profile's contour
1111
+ * }
1112
+ * ```
1113
+ */
1114
+ public abstract storeyOutline(
1115
+ options?: PluginStoreyOutlineOptions,
1116
+ ): PluginApiReturn<PluginStoreyOutlineResult>
1117
+ }
1118
+
1119
+
1120
+ /** A point in the world-space plan (x, z) projection, Snaptrude internal units. */
1121
+ export const PluginOutlinePlanPoint = z.object({ x: z.number(), z: z.number() })
1122
+ export type PluginOutlinePlanPoint = z.infer<typeof PluginOutlinePlanPoint>
1123
+
1124
+ /**
1125
+ * Options for {@link PluginDesignQueryApi.storeyOutline}.
1126
+ *
1127
+ * | Property | Type | Description |
1128
+ * |---|---|---|
1129
+ * | `storey` | `number`? | Only components on this storey (default: all storeys) |
1130
+ * | `include` | {@link PluginEntityType}`[]`? | Component kinds to union (default `["wall"]`) |
1131
+ * | `minArea` | `number`? | Drop union pieces below this plan area, squared internal units (default `1`) |
1132
+ */
1133
+ export const PluginStoreyOutlineOptions = z.object({
1134
+ storey: z.number().int().optional(),
1135
+ include: z.array(PluginEntityType).nonempty().default(["wall"]),
1136
+ minArea: z.number().nonnegative().default(1),
1137
+ })
1138
+ export type PluginStoreyOutlineOptions = z.input<
1139
+ typeof PluginStoreyOutlineOptions
1140
+ >
1141
+
1142
+ /**
1143
+ * One connected footprint from {@link PluginDesignQueryApi.storeyOutline}.
1144
+ * `outline` traces the OUTSIDE wall face; `holes` are the enclosed regions
1145
+ * (rooms and courtyards). `enclosed` is `false` when the wall network does not
1146
+ * close around any region (open C-shape) — don't slab an unenclosed outline
1147
+ * without checking it.
1148
+ */
1149
+ export const PluginStoreyFootprint = z.object({
1150
+ outline: z.array(PluginOutlinePlanPoint),
1151
+ holes: z.array(
1152
+ z.object({
1153
+ ring: z.array(PluginOutlinePlanPoint),
1154
+ areaSq: z.number().nonnegative(),
1155
+ }),
1156
+ ),
1157
+ areaSq: z.number().nonnegative(),
1158
+ enclosed: z.boolean(),
1159
+ })
1160
+ export type PluginStoreyFootprint = z.infer<typeof PluginStoreyFootprint>
1161
+
1162
+ /** Result of {@link PluginDesignQueryApi.storeyOutline}. */
1163
+ export const PluginStoreyOutlineResult = z.object({
1164
+ footprints: z.array(PluginStoreyFootprint),
1165
+ discarded: z.array(
1166
+ z.object({ areaSq: z.number().nonnegative(), reason: z.string() }),
1167
+ ),
1168
+ })
1169
+ export type PluginStoreyOutlineResult = z.infer<
1170
+ typeof PluginStoreyOutlineResult
1171
+ >
1172
+
1173
+ export * from "./geometry"
1174
+ export * from "./spaces"
1175
+ export * from "./referenceLines"
1176
+ export * from "./grids"