@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
|
@@ -7,8 +7,10 @@ import {
|
|
|
7
7
|
PluginDepartmentId,
|
|
8
8
|
PluginAreaClass,
|
|
9
9
|
} from "../../entity/space"
|
|
10
|
+
import { PluginStaircasePreset } from "../create"
|
|
10
11
|
import { PluginDesignQueryGeometryApi } from "./geometry"
|
|
11
12
|
import { PluginDesignQuerySpacesApi } from "./spaces"
|
|
13
|
+
import { PluginDesignQueryReferenceLinesApi } from "./referenceLines"
|
|
12
14
|
|
|
13
15
|
// ---------------------------------------------------------------------------
|
|
14
16
|
// Entity type vocabulary
|
|
@@ -167,6 +169,7 @@ export type PluginDesignQueryComponentsArgs = z.infer<
|
|
|
167
169
|
* | `spaceType` | {@linkcode PluginSpaceType} | Space-type (spaces only) |
|
|
168
170
|
* | `areaClass` | {@linkcode PluginAreaClass} | Area classification (spaces only) |
|
|
169
171
|
* | `departmentId` | `string` | Department (masses only) |
|
|
172
|
+
* | `buildingType` | `string` | Assigned building type NAME (walls / slabs / floors / roofs / ceilings only) — the Object Properties panel's Wall/Slab/Floor/Roof/Ceiling Type dropdown value, matching the names from `design.types.list(kind)` |
|
|
170
173
|
* | `isLocked` | `boolean` | Lock flag |
|
|
171
174
|
* | `isHidden` | `boolean` | User-hidden flag |
|
|
172
175
|
* | `isSelected` | `boolean` | Current selection state |
|
|
@@ -185,6 +188,7 @@ export const PluginEntityProperties = z
|
|
|
185
188
|
spaceType: PluginSpaceType,
|
|
186
189
|
areaClass: PluginAreaClass,
|
|
187
190
|
departmentId: z.string(),
|
|
191
|
+
buildingType: z.string(),
|
|
188
192
|
isLocked: z.boolean(),
|
|
189
193
|
isHidden: z.boolean(),
|
|
190
194
|
isSelected: z.boolean(),
|
|
@@ -200,21 +204,82 @@ export type PluginEntityProperties = z.infer<typeof PluginEntityProperties>
|
|
|
200
204
|
* entity's type computes them (area: floors/masses/slabs/roofs/beams/columns;
|
|
201
205
|
* volume: all; length: walls/beams).
|
|
202
206
|
*
|
|
207
|
+
* `thickness` and `height` are the Object Properties panel's dimension reads
|
|
208
|
+
* (the same engine source `design.update.wall` / `design.update.slab` etc.
|
|
209
|
+
* write through), in engine units. `thickness`: walls (the plan thickness —
|
|
210
|
+
* present only for straight orthogonal walls, exactly when the panel shows it)
|
|
211
|
+
* and slabs/floors/roofs/ceilings (the vertical extent the panel calls
|
|
212
|
+
* Thickness). `height`: walls only.
|
|
213
|
+
*
|
|
203
214
|
* | Property | Type | Description |
|
|
204
215
|
* |---|---|---|
|
|
205
216
|
* | `area` | `number`? | Bottom-face area |
|
|
206
217
|
* | `volume` | `number`? | Solid volume |
|
|
207
218
|
* | `length` | `number`? | Running length (linear elements) |
|
|
219
|
+
* | `thickness` | `number`? | Panel Thickness — walls (straight orthogonal only) and the slab family |
|
|
220
|
+
* | `height` | `number`? | Panel Height — walls only |
|
|
208
221
|
* | `boundingBox` | {@linkcode BBoxComponents} | World-space AABB (always present) |
|
|
209
222
|
*/
|
|
210
223
|
export const PluginEntityMeasurements = z.object({
|
|
211
224
|
area: z.number().optional(),
|
|
212
225
|
volume: z.number().optional(),
|
|
213
226
|
length: z.number().optional(),
|
|
227
|
+
thickness: z.number().optional(),
|
|
228
|
+
height: z.number().optional(),
|
|
214
229
|
boundingBox: BBoxComponents,
|
|
215
230
|
})
|
|
216
231
|
export type PluginEntityMeasurements = z.infer<typeof PluginEntityMeasurements>
|
|
217
232
|
|
|
233
|
+
/**
|
|
234
|
+
* The parametric properties of a staircase — the same editable fields the
|
|
235
|
+
* staircase properties panel exposes. Returned by
|
|
236
|
+
* {@linkcode PluginDesignQueryApi.getStaircaseParams}; the write side is
|
|
237
|
+
* `design.update.staircase`. Engine internals (block schema, min well size,
|
|
238
|
+
* square-well padding) are deliberately excluded.
|
|
239
|
+
*
|
|
240
|
+
* All dimensions are in **engine units** (the same convention as
|
|
241
|
+
* `design.doors.getWidth`); `steps` is a unitless count. The invariant
|
|
242
|
+
* `staircaseHeight = steps × riser` is governed by the two lock booleans — see
|
|
243
|
+
* `design.update.staircase`. Type-specific fields (`wellSize`, `landingWidth`,
|
|
244
|
+
* `flightStartDistAfterTurn`) are present only when the preset uses them.
|
|
245
|
+
*
|
|
246
|
+
* | Property | Type | Description |
|
|
247
|
+
* |---|---|---|
|
|
248
|
+
* | `staircaseType` | {@linkcode PluginStaircasePreset} | Base staircase type |
|
|
249
|
+
* | `staircasePreset` | {@linkcode PluginStaircasePreset} | Named parametric preset |
|
|
250
|
+
* | `staircaseHeight` | `number` | Total rise (engine units) |
|
|
251
|
+
* | `steps` | `number` | Step count (unitless) |
|
|
252
|
+
* | `riser` | `number` | Riser height (engine units) |
|
|
253
|
+
* | `tread` | `number` | Tread depth (engine units) |
|
|
254
|
+
* | `width` | `number` | Flight width (engine units) |
|
|
255
|
+
* | `depth` | `number` | Slab/waist thickness (engine units) |
|
|
256
|
+
* | `wellSize` | `number`? | Stairwell gap (dogLegged / openWell / square) |
|
|
257
|
+
* | `landingWidth` | `number`? | Landing depth (straight / dogLegged) |
|
|
258
|
+
* | `flightStartDistAfterTurn` | `number`? | Flight offset after a turn (dogLegged / lShaped / square) |
|
|
259
|
+
* | `baseOffset` | `number` | Vertical offset from the storey base (engine units) |
|
|
260
|
+
* | `isStoreyHeightUnlocked` | `boolean` | When `false`, height is tied to the storey height |
|
|
261
|
+
* | `isStaircaseHeightUnlocked` | `boolean` | When `false`, height recomputes from steps × riser |
|
|
262
|
+
* | `storey` | `number` | Storey/floor level the staircase sits on |
|
|
263
|
+
*/
|
|
264
|
+
export const PluginStaircaseParams = z.object({
|
|
265
|
+
staircaseType: PluginStaircasePreset,
|
|
266
|
+
staircasePreset: PluginStaircasePreset,
|
|
267
|
+
staircaseHeight: z.number(),
|
|
268
|
+
steps: z.number(),
|
|
269
|
+
riser: z.number(),
|
|
270
|
+
tread: z.number(),
|
|
271
|
+
width: z.number(),
|
|
272
|
+
depth: z.number(),
|
|
273
|
+
wellSize: z.number().optional(),
|
|
274
|
+
landingWidth: z.number().optional(),
|
|
275
|
+
flightStartDistAfterTurn: z.number().optional(),
|
|
276
|
+
baseOffset: z.number(),
|
|
277
|
+
isStoreyHeightUnlocked: z.boolean(),
|
|
278
|
+
isStaircaseHeightUnlocked: z.boolean(),
|
|
279
|
+
storey: z.number(),
|
|
280
|
+
})
|
|
281
|
+
export type PluginStaircaseParams = z.infer<typeof PluginStaircaseParams>
|
|
282
|
+
|
|
218
283
|
// ---------------------------------------------------------------------------
|
|
219
284
|
// The query API
|
|
220
285
|
// ---------------------------------------------------------------------------
|
|
@@ -237,6 +302,8 @@ export abstract class PluginDesignQueryApi {
|
|
|
237
302
|
public abstract geometry: PluginDesignQueryGeometryApi
|
|
238
303
|
/** Space-specific reads (footprint, …). See {@linkcode PluginDesignQuerySpacesApi}. */
|
|
239
304
|
public abstract spaces: PluginDesignQuerySpacesApi
|
|
305
|
+
/** Reference-line-specific reads. See {@linkcode PluginDesignQueryReferenceLinesApi}. */
|
|
306
|
+
public abstract referenceLines: PluginDesignQueryReferenceLinesApi
|
|
240
307
|
|
|
241
308
|
constructor() {}
|
|
242
309
|
|
|
@@ -704,9 +771,7 @@ export abstract class PluginDesignQueryApi {
|
|
|
704
771
|
* }
|
|
705
772
|
* ```
|
|
706
773
|
*/
|
|
707
|
-
public abstract exists(
|
|
708
|
-
id: ComponentHandle,
|
|
709
|
-
): PluginApiReturn<boolean>
|
|
774
|
+
public abstract exists(id: ComponentHandle): PluginApiReturn<boolean>
|
|
710
775
|
|
|
711
776
|
/**
|
|
712
777
|
* Get the kind of BIM entity a handle refers to — wall, door, space, slab,
|
|
@@ -760,9 +825,7 @@ export abstract class PluginDesignQueryApi {
|
|
|
760
825
|
* }
|
|
761
826
|
* ```
|
|
762
827
|
*/
|
|
763
|
-
public abstract getLabel(
|
|
764
|
-
component: ComponentHandle,
|
|
765
|
-
): PluginApiReturn<string>
|
|
828
|
+
public abstract getLabel(component: ComponentHandle): PluginApiReturn<string>
|
|
766
829
|
|
|
767
830
|
/**
|
|
768
831
|
* Get a serializable, persistable reference to an entity. Under the all-handle
|
|
@@ -846,13 +909,16 @@ export abstract class PluginDesignQueryApi {
|
|
|
846
909
|
* Read an entity's common properties as a {@linkcode PluginEntityProperties}
|
|
847
910
|
* record (only applicable fields are present). For spaces/masses this includes
|
|
848
911
|
* `adjacency` — the per-entity adjacency read (bulk form:
|
|
849
|
-
* `program.adjacency.getMatrix`).
|
|
912
|
+
* `program.adjacency.getMatrix`). For walls and the slab family (slab / floor
|
|
913
|
+
* / roof / ceiling) this includes `buildingType` — the assigned building type
|
|
914
|
+
* NAME the panel's type dropdown shows, matching `design.types.list(kind)`.
|
|
850
915
|
*
|
|
851
916
|
* @param component - the entity's {@linkcode ComponentHandle}
|
|
852
917
|
* @returns the property record
|
|
853
918
|
*
|
|
854
919
|
* @examplePrompt Show me all the details of the selected object
|
|
855
920
|
* @examplePrompt What storey is this wall on?
|
|
921
|
+
* @examplePrompt Which wall type is assigned to this wall?
|
|
856
922
|
* @examplePrompt Which department does this room belong to?
|
|
857
923
|
* @examplePrompt Is this element locked or hidden?
|
|
858
924
|
* @examplePrompt Get the adjacencies of this space
|
|
@@ -882,11 +948,20 @@ export abstract class PluginDesignQueryApi {
|
|
|
882
948
|
* Measure an entity — read its area, volume, and/or running length (whichever
|
|
883
949
|
* its type supports) together with its world-space bounding box in one call.
|
|
884
950
|
*
|
|
951
|
+
* For walls and the slab family this also carries the Object Properties
|
|
952
|
+
* panel's dimension reads in engine units: `thickness` (walls — straight
|
|
953
|
+
* orthogonal only, exactly when the panel shows it; slabs / floors / roofs /
|
|
954
|
+
* ceilings — the vertical extent the panel calls Thickness) and `height`
|
|
955
|
+
* (walls). These are the read side of `design.update.wall` /
|
|
956
|
+
* `design.update.slab` / `.floor` / `.roof` / `.ceiling`.
|
|
957
|
+
*
|
|
885
958
|
* @param component - the entity's {@linkcode ComponentHandle}
|
|
886
959
|
* @returns a {@linkcode PluginEntityMeasurements}, or `null` if the entity is gone
|
|
887
960
|
*
|
|
888
961
|
* @examplePrompt What's the area of this room?
|
|
889
962
|
* @examplePrompt How long is the selected wall?
|
|
963
|
+
* @examplePrompt How thick is this wall?
|
|
964
|
+
* @examplePrompt Get the thickness of the slab on level 2
|
|
890
965
|
* @examplePrompt Get the volume of this mass
|
|
891
966
|
* @examplePrompt Give me the dimensions of the selected element
|
|
892
967
|
* @examplePrompt What's the floor area of the kitchen?
|
|
@@ -896,12 +971,47 @@ export abstract class PluginDesignQueryApi {
|
|
|
896
971
|
* const [space] = await snaptrude.design.query.listSpaces()
|
|
897
972
|
* const m = await snaptrude.design.query.measure(space)
|
|
898
973
|
* console.log(m?.area, m?.volume)
|
|
974
|
+
*
|
|
975
|
+
* // wall dimensions — the panel's Thickness / Height, in engine units
|
|
976
|
+
* const [wall] = await snaptrude.design.query.listWalls()
|
|
977
|
+
* const wm = await snaptrude.design.query.measure(wall)
|
|
978
|
+
* console.log(wm?.thickness, wm?.height)
|
|
899
979
|
* ```
|
|
900
980
|
*/
|
|
901
981
|
public abstract measure(
|
|
902
982
|
component: ComponentHandle,
|
|
903
983
|
): PluginApiReturn<PluginEntityMeasurements | null>
|
|
904
984
|
|
|
985
|
+
/**
|
|
986
|
+
* Read a staircase's parametric properties — its preset, dimensions, step
|
|
987
|
+
* count, base offset, and height-lock state — as a
|
|
988
|
+
* {@linkcode PluginStaircaseParams} record. The paired write is
|
|
989
|
+
* `design.update.staircase`.
|
|
990
|
+
*
|
|
991
|
+
* All dimensions are in **engine units** (the same convention as
|
|
992
|
+
* `design.doors.getWidth`); `steps` is a unitless count. A read — never
|
|
993
|
+
* throws: returns `null` for a handle that is not a staircase or no longer
|
|
994
|
+
* resolves.
|
|
995
|
+
*
|
|
996
|
+
* @param staircase - the staircase's {@linkcode ComponentHandle}
|
|
997
|
+
* @returns the {@linkcode PluginStaircaseParams} record, or `null`
|
|
998
|
+
*
|
|
999
|
+
* @examplePrompt What's the riser height of this staircase?
|
|
1000
|
+
* @examplePrompt How many steps does the selected stair have?
|
|
1001
|
+
* @examplePrompt Show me the tread and width of this staircase
|
|
1002
|
+
* @examplePrompt Read all the parameters of the stairs on level 1
|
|
1003
|
+
*
|
|
1004
|
+
* # Example
|
|
1005
|
+
* ```ts
|
|
1006
|
+
* const [stair] = await snaptrude.design.query.listStaircases({ isSelected: true })
|
|
1007
|
+
* const params = stair ? await snaptrude.design.query.getStaircaseParams(stair) : null
|
|
1008
|
+
* if (params) console.log(params.steps, params.riser, params.tread)
|
|
1009
|
+
* ```
|
|
1010
|
+
*/
|
|
1011
|
+
public abstract getStaircaseParams(
|
|
1012
|
+
staircase: ComponentHandle,
|
|
1013
|
+
): PluginApiReturn<PluginStaircaseParams | null>
|
|
1014
|
+
|
|
905
1015
|
/**
|
|
906
1016
|
* Get the **union** axis-aligned bounding box enclosing a set of entities.
|
|
907
1017
|
*
|
|
@@ -931,7 +1041,107 @@ export abstract class PluginDesignQueryApi {
|
|
|
931
1041
|
public abstract getBoundingBox(
|
|
932
1042
|
components: ComponentHandle[],
|
|
933
1043
|
): PluginApiReturn<BBoxComponents | null>
|
|
1044
|
+
|
|
1045
|
+
/**
|
|
1046
|
+
* Compute the plan **outline of what is built on a storey** — the union of
|
|
1047
|
+
* the storey's wall (by default) footprints as polygons-with-holes. This is
|
|
1048
|
+
* the footprint-from-the-built-model query: by the time slabs are needed the
|
|
1049
|
+
* walls exist, and the engine's own solids (snapped, joined and mitred at
|
|
1050
|
+
* creation) are the cleanest wall network available — no CAD re-tracing.
|
|
1051
|
+
*
|
|
1052
|
+
* Semantics: the union of wall solids is the wall *material* — a ring-shaped
|
|
1053
|
+
* polygon. The **outer ring is the OUTSIDE wall face** (the slab boundary);
|
|
1054
|
+
* every enclosed region — rooms AND courtyards — appears as a hole. When the
|
|
1055
|
+
* largest hole is ~zero the walls don't enclose anything: the footprint
|
|
1056
|
+
* reports `enclosed: false` (an open wall network), never a garbage outline.
|
|
1057
|
+
* Detached buildings come back as separate footprints.
|
|
1058
|
+
*
|
|
1059
|
+
* A read — nothing is created. Feed a footprint's `outline` to
|
|
1060
|
+
* `core.geom.create.profileFromLinePoints` → `design.create.slab` to build
|
|
1061
|
+
* the floor/roof plate. Coordinates are world-space plan (x, z) in Snaptrude
|
|
1062
|
+
* internal units; `areaSq` values are in squared internal units.
|
|
1063
|
+
*
|
|
1064
|
+
* @param options - storey / included kinds / debris filter; see
|
|
1065
|
+
* {@linkcode PluginStoreyOutlineOptions}.
|
|
1066
|
+
* @returns the storey's footprints (possibly several for detached buildings)
|
|
1067
|
+
* plus pieces discarded by `minArea` (`footprints: []` when nothing matches).
|
|
1068
|
+
*
|
|
1069
|
+
* @examplePrompt What is the building footprint on the ground floor?
|
|
1070
|
+
* @examplePrompt Create a floor slab covering the whole storey
|
|
1071
|
+
* @examplePrompt Get the outline of the walls on storey 1
|
|
1072
|
+
* @examplePrompt How much area do the ground-floor walls enclose?
|
|
1073
|
+
*
|
|
1074
|
+
* # Example
|
|
1075
|
+
* ```ts
|
|
1076
|
+
* const r = await snaptrude.design.query.storeyOutline({ storey: 1 })
|
|
1077
|
+
* const main = r.footprints.find((f) => f.enclosed)
|
|
1078
|
+
* if (main) {
|
|
1079
|
+
* const profile = await snaptrude.core.geom.create.profileFromLinePoints(
|
|
1080
|
+
* main.outline.map((p) => ({ x: p.x, y: 0, z: p.z })),
|
|
1081
|
+
* )
|
|
1082
|
+
* // → design.create.slab with the profile's contour
|
|
1083
|
+
* }
|
|
1084
|
+
* ```
|
|
1085
|
+
*/
|
|
1086
|
+
public abstract storeyOutline(
|
|
1087
|
+
options?: PluginStoreyOutlineOptions,
|
|
1088
|
+
): PluginApiReturn<PluginStoreyOutlineResult>
|
|
934
1089
|
}
|
|
935
1090
|
|
|
1091
|
+
|
|
1092
|
+
/** A point in the world-space plan (x, z) projection, Snaptrude internal units. */
|
|
1093
|
+
export const PluginOutlinePlanPoint = z.object({ x: z.number(), z: z.number() })
|
|
1094
|
+
export type PluginOutlinePlanPoint = z.infer<typeof PluginOutlinePlanPoint>
|
|
1095
|
+
|
|
1096
|
+
/**
|
|
1097
|
+
* Options for {@link PluginDesignQueryApi.storeyOutline}.
|
|
1098
|
+
*
|
|
1099
|
+
* | Property | Type | Description |
|
|
1100
|
+
* |---|---|---|
|
|
1101
|
+
* | `storey` | `number`? | Only components on this storey (default: all storeys) |
|
|
1102
|
+
* | `include` | {@link PluginEntityType}`[]`? | Component kinds to union (default `["wall"]`) |
|
|
1103
|
+
* | `minArea` | `number`? | Drop union pieces below this plan area, squared internal units (default `1`) |
|
|
1104
|
+
*/
|
|
1105
|
+
export const PluginStoreyOutlineOptions = z.object({
|
|
1106
|
+
storey: z.number().int().optional(),
|
|
1107
|
+
include: z.array(PluginEntityType).nonempty().default(["wall"]),
|
|
1108
|
+
minArea: z.number().nonnegative().default(1),
|
|
1109
|
+
})
|
|
1110
|
+
export type PluginStoreyOutlineOptions = z.input<
|
|
1111
|
+
typeof PluginStoreyOutlineOptions
|
|
1112
|
+
>
|
|
1113
|
+
|
|
1114
|
+
/**
|
|
1115
|
+
* One connected footprint from {@link PluginDesignQueryApi.storeyOutline}.
|
|
1116
|
+
* `outline` traces the OUTSIDE wall face; `holes` are the enclosed regions
|
|
1117
|
+
* (rooms and courtyards). `enclosed` is `false` when the wall network does not
|
|
1118
|
+
* close around any region (open C-shape) — don't slab an unenclosed outline
|
|
1119
|
+
* without checking it.
|
|
1120
|
+
*/
|
|
1121
|
+
export const PluginStoreyFootprint = z.object({
|
|
1122
|
+
outline: z.array(PluginOutlinePlanPoint),
|
|
1123
|
+
holes: z.array(
|
|
1124
|
+
z.object({
|
|
1125
|
+
ring: z.array(PluginOutlinePlanPoint),
|
|
1126
|
+
areaSq: z.number().nonnegative(),
|
|
1127
|
+
}),
|
|
1128
|
+
),
|
|
1129
|
+
areaSq: z.number().nonnegative(),
|
|
1130
|
+
enclosed: z.boolean(),
|
|
1131
|
+
})
|
|
1132
|
+
export type PluginStoreyFootprint = z.infer<typeof PluginStoreyFootprint>
|
|
1133
|
+
|
|
1134
|
+
/** Result of {@link PluginDesignQueryApi.storeyOutline}. */
|
|
1135
|
+
export const PluginStoreyOutlineResult = z.object({
|
|
1136
|
+
footprints: z.array(PluginStoreyFootprint),
|
|
1137
|
+
discarded: z.array(
|
|
1138
|
+
z.object({ areaSq: z.number().nonnegative(), reason: z.string() }),
|
|
1139
|
+
),
|
|
1140
|
+
})
|
|
1141
|
+
export type PluginStoreyOutlineResult = z.infer<
|
|
1142
|
+
typeof PluginStoreyOutlineResult
|
|
1143
|
+
>
|
|
1144
|
+
|
|
936
1145
|
export * from "./geometry"
|
|
937
1146
|
export * from "./spaces"
|
|
1147
|
+
export * from "./referenceLines"
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import * as z from "zod"
|
|
2
|
+
import { PluginApiReturn } from "../../../types"
|
|
3
|
+
import {
|
|
4
|
+
PluginReferenceLineGetProperty,
|
|
5
|
+
PluginReferenceLineGetResult,
|
|
6
|
+
} from "../../entity/referenceLine"
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* `design.query.referenceLines.*` — reference-line-specific reads.
|
|
10
|
+
*
|
|
11
|
+
* A **reference line** is a 2D guide line (or arc) in the scene, typically used
|
|
12
|
+
* for grid lines and alignment guides. Enumerate reference lines with
|
|
13
|
+
* `design.query.listReferenceLines`; read an individual line's properties here.
|
|
14
|
+
* This is the canonical home of the read formerly at `entity.referenceLine.get`
|
|
15
|
+
* (now deprecated).
|
|
16
|
+
*
|
|
17
|
+
* Accessed via `snaptrude.design.query.referenceLines`.
|
|
18
|
+
*/
|
|
19
|
+
export abstract class PluginDesignQueryReferenceLinesApi {
|
|
20
|
+
constructor() {}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Get properties of a reference line by its ID.
|
|
24
|
+
*
|
|
25
|
+
* Only the properties listed in `properties` are returned — unlisted
|
|
26
|
+
* properties will be `undefined` in the result.
|
|
27
|
+
*
|
|
28
|
+
* @param referenceLineId - The unique reference line ID
|
|
29
|
+
* @param properties - Array of property names to retrieve. See
|
|
30
|
+
* {@linkcode PluginReferenceLineGetProperty}.
|
|
31
|
+
* @returns A partial {@linkcode PluginReferenceLineGetResult} containing only the
|
|
32
|
+
* requested properties
|
|
33
|
+
* @throws If the reference line does not exist
|
|
34
|
+
*
|
|
35
|
+
* @examplePrompt Get the curve geometry of this reference line
|
|
36
|
+
* @examplePrompt Where does this grid line run?
|
|
37
|
+
* @examplePrompt Read the geometry of a guide line by its id
|
|
38
|
+
* @examplePrompt Look up the curve of the selected reference line
|
|
39
|
+
*
|
|
40
|
+
* # Example
|
|
41
|
+
* ```ts
|
|
42
|
+
* const [refLine] = await snaptrude.design.query.listReferenceLines()
|
|
43
|
+
* const result = await snaptrude.design.query.referenceLines.get(refLine, ["curve"])
|
|
44
|
+
* // result.curve is an opaque CurveHandle; read its coordinates via
|
|
45
|
+
* // `snaptrude.core.geom.curve`.
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
public abstract get(
|
|
49
|
+
referenceLineId: string,
|
|
50
|
+
properties: z.infer<typeof PluginReferenceLineGetProperty>[],
|
|
51
|
+
): PluginApiReturn<PluginReferenceLineGetResult>
|
|
52
|
+
}
|
|
@@ -75,6 +75,55 @@ export abstract class PluginDesignQuerySpacesApi {
|
|
|
75
75
|
public abstract getFootprint(
|
|
76
76
|
space: ComponentHandle,
|
|
77
77
|
): PluginApiReturn<ContourHandle | null>
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Get the **enclosure** of a space — the floor and ceiling that cap it, the
|
|
81
|
+
* bounding walls around it (with each wall's door/window openings), and the
|
|
82
|
+
* neighbouring spaces it shares a boundary with.
|
|
83
|
+
*
|
|
84
|
+
* **Geometric v1 — best effort.** The engine has no persisted space→surface
|
|
85
|
+
* topology, so this read is derived purely from *plan geometry*: the space
|
|
86
|
+
* footprint is matched against the plan footprints/baselines of the slabs and
|
|
87
|
+
* walls on the same storey. Consequences a caller must account for:
|
|
88
|
+
*
|
|
89
|
+
* - `faceIndices` is **always `[]`**. The triangle→B-rep-face provenance that
|
|
90
|
+
* would populate it is a separate engine capability that does not exist yet;
|
|
91
|
+
* read a surface's full geometry via
|
|
92
|
+
* {@linkcode PluginDesignQueryGeometryApi.getBrep} on its `component` instead.
|
|
93
|
+
* - After heavy edits (move / stretch / boolean) or on imported models the plan
|
|
94
|
+
* match can miss or mis-attribute a surface — treat the result as advisory,
|
|
95
|
+
* not authoritative.
|
|
96
|
+
* - `adjacentSpaces` comes from the same adjacency data as
|
|
97
|
+
* {@linkcode PluginProgramAdjacencyApi.getMatrix} (so the two agree on which
|
|
98
|
+
* spaces neighbour). `sharedEdgeLength` is `0` because that data exposes no
|
|
99
|
+
* edge length, and `sharedSurface` is the common boundary wall only when one
|
|
100
|
+
* is found geometrically (else `null`).
|
|
101
|
+
*
|
|
102
|
+
* Read-only; never mutates the model.
|
|
103
|
+
*
|
|
104
|
+
* @param space - The space (room mass) to read
|
|
105
|
+
* @returns the {@linkcode PluginSpaceEnclosure}, or `null` when `space` is not a
|
|
106
|
+
* space (room mass) or has no extractable plan footprint
|
|
107
|
+
*
|
|
108
|
+
* @examplePrompt What walls, floor and ceiling enclose this room?
|
|
109
|
+
* @examplePrompt Which of this room's walls are external?
|
|
110
|
+
* @examplePrompt List the doors and windows around the selected space
|
|
111
|
+
* @examplePrompt Which spaces are adjacent to this room, and through which wall?
|
|
112
|
+
*
|
|
113
|
+
* # Example
|
|
114
|
+
* ```ts
|
|
115
|
+
* const [space] = await snaptrude.design.query.listSpaces()
|
|
116
|
+
* const enclosure = await snaptrude.design.query.spaces.getEnclosure(space)
|
|
117
|
+
* if (enclosure) {
|
|
118
|
+
* const walls = enclosure.surfaces.filter((s) => s.role === "wall")
|
|
119
|
+
* const external = walls.filter((s) => s.isExternal)
|
|
120
|
+
* console.log(`${walls.length} walls, ${external.length} external`)
|
|
121
|
+
* }
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
public abstract getEnclosure(
|
|
125
|
+
space: ComponentHandle,
|
|
126
|
+
): PluginApiReturn<PluginSpaceEnclosure | null>
|
|
78
127
|
}
|
|
79
128
|
|
|
80
129
|
/**
|
|
@@ -130,3 +179,97 @@ export const PluginDesignQuerySpacesGetResult = PluginSpaceGetResult.omit({
|
|
|
130
179
|
export type PluginDesignQuerySpacesGetResult = z.infer<
|
|
131
180
|
typeof PluginDesignQuerySpacesGetResult
|
|
132
181
|
>
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Arguments for {@linkcode PluginDesignQuerySpacesApi.getEnclosure}.
|
|
185
|
+
*
|
|
186
|
+
* | Property | Type | Description |
|
|
187
|
+
* |---|---|---|
|
|
188
|
+
* | `space` | {@linkcode ComponentHandle} | The space (room mass) to read |
|
|
189
|
+
*/
|
|
190
|
+
export const PluginDesignQuerySpacesGetEnclosureArgs = z.object({
|
|
191
|
+
space: ComponentHandle,
|
|
192
|
+
})
|
|
193
|
+
export type PluginDesignQuerySpacesGetEnclosureArgs = z.infer<
|
|
194
|
+
typeof PluginDesignQuerySpacesGetEnclosureArgs
|
|
195
|
+
>
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* The role a bounding surface plays in a {@linkcode PluginSpaceEnclosure}:
|
|
199
|
+
* `"floor"` (slab below), `"ceiling"` (slab/roof above), or `"wall"`.
|
|
200
|
+
*/
|
|
201
|
+
export const PluginEnclosureRole = z.enum(["floor", "ceiling", "wall"])
|
|
202
|
+
export type PluginEnclosureRole = z.infer<typeof PluginEnclosureRole>
|
|
203
|
+
|
|
204
|
+
/** The kind of opening hosted in a bounding wall. */
|
|
205
|
+
export const PluginEnclosureOpeningKind = z.enum(["door", "window", "void"])
|
|
206
|
+
export type PluginEnclosureOpeningKind = z.infer<
|
|
207
|
+
typeof PluginEnclosureOpeningKind
|
|
208
|
+
>
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* One opening (door / window / void) in a bounding wall.
|
|
212
|
+
*
|
|
213
|
+
* | Property | Type | Description |
|
|
214
|
+
* |---|---|---|
|
|
215
|
+
* | `kind` | {@linkcode PluginEnclosureOpeningKind} | `"door"`, `"window"`, or `"void"` |
|
|
216
|
+
* | `component` | {@linkcode ComponentHandle} | The opening entity |
|
|
217
|
+
*/
|
|
218
|
+
export const PluginEnclosureOpening = z.object({
|
|
219
|
+
kind: PluginEnclosureOpeningKind,
|
|
220
|
+
component: ComponentHandle,
|
|
221
|
+
})
|
|
222
|
+
export type PluginEnclosureOpening = z.infer<typeof PluginEnclosureOpening>
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* One bounding surface of a space's enclosure.
|
|
226
|
+
*
|
|
227
|
+
* | Property | Type | Description |
|
|
228
|
+
* |---|---|---|
|
|
229
|
+
* | `role` | {@linkcode PluginEnclosureRole} | `"floor"`, `"ceiling"`, or `"wall"` |
|
|
230
|
+
* | `component` | {@linkcode ComponentHandle} | The wall / slab / roof entity |
|
|
231
|
+
* | `faceIndices` | `number[]` | B-rep face indices facing the space. **Always `[]` in geometric v1** (no triangle→face provenance yet) |
|
|
232
|
+
* | `isExternal` | `boolean` | No space on the other side — for a wall, no other room bounds it; for a floor/ceiling, no room caps the storey below/above |
|
|
233
|
+
* | `openings` | {@linkcode PluginEnclosureOpening}`[]` | Doors/windows/voids in the surface (walls only; `[]` for floor/ceiling in v1) |
|
|
234
|
+
*/
|
|
235
|
+
export const PluginEnclosureSurface = z.object({
|
|
236
|
+
role: PluginEnclosureRole,
|
|
237
|
+
component: ComponentHandle,
|
|
238
|
+
faceIndices: z.array(z.number()),
|
|
239
|
+
isExternal: z.boolean(),
|
|
240
|
+
openings: z.array(PluginEnclosureOpening),
|
|
241
|
+
})
|
|
242
|
+
export type PluginEnclosureSurface = z.infer<typeof PluginEnclosureSurface>
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* A space that neighbours the queried space.
|
|
246
|
+
*
|
|
247
|
+
* | Property | Type | Description |
|
|
248
|
+
* |---|---|---|
|
|
249
|
+
* | `space` | {@linkcode ComponentHandle} | The neighbouring space |
|
|
250
|
+
* | `sharedSurface` | {@linkcode ComponentHandle}` \| null` | The common boundary wall when one is found geometrically, else `null` (e.g. an open-plan or non-physical adjacency) |
|
|
251
|
+
* | `sharedEdgeLength` | `number` | Plan-unit length of the shared boundary — **always `0` in geometric v1** (the adjacency data exposes no edge length) |
|
|
252
|
+
*/
|
|
253
|
+
export const PluginAdjacentSpace = z.object({
|
|
254
|
+
space: ComponentHandle,
|
|
255
|
+
sharedSurface: ComponentHandle.nullable(),
|
|
256
|
+
sharedEdgeLength: z.number(),
|
|
257
|
+
})
|
|
258
|
+
export type PluginAdjacentSpace = z.infer<typeof PluginAdjacentSpace>
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Result of {@linkcode PluginDesignQuerySpacesApi.getEnclosure} — the geometric
|
|
262
|
+
* v1 enclosure of a space.
|
|
263
|
+
*
|
|
264
|
+
* | Property | Type | Description |
|
|
265
|
+
* |---|---|---|
|
|
266
|
+
* | `space` | {@linkcode ComponentHandle} | The queried space |
|
|
267
|
+
* | `surfaces` | {@linkcode PluginEnclosureSurface}`[]` | Floor + ceiling + bounding walls, as a flat list (any of the three may be absent when no plan match is found) |
|
|
268
|
+
* | `adjacentSpaces` | {@linkcode PluginAdjacentSpace}`[]` | Neighbouring spaces from the adjacency data (`[]` when adjacency was never computed) |
|
|
269
|
+
*/
|
|
270
|
+
export const PluginSpaceEnclosure = z.object({
|
|
271
|
+
space: ComponentHandle,
|
|
272
|
+
surfaces: z.array(PluginEnclosureSurface),
|
|
273
|
+
adjacentSpaces: z.array(PluginAdjacentSpace),
|
|
274
|
+
})
|
|
275
|
+
export type PluginSpaceEnclosure = z.infer<typeof PluginSpaceEnclosure>
|
|
@@ -3,6 +3,91 @@ import { PluginApiReturn } from "../../../types"
|
|
|
3
3
|
import { ComponentHandle } from "../../../handles"
|
|
4
4
|
import { PluginDesignChangeResult } from "../lock"
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* The entity kinds {@linkcode PluginDesignSelectionApi.setByFilter} can select —
|
|
8
|
+
* the union of the editor's "Filter selection" menus (Design tab + BIM tab).
|
|
9
|
+
* Tokens mirror {@linkcode PluginEntityType} where a kind exists on the query
|
|
10
|
+
* surface; the rest are selection-only kinds the query surface cannot reach
|
|
11
|
+
* (layer-backed and annotation objects).
|
|
12
|
+
*
|
|
13
|
+
* | Value | Entity (menu label) |
|
|
14
|
+
* |---|---|
|
|
15
|
+
* | `"wall"` | Wall |
|
|
16
|
+
* | `"slab"` | Floor slab |
|
|
17
|
+
* | `"floor"` | Flooring |
|
|
18
|
+
* | `"door"` | Door |
|
|
19
|
+
* | `"window"` | Window |
|
|
20
|
+
* | `"beam"` | Beam |
|
|
21
|
+
* | `"column"` | Column |
|
|
22
|
+
* | `"ceiling"` | Ceiling |
|
|
23
|
+
* | `"roof"` | Roof |
|
|
24
|
+
* | `"staircase"` | Staircase |
|
|
25
|
+
* | `"furniture"` | Furniture |
|
|
26
|
+
* | `"pergola"` | Pergola |
|
|
27
|
+
* | `"sunshade"` | Sunshade |
|
|
28
|
+
* | `"referenceLine"` | Reference line |
|
|
29
|
+
* | `"space"` | Space (room mass) |
|
|
30
|
+
* | `"site"` | Site |
|
|
31
|
+
* | `"terrain"` | Terrain |
|
|
32
|
+
* | `"cad"` | CAD import |
|
|
33
|
+
* | `"pdf"` | PDF import |
|
|
34
|
+
* | `"image"` | Image import |
|
|
35
|
+
* | `"dimensionLine"` | Dimension line |
|
|
36
|
+
* | `"model3d"` | Imported 3D model |
|
|
37
|
+
* | `"neighborhoodBuilding"` | Neighborhood building |
|
|
38
|
+
* | `"programBlock"` | Program block (department mass) |
|
|
39
|
+
*/
|
|
40
|
+
export const PluginSelectionEntityType = z.enum([
|
|
41
|
+
"wall",
|
|
42
|
+
"slab",
|
|
43
|
+
"floor",
|
|
44
|
+
"door",
|
|
45
|
+
"window",
|
|
46
|
+
"beam",
|
|
47
|
+
"column",
|
|
48
|
+
"ceiling",
|
|
49
|
+
"roof",
|
|
50
|
+
"staircase",
|
|
51
|
+
"furniture",
|
|
52
|
+
"pergola",
|
|
53
|
+
"sunshade",
|
|
54
|
+
"referenceLine",
|
|
55
|
+
"space",
|
|
56
|
+
"site",
|
|
57
|
+
"terrain",
|
|
58
|
+
"cad",
|
|
59
|
+
"pdf",
|
|
60
|
+
"image",
|
|
61
|
+
"dimensionLine",
|
|
62
|
+
"model3d",
|
|
63
|
+
"neighborhoodBuilding",
|
|
64
|
+
"programBlock",
|
|
65
|
+
])
|
|
66
|
+
export type PluginSelectionEntityType = z.infer<typeof PluginSelectionEntityType>
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* The filter for {@linkcode PluginDesignSelectionApi.setByFilter}. At least one
|
|
70
|
+
* field must be non-empty (to empty the selection use
|
|
71
|
+
* {@linkcode PluginDesignSelectionApi.clear}). Fields **AND**-combine; values
|
|
72
|
+
* within a field **OR**-combine — `{ storeys: [2], types: ["furniture"] }`
|
|
73
|
+
* selects only the furniture on storey 2.
|
|
74
|
+
*
|
|
75
|
+
* | Field | Type | Selects entities where |
|
|
76
|
+
* |---|---|---|
|
|
77
|
+
* | `storeys` | `number[]` | storey/floor level ∈ `storeys` (negative = basement) |
|
|
78
|
+
* | `types` | {@linkcode PluginSelectionEntityType}`[]` | entity kind ∈ `types` |
|
|
79
|
+
*/
|
|
80
|
+
export const PluginSelectionFilter = z
|
|
81
|
+
.object({
|
|
82
|
+
storeys: z.array(z.number()).optional(),
|
|
83
|
+
types: z.array(PluginSelectionEntityType).optional(),
|
|
84
|
+
})
|
|
85
|
+
.refine((f) => (f.storeys?.length ?? 0) + (f.types?.length ?? 0) > 0, {
|
|
86
|
+
message:
|
|
87
|
+
"PluginSelectionFilter requires at least one non-empty field (storeys or types); use design.selection.clear() to deselect everything",
|
|
88
|
+
})
|
|
89
|
+
export type PluginSelectionFilter = z.infer<typeof PluginSelectionFilter>
|
|
90
|
+
|
|
6
91
|
/**
|
|
7
92
|
* `snaptrude.design.selection` — read and mutate the current scene selection.
|
|
8
93
|
*
|
|
@@ -123,6 +208,50 @@ export abstract class PluginDesignSelectionApi {
|
|
|
123
208
|
* ```
|
|
124
209
|
*/
|
|
125
210
|
public abstract clear(): PluginApiReturn<PluginDesignChangeResult>
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Replace the selection with every visible entity of the active building that
|
|
214
|
+
* matches the filter — the programmatic equivalent of the editor's
|
|
215
|
+
* **Story selection** (`storeys`) and **Filter selection** (`types`) menus
|
|
216
|
+
* under the select tool, including their combination (fields AND, values
|
|
217
|
+
* within a field OR). Reaches selection-only kinds the query surface cannot
|
|
218
|
+
* (sites, terrain, CAD/PDF/image imports, dimension lines, 3D models,
|
|
219
|
+
* neighborhood buildings) and selects whole groups the way the editor does.
|
|
220
|
+
*
|
|
221
|
+
* This is a one-shot bulk select, not a persistent mode: the user's next
|
|
222
|
+
* canvas click resets the underlying filter state (the selection it made
|
|
223
|
+
* stays until changed). Results honor the ambient view — active building,
|
|
224
|
+
* hidden objects/buckets, and in 2D the active storey.
|
|
225
|
+
*
|
|
226
|
+
* @param filter Which entities to select — {@linkcode PluginSelectionFilter};
|
|
227
|
+
* at least one field must be non-empty
|
|
228
|
+
* @returns The resulting selection snapshot
|
|
229
|
+
*
|
|
230
|
+
* @examplePrompt Select everything on storey 2
|
|
231
|
+
* @examplePrompt Select all the walls and doors
|
|
232
|
+
* @examplePrompt Story selection: select the ground floor and first floor
|
|
233
|
+
* @examplePrompt Filter selection: select all furniture in the model
|
|
234
|
+
* @examplePrompt Select only the furniture on the second storey
|
|
235
|
+
* @examplePrompt Select all the spaces so I can recolor them
|
|
236
|
+
*
|
|
237
|
+
* # Example
|
|
238
|
+
* ```ts
|
|
239
|
+
* // "Story selection": everything on storeys 1 and 2
|
|
240
|
+
* await snaptrude.design.selection.setByFilter({ storeys: [1, 2] })
|
|
241
|
+
*
|
|
242
|
+
* // "Filter selection": all walls and doors
|
|
243
|
+
* await snaptrude.design.selection.setByFilter({ types: ["wall", "door"] })
|
|
244
|
+
*
|
|
245
|
+
* // Combined: only the furniture on storey 2
|
|
246
|
+
* const { affected } = await snaptrude.design.selection.setByFilter({
|
|
247
|
+
* storeys: [2],
|
|
248
|
+
* types: ["furniture"],
|
|
249
|
+
* })
|
|
250
|
+
* ```
|
|
251
|
+
*/
|
|
252
|
+
public abstract setByFilter(
|
|
253
|
+
filter: PluginSelectionFilter
|
|
254
|
+
): PluginApiReturn<PluginDesignChangeResult>
|
|
126
255
|
}
|
|
127
256
|
|
|
128
257
|
/**
|