@snaptrude/plugin-core 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -1
- package/api-manifest.full.json +1350 -89
- package/api-manifest.json +826 -40
- 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 +438 -14
- package/dist/api/analysis/heatmaps.d.ts.map +1 -1
- package/dist/api/analysis/index.d.ts +15 -0
- package/dist/api/analysis/index.d.ts.map +1 -1
- package/dist/api/analysis/solar.d.ts +249 -0
- package/dist/api/analysis/solar.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 +37 -0
- package/dist/api/core/camera/index.d.ts.map +1 -1
- package/dist/api/core/geom/create/index.d.ts +318 -1
- package/dist/api/core/geom/create/index.d.ts.map +1 -1
- package/dist/api/core/index.d.ts +9 -0
- package/dist/api/core/index.d.ts.map +1 -1
- package/dist/api/core/io/export/index.d.ts +3 -1
- package/dist/api/core/io/export/index.d.ts.map +1 -1
- package/dist/api/core/io/import/index.d.ts +61 -0
- package/dist/api/core/io/import/index.d.ts.map +1 -1
- 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/storeys/index.d.ts +251 -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/zoom/index.d.ts +4 -0
- package/dist/api/core/zoom/index.d.ts.map +1 -1
- package/dist/api/design/create/index.d.ts +115 -4
- 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/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 +4 -0
- 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 +173 -0
- package/dist/api/design/query/spaces.d.ts.map +1 -1
- package/dist/api/design/transform/index.d.ts +12 -0
- package/dist/api/design/transform/index.d.ts.map +1 -1
- package/dist/api/design/update/index.d.ts +51 -1
- package/dist/api/design/update/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 +8 -0
- package/dist/api/entity/referenceLine.d.ts.map +1 -1
- package/dist/api/entity/story.d.ts +20 -0
- package/dist/api/entity/story.d.ts.map +1 -1
- package/dist/api/index.d.ts +5 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/presentation/export.d.ts +4 -0
- package/dist/api/presentation/export.d.ts.map +1 -1
- package/dist/api/presentation/import.d.ts +6 -0
- package/dist/api/presentation/import.d.ts.map +1 -1
- package/dist/api/presentation/index.d.ts +9 -0
- package/dist/api/presentation/index.d.ts.map +1 -1
- package/dist/api/presentation/placedViews.d.ts +370 -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/program/site.d.ts +94 -0
- package/dist/api/program/site.d.ts.map +1 -1
- package/dist/api/program/spreadsheet.d.ts +260 -28
- package/dist/api/program/spreadsheet.d.ts.map +1 -1
- package/dist/api/workspace/index.d.ts +460 -0
- package/dist/api/workspace/index.d.ts.map +1 -0
- package/dist/index.cjs +2625 -1758
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2515 -1758
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
- package/scripts/generate-manifest.mjs +45 -0
- package/src/api/analysis/daylight.ts +470 -0
- package/src/api/analysis/heatmaps.ts +444 -17
- package/src/api/analysis/index.ts +15 -0
- package/src/api/analysis/solar.ts +237 -0
- package/src/api/analysis/weather.ts +179 -0
- package/src/api/core/camera/index.ts +39 -0
- package/src/api/core/geom/create/index.ts +344 -1
- package/src/api/core/index.ts +9 -0
- package/src/api/core/io/export/index.ts +3 -1
- package/src/api/core/io/import/index.ts +64 -0
- package/src/api/core/mode/index.ts +96 -0
- package/src/api/core/storeys/index.ts +279 -0
- package/src/api/core/tags.ts +27 -0
- package/src/api/core/zoom/index.ts +4 -0
- package/src/api/design/create/index.ts +138 -1
- package/src/api/design/delete/index.ts +3 -0
- package/src/api/design/query/geometry/index.ts +125 -3
- package/src/api/design/query/index.ts +4 -0
- package/src/api/design/query/referenceLines.ts +52 -0
- package/src/api/design/query/spaces.ts +143 -0
- package/src/api/design/transform/index.ts +12 -0
- package/src/api/design/update/index.ts +66 -1
- package/src/api/entity/buildableEnvelope.ts +4 -0
- package/src/api/entity/referenceLine.ts +8 -0
- package/src/api/entity/story.ts +20 -0
- package/src/api/index.ts +5 -0
- package/src/api/presentation/export.ts +4 -0
- package/src/api/presentation/import.ts +6 -0
- package/src/api/presentation/index.ts +9 -0
- package/src/api/presentation/placedViews.ts +363 -0
- package/src/api/presentation/shapes.ts +274 -0
- package/src/api/program/site.ts +95 -0
- package/src/api/program/spreadsheet.ts +251 -6
- package/src/api/workspace/index.ts +516 -0
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
import * as z from "zod"
|
|
2
|
+
import { PluginApiReturn } from "../../../types"
|
|
3
|
+
import { ComponentHandle } from "../../../handles"
|
|
4
|
+
import {
|
|
5
|
+
PluginStoryGetProperty,
|
|
6
|
+
PluginStoryGetResult,
|
|
7
|
+
PluginStoryGetAllResult,
|
|
8
|
+
PluginStoryCreateResult,
|
|
9
|
+
PluginStoryUpdateResult,
|
|
10
|
+
PluginStorySetActiveResult,
|
|
11
|
+
PluginStoryDeleteResult,
|
|
12
|
+
PluginStoryDuplicateResult,
|
|
13
|
+
} from "../../entity/story"
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Storey (floor) management.
|
|
17
|
+
*
|
|
18
|
+
* A storey represents a building floor in the Snaptrude project. Storeys are
|
|
19
|
+
* identified by their integer **storey value** (e.g. `1` for the ground floor,
|
|
20
|
+
* `2` for the first floor, `-1` for a basement).
|
|
21
|
+
*
|
|
22
|
+
* This is the canonical home for storey operations; it shares its implementation
|
|
23
|
+
* and schemas with the deprecated `entity.story` surface. All methods are **host
|
|
24
|
+
* API calls** that return Promises and support undo/redo via Snaptrude's command
|
|
25
|
+
* system (except {@linkcode PluginCoreStoreysApi.setActive}, a view change).
|
|
26
|
+
*
|
|
27
|
+
* Accessed via `snaptrude.core.storeys`.
|
|
28
|
+
*/
|
|
29
|
+
export abstract class PluginCoreStoreysApi {
|
|
30
|
+
constructor() {}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Get properties of a storey by its storey number.
|
|
34
|
+
*
|
|
35
|
+
* Only the properties listed in `properties` are returned — unlisted
|
|
36
|
+
* properties will be `undefined` in the result.
|
|
37
|
+
*
|
|
38
|
+
* @param storyValue - Integer storey number
|
|
39
|
+
* (e.g. `1` for ground floor, `2` for first floor, `-1` for basement)
|
|
40
|
+
* @param properties - Array of property names to retrieve. See
|
|
41
|
+
* {@linkcode PluginStoryGetProperty} for available values.
|
|
42
|
+
* @returns A partial {@linkcode PluginStoryGetResult} containing only the requested properties
|
|
43
|
+
* @throws If the storey with the given value does not exist
|
|
44
|
+
*
|
|
45
|
+
* @examplePrompt What is the height of the ground floor?
|
|
46
|
+
* @examplePrompt How many rooms are on the second storey?
|
|
47
|
+
* @examplePrompt Get the total floor area of level 3
|
|
48
|
+
* @examplePrompt Is the first floor hidden in the viewport?
|
|
49
|
+
* @examplePrompt Show me the name and height of storey 2
|
|
50
|
+
*
|
|
51
|
+
* # Example
|
|
52
|
+
* ```ts
|
|
53
|
+
* const info = await snaptrude.core.storeys.get(1, ["height", "name", "spacesCount"])
|
|
54
|
+
* console.log(info.name, info.height, info.spacesCount)
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
public abstract get(
|
|
58
|
+
storyValue: number,
|
|
59
|
+
properties: PluginStoryGetProperty[],
|
|
60
|
+
): PluginApiReturn<PluginStoryGetResult>
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* List all storeys in the current project.
|
|
64
|
+
*
|
|
65
|
+
* Returns basic identification data for every storey. Storeys are sorted
|
|
66
|
+
* from **top to bottom** (highest storey value first).
|
|
67
|
+
*
|
|
68
|
+
* @returns A {@linkcode PluginCoreStoreysListResult} with a `storeys` array,
|
|
69
|
+
* each entry containing `value`, `id`, and `name`
|
|
70
|
+
*
|
|
71
|
+
* @examplePrompt How many floors does this building have?
|
|
72
|
+
* @examplePrompt List all the storeys in the project
|
|
73
|
+
* @examplePrompt Show me every level with its name
|
|
74
|
+
* @examplePrompt Which storeys exist in this model?
|
|
75
|
+
*
|
|
76
|
+
* # Example
|
|
77
|
+
* ```ts
|
|
78
|
+
* const { storeys } = await snaptrude.core.storeys.list()
|
|
79
|
+
* for (const s of storeys) {
|
|
80
|
+
* console.log(`Storey ${s.value}: ${s.name} (id: ${s.id})`)
|
|
81
|
+
* }
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
public abstract list(): PluginApiReturn<PluginCoreStoreysListResult>
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Create a new storey (floor) in the project.
|
|
88
|
+
*
|
|
89
|
+
* The new storey is inserted at the position specified by `storyValue`. This
|
|
90
|
+
* operation is undoable.
|
|
91
|
+
*
|
|
92
|
+
* @param storyValue - Integer storey number
|
|
93
|
+
* to create (e.g. `3` to add a third floor)
|
|
94
|
+
* @param height - Optional height in Babylon
|
|
95
|
+
* units. If omitted, the project's default storey height is used.
|
|
96
|
+
* @returns A {@linkcode PluginStoryCreateResult} with `storyId` and `storyValue`
|
|
97
|
+
* @throws If a storey with the given value already exists or creation fails
|
|
98
|
+
*
|
|
99
|
+
* @examplePrompt Add a third floor to the building
|
|
100
|
+
* @examplePrompt Create a new storey above the second floor
|
|
101
|
+
* @examplePrompt Add a basement level to this project
|
|
102
|
+
* @examplePrompt Insert a new level with a custom floor height
|
|
103
|
+
*
|
|
104
|
+
* # Example
|
|
105
|
+
* ```ts
|
|
106
|
+
* // Create a new third floor with custom height
|
|
107
|
+
* const { storyId } = await snaptrude.core.storeys.create(3, 4.5)
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
public abstract create(
|
|
111
|
+
storyValue: number,
|
|
112
|
+
height?: number,
|
|
113
|
+
): PluginApiReturn<PluginStoryCreateResult>
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Update a storey's floor-to-floor `height` and/or `name`.
|
|
117
|
+
*
|
|
118
|
+
* **Height** is the same operation as editing the height in the Storeys panel:
|
|
119
|
+
* the walls, columns, and masses on the storey are **stretched** to the new
|
|
120
|
+
* height, every storey **above shifts up/down** by the delta so the stack stays
|
|
121
|
+
* contiguous, and coupled elements (staircases, parametric curtain walls,
|
|
122
|
+
* furniture offsets) are re-fitted. The whole height cascade is committed as
|
|
123
|
+
* **one undo step**. Height-locked elements are left untouched.
|
|
124
|
+
*
|
|
125
|
+
* **Name** is the same as renaming the storey in the Storeys panel: it is
|
|
126
|
+
* persisted immediately but, mirroring the panel, is **not** part of the height
|
|
127
|
+
* undo step.
|
|
128
|
+
*
|
|
129
|
+
* At least one of `height` or `options.name` must be supplied. Omitting the
|
|
130
|
+
* `height` argument (e.g. for a rename-only update) leaves the height untouched.
|
|
131
|
+
*
|
|
132
|
+
* @param storyValue - Integer storey number identifying the storey to update
|
|
133
|
+
* @param height - New floor-to-floor height in
|
|
134
|
+
* Babylon units. Omit to leave the height unchanged.
|
|
135
|
+
* @param options - `name` (new display name for the storey)
|
|
136
|
+
* @returns A {@linkcode PluginStoryUpdateResult} with the storey's
|
|
137
|
+
* `storyValue`, `height`, and `name` after the update
|
|
138
|
+
* @throws `PRECONDITION_FAILED` if no storey has the given value;
|
|
139
|
+
* `VALIDATION` if neither `height` nor `options.name` is supplied;
|
|
140
|
+
* `STORY_HEIGHT_REJECTED` if the engine rejects the height;
|
|
141
|
+
* `STORY_UPDATE_FAILED` if the storey cannot be re-read after the update
|
|
142
|
+
*
|
|
143
|
+
* @examplePrompt Change the ground floor height to 3.5 metres
|
|
144
|
+
* @examplePrompt Make the second storey taller
|
|
145
|
+
* @examplePrompt Rename the ground floor to "Lobby"
|
|
146
|
+
* @examplePrompt Set the floor-to-floor height of level 1
|
|
147
|
+
*
|
|
148
|
+
* # Example
|
|
149
|
+
* ```ts
|
|
150
|
+
* // Set ground floor height to 5 Babylon units — walls stretch and the
|
|
151
|
+
* // floors above move up to match, all in a single undo step.
|
|
152
|
+
* const result = await snaptrude.core.storeys.update(1, 5)
|
|
153
|
+
* // Rename only, leaving the height untouched.
|
|
154
|
+
* await snaptrude.core.storeys.update(1, undefined, { name: "Lobby" })
|
|
155
|
+
* ```
|
|
156
|
+
*/
|
|
157
|
+
public abstract update(
|
|
158
|
+
storyValue: number,
|
|
159
|
+
height?: number,
|
|
160
|
+
options?: { name?: string },
|
|
161
|
+
): PluginApiReturn<PluginStoryUpdateResult>
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Make a storey the active storey — the same as clicking it in the storey/layer
|
|
165
|
+
* panel. Subsequent draws and creates target this storey, and in 2D the
|
|
166
|
+
* viewport switches to it. This is a view/navigation change: it is **not**
|
|
167
|
+
* undoable and commits nothing to the model.
|
|
168
|
+
*
|
|
169
|
+
* @param storyValue - Integer storey number to activate
|
|
170
|
+
* @returns A {@linkcode PluginStorySetActiveResult} echoing the now-active `storyValue`
|
|
171
|
+
* @throws `PRECONDITION_FAILED` if no storey has the given value
|
|
172
|
+
*
|
|
173
|
+
* @examplePrompt Switch to the second floor
|
|
174
|
+
* @examplePrompt Make the ground storey active
|
|
175
|
+
* @examplePrompt Go to the basement level
|
|
176
|
+
* @examplePrompt Set level 3 as the current storey
|
|
177
|
+
*
|
|
178
|
+
* # Example
|
|
179
|
+
* ```ts
|
|
180
|
+
* // Activate storey 2, then draw a wall — it lands on storey 2.
|
|
181
|
+
* await snaptrude.core.storeys.setActive(2)
|
|
182
|
+
* ```
|
|
183
|
+
*/
|
|
184
|
+
public abstract setActive(
|
|
185
|
+
storyValue: number,
|
|
186
|
+
): PluginApiReturn<PluginStorySetActiveResult>
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Delete a storey and everything on it — the same as removing it from the
|
|
190
|
+
* storey panel. Every element placed on the storey (walls, floors, masses, …)
|
|
191
|
+
* is deleted with it, the remaining storeys are re-stacked, and the active
|
|
192
|
+
* storey falls back to an adjacent one. Committed as a single undo step.
|
|
193
|
+
*
|
|
194
|
+
* @param storyValue - Integer storey number to delete
|
|
195
|
+
* @returns A {@linkcode PluginStoryDeleteResult} with the deleted `storyValue`
|
|
196
|
+
* and the `newActiveStory` the editor fell back to
|
|
197
|
+
* @throws `PRECONDITION_FAILED` if no storey has the given value; or if plugin
|
|
198
|
+
* writes are disabled
|
|
199
|
+
*
|
|
200
|
+
* @examplePrompt Delete the top floor
|
|
201
|
+
* @examplePrompt Remove the basement level
|
|
202
|
+
* @examplePrompt Get rid of storey 3
|
|
203
|
+
* @examplePrompt Delete the second floor and everything on it
|
|
204
|
+
*
|
|
205
|
+
* # Example
|
|
206
|
+
* ```ts
|
|
207
|
+
* const { newActiveStory } = await snaptrude.core.storeys.delete(3)
|
|
208
|
+
* console.log(`Deleted storey 3; now on storey ${newActiveStory}`)
|
|
209
|
+
* ```
|
|
210
|
+
*/
|
|
211
|
+
public abstract delete(
|
|
212
|
+
storyValue: number,
|
|
213
|
+
): PluginApiReturn<PluginStoryDeleteResult>
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Copy a storey into the adjacent level, up or down.
|
|
217
|
+
*
|
|
218
|
+
* By default the **whole storey** is copied: every eligible element on the
|
|
219
|
+
* active storey (walls, floors, roofs, masses, columns, beams, staircases,
|
|
220
|
+
* ceilings, parametric curtain walls, and furniture) is copied into the storey
|
|
221
|
+
* one level `"up"` or `"down"`. Pass `options.components` to copy only a subset
|
|
222
|
+
* instead. The target storey is **created automatically** if it does not yet
|
|
223
|
+
* exist, inheriting the source storey's height.
|
|
224
|
+
*
|
|
225
|
+
* Copies are **instanced** by default (`unique: false`) — they share geometry
|
|
226
|
+
* with the source, so later edits propagate. Set `unique: true` for independent
|
|
227
|
+
* geometry. Doors and windows are never copied on their own; they ride along
|
|
228
|
+
* with their host wall. Locked, throw-away, and unsupported elements are skipped
|
|
229
|
+
* and counted in `skipped`. The whole operation is a single undo step.
|
|
230
|
+
*
|
|
231
|
+
* @param direction - `"up"` to copy into the storey above, `"down"` for below
|
|
232
|
+
* @param options - `components` (restrict to a subset of the storey's elements;
|
|
233
|
+
* omit for the whole storey) and `unique` (default `false` = instanced copies;
|
|
234
|
+
* `true` = independent geometry)
|
|
235
|
+
* @returns A {@linkcode PluginStoryDuplicateResult} with the `sourceStory`, the
|
|
236
|
+
* `targetStories` the copies landed on, the `created` component handles, the
|
|
237
|
+
* `createdStoryValues` for any storeys generated to receive them, and the
|
|
238
|
+
* `skipped` count of ineligible elements
|
|
239
|
+
* @throws `NO_ACTIVE_STRUCTURE` if there is no active structure to copy into;
|
|
240
|
+
* `NO_ELIGIBLE_ELEMENTS` if nothing on the source storey (or in
|
|
241
|
+
* `options.components`) is copyable; `HANDLE_INVALID` for a stale or foreign
|
|
242
|
+
* supplied handle; or if plugin writes are disabled
|
|
243
|
+
*
|
|
244
|
+
* @examplePrompt Copy this floor to the storey above
|
|
245
|
+
* @examplePrompt Copy the ground floor down into a new basement
|
|
246
|
+
* @examplePrompt Repeat this level upwards with its own independent geometry
|
|
247
|
+
* @examplePrompt Copy just the selected walls onto the next floor up
|
|
248
|
+
*
|
|
249
|
+
* # Example
|
|
250
|
+
* ```ts
|
|
251
|
+
* // Copy the whole active storey one level up (instanced copies).
|
|
252
|
+
* const { targetStories, created, skipped } =
|
|
253
|
+
* await snaptrude.core.storeys.copy("up")
|
|
254
|
+
* console.log(`Copied ${created.length} elements onto storey ${targetStories}`)
|
|
255
|
+
* if (skipped) console.log(`${skipped} elements were skipped`)
|
|
256
|
+
* ```
|
|
257
|
+
*/
|
|
258
|
+
public abstract copy(
|
|
259
|
+
direction: "up" | "down",
|
|
260
|
+
options?: { components?: ComponentHandle[]; unique?: boolean },
|
|
261
|
+
): PluginApiReturn<PluginStoryDuplicateResult>
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Result of {@linkcode PluginCoreStoreysApi.list} — the {@linkcode PluginStoryGetAllResult}
|
|
266
|
+
* shape with the array field renamed `stories` → `storeys`. Each entry shares the
|
|
267
|
+
* same element type: `{ value, id, name }`, sorted top to bottom.
|
|
268
|
+
*
|
|
269
|
+
* | Property | Type | Description |
|
|
270
|
+
* |---|---|---|
|
|
271
|
+
* | `storeys` | `Array<{ value, id, name }>` | All storeys, sorted top to bottom |
|
|
272
|
+
*/
|
|
273
|
+
export const PluginCoreStoreysListResult = z.object({
|
|
274
|
+
storeys: PluginStoryGetAllResult.shape.stories,
|
|
275
|
+
})
|
|
276
|
+
|
|
277
|
+
export type PluginCoreStoreysListResult = z.infer<
|
|
278
|
+
typeof PluginCoreStoreysListResult
|
|
279
|
+
>
|
package/src/api/core/tags.ts
CHANGED
|
@@ -131,11 +131,38 @@ export abstract class PluginCoreTagsApi {
|
|
|
131
131
|
* const { tags } = await snaptrude.core.tags.getTagsForComponent("cmp_42")
|
|
132
132
|
* for (const t of tags) console.log(t.categoryName, t.tagName)
|
|
133
133
|
* ```
|
|
134
|
+
*
|
|
135
|
+
* @deprecated Use `core.tags.listForComponent`
|
|
134
136
|
*/
|
|
135
137
|
public abstract getTagsForComponent(
|
|
136
138
|
componentId: ComponentHandle,
|
|
137
139
|
): PluginApiReturn<PluginCoreTagsGetTagsForComponentResult>
|
|
138
140
|
|
|
141
|
+
/**
|
|
142
|
+
* List the tags carried by a component.
|
|
143
|
+
*
|
|
144
|
+
* Returns one entry per category the component is tagged in, each carrying the
|
|
145
|
+
* category and tag names and the tag color. Canonical home of the read formerly
|
|
146
|
+
* at `getTagsForComponent` (now deprecated).
|
|
147
|
+
*
|
|
148
|
+
* @param componentId - The `Component.id` to read.
|
|
149
|
+
* @returns A {@linkcode PluginCoreTagsGetTagsForComponentResult} with a `tags`
|
|
150
|
+
* array (empty when the component has none or does not exist).
|
|
151
|
+
*
|
|
152
|
+
* @examplePrompt What tags does this space have?
|
|
153
|
+
* @examplePrompt List the tags on component cmp_42
|
|
154
|
+
* @examplePrompt Show the labels applied to this room
|
|
155
|
+
*
|
|
156
|
+
* # Example
|
|
157
|
+
* ```ts
|
|
158
|
+
* const { tags } = await snaptrude.core.tags.listForComponent("cmp_42")
|
|
159
|
+
* for (const t of tags) console.log(t.categoryName, t.tagName)
|
|
160
|
+
* ```
|
|
161
|
+
*/
|
|
162
|
+
public abstract listForComponent(
|
|
163
|
+
componentId: ComponentHandle,
|
|
164
|
+
): PluginApiReturn<PluginCoreTagsGetTagsForComponentResult>
|
|
165
|
+
|
|
139
166
|
/**
|
|
140
167
|
* List the components carrying a given tag or category.
|
|
141
168
|
*
|
|
@@ -24,6 +24,8 @@ export abstract class PluginZoomApi {
|
|
|
24
24
|
* ```ts
|
|
25
25
|
* await snaptrude.core.zoom.extents()
|
|
26
26
|
* ```
|
|
27
|
+
*
|
|
28
|
+
* @deprecated Use `core.camera.zoomExtents`
|
|
27
29
|
*/
|
|
28
30
|
public abstract extents(): PluginApiReturn<boolean>
|
|
29
31
|
|
|
@@ -42,6 +44,8 @@ export abstract class PluginZoomApi {
|
|
|
42
44
|
* ```ts
|
|
43
45
|
* await snaptrude.core.zoom.selection()
|
|
44
46
|
* ```
|
|
47
|
+
*
|
|
48
|
+
* @deprecated Use `core.camera.zoomSelection`
|
|
45
49
|
*/
|
|
46
50
|
public abstract selection(): PluginApiReturn<boolean>
|
|
47
51
|
}
|
|
@@ -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.
|
|
@@ -52,7 +59,7 @@ export abstract class PluginDesignCreateApi {
|
|
|
52
59
|
* @param departmentId - Department assignment (default department)
|
|
53
60
|
* @param storey - Target storey number to place the space on — the same integer
|
|
54
61
|
* `entity.story` uses (`1` ground, `2` first floor, `-1` basement). Default:
|
|
55
|
-
* the active storey. Folds
|
|
62
|
+
* the active storey. Folds a `core.storeys.setActive` call into the create,
|
|
56
63
|
* placing the space at that storey's floor elevation (any `position` offset is
|
|
57
64
|
* applied on top). Throws if no storey has that value.
|
|
58
65
|
* @returns the {@linkcode ComponentHandle} of the created space
|
|
@@ -66,6 +73,10 @@ export abstract class PluginDesignCreateApi {
|
|
|
66
73
|
* @examplePrompt Can you create a Kitchen space from the sketch I just drew?
|
|
67
74
|
* @examplePrompt Create a bedroom on the second floor from this outline
|
|
68
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).
|
|
79
|
+
*
|
|
69
80
|
* # Example
|
|
70
81
|
* ```ts
|
|
71
82
|
* const v = snaptrude.core.math.vec3
|
|
@@ -126,6 +137,51 @@ export abstract class PluginDesignCreateApi {
|
|
|
126
137
|
massType?: PluginMassType,
|
|
127
138
|
): PluginApiReturn<ComponentHandle>
|
|
128
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
|
+
|
|
129
185
|
/**
|
|
130
186
|
* Create a **slab** by extruding a footprint contour by `thickness`
|
|
131
187
|
* (default direction: down).
|
|
@@ -685,6 +741,11 @@ export abstract class PluginDesignCreateApi {
|
|
|
685
741
|
* @examplePrompt Array these walls with a 3m offset
|
|
686
742
|
* @examplePrompt Clone the desk as a unique copy, not an instance
|
|
687
743
|
*
|
|
744
|
+
* @performance To place N repeats of the same geometry, bulk-create the seed(s) once then
|
|
745
|
+
* call this ONCE with `{ count: N - 1 }` — one host round-trip for all copies. Never
|
|
746
|
+
* reproduce geometry by looping `design.create.*` N times. Copy only after the create
|
|
747
|
+
* that mints the seed ids.
|
|
748
|
+
*
|
|
688
749
|
* # Example
|
|
689
750
|
* ```ts
|
|
690
751
|
* const { vec3 } = snaptrude.core.math
|
|
@@ -717,6 +778,10 @@ export abstract class PluginDesignCreateApi {
|
|
|
717
778
|
* @examplePrompt Add three rooms with different heights in a single undo step
|
|
718
779
|
* @examplePrompt Create one room on the ground floor and one on the first floor
|
|
719
780
|
*
|
|
781
|
+
* @performance Bulk creator — the whole batch is ONE host round-trip. Always prefer this
|
|
782
|
+
* over calling `design.create.space` in a loop: build the full `items[]` array first
|
|
783
|
+
* (all per-item math and geometry up front), then make one call.
|
|
784
|
+
*
|
|
720
785
|
* # Example
|
|
721
786
|
* ```ts
|
|
722
787
|
* const rect = await snaptrude.core.geom.create.profileRect(4, 3)
|
|
@@ -730,6 +795,58 @@ export abstract class PluginDesignCreateApi {
|
|
|
730
795
|
public abstract spaces(
|
|
731
796
|
items: PluginCreateSpaceItem[],
|
|
732
797
|
): PluginApiReturn<ComponentHandle[]>
|
|
798
|
+
|
|
799
|
+
/**
|
|
800
|
+
* Create a new parametric buildable envelope — the zoning-regulated volume a
|
|
801
|
+
* building may occupy — generated from a site polygon, tiered setbacks, a
|
|
802
|
+
* height or floor-count cap, and optional FAR and lot-coverage limits. The host
|
|
803
|
+
* mints the envelope id and returns it. Canonical home of the create formerly
|
|
804
|
+
* at `entity.buildableEnvelope.create` (now deprecated).
|
|
805
|
+
*
|
|
806
|
+
* @param sitePolygon - Site polygon vertices in `lengthUnit`; minimum 3 vertices.
|
|
807
|
+
* @param lengthUnit - Unit used by all length fields (`"ft" | "m"`).
|
|
808
|
+
* @param setbacks - Setback profile, ground tier first; minimum 1 tier.
|
|
809
|
+
* @param verticalCap - Maximum height or floor count.
|
|
810
|
+
* @param floorToFloor - Required floor-to-floor height in `lengthUnit`.
|
|
811
|
+
* @param farRatio - Optional FAR value, positive when provided.
|
|
812
|
+
* @param lotCoverageMaxPct - Optional lot coverage cap, `0..100`.
|
|
813
|
+
* @returns A {@linkcode PluginBuildableEnvelopeCreateResult} with the
|
|
814
|
+
* `buildableEnvelopeId` of the created envelope.
|
|
815
|
+
* @throws If validation fails or generation produces no renderable geometry.
|
|
816
|
+
*
|
|
817
|
+
* @examplePrompt Create a buildable envelope for my site
|
|
818
|
+
* @examplePrompt Generate the zoning envelope with 10ft front setbacks
|
|
819
|
+
* @examplePrompt Show the maximum buildable volume with a 150ft height limit
|
|
820
|
+
* @examplePrompt Create a zoning envelope capped at 12 floors with FAR 3
|
|
821
|
+
*
|
|
822
|
+
* # Example
|
|
823
|
+
* ```ts
|
|
824
|
+
* const { buildableEnvelopeId } = await snaptrude.design.create.buildableEnvelope(
|
|
825
|
+
* [
|
|
826
|
+
* { x: 0, z: 0 },
|
|
827
|
+
* { x: 100, z: 0 },
|
|
828
|
+
* { x: 100, z: 80 },
|
|
829
|
+
* { x: 0, z: 80 },
|
|
830
|
+
* ],
|
|
831
|
+
* "ft",
|
|
832
|
+
* [
|
|
833
|
+
* { aboveHeight: 0, front: 10, side: 5, rear: 10 },
|
|
834
|
+
* { aboveHeight: 100, front: 20, side: 10, rear: 20 },
|
|
835
|
+
* ],
|
|
836
|
+
* { kind: "max_height", maxHeight: 150 },
|
|
837
|
+
* 12,
|
|
838
|
+
* )
|
|
839
|
+
* ```
|
|
840
|
+
*/
|
|
841
|
+
public abstract buildableEnvelope(
|
|
842
|
+
sitePolygon: PluginBuildableEnvelopePolygonVertex[],
|
|
843
|
+
lengthUnit: "ft" | "m",
|
|
844
|
+
setbacks: PluginBuildableEnvelopeSetbackTier[],
|
|
845
|
+
verticalCap: PluginBuildableEnvelopeVerticalCap,
|
|
846
|
+
floorToFloor: number,
|
|
847
|
+
farRatio?: number,
|
|
848
|
+
lotCoverageMaxPct?: number,
|
|
849
|
+
): PluginApiReturn<PluginBuildableEnvelopeCreateResult>
|
|
733
850
|
}
|
|
734
851
|
|
|
735
852
|
// ---------------------------------------------------------------------------
|
|
@@ -851,6 +968,26 @@ export type PluginDesignCreateMassArgs = z.infer<
|
|
|
851
968
|
typeof PluginDesignCreateMassArgs
|
|
852
969
|
>
|
|
853
970
|
|
|
971
|
+
// ---------------------------------------------------------------------------
|
|
972
|
+
// massFromBrep
|
|
973
|
+
// ---------------------------------------------------------------------------
|
|
974
|
+
|
|
975
|
+
/**
|
|
976
|
+
* Arguments for {@linkcode PluginDesignCreateApi.massFromBrep}.
|
|
977
|
+
*
|
|
978
|
+
* | Property | Type | Description |
|
|
979
|
+
* |---|---|---|
|
|
980
|
+
* | `brep` | {@linkcode BrepHandle} | A solid from a `core.geom.create` brep constructor |
|
|
981
|
+
* | `label` | `string`? | Label (maps to `room_type`) |
|
|
982
|
+
*/
|
|
983
|
+
export const PluginDesignCreateMassFromBrepArgs = z.object({
|
|
984
|
+
brep: BrepHandle,
|
|
985
|
+
label: z.string().optional(),
|
|
986
|
+
})
|
|
987
|
+
export type PluginDesignCreateMassFromBrepArgs = z.infer<
|
|
988
|
+
typeof PluginDesignCreateMassFromBrepArgs
|
|
989
|
+
>
|
|
990
|
+
|
|
854
991
|
// ---------------------------------------------------------------------------
|
|
855
992
|
// slab
|
|
856
993
|
// ---------------------------------------------------------------------------
|
|
@@ -52,6 +52,9 @@ export abstract class PluginDesignDeleteApi {
|
|
|
52
52
|
* @examplePrompt Delete all the furniture I picked
|
|
53
53
|
* @examplePrompt Remove the door and window I just created
|
|
54
54
|
*
|
|
55
|
+
* @performance Array delete — pass every target in one call (one host round-trip). There is
|
|
56
|
+
* no per-item delete; collect the whole set and never loop this per entity.
|
|
57
|
+
*
|
|
55
58
|
* # Example
|
|
56
59
|
* ```ts
|
|
57
60
|
* // Hard-delete every furniture item on storey 2 (a single undo entry)
|