@snaptrude/plugin-core 0.10.0 → 1.0.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.
- package/AGENTS.md +4 -0
- package/CHANGELOG.md +187 -3
- package/api-manifest.json +929 -25
- 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 +463 -0
- package/dist/api/core/camera/index.d.ts.map +1 -1
- package/dist/api/core/geom/create/index.d.ts +942 -101
- package/dist/api/core/geom/create/index.d.ts.map +1 -1
- package/dist/api/core/geom/query/brep.d.ts +59 -2
- package/dist/api/core/geom/query/brep.d.ts.map +1 -1
- package/dist/api/core/geom/query/curve.d.ts +59 -35
- package/dist/api/core/geom/query/curve.d.ts.map +1 -1
- package/dist/api/core/geom/query/edge.d.ts +2 -2
- package/dist/api/core/geom/query/face.d.ts +105 -0
- package/dist/api/core/geom/query/face.d.ts.map +1 -1
- package/dist/api/core/geom/update/contour.d.ts +10 -2
- package/dist/api/core/geom/update/contour.d.ts.map +1 -1
- package/dist/api/core/geom/update/curve.d.ts +5 -5
- package/dist/api/core/geom/update/profile.d.ts +3 -1
- package/dist/api/core/geom/update/profile.d.ts.map +1 -1
- package/dist/api/core/handles/index.d.ts +4 -2
- package/dist/api/core/handles/index.d.ts.map +1 -1
- package/dist/api/core/index.d.ts +4 -4
- package/dist/api/core/index.d.ts.map +1 -1
- package/dist/api/core/io/import/index.d.ts +3 -1
- package/dist/api/core/io/import/index.d.ts.map +1 -1
- package/dist/api/core/layers.d.ts +377 -255
- package/dist/api/core/layers.d.ts.map +1 -1
- package/dist/api/core/mode/index.d.ts +19 -7
- package/dist/api/core/mode/index.d.ts.map +1 -1
- package/dist/api/core/project/index.d.ts +68 -1
- package/dist/api/core/project/index.d.ts.map +1 -1
- package/dist/api/core/proposals/index.d.ts +4 -3
- package/dist/api/core/proposals/index.d.ts.map +1 -1
- package/dist/api/core/storeys/index.d.ts +31 -2
- package/dist/api/core/storeys/index.d.ts.map +1 -1
- package/dist/api/core/storeys/layers.d.ts +408 -0
- package/dist/api/core/storeys/layers.d.ts.map +1 -0
- package/dist/api/core/tags.d.ts +84 -3
- package/dist/api/core/tags.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 +269 -0
- package/dist/api/design/create/bulk-items.d.ts.map +1 -0
- package/dist/api/design/create/grids.d.ts +132 -0
- package/dist/api/design/create/grids.d.ts.map +1 -0
- package/dist/api/design/create/index.d.ts +752 -78
- package/dist/api/design/create/index.d.ts.map +1 -1
- package/dist/api/design/create/opening-fields.d.ts +38 -0
- package/dist/api/design/create/opening-fields.d.ts.map +1 -0
- package/dist/api/design/delete/index.d.ts +5 -0
- package/dist/api/design/delete/index.d.ts.map +1 -1
- package/dist/api/design/dimensions.d.ts +427 -0
- package/dist/api/design/dimensions.d.ts.map +1 -0
- package/dist/api/design/doors/index.d.ts +24 -23
- package/dist/api/design/doors/index.d.ts.map +1 -1
- package/dist/api/design/family.d.ts +1446 -0
- package/dist/api/design/family.d.ts.map +1 -0
- package/dist/api/design/furniture/index.d.ts +33 -0
- package/dist/api/design/furniture/index.d.ts.map +1 -1
- package/dist/api/design/grids.d.ts +237 -0
- package/dist/api/design/grids.d.ts.map +1 -0
- package/dist/api/design/index.d.ts +30 -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/geometry/index.d.ts +33 -5
- package/dist/api/design/query/geometry/index.d.ts.map +1 -1
- package/dist/api/design/query/grids.d.ts +287 -0
- package/dist/api/design/query/grids.d.ts.map +1 -0
- package/dist/api/design/query/index.d.ts +143 -34
- package/dist/api/design/query/index.d.ts.map +1 -1
- package/dist/api/design/query/spaces.d.ts +5 -5
- package/dist/api/design/selection/index.d.ts +12 -12
- 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 +412 -8
- package/dist/api/design/update/index.d.ts.map +1 -1
- package/dist/api/design/visibility.d.ts +28 -0
- package/dist/api/design/visibility.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/entity/referenceLine.d.ts +13 -1
- package/dist/api/entity/referenceLine.d.ts.map +1 -1
- package/dist/api/entity/space.d.ts +12 -12
- package/dist/api/entity/story.d.ts +4 -4
- package/dist/api/presentation/aiInspiration.d.ts +24 -24
- package/dist/api/presentation/annotate.d.ts +38 -22
- package/dist/api/presentation/annotate.d.ts.map +1 -1
- package/dist/api/presentation/camera.d.ts +265 -0
- package/dist/api/presentation/camera.d.ts.map +1 -0
- 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/graphics.d.ts +419 -0
- package/dist/api/presentation/graphics.d.ts.map +1 -0
- package/dist/api/presentation/index.d.ts +66 -12
- package/dist/api/presentation/index.d.ts.map +1 -1
- package/dist/api/presentation/placedViews.d.ts +116 -16
- 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/standards.d.ts +590 -0
- package/dist/api/presentation/standards.d.ts.map +1 -0
- 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 +144 -9
- package/dist/api/presentation/views.d.ts.map +1 -1
- package/dist/api/presentation/walkthroughs.d.ts +1350 -0
- package/dist/api/presentation/walkthroughs.d.ts.map +1 -0
- package/dist/api/program/departments.d.ts +58 -2
- package/dist/api/program/departments.d.ts.map +1 -1
- package/dist/api/program/index.d.ts +16 -6
- package/dist/api/program/index.d.ts.map +1 -1
- package/dist/api/program/labels.d.ts +355 -0
- package/dist/api/program/labels.d.ts.map +1 -0
- package/dist/api/program/metadata.d.ts +328 -0
- package/dist/api/program/metadata.d.ts.map +1 -0
- package/dist/api/program/site.d.ts +4 -4
- package/dist/api/program/spreadsheet.d.ts +267 -4
- package/dist/api/program/spreadsheet.d.ts.map +1 -1
- package/dist/api/workspace/index.d.ts +49 -2
- package/dist/api/workspace/index.d.ts.map +1 -1
- package/dist/errors/codes.d.ts +3 -1
- package/dist/errors/codes.d.ts.map +1 -1
- package/dist/handles.d.ts +32 -3
- package/dist/handles.d.ts.map +1 -1
- package/dist/index.cjs +6539 -2804
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6121 -2801
- package/dist/index.js.map +1 -1
- package/dist/massParameters.d.ts +287 -0
- package/dist/massParameters.d.ts.map +1 -0
- package/dist/massParameters.ops.d.ts +138 -0
- package/dist/massParameters.ops.d.ts.map +1 -0
- package/package.json +14 -13
- package/scripts/check-dist-fresh.mjs +22 -0
- package/scripts/generate-manifest.mjs +5 -0
- package/scripts/generate-manifest.test.mjs +14 -3
- package/src/api/core/camera/index.ts +446 -1
- package/src/api/core/geom/create/index.ts +1037 -102
- package/src/api/core/geom/query/brep.ts +60 -2
- package/src/api/core/geom/query/curve.ts +26 -2
- package/src/api/core/geom/query/edge.ts +2 -2
- package/src/api/core/geom/query/face.ts +109 -4
- package/src/api/core/geom/update/contour.ts +10 -2
- package/src/api/core/geom/update/profile.ts +2 -0
- package/src/api/core/handles/index.ts +3 -2
- package/src/api/core/index.ts +4 -4
- package/src/api/core/io/import/index.ts +11 -3
- package/src/api/core/layers.ts +380 -173
- package/src/api/core/mode/index.ts +19 -7
- package/src/api/core/project/index.ts +62 -1
- package/src/api/core/proposals/index.ts +4 -3
- package/src/api/core/storeys/index.ts +34 -2
- package/src/api/core/storeys/layers.ts +339 -0
- package/src/api/core/tags.ts +76 -0
- package/src/api/core/zoom/index.ts +13 -0
- package/src/api/design/bim.ts +210 -0
- package/src/api/design/boolean/index.ts +2 -0
- package/src/api/design/catalog.ts +203 -0
- package/src/api/design/create/bulk-items.ts +294 -0
- package/src/api/design/create/grids.ts +137 -0
- package/src/api/design/create/index.ts +823 -114
- package/src/api/design/create/opening-fields.ts +40 -0
- package/src/api/design/delete/index.ts +5 -0
- package/src/api/design/dimensions.ts +453 -0
- package/src/api/design/doors/index.ts +64 -41
- package/src/api/design/family.ts +1342 -0
- package/src/api/design/furniture/index.ts +34 -0
- package/src/api/design/grids.ts +237 -0
- package/src/api/design/index.ts +49 -4
- package/src/api/design/networks.ts +607 -0
- package/src/api/design/query/geometry/index.ts +35 -4
- package/src/api/design/query/grids.ts +197 -0
- package/src/api/design/query/index.ts +105 -3
- package/src/api/design/types/index.ts +31 -24
- package/src/api/design/update/index.ts +398 -4
- package/src/api/design/visibility.ts +34 -0
- package/src/api/design/windows/index.ts +40 -22
- package/src/api/entity/buildableEnvelope.ts +77 -2
- package/src/api/entity/referenceLine.ts +25 -12
- package/src/api/presentation/annotate.ts +90 -58
- package/src/api/presentation/camera.ts +289 -0
- package/src/api/presentation/drawingContract.ts +70 -0
- package/src/api/presentation/drawings.ts +1179 -0
- package/src/api/presentation/export.ts +32 -6
- package/src/api/presentation/graphics.ts +324 -0
- package/src/api/presentation/index.ts +73 -14
- package/src/api/presentation/placedViews.ts +119 -28
- package/src/api/presentation/sections.ts +420 -0
- package/src/api/presentation/sheets.ts +181 -20
- package/src/api/presentation/standards.ts +445 -0
- package/src/api/presentation/viewPresets.ts +241 -0
- package/src/api/presentation/views.ts +81 -10
- package/src/api/presentation/walkthroughs.ts +1201 -0
- package/src/api/program/departments.ts +54 -2
- package/src/api/program/index.ts +16 -6
- package/src/api/program/labels.ts +332 -0
- package/src/api/program/metadata.ts +364 -0
- package/src/api/program/spreadsheet.ts +282 -0
- package/src/api/workspace/index.ts +51 -2
- package/src/errors/codes.ts +7 -0
- package/src/handles.ts +42 -3
- package/src/index.ts +2 -0
- package/src/massParameters.ops.ts +246 -0
- package/src/massParameters.ts +427 -0
- package/test/drawingContract.test.mjs +288 -0
- package/test/errors.test.mjs +1 -0
- package/test/massParameters.test.mjs +952 -0
- package/test/paperPensContract.test.mjs +75 -0
- package/test/presentationViewSettings.test.mjs +85 -0
|
@@ -4,9 +4,13 @@ import {
|
|
|
4
4
|
BrepHandle,
|
|
5
5
|
ComponentHandle,
|
|
6
6
|
ContourHandle,
|
|
7
|
+
LineHandle,
|
|
8
|
+
CurveHandle,
|
|
7
9
|
ProfileHandle,
|
|
8
10
|
Vec3Handle,
|
|
9
11
|
} from "../../../handles"
|
|
12
|
+
import { PluginGridStyleOptions } from "./grids"
|
|
13
|
+
import { PluginGraphicsLineStyleId } from "../../presentation/graphics"
|
|
10
14
|
import {
|
|
11
15
|
PluginSpaceType,
|
|
12
16
|
PluginMassType,
|
|
@@ -17,13 +21,33 @@ import {
|
|
|
17
21
|
PluginBuildableEnvelopeSetbackTier,
|
|
18
22
|
PluginBuildableEnvelopeVerticalCap,
|
|
19
23
|
PluginBuildableEnvelopeCreateResult,
|
|
24
|
+
PluginDesignCreateBuildableEnvelopeFromSiteResult,
|
|
20
25
|
} from "../../entity/buildableEnvelope"
|
|
26
|
+
import { PluginOpeningBaseOptions } from "./opening-fields"
|
|
27
|
+
import type {
|
|
28
|
+
PluginCreateDoorItem,
|
|
29
|
+
PluginCreateFloorItem,
|
|
30
|
+
PluginCreateFurnitureItem,
|
|
31
|
+
PluginCreateVoidItem,
|
|
32
|
+
PluginCreateWallRunItem,
|
|
33
|
+
PluginCreateWindowItem,
|
|
34
|
+
} from "./bulk-items"
|
|
35
|
+
import { PluginWallTopProfile } from "./bulk-items"
|
|
36
|
+
import { PluginWallType } from "../types"
|
|
37
|
+
import {
|
|
38
|
+
PluginFamilyPlacement,
|
|
39
|
+
PluginFamilyFloorOptions,
|
|
40
|
+
PluginFamilySlabOptions,
|
|
41
|
+
PluginFamilyCeilingOptions,
|
|
42
|
+
PluginFamilyValues,
|
|
43
|
+
} from "../catalog"
|
|
21
44
|
|
|
22
45
|
/**
|
|
23
46
|
* `design.create.*` — author new scene-committed BIM entities.
|
|
24
47
|
*
|
|
25
48
|
* Every creator takes geometry handles + scalars and returns a
|
|
26
|
-
* {@linkcode ComponentHandle} (or `ComponentHandle[]` for plural creators
|
|
49
|
+
* {@linkcode ComponentHandle} (or `ComponentHandle[]` for plural creators;
|
|
50
|
+
* `wallRuns` returns one `ComponentHandle[]` per run) — the
|
|
27
51
|
* `Component.id` of the created entity, resolvable across the rest of the
|
|
28
52
|
* `design.*` surface. Creation is an undoable host call; it **throws** on failure
|
|
29
53
|
* (no `Result` wrapper — consistent with `core.geom.create.*`).
|
|
@@ -31,9 +55,17 @@ import {
|
|
|
31
55
|
* Footprint objects take a {@linkcode ContourHandle} (outer profile + holes);
|
|
32
56
|
* build one with `snaptrude.core.geom.create.contourFromProfile(s)`.
|
|
33
57
|
*
|
|
34
|
-
*
|
|
58
|
+
* Family overloads take `{ type, values? }` from `design.catalog`. The family supplies
|
|
59
|
+
* construction; the contour or axis supplies instance geometry. Geometry uses SU,
|
|
60
|
+
* while family length overrides use mm and angles use degrees. Omitted parameters
|
|
61
|
+
* retain family defaults; shared/type, formula and geometry-bound overrides are refused.
|
|
62
|
+
* Placement never publishes a definition. Unsupported references or geometry fail before mutation.
|
|
63
|
+
*
|
|
64
|
+
* `door`/`window` place a parametric family into a host wall (the world point is
|
|
35
65
|
* projected onto the wall face to locate the opening; the wall is re-cut in one
|
|
36
|
-
* undo entry) and throw if the point projects outside the wall.
|
|
66
|
+
* undo entry) and throw if the point projects outside the wall. Voids
|
|
67
|
+
* (`void`/`voids`) are the third hosted child: holes through slabs, floors,
|
|
68
|
+
* roofs and ceilings. `smartLayout` is
|
|
37
69
|
* the one creator returning a grouped {@linkcode PluginSmartLayoutResult} rather
|
|
38
70
|
* than a handle — it clones an in-scene template into one or more target spaces,
|
|
39
71
|
* merging every target into a single undo batch (see its JSDoc).
|
|
@@ -186,6 +218,9 @@ export abstract class PluginDesignCreateApi {
|
|
|
186
218
|
* Create a **slab** by extruding a footprint contour by `thickness`
|
|
187
219
|
* (default direction: down).
|
|
188
220
|
*
|
|
221
|
+
* To cut a hole in an EXISTING one, use `design.create.void`; a contour hole
|
|
222
|
+
* here is baked into the footprint.
|
|
223
|
+
*
|
|
189
224
|
* @param contour - Footprint (outer + holes)
|
|
190
225
|
* @param thickness - Slab thickness (> 0)
|
|
191
226
|
* @param direction - Extrusion direction (default `"down"`)
|
|
@@ -207,20 +242,32 @@ export abstract class PluginDesignCreateApi {
|
|
|
207
242
|
* ```
|
|
208
243
|
*/
|
|
209
244
|
public abstract slab(
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
245
|
+
...args:
|
|
246
|
+
| [
|
|
247
|
+
contour: ContourHandle,
|
|
248
|
+
thickness: number,
|
|
249
|
+
direction?: "up" | "down",
|
|
250
|
+
slabType?: PluginSlabType,
|
|
251
|
+
]
|
|
252
|
+
| [contour: ContourHandle, options: PluginFamilySlabOptions]
|
|
214
253
|
): PluginApiReturn<ComponentHandle>
|
|
215
254
|
|
|
216
255
|
/**
|
|
217
256
|
* Create a **floor** by extruding a footprint contour by `thickness`
|
|
218
257
|
* (extruded upward).
|
|
219
258
|
*
|
|
259
|
+
* The native family overload takes `{ type, values?, position? }`. Contour
|
|
260
|
+
* geometry uses SU; family values use mm. The family supplies layer thickness.
|
|
261
|
+
* PG2 can split or merge the footprint, so both overloads return an array.
|
|
262
|
+
* A merge into an existing floor can return no newly created handles.
|
|
263
|
+
*
|
|
264
|
+
* To cut a hole in an EXISTING one, use `design.create.void`; a contour hole
|
|
265
|
+
* here is baked into the footprint.
|
|
266
|
+
*
|
|
220
267
|
* @param contour - Footprint (outer + holes)
|
|
221
268
|
* @param thickness - Floor thickness (> 0)
|
|
222
269
|
* @param position - Offset from origin
|
|
223
|
-
* @returns
|
|
270
|
+
* @returns Newly created {@linkcode ComponentHandle}s; an empty array after a merge
|
|
224
271
|
* @throws if the contour is invalid or the thickness is not positive
|
|
225
272
|
*
|
|
226
273
|
* @examplePrompt Create a floor from this room outline
|
|
@@ -234,17 +281,64 @@ export abstract class PluginDesignCreateApi {
|
|
|
234
281
|
* const contour = await snaptrude.core.geom.create.contourFromProfile(rect)
|
|
235
282
|
* const floor = await snaptrude.design.create.floor(contour, 0.1)
|
|
236
283
|
* ```
|
|
284
|
+
*
|
|
285
|
+
* @performance For dimensional floors, `design.create.floors(items[])` uses one
|
|
286
|
+
* host round-trip and one undo entry. That bulk method does not accept native
|
|
287
|
+
* family options; use this method for a family-backed floor.
|
|
237
288
|
*/
|
|
238
289
|
public abstract floor(
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
): PluginApiReturn<ComponentHandle>
|
|
290
|
+
...args:
|
|
291
|
+
| [contour: ContourHandle, thickness: number, position?: Vec3Handle]
|
|
292
|
+
| [contour: ContourHandle, options: PluginFamilyFloorOptions]
|
|
293
|
+
): PluginApiReturn<ComponentHandle[]>
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Create **many floors** in one undoable operation (bulk plural of
|
|
297
|
+
* {@linkcode floor}). Each item extrudes its own footprint contour (outer
|
|
298
|
+
* profile + holes) upward by its own `thickness`, at its own optional
|
|
299
|
+
* position offset. Validate-all-or-throw; one command.
|
|
300
|
+
*
|
|
301
|
+
* @param items - One {@linkcode PluginCreateFloorItem} per floor to create
|
|
302
|
+
* (≥1, ≤1000)
|
|
303
|
+
* @returns the created floors as {@linkcode ComponentHandle}`[]`, in input order
|
|
304
|
+
* @throws `VALIDATION` if the items fail the schema (empty array, more than
|
|
305
|
+
* 1000 items, a non-positive thickness) or a contour is degenerate;
|
|
306
|
+
* `HANDLE_INVALID` if a `contour` or `position` handle is unknown or
|
|
307
|
+
* released; `OPERATION_FAILED` if extrusion fails (nothing is created —
|
|
308
|
+
* `details.itemIndex` is the failing item); `METHOD_NOT_PERMITTED` if the
|
|
309
|
+
* plugin may not write.
|
|
310
|
+
*
|
|
311
|
+
* @examplePrompt Create floors for all these room outlines at once
|
|
312
|
+
* @examplePrompt Add a floor to every space in one operation
|
|
313
|
+
* @examplePrompt Bulk create the floor plates for this building
|
|
314
|
+
* @examplePrompt Lay 100mm floors across these five footprints in one undo step
|
|
315
|
+
* @examplePrompt Create the ground and first floor slabs together
|
|
316
|
+
*
|
|
317
|
+
* @performance Bulk creator — the whole batch is ONE host round-trip and ONE undo
|
|
318
|
+
* entry. Always prefer this over calling `design.create.floor` in a loop: build the
|
|
319
|
+
* full `items[]` array first (all contours and offsets up front), then make one call.
|
|
320
|
+
*
|
|
321
|
+
* # Example
|
|
322
|
+
* ```ts
|
|
323
|
+
* const rect = await snaptrude.core.geom.create.profileRect(5, 4)
|
|
324
|
+
* const contour = await snaptrude.core.geom.create.contourFromProfile(rect)
|
|
325
|
+
* const [ground, upper] = await snaptrude.design.create.floors([
|
|
326
|
+
* { contour, thickness: 0.1 },
|
|
327
|
+
* { contour, thickness: 0.1, position: await snaptrude.core.math.vec3.new(0, 3, 0) },
|
|
328
|
+
* ])
|
|
329
|
+
* ```
|
|
330
|
+
*/
|
|
331
|
+
public abstract floors(
|
|
332
|
+
items: PluginCreateFloorItem[],
|
|
333
|
+
): PluginApiReturn<ComponentHandle[]>
|
|
243
334
|
|
|
244
335
|
/**
|
|
245
336
|
* Create a **roof** by extruding a footprint contour by `thickness`. Created
|
|
246
337
|
* flat (extruded downward); pitch/slope is a separate post-creation edit.
|
|
247
338
|
*
|
|
339
|
+
* To cut a hole in an EXISTING one, use `design.create.void`; a contour hole
|
|
340
|
+
* here is baked into the footprint.
|
|
341
|
+
*
|
|
248
342
|
* @param contour - Footprint (outer + holes)
|
|
249
343
|
* @param thickness - Roof-slab thickness (> 0)
|
|
250
344
|
* @returns the {@linkcode ComponentHandle} of the created roof
|
|
@@ -264,13 +358,16 @@ export abstract class PluginDesignCreateApi {
|
|
|
264
358
|
*/
|
|
265
359
|
public abstract roof(
|
|
266
360
|
contour: ContourHandle,
|
|
267
|
-
thickness: number,
|
|
361
|
+
thickness: number | PluginFamilyPlacement,
|
|
268
362
|
): PluginApiReturn<ComponentHandle>
|
|
269
363
|
|
|
270
364
|
/**
|
|
271
365
|
* Create a **ceiling** by extruding a footprint contour by `thickness`, lifted
|
|
272
366
|
* `heightFromFloor` above the floor.
|
|
273
367
|
*
|
|
368
|
+
* To cut a hole in an EXISTING one, use `design.create.void`; a contour hole
|
|
369
|
+
* here is baked into the footprint.
|
|
370
|
+
*
|
|
274
371
|
* @param contour - Footprint (outer + holes)
|
|
275
372
|
* @param thickness - Ceiling thickness (> 0)
|
|
276
373
|
* @param heightFromFloor - Lift above the floor (default 0)
|
|
@@ -290,9 +387,9 @@ export abstract class PluginDesignCreateApi {
|
|
|
290
387
|
* ```
|
|
291
388
|
*/
|
|
292
389
|
public abstract ceiling(
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
390
|
+
...args:
|
|
391
|
+
| [contour: ContourHandle, thickness: number, heightFromFloor?: number]
|
|
392
|
+
| [contour: ContourHandle, options: PluginFamilyCeilingOptions]
|
|
296
393
|
): PluginApiReturn<ComponentHandle>
|
|
297
394
|
|
|
298
395
|
/**
|
|
@@ -323,10 +420,14 @@ export abstract class PluginDesignCreateApi {
|
|
|
323
420
|
* ```
|
|
324
421
|
*/
|
|
325
422
|
public abstract column(
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
423
|
+
...args:
|
|
424
|
+
| [
|
|
425
|
+
position: Vec3Handle,
|
|
426
|
+
crossSection: ContourHandle,
|
|
427
|
+
height: number,
|
|
428
|
+
directionUp?: Vec3Handle,
|
|
429
|
+
]
|
|
430
|
+
| [axis: LineHandle, options: PluginFamilyPlacement]
|
|
330
431
|
): PluginApiReturn<ComponentHandle>
|
|
331
432
|
|
|
332
433
|
/**
|
|
@@ -370,9 +471,9 @@ export abstract class PluginDesignCreateApi {
|
|
|
370
471
|
* ```
|
|
371
472
|
*/
|
|
372
473
|
public abstract beam(
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
474
|
+
...args:
|
|
475
|
+
| [section: ContourHandle, length: number, direction?: Vec3Handle]
|
|
476
|
+
| [axis: LineHandle, options: PluginFamilyPlacement]
|
|
376
477
|
): PluginApiReturn<ComponentHandle>
|
|
377
478
|
|
|
378
479
|
/**
|
|
@@ -383,21 +484,27 @@ export abstract class PluginDesignCreateApi {
|
|
|
383
484
|
* @param height - Wall height (default engine default)
|
|
384
485
|
* @param thickness - Wall thickness (default: the `wallType`'s total layer
|
|
385
486
|
* thickness when `wallType` is given, else the engine default)
|
|
386
|
-
* @param wallType -
|
|
387
|
-
*
|
|
388
|
-
*
|
|
389
|
-
*
|
|
390
|
-
*
|
|
391
|
-
* generic wall.
|
|
487
|
+
* @param wallType - Legacy label/`wall:` id, or the exact `nativeFamily`
|
|
488
|
+
* `{ id, version }` pin from `design.types.list("wall")`. Native pins are
|
|
489
|
+
* authorized on every use; selecting a family in Draw is not registration.
|
|
490
|
+
* Native pins support straight horizontal centerlines and flat tops only.
|
|
491
|
+
* Omit thickness for native pins; a conflicting explicit thickness rejects.
|
|
492
|
+
* Default: the engine's generic wall.
|
|
392
493
|
* @param storey - Target storey (integer: `1` ground, `2` first floor, `-1`
|
|
393
494
|
* basement — same convention as `design.create.space`). The walls are
|
|
394
495
|
* assigned to it and lifted to its base elevation, all inside the same
|
|
395
496
|
* single undo entry. The storey must already exist
|
|
396
497
|
* (`core.storeys.create` first). Default: geometry-derived — a profile
|
|
397
498
|
* drawn at y = 0 lands on storey 1; the ACTIVE storey is NOT consulted.
|
|
499
|
+
* @param topProfiles - Optional top edge per curve of `profile` (same order):
|
|
500
|
+
* a {@linkcode PluginWallTopProfile} makes that wall raked / gabled; `null`
|
|
501
|
+
* or a missing entry keeps it flat at `height`. Straight curves only. Such
|
|
502
|
+
* walls are non-parametric (see {@linkcode PluginWallTopProfile}).
|
|
398
503
|
* @returns a {@linkcode ComponentHandle}`[]` (one per wall), in profile order
|
|
399
504
|
* @throws if the profile is empty, `wallType` names no wall type in the
|
|
400
|
-
* project, `storey` does not exist,
|
|
505
|
+
* project, `storey` does not exist, `topProfiles` has more entries than the
|
|
506
|
+
* profile has curves or names an arc curve, a top profile drops to the wall
|
|
507
|
+
* base at a mitred corner, or wall creation fails
|
|
401
508
|
*
|
|
402
509
|
* @examplePrompt Draw walls along this centerline
|
|
403
510
|
* @examplePrompt Create 3m high, 200mm thick walls from these points
|
|
@@ -406,6 +513,9 @@ export abstract class PluginDesignCreateApi {
|
|
|
406
513
|
* @examplePrompt Add walls with mitred corners along the path
|
|
407
514
|
* @examplePrompt Draw brick walls with plaster along this outline
|
|
408
515
|
* @examplePrompt Build the perimeter in exposed concrete walls
|
|
516
|
+
* @examplePrompt Create a raked wall that slopes from 3m to 5m
|
|
517
|
+
* @examplePrompt Build a gable end wall with the ridge in the middle
|
|
518
|
+
* @examplePrompt Draw a wall with a sloped top edge
|
|
409
519
|
*
|
|
410
520
|
* # Example
|
|
411
521
|
* ```ts
|
|
@@ -421,16 +531,89 @@ export abstract class PluginDesignCreateApi {
|
|
|
421
531
|
* const brickWalls = await snaptrude.design.create.walls(
|
|
422
532
|
* centerlines, 3, undefined, brick.label,
|
|
423
533
|
* )
|
|
534
|
+
* // …a raked wall (3m at the start, 5m at the end) on a single centerline:
|
|
535
|
+
* const run = await snaptrude.core.geom.create.profileFromCurves([
|
|
536
|
+
* await snaptrude.core.geom.create.line(await v.new(0, 0, 10), await v.new(8, 0, 10)),
|
|
537
|
+
* ])
|
|
538
|
+
* const [raked] = await snaptrude.design.create.walls(run, undefined, 0.2, undefined, undefined, [
|
|
539
|
+
* [{ along: 0, height: 3 }, { along: 1, height: 5 }],
|
|
540
|
+
* ])
|
|
424
541
|
* ```
|
|
542
|
+
*
|
|
543
|
+
* @performance For MORE THAN ONE run, call `design.create.wallRuns(items[])` — one
|
|
544
|
+
* host round-trip and ONE undo entry for every run in the batch. Looping this
|
|
545
|
+
* single-run creator is N round-trips and N undo entries.
|
|
425
546
|
*/
|
|
426
547
|
public abstract walls(
|
|
427
548
|
profile: ProfileHandle,
|
|
428
549
|
height?: number,
|
|
429
550
|
thickness?: number,
|
|
430
|
-
wallType?:
|
|
551
|
+
wallType?: PluginWallType,
|
|
431
552
|
storey?: number,
|
|
553
|
+
topProfiles?: (PluginWallTopProfile | null)[],
|
|
554
|
+
values?: PluginFamilyValues,
|
|
432
555
|
): PluginApiReturn<ComponentHandle[]>
|
|
433
556
|
|
|
557
|
+
/**
|
|
558
|
+
* Create **many wall runs** in one undoable operation (bulk plural of
|
|
559
|
+
* {@linkcode walls}). Each item is one full run — a wall per curve in that
|
|
560
|
+
* item's profile chain, mitred at shared endpoints. Junctions resolve within a
|
|
561
|
+
* run, not between runs. Each item carries its own
|
|
562
|
+
* dimensions, `wallType` and `storey`, so a single call can build a whole
|
|
563
|
+
* floor plate or several storeys at once. Per-curve `topProfiles` make raked
|
|
564
|
+
* or gabled walls (see {@linkcode PluginWallTopProfile}). Validate-all-or-throw;
|
|
565
|
+
* one command.
|
|
566
|
+
*
|
|
567
|
+
* @param items - One {@linkcode PluginCreateWallRunItem} per run to create
|
|
568
|
+
* (≥1, ≤1000)
|
|
569
|
+
* @returns one {@linkcode ComponentHandle}`[]` per item, in input order —
|
|
570
|
+
* each inner array holding that run's walls in profile-curve order
|
|
571
|
+
* @throws `VALIDATION` if the items fail the schema (empty array, more than
|
|
572
|
+
* 1000 items, a non-positive height or thickness, a zero-length curve);
|
|
573
|
+
* `HANDLE_INVALID` if a `profile` handle is unknown or released;
|
|
574
|
+
* `PRECONDITION_FAILED` if a profile has no curves, `wallType` names no
|
|
575
|
+
* wall type in the project, or `storey` does not exist;
|
|
576
|
+
* `OPERATION_FAILED` if wall creation fails (nothing is created —
|
|
577
|
+
* `details.itemIndex` is the failing item); `METHOD_NOT_PERMITTED` if the
|
|
578
|
+
* plugin may not write.
|
|
579
|
+
*
|
|
580
|
+
* @examplePrompt Draw all the walls of this floor plan at once
|
|
581
|
+
* @examplePrompt Build every room's perimeter in one operation
|
|
582
|
+
* @examplePrompt Bulk create wall runs from these centerlines
|
|
583
|
+
* @examplePrompt Create the walls for both storeys in a single undo step
|
|
584
|
+
* @examplePrompt Turn these polylines into 200mm brick walls together
|
|
585
|
+
* @examplePrompt Import these raked walls with their top profiles in one go
|
|
586
|
+
*
|
|
587
|
+
* @performance Bulk creator — the whole batch is ONE host round-trip and ONE undo
|
|
588
|
+
* entry. Always prefer this over calling `design.create.walls` in a loop: build the
|
|
589
|
+
* full `items[]` array first (all profiles up front), then make one call.
|
|
590
|
+
*
|
|
591
|
+
* # Example
|
|
592
|
+
* ```ts
|
|
593
|
+
* const v = snaptrude.core.math.vec3
|
|
594
|
+
* const ground = await snaptrude.core.geom.create.profileFromLinePoints([
|
|
595
|
+
* await v.new(0, 0, 0),
|
|
596
|
+
* await v.new(8, 0, 0),
|
|
597
|
+
* await v.new(8, 0, 6),
|
|
598
|
+
* ])
|
|
599
|
+
* const upper = await snaptrude.core.geom.create.profileFromLinePoints([
|
|
600
|
+
* await v.new(0, 0, 0),
|
|
601
|
+
* await v.new(8, 0, 0),
|
|
602
|
+
* ])
|
|
603
|
+
* const [groundWalls, upperWalls] = await snaptrude.design.create.wallRuns([
|
|
604
|
+
* { profile: ground, height: 3, thickness: 0.2 },
|
|
605
|
+
* { profile: upper, height: 3, storey: 2 },
|
|
606
|
+
* // one gable wall: 3m at both ends, 5m ridge in the middle
|
|
607
|
+
* { profile: upper, thickness: 0.2, storey: 3,
|
|
608
|
+
* topProfiles: [[{ along: 0, height: 3 }, { along: 0.5, height: 5 }, { along: 1, height: 3 }]] },
|
|
609
|
+
* ])
|
|
610
|
+
* console.log(groundWalls.length, "walls on the ground floor")
|
|
611
|
+
* ```
|
|
612
|
+
*/
|
|
613
|
+
public abstract wallRuns(
|
|
614
|
+
items: PluginCreateWallRunItem[],
|
|
615
|
+
): PluginApiReturn<ComponentHandle[][]>
|
|
616
|
+
|
|
434
617
|
/**
|
|
435
618
|
* Create a **staircase** from a parametric preset, placed at a point.
|
|
436
619
|
*
|
|
@@ -481,8 +664,14 @@ export abstract class PluginDesignCreateApi {
|
|
|
481
664
|
* every created line.
|
|
482
665
|
*
|
|
483
666
|
* @param profile - Ordered curve chain (centerlines)
|
|
484
|
-
*
|
|
485
|
-
*
|
|
667
|
+
* Prefer `{ styleId: "wide" }`: the project style's pen/pattern and native
|
|
668
|
+
* legacy mirror are saved in the creation command, as one undo step. styleId
|
|
669
|
+
* requires Paper Pens; unstyled legacy creation works with the feature off.
|
|
670
|
+
* Do not mix options with trailing positional arguments, or styleId with
|
|
671
|
+
* legacy thickness/style. The old positional signature remains supported.
|
|
672
|
+
*
|
|
673
|
+
* @param colorOrOptions - Options, or legacy hex color `"#RRGGBB"`.
|
|
674
|
+
* @param thickness - Legacy line thickness (default 1)
|
|
486
675
|
* @param style - Line style (default `SOLID`)
|
|
487
676
|
* @param gridTag - Grid tag label (default `"A"`)
|
|
488
677
|
* @returns a {@linkcode ComponentHandle}`[]` (one per curve), in profile order
|
|
@@ -511,12 +700,140 @@ export abstract class PluginDesignCreateApi {
|
|
|
511
700
|
*/
|
|
512
701
|
public abstract referenceLines(
|
|
513
702
|
profile: ProfileHandle,
|
|
514
|
-
|
|
703
|
+
colorOrOptions?: string | PluginReferenceLineOptions,
|
|
515
704
|
thickness?: number,
|
|
516
705
|
style?: PluginReferenceLineStyle,
|
|
517
706
|
gridTag?: string,
|
|
518
707
|
): PluginApiReturn<ComponentHandle[]>
|
|
519
708
|
|
|
709
|
+
/**
|
|
710
|
+
* Create a free rectangular **structural grid** — one grid group with two
|
|
711
|
+
* perpendicular line families (`linesX` lines spaced `spacingX` apart, and
|
|
712
|
+
* `linesY` lines spaced `spacingY` apart) on the active storey. One undoable
|
|
713
|
+
* creation.
|
|
714
|
+
*
|
|
715
|
+
* Units: spacings in Snaptrude units; `angle` in degrees (CCW about +Y,
|
|
716
|
+
* default 0). Without `center` the grid is centred on the current viewport
|
|
717
|
+
* (the native tool's behavior) — pass `center` for deterministic placement.
|
|
718
|
+
*
|
|
719
|
+
* @param linesX - Line count of the first family (integer ≥ 1)
|
|
720
|
+
* @param linesY - Line count of the second family (integer ≥ 1)
|
|
721
|
+
* @param spacingX - First-family spacing (Snaptrude units, > 0)
|
|
722
|
+
* @param spacingY - Second-family spacing (Snaptrude units, > 0)
|
|
723
|
+
* @param options - `angle`, `center`, and {@linkcode PluginGridStyleOptions}
|
|
724
|
+
* @returns the created grid group's {@linkcode ComponentHandle}
|
|
725
|
+
*
|
|
726
|
+
* @examplePrompt Create a 5 by 8 structural grid with 6 metre spacing
|
|
727
|
+
* @examplePrompt Add a column grid rotated 30 degrees
|
|
728
|
+
* @examplePrompt Set up a structural grid at the site origin
|
|
729
|
+
*
|
|
730
|
+
* # Example
|
|
731
|
+
* ```ts
|
|
732
|
+
* const centre = await snaptrude.core.math.vec3.new(0, 0, 0)
|
|
733
|
+
* const grid = await snaptrude.design.create.grid(5, 8, 6, 6, { center: centre })
|
|
734
|
+
* ```
|
|
735
|
+
*/
|
|
736
|
+
public abstract grid(
|
|
737
|
+
linesX: number,
|
|
738
|
+
linesY: number,
|
|
739
|
+
spacingX: number,
|
|
740
|
+
spacingY: number,
|
|
741
|
+
options?: {
|
|
742
|
+
angle?: number
|
|
743
|
+
center?: Vec3Handle
|
|
744
|
+
} & PluginGridStyleOptions,
|
|
745
|
+
): PluginApiReturn<ComponentHandle>
|
|
746
|
+
|
|
747
|
+
/**
|
|
748
|
+
* Create a **structural grid from a single curve** — one grid group holding
|
|
749
|
+
* one wing with one line (the draw tool's output). The curve may be a line
|
|
750
|
+
* or an arc; circles are rejected with `VALIDATION`. Undoable.
|
|
751
|
+
*
|
|
752
|
+
* @param curve - The grid line's geometry ({@linkcode CurveHandle}, world space)
|
|
753
|
+
* @param options - `tag` (defaults to the draw tool's next tag) and
|
|
754
|
+
* {@linkcode PluginGridStyleOptions}
|
|
755
|
+
* @returns the created grid group's {@linkcode ComponentHandle}
|
|
756
|
+
*
|
|
757
|
+
* @examplePrompt Draw a grid line from A to B
|
|
758
|
+
* @examplePrompt Add a curved grid line through these points
|
|
759
|
+
* @examplePrompt Create grid line "C" along this wall
|
|
760
|
+
*
|
|
761
|
+
* # Example
|
|
762
|
+
* ```ts
|
|
763
|
+
* const { vec3 } = snaptrude.core.math
|
|
764
|
+
* const from = await vec3.new(0, 0, 0)
|
|
765
|
+
* const to = await vec3.new(30, 0, 0)
|
|
766
|
+
* const curve = await snaptrude.core.geom.create.line(from, to)
|
|
767
|
+
* const grid = await snaptrude.design.create.gridFromCurve(curve, { tag: "A" })
|
|
768
|
+
* ```
|
|
769
|
+
*/
|
|
770
|
+
public abstract gridFromCurve(
|
|
771
|
+
curve: CurveHandle,
|
|
772
|
+
options?: {
|
|
773
|
+
tag?: string
|
|
774
|
+
} & PluginGridStyleOptions,
|
|
775
|
+
): PluginApiReturn<ComponentHandle>
|
|
776
|
+
|
|
777
|
+
/**
|
|
778
|
+
* Generate **structural grids fitted to mass footprints** — one grid group
|
|
779
|
+
* per footprint cluster, with counts and orientation derived from each
|
|
780
|
+
* footprint's geometry and the given spacings. All created groups commit as
|
|
781
|
+
* ONE undoable unit.
|
|
782
|
+
*
|
|
783
|
+
* Lenient like the native tool: masses without an extractable footprint
|
|
784
|
+
* (no B-rep, degenerate top face) are skipped; throws `VALIDATION` only when
|
|
785
|
+
* NONE of the given masses yields a footprint.
|
|
786
|
+
*
|
|
787
|
+
* @param masses - Masses whose footprints seat the grids
|
|
788
|
+
* @param spacingX - First-family spacing (Snaptrude units, > 0)
|
|
789
|
+
* @param spacingY - Second-family spacing (Snaptrude units, > 0)
|
|
790
|
+
* @param options - {@linkcode PluginGridStyleOptions}
|
|
791
|
+
* @returns the created grid groups' {@linkcode ComponentHandle}`[]`
|
|
792
|
+
*
|
|
793
|
+
* @examplePrompt Generate grids for the selected masses
|
|
794
|
+
* @examplePrompt Auto-generate a 6m structural grid on this building
|
|
795
|
+
* @examplePrompt Fit column grids to every mass on this storey
|
|
796
|
+
*
|
|
797
|
+
* # Example
|
|
798
|
+
* ```ts
|
|
799
|
+
* const masses = await snaptrude.design.query.listMasses({ storeys: [1] })
|
|
800
|
+
* const grids = await snaptrude.design.create.gridsFromMasses(masses, 6, 6)
|
|
801
|
+
* ```
|
|
802
|
+
*/
|
|
803
|
+
public abstract gridsFromMasses(
|
|
804
|
+
masses: ComponentHandle[],
|
|
805
|
+
spacingX: number,
|
|
806
|
+
spacingY: number,
|
|
807
|
+
options?: PluginGridStyleOptions,
|
|
808
|
+
): PluginApiReturn<ComponentHandle[]>
|
|
809
|
+
|
|
810
|
+
/**
|
|
811
|
+
* Create **columns at every grid-line intersection** of the given grid
|
|
812
|
+
* groups, sized `width` × `depth` and oriented to the grid axes, on the
|
|
813
|
+
* grids' storey. All columns commit as ONE undoable unit.
|
|
814
|
+
*
|
|
815
|
+
* @param grids - Grid groups whose intersections seat the columns
|
|
816
|
+
* @param width - Column width (Snaptrude units, > 0)
|
|
817
|
+
* @param depth - Column depth (Snaptrude units, > 0)
|
|
818
|
+
* @returns the created columns' {@linkcode ComponentHandle}`[]`
|
|
819
|
+
* @throws `VALIDATION` when an id does not resolve to a grid group;
|
|
820
|
+
* `OPERATION_FAILED` when the grids have no line intersections
|
|
821
|
+
*
|
|
822
|
+
* @examplePrompt Generate columns on this grid
|
|
823
|
+
* @examplePrompt Place 450mm square columns at every grid intersection
|
|
824
|
+
*
|
|
825
|
+
* # Example
|
|
826
|
+
* ```ts
|
|
827
|
+
* const grids = await snaptrude.design.query.listGrids()
|
|
828
|
+
* const columns = await snaptrude.design.create.columnsFromGrids(grids, 0.45, 0.45)
|
|
829
|
+
* ```
|
|
830
|
+
*/
|
|
831
|
+
public abstract columnsFromGrids(
|
|
832
|
+
grids: ComponentHandle[],
|
|
833
|
+
width: number,
|
|
834
|
+
depth: number,
|
|
835
|
+
): PluginApiReturn<ComponentHandle[]>
|
|
836
|
+
|
|
520
837
|
/**
|
|
521
838
|
* Place a **furniture** item from the project library at a world position.
|
|
522
839
|
*
|
|
@@ -535,15 +852,19 @@ export abstract class PluginDesignCreateApi {
|
|
|
535
852
|
* `position.y` (the same surface-flush contract as interactive drag-drop) —
|
|
536
853
|
* pass the floor/storey elevation to stand furniture on it; never add half
|
|
537
854
|
* the item's height yourself.
|
|
538
|
-
* @param options - Optional placement options: `label` — instance name
|
|
539
|
-
* (default auto `${name}Ins${n}`);
|
|
540
|
-
*
|
|
855
|
+
* @param options - Optional placement options: `label` — instance name and
|
|
856
|
+
* readable label (`design.query.getLabel`; default auto `${name}Ins${n}`);
|
|
857
|
+
* `createNewSourceMesh` — legacy flag, kept for compatibility. The host owns
|
|
858
|
+
* source-mesh persistence: a catalog source is recorded exactly once, by the
|
|
859
|
+
* first placement that brings it in, and this flag cannot skip that record.
|
|
541
860
|
* @param angleInDegrees - Optional signed rotation about the vertical axis, in
|
|
542
861
|
* degrees (same convention as {@linkcode PluginDesignTransformApi.rotate}).
|
|
543
862
|
* Applied at creation time so it is part of the placement's single undo entry.
|
|
544
863
|
* Default: the item's own (unrotated) orientation.
|
|
545
864
|
* @returns the {@linkcode ComponentHandle} of the placed furniture instance
|
|
546
|
-
* @throws if the catalog id is unknown, the source mesh fails to load, or placement fails
|
|
865
|
+
* @throws if the catalog id is unknown, the source mesh fails to load, or placement fails;
|
|
866
|
+
* `PRECONDITION_FAILED` (`details.engineCode: "TOOL_ACTIVE"`) while the interactive
|
|
867
|
+
* furniture tool is active — finish or cancel it first
|
|
547
868
|
*
|
|
548
869
|
* @examplePrompt Place a chair from the library at this spot
|
|
549
870
|
* @examplePrompt Add a sofa from the furniture catalog to the living room
|
|
@@ -567,6 +888,10 @@ export abstract class PluginDesignCreateApi {
|
|
|
567
888
|
* 90,
|
|
568
889
|
* )
|
|
569
890
|
* ```
|
|
891
|
+
*
|
|
892
|
+
* @performance For MORE THAN ONE item, call `design.create.furnitureItems(items[])` —
|
|
893
|
+
* one host round-trip and ONE undo entry, and a catalog source shared by several
|
|
894
|
+
* items is fetched once. Looping this single-item creator is N round-trips.
|
|
570
895
|
*/
|
|
571
896
|
public abstract furniture(
|
|
572
897
|
catalogId: string,
|
|
@@ -576,27 +901,69 @@ export abstract class PluginDesignCreateApi {
|
|
|
576
901
|
): PluginApiReturn<ComponentHandle>
|
|
577
902
|
|
|
578
903
|
/**
|
|
579
|
-
* Place
|
|
904
|
+
* Place **many furniture items** in one undoable operation (bulk plural of
|
|
905
|
+
* {@linkcode furniture}). Each item names a catalog id and an absolute world
|
|
906
|
+
* position (`position.y` is the REST elevation — the same grounding contract
|
|
907
|
+
* as the singular creator), with optional label and rotation. A catalog
|
|
908
|
+
* source shared by several items is fetched and recorded once for the whole
|
|
909
|
+
* batch, so the host — not the caller — owns source persistence (there is no
|
|
910
|
+
* per-item `createNewSourceMesh`). Validate-all-or-throw; one command.
|
|
911
|
+
*
|
|
912
|
+
* @param items - One {@linkcode PluginCreateFurnitureItem} per instance to
|
|
913
|
+
* place (≥1, ≤1000)
|
|
914
|
+
* @returns the placed instances as {@linkcode ComponentHandle}`[]`, in input order
|
|
915
|
+
* @throws `VALIDATION` if the items fail the schema (empty array, more than
|
|
916
|
+
* 1000 items); `HANDLE_INVALID` if a `position` handle is unknown or
|
|
917
|
+
* released; `PRECONDITION_FAILED` if a catalog id is unknown, a furniture
|
|
918
|
+
* tool is active, or a parametric group is active (exit it first, or place
|
|
919
|
+
* items one at a time with `furniture`); `OPERATION_FAILED` if a source
|
|
920
|
+
* mesh fails to load or placement fails (nothing is created —
|
|
921
|
+
* `details.itemIndex` is the failing item); `METHOD_NOT_PERMITTED` if the plugin may not write.
|
|
922
|
+
*
|
|
923
|
+
* @examplePrompt Place all the desks for this office at once
|
|
924
|
+
* @examplePrompt Furnish every bedroom in one operation
|
|
925
|
+
* @examplePrompt Bulk place these chairs around the table
|
|
926
|
+
* @examplePrompt Add the whole furniture layout in a single undo step
|
|
927
|
+
* @examplePrompt Drop twenty copies of this chair at these positions
|
|
928
|
+
*
|
|
929
|
+
* @performance Bulk creator — the whole batch is ONE host round-trip and ONE undo
|
|
930
|
+
* entry, and each distinct catalog source loads once. Always prefer this over
|
|
931
|
+
* calling `design.create.furniture` in a loop: build the full `items[]` array
|
|
932
|
+
* first (all positions and angles up front), then make one call.
|
|
933
|
+
*
|
|
934
|
+
* # Example
|
|
935
|
+
* ```ts
|
|
936
|
+
* const v = snaptrude.core.math.vec3
|
|
937
|
+
* const [chair] = await snaptrude.design.furniture.listCatalog()
|
|
938
|
+
* const placed = await snaptrude.design.create.furnitureItems([
|
|
939
|
+
* { catalogId: chair.id, position: await v.new(3, 0, 5), label: "Chair-01" },
|
|
940
|
+
* { catalogId: chair.id, position: await v.new(4, 0, 5), angleInDegrees: 90 },
|
|
941
|
+
* { catalogId: chair.id, position: await v.new(5, 0, 5), angleInDegrees: 180 },
|
|
942
|
+
* ])
|
|
943
|
+
* ```
|
|
944
|
+
*/
|
|
945
|
+
public abstract furnitureItems(
|
|
946
|
+
items: PluginCreateFurnitureItem[],
|
|
947
|
+
): PluginApiReturn<ComponentHandle[]>
|
|
948
|
+
|
|
949
|
+
/**
|
|
950
|
+
* Place a parametric **door** family into a host wall.
|
|
580
951
|
*
|
|
581
|
-
* Identified by a **
|
|
582
|
-
* or the general library's `fullName`. Discover ids with
|
|
952
|
+
* Identified by a saved **family definition id**. Discover ids with
|
|
583
953
|
* {@linkcode PluginDesignDoorsApi.listCatalog}. The world `position` is
|
|
584
954
|
* projected onto the host wall's face to locate the opening; the wall is
|
|
585
955
|
* re-cut and the door hosted in a single undo entry. Placement is
|
|
586
|
-
* asynchronous
|
|
956
|
+
* asynchronous. Values and host bindings are evaluated before the first cut.
|
|
587
957
|
*
|
|
588
|
-
* @param
|
|
958
|
+
* @param familyId - Hosted door definition ID; legacy mesh catalog IDs are not accepted
|
|
589
959
|
* @param hostWall - The wall to host the door
|
|
590
960
|
* @param position - World point projected onto the wall to locate the opening
|
|
591
|
-
* @param options -
|
|
592
|
-
*
|
|
593
|
-
*
|
|
594
|
-
*
|
|
595
|
-
* on that side works (e.g. the room's center). Default: the engine picks a
|
|
596
|
-
* side (nondeterministic when `position` sits on the wall centerline).
|
|
961
|
+
* @param options - `version` pins the definition. `values` sets authored parameters
|
|
962
|
+
* (numeric lengths in SU, or unit strings). `label` names the instance.
|
|
963
|
+
* `hinge` selects the declared `hand` enum: local -X is left, +X is right.
|
|
964
|
+
* @param facing - World point selecting local +Z; omitted uses the picked face
|
|
597
965
|
* @returns the {@linkcode ComponentHandle} of the placed door
|
|
598
|
-
* @throws if the
|
|
599
|
-
* mesh fails to load, or the projected point falls **outside** the host wall
|
|
966
|
+
* @throws if the family/category/parameters are invalid, or placement or cutting fails
|
|
600
967
|
*
|
|
601
968
|
* @examplePrompt Add a door to this wall here
|
|
602
969
|
* @examplePrompt Place a sliding door on the selected wall
|
|
@@ -604,6 +971,7 @@ export abstract class PluginDesignCreateApi {
|
|
|
604
971
|
* @examplePrompt Insert the entrance door into this wall
|
|
605
972
|
* @examplePrompt Add a door to the wall and call it Entry-01
|
|
606
973
|
* @examplePrompt Add a door that opens into the living room
|
|
974
|
+
* @examplePrompt Put a door here hinged on the north jamb
|
|
607
975
|
*
|
|
608
976
|
* # Example
|
|
609
977
|
* ```ts
|
|
@@ -623,37 +991,100 @@ export abstract class PluginDesignCreateApi {
|
|
|
623
991
|
* undefined,
|
|
624
992
|
* await snaptrude.core.math.vec3.new(3, 0, 9),
|
|
625
993
|
* )
|
|
994
|
+
* // …and hinged on the jamb nearest a point (here the +x end of the opening):
|
|
995
|
+
* const hingedRight = await snaptrude.design.create.door(
|
|
996
|
+
* entry.id,
|
|
997
|
+
* wall,
|
|
998
|
+
* await snaptrude.core.math.vec3.new(3, 0, 5),
|
|
999
|
+
* { hinge: await snaptrude.core.math.vec3.new(3.5, 0, 5) },
|
|
1000
|
+
* await snaptrude.core.math.vec3.new(3, 0, 9),
|
|
1001
|
+
* )
|
|
626
1002
|
* ```
|
|
1003
|
+
*
|
|
1004
|
+
* @performance For MORE THAN ONE door, call `design.create.doors(items[])` — one host
|
|
1005
|
+
* round-trip and ONE undo entry, with each host wall re-cut once per opening inside
|
|
1006
|
+
* that single call. Looping this single-door creator is N round-trips.
|
|
627
1007
|
*/
|
|
628
1008
|
public abstract door(
|
|
629
|
-
|
|
1009
|
+
familyId: string,
|
|
630
1010
|
hostWall: ComponentHandle,
|
|
631
1011
|
position: Vec3Handle,
|
|
632
|
-
options?: {
|
|
1012
|
+
options?: {
|
|
1013
|
+
label?: string
|
|
1014
|
+
hinge?: Vec3Handle
|
|
1015
|
+
version?: number
|
|
1016
|
+
values?: Record<string, number | string>
|
|
1017
|
+
},
|
|
633
1018
|
facing?: Vec3Handle,
|
|
634
1019
|
): PluginApiReturn<ComponentHandle>
|
|
635
1020
|
|
|
636
1021
|
/**
|
|
637
|
-
* Place
|
|
1022
|
+
* Place **many doors** into host walls in one undoable operation (bulk plural
|
|
1023
|
+
* of {@linkcode door}). Each item carries its own family id, host wall,
|
|
1024
|
+
* world position, and optional `facing`, `label`, `width` and `height` — the
|
|
1025
|
+
* same fields as a `"door"` {@linkcode PluginDesignCreateOpeningOptions}.
|
|
1026
|
+
* Validate-all-or-throw; one command.
|
|
1027
|
+
*
|
|
1028
|
+
* The wall keeps its identity. Several items may use the same host.
|
|
1029
|
+
* Width and height set named recipe parameters, not mesh scale. The recipe's
|
|
1030
|
+
* evaluated hole can include frame allowances. A failed item rolls back the batch.
|
|
1031
|
+
*
|
|
1032
|
+
* @param items - One {@linkcode PluginCreateDoorItem} per door to place
|
|
1033
|
+
* (≥1, ≤1000)
|
|
1034
|
+
* @returns the placed doors as {@linkcode ComponentHandle}`[]`, in input order
|
|
1035
|
+
* @throws `VALIDATION` if the items fail the schema (empty array, more than
|
|
1036
|
+
* 1000 items, unknown fields, a non-positive `width`/`height`);
|
|
1037
|
+
* `HANDLE_INVALID` if a `position`, `facing` or `hinge` handle is unknown
|
|
1038
|
+
* or released; `PRECONDITION_FAILED` if the family cannot be resolved or saved,
|
|
1039
|
+
* or a host is locked / is not in the active proposal;
|
|
1040
|
+
* `OPERATION_FAILED` if placement, containment, overlap checks or cutting fail
|
|
1041
|
+
* (nothing is created — `details.itemIndex` is the failing item);
|
|
1042
|
+
* `METHOD_NOT_PERMITTED` if the plugin may not write.
|
|
1043
|
+
*
|
|
1044
|
+
* @examplePrompt Add doors to all of these walls at once
|
|
1045
|
+
* @examplePrompt Place a door in every room in one operation
|
|
1046
|
+
* @examplePrompt Bulk add the entrance doors from this schedule
|
|
1047
|
+
* @examplePrompt Put three doors on this wall in a single undo step
|
|
1048
|
+
* @examplePrompt Add all the doors for this floor plan together
|
|
1049
|
+
*
|
|
1050
|
+
* @performance Bulk creator — the whole batch is ONE host round-trip and ONE undo
|
|
1051
|
+
* entry. Always prefer this over
|
|
1052
|
+
* calling `design.create.door` in a loop: build the full `items[]` array first
|
|
1053
|
+
* (all host walls and points up front), then make one call.
|
|
638
1054
|
*
|
|
639
|
-
*
|
|
640
|
-
*
|
|
1055
|
+
* # Example
|
|
1056
|
+
* ```ts
|
|
1057
|
+
* const v = snaptrude.core.math.vec3
|
|
1058
|
+
* const [wall] = await snaptrude.design.query.listWalls({ isSelected: true })
|
|
1059
|
+
* const [entry] = await snaptrude.design.doors.listCatalog()
|
|
1060
|
+
* const [front, side] = await snaptrude.design.create.doors([
|
|
1061
|
+
* { familyId: entry.id, hostWall: wall, position: await v.new(2, 0, 5), label: "D-01" },
|
|
1062
|
+
* { familyId: entry.id, hostWall: wall, position: await v.new(6, 0, 5), values: { width: "1200mm" } },
|
|
1063
|
+
* ])
|
|
1064
|
+
* // The host still resolves after both cuts:
|
|
1065
|
+
* const currentWall = await snaptrude.design.query.getHost(front)
|
|
1066
|
+
* ```
|
|
1067
|
+
*/
|
|
1068
|
+
public abstract doors(
|
|
1069
|
+
items: PluginCreateDoorItem[],
|
|
1070
|
+
): PluginApiReturn<ComponentHandle[]>
|
|
1071
|
+
|
|
1072
|
+
/**
|
|
1073
|
+
* Place a parametric **window** family into a host wall.
|
|
1074
|
+
*
|
|
1075
|
+
* Identified by a saved **family definition id**. Discover ids with
|
|
641
1076
|
* {@linkcode PluginDesignWindowsApi.listCatalog}. The world `position` is
|
|
642
1077
|
* projected onto the host wall's face to locate the opening; the wall is
|
|
643
1078
|
* re-cut and the window hosted in a single undo entry. Placement is
|
|
644
|
-
* asynchronous
|
|
1079
|
+
* asynchronous. The sill parameter determines elevation; position Y is ignored.
|
|
645
1080
|
*
|
|
646
|
-
* @param
|
|
1081
|
+
* @param familyId - Hosted window definition ID; legacy mesh catalog IDs are not accepted
|
|
647
1082
|
* @param hostWall - The wall to host the window
|
|
648
1083
|
* @param position - World point projected onto the wall to locate the opening
|
|
649
|
-
* @param options -
|
|
650
|
-
* @param facing - World point selecting
|
|
651
|
-
* faces (matters for asymmetric windows, e.g. casement swing) — same
|
|
652
|
-
* convention as {@linkcode PluginDesignCreateApi.door}. Default: the engine
|
|
653
|
-
* picks a side (nondeterministic when `position` sits on the centerline).
|
|
1084
|
+
* @param options - `version`, `values`, `label`, and parameter-driven `hinge`, as for door
|
|
1085
|
+
* @param facing - World point selecting local +Z; omitted uses the picked face
|
|
654
1086
|
* @returns the {@linkcode ComponentHandle} of the placed window
|
|
655
|
-
* @throws if the
|
|
656
|
-
* mesh fails to load, or the projected point falls **outside** the host wall
|
|
1087
|
+
* @throws if the family/category/parameters are invalid, or placement or cutting fails
|
|
657
1088
|
*
|
|
658
1089
|
* @examplePrompt Add a window to this wall here
|
|
659
1090
|
* @examplePrompt Place a casement window on the selected wall
|
|
@@ -673,40 +1104,244 @@ export abstract class PluginDesignCreateApi {
|
|
|
673
1104
|
* { label: "Win-01" },
|
|
674
1105
|
* )
|
|
675
1106
|
* ```
|
|
1107
|
+
*
|
|
1108
|
+
* @performance For MORE THAN ONE window, call `design.create.windows(items[])` — one
|
|
1109
|
+
* host round-trip and ONE undo entry, with each host wall re-cut once per opening
|
|
1110
|
+
* inside that single call. Looping this single-window creator is N round-trips.
|
|
676
1111
|
*/
|
|
677
1112
|
public abstract window(
|
|
678
|
-
|
|
1113
|
+
familyId: string,
|
|
679
1114
|
hostWall: ComponentHandle,
|
|
680
1115
|
position: Vec3Handle,
|
|
681
|
-
options?: {
|
|
1116
|
+
options?: {
|
|
1117
|
+
label?: string
|
|
1118
|
+
hinge?: Vec3Handle
|
|
1119
|
+
version?: number
|
|
1120
|
+
values?: Record<string, number | string>
|
|
1121
|
+
},
|
|
682
1122
|
facing?: Vec3Handle,
|
|
683
1123
|
): PluginApiReturn<ComponentHandle>
|
|
684
1124
|
|
|
685
1125
|
/**
|
|
686
|
-
* Place
|
|
1126
|
+
* Place **many windows** into host walls in one undoable operation (bulk
|
|
1127
|
+
* plural of {@linkcode window}). Each item carries its own family id, host
|
|
1128
|
+
* wall, world position, and optional `facing`, `label`, `width`, `height` and
|
|
1129
|
+
* `sillHeight` — the same fields as a `"window"`
|
|
1130
|
+
* {@linkcode PluginDesignCreateOpeningOptions}. `sillHeight` is measured from
|
|
1131
|
+
* the host wall base to the BOTTOM of the window. Validate-all-or-throw; one
|
|
1132
|
+
* command.
|
|
1133
|
+
*
|
|
1134
|
+
* Hosts keep their identity. Width, height and sillHeight set the declared
|
|
1135
|
+
* width, height and sill parameters before the first cut. No mesh scaling occurs.
|
|
1136
|
+
*
|
|
1137
|
+
* @param items - One {@linkcode PluginCreateWindowItem} per window to place
|
|
1138
|
+
* (≥1, ≤1000)
|
|
1139
|
+
* @returns the placed windows as {@linkcode ComponentHandle}`[]`, in input order
|
|
1140
|
+
* @throws `VALIDATION` if the items fail the schema (empty array, more than
|
|
1141
|
+
* 1000 items, unknown fields, a non-positive `width`/`height`, a negative
|
|
1142
|
+
* `sillHeight`); `HANDLE_INVALID` if a `position`, `facing` or `hinge`
|
|
1143
|
+
* handle is unknown or released; `PRECONDITION_FAILED` if the family cannot be
|
|
1144
|
+
* resolved or saved, or a host is locked / is not in the active proposal;
|
|
1145
|
+
* `OPERATION_FAILED` if placement, containment, overlap checks or cutting fail
|
|
1146
|
+
* (nothing is created — `details.itemIndex` is the failing item);
|
|
1147
|
+
* `METHOD_NOT_PERMITTED` if the plugin may not write.
|
|
1148
|
+
*
|
|
1149
|
+
* @examplePrompt Add windows along this whole facade at once
|
|
1150
|
+
* @examplePrompt Place a window in every bedroom in one operation
|
|
1151
|
+
* @examplePrompt Bulk add the windows from this schedule
|
|
1152
|
+
* @examplePrompt Put four windows on this wall in a single undo step
|
|
1153
|
+
* @examplePrompt Add all the windows with a 0.9m sill height together
|
|
1154
|
+
*
|
|
1155
|
+
* @performance Bulk creator — the whole batch is ONE host round-trip and ONE undo
|
|
1156
|
+
* entry. Always prefer this over
|
|
1157
|
+
* calling `design.create.window` in a loop: build the full `items[]` array first
|
|
1158
|
+
* (all host walls and points up front), then make one call.
|
|
1159
|
+
*
|
|
1160
|
+
* # Example
|
|
1161
|
+
* ```ts
|
|
1162
|
+
* const v = snaptrude.core.math.vec3
|
|
1163
|
+
* const [wall] = await snaptrude.design.query.listWalls({ isSelected: true })
|
|
1164
|
+
* const [casement] = await snaptrude.design.windows.listCatalog()
|
|
1165
|
+
* const placed = await snaptrude.design.create.windows([
|
|
1166
|
+
* { familyId: casement.id, hostWall: wall, position: await v.new(2, 0, 5), values: { sill: "900mm" } },
|
|
1167
|
+
* { familyId: casement.id, hostWall: wall, position: await v.new(5, 0, 5), values: { sill: "900mm" } },
|
|
1168
|
+
* ])
|
|
1169
|
+
* const currentWall = await snaptrude.design.query.getHost(placed[0])
|
|
1170
|
+
* ```
|
|
1171
|
+
*/
|
|
1172
|
+
public abstract windows(
|
|
1173
|
+
items: PluginCreateWindowItem[],
|
|
1174
|
+
): PluginApiReturn<ComponentHandle[]>
|
|
1175
|
+
|
|
1176
|
+
/**
|
|
1177
|
+
* Cut a **void** — a hole, opening or shaft — through an existing FLAT slab,
|
|
1178
|
+
* floor, roof or ceiling. The void is a selectable child object of its host
|
|
1179
|
+
* (the "Void" of the Draw Void tool). It always cuts the full host thickness.
|
|
1180
|
+
* It can be moved with `design.transform.move` (a move that would leave the
|
|
1181
|
+
* host is shortened without a report) and removed with
|
|
1182
|
+
* `design.delete.entities`; to resize, delete it and cut a new one
|
|
1183
|
+
* (`design.update.space` refuses a void).
|
|
1184
|
+
*
|
|
1185
|
+
* Give the outline **in plan** (all points at one height): its height is
|
|
1186
|
+
* ignored, and it is dropped straight onto the host's top face, so one outline
|
|
1187
|
+
* works on every storey. Keep it at least 25.4 mm (0.1 SU) inside the host
|
|
1188
|
+
* edge and away from other voids; merge overlapping holes into one outline.
|
|
1189
|
+
* Straight segments and arcs only (no splines).
|
|
1190
|
+
*
|
|
1191
|
+
* **A room has a floor finish AND a structural slab that overlap in plan; a
|
|
1192
|
+
* void in one does not cut the other, so a through-opening needs one void in
|
|
1193
|
+
* each.**
|
|
1194
|
+
*
|
|
1195
|
+
* `getEntityType` reports a void as `"void"`. Use `design.query.listVoids`
|
|
1196
|
+
* or `listByType("void")`; `listMasses` excludes voids. `getHost` and
|
|
1197
|
+
* `listChildren(host)` expose the host relationship, including after a copy.
|
|
1198
|
+
* Authored parametric families with a cut relationship keep their family
|
|
1199
|
+
* identity; discover those through family queries instead.
|
|
1200
|
+
*
|
|
1201
|
+
* Call it as `snaptrude.design.create.void(...)`; `void` is a reserved word and
|
|
1202
|
+
* cannot be destructured. Voids in walls, on sloped, generated or multi-plane
|
|
1203
|
+
* roofs, and on instanced hosts are not available yet; for a door or window
|
|
1204
|
+
* use `design.create.door` / `window`. To make a NEW slab that already has a
|
|
1205
|
+
* fixed hole, pass a contour with holes to `design.create.slab`; that hole is
|
|
1206
|
+
* part of the footprint, not an object. For a contour's outer loop, pass
|
|
1207
|
+
* `core.geom.query.contour.getOuterProfile(contour)`.
|
|
1208
|
+
*
|
|
1209
|
+
* # Example
|
|
1210
|
+
* ```ts
|
|
1211
|
+
* const m = 1000 / 254 // metres → Snaptrude units (SU)
|
|
1212
|
+
* const [slab] = await snaptrude.design.query.listByType("slab", { isSelected: true })
|
|
1213
|
+
* const center = await snaptrude.core.math.vec3.new(10 * m, 0, 5 * m) // plan point; y is ignored
|
|
1214
|
+
* const outline = await snaptrude.core.geom.create.profileRect(2 * m, 2 * m, center) // 2 m x 2 m
|
|
1215
|
+
* const hole = await snaptrude.design.create.void(slab, outline)
|
|
1216
|
+
* ```
|
|
1217
|
+
*
|
|
1218
|
+
* A round hole is two arcs (a circle handle is not a profile):
|
|
1219
|
+
* ```ts
|
|
1220
|
+
* const m = 1000 / 254
|
|
1221
|
+
* const { vec3 } = snaptrude.core.math
|
|
1222
|
+
* const g = snaptrude.core.geom.create
|
|
1223
|
+
* const r = 0.5 * m // 1 m diameter
|
|
1224
|
+
* const centre = await vec3.new(10 * m, 0, 5 * m)
|
|
1225
|
+
* const axis = await vec3.new(0, -1, 0)
|
|
1226
|
+
* const east = await vec3.new(10 * m + r, 0, 5 * m)
|
|
1227
|
+
* const west = await vec3.new(10 * m - r, 0, 5 * m)
|
|
1228
|
+
* const round = await g.profileFromCurves([await g.arc(east, west, centre, axis), await g.arc(west, east, centre, axis)])
|
|
1229
|
+
* await snaptrude.design.create.void(slab, round) // never destructure `void`
|
|
1230
|
+
* ```
|
|
1231
|
+
*
|
|
1232
|
+
* @param host - The slab, floor, roof or ceiling to cut through
|
|
1233
|
+
* @param outline - Closed, flat plan outline (world SU); its height is ignored
|
|
1234
|
+
* @returns the {@linkcode ComponentHandle} of the new void
|
|
1235
|
+
* @throws `VALIDATION` if the outline is open, crosses itself, is not flat or
|
|
1236
|
+
* has a spline, or the arguments are the wrong handle kinds or swapped;
|
|
1237
|
+
* `HANDLE_INVALID` if a handle is unknown or released or the host was
|
|
1238
|
+
* deleted; `HANDLE_STALE` if the host was rebuilt (re-query it);
|
|
1239
|
+
* `PRECONDITION_FAILED` if the
|
|
1240
|
+
* host is a wall or not a slab/floor/roof/ceiling, is sloped, instanced, in
|
|
1241
|
+
* another building, locked, outside the active proposal, a generated roof or
|
|
1242
|
+
* not a single plate, or there is no active structure (`engineCode`
|
|
1243
|
+
* `NO_ACTIVE_STRUCTURE`); `OPERATION_FAILED` with `engineCode`
|
|
1244
|
+
* `VOID_DOES_NOT_FIT` when the outline crosses the host edge, overlaps a void
|
|
1245
|
+
* or hole, is closer than 25.4 mm to either, or the fit could not be checked,
|
|
1246
|
+
* or another `engineCode` when the cut failed (nothing is created, except
|
|
1247
|
+
* `PUBLISH_FAILED` with a hint that the voids are in the scene: undo, then
|
|
1248
|
+
* retry); `METHOD_NOT_PERMITTED` if the plugin may not write.
|
|
1249
|
+
*
|
|
1250
|
+
* @examplePrompt Cut a hole in this slab
|
|
1251
|
+
* @examplePrompt Add a 1.2m by 2.4m stair opening in the first-floor slab
|
|
1252
|
+
* @examplePrompt Make a 600 x 600 service penetration in the floor for the riser
|
|
1253
|
+
* @examplePrompt Put a skylight opening through the roof
|
|
1254
|
+
* @examplePrompt Cut a round 1m duct hole in the slab
|
|
1255
|
+
* @examplePrompt Make a cut-out in the ceiling for the light well
|
|
1256
|
+
* @examplePrompt Add a double-height atrium void in the level 2 floor
|
|
1257
|
+
*
|
|
1258
|
+
* @performance Single-void creator. For MORE THAN ONE void, call
|
|
1259
|
+
* `design.create.voids(items[])`: one host round-trip, ONE undo entry, one cut
|
|
1260
|
+
* per host.
|
|
1261
|
+
*/
|
|
1262
|
+
public abstract void(
|
|
1263
|
+
host: ComponentHandle,
|
|
1264
|
+
outline: ProfileHandle,
|
|
1265
|
+
): PluginApiReturn<ComponentHandle>
|
|
1266
|
+
|
|
1267
|
+
/**
|
|
1268
|
+
* Cut **many voids** (holes, openings, shafts) through slabs, floors, roofs
|
|
1269
|
+
* and ceilings in one undoable operation (bulk plural of {@linkcode void}).
|
|
1270
|
+
* Items may share a host or use different hosts — one shaft outline on every
|
|
1271
|
+
* storey's slab AND floor is one call. Validate-all-or-throw: one item whose
|
|
1272
|
+
* host does not contain the outline rejects the whole batch, so pass only the
|
|
1273
|
+
* hosts that contain it; `details.itemIndex` names the failing item (for two
|
|
1274
|
+
* overlapping items of the batch, the earlier one). At most 50 voids per host
|
|
1275
|
+
* and 200 in all per call. Same outline rules as {@linkcode void}: plan outline, 25.4 mm
|
|
1276
|
+
* (0.1 SU) clearance, floor AND slab are separate hosts. Call it as
|
|
1277
|
+
* `snaptrude.design.create.voids(...)`.
|
|
1278
|
+
*
|
|
1279
|
+
* # Example
|
|
1280
|
+
* ```ts
|
|
1281
|
+
* const m = 1000 / 254
|
|
1282
|
+
* // The user selects the slabs AND floors the shaft passes through; every one must contain the outline.
|
|
1283
|
+
* const hosts = [
|
|
1284
|
+
* ...(await snaptrude.design.query.listByType("slab", { isSelected: true })),
|
|
1285
|
+
* ...(await snaptrude.design.query.listByType("floor", { isSelected: true })),
|
|
1286
|
+
* ]
|
|
1287
|
+
* const centre = await snaptrude.core.math.vec3.new(12 * m, 0, -6 * m)
|
|
1288
|
+
* const shaft = await snaptrude.core.geom.create.profileRect(2 * m, 2 * m, centre)
|
|
1289
|
+
* const holes = await snaptrude.design.create.voids(hosts.map((host) => ({ host, outline: shaft })))
|
|
1290
|
+
* ```
|
|
1291
|
+
*
|
|
1292
|
+
* @param items - One {@linkcode PluginCreateVoidItem} per void (≥1, ≤200; ≤50 per host)
|
|
1293
|
+
* @returns the new voids as {@linkcode ComponentHandle}`[]`, in input order
|
|
1294
|
+
* @throws `VALIDATION` if the items fail the schema (empty array, more than
|
|
1295
|
+
* 1000 items, unknown fields), an outline is invalid (as for
|
|
1296
|
+
* {@linkcode void}), more than 50 items share one host, or there are more
|
|
1297
|
+
* than 200 items; plus every code {@linkcode void} throws, each with
|
|
1298
|
+
* `details.itemIndex`. Nothing is created on any failure, except
|
|
1299
|
+
* `PUBLISH_FAILED` (as for {@linkcode void}).
|
|
1300
|
+
*
|
|
1301
|
+
* @examplePrompt Cut a lift shaft through every floor slab of the core
|
|
1302
|
+
* @examplePrompt Cut a 2m x 2m shaft through all the slabs at this location
|
|
1303
|
+
* @examplePrompt Make stair openings in all the floors above the staircases
|
|
1304
|
+
* @examplePrompt Make holes in the roof for these three skylights
|
|
1305
|
+
* @examplePrompt Cut openings in each storey's slab matching this outline
|
|
1306
|
+
* @examplePrompt Punch the same riser penetration through every floor at once
|
|
1307
|
+
*
|
|
1308
|
+
* @performance ONE host round-trip, ONE undo entry, ONE cut per host. Never call
|
|
1309
|
+
* `void` in a loop. Runs synchronously on the main thread: 50 voids on one
|
|
1310
|
+
* host take about 1 s, and the time grows with the number of hosts (caps:
|
|
1311
|
+
* 50 per host, 200 per call).
|
|
1312
|
+
*/
|
|
1313
|
+
public abstract voids(
|
|
1314
|
+
items: PluginCreateVoidItem[],
|
|
1315
|
+
): PluginApiReturn<ComponentHandle[]>
|
|
1316
|
+
|
|
1317
|
+
/**
|
|
1318
|
+
* Place a parametric **door or window** into a host wall with parameter overrides.
|
|
687
1319
|
*
|
|
688
1320
|
* The world `position` is projected onto the host wall to locate the opening.
|
|
689
1321
|
* All supplied dimensions use Snaptrude engine units. Window `sillHeight` is
|
|
690
1322
|
* measured from the host wall base to the bottom of the window, not to
|
|
691
1323
|
* its center. Placement is asynchronous and committed as one undoable creation.
|
|
692
1324
|
*
|
|
693
|
-
*
|
|
694
|
-
*
|
|
1325
|
+
* Wall only. For a hole in a slab, floor or roof use `design.create.void`.
|
|
1326
|
+
*
|
|
1327
|
+
* @param options - Opening kind, family and host references, placement, and
|
|
1328
|
+
* optional facing (swing side), hinge (hinged jamb), label, and dimensions
|
|
695
1329
|
* @returns the {@linkcode ComponentHandle} of the placed door or window
|
|
696
|
-
* @throws if the options are invalid, the
|
|
1330
|
+
* @throws if the options are invalid, the family id is unknown, the host is
|
|
697
1331
|
* not a wall, loading fails, or the opening cannot be placed on the host
|
|
698
1332
|
*
|
|
699
1333
|
* @examplePrompt Add a 1m wide door to this wall here
|
|
700
1334
|
* @examplePrompt Place a window with a 0.9m sill height on the selected wall
|
|
701
1335
|
*
|
|
702
|
-
* @performance Single-opening creator — use it for one hosted opening.
|
|
703
|
-
*
|
|
1336
|
+
* @performance Single-opening creator — use it for one hosted opening. For MORE
|
|
1337
|
+
* THAN ONE, call `design.create.doors(items[])` / `design.create.windows(items[])`:
|
|
1338
|
+
* the same per-item fields, one host round-trip, ONE undo entry.
|
|
704
1339
|
*
|
|
705
1340
|
* # Example
|
|
706
1341
|
* ```ts
|
|
707
1342
|
* const opening = await snaptrude.design.create.opening({
|
|
708
1343
|
* kind: "window",
|
|
709
|
-
*
|
|
1344
|
+
* familyId: windowType.id,
|
|
710
1345
|
* hostWall: wall,
|
|
711
1346
|
* position: await snaptrude.core.math.vec3.new(3, 0, 5),
|
|
712
1347
|
* width: 1.2,
|
|
@@ -901,6 +1536,35 @@ export abstract class PluginDesignCreateApi {
|
|
|
901
1536
|
farRatio?: number,
|
|
902
1537
|
lotCoverageMaxPct?: number,
|
|
903
1538
|
): PluginApiReturn<PluginBuildableEnvelopeCreateResult>
|
|
1539
|
+
|
|
1540
|
+
/**
|
|
1541
|
+
* Create a default buildable envelope for an existing site — the same as the
|
|
1542
|
+
* right panel's "Create Buildable Envelope" button. Front, side and rear
|
|
1543
|
+
* distances are seeded from Site Analysis or the Program sheet, with a 10 ft
|
|
1544
|
+
* fallback, and the envelope is linked to the site. Call it only after the
|
|
1545
|
+
* user agrees (for example when `design.update.siteEdge` throws
|
|
1546
|
+
* `NO_BUILDABLE_ENVELOPE`).
|
|
1547
|
+
*
|
|
1548
|
+
* @param siteId - Site component id, from `program.site.listEdges()`.
|
|
1549
|
+
* @returns A {@linkcode PluginDesignCreateBuildableEnvelopeFromSiteResult}
|
|
1550
|
+
* with the `buildableEnvelopeId` of the created envelope.
|
|
1551
|
+
* @throws `HANDLE_INVALID` for an unknown `siteId`. `PRECONDITION_FAILED`
|
|
1552
|
+
* (`details.reason: "SITE_HAS_ENVELOPE"`) when the site already has an
|
|
1553
|
+
* envelope.
|
|
1554
|
+
*
|
|
1555
|
+
* @examplePrompt Create a buildable envelope for this site with default setbacks
|
|
1556
|
+
* @examplePrompt Add the zoning envelope to my site
|
|
1557
|
+
*
|
|
1558
|
+
* # Example
|
|
1559
|
+
* ```ts
|
|
1560
|
+
* const [{ siteId }] = (await snaptrude.program.site.listEdges()).sites
|
|
1561
|
+
* const { buildableEnvelopeId } =
|
|
1562
|
+
* await snaptrude.design.create.buildableEnvelopeFromSite(siteId)
|
|
1563
|
+
* ```
|
|
1564
|
+
*/
|
|
1565
|
+
public abstract buildableEnvelopeFromSite(
|
|
1566
|
+
siteId: string,
|
|
1567
|
+
): PluginApiReturn<PluginDesignCreateBuildableEnvelopeFromSiteResult>
|
|
904
1568
|
}
|
|
905
1569
|
|
|
906
1570
|
// ---------------------------------------------------------------------------
|
|
@@ -1206,21 +1870,24 @@ export type PluginDesignCreateBeamArgs = z.infer<
|
|
|
1206
1870
|
* | `profile` | {@linkcode ProfileHandle} | Ordered curve chain (wall centerlines) |
|
|
1207
1871
|
* | `height` | `number`? | Wall height (default engine default) |
|
|
1208
1872
|
* | `thickness` | `number`? | Wall thickness (default: `wallType`'s total layer thickness when given, else engine default) |
|
|
1209
|
-
* | `wallType` |
|
|
1873
|
+
* | `wallType` | {@linkcode PluginWallType}? | Legacy name/id or exact native `{ id, version }` pin from `design.types.list("wall")` (default generic) |
|
|
1210
1874
|
* | `storey` | `number`? | Target storey (integer, must exist) — walls assigned + lifted to its base in the same undo entry (default: geometry-derived) |
|
|
1875
|
+
* | `topProfiles` | ({@linkcode PluginWallTopProfile} \| `null`)[]? | Top edge per curve (same order); `null`/missing = flat at `height`. Straight curves only |
|
|
1211
1876
|
*/
|
|
1212
1877
|
export const PluginDesignCreateWallsArgs = z.object({
|
|
1213
1878
|
profile: ProfileHandle,
|
|
1214
1879
|
height: z.number().optional(),
|
|
1215
1880
|
thickness: z.number().optional(),
|
|
1216
|
-
wallType:
|
|
1881
|
+
wallType: PluginWallType.optional(),
|
|
1217
1882
|
storey: z.number().int().optional(),
|
|
1883
|
+
topProfiles: z.array(PluginWallTopProfile.nullable()).optional(),
|
|
1884
|
+
values: PluginFamilyValues.optional(),
|
|
1218
1885
|
})
|
|
1219
1886
|
export type PluginDesignCreateWallsArgs = z.infer<
|
|
1220
1887
|
typeof PluginDesignCreateWallsArgs
|
|
1221
1888
|
>
|
|
1222
|
-
// TRANSPORT: positional signature shipped — storey is the
|
|
1223
|
-
// walls(profile: ProfileHandle, height?: number, thickness?: number, wallType?: string, storey?: number)
|
|
1889
|
+
// TRANSPORT: positional signature shipped — storey is the 5th arg, topProfiles the trailing 6th:
|
|
1890
|
+
// walls(profile: ProfileHandle, height?: number, thickness?: number, wallType?: string, storey?: number, topProfiles?: (PluginWallTopProfile | null)[])
|
|
1224
1891
|
|
|
1225
1892
|
// ---------------------------------------------------------------------------
|
|
1226
1893
|
// staircase
|
|
@@ -1262,7 +1929,7 @@ export type PluginDesignCreateStaircaseArgs = z.infer<
|
|
|
1262
1929
|
* | `catalogId` | `string` | Library id: team `_id` or general `fullName` |
|
|
1263
1930
|
* | `position` | {@linkcode Vec3Handle} | Absolute world placement point |
|
|
1264
1931
|
* | `label` | `string`? | Instance name (default auto `${name}Ins${n}`) |
|
|
1265
|
-
* | `createNewSourceMesh` | `boolean`? |
|
|
1932
|
+
* | `createNewSourceMesh` | `boolean`? | Legacy, kept for compatibility; the host records a catalog source exactly once and this flag cannot skip it |
|
|
1266
1933
|
* | `angleInDegrees` | `number`? | Rotation about the vertical axis, in degrees (default unrotated) |
|
|
1267
1934
|
*/
|
|
1268
1935
|
export const PluginDesignCreateFurnitureArgs = z.object({
|
|
@@ -1287,24 +1954,23 @@ export type PluginDesignCreateFurnitureArgs = z.infer<
|
|
|
1287
1954
|
*
|
|
1288
1955
|
* | Property | Type | Description |
|
|
1289
1956
|
* |---|---|---|
|
|
1290
|
-
* | `
|
|
1957
|
+
* | `familyId` | `string` | Hosted door family definition ID |
|
|
1958
|
+
* | `version` | `number`? | Exact version; newest known by default |
|
|
1959
|
+
* | `values` | `Record<string, number \| string>`? | Parameters; numeric lengths use SU |
|
|
1291
1960
|
* | `hostWall` | {@linkcode ComponentHandle} | The wall to host the door |
|
|
1292
1961
|
* | `position` | {@linkcode Vec3Handle} | World point projected onto the wall |
|
|
1293
1962
|
* | `label` | `string`? | Instance name (optional) |
|
|
1294
|
-
* | `facing` | {@linkcode Vec3Handle}? | World point on the side of the wall the door
|
|
1963
|
+
* | `facing` | {@linkcode Vec3Handle}? | World point on the side of the wall the door swings open to (default engine-chosen) |
|
|
1964
|
+
* | `hinge` | {@linkcode Vec3Handle}? | World point near the hinged jamb; requires hand control |
|
|
1295
1965
|
*/
|
|
1296
1966
|
export const PluginDesignCreateDoorArgs = z.object({
|
|
1297
|
-
|
|
1298
|
-
hostWall: ComponentHandle,
|
|
1299
|
-
position: Vec3Handle,
|
|
1300
|
-
label: z.string().optional(),
|
|
1301
|
-
facing: Vec3Handle.optional(),
|
|
1967
|
+
...PluginOpeningBaseOptions,
|
|
1302
1968
|
})
|
|
1303
1969
|
export type PluginDesignCreateDoorArgs = z.infer<
|
|
1304
1970
|
typeof PluginDesignCreateDoorArgs
|
|
1305
1971
|
>
|
|
1306
|
-
// TRANSPORT: positional signature shipped — facing is the trailing 5th arg:
|
|
1307
|
-
// door(
|
|
1972
|
+
// TRANSPORT: positional signature shipped — facing is the trailing 5th arg, hinge rides in options:
|
|
1973
|
+
// door(familyId, hostWall, position, options?: { label?, hinge?, version?, values? }, facing?)
|
|
1308
1974
|
|
|
1309
1975
|
// ---------------------------------------------------------------------------
|
|
1310
1976
|
// window
|
|
@@ -1315,39 +1981,28 @@ export type PluginDesignCreateDoorArgs = z.infer<
|
|
|
1315
1981
|
*
|
|
1316
1982
|
* | Property | Type | Description |
|
|
1317
1983
|
* |---|---|---|
|
|
1318
|
-
* | `
|
|
1984
|
+
* | `familyId` | `string` | Hosted window family definition ID |
|
|
1985
|
+
* | `version` | `number`? | Exact version; newest known by default |
|
|
1986
|
+
* | `values` | `Record<string, number \| string>`? | Parameters; numeric lengths use SU |
|
|
1319
1987
|
* | `hostWall` | {@linkcode ComponentHandle} | The wall to host the window |
|
|
1320
1988
|
* | `position` | {@linkcode Vec3Handle} | World point projected onto the wall |
|
|
1321
1989
|
* | `label` | `string`? | Instance name (optional) |
|
|
1322
|
-
* | `facing` | {@linkcode Vec3Handle}? | World point on the side of the wall the window
|
|
1990
|
+
* | `facing` | {@linkcode Vec3Handle}? | World point on the side of the wall the window opens to (default engine-chosen) |
|
|
1991
|
+
* | `hinge` | {@linkcode Vec3Handle}? | World point near the hinged jamb; requires hand control |
|
|
1323
1992
|
*/
|
|
1324
1993
|
export const PluginDesignCreateWindowArgs = z.object({
|
|
1325
|
-
|
|
1326
|
-
hostWall: ComponentHandle,
|
|
1327
|
-
position: Vec3Handle,
|
|
1328
|
-
label: z.string().optional(),
|
|
1329
|
-
facing: Vec3Handle.optional(),
|
|
1994
|
+
...PluginOpeningBaseOptions,
|
|
1330
1995
|
})
|
|
1331
1996
|
export type PluginDesignCreateWindowArgs = z.infer<
|
|
1332
1997
|
typeof PluginDesignCreateWindowArgs
|
|
1333
1998
|
>
|
|
1334
|
-
// TRANSPORT: positional signature shipped — facing is the trailing 5th arg:
|
|
1335
|
-
// window(
|
|
1999
|
+
// TRANSPORT: positional signature shipped — facing is the trailing 5th arg, hinge rides in options:
|
|
2000
|
+
// window(familyId, hostWall, position, options?: { label?, hinge?, version?, values? }, facing?)
|
|
1336
2001
|
|
|
1337
2002
|
// ---------------------------------------------------------------------------
|
|
1338
2003
|
// opening
|
|
1339
2004
|
// ---------------------------------------------------------------------------
|
|
1340
2005
|
|
|
1341
|
-
const PluginOpeningBaseOptions = {
|
|
1342
|
-
catalogId: z.string().min(1),
|
|
1343
|
-
hostWall: ComponentHandle,
|
|
1344
|
-
position: Vec3Handle,
|
|
1345
|
-
facing: Vec3Handle.optional(),
|
|
1346
|
-
label: z.string().optional(),
|
|
1347
|
-
width: z.number().finite().positive().optional(),
|
|
1348
|
-
height: z.number().finite().positive().optional(),
|
|
1349
|
-
}
|
|
1350
|
-
|
|
1351
2006
|
/**
|
|
1352
2007
|
* Options for {@linkcode PluginDesignCreateApi.opening}, discriminated by
|
|
1353
2008
|
* `kind`. Width and height are positive Snaptrude engine-unit values.
|
|
@@ -1446,13 +2101,63 @@ export type PluginSmartLayoutResult = z.infer<typeof PluginSmartLayoutResult>
|
|
|
1446
2101
|
* | `style` | {@linkcode PluginReferenceLineStyle}? | Line style (default `SOLID`) |
|
|
1447
2102
|
* | `gridTag` | `string`? | Grid tag label (default `"A"`) |
|
|
1448
2103
|
*/
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
2104
|
+
/**
|
|
2105
|
+
* Reference-line creation options. styleId selects a project pen/pattern; its
|
|
2106
|
+
* native legacy mirror is saved too. Omitted options preserve tool defaults.
|
|
2107
|
+
*/
|
|
2108
|
+
export const PluginReferenceLineOptions = z
|
|
2109
|
+
.object({
|
|
2110
|
+
styleId: PluginGraphicsLineStyleId.optional(),
|
|
2111
|
+
color: z
|
|
2112
|
+
.string()
|
|
2113
|
+
.regex(/^#[0-9a-f]{6}$/i)
|
|
2114
|
+
.optional(),
|
|
2115
|
+
thickness: z.number().finite().positive().optional(),
|
|
2116
|
+
style: PluginReferenceLineStyle.optional(),
|
|
2117
|
+
})
|
|
2118
|
+
.strict()
|
|
2119
|
+
.superRefine((options, ctx) => {
|
|
2120
|
+
if (
|
|
2121
|
+
options.styleId !== undefined &&
|
|
2122
|
+
(options.thickness !== undefined || options.style !== undefined)
|
|
2123
|
+
) {
|
|
2124
|
+
ctx.addIssue({
|
|
2125
|
+
code: "custom",
|
|
2126
|
+
message: "styleId cannot be combined with legacy thickness or style",
|
|
2127
|
+
})
|
|
2128
|
+
}
|
|
2129
|
+
})
|
|
2130
|
+
export type PluginReferenceLineOptions = z.infer<
|
|
2131
|
+
typeof PluginReferenceLineOptions
|
|
2132
|
+
>
|
|
2133
|
+
|
|
2134
|
+
/**
|
|
2135
|
+
* Normalized arguments. The host maps the second positional argument to either
|
|
2136
|
+
* the legacy color field or options; mixing those forms is rejected atomically.
|
|
2137
|
+
*/
|
|
2138
|
+
export const PluginDesignCreateReferenceLinesArgs = z
|
|
2139
|
+
.object({
|
|
2140
|
+
profile: ProfileHandle,
|
|
2141
|
+
options: PluginReferenceLineOptions.optional(),
|
|
2142
|
+
color: z.string().optional(),
|
|
2143
|
+
thickness: z.number().finite().optional(),
|
|
2144
|
+
style: PluginReferenceLineStyle.optional(),
|
|
2145
|
+
gridTag: z.string().optional(),
|
|
2146
|
+
})
|
|
2147
|
+
.strict()
|
|
2148
|
+
.superRefine((args, ctx) => {
|
|
2149
|
+
if (
|
|
2150
|
+
args.options !== undefined &&
|
|
2151
|
+
[args.color, args.thickness, args.style, args.gridTag].some(
|
|
2152
|
+
(v) => v !== undefined,
|
|
2153
|
+
)
|
|
2154
|
+
) {
|
|
2155
|
+
ctx.addIssue({
|
|
2156
|
+
code: "custom",
|
|
2157
|
+
message: "Options cannot be combined with legacy positional arguments",
|
|
2158
|
+
})
|
|
2159
|
+
}
|
|
2160
|
+
})
|
|
1456
2161
|
export type PluginDesignCreateReferenceLinesArgs = z.infer<
|
|
1457
2162
|
typeof PluginDesignCreateReferenceLinesArgs
|
|
1458
2163
|
>
|
|
@@ -1524,3 +2229,7 @@ export const PluginCreateSpaceItem = z.object({
|
|
|
1524
2229
|
storey: z.number().int().optional(),
|
|
1525
2230
|
})
|
|
1526
2231
|
export type PluginCreateSpaceItem = z.infer<typeof PluginCreateSpaceItem>
|
|
2232
|
+
|
|
2233
|
+
export * from "./opening-fields"
|
|
2234
|
+
export * from "./bulk-items"
|
|
2235
|
+
export * from "./grids"
|