@snaptrude/plugin-core 0.9.16 → 0.9.18-edgesetbacks-20261021.1
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.
- package/AGENTS.md +231 -231
- package/CHANGELOG.md +408 -402
- package/CLAUDE.md +11 -11
- package/api-manifest.json +1510 -701
- package/dist/api/analysis/daylight.d.ts +5 -5
- package/dist/api/analysis/solar.d.ts +2 -2
- package/dist/api/core/camera/index.d.ts +29 -0
- package/dist/api/core/camera/index.d.ts.map +1 -1
- package/dist/api/core/geom/create/index.d.ts +7 -1
- package/dist/api/core/geom/create/index.d.ts.map +1 -1
- package/dist/api/core/geom/update/contour.d.ts +8 -2
- package/dist/api/core/geom/update/contour.d.ts.map +1 -1
- package/dist/api/core/storeys/index.d.ts +5 -2
- package/dist/api/core/storeys/index.d.ts.map +1 -1
- package/dist/api/core/zoom/index.d.ts +13 -0
- package/dist/api/core/zoom/index.d.ts.map +1 -1
- package/dist/api/design/bim.d.ts +299 -0
- package/dist/api/design/bim.d.ts.map +1 -0
- package/dist/api/design/boolean/index.d.ts +2 -0
- package/dist/api/design/boolean/index.d.ts.map +1 -1
- package/dist/api/design/catalog.d.ts +320 -0
- package/dist/api/design/catalog.d.ts.map +1 -0
- package/dist/api/design/create/bulk-items.d.ts +65 -25
- package/dist/api/design/create/bulk-items.d.ts.map +1 -1
- package/dist/api/design/create/index.d.ts +299 -100
- package/dist/api/design/create/index.d.ts.map +1 -1
- package/dist/api/design/create/opening-fields.d.ts +13 -12
- package/dist/api/design/create/opening-fields.d.ts.map +1 -1
- package/dist/api/design/delete/index.d.ts +1 -0
- package/dist/api/design/delete/index.d.ts.map +1 -1
- package/dist/api/design/doors/index.d.ts +18 -24
- package/dist/api/design/doors/index.d.ts.map +1 -1
- package/dist/api/design/family.d.ts +813 -35
- package/dist/api/design/family.d.ts.map +1 -1
- package/dist/api/design/index.d.ts +16 -0
- package/dist/api/design/index.d.ts.map +1 -1
- package/dist/api/design/networks.d.ts +1703 -0
- package/dist/api/design/networks.d.ts.map +1 -0
- package/dist/api/design/query/grids.d.ts +2 -2
- package/dist/api/design/query/index.d.ts +42 -32
- package/dist/api/design/query/index.d.ts.map +1 -1
- package/dist/api/design/selection/index.d.ts +10 -10
- package/dist/api/design/types/index.d.ts +40 -24
- package/dist/api/design/types/index.d.ts.map +1 -1
- package/dist/api/design/update/index.d.ts +111 -6
- package/dist/api/design/update/index.d.ts.map +1 -1
- package/dist/api/design/windows/index.d.ts +8 -8
- package/dist/api/design/windows/index.d.ts.map +1 -1
- package/dist/api/entity/buildableEnvelope.d.ts +84 -2
- package/dist/api/entity/buildableEnvelope.d.ts.map +1 -1
- package/dist/api/presentation/aiInspiration.d.ts +10 -10
- package/dist/api/presentation/annotate.d.ts +38 -22
- package/dist/api/presentation/annotate.d.ts.map +1 -1
- package/dist/api/presentation/drawingContract.d.ts +32 -0
- package/dist/api/presentation/drawingContract.d.ts.map +1 -0
- package/dist/api/presentation/drawings.d.ts +3523 -0
- package/dist/api/presentation/drawings.d.ts.map +1 -0
- package/dist/api/presentation/export.d.ts +23 -5
- package/dist/api/presentation/export.d.ts.map +1 -1
- package/dist/api/presentation/index.d.ts +41 -12
- package/dist/api/presentation/index.d.ts.map +1 -1
- package/dist/api/presentation/placedViews.d.ts +106 -6
- package/dist/api/presentation/placedViews.d.ts.map +1 -1
- package/dist/api/presentation/sections.d.ts +461 -0
- package/dist/api/presentation/sections.d.ts.map +1 -0
- package/dist/api/presentation/shapes.d.ts +2 -2
- package/dist/api/presentation/sheets.d.ts +175 -19
- package/dist/api/presentation/sheets.d.ts.map +1 -1
- package/dist/api/presentation/viewPresets.d.ts +222 -0
- package/dist/api/presentation/viewPresets.d.ts.map +1 -0
- package/dist/api/presentation/views.d.ts +141 -8
- package/dist/api/presentation/views.d.ts.map +1 -1
- package/dist/api/presentation/walkthroughs.d.ts +6 -6
- package/dist/errors/codes.d.ts +3 -1
- package/dist/errors/codes.d.ts.map +1 -1
- package/dist/index.cjs +3883 -2385
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +3744 -2385
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/scripts/check-dist-fresh.mjs +22 -22
- package/scripts/generate-manifest.mjs +243 -238
- package/scripts/generate-manifest.test.mjs +303 -303
- package/src/api/analysis/daylight.ts +470 -470
- package/src/api/analysis/heatmaps.ts +683 -683
- package/src/api/analysis/illuminance.ts +155 -155
- package/src/api/analysis/index.ts +61 -61
- package/src/api/analysis/shadows.ts +183 -183
- package/src/api/analysis/solar.ts +237 -237
- package/src/api/analysis/sunlightHours.ts +211 -211
- package/src/api/analysis/sunpath.ts +83 -83
- package/src/api/analysis/weather.ts +179 -179
- package/src/api/core/buildings.ts +485 -485
- package/src/api/core/camera/index.ts +696 -667
- package/src/api/core/comment/index.ts +376 -376
- package/src/api/core/geom/create/index.ts +2139 -2133
- package/src/api/core/geom/delete/index.ts +84 -84
- package/src/api/core/geom/index.ts +35 -35
- package/src/api/core/geom/query/arc.ts +169 -169
- package/src/api/core/geom/query/brep.ts +621 -621
- package/src/api/core/geom/query/circle.ts +404 -404
- package/src/api/core/geom/query/contour.ts +540 -540
- package/src/api/core/geom/query/curve.ts +1102 -1102
- package/src/api/core/geom/query/edge.ts +130 -130
- package/src/api/core/geom/query/face.ts +508 -508
- package/src/api/core/geom/query/halfedge.ts +210 -210
- package/src/api/core/geom/query/index.ts +63 -63
- package/src/api/core/geom/query/profile.ts +473 -473
- package/src/api/core/geom/query/vertex.ts +205 -205
- package/src/api/core/geom/update/contour.ts +323 -317
- package/src/api/core/geom/update/curve.ts +209 -209
- package/src/api/core/geom/update/index.ts +29 -29
- package/src/api/core/geom/update/profile.ts +379 -379
- package/src/api/core/groups.ts +521 -521
- package/src/api/core/handles/index.ts +234 -234
- package/src/api/core/history/index.ts +84 -84
- package/src/api/core/index.ts +99 -99
- package/src/api/core/io/export/index.ts +126 -126
- package/src/api/core/io/import/index.ts +504 -504
- package/src/api/core/io/index.ts +42 -42
- package/src/api/core/io/job/index.ts +140 -140
- package/src/api/core/io/query/index.ts +71 -71
- package/src/api/core/io/terrain/index.ts +360 -360
- package/src/api/core/io/underlay/index.ts +705 -705
- package/src/api/core/layers.ts +540 -540
- package/src/api/core/math/index.ts +20 -20
- package/src/api/core/math/quat.ts +172 -172
- package/src/api/core/math/vec3.ts +179 -179
- package/src/api/core/mode/index.ts +108 -108
- package/src/api/core/project/index.ts +479 -479
- package/src/api/core/proposals/index.ts +570 -570
- package/src/api/core/storeys/index.ts +311 -308
- package/src/api/core/storeys/layers.ts +339 -339
- package/src/api/core/tags.ts +911 -911
- package/src/api/core/units/index.ts +164 -164
- package/src/api/core/user.ts +46 -46
- package/src/api/core/zoom/index.ts +64 -51
- package/src/api/design/bim.ts +210 -0
- package/src/api/design/boolean/index.ts +181 -179
- package/src/api/design/catalog.ts +203 -0
- package/src/api/design/create/bulk-items.ts +294 -254
- package/src/api/design/create/grids.ts +137 -137
- package/src/api/design/create/index.ts +2178 -1980
- package/src/api/design/create/opening-fields.ts +40 -37
- package/src/api/design/delete/index.ts +75 -74
- package/src/api/design/dimensions.ts +453 -453
- package/src/api/design/doors/index.ts +516 -500
- package/src/api/design/edit/index.ts +54 -54
- package/src/api/design/erase/index.ts +151 -151
- package/src/api/design/family.ts +1342 -704
- package/src/api/design/furniture/index.ts +319 -319
- package/src/api/design/grids.ts +237 -237
- package/src/api/design/index.ts +304 -274
- package/src/api/design/lock.ts +69 -69
- package/src/api/design/materials/index.ts +608 -608
- package/src/api/design/networks.ts +607 -0
- package/src/api/design/query/geometry/index.ts +319 -319
- package/src/api/design/query/grids.ts +197 -197
- package/src/api/design/query/index.ts +1236 -1226
- package/src/api/design/query/referenceLines.ts +52 -52
- package/src/api/design/query/spaces.ts +275 -275
- package/src/api/design/selection/index.ts +273 -273
- package/src/api/design/shared.ts +40 -40
- package/src/api/design/transform/index.ts +254 -254
- package/src/api/design/types/index.ts +163 -156
- package/src/api/design/update/index.ts +1096 -983
- package/src/api/design/visibility.ts +143 -143
- package/src/api/design/windows/index.ts +351 -333
- package/src/api/entity/buildableEnvelope.ts +397 -322
- package/src/api/entity/index.ts +30 -30
- package/src/api/entity/referenceLine.ts +235 -235
- package/src/api/entity/space.ts +612 -612
- package/src/api/entity/story.ts +517 -517
- package/src/api/index.ts +47 -47
- package/src/api/presentation/aiInspiration.ts +1116 -1116
- package/src/api/presentation/annotate.ts +417 -385
- package/src/api/presentation/camera.ts +289 -289
- package/src/api/presentation/diagrams.ts +194 -194
- package/src/api/presentation/drawingContract.ts +70 -0
- package/src/api/presentation/drawings.ts +1179 -0
- package/src/api/presentation/export.ts +134 -108
- package/src/api/presentation/import.ts +159 -159
- package/src/api/presentation/index.ts +160 -126
- package/src/api/presentation/placedViews.ts +1211 -1120
- package/src/api/presentation/sections.ts +420 -0
- package/src/api/presentation/shapes.ts +274 -274
- package/src/api/presentation/sheets.ts +746 -585
- package/src/api/presentation/slideshow.ts +134 -134
- package/src/api/presentation/tables.ts +84 -84
- package/src/api/presentation/viewPresets.ts +241 -0
- package/src/api/presentation/views.ts +742 -673
- package/src/api/presentation/walkthroughs.ts +1201 -1201
- package/src/api/program/adjacency.ts +164 -164
- package/src/api/program/areas.ts +408 -408
- package/src/api/program/classification.ts +138 -138
- package/src/api/program/cores.ts +83 -83
- package/src/api/program/departments.ts +517 -517
- package/src/api/program/index.ts +73 -73
- package/src/api/program/labels.ts +332 -332
- package/src/api/program/layout.ts +422 -422
- package/src/api/program/metadata.ts +364 -364
- package/src/api/program/metrics.ts +120 -120
- package/src/api/program/site.ts +748 -748
- package/src/api/program/spreadsheet.ts +2698 -2698
- package/src/api/workspace/index.ts +612 -612
- package/src/errors/codes.ts +143 -136
- package/src/errors/envelope.ts +75 -75
- package/src/errors/index.ts +21 -21
- package/src/errors/plugin-error.ts +134 -134
- package/src/handles.ts +297 -297
- package/src/host-utils.ts +67 -67
- package/src/index.ts +7 -7
- package/src/massParameters.ops.ts +246 -246
- package/src/massParameters.ts +427 -427
- package/src/types.ts +16 -16
- package/test/drawingContract.test.mjs +288 -0
- package/test/errors.test.mjs +185 -184
- package/test/massParameters.test.mjs +952 -952
- package/test/presentationViewSettings.test.mjs +85 -0
- package/tsconfig.json +22 -22
- package/tsup.config.ts +12 -12
|
@@ -1,983 +1,1096 @@
|
|
|
1
|
-
import * as z from "zod"
|
|
2
|
-
import { PluginApiReturn } from "../../../types"
|
|
3
|
-
import { ComponentHandle, ProfileHandle } from "../../../handles"
|
|
4
|
-
import {
|
|
5
|
-
PluginSpaceType,
|
|
6
|
-
PluginMassType,
|
|
7
|
-
PluginDepartmentId,
|
|
8
|
-
PluginAreaClass,
|
|
9
|
-
PluginSpaceUpdateResult,
|
|
10
|
-
} from "../../entity/space"
|
|
11
|
-
import { PluginDesignChangeResult } from "../lock"
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
* |
|
|
98
|
-
*
|
|
99
|
-
* | `
|
|
100
|
-
* | `
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
*
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
*
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
export
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
*
|
|
262
|
-
*
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
export type
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
*
|
|
276
|
-
*
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
export type
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
*
|
|
290
|
-
*
|
|
291
|
-
*
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
/**
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
export
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
*/
|
|
317
|
-
export
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
*
|
|
341
|
-
*
|
|
342
|
-
*
|
|
343
|
-
*
|
|
344
|
-
*
|
|
345
|
-
*
|
|
346
|
-
*
|
|
347
|
-
*
|
|
348
|
-
*
|
|
349
|
-
*
|
|
350
|
-
*
|
|
351
|
-
*
|
|
352
|
-
*
|
|
353
|
-
*
|
|
354
|
-
*
|
|
355
|
-
*
|
|
356
|
-
*
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
*
|
|
365
|
-
*
|
|
366
|
-
*
|
|
367
|
-
*
|
|
368
|
-
*
|
|
369
|
-
*
|
|
370
|
-
*
|
|
371
|
-
*
|
|
372
|
-
*
|
|
373
|
-
*
|
|
374
|
-
*
|
|
375
|
-
*
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
*
|
|
384
|
-
*
|
|
385
|
-
*
|
|
386
|
-
*
|
|
387
|
-
*
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
*
|
|
396
|
-
*
|
|
397
|
-
*
|
|
398
|
-
*
|
|
399
|
-
*
|
|
400
|
-
* @
|
|
401
|
-
*
|
|
402
|
-
*
|
|
403
|
-
*
|
|
404
|
-
*
|
|
405
|
-
*
|
|
406
|
-
*
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
*
|
|
415
|
-
*
|
|
416
|
-
*
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
*
|
|
428
|
-
*
|
|
429
|
-
*
|
|
430
|
-
*
|
|
431
|
-
*
|
|
432
|
-
*
|
|
433
|
-
*
|
|
434
|
-
*
|
|
435
|
-
*
|
|
436
|
-
*
|
|
437
|
-
*
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
*
|
|
449
|
-
*
|
|
450
|
-
*
|
|
451
|
-
*
|
|
452
|
-
*
|
|
453
|
-
*
|
|
454
|
-
*
|
|
455
|
-
*
|
|
456
|
-
*
|
|
457
|
-
*
|
|
458
|
-
*
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
*
|
|
466
|
-
*
|
|
467
|
-
*
|
|
468
|
-
*
|
|
469
|
-
*
|
|
470
|
-
*
|
|
471
|
-
*
|
|
472
|
-
*
|
|
473
|
-
*
|
|
474
|
-
*
|
|
475
|
-
*
|
|
476
|
-
*
|
|
477
|
-
*
|
|
478
|
-
*
|
|
479
|
-
*
|
|
480
|
-
*
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
*
|
|
488
|
-
*
|
|
489
|
-
*
|
|
490
|
-
*
|
|
491
|
-
*
|
|
492
|
-
*
|
|
493
|
-
*
|
|
494
|
-
*
|
|
495
|
-
*
|
|
496
|
-
*
|
|
497
|
-
*
|
|
498
|
-
*
|
|
499
|
-
*
|
|
500
|
-
*
|
|
501
|
-
*
|
|
502
|
-
*
|
|
503
|
-
*
|
|
504
|
-
*
|
|
505
|
-
*
|
|
506
|
-
*
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
*
|
|
515
|
-
*
|
|
516
|
-
*
|
|
517
|
-
*
|
|
518
|
-
*
|
|
519
|
-
*
|
|
520
|
-
*
|
|
521
|
-
*
|
|
522
|
-
*
|
|
523
|
-
*
|
|
524
|
-
*
|
|
525
|
-
*
|
|
526
|
-
*
|
|
527
|
-
*
|
|
528
|
-
*
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
*
|
|
537
|
-
*
|
|
538
|
-
*
|
|
539
|
-
*
|
|
540
|
-
*
|
|
541
|
-
*
|
|
542
|
-
*
|
|
543
|
-
*
|
|
544
|
-
*
|
|
545
|
-
*
|
|
546
|
-
*
|
|
547
|
-
*
|
|
548
|
-
*
|
|
549
|
-
*
|
|
550
|
-
*
|
|
551
|
-
*
|
|
552
|
-
*
|
|
553
|
-
*
|
|
554
|
-
*
|
|
555
|
-
*
|
|
556
|
-
*
|
|
557
|
-
*
|
|
558
|
-
*
|
|
559
|
-
*
|
|
560
|
-
*
|
|
561
|
-
*
|
|
562
|
-
*
|
|
563
|
-
*
|
|
564
|
-
*
|
|
565
|
-
*
|
|
566
|
-
*
|
|
567
|
-
*
|
|
568
|
-
*
|
|
569
|
-
*
|
|
570
|
-
*
|
|
571
|
-
*
|
|
572
|
-
*
|
|
573
|
-
*
|
|
574
|
-
*
|
|
575
|
-
*
|
|
576
|
-
*
|
|
577
|
-
*
|
|
578
|
-
*
|
|
579
|
-
*
|
|
580
|
-
*
|
|
581
|
-
*
|
|
582
|
-
*
|
|
583
|
-
*
|
|
584
|
-
*
|
|
585
|
-
*
|
|
586
|
-
*
|
|
587
|
-
*
|
|
588
|
-
*
|
|
589
|
-
*
|
|
590
|
-
*
|
|
591
|
-
*
|
|
592
|
-
*
|
|
593
|
-
*
|
|
594
|
-
*
|
|
595
|
-
*
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
*
|
|
604
|
-
*
|
|
605
|
-
*
|
|
606
|
-
*
|
|
607
|
-
*
|
|
608
|
-
*
|
|
609
|
-
*
|
|
610
|
-
*
|
|
611
|
-
*
|
|
612
|
-
*
|
|
613
|
-
*
|
|
614
|
-
*
|
|
615
|
-
*
|
|
616
|
-
*
|
|
617
|
-
*
|
|
618
|
-
*
|
|
619
|
-
*
|
|
620
|
-
*
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
*
|
|
629
|
-
*
|
|
630
|
-
*
|
|
631
|
-
*
|
|
632
|
-
*
|
|
633
|
-
*
|
|
634
|
-
*
|
|
635
|
-
*
|
|
636
|
-
*
|
|
637
|
-
*
|
|
638
|
-
*
|
|
639
|
-
*
|
|
640
|
-
*
|
|
641
|
-
*
|
|
642
|
-
*
|
|
643
|
-
*
|
|
644
|
-
*
|
|
645
|
-
*
|
|
646
|
-
*
|
|
647
|
-
*
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
*
|
|
656
|
-
*
|
|
657
|
-
*
|
|
658
|
-
*
|
|
659
|
-
*
|
|
660
|
-
*
|
|
661
|
-
* a
|
|
662
|
-
*
|
|
663
|
-
*
|
|
664
|
-
*
|
|
665
|
-
*
|
|
666
|
-
*
|
|
667
|
-
*
|
|
668
|
-
*
|
|
669
|
-
*
|
|
670
|
-
*
|
|
671
|
-
*
|
|
672
|
-
*
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
*
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
*
|
|
689
|
-
*
|
|
690
|
-
*
|
|
691
|
-
*
|
|
692
|
-
*
|
|
693
|
-
*
|
|
694
|
-
*
|
|
695
|
-
*
|
|
696
|
-
* @
|
|
697
|
-
* @
|
|
698
|
-
* @
|
|
699
|
-
*
|
|
700
|
-
*
|
|
701
|
-
*
|
|
702
|
-
*
|
|
703
|
-
*
|
|
704
|
-
*
|
|
705
|
-
* ```
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
*
|
|
717
|
-
*
|
|
718
|
-
*
|
|
719
|
-
*
|
|
720
|
-
*
|
|
721
|
-
*
|
|
722
|
-
*
|
|
723
|
-
*
|
|
724
|
-
*
|
|
725
|
-
*
|
|
726
|
-
*
|
|
727
|
-
* @
|
|
728
|
-
*
|
|
729
|
-
*
|
|
730
|
-
*
|
|
731
|
-
*
|
|
732
|
-
*
|
|
733
|
-
*
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
*
|
|
749
|
-
*
|
|
750
|
-
*
|
|
751
|
-
*
|
|
752
|
-
*
|
|
753
|
-
*
|
|
754
|
-
*
|
|
755
|
-
*
|
|
756
|
-
*
|
|
757
|
-
* @
|
|
758
|
-
* @
|
|
759
|
-
* @
|
|
760
|
-
*
|
|
761
|
-
*
|
|
762
|
-
*
|
|
763
|
-
*
|
|
764
|
-
*
|
|
765
|
-
*
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
*
|
|
778
|
-
*
|
|
779
|
-
* the
|
|
780
|
-
*
|
|
781
|
-
*
|
|
782
|
-
*
|
|
783
|
-
*
|
|
784
|
-
*
|
|
785
|
-
*
|
|
786
|
-
*
|
|
787
|
-
* @
|
|
788
|
-
* @
|
|
789
|
-
*
|
|
790
|
-
*
|
|
791
|
-
*
|
|
792
|
-
*
|
|
793
|
-
*
|
|
794
|
-
*
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
*
|
|
812
|
-
*
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
*
|
|
821
|
-
*
|
|
822
|
-
*
|
|
823
|
-
*
|
|
824
|
-
*
|
|
825
|
-
*
|
|
826
|
-
*
|
|
827
|
-
*
|
|
828
|
-
*
|
|
829
|
-
*
|
|
830
|
-
*
|
|
831
|
-
*
|
|
832
|
-
*
|
|
833
|
-
*
|
|
834
|
-
*
|
|
835
|
-
*
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
*
|
|
844
|
-
*
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
*
|
|
853
|
-
*
|
|
854
|
-
*
|
|
855
|
-
*
|
|
856
|
-
*
|
|
857
|
-
*
|
|
858
|
-
*
|
|
859
|
-
*
|
|
860
|
-
*
|
|
861
|
-
*
|
|
862
|
-
*
|
|
863
|
-
*
|
|
864
|
-
*
|
|
865
|
-
* @
|
|
866
|
-
* @
|
|
867
|
-
* @
|
|
868
|
-
*
|
|
869
|
-
*
|
|
870
|
-
*
|
|
871
|
-
*
|
|
872
|
-
*
|
|
873
|
-
*
|
|
874
|
-
*
|
|
875
|
-
*
|
|
876
|
-
*
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
*
|
|
887
|
-
*
|
|
888
|
-
*
|
|
889
|
-
* component
|
|
890
|
-
*
|
|
891
|
-
*
|
|
892
|
-
*
|
|
893
|
-
*
|
|
894
|
-
*
|
|
895
|
-
*
|
|
896
|
-
*
|
|
897
|
-
*
|
|
898
|
-
*
|
|
899
|
-
*
|
|
900
|
-
*
|
|
901
|
-
*
|
|
902
|
-
*
|
|
903
|
-
*
|
|
904
|
-
*
|
|
905
|
-
* @param
|
|
906
|
-
* @
|
|
907
|
-
*
|
|
908
|
-
* @
|
|
909
|
-
*
|
|
910
|
-
*
|
|
911
|
-
* @examplePrompt
|
|
912
|
-
*
|
|
913
|
-
*
|
|
914
|
-
*
|
|
915
|
-
*
|
|
916
|
-
*
|
|
917
|
-
*
|
|
918
|
-
*
|
|
919
|
-
* ```
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
*
|
|
933
|
-
*
|
|
934
|
-
*
|
|
935
|
-
*
|
|
936
|
-
*
|
|
937
|
-
*
|
|
938
|
-
*
|
|
939
|
-
*
|
|
940
|
-
*
|
|
941
|
-
*
|
|
942
|
-
*
|
|
943
|
-
*
|
|
944
|
-
*
|
|
945
|
-
*
|
|
946
|
-
*
|
|
947
|
-
*
|
|
948
|
-
* @
|
|
949
|
-
*
|
|
950
|
-
*
|
|
951
|
-
* @
|
|
952
|
-
*
|
|
953
|
-
*
|
|
954
|
-
* @examplePrompt
|
|
955
|
-
*
|
|
956
|
-
*
|
|
957
|
-
*
|
|
958
|
-
*
|
|
959
|
-
*
|
|
960
|
-
*
|
|
961
|
-
*
|
|
962
|
-
*
|
|
963
|
-
*
|
|
964
|
-
*
|
|
965
|
-
*
|
|
966
|
-
*
|
|
967
|
-
*
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
1
|
+
import * as z from "zod"
|
|
2
|
+
import { PluginApiReturn } from "../../../types"
|
|
3
|
+
import { ComponentHandle, ProfileHandle } from "../../../handles"
|
|
4
|
+
import {
|
|
5
|
+
PluginSpaceType,
|
|
6
|
+
PluginMassType,
|
|
7
|
+
PluginDepartmentId,
|
|
8
|
+
PluginAreaClass,
|
|
9
|
+
PluginSpaceUpdateResult,
|
|
10
|
+
} from "../../entity/space"
|
|
11
|
+
import { PluginDesignChangeResult } from "../lock"
|
|
12
|
+
import {
|
|
13
|
+
MassParametersPatch,
|
|
14
|
+
type MassParametersRecord,
|
|
15
|
+
} from "../../../massParameters"
|
|
16
|
+
import {
|
|
17
|
+
PluginBuildableEnvelopePolygonVertex,
|
|
18
|
+
PluginBuildableEnvelopeSetbackTier,
|
|
19
|
+
PluginBuildableEnvelopeVerticalCap,
|
|
20
|
+
PluginBuildableEnvelopeUpdateResult,
|
|
21
|
+
PluginSiteEdgePatch,
|
|
22
|
+
PluginDesignUpdateSiteEdgeResult,
|
|
23
|
+
} from "../../entity/buildableEnvelope"
|
|
24
|
+
import { PluginGridStyleOptions } from "../create/grids"
|
|
25
|
+
import { PluginEntityType } from "../query"
|
|
26
|
+
import { PluginWallType } from "../types"
|
|
27
|
+
import {
|
|
28
|
+
PluginConstructionType,
|
|
29
|
+
PluginFamilyValues,
|
|
30
|
+
type PluginFamilyUpdates,
|
|
31
|
+
} from "../catalog"
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Sparse property updates for a space. Only provided fields change.
|
|
35
|
+
*
|
|
36
|
+
* | Property | Type | Description |
|
|
37
|
+
* |---|---|---|
|
|
38
|
+
* | `room_type` | `string`? | Room label |
|
|
39
|
+
* | `massType` | `PluginMassType`? | Mass type |
|
|
40
|
+
* | `spaceType` | `PluginSpaceType`? | Space type |
|
|
41
|
+
* | `areaClass` | `PluginAreaClass`? | Area class (NET/GROSS/EXCLUDED) |
|
|
42
|
+
* | `departmentId` | `PluginDepartmentId`? | Department |
|
|
43
|
+
*/
|
|
44
|
+
export const PluginSpacePropertyUpdates = z.object({
|
|
45
|
+
room_type: z.string().optional(),
|
|
46
|
+
massType: PluginMassType.optional(),
|
|
47
|
+
spaceType: PluginSpaceType.optional(),
|
|
48
|
+
areaClass: PluginAreaClass.optional(),
|
|
49
|
+
departmentId: PluginDepartmentId.optional(),
|
|
50
|
+
})
|
|
51
|
+
export type PluginSpacePropertyUpdates = z.infer<
|
|
52
|
+
typeof PluginSpacePropertyUpdates
|
|
53
|
+
>
|
|
54
|
+
|
|
55
|
+
/** Geometry replacement for a space — re-extrude a profile. */
|
|
56
|
+
export const PluginSpaceGeometryUpdate = z.object({
|
|
57
|
+
profile: ProfileHandle,
|
|
58
|
+
extrudeHeight: z.number(),
|
|
59
|
+
})
|
|
60
|
+
export type PluginSpaceGeometryUpdate = z.infer<
|
|
61
|
+
typeof PluginSpaceGeometryUpdate
|
|
62
|
+
>
|
|
63
|
+
|
|
64
|
+
/** One space to update via {@linkcode PluginDesignUpdateApi.spaces}. */
|
|
65
|
+
export const PluginUpdateSpaceItem = z.object({
|
|
66
|
+
space: ComponentHandle,
|
|
67
|
+
properties: PluginSpacePropertyUpdates.optional(),
|
|
68
|
+
geometry: PluginSpaceGeometryUpdate.optional(),
|
|
69
|
+
})
|
|
70
|
+
export type PluginUpdateSpaceItem = z.infer<typeof PluginUpdateSpaceItem>
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Wire schema for {@linkcode PluginDesignUpdateApi.setLabel}.
|
|
74
|
+
*
|
|
75
|
+
* | Property | Type | Description |
|
|
76
|
+
* |---|---|---|
|
|
77
|
+
* | `component` | `ComponentHandle` | The component to relabel |
|
|
78
|
+
* | `label` | `string` | New label (non-empty after trimming) |
|
|
79
|
+
*/
|
|
80
|
+
export const PluginDesignSetLabelArgs = z.object({
|
|
81
|
+
component: ComponentHandle,
|
|
82
|
+
label: z.string().trim().min(1),
|
|
83
|
+
})
|
|
84
|
+
export type PluginDesignSetLabelArgs = z.infer<typeof PluginDesignSetLabelArgs>
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Sparse parametric updates for a staircase (all fields optional; at least one
|
|
88
|
+
* required). Only the fields you provide change. Consumed by
|
|
89
|
+
* {@linkcode PluginDesignUpdateApi.staircase}; the paired read is
|
|
90
|
+
* `design.query.getStaircaseParams`.
|
|
91
|
+
*
|
|
92
|
+
* All dimensions are in **engine units** (the same convention as
|
|
93
|
+
* `design.doors.setWidth`); `steps` is a unitless integer count. Height, riser,
|
|
94
|
+
* and step count are **coupled** (`staircaseHeight = steps × riser`); the two
|
|
95
|
+
* lock booleans govern which value recomputes — see the method JSDoc.
|
|
96
|
+
*
|
|
97
|
+
* | Property | Type | Description |
|
|
98
|
+
* |---|---|---|
|
|
99
|
+
* | `isStoreyHeightUnlocked` | `boolean`? | Unlock the staircase height from the storey height |
|
|
100
|
+
* | `isStaircaseHeightUnlocked` | `boolean`? | Unlock the height from `steps × riser` |
|
|
101
|
+
* | `storeyHeight` | `number`? | Storey height the stair sits within (engine units) |
|
|
102
|
+
* | `staircaseHeight` | `number`? | Total rise (engine units) |
|
|
103
|
+
* | `steps` | `number`? | Step count (unitless integer) |
|
|
104
|
+
* | `riser` | `number`? | Riser height (engine units) |
|
|
105
|
+
* | `tread` | `number`? | Tread depth (engine units) |
|
|
106
|
+
* | `width` | `number`? | Flight width (engine units) |
|
|
107
|
+
* | `depth` | `number`? | Slab/waist thickness (engine units) |
|
|
108
|
+
* | `wellSize` | `number`? | Stairwell gap (dogLegged / openWell / square) |
|
|
109
|
+
* | `flightStartDistAfterTurn` | `number`? | Flight offset after a turn (dogLegged / lShaped / square) |
|
|
110
|
+
* | `landingWidth` | `number`? | Landing depth (straight / dogLegged) |
|
|
111
|
+
* | `baseOffset` | `number`? | Vertical offset from the storey base (engine units) |
|
|
112
|
+
*/
|
|
113
|
+
export const PluginStaircaseParamUpdates = z
|
|
114
|
+
.object({
|
|
115
|
+
isStoreyHeightUnlocked: z.boolean().optional(),
|
|
116
|
+
isStaircaseHeightUnlocked: z.boolean().optional(),
|
|
117
|
+
storeyHeight: z.number().optional(),
|
|
118
|
+
staircaseHeight: z.number().optional(),
|
|
119
|
+
steps: z.number().int().optional(),
|
|
120
|
+
riser: z.number().optional(),
|
|
121
|
+
tread: z.number().optional(),
|
|
122
|
+
width: z.number().optional(),
|
|
123
|
+
depth: z.number().optional(),
|
|
124
|
+
wellSize: z.number().optional(),
|
|
125
|
+
flightStartDistAfterTurn: z.number().optional(),
|
|
126
|
+
landingWidth: z.number().optional(),
|
|
127
|
+
baseOffset: z.number().optional(),
|
|
128
|
+
})
|
|
129
|
+
.refine((p) => Object.keys(p).length > 0, {
|
|
130
|
+
message:
|
|
131
|
+
"PluginStaircaseParamUpdates requires at least one field to change",
|
|
132
|
+
})
|
|
133
|
+
export type PluginStaircaseParamUpdates = z.infer<
|
|
134
|
+
typeof PluginStaircaseParamUpdates
|
|
135
|
+
>
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Arguments for {@linkcode PluginDesignUpdateApi.staircase}.
|
|
139
|
+
*
|
|
140
|
+
* | Property | Type | Description |
|
|
141
|
+
* |---|---|---|
|
|
142
|
+
* | `staircases` | {@linkcode ComponentHandle}`[]` | The staircases to update |
|
|
143
|
+
* | `params` | {@linkcode PluginStaircaseParamUpdates} | Sparse parametric changes (≥ 1 field) |
|
|
144
|
+
*/
|
|
145
|
+
export const PluginDesignUpdateStaircaseArgs = z.object({
|
|
146
|
+
staircases: z.array(ComponentHandle),
|
|
147
|
+
params: PluginStaircaseParamUpdates,
|
|
148
|
+
})
|
|
149
|
+
export type PluginDesignUpdateStaircaseArgs = z.infer<
|
|
150
|
+
typeof PluginDesignUpdateStaircaseArgs
|
|
151
|
+
>
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Arguments for {@linkcode PluginDesignUpdateApi.parameters}.
|
|
155
|
+
*
|
|
156
|
+
* | Property | Type | Description |
|
|
157
|
+
* |---|---|---|
|
|
158
|
+
* | `component` | {@linkcode ComponentHandle} | The parametric mass to edit |
|
|
159
|
+
* | `patch` | {@linkcode MassParametersPatch} | Partial `values` (+ optional `operations`), or the full edited record |
|
|
160
|
+
*/
|
|
161
|
+
export const PluginDesignUpdateParametersArgs = z.object({
|
|
162
|
+
component: ComponentHandle,
|
|
163
|
+
patch: MassParametersPatch,
|
|
164
|
+
})
|
|
165
|
+
export type PluginDesignUpdateParametersArgs = z.infer<
|
|
166
|
+
typeof PluginDesignUpdateParametersArgs
|
|
167
|
+
>
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Sparse edits for a wall (all optional; at least one required). Only the
|
|
171
|
+
* fields you provide change. Dimensions are in **engine units** (the same
|
|
172
|
+
* convention as `design.doors.setWidth`). Consumed by
|
|
173
|
+
* {@linkcode PluginDesignUpdateApi.wall}.
|
|
174
|
+
*
|
|
175
|
+
* | Property | Type | Description |
|
|
176
|
+
* |---|---|---|
|
|
177
|
+
* | `thickness` | `number`? | Wall thickness, engine units (> 0) |
|
|
178
|
+
* | `height` | `number`? | Wall height, engine units (> 0) |
|
|
179
|
+
* | `type` | {@linkcode PluginWallType}? | Legacy name/id or exact authorized native `{ id, version }` pin from `design.types.list("wall")` |
|
|
180
|
+
*/
|
|
181
|
+
export const PluginWallUpdates = z
|
|
182
|
+
.object({
|
|
183
|
+
thickness: z.number().positive().optional(),
|
|
184
|
+
height: z.number().positive().optional(),
|
|
185
|
+
type: PluginWallType.optional(),
|
|
186
|
+
values: PluginFamilyValues.optional(),
|
|
187
|
+
})
|
|
188
|
+
.refine((p) => Object.keys(p).length > 0, {
|
|
189
|
+
message: "PluginWallUpdates requires at least one field to change",
|
|
190
|
+
})
|
|
191
|
+
export type PluginWallUpdates = z.infer<typeof PluginWallUpdates>
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Sparse dimension edits for a slab-family element (slab / floor / roof /
|
|
195
|
+
* ceiling). All values are engine units, the same convention as
|
|
196
|
+
* `design.doors.setWidth`. Consumed by {@linkcode PluginDesignUpdateApi.slab},
|
|
197
|
+
* `floor`, `roof`, and `ceiling`.
|
|
198
|
+
*
|
|
199
|
+
* `overhang` is only available on **slabs and roofs** (the panel's Overhang
|
|
200
|
+
* slider) — floors and ceilings reject it with `PRECONDITION_FAILED`.
|
|
201
|
+
*
|
|
202
|
+
* | Property | Type | Description |
|
|
203
|
+
* |---|---|---|
|
|
204
|
+
* | `thickness` | `number`? | Element thickness, engine units (> 0) |
|
|
205
|
+
* | `overhang` | `number`? | Absolute overhang offset, engine units (slab / roof only) |
|
|
206
|
+
*/
|
|
207
|
+
export const PluginSlabUpdates = z
|
|
208
|
+
.object({
|
|
209
|
+
thickness: z.number().positive().optional(),
|
|
210
|
+
overhang: z.number().optional(),
|
|
211
|
+
type: PluginConstructionType.optional(),
|
|
212
|
+
values: PluginFamilyValues.optional(),
|
|
213
|
+
})
|
|
214
|
+
.refine((p) => Object.keys(p).length > 0, {
|
|
215
|
+
message: "PluginSlabUpdates requires at least one field to change",
|
|
216
|
+
})
|
|
217
|
+
export type PluginSlabUpdates = z.infer<typeof PluginSlabUpdates>
|
|
218
|
+
|
|
219
|
+
/** Arguments for {@linkcode PluginDesignUpdateApi.wall}. */
|
|
220
|
+
export const PluginDesignUpdateWallArgs = z.object({
|
|
221
|
+
component: ComponentHandle,
|
|
222
|
+
updates: PluginWallUpdates,
|
|
223
|
+
})
|
|
224
|
+
export type PluginDesignUpdateWallArgs = z.infer<
|
|
225
|
+
typeof PluginDesignUpdateWallArgs
|
|
226
|
+
>
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Arguments for the slab-family updaters —
|
|
230
|
+
* {@linkcode PluginDesignUpdateApi.slab}, `floor`, `roof`, `ceiling`.
|
|
231
|
+
*/
|
|
232
|
+
export const PluginDesignUpdateSlabArgs = z.object({
|
|
233
|
+
component: ComponentHandle,
|
|
234
|
+
updates: PluginSlabUpdates,
|
|
235
|
+
})
|
|
236
|
+
export type PluginDesignUpdateSlabArgs = z.infer<
|
|
237
|
+
typeof PluginDesignUpdateSlabArgs
|
|
238
|
+
>
|
|
239
|
+
|
|
240
|
+
/** Arguments for {@linkcode PluginDesignUpdateApi.setElevation}. */
|
|
241
|
+
export const PluginDesignSetElevationArgs = z.object({
|
|
242
|
+
component: ComponentHandle,
|
|
243
|
+
elevation: z.number(),
|
|
244
|
+
})
|
|
245
|
+
export type PluginDesignSetElevationArgs = z.infer<
|
|
246
|
+
typeof PluginDesignSetElevationArgs
|
|
247
|
+
>
|
|
248
|
+
|
|
249
|
+
/** Arguments for {@linkcode PluginDesignUpdateApi.setBaseOffset}. */
|
|
250
|
+
export const PluginDesignSetBaseOffsetArgs = z.object({
|
|
251
|
+
component: ComponentHandle,
|
|
252
|
+
offset: z.number(),
|
|
253
|
+
})
|
|
254
|
+
export type PluginDesignSetBaseOffsetArgs = z.infer<
|
|
255
|
+
typeof PluginDesignSetBaseOffsetArgs
|
|
256
|
+
>
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Arguments for {@linkcode PluginDesignUpdateApi.setStorey}.
|
|
260
|
+
*
|
|
261
|
+
* | Property | Type | Description |
|
|
262
|
+
* |---|---|---|
|
|
263
|
+
* | `components` | {@linkcode ComponentHandle}`[]` | The components to reassign |
|
|
264
|
+
* | `storey` | `number` | Target integer storey number (`entity.story` convention; must exist) |
|
|
265
|
+
*/
|
|
266
|
+
export const PluginDesignSetStoreyArgs = z.object({
|
|
267
|
+
components: z.array(ComponentHandle),
|
|
268
|
+
storey: z.number().int(),
|
|
269
|
+
})
|
|
270
|
+
export type PluginDesignSetStoreyArgs = z.infer<
|
|
271
|
+
typeof PluginDesignSetStoreyArgs
|
|
272
|
+
>
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Object types {@linkcode PluginDesignUpdateApi.setObjectType} can turn a mass
|
|
276
|
+
* into — the `design.query` `type` vocabulary.
|
|
277
|
+
*/
|
|
278
|
+
export const PluginObjectType = PluginEntityType.extract([
|
|
279
|
+
"wall",
|
|
280
|
+
"roof",
|
|
281
|
+
"slab",
|
|
282
|
+
"floor",
|
|
283
|
+
])
|
|
284
|
+
export type PluginObjectType = z.infer<typeof PluginObjectType>
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Arguments for {@linkcode PluginDesignUpdateApi.setObjectType}.
|
|
288
|
+
*
|
|
289
|
+
* | Property | Type | Description |
|
|
290
|
+
* |---|---|---|
|
|
291
|
+
* | `components` | {@linkcode ComponentHandle}`[]` | The masses to convert (>= 1) |
|
|
292
|
+
* | `objectType` | {@linkcode PluginObjectType} | Target object type (`"wall"`, `"roof"`, `"slab"`, `"floor"`) |
|
|
293
|
+
*/
|
|
294
|
+
export const PluginDesignSetObjectTypeArgs = z.object({
|
|
295
|
+
components: z.array(ComponentHandle).min(1),
|
|
296
|
+
objectType: PluginObjectType,
|
|
297
|
+
})
|
|
298
|
+
export type PluginDesignSetObjectTypeArgs = z.infer<
|
|
299
|
+
typeof PluginDesignSetObjectTypeArgs
|
|
300
|
+
>
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* The sparse GROUP-LEVEL patch accepted by {@linkcode PluginDesignUpdateApi.grid}.
|
|
304
|
+
* Only provided fields change. Wing- and line-level updates live on the grids
|
|
305
|
+
* entity family: `design.grids.updateWings` / `design.grids.updateLines`.
|
|
306
|
+
*/
|
|
307
|
+
export const PluginGridPatch = z.object({
|
|
308
|
+
angle: z.number().finite().optional(),
|
|
309
|
+
props: PluginGridStyleOptions.optional(),
|
|
310
|
+
storeyVisibility: z
|
|
311
|
+
.array(z.object({ storey: z.number().int(), visible: z.boolean() }))
|
|
312
|
+
.optional(),
|
|
313
|
+
})
|
|
314
|
+
export type PluginGridPatch = z.infer<typeof PluginGridPatch>
|
|
315
|
+
|
|
316
|
+
/** Arguments for {@linkcode PluginDesignUpdateApi.grid}. */
|
|
317
|
+
export const PluginDesignUpdateGridArgs = z.object({
|
|
318
|
+
grid: ComponentHandle,
|
|
319
|
+
patch: PluginGridPatch,
|
|
320
|
+
})
|
|
321
|
+
export type PluginDesignUpdateGridArgs = z.infer<
|
|
322
|
+
typeof PluginDesignUpdateGridArgs
|
|
323
|
+
>
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* `snaptrude.design.update` — edit existing scene entities (properties + geometry).
|
|
327
|
+
*
|
|
328
|
+
* Migrated from the removed `entity.space.{update, updateGeometryFromProfile, bulkUpdate}`.
|
|
329
|
+
* Only provided fields change; each call is undoable. Failures throw (RPC rejects).
|
|
330
|
+
*
|
|
331
|
+
* Native family edits accept `type` and/or sparse `values` from `design.catalog`.
|
|
332
|
+
* Length overrides use mm; dimensional arguments use SU. Contours and axes stay unchanged.
|
|
333
|
+
* Shared/type overrides are refused. A thickness argument must agree with the layer values.
|
|
334
|
+
* Family roof overhang is unsupported; use the native slab path for family overhang edits.
|
|
335
|
+
*/
|
|
336
|
+
export abstract class PluginDesignUpdateApi {
|
|
337
|
+
constructor() {}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Set a component's **Label** — the same editable Label field the properties
|
|
341
|
+
* panel shows (doors, windows, furniture, spaces, and every other labelled
|
|
342
|
+
* component). The paired read is `design.query.getLabel`. Undoable; the
|
|
343
|
+
* canvas label text updates immediately.
|
|
344
|
+
*
|
|
345
|
+
* Strictly **per component**: labelling one door of a placed family never
|
|
346
|
+
* touches its sibling doors (the panel's Label edit, by contrast, applies to
|
|
347
|
+
* the whole family). On **legacy masses** without a space type, panel parity
|
|
348
|
+
* applies — a label matching a room-type preset with a height can also
|
|
349
|
+
* adjust the mass's height and material, exactly like typing it in the panel.
|
|
350
|
+
*
|
|
351
|
+
* Throws when the component is locked, the handle is gone/forged, the label
|
|
352
|
+
* is empty, or the component has no mesh to label. Re-applying the current
|
|
353
|
+
* label is a no-op that returns `true` without touching the undo stack.
|
|
354
|
+
*
|
|
355
|
+
* @param component - The component to relabel
|
|
356
|
+
* @param label - New label text (non-empty; leading/trailing whitespace trimmed)
|
|
357
|
+
* @returns `true` once the label is applied
|
|
358
|
+
*
|
|
359
|
+
* @examplePrompt Rename this door to D-101
|
|
360
|
+
* @examplePrompt Number all doors on storey 2 with a D-2-XX tag
|
|
361
|
+
* @examplePrompt Set the selected window's label to W-04
|
|
362
|
+
* @examplePrompt Tag every door with its fire rating
|
|
363
|
+
*
|
|
364
|
+
* # Example
|
|
365
|
+
* ```ts
|
|
366
|
+
* // Door tag numbering: label every door as D-<storey>-<n>, numbered per storey
|
|
367
|
+
* await snaptrude.design.selection.setByFilter({ types: ["door"] })
|
|
368
|
+
* const doors = await snaptrude.design.selection.get()
|
|
369
|
+
* const counts = {}
|
|
370
|
+
* for (const door of doors) {
|
|
371
|
+
* const { storey = 0 } = await snaptrude.design.query.getProperties(door)
|
|
372
|
+
* counts[storey] = (counts[storey] ?? 0) + 1
|
|
373
|
+
* await snaptrude.design.update.setLabel(door, `D-${storey}-${String(counts[storey]).padStart(2, "0")}`)
|
|
374
|
+
* }
|
|
375
|
+
* ```
|
|
376
|
+
*/
|
|
377
|
+
public abstract setLabel(
|
|
378
|
+
component: ComponentHandle,
|
|
379
|
+
label: string,
|
|
380
|
+
): PluginApiReturn<boolean>
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Update a structural grid's **group-level** fields with a sparse patch —
|
|
384
|
+
* default line styling, absolute angle, and per-storey 2D visibility. Only
|
|
385
|
+
* provided fields change. Wing- and line-level updates live on the grids
|
|
386
|
+
* entity family: {@linkcode PluginDesignGridsApi.updateWings} /
|
|
387
|
+
* {@linkcode PluginDesignGridsApi.updateLines}.
|
|
388
|
+
*
|
|
389
|
+
* Every change routes through the exact setters the native panel uses —
|
|
390
|
+
* each changed field commits its own undoable command, identical to editing
|
|
391
|
+
* that field in the panel. `angle` is an absolute target in degrees (CCW
|
|
392
|
+
* about +Y).
|
|
393
|
+
*
|
|
394
|
+
* @param grid - The grid group to update
|
|
395
|
+
* @param patch - The sparse {@linkcode PluginGridPatch}
|
|
396
|
+
* @returns `true` once applied
|
|
397
|
+
*
|
|
398
|
+
* @examplePrompt Rotate the grid to 45 degrees
|
|
399
|
+
* @examplePrompt Make this grid's lines dashed and grey
|
|
400
|
+
* @examplePrompt Hide this grid on storey 3's plan
|
|
401
|
+
*
|
|
402
|
+
* # Example
|
|
403
|
+
* ```ts
|
|
404
|
+
* const [grid] = await snaptrude.design.query.listGrids()
|
|
405
|
+
* await snaptrude.design.update.grid(grid, { angle: 45, props: { style: "DASHED" } })
|
|
406
|
+
* ```
|
|
407
|
+
*/
|
|
408
|
+
public abstract grid(
|
|
409
|
+
grid: ComponentHandle,
|
|
410
|
+
patch: PluginGridPatch,
|
|
411
|
+
): PluginApiReturn<boolean>
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Update a single space (room) — change its properties (room label, space
|
|
415
|
+
* type, mass type, area class, department) and/or replace its geometry by
|
|
416
|
+
* re-extruding a profile to a new height. Sparse and undoable: only the
|
|
417
|
+
* fields you provide change.
|
|
418
|
+
*
|
|
419
|
+
* @param space - The space to update
|
|
420
|
+
* @param options - `properties` (sparse) and/or `geometry` ({ profile, extrudeHeight })
|
|
421
|
+
* @returns the updated space's echoed {@linkcode PluginSpaceUpdateResult}
|
|
422
|
+
* @throws PRECONDITION_FAILED for a void (a hole cut with `design.create.void`): delete it and
|
|
423
|
+
* cut a new one
|
|
424
|
+
*
|
|
425
|
+
* @examplePrompt Rename this room to Office
|
|
426
|
+
* @examplePrompt Change this space's room type to Meeting Room
|
|
427
|
+
* @examplePrompt Set the height of this room to 3 metres
|
|
428
|
+
* @examplePrompt Move this space into the Circulation department
|
|
429
|
+
* @examplePrompt Exclude this room from the area calculations
|
|
430
|
+
*
|
|
431
|
+
* @performance For MORE THAN ONE space, call `design.update.spaces(items[])` — the whole
|
|
432
|
+
* batch is one host round-trip. Looping this single-space updater is N round-trips.
|
|
433
|
+
*
|
|
434
|
+
* # Example
|
|
435
|
+
* ```ts
|
|
436
|
+
* await snaptrude.design.update.space("space-id", { properties: { room_type: "Office" } })
|
|
437
|
+
* ```
|
|
438
|
+
*/
|
|
439
|
+
public abstract space(
|
|
440
|
+
space: ComponentHandle,
|
|
441
|
+
options: {
|
|
442
|
+
properties?: PluginSpacePropertyUpdates
|
|
443
|
+
geometry?: PluginSpaceGeometryUpdate
|
|
444
|
+
},
|
|
445
|
+
): PluginApiReturn<PluginSpaceUpdateResult>
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Update many spaces (rooms) in one undoable operation — the bulk form of
|
|
449
|
+
* {@linkcode space}. Each item pairs a space with the sparse property
|
|
450
|
+
* changes and/or geometry re-extrude to apply; every item is validated up
|
|
451
|
+
* front, then all changes are applied as a single command.
|
|
452
|
+
*
|
|
453
|
+
* Migrated from `entity.space.bulkUpdate`.
|
|
454
|
+
*
|
|
455
|
+
* @param items - One {@linkcode PluginUpdateSpaceItem} per space
|
|
456
|
+
* @returns one {@linkcode PluginSpaceUpdateResult} per item, in input order
|
|
457
|
+
* @throws PRECONDITION_FAILED for a void, like {@linkcode space}
|
|
458
|
+
*
|
|
459
|
+
* @examplePrompt Label all the selected rooms as Bedrooms
|
|
460
|
+
* @examplePrompt Change the room type of these five spaces at once
|
|
461
|
+
* @examplePrompt Set every room on this floor to a 3m height in one go
|
|
462
|
+
* @examplePrompt Bulk-assign these spaces to the Service department
|
|
463
|
+
* @examplePrompt Mark all of these rooms as excluded from area in one update
|
|
464
|
+
*
|
|
465
|
+
* @performance Bulk update — the whole batch is ONE host round-trip. Prefer over looping
|
|
466
|
+
* `design.update.space`: build the `items[]` array first, then make one call.
|
|
467
|
+
*
|
|
468
|
+
* # Example
|
|
469
|
+
* ```ts
|
|
470
|
+
* // Re-label every selected room and mark it NET area — one undoable bulk update
|
|
471
|
+
* const rooms = await snaptrude.design.query.listSpaces({ isSelected: true })
|
|
472
|
+
* const results = await snaptrude.design.update.spaces(
|
|
473
|
+
* rooms.map((space) => ({
|
|
474
|
+
* space,
|
|
475
|
+
* properties: { room_type: "Bedroom", areaClass: "NET" },
|
|
476
|
+
* })),
|
|
477
|
+
* )
|
|
478
|
+
* // One result per item, in input order
|
|
479
|
+
* console.log(results.map((r) => r.spaceId))
|
|
480
|
+
* ```
|
|
481
|
+
*/
|
|
482
|
+
public abstract spaces(
|
|
483
|
+
items: PluginUpdateSpaceItem[],
|
|
484
|
+
): PluginApiReturn<PluginSpaceUpdateResult[]>
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* Update the parameters of one or more staircases — riser, tread, width,
|
|
488
|
+
* depth, step count, total height, well size, landing depth, base offset,
|
|
489
|
+
* and the two height locks — in one undoable operation. Sparse: only the
|
|
490
|
+
* fields you provide change. The paired read is
|
|
491
|
+
* `design.query.getStaircaseParams`.
|
|
492
|
+
*
|
|
493
|
+
* All dimensions are in **engine units** (the same convention as
|
|
494
|
+
* `design.doors.setWidth`); `steps` is a unitless integer count. The height,
|
|
495
|
+
* riser, and step count are **coupled** — `staircaseHeight = steps × riser` —
|
|
496
|
+
* and the two lock booleans govern which value recomputes when another
|
|
497
|
+
* changes. With `isStoreyHeightUnlocked` false the staircase height follows
|
|
498
|
+
* the storey height; unlocking it also unlocks the staircase height. Setting
|
|
499
|
+
* `steps` recomputes `riser` (or the height, once the height is unlocked),
|
|
500
|
+
* and setting `riser` recomputes `steps`/height in turn.
|
|
501
|
+
*
|
|
502
|
+
* Presets-only: this edits the parametric fields of a preset staircase; it
|
|
503
|
+
* does not change the staircase's type/preset (there is no in-place re-type).
|
|
504
|
+
* Every edit rebuilds the staircase geometry, so the call is async.
|
|
505
|
+
*
|
|
506
|
+
* Throws when a handle is not a staircase, when a staircase is locked, or
|
|
507
|
+
* when a value falls outside the engine's accepted range (RPC rejects).
|
|
508
|
+
*
|
|
509
|
+
* @param staircases - the staircases to update
|
|
510
|
+
* @param params - sparse {@linkcode PluginStaircaseParamUpdates} (at least one field)
|
|
511
|
+
* @returns the affected staircases
|
|
512
|
+
*
|
|
513
|
+
* @examplePrompt Set the riser of this staircase to 165mm
|
|
514
|
+
* @examplePrompt Change all the stairs to 14 steps
|
|
515
|
+
* @examplePrompt Make the selected staircase 1200 wide with a 280 tread
|
|
516
|
+
* @examplePrompt Widen every staircase on level 1 to 1 metre
|
|
517
|
+
* @examplePrompt Unlock the height and set this stair to 3200 tall
|
|
518
|
+
*
|
|
519
|
+
* # Example
|
|
520
|
+
* ```ts
|
|
521
|
+
* // Give every ground-floor staircase a common riser + tread (engine units)
|
|
522
|
+
* const stairs = await snaptrude.design.query.listStaircases({ storeys: [1] })
|
|
523
|
+
* const { affected } = await snaptrude.design.update.staircase(stairs, {
|
|
524
|
+
* riser: 165,
|
|
525
|
+
* tread: 280,
|
|
526
|
+
* })
|
|
527
|
+
* console.log("updated", affected.length, "staircases")
|
|
528
|
+
* ```
|
|
529
|
+
*/
|
|
530
|
+
public abstract staircase(
|
|
531
|
+
staircases: ComponentHandle[],
|
|
532
|
+
params: PluginStaircaseParamUpdates,
|
|
533
|
+
): PluginApiReturn<PluginDesignChangeResult>
|
|
534
|
+
|
|
535
|
+
/**
|
|
536
|
+
* Edit a parametric mass by patching its creation recipe and rebuilding the
|
|
537
|
+
* solid in place — the mass keeps its id, storey, materials, position and
|
|
538
|
+
* linked copies; only the geometry changes. Read the current record with
|
|
539
|
+
* `design.query.getParameters` first.
|
|
540
|
+
*
|
|
541
|
+
* `patch` is a partial of `record.values` — or the whole record you read
|
|
542
|
+
* back, edited. A key you leave out is unchanged (that includes
|
|
543
|
+
* `operations`). Each key you send replaces that value whole — a scalar, a
|
|
544
|
+
* point, a list or a record (`contour`, `profile`, `sections`, `path`,
|
|
545
|
+
* `options`, `operations`) alike — so send the complete value you read,
|
|
546
|
+
* edited (a partial `options` drops the switches it leaves out);
|
|
547
|
+
* `{ operations: [] }` drops every operation. An optional key
|
|
548
|
+
* the record does not carry yet may be patched in when the kind allows it:
|
|
549
|
+
* a straight extrusion acquires `twistInDegrees` or `topScale`, an
|
|
550
|
+
* options-less loft or sweep acquires `options` (`levels` is not one — send
|
|
551
|
+
* the angle, not the section count). A patch that changes nothing
|
|
552
|
+
* returns the current record and records no edit (no undo step). `kind` and
|
|
553
|
+
* `version` are immutable: to change the kind, build a new mass. Keys are the
|
|
554
|
+
* record's `values` keys for its `kind` (sphere: `centre`, `radius`;
|
|
555
|
+
* cylinder: `base`, `axis`, `radius`, `height`; torus: `centre`, `axis`,
|
|
556
|
+
* `majorRadius`, `minorRadius`; …) plus `operations`. To change a fillet
|
|
557
|
+
* radius, edit `operations[i].radius` in the record you read and send
|
|
558
|
+
* `{ operations }` back. Points and axes are WORLD coordinates in internal
|
|
559
|
+
* units, exactly as `getParameters` reports them.
|
|
560
|
+
*
|
|
561
|
+
* Rebuilds in memory first, then swaps onto the SAME component; every linked
|
|
562
|
+
* copy regenerates together. One undo step; saves and syncs to collaborators
|
|
563
|
+
* like any geometry edit. Kernel kinds (revolution, sweep, loft, primitives,
|
|
564
|
+
* any `operations`) run on OpenCascade — expect a short pause.
|
|
565
|
+
*
|
|
566
|
+
* @param component - a mass whose `getParameters` is non-null
|
|
567
|
+
* @param patch - partial `values` (+ optional `operations`), or the full edited record
|
|
568
|
+
* @returns the complete post-edit record, world coordinates (what
|
|
569
|
+
* `getParameters` now returns)
|
|
570
|
+
* @throws PRECONDITION_FAILED when the component is not a mass (a family
|
|
571
|
+
* instance: use `design.family.setParameters`).
|
|
572
|
+
* Also PRECONDITION_FAILED when the mass carries no live recipe — built
|
|
573
|
+
* from a boolean, split, `brepFromFaces`/`brepFromMesh` or drawn; edited
|
|
574
|
+
* free-form since (push/pull, move face, boolean); or scaled with the
|
|
575
|
+
* transform tool. `getParameters` returns `null` for exactly these.
|
|
576
|
+
* Do not retry — rebuild it with a recipe constructor and say so.
|
|
577
|
+
* A scaled mass is the exception: undo the scale and call again.
|
|
578
|
+
* Also PRECONDITION_FAILED when the mass (or a linked copy) is **locked**
|
|
579
|
+
* (the message says so). Locking is invisible to `getParameters` — a
|
|
580
|
+
* locked parametric mass still reads back a full record. Unlock it (and
|
|
581
|
+
* every linked copy) and call again; never rebuild it, the recipe is intact.
|
|
582
|
+
* Also PRECONDITION_FAILED when an `operations` entry's edge/face selectors
|
|
583
|
+
* no longer resolve on the rebuilt base (the message names the operation
|
|
584
|
+
* and edge): re-select the edges on the new shape and re-apply that
|
|
585
|
+
* operation.
|
|
586
|
+
* Also PRECONDITION_FAILED when the edit is the first twist or taper — or
|
|
587
|
+
* the straightening — of an extrusion that carries a shell, fillet or
|
|
588
|
+
* chamfer (the kernel numbers its faces differently): send the twist/taper
|
|
589
|
+
* keys with `operations: []` first (the message names them), re-select on
|
|
590
|
+
* the new shape, then send `{ operations }` back.
|
|
591
|
+
* Graph-bound spaces accept amount-only extrusion edits. Footprint, twist,
|
|
592
|
+
* taper and operation edits require the owning boundary tools, so generated
|
|
593
|
+
* walls, junctions and hosted openings remain synchronized.
|
|
594
|
+
* @throws VALIDATION for a key the kind does not have (the message lists the
|
|
595
|
+
* kind's keys), `kind` or `version` in a partial patch, or a value outside
|
|
596
|
+
* the constructor's own rules (torus tube ≥ ring, revolution angle ∉
|
|
597
|
+
* (0, 360], a profile crossing its axis, a spline with fewer than
|
|
598
|
+
* degree + 1 poles).
|
|
599
|
+
* @throws OPERATION_FAILED when the kernel cannot build the edited recipe;
|
|
600
|
+
* the model is left unchanged.
|
|
601
|
+
*
|
|
602
|
+
* @examplePrompt Make the dome's radius 8 metres
|
|
603
|
+
* @examplePrompt Raise the podium to 5 m
|
|
604
|
+
* @examplePrompt Widen the vase — move its profile points 20 cm outward
|
|
605
|
+
* @examplePrompt Change the fillet on the rounded column to 300 mm
|
|
606
|
+
*
|
|
607
|
+
* # Example
|
|
608
|
+
* ```ts
|
|
609
|
+
* // { kind: "sphere", values: { centre, radius: 19.685 }, … }
|
|
610
|
+
* const before = await snaptrude.design.query.getParameters(dome)
|
|
611
|
+
* const after = await snaptrude.design.update.parameters(dome, { radius: 31.496 }) // 8 m in internal units
|
|
612
|
+
*
|
|
613
|
+
* // Fillet radius on a recorded result: read → edit → send the array back
|
|
614
|
+
* const rec = await snaptrude.design.query.getParameters(column)
|
|
615
|
+
* const operations = rec?.operations ?? []
|
|
616
|
+
* if (operations[0]?.op === "fillet") {
|
|
617
|
+
* operations[0].radius = 1.181
|
|
618
|
+
* await snaptrude.design.update.parameters(column, { operations })
|
|
619
|
+
* }
|
|
620
|
+
* ```
|
|
621
|
+
*/
|
|
622
|
+
public abstract parameters(
|
|
623
|
+
component: ComponentHandle,
|
|
624
|
+
patch: MassParametersPatch,
|
|
625
|
+
): PluginApiReturn<MassParametersRecord>
|
|
626
|
+
|
|
627
|
+
/**
|
|
628
|
+
* Edit a **wall** — its thickness and/or height (the same command the
|
|
629
|
+
* properties panel's Thickness/Height fields drive) and/or its **wall type**
|
|
630
|
+
* (the panel's Wall Types dropdown: converts the wall to another type,
|
|
631
|
+
* rebuilding its layer stack and materials). Sparse: only the fields you
|
|
632
|
+
* provide change. Undoable; the geometry rebuilds and any dimension lines
|
|
633
|
+
* refresh. Stacked-wall companions and hosted fenestration are handled
|
|
634
|
+
* exactly as the panel does.
|
|
635
|
+
*
|
|
636
|
+
* Thickness/height are in **engine units** (the same convention as
|
|
637
|
+
* `design.doors.setWidth`) and must be `> 0`. Shrinking a wall past its
|
|
638
|
+
* openings is rejected by the engine (the wall is skipped with no change).
|
|
639
|
+
* `type` accepts a type name from `design.types.list("wall")` (or its
|
|
640
|
+
* `wall:`-prefixed id); when combined with dimensions, the type conversion
|
|
641
|
+
* is applied first so an explicit thickness/height wins over the type's
|
|
642
|
+
* defaults. Re-applying the wall's current type is a no-op.
|
|
643
|
+
*
|
|
644
|
+
* Throws when the handle is not a wall, when the wall is locked, when the
|
|
645
|
+
* handle is gone/forged, when `type` names an unknown wall type, when the
|
|
646
|
+
* engine rejects the conversion (e.g. a curved wall thinner than the new
|
|
647
|
+
* type's minimum thickness), or when no field is provided.
|
|
648
|
+
*
|
|
649
|
+
* A type conversion (and a thickness edit on a parametric wall) REBUILDS the
|
|
650
|
+
* wall, replacing it with a new component: the input handle is then dead
|
|
651
|
+
* (further calls throw HANDLE_INVALID) and `affected[0]` carries the
|
|
652
|
+
* replacement's handle — use it for any follow-up calls.
|
|
653
|
+
*
|
|
654
|
+
* @param component - The wall to edit
|
|
655
|
+
* @param updates - Sparse {@linkcode PluginWallUpdates} (at least one field)
|
|
656
|
+
* @returns the affected wall — after a rebuild, the REPLACEMENT wall's handle
|
|
657
|
+
*
|
|
658
|
+
* @examplePrompt Make this wall 230mm thick
|
|
659
|
+
* @examplePrompt Set the selected wall's height to 3 metres
|
|
660
|
+
* @examplePrompt Thicken every exterior wall to 300
|
|
661
|
+
* @examplePrompt Change this wall to a Glass Wall
|
|
662
|
+
* @examplePrompt Convert all the partitions on this floor to Brick Wall
|
|
663
|
+
*
|
|
664
|
+
* # Example
|
|
665
|
+
* ```ts
|
|
666
|
+
* // Convert every wall on storey 1 to the first listed wall type
|
|
667
|
+
* const [wallType] = await snaptrude.design.types.list("wall")
|
|
668
|
+
* const walls = await snaptrude.design.query.listWalls({ storeys: [1] })
|
|
669
|
+
* for (const wall of walls) {
|
|
670
|
+
* await snaptrude.design.update.wall(wall, { type: wallType.id })
|
|
671
|
+
* }
|
|
672
|
+
* ```
|
|
673
|
+
*/
|
|
674
|
+
public abstract wall(
|
|
675
|
+
component: ComponentHandle,
|
|
676
|
+
updates: PluginWallUpdates,
|
|
677
|
+
): PluginApiReturn<PluginDesignChangeResult>
|
|
678
|
+
|
|
679
|
+
/**
|
|
680
|
+
* Edit a **slab's** thickness and/or overhang — the same commands the
|
|
681
|
+
* properties panel's Thickness field and Overhang slider drive. Sparse: only
|
|
682
|
+
* the fields you provide change. Undoable; the slab rebuilds and dimension
|
|
683
|
+
* lines refresh. Both values are in **engine units** (the same convention as
|
|
684
|
+
* `design.doors.setWidth`); thickness must be `> 0`, overhang is an absolute
|
|
685
|
+
* offset (negative insets the slab) and re-applying the current overhang is
|
|
686
|
+
* a no-op.
|
|
687
|
+
*
|
|
688
|
+
* Throws when the handle is not a slab, when it is locked, when the handle is
|
|
689
|
+
* gone/forged, when `overhang` is set on a slab that has no overhang (plinth /
|
|
690
|
+
* basement slabs, or overhang disabled), or when no field is provided.
|
|
691
|
+
*
|
|
692
|
+
* @param component - The slab to edit
|
|
693
|
+
* @param updates - Sparse {@linkcode PluginSlabUpdates} (at least one field)
|
|
694
|
+
* @returns the affected slab
|
|
695
|
+
*
|
|
696
|
+
* @examplePrompt Set this slab's thickness to 250mm
|
|
697
|
+
* @examplePrompt Make the floor slab 300 thick
|
|
698
|
+
* @examplePrompt Give this slab a 200 overhang
|
|
699
|
+
* @examplePrompt Remove the overhang on every slab on level 2
|
|
700
|
+
*
|
|
701
|
+
* # Example
|
|
702
|
+
* ```ts
|
|
703
|
+
* const [slab] = await snaptrude.design.query.listSlabs()
|
|
704
|
+
* await snaptrude.design.update.slab(slab, { thickness: 250, overhang: 200 })
|
|
705
|
+
* ```
|
|
706
|
+
*/
|
|
707
|
+
public abstract slab(
|
|
708
|
+
component: ComponentHandle,
|
|
709
|
+
updates: PluginSlabUpdates,
|
|
710
|
+
): PluginApiReturn<PluginDesignChangeResult>
|
|
711
|
+
|
|
712
|
+
/**
|
|
713
|
+
* Edit a **floor's** thickness — the slab-family updater for floors (shares
|
|
714
|
+
* the slab thickness command). Undoable. Thickness is in **engine units**
|
|
715
|
+
* (the `design.doors.setWidth` convention) and must be `> 0`. Floors have no
|
|
716
|
+
* Overhang control, so `overhang` is rejected with `PRECONDITION_FAILED`.
|
|
717
|
+
*
|
|
718
|
+
* Throws when the handle is not a floor, when it is locked, when the handle
|
|
719
|
+
* is gone/forged, when `overhang` is provided, or when no field is provided.
|
|
720
|
+
*
|
|
721
|
+
* @param component - The floor to edit
|
|
722
|
+
* @param updates - {@linkcode PluginSlabUpdates} (a `thickness`)
|
|
723
|
+
* @returns the affected floor
|
|
724
|
+
*
|
|
725
|
+
* @examplePrompt Make this floor 200mm thick
|
|
726
|
+
* @examplePrompt Set every floor to a 250 thickness
|
|
727
|
+
* @examplePrompt Thicken the ground floor slab to 300
|
|
728
|
+
*
|
|
729
|
+
* # Example
|
|
730
|
+
* ```ts
|
|
731
|
+
* const [floor] = await snaptrude.design.query.listFloors()
|
|
732
|
+
* await snaptrude.design.update.floor(floor, { thickness: 200 })
|
|
733
|
+
* ```
|
|
734
|
+
*/
|
|
735
|
+
public abstract floor(
|
|
736
|
+
component: ComponentHandle,
|
|
737
|
+
updates: PluginSlabUpdates,
|
|
738
|
+
): PluginApiReturn<PluginDesignChangeResult>
|
|
739
|
+
|
|
740
|
+
/**
|
|
741
|
+
* Edit a **roof's** thickness and/or overhang — the same commands the roof
|
|
742
|
+
* panel's Thickness field and Overhang slider drive (shares the slab-family
|
|
743
|
+
* machinery). Sparse: only the fields you provide change. Undoable. Both
|
|
744
|
+
* values are in **engine units** (the `design.doors.setWidth` convention);
|
|
745
|
+
* thickness must be `> 0`, overhang is an absolute offset (negative insets
|
|
746
|
+
* the roof) and re-applying the current overhang is a no-op.
|
|
747
|
+
*
|
|
748
|
+
* Throws when the handle is not a roof, when it is locked, when the handle is
|
|
749
|
+
* gone/forged, when `overhang` is set on a roof whose overhang is disabled,
|
|
750
|
+
* or when no field is provided.
|
|
751
|
+
*
|
|
752
|
+
* @param component - The roof to edit
|
|
753
|
+
* @param updates - Sparse {@linkcode PluginSlabUpdates} (at least one field)
|
|
754
|
+
* @returns the affected roof
|
|
755
|
+
*
|
|
756
|
+
* @examplePrompt Make this roof 300mm thick
|
|
757
|
+
* @examplePrompt Set the roof slab thickness to 250
|
|
758
|
+
* @examplePrompt Give the roof a 600 overhang
|
|
759
|
+
* @examplePrompt Pull the roof overhang back to 0
|
|
760
|
+
*
|
|
761
|
+
* # Example
|
|
762
|
+
* ```ts
|
|
763
|
+
* const [roof] = await snaptrude.design.query.listRoofs()
|
|
764
|
+
* await snaptrude.design.update.roof(roof, { overhang: 600 })
|
|
765
|
+
* ```
|
|
766
|
+
*/
|
|
767
|
+
public abstract roof(
|
|
768
|
+
component: ComponentHandle,
|
|
769
|
+
updates: PluginSlabUpdates,
|
|
770
|
+
): PluginApiReturn<PluginDesignChangeResult>
|
|
771
|
+
|
|
772
|
+
/**
|
|
773
|
+
* Edit a **ceiling's** thickness — the slab-family updater for ceilings
|
|
774
|
+
* (shares the slab thickness command). Undoable. Thickness is in **engine
|
|
775
|
+
* units** (the `design.doors.setWidth` convention) and must be `> 0`.
|
|
776
|
+
* Ceilings have no Overhang control, so `overhang` is rejected with
|
|
777
|
+
* `PRECONDITION_FAILED`.
|
|
778
|
+
*
|
|
779
|
+
* Throws when the handle is not a ceiling, when it is locked, when the handle
|
|
780
|
+
* is gone/forged, when `overhang` is provided, or when no field is provided.
|
|
781
|
+
*
|
|
782
|
+
* @param component - The ceiling to edit
|
|
783
|
+
* @param updates - {@linkcode PluginSlabUpdates} (a `thickness`)
|
|
784
|
+
* @returns the affected ceiling
|
|
785
|
+
*
|
|
786
|
+
* @examplePrompt Make this ceiling 150mm thick
|
|
787
|
+
* @examplePrompt Set every ceiling to a 100 thickness
|
|
788
|
+
* @examplePrompt Thicken the ceiling to 200
|
|
789
|
+
*
|
|
790
|
+
* # Example
|
|
791
|
+
* ```ts
|
|
792
|
+
* const [ceiling] = await snaptrude.design.query.listCeilings()
|
|
793
|
+
* await snaptrude.design.update.ceiling(ceiling, { thickness: 150 })
|
|
794
|
+
* ```
|
|
795
|
+
*/
|
|
796
|
+
public abstract ceiling(
|
|
797
|
+
component: ComponentHandle,
|
|
798
|
+
updates: PluginSlabUpdates,
|
|
799
|
+
): PluginApiReturn<PluginDesignChangeResult>
|
|
800
|
+
|
|
801
|
+
/** Replace a native beam family while preserving its authored axis. Values use mm/degrees.
|
|
802
|
+
* @param component Native beam. @param updates Saved family reference and optional instance values.
|
|
803
|
+
* @returns Affected component IDs. One undoable operation; unsupported geometry fails before mutation.
|
|
804
|
+
*/
|
|
805
|
+
public abstract beam(
|
|
806
|
+
component: ComponentHandle,
|
|
807
|
+
updates: PluginFamilyUpdates,
|
|
808
|
+
): PluginApiReturn<PluginDesignChangeResult>
|
|
809
|
+
|
|
810
|
+
/** Replace a native column family while preserving its authored axis. Values use mm/degrees.
|
|
811
|
+
* @param component Native column. @param updates Saved family reference and optional instance values.
|
|
812
|
+
* @returns Affected component IDs. One undoable operation; unsupported geometry fails before mutation.
|
|
813
|
+
*/
|
|
814
|
+
public abstract column(
|
|
815
|
+
component: ComponentHandle,
|
|
816
|
+
updates: PluginFamilyUpdates,
|
|
817
|
+
): PluginApiReturn<PluginDesignChangeResult>
|
|
818
|
+
|
|
819
|
+
/**
|
|
820
|
+
* Set a component's **absolute world elevation** — moves it vertically so its
|
|
821
|
+
* base (the bounding-box bottom, world Y) lands at `elevation`. Composed over
|
|
822
|
+
* the canonical command-backed move machinery, so it is undoable and persisted
|
|
823
|
+
* exactly like dragging the element up or down; per-type invariants (e.g. a
|
|
824
|
+
* staircase's base offset) stay in sync. `elevation` is in **engine units**
|
|
825
|
+
* (the `design.doors.setWidth` convention). Re-applying the current elevation
|
|
826
|
+
* is a no-op.
|
|
827
|
+
*
|
|
828
|
+
* Throws when the component is locked or the handle is gone/forged.
|
|
829
|
+
*
|
|
830
|
+
* @param component - The component to move vertically
|
|
831
|
+
* @param elevation - Target world elevation of the component's base (engine units)
|
|
832
|
+
* @returns the affected component
|
|
833
|
+
*
|
|
834
|
+
* @examplePrompt Set this element's elevation to 3000
|
|
835
|
+
* @examplePrompt Raise this mass so its base sits at 3 metres
|
|
836
|
+
* @examplePrompt Drop the selected slab to elevation 0
|
|
837
|
+
* @examplePrompt Put this staircase's base at 3200
|
|
838
|
+
*
|
|
839
|
+
* # Example
|
|
840
|
+
* ```ts
|
|
841
|
+
* // Sit the roof slab exactly at the top of a 3m storey
|
|
842
|
+
* const [roof] = await snaptrude.design.query.listRoofs()
|
|
843
|
+
* await snaptrude.design.update.setElevation(roof, 3000)
|
|
844
|
+
* ```
|
|
845
|
+
*/
|
|
846
|
+
public abstract setElevation(
|
|
847
|
+
component: ComponentHandle,
|
|
848
|
+
elevation: number,
|
|
849
|
+
): PluginApiReturn<PluginDesignChangeResult>
|
|
850
|
+
|
|
851
|
+
/**
|
|
852
|
+
* Set a component's **base offset** — its vertical distance above its own
|
|
853
|
+
* storey's base level. Moves the component so its base lands at
|
|
854
|
+
* `storeyBase + offset`, composed over the same command-backed move machinery
|
|
855
|
+
* as {@linkcode setElevation} (undoable, persisted, per-type invariants kept
|
|
856
|
+
* in sync). Use this instead of {@linkcode setElevation} when you want an
|
|
857
|
+
* offset relative to the storey rather than an absolute world height.
|
|
858
|
+
* `offset` is in **engine units** (the `design.doors.setWidth` convention);
|
|
859
|
+
* `0` sits the base flush with the storey base. Re-applying the current
|
|
860
|
+
* offset is a no-op.
|
|
861
|
+
*
|
|
862
|
+
* Throws when the component is locked, when it has no storey to offset from,
|
|
863
|
+
* or when the handle is gone/forged.
|
|
864
|
+
*
|
|
865
|
+
* @param component - The component to offset
|
|
866
|
+
* @param offset - Distance of the component's base above its storey base (engine units)
|
|
867
|
+
* @returns the affected component
|
|
868
|
+
*
|
|
869
|
+
* @examplePrompt Lift this element 300 above its floor
|
|
870
|
+
* @examplePrompt Set this staircase's base offset to 0
|
|
871
|
+
* @examplePrompt Raise the selected mass 500 off the storey base
|
|
872
|
+
* @examplePrompt Offset this slab 150 above the floor level
|
|
873
|
+
*
|
|
874
|
+
* # Example
|
|
875
|
+
* ```ts
|
|
876
|
+
* const [stair] = await snaptrude.design.query.listStaircases()
|
|
877
|
+
* await snaptrude.design.update.setBaseOffset(stair, 0)
|
|
878
|
+
* ```
|
|
879
|
+
*/
|
|
880
|
+
public abstract setBaseOffset(
|
|
881
|
+
component: ComponentHandle,
|
|
882
|
+
offset: number,
|
|
883
|
+
): PluginApiReturn<PluginDesignChangeResult>
|
|
884
|
+
|
|
885
|
+
/**
|
|
886
|
+
* Reassign one or more components to another **storey** — the same operation
|
|
887
|
+
* as the properties panel's Story dropdown, and it works across element kinds
|
|
888
|
+
* exactly like the panel (walls, slabs, masses, furniture, staircases, ...).
|
|
889
|
+
* Each component is moved vertically to the target storey's level (per-kind
|
|
890
|
+
* placement rules — e.g. a slab sits at the storey base, a wall on it) and
|
|
891
|
+
* its storey assignment, children, and dimension lines update together as
|
|
892
|
+
* **one undoable operation**.
|
|
893
|
+
*
|
|
894
|
+
* `storey` is an integer storey number in the `entity.story` convention
|
|
895
|
+
* (`1` is the ground storey, `-1` the first basement; `0` does not exist)
|
|
896
|
+
* and **must already exist** in each component's building — this call never
|
|
897
|
+
* creates storeys (use `core.storeys.create` first). Components already on
|
|
898
|
+
* the target storey are skipped (no-op) and are not echoed in `affected`.
|
|
899
|
+
*
|
|
900
|
+
* Throws when the target storey does not exist, when any component is
|
|
901
|
+
* locked, or when a handle is gone/forged — all before anything moves
|
|
902
|
+
* (all-or-nothing).
|
|
903
|
+
*
|
|
904
|
+
* @param components - The components to reassign
|
|
905
|
+
* @param storey - Target storey number (integer, `entity.story` convention)
|
|
906
|
+
* @returns the components actually reassigned
|
|
907
|
+
*
|
|
908
|
+
* @examplePrompt Move this sofa to storey 2
|
|
909
|
+
* @examplePrompt Put the selected walls on the first basement level
|
|
910
|
+
* @examplePrompt Send everything on this storey up one level
|
|
911
|
+
* @examplePrompt Reassign these slabs to storey 3
|
|
912
|
+
*
|
|
913
|
+
* # Example
|
|
914
|
+
* ```ts
|
|
915
|
+
* // Move the current selection up to storey 2
|
|
916
|
+
* const selection = await snaptrude.design.selection.get()
|
|
917
|
+
* const { affected } = await snaptrude.design.update.setStorey(selection, 2)
|
|
918
|
+
* console.log("moved", affected.length, "components")
|
|
919
|
+
* ```
|
|
920
|
+
*/
|
|
921
|
+
public abstract setStorey(
|
|
922
|
+
components: ComponentHandle[],
|
|
923
|
+
storey: number,
|
|
924
|
+
): PluginApiReturn<PluginDesignChangeResult>
|
|
925
|
+
|
|
926
|
+
/**
|
|
927
|
+
* Change the **object type** of one or more masses — turn a mass into a real
|
|
928
|
+
* wall, roof, slab or floor: the properties panel's Object Type dropdown,
|
|
929
|
+
* headless. The geometry is kept exactly as it is (a wedge stays a wedge;
|
|
930
|
+
* nothing is flattened to a default thickness), so a sloped mass built with
|
|
931
|
+
* `design.create.massFromBrep` becomes a sloped roof or a raked wall. The
|
|
932
|
+
* component keeps its handle, label and storey; it gains the target type's
|
|
933
|
+
* construction layers and properties, and the type's default material when
|
|
934
|
+
* the mass still wore the default. One undoable operation for the whole
|
|
935
|
+
* list; undo turns them back into masses.
|
|
936
|
+
*
|
|
937
|
+
* Instances convert as a family: passing one instance (or the source) of an
|
|
938
|
+
* instanced mass converts its source and every sibling; `affected` echoes
|
|
939
|
+
* every visible member (the hidden instancing template converts too but is
|
|
940
|
+
* not listed). A converted component cannot be converted again (same rule
|
|
941
|
+
* as the panel). A converted wall has no parametric centerline: it hosts
|
|
942
|
+
* doors and windows and exports, but neighbours do not re-mitre against it.
|
|
943
|
+
*
|
|
944
|
+
* Throws before anything changes (all-or-nothing) when a component is not a
|
|
945
|
+
* mass, is a plinth, is locked or in a locked bucket, already had its type
|
|
946
|
+
* changed, or when a handle is gone/forged.
|
|
947
|
+
*
|
|
948
|
+
* @param components - The masses to convert
|
|
949
|
+
* @param objectType - Target type: `"wall"`, `"roof"`, `"slab"` or `"floor"`
|
|
950
|
+
* (the `design.query.getEntityType` vocabulary)
|
|
951
|
+
* @returns the visible components converted — the same handles, plus any
|
|
952
|
+
* instance siblings pulled in by family expansion
|
|
953
|
+
*
|
|
954
|
+
* @examplePrompt Convert this mass into a wall
|
|
955
|
+
* @examplePrompt Turn the sloped mass into a roof
|
|
956
|
+
* @examplePrompt Make these masses real slabs
|
|
957
|
+
* @examplePrompt Change the object type of the selection to wall
|
|
958
|
+
* @examplePrompt Convert the wedge I built into a raked wall
|
|
959
|
+
* @examplePrompt Turn this mass into a floor
|
|
960
|
+
*
|
|
961
|
+
* # Example
|
|
962
|
+
* ```ts
|
|
963
|
+
* const brep = await snaptrude.core.geom.create.brepFromFaces(wedgeFaces)
|
|
964
|
+
* const wedge = await snaptrude.design.create.massFromBrep(brep, "Gable end")
|
|
965
|
+
* const { affected } = await snaptrude.design.update.setObjectType([wedge], "wall")
|
|
966
|
+
* console.log(await snaptrude.design.query.getEntityType(affected[0])) // "wall"
|
|
967
|
+
* ```
|
|
968
|
+
*/
|
|
969
|
+
public abstract setObjectType(
|
|
970
|
+
components: ComponentHandle[],
|
|
971
|
+
objectType: PluginObjectType,
|
|
972
|
+
): PluginApiReturn<PluginDesignChangeResult>
|
|
973
|
+
|
|
974
|
+
/**
|
|
975
|
+
* Update an existing parametric buildable envelope — regenerate the zoning
|
|
976
|
+
* volume from a revised site polygon, setbacks, vertical cap, or FAR and
|
|
977
|
+
* lot-coverage limits, keeping the same envelope id. Canonical home of the
|
|
978
|
+
* update formerly at `entity.buildableEnvelope.update` (now deprecated).
|
|
979
|
+
*
|
|
980
|
+
* Edge state is preserved, like the right panel: every edge's type
|
|
981
|
+
* (front/side/rear) is kept. For each type whose value changed (by more than
|
|
982
|
+
* 2 mm), the per-edge custom distances on edges of that type are cleared;
|
|
983
|
+
* custom distances on types whose value did not change are kept.
|
|
984
|
+
*
|
|
985
|
+
* @param buildableEnvelopeId - Existing envelope ID to update; non-empty and
|
|
986
|
+
* must match an existing envelope on the canvas.
|
|
987
|
+
* @param sitePolygon - Site polygon vertices in `lengthUnit`; minimum 3 vertices.
|
|
988
|
+
* @param lengthUnit - Unit used by all length fields (`"ft" | "m"`).
|
|
989
|
+
* @param setbacks - Setback profile, ground tier first; minimum 1 tier.
|
|
990
|
+
* @param verticalCap - Maximum height or floor count.
|
|
991
|
+
* @param floorToFloor - Required floor-to-floor height in `lengthUnit`.
|
|
992
|
+
* @param farRatio - Optional FAR value, positive when provided.
|
|
993
|
+
* @param lotCoverageMaxPct - Optional lot coverage cap, `0..100`.
|
|
994
|
+
* @returns A {@linkcode PluginBuildableEnvelopeUpdateResult} with the
|
|
995
|
+
* `buildableEnvelopeId` of the updated envelope and `clearedEdgeSetbacks`,
|
|
996
|
+
* the `edgeIndex` of each edge that lost its custom distance (empty when
|
|
997
|
+
* none). Tell the user about any cleared edges.
|
|
998
|
+
* @throws If validation fails, the envelope does not exist, or generation
|
|
999
|
+
* produces no renderable geometry. Also throws `PRECONDITION_FAILED`
|
|
1000
|
+
* (`details.reason: "STALE_EDGE_SETTINGS"`, nothing changes) when the site
|
|
1001
|
+
* outline changed since the edge settings were made. Tell the user;
|
|
1002
|
+
* editing any edge on the canvas setback pills resets the edge settings
|
|
1003
|
+
* to the new outline (dropping the old ones), after which you can retry.
|
|
1004
|
+
*
|
|
1005
|
+
* @examplePrompt Change the envelope's height limit to 175 feet
|
|
1006
|
+
* @examplePrompt Update the setbacks on the buildable envelope
|
|
1007
|
+
* @examplePrompt Regenerate the zoning envelope with a new site boundary
|
|
1008
|
+
* @examplePrompt Increase the FAR on the buildable volume
|
|
1009
|
+
*
|
|
1010
|
+
* # Example
|
|
1011
|
+
* ```ts
|
|
1012
|
+
* const { buildableEnvelopeId } = await snaptrude.design.update.buildableEnvelope(
|
|
1013
|
+
* existingId,
|
|
1014
|
+
* [
|
|
1015
|
+
* { x: 0, z: 0 },
|
|
1016
|
+
* { x: 100, z: 0 },
|
|
1017
|
+
* { x: 100, z: 80 },
|
|
1018
|
+
* { x: 0, z: 80 },
|
|
1019
|
+
* ],
|
|
1020
|
+
* "ft",
|
|
1021
|
+
* [{ aboveHeight: 0, front: 10, side: 5, rear: 10 }],
|
|
1022
|
+
* { kind: "max_height", maxHeight: 175 },
|
|
1023
|
+
* 12,
|
|
1024
|
+
* )
|
|
1025
|
+
* ```
|
|
1026
|
+
*/
|
|
1027
|
+
public abstract buildableEnvelope(
|
|
1028
|
+
buildableEnvelopeId: string,
|
|
1029
|
+
sitePolygon: PluginBuildableEnvelopePolygonVertex[],
|
|
1030
|
+
lengthUnit: "ft" | "m",
|
|
1031
|
+
setbacks: PluginBuildableEnvelopeSetbackTier[],
|
|
1032
|
+
verticalCap: PluginBuildableEnvelopeVerticalCap,
|
|
1033
|
+
floorToFloor: number,
|
|
1034
|
+
farRatio?: number,
|
|
1035
|
+
lotCoverageMaxPct?: number,
|
|
1036
|
+
): PluginApiReturn<PluginBuildableEnvelopeUpdateResult>
|
|
1037
|
+
|
|
1038
|
+
/**
|
|
1039
|
+
* Change one site edge's type (front / side / rear) and/or give that edge
|
|
1040
|
+
* its own setback distance, the same as editing a setback pill on the
|
|
1041
|
+
* canvas. One undo step; the pills and Site Analysis sheet refresh.
|
|
1042
|
+
*
|
|
1043
|
+
* Address the edge with `siteId` and `edgeIndex` from
|
|
1044
|
+
* `program.site.listEdges()`. Setting `role` clears that edge's own
|
|
1045
|
+
* distance. `setback: null` clears the edge's own distance and puts it back
|
|
1046
|
+
* on its type's distance. When `role` and a numeric `setback` are both
|
|
1047
|
+
* given, the role is applied first and then the setback, so the new distance
|
|
1048
|
+
* wins. On the only edge of its type, a numeric setback becomes that type's
|
|
1049
|
+
* value (like the canvas pills), so `null` afterwards has nothing to
|
|
1050
|
+
* clear; set the type's value instead. Only call this when the user asks to
|
|
1051
|
+
* change an edge.
|
|
1052
|
+
*
|
|
1053
|
+
* @param siteId - Site component id, from `program.site.listEdges()`.
|
|
1054
|
+
* @param edgeIndex - Edge index from `program.site.listEdges()`; nonnegative
|
|
1055
|
+
* integer, upper bound checked by the host.
|
|
1056
|
+
* @param patch - A {@linkcode PluginSiteEdgePatch}: `role`, `setback` (a
|
|
1057
|
+
* number in `lengthUnit`, or `null` to clear), and `lengthUnit` (required
|
|
1058
|
+
* with a numeric `setback`). Provide `role` and/or `setback`.
|
|
1059
|
+
* @returns The refreshed {@linkcode PluginDesignUpdateSiteEdgeResult} for the
|
|
1060
|
+
* site, as `program.site.listEdges()` returns it.
|
|
1061
|
+
* @throws
|
|
1062
|
+
* - `HANDLE_INVALID`: unknown `siteId` (invalid site handle).
|
|
1063
|
+
* - `VALIDATION`: `edgeIndex` is out of range or not a nonnegative
|
|
1064
|
+
* integer; when the index is out of range, `details` include `edgeCount`.
|
|
1065
|
+
* - `PRECONDITION_FAILED`, with `details.reason` one of:
|
|
1066
|
+
* - `NO_BUILDABLE_ENVELOPE`: the site has no envelope to store edge
|
|
1067
|
+
* settings on. Ask the user whether to create a default envelope with
|
|
1068
|
+
* `design.create.buildableEnvelopeFromSite(siteId)` or to create one
|
|
1069
|
+
* themselves; do not create one unasked.
|
|
1070
|
+
* - `MASSING_ENVELOPE`: the site's envelope is a massing envelope. Tell
|
|
1071
|
+
* the user; change nothing.
|
|
1072
|
+
* - `ENVELOPE_TRANSFORMED`: the envelope has been rotated or scaled, so
|
|
1073
|
+
* edge editing is unavailable. Tell the user.
|
|
1074
|
+
* - `STALE_EDGE_SETTINGS`: the site outline changed since the edge
|
|
1075
|
+
* settings were made. Tell the user; editing any edge on the canvas
|
|
1076
|
+
* setback pills resets the edge settings to the new outline (dropping
|
|
1077
|
+
* the old ones), after which you can retry.
|
|
1078
|
+
*
|
|
1079
|
+
* @examplePrompt Make edge 2 the front
|
|
1080
|
+
* @examplePrompt Set just the north edge setback to 8 m
|
|
1081
|
+
* @examplePrompt Remove the custom setback on edge 3
|
|
1082
|
+
*
|
|
1083
|
+
* # Example
|
|
1084
|
+
* ```ts
|
|
1085
|
+
* const [{ siteId }] = (await snaptrude.program.site.listEdges()).sites
|
|
1086
|
+
* await snaptrude.design.update.siteEdge(siteId, 2, { role: "front" })
|
|
1087
|
+
* await snaptrude.design.update.siteEdge(siteId, 3, { setback: 8, lengthUnit: "m" })
|
|
1088
|
+
* await snaptrude.design.update.siteEdge(siteId, 3, { setback: null })
|
|
1089
|
+
* ```
|
|
1090
|
+
*/
|
|
1091
|
+
public abstract siteEdge(
|
|
1092
|
+
siteId: string,
|
|
1093
|
+
edgeIndex: number,
|
|
1094
|
+
patch: PluginSiteEdgePatch,
|
|
1095
|
+
): PluginApiReturn<PluginDesignUpdateSiteEdgeResult>
|
|
1096
|
+
}
|