@snaptrude/plugin-core 0.10.0 → 0.11.0-rc.1
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 +24 -2
- package/api-manifest.full.json +6928 -0
- package/api-manifest.json +85 -4
- package/dist/api/core/camera/index.d.ts +16 -0
- package/dist/api/core/camera/index.d.ts.map +1 -1
- package/dist/api/core/project/index.d.ts +68 -1
- package/dist/api/core/project/index.d.ts.map +1 -1
- package/dist/api/core/storeys/index.d.ts +14 -0
- package/dist/api/core/storeys/index.d.ts.map +1 -1
- package/dist/api/design/create/index.d.ts +29 -6
- package/dist/api/design/create/index.d.ts.map +1 -1
- package/dist/api/design/delete/index.d.ts +20 -2
- package/dist/api/design/delete/index.d.ts.map +1 -1
- package/dist/api/design/furniture/index.d.ts +33 -0
- package/dist/api/design/furniture/index.d.ts.map +1 -1
- package/dist/api/design/query/index.d.ts +2 -0
- package/dist/api/design/query/index.d.ts.map +1 -1
- package/dist/api/design/query/spaces.d.ts +61 -0
- package/dist/api/design/query/spaces.d.ts.map +1 -1
- package/dist/api/design/visibility.d.ts +28 -0
- package/dist/api/design/visibility.d.ts.map +1 -1
- package/dist/api/entity/space.d.ts +3 -0
- package/dist/api/entity/space.d.ts.map +1 -1
- package/dist/api/presentation/placedViews.d.ts +35 -1
- package/dist/api/presentation/placedViews.d.ts.map +1 -1
- package/dist/api/presentation/sheets.d.ts +20 -2
- package/dist/api/presentation/sheets.d.ts.map +1 -1
- package/dist/errors/codes.d.ts +8 -3
- package/dist/errors/codes.d.ts.map +1 -1
- package/dist/index.cjs +69 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +62 -3
- package/dist/index.js.map +1 -1
- package/package.json +13 -13
- package/snaptrude-plugin-core-0.11.0.tgz +0 -0
- package/src/api/core/camera/index.ts +17 -0
- package/src/api/core/project/index.ts +62 -1
- package/src/api/core/storeys/index.ts +15 -0
- package/src/api/design/create/index.ts +34 -8
- package/src/api/design/delete/index.ts +20 -1
- package/src/api/design/furniture/index.ts +34 -0
- package/src/api/design/query/index.ts +2 -0
- package/src/api/design/query/spaces.ts +68 -0
- package/src/api/design/visibility.ts +34 -0
- package/src/api/entity/space.ts +2 -0
- package/src/api/presentation/placedViews.ts +29 -1
- package/src/api/presentation/sheets.ts +19 -3
- package/src/errors/codes.ts +30 -2
- package/test/errors.test.mjs +4 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@snaptrude/plugin-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0-rc.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -16,17 +16,6 @@
|
|
|
16
16
|
"publishConfig": {
|
|
17
17
|
"access": "public"
|
|
18
18
|
},
|
|
19
|
-
"scripts": {
|
|
20
|
-
"check-types": "tsc --noEmit",
|
|
21
|
-
"build": "tsup --clean",
|
|
22
|
-
"dev": "tsup --watch",
|
|
23
|
-
"clean-dist": "rm -rf dist",
|
|
24
|
-
"test": "node --test test/*.test.mjs",
|
|
25
|
-
"generate:manifest": "node scripts/generate-manifest.mjs",
|
|
26
|
-
"generate:manifest:check": "node scripts/generate-manifest.mjs --check",
|
|
27
|
-
"generate:manifest:all": "node scripts/generate-manifest.mjs --all",
|
|
28
|
-
"generate:manifest:all:check": "node scripts/generate-manifest.mjs --all --check"
|
|
29
|
-
},
|
|
30
19
|
"devDependencies": {
|
|
31
20
|
"ts-morph": "^28.0.0",
|
|
32
21
|
"tsup": "^8.5.1",
|
|
@@ -37,5 +26,16 @@
|
|
|
37
26
|
},
|
|
38
27
|
"peerDependencies": {
|
|
39
28
|
"zod": "^3.25.0 || ^4.0.0"
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"check-types": "tsc --noEmit",
|
|
32
|
+
"build": "tsup --clean",
|
|
33
|
+
"dev": "tsup --watch",
|
|
34
|
+
"clean-dist": "rm -rf dist",
|
|
35
|
+
"test": "node --test test/*.test.mjs",
|
|
36
|
+
"generate:manifest": "node scripts/generate-manifest.mjs",
|
|
37
|
+
"generate:manifest:check": "node scripts/generate-manifest.mjs --check",
|
|
38
|
+
"generate:manifest:all": "node scripts/generate-manifest.mjs --all",
|
|
39
|
+
"generate:manifest:all:check": "node scripts/generate-manifest.mjs --all --check"
|
|
40
40
|
}
|
|
41
|
-
}
|
|
41
|
+
}
|
|
Binary file
|
|
@@ -62,6 +62,23 @@ export abstract class PluginCameraApi {
|
|
|
62
62
|
view: PluginStandardView,
|
|
63
63
|
): PluginApiReturn<boolean>
|
|
64
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Get the current camera mode. Paired with {@linkcode PluginCameraApi.setMode}.
|
|
67
|
+
*
|
|
68
|
+
* @returns `"2d"` when the editor is in plan view, `"3d"` otherwise.
|
|
69
|
+
*
|
|
70
|
+
* @examplePrompt Am I in 2D or 3D?
|
|
71
|
+
* @examplePrompt What view mode is the editor in?
|
|
72
|
+
*
|
|
73
|
+
* # Example
|
|
74
|
+
* ```ts
|
|
75
|
+
* if ((await snaptrude.core.camera.getMode()) === "2d") {
|
|
76
|
+
* await snaptrude.core.camera.setMode("3d")
|
|
77
|
+
* }
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
public abstract getMode(): PluginApiReturn<PluginCameraMode>
|
|
81
|
+
|
|
65
82
|
/**
|
|
66
83
|
* Toggle the modelling mode between `2d` (plan) and `3d`. Mirrors the canvas
|
|
67
84
|
* 2D/3D toggle: `3d` enters the isometric perspective view, `2d` drops to the
|
|
@@ -1,15 +1,47 @@
|
|
|
1
1
|
import * as z from "zod"
|
|
2
2
|
import { PluginApiReturn } from "../../../types"
|
|
3
|
+
import { PUnitType } from "../units"
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Project-level settings and info.
|
|
6
7
|
*
|
|
7
|
-
* Accessed via `snaptrude.core.project`.
|
|
8
|
+
* Accessed via `snaptrude.core.project`. Exposes
|
|
9
|
+
* {@linkcode PluginProjectApi.getInfo} (project identity) and
|
|
8
10
|
* {@linkcode PluginProjectApi.settings} (snap + grid controls).
|
|
9
11
|
*/
|
|
10
12
|
export abstract class PluginProjectApi {
|
|
11
13
|
constructor() {}
|
|
12
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Read identity and headline facts about the currently open project — id,
|
|
17
|
+
* display name, unit type, storey count, active storey, and site location
|
|
18
|
+
* when the project is geo-located.
|
|
19
|
+
*
|
|
20
|
+
* `activeStorey` and `storeyCount` are both scoped to the ACTIVE BUILDING, so
|
|
21
|
+
* they always describe the same building. In a multi-building project
|
|
22
|
+
* `storeyCount` is therefore NOT the total across every building — use
|
|
23
|
+
* `core.storeys.list()`, which spans all buildings, for that.
|
|
24
|
+
*
|
|
25
|
+
* @returns A {@linkcode PluginProjectInfo}. `name` is `null` only when the
|
|
26
|
+
* project genuinely has no title; `location` is `null` only when the project
|
|
27
|
+
* is not geo-located. Neither is used to signal a failure.
|
|
28
|
+
* @throws PRECONDITION_FAILED when no project is open.
|
|
29
|
+
* @throws OPERATION_FAILED when the project lookup or the site-location read
|
|
30
|
+
* fails. A failed read is never reported as `null`.
|
|
31
|
+
*
|
|
32
|
+
* @examplePrompt What is this project called?
|
|
33
|
+
* @examplePrompt Where is this project located?
|
|
34
|
+
* @examplePrompt Give me a summary of this project
|
|
35
|
+
* @examplePrompt How many storeys does this project have?
|
|
36
|
+
*
|
|
37
|
+
* # Example
|
|
38
|
+
* ```ts
|
|
39
|
+
* const info = await snaptrude.core.project.getInfo()
|
|
40
|
+
* console.log(info.name, info.units, info.storeyCount)
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
public abstract getInfo(): PluginApiReturn<PluginProjectInfo>
|
|
44
|
+
|
|
13
45
|
/** Project settings — snaps and grid. See {@linkcode PluginProjectSettingsApi}. */
|
|
14
46
|
public abstract settings: PluginProjectSettingsApi
|
|
15
47
|
}
|
|
@@ -416,3 +448,32 @@ export const PluginToleranceArgs = z.object({
|
|
|
416
448
|
})
|
|
417
449
|
|
|
418
450
|
export type PluginToleranceArgs = z.infer<typeof PluginToleranceArgs>
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* Identity and headline facts about the currently open project.
|
|
454
|
+
*
|
|
455
|
+
* `location` is a read-only projection of {@linkcode PluginProgramSiteApi.getLocation}
|
|
456
|
+
* — `program.site.*` remains the full site surface (context, weather, polygons).
|
|
457
|
+
* It is mirrored here because "what and where is this project" is one question.
|
|
458
|
+
*
|
|
459
|
+
* | Property | Type | Description |
|
|
460
|
+
* |---|---|---|
|
|
461
|
+
* | `projectId` | `string` | The open project's id (floorkey) |
|
|
462
|
+
* | `name` | `string \| null` | Display name; `null` only when the project has no title (a failed lookup throws) |
|
|
463
|
+
* | `units` | {@linkcode PUnitType} | The project's unit type |
|
|
464
|
+
* | `activeStorey` | `number` | The active storey value, in the active building |
|
|
465
|
+
* | `storeyCount` | `number` | How many storeys the ACTIVE BUILDING has (not the project-wide total — `core.storeys.list()` spans all buildings) |
|
|
466
|
+
* | `location` | `{ latitude, longitude } \| null` | Site location; `null` only when not geo-located (a failed read throws) |
|
|
467
|
+
*/
|
|
468
|
+
export const PluginProjectInfo = z.object({
|
|
469
|
+
projectId: z.string(),
|
|
470
|
+
name: z.string().nullable(),
|
|
471
|
+
units: PUnitType,
|
|
472
|
+
activeStorey: z.number(),
|
|
473
|
+
storeyCount: z.number(),
|
|
474
|
+
location: z
|
|
475
|
+
.object({ latitude: z.number(), longitude: z.number() })
|
|
476
|
+
.nullable(),
|
|
477
|
+
})
|
|
478
|
+
|
|
479
|
+
export type PluginProjectInfo = z.infer<typeof PluginProjectInfo>
|
|
@@ -160,6 +160,21 @@ export abstract class PluginCoreStoreysApi {
|
|
|
160
160
|
options?: { name?: string },
|
|
161
161
|
): PluginApiReturn<PluginStoryUpdateResult>
|
|
162
162
|
|
|
163
|
+
/**
|
|
164
|
+
* Get the active storey's value. Paired with {@linkcode PluginCoreStoreysApi.setActive}.
|
|
165
|
+
*
|
|
166
|
+
* @returns The active storey value, in the same numbering `list` and `get` use.
|
|
167
|
+
*
|
|
168
|
+
* @examplePrompt Which storey am I on?
|
|
169
|
+
* @examplePrompt What is the current storey?
|
|
170
|
+
*
|
|
171
|
+
* # Example
|
|
172
|
+
* ```ts
|
|
173
|
+
* const storey = await snaptrude.core.storeys.getActive()
|
|
174
|
+
* ```
|
|
175
|
+
*/
|
|
176
|
+
public abstract getActive(): PluginApiReturn<number>
|
|
177
|
+
|
|
163
178
|
/**
|
|
164
179
|
* Make a storey the active storey — the same as clicking it in the storey/layer
|
|
165
180
|
* panel. Subsequent draws and creates target this storey, and in 2D the
|
|
@@ -217,11 +217,26 @@ export abstract class PluginDesignCreateApi {
|
|
|
217
217
|
* Create a **floor** by extruding a footprint contour by `thickness`
|
|
218
218
|
* (extruded upward).
|
|
219
219
|
*
|
|
220
|
+
* The parametric engine owns floor topology and may resolve the request
|
|
221
|
+
* differently than asked: drawing against existing floors can **split** the
|
|
222
|
+
* footprint into several floors, or **merge** it into a pre-existing
|
|
223
|
+
* neighbour (that floor's region grows; nothing new is created). The call
|
|
224
|
+
* honors the engine's resolution and returns **every floor that covers the
|
|
225
|
+
* requested footprint after the operation** — the newly created floor(s),
|
|
226
|
+
* and/or the pre-existing floor that absorbed it. The array is never empty
|
|
227
|
+
* on success; a lone independently-created floor comes back as `[floor]`.
|
|
228
|
+
*
|
|
229
|
+
* **Breaking change in 0.11.0** — previously returned a single
|
|
230
|
+
* {@linkcode ComponentHandle}; callers must switch to the array (the first
|
|
231
|
+
* element preserves the old single-floor behavior for simple creates).
|
|
232
|
+
*
|
|
220
233
|
* @param contour - Footprint (outer + holes)
|
|
221
234
|
* @param thickness - Floor thickness (> 0)
|
|
222
235
|
* @param position - Offset from origin
|
|
223
|
-
* @returns the {@linkcode ComponentHandle} of
|
|
224
|
-
*
|
|
236
|
+
* @returns the {@linkcode ComponentHandle}s of every floor covering the
|
|
237
|
+
* requested footprint after parametric resolution (created and/or absorbing)
|
|
238
|
+
* @throws if the contour is invalid, the thickness is not positive, or the
|
|
239
|
+
* engine rejected the operation (nothing covers the footprint)
|
|
225
240
|
*
|
|
226
241
|
* @examplePrompt Create a floor from this room outline
|
|
227
242
|
* @examplePrompt Add a 100mm thick floor over the footprint
|
|
@@ -232,14 +247,14 @@ export abstract class PluginDesignCreateApi {
|
|
|
232
247
|
* ```ts
|
|
233
248
|
* const rect = await snaptrude.core.geom.create.profileRect(5, 4)
|
|
234
249
|
* const contour = await snaptrude.core.geom.create.contourFromProfile(rect)
|
|
235
|
-
* const floor = await snaptrude.design.create.floor(contour, 0.1)
|
|
250
|
+
* const [floor, ...siblings] = await snaptrude.design.create.floor(contour, 0.1)
|
|
236
251
|
* ```
|
|
237
252
|
*/
|
|
238
253
|
public abstract floor(
|
|
239
254
|
contour: ContourHandle,
|
|
240
255
|
thickness: number,
|
|
241
256
|
position?: Vec3Handle,
|
|
242
|
-
): PluginApiReturn<ComponentHandle>
|
|
257
|
+
): PluginApiReturn<ComponentHandle[]>
|
|
243
258
|
|
|
244
259
|
/**
|
|
245
260
|
* Create a **roof** by extruding a footprint contour by `thickness`. Created
|
|
@@ -395,7 +410,13 @@ export abstract class PluginDesignCreateApi {
|
|
|
395
410
|
* single undo entry. The storey must already exist
|
|
396
411
|
* (`core.storeys.create` first). Default: geometry-derived — a profile
|
|
397
412
|
* drawn at y = 0 lands on storey 1; the ACTIVE storey is NOT consulted.
|
|
398
|
-
* @returns
|
|
413
|
+
* @returns the actually-created wall {@linkcode ComponentHandle}s. The
|
|
414
|
+
* parametric engine owns wall topology — curves touching existing walls
|
|
415
|
+
* may merge into or split against them, so the returned count can differ
|
|
416
|
+
* from the input curve count. Profile-ordered 1:1 matches come first,
|
|
417
|
+
* then the remaining merged/split products in creation order. Re-query
|
|
418
|
+
* (e.g. `design.query.spaces.listGeneratedBim`) rather than assuming a
|
|
419
|
+
* wall per input curve.
|
|
399
420
|
* @throws if the profile is empty, `wallType` names no wall type in the
|
|
400
421
|
* project, `storey` does not exist, or wall creation fails
|
|
401
422
|
*
|
|
@@ -537,7 +558,9 @@ export abstract class PluginDesignCreateApi {
|
|
|
537
558
|
* the item's height yourself.
|
|
538
559
|
* @param options - Optional placement options: `label` — instance name
|
|
539
560
|
* (default auto `${name}Ins${n}`); `createNewSourceMesh` — emit a
|
|
540
|
-
* source-mesh creation command (default `true`)
|
|
561
|
+
* source-mesh creation command (default `true`). `position.y` is always
|
|
562
|
+
* grounded: the placed instance's bounding-box bottom rests at it (the
|
|
563
|
+
* surface-flush grounding described above)
|
|
541
564
|
* @param angleInDegrees - Optional signed rotation about the vertical axis, in
|
|
542
565
|
* degrees (same convention as {@linkcode PluginDesignTransformApi.rotate}).
|
|
543
566
|
* Applied at creation time so it is part of the placement's single undo entry.
|
|
@@ -571,7 +594,10 @@ export abstract class PluginDesignCreateApi {
|
|
|
571
594
|
public abstract furniture(
|
|
572
595
|
catalogId: string,
|
|
573
596
|
position: Vec3Handle,
|
|
574
|
-
options?: {
|
|
597
|
+
options?: {
|
|
598
|
+
label?: string
|
|
599
|
+
createNewSourceMesh?: boolean
|
|
600
|
+
},
|
|
575
601
|
angleInDegrees?: number,
|
|
576
602
|
): PluginApiReturn<ComponentHandle>
|
|
577
603
|
|
|
@@ -1219,7 +1245,7 @@ export const PluginDesignCreateWallsArgs = z.object({
|
|
|
1219
1245
|
export type PluginDesignCreateWallsArgs = z.infer<
|
|
1220
1246
|
typeof PluginDesignCreateWallsArgs
|
|
1221
1247
|
>
|
|
1222
|
-
// TRANSPORT: positional signature shipped
|
|
1248
|
+
// TRANSPORT: positional signature shipped:
|
|
1223
1249
|
// walls(profile: ProfileHandle, height?: number, thickness?: number, wallType?: string, storey?: number)
|
|
1224
1250
|
|
|
1225
1251
|
// ---------------------------------------------------------------------------
|
|
@@ -20,6 +20,22 @@ export const PluginDesignDeleteEntitiesArgs = z.object({
|
|
|
20
20
|
})
|
|
21
21
|
export type PluginDesignDeleteEntitiesArgs = z.infer<typeof PluginDesignDeleteEntitiesArgs>
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Result of {@linkcode PluginDesignDeleteApi.entities} — the shared
|
|
25
|
+
* change-result shape plus the delete cascade. Deliberately a delete-specific
|
|
26
|
+
* extension of {@linkcode PluginDesignChangeResult} (which other change
|
|
27
|
+
* mutations keep unchanged).
|
|
28
|
+
*
|
|
29
|
+
* | Property | Type | Description |
|
|
30
|
+
* |---|---|---|
|
|
31
|
+
* | `affected` | {@linkcode ComponentHandle}`[]` | The entities that were deleted (the resolved input set) |
|
|
32
|
+
* | `cascaded` | {@linkcode ComponentHandle}`[]`? | Components PG2 removed as a consequence — derived walls/floors/slabs of deleted spaces; returned so callers can invalidate cached handles |
|
|
33
|
+
*/
|
|
34
|
+
export const PluginDesignDeleteResult = PluginDesignChangeResult.extend({
|
|
35
|
+
cascaded: z.array(ComponentHandle).optional(),
|
|
36
|
+
})
|
|
37
|
+
export type PluginDesignDeleteResult = z.infer<typeof PluginDesignDeleteResult>
|
|
38
|
+
|
|
23
39
|
/**
|
|
24
40
|
* `snaptrude.design.delete.*` — **hard removal** of scene BIM entities.
|
|
25
41
|
*
|
|
@@ -43,6 +59,9 @@ export abstract class PluginDesignDeleteApi {
|
|
|
43
59
|
* @returns The entities that were deleted, as {@linkcode ComponentHandle}`[]`
|
|
44
60
|
* (echoed host-side from the resolved+deleted set — the engine returns no ids).
|
|
45
61
|
* Deleted handles are **stale** afterwards: re-resolving one throws `HANDLE_INVALID`.
|
|
62
|
+
* When the parametric engine removes further components as a consequence
|
|
63
|
+
* (derived walls/floors/slabs of deleted spaces), those are reported in the
|
|
64
|
+
* optional `cascaded` array — invalidate any cached handles to them too.
|
|
46
65
|
* @throws If any supplied handle is unknown/forged (`HANDLE_INVALID`) — the whole
|
|
47
66
|
* call rejects before anything is deleted (all-or-nothing resolution).
|
|
48
67
|
*
|
|
@@ -66,5 +85,5 @@ export abstract class PluginDesignDeleteApi {
|
|
|
66
85
|
*/
|
|
67
86
|
public abstract entities(
|
|
68
87
|
components: ComponentHandle[],
|
|
69
|
-
): PluginApiReturn<
|
|
88
|
+
): PluginApiReturn<PluginDesignDeleteResult>
|
|
70
89
|
}
|
|
@@ -2,6 +2,7 @@ import * as z from "zod"
|
|
|
2
2
|
import { PluginApiReturn } from "../../../types"
|
|
3
3
|
import { ComponentHandle } from "../../../handles"
|
|
4
4
|
import { PluginDesignChangeResult } from "../lock"
|
|
5
|
+
import { PluginObjectCatalogGroup } from "../doors"
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* `snaptrude.design.furniture` — the placeable furniture **catalog** (a library of
|
|
@@ -92,9 +93,42 @@ export abstract class PluginDesignFurnitureApi {
|
|
|
92
93
|
* const items = await snaptrude.design.furniture.listCatalog(undefined, first)
|
|
93
94
|
* console.log(first, "→", items.length, "items")
|
|
94
95
|
* ```
|
|
96
|
+
*
|
|
97
|
+
* @deprecated Use `design.furniture.listCatalogGroups` — the same name
|
|
98
|
+
* `design.doors` and `design.windows` use. Still supported.
|
|
95
99
|
*/
|
|
96
100
|
public abstract listCategories(): PluginApiReturn<string[]>
|
|
97
101
|
|
|
102
|
+
/**
|
|
103
|
+
* List the furniture catalog's groups. Matches
|
|
104
|
+
* {@linkcode PluginDesignDoorsApi.listCatalogGroups} and
|
|
105
|
+
* {@linkcode PluginDesignWindowsApi.listCatalogGroups}, so all three catalog
|
|
106
|
+
* surfaces are named alike.
|
|
107
|
+
*
|
|
108
|
+
* `source` is `"default"` for the built-in picker groups and `"team"` for the
|
|
109
|
+
* sub-types of THIS project's team library — exactly the split
|
|
110
|
+
* {@linkcode PluginDesignFurnitureApi.listCatalog}'s `source` filter uses, so
|
|
111
|
+
* every `"team"` group is guaranteed to match at least one team item here.
|
|
112
|
+
* For furniture the group token and its label are the same string (the
|
|
113
|
+
* category), so `dbType === label`; `design.doors`/`design.windows` have a
|
|
114
|
+
* distinct engine `dbType`.
|
|
115
|
+
*
|
|
116
|
+
* @returns The catalog groups as {@linkcode PluginObjectCatalogGroup}`[]`
|
|
117
|
+
* (`[]` when empty). Pass a group's `dbType` (=== `label`) to
|
|
118
|
+
* {@linkcode PluginDesignFurnitureApi.listCatalog}'s `category` filter to
|
|
119
|
+
* list its items.
|
|
120
|
+
*
|
|
121
|
+
* @examplePrompt What furniture groups are available?
|
|
122
|
+
* @examplePrompt List the furniture categories in this project
|
|
123
|
+
*
|
|
124
|
+
* # Example
|
|
125
|
+
* ```ts
|
|
126
|
+
* const groups = await snaptrude.design.furniture.listCatalogGroups()
|
|
127
|
+
* for (const g of groups) console.log(g.dbType, g.label, g.source)
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
130
|
+
public abstract listCatalogGroups(): PluginApiReturn<PluginObjectCatalogGroup[]>
|
|
131
|
+
|
|
98
132
|
/**
|
|
99
133
|
* List the placeable furniture catalog (team + general libraries),
|
|
100
134
|
* optionally filtered by library `source` and/or `category`.
|
|
@@ -173,6 +173,7 @@ export type PluginDesignQueryComponentsArgs = z.infer<
|
|
|
173
173
|
* | `isLocked` | `boolean` | Lock flag |
|
|
174
174
|
* | `isHidden` | `boolean` | User-hidden flag |
|
|
175
175
|
* | `isSelected` | `boolean` | Current selection state |
|
|
176
|
+
* | `isVisible` | `boolean` | Whether the entity currently has a visible representation on canvas (user hide flag AND LOD/mode gating both considered); read-only |
|
|
176
177
|
* | `boundingBox` | {@linkcode BBoxComponents} | World-space AABB |
|
|
177
178
|
* | `adjacency` | `{ spaceId: string; value: number }[]` | Adjacency relationships (spaces/masses only). `value`: `2` = Direct (required), `1` = Indirect or physical contact, `-1` = Restricted; `0` entries are filtered out. `[]` when adjacency has never been computed — see `program.adjacency.compute`. |
|
|
178
179
|
*/
|
|
@@ -192,6 +193,7 @@ export const PluginEntityProperties = z
|
|
|
192
193
|
isLocked: z.boolean(),
|
|
193
194
|
isHidden: z.boolean(),
|
|
194
195
|
isSelected: z.boolean(),
|
|
196
|
+
isVisible: z.boolean(),
|
|
195
197
|
boundingBox: BBoxComponents,
|
|
196
198
|
adjacency: z.array(z.object({ spaceId: z.string(), value: z.number() })),
|
|
197
199
|
})
|
|
@@ -124,6 +124,41 @@ export abstract class PluginDesignQuerySpacesApi {
|
|
|
124
124
|
public abstract getEnclosure(
|
|
125
125
|
space: ComponentHandle,
|
|
126
126
|
): PluginApiReturn<PluginSpaceEnclosure | null>
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* List the space's **engine-generated BIM components** — the walls, floors
|
|
130
|
+
* and slabs the parametric engine derived from this space, grouped by kind.
|
|
131
|
+
*
|
|
132
|
+
* Unlike {@linkcode getEnclosure} (a geometric best-effort match), this read
|
|
133
|
+
* reports the engine's own derivation records, so every returned handle is a
|
|
134
|
+
* component the engine created *for this space*.
|
|
135
|
+
*
|
|
136
|
+
* The derived set is NOT stable across writes: a merge/split/rebuild of the
|
|
137
|
+
* space graph retires members and creates successors — re-query after any
|
|
138
|
+
* write that touches the space. This is the churn-recovery anchor: when a
|
|
139
|
+
* cached derived handle goes stale, call this again to pick up the current
|
|
140
|
+
* set.
|
|
141
|
+
*
|
|
142
|
+
* @param space - The space (room mass) to read
|
|
143
|
+
* @returns the generated component handles, grouped by kind
|
|
144
|
+
* ({@linkcode PluginSpaceGeneratedBim}); a group is `[]` when the engine
|
|
145
|
+
* derived nothing of that kind
|
|
146
|
+
* @throws If the space does not exist or the component is not a space/mass
|
|
147
|
+
*
|
|
148
|
+
* @examplePrompt Which walls did this room generate?
|
|
149
|
+
* @examplePrompt List the BIM components derived from the selected space
|
|
150
|
+
* @examplePrompt Get the floors and slabs that belong to this room
|
|
151
|
+
*
|
|
152
|
+
* # Example
|
|
153
|
+
* ```ts
|
|
154
|
+
* const [space] = await snaptrude.design.query.listSpaces()
|
|
155
|
+
* const bim = await snaptrude.design.query.spaces.listGeneratedBim(space)
|
|
156
|
+
* console.log(`${bim.walls.length} walls, ${bim.floors.length} floors`)
|
|
157
|
+
* ```
|
|
158
|
+
*/
|
|
159
|
+
public abstract listGeneratedBim(
|
|
160
|
+
space: ComponentHandle,
|
|
161
|
+
): PluginApiReturn<PluginSpaceGeneratedBim>
|
|
127
162
|
}
|
|
128
163
|
|
|
129
164
|
/**
|
|
@@ -273,3 +308,36 @@ export const PluginSpaceEnclosure = z.object({
|
|
|
273
308
|
adjacentSpaces: z.array(PluginAdjacentSpace),
|
|
274
309
|
})
|
|
275
310
|
export type PluginSpaceEnclosure = z.infer<typeof PluginSpaceEnclosure>
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Arguments for {@linkcode PluginDesignQuerySpacesApi.listGeneratedBim}.
|
|
314
|
+
*
|
|
315
|
+
* | Property | Type | Description |
|
|
316
|
+
* |---|---|---|
|
|
317
|
+
* | `space` | {@linkcode ComponentHandle} | The space (room mass) to read |
|
|
318
|
+
*/
|
|
319
|
+
export const PluginDesignQuerySpacesListGeneratedBimArgs = z.object({
|
|
320
|
+
space: ComponentHandle,
|
|
321
|
+
})
|
|
322
|
+
export type PluginDesignQuerySpacesListGeneratedBimArgs = z.infer<
|
|
323
|
+
typeof PluginDesignQuerySpacesListGeneratedBimArgs
|
|
324
|
+
>
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Result of {@linkcode PluginDesignQuerySpacesApi.listGeneratedBim} — the
|
|
328
|
+
* space's engine-generated BIM component handles, grouped by kind. The set
|
|
329
|
+
* changes whenever a write merges/splits/rebuilds the space graph — re-query
|
|
330
|
+
* after writes rather than caching it.
|
|
331
|
+
*
|
|
332
|
+
* | Property | Type | Description |
|
|
333
|
+
* |---|---|---|
|
|
334
|
+
* | `walls` | {@linkcode ComponentHandle}`[]` | Walls the engine derived from the space |
|
|
335
|
+
* | `floors` | {@linkcode ComponentHandle}`[]` | Floors the engine derived from the space |
|
|
336
|
+
* | `slabs` | {@linkcode ComponentHandle}`[]` | Slabs the engine derived from the space |
|
|
337
|
+
*/
|
|
338
|
+
export const PluginSpaceGeneratedBim = z.object({
|
|
339
|
+
walls: z.array(ComponentHandle),
|
|
340
|
+
floors: z.array(ComponentHandle),
|
|
341
|
+
slabs: z.array(ComponentHandle),
|
|
342
|
+
})
|
|
343
|
+
export type PluginSpaceGeneratedBim = z.infer<typeof PluginSpaceGeneratedBim>
|
|
@@ -39,6 +39,26 @@ export abstract class PluginDesignVisibilityApi {
|
|
|
39
39
|
components: ComponentHandle[],
|
|
40
40
|
): PluginApiReturn<PluginDesignChangeResult>
|
|
41
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Reveal specific hidden components — the inverse of
|
|
44
|
+
* {@linkcode PluginDesignVisibilityApi.hide}. Use
|
|
45
|
+
* {@linkcode PluginDesignVisibilityApi.showAll} to reveal everything.
|
|
46
|
+
*
|
|
47
|
+
* @param components - The components to reveal.
|
|
48
|
+
* @returns A {@linkcode PluginDesignChangeResult} echoing the components shown.
|
|
49
|
+
*
|
|
50
|
+
* @examplePrompt Show these walls again
|
|
51
|
+
* @examplePrompt Unhide the selected furniture
|
|
52
|
+
*
|
|
53
|
+
* # Example
|
|
54
|
+
* ```ts
|
|
55
|
+
* await snaptrude.design.visibility.show([wall])
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
public abstract show(
|
|
59
|
+
components: ComponentHandle[],
|
|
60
|
+
): PluginApiReturn<PluginDesignChangeResult>
|
|
61
|
+
|
|
42
62
|
/**
|
|
43
63
|
* Isolate entities — hide everything else so only the given entities remain
|
|
44
64
|
* visible (the "Isolate" / solo action). Undoable. Reverse it with
|
|
@@ -94,6 +114,20 @@ export const PluginDesignVisibilityHideArgs = z.object({
|
|
|
94
114
|
})
|
|
95
115
|
export type PluginDesignVisibilityHideArgs = z.infer<typeof PluginDesignVisibilityHideArgs>
|
|
96
116
|
|
|
117
|
+
/**
|
|
118
|
+
* Arguments for {@linkcode PluginDesignVisibilityApi.show}.
|
|
119
|
+
*
|
|
120
|
+
* | Property | Type | Description |
|
|
121
|
+
* |---|---|---|
|
|
122
|
+
* | `components` | {@linkcode ComponentHandle}`[]` | Entities to reveal |
|
|
123
|
+
*/
|
|
124
|
+
export const PluginDesignVisibilityShowArgs = z.object({
|
|
125
|
+
components: z.array(ComponentHandle),
|
|
126
|
+
})
|
|
127
|
+
export type PluginDesignVisibilityShowArgs = z.infer<
|
|
128
|
+
typeof PluginDesignVisibilityShowArgs
|
|
129
|
+
>
|
|
130
|
+
|
|
97
131
|
/**
|
|
98
132
|
* Arguments for {@linkcode PluginDesignVisibilityApi.isolate}.
|
|
99
133
|
*
|
package/src/api/entity/space.ts
CHANGED
|
@@ -434,6 +434,7 @@ export type PluginSpaceUpdateArgs = z.infer<typeof PluginSpaceUpdateArgs>
|
|
|
434
434
|
* | `massType` | `string?` | Updated mass type (if changed) |
|
|
435
435
|
* | `spaceType` | `string?` | Updated space type (if changed) |
|
|
436
436
|
* | `departmentId` | `string \| null?` | Updated department ID (if changed) |
|
|
437
|
+
* | `rebuilt` | `boolean?` | `true` when a geometry update rebuilt the space's derived BIM — hosted children were re-created and the previous derived handles are retired (re-query them) |
|
|
437
438
|
*/
|
|
438
439
|
export const PluginSpaceUpdateResult = z.object({
|
|
439
440
|
spaceId: z.string(),
|
|
@@ -442,6 +443,7 @@ export const PluginSpaceUpdateResult = z.object({
|
|
|
442
443
|
spaceType: z.string().optional(),
|
|
443
444
|
areaClass: PluginAreaClass.optional(),
|
|
444
445
|
departmentId: z.string().nullable().optional(),
|
|
446
|
+
rebuilt: z.boolean().optional(),
|
|
445
447
|
})
|
|
446
448
|
|
|
447
449
|
export type PluginSpaceUpdateResult = z.infer<typeof PluginSpaceUpdateResult>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as z from "zod"
|
|
2
2
|
import { PluginApiReturn } from "../../types"
|
|
3
|
-
import { PluginSheetPosition } from "./sheets"
|
|
3
|
+
import { PluginSheetPosition, PluginViewLod } from "./sheets"
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Placed views — the view shapes already laid out on the Present canvas.
|
|
@@ -613,6 +613,23 @@ export abstract class PluginPresentationPlacedViewsApi {
|
|
|
613
613
|
shapeId: string,
|
|
614
614
|
enabled: boolean,
|
|
615
615
|
): PluginApiReturn<void>
|
|
616
|
+
|
|
617
|
+
/**
|
|
618
|
+
* Set the level of detail a placed view renders at — `"design"` (the
|
|
619
|
+
* Design-mode massing representation) or `"bim"` (the detailed BIM
|
|
620
|
+
* representation). Views only. Undoable. Requires Present mode to be open.
|
|
621
|
+
*
|
|
622
|
+
* @param shapeId - The placed view shape.
|
|
623
|
+
* @param lod - Target level of detail.
|
|
624
|
+
* @throws If Present mode is not open or `shapeId` is not a placed view.
|
|
625
|
+
*
|
|
626
|
+
* @examplePrompt Switch this placed view to the BIM level of detail
|
|
627
|
+
* @examplePrompt Show the massing version of the placed plan
|
|
628
|
+
*/
|
|
629
|
+
public abstract setLod(
|
|
630
|
+
shapeId: string,
|
|
631
|
+
lod: PluginViewLod,
|
|
632
|
+
): PluginApiReturn<void>
|
|
616
633
|
}
|
|
617
634
|
|
|
618
635
|
/** A point in crop space — fractions (0–1) of the uncropped view. */
|
|
@@ -657,6 +674,8 @@ export type PluginPlacedViewCrop = z.infer<typeof PluginPlacedViewCrop>
|
|
|
657
674
|
* | `rotation` | `number` | Rotation in radians, `[0, 2π)` (nonzero only for 3D views — 2D views cannot rotate; set with `setRotation`) |
|
|
658
675
|
* | `crop` | {@linkcode PluginPlacedViewCrop}` \| null` | Crop window (`null` when uncropped) |
|
|
659
676
|
* | `isUnlinked` | `boolean` | Whether the source proposal was removed (an unlinked view no longer refreshes) |
|
|
677
|
+
* | `lod` | {@linkcode PluginViewLod}? | Level of detail the view renders at (`"design"` massing / `"bim"` detail); absent on views that predate LOD variants (set with `setLod`) |
|
|
678
|
+
* | `inactiveBuildingMask` | `boolean`? | Whether inactive proposal buildings are masked (the `setMask` toggle); absent when never set (masked by default) |
|
|
660
679
|
*/
|
|
661
680
|
export const PluginPlacedView = z.object({
|
|
662
681
|
shapeId: z.string(),
|
|
@@ -670,6 +689,8 @@ export const PluginPlacedView = z.object({
|
|
|
670
689
|
rotation: z.number(),
|
|
671
690
|
crop: PluginPlacedViewCrop.nullable(),
|
|
672
691
|
isUnlinked: z.boolean(),
|
|
692
|
+
lod: PluginViewLod.optional(),
|
|
693
|
+
inactiveBuildingMask: z.boolean().optional(),
|
|
673
694
|
})
|
|
674
695
|
export type PluginPlacedView = z.infer<typeof PluginPlacedView>
|
|
675
696
|
|
|
@@ -1118,3 +1139,10 @@ export const PluginPlacedViewsSetMaskArgs = z.object({
|
|
|
1118
1139
|
enabled: z.boolean(),
|
|
1119
1140
|
})
|
|
1120
1141
|
export type PluginPlacedViewsSetMaskArgs = z.infer<typeof PluginPlacedViewsSetMaskArgs>
|
|
1142
|
+
|
|
1143
|
+
/** Arguments for {@link PluginPresentationPlacedViewsApi.setLod}. */
|
|
1144
|
+
export const PluginPlacedViewsSetLodArgs = z.object({
|
|
1145
|
+
shapeId: z.string().min(1),
|
|
1146
|
+
lod: PluginViewLod,
|
|
1147
|
+
})
|
|
1148
|
+
export type PluginPlacedViewsSetLodArgs = z.infer<typeof PluginPlacedViewsSetLodArgs>
|
|
@@ -172,9 +172,10 @@ export abstract class PluginPresentationSheetsApi {
|
|
|
172
172
|
* @param sheetId - The id of the sheet to place onto.
|
|
173
173
|
* @param viewId - The id of the saved view to place.
|
|
174
174
|
* @param options - Optional `position` ({@linkcode PluginSheetPosition}) —
|
|
175
|
-
* where to place it (sheet centre when omitted) —
|
|
175
|
+
* where to place it (sheet centre when omitted) — `scale` — a standard
|
|
176
176
|
* scale value for the project's unit system (2D/site-plan views only;
|
|
177
|
-
* auto-fit when omitted)
|
|
177
|
+
* auto-fit when omitted) — and `lod` ({@linkcode PluginViewLod}) — the LOD
|
|
178
|
+
* of the placed view (default: the product's Design default).
|
|
178
179
|
* @returns A {@linkcode PluginPresentationSheetsPlaceResult} with the created
|
|
179
180
|
* `shapeId`.
|
|
180
181
|
* @throws If Present mode is not open, the sheet/view id is invalid, `scale`
|
|
@@ -197,7 +198,11 @@ export abstract class PluginPresentationSheetsApi {
|
|
|
197
198
|
public abstract place(
|
|
198
199
|
sheetId: string,
|
|
199
200
|
viewId: string,
|
|
200
|
-
options?: {
|
|
201
|
+
options?: {
|
|
202
|
+
position?: PluginSheetPosition
|
|
203
|
+
scale?: number
|
|
204
|
+
lod?: PluginViewLod
|
|
205
|
+
},
|
|
201
206
|
): PluginApiReturn<PluginPresentationSheetsPlaceResult>
|
|
202
207
|
|
|
203
208
|
/**
|
|
@@ -408,6 +413,15 @@ export const PluginSheetPosition = z.object({
|
|
|
408
413
|
})
|
|
409
414
|
export type PluginSheetPosition = z.infer<typeof PluginSheetPosition>
|
|
410
415
|
|
|
416
|
+
/**
|
|
417
|
+
* The level of detail a placed view renders at: `"design"` (the Design-mode
|
|
418
|
+
* massing representation) or `"bim"` (the detailed BIM representation).
|
|
419
|
+
* Shared by `sheets.place` and `placedViews.*` (defined here because
|
|
420
|
+
* `placedViews` already imports from this module).
|
|
421
|
+
*/
|
|
422
|
+
export const PluginViewLod = z.enum(["design", "bim"])
|
|
423
|
+
export type PluginViewLod = z.infer<typeof PluginViewLod>
|
|
424
|
+
|
|
411
425
|
/** Result of {@linkcode PluginPresentationSheetsApi.list}. */
|
|
412
426
|
export const PluginPresentationSheetsListResult = z.object({
|
|
413
427
|
sheets: z.array(PluginPresentationSheet),
|
|
@@ -469,12 +483,14 @@ export type PluginPresentationSheetsSetMarginArgs = z.infer<
|
|
|
469
483
|
* | `viewId` | `string` | The saved view to place |
|
|
470
484
|
* | `position` | {@linkcode PluginSheetPosition}` \| undefined` | Where to place it (sheet centre when omitted) |
|
|
471
485
|
* | `scale` | `number \| undefined` | Standard scale value for the project's unit system (2D/site-plan views only; auto-fit to the closest standard scale when omitted) |
|
|
486
|
+
* | `lod` | {@linkcode PluginViewLod}` \| undefined` | LOD of the placed view (default: the product's Design default) |
|
|
472
487
|
*/
|
|
473
488
|
export const PluginPresentationSheetsPlaceArgs = z.object({
|
|
474
489
|
sheetId: z.string(),
|
|
475
490
|
viewId: z.string(),
|
|
476
491
|
position: PluginSheetPosition.optional(),
|
|
477
492
|
scale: z.number().positive().optional(),
|
|
493
|
+
lod: PluginViewLod.optional(),
|
|
478
494
|
})
|
|
479
495
|
export type PluginPresentationSheetsPlaceArgs = z.infer<
|
|
480
496
|
typeof PluginPresentationSheetsPlaceArgs
|