@snaptrude/plugin-core 0.11.0-rc.1 → 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 +176 -14
- package/api-manifest.json +872 -49
- 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 +447 -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/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 +17 -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 +753 -102
- 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 +7 -20
- 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/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 -36
- package/dist/api/design/query/index.d.ts.map +1 -1
- package/dist/api/design/query/spaces.d.ts +5 -66
- package/dist/api/design/query/spaces.d.ts.map +1 -1
- 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/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 -15
- package/dist/api/entity/space.d.ts.map +1 -1
- 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 +117 -51
- 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 -37
- 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 +5 -8
- 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 +6534 -2865
- 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 +6118 -2857
- 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 +2 -1
- 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 +429 -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/proposals/index.ts +4 -3
- package/src/api/core/storeys/index.ts +19 -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 +824 -141
- package/src/api/design/create/opening-fields.ts +40 -0
- package/src/api/design/delete/index.ts +6 -20
- 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/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 -5
- package/src/api/design/query/spaces.ts +0 -68
- package/src/api/design/types/index.ts +31 -24
- package/src/api/design/update/index.ts +398 -4
- 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/entity/space.ts +0 -2
- 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 +120 -57
- package/src/api/presentation/sections.ts +420 -0
- package/src/api/presentation/sheets.ts +182 -37
- 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 +9 -30
- 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 -4
- package/test/massParameters.test.mjs +952 -0
- package/test/paperPensContract.test.mjs +75 -0
- package/test/presentationViewSettings.test.mjs +85 -0
- package/api-manifest.full.json +0 -6928
- package/snaptrude-plugin-core-0.11.0.tgz +0 -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,36 +242,33 @@ 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
|
*
|
|
220
|
-
* The
|
|
221
|
-
*
|
|
222
|
-
*
|
|
223
|
-
*
|
|
224
|
-
* honors the engine's resolution and returns **every floor that covers the
|
|
225
|
-
* requested footprint after the operation** — the newly created floor(s),
|
|
226
|
-
* and/or the pre-existing floor that absorbed it. The array is never empty
|
|
227
|
-
* on success; a lone independently-created floor comes back as `[floor]`.
|
|
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.
|
|
228
263
|
*
|
|
229
|
-
*
|
|
230
|
-
*
|
|
231
|
-
* element preserves the old single-floor behavior for simple creates).
|
|
264
|
+
* To cut a hole in an EXISTING one, use `design.create.void`; a contour hole
|
|
265
|
+
* here is baked into the footprint.
|
|
232
266
|
*
|
|
233
267
|
* @param contour - Footprint (outer + holes)
|
|
234
268
|
* @param thickness - Floor thickness (> 0)
|
|
235
269
|
* @param position - Offset from origin
|
|
236
|
-
* @returns
|
|
237
|
-
*
|
|
238
|
-
* @throws if the contour is invalid, the thickness is not positive, or the
|
|
239
|
-
* engine rejected the operation (nothing covers the footprint)
|
|
270
|
+
* @returns Newly created {@linkcode ComponentHandle}s; an empty array after a merge
|
|
271
|
+
* @throws if the contour is invalid or the thickness is not positive
|
|
240
272
|
*
|
|
241
273
|
* @examplePrompt Create a floor from this room outline
|
|
242
274
|
* @examplePrompt Add a 100mm thick floor over the footprint
|
|
@@ -247,19 +279,66 @@ export abstract class PluginDesignCreateApi {
|
|
|
247
279
|
* ```ts
|
|
248
280
|
* const rect = await snaptrude.core.geom.create.profileRect(5, 4)
|
|
249
281
|
* const contour = await snaptrude.core.geom.create.contourFromProfile(rect)
|
|
250
|
-
* const
|
|
282
|
+
* const floor = await snaptrude.design.create.floor(contour, 0.1)
|
|
251
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.
|
|
252
288
|
*/
|
|
253
289
|
public abstract floor(
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
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[],
|
|
257
333
|
): PluginApiReturn<ComponentHandle[]>
|
|
258
334
|
|
|
259
335
|
/**
|
|
260
336
|
* Create a **roof** by extruding a footprint contour by `thickness`. Created
|
|
261
337
|
* flat (extruded downward); pitch/slope is a separate post-creation edit.
|
|
262
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
|
+
*
|
|
263
342
|
* @param contour - Footprint (outer + holes)
|
|
264
343
|
* @param thickness - Roof-slab thickness (> 0)
|
|
265
344
|
* @returns the {@linkcode ComponentHandle} of the created roof
|
|
@@ -279,13 +358,16 @@ export abstract class PluginDesignCreateApi {
|
|
|
279
358
|
*/
|
|
280
359
|
public abstract roof(
|
|
281
360
|
contour: ContourHandle,
|
|
282
|
-
thickness: number,
|
|
361
|
+
thickness: number | PluginFamilyPlacement,
|
|
283
362
|
): PluginApiReturn<ComponentHandle>
|
|
284
363
|
|
|
285
364
|
/**
|
|
286
365
|
* Create a **ceiling** by extruding a footprint contour by `thickness`, lifted
|
|
287
366
|
* `heightFromFloor` above the floor.
|
|
288
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
|
+
*
|
|
289
371
|
* @param contour - Footprint (outer + holes)
|
|
290
372
|
* @param thickness - Ceiling thickness (> 0)
|
|
291
373
|
* @param heightFromFloor - Lift above the floor (default 0)
|
|
@@ -305,9 +387,9 @@ export abstract class PluginDesignCreateApi {
|
|
|
305
387
|
* ```
|
|
306
388
|
*/
|
|
307
389
|
public abstract ceiling(
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
390
|
+
...args:
|
|
391
|
+
| [contour: ContourHandle, thickness: number, heightFromFloor?: number]
|
|
392
|
+
| [contour: ContourHandle, options: PluginFamilyCeilingOptions]
|
|
311
393
|
): PluginApiReturn<ComponentHandle>
|
|
312
394
|
|
|
313
395
|
/**
|
|
@@ -338,10 +420,14 @@ export abstract class PluginDesignCreateApi {
|
|
|
338
420
|
* ```
|
|
339
421
|
*/
|
|
340
422
|
public abstract column(
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
423
|
+
...args:
|
|
424
|
+
| [
|
|
425
|
+
position: Vec3Handle,
|
|
426
|
+
crossSection: ContourHandle,
|
|
427
|
+
height: number,
|
|
428
|
+
directionUp?: Vec3Handle,
|
|
429
|
+
]
|
|
430
|
+
| [axis: LineHandle, options: PluginFamilyPlacement]
|
|
345
431
|
): PluginApiReturn<ComponentHandle>
|
|
346
432
|
|
|
347
433
|
/**
|
|
@@ -385,9 +471,9 @@ export abstract class PluginDesignCreateApi {
|
|
|
385
471
|
* ```
|
|
386
472
|
*/
|
|
387
473
|
public abstract beam(
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
474
|
+
...args:
|
|
475
|
+
| [section: ContourHandle, length: number, direction?: Vec3Handle]
|
|
476
|
+
| [axis: LineHandle, options: PluginFamilyPlacement]
|
|
391
477
|
): PluginApiReturn<ComponentHandle>
|
|
392
478
|
|
|
393
479
|
/**
|
|
@@ -398,27 +484,27 @@ export abstract class PluginDesignCreateApi {
|
|
|
398
484
|
* @param height - Wall height (default engine default)
|
|
399
485
|
* @param thickness - Wall thickness (default: the `wallType`'s total layer
|
|
400
486
|
* thickness when `wallType` is given, else the engine default)
|
|
401
|
-
* @param wallType -
|
|
402
|
-
*
|
|
403
|
-
*
|
|
404
|
-
*
|
|
405
|
-
*
|
|
406
|
-
* 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.
|
|
407
493
|
* @param storey - Target storey (integer: `1` ground, `2` first floor, `-1`
|
|
408
494
|
* basement — same convention as `design.create.space`). The walls are
|
|
409
495
|
* assigned to it and lifted to its base elevation, all inside the same
|
|
410
496
|
* single undo entry. The storey must already exist
|
|
411
497
|
* (`core.storeys.create` first). Default: geometry-derived — a profile
|
|
412
498
|
* drawn at y = 0 lands on storey 1; the ACTIVE storey is NOT consulted.
|
|
413
|
-
* @
|
|
414
|
-
*
|
|
415
|
-
*
|
|
416
|
-
*
|
|
417
|
-
*
|
|
418
|
-
* (e.g. `design.query.spaces.listGeneratedBim`) rather than assuming a
|
|
419
|
-
* wall per input curve.
|
|
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}).
|
|
503
|
+
* @returns a {@linkcode ComponentHandle}`[]` (one per wall), in profile order
|
|
420
504
|
* @throws if the profile is empty, `wallType` names no wall type in the
|
|
421
|
-
* 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
|
|
422
508
|
*
|
|
423
509
|
* @examplePrompt Draw walls along this centerline
|
|
424
510
|
* @examplePrompt Create 3m high, 200mm thick walls from these points
|
|
@@ -427,6 +513,9 @@ export abstract class PluginDesignCreateApi {
|
|
|
427
513
|
* @examplePrompt Add walls with mitred corners along the path
|
|
428
514
|
* @examplePrompt Draw brick walls with plaster along this outline
|
|
429
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
|
|
430
519
|
*
|
|
431
520
|
* # Example
|
|
432
521
|
* ```ts
|
|
@@ -442,16 +531,89 @@ export abstract class PluginDesignCreateApi {
|
|
|
442
531
|
* const brickWalls = await snaptrude.design.create.walls(
|
|
443
532
|
* centerlines, 3, undefined, brick.label,
|
|
444
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
|
+
* ])
|
|
445
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.
|
|
446
546
|
*/
|
|
447
547
|
public abstract walls(
|
|
448
548
|
profile: ProfileHandle,
|
|
449
549
|
height?: number,
|
|
450
550
|
thickness?: number,
|
|
451
|
-
wallType?:
|
|
551
|
+
wallType?: PluginWallType,
|
|
452
552
|
storey?: number,
|
|
553
|
+
topProfiles?: (PluginWallTopProfile | null)[],
|
|
554
|
+
values?: PluginFamilyValues,
|
|
453
555
|
): PluginApiReturn<ComponentHandle[]>
|
|
454
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
|
+
|
|
455
617
|
/**
|
|
456
618
|
* Create a **staircase** from a parametric preset, placed at a point.
|
|
457
619
|
*
|
|
@@ -502,8 +664,14 @@ export abstract class PluginDesignCreateApi {
|
|
|
502
664
|
* every created line.
|
|
503
665
|
*
|
|
504
666
|
* @param profile - Ordered curve chain (centerlines)
|
|
505
|
-
*
|
|
506
|
-
*
|
|
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)
|
|
507
675
|
* @param style - Line style (default `SOLID`)
|
|
508
676
|
* @param gridTag - Grid tag label (default `"A"`)
|
|
509
677
|
* @returns a {@linkcode ComponentHandle}`[]` (one per curve), in profile order
|
|
@@ -532,12 +700,140 @@ export abstract class PluginDesignCreateApi {
|
|
|
532
700
|
*/
|
|
533
701
|
public abstract referenceLines(
|
|
534
702
|
profile: ProfileHandle,
|
|
535
|
-
|
|
703
|
+
colorOrOptions?: string | PluginReferenceLineOptions,
|
|
536
704
|
thickness?: number,
|
|
537
705
|
style?: PluginReferenceLineStyle,
|
|
538
706
|
gridTag?: string,
|
|
539
707
|
): PluginApiReturn<ComponentHandle[]>
|
|
540
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
|
+
|
|
541
837
|
/**
|
|
542
838
|
* Place a **furniture** item from the project library at a world position.
|
|
543
839
|
*
|
|
@@ -556,17 +852,19 @@ export abstract class PluginDesignCreateApi {
|
|
|
556
852
|
* `position.y` (the same surface-flush contract as interactive drag-drop) —
|
|
557
853
|
* pass the floor/storey elevation to stand furniture on it; never add half
|
|
558
854
|
* the item's height yourself.
|
|
559
|
-
* @param options - Optional placement options: `label` — instance name
|
|
560
|
-
* (default auto `${name}Ins${n}`);
|
|
561
|
-
*
|
|
562
|
-
*
|
|
563
|
-
*
|
|
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.
|
|
564
860
|
* @param angleInDegrees - Optional signed rotation about the vertical axis, in
|
|
565
861
|
* degrees (same convention as {@linkcode PluginDesignTransformApi.rotate}).
|
|
566
862
|
* Applied at creation time so it is part of the placement's single undo entry.
|
|
567
863
|
* Default: the item's own (unrotated) orientation.
|
|
568
864
|
* @returns the {@linkcode ComponentHandle} of the placed furniture instance
|
|
569
|
-
* @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
|
|
570
868
|
*
|
|
571
869
|
* @examplePrompt Place a chair from the library at this spot
|
|
572
870
|
* @examplePrompt Add a sofa from the furniture catalog to the living room
|
|
@@ -590,39 +888,82 @@ export abstract class PluginDesignCreateApi {
|
|
|
590
888
|
* 90,
|
|
591
889
|
* )
|
|
592
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.
|
|
593
895
|
*/
|
|
594
896
|
public abstract furniture(
|
|
595
897
|
catalogId: string,
|
|
596
898
|
position: Vec3Handle,
|
|
597
|
-
options?: {
|
|
598
|
-
label?: string
|
|
599
|
-
createNewSourceMesh?: boolean
|
|
600
|
-
},
|
|
899
|
+
options?: { label?: string; createNewSourceMesh?: boolean },
|
|
601
900
|
angleInDegrees?: number,
|
|
602
901
|
): PluginApiReturn<ComponentHandle>
|
|
603
902
|
|
|
604
903
|
/**
|
|
605
|
-
* 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.
|
|
606
933
|
*
|
|
607
|
-
*
|
|
608
|
-
*
|
|
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.
|
|
951
|
+
*
|
|
952
|
+
* Identified by a saved **family definition id**. Discover ids with
|
|
609
953
|
* {@linkcode PluginDesignDoorsApi.listCatalog}. The world `position` is
|
|
610
954
|
* projected onto the host wall's face to locate the opening; the wall is
|
|
611
955
|
* re-cut and the door hosted in a single undo entry. Placement is
|
|
612
|
-
* asynchronous
|
|
956
|
+
* asynchronous. Values and host bindings are evaluated before the first cut.
|
|
613
957
|
*
|
|
614
|
-
* @param
|
|
958
|
+
* @param familyId - Hosted door definition ID; legacy mesh catalog IDs are not accepted
|
|
615
959
|
* @param hostWall - The wall to host the door
|
|
616
960
|
* @param position - World point projected onto the wall to locate the opening
|
|
617
|
-
* @param options -
|
|
618
|
-
*
|
|
619
|
-
*
|
|
620
|
-
*
|
|
621
|
-
* on that side works (e.g. the room's center). Default: the engine picks a
|
|
622
|
-
* 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
|
|
623
965
|
* @returns the {@linkcode ComponentHandle} of the placed door
|
|
624
|
-
* @throws if the
|
|
625
|
-
* 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
|
|
626
967
|
*
|
|
627
968
|
* @examplePrompt Add a door to this wall here
|
|
628
969
|
* @examplePrompt Place a sliding door on the selected wall
|
|
@@ -630,6 +971,7 @@ export abstract class PluginDesignCreateApi {
|
|
|
630
971
|
* @examplePrompt Insert the entrance door into this wall
|
|
631
972
|
* @examplePrompt Add a door to the wall and call it Entry-01
|
|
632
973
|
* @examplePrompt Add a door that opens into the living room
|
|
974
|
+
* @examplePrompt Put a door here hinged on the north jamb
|
|
633
975
|
*
|
|
634
976
|
* # Example
|
|
635
977
|
* ```ts
|
|
@@ -649,37 +991,100 @@ export abstract class PluginDesignCreateApi {
|
|
|
649
991
|
* undefined,
|
|
650
992
|
* await snaptrude.core.math.vec3.new(3, 0, 9),
|
|
651
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
|
+
* )
|
|
652
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.
|
|
653
1007
|
*/
|
|
654
1008
|
public abstract door(
|
|
655
|
-
|
|
1009
|
+
familyId: string,
|
|
656
1010
|
hostWall: ComponentHandle,
|
|
657
1011
|
position: Vec3Handle,
|
|
658
|
-
options?: {
|
|
1012
|
+
options?: {
|
|
1013
|
+
label?: string
|
|
1014
|
+
hinge?: Vec3Handle
|
|
1015
|
+
version?: number
|
|
1016
|
+
values?: Record<string, number | string>
|
|
1017
|
+
},
|
|
659
1018
|
facing?: Vec3Handle,
|
|
660
1019
|
): PluginApiReturn<ComponentHandle>
|
|
661
1020
|
|
|
662
1021
|
/**
|
|
663
|
-
* 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.
|
|
664
1054
|
*
|
|
665
|
-
*
|
|
666
|
-
*
|
|
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
|
|
667
1076
|
* {@linkcode PluginDesignWindowsApi.listCatalog}. The world `position` is
|
|
668
1077
|
* projected onto the host wall's face to locate the opening; the wall is
|
|
669
1078
|
* re-cut and the window hosted in a single undo entry. Placement is
|
|
670
|
-
* asynchronous
|
|
1079
|
+
* asynchronous. The sill parameter determines elevation; position Y is ignored.
|
|
671
1080
|
*
|
|
672
|
-
* @param
|
|
1081
|
+
* @param familyId - Hosted window definition ID; legacy mesh catalog IDs are not accepted
|
|
673
1082
|
* @param hostWall - The wall to host the window
|
|
674
1083
|
* @param position - World point projected onto the wall to locate the opening
|
|
675
|
-
* @param options -
|
|
676
|
-
* @param facing - World point selecting
|
|
677
|
-
* faces (matters for asymmetric windows, e.g. casement swing) — same
|
|
678
|
-
* convention as {@linkcode PluginDesignCreateApi.door}. Default: the engine
|
|
679
|
-
* 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
|
|
680
1086
|
* @returns the {@linkcode ComponentHandle} of the placed window
|
|
681
|
-
* @throws if the
|
|
682
|
-
* 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
|
|
683
1088
|
*
|
|
684
1089
|
* @examplePrompt Add a window to this wall here
|
|
685
1090
|
* @examplePrompt Place a casement window on the selected wall
|
|
@@ -699,40 +1104,244 @@ export abstract class PluginDesignCreateApi {
|
|
|
699
1104
|
* { label: "Win-01" },
|
|
700
1105
|
* )
|
|
701
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.
|
|
702
1111
|
*/
|
|
703
1112
|
public abstract window(
|
|
704
|
-
|
|
1113
|
+
familyId: string,
|
|
705
1114
|
hostWall: ComponentHandle,
|
|
706
1115
|
position: Vec3Handle,
|
|
707
|
-
options?: {
|
|
1116
|
+
options?: {
|
|
1117
|
+
label?: string
|
|
1118
|
+
hinge?: Vec3Handle
|
|
1119
|
+
version?: number
|
|
1120
|
+
values?: Record<string, number | string>
|
|
1121
|
+
},
|
|
708
1122
|
facing?: Vec3Handle,
|
|
709
1123
|
): PluginApiReturn<ComponentHandle>
|
|
710
1124
|
|
|
711
1125
|
/**
|
|
712
|
-
* 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.
|
|
713
1319
|
*
|
|
714
1320
|
* The world `position` is projected onto the host wall to locate the opening.
|
|
715
1321
|
* All supplied dimensions use Snaptrude engine units. Window `sillHeight` is
|
|
716
1322
|
* measured from the host wall base to the bottom of the window, not to
|
|
717
1323
|
* its center. Placement is asynchronous and committed as one undoable creation.
|
|
718
1324
|
*
|
|
719
|
-
*
|
|
720
|
-
*
|
|
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
|
|
721
1329
|
* @returns the {@linkcode ComponentHandle} of the placed door or window
|
|
722
|
-
* @throws if the options are invalid, the
|
|
1330
|
+
* @throws if the options are invalid, the family id is unknown, the host is
|
|
723
1331
|
* not a wall, loading fails, or the opening cannot be placed on the host
|
|
724
1332
|
*
|
|
725
1333
|
* @examplePrompt Add a 1m wide door to this wall here
|
|
726
1334
|
* @examplePrompt Place a window with a 0.9m sill height on the selected wall
|
|
727
1335
|
*
|
|
728
|
-
* @performance Single-opening creator — use it for one hosted opening.
|
|
729
|
-
*
|
|
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.
|
|
730
1339
|
*
|
|
731
1340
|
* # Example
|
|
732
1341
|
* ```ts
|
|
733
1342
|
* const opening = await snaptrude.design.create.opening({
|
|
734
1343
|
* kind: "window",
|
|
735
|
-
*
|
|
1344
|
+
* familyId: windowType.id,
|
|
736
1345
|
* hostWall: wall,
|
|
737
1346
|
* position: await snaptrude.core.math.vec3.new(3, 0, 5),
|
|
738
1347
|
* width: 1.2,
|
|
@@ -927,6 +1536,35 @@ export abstract class PluginDesignCreateApi {
|
|
|
927
1536
|
farRatio?: number,
|
|
928
1537
|
lotCoverageMaxPct?: number,
|
|
929
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>
|
|
930
1568
|
}
|
|
931
1569
|
|
|
932
1570
|
// ---------------------------------------------------------------------------
|
|
@@ -1232,21 +1870,24 @@ export type PluginDesignCreateBeamArgs = z.infer<
|
|
|
1232
1870
|
* | `profile` | {@linkcode ProfileHandle} | Ordered curve chain (wall centerlines) |
|
|
1233
1871
|
* | `height` | `number`? | Wall height (default engine default) |
|
|
1234
1872
|
* | `thickness` | `number`? | Wall thickness (default: `wallType`'s total layer thickness when given, else engine default) |
|
|
1235
|
-
* | `wallType` |
|
|
1873
|
+
* | `wallType` | {@linkcode PluginWallType}? | Legacy name/id or exact native `{ id, version }` pin from `design.types.list("wall")` (default generic) |
|
|
1236
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 |
|
|
1237
1876
|
*/
|
|
1238
1877
|
export const PluginDesignCreateWallsArgs = z.object({
|
|
1239
1878
|
profile: ProfileHandle,
|
|
1240
1879
|
height: z.number().optional(),
|
|
1241
1880
|
thickness: z.number().optional(),
|
|
1242
|
-
wallType:
|
|
1881
|
+
wallType: PluginWallType.optional(),
|
|
1243
1882
|
storey: z.number().int().optional(),
|
|
1883
|
+
topProfiles: z.array(PluginWallTopProfile.nullable()).optional(),
|
|
1884
|
+
values: PluginFamilyValues.optional(),
|
|
1244
1885
|
})
|
|
1245
1886
|
export type PluginDesignCreateWallsArgs = z.infer<
|
|
1246
1887
|
typeof PluginDesignCreateWallsArgs
|
|
1247
1888
|
>
|
|
1248
|
-
// TRANSPORT: positional signature shipped:
|
|
1249
|
-
// 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)[])
|
|
1250
1891
|
|
|
1251
1892
|
// ---------------------------------------------------------------------------
|
|
1252
1893
|
// staircase
|
|
@@ -1288,7 +1929,7 @@ export type PluginDesignCreateStaircaseArgs = z.infer<
|
|
|
1288
1929
|
* | `catalogId` | `string` | Library id: team `_id` or general `fullName` |
|
|
1289
1930
|
* | `position` | {@linkcode Vec3Handle} | Absolute world placement point |
|
|
1290
1931
|
* | `label` | `string`? | Instance name (default auto `${name}Ins${n}`) |
|
|
1291
|
-
* | `createNewSourceMesh` | `boolean`? |
|
|
1932
|
+
* | `createNewSourceMesh` | `boolean`? | Legacy, kept for compatibility; the host records a catalog source exactly once and this flag cannot skip it |
|
|
1292
1933
|
* | `angleInDegrees` | `number`? | Rotation about the vertical axis, in degrees (default unrotated) |
|
|
1293
1934
|
*/
|
|
1294
1935
|
export const PluginDesignCreateFurnitureArgs = z.object({
|
|
@@ -1313,24 +1954,23 @@ export type PluginDesignCreateFurnitureArgs = z.infer<
|
|
|
1313
1954
|
*
|
|
1314
1955
|
* | Property | Type | Description |
|
|
1315
1956
|
* |---|---|---|
|
|
1316
|
-
* | `
|
|
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 |
|
|
1317
1960
|
* | `hostWall` | {@linkcode ComponentHandle} | The wall to host the door |
|
|
1318
1961
|
* | `position` | {@linkcode Vec3Handle} | World point projected onto the wall |
|
|
1319
1962
|
* | `label` | `string`? | Instance name (optional) |
|
|
1320
|
-
* | `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 |
|
|
1321
1965
|
*/
|
|
1322
1966
|
export const PluginDesignCreateDoorArgs = z.object({
|
|
1323
|
-
|
|
1324
|
-
hostWall: ComponentHandle,
|
|
1325
|
-
position: Vec3Handle,
|
|
1326
|
-
label: z.string().optional(),
|
|
1327
|
-
facing: Vec3Handle.optional(),
|
|
1967
|
+
...PluginOpeningBaseOptions,
|
|
1328
1968
|
})
|
|
1329
1969
|
export type PluginDesignCreateDoorArgs = z.infer<
|
|
1330
1970
|
typeof PluginDesignCreateDoorArgs
|
|
1331
1971
|
>
|
|
1332
|
-
// TRANSPORT: positional signature shipped — facing is the trailing 5th arg:
|
|
1333
|
-
// 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?)
|
|
1334
1974
|
|
|
1335
1975
|
// ---------------------------------------------------------------------------
|
|
1336
1976
|
// window
|
|
@@ -1341,39 +1981,28 @@ export type PluginDesignCreateDoorArgs = z.infer<
|
|
|
1341
1981
|
*
|
|
1342
1982
|
* | Property | Type | Description |
|
|
1343
1983
|
* |---|---|---|
|
|
1344
|
-
* | `
|
|
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 |
|
|
1345
1987
|
* | `hostWall` | {@linkcode ComponentHandle} | The wall to host the window |
|
|
1346
1988
|
* | `position` | {@linkcode Vec3Handle} | World point projected onto the wall |
|
|
1347
1989
|
* | `label` | `string`? | Instance name (optional) |
|
|
1348
|
-
* | `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 |
|
|
1349
1992
|
*/
|
|
1350
1993
|
export const PluginDesignCreateWindowArgs = z.object({
|
|
1351
|
-
|
|
1352
|
-
hostWall: ComponentHandle,
|
|
1353
|
-
position: Vec3Handle,
|
|
1354
|
-
label: z.string().optional(),
|
|
1355
|
-
facing: Vec3Handle.optional(),
|
|
1994
|
+
...PluginOpeningBaseOptions,
|
|
1356
1995
|
})
|
|
1357
1996
|
export type PluginDesignCreateWindowArgs = z.infer<
|
|
1358
1997
|
typeof PluginDesignCreateWindowArgs
|
|
1359
1998
|
>
|
|
1360
|
-
// TRANSPORT: positional signature shipped — facing is the trailing 5th arg:
|
|
1361
|
-
// 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?)
|
|
1362
2001
|
|
|
1363
2002
|
// ---------------------------------------------------------------------------
|
|
1364
2003
|
// opening
|
|
1365
2004
|
// ---------------------------------------------------------------------------
|
|
1366
2005
|
|
|
1367
|
-
const PluginOpeningBaseOptions = {
|
|
1368
|
-
catalogId: z.string().min(1),
|
|
1369
|
-
hostWall: ComponentHandle,
|
|
1370
|
-
position: Vec3Handle,
|
|
1371
|
-
facing: Vec3Handle.optional(),
|
|
1372
|
-
label: z.string().optional(),
|
|
1373
|
-
width: z.number().finite().positive().optional(),
|
|
1374
|
-
height: z.number().finite().positive().optional(),
|
|
1375
|
-
}
|
|
1376
|
-
|
|
1377
2006
|
/**
|
|
1378
2007
|
* Options for {@linkcode PluginDesignCreateApi.opening}, discriminated by
|
|
1379
2008
|
* `kind`. Width and height are positive Snaptrude engine-unit values.
|
|
@@ -1472,13 +2101,63 @@ export type PluginSmartLayoutResult = z.infer<typeof PluginSmartLayoutResult>
|
|
|
1472
2101
|
* | `style` | {@linkcode PluginReferenceLineStyle}? | Line style (default `SOLID`) |
|
|
1473
2102
|
* | `gridTag` | `string`? | Grid tag label (default `"A"`) |
|
|
1474
2103
|
*/
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
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
|
+
})
|
|
1482
2161
|
export type PluginDesignCreateReferenceLinesArgs = z.infer<
|
|
1483
2162
|
typeof PluginDesignCreateReferenceLinesArgs
|
|
1484
2163
|
>
|
|
@@ -1550,3 +2229,7 @@ export const PluginCreateSpaceItem = z.object({
|
|
|
1550
2229
|
storey: z.number().int().optional(),
|
|
1551
2230
|
})
|
|
1552
2231
|
export type PluginCreateSpaceItem = z.infer<typeof PluginCreateSpaceItem>
|
|
2232
|
+
|
|
2233
|
+
export * from "./opening-fields"
|
|
2234
|
+
export * from "./bulk-items"
|
|
2235
|
+
export * from "./grids"
|