@snaptrude/plugin-core 0.7.0 → 0.8.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.
Files changed (133) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/api-manifest.full.json +360 -19
  3. package/api-manifest.json +915 -37
  4. package/dist/api/core/camera/index.d.ts +208 -0
  5. package/dist/api/core/camera/index.d.ts.map +1 -0
  6. package/dist/api/core/comment/index.d.ts +105 -2
  7. package/dist/api/core/comment/index.d.ts.map +1 -1
  8. package/dist/api/core/geom/create/index.d.ts +13 -13
  9. package/dist/api/core/geom/delete/index.d.ts +8 -2
  10. package/dist/api/core/geom/delete/index.d.ts.map +1 -1
  11. package/dist/api/core/geom/query/arc.d.ts +5 -5
  12. package/dist/api/core/geom/query/brep.d.ts +18 -18
  13. package/dist/api/core/geom/query/circle.d.ts +18 -18
  14. package/dist/api/core/geom/query/contour.d.ts +20 -20
  15. package/dist/api/core/geom/query/curve.d.ts +49 -49
  16. package/dist/api/core/geom/query/edge.d.ts +5 -5
  17. package/dist/api/core/geom/query/face.d.ts +16 -16
  18. package/dist/api/core/geom/query/halfedge.d.ts +8 -8
  19. package/dist/api/core/geom/query/profile.d.ts +19 -19
  20. package/dist/api/core/geom/query/vertex.d.ts +8 -8
  21. package/dist/api/core/geom/update/contour.d.ts +14 -14
  22. package/dist/api/core/geom/update/curve.d.ts +7 -7
  23. package/dist/api/core/geom/update/profile.d.ts +16 -16
  24. package/dist/api/core/handles/index.d.ts +210 -0
  25. package/dist/api/core/handles/index.d.ts.map +1 -0
  26. package/dist/api/core/index.d.ts +15 -0
  27. package/dist/api/core/index.d.ts.map +1 -1
  28. package/dist/api/core/io/export/index.d.ts +132 -0
  29. package/dist/api/core/io/export/index.d.ts.map +1 -0
  30. package/dist/api/core/io/import/index.d.ts +1 -1
  31. package/dist/api/core/io/index.d.ts +5 -0
  32. package/dist/api/core/io/index.d.ts.map +1 -1
  33. package/dist/api/core/layers.d.ts +7 -7
  34. package/dist/api/core/proposals/index.d.ts +65 -9
  35. package/dist/api/core/proposals/index.d.ts.map +1 -1
  36. package/dist/api/core/user.d.ts +44 -0
  37. package/dist/api/core/user.d.ts.map +1 -0
  38. package/dist/api/design/boolean/index.d.ts +4 -4
  39. package/dist/api/design/create/index.d.ts +139 -44
  40. package/dist/api/design/create/index.d.ts.map +1 -1
  41. package/dist/api/design/doors/index.d.ts +36 -0
  42. package/dist/api/design/doors/index.d.ts.map +1 -1
  43. package/dist/api/design/edit/index.d.ts +1 -1
  44. package/dist/api/design/erase/index.d.ts +2 -2
  45. package/dist/api/design/furniture/index.d.ts +114 -3
  46. package/dist/api/design/furniture/index.d.ts.map +1 -1
  47. package/dist/api/design/index.d.ts +10 -0
  48. package/dist/api/design/index.d.ts.map +1 -1
  49. package/dist/api/design/materials/index.d.ts +111 -14
  50. package/dist/api/design/materials/index.d.ts.map +1 -1
  51. package/dist/api/design/query/index.d.ts +31 -1
  52. package/dist/api/design/query/index.d.ts.map +1 -1
  53. package/dist/api/design/query/spaces.d.ts +5 -5
  54. package/dist/api/design/transform/index.d.ts +83 -14
  55. package/dist/api/design/transform/index.d.ts.map +1 -1
  56. package/dist/api/design/types/index.d.ts +181 -0
  57. package/dist/api/design/types/index.d.ts.map +1 -0
  58. package/dist/api/design/update/index.d.ts +335 -2
  59. package/dist/api/design/update/index.d.ts.map +1 -1
  60. package/dist/api/design/visibility.d.ts +98 -0
  61. package/dist/api/design/visibility.d.ts.map +1 -0
  62. package/dist/api/entity/referenceLine.d.ts +2 -2
  63. package/dist/api/entity/space.d.ts +19 -19
  64. package/dist/api/entity/story.d.ts +128 -15
  65. package/dist/api/entity/story.d.ts.map +1 -1
  66. package/dist/api/presentation/aiInspiration.d.ts +1967 -7
  67. package/dist/api/presentation/aiInspiration.d.ts.map +1 -1
  68. package/dist/api/presentation/annotate.d.ts +448 -0
  69. package/dist/api/presentation/annotate.d.ts.map +1 -0
  70. package/dist/api/presentation/diagrams.d.ts +49 -8
  71. package/dist/api/presentation/diagrams.d.ts.map +1 -1
  72. package/dist/api/presentation/export.d.ts +104 -0
  73. package/dist/api/presentation/export.d.ts.map +1 -0
  74. package/dist/api/presentation/index.d.ts +40 -3
  75. package/dist/api/presentation/index.d.ts.map +1 -1
  76. package/dist/api/presentation/sheets.d.ts +410 -13
  77. package/dist/api/presentation/sheets.d.ts.map +1 -1
  78. package/dist/api/presentation/views.d.ts +165 -10
  79. package/dist/api/presentation/views.d.ts.map +1 -1
  80. package/dist/api/program/areas.d.ts +63 -3
  81. package/dist/api/program/areas.d.ts.map +1 -1
  82. package/dist/api/program/cores.d.ts +3 -99
  83. package/dist/api/program/cores.d.ts.map +1 -1
  84. package/dist/api/program/index.d.ts +2 -2
  85. package/dist/api/program/index.d.ts.map +1 -1
  86. package/dist/api/program/layout.d.ts +172 -12
  87. package/dist/api/program/layout.d.ts.map +1 -1
  88. package/dist/api/program/site.d.ts +11 -8
  89. package/dist/api/program/site.d.ts.map +1 -1
  90. package/dist/api/program/spreadsheet.d.ts +105 -13
  91. package/dist/api/program/spreadsheet.d.ts.map +1 -1
  92. package/dist/handles.d.ts +64 -25
  93. package/dist/handles.d.ts.map +1 -1
  94. package/dist/index.cjs +2502 -1466
  95. package/dist/index.cjs.map +1 -1
  96. package/dist/index.js +2369 -1461
  97. package/dist/index.js.map +1 -1
  98. package/package.json +1 -1
  99. package/src/api/core/camera/index.ts +212 -0
  100. package/src/api/core/comment/index.ts +120 -2
  101. package/src/api/core/geom/delete/index.ts +6 -0
  102. package/src/api/core/handles/index.ts +233 -0
  103. package/src/api/core/index.ts +15 -0
  104. package/src/api/core/io/export/index.ts +124 -0
  105. package/src/api/core/io/index.ts +5 -0
  106. package/src/api/core/proposals/index.ts +71 -11
  107. package/src/api/core/user.ts +46 -0
  108. package/src/api/design/create/index.ts +166 -36
  109. package/src/api/design/doors/index.ts +40 -0
  110. package/src/api/design/furniture/index.ts +127 -3
  111. package/src/api/design/index.ts +10 -0
  112. package/src/api/design/materials/index.ts +157 -30
  113. package/src/api/design/query/index.ts +33 -7
  114. package/src/api/design/transform/index.ts +89 -12
  115. package/src/api/design/types/index.ts +156 -0
  116. package/src/api/design/update/index.ts +402 -6
  117. package/src/api/design/visibility.ts +109 -0
  118. package/src/api/entity/story.ts +141 -15
  119. package/src/api/presentation/aiInspiration.ts +761 -7
  120. package/src/api/presentation/annotate.ts +360 -0
  121. package/src/api/presentation/diagrams.ts +53 -8
  122. package/src/api/presentation/export.ts +104 -0
  123. package/src/api/presentation/index.ts +48 -3
  124. package/src/api/presentation/sheets.ts +346 -13
  125. package/src/api/presentation/views.ts +164 -12
  126. package/src/api/program/areas.ts +57 -6
  127. package/src/api/program/cores.ts +3 -91
  128. package/src/api/program/index.ts +2 -2
  129. package/src/api/program/layout.ts +182 -12
  130. package/src/api/program/site.ts +11 -8
  131. package/src/api/program/spreadsheet.ts +125 -29
  132. package/src/handles.ts +77 -13
  133. package/tsconfig.json +7 -2
@@ -1,19 +1,78 @@
1
1
  import * as z from "zod"
2
2
  import { PluginApiReturn } from "../../../types"
3
+ import { ComponentHandle } from "../../../handles"
4
+ import { PluginDesignChangeResult } from "../lock"
3
5
 
4
6
  /**
5
7
  * `snaptrude.design.furniture` — the placeable furniture **catalog** (a library of
6
- * source items, NOT scene entities). Placement lives at `design.create.furniture`
7
- * (returns a {@linkcode ComponentHandle}); reads of placed furniture live at
8
- * `design.query.listFurniture`/`getProperties`.
8
+ * source items, NOT scene entities) plus dimension reads/edits of PLACED furniture.
9
+ * Placement lives at `design.create.furniture` (returns a {@linkcode ComponentHandle});
10
+ * generic reads of placed furniture live at `design.query.listFurniture`/`getProperties`.
9
11
  *
10
12
  * Catalog items are plain value records ({@linkcode PluginFurnitureCatalogItem}) keyed
11
13
  * by a library id (team `_id` or general `fullName`) — not handles. Reads are async
12
14
  * (network-backed) but carry no `Async` suffix (§6.6).
15
+ *
16
+ * {@linkcode PluginDesignFurnitureApi.getDimensions} / {@linkcode PluginDesignFurnitureApi.setDimensions}
17
+ * target a PLACED furniture {@linkcode ComponentHandle} (not a catalog id) — `length`
18
+ * along the object, `width` across it, `height` up. Values are engine units, matching
19
+ * the length/width/height fields the furniture properties panel shows.
13
20
  */
14
21
  export abstract class PluginDesignFurnitureApi {
15
22
  constructor() {}
16
23
 
24
+ /**
25
+ * Get the dimensions of a PLACED furniture item — `length` (along the object),
26
+ * `width` (across it) and `height` (vertical), in engine units. Mirrors the
27
+ * Length/Width/Height fields of the furniture properties panel.
28
+ *
29
+ * @param item The placed furniture to query
30
+ * @returns The dimensions, or `null` if the geometry is degenerate
31
+ *
32
+ * @examplePrompt How big is this sofa?
33
+ * @examplePrompt What are the dimensions of the selected furniture?
34
+ * @examplePrompt Measure the length, width and height of this table
35
+ * @examplePrompt Get the size of the chair I just placed
36
+ *
37
+ * # Example
38
+ * ```ts
39
+ * const [item] = await snaptrude.design.query.listFurniture({ isSelected: true })
40
+ * const dims = await snaptrude.design.furniture.getDimensions(item)
41
+ * if (dims) console.log(dims.length, dims.width, dims.height)
42
+ * ```
43
+ */
44
+ public abstract getDimensions(
45
+ item: ComponentHandle
46
+ ): PluginApiReturn<PluginFurnitureDimensions | null>
47
+
48
+ /**
49
+ * Resize a PLACED furniture item along one or more axes — `length`, `width`
50
+ * and/or `height` (engine units). Omitted axes are left unchanged. Each supplied
51
+ * axis is an undoable command, mirroring editing the furniture properties panel.
52
+ *
53
+ * @param item The placed furniture to resize
54
+ * @param dimensions New `length` / `width` / `height` (each optional, engine units)
55
+ * @returns The affected furniture
56
+ *
57
+ * @examplePrompt Make this table 1.8m long
58
+ * @examplePrompt Resize the selected sofa to 2000 wide
59
+ * @examplePrompt Set this furniture to 800mm tall
60
+ * @examplePrompt Change the desk to 1500 long and 700 deep
61
+ *
62
+ * # Example
63
+ * ```ts
64
+ * const [item] = await snaptrude.design.query.listFurniture({ isSelected: true })
65
+ * const { affected } = await snaptrude.design.furniture.setDimensions(item, {
66
+ * length: 1800,
67
+ * height: 750
68
+ * })
69
+ * ```
70
+ */
71
+ public abstract setDimensions(
72
+ item: ComponentHandle,
73
+ dimensions: PluginFurnitureDimensionUpdates
74
+ ): PluginApiReturn<PluginDesignChangeResult>
75
+
17
76
  /**
18
77
  * List the categories (Living, Bedroom, Kitchen, …) that organize the
19
78
  * furniture catalog — the picker taxonomy, merged from built-in categories,
@@ -159,3 +218,68 @@ export type PluginDesignFurnitureGetCatalogItemArgs = z.infer<
159
218
 
160
219
  export const PluginDesignFurnitureExistsArgs = PluginDesignFurnitureGetCatalogItemArgs
161
220
  export type PluginDesignFurnitureExistsArgs = z.infer<typeof PluginDesignFurnitureExistsArgs>
221
+
222
+ // ---------------------------------------------------------------------------
223
+ // placed-furniture dimensions
224
+ // ---------------------------------------------------------------------------
225
+
226
+ /**
227
+ * A placed furniture item's dimensions (engine units).
228
+ *
229
+ * | Property | Type | Description |
230
+ * |---|---|---|
231
+ * | `length` | `number` | Along the object (panel "Length") |
232
+ * | `width` | `number` | Across the object (panel "Width") |
233
+ * | `height` | `number` | Vertical (panel "Height") |
234
+ */
235
+ export const PluginFurnitureDimensions = z.object({
236
+ length: z.number(),
237
+ width: z.number(),
238
+ height: z.number(),
239
+ })
240
+ export type PluginFurnitureDimensions = z.infer<typeof PluginFurnitureDimensions>
241
+
242
+ /**
243
+ * Arguments for {@linkcode PluginDesignFurnitureApi.getDimensions}.
244
+ *
245
+ * | Property | Type | Description |
246
+ * |---|---|---|
247
+ * | `item` | {@linkcode ComponentHandle} | The placed furniture to query |
248
+ */
249
+ export const PluginDesignFurnitureItemArgs = z.object({
250
+ item: ComponentHandle,
251
+ })
252
+ export type PluginDesignFurnitureItemArgs = z.infer<typeof PluginDesignFurnitureItemArgs>
253
+
254
+ /**
255
+ * A partial dimension patch — each axis is optional; omitted axes are unchanged.
256
+ * Every supplied axis must be a positive engine-unit length.
257
+ *
258
+ * | Property | Type | Description |
259
+ * |---|---|---|
260
+ * | `length` | `number`? | New length along the object (engine units, > 0) |
261
+ * | `width` | `number`? | New width across the object (engine units, > 0) |
262
+ * | `height` | `number`? | New height (engine units, > 0) |
263
+ */
264
+ export const PluginFurnitureDimensionUpdates = z.object({
265
+ length: z.number().positive().optional(),
266
+ width: z.number().positive().optional(),
267
+ height: z.number().positive().optional(),
268
+ })
269
+ export type PluginFurnitureDimensionUpdates = z.infer<typeof PluginFurnitureDimensionUpdates>
270
+
271
+ /**
272
+ * Arguments for {@linkcode PluginDesignFurnitureApi.setDimensions}.
273
+ *
274
+ * | Property | Type | Description |
275
+ * |---|---|---|
276
+ * | `item` | {@linkcode ComponentHandle} | The placed furniture to resize |
277
+ * | `dimensions` | {@linkcode PluginFurnitureDimensionUpdates} | The axes to change (each optional) |
278
+ */
279
+ export const PluginDesignFurnitureSetDimensionsArgs = z.object({
280
+ item: ComponentHandle,
281
+ dimensions: PluginFurnitureDimensionUpdates,
282
+ })
283
+ export type PluginDesignFurnitureSetDimensionsArgs = z.infer<
284
+ typeof PluginDesignFurnitureSetDimensionsArgs
285
+ >
@@ -13,6 +13,8 @@ import { PluginDesignBooleanApi } from "./boolean"
13
13
  import { PluginDesignTransformApi } from "./transform"
14
14
  import { PluginDesignEditApi } from "./edit"
15
15
  import { PluginDesignUpdateApi } from "./update"
16
+ import { PluginDesignVisibilityApi } from "./visibility"
17
+ import { PluginDesignTypesApi } from "./types"
16
18
  import { PluginDesignChangeResult } from "./lock"
17
19
 
18
20
  /**
@@ -27,6 +29,8 @@ import { PluginDesignChangeResult } from "./lock"
27
29
  * - {@linkcode PluginDesignApi.boolean} — CSG boolean ops (union / subtract / intersect)
28
30
  * - {@linkcode PluginDesignApi.erase} — plan-level adjacency-edge erase (NOT hard delete)
29
31
  * - {@linkcode PluginDesignApi.delete} — hard entity removal
32
+ * - {@linkcode PluginDesignApi.visibility} — hide / isolate / reveal entities
33
+ * - {@linkcode PluginDesignApi.types} — read-only building type / assembly reference
30
34
  * - {@linkcode PluginDesignApi.lock} / {@linkcode PluginDesignApi.unlock} / {@linkcode PluginDesignApi.isLocked} / {@linkcode PluginDesignApi.listLocked} — lock state (top-level design verbs, §2A.1)
31
35
  * - {@linkcode PluginDesignApi.lockArea} / {@linkcode PluginDesignApi.unlockArea} / {@linkcode PluginDesignApi.isAreaLocked} / {@linkcode PluginDesignApi.listAreaLocked} — footprint-area lock for Room/Department spaces
32
36
  *
@@ -59,6 +63,10 @@ export abstract class PluginDesignApi {
59
63
  public abstract edit: PluginDesignEditApi
60
64
  /** Update existing entities — properties + geometry. See {@linkcode PluginDesignUpdateApi}. */
61
65
  public abstract update: PluginDesignUpdateApi
66
+ /** Hide / isolate / reveal entities. See {@linkcode PluginDesignVisibilityApi}. */
67
+ public abstract visibility: PluginDesignVisibilityApi
68
+ /** Read-only building type / assembly reference. See {@linkcode PluginDesignTypesApi}. */
69
+ public abstract types: PluginDesignTypesApi
62
70
 
63
71
  /**
64
72
  * Lock entities so they cannot be edited. Undoable. Cascades to void/door/window
@@ -247,3 +255,5 @@ export * from "./boolean"
247
255
  export * from "./transform"
248
256
  export * from "./edit"
249
257
  export * from "./update"
258
+ export * from "./visibility"
259
+ export * from "./types"
@@ -8,7 +8,9 @@ import { ComponentHandle, MaterialHandle } from "../../../handles"
8
8
  * Materials are {@linkcode MaterialHandle}s (entity-style, name-addressed). Reads return
9
9
  * a {@linkcode MaterialHandle}/{@linkcode PluginMaterialInfo}; `apply`/`reset` mutate the
10
10
  * scene (undoable via `save`, default `true`). `create` mints a material from a
11
- * {@linkcode PluginMaterialSpec} (idempotent by name).
11
+ * {@linkcode PluginMaterialSpec} (idempotent by name). `list` reads the materials loaded
12
+ * in the project; `listPresets` reads the browsable preset/library catalog (handle-less
13
+ * {@linkcode PluginPresetMaterial} records that become materials via `create`/`apply`).
12
14
  *
13
15
  * Per-face assignment — {@linkcode PluginDesignMaterialsApi.applyToFaces} /
14
16
  * {@linkcode PluginDesignMaterialsApi.resetFaces} plus per-face reads
@@ -24,23 +26,59 @@ export abstract class PluginDesignMaterialsApi {
24
26
  constructor() {}
25
27
 
26
28
  /**
27
- * List the project materials.
28
- * @param scope Which library to list (optional)
29
+ * List the materials loaded in the project — every named material in the live
30
+ * scene (applied finishes, plugin-created materials, and type defaults in use).
31
+ * For the browsable preset/library catalog (finishes not yet in the project),
32
+ * use {@linkcode PluginDesignMaterialsApi.listPresets}.
33
+ *
29
34
  * @returns The materials as {@linkcode MaterialHandle}`[]`
30
35
  *
31
36
  * @examplePrompt List all the materials in this project
32
37
  * @examplePrompt What materials do I have available to apply?
33
- * @examplePrompt Show me the preset materials library
34
38
  * @examplePrompt Which finishes exist in this model?
35
39
  * @examplePrompt Get every material in the project palette
36
40
  *
37
41
  * # Example
38
42
  * ```ts
39
- * const presets = await snaptrude.design.materials.list("preset")
40
- * console.log(presets.length, "preset materials")
43
+ * const materials = await snaptrude.design.materials.list()
44
+ * console.log(materials.length, "materials in the project")
41
45
  * ```
42
46
  */
43
- public abstract list(scope?: "project" | "preset"): PluginApiReturn<MaterialHandle[]>
47
+ public abstract list(): PluginApiReturn<MaterialHandle[]>
48
+
49
+ /**
50
+ * List the preset material library — the catalog the app's material browser
51
+ * shows (the built-in finishes plus the workspace's uploaded materials),
52
+ * fetched from the material library service. Library entries are **not**
53
+ * scene materials and carry no {@linkcode MaterialHandle}; each is a named
54
+ * texture record. To use one, feed it to
55
+ * {@linkcode PluginDesignMaterialsApi.create} /
56
+ * {@linkcode PluginDesignMaterialsApi.apply} as a
57
+ * {@linkcode PluginMaterialSpec}: `{ name, textureUrl, materialType: category }`.
58
+ *
59
+ * @returns The library as {@linkcode PluginPresetMaterial}`[]` (`[]` when the
60
+ * library service is unreachable)
61
+ *
62
+ * @examplePrompt Show me the preset materials library
63
+ * @examplePrompt What wood finishes are available in the material library?
64
+ * @examplePrompt Browse the material catalog and apply a brick texture
65
+ * @examplePrompt Which preset materials can I choose from?
66
+ *
67
+ * # Example
68
+ * ```ts
69
+ * const presets = await snaptrude.design.materials.listPresets()
70
+ * const brick = presets.find((p) => p.category.toLowerCase().includes("brick"))
71
+ * if (brick) {
72
+ * const walls = await snaptrude.design.query.listWalls()
73
+ * await snaptrude.design.materials.apply(walls, {
74
+ * name: brick.name,
75
+ * textureUrl: brick.textureUrl,
76
+ * materialType: brick.category,
77
+ * })
78
+ * }
79
+ * ```
80
+ */
81
+ public abstract listPresets(): PluginApiReturn<PluginPresetMaterial[]>
44
82
 
45
83
  /**
46
84
  * Read a material's descriptor — its name, color, opacity, and texture
@@ -61,7 +99,43 @@ export abstract class PluginDesignMaterialsApi {
61
99
  * if (info) console.log(info.name, info.colorHex, info.alpha)
62
100
  * ```
63
101
  */
64
- public abstract getInfo(material: MaterialHandle): PluginApiReturn<PluginMaterialInfo | null>
102
+ public abstract getInfo(
103
+ material: MaterialHandle,
104
+ ): PluginApiReturn<PluginMaterialInfo | null>
105
+
106
+ /**
107
+ * Read the material applied to a component **as a whole** — the eyedropper. For a
108
+ * uniformly-painted component this is that single material; for a per-face-painted
109
+ * component it is the material on the component's base/first face. Use
110
+ * {@linkcode PluginDesignMaterialsApi.getByFace} /
111
+ * {@linkcode PluginDesignMaterialsApi.listByFace} for the per-face breakdown.
112
+ *
113
+ * @param component The component to sample
114
+ * @returns The whole-object material as a {@linkcode PluginComponentMaterial} — its
115
+ * handle (chain it into `apply` / `getInfo`), engine id, name, and whether the
116
+ * component carries its type `default` or an explicitly `applied` finish — or `null`
117
+ * if the component carries no material
118
+ *
119
+ * @examplePrompt What material is on this wall?
120
+ * @examplePrompt Eyedrop the finish of the selected object
121
+ * @examplePrompt Which material does this slab use?
122
+ * @examplePrompt Read the material on this column so I can paint others with it
123
+ * @examplePrompt Is this component painted, and with what?
124
+ *
125
+ * # Example
126
+ * ```ts
127
+ * const [component] = await snaptrude.design.selection.get()
128
+ * const sampled = await snaptrude.design.materials.get(component)
129
+ * if (sampled) {
130
+ * console.log(sampled.name, sampled.source) // e.g. "Brick Red" "applied"
131
+ * const info = await snaptrude.design.materials.getInfo(sampled.material)
132
+ * console.log(info?.colorHex)
133
+ * }
134
+ * ```
135
+ */
136
+ public abstract get(
137
+ component: ComponentHandle,
138
+ ): PluginApiReturn<PluginComponentMaterial | null>
65
139
 
66
140
  /**
67
141
  * Apply a material to one or more components — an existing project material by
@@ -90,7 +164,7 @@ export abstract class PluginDesignMaterialsApi {
90
164
  public abstract apply(
91
165
  targets: ComponentHandle[],
92
166
  material: MaterialHandle | PluginMaterialSpec,
93
- save?: boolean
167
+ save?: boolean,
94
168
  ): PluginApiReturn<PluginMaterialResult>
95
169
 
96
170
  /**
@@ -116,7 +190,7 @@ export abstract class PluginDesignMaterialsApi {
116
190
  */
117
191
  public abstract reset(
118
192
  components: ComponentHandle[],
119
- save?: boolean
193
+ save?: boolean,
120
194
  ): PluginApiReturn<PluginMaterialResult>
121
195
 
122
196
  /**
@@ -155,7 +229,7 @@ export abstract class PluginDesignMaterialsApi {
155
229
  component: ComponentHandle,
156
230
  faces: number[],
157
231
  material: MaterialHandle | PluginMaterialSpec,
158
- save?: boolean
232
+ save?: boolean,
159
233
  ): PluginApiReturn<PluginMaterialResult>
160
234
 
161
235
  /**
@@ -183,7 +257,7 @@ export abstract class PluginDesignMaterialsApi {
183
257
  public abstract resetFaces(
184
258
  component: ComponentHandle,
185
259
  faces: number[],
186
- save?: boolean
260
+ save?: boolean,
187
261
  ): PluginApiReturn<PluginMaterialResult>
188
262
 
189
263
  /**
@@ -207,7 +281,7 @@ export abstract class PluginDesignMaterialsApi {
207
281
  */
208
282
  public abstract getByFace(
209
283
  component: ComponentHandle,
210
- face: number
284
+ face: number,
211
285
  ): PluginApiReturn<MaterialHandle | null>
212
286
 
213
287
  /**
@@ -230,7 +304,7 @@ export abstract class PluginDesignMaterialsApi {
230
304
  * ```
231
305
  */
232
306
  public abstract listByFace(
233
- component: ComponentHandle
307
+ component: ComponentHandle,
234
308
  ): PluginApiReturn<PluginFaceMaterial[]>
235
309
 
236
310
  /**
@@ -253,7 +327,9 @@ export abstract class PluginDesignMaterialsApi {
253
327
  * await snaptrude.design.materials.apply(walls, glass)
254
328
  * ```
255
329
  */
256
- public abstract create(spec: PluginMaterialSpec): PluginApiReturn<MaterialHandle>
330
+ public abstract create(
331
+ spec: PluginMaterialSpec,
332
+ ): PluginApiReturn<MaterialHandle>
257
333
 
258
334
  /**
259
335
  * Get the default material for a component's type.
@@ -272,7 +348,9 @@ export abstract class PluginDesignMaterialsApi {
272
348
  * if (defaultMaterial) console.log(await snaptrude.design.materials.getInfo(defaultMaterial))
273
349
  * ```
274
350
  */
275
- public abstract getDefault(component: ComponentHandle): PluginApiReturn<MaterialHandle | null>
351
+ public abstract getDefault(
352
+ component: ComponentHandle,
353
+ ): PluginApiReturn<MaterialHandle | null>
276
354
 
277
355
  /**
278
356
  * Test whether a component carries its (type) default material.
@@ -291,7 +369,9 @@ export abstract class PluginDesignMaterialsApi {
291
369
  * console.log(untouched ? "still default" : "has been painted")
292
370
  * ```
293
371
  */
294
- public abstract isDefault(component: ComponentHandle): PluginApiReturn<boolean>
372
+ public abstract isDefault(
373
+ component: ComponentHandle,
374
+ ): PluginApiReturn<boolean>
295
375
 
296
376
  /**
297
377
  * Test whether a component has a single (uniform) material across all faces.
@@ -310,7 +390,9 @@ export abstract class PluginDesignMaterialsApi {
310
390
  * console.log(uniform ? "one material all over" : "painted per face")
311
391
  * ```
312
392
  */
313
- public abstract isUniform(component: ComponentHandle): PluginApiReturn<boolean>
393
+ public abstract isUniform(
394
+ component: ComponentHandle,
395
+ ): PluginApiReturn<boolean>
314
396
 
315
397
  /**
316
398
  * Test whether a material has a texture.
@@ -392,18 +474,54 @@ export const PluginFaceMaterial = z.object({
392
474
  })
393
475
  export type PluginFaceMaterial = z.infer<typeof PluginFaceMaterial>
394
476
 
395
- /** Arguments for {@linkcode PluginDesignMaterialsApi.list}. */
396
- export const PluginDesignMaterialsListArgs = z.object({
397
- scope: z.enum(["project", "preset"]).optional(),
477
+ /**
478
+ * The material on a component **as a whole** — the eyedropper read returned by
479
+ * {@linkcode PluginDesignMaterialsApi.get} (value record, plus a reusable handle).
480
+ *
481
+ * | Property | Type | Description |
482
+ * |---|---|---|
483
+ * | `material` | {@linkcode MaterialHandle} | The whole-object material — chain into `apply` / `getInfo` |
484
+ * | `id` | `string` | Engine material id |
485
+ * | `name` | `string` | Material name (== the handle token) |
486
+ * | `source` | `"default" \| "applied"` | Whether it is the component's type default or an explicitly-applied finish |
487
+ */
488
+ export const PluginComponentMaterial = z.object({
489
+ material: MaterialHandle,
490
+ id: z.string(),
491
+ name: z.string(),
492
+ source: z.enum(["default", "applied"]),
493
+ })
494
+ export type PluginComponentMaterial = z.infer<typeof PluginComponentMaterial>
495
+
496
+ /**
497
+ * A preset material library entry (value record — NOT a handle), returned by
498
+ * {@linkcode PluginDesignMaterialsApi.listPresets}.
499
+ *
500
+ * | Property | Type | Description |
501
+ * |---|---|---|
502
+ * | `name` | `string` | Display name of the library entry |
503
+ * | `category` | `string` | Library category (camelCase, e.g. `"wood"`, `"colors"`, `"brick"`) |
504
+ * | `textureUrl` | `string` | Texture/swatch image URL — feed to {@linkcode PluginMaterialSpec}`.textureUrl` |
505
+ */
506
+ export const PluginPresetMaterial = z.object({
507
+ name: z.string(),
508
+ category: z.string(),
509
+ textureUrl: z.string(),
398
510
  })
399
- export type PluginDesignMaterialsListArgs = z.infer<typeof PluginDesignMaterialsListArgs>
511
+ export type PluginPresetMaterial = z.infer<typeof PluginPresetMaterial>
400
512
 
401
513
  /** Arguments for {@linkcode PluginDesignMaterialsApi.getInfo} / `hasTexture`. */
402
- export const PluginDesignMaterialsGetInfoArgs = z.object({ material: MaterialHandle })
403
- export type PluginDesignMaterialsGetInfoArgs = z.infer<typeof PluginDesignMaterialsGetInfoArgs>
514
+ export const PluginDesignMaterialsGetInfoArgs = z.object({
515
+ material: MaterialHandle,
516
+ })
517
+ export type PluginDesignMaterialsGetInfoArgs = z.infer<
518
+ typeof PluginDesignMaterialsGetInfoArgs
519
+ >
404
520
 
405
521
  /** Arguments for component-scoped predicates (`getDefault`/`isDefault`/`isUniform`). */
406
- export const PluginDesignMaterialsComponentArgs = z.object({ component: ComponentHandle })
522
+ export const PluginDesignMaterialsComponentArgs = z.object({
523
+ component: ComponentHandle,
524
+ })
407
525
  export type PluginDesignMaterialsComponentArgs = z.infer<
408
526
  typeof PluginDesignMaterialsComponentArgs
409
527
  >
@@ -422,18 +540,26 @@ export const PluginDesignMaterialsApplyArgs = z.object({
422
540
  material: z.union([MaterialHandle, PluginMaterialSpec]),
423
541
  save: z.boolean().optional(),
424
542
  })
425
- export type PluginDesignMaterialsApplyArgs = z.infer<typeof PluginDesignMaterialsApplyArgs>
543
+ export type PluginDesignMaterialsApplyArgs = z.infer<
544
+ typeof PluginDesignMaterialsApplyArgs
545
+ >
426
546
 
427
547
  /** Arguments for {@linkcode PluginDesignMaterialsApi.reset}. */
428
548
  export const PluginDesignMaterialsResetArgs = z.object({
429
549
  components: z.array(ComponentHandle),
430
550
  save: z.boolean().optional(),
431
551
  })
432
- export type PluginDesignMaterialsResetArgs = z.infer<typeof PluginDesignMaterialsResetArgs>
552
+ export type PluginDesignMaterialsResetArgs = z.infer<
553
+ typeof PluginDesignMaterialsResetArgs
554
+ >
433
555
 
434
556
  /** Arguments for {@linkcode PluginDesignMaterialsApi.create}. */
435
- export const PluginDesignMaterialsCreateArgs = z.object({ spec: PluginMaterialSpec })
436
- export type PluginDesignMaterialsCreateArgs = z.infer<typeof PluginDesignMaterialsCreateArgs>
557
+ export const PluginDesignMaterialsCreateArgs = z.object({
558
+ spec: PluginMaterialSpec,
559
+ })
560
+ export type PluginDesignMaterialsCreateArgs = z.infer<
561
+ typeof PluginDesignMaterialsCreateArgs
562
+ >
437
563
 
438
564
  /**
439
565
  * Arguments for {@linkcode PluginDesignMaterialsApi.applyToFaces}.
@@ -475,7 +601,8 @@ export type PluginDesignMaterialsGetByFaceArgs = z.infer<
475
601
  >
476
602
 
477
603
  /** Arguments for {@linkcode PluginDesignMaterialsApi.listByFace} (component only). */
478
- export const PluginDesignMaterialsListByFaceArgs = PluginDesignMaterialsComponentArgs
604
+ export const PluginDesignMaterialsListByFaceArgs =
605
+ PluginDesignMaterialsComponentArgs
479
606
  export type PluginDesignMaterialsListByFaceArgs = z.infer<
480
607
  typeof PluginDesignMaterialsListByFaceArgs
481
608
  >
@@ -168,6 +168,7 @@ export type PluginDesignQueryComponentsArgs = z.infer<
168
168
  * | `spaceType` | {@linkcode PluginSpaceType} | Space-type (spaces only) |
169
169
  * | `areaClass` | {@linkcode PluginAreaClass} | Area classification (spaces only) |
170
170
  * | `departmentId` | `string` | Department (masses only) |
171
+ * | `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)` |
171
172
  * | `isLocked` | `boolean` | Lock flag |
172
173
  * | `isHidden` | `boolean` | User-hidden flag |
173
174
  * | `isSelected` | `boolean` | Current selection state |
@@ -186,6 +187,7 @@ export const PluginEntityProperties = z
186
187
  spaceType: PluginSpaceType,
187
188
  areaClass: PluginAreaClass,
188
189
  departmentId: z.string(),
190
+ buildingType: z.string(),
189
191
  isLocked: z.boolean(),
190
192
  isHidden: z.boolean(),
191
193
  isSelected: z.boolean(),
@@ -201,17 +203,28 @@ export type PluginEntityProperties = z.infer<typeof PluginEntityProperties>
201
203
  * entity's type computes them (area: floors/masses/slabs/roofs/beams/columns;
202
204
  * volume: all; length: walls/beams).
203
205
  *
206
+ * `thickness` and `height` are the Object Properties panel's dimension reads
207
+ * (the same engine source `design.update.wall` / `design.update.slab` etc.
208
+ * write through), in engine units. `thickness`: walls (the plan thickness —
209
+ * present only for straight orthogonal walls, exactly when the panel shows it)
210
+ * and slabs/floors/roofs/ceilings (the vertical extent the panel calls
211
+ * Thickness). `height`: walls only.
212
+ *
204
213
  * | Property | Type | Description |
205
214
  * |---|---|---|
206
215
  * | `area` | `number`? | Bottom-face area |
207
216
  * | `volume` | `number`? | Solid volume |
208
217
  * | `length` | `number`? | Running length (linear elements) |
218
+ * | `thickness` | `number`? | Panel Thickness — walls (straight orthogonal only) and the slab family |
219
+ * | `height` | `number`? | Panel Height — walls only |
209
220
  * | `boundingBox` | {@linkcode BBoxComponents} | World-space AABB (always present) |
210
221
  */
211
222
  export const PluginEntityMeasurements = z.object({
212
223
  area: z.number().optional(),
213
224
  volume: z.number().optional(),
214
225
  length: z.number().optional(),
226
+ thickness: z.number().optional(),
227
+ height: z.number().optional(),
215
228
  boundingBox: BBoxComponents,
216
229
  })
217
230
  export type PluginEntityMeasurements = z.infer<typeof PluginEntityMeasurements>
@@ -755,9 +768,7 @@ export abstract class PluginDesignQueryApi {
755
768
  * }
756
769
  * ```
757
770
  */
758
- public abstract exists(
759
- id: ComponentHandle,
760
- ): PluginApiReturn<boolean>
771
+ public abstract exists(id: ComponentHandle): PluginApiReturn<boolean>
761
772
 
762
773
  /**
763
774
  * Get the kind of BIM entity a handle refers to — wall, door, space, slab,
@@ -811,9 +822,7 @@ export abstract class PluginDesignQueryApi {
811
822
  * }
812
823
  * ```
813
824
  */
814
- public abstract getLabel(
815
- component: ComponentHandle,
816
- ): PluginApiReturn<string>
825
+ public abstract getLabel(component: ComponentHandle): PluginApiReturn<string>
817
826
 
818
827
  /**
819
828
  * Get a serializable, persistable reference to an entity. Under the all-handle
@@ -897,13 +906,16 @@ export abstract class PluginDesignQueryApi {
897
906
  * Read an entity's common properties as a {@linkcode PluginEntityProperties}
898
907
  * record (only applicable fields are present). For spaces/masses this includes
899
908
  * `adjacency` — the per-entity adjacency read (bulk form:
900
- * `program.adjacency.getMatrix`).
909
+ * `program.adjacency.getMatrix`). For walls and the slab family (slab / floor
910
+ * / roof / ceiling) this includes `buildingType` — the assigned building type
911
+ * NAME the panel's type dropdown shows, matching `design.types.list(kind)`.
901
912
  *
902
913
  * @param component - the entity's {@linkcode ComponentHandle}
903
914
  * @returns the property record
904
915
  *
905
916
  * @examplePrompt Show me all the details of the selected object
906
917
  * @examplePrompt What storey is this wall on?
918
+ * @examplePrompt Which wall type is assigned to this wall?
907
919
  * @examplePrompt Which department does this room belong to?
908
920
  * @examplePrompt Is this element locked or hidden?
909
921
  * @examplePrompt Get the adjacencies of this space
@@ -933,11 +945,20 @@ export abstract class PluginDesignQueryApi {
933
945
  * Measure an entity — read its area, volume, and/or running length (whichever
934
946
  * its type supports) together with its world-space bounding box in one call.
935
947
  *
948
+ * For walls and the slab family this also carries the Object Properties
949
+ * panel's dimension reads in engine units: `thickness` (walls — straight
950
+ * orthogonal only, exactly when the panel shows it; slabs / floors / roofs /
951
+ * ceilings — the vertical extent the panel calls Thickness) and `height`
952
+ * (walls). These are the read side of `design.update.wall` /
953
+ * `design.update.slab` / `.floor` / `.roof` / `.ceiling`.
954
+ *
936
955
  * @param component - the entity's {@linkcode ComponentHandle}
937
956
  * @returns a {@linkcode PluginEntityMeasurements}, or `null` if the entity is gone
938
957
  *
939
958
  * @examplePrompt What's the area of this room?
940
959
  * @examplePrompt How long is the selected wall?
960
+ * @examplePrompt How thick is this wall?
961
+ * @examplePrompt Get the thickness of the slab on level 2
941
962
  * @examplePrompt Get the volume of this mass
942
963
  * @examplePrompt Give me the dimensions of the selected element
943
964
  * @examplePrompt What's the floor area of the kitchen?
@@ -947,6 +968,11 @@ export abstract class PluginDesignQueryApi {
947
968
  * const [space] = await snaptrude.design.query.listSpaces()
948
969
  * const m = await snaptrude.design.query.measure(space)
949
970
  * console.log(m?.area, m?.volume)
971
+ *
972
+ * // wall dimensions — the panel's Thickness / Height, in engine units
973
+ * const [wall] = await snaptrude.design.query.listWalls()
974
+ * const wm = await snaptrude.design.query.measure(wall)
975
+ * console.log(wm?.thickness, wm?.height)
950
976
  * ```
951
977
  */
952
978
  public abstract measure(