@snaptrude/plugin-core 0.0.0-dev-20260708130115 → 0.0.0-dev-20260827135706
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/CHANGELOG.md +152 -1
- package/api-manifest.json +3620 -276
- package/dist/api/analysis/daylight.d.ts +603 -0
- package/dist/api/analysis/daylight.d.ts.map +1 -0
- package/dist/api/analysis/heatmaps.d.ts +658 -0
- package/dist/api/analysis/heatmaps.d.ts.map +1 -0
- package/dist/api/analysis/illuminance.d.ts +145 -0
- package/dist/api/analysis/illuminance.d.ts.map +1 -0
- package/dist/api/analysis/index.d.ts +59 -0
- package/dist/api/analysis/index.d.ts.map +1 -0
- package/dist/api/analysis/shadows.d.ts +165 -0
- package/dist/api/analysis/shadows.d.ts.map +1 -0
- package/dist/api/analysis/solar.d.ts +249 -0
- package/dist/api/analysis/solar.d.ts.map +1 -0
- package/dist/api/analysis/sunlightHours.d.ts +208 -0
- package/dist/api/analysis/sunlightHours.d.ts.map +1 -0
- package/dist/api/analysis/sunpath.d.ts +80 -0
- package/dist/api/analysis/sunpath.d.ts.map +1 -0
- package/dist/api/analysis/weather.d.ts +193 -0
- package/dist/api/analysis/weather.d.ts.map +1 -0
- package/dist/api/core/camera/index.d.ts +261 -0
- package/dist/api/core/camera/index.d.ts.map +1 -0
- package/dist/api/core/comment/index.d.ts +105 -2
- package/dist/api/core/comment/index.d.ts.map +1 -1
- package/dist/api/core/geom/create/index.d.ts +840 -14
- package/dist/api/core/geom/create/index.d.ts.map +1 -1
- package/dist/api/core/geom/delete/index.d.ts +8 -2
- package/dist/api/core/geom/delete/index.d.ts.map +1 -1
- package/dist/api/core/geom/query/arc.d.ts +5 -5
- package/dist/api/core/geom/query/brep.d.ts +130 -18
- package/dist/api/core/geom/query/brep.d.ts.map +1 -1
- package/dist/api/core/geom/query/circle.d.ts +18 -18
- package/dist/api/core/geom/query/contour.d.ts +20 -20
- package/dist/api/core/geom/query/curve.d.ts +49 -49
- package/dist/api/core/geom/query/edge.d.ts +5 -5
- package/dist/api/core/geom/query/face.d.ts +16 -16
- package/dist/api/core/geom/query/halfedge.d.ts +8 -8
- package/dist/api/core/geom/query/profile.d.ts +19 -19
- package/dist/api/core/geom/query/vertex.d.ts +8 -8
- package/dist/api/core/geom/update/contour.d.ts +14 -14
- package/dist/api/core/geom/update/curve.d.ts +7 -7
- package/dist/api/core/geom/update/profile.d.ts +16 -16
- package/dist/api/core/handles/index.d.ts +210 -0
- package/dist/api/core/handles/index.d.ts.map +1 -0
- package/dist/api/core/index.d.ts +34 -0
- package/dist/api/core/index.d.ts.map +1 -1
- package/dist/api/core/io/export/index.d.ts +134 -0
- package/dist/api/core/io/export/index.d.ts.map +1 -0
- package/dist/api/core/io/import/index.d.ts +453 -0
- package/dist/api/core/io/import/index.d.ts.map +1 -0
- package/dist/api/core/io/index.d.ts +40 -0
- package/dist/api/core/io/index.d.ts.map +1 -0
- package/dist/api/core/io/job/index.d.ts +139 -0
- package/dist/api/core/io/job/index.d.ts.map +1 -0
- package/dist/api/core/io/query/index.d.ts +74 -0
- package/dist/api/core/io/query/index.d.ts.map +1 -0
- package/dist/api/core/io/terrain/index.d.ts +341 -0
- package/dist/api/core/io/terrain/index.d.ts.map +1 -0
- package/dist/api/core/io/underlay/index.d.ts +805 -0
- package/dist/api/core/io/underlay/index.d.ts.map +1 -0
- package/dist/api/core/layers.d.ts +7 -7
- package/dist/api/core/mode/index.d.ts +99 -0
- package/dist/api/core/mode/index.d.ts.map +1 -0
- 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 +531 -0
- package/dist/api/core/proposals/index.d.ts.map +1 -0
- package/dist/api/core/storeys/index.d.ts +265 -0
- package/dist/api/core/storeys/index.d.ts.map +1 -0
- package/dist/api/core/tags.d.ts +24 -0
- package/dist/api/core/tags.d.ts.map +1 -1
- package/dist/api/core/user.d.ts +44 -0
- package/dist/api/core/user.d.ts.map +1 -0
- package/dist/api/core/zoom/index.d.ts +4 -0
- package/dist/api/core/zoom/index.d.ts.map +1 -1
- package/dist/api/design/boolean/index.d.ts +4 -4
- package/dist/api/design/create/index.d.ts +568 -45
- package/dist/api/design/create/index.d.ts.map +1 -1
- package/dist/api/design/delete/index.d.ts +3 -0
- package/dist/api/design/delete/index.d.ts.map +1 -1
- package/dist/api/design/doors/index.d.ts +195 -0
- package/dist/api/design/doors/index.d.ts.map +1 -1
- package/dist/api/design/edit/index.d.ts +1 -1
- package/dist/api/design/erase/index.d.ts +2 -2
- package/dist/api/design/family.d.ts +349 -0
- package/dist/api/design/family.d.ts.map +1 -0
- package/dist/api/design/furniture/index.d.ts +181 -8
- package/dist/api/design/furniture/index.d.ts.map +1 -1
- package/dist/api/design/index.d.ts +98 -0
- package/dist/api/design/index.d.ts.map +1 -1
- package/dist/api/design/lock.d.ts +26 -0
- package/dist/api/design/lock.d.ts.map +1 -1
- package/dist/api/design/materials/index.d.ts +270 -16
- package/dist/api/design/materials/index.d.ts.map +1 -1
- package/dist/api/design/query/geometry/index.d.ts +112 -0
- package/dist/api/design/query/geometry/index.d.ts.map +1 -1
- package/dist/api/design/query/index.d.ts +282 -11
- package/dist/api/design/query/index.d.ts.map +1 -1
- package/dist/api/design/query/referenceLines.d.ts +45 -0
- package/dist/api/design/query/referenceLines.d.ts.map +1 -0
- package/dist/api/design/query/spaces.d.ts +181 -8
- package/dist/api/design/query/spaces.d.ts.map +1 -1
- package/dist/api/design/selection/index.d.ts +144 -0
- package/dist/api/design/selection/index.d.ts.map +1 -1
- package/dist/api/design/transform/index.d.ts +172 -10
- package/dist/api/design/transform/index.d.ts.map +1 -1
- package/dist/api/design/types/index.d.ts +181 -0
- package/dist/api/design/types/index.d.ts.map +1 -0
- package/dist/api/design/update/index.d.ts +553 -2
- package/dist/api/design/update/index.d.ts.map +1 -1
- package/dist/api/design/visibility.d.ts +126 -0
- package/dist/api/design/visibility.d.ts.map +1 -0
- package/dist/api/design/windows/index.d.ts +113 -2
- package/dist/api/design/windows/index.d.ts.map +1 -1
- package/dist/api/entity/buildableEnvelope.d.ts +4 -0
- package/dist/api/entity/buildableEnvelope.d.ts.map +1 -1
- package/dist/api/entity/referenceLine.d.ts +10 -2
- package/dist/api/entity/referenceLine.d.ts.map +1 -1
- package/dist/api/entity/space.d.ts +21 -21
- package/dist/api/entity/story.d.ts +242 -15
- package/dist/api/entity/story.d.ts.map +1 -1
- package/dist/api/index.d.ts +10 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/presentation/aiInspiration.d.ts +25 -25
- package/dist/api/presentation/annotate.d.ts +467 -0
- package/dist/api/presentation/annotate.d.ts.map +1 -0
- package/dist/api/presentation/diagrams.d.ts +111 -8
- package/dist/api/presentation/diagrams.d.ts.map +1 -1
- package/dist/api/presentation/export.d.ts +108 -0
- package/dist/api/presentation/export.d.ts.map +1 -0
- package/dist/api/presentation/import.d.ts +55 -4
- package/dist/api/presentation/import.d.ts.map +1 -1
- package/dist/api/presentation/index.d.ts +58 -1
- package/dist/api/presentation/index.d.ts.map +1 -1
- package/dist/api/presentation/placedViews.d.ts +1139 -0
- package/dist/api/presentation/placedViews.d.ts.map +1 -0
- package/dist/api/presentation/shapes.d.ts +481 -0
- package/dist/api/presentation/shapes.d.ts.map +1 -0
- package/dist/api/presentation/sheets.d.ts +452 -13
- package/dist/api/presentation/sheets.d.ts.map +1 -1
- package/dist/api/presentation/slideshow.d.ts +125 -0
- package/dist/api/presentation/slideshow.d.ts.map +1 -0
- package/dist/api/presentation/tables.d.ts +81 -0
- package/dist/api/presentation/tables.d.ts.map +1 -0
- package/dist/api/presentation/views.d.ts +367 -7
- package/dist/api/presentation/views.d.ts.map +1 -1
- package/dist/api/program/areas.d.ts +102 -12
- package/dist/api/program/areas.d.ts.map +1 -1
- package/dist/api/program/cores.d.ts +3 -99
- package/dist/api/program/cores.d.ts.map +1 -1
- package/dist/api/program/index.d.ts +7 -15
- package/dist/api/program/index.d.ts.map +1 -1
- package/dist/api/program/layout.d.ts +346 -11
- package/dist/api/program/layout.d.ts.map +1 -1
- package/dist/api/program/site.d.ts +469 -13
- package/dist/api/program/site.d.ts.map +1 -1
- package/dist/api/program/spreadsheet.d.ts +365 -41
- package/dist/api/program/spreadsheet.d.ts.map +1 -1
- package/dist/api/workspace/index.d.ts +505 -0
- package/dist/api/workspace/index.d.ts.map +1 -0
- package/dist/errors/codes.d.ts +34 -0
- package/dist/errors/codes.d.ts.map +1 -0
- package/dist/errors/envelope.d.ts +56 -0
- package/dist/errors/envelope.d.ts.map +1 -0
- package/dist/errors/index.d.ts +6 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/plugin-error.d.ts +69 -0
- package/dist/errors/plugin-error.d.ts.map +1 -0
- package/dist/handles.d.ts +97 -25
- package/dist/handles.d.ts.map +1 -1
- package/dist/host-utils.d.ts +4 -0
- package/dist/host-utils.d.ts.map +1 -1
- package/dist/index.cjs +4582 -1422
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4171 -1411
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
- package/scripts/generate-manifest.mjs +45 -0
- package/scripts/generate-manifest.test.mjs +103 -4
- package/src/api/analysis/daylight.ts +470 -0
- package/src/api/analysis/heatmaps.ts +683 -0
- package/src/api/analysis/illuminance.ts +155 -0
- package/src/api/analysis/index.ts +61 -0
- package/src/api/analysis/shadows.ts +183 -0
- package/src/api/analysis/solar.ts +237 -0
- package/src/api/analysis/sunlightHours.ts +211 -0
- package/src/api/analysis/sunpath.ts +83 -0
- package/src/api/analysis/weather.ts +179 -0
- package/src/api/core/camera/index.ts +268 -0
- package/src/api/core/comment/index.ts +120 -2
- package/src/api/core/geom/create/index.ts +912 -1
- package/src/api/core/geom/delete/index.ts +6 -0
- package/src/api/core/geom/query/brep.ts +119 -0
- package/src/api/core/handles/index.ts +233 -0
- package/src/api/core/index.ts +34 -0
- package/src/api/core/io/export/index.ts +126 -0
- package/src/api/core/io/import/index.ts +496 -0
- package/src/api/core/io/index.ts +42 -0
- package/src/api/core/io/job/index.ts +140 -0
- package/src/api/core/io/query/index.ts +71 -0
- package/src/api/core/io/terrain/index.ts +360 -0
- package/src/api/core/io/underlay/index.ts +705 -0
- package/src/api/core/mode/index.ts +96 -0
- package/src/api/core/project/index.ts +62 -1
- package/src/api/core/proposals/index.ts +569 -0
- package/src/api/core/storeys/index.ts +294 -0
- package/src/api/core/tags.ts +27 -0
- package/src/api/core/user.ts +46 -0
- package/src/api/core/zoom/index.ts +4 -0
- package/src/api/design/create/index.ts +670 -30
- package/src/api/design/delete/index.ts +3 -0
- package/src/api/design/doors/index.ts +208 -0
- package/src/api/design/erase/index.ts +1 -1
- package/src/api/design/family.ts +388 -0
- package/src/api/design/furniture/index.ts +197 -8
- package/src/api/design/index.ts +102 -0
- package/src/api/design/lock.ts +27 -0
- package/src/api/design/materials/index.ts +334 -27
- package/src/api/design/query/geometry/index.ts +125 -3
- package/src/api/design/query/index.ts +217 -7
- package/src/api/design/query/referenceLines.ts +52 -0
- package/src/api/design/query/spaces.ts +143 -0
- package/src/api/design/selection/index.ts +129 -0
- package/src/api/design/transform/index.ts +170 -9
- package/src/api/design/types/index.ts +156 -0
- package/src/api/design/update/index.ts +631 -3
- package/src/api/design/visibility.ts +143 -0
- package/src/api/design/windows/index.ts +128 -2
- package/src/api/entity/buildableEnvelope.ts +4 -0
- package/src/api/entity/referenceLine.ts +8 -0
- package/src/api/entity/story.ts +259 -15
- package/src/api/index.ts +10 -0
- package/src/api/presentation/annotate.ts +385 -0
- package/src/api/presentation/diagrams.ts +118 -8
- package/src/api/presentation/export.ts +108 -0
- package/src/api/presentation/import.ts +51 -4
- package/src/api/presentation/index.ts +66 -1
- package/src/api/presentation/placedViews.ts +1120 -0
- package/src/api/presentation/shapes.ts +274 -0
- package/src/api/presentation/sheets.ts +400 -13
- package/src/api/presentation/slideshow.ts +134 -0
- package/src/api/presentation/tables.ts +84 -0
- package/src/api/presentation/views.ts +376 -8
- package/src/api/program/areas.ts +88 -15
- package/src/api/program/cores.ts +3 -91
- package/src/api/program/index.ts +7 -15
- package/src/api/program/layout.ts +365 -11
- package/src/api/program/site.ts +435 -13
- package/src/api/program/spreadsheet.ts +376 -35
- package/src/api/workspace/index.ts +563 -0
- package/src/errors/codes.ts +136 -0
- package/src/errors/envelope.ts +75 -0
- package/src/errors/index.ts +21 -0
- package/src/errors/plugin-error.ts +134 -0
- package/src/handles.ts +123 -13
- package/src/host-utils.ts +4 -0
- package/src/index.ts +1 -0
- package/test/errors.test.mjs +184 -0
- package/tsconfig.json +7 -2
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as z from "zod"
|
|
2
2
|
import { PluginApiReturn } from "../../../types"
|
|
3
3
|
import {
|
|
4
|
+
BrepHandle,
|
|
4
5
|
ComponentHandle,
|
|
5
6
|
ContourHandle,
|
|
6
7
|
ProfileHandle,
|
|
@@ -11,6 +12,12 @@ import {
|
|
|
11
12
|
PluginMassType,
|
|
12
13
|
PluginDepartmentId,
|
|
13
14
|
} from "../../entity/space"
|
|
15
|
+
import {
|
|
16
|
+
PluginBuildableEnvelopePolygonVertex,
|
|
17
|
+
PluginBuildableEnvelopeSetbackTier,
|
|
18
|
+
PluginBuildableEnvelopeVerticalCap,
|
|
19
|
+
PluginBuildableEnvelopeCreateResult,
|
|
20
|
+
} from "../../entity/buildableEnvelope"
|
|
14
21
|
|
|
15
22
|
/**
|
|
16
23
|
* `design.create.*` — author new scene-committed BIM entities.
|
|
@@ -24,6 +31,13 @@ import {
|
|
|
24
31
|
* Footprint objects take a {@linkcode ContourHandle} (outer profile + holes);
|
|
25
32
|
* build one with `snaptrude.core.geom.create.contourFromProfile(s)`.
|
|
26
33
|
*
|
|
34
|
+
* `door`/`window` place a catalog item into a host wall (the world point is
|
|
35
|
+
* 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. `smartLayout` is
|
|
37
|
+
* the one creator returning a grouped {@linkcode PluginSmartLayoutResult} rather
|
|
38
|
+
* than a handle — it clones an in-scene template into one or more target spaces,
|
|
39
|
+
* merging every target into a single undo batch (see its JSDoc).
|
|
40
|
+
*
|
|
27
41
|
* Accessed via `snaptrude.design.create`.
|
|
28
42
|
*/
|
|
29
43
|
export abstract class PluginDesignCreateApi {
|
|
@@ -43,14 +57,25 @@ export abstract class PluginDesignCreateApi {
|
|
|
43
57
|
* @param spaceType - Space-type classification (default `Room`)
|
|
44
58
|
* @param massType - Mass-type classification (default `Room`)
|
|
45
59
|
* @param departmentId - Department assignment (default department)
|
|
60
|
+
* @param storey - Target storey number to place the space on — the same integer
|
|
61
|
+
* `entity.story` uses (`1` ground, `2` first floor, `-1` basement). Default:
|
|
62
|
+
* the active storey. Folds a `core.storeys.setActive` call into the create,
|
|
63
|
+
* placing the space at that storey's floor elevation (any `position` offset is
|
|
64
|
+
* applied on top). Throws if no storey has that value.
|
|
46
65
|
* @returns the {@linkcode ComponentHandle} of the created space
|
|
47
|
-
* @throws if the contour is invalid
|
|
66
|
+
* @throws if the contour is invalid, the height is not positive, or the target
|
|
67
|
+
* storey does not exist
|
|
48
68
|
*
|
|
49
69
|
* @examplePrompt Create a room called Living Room that's 3m tall from this outline
|
|
50
70
|
* @examplePrompt Add a new space on the current storey using this footprint
|
|
51
71
|
* @examplePrompt Make a bedroom here and assign it to the Residential department
|
|
52
72
|
* @examplePrompt Extrude this closed outline into a 10 foot high room
|
|
53
73
|
* @examplePrompt Can you create a Kitchen space from the sketch I just drew?
|
|
74
|
+
* @examplePrompt Create a bedroom on the second floor from this outline
|
|
75
|
+
*
|
|
76
|
+
* @performance For MORE THAN ONE space, call `design.create.spaces(items[])` — the whole
|
|
77
|
+
* batch is one host round-trip. Looping this single-space creator is N round-trips (slow,
|
|
78
|
+
* and a large loop can trip the plugin rate limit).
|
|
54
79
|
*
|
|
55
80
|
* # Example
|
|
56
81
|
* ```ts
|
|
@@ -63,6 +88,10 @@ export abstract class PluginDesignCreateApi {
|
|
|
63
88
|
* ])
|
|
64
89
|
* const contour = await snaptrude.core.geom.create.contourFromProfile(outer)
|
|
65
90
|
* const space = await snaptrude.design.create.space(contour, 3, "Living")
|
|
91
|
+
* // …place one directly on the second floor (no setActive dance):
|
|
92
|
+
* const upstairs = await snaptrude.design.create.space(
|
|
93
|
+
* contour, 3, "Bedroom", undefined, undefined, undefined, undefined, 2,
|
|
94
|
+
* )
|
|
66
95
|
* ```
|
|
67
96
|
*/
|
|
68
97
|
public abstract space(
|
|
@@ -73,6 +102,7 @@ export abstract class PluginDesignCreateApi {
|
|
|
73
102
|
spaceType?: PluginSpaceType,
|
|
74
103
|
massType?: PluginMassType,
|
|
75
104
|
departmentId?: PluginDepartmentId,
|
|
105
|
+
storey?: number,
|
|
76
106
|
): PluginApiReturn<ComponentHandle>
|
|
77
107
|
|
|
78
108
|
/**
|
|
@@ -107,6 +137,51 @@ export abstract class PluginDesignCreateApi {
|
|
|
107
137
|
massType?: PluginMassType,
|
|
108
138
|
): PluginApiReturn<ComponentHandle>
|
|
109
139
|
|
|
140
|
+
/**
|
|
141
|
+
* Create a **mass** from a custom solid built with a `core.geom.create` brep
|
|
142
|
+
* constructor (`brepFromFaces`, `brepFromExtrusion`, `brepFromLoft`,
|
|
143
|
+
* `brepFromMesh`, or a brep boolean) — the free-form counterpart of
|
|
144
|
+
* {@linkcode PluginDesignCreateApi.mass}, for solids that are not simple
|
|
145
|
+
* footprint extrusions (pyramids, wedges, faceted volumes).
|
|
146
|
+
*
|
|
147
|
+
* Only accepts breps **minted by a `core.geom.create` brep constructor** —
|
|
148
|
+
* scene-derived breps from `design.query.geometry.getBrep` are read-only and
|
|
149
|
+
* throw. The mass is created as a generic mass (`massType` "Generic mass") at
|
|
150
|
+
* the exact coordinates the solid was authored in, committed as a single
|
|
151
|
+
* undo step, and synced to collaborators like any other creator.
|
|
152
|
+
*
|
|
153
|
+
* @param brep - A solid from a `core.geom.create` brep constructor
|
|
154
|
+
* @param label - Label (maps to `room_type`)
|
|
155
|
+
* @returns the {@linkcode ComponentHandle} of the created mass
|
|
156
|
+
* @throws if the brep handle is invalid, or the brep was not created by a
|
|
157
|
+
* `core.geom.create` brep constructor
|
|
158
|
+
*
|
|
159
|
+
* @examplePrompt Create a mass from these faces
|
|
160
|
+
* @examplePrompt Turn this custom brep into a scene mass
|
|
161
|
+
* @examplePrompt Add a pyramid-shaped mass to the model
|
|
162
|
+
*
|
|
163
|
+
* # Example
|
|
164
|
+
* ```ts
|
|
165
|
+
* const apex = { x: 0, y: 4, z: 0 }
|
|
166
|
+
* const a = { x: -2, y: 0, z: -2 }
|
|
167
|
+
* const b = { x: 2, y: 0, z: -2 }
|
|
168
|
+
* const c = { x: 2, y: 0, z: 2 }
|
|
169
|
+
* const d = { x: -2, y: 0, z: 2 }
|
|
170
|
+
* const brep = await snaptrude.core.geom.create.brepFromFaces([
|
|
171
|
+
* [a, d, c, b],
|
|
172
|
+
* [a, b, apex],
|
|
173
|
+
* [b, c, apex],
|
|
174
|
+
* [c, d, apex],
|
|
175
|
+
* [d, a, apex],
|
|
176
|
+
* ])
|
|
177
|
+
* const pyramid = await snaptrude.design.create.massFromBrep(brep, "Pavilion")
|
|
178
|
+
* ```
|
|
179
|
+
*/
|
|
180
|
+
public abstract massFromBrep(
|
|
181
|
+
brep: BrepHandle,
|
|
182
|
+
label?: string,
|
|
183
|
+
): PluginApiReturn<ComponentHandle>
|
|
184
|
+
|
|
110
185
|
/**
|
|
111
186
|
* Create a **slab** by extruding a footprint contour by `thickness`
|
|
112
187
|
* (default direction: down).
|
|
@@ -222,14 +297,17 @@ export abstract class PluginDesignCreateApi {
|
|
|
222
297
|
|
|
223
298
|
/**
|
|
224
299
|
* Create a **column** by extruding a cross-section contour upward by `height`
|
|
225
|
-
* from a base `position`.
|
|
300
|
+
* from a base `position`. The column is built to EXACTLY `height` — unlike
|
|
301
|
+
* the interactive draw tool, no slab-thickness deduction is applied.
|
|
226
302
|
*
|
|
227
303
|
* @param position - Base point
|
|
228
304
|
* @param crossSection - Column cross-section footprint
|
|
229
|
-
* @param height - Column height (> 0)
|
|
230
|
-
* @param directionUp - Up axis (default world up)
|
|
305
|
+
* @param height - Column height (> 0), built exactly
|
|
306
|
+
* @param directionUp - Up axis (default world up); normalized by the host, so
|
|
307
|
+
* magnitude does not scale the height
|
|
231
308
|
* @returns the {@linkcode ComponentHandle} of the created column
|
|
232
|
-
* @throws if the cross-section is invalid
|
|
309
|
+
* @throws if the cross-section is invalid, the height is not positive, or the
|
|
310
|
+
* direction is zero / lies in the cross-section plane (degenerate extrusion)
|
|
233
311
|
*
|
|
234
312
|
* @examplePrompt Add a 3m tall column at this point
|
|
235
313
|
* @examplePrompt Place a column at the grid intersection
|
|
@@ -253,13 +331,30 @@ export abstract class PluginDesignCreateApi {
|
|
|
253
331
|
|
|
254
332
|
/**
|
|
255
333
|
* Create a **beam** by extruding a cross-section contour along `direction` by
|
|
256
|
-
* `length`.
|
|
334
|
+
* `length`. Matches the Snaptrude beam tool's semantics: the beam body hangs
|
|
335
|
+
* BELOW the plane the section is authored on.
|
|
336
|
+
*
|
|
337
|
+
* For a **horizontal** `direction` (the common spanning beam), author the
|
|
338
|
+
* section as an axis-aligned plan rectangle: its X extent is the beam's
|
|
339
|
+
* width, its Z extent is the beam's depth (the vertical drop). The beam runs
|
|
340
|
+
* `length` along `direction` starting at the section's centre, hanging below
|
|
341
|
+
* the authoring plane by its depth — exactly like an interactively drawn
|
|
342
|
+
* beam. Only axis-aligned rectangular sections are supported horizontally.
|
|
257
343
|
*
|
|
258
|
-
*
|
|
259
|
-
*
|
|
260
|
-
*
|
|
344
|
+
* For a **vertical** `direction` (the default), the section itself is
|
|
345
|
+
* extruded by `length`, again hanging below the authoring plane. Diagonal
|
|
346
|
+
* directions are rejected.
|
|
347
|
+
*
|
|
348
|
+
* @param section - Beam cross-section, an axis-aligned rectangle in plan
|
|
349
|
+
* (X extent = width, Z extent = depth)
|
|
350
|
+
* @param length - Beam length along `direction` (> 0); direction is
|
|
351
|
+
* normalized by the host, so magnitude does not scale the length
|
|
352
|
+
* @param direction - Beam axis: horizontal for a spanning beam, or vertical
|
|
353
|
+
* (default world up). Diagonal directions throw.
|
|
261
354
|
* @returns the {@linkcode ComponentHandle} of the created beam
|
|
262
|
-
* @throws if the section is invalid
|
|
355
|
+
* @throws if the section is invalid (horizontal beams: not an axis-aligned
|
|
356
|
+
* plan rectangle), the length is not positive, or the direction is zero or
|
|
357
|
+
* diagonal
|
|
263
358
|
*
|
|
264
359
|
* @examplePrompt Add a beam spanning 6 metres between the columns
|
|
265
360
|
* @examplePrompt Create a horizontal beam along the X axis
|
|
@@ -286,15 +381,31 @@ export abstract class PluginDesignCreateApi {
|
|
|
286
381
|
*
|
|
287
382
|
* @param profile - Ordered curve chain (wall centerlines)
|
|
288
383
|
* @param height - Wall height (default engine default)
|
|
289
|
-
* @param thickness - Wall thickness (default
|
|
384
|
+
* @param thickness - Wall thickness (default: the `wallType`'s total layer
|
|
385
|
+
* thickness when `wallType` is given, else the engine default)
|
|
386
|
+
* @param wallType - Wall type to build with — the same searchable list the
|
|
387
|
+
* Draw tab's Wall Type dropdown offers. Pass a name from
|
|
388
|
+
* `design.types.list("wall")` (the summary's `label`, or its `"wall:…"` id).
|
|
389
|
+
* Drives the wall's construction layers and default material, and — when
|
|
390
|
+
* `thickness` is omitted — its total layer thickness. Default: the engine's
|
|
391
|
+
* generic wall.
|
|
392
|
+
* @param storey - Target storey (integer: `1` ground, `2` first floor, `-1`
|
|
393
|
+
* basement — same convention as `design.create.space`). The walls are
|
|
394
|
+
* assigned to it and lifted to its base elevation, all inside the same
|
|
395
|
+
* single undo entry. The storey must already exist
|
|
396
|
+
* (`core.storeys.create` first). Default: geometry-derived — a profile
|
|
397
|
+
* drawn at y = 0 lands on storey 1; the ACTIVE storey is NOT consulted.
|
|
290
398
|
* @returns a {@linkcode ComponentHandle}`[]` (one per wall), in profile order
|
|
291
|
-
* @throws if the profile is empty
|
|
399
|
+
* @throws if the profile is empty, `wallType` names no wall type in the
|
|
400
|
+
* project, `storey` does not exist, or wall creation fails
|
|
292
401
|
*
|
|
293
402
|
* @examplePrompt Draw walls along this centerline
|
|
294
403
|
* @examplePrompt Create 3m high, 200mm thick walls from these points
|
|
295
404
|
* @examplePrompt Build a wall run around the room outline
|
|
296
405
|
* @examplePrompt Turn this polyline sketch into walls
|
|
297
406
|
* @examplePrompt Add walls with mitred corners along the path
|
|
407
|
+
* @examplePrompt Draw brick walls with plaster along this outline
|
|
408
|
+
* @examplePrompt Build the perimeter in exposed concrete walls
|
|
298
409
|
*
|
|
299
410
|
* # Example
|
|
300
411
|
* ```ts
|
|
@@ -305,12 +416,19 @@ export abstract class PluginDesignCreateApi {
|
|
|
305
416
|
* await v.new(8, 0, 6),
|
|
306
417
|
* ])
|
|
307
418
|
* const walls = await snaptrude.design.create.walls(centerlines, 3, 0.2)
|
|
419
|
+
* // …built as a specific wall type (layers/material/thickness from the type):
|
|
420
|
+
* const [brick] = await snaptrude.design.types.list("wall")
|
|
421
|
+
* const brickWalls = await snaptrude.design.create.walls(
|
|
422
|
+
* centerlines, 3, undefined, brick.label,
|
|
423
|
+
* )
|
|
308
424
|
* ```
|
|
309
425
|
*/
|
|
310
426
|
public abstract walls(
|
|
311
427
|
profile: ProfileHandle,
|
|
312
428
|
height?: number,
|
|
313
429
|
thickness?: number,
|
|
430
|
+
wallType?: string,
|
|
431
|
+
storey?: number,
|
|
314
432
|
): PluginApiReturn<ComponentHandle[]>
|
|
315
433
|
|
|
316
434
|
/**
|
|
@@ -318,12 +436,17 @@ export abstract class PluginDesignCreateApi {
|
|
|
318
436
|
*
|
|
319
437
|
* Geometry is procedurally generated from the chosen `preset`; there is no
|
|
320
438
|
* footprint input. Placed on the active structure/story unless overridden.
|
|
439
|
+
* The promise resolves only after the staircase's asynchronous geometry union
|
|
440
|
+
* and creation-command capture settle; a union failure rejects the call.
|
|
321
441
|
*
|
|
322
442
|
* @param preset - The parametric preset to generate
|
|
323
443
|
* @param position - Placement point
|
|
324
444
|
* @param label - Optional label
|
|
325
445
|
* @param structureId - Target structure (default active)
|
|
326
446
|
* @param level - Target level name (default active/`"01"`)
|
|
447
|
+
* @param dimensions - Optional positive dimension overrides in Snaptrude engine
|
|
448
|
+
* units, plus a placement angle in 90-degree increments. Overrides are
|
|
449
|
+
* applied to the staircase parameters before the creation command runs.
|
|
327
450
|
* @returns the {@linkcode ComponentHandle} of the created staircase
|
|
328
451
|
* @throws if the preset is unknown or placement fails
|
|
329
452
|
*
|
|
@@ -347,6 +470,7 @@ export abstract class PluginDesignCreateApi {
|
|
|
347
470
|
label?: string,
|
|
348
471
|
structureId?: string,
|
|
349
472
|
level?: string,
|
|
473
|
+
dimensions?: PluginStaircaseDimensions,
|
|
350
474
|
): PluginApiReturn<ComponentHandle>
|
|
351
475
|
|
|
352
476
|
/**
|
|
@@ -401,14 +525,23 @@ export abstract class PluginDesignCreateApi {
|
|
|
401
525
|
* with {@linkcode PluginDesignFurnitureApi.listCatalog}. Placement is asynchronous
|
|
402
526
|
* (the source mesh is fetched if not cached) and creates one undo entry.
|
|
403
527
|
*
|
|
404
|
-
* Placed at the item's default rotation
|
|
405
|
-
*
|
|
528
|
+
* Placed at the item's default rotation unless `angleInDegrees` is given, which
|
|
529
|
+
* rotates it about the vertical axis at creation time (baked into the same undo
|
|
530
|
+
* entry). To rotate an existing instance instead, use `design.transform.rotate`.
|
|
406
531
|
*
|
|
407
532
|
* @param catalogId - Library id: team `_id` or general `fullName`
|
|
408
|
-
* @param position - Absolute world placement point
|
|
533
|
+
* @param position - Absolute world placement point. `position.y` is the REST
|
|
534
|
+
* elevation: the item is grounded so its bounding-box base sits exactly at
|
|
535
|
+
* `position.y` (the same surface-flush contract as interactive drag-drop) —
|
|
536
|
+
* pass the floor/storey elevation to stand furniture on it; never add half
|
|
537
|
+
* the item's height yourself.
|
|
409
538
|
* @param options - Optional placement options: `label` — instance name
|
|
410
539
|
* (default auto `${name}Ins${n}`); `createNewSourceMesh` — emit a
|
|
411
540
|
* source-mesh creation command (default `true`)
|
|
541
|
+
* @param angleInDegrees - Optional signed rotation about the vertical axis, in
|
|
542
|
+
* degrees (same convention as {@linkcode PluginDesignTransformApi.rotate}).
|
|
543
|
+
* Applied at creation time so it is part of the placement's single undo entry.
|
|
544
|
+
* Default: the item's own (unrotated) orientation.
|
|
412
545
|
* @returns the {@linkcode ComponentHandle} of the placed furniture instance
|
|
413
546
|
* @throws if the catalog id is unknown, the source mesh fails to load, or placement fails
|
|
414
547
|
*
|
|
@@ -417,6 +550,7 @@ export abstract class PluginDesignCreateApi {
|
|
|
417
550
|
* @examplePrompt Drop a desk into the scene at 3, 0, 5
|
|
418
551
|
* @examplePrompt Insert the uploaded bed model in the bedroom
|
|
419
552
|
* @examplePrompt Put a table from my project library here and name it Table-01
|
|
553
|
+
* @examplePrompt Place a chair here rotated 90 degrees
|
|
420
554
|
*
|
|
421
555
|
* # Example
|
|
422
556
|
* ```ts
|
|
@@ -425,24 +559,235 @@ export abstract class PluginDesignCreateApi {
|
|
|
425
559
|
* await snaptrude.core.math.vec3.new(3, 0, 5),
|
|
426
560
|
* { label: "Chair-01" },
|
|
427
561
|
* )
|
|
562
|
+
* // …placed already turned 90° about the vertical axis:
|
|
563
|
+
* const turned = await snaptrude.design.create.furniture(
|
|
564
|
+
* "6620f1a…",
|
|
565
|
+
* await snaptrude.core.math.vec3.new(3, 0, 5),
|
|
566
|
+
* undefined,
|
|
567
|
+
* 90,
|
|
568
|
+
* )
|
|
428
569
|
* ```
|
|
429
570
|
*/
|
|
430
571
|
public abstract furniture(
|
|
431
572
|
catalogId: string,
|
|
432
573
|
position: Vec3Handle,
|
|
433
574
|
options?: { label?: string; createNewSourceMesh?: boolean },
|
|
575
|
+
angleInDegrees?: number,
|
|
576
|
+
): PluginApiReturn<ComponentHandle>
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* Place a **door** from the catalog into a host wall.
|
|
580
|
+
*
|
|
581
|
+
* Identified by a **catalog (library) id** — the team object's stable `_id`
|
|
582
|
+
* or the general library's `fullName`. Discover ids with
|
|
583
|
+
* {@linkcode PluginDesignDoorsApi.listCatalog}. The world `position` is
|
|
584
|
+
* projected onto the host wall's face to locate the opening; the wall is
|
|
585
|
+
* re-cut and the door hosted in a single undo entry. Placement is
|
|
586
|
+
* asynchronous (the source mesh is fetched if not cached).
|
|
587
|
+
*
|
|
588
|
+
* @param catalogId - Library id: team `_id` or general `fullName`
|
|
589
|
+
* @param hostWall - The wall to host the door
|
|
590
|
+
* @param position - World point projected onto the wall to locate the opening
|
|
591
|
+
* @param options - Optional placement options: `label` — instance name
|
|
592
|
+
* @param facing - World point selecting which side of the wall the door faces
|
|
593
|
+
* (the room it opens into) — the same convention as approaching the wall
|
|
594
|
+
* from that side with the cursor in the interactive tool. Any point clearly
|
|
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).
|
|
597
|
+
* @returns the {@linkcode ComponentHandle} of the placed door
|
|
598
|
+
* @throws if the catalog id is unknown, the host is not a wall, the source
|
|
599
|
+
* mesh fails to load, or the projected point falls **outside** the host wall
|
|
600
|
+
*
|
|
601
|
+
* @examplePrompt Add a door to this wall here
|
|
602
|
+
* @examplePrompt Place a sliding door on the selected wall
|
|
603
|
+
* @examplePrompt Put a door from the catalog at this point on the wall
|
|
604
|
+
* @examplePrompt Insert the entrance door into this wall
|
|
605
|
+
* @examplePrompt Add a door to the wall and call it Entry-01
|
|
606
|
+
* @examplePrompt Add a door that opens into the living room
|
|
607
|
+
*
|
|
608
|
+
* # Example
|
|
609
|
+
* ```ts
|
|
610
|
+
* const [wall] = await snaptrude.design.query.listWalls({ isSelected: true })
|
|
611
|
+
* const [entry] = await snaptrude.design.doors.listCatalog()
|
|
612
|
+
* const door = await snaptrude.design.create.door(
|
|
613
|
+
* entry.id,
|
|
614
|
+
* wall,
|
|
615
|
+
* await snaptrude.core.math.vec3.new(3, 0, 5),
|
|
616
|
+
* { label: "Entry-01" },
|
|
617
|
+
* )
|
|
618
|
+
* // …facing a specific side of the wall (pass a point inside that room):
|
|
619
|
+
* const intoKitchen = await snaptrude.design.create.door(
|
|
620
|
+
* entry.id,
|
|
621
|
+
* wall,
|
|
622
|
+
* await snaptrude.core.math.vec3.new(3, 0, 5),
|
|
623
|
+
* undefined,
|
|
624
|
+
* await snaptrude.core.math.vec3.new(3, 0, 9),
|
|
625
|
+
* )
|
|
626
|
+
* ```
|
|
627
|
+
*/
|
|
628
|
+
public abstract door(
|
|
629
|
+
catalogId: string,
|
|
630
|
+
hostWall: ComponentHandle,
|
|
631
|
+
position: Vec3Handle,
|
|
632
|
+
options?: { label?: string },
|
|
633
|
+
facing?: Vec3Handle,
|
|
634
|
+
): PluginApiReturn<ComponentHandle>
|
|
635
|
+
|
|
636
|
+
/**
|
|
637
|
+
* Place a **window** from the catalog into a host wall.
|
|
638
|
+
*
|
|
639
|
+
* Identified by a **catalog (library) id** — the team object's stable `_id`
|
|
640
|
+
* or the general library's `fullName`. Discover ids with
|
|
641
|
+
* {@linkcode PluginDesignWindowsApi.listCatalog}. The world `position` is
|
|
642
|
+
* projected onto the host wall's face to locate the opening; the wall is
|
|
643
|
+
* re-cut and the window hosted in a single undo entry. Placement is
|
|
644
|
+
* asynchronous (the source mesh is fetched if not cached).
|
|
645
|
+
*
|
|
646
|
+
* @param catalogId - Library id: team `_id` or general `fullName`
|
|
647
|
+
* @param hostWall - The wall to host the window
|
|
648
|
+
* @param position - World point projected onto the wall to locate the opening
|
|
649
|
+
* @param options - Optional placement options: `label` — instance name
|
|
650
|
+
* @param facing - World point selecting which side of the wall the window
|
|
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).
|
|
654
|
+
* @returns the {@linkcode ComponentHandle} of the placed window
|
|
655
|
+
* @throws if the catalog id is unknown, the host is not a wall, the source
|
|
656
|
+
* mesh fails to load, or the projected point falls **outside** the host wall
|
|
657
|
+
*
|
|
658
|
+
* @examplePrompt Add a window to this wall here
|
|
659
|
+
* @examplePrompt Place a casement window on the selected wall
|
|
660
|
+
* @examplePrompt Put a window from the catalog at this point on the wall
|
|
661
|
+
* @examplePrompt Insert a window into the living room wall
|
|
662
|
+
* @examplePrompt Add a window to the wall and name it Win-01
|
|
663
|
+
* @examplePrompt Add a casement window opening toward the garden side
|
|
664
|
+
*
|
|
665
|
+
* # Example
|
|
666
|
+
* ```ts
|
|
667
|
+
* const [wall] = await snaptrude.design.query.listWalls({ isSelected: true })
|
|
668
|
+
* const [entry] = await snaptrude.design.windows.listCatalog()
|
|
669
|
+
* const window = await snaptrude.design.create.window(
|
|
670
|
+
* entry.id,
|
|
671
|
+
* wall,
|
|
672
|
+
* await snaptrude.core.math.vec3.new(3, 0, 5),
|
|
673
|
+
* { label: "Win-01" },
|
|
674
|
+
* )
|
|
675
|
+
* ```
|
|
676
|
+
*/
|
|
677
|
+
public abstract window(
|
|
678
|
+
catalogId: string,
|
|
679
|
+
hostWall: ComponentHandle,
|
|
680
|
+
position: Vec3Handle,
|
|
681
|
+
options?: { label?: string },
|
|
682
|
+
facing?: Vec3Handle,
|
|
434
683
|
): PluginApiReturn<ComponentHandle>
|
|
435
684
|
|
|
685
|
+
/**
|
|
686
|
+
* Place a catalog **door or window** into a host wall with optional size overrides.
|
|
687
|
+
*
|
|
688
|
+
* The world `position` is projected onto the host wall to locate the opening.
|
|
689
|
+
* All supplied dimensions use Snaptrude engine units. Window `sillHeight` is
|
|
690
|
+
* measured from the host wall base to the bottom of the window, not to
|
|
691
|
+
* its center. Placement is asynchronous and committed as one undoable creation.
|
|
692
|
+
*
|
|
693
|
+
* @param options - Opening kind, catalog and host references, placement, and
|
|
694
|
+
* optional facing, label, and dimensions
|
|
695
|
+
* @returns the {@linkcode ComponentHandle} of the placed door or window
|
|
696
|
+
* @throws if the options are invalid, the catalog id is unknown, the host is
|
|
697
|
+
* not a wall, loading fails, or the opening cannot be placed on the host
|
|
698
|
+
*
|
|
699
|
+
* @examplePrompt Add a 1m wide door to this wall here
|
|
700
|
+
* @examplePrompt Place a window with a 0.9m sill height on the selected wall
|
|
701
|
+
*
|
|
702
|
+
* @performance Single-opening creator — use it for one hosted opening. A plural
|
|
703
|
+
* API is intentionally unavailable until host placement can be atomic.
|
|
704
|
+
*
|
|
705
|
+
* # Example
|
|
706
|
+
* ```ts
|
|
707
|
+
* const opening = await snaptrude.design.create.opening({
|
|
708
|
+
* kind: "window",
|
|
709
|
+
* catalogId: windowType.id,
|
|
710
|
+
* hostWall: wall,
|
|
711
|
+
* position: await snaptrude.core.math.vec3.new(3, 0, 5),
|
|
712
|
+
* width: 1.2,
|
|
713
|
+
* height: 1.5,
|
|
714
|
+
* sillHeight: 0.9,
|
|
715
|
+
* })
|
|
716
|
+
* ```
|
|
717
|
+
*/
|
|
718
|
+
public abstract opening(
|
|
719
|
+
options: PluginDesignCreateOpeningOptions,
|
|
720
|
+
): PluginApiReturn<ComponentHandle>
|
|
721
|
+
|
|
722
|
+
/**
|
|
723
|
+
* Place a **smart layout** — clone an in-scene template cluster (walls,
|
|
724
|
+
* furniture, doors, windows, floors) into one or more target ROOM/DEPARTMENT
|
|
725
|
+
* spaces, adapting orientation and fit to each target.
|
|
726
|
+
*
|
|
727
|
+
* Supply the template as **exactly one** of `templateGroup` (a group **id**
|
|
728
|
+
* from `snaptrude.core.groups.list` — groups are string-id entities, not
|
|
729
|
+
* component handles) or
|
|
730
|
+
* `templateComponents` (an explicit component set); every target in `targets`
|
|
731
|
+
* (≥1) receives its own placement. By default the target spaces are hidden
|
|
732
|
+
* after placement (`hideTargets`, mirroring the product) — pass `false` to keep
|
|
733
|
+
* them visible.
|
|
734
|
+
*
|
|
735
|
+
* The whole operation — every wall/opening/furniture/floor across every target,
|
|
736
|
+
* plus the target-hide — is committed as a **single undo step**. Because all
|
|
737
|
+
* targets merge into one creation batch, the created entities are returned
|
|
738
|
+
* **flat, grouped by kind** ({@linkcode PluginSmartLayoutResult}), NOT attributed
|
|
739
|
+
* per target (per-target attribution would break the single-undo guarantee).
|
|
740
|
+
* `skippedWalls` is the interior-optimizer's best-candidate count of walls it
|
|
741
|
+
* could not place. Synchronous and heavy — many targets can jank the main thread.
|
|
742
|
+
*
|
|
743
|
+
* @param options - {@linkcode PluginSmartLayoutArgs}: template source, targets, and `hideTargets`
|
|
744
|
+
* @returns a {@linkcode PluginSmartLayoutResult} — created entities grouped by kind + `skippedWalls`
|
|
745
|
+
* @throws if smart layout is not enabled, the template group is invalid, there
|
|
746
|
+
* is no template / no targets / no valid mappings, or component creation fails
|
|
747
|
+
*
|
|
748
|
+
* @examplePrompt Copy this room's layout into the selected rooms
|
|
749
|
+
* @examplePrompt Apply this furniture arrangement to the other offices
|
|
750
|
+
* @examplePrompt Replicate this template into these two spaces
|
|
751
|
+
* @examplePrompt Place this desk cluster into every meeting room
|
|
752
|
+
* @examplePrompt Use this room as a template for the rooms I selected but keep them visible
|
|
753
|
+
*
|
|
754
|
+
* # Example
|
|
755
|
+
* ```ts
|
|
756
|
+
* const [templateRoom, ...targets] = await snaptrude.design.query.listSpaces({ isSelected: true })
|
|
757
|
+
* const result = await snaptrude.design.create.smartLayout({
|
|
758
|
+
* templateComponents: [templateRoom],
|
|
759
|
+
* targets,
|
|
760
|
+
* })
|
|
761
|
+
* console.log("placed walls:", result.created.walls.length, "skipped:", result.skippedWalls)
|
|
762
|
+
*
|
|
763
|
+
* // …or clone a saved group by its id (from core.groups.list)
|
|
764
|
+
* const { groups } = await snaptrude.core.groups.list()
|
|
765
|
+
* await snaptrude.design.create.smartLayout({ templateGroup: groups[0].id, targets })
|
|
766
|
+
* ```
|
|
767
|
+
*/
|
|
768
|
+
public abstract smartLayout(
|
|
769
|
+
options: PluginSmartLayoutArgs,
|
|
770
|
+
): PluginApiReturn<PluginSmartLayoutResult>
|
|
771
|
+
|
|
436
772
|
/**
|
|
437
773
|
* **Copy** existing entities, offsetting each copy by `displacement * i` (i = 1…count),
|
|
438
774
|
* source positions preserved. Migrated from the removed `tools.copy`. In `"instance"`
|
|
439
775
|
* mode copies stay in the source's instance family where possible; `"unique"` makes
|
|
440
776
|
* independent geometry. The created copies become the active selection. Undoable.
|
|
441
777
|
*
|
|
778
|
+
* Runs on the engine's array-copy tool, so its semantics carry over: an
|
|
779
|
+
* `"instance"` copy of a source that is not yet an instance **replaces that
|
|
780
|
+
* source** with a fresh instance component — the handle you passed in stops
|
|
781
|
+
* resolving after the call. Re-query (e.g. `design.query.listSpaces`) to pick
|
|
782
|
+
* up the replacement before operating on that entity again; copying the stale
|
|
783
|
+
* handle throws. `"unique"` mode never replaces sources.
|
|
784
|
+
*
|
|
442
785
|
* @param components - Entities to copy (≥1)
|
|
443
786
|
* @param displacement - Per-copy offset as a {@linkcode Vec3Handle} (copy `i` at `displacement * i`)
|
|
444
787
|
* @param options - `count` (copies per component, default 1), `mode` (`"instance"` | `"unique"`, default `"instance"`)
|
|
445
788
|
* @returns the created copies as {@linkcode ComponentHandle}`[]`
|
|
789
|
+
* @throws if a component handle is unknown or stale (replaced by an earlier
|
|
790
|
+
* `"instance"` copy), `count` is not a positive integer, or the engine fails
|
|
446
791
|
*
|
|
447
792
|
* @examplePrompt Copy this room 3 times spaced 6m apart
|
|
448
793
|
* @examplePrompt Duplicate the selected furniture along the X axis
|
|
@@ -450,6 +795,11 @@ export abstract class PluginDesignCreateApi {
|
|
|
450
795
|
* @examplePrompt Array these walls with a 3m offset
|
|
451
796
|
* @examplePrompt Clone the desk as a unique copy, not an instance
|
|
452
797
|
*
|
|
798
|
+
* @performance To place N repeats of the same geometry, bulk-create the seed(s) once then
|
|
799
|
+
* call this ONCE with `{ count: N - 1 }` — one host round-trip for all copies. Never
|
|
800
|
+
* reproduce geometry by looping `design.create.*` N times. Copy only after the create
|
|
801
|
+
* that mints the seed ids.
|
|
802
|
+
*
|
|
453
803
|
* # Example
|
|
454
804
|
* ```ts
|
|
455
805
|
* const { vec3 } = snaptrude.core.math
|
|
@@ -467,15 +817,24 @@ export abstract class PluginDesignCreateApi {
|
|
|
467
817
|
* Migrated from the removed `entity.space.bulkCreate`. Each item extrudes a contour
|
|
468
818
|
* footprint up `height`. Validate-all-or-throw; one command. For a rectangular
|
|
469
819
|
* (box) space, build the footprint with `core.geom.create.profileRect` →
|
|
470
|
-
* `contourFromProfile`, then pass it as an item.
|
|
820
|
+
* `contourFromProfile`, then pass it as an item. Each item may carry its own
|
|
821
|
+
* `storey` (see {@linkcode PluginCreateSpaceItem}) so a single call can populate
|
|
822
|
+
* several floors at once.
|
|
471
823
|
*
|
|
472
824
|
* @param items - One {@linkcode PluginCreateSpaceItem} per space to create (≥1)
|
|
473
825
|
* @returns the created spaces as {@linkcode ComponentHandle}`[]`, in input order
|
|
826
|
+
* @throws if any item's contour is invalid, its height is not positive, or its
|
|
827
|
+
* target `storey` does not exist (all-or-nothing — nothing is created)
|
|
474
828
|
*
|
|
475
829
|
* @examplePrompt Create several rooms at once from these footprints
|
|
476
830
|
* @examplePrompt Generate all the bedrooms in one operation
|
|
477
831
|
* @examplePrompt Bulk create the spaces for this floor plan
|
|
478
832
|
* @examplePrompt Add three rooms with different heights in a single undo step
|
|
833
|
+
* @examplePrompt Create one room on the ground floor and one on the first floor
|
|
834
|
+
*
|
|
835
|
+
* @performance Bulk creator — the whole batch is ONE host round-trip. Always prefer this
|
|
836
|
+
* over calling `design.create.space` in a loop: build the full `items[]` array first
|
|
837
|
+
* (all per-item math and geometry up front), then make one call.
|
|
479
838
|
*
|
|
480
839
|
* # Example
|
|
481
840
|
* ```ts
|
|
@@ -487,7 +846,61 @@ export abstract class PluginDesignCreateApi {
|
|
|
487
846
|
* ])
|
|
488
847
|
* ```
|
|
489
848
|
*/
|
|
490
|
-
public abstract spaces(
|
|
849
|
+
public abstract spaces(
|
|
850
|
+
items: PluginCreateSpaceItem[],
|
|
851
|
+
): PluginApiReturn<ComponentHandle[]>
|
|
852
|
+
|
|
853
|
+
/**
|
|
854
|
+
* Create a new parametric buildable envelope — the zoning-regulated volume a
|
|
855
|
+
* building may occupy — generated from a site polygon, tiered setbacks, a
|
|
856
|
+
* height or floor-count cap, and optional FAR and lot-coverage limits. The host
|
|
857
|
+
* mints the envelope id and returns it. Canonical home of the create formerly
|
|
858
|
+
* at `entity.buildableEnvelope.create` (now deprecated).
|
|
859
|
+
*
|
|
860
|
+
* @param sitePolygon - Site polygon vertices in `lengthUnit`; minimum 3 vertices.
|
|
861
|
+
* @param lengthUnit - Unit used by all length fields (`"ft" | "m"`).
|
|
862
|
+
* @param setbacks - Setback profile, ground tier first; minimum 1 tier.
|
|
863
|
+
* @param verticalCap - Maximum height or floor count.
|
|
864
|
+
* @param floorToFloor - Required floor-to-floor height in `lengthUnit`.
|
|
865
|
+
* @param farRatio - Optional FAR value, positive when provided.
|
|
866
|
+
* @param lotCoverageMaxPct - Optional lot coverage cap, `0..100`.
|
|
867
|
+
* @returns A {@linkcode PluginBuildableEnvelopeCreateResult} with the
|
|
868
|
+
* `buildableEnvelopeId` of the created envelope.
|
|
869
|
+
* @throws If validation fails or generation produces no renderable geometry.
|
|
870
|
+
*
|
|
871
|
+
* @examplePrompt Create a buildable envelope for my site
|
|
872
|
+
* @examplePrompt Generate the zoning envelope with 10ft front setbacks
|
|
873
|
+
* @examplePrompt Show the maximum buildable volume with a 150ft height limit
|
|
874
|
+
* @examplePrompt Create a zoning envelope capped at 12 floors with FAR 3
|
|
875
|
+
*
|
|
876
|
+
* # Example
|
|
877
|
+
* ```ts
|
|
878
|
+
* const { buildableEnvelopeId } = await snaptrude.design.create.buildableEnvelope(
|
|
879
|
+
* [
|
|
880
|
+
* { x: 0, z: 0 },
|
|
881
|
+
* { x: 100, z: 0 },
|
|
882
|
+
* { x: 100, z: 80 },
|
|
883
|
+
* { x: 0, z: 80 },
|
|
884
|
+
* ],
|
|
885
|
+
* "ft",
|
|
886
|
+
* [
|
|
887
|
+
* { aboveHeight: 0, front: 10, side: 5, rear: 10 },
|
|
888
|
+
* { aboveHeight: 100, front: 20, side: 10, rear: 20 },
|
|
889
|
+
* ],
|
|
890
|
+
* { kind: "max_height", maxHeight: 150 },
|
|
891
|
+
* 12,
|
|
892
|
+
* )
|
|
893
|
+
* ```
|
|
894
|
+
*/
|
|
895
|
+
public abstract buildableEnvelope(
|
|
896
|
+
sitePolygon: PluginBuildableEnvelopePolygonVertex[],
|
|
897
|
+
lengthUnit: "ft" | "m",
|
|
898
|
+
setbacks: PluginBuildableEnvelopeSetbackTier[],
|
|
899
|
+
verticalCap: PluginBuildableEnvelopeVerticalCap,
|
|
900
|
+
floorToFloor: number,
|
|
901
|
+
farRatio?: number,
|
|
902
|
+
lotCoverageMaxPct?: number,
|
|
903
|
+
): PluginApiReturn<PluginBuildableEnvelopeCreateResult>
|
|
491
904
|
}
|
|
492
905
|
|
|
493
906
|
// ---------------------------------------------------------------------------
|
|
@@ -549,6 +962,24 @@ export const PluginStaircasePreset = z.enum([
|
|
|
549
962
|
])
|
|
550
963
|
export type PluginStaircasePreset = z.infer<typeof PluginStaircasePreset>
|
|
551
964
|
|
|
965
|
+
/**
|
|
966
|
+
* Optional staircase dimension overrides. Lengths use Snaptrude engine units
|
|
967
|
+
* and must be positive. `angleInDegrees` controls placement about the vertical
|
|
968
|
+
* axis and must be a multiple of 90 degrees.
|
|
969
|
+
*/
|
|
970
|
+
export const PluginStaircaseDimensions = z
|
|
971
|
+
.object({
|
|
972
|
+
width: z.number().finite().positive().optional(),
|
|
973
|
+
tread: z.number().finite().positive().optional(),
|
|
974
|
+
riser: z.number().finite().positive().optional(),
|
|
975
|
+
landingWidth: z.number().finite().positive().optional(),
|
|
976
|
+
angleInDegrees: z.number().finite().multipleOf(90).optional(),
|
|
977
|
+
})
|
|
978
|
+
.strict()
|
|
979
|
+
export type PluginStaircaseDimensions = z.infer<
|
|
980
|
+
typeof PluginStaircaseDimensions
|
|
981
|
+
>
|
|
982
|
+
|
|
552
983
|
// ---------------------------------------------------------------------------
|
|
553
984
|
// space
|
|
554
985
|
// ---------------------------------------------------------------------------
|
|
@@ -565,6 +996,7 @@ export type PluginStaircasePreset = z.infer<typeof PluginStaircasePreset>
|
|
|
565
996
|
* | `spaceType` | {@linkcode PluginSpaceType}? | Space-type classification (default `Room`) |
|
|
566
997
|
* | `massType` | {@linkcode PluginMassType}? | Mass-type classification (default `Room`) |
|
|
567
998
|
* | `departmentId` | {@linkcode PluginDepartmentId}? | Department assignment (default department) |
|
|
999
|
+
* | `storey` | `number`? (int) | Target storey number (default active storey) |
|
|
568
1000
|
*/
|
|
569
1001
|
export const PluginDesignCreateSpaceArgs = z.object({
|
|
570
1002
|
contour: ContourHandle,
|
|
@@ -574,8 +1006,13 @@ export const PluginDesignCreateSpaceArgs = z.object({
|
|
|
574
1006
|
spaceType: PluginSpaceType.optional(),
|
|
575
1007
|
massType: PluginMassType.optional(),
|
|
576
1008
|
departmentId: PluginDepartmentId.optional(),
|
|
1009
|
+
storey: z.number().int().optional(),
|
|
577
1010
|
})
|
|
578
|
-
export type PluginDesignCreateSpaceArgs = z.infer<
|
|
1011
|
+
export type PluginDesignCreateSpaceArgs = z.infer<
|
|
1012
|
+
typeof PluginDesignCreateSpaceArgs
|
|
1013
|
+
>
|
|
1014
|
+
// TRANSPORT: positional signature shipped — storey is the trailing 8th arg:
|
|
1015
|
+
// space(contour, height, label?, position?, spaceType?, massType?, departmentId?, storey?)
|
|
579
1016
|
|
|
580
1017
|
// ---------------------------------------------------------------------------
|
|
581
1018
|
// mass
|
|
@@ -599,7 +1036,29 @@ export const PluginDesignCreateMassArgs = z.object({
|
|
|
599
1036
|
position: Vec3Handle.optional(),
|
|
600
1037
|
massType: PluginMassType.optional(),
|
|
601
1038
|
})
|
|
602
|
-
export type PluginDesignCreateMassArgs = z.infer<
|
|
1039
|
+
export type PluginDesignCreateMassArgs = z.infer<
|
|
1040
|
+
typeof PluginDesignCreateMassArgs
|
|
1041
|
+
>
|
|
1042
|
+
|
|
1043
|
+
// ---------------------------------------------------------------------------
|
|
1044
|
+
// massFromBrep
|
|
1045
|
+
// ---------------------------------------------------------------------------
|
|
1046
|
+
|
|
1047
|
+
/**
|
|
1048
|
+
* Arguments for {@linkcode PluginDesignCreateApi.massFromBrep}.
|
|
1049
|
+
*
|
|
1050
|
+
* | Property | Type | Description |
|
|
1051
|
+
* |---|---|---|
|
|
1052
|
+
* | `brep` | {@linkcode BrepHandle} | A solid from a `core.geom.create` brep constructor |
|
|
1053
|
+
* | `label` | `string`? | Label (maps to `room_type`) |
|
|
1054
|
+
*/
|
|
1055
|
+
export const PluginDesignCreateMassFromBrepArgs = z.object({
|
|
1056
|
+
brep: BrepHandle,
|
|
1057
|
+
label: z.string().optional(),
|
|
1058
|
+
})
|
|
1059
|
+
export type PluginDesignCreateMassFromBrepArgs = z.infer<
|
|
1060
|
+
typeof PluginDesignCreateMassFromBrepArgs
|
|
1061
|
+
>
|
|
603
1062
|
|
|
604
1063
|
// ---------------------------------------------------------------------------
|
|
605
1064
|
// slab
|
|
@@ -621,7 +1080,9 @@ export const PluginDesignCreateSlabArgs = z.object({
|
|
|
621
1080
|
direction: z.enum(["up", "down"]).optional(),
|
|
622
1081
|
slabType: PluginSlabType.optional(),
|
|
623
1082
|
})
|
|
624
|
-
export type PluginDesignCreateSlabArgs = z.infer<
|
|
1083
|
+
export type PluginDesignCreateSlabArgs = z.infer<
|
|
1084
|
+
typeof PluginDesignCreateSlabArgs
|
|
1085
|
+
>
|
|
625
1086
|
|
|
626
1087
|
// ---------------------------------------------------------------------------
|
|
627
1088
|
// floor
|
|
@@ -641,7 +1102,9 @@ export const PluginDesignCreateFloorArgs = z.object({
|
|
|
641
1102
|
thickness: z.number(),
|
|
642
1103
|
position: Vec3Handle.optional(),
|
|
643
1104
|
})
|
|
644
|
-
export type PluginDesignCreateFloorArgs = z.infer<
|
|
1105
|
+
export type PluginDesignCreateFloorArgs = z.infer<
|
|
1106
|
+
typeof PluginDesignCreateFloorArgs
|
|
1107
|
+
>
|
|
645
1108
|
|
|
646
1109
|
// ---------------------------------------------------------------------------
|
|
647
1110
|
// roof
|
|
@@ -659,7 +1122,9 @@ export const PluginDesignCreateRoofArgs = z.object({
|
|
|
659
1122
|
contour: ContourHandle,
|
|
660
1123
|
thickness: z.number(),
|
|
661
1124
|
})
|
|
662
|
-
export type PluginDesignCreateRoofArgs = z.infer<
|
|
1125
|
+
export type PluginDesignCreateRoofArgs = z.infer<
|
|
1126
|
+
typeof PluginDesignCreateRoofArgs
|
|
1127
|
+
>
|
|
663
1128
|
|
|
664
1129
|
// ---------------------------------------------------------------------------
|
|
665
1130
|
// ceiling
|
|
@@ -679,7 +1144,9 @@ export const PluginDesignCreateCeilingArgs = z.object({
|
|
|
679
1144
|
thickness: z.number(),
|
|
680
1145
|
heightFromFloor: z.number().optional(),
|
|
681
1146
|
})
|
|
682
|
-
export type PluginDesignCreateCeilingArgs = z.infer<
|
|
1147
|
+
export type PluginDesignCreateCeilingArgs = z.infer<
|
|
1148
|
+
typeof PluginDesignCreateCeilingArgs
|
|
1149
|
+
>
|
|
683
1150
|
|
|
684
1151
|
// ---------------------------------------------------------------------------
|
|
685
1152
|
// column
|
|
@@ -701,7 +1168,9 @@ export const PluginDesignCreateColumnArgs = z.object({
|
|
|
701
1168
|
height: z.number(),
|
|
702
1169
|
directionUp: Vec3Handle.optional(),
|
|
703
1170
|
})
|
|
704
|
-
export type PluginDesignCreateColumnArgs = z.infer<
|
|
1171
|
+
export type PluginDesignCreateColumnArgs = z.infer<
|
|
1172
|
+
typeof PluginDesignCreateColumnArgs
|
|
1173
|
+
>
|
|
705
1174
|
|
|
706
1175
|
// ---------------------------------------------------------------------------
|
|
707
1176
|
// beam
|
|
@@ -721,7 +1190,9 @@ export const PluginDesignCreateBeamArgs = z.object({
|
|
|
721
1190
|
length: z.number(),
|
|
722
1191
|
direction: Vec3Handle.optional(),
|
|
723
1192
|
})
|
|
724
|
-
export type PluginDesignCreateBeamArgs = z.infer<
|
|
1193
|
+
export type PluginDesignCreateBeamArgs = z.infer<
|
|
1194
|
+
typeof PluginDesignCreateBeamArgs
|
|
1195
|
+
>
|
|
725
1196
|
|
|
726
1197
|
// ---------------------------------------------------------------------------
|
|
727
1198
|
// walls
|
|
@@ -734,14 +1205,22 @@ export type PluginDesignCreateBeamArgs = z.infer<typeof PluginDesignCreateBeamAr
|
|
|
734
1205
|
* |---|---|---|
|
|
735
1206
|
* | `profile` | {@linkcode ProfileHandle} | Ordered curve chain (wall centerlines) |
|
|
736
1207
|
* | `height` | `number`? | Wall height (default engine default) |
|
|
737
|
-
* | `thickness` | `number`? | Wall thickness (default engine default) |
|
|
1208
|
+
* | `thickness` | `number`? | Wall thickness (default: `wallType`'s total layer thickness when given, else engine default) |
|
|
1209
|
+
* | `wallType` | `string`? | Wall type name from `design.types.list("wall")` — layers/material/thickness defaults (default generic) |
|
|
1210
|
+
* | `storey` | `number`? | Target storey (integer, must exist) — walls assigned + lifted to its base in the same undo entry (default: geometry-derived) |
|
|
738
1211
|
*/
|
|
739
1212
|
export const PluginDesignCreateWallsArgs = z.object({
|
|
740
1213
|
profile: ProfileHandle,
|
|
741
1214
|
height: z.number().optional(),
|
|
742
1215
|
thickness: z.number().optional(),
|
|
1216
|
+
wallType: z.string().min(1).optional(),
|
|
1217
|
+
storey: z.number().int().optional(),
|
|
743
1218
|
})
|
|
744
|
-
export type PluginDesignCreateWallsArgs = z.infer<
|
|
1219
|
+
export type PluginDesignCreateWallsArgs = z.infer<
|
|
1220
|
+
typeof PluginDesignCreateWallsArgs
|
|
1221
|
+
>
|
|
1222
|
+
// TRANSPORT: positional signature shipped — storey is the trailing 5th arg:
|
|
1223
|
+
// walls(profile: ProfileHandle, height?: number, thickness?: number, wallType?: string, storey?: number)
|
|
745
1224
|
|
|
746
1225
|
// ---------------------------------------------------------------------------
|
|
747
1226
|
// staircase
|
|
@@ -757,6 +1236,7 @@ export type PluginDesignCreateWallsArgs = z.infer<typeof PluginDesignCreateWalls
|
|
|
757
1236
|
* | `label` | `string`? | Optional label |
|
|
758
1237
|
* | `structureId` | `string`? | Target structure (default active) |
|
|
759
1238
|
* | `level` | `string`? | Target level name (default active/`"01"`) |
|
|
1239
|
+
* | `dimensions` | {@linkcode PluginStaircaseDimensions}? | Positive dimension overrides in engine units, applied before creation |
|
|
760
1240
|
*/
|
|
761
1241
|
export const PluginDesignCreateStaircaseArgs = z.object({
|
|
762
1242
|
preset: PluginStaircasePreset,
|
|
@@ -764,6 +1244,7 @@ export const PluginDesignCreateStaircaseArgs = z.object({
|
|
|
764
1244
|
label: z.string().optional(),
|
|
765
1245
|
structureId: z.string().optional(),
|
|
766
1246
|
level: z.string().optional(),
|
|
1247
|
+
dimensions: PluginStaircaseDimensions.optional(),
|
|
767
1248
|
})
|
|
768
1249
|
export type PluginDesignCreateStaircaseArgs = z.infer<
|
|
769
1250
|
typeof PluginDesignCreateStaircaseArgs
|
|
@@ -782,18 +1263,173 @@ export type PluginDesignCreateStaircaseArgs = z.infer<
|
|
|
782
1263
|
* | `position` | {@linkcode Vec3Handle} | Absolute world placement point |
|
|
783
1264
|
* | `label` | `string`? | Instance name (default auto `${name}Ins${n}`) |
|
|
784
1265
|
* | `createNewSourceMesh` | `boolean`? | Emit a source-mesh creation command (default `true`) |
|
|
1266
|
+
* | `angleInDegrees` | `number`? | Rotation about the vertical axis, in degrees (default unrotated) |
|
|
785
1267
|
*/
|
|
786
1268
|
export const PluginDesignCreateFurnitureArgs = z.object({
|
|
787
1269
|
catalogId: z.string().min(1),
|
|
788
1270
|
position: Vec3Handle,
|
|
789
1271
|
label: z.string().optional(),
|
|
790
1272
|
createNewSourceMesh: z.boolean().optional(),
|
|
1273
|
+
angleInDegrees: z.number().optional(),
|
|
791
1274
|
})
|
|
792
1275
|
export type PluginDesignCreateFurnitureArgs = z.infer<
|
|
793
1276
|
typeof PluginDesignCreateFurnitureArgs
|
|
794
1277
|
>
|
|
795
|
-
// TRANSPORT: positional signature shipped —
|
|
796
|
-
// furniture(catalogId: string, position: Vec3Handle, options?: { label?, createNewSourceMesh? })
|
|
1278
|
+
// TRANSPORT: positional signature shipped — angleInDegrees is the trailing 4th arg:
|
|
1279
|
+
// furniture(catalogId: string, position: Vec3Handle, options?: { label?, createNewSourceMesh? }, angleInDegrees?: number)
|
|
1280
|
+
|
|
1281
|
+
// ---------------------------------------------------------------------------
|
|
1282
|
+
// door
|
|
1283
|
+
// ---------------------------------------------------------------------------
|
|
1284
|
+
|
|
1285
|
+
/**
|
|
1286
|
+
* Arguments for {@linkcode PluginDesignCreateApi.door}.
|
|
1287
|
+
*
|
|
1288
|
+
* | Property | Type | Description |
|
|
1289
|
+
* |---|---|---|
|
|
1290
|
+
* | `catalogId` | `string` | Library id: team `_id` or general `fullName` |
|
|
1291
|
+
* | `hostWall` | {@linkcode ComponentHandle} | The wall to host the door |
|
|
1292
|
+
* | `position` | {@linkcode Vec3Handle} | World point projected onto the wall |
|
|
1293
|
+
* | `label` | `string`? | Instance name (optional) |
|
|
1294
|
+
* | `facing` | {@linkcode Vec3Handle}? | World point on the side of the wall the door faces (default engine-chosen) |
|
|
1295
|
+
*/
|
|
1296
|
+
export const PluginDesignCreateDoorArgs = z.object({
|
|
1297
|
+
catalogId: z.string().min(1),
|
|
1298
|
+
hostWall: ComponentHandle,
|
|
1299
|
+
position: Vec3Handle,
|
|
1300
|
+
label: z.string().optional(),
|
|
1301
|
+
facing: Vec3Handle.optional(),
|
|
1302
|
+
})
|
|
1303
|
+
export type PluginDesignCreateDoorArgs = z.infer<
|
|
1304
|
+
typeof PluginDesignCreateDoorArgs
|
|
1305
|
+
>
|
|
1306
|
+
// TRANSPORT: positional signature shipped — facing is the trailing 5th arg:
|
|
1307
|
+
// door(catalogId: string, hostWall: ComponentHandle, position: Vec3Handle, options?: { label? }, facing?: Vec3Handle)
|
|
1308
|
+
|
|
1309
|
+
// ---------------------------------------------------------------------------
|
|
1310
|
+
// window
|
|
1311
|
+
// ---------------------------------------------------------------------------
|
|
1312
|
+
|
|
1313
|
+
/**
|
|
1314
|
+
* Arguments for {@linkcode PluginDesignCreateApi.window}.
|
|
1315
|
+
*
|
|
1316
|
+
* | Property | Type | Description |
|
|
1317
|
+
* |---|---|---|
|
|
1318
|
+
* | `catalogId` | `string` | Library id: team `_id` or general `fullName` |
|
|
1319
|
+
* | `hostWall` | {@linkcode ComponentHandle} | The wall to host the window |
|
|
1320
|
+
* | `position` | {@linkcode Vec3Handle} | World point projected onto the wall |
|
|
1321
|
+
* | `label` | `string`? | Instance name (optional) |
|
|
1322
|
+
* | `facing` | {@linkcode Vec3Handle}? | World point on the side of the wall the window faces (default engine-chosen) |
|
|
1323
|
+
*/
|
|
1324
|
+
export const PluginDesignCreateWindowArgs = z.object({
|
|
1325
|
+
catalogId: z.string().min(1),
|
|
1326
|
+
hostWall: ComponentHandle,
|
|
1327
|
+
position: Vec3Handle,
|
|
1328
|
+
label: z.string().optional(),
|
|
1329
|
+
facing: Vec3Handle.optional(),
|
|
1330
|
+
})
|
|
1331
|
+
export type PluginDesignCreateWindowArgs = z.infer<
|
|
1332
|
+
typeof PluginDesignCreateWindowArgs
|
|
1333
|
+
>
|
|
1334
|
+
// TRANSPORT: positional signature shipped — facing is the trailing 5th arg:
|
|
1335
|
+
// window(catalogId: string, hostWall: ComponentHandle, position: Vec3Handle, options?: { label? }, facing?: Vec3Handle)
|
|
1336
|
+
|
|
1337
|
+
// ---------------------------------------------------------------------------
|
|
1338
|
+
// opening
|
|
1339
|
+
// ---------------------------------------------------------------------------
|
|
1340
|
+
|
|
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
|
+
/**
|
|
1352
|
+
* Options for {@linkcode PluginDesignCreateApi.opening}, discriminated by
|
|
1353
|
+
* `kind`. Width and height are positive Snaptrude engine-unit values.
|
|
1354
|
+
* `sillHeight` is available only for windows, is nonnegative, and is precisely
|
|
1355
|
+
* the distance from the host wall base to the bottom of the window.
|
|
1356
|
+
*/
|
|
1357
|
+
export const PluginDesignCreateOpeningOptions = z.discriminatedUnion("kind", [
|
|
1358
|
+
z
|
|
1359
|
+
.object({
|
|
1360
|
+
kind: z.literal("door"),
|
|
1361
|
+
...PluginOpeningBaseOptions,
|
|
1362
|
+
})
|
|
1363
|
+
.strict(),
|
|
1364
|
+
z
|
|
1365
|
+
.object({
|
|
1366
|
+
kind: z.literal("window"),
|
|
1367
|
+
...PluginOpeningBaseOptions,
|
|
1368
|
+
sillHeight: z.number().finite().nonnegative().optional(),
|
|
1369
|
+
})
|
|
1370
|
+
.strict(),
|
|
1371
|
+
])
|
|
1372
|
+
export type PluginDesignCreateOpeningOptions = z.infer<
|
|
1373
|
+
typeof PluginDesignCreateOpeningOptions
|
|
1374
|
+
>
|
|
1375
|
+
|
|
1376
|
+
// ---------------------------------------------------------------------------
|
|
1377
|
+
// smartLayout
|
|
1378
|
+
// ---------------------------------------------------------------------------
|
|
1379
|
+
|
|
1380
|
+
/**
|
|
1381
|
+
* Arguments for {@linkcode PluginDesignCreateApi.smartLayout}. Provide **exactly
|
|
1382
|
+
* one** template source: `templateGroup` or a non-empty `templateComponents`.
|
|
1383
|
+
*
|
|
1384
|
+
* | Property | Type | Description |
|
|
1385
|
+
* |---|---|---|
|
|
1386
|
+
* | `templateGroup` | `string`? | Id of the group to clone as the template (a group id from `snaptrude.core.groups.list`, NOT a component handle) |
|
|
1387
|
+
* | `templateComponents` | {@linkcode ComponentHandle}`[]`? | Explicit component set to clone as the template |
|
|
1388
|
+
* | `targets` | {@linkcode ComponentHandle}`[]` | ROOM/DEPARTMENT spaces to place into (≥1) |
|
|
1389
|
+
* | `hideTargets` | `boolean`? | Hide the target spaces after placement (default `true`) |
|
|
1390
|
+
*/
|
|
1391
|
+
export const PluginSmartLayoutArgs = z
|
|
1392
|
+
.object({
|
|
1393
|
+
templateGroup: z.string().min(1).optional(),
|
|
1394
|
+
templateComponents: z.array(ComponentHandle).optional(),
|
|
1395
|
+
targets: z.array(ComponentHandle).min(1),
|
|
1396
|
+
hideTargets: z.boolean().optional(),
|
|
1397
|
+
})
|
|
1398
|
+
.refine(
|
|
1399
|
+
(v) =>
|
|
1400
|
+
(v.templateGroup != null) !== (v.templateComponents?.length ?? 0) > 0,
|
|
1401
|
+
{
|
|
1402
|
+
message:
|
|
1403
|
+
"Provide exactly one template source: templateGroup or a non-empty templateComponents",
|
|
1404
|
+
},
|
|
1405
|
+
)
|
|
1406
|
+
export type PluginSmartLayoutArgs = z.infer<typeof PluginSmartLayoutArgs>
|
|
1407
|
+
|
|
1408
|
+
/**
|
|
1409
|
+
* Result of {@linkcode PluginDesignCreateApi.smartLayout} — the entities the run
|
|
1410
|
+
* created, grouped by kind (flat across all targets; see the method JSDoc for why
|
|
1411
|
+
* this is not attributed per target).
|
|
1412
|
+
*
|
|
1413
|
+
* | Property | Type | Description |
|
|
1414
|
+
* |---|---|---|
|
|
1415
|
+
* | `created.walls` | {@linkcode ComponentHandle}`[]` | Created walls |
|
|
1416
|
+
* | `created.furniture` | {@linkcode ComponentHandle}`[]` | Created furniture |
|
|
1417
|
+
* | `created.doors` | {@linkcode ComponentHandle}`[]` | Created doors |
|
|
1418
|
+
* | `created.windows` | {@linkcode ComponentHandle}`[]` | Created windows |
|
|
1419
|
+
* | `created.floors` | {@linkcode ComponentHandle}`[]` | Created floors |
|
|
1420
|
+
* | `skippedWalls` | `number` | Walls the interior optimizer could not place |
|
|
1421
|
+
*/
|
|
1422
|
+
export const PluginSmartLayoutResult = z.object({
|
|
1423
|
+
created: z.object({
|
|
1424
|
+
walls: z.array(ComponentHandle),
|
|
1425
|
+
furniture: z.array(ComponentHandle),
|
|
1426
|
+
doors: z.array(ComponentHandle),
|
|
1427
|
+
windows: z.array(ComponentHandle),
|
|
1428
|
+
floors: z.array(ComponentHandle),
|
|
1429
|
+
}),
|
|
1430
|
+
skippedWalls: z.number(),
|
|
1431
|
+
})
|
|
1432
|
+
export type PluginSmartLayoutResult = z.infer<typeof PluginSmartLayoutResult>
|
|
797
1433
|
|
|
798
1434
|
// ---------------------------------------------------------------------------
|
|
799
1435
|
// referenceLines
|
|
@@ -852,7 +1488,9 @@ export const PluginDesignCreateCopyArgs = z.object({
|
|
|
852
1488
|
count: z.number().int().positive().optional(),
|
|
853
1489
|
mode: PluginCopyMode.optional(),
|
|
854
1490
|
})
|
|
855
|
-
export type PluginDesignCreateCopyArgs = z.infer<
|
|
1491
|
+
export type PluginDesignCreateCopyArgs = z.infer<
|
|
1492
|
+
typeof PluginDesignCreateCopyArgs
|
|
1493
|
+
>
|
|
856
1494
|
// TRANSPORT: positional signature shipped —
|
|
857
1495
|
// copy(components: ComponentHandle[], displacement: Vec3Handle, options?: { count?, mode? })
|
|
858
1496
|
|
|
@@ -873,6 +1511,7 @@ export type PluginDesignCreateCopyArgs = z.infer<typeof PluginDesignCreateCopyAr
|
|
|
873
1511
|
* | `spaceType` | `PluginSpaceType`? | Space type |
|
|
874
1512
|
* | `massType` | `PluginMassType`? | Mass type |
|
|
875
1513
|
* | `departmentId` | `PluginDepartmentId`? | Department |
|
|
1514
|
+
* | `storey` | `number`? (int) | Target storey number (default active storey) |
|
|
876
1515
|
*/
|
|
877
1516
|
export const PluginCreateSpaceItem = z.object({
|
|
878
1517
|
contour: ContourHandle,
|
|
@@ -882,5 +1521,6 @@ export const PluginCreateSpaceItem = z.object({
|
|
|
882
1521
|
spaceType: PluginSpaceType.optional(),
|
|
883
1522
|
massType: PluginMassType.optional(),
|
|
884
1523
|
departmentId: PluginDepartmentId.optional(),
|
|
1524
|
+
storey: z.number().int().optional(),
|
|
885
1525
|
})
|
|
886
1526
|
export type PluginCreateSpaceItem = z.infer<typeof PluginCreateSpaceItem>
|