@snaptrude/plugin-core 0.7.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/api-manifest.full.json +7703 -0
  3. package/api-manifest.json +2946 -259
  4. package/dist/api/analysis/daylight.d.ts +603 -0
  5. package/dist/api/analysis/daylight.d.ts.map +1 -0
  6. package/dist/api/analysis/heatmaps.d.ts +438 -14
  7. package/dist/api/analysis/heatmaps.d.ts.map +1 -1
  8. package/dist/api/analysis/index.d.ts +15 -0
  9. package/dist/api/analysis/index.d.ts.map +1 -1
  10. package/dist/api/analysis/solar.d.ts +249 -0
  11. package/dist/api/analysis/solar.d.ts.map +1 -0
  12. package/dist/api/analysis/weather.d.ts +193 -0
  13. package/dist/api/analysis/weather.d.ts.map +1 -0
  14. package/dist/api/core/camera/index.d.ts +245 -0
  15. package/dist/api/core/camera/index.d.ts.map +1 -0
  16. package/dist/api/core/comment/index.d.ts +105 -2
  17. package/dist/api/core/comment/index.d.ts.map +1 -1
  18. package/dist/api/core/geom/create/index.d.ts +331 -14
  19. package/dist/api/core/geom/create/index.d.ts.map +1 -1
  20. package/dist/api/core/geom/delete/index.d.ts +8 -2
  21. package/dist/api/core/geom/delete/index.d.ts.map +1 -1
  22. package/dist/api/core/geom/query/arc.d.ts +5 -5
  23. package/dist/api/core/geom/query/brep.d.ts +18 -18
  24. package/dist/api/core/geom/query/circle.d.ts +18 -18
  25. package/dist/api/core/geom/query/contour.d.ts +20 -20
  26. package/dist/api/core/geom/query/curve.d.ts +49 -49
  27. package/dist/api/core/geom/query/edge.d.ts +5 -5
  28. package/dist/api/core/geom/query/face.d.ts +16 -16
  29. package/dist/api/core/geom/query/halfedge.d.ts +8 -8
  30. package/dist/api/core/geom/query/profile.d.ts +19 -19
  31. package/dist/api/core/geom/query/vertex.d.ts +8 -8
  32. package/dist/api/core/geom/update/contour.d.ts +14 -14
  33. package/dist/api/core/geom/update/curve.d.ts +7 -7
  34. package/dist/api/core/geom/update/profile.d.ts +16 -16
  35. package/dist/api/core/handles/index.d.ts +210 -0
  36. package/dist/api/core/handles/index.d.ts.map +1 -0
  37. package/dist/api/core/index.d.ts +24 -0
  38. package/dist/api/core/index.d.ts.map +1 -1
  39. package/dist/api/core/io/export/index.d.ts +134 -0
  40. package/dist/api/core/io/export/index.d.ts.map +1 -0
  41. package/dist/api/core/io/import/index.d.ts +62 -1
  42. package/dist/api/core/io/import/index.d.ts.map +1 -1
  43. package/dist/api/core/io/index.d.ts +5 -0
  44. package/dist/api/core/io/index.d.ts.map +1 -1
  45. package/dist/api/core/layers.d.ts +7 -7
  46. package/dist/api/core/mode/index.d.ts +99 -0
  47. package/dist/api/core/mode/index.d.ts.map +1 -0
  48. package/dist/api/core/proposals/index.d.ts +65 -9
  49. package/dist/api/core/proposals/index.d.ts.map +1 -1
  50. package/dist/api/core/storeys/index.d.ts +251 -0
  51. package/dist/api/core/storeys/index.d.ts.map +1 -0
  52. package/dist/api/core/tags.d.ts +24 -0
  53. package/dist/api/core/tags.d.ts.map +1 -1
  54. package/dist/api/core/user.d.ts +44 -0
  55. package/dist/api/core/user.d.ts.map +1 -0
  56. package/dist/api/core/zoom/index.d.ts +4 -0
  57. package/dist/api/core/zoom/index.d.ts.map +1 -1
  58. package/dist/api/design/boolean/index.d.ts +4 -4
  59. package/dist/api/design/create/index.d.ts +253 -47
  60. package/dist/api/design/create/index.d.ts.map +1 -1
  61. package/dist/api/design/delete/index.d.ts +3 -0
  62. package/dist/api/design/delete/index.d.ts.map +1 -1
  63. package/dist/api/design/doors/index.d.ts +36 -0
  64. package/dist/api/design/doors/index.d.ts.map +1 -1
  65. package/dist/api/design/edit/index.d.ts +1 -1
  66. package/dist/api/design/erase/index.d.ts +2 -2
  67. package/dist/api/design/furniture/index.d.ts +114 -3
  68. package/dist/api/design/furniture/index.d.ts.map +1 -1
  69. package/dist/api/design/index.d.ts +10 -0
  70. package/dist/api/design/index.d.ts.map +1 -1
  71. package/dist/api/design/materials/index.d.ts +111 -14
  72. package/dist/api/design/materials/index.d.ts.map +1 -1
  73. package/dist/api/design/query/geometry/index.d.ts +112 -0
  74. package/dist/api/design/query/geometry/index.d.ts.map +1 -1
  75. package/dist/api/design/query/index.d.ts +35 -1
  76. package/dist/api/design/query/index.d.ts.map +1 -1
  77. package/dist/api/design/query/referenceLines.d.ts +45 -0
  78. package/dist/api/design/query/referenceLines.d.ts.map +1 -0
  79. package/dist/api/design/query/spaces.d.ts +178 -5
  80. package/dist/api/design/query/spaces.d.ts.map +1 -1
  81. package/dist/api/design/transform/index.d.ts +95 -14
  82. package/dist/api/design/transform/index.d.ts.map +1 -1
  83. package/dist/api/design/types/index.d.ts +181 -0
  84. package/dist/api/design/types/index.d.ts.map +1 -0
  85. package/dist/api/design/update/index.d.ts +385 -2
  86. package/dist/api/design/update/index.d.ts.map +1 -1
  87. package/dist/api/design/visibility.d.ts +98 -0
  88. package/dist/api/design/visibility.d.ts.map +1 -0
  89. package/dist/api/entity/buildableEnvelope.d.ts +4 -0
  90. package/dist/api/entity/buildableEnvelope.d.ts.map +1 -1
  91. package/dist/api/entity/referenceLine.d.ts +10 -2
  92. package/dist/api/entity/referenceLine.d.ts.map +1 -1
  93. package/dist/api/entity/space.d.ts +19 -19
  94. package/dist/api/entity/story.d.ts +148 -15
  95. package/dist/api/entity/story.d.ts.map +1 -1
  96. package/dist/api/index.d.ts +5 -0
  97. package/dist/api/index.d.ts.map +1 -1
  98. package/dist/api/presentation/annotate.d.ts +448 -0
  99. package/dist/api/presentation/annotate.d.ts.map +1 -0
  100. package/dist/api/presentation/diagrams.d.ts +49 -8
  101. package/dist/api/presentation/diagrams.d.ts.map +1 -1
  102. package/dist/api/presentation/export.d.ts +108 -0
  103. package/dist/api/presentation/export.d.ts.map +1 -0
  104. package/dist/api/presentation/import.d.ts +6 -0
  105. package/dist/api/presentation/import.d.ts.map +1 -1
  106. package/dist/api/presentation/index.d.ts +47 -0
  107. package/dist/api/presentation/index.d.ts.map +1 -1
  108. package/dist/api/presentation/placedViews.d.ts +370 -0
  109. package/dist/api/presentation/placedViews.d.ts.map +1 -0
  110. package/dist/api/presentation/shapes.d.ts +481 -0
  111. package/dist/api/presentation/shapes.d.ts.map +1 -0
  112. package/dist/api/presentation/sheets.d.ts +410 -13
  113. package/dist/api/presentation/sheets.d.ts.map +1 -1
  114. package/dist/api/presentation/views.d.ts +165 -10
  115. package/dist/api/presentation/views.d.ts.map +1 -1
  116. package/dist/api/program/areas.d.ts +63 -3
  117. package/dist/api/program/areas.d.ts.map +1 -1
  118. package/dist/api/program/cores.d.ts +3 -99
  119. package/dist/api/program/cores.d.ts.map +1 -1
  120. package/dist/api/program/index.d.ts +2 -2
  121. package/dist/api/program/index.d.ts.map +1 -1
  122. package/dist/api/program/layout.d.ts +172 -12
  123. package/dist/api/program/layout.d.ts.map +1 -1
  124. package/dist/api/program/site.d.ts +105 -8
  125. package/dist/api/program/site.d.ts.map +1 -1
  126. package/dist/api/program/spreadsheet.d.ts +365 -41
  127. package/dist/api/program/spreadsheet.d.ts.map +1 -1
  128. package/dist/api/workspace/index.d.ts +460 -0
  129. package/dist/api/workspace/index.d.ts.map +1 -0
  130. package/dist/handles.d.ts +64 -25
  131. package/dist/handles.d.ts.map +1 -1
  132. package/dist/index.cjs +3210 -1671
  133. package/dist/index.cjs.map +1 -1
  134. package/dist/index.js +3008 -1666
  135. package/dist/index.js.map +1 -1
  136. package/package.json +3 -2
  137. package/scripts/generate-manifest.mjs +45 -0
  138. package/src/api/analysis/daylight.ts +470 -0
  139. package/src/api/analysis/heatmaps.ts +444 -17
  140. package/src/api/analysis/index.ts +15 -0
  141. package/src/api/analysis/solar.ts +237 -0
  142. package/src/api/analysis/weather.ts +179 -0
  143. package/src/api/core/camera/index.ts +251 -0
  144. package/src/api/core/comment/index.ts +120 -2
  145. package/src/api/core/geom/create/index.ts +344 -1
  146. package/src/api/core/geom/delete/index.ts +6 -0
  147. package/src/api/core/handles/index.ts +233 -0
  148. package/src/api/core/index.ts +24 -0
  149. package/src/api/core/io/export/index.ts +126 -0
  150. package/src/api/core/io/import/index.ts +64 -0
  151. package/src/api/core/io/index.ts +5 -0
  152. package/src/api/core/mode/index.ts +96 -0
  153. package/src/api/core/proposals/index.ts +71 -11
  154. package/src/api/core/storeys/index.ts +279 -0
  155. package/src/api/core/tags.ts +27 -0
  156. package/src/api/core/user.ts +46 -0
  157. package/src/api/core/zoom/index.ts +4 -0
  158. package/src/api/design/create/index.ts +303 -36
  159. package/src/api/design/delete/index.ts +3 -0
  160. package/src/api/design/doors/index.ts +40 -0
  161. package/src/api/design/furniture/index.ts +127 -3
  162. package/src/api/design/index.ts +10 -0
  163. package/src/api/design/materials/index.ts +157 -30
  164. package/src/api/design/query/geometry/index.ts +125 -3
  165. package/src/api/design/query/index.ts +37 -7
  166. package/src/api/design/query/referenceLines.ts +52 -0
  167. package/src/api/design/query/spaces.ts +143 -0
  168. package/src/api/design/transform/index.ts +101 -12
  169. package/src/api/design/types/index.ts +156 -0
  170. package/src/api/design/update/index.ts +467 -6
  171. package/src/api/design/visibility.ts +109 -0
  172. package/src/api/entity/buildableEnvelope.ts +4 -0
  173. package/src/api/entity/referenceLine.ts +8 -0
  174. package/src/api/entity/story.ts +161 -15
  175. package/src/api/index.ts +5 -0
  176. package/src/api/presentation/annotate.ts +360 -0
  177. package/src/api/presentation/diagrams.ts +53 -8
  178. package/src/api/presentation/export.ts +108 -0
  179. package/src/api/presentation/import.ts +6 -0
  180. package/src/api/presentation/index.ts +55 -0
  181. package/src/api/presentation/placedViews.ts +363 -0
  182. package/src/api/presentation/shapes.ts +274 -0
  183. package/src/api/presentation/sheets.ts +346 -13
  184. package/src/api/presentation/views.ts +164 -12
  185. package/src/api/program/areas.ts +57 -6
  186. package/src/api/program/cores.ts +3 -91
  187. package/src/api/program/index.ts +2 -2
  188. package/src/api/program/layout.ts +182 -12
  189. package/src/api/program/site.ts +106 -8
  190. package/src/api/program/spreadsheet.ts +376 -35
  191. package/src/api/workspace/index.ts +516 -0
  192. package/src/handles.ts +77 -13
  193. package/tsconfig.json +7 -2
@@ -9,6 +9,12 @@ import {
9
9
  PluginSpaceUpdateResult,
10
10
  } from "../../entity/space"
11
11
  import { PluginDesignChangeResult } from "../lock"
12
+ import {
13
+ PluginBuildableEnvelopePolygonVertex,
14
+ PluginBuildableEnvelopeSetbackTier,
15
+ PluginBuildableEnvelopeVerticalCap,
16
+ PluginBuildableEnvelopeUpdateResult,
17
+ } from "../../entity/buildableEnvelope"
12
18
 
13
19
  /**
14
20
  * Sparse property updates for a space. Only provided fields change.
@@ -28,14 +34,18 @@ export const PluginSpacePropertyUpdates = z.object({
28
34
  areaClass: PluginAreaClass.optional(),
29
35
  departmentId: PluginDepartmentId.optional(),
30
36
  })
31
- export type PluginSpacePropertyUpdates = z.infer<typeof PluginSpacePropertyUpdates>
37
+ export type PluginSpacePropertyUpdates = z.infer<
38
+ typeof PluginSpacePropertyUpdates
39
+ >
32
40
 
33
41
  /** Geometry replacement for a space — re-extrude a profile. */
34
42
  export const PluginSpaceGeometryUpdate = z.object({
35
43
  profile: ProfileHandle,
36
44
  extrudeHeight: z.number(),
37
45
  })
38
- export type PluginSpaceGeometryUpdate = z.infer<typeof PluginSpaceGeometryUpdate>
46
+ export type PluginSpaceGeometryUpdate = z.infer<
47
+ typeof PluginSpaceGeometryUpdate
48
+ >
39
49
 
40
50
  /** One space to update via {@linkcode PluginDesignUpdateApi.spaces}. */
41
51
  export const PluginUpdateSpaceItem = z.object({
@@ -106,7 +116,9 @@ export const PluginStaircaseParamUpdates = z
106
116
  message:
107
117
  "PluginStaircaseParamUpdates requires at least one field to change",
108
118
  })
109
- export type PluginStaircaseParamUpdates = z.infer<typeof PluginStaircaseParamUpdates>
119
+ export type PluginStaircaseParamUpdates = z.infer<
120
+ typeof PluginStaircaseParamUpdates
121
+ >
110
122
 
111
123
  /**
112
124
  * Arguments for {@linkcode PluginDesignUpdateApi.staircase}.
@@ -120,7 +132,111 @@ export const PluginDesignUpdateStaircaseArgs = z.object({
120
132
  staircases: z.array(ComponentHandle),
121
133
  params: PluginStaircaseParamUpdates,
122
134
  })
123
- export type PluginDesignUpdateStaircaseArgs = z.infer<typeof PluginDesignUpdateStaircaseArgs>
135
+ export type PluginDesignUpdateStaircaseArgs = z.infer<
136
+ typeof PluginDesignUpdateStaircaseArgs
137
+ >
138
+
139
+ /**
140
+ * Sparse edits for a wall (all optional; at least one required). Only the
141
+ * fields you provide change. Dimensions are in **engine units** (the same
142
+ * convention as `design.doors.setWidth`). Consumed by
143
+ * {@linkcode PluginDesignUpdateApi.wall}.
144
+ *
145
+ * | Property | Type | Description |
146
+ * |---|---|---|
147
+ * | `thickness` | `number`? | Wall thickness, engine units (> 0) |
148
+ * | `height` | `number`? | Wall height, engine units (> 0) |
149
+ * | `type` | `string`? | Convert the wall to another wall type — a name (or `wall:`-prefixed id) from `design.types.list("wall")` |
150
+ */
151
+ export const PluginWallUpdates = z
152
+ .object({
153
+ thickness: z.number().positive().optional(),
154
+ height: z.number().positive().optional(),
155
+ type: z.string().trim().min(1).optional(),
156
+ })
157
+ .refine((p) => Object.keys(p).length > 0, {
158
+ message: "PluginWallUpdates requires at least one field to change",
159
+ })
160
+ export type PluginWallUpdates = z.infer<typeof PluginWallUpdates>
161
+
162
+ /**
163
+ * Sparse dimension edits for a slab-family element (slab / floor / roof /
164
+ * ceiling). All values are engine units, the same convention as
165
+ * `design.doors.setWidth`. Consumed by {@linkcode PluginDesignUpdateApi.slab},
166
+ * `floor`, `roof`, and `ceiling`.
167
+ *
168
+ * `overhang` is only available on **slabs and roofs** (the panel's Overhang
169
+ * slider) — floors and ceilings reject it with `PRECONDITION_FAILED`.
170
+ *
171
+ * | Property | Type | Description |
172
+ * |---|---|---|
173
+ * | `thickness` | `number`? | Element thickness, engine units (> 0) |
174
+ * | `overhang` | `number`? | Absolute overhang offset, engine units (slab / roof only) |
175
+ */
176
+ export const PluginSlabUpdates = z
177
+ .object({
178
+ thickness: z.number().positive().optional(),
179
+ overhang: z.number().optional(),
180
+ })
181
+ .refine((p) => Object.keys(p).length > 0, {
182
+ message: "PluginSlabUpdates requires at least one field to change",
183
+ })
184
+ export type PluginSlabUpdates = z.infer<typeof PluginSlabUpdates>
185
+
186
+ /** Arguments for {@linkcode PluginDesignUpdateApi.wall}. */
187
+ export const PluginDesignUpdateWallArgs = z.object({
188
+ component: ComponentHandle,
189
+ updates: PluginWallUpdates,
190
+ })
191
+ export type PluginDesignUpdateWallArgs = z.infer<
192
+ typeof PluginDesignUpdateWallArgs
193
+ >
194
+
195
+ /**
196
+ * Arguments for the slab-family updaters —
197
+ * {@linkcode PluginDesignUpdateApi.slab}, `floor`, `roof`, `ceiling`.
198
+ */
199
+ export const PluginDesignUpdateSlabArgs = z.object({
200
+ component: ComponentHandle,
201
+ updates: PluginSlabUpdates,
202
+ })
203
+ export type PluginDesignUpdateSlabArgs = z.infer<
204
+ typeof PluginDesignUpdateSlabArgs
205
+ >
206
+
207
+ /** Arguments for {@linkcode PluginDesignUpdateApi.setElevation}. */
208
+ export const PluginDesignSetElevationArgs = z.object({
209
+ component: ComponentHandle,
210
+ elevation: z.number(),
211
+ })
212
+ export type PluginDesignSetElevationArgs = z.infer<
213
+ typeof PluginDesignSetElevationArgs
214
+ >
215
+
216
+ /** Arguments for {@linkcode PluginDesignUpdateApi.setBaseOffset}. */
217
+ export const PluginDesignSetBaseOffsetArgs = z.object({
218
+ component: ComponentHandle,
219
+ offset: z.number(),
220
+ })
221
+ export type PluginDesignSetBaseOffsetArgs = z.infer<
222
+ typeof PluginDesignSetBaseOffsetArgs
223
+ >
224
+
225
+ /**
226
+ * Arguments for {@linkcode PluginDesignUpdateApi.setStorey}.
227
+ *
228
+ * | Property | Type | Description |
229
+ * |---|---|---|
230
+ * | `components` | {@linkcode ComponentHandle}`[]` | The components to reassign |
231
+ * | `storey` | `number` | Target integer storey number (`entity.story` convention; must exist) |
232
+ */
233
+ export const PluginDesignSetStoreyArgs = z.object({
234
+ components: z.array(ComponentHandle),
235
+ storey: z.number().int(),
236
+ })
237
+ export type PluginDesignSetStoreyArgs = z.infer<
238
+ typeof PluginDesignSetStoreyArgs
239
+ >
124
240
 
125
241
  /**
126
242
  * `snaptrude.design.update` — edit existing scene entities (properties + geometry).
@@ -169,7 +285,10 @@ export abstract class PluginDesignUpdateApi {
169
285
  * }
170
286
  * ```
171
287
  */
172
- public abstract setLabel(component: ComponentHandle, label: string): PluginApiReturn<boolean>
288
+ public abstract setLabel(
289
+ component: ComponentHandle,
290
+ label: string,
291
+ ): PluginApiReturn<boolean>
173
292
 
174
293
  /**
175
294
  * Update a single space (room) — change its properties (room label, space
@@ -187,6 +306,9 @@ export abstract class PluginDesignUpdateApi {
187
306
  * @examplePrompt Move this space into the Circulation department
188
307
  * @examplePrompt Exclude this room from the area calculations
189
308
  *
309
+ * @performance For MORE THAN ONE space, call `design.update.spaces(items[])` — the whole
310
+ * batch is one host round-trip. Looping this single-space updater is N round-trips.
311
+ *
190
312
  * # Example
191
313
  * ```ts
192
314
  * await snaptrude.design.update.space("space-id", { properties: { room_type: "Office" } })
@@ -217,6 +339,9 @@ export abstract class PluginDesignUpdateApi {
217
339
  * @examplePrompt Bulk-assign these spaces to the Service department
218
340
  * @examplePrompt Mark all of these rooms as excluded from area in one update
219
341
  *
342
+ * @performance Bulk update — the whole batch is ONE host round-trip. Prefer over looping
343
+ * `design.update.space`: build the `items[]` array first, then make one call.
344
+ *
220
345
  * # Example
221
346
  * ```ts
222
347
  * // Re-label every selected room and mark it NET area — one undoable bulk update
@@ -231,7 +356,9 @@ export abstract class PluginDesignUpdateApi {
231
356
  * console.log(results.map((r) => r.spaceId))
232
357
  * ```
233
358
  */
234
- public abstract spaces(items: PluginUpdateSpaceItem[]): PluginApiReturn<PluginSpaceUpdateResult[]>
359
+ public abstract spaces(
360
+ items: PluginUpdateSpaceItem[],
361
+ ): PluginApiReturn<PluginSpaceUpdateResult[]>
235
362
 
236
363
  /**
237
364
  * Update the parameters of one or more staircases — riser, tread, width,
@@ -281,4 +408,338 @@ export abstract class PluginDesignUpdateApi {
281
408
  staircases: ComponentHandle[],
282
409
  params: PluginStaircaseParamUpdates,
283
410
  ): PluginApiReturn<PluginDesignChangeResult>
411
+
412
+ /**
413
+ * Edit a **wall** — its thickness and/or height (the same command the
414
+ * properties panel's Thickness/Height fields drive) and/or its **wall type**
415
+ * (the panel's Wall Types dropdown: converts the wall to another type,
416
+ * rebuilding its layer stack and materials). Sparse: only the fields you
417
+ * provide change. Undoable; the geometry rebuilds and any dimension lines
418
+ * refresh. Stacked-wall companions and hosted fenestration are handled
419
+ * exactly as the panel does.
420
+ *
421
+ * Thickness/height are in **engine units** (the same convention as
422
+ * `design.doors.setWidth`) and must be `> 0`. Shrinking a wall past its
423
+ * openings is rejected by the engine (the wall is skipped with no change).
424
+ * `type` accepts a type name from `design.types.list("wall")` (or its
425
+ * `wall:`-prefixed id); when combined with dimensions, the type conversion
426
+ * is applied first so an explicit thickness/height wins over the type's
427
+ * defaults. Re-applying the wall's current type is a no-op.
428
+ *
429
+ * Throws when the handle is not a wall, when the wall is locked, when the
430
+ * handle is gone/forged, when `type` names an unknown wall type, when the
431
+ * engine rejects the conversion (e.g. a curved wall thinner than the new
432
+ * type's minimum thickness), or when no field is provided.
433
+ *
434
+ * A type conversion (and a thickness edit on a parametric wall) REBUILDS the
435
+ * wall, replacing it with a new component: the input handle is then dead
436
+ * (further calls throw HANDLE_INVALID) and `affected[0]` carries the
437
+ * replacement's handle — use it for any follow-up calls.
438
+ *
439
+ * @param component - The wall to edit
440
+ * @param updates - Sparse {@linkcode PluginWallUpdates} (at least one field)
441
+ * @returns the affected wall — after a rebuild, the REPLACEMENT wall's handle
442
+ *
443
+ * @examplePrompt Make this wall 230mm thick
444
+ * @examplePrompt Set the selected wall's height to 3 metres
445
+ * @examplePrompt Thicken every exterior wall to 300
446
+ * @examplePrompt Change this wall to a Glass Wall
447
+ * @examplePrompt Convert all the partitions on this floor to Brick Wall
448
+ *
449
+ * # Example
450
+ * ```ts
451
+ * // Convert every wall on storey 1 to the first listed wall type
452
+ * const [wallType] = await snaptrude.design.types.list("wall")
453
+ * const walls = await snaptrude.design.query.listWalls({ storeys: [1] })
454
+ * for (const wall of walls) {
455
+ * await snaptrude.design.update.wall(wall, { type: wallType.id })
456
+ * }
457
+ * ```
458
+ */
459
+ public abstract wall(
460
+ component: ComponentHandle,
461
+ updates: PluginWallUpdates,
462
+ ): PluginApiReturn<PluginDesignChangeResult>
463
+
464
+ /**
465
+ * Edit a **slab's** thickness and/or overhang — the same commands the
466
+ * properties panel's Thickness field and Overhang slider drive. Sparse: only
467
+ * the fields you provide change. Undoable; the slab rebuilds and dimension
468
+ * lines refresh. Both values are in **engine units** (the same convention as
469
+ * `design.doors.setWidth`); thickness must be `> 0`, overhang is an absolute
470
+ * offset (negative insets the slab) and re-applying the current overhang is
471
+ * a no-op.
472
+ *
473
+ * Throws when the handle is not a slab, when it is locked, when the handle is
474
+ * gone/forged, when `overhang` is set on a slab that has no overhang (plinth /
475
+ * basement slabs, or overhang disabled), or when no field is provided.
476
+ *
477
+ * @param component - The slab to edit
478
+ * @param updates - Sparse {@linkcode PluginSlabUpdates} (at least one field)
479
+ * @returns the affected slab
480
+ *
481
+ * @examplePrompt Set this slab's thickness to 250mm
482
+ * @examplePrompt Make the floor slab 300 thick
483
+ * @examplePrompt Give this slab a 200 overhang
484
+ * @examplePrompt Remove the overhang on every slab on level 2
485
+ *
486
+ * # Example
487
+ * ```ts
488
+ * const [slab] = await snaptrude.design.query.listSlabs()
489
+ * await snaptrude.design.update.slab(slab, { thickness: 250, overhang: 200 })
490
+ * ```
491
+ */
492
+ public abstract slab(
493
+ component: ComponentHandle,
494
+ updates: PluginSlabUpdates,
495
+ ): PluginApiReturn<PluginDesignChangeResult>
496
+
497
+ /**
498
+ * Edit a **floor's** thickness — the slab-family updater for floors (shares
499
+ * the slab thickness command). Undoable. Thickness is in **engine units**
500
+ * (the `design.doors.setWidth` convention) and must be `> 0`. Floors have no
501
+ * Overhang control, so `overhang` is rejected with `PRECONDITION_FAILED`.
502
+ *
503
+ * Throws when the handle is not a floor, when it is locked, when the handle
504
+ * is gone/forged, when `overhang` is provided, or when no field is provided.
505
+ *
506
+ * @param component - The floor to edit
507
+ * @param updates - {@linkcode PluginSlabUpdates} (a `thickness`)
508
+ * @returns the affected floor
509
+ *
510
+ * @examplePrompt Make this floor 200mm thick
511
+ * @examplePrompt Set every floor to a 250 thickness
512
+ * @examplePrompt Thicken the ground floor slab to 300
513
+ *
514
+ * # Example
515
+ * ```ts
516
+ * const [floor] = await snaptrude.design.query.listFloors()
517
+ * await snaptrude.design.update.floor(floor, { thickness: 200 })
518
+ * ```
519
+ */
520
+ public abstract floor(
521
+ component: ComponentHandle,
522
+ updates: PluginSlabUpdates,
523
+ ): PluginApiReturn<PluginDesignChangeResult>
524
+
525
+ /**
526
+ * Edit a **roof's** thickness and/or overhang — the same commands the roof
527
+ * panel's Thickness field and Overhang slider drive (shares the slab-family
528
+ * machinery). Sparse: only the fields you provide change. Undoable. Both
529
+ * values are in **engine units** (the `design.doors.setWidth` convention);
530
+ * thickness must be `> 0`, overhang is an absolute offset (negative insets
531
+ * the roof) and re-applying the current overhang is a no-op.
532
+ *
533
+ * Throws when the handle is not a roof, when it is locked, when the handle is
534
+ * gone/forged, when `overhang` is set on a roof whose overhang is disabled,
535
+ * or when no field is provided.
536
+ *
537
+ * @param component - The roof to edit
538
+ * @param updates - Sparse {@linkcode PluginSlabUpdates} (at least one field)
539
+ * @returns the affected roof
540
+ *
541
+ * @examplePrompt Make this roof 300mm thick
542
+ * @examplePrompt Set the roof slab thickness to 250
543
+ * @examplePrompt Give the roof a 600 overhang
544
+ * @examplePrompt Pull the roof overhang back to 0
545
+ *
546
+ * # Example
547
+ * ```ts
548
+ * const [roof] = await snaptrude.design.query.listRoofs()
549
+ * await snaptrude.design.update.roof(roof, { overhang: 600 })
550
+ * ```
551
+ */
552
+ public abstract roof(
553
+ component: ComponentHandle,
554
+ updates: PluginSlabUpdates,
555
+ ): PluginApiReturn<PluginDesignChangeResult>
556
+
557
+ /**
558
+ * Edit a **ceiling's** thickness — the slab-family updater for ceilings
559
+ * (shares the slab thickness command). Undoable. Thickness is in **engine
560
+ * units** (the `design.doors.setWidth` convention) and must be `> 0`.
561
+ * Ceilings have no Overhang control, so `overhang` is rejected with
562
+ * `PRECONDITION_FAILED`.
563
+ *
564
+ * Throws when the handle is not a ceiling, when it is locked, when the handle
565
+ * is gone/forged, when `overhang` is provided, or when no field is provided.
566
+ *
567
+ * @param component - The ceiling to edit
568
+ * @param updates - {@linkcode PluginSlabUpdates} (a `thickness`)
569
+ * @returns the affected ceiling
570
+ *
571
+ * @examplePrompt Make this ceiling 150mm thick
572
+ * @examplePrompt Set every ceiling to a 100 thickness
573
+ * @examplePrompt Thicken the ceiling to 200
574
+ *
575
+ * # Example
576
+ * ```ts
577
+ * const [ceiling] = await snaptrude.design.query.listCeilings()
578
+ * await snaptrude.design.update.ceiling(ceiling, { thickness: 150 })
579
+ * ```
580
+ */
581
+ public abstract ceiling(
582
+ component: ComponentHandle,
583
+ updates: PluginSlabUpdates,
584
+ ): PluginApiReturn<PluginDesignChangeResult>
585
+
586
+ /**
587
+ * Set a component's **absolute world elevation** — moves it vertically so its
588
+ * base (the bounding-box bottom, world Y) lands at `elevation`. Composed over
589
+ * the canonical command-backed move machinery, so it is undoable and persisted
590
+ * exactly like dragging the element up or down; per-type invariants (e.g. a
591
+ * staircase's base offset) stay in sync. `elevation` is in **engine units**
592
+ * (the `design.doors.setWidth` convention). Re-applying the current elevation
593
+ * is a no-op.
594
+ *
595
+ * Throws when the component is locked or the handle is gone/forged.
596
+ *
597
+ * @param component - The component to move vertically
598
+ * @param elevation - Target world elevation of the component's base (engine units)
599
+ * @returns the affected component
600
+ *
601
+ * @examplePrompt Set this element's elevation to 3000
602
+ * @examplePrompt Raise this mass so its base sits at 3 metres
603
+ * @examplePrompt Drop the selected slab to elevation 0
604
+ * @examplePrompt Put this staircase's base at 3200
605
+ *
606
+ * # Example
607
+ * ```ts
608
+ * // Sit the roof slab exactly at the top of a 3m storey
609
+ * const [roof] = await snaptrude.design.query.listRoofs()
610
+ * await snaptrude.design.update.setElevation(roof, 3000)
611
+ * ```
612
+ */
613
+ public abstract setElevation(
614
+ component: ComponentHandle,
615
+ elevation: number,
616
+ ): PluginApiReturn<PluginDesignChangeResult>
617
+
618
+ /**
619
+ * Set a component's **base offset** — its vertical distance above its own
620
+ * storey's base level. Moves the component so its base lands at
621
+ * `storeyBase + offset`, composed over the same command-backed move machinery
622
+ * as {@linkcode setElevation} (undoable, persisted, per-type invariants kept
623
+ * in sync). Use this instead of {@linkcode setElevation} when you want an
624
+ * offset relative to the storey rather than an absolute world height.
625
+ * `offset` is in **engine units** (the `design.doors.setWidth` convention);
626
+ * `0` sits the base flush with the storey base. Re-applying the current
627
+ * offset is a no-op.
628
+ *
629
+ * Throws when the component is locked, when it has no storey to offset from,
630
+ * or when the handle is gone/forged.
631
+ *
632
+ * @param component - The component to offset
633
+ * @param offset - Distance of the component's base above its storey base (engine units)
634
+ * @returns the affected component
635
+ *
636
+ * @examplePrompt Lift this element 300 above its floor
637
+ * @examplePrompt Set this staircase's base offset to 0
638
+ * @examplePrompt Raise the selected mass 500 off the storey base
639
+ * @examplePrompt Offset this slab 150 above the floor level
640
+ *
641
+ * # Example
642
+ * ```ts
643
+ * const [stair] = await snaptrude.design.query.listStaircases()
644
+ * await snaptrude.design.update.setBaseOffset(stair, 0)
645
+ * ```
646
+ */
647
+ public abstract setBaseOffset(
648
+ component: ComponentHandle,
649
+ offset: number,
650
+ ): PluginApiReturn<PluginDesignChangeResult>
651
+
652
+ /**
653
+ * Reassign one or more components to another **storey** — the same operation
654
+ * as the properties panel's Story dropdown, and it works across element kinds
655
+ * exactly like the panel (walls, slabs, masses, furniture, staircases, ...).
656
+ * Each component is moved vertically to the target storey's level (per-kind
657
+ * placement rules — e.g. a slab sits at the storey base, a wall on it) and
658
+ * its storey assignment, children, and dimension lines update together as
659
+ * **one undoable operation**.
660
+ *
661
+ * `storey` is an integer storey number in the `entity.story` convention
662
+ * (`1` is the ground storey, `-1` the first basement; `0` does not exist)
663
+ * and **must already exist** in each component's building — this call never
664
+ * creates storeys (use `core.storeys.create` first). Components already on
665
+ * the target storey are skipped (no-op) and are not echoed in `affected`.
666
+ *
667
+ * Throws when the target storey does not exist, when any component is
668
+ * locked, or when a handle is gone/forged — all before anything moves
669
+ * (all-or-nothing).
670
+ *
671
+ * @param components - The components to reassign
672
+ * @param storey - Target storey number (integer, `entity.story` convention)
673
+ * @returns the components actually reassigned
674
+ *
675
+ * @examplePrompt Move this sofa to storey 2
676
+ * @examplePrompt Put the selected walls on the first basement level
677
+ * @examplePrompt Send everything on this storey up one level
678
+ * @examplePrompt Reassign these slabs to storey 3
679
+ *
680
+ * # Example
681
+ * ```ts
682
+ * // Move the current selection up to storey 2
683
+ * const selection = await snaptrude.design.selection.get()
684
+ * const { affected } = await snaptrude.design.update.setStorey(selection, 2)
685
+ * console.log("moved", affected.length, "components")
686
+ * ```
687
+ */
688
+ public abstract setStorey(
689
+ components: ComponentHandle[],
690
+ storey: number,
691
+ ): PluginApiReturn<PluginDesignChangeResult>
692
+
693
+ /**
694
+ * Update an existing parametric buildable envelope — regenerate the zoning
695
+ * volume from a revised site polygon, setbacks, vertical cap, or FAR and
696
+ * lot-coverage limits, keeping the same envelope id. Canonical home of the
697
+ * update formerly at `entity.buildableEnvelope.update` (now deprecated).
698
+ *
699
+ * @param buildableEnvelopeId - Existing envelope ID to update; non-empty and
700
+ * must match an existing envelope on the canvas.
701
+ * @param sitePolygon - Site polygon vertices in `lengthUnit`; minimum 3 vertices.
702
+ * @param lengthUnit - Unit used by all length fields (`"ft" | "m"`).
703
+ * @param setbacks - Setback profile, ground tier first; minimum 1 tier.
704
+ * @param verticalCap - Maximum height or floor count.
705
+ * @param floorToFloor - Required floor-to-floor height in `lengthUnit`.
706
+ * @param farRatio - Optional FAR value, positive when provided.
707
+ * @param lotCoverageMaxPct - Optional lot coverage cap, `0..100`.
708
+ * @returns A {@linkcode PluginBuildableEnvelopeUpdateResult} with the
709
+ * `buildableEnvelopeId` of the updated envelope.
710
+ * @throws If validation fails, the envelope does not exist, or generation
711
+ * produces no renderable geometry.
712
+ *
713
+ * @examplePrompt Change the envelope's height limit to 175 feet
714
+ * @examplePrompt Update the setbacks on the buildable envelope
715
+ * @examplePrompt Regenerate the zoning envelope with a new site boundary
716
+ * @examplePrompt Increase the FAR on the buildable volume
717
+ *
718
+ * # Example
719
+ * ```ts
720
+ * const { buildableEnvelopeId } = await snaptrude.design.update.buildableEnvelope(
721
+ * existingId,
722
+ * [
723
+ * { x: 0, z: 0 },
724
+ * { x: 100, z: 0 },
725
+ * { x: 100, z: 80 },
726
+ * { x: 0, z: 80 },
727
+ * ],
728
+ * "ft",
729
+ * [{ aboveHeight: 0, front: 10, side: 5, rear: 10 }],
730
+ * { kind: "max_height", maxHeight: 175 },
731
+ * 12,
732
+ * )
733
+ * ```
734
+ */
735
+ public abstract buildableEnvelope(
736
+ buildableEnvelopeId: string,
737
+ sitePolygon: PluginBuildableEnvelopePolygonVertex[],
738
+ lengthUnit: "ft" | "m",
739
+ setbacks: PluginBuildableEnvelopeSetbackTier[],
740
+ verticalCap: PluginBuildableEnvelopeVerticalCap,
741
+ floorToFloor: number,
742
+ farRatio?: number,
743
+ lotCoverageMaxPct?: number,
744
+ ): PluginApiReturn<PluginBuildableEnvelopeUpdateResult>
284
745
  }
@@ -0,0 +1,109 @@
1
+ import * as z from "zod"
2
+ import { PluginApiReturn } from "../../types"
3
+ import { ComponentHandle } from "../../handles"
4
+ import { PluginDesignChangeResult } from "./lock"
5
+
6
+ /**
7
+ * `snaptrude.design.visibility.*` — hide, isolate, and reveal scene entities.
8
+ *
9
+ * Visibility is a per-component user flag (the same one the "Hide" / "Isolate" /
10
+ * "Show All" toolbar and right-click actions toggle). Every method here commits
11
+ * an undoable command and echoes the affected entities as
12
+ * {@linkcode PluginDesignChangeResult}.
13
+ *
14
+ * Accessed via `snaptrude.design.visibility`.
15
+ */
16
+ export abstract class PluginDesignVisibilityApi {
17
+ constructor() {}
18
+
19
+ /**
20
+ * Hide entities from the viewport — the same as the "Hide" action. Undoable.
21
+ * Hosted door/window/void children ride along with their wall. Already-hidden
22
+ * entities stay hidden.
23
+ *
24
+ * @param components Entities to hide
25
+ * @returns The affected entities (echoing the input handles)
26
+ *
27
+ * @examplePrompt Hide the selected walls
28
+ * @examplePrompt Conceal these masses so I can see behind them
29
+ * @examplePrompt Hide every column on this floor
30
+ * @examplePrompt Make this furniture disappear from view
31
+ *
32
+ * # Example
33
+ * ```ts
34
+ * const walls = await snaptrude.design.query.listWalls({ storeys: [1] })
35
+ * const { affected } = await snaptrude.design.visibility.hide(walls)
36
+ * ```
37
+ */
38
+ public abstract hide(
39
+ components: ComponentHandle[],
40
+ ): PluginApiReturn<PluginDesignChangeResult>
41
+
42
+ /**
43
+ * Isolate entities — hide everything else so only the given entities remain
44
+ * visible (the "Isolate" / solo action). Undoable. Reverse it with
45
+ * {@linkcode PluginDesignVisibilityApi.showAll}.
46
+ *
47
+ * @param components Entities to keep visible; everything else is hidden
48
+ * @returns The isolated entities (echoing the input handles)
49
+ *
50
+ * @examplePrompt Isolate the selected room so I can focus on it
51
+ * @examplePrompt Show only these walls and hide the rest
52
+ * @examplePrompt Solo this mass
53
+ * @examplePrompt Hide everything except the staircase
54
+ *
55
+ * # Example
56
+ * ```ts
57
+ * const [room] = await snaptrude.design.selection.get()
58
+ * await snaptrude.design.visibility.isolate([room])
59
+ * ```
60
+ */
61
+ public abstract isolate(
62
+ components: ComponentHandle[],
63
+ ): PluginApiReturn<PluginDesignChangeResult>
64
+
65
+ /**
66
+ * Reveal everything hidden on the active story — the "Show All" action, which
67
+ * also exits an isolate. Undoable.
68
+ *
69
+ * @returns The entities that were made visible
70
+ *
71
+ * @examplePrompt Show everything again
72
+ * @examplePrompt Unhide all the hidden objects
73
+ * @examplePrompt Exit isolate mode
74
+ * @examplePrompt Reveal everything I hid earlier
75
+ *
76
+ * # Example
77
+ * ```ts
78
+ * const { affected } = await snaptrude.design.visibility.showAll()
79
+ * console.log(`Revealed ${affected.length} entities`)
80
+ * ```
81
+ */
82
+ public abstract showAll(): PluginApiReturn<PluginDesignChangeResult>
83
+ }
84
+
85
+ /**
86
+ * Arguments for {@linkcode PluginDesignVisibilityApi.hide}.
87
+ *
88
+ * | Property | Type | Description |
89
+ * |---|---|---|
90
+ * | `components` | {@linkcode ComponentHandle}`[]` | Entities to hide |
91
+ */
92
+ export const PluginDesignVisibilityHideArgs = z.object({
93
+ components: z.array(ComponentHandle),
94
+ })
95
+ export type PluginDesignVisibilityHideArgs = z.infer<typeof PluginDesignVisibilityHideArgs>
96
+
97
+ /**
98
+ * Arguments for {@linkcode PluginDesignVisibilityApi.isolate}.
99
+ *
100
+ * | Property | Type | Description |
101
+ * |---|---|---|
102
+ * | `components` | {@linkcode ComponentHandle}`[]` | Entities to keep visible |
103
+ */
104
+ export const PluginDesignVisibilityIsolateArgs = z.object({
105
+ components: z.array(ComponentHandle),
106
+ })
107
+ export type PluginDesignVisibilityIsolateArgs = z.infer<
108
+ typeof PluginDesignVisibilityIsolateArgs
109
+ >
@@ -54,6 +54,8 @@ export abstract class PluginBuildableEnvelopeApi {
54
54
  * 12,
55
55
  * )
56
56
  * ```
57
+ *
58
+ * @deprecated Use `design.create.buildableEnvelope`
57
59
  */
58
60
  public abstract create(
59
61
  sitePolygon: PluginBuildableEnvelopePolygonVertex[],
@@ -106,6 +108,8 @@ export abstract class PluginBuildableEnvelopeApi {
106
108
  * 12,
107
109
  * )
108
110
  * ```
111
+ *
112
+ * @deprecated Use `design.update.buildableEnvelope`
109
113
  */
110
114
  public abstract update(
111
115
  buildableEnvelopeId: string,
@@ -49,6 +49,8 @@ export abstract class PluginReferenceLineApi {
49
49
  *
50
50
  * const { referenceLineIds } = await snaptrude.entity.referenceLine.createMulti(profile)
51
51
  * ```
52
+ *
53
+ * @deprecated Use `design.create.referenceLines`
52
54
  */
53
55
  public abstract createMulti(
54
56
  profile: ProfileHandle
@@ -78,6 +80,8 @@ export abstract class PluginReferenceLineApi {
78
80
  * // result.curve is an opaque CurveHandle; a dedicated curve read API for its
79
81
  * // coordinates is exposed separately via `snaptrude.core.geom.curve`.
80
82
  * ```
83
+ *
84
+ * @deprecated Use `design.query.referenceLines.get`
81
85
  */
82
86
  public abstract get(
83
87
  referenceLineId: string,
@@ -104,6 +108,8 @@ export abstract class PluginReferenceLineApi {
104
108
  * const { referenceLineIds } = await snaptrude.entity.referenceLine.getAll()
105
109
  * console.log(`Project has ${referenceLineIds.length} reference lines`)
106
110
  * ```
111
+ *
112
+ * @deprecated Use `design.query.listReferenceLines`
107
113
  */
108
114
  public abstract getAll(): PluginApiReturn<PluginReferenceLineGetAllResult>
109
115
 
@@ -125,6 +131,8 @@ export abstract class PluginReferenceLineApi {
125
131
  * ```ts
126
132
  * await snaptrude.entity.referenceLine.delete("some-ref-line-id")
127
133
  * ```
134
+ *
135
+ * @deprecated Use `design.delete.entities`
128
136
  */
129
137
  public abstract delete(
130
138
  referenceLineId: string