@pascal-app/core 0.5.1 → 0.7.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 (134) hide show
  1. package/dist/events/bus.d.ts +74 -4
  2. package/dist/events/bus.d.ts.map +1 -1
  3. package/dist/events/bus.js +1 -1
  4. package/dist/hooks/scene-registry/scene-registry.d.ts +2 -0
  5. package/dist/hooks/scene-registry/scene-registry.d.ts.map +1 -1
  6. package/dist/hooks/scene-registry/scene-registry.js +2 -0
  7. package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts.map +1 -1
  8. package/dist/hooks/spatial-grid/spatial-grid-manager.js +164 -6
  9. package/dist/hooks/spatial-grid/spatial-grid.d.ts +2 -0
  10. package/dist/hooks/spatial-grid/spatial-grid.d.ts.map +1 -1
  11. package/dist/hooks/spatial-grid/spatial-grid.js +43 -20
  12. package/dist/index.d.ts +9 -13
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +7 -11
  15. package/dist/lib/door-operation.d.ts +7 -0
  16. package/dist/lib/door-operation.d.ts.map +1 -0
  17. package/dist/lib/door-operation.js +25 -0
  18. package/dist/lib/polygon-geometry.d.ts +3 -0
  19. package/dist/lib/polygon-geometry.d.ts.map +1 -0
  20. package/dist/lib/polygon-geometry.js +90 -0
  21. package/dist/lib/slab-polygon.d.ts +3 -0
  22. package/dist/lib/slab-polygon.d.ts.map +1 -0
  23. package/dist/lib/slab-polygon.js +58 -0
  24. package/dist/lib/space-detection.d.ts +10 -17
  25. package/dist/lib/space-detection.d.ts.map +1 -1
  26. package/dist/lib/space-detection.js +666 -453
  27. package/dist/material-library.d.ts +20 -0
  28. package/dist/material-library.d.ts.map +1 -0
  29. package/dist/material-library.js +580 -0
  30. package/dist/schema/asset-url.d.ts +34 -0
  31. package/dist/schema/asset-url.d.ts.map +1 -0
  32. package/dist/schema/asset-url.js +79 -0
  33. package/dist/schema/asset-url.test.d.ts +2 -0
  34. package/dist/schema/asset-url.test.d.ts.map +1 -0
  35. package/dist/schema/asset-url.test.js +138 -0
  36. package/dist/schema/index.d.ts +14 -7
  37. package/dist/schema/index.d.ts.map +1 -1
  38. package/dist/schema/index.js +10 -7
  39. package/dist/schema/material.d.ts +112 -2
  40. package/dist/schema/material.d.ts.map +1 -1
  41. package/dist/schema/material.js +55 -1
  42. package/dist/schema/nodes/ceiling.d.ts +11 -1
  43. package/dist/schema/nodes/ceiling.d.ts.map +1 -1
  44. package/dist/schema/nodes/ceiling.js +6 -0
  45. package/dist/schema/nodes/column.d.ts +520 -0
  46. package/dist/schema/nodes/column.d.ts.map +1 -0
  47. package/dist/schema/nodes/column.js +385 -0
  48. package/dist/schema/nodes/door.d.ts +74 -1
  49. package/dist/schema/nodes/door.d.ts.map +1 -1
  50. package/dist/schema/nodes/door.js +39 -2
  51. package/dist/schema/nodes/fence.d.ts +34 -0
  52. package/dist/schema/nodes/fence.d.ts.map +1 -1
  53. package/dist/schema/nodes/fence.js +5 -0
  54. package/dist/schema/nodes/guide.d.ts +17 -0
  55. package/dist/schema/nodes/guide.d.ts.map +1 -1
  56. package/dist/schema/nodes/guide.js +11 -1
  57. package/dist/schema/nodes/item.d.ts +10 -2
  58. package/dist/schema/nodes/item.d.ts.map +1 -1
  59. package/dist/schema/nodes/item.js +18 -1
  60. package/dist/schema/nodes/level.d.ts +1 -1
  61. package/dist/schema/nodes/level.d.ts.map +1 -1
  62. package/dist/schema/nodes/level.js +6 -0
  63. package/dist/schema/nodes/roof-segment.d.ts +3 -1
  64. package/dist/schema/nodes/roof-segment.d.ts.map +1 -1
  65. package/dist/schema/nodes/roof-segment.js +1 -0
  66. package/dist/schema/nodes/roof.d.ts +108 -0
  67. package/dist/schema/nodes/roof.d.ts.map +1 -1
  68. package/dist/schema/nodes/roof.js +58 -2
  69. package/dist/schema/nodes/scan.d.ts.map +1 -1
  70. package/dist/schema/nodes/scan.js +2 -1
  71. package/dist/schema/nodes/site.d.ts +2 -1
  72. package/dist/schema/nodes/site.d.ts.map +1 -1
  73. package/dist/schema/nodes/slab.d.ts +11 -1
  74. package/dist/schema/nodes/slab.d.ts.map +1 -1
  75. package/dist/schema/nodes/slab.js +7 -0
  76. package/dist/schema/nodes/spawn.d.ts +24 -0
  77. package/dist/schema/nodes/spawn.d.ts.map +1 -0
  78. package/dist/schema/nodes/spawn.js +8 -0
  79. package/dist/schema/nodes/stair-segment.d.ts +3 -1
  80. package/dist/schema/nodes/stair-segment.d.ts.map +1 -1
  81. package/dist/schema/nodes/stair-segment.js +1 -0
  82. package/dist/schema/nodes/stair.d.ts +122 -2
  83. package/dist/schema/nodes/stair.d.ts.map +1 -1
  84. package/dist/schema/nodes/stair.js +72 -2
  85. package/dist/schema/nodes/surface-hole-metadata.d.ts +10 -0
  86. package/dist/schema/nodes/surface-hole-metadata.d.ts.map +1 -0
  87. package/dist/schema/nodes/surface-hole-metadata.js +5 -0
  88. package/dist/schema/nodes/wall.d.ts +87 -1
  89. package/dist/schema/nodes/wall.d.ts.map +1 -1
  90. package/dist/schema/nodes/wall.js +45 -4
  91. package/dist/schema/nodes/window.d.ts +57 -1
  92. package/dist/schema/nodes/window.d.ts.map +1 -1
  93. package/dist/schema/nodes/window.js +29 -0
  94. package/dist/schema/types.d.ts +653 -12
  95. package/dist/schema/types.d.ts.map +1 -1
  96. package/dist/schema/types.js +4 -0
  97. package/dist/store/actions/node-actions.d.ts +1 -1
  98. package/dist/store/actions/node-actions.d.ts.map +1 -1
  99. package/dist/store/actions/node-actions.js +181 -5
  100. package/dist/store/history-control.d.ts +14 -0
  101. package/dist/store/history-control.d.ts.map +1 -0
  102. package/dist/store/history-control.js +22 -0
  103. package/dist/store/use-interactive.d.ts +43 -0
  104. package/dist/store/use-interactive.d.ts.map +1 -1
  105. package/dist/store/use-interactive.js +66 -0
  106. package/dist/store/use-scene.d.ts.map +1 -1
  107. package/dist/store/use-scene.js +307 -3
  108. package/dist/systems/ceiling/ceiling-system.d.ts.map +1 -1
  109. package/dist/systems/ceiling/ceiling-system.js +7 -0
  110. package/dist/systems/fence/fence-system.d.ts.map +1 -1
  111. package/dist/systems/fence/fence-system.js +106 -39
  112. package/dist/systems/roof/roof-system.d.ts.map +1 -1
  113. package/dist/systems/roof/roof-system.js +31 -1
  114. package/dist/systems/slab/slab-system.d.ts.map +1 -1
  115. package/dist/systems/slab/slab-system.js +45 -8
  116. package/dist/systems/stair/stair-opening-sync.d.ts +6 -0
  117. package/dist/systems/stair/stair-opening-sync.d.ts.map +1 -0
  118. package/dist/systems/stair/stair-opening-sync.js +576 -0
  119. package/dist/systems/stair/stair-opening-sync.test.d.ts +2 -0
  120. package/dist/systems/stair/stair-opening-sync.test.d.ts.map +1 -0
  121. package/dist/systems/stair/stair-opening-sync.test.js +65 -0
  122. package/dist/systems/stair/stair-system.d.ts.map +1 -1
  123. package/dist/systems/stair/stair-system.js +119 -2
  124. package/dist/systems/wall/wall-curve.d.ts +43 -0
  125. package/dist/systems/wall/wall-curve.d.ts.map +1 -0
  126. package/dist/systems/wall/wall-curve.js +176 -0
  127. package/dist/systems/wall/wall-footprint.d.ts.map +1 -1
  128. package/dist/systems/wall/wall-footprint.js +16 -2
  129. package/dist/systems/wall/wall-mitering.d.ts +7 -0
  130. package/dist/systems/wall/wall-mitering.d.ts.map +1 -1
  131. package/dist/systems/wall/wall-mitering.js +76 -3
  132. package/dist/systems/wall/wall-system.d.ts.map +1 -1
  133. package/dist/systems/wall/wall-system.js +202 -2
  134. package/package.json +33 -5
@@ -1,4 +1,5 @@
1
1
  import { z } from 'zod';
2
+ import { type MaterialSchema } from '../material';
2
3
  export declare const StairRailingMode: z.ZodEnum<{
3
4
  none: "none";
4
5
  left: "left";
@@ -7,16 +8,26 @@ export declare const StairRailingMode: z.ZodEnum<{
7
8
  }>;
8
9
  export declare const StairType: z.ZodEnum<{
9
10
  straight: "straight";
10
- curved: "curved";
11
11
  spiral: "spiral";
12
+ curved: "curved";
12
13
  }>;
13
14
  export declare const StairTopLandingMode: z.ZodEnum<{
14
15
  none: "none";
15
16
  integrated: "integrated";
16
17
  }>;
18
+ export declare const StairSlabOpeningMode: z.ZodEnum<{
19
+ none: "none";
20
+ destination: "destination";
21
+ }>;
17
22
  export type StairRailingMode = z.infer<typeof StairRailingMode>;
18
23
  export type StairType = z.infer<typeof StairType>;
19
24
  export type StairTopLandingMode = z.infer<typeof StairTopLandingMode>;
25
+ export type StairSlabOpeningMode = z.infer<typeof StairSlabOpeningMode>;
26
+ export type StairSurfaceMaterialRole = 'railing' | 'tread' | 'side';
27
+ export type StairSurfaceMaterialSpec = {
28
+ material?: MaterialSchema;
29
+ materialPreset?: string;
30
+ };
20
31
  export declare const StairNode: z.ZodObject<{
21
32
  object: z.ZodDefault<z.ZodLiteral<"node">>;
22
33
  name: z.ZodOptional<z.ZodString>;
@@ -36,8 +47,107 @@ export declare const StairNode: z.ZodObject<{
36
47
  id: z.ZodDefault<z.ZodTemplateLiteral<`stair_${string}`>>;
37
48
  type: z.ZodDefault<z.ZodLiteral<"stair">>;
38
49
  material: z.ZodOptional<z.ZodObject<{
50
+ id: z.ZodOptional<z.ZodString>;
51
+ preset: z.ZodOptional<z.ZodEnum<{
52
+ white: "white";
53
+ brick: "brick";
54
+ concrete: "concrete";
55
+ wood: "wood";
56
+ glass: "glass";
57
+ metal: "metal";
58
+ plaster: "plaster";
59
+ tile: "tile";
60
+ marble: "marble";
61
+ custom: "custom";
62
+ }>>;
63
+ properties: z.ZodOptional<z.ZodObject<{
64
+ color: z.ZodDefault<z.ZodString>;
65
+ roughness: z.ZodDefault<z.ZodNumber>;
66
+ metalness: z.ZodDefault<z.ZodNumber>;
67
+ opacity: z.ZodDefault<z.ZodNumber>;
68
+ transparent: z.ZodDefault<z.ZodBoolean>;
69
+ side: z.ZodDefault<z.ZodEnum<{
70
+ front: "front";
71
+ back: "back";
72
+ double: "double";
73
+ }>>;
74
+ }, z.core.$strip>>;
75
+ texture: z.ZodOptional<z.ZodObject<{
76
+ url: z.ZodString;
77
+ repeat: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
78
+ scale: z.ZodOptional<z.ZodNumber>;
79
+ }, z.core.$strip>>;
80
+ }, z.core.$strip>>;
81
+ materialPreset: z.ZodOptional<z.ZodString>;
82
+ railingMaterial: z.ZodOptional<z.ZodObject<{
83
+ id: z.ZodOptional<z.ZodString>;
84
+ preset: z.ZodOptional<z.ZodEnum<{
85
+ white: "white";
86
+ brick: "brick";
87
+ concrete: "concrete";
88
+ wood: "wood";
89
+ glass: "glass";
90
+ metal: "metal";
91
+ plaster: "plaster";
92
+ tile: "tile";
93
+ marble: "marble";
94
+ custom: "custom";
95
+ }>>;
96
+ properties: z.ZodOptional<z.ZodObject<{
97
+ color: z.ZodDefault<z.ZodString>;
98
+ roughness: z.ZodDefault<z.ZodNumber>;
99
+ metalness: z.ZodDefault<z.ZodNumber>;
100
+ opacity: z.ZodDefault<z.ZodNumber>;
101
+ transparent: z.ZodDefault<z.ZodBoolean>;
102
+ side: z.ZodDefault<z.ZodEnum<{
103
+ front: "front";
104
+ back: "back";
105
+ double: "double";
106
+ }>>;
107
+ }, z.core.$strip>>;
108
+ texture: z.ZodOptional<z.ZodObject<{
109
+ url: z.ZodString;
110
+ repeat: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
111
+ scale: z.ZodOptional<z.ZodNumber>;
112
+ }, z.core.$strip>>;
113
+ }, z.core.$strip>>;
114
+ railingMaterialPreset: z.ZodOptional<z.ZodString>;
115
+ treadMaterial: z.ZodOptional<z.ZodObject<{
116
+ id: z.ZodOptional<z.ZodString>;
39
117
  preset: z.ZodOptional<z.ZodEnum<{
118
+ white: "white";
119
+ brick: "brick";
120
+ concrete: "concrete";
121
+ wood: "wood";
122
+ glass: "glass";
123
+ metal: "metal";
124
+ plaster: "plaster";
125
+ tile: "tile";
126
+ marble: "marble";
40
127
  custom: "custom";
128
+ }>>;
129
+ properties: z.ZodOptional<z.ZodObject<{
130
+ color: z.ZodDefault<z.ZodString>;
131
+ roughness: z.ZodDefault<z.ZodNumber>;
132
+ metalness: z.ZodDefault<z.ZodNumber>;
133
+ opacity: z.ZodDefault<z.ZodNumber>;
134
+ transparent: z.ZodDefault<z.ZodBoolean>;
135
+ side: z.ZodDefault<z.ZodEnum<{
136
+ front: "front";
137
+ back: "back";
138
+ double: "double";
139
+ }>>;
140
+ }, z.core.$strip>>;
141
+ texture: z.ZodOptional<z.ZodObject<{
142
+ url: z.ZodString;
143
+ repeat: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
144
+ scale: z.ZodOptional<z.ZodNumber>;
145
+ }, z.core.$strip>>;
146
+ }, z.core.$strip>>;
147
+ treadMaterialPreset: z.ZodOptional<z.ZodString>;
148
+ sideMaterial: z.ZodOptional<z.ZodObject<{
149
+ id: z.ZodOptional<z.ZodString>;
150
+ preset: z.ZodOptional<z.ZodEnum<{
41
151
  white: "white";
42
152
  brick: "brick";
43
153
  concrete: "concrete";
@@ -47,6 +157,7 @@ export declare const StairNode: z.ZodObject<{
47
157
  plaster: "plaster";
48
158
  tile: "tile";
49
159
  marble: "marble";
160
+ custom: "custom";
50
161
  }>>;
51
162
  properties: z.ZodOptional<z.ZodObject<{
52
163
  color: z.ZodDefault<z.ZodString>;
@@ -66,13 +177,21 @@ export declare const StairNode: z.ZodObject<{
66
177
  scale: z.ZodOptional<z.ZodNumber>;
67
178
  }, z.core.$strip>>;
68
179
  }, z.core.$strip>>;
180
+ sideMaterialPreset: z.ZodOptional<z.ZodString>;
69
181
  position: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
70
182
  rotation: z.ZodDefault<z.ZodNumber>;
71
183
  stairType: z.ZodDefault<z.ZodEnum<{
72
184
  straight: "straight";
73
- curved: "curved";
74
185
  spiral: "spiral";
186
+ curved: "curved";
187
+ }>>;
188
+ fromLevelId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
189
+ toLevelId: z.ZodDefault<z.ZodNullable<z.ZodString>>;
190
+ slabOpeningMode: z.ZodDefault<z.ZodEnum<{
191
+ none: "none";
192
+ destination: "destination";
75
193
  }>>;
194
+ openingOffset: z.ZodDefault<z.ZodNumber>;
76
195
  width: z.ZodDefault<z.ZodNumber>;
77
196
  totalRise: z.ZodDefault<z.ZodNumber>;
78
197
  stepCount: z.ZodDefault<z.ZodNumber>;
@@ -97,4 +216,5 @@ export declare const StairNode: z.ZodObject<{
97
216
  children: z.ZodDefault<z.ZodArray<z.ZodDefault<z.ZodTemplateLiteral<`sseg_${string}`>>>>;
98
217
  }, z.core.$strip>;
99
218
  export type StairNode = z.infer<typeof StairNode>;
219
+ export declare function getEffectiveStairSurfaceMaterial(node: StairNode, role: StairSurfaceMaterialRole): StairSurfaceMaterialSpec;
100
220
  //# sourceMappingURL=stair.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stair.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/stair.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAKvB,eAAO,MAAM,gBAAgB;;;;;EAA4C,CAAA;AACzE,eAAO,MAAM,SAAS;;;;EAA2C,CAAA;AACjE,eAAO,MAAM,mBAAmB;;;EAAiC,CAAA;AAEjE,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAC/D,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAA;AACjD,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA;AAErE,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA8CrB,CAAA;AAED,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAA"}
1
+ {"version":3,"file":"stair.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/stair.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,EAAE,KAAK,cAAc,EAA0C,MAAM,aAAa,CAAA;AAGzF,eAAO,MAAM,gBAAgB;;;;;EAA4C,CAAA;AACzE,eAAO,MAAM,SAAS;;;;EAA2C,CAAA;AACjE,eAAO,MAAM,mBAAmB;;;EAAiC,CAAA;AACjE,eAAO,MAAM,oBAAoB;;;EAAkC,CAAA;AAEnE,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAC/D,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAA;AACjD,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA;AACrE,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAA;AACvE,MAAM,MAAM,wBAAwB,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAA;AACnE,MAAM,MAAM,wBAAwB,GAAG;IACrC,QAAQ,CAAC,EAAE,cAAc,CAAA;IACzB,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAED,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA4DrB,CAAA;AAED,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,SAAS,CAAC,CAAA;AASjD,wBAAgB,gCAAgC,CAC9C,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,wBAAwB,GAC7B,wBAAwB,CA2D1B"}
@@ -1,19 +1,31 @@
1
1
  import dedent from 'dedent';
2
2
  import { z } from 'zod';
3
3
  import { BaseNode, nodeType, objectId } from '../base';
4
- import { MaterialSchema } from '../material';
4
+ import { MaterialSchema as MaterialSchemaSchema } from '../material';
5
5
  import { StairSegmentNode } from './stair-segment';
6
6
  export const StairRailingMode = z.enum(['none', 'left', 'right', 'both']);
7
7
  export const StairType = z.enum(['straight', 'curved', 'spiral']);
8
8
  export const StairTopLandingMode = z.enum(['none', 'integrated']);
9
+ export const StairSlabOpeningMode = z.enum(['none', 'destination']);
9
10
  export const StairNode = BaseNode.extend({
10
11
  id: objectId('stair'),
11
12
  type: nodeType('stair'),
12
- material: MaterialSchema.optional(),
13
+ material: MaterialSchemaSchema.optional(),
14
+ materialPreset: z.string().optional(),
15
+ railingMaterial: MaterialSchemaSchema.optional(),
16
+ railingMaterialPreset: z.string().optional(),
17
+ treadMaterial: MaterialSchemaSchema.optional(),
18
+ treadMaterialPreset: z.string().optional(),
19
+ sideMaterial: MaterialSchemaSchema.optional(),
20
+ sideMaterialPreset: z.string().optional(),
13
21
  position: z.tuple([z.number(), z.number(), z.number()]).default([0, 0, 0]),
14
22
  // Rotation around Y axis in radians
15
23
  rotation: z.number().default(0),
16
24
  stairType: StairType.default('straight'),
25
+ fromLevelId: z.string().nullable().default(null),
26
+ toLevelId: z.string().nullable().default(null),
27
+ slabOpeningMode: StairSlabOpeningMode.default('none'),
28
+ openingOffset: z.number().default(0),
17
29
  width: z.number().default(1.0),
18
30
  totalRise: z.number().default(2.5),
19
31
  stepCount: z.number().default(10),
@@ -36,6 +48,9 @@ export const StairNode = BaseNode.extend({
36
48
  - position: center position of the stair group
37
49
  - rotation: rotation around Y axis
38
50
  - stairType: straight (segment-based), curved (arc-based), or spiral
51
+ - fromLevelId / toLevelId: source and destination levels used for auto slab cutouts
52
+ - slabOpeningMode: whether a destination-level slab opening is generated for this stair
53
+ - openingOffset: extra opening expansion applied after the cutout polygon is computed
39
54
  - width: stair width
40
55
  - totalRise: total stair height
41
56
  - stepCount: number of visible steps
@@ -51,3 +66,58 @@ export const StairNode = BaseNode.extend({
51
66
  - railingHeight: top height of the railing above the stair surface
52
67
  - children: array of StairSegmentNode IDs for straight stairs
53
68
  `);
69
+ function getLegacyStairSurfaceMaterial(node) {
70
+ return {
71
+ material: node.material,
72
+ materialPreset: node.materialPreset,
73
+ };
74
+ }
75
+ export function getEffectiveStairSurfaceMaterial(node, role) {
76
+ if (role === 'railing') {
77
+ if (node.railingMaterial !== undefined || typeof node.railingMaterialPreset === 'string') {
78
+ return {
79
+ material: node.railingMaterial,
80
+ materialPreset: typeof node.railingMaterialPreset === 'string' ? node.railingMaterialPreset : undefined,
81
+ };
82
+ }
83
+ }
84
+ if (role === 'tread') {
85
+ if (node.treadMaterial !== undefined || typeof node.treadMaterialPreset === 'string') {
86
+ return {
87
+ material: node.treadMaterial,
88
+ materialPreset: typeof node.treadMaterialPreset === 'string' ? node.treadMaterialPreset : undefined,
89
+ };
90
+ }
91
+ }
92
+ if (role === 'side') {
93
+ if (node.sideMaterial !== undefined || typeof node.sideMaterialPreset === 'string') {
94
+ return {
95
+ material: node.sideMaterial,
96
+ materialPreset: typeof node.sideMaterialPreset === 'string' ? node.sideMaterialPreset : undefined,
97
+ };
98
+ }
99
+ }
100
+ const treadFallback = {
101
+ material: node.treadMaterial,
102
+ materialPreset: typeof node.treadMaterialPreset === 'string' ? node.treadMaterialPreset : undefined,
103
+ };
104
+ const sideFallback = {
105
+ material: node.sideMaterial,
106
+ materialPreset: typeof node.sideMaterialPreset === 'string' ? node.sideMaterialPreset : undefined,
107
+ };
108
+ if (role === 'tread' && (sideFallback.material !== undefined || sideFallback.materialPreset !== undefined)) {
109
+ return sideFallback;
110
+ }
111
+ if (role === 'side' && (treadFallback.material !== undefined || treadFallback.materialPreset !== undefined)) {
112
+ return treadFallback;
113
+ }
114
+ if (role === 'railing') {
115
+ if (treadFallback.material !== undefined || treadFallback.materialPreset !== undefined) {
116
+ return treadFallback;
117
+ }
118
+ if (sideFallback.material !== undefined || sideFallback.materialPreset !== undefined) {
119
+ return sideFallback;
120
+ }
121
+ }
122
+ return getLegacyStairSurfaceMaterial(node);
123
+ }
@@ -0,0 +1,10 @@
1
+ import { z } from 'zod';
2
+ export declare const SurfaceHoleMetadata: z.ZodObject<{
3
+ source: z.ZodDefault<z.ZodEnum<{
4
+ stair: "stair";
5
+ manual: "manual";
6
+ }>>;
7
+ stairId: z.ZodOptional<z.ZodString>;
8
+ }, z.core.$strip>;
9
+ export type SurfaceHoleMetadata = z.infer<typeof SurfaceHoleMetadata>;
10
+ //# sourceMappingURL=surface-hole-metadata.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surface-hole-metadata.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/surface-hole-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,eAAO,MAAM,mBAAmB;;;;;;iBAG9B,CAAA;AAEF,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA"}
@@ -0,0 +1,5 @@
1
+ import { z } from 'zod';
2
+ export const SurfaceHoleMetadata = z.object({
3
+ source: z.enum(['manual', 'stair']).default('manual'),
4
+ stairId: z.string().optional(),
5
+ });
@@ -1,4 +1,5 @@
1
1
  import { z } from 'zod';
2
+ import { MaterialSchema } from '../material';
2
3
  export declare const WallNode: z.ZodObject<{
3
4
  object: z.ZodDefault<z.ZodLiteral<"node">>;
4
5
  name: z.ZodOptional<z.ZodString>;
@@ -17,10 +18,76 @@ export declare const WallNode: z.ZodObject<{
17
18
  metadata: z.ZodDefault<z.ZodOptional<z.ZodJSONSchema>>;
18
19
  id: z.ZodDefault<z.ZodTemplateLiteral<`wall_${string}`>>;
19
20
  type: z.ZodDefault<z.ZodLiteral<"wall">>;
20
- children: z.ZodDefault<z.ZodArray<z.ZodDefault<z.ZodTemplateLiteral<`item_${string}`>>>>;
21
+ children: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodDefault<z.ZodTemplateLiteral<`item_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`door_${string}`>>, z.ZodDefault<z.ZodTemplateLiteral<`window_${string}`>>]>>>;
21
22
  material: z.ZodOptional<z.ZodObject<{
23
+ id: z.ZodOptional<z.ZodString>;
22
24
  preset: z.ZodOptional<z.ZodEnum<{
25
+ white: "white";
26
+ brick: "brick";
27
+ concrete: "concrete";
28
+ wood: "wood";
29
+ glass: "glass";
30
+ metal: "metal";
31
+ plaster: "plaster";
32
+ tile: "tile";
33
+ marble: "marble";
34
+ custom: "custom";
35
+ }>>;
36
+ properties: z.ZodOptional<z.ZodObject<{
37
+ color: z.ZodDefault<z.ZodString>;
38
+ roughness: z.ZodDefault<z.ZodNumber>;
39
+ metalness: z.ZodDefault<z.ZodNumber>;
40
+ opacity: z.ZodDefault<z.ZodNumber>;
41
+ transparent: z.ZodDefault<z.ZodBoolean>;
42
+ side: z.ZodDefault<z.ZodEnum<{
43
+ front: "front";
44
+ back: "back";
45
+ double: "double";
46
+ }>>;
47
+ }, z.core.$strip>>;
48
+ texture: z.ZodOptional<z.ZodObject<{
49
+ url: z.ZodString;
50
+ repeat: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
51
+ scale: z.ZodOptional<z.ZodNumber>;
52
+ }, z.core.$strip>>;
53
+ }, z.core.$strip>>;
54
+ materialPreset: z.ZodOptional<z.ZodString>;
55
+ interiorMaterial: z.ZodOptional<z.ZodObject<{
56
+ id: z.ZodOptional<z.ZodString>;
57
+ preset: z.ZodOptional<z.ZodEnum<{
58
+ white: "white";
59
+ brick: "brick";
60
+ concrete: "concrete";
61
+ wood: "wood";
62
+ glass: "glass";
63
+ metal: "metal";
64
+ plaster: "plaster";
65
+ tile: "tile";
66
+ marble: "marble";
23
67
  custom: "custom";
68
+ }>>;
69
+ properties: z.ZodOptional<z.ZodObject<{
70
+ color: z.ZodDefault<z.ZodString>;
71
+ roughness: z.ZodDefault<z.ZodNumber>;
72
+ metalness: z.ZodDefault<z.ZodNumber>;
73
+ opacity: z.ZodDefault<z.ZodNumber>;
74
+ transparent: z.ZodDefault<z.ZodBoolean>;
75
+ side: z.ZodDefault<z.ZodEnum<{
76
+ front: "front";
77
+ back: "back";
78
+ double: "double";
79
+ }>>;
80
+ }, z.core.$strip>>;
81
+ texture: z.ZodOptional<z.ZodObject<{
82
+ url: z.ZodString;
83
+ repeat: z.ZodOptional<z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>>;
84
+ scale: z.ZodOptional<z.ZodNumber>;
85
+ }, z.core.$strip>>;
86
+ }, z.core.$strip>>;
87
+ interiorMaterialPreset: z.ZodOptional<z.ZodString>;
88
+ exteriorMaterial: z.ZodOptional<z.ZodObject<{
89
+ id: z.ZodOptional<z.ZodString>;
90
+ preset: z.ZodOptional<z.ZodEnum<{
24
91
  white: "white";
25
92
  brick: "brick";
26
93
  concrete: "concrete";
@@ -30,6 +97,7 @@ export declare const WallNode: z.ZodObject<{
30
97
  plaster: "plaster";
31
98
  tile: "tile";
32
99
  marble: "marble";
100
+ custom: "custom";
33
101
  }>>;
34
102
  properties: z.ZodOptional<z.ZodObject<{
35
103
  color: z.ZodDefault<z.ZodString>;
@@ -49,8 +117,10 @@ export declare const WallNode: z.ZodObject<{
49
117
  scale: z.ZodOptional<z.ZodNumber>;
50
118
  }, z.core.$strip>>;
51
119
  }, z.core.$strip>>;
120
+ exteriorMaterialPreset: z.ZodOptional<z.ZodString>;
52
121
  thickness: z.ZodOptional<z.ZodNumber>;
53
122
  height: z.ZodOptional<z.ZodNumber>;
123
+ curveOffset: z.ZodOptional<z.ZodNumber>;
54
124
  start: z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>;
55
125
  end: z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>;
56
126
  frontSide: z.ZodDefault<z.ZodEnum<{
@@ -65,4 +135,20 @@ export declare const WallNode: z.ZodObject<{
65
135
  }>>;
66
136
  }, z.core.$strip>;
67
137
  export type WallNode = z.infer<typeof WallNode>;
138
+ export type WallSurfaceSide = 'interior' | 'exterior';
139
+ export type WallSurfaceMaterialSpec = {
140
+ material?: z.infer<typeof MaterialSchema>;
141
+ materialPreset?: string;
142
+ };
143
+ type WallSurfaceMaterialSource = {
144
+ material?: z.infer<typeof MaterialSchema>;
145
+ materialPreset?: string;
146
+ interiorMaterial?: z.infer<typeof MaterialSchema>;
147
+ interiorMaterialPreset?: string;
148
+ exteriorMaterial?: z.infer<typeof MaterialSchema>;
149
+ exteriorMaterialPreset?: string;
150
+ };
151
+ export declare function getEffectiveWallSurfaceMaterial(wall: WallSurfaceMaterialSource, side: WallSurfaceSide): WallSurfaceMaterialSpec;
152
+ export declare function getWallSurfaceMaterialSignature(spec: WallSurfaceMaterialSpec): string;
153
+ export {};
68
154
  //# sourceMappingURL=wall.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"wall.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/wall.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAQvB,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAwBpB,CAAA;AACD,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAA"}
1
+ {"version":3,"file":"wall.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/wall.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAK5C,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAmCpB,CAAA;AACD,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAA;AAE/C,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,UAAU,CAAA;AAErD,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;IACzC,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAED,KAAK,yBAAyB,GAAG;IAC/B,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;IACzC,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,gBAAgB,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;IACjD,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,gBAAgB,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAA;IACjD,sBAAsB,CAAC,EAAE,MAAM,CAAA;CAChC,CAAA;AAuBD,wBAAgB,+BAA+B,CAC7C,IAAI,EAAE,yBAAyB,EAC/B,IAAI,EAAE,eAAe,GACpB,uBAAuB,CAUzB;AAED,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,uBAAuB,GAAG,MAAM,CAKrF"}
@@ -2,17 +2,26 @@ import dedent from 'dedent';
2
2
  import { z } from 'zod';
3
3
  import { BaseNode, nodeType, objectId } from '../base';
4
4
  import { MaterialSchema } from '../material';
5
+ import { DoorNode } from './door';
5
6
  import { ItemNode } from './item';
6
- // import { DoorNode } from "./door";
7
- // import { ItemNode } from "./item";
8
- // import { WindowNode } from "./window";
7
+ import { WindowNode } from './window';
9
8
  export const WallNode = BaseNode.extend({
10
9
  id: objectId('wall'),
11
10
  type: nodeType('wall'),
12
- children: z.array(ItemNode.shape.id).default([]),
11
+ children: z
12
+ .array(z.union([ItemNode.shape.id, DoorNode.shape.id, WindowNode.shape.id]))
13
+ .default([]),
14
+ // Legacy single-material wall finish. Read for backward compatibility only.
13
15
  material: MaterialSchema.optional(),
16
+ // Legacy single-material wall finish preset. Read for backward compatibility only.
17
+ materialPreset: z.string().optional(),
18
+ interiorMaterial: MaterialSchema.optional(),
19
+ interiorMaterialPreset: z.string().optional(),
20
+ exteriorMaterial: MaterialSchema.optional(),
21
+ exteriorMaterialPreset: z.string().optional(),
14
22
  thickness: z.number().optional(),
15
23
  height: z.number().optional(),
24
+ curveOffset: z.number().optional(),
16
25
  // e.g., start/end points for path
17
26
  start: z.tuple([z.number(), z.number()]),
18
27
  end: z.tuple([z.number(), z.number()]),
@@ -23,9 +32,41 @@ export const WallNode = BaseNode.extend({
23
32
  Wall node - used to represent a wall in the building
24
33
  - thickness: thickness in meters
25
34
  - height: height in meters
35
+ - curveOffset: midpoint sagitta offset used to bend the wall into an arc
26
36
  - start: start point of the wall in level coordinate system
27
37
  - end: end point of the wall in level coordinate system
28
38
  - size: size of the wall in grid units
29
39
  - frontSide: whether the front side faces interior, exterior, or unknown
30
40
  - backSide: whether the back side faces interior, exterior, or unknown
31
41
  `);
42
+ function getConfiguredWallSurfaceMaterial(wall, side) {
43
+ if (side === 'interior') {
44
+ return {
45
+ material: wall.interiorMaterial,
46
+ materialPreset: wall.interiorMaterialPreset,
47
+ };
48
+ }
49
+ return {
50
+ material: wall.exteriorMaterial,
51
+ materialPreset: wall.exteriorMaterialPreset,
52
+ };
53
+ }
54
+ function hasSurfaceMaterial(spec) {
55
+ return spec.material !== undefined || typeof spec.materialPreset === 'string';
56
+ }
57
+ export function getEffectiveWallSurfaceMaterial(wall, side) {
58
+ const configured = getConfiguredWallSurfaceMaterial(wall, side);
59
+ if (hasSurfaceMaterial(configured)) {
60
+ return configured;
61
+ }
62
+ return {
63
+ material: wall.material,
64
+ materialPreset: wall.materialPreset,
65
+ };
66
+ }
67
+ export function getWallSurfaceMaterialSignature(spec) {
68
+ return JSON.stringify({
69
+ material: spec.material ?? null,
70
+ materialPreset: spec.materialPreset ?? null,
71
+ });
72
+ }
@@ -1,4 +1,17 @@
1
1
  import { z } from 'zod';
2
+ export declare const WindowType: z.ZodEnum<{
3
+ sliding: "sliding";
4
+ fixed: "fixed";
5
+ casement: "casement";
6
+ awning: "awning";
7
+ hopper: "hopper";
8
+ "single-hung": "single-hung";
9
+ "double-hung": "double-hung";
10
+ bay: "bay";
11
+ bow: "bow";
12
+ louvered: "louvered";
13
+ }>;
14
+ export type WindowType = z.infer<typeof WindowType>;
2
15
  export declare const WindowNode: z.ZodObject<{
3
16
  object: z.ZodDefault<z.ZodLiteral<"node">>;
4
17
  name: z.ZodOptional<z.ZodString>;
@@ -18,8 +31,8 @@ export declare const WindowNode: z.ZodObject<{
18
31
  id: z.ZodDefault<z.ZodTemplateLiteral<`window_${string}`>>;
19
32
  type: z.ZodDefault<z.ZodLiteral<"window">>;
20
33
  material: z.ZodOptional<z.ZodObject<{
34
+ id: z.ZodOptional<z.ZodString>;
21
35
  preset: z.ZodOptional<z.ZodEnum<{
22
- custom: "custom";
23
36
  white: "white";
24
37
  brick: "brick";
25
38
  concrete: "concrete";
@@ -29,6 +42,7 @@ export declare const WindowNode: z.ZodObject<{
29
42
  plaster: "plaster";
30
43
  tile: "tile";
31
44
  marble: "marble";
45
+ custom: "custom";
32
46
  }>>;
33
47
  properties: z.ZodOptional<z.ZodObject<{
34
48
  color: z.ZodDefault<z.ZodString>;
@@ -57,6 +71,48 @@ export declare const WindowNode: z.ZodObject<{
57
71
  wallId: z.ZodOptional<z.ZodString>;
58
72
  width: z.ZodDefault<z.ZodNumber>;
59
73
  height: z.ZodDefault<z.ZodNumber>;
74
+ openingKind: z.ZodDefault<z.ZodEnum<{
75
+ window: "window";
76
+ opening: "opening";
77
+ }>>;
78
+ windowType: z.ZodDefault<z.ZodEnum<{
79
+ sliding: "sliding";
80
+ fixed: "fixed";
81
+ casement: "casement";
82
+ awning: "awning";
83
+ hopper: "hopper";
84
+ "single-hung": "single-hung";
85
+ "double-hung": "double-hung";
86
+ bay: "bay";
87
+ bow: "bow";
88
+ louvered: "louvered";
89
+ }>>;
90
+ operationState: z.ZodDefault<z.ZodNumber>;
91
+ awningDirection: z.ZodDefault<z.ZodEnum<{
92
+ up: "up";
93
+ down: "down";
94
+ }>>;
95
+ casementStyle: z.ZodDefault<z.ZodEnum<{
96
+ french: "french";
97
+ single: "single";
98
+ }>>;
99
+ hingesSide: z.ZodDefault<z.ZodEnum<{
100
+ left: "left";
101
+ right: "right";
102
+ }>>;
103
+ openingShape: z.ZodDefault<z.ZodEnum<{
104
+ rectangle: "rectangle";
105
+ rounded: "rounded";
106
+ arch: "arch";
107
+ }>>;
108
+ openingRadiusMode: z.ZodDefault<z.ZodEnum<{
109
+ all: "all";
110
+ individual: "individual";
111
+ }>>;
112
+ openingCornerRadii: z.ZodDefault<z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber, z.ZodNumber], null>>;
113
+ cornerRadius: z.ZodDefault<z.ZodNumber>;
114
+ archHeight: z.ZodDefault<z.ZodNumber>;
115
+ openingRevealRadius: z.ZodDefault<z.ZodNumber>;
60
116
  frameThickness: z.ZodDefault<z.ZodNumber>;
61
117
  frameDepth: z.ZodDefault<z.ZodNumber>;
62
118
  columnRatios: z.ZodDefault<z.ZodArray<z.ZodNumber>>;
@@ -1 +1 @@
1
- {"version":3,"file":"window.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/window.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAwCrB,CAAA;AAEF,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAA"}
1
+ {"version":3,"file":"window.d.ts","sourceRoot":"","sources":["../../../src/schema/nodes/window.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,eAAO,MAAM,UAAU;;;;;;;;;;;EAWrB,CAAA;AACF,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAA;AAEnD,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA2DrB,CAAA;AAEF,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAA"}
@@ -2,6 +2,18 @@ import dedent from 'dedent';
2
2
  import { z } from 'zod';
3
3
  import { BaseNode, nodeType, objectId } from '../base';
4
4
  import { MaterialSchema } from '../material';
5
+ export const WindowType = z.enum([
6
+ 'fixed',
7
+ 'sliding',
8
+ 'casement',
9
+ 'awning',
10
+ 'hopper',
11
+ 'single-hung',
12
+ 'double-hung',
13
+ 'bay',
14
+ 'bow',
15
+ 'louvered',
16
+ ]);
5
17
  export const WindowNode = BaseNode.extend({
6
18
  id: objectId('window'),
7
19
  type: nodeType('window'),
@@ -14,6 +26,22 @@ export const WindowNode = BaseNode.extend({
14
26
  // Overall dimensions
15
27
  width: z.number().default(1.5),
16
28
  height: z.number().default(1.5),
29
+ // Opening mode - when set to "opening", the window is only a shaped cutout
30
+ openingKind: z.enum(['window', 'opening']).default('window'),
31
+ // Window family
32
+ windowType: WindowType.default('fixed'),
33
+ operationState: z.number().min(0).max(1).default(0),
34
+ awningDirection: z.enum(['up', 'down']).default('up'),
35
+ casementStyle: z.enum(['single', 'french']).default('single'),
36
+ hingesSide: z.enum(['left', 'right']).default('left'),
37
+ openingShape: z.enum(['rectangle', 'rounded', 'arch']).default('rectangle'),
38
+ openingRadiusMode: z.enum(['all', 'individual']).default('all'),
39
+ openingCornerRadii: z
40
+ .tuple([z.number(), z.number(), z.number(), z.number()])
41
+ .default([0.15, 0.15, 0.15, 0.15]),
42
+ cornerRadius: z.number().default(0.15),
43
+ archHeight: z.number().default(0.35),
44
+ openingRevealRadius: z.number().default(0.025),
17
45
  // Frame
18
46
  frameThickness: z.number().default(0.05),
19
47
  frameDepth: z.number().default(0.07),
@@ -32,6 +60,7 @@ export const WindowNode = BaseNode.extend({
32
60
  }).describe(dedent `Window node - a parametric window placed on a wall
33
61
  - position: center of the window in wall-local coordinate system
34
62
  - width/height: overall outer dimensions
63
+ - windowType: explicit window family, defaulting old windows to fixed
35
64
  - frameThickness: width of the frame members
36
65
  - frameDepth: how deep the frame sits within the wall
37
66
  - columnRatios/rowRatios: pane division ratios