@snaptrude/plugin-core 0.9.16-networks-20261012.1 → 0.9.17

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 (88) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/api-manifest.json +9711 -0
  3. package/dist/api/analysis/daylight.d.ts +5 -5
  4. package/dist/api/analysis/solar.d.ts +2 -2
  5. package/dist/api/core/camera/index.d.ts +0 -29
  6. package/dist/api/core/camera/index.d.ts.map +1 -1
  7. package/dist/api/core/zoom/index.d.ts +0 -13
  8. package/dist/api/core/zoom/index.d.ts.map +1 -1
  9. package/dist/api/design/create/bulk-items.d.ts +21 -40
  10. package/dist/api/design/create/bulk-items.d.ts.map +1 -1
  11. package/dist/api/design/create/index.d.ts +97 -120
  12. package/dist/api/design/create/index.d.ts.map +1 -1
  13. package/dist/api/design/create/opening-fields.d.ts +12 -13
  14. package/dist/api/design/create/opening-fields.d.ts.map +1 -1
  15. package/dist/api/design/doors/index.d.ts +24 -18
  16. package/dist/api/design/doors/index.d.ts.map +1 -1
  17. package/dist/api/design/family.d.ts +27 -797
  18. package/dist/api/design/family.d.ts.map +1 -1
  19. package/dist/api/design/index.d.ts +0 -16
  20. package/dist/api/design/index.d.ts.map +1 -1
  21. package/dist/api/design/query/index.d.ts +30 -30
  22. package/dist/api/design/selection/index.d.ts +10 -10
  23. package/dist/api/design/types/index.d.ts +24 -40
  24. package/dist/api/design/types/index.d.ts.map +1 -1
  25. package/dist/api/design/update/index.d.ts +3 -40
  26. package/dist/api/design/update/index.d.ts.map +1 -1
  27. package/dist/api/design/windows/index.d.ts +8 -8
  28. package/dist/api/design/windows/index.d.ts.map +1 -1
  29. package/dist/api/presentation/aiInspiration.d.ts +10 -10
  30. package/dist/api/presentation/annotate.d.ts +22 -38
  31. package/dist/api/presentation/annotate.d.ts.map +1 -1
  32. package/dist/api/presentation/export.d.ts +5 -23
  33. package/dist/api/presentation/export.d.ts.map +1 -1
  34. package/dist/api/presentation/index.d.ts +21 -32
  35. package/dist/api/presentation/index.d.ts.map +1 -1
  36. package/dist/api/presentation/placedViews.d.ts +6 -106
  37. package/dist/api/presentation/placedViews.d.ts.map +1 -1
  38. package/dist/api/presentation/sections.d.ts +461 -0
  39. package/dist/api/presentation/sections.d.ts.map +1 -0
  40. package/dist/api/presentation/shapes.d.ts +2 -2
  41. package/dist/api/presentation/sheets.d.ts +19 -175
  42. package/dist/api/presentation/sheets.d.ts.map +1 -1
  43. package/dist/api/presentation/views.d.ts +5 -103
  44. package/dist/api/presentation/views.d.ts.map +1 -1
  45. package/dist/api/presentation/walkthroughs.d.ts +6 -6
  46. package/dist/index.cjs +2434 -3619
  47. package/dist/index.cjs.map +1 -1
  48. package/dist/index.js +2421 -3501
  49. package/dist/index.js.map +1 -1
  50. package/package.json +1 -1
  51. package/scripts/generate-manifest.mjs +0 -5
  52. package/src/api/core/camera/index.ts +0 -29
  53. package/src/api/core/zoom/index.ts +0 -13
  54. package/src/api/design/create/bulk-items.ts +16 -23
  55. package/src/api/design/create/index.ts +119 -129
  56. package/src/api/design/create/opening-fields.ts +12 -15
  57. package/src/api/design/doors/index.ts +42 -58
  58. package/src/api/design/family.ts +32 -662
  59. package/src/api/design/index.ts +4 -34
  60. package/src/api/design/types/index.ts +24 -31
  61. package/src/api/design/update/index.ts +3 -41
  62. package/src/api/design/windows/index.ts +22 -40
  63. package/src/api/presentation/annotate.ts +58 -90
  64. package/src/api/presentation/export.ts +6 -32
  65. package/src/api/presentation/index.ts +23 -39
  66. package/src/api/presentation/placedViews.ts +28 -119
  67. package/src/api/presentation/sections.ts +420 -0
  68. package/src/api/presentation/sheets.ts +20 -181
  69. package/src/api/presentation/views.ts +6 -46
  70. package/dist/api/design/bim.d.ts +0 -209
  71. package/dist/api/design/bim.d.ts.map +0 -1
  72. package/dist/api/design/catalog.d.ts +0 -320
  73. package/dist/api/design/catalog.d.ts.map +0 -1
  74. package/dist/api/design/networks.d.ts +0 -1703
  75. package/dist/api/design/networks.d.ts.map +0 -1
  76. package/dist/api/presentation/drawingContract.d.ts +0 -32
  77. package/dist/api/presentation/drawingContract.d.ts.map +0 -1
  78. package/dist/api/presentation/drawings.d.ts +0 -3523
  79. package/dist/api/presentation/drawings.d.ts.map +0 -1
  80. package/dist/api/presentation/viewPresets.d.ts +0 -222
  81. package/dist/api/presentation/viewPresets.d.ts.map +0 -1
  82. package/src/api/design/bim.ts +0 -121
  83. package/src/api/design/catalog.ts +0 -203
  84. package/src/api/design/networks.ts +0 -607
  85. package/src/api/presentation/drawingContract.ts +0 -70
  86. package/src/api/presentation/drawings.ts +0 -1179
  87. package/src/api/presentation/viewPresets.ts +0 -241
  88. package/test/drawingContract.test.mjs +0 -288
@@ -4,7 +4,6 @@ import {
4
4
  BrepHandle,
5
5
  ComponentHandle,
6
6
  ContourHandle,
7
- LineHandle,
8
7
  CurveHandle,
9
8
  ProfileHandle,
10
9
  Vec3Handle,
@@ -30,14 +29,6 @@ import type {
30
29
  PluginCreateWindowItem,
31
30
  } from "./bulk-items"
32
31
  import { PluginWallTopProfile } from "./bulk-items"
33
- import { PluginWallType } from "../types"
34
- import {
35
- PluginFamilyPlacement,
36
- PluginFamilyFloorOptions,
37
- PluginFamilySlabOptions,
38
- PluginFamilyCeilingOptions,
39
- PluginFamilyValues,
40
- } from "../catalog"
41
32
 
42
33
  /**
43
34
  * `design.create.*` — author new scene-committed BIM entities.
@@ -52,13 +43,7 @@ import {
52
43
  * Footprint objects take a {@linkcode ContourHandle} (outer profile + holes);
53
44
  * build one with `snaptrude.core.geom.create.contourFromProfile(s)`.
54
45
  *
55
- * Family overloads take `{ type, values? }` from `design.catalog`. The family supplies
56
- * construction; the contour or axis supplies instance geometry. Geometry uses SU,
57
- * while family length overrides use mm and angles use degrees. Omitted parameters
58
- * retain family defaults; shared/type, formula and geometry-bound overrides are refused.
59
- * Placement never publishes a definition. Unsupported references or geometry fail before mutation.
60
- *
61
- * `door`/`window` place a parametric family into a host wall (the world point is
46
+ * `door`/`window` place a catalog item into a host wall (the world point is
62
47
  * projected onto the wall face to locate the opening; the wall is re-cut in one
63
48
  * undo entry) and throw if the point projects outside the wall. `smartLayout` is
64
49
  * the one creator returning a grouped {@linkcode PluginSmartLayoutResult} rather
@@ -234,29 +219,20 @@ export abstract class PluginDesignCreateApi {
234
219
  * ```
235
220
  */
236
221
  public abstract slab(
237
- ...args:
238
- | [
239
- contour: ContourHandle,
240
- thickness: number,
241
- direction?: "up" | "down",
242
- slabType?: PluginSlabType,
243
- ]
244
- | [contour: ContourHandle, options: PluginFamilySlabOptions]
222
+ contour: ContourHandle,
223
+ thickness: number,
224
+ direction?: "up" | "down",
225
+ slabType?: PluginSlabType,
245
226
  ): PluginApiReturn<ComponentHandle>
246
227
 
247
228
  /**
248
229
  * Create a **floor** by extruding a footprint contour by `thickness`
249
230
  * (extruded upward).
250
231
  *
251
- * The native family overload takes `{ type, values?, position? }`. Contour
252
- * geometry uses SU; family values use mm. The family supplies layer thickness.
253
- * PG2 can split or merge the footprint, so both overloads return an array.
254
- * A merge into an existing floor can return no newly created handles.
255
- *
256
232
  * @param contour - Footprint (outer + holes)
257
233
  * @param thickness - Floor thickness (> 0)
258
234
  * @param position - Offset from origin
259
- * @returns Newly created {@linkcode ComponentHandle}s; an empty array after a merge
235
+ * @returns the {@linkcode ComponentHandle} of the created floor
260
236
  * @throws if the contour is invalid or the thickness is not positive
261
237
  *
262
238
  * @examplePrompt Create a floor from this room outline
@@ -271,15 +247,15 @@ export abstract class PluginDesignCreateApi {
271
247
  * const floor = await snaptrude.design.create.floor(contour, 0.1)
272
248
  * ```
273
249
  *
274
- * @performance For dimensional floors, `design.create.floors(items[])` uses one
275
- * host round-trip and one undo entry. That bulk method does not accept native
276
- * family options; use this method for a family-backed floor.
250
+ * @performance For MORE THAN ONE floor, call `design.create.floors(items[])` — one
251
+ * host round-trip and ONE undo entry for the whole batch. Looping this single-floor
252
+ * creator is N round-trips and N undo entries.
277
253
  */
278
254
  public abstract floor(
279
- ...args:
280
- | [contour: ContourHandle, thickness: number, position?: Vec3Handle]
281
- | [contour: ContourHandle, options: PluginFamilyFloorOptions]
282
- ): PluginApiReturn<ComponentHandle[]>
255
+ contour: ContourHandle,
256
+ thickness: number,
257
+ position?: Vec3Handle,
258
+ ): PluginApiReturn<ComponentHandle>
283
259
 
284
260
  /**
285
261
  * Create **many floors** in one undoable operation (bulk plural of
@@ -344,7 +320,7 @@ export abstract class PluginDesignCreateApi {
344
320
  */
345
321
  public abstract roof(
346
322
  contour: ContourHandle,
347
- thickness: number | PluginFamilyPlacement,
323
+ thickness: number,
348
324
  ): PluginApiReturn<ComponentHandle>
349
325
 
350
326
  /**
@@ -370,9 +346,9 @@ export abstract class PluginDesignCreateApi {
370
346
  * ```
371
347
  */
372
348
  public abstract ceiling(
373
- ...args:
374
- | [contour: ContourHandle, thickness: number, heightFromFloor?: number]
375
- | [contour: ContourHandle, options: PluginFamilyCeilingOptions]
349
+ contour: ContourHandle,
350
+ thickness: number,
351
+ heightFromFloor?: number,
376
352
  ): PluginApiReturn<ComponentHandle>
377
353
 
378
354
  /**
@@ -403,14 +379,10 @@ export abstract class PluginDesignCreateApi {
403
379
  * ```
404
380
  */
405
381
  public abstract column(
406
- ...args:
407
- | [
408
- position: Vec3Handle,
409
- crossSection: ContourHandle,
410
- height: number,
411
- directionUp?: Vec3Handle,
412
- ]
413
- | [axis: LineHandle, options: PluginFamilyPlacement]
382
+ position: Vec3Handle,
383
+ crossSection: ContourHandle,
384
+ height: number,
385
+ directionUp?: Vec3Handle,
414
386
  ): PluginApiReturn<ComponentHandle>
415
387
 
416
388
  /**
@@ -454,9 +426,9 @@ export abstract class PluginDesignCreateApi {
454
426
  * ```
455
427
  */
456
428
  public abstract beam(
457
- ...args:
458
- | [section: ContourHandle, length: number, direction?: Vec3Handle]
459
- | [axis: LineHandle, options: PluginFamilyPlacement]
429
+ section: ContourHandle,
430
+ length: number,
431
+ direction?: Vec3Handle,
460
432
  ): PluginApiReturn<ComponentHandle>
461
433
 
462
434
  /**
@@ -467,12 +439,12 @@ export abstract class PluginDesignCreateApi {
467
439
  * @param height - Wall height (default engine default)
468
440
  * @param thickness - Wall thickness (default: the `wallType`'s total layer
469
441
  * thickness when `wallType` is given, else the engine default)
470
- * @param wallType - Legacy label/`wall:` id, or the exact `nativeFamily`
471
- * `{ id, version }` pin from `design.types.list("wall")`. Native pins are
472
- * authorized on every use; selecting a family in Draw is not registration.
473
- * Native pins support straight horizontal centerlines and flat tops only.
474
- * Omit thickness for native pins; a conflicting explicit thickness rejects.
475
- * Default: the engine's generic wall.
442
+ * @param wallType - Wall type to build with — the same searchable list the
443
+ * Draw tab's Wall Type dropdown offers. Pass a name from
444
+ * `design.types.list("wall")` (the summary's `label`, or its `"wall:…"` id).
445
+ * Drives the wall's construction layers and default material, and — when
446
+ * `thickness` is omitted — its total layer thickness. Default: the engine's
447
+ * generic wall.
476
448
  * @param storey - Target storey (integer: `1` ground, `2` first floor, `-1`
477
449
  * basement — same convention as `design.create.space`). The walls are
478
450
  * assigned to it and lifted to its base elevation, all inside the same
@@ -531,10 +503,9 @@ export abstract class PluginDesignCreateApi {
531
503
  profile: ProfileHandle,
532
504
  height?: number,
533
505
  thickness?: number,
534
- wallType?: PluginWallType,
506
+ wallType?: string,
535
507
  storey?: number,
536
508
  topProfiles?: (PluginWallTopProfile | null)[],
537
- values?: PluginFamilyValues,
538
509
  ): PluginApiReturn<ComponentHandle[]>
539
510
 
540
511
  /**
@@ -924,23 +895,30 @@ export abstract class PluginDesignCreateApi {
924
895
  ): PluginApiReturn<ComponentHandle[]>
925
896
 
926
897
  /**
927
- * Place a parametric **door** family into a host wall.
898
+ * Place a **door** from the catalog into a host wall.
928
899
  *
929
- * Identified by a saved **family definition id**. Discover ids with
900
+ * Identified by a **catalog (library) id** — the team object's stable `_id`
901
+ * or the general library's `fullName`. Discover ids with
930
902
  * {@linkcode PluginDesignDoorsApi.listCatalog}. The world `position` is
931
903
  * projected onto the host wall's face to locate the opening; the wall is
932
904
  * re-cut and the door hosted in a single undo entry. Placement is
933
- * asynchronous. Values and host bindings are evaluated before the first cut.
905
+ * asynchronous (the source mesh is fetched if not cached).
934
906
  *
935
- * @param familyId - Hosted door definition ID; legacy mesh catalog IDs are not accepted
907
+ * @param catalogId - Library id: team `_id` or general `fullName`
936
908
  * @param hostWall - The wall to host the door
937
909
  * @param position - World point projected onto the wall to locate the opening
938
- * @param options - `version` pins the definition. `values` sets authored parameters
939
- * (numeric lengths in SU, or unit strings). `label` names the instance.
940
- * `hinge` selects the declared `hand` enum: local -X is left, +X is right.
941
- * @param facing - World point selecting local +Z; omitted uses the picked face
910
+ * @param options - Optional placement options: `label` — instance name;
911
+ * `hinge` — world point near the jamb the door is hinged on (the door is
912
+ * reflected along the wall so its hinged jamb is the one nearer this
913
+ * point; default the catalog item's authored hinge side)
914
+ * @param facing - World point on the side of the wall the door swings open
915
+ * to (the room it opens into — where the plan symbol draws the swing arc).
916
+ * Any point clearly on that side works (e.g. the room's center). Default:
917
+ * the engine picks a side (nondeterministic when `position` sits on the
918
+ * wall centerline).
942
919
  * @returns the {@linkcode ComponentHandle} of the placed door
943
- * @throws if the family/category/parameters are invalid, or placement or cutting fails
920
+ * @throws if the catalog id is unknown, the host is not a wall, the source
921
+ * mesh fails to load, or the projected point falls **outside** the host wall
944
922
  *
945
923
  * @examplePrompt Add a door to this wall here
946
924
  * @examplePrompt Place a sliding door on the selected wall
@@ -983,28 +961,26 @@ export abstract class PluginDesignCreateApi {
983
961
  * that single call. Looping this single-door creator is N round-trips.
984
962
  */
985
963
  public abstract door(
986
- familyId: string,
964
+ catalogId: string,
987
965
  hostWall: ComponentHandle,
988
966
  position: Vec3Handle,
989
- options?: {
990
- label?: string
991
- hinge?: Vec3Handle
992
- version?: number
993
- values?: Record<string, number | string>
994
- },
967
+ options?: { label?: string; hinge?: Vec3Handle },
995
968
  facing?: Vec3Handle,
996
969
  ): PluginApiReturn<ComponentHandle>
997
970
 
998
971
  /**
999
972
  * Place **many doors** into host walls in one undoable operation (bulk plural
1000
- * of {@linkcode door}). Each item carries its own family id, host wall,
973
+ * of {@linkcode door}). Each item carries its own catalog id, host wall,
1001
974
  * world position, and optional `facing`, `label`, `width` and `height` — the
1002
975
  * same fields as a `"door"` {@linkcode PluginDesignCreateOpeningOptions}.
1003
976
  * Validate-all-or-throw; one command.
1004
977
  *
1005
- * The wall keeps its identity. Several items may use the same host.
1006
- * Width and height set named recipe parameters, not mesh scale. The recipe's
1007
- * evaluated hole can include frame allowances. A failed item rolls back the batch.
978
+ * As with the singular creator, placing an opening **re-cuts its host wall**:
979
+ * the wall you passed as `hostWall` stops resolving once the call returns.
980
+ * Several items MAY name the same original wall handle in one call — the host
981
+ * chains the re-cuts internally — but after the call recover the surviving
982
+ * wall with `design.query.getHost(opening)`, never by reusing the handle you
983
+ * passed in.
1008
984
  *
1009
985
  * @param items - One {@linkcode PluginCreateDoorItem} per door to place
1010
986
  * (≥1, ≤1000)
@@ -1012,9 +988,10 @@ export abstract class PluginDesignCreateApi {
1012
988
  * @throws `VALIDATION` if the items fail the schema (empty array, more than
1013
989
  * 1000 items, unknown fields, a non-positive `width`/`height`);
1014
990
  * `HANDLE_INVALID` if a `position`, `facing` or `hinge` handle is unknown
1015
- * or released; `PRECONDITION_FAILED` if the family cannot be resolved or saved,
1016
- * or a host is locked / is not in the active proposal;
1017
- * `OPERATION_FAILED` if placement, containment, overlap checks or cutting fail
991
+ * or released; `PRECONDITION_FAILED` if a catalog id is unknown, a `hostWall`
992
+ * is not a wall / is locked / is not in the active proposal, the projected
993
+ * point falls outside its host wall, or a door tool is active;
994
+ * `OPERATION_FAILED` if a source mesh fails to load or placement fails
1018
995
  * (nothing is created — `details.itemIndex` is the failing item);
1019
996
  * `METHOD_NOT_PERMITTED` if the plugin may not write.
1020
997
  *
@@ -1025,7 +1002,7 @@ export abstract class PluginDesignCreateApi {
1025
1002
  * @examplePrompt Add all the doors for this floor plan together
1026
1003
  *
1027
1004
  * @performance Bulk creator — the whole batch is ONE host round-trip and ONE undo
1028
- * entry. Always prefer this over
1005
+ * entry, and each distinct catalog source loads once. Always prefer this over
1029
1006
  * calling `design.create.door` in a loop: build the full `items[]` array first
1030
1007
  * (all host walls and points up front), then make one call.
1031
1008
  *
@@ -1035,10 +1012,10 @@ export abstract class PluginDesignCreateApi {
1035
1012
  * const [wall] = await snaptrude.design.query.listWalls({ isSelected: true })
1036
1013
  * const [entry] = await snaptrude.design.doors.listCatalog()
1037
1014
  * const [front, side] = await snaptrude.design.create.doors([
1038
- * { familyId: entry.id, hostWall: wall, position: await v.new(2, 0, 5), label: "D-01" },
1039
- * { familyId: entry.id, hostWall: wall, position: await v.new(6, 0, 5), values: { width: "1200mm" } },
1015
+ * { catalogId: entry.id, hostWall: wall, position: await v.new(2, 0, 5), label: "D-01" },
1016
+ * { catalogId: entry.id, hostWall: wall, position: await v.new(6, 0, 5), width: 1.2 },
1040
1017
  * ])
1041
- * // The host still resolves after both cuts:
1018
+ * // `wall` was re-cut twice and no longer resolves — ask the opening for its host:
1042
1019
  * const currentWall = await snaptrude.design.query.getHost(front)
1043
1020
  * ```
1044
1021
  */
@@ -1047,21 +1024,29 @@ export abstract class PluginDesignCreateApi {
1047
1024
  ): PluginApiReturn<ComponentHandle[]>
1048
1025
 
1049
1026
  /**
1050
- * Place a parametric **window** family into a host wall.
1027
+ * Place a **window** from the catalog into a host wall.
1051
1028
  *
1052
- * Identified by a saved **family definition id**. Discover ids with
1029
+ * Identified by a **catalog (library) id** — the team object's stable `_id`
1030
+ * or the general library's `fullName`. Discover ids with
1053
1031
  * {@linkcode PluginDesignWindowsApi.listCatalog}. The world `position` is
1054
1032
  * projected onto the host wall's face to locate the opening; the wall is
1055
1033
  * re-cut and the window hosted in a single undo entry. Placement is
1056
- * asynchronous. The sill parameter determines elevation; position Y is ignored.
1034
+ * asynchronous (the source mesh is fetched if not cached).
1057
1035
  *
1058
- * @param familyId - Hosted window definition ID; legacy mesh catalog IDs are not accepted
1036
+ * @param catalogId - Library id: team `_id` or general `fullName`
1059
1037
  * @param hostWall - The wall to host the window
1060
1038
  * @param position - World point projected onto the wall to locate the opening
1061
- * @param options - `version`, `values`, `label`, and parameter-driven `hinge`, as for door
1062
- * @param facing - World point selecting local +Z; omitted uses the picked face
1039
+ * @param options - Optional placement options: `label` — instance name;
1040
+ * `hinge` — world point near the jamb the window is hinged on (same rule
1041
+ * as {@linkcode PluginDesignCreateApi.door}; default the catalog item's
1042
+ * authored side)
1043
+ * @param facing - World point on the side of the wall the window opens to
1044
+ * (matters for asymmetric windows, e.g. casement swing) — same convention
1045
+ * as {@linkcode PluginDesignCreateApi.door}. Default: the engine picks a
1046
+ * side (nondeterministic when `position` sits on the centerline).
1063
1047
  * @returns the {@linkcode ComponentHandle} of the placed window
1064
- * @throws if the family/category/parameters are invalid, or placement or cutting fails
1048
+ * @throws if the catalog id is unknown, the host is not a wall, the source
1049
+ * mesh fails to load, or the projected point falls **outside** the host wall
1065
1050
  *
1066
1051
  * @examplePrompt Add a window to this wall here
1067
1052
  * @examplePrompt Place a casement window on the selected wall
@@ -1087,29 +1072,28 @@ export abstract class PluginDesignCreateApi {
1087
1072
  * inside that single call. Looping this single-window creator is N round-trips.
1088
1073
  */
1089
1074
  public abstract window(
1090
- familyId: string,
1075
+ catalogId: string,
1091
1076
  hostWall: ComponentHandle,
1092
1077
  position: Vec3Handle,
1093
- options?: {
1094
- label?: string
1095
- hinge?: Vec3Handle
1096
- version?: number
1097
- values?: Record<string, number | string>
1098
- },
1078
+ options?: { label?: string; hinge?: Vec3Handle },
1099
1079
  facing?: Vec3Handle,
1100
1080
  ): PluginApiReturn<ComponentHandle>
1101
1081
 
1102
1082
  /**
1103
1083
  * Place **many windows** into host walls in one undoable operation (bulk
1104
- * plural of {@linkcode window}). Each item carries its own family id, host
1084
+ * plural of {@linkcode window}). Each item carries its own catalog id, host
1105
1085
  * wall, world position, and optional `facing`, `label`, `width`, `height` and
1106
1086
  * `sillHeight` — the same fields as a `"window"`
1107
1087
  * {@linkcode PluginDesignCreateOpeningOptions}. `sillHeight` is measured from
1108
1088
  * the host wall base to the BOTTOM of the window. Validate-all-or-throw; one
1109
1089
  * command.
1110
1090
  *
1111
- * Hosts keep their identity. Width, height and sillHeight set the declared
1112
- * width, height and sill parameters before the first cut. No mesh scaling occurs.
1091
+ * As with the singular creator, placing an opening **re-cuts its host wall**:
1092
+ * the wall you passed as `hostWall` stops resolving once the call returns.
1093
+ * Several items MAY name the same original wall handle in one call — the host
1094
+ * chains the re-cuts internally — but after the call recover the surviving
1095
+ * wall with `design.query.getHost(opening)`, never by reusing the handle you
1096
+ * passed in.
1113
1097
  *
1114
1098
  * @param items - One {@linkcode PluginCreateWindowItem} per window to place
1115
1099
  * (≥1, ≤1000)
@@ -1117,9 +1101,10 @@ export abstract class PluginDesignCreateApi {
1117
1101
  * @throws `VALIDATION` if the items fail the schema (empty array, more than
1118
1102
  * 1000 items, unknown fields, a non-positive `width`/`height`, a negative
1119
1103
  * `sillHeight`); `HANDLE_INVALID` if a `position`, `facing` or `hinge`
1120
- * handle is unknown or released; `PRECONDITION_FAILED` if the family cannot be
1121
- * resolved or saved, or a host is locked / is not in the active proposal;
1122
- * `OPERATION_FAILED` if placement, containment, overlap checks or cutting fail
1104
+ * handle is unknown or released; `PRECONDITION_FAILED` if a catalog id is unknown, a
1105
+ * `hostWall` is not a wall / is locked / is not in the active proposal, the
1106
+ * projected point falls outside its host wall, or a window tool is active;
1107
+ * `OPERATION_FAILED` if a source mesh fails to load or placement fails
1123
1108
  * (nothing is created — `details.itemIndex` is the failing item);
1124
1109
  * `METHOD_NOT_PERMITTED` if the plugin may not write.
1125
1110
  *
@@ -1130,7 +1115,7 @@ export abstract class PluginDesignCreateApi {
1130
1115
  * @examplePrompt Add all the windows with a 0.9m sill height together
1131
1116
  *
1132
1117
  * @performance Bulk creator — the whole batch is ONE host round-trip and ONE undo
1133
- * entry. Always prefer this over
1118
+ * entry, and each distinct catalog source loads once. Always prefer this over
1134
1119
  * calling `design.create.window` in a loop: build the full `items[]` array first
1135
1120
  * (all host walls and points up front), then make one call.
1136
1121
  *
@@ -1140,8 +1125,8 @@ export abstract class PluginDesignCreateApi {
1140
1125
  * const [wall] = await snaptrude.design.query.listWalls({ isSelected: true })
1141
1126
  * const [casement] = await snaptrude.design.windows.listCatalog()
1142
1127
  * const placed = await snaptrude.design.create.windows([
1143
- * { familyId: casement.id, hostWall: wall, position: await v.new(2, 0, 5), values: { sill: "900mm" } },
1144
- * { familyId: casement.id, hostWall: wall, position: await v.new(5, 0, 5), values: { sill: "900mm" } },
1128
+ * { catalogId: casement.id, hostWall: wall, position: await v.new(2, 0, 5), sillHeight: 0.9 },
1129
+ * { catalogId: casement.id, hostWall: wall, position: await v.new(5, 0, 5), sillHeight: 0.9 },
1145
1130
  * ])
1146
1131
  * const currentWall = await snaptrude.design.query.getHost(placed[0])
1147
1132
  * ```
@@ -1151,17 +1136,17 @@ export abstract class PluginDesignCreateApi {
1151
1136
  ): PluginApiReturn<ComponentHandle[]>
1152
1137
 
1153
1138
  /**
1154
- * Place a parametric **door or window** into a host wall with parameter overrides.
1139
+ * Place a catalog **door or window** into a host wall with optional size overrides.
1155
1140
  *
1156
1141
  * The world `position` is projected onto the host wall to locate the opening.
1157
1142
  * All supplied dimensions use Snaptrude engine units. Window `sillHeight` is
1158
1143
  * measured from the host wall base to the bottom of the window, not to
1159
1144
  * its center. Placement is asynchronous and committed as one undoable creation.
1160
1145
  *
1161
- * @param options - Opening kind, family and host references, placement, and
1146
+ * @param options - Opening kind, catalog and host references, placement, and
1162
1147
  * optional facing (swing side), hinge (hinged jamb), label, and dimensions
1163
1148
  * @returns the {@linkcode ComponentHandle} of the placed door or window
1164
- * @throws if the options are invalid, the family id is unknown, the host is
1149
+ * @throws if the options are invalid, the catalog id is unknown, the host is
1165
1150
  * not a wall, loading fails, or the opening cannot be placed on the host
1166
1151
  *
1167
1152
  * @examplePrompt Add a 1m wide door to this wall here
@@ -1175,7 +1160,7 @@ export abstract class PluginDesignCreateApi {
1175
1160
  * ```ts
1176
1161
  * const opening = await snaptrude.design.create.opening({
1177
1162
  * kind: "window",
1178
- * familyId: windowType.id,
1163
+ * catalogId: windowType.id,
1179
1164
  * hostWall: wall,
1180
1165
  * position: await snaptrude.core.math.vec3.new(3, 0, 5),
1181
1166
  * width: 1.2,
@@ -1675,7 +1660,7 @@ export type PluginDesignCreateBeamArgs = z.infer<
1675
1660
  * | `profile` | {@linkcode ProfileHandle} | Ordered curve chain (wall centerlines) |
1676
1661
  * | `height` | `number`? | Wall height (default engine default) |
1677
1662
  * | `thickness` | `number`? | Wall thickness (default: `wallType`'s total layer thickness when given, else engine default) |
1678
- * | `wallType` | {@linkcode PluginWallType}? | Legacy name/id or exact native `{ id, version }` pin from `design.types.list("wall")` (default generic) |
1663
+ * | `wallType` | `string`? | Wall type name from `design.types.list("wall")` — layers/material/thickness defaults (default generic) |
1679
1664
  * | `storey` | `number`? | Target storey (integer, must exist) — walls assigned + lifted to its base in the same undo entry (default: geometry-derived) |
1680
1665
  * | `topProfiles` | ({@linkcode PluginWallTopProfile} \| `null`)[]? | Top edge per curve (same order); `null`/missing = flat at `height`. Straight curves only |
1681
1666
  */
@@ -1683,10 +1668,9 @@ export const PluginDesignCreateWallsArgs = z.object({
1683
1668
  profile: ProfileHandle,
1684
1669
  height: z.number().optional(),
1685
1670
  thickness: z.number().optional(),
1686
- wallType: PluginWallType.optional(),
1671
+ wallType: z.string().min(1).optional(),
1687
1672
  storey: z.number().int().optional(),
1688
1673
  topProfiles: z.array(PluginWallTopProfile.nullable()).optional(),
1689
- values: PluginFamilyValues.optional(),
1690
1674
  })
1691
1675
  export type PluginDesignCreateWallsArgs = z.infer<
1692
1676
  typeof PluginDesignCreateWallsArgs
@@ -1759,23 +1743,26 @@ export type PluginDesignCreateFurnitureArgs = z.infer<
1759
1743
  *
1760
1744
  * | Property | Type | Description |
1761
1745
  * |---|---|---|
1762
- * | `familyId` | `string` | Hosted door family definition ID |
1763
- * | `version` | `number`? | Exact version; newest known by default |
1764
- * | `values` | `Record<string, number \| string>`? | Parameters; numeric lengths use SU |
1746
+ * | `catalogId` | `string` | Library id: team `_id` or general `fullName` |
1765
1747
  * | `hostWall` | {@linkcode ComponentHandle} | The wall to host the door |
1766
1748
  * | `position` | {@linkcode Vec3Handle} | World point projected onto the wall |
1767
1749
  * | `label` | `string`? | Instance name (optional) |
1768
1750
  * | `facing` | {@linkcode Vec3Handle}? | World point on the side of the wall the door swings open to (default engine-chosen) |
1769
- * | `hinge` | {@linkcode Vec3Handle}? | World point near the hinged jamb; requires hand control |
1751
+ * | `hinge` | {@linkcode Vec3Handle}? | World point near the jamb the door is hinged on (default the catalog item's authored side) |
1770
1752
  */
1771
1753
  export const PluginDesignCreateDoorArgs = z.object({
1772
- ...PluginOpeningBaseOptions,
1754
+ catalogId: z.string().min(1),
1755
+ hostWall: ComponentHandle,
1756
+ position: Vec3Handle,
1757
+ label: z.string().optional(),
1758
+ facing: Vec3Handle.optional(),
1759
+ hinge: Vec3Handle.optional(),
1773
1760
  })
1774
1761
  export type PluginDesignCreateDoorArgs = z.infer<
1775
1762
  typeof PluginDesignCreateDoorArgs
1776
1763
  >
1777
1764
  // TRANSPORT: positional signature shipped — facing is the trailing 5th arg, hinge rides in options:
1778
- // door(familyId, hostWall, position, options?: { label?, hinge?, version?, values? }, facing?)
1765
+ // door(catalogId: string, hostWall: ComponentHandle, position: Vec3Handle, options?: { label?, hinge? }, facing?: Vec3Handle)
1779
1766
 
1780
1767
  // ---------------------------------------------------------------------------
1781
1768
  // window
@@ -1786,23 +1773,26 @@ export type PluginDesignCreateDoorArgs = z.infer<
1786
1773
  *
1787
1774
  * | Property | Type | Description |
1788
1775
  * |---|---|---|
1789
- * | `familyId` | `string` | Hosted window family definition ID |
1790
- * | `version` | `number`? | Exact version; newest known by default |
1791
- * | `values` | `Record<string, number \| string>`? | Parameters; numeric lengths use SU |
1776
+ * | `catalogId` | `string` | Library id: team `_id` or general `fullName` |
1792
1777
  * | `hostWall` | {@linkcode ComponentHandle} | The wall to host the window |
1793
1778
  * | `position` | {@linkcode Vec3Handle} | World point projected onto the wall |
1794
1779
  * | `label` | `string`? | Instance name (optional) |
1795
1780
  * | `facing` | {@linkcode Vec3Handle}? | World point on the side of the wall the window opens to (default engine-chosen) |
1796
- * | `hinge` | {@linkcode Vec3Handle}? | World point near the hinged jamb; requires hand control |
1781
+ * | `hinge` | {@linkcode Vec3Handle}? | World point near the jamb the window is hinged on (default the catalog item's authored side) |
1797
1782
  */
1798
1783
  export const PluginDesignCreateWindowArgs = z.object({
1799
- ...PluginOpeningBaseOptions,
1784
+ catalogId: z.string().min(1),
1785
+ hostWall: ComponentHandle,
1786
+ position: Vec3Handle,
1787
+ label: z.string().optional(),
1788
+ facing: Vec3Handle.optional(),
1789
+ hinge: Vec3Handle.optional(),
1800
1790
  })
1801
1791
  export type PluginDesignCreateWindowArgs = z.infer<
1802
1792
  typeof PluginDesignCreateWindowArgs
1803
1793
  >
1804
1794
  // TRANSPORT: positional signature shipped — facing is the trailing 5th arg, hinge rides in options:
1805
- // window(familyId, hostWall, position, options?: { label?, hinge?, version?, values? }, facing?)
1795
+ // window(catalogId: string, hostWall: ComponentHandle, position: Vec3Handle, options?: { label?, hinge? }, facing?: Vec3Handle)
1806
1796
 
1807
1797
  // ---------------------------------------------------------------------------
1808
1798
  // opening
@@ -6,30 +6,27 @@ import { ComponentHandle, Vec3Handle } from "../../../handles"
6
6
  * {@linkcode PluginDesignCreateOpeningOptions} and by the bulk item schemas in
7
7
  * `bulk-items.ts`, so singular and plural openings validate identically.
8
8
  *
9
- * PC-only placement. The family recipe owns dimensions and geometry. Overrides
10
- * are applied before fit checks and cutting, never by scaling generated meshes.
11
- * `facing` selects the host frame's +Z side. `hinge` selects the declared
12
- * `hand` parameter (left/right); families without that control reject it.
9
+ * `facing` and `hinge` are WORLD POINTS, not directions: `facing` sits on the
10
+ * side of the wall the leaf swings open to (where the plan symbol draws the
11
+ * swing arc); `hinge` sits near the jamb the leaf is hinged on — the item is
12
+ * reflected along the wall so its hinged jamb is the one nearer that point.
13
+ * Either may be omitted (engine-chosen side / the catalog item's authored
14
+ * hinge side). Neither has a visible effect on symmetric items such as
15
+ * sliders or fixed windows.
13
16
  *
14
17
  * | Property | Type | Description |
15
18
  * |---|---|---|
16
- * | `familyId` | `string` | Hosted parametric definition ID, not a mesh catalog ID |
17
- * | `version` | `number`? | Exact family version; newest known by default |
18
- * | `values` | `Record<string, number \| string>`? | Authored instance parameters; numeric lengths use Snaptrude units |
19
+ * | `catalogId` | `string` | Library id: team `_id` or general `fullName` |
19
20
  * | `hostWall` | {@linkcode ComponentHandle} | The wall to host the opening |
20
21
  * | `position` | {@linkcode Vec3Handle} | World point projected onto the wall |
21
22
  * | `facing` | {@linkcode Vec3Handle}? | World point on the side of the wall the opening swings open to (default engine-chosen) |
22
- * | `hinge` | {@linkcode Vec3Handle}? | World point near the hinged jamb; requires the recipe's hand parameter |
23
+ * | `hinge` | {@linkcode Vec3Handle}? | World point near the jamb the opening is hinged on (default the catalog item's authored side) |
23
24
  * | `label` | `string`? | Instance name (optional) |
24
- * | `width` | `number`? | Sets the declared width parameter, not the opening's evaluated envelope |
25
- * | `height` | `number`? | Sets the declared height parameter |
25
+ * | `width` | `number`? | Width override (Snaptrude units, > 0; default the catalog item's) |
26
+ * | `height` | `number`? | Height override (Snaptrude units, > 0; default the catalog item's) |
26
27
  */
27
28
  export const PluginOpeningBaseOptions = {
28
- familyId: z.string().min(1),
29
- version: z.number().int().positive().optional(),
30
- values: z
31
- .record(z.string(), z.union([z.number().finite(), z.string()]))
32
- .optional(),
29
+ catalogId: z.string().min(1),
33
30
  hostWall: ComponentHandle,
34
31
  position: Vec3Handle,
35
32
  facing: Vec3Handle.optional(),