@pascal-app/nodes 1.0.1 → 1.0.3

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 (319) hide show
  1. package/dist/block/definition.d.ts.map +1 -1
  2. package/dist/block/definition.js +4 -1
  3. package/dist/block/face-host.d.ts.map +1 -1
  4. package/dist/block/face-host.js +19 -2
  5. package/dist/block/hosted-edit.d.ts +13 -0
  6. package/dist/block/hosted-edit.d.ts.map +1 -0
  7. package/dist/block/hosted-edit.js +205 -0
  8. package/dist/block/last-operation.d.ts +1 -1
  9. package/dist/block/last-operation.d.ts.map +1 -1
  10. package/dist/block/last-operation.js +6 -4
  11. package/dist/block/modal-session.d.ts +2 -1
  12. package/dist/block/modal-session.d.ts.map +1 -1
  13. package/dist/block/modal-session.js +2 -2
  14. package/dist/block/selection.d.ts.map +1 -1
  15. package/dist/block/selection.js +82 -24
  16. package/dist/block/surface.d.ts +4 -0
  17. package/dist/block/surface.d.ts.map +1 -0
  18. package/dist/block/surface.js +54 -0
  19. package/dist/block/use-block-face-operation.d.ts +2 -2
  20. package/dist/block/use-block-face-operation.d.ts.map +1 -1
  21. package/dist/block/use-block-face-operation.js +25 -11
  22. package/dist/box-vent/definition.d.ts.map +1 -1
  23. package/dist/box-vent/definition.js +1 -0
  24. package/dist/building/renderer.d.ts.map +1 -1
  25. package/dist/building/renderer.js +1 -1
  26. package/dist/cabinet/definition.d.ts.map +1 -1
  27. package/dist/cabinet/definition.js +3 -1
  28. package/dist/cabinet/hosted-resize.d.ts +3 -6
  29. package/dist/cabinet/hosted-resize.d.ts.map +1 -1
  30. package/dist/cabinet/hosted-resize.js +9 -153
  31. package/dist/cabinet/placement-snap.d.ts.map +1 -1
  32. package/dist/cabinet/placement-snap.js +4 -2
  33. package/dist/cabinet/surfaces.d.ts +1 -0
  34. package/dist/cabinet/surfaces.d.ts.map +1 -1
  35. package/dist/cabinet/surfaces.js +13 -1
  36. package/dist/cabinet/tool.d.ts.map +1 -1
  37. package/dist/cabinet/tool.js +8 -4
  38. package/dist/ceiling/definition.d.ts.map +1 -1
  39. package/dist/ceiling/definition.js +5 -0
  40. package/dist/ceiling/renderer.d.ts.map +1 -1
  41. package/dist/ceiling/renderer.js +3 -2
  42. package/dist/chimney/definition.d.ts.map +1 -1
  43. package/dist/chimney/definition.js +1 -0
  44. package/dist/column/definition.d.ts.map +1 -1
  45. package/dist/column/definition.js +10 -3
  46. package/dist/column/floorplan-affordances.d.ts.map +1 -1
  47. package/dist/column/floorplan-affordances.js +6 -1
  48. package/dist/column/floorplan.d.ts.map +1 -1
  49. package/dist/column/floorplan.js +23 -11
  50. package/dist/column/hosted-resize.d.ts +116 -0
  51. package/dist/column/hosted-resize.d.ts.map +1 -0
  52. package/dist/column/hosted-resize.js +9 -0
  53. package/dist/column/panel.d.ts.map +1 -1
  54. package/dist/column/panel.js +6 -3
  55. package/dist/column/renderer.d.ts.map +1 -1
  56. package/dist/column/renderer.js +25 -103
  57. package/dist/column/shape.d.ts +22 -0
  58. package/dist/column/shape.d.ts.map +1 -0
  59. package/dist/column/shape.js +120 -0
  60. package/dist/column/surface.d.ts +4 -0
  61. package/dist/column/surface.d.ts.map +1 -0
  62. package/dist/column/surface.js +66 -0
  63. package/dist/cupola/definition.d.ts.map +1 -1
  64. package/dist/cupola/definition.js +1 -0
  65. package/dist/door/definition.d.ts.map +1 -1
  66. package/dist/door/definition.js +40 -1
  67. package/dist/door/door-math.d.ts +1 -1
  68. package/dist/door/door-math.d.ts.map +1 -1
  69. package/dist/door/door-math.js +7 -10
  70. package/dist/door/floorplan-affordances.d.ts.map +1 -1
  71. package/dist/door/floorplan-affordances.js +8 -12
  72. package/dist/door/move-tool.d.ts.map +1 -1
  73. package/dist/door/move-tool.js +3 -4
  74. package/dist/door/panel.d.ts.map +1 -1
  75. package/dist/door/panel.js +23 -52
  76. package/dist/door/tool.d.ts.map +1 -1
  77. package/dist/door/tool.js +20 -2
  78. package/dist/dormer/definition.d.ts.map +1 -1
  79. package/dist/dormer/definition.js +1 -0
  80. package/dist/downspout/definition.d.ts.map +1 -1
  81. package/dist/downspout/definition.js +1 -0
  82. package/dist/duct-segment/tool.d.ts.map +1 -1
  83. package/dist/duct-segment/tool.js +11 -0
  84. package/dist/duct-terminal/tool.d.ts.map +1 -1
  85. package/dist/duct-terminal/tool.js +77 -8
  86. package/dist/elevator/definition.d.ts.map +1 -1
  87. package/dist/elevator/definition.js +2 -0
  88. package/dist/elevator/parametrics.d.ts.map +1 -1
  89. package/dist/elevator/parametrics.js +98 -1
  90. package/dist/eyebrow-vent/definition.d.ts.map +1 -1
  91. package/dist/eyebrow-vent/definition.js +1 -0
  92. package/dist/fence/definition.d.ts.map +1 -1
  93. package/dist/fence/definition.js +1 -0
  94. package/dist/fence/tool.js +2 -2
  95. package/dist/guide/definition.d.ts.map +1 -1
  96. package/dist/guide/definition.js +1 -0
  97. package/dist/gutter/definition.d.ts.map +1 -1
  98. package/dist/gutter/definition.js +1 -0
  99. package/dist/hvac-equipment/tool.d.ts.map +1 -1
  100. package/dist/hvac-equipment/tool.js +8 -2
  101. package/dist/item/__fixtures__/main-floorplan.d.ts +26 -0
  102. package/dist/item/__fixtures__/main-floorplan.d.ts.map +1 -0
  103. package/dist/item/__fixtures__/main-floorplan.js +297 -0
  104. package/dist/item/definition.d.ts.map +1 -1
  105. package/dist/item/definition.js +3 -1
  106. package/dist/item/floorplan-move.d.ts.map +1 -1
  107. package/dist/item/floorplan-move.js +209 -130
  108. package/dist/item/floorplan.d.ts +22 -0
  109. package/dist/item/floorplan.d.ts.map +1 -1
  110. package/dist/item/floorplan.js +61 -2
  111. package/dist/item/move-tool.d.ts +1 -1
  112. package/dist/item/move-tool.d.ts.map +1 -1
  113. package/dist/item/move-tool.js +15 -7
  114. package/dist/item/renderer.d.ts.map +1 -1
  115. package/dist/item/renderer.js +8 -2
  116. package/dist/level/renderer.js +1 -1
  117. package/dist/lineset/tool.d.ts.map +1 -1
  118. package/dist/lineset/tool.js +1 -0
  119. package/dist/liquid-line/tool.d.ts.map +1 -1
  120. package/dist/liquid-line/tool.js +5 -1
  121. package/dist/measurement/definition.d.ts.map +1 -1
  122. package/dist/measurement/definition.js +1 -0
  123. package/dist/pipe-segment/tool.d.ts.map +1 -1
  124. package/dist/pipe-segment/tool.js +14 -3
  125. package/dist/pipe-trap/tool.d.ts.map +1 -1
  126. package/dist/pipe-trap/tool.js +7 -8
  127. package/dist/procedural-item/definition.d.ts.map +1 -1
  128. package/dist/procedural-item/definition.js +4 -1
  129. package/dist/ridge-vent/definition.d.ts.map +1 -1
  130. package/dist/ridge-vent/definition.js +1 -0
  131. package/dist/roof/definition.d.ts.map +1 -1
  132. package/dist/roof/definition.js +4 -1
  133. package/dist/roof/panel-model.d.ts +4 -0
  134. package/dist/roof/panel-model.d.ts.map +1 -0
  135. package/dist/roof/panel-model.js +151 -0
  136. package/dist/roof/panel.d.ts.map +1 -1
  137. package/dist/roof/panel.js +3 -4
  138. package/dist/roof/parametrics.d.ts.map +1 -1
  139. package/dist/roof/parametrics.js +16 -1
  140. package/dist/roof-segment/definition.d.ts.map +1 -1
  141. package/dist/roof-segment/definition.js +1 -0
  142. package/dist/roof-segment/parametrics.d.ts.map +1 -1
  143. package/dist/roof-segment/parametrics.js +176 -1
  144. package/dist/scan/definition.d.ts.map +1 -1
  145. package/dist/scan/definition.js +1 -0
  146. package/dist/shared/commit-opening-move.d.ts +4 -0
  147. package/dist/shared/commit-opening-move.d.ts.map +1 -0
  148. package/dist/shared/commit-opening-move.js +9 -0
  149. package/dist/shared/curtain-opening-limits.d.ts +14 -0
  150. package/dist/shared/curtain-opening-limits.d.ts.map +1 -0
  151. package/dist/shared/curtain-opening-limits.js +53 -0
  152. package/dist/shared/draft-axis-guides.d.ts +0 -6
  153. package/dist/shared/draft-axis-guides.d.ts.map +1 -1
  154. package/dist/shared/draft-axis-guides.js +1 -8
  155. package/dist/shared/hosted-resize.d.ts +12 -0
  156. package/dist/shared/hosted-resize.d.ts.map +1 -0
  157. package/dist/shared/hosted-resize.js +166 -0
  158. package/dist/shared/opening-grid-follow.d.ts +8 -0
  159. package/dist/shared/opening-grid-follow.d.ts.map +1 -0
  160. package/dist/shared/opening-grid-follow.js +12 -0
  161. package/dist/shared/opening-property-preview-host.d.ts +3 -0
  162. package/dist/shared/opening-property-preview-host.d.ts.map +1 -0
  163. package/dist/shared/opening-property-preview-host.js +21 -0
  164. package/dist/shared/opening-property-preview.d.ts +19 -0
  165. package/dist/shared/opening-property-preview.d.ts.map +1 -0
  166. package/dist/shared/opening-property-preview.js +99 -0
  167. package/dist/shared/resting-surface-plan.d.ts +2 -1
  168. package/dist/shared/resting-surface-plan.d.ts.map +1 -1
  169. package/dist/shared/resting-surface-plan.js +29 -4
  170. package/dist/shared/surface-counterparts.d.ts +12 -0
  171. package/dist/shared/surface-counterparts.d.ts.map +1 -0
  172. package/dist/shared/surface-counterparts.js +27 -0
  173. package/dist/shared/wall-attach-target.d.ts +1 -0
  174. package/dist/shared/wall-attach-target.d.ts.map +1 -1
  175. package/dist/shared/wall-attach-target.js +4 -1
  176. package/dist/shared/wall-event-from-grid.d.ts +5 -0
  177. package/dist/shared/wall-event-from-grid.d.ts.map +1 -0
  178. package/dist/shared/wall-event-from-grid.js +36 -0
  179. package/dist/shelf/definition.d.ts.map +1 -1
  180. package/dist/shelf/definition.js +3 -1
  181. package/dist/shelf/floorplan.d.ts.map +1 -1
  182. package/dist/shelf/floorplan.js +9 -2
  183. package/dist/site/renderer.d.ts.map +1 -1
  184. package/dist/site/renderer.js +9 -2
  185. package/dist/skylight/definition.d.ts.map +1 -1
  186. package/dist/skylight/definition.js +1 -0
  187. package/dist/slab/definition.d.ts.map +1 -1
  188. package/dist/slab/definition.js +4 -0
  189. package/dist/solar-panel/definition.d.ts.map +1 -1
  190. package/dist/solar-panel/definition.js +1 -0
  191. package/dist/spawn/definition.d.ts.map +1 -1
  192. package/dist/spawn/definition.js +1 -0
  193. package/dist/stair/definition.d.ts.map +1 -1
  194. package/dist/stair/definition.js +2 -0
  195. package/dist/stair/parametrics.d.ts.map +1 -1
  196. package/dist/stair/parametrics.js +164 -1
  197. package/dist/stair-segment/definition.d.ts.map +1 -1
  198. package/dist/stair-segment/definition.js +1 -0
  199. package/dist/stair-segment/parametrics.d.ts.map +1 -1
  200. package/dist/stair-segment/parametrics.js +81 -1
  201. package/dist/turbine-vent/definition.d.ts.map +1 -1
  202. package/dist/turbine-vent/definition.js +1 -0
  203. package/dist/wall/actions.d.ts +3 -0
  204. package/dist/wall/actions.d.ts.map +1 -0
  205. package/dist/wall/actions.js +56 -0
  206. package/dist/wall/curtain-opening-frame.d.ts +14 -0
  207. package/dist/wall/curtain-opening-frame.d.ts.map +1 -0
  208. package/dist/wall/curtain-opening-frame.js +111 -0
  209. package/dist/wall/curtain-panel-highlight.d.ts +3 -0
  210. package/dist/wall/curtain-panel-highlight.d.ts.map +1 -0
  211. package/dist/wall/curtain-panel-highlight.js +113 -0
  212. package/dist/wall/curtain-wall-adapter.d.ts +3 -0
  213. package/dist/wall/curtain-wall-adapter.d.ts.map +1 -0
  214. package/dist/wall/curtain-wall-adapter.js +55 -0
  215. package/dist/wall/curtain-wall-floorplan.d.ts +3 -0
  216. package/dist/wall/curtain-wall-floorplan.d.ts.map +1 -0
  217. package/dist/wall/curtain-wall-floorplan.js +91 -0
  218. package/dist/wall/curtain-wall-geometry.d.ts +4 -0
  219. package/dist/wall/curtain-wall-geometry.d.ts.map +1 -0
  220. package/dist/wall/curtain-wall-geometry.js +226 -0
  221. package/dist/wall/curtain-wall-layout.d.ts +16 -0
  222. package/dist/wall/curtain-wall-layout.d.ts.map +1 -0
  223. package/dist/wall/curtain-wall-layout.js +176 -0
  224. package/dist/wall/curtain-wall-materials.d.ts +5 -0
  225. package/dist/wall/curtain-wall-materials.d.ts.map +1 -0
  226. package/dist/wall/curtain-wall-materials.js +55 -0
  227. package/dist/wall/curtain-wall-panel.d.ts +14 -0
  228. package/dist/wall/curtain-wall-panel.d.ts.map +1 -0
  229. package/dist/wall/curtain-wall-panel.js +167 -0
  230. package/dist/wall/curtain-wall-piece-geometry.d.ts +5 -0
  231. package/dist/wall/curtain-wall-piece-geometry.d.ts.map +1 -0
  232. package/dist/wall/curtain-wall-piece-geometry.js +220 -0
  233. package/dist/wall/curtain-wall-shadow.d.ts +4 -0
  234. package/dist/wall/curtain-wall-shadow.d.ts.map +1 -0
  235. package/dist/wall/curtain-wall-shadow.js +15 -0
  236. package/dist/wall/definition.d.ts +0 -15
  237. package/dist/wall/definition.d.ts.map +1 -1
  238. package/dist/wall/definition.js +65 -4
  239. package/dist/wall/drawing-mode.d.ts +12 -0
  240. package/dist/wall/drawing-mode.d.ts.map +1 -0
  241. package/dist/wall/drawing-mode.js +38 -0
  242. package/dist/wall/floorplan-tool.d.ts +4 -0
  243. package/dist/wall/floorplan-tool.d.ts.map +1 -0
  244. package/dist/wall/floorplan-tool.js +107 -0
  245. package/dist/wall/floorplan.d.ts.map +1 -1
  246. package/dist/wall/floorplan.js +6 -2
  247. package/dist/wall/length-patch.d.ts +3 -0
  248. package/dist/wall/length-patch.d.ts.map +1 -0
  249. package/dist/wall/length-patch.js +14 -0
  250. package/dist/wall/move-tool.d.ts.map +1 -1
  251. package/dist/wall/move-tool.js +23 -1
  252. package/dist/wall/paint.d.ts.map +1 -1
  253. package/dist/wall/paint.js +39 -4
  254. package/dist/wall/panel-model.d.ts +4 -0
  255. package/dist/wall/panel-model.d.ts.map +1 -0
  256. package/dist/wall/panel-model.js +117 -0
  257. package/dist/wall/panel.d.ts.map +1 -1
  258. package/dist/wall/panel.js +20 -24
  259. package/dist/wall/property-preview.d.ts +7 -0
  260. package/dist/wall/property-preview.d.ts.map +1 -0
  261. package/dist/wall/property-preview.js +31 -0
  262. package/dist/wall/rectangle-command.d.ts +149 -0
  263. package/dist/wall/rectangle-command.d.ts.map +1 -0
  264. package/dist/wall/rectangle-command.js +22 -0
  265. package/dist/wall/rectangle-tool.d.ts +2 -0
  266. package/dist/wall/rectangle-tool.d.ts.map +1 -0
  267. package/dist/wall/rectangle-tool.js +147 -0
  268. package/dist/wall/renderer.d.ts.map +1 -1
  269. package/dist/wall/renderer.js +7 -4
  270. package/dist/wall/slots.d.ts +2 -2
  271. package/dist/wall/slots.d.ts.map +1 -1
  272. package/dist/wall/slots.js +10 -2
  273. package/dist/wall/split-floorplan-layer.d.ts +4 -0
  274. package/dist/wall/split-floorplan-layer.d.ts.map +1 -0
  275. package/dist/wall/split-floorplan-layer.js +71 -0
  276. package/dist/wall/split-pointer.d.ts +3 -0
  277. package/dist/wall/split-pointer.d.ts.map +1 -0
  278. package/dist/wall/split-pointer.js +95 -0
  279. package/dist/wall/split-preview.d.ts +55 -0
  280. package/dist/wall/split-preview.d.ts.map +1 -0
  281. package/dist/wall/split-preview.js +106 -0
  282. package/dist/wall/split-session.d.ts +16 -0
  283. package/dist/wall/split-session.d.ts.map +1 -0
  284. package/dist/wall/split-session.js +138 -0
  285. package/dist/wall/split-store.d.ts +16 -0
  286. package/dist/wall/split-store.d.ts.map +1 -0
  287. package/dist/wall/split-store.js +6 -0
  288. package/dist/wall/split-tool.d.ts +10 -0
  289. package/dist/wall/split-tool.d.ts.map +1 -0
  290. package/dist/wall/split-tool.js +95 -0
  291. package/dist/wall/system.d.ts.map +1 -1
  292. package/dist/wall/system.js +3 -1
  293. package/dist/wall/tool.d.ts.map +1 -1
  294. package/dist/wall/tool.js +14 -6
  295. package/dist/wall/wall-batch-system.d.ts.map +1 -1
  296. package/dist/wall/wall-batch-system.js +3 -0
  297. package/dist/window/definition.d.ts.map +1 -1
  298. package/dist/window/definition.js +48 -1
  299. package/dist/window/floorplan-affordances.d.ts.map +1 -1
  300. package/dist/window/floorplan-affordances.js +8 -10
  301. package/dist/window/move-tool.d.ts.map +1 -1
  302. package/dist/window/move-tool.js +4 -6
  303. package/dist/window/panel.d.ts.map +1 -1
  304. package/dist/window/panel.js +21 -59
  305. package/dist/window/tool.d.ts.map +1 -1
  306. package/dist/window/tool.js +34 -2
  307. package/dist/window/window-math.d.ts +1 -1
  308. package/dist/window/window-math.d.ts.map +1 -1
  309. package/dist/window/window-math.js +8 -11
  310. package/dist/zone/definition.d.ts.map +1 -1
  311. package/dist/zone/definition.js +1 -0
  312. package/dist/zone/quantities-panel.d.ts.map +1 -1
  313. package/dist/zone/quantities-panel.js +3 -19
  314. package/dist/zone/renderer.d.ts.map +1 -1
  315. package/dist/zone/renderer.js +1 -1
  316. package/package.json +8 -8
  317. package/dist/shared/opening-documentation-fields.d.ts +0 -16
  318. package/dist/shared/opening-documentation-fields.d.ts.map +0 -1
  319. package/dist/shared/opening-documentation-fields.js +0 -54
@@ -30,6 +30,7 @@ export const scanDefinition = {
30
30
  presettable: false,
31
31
  },
32
32
  parametrics: scanParametrics,
33
+ rendersChildren: false,
33
34
  renderer: {
34
35
  kind: 'parametric',
35
36
  module: () => import('./renderer'),
@@ -0,0 +1,4 @@
1
+ import { type AnyNodeId, type DoorNode, type WindowNode } from '@pascal-app/core';
2
+ /** A move changes placement, not persistent ownership (Array, assets, etc.). */
3
+ export declare function commitOpeningMove(id: AnyNodeId, patch: Partial<DoorNode | WindowNode>): void;
4
+ //# sourceMappingURL=commit-opening-move.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commit-opening-move.d.ts","sourceRoot":"","sources":["../../src/shared/commit-opening-move.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,QAAQ,EAAY,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE3F,gFAAgF;AAChF,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,QAAQ,GAAG,UAAU,CAAC,QAKrF"}
@@ -0,0 +1,9 @@
1
+ import { useScene } from '@pascal-app/core';
2
+ /** A move changes placement, not persistent ownership (Array, assets, etc.). */
3
+ export function commitOpeningMove(id, patch) {
4
+ const node = useScene.getState().nodes[id];
5
+ if (!node || (node.type !== 'window' && node.type !== 'door'))
6
+ return;
7
+ const { isNew: _new, isTransient: _transient, ...metadata } = node.metadata;
8
+ useScene.getState().updateNode(id, { ...patch, metadata });
9
+ }
@@ -0,0 +1,14 @@
1
+ import { type AnyNode, type AnyNodeId, type DoorNode, type WindowNode } from '@pascal-app/core';
2
+ type Opening = DoorNode | WindowNode;
3
+ export declare function curtainOpeningResizeMax(opening: Opening, nodes: Readonly<Record<AnyNodeId, AnyNode>>, axis: 'x' | 'y', sign: number): number | undefined;
4
+ export declare function curtainOpeningLimits(opening: Opening, nodes: Readonly<Record<AnyNodeId, AnyNode>>): {
5
+ margin: number;
6
+ length: number;
7
+ top: number;
8
+ bottom: number;
9
+ width: number;
10
+ height: number;
11
+ } | null;
12
+ export declare function constrainCurtainOpening<T extends Opening>(opening: T, patch: Partial<T>, nodes: Readonly<Record<AnyNodeId, AnyNode>>): Partial<T>;
13
+ export {};
14
+ //# sourceMappingURL=curtain-opening-limits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"curtain-opening-limits.d.ts","sourceRoot":"","sources":["../../src/shared/curtain-opening-limits.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,SAAS,EACd,KAAK,QAAQ,EAGb,KAAK,UAAU,EAChB,MAAM,kBAAkB,CAAA;AAGzB,KAAK,OAAO,GAAG,QAAQ,GAAG,UAAU,CAAA;AAEpC,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,EAC3C,IAAI,EAAE,GAAG,GAAG,GAAG,EACf,IAAI,EAAE,MAAM,sBAcb;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;;;;;;;SAwB5C;AAED,wBAAgB,uBAAuB,CAAC,CAAC,SAAS,OAAO,EACvD,OAAO,EAAE,CAAC,EACV,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,EACjB,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,GAC1C,OAAO,CAAC,CAAC,CAAC,CAsBZ"}
@@ -0,0 +1,53 @@
1
+ import { getCurtainWallConfig, getWallCurveLength, } from '@pascal-app/core';
2
+ import { resolveWallOpeningCeiling } from './wall-opening-ceiling';
3
+ export function curtainOpeningResizeMax(opening, nodes, axis, sign) {
4
+ const limits = curtainOpeningLimits(opening, nodes);
5
+ if (!limits)
6
+ return undefined;
7
+ if (axis === 'y') {
8
+ const anchor = opening.position[1] - (sign * opening.height) / 2;
9
+ return Math.max(0, sign > 0 ? limits.top - anchor : anchor - limits.bottom);
10
+ }
11
+ const direction = Math.cos(opening.rotation[1]) >= 0 ? sign : -sign;
12
+ const anchor = opening.position[0] - (direction * opening.width) / 2;
13
+ return Math.max(0, direction > 0 ? limits.length - limits.margin - anchor : anchor - limits.margin);
14
+ }
15
+ export function curtainOpeningLimits(opening, nodes) {
16
+ const wall = nodes[(opening.parentId ?? opening.wallId)];
17
+ if (wall?.type !== 'wall' || wall.wallType !== 'curtain')
18
+ return null;
19
+ const margin = getCurtainWallConfig(wall).perimeterWidth;
20
+ const length = getWallCurveLength(wall);
21
+ const top = resolveWallOpeningCeiling(wall, nodes) - margin;
22
+ const bottom = opening.type === 'door' ? 0 : margin;
23
+ return {
24
+ margin,
25
+ length,
26
+ top,
27
+ bottom,
28
+ width: Math.max(0, 2 * Math.min(opening.position[0] - margin, length - margin - opening.position[0])),
29
+ height: Math.max(0, opening.type === 'door'
30
+ ? top
31
+ : 2 * Math.min(opening.position[1] - bottom, top - opening.position[1])),
32
+ };
33
+ }
34
+ export function constrainCurtainOpening(opening, patch, nodes) {
35
+ const limits = curtainOpeningLimits(opening, nodes);
36
+ if (!limits || !('width' in patch || 'height' in patch || 'position' in patch))
37
+ return patch;
38
+ const next = { ...opening, ...patch };
39
+ const moving = patch.position !== undefined && patch.width === undefined && patch.height === undefined;
40
+ const availableWidth = Math.max(0, limits.length - 2 * limits.margin);
41
+ const availableHeight = Math.max(0, limits.top - limits.bottom);
42
+ const widthLimit = moving || limits.width < 0.01 ? availableWidth : limits.width;
43
+ const heightLimit = moving || limits.height < 0.01 ? availableHeight : limits.height;
44
+ const width = Math.min(Math.max(0.01, next.width), widthLimit);
45
+ const height = Math.min(Math.max(0.01, next.height), heightLimit);
46
+ if (width < 0.01 || height < 0.01)
47
+ return {};
48
+ const x = Math.max(limits.margin + width / 2, Math.min(limits.length - limits.margin - width / 2, next.position[0]));
49
+ const y = opening.type === 'door'
50
+ ? height / 2
51
+ : Math.max(limits.bottom + height / 2, Math.min(limits.top - height / 2, next.position[1]));
52
+ return { ...patch, width, height, position: [x, y, next.position[2]] };
53
+ }
@@ -27,10 +27,4 @@ export declare function DraftAngleArc({ arc, color }: {
27
27
  arc: DraftAngleLabel['arc'];
28
28
  color: string;
29
29
  }): import("react").JSX.Element;
30
- export declare function DraftMeasurementLabel({ color, label, position, shadowColor, }: {
31
- color: string;
32
- label: string;
33
- position: [number, number, number];
34
- shadowColor: string;
35
- }): import("react").JSX.Element;
36
30
  //# sourceMappingURL=draft-axis-guides.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"draft-axis-guides.d.ts","sourceRoot":"","sources":["../../src/shared/draft-axis-guides.tsx"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,aAAa,EACnB,MAAM,oBAAoB,CAAA;AA6B3B,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAClC,GAAG,EAAE;QACH,MAAM,EAAE,aAAa,CAAA;QACrB,MAAM,EAAE,MAAM,CAAA;QACd,UAAU,EAAE,MAAM,CAAA;QAClB,QAAQ,EAAE,MAAM,CAAA;QAChB,CAAC,EAAE,MAAM,CAAA;KACV,CAAA;CACF,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,aAAa,CAAA;IACrB,SAAS,EAAE,aAAa,GAAG,IAAI,CAAA;IAC/B,CAAC,EAAE,MAAM,CAAA;IACT,UAAU,EAAE,eAAe,GAAG,IAAI,CAAA;CACnC,GAAG,IAAI,CAAA;AAeR,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,aAAa,EACpB,GAAG,EAAE,aAAa,EAClB,CAAC,EAAE,MAAM,GACR,eAAe,GAAG,IAAI,CAyCxB;AAED,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,UAAU,EACV,gBAAgB,GACjB,EAAE;IACD,KAAK,EAAE,mBAAmB,CAAA;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,gBAAgB,EAAE,MAAM,CAAA;CACzB,sCA2CA;AAoBD,wBAAgB,aAAa,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE;IAAE,GAAG,EAAE,eAAe,CAAC,KAAK,CAAC,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,+BAkC3F;AAED,wBAAgB,qBAAqB,CAAC,EACpC,KAAK,EACL,KAAK,EACL,QAAQ,EACR,WAAW,GACZ,EAAE;IACD,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAClC,WAAW,EAAE,MAAM,CAAA;CACpB,+BAmBA"}
1
+ {"version":3,"file":"draft-axis-guides.d.ts","sourceRoot":"","sources":["../../src/shared/draft-axis-guides.tsx"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,aAAa,EACnB,MAAM,oBAAoB,CAAA;AA4B3B,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAClC,GAAG,EAAE;QACH,MAAM,EAAE,aAAa,CAAA;QACrB,MAAM,EAAE,MAAM,CAAA;QACd,UAAU,EAAE,MAAM,CAAA;QAClB,QAAQ,EAAE,MAAM,CAAA;QAChB,CAAC,EAAE,MAAM,CAAA;KACV,CAAA;CACF,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,aAAa,CAAA;IACrB,SAAS,EAAE,aAAa,GAAG,IAAI,CAAA;IAC/B,CAAC,EAAE,MAAM,CAAA;IACT,UAAU,EAAE,eAAe,GAAG,IAAI,CAAA;CACnC,GAAG,IAAI,CAAA;AAeR,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,aAAa,EACpB,GAAG,EAAE,aAAa,EAClB,CAAC,EAAE,MAAM,GACR,eAAe,GAAG,IAAI,CAyCxB;AAED,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,UAAU,EACV,gBAAgB,GACjB,EAAE;IACD,KAAK,EAAE,mBAAmB,CAAA;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,gBAAgB,EAAE,MAAM,CAAA;CACzB,sCA2CA;AAoBD,wBAAgB,aAAa,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE;IAAE,GAAG,EAAE,eAAe,CAAC,KAAK,CAAC,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,+BAkC3F"}
@@ -1,6 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { EDITOR_LAYER, formatAngleRadians, getAngleArcToSegmentReference, getAngleToSegmentReference, } from '@pascal-app/editor';
3
- import { Html } from '@react-three/drei';
2
+ import { DraftMeasurementLabel, EDITOR_LAYER, formatAngleRadians, getAngleArcToSegmentReference, getAngleToSegmentReference, } from '@pascal-app/editor';
4
3
  import { useMemo } from 'react';
5
4
  import { BufferGeometry, Vector3 } from 'three';
6
5
  /**
@@ -99,9 +98,3 @@ export function DraftAngleArc({ arc, color }) {
99
98
  }, [arc]);
100
99
  return (_jsx("line", { frustumCulled: false, geometry: geometry, layers: EDITOR_LAYER, renderOrder: 2, children: _jsx("lineBasicNodeMaterial", { color: color, depthTest: false, depthWrite: false, linewidth: 2, opacity: 0.95, transparent: true }) }));
101
100
  }
102
- export function DraftMeasurementLabel({ color, label, position, shadowColor, }) {
103
- return (_jsx(Html, { center: true, position: position, style: { pointerEvents: 'none', userSelect: 'none' }, zIndexRange: [100, 0], children: _jsx("div", { className: "whitespace-nowrap font-bold font-mono text-[15px]", style: {
104
- color,
105
- textShadow: `-1.5px -1.5px 0 ${shadowColor}, 1.5px -1.5px 0 ${shadowColor}, -1.5px 1.5px 0 ${shadowColor}, 1.5px 1.5px 0 ${shadowColor}, 0 0 4px ${shadowColor}, 0 0 4px ${shadowColor}`,
106
- }, children: label }) }));
107
- }
@@ -0,0 +1,12 @@
1
+ import { type AnyNode, type AnyNodeId, type HandleDescriptor, type SceneApi } from '@pascal-app/core';
2
+ export type HostedEditPolicy = {
3
+ host: (node: AnyNode) => boolean;
4
+ child: (node: AnyNode) => boolean;
5
+ };
6
+ type Nodes = Record<AnyNodeId, AnyNode>;
7
+ export type HostedUpdate = readonly [AnyNodeId, Partial<AnyNode>];
8
+ export declare function hostedChildUpdates(before: Nodes, after: Nodes, policy: HostedEditPolicy): HostedUpdate[] | null;
9
+ export declare function planHostedEdit(sceneApi: SceneApi, apply: (staged: SceneApi) => void, policy: HostedEditPolicy): HostedUpdate[] | null;
10
+ export declare function withHostedChildren<N extends AnyNode>(descriptor: HandleDescriptor<N>, policy: HostedEditPolicy): HandleDescriptor<N>;
11
+ export {};
12
+ //# sourceMappingURL=hosted-resize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hosted-resize.d.ts","sourceRoot":"","sources":["../../src/shared/hosted-resize.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,SAAS,EAGd,KAAK,gBAAgB,EAGrB,KAAK,QAAQ,EAEd,MAAM,kBAAkB,CAAA;AAGzB,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAA;IAChC,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,OAAO,CAAA;CAClC,CAAA;AAED,KAAK,KAAK,GAAG,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;AACvC,MAAM,MAAM,YAAY,GAAG,SAAS,CAAC,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAA;AASjE,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,KAAK,EACb,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,gBAAgB,GACvB,YAAY,EAAE,GAAG,IAAI,CA4EvB;AAED,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,CAAC,MAAM,EAAE,QAAQ,KAAK,IAAI,EACjC,MAAM,EAAE,gBAAgB,GACvB,YAAY,EAAE,GAAG,IAAI,CA8BvB;AAED,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,OAAO,EAClD,UAAU,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAC/B,MAAM,EAAE,gBAAgB,GACvB,gBAAgB,CAAC,CAAC,CAAC,CA6DrB"}
@@ -0,0 +1,166 @@
1
+ import { getScaledDimensions, getSurfaceProvider, nodeRegistry, surfaceRegionContainsFootprint, } from '@pascal-app/core';
2
+ import { boundsOf, boxCorners, frame, transformPoint } from '@pascal-app/core/procedural-items';
3
+ function surfaceScene(nodes) {
4
+ return {
5
+ nodes: () => nodes,
6
+ get: (id) => nodes[id],
7
+ };
8
+ }
9
+ export function hostedChildUpdates(before, after, policy) {
10
+ const updates = [];
11
+ for (const host of Object.values(before)) {
12
+ if (!policy.host(host))
13
+ continue;
14
+ const children = (host.children ?? [])
15
+ .map((id) => before[id])
16
+ .filter((child) => child?.parentId === host.id && policy.child(child));
17
+ if (!children.length)
18
+ continue;
19
+ const nextHost = after[host.id];
20
+ if (!nextHost || !policy.host(nextHost))
21
+ return null;
22
+ const provider = getSurfaceProvider(host);
23
+ const nextSurfaces = provider.surfaces?.(nextHost, { scene: surfaceScene(after) }) ?? [];
24
+ if (JSON.stringify(provider.surfaces?.(host, { scene: surfaceScene(before) })) ===
25
+ JSON.stringify(nextSurfaces))
26
+ continue;
27
+ for (const child of children) {
28
+ if (!child || !('position' in child) || !('rotation' in child))
29
+ continue;
30
+ const bounds = child.type === 'item'
31
+ ? { size: getScaledDimensions(child), center: undefined }
32
+ : nodeRegistry.get(child.type)?.capabilities.dragBounds?.(child, before);
33
+ if (!bounds)
34
+ continue;
35
+ const center = bounds.center ?? [0, bounds.size[1] / 2, 0];
36
+ const localBounds = {
37
+ min: center.map((v, i) => v - bounds.size[i] / 2),
38
+ max: center.map((v, i) => v + bounds.size[i] / 2),
39
+ };
40
+ const position = child.position;
41
+ const rotation = (typeof child.rotation === 'number' ? [0, child.rotation, 0] : child.rotation);
42
+ const projected = boundsOf(boxCorners(localBounds.min, localBounds.max).map((p) => transformPoint(frame(position, rotation), p)));
43
+ const hit = {
44
+ point: [
45
+ (projected.min[0] + projected.max[0]) / 2,
46
+ projected.min[1],
47
+ (projected.min[2] + projected.max[2]) / 2,
48
+ ],
49
+ normalWorldY: 1,
50
+ };
51
+ const previousSurface = provider.resolveHit(host, hit, { scene: surfaceScene(before) });
52
+ if (!previousSurface || Math.abs(previousSurface.position[1] - projected.min[1]) > 1e-5)
53
+ continue;
54
+ const nextSurface = nextSurfaces.find((surface) => surface.id === previousSurface.id);
55
+ if (!nextSurface)
56
+ return null;
57
+ const nextPosition = [
58
+ position[0],
59
+ position[1] + nextSurface.position[1] - previousSurface.position[1],
60
+ position[2],
61
+ ];
62
+ const surfaceLocal = [
63
+ nextPosition[0] - nextSurface.position[0],
64
+ nextPosition[1] - nextSurface.position[1],
65
+ nextPosition[2] - nextSurface.position[2],
66
+ ];
67
+ if (!surfaceRegionContainsFootprint(nextSurface.region, surfaceLocal, bounds.size, rotation, localBounds))
68
+ return null;
69
+ if (Math.abs(nextPosition[1] - position[1]) > 1e-8)
70
+ updates.push([child.id, { position: nextPosition }]);
71
+ }
72
+ }
73
+ return updates;
74
+ }
75
+ export function planHostedEdit(sceneApi, apply, policy) {
76
+ const before = sceneApi.nodes();
77
+ const after = { ...before };
78
+ const updates = new Map();
79
+ let supported = true;
80
+ const staged = {
81
+ ...sceneApi,
82
+ ...surfaceScene(after),
83
+ update(id, data) {
84
+ if (!after[id])
85
+ return;
86
+ after[id] = { ...after[id], ...data };
87
+ updates.set(id, { ...updates.get(id), ...data });
88
+ },
89
+ upsert(node) {
90
+ supported = false;
91
+ return node.id;
92
+ },
93
+ delete() {
94
+ supported = false;
95
+ },
96
+ markDirty() { },
97
+ pauseHistory() { },
98
+ resumeHistory() { },
99
+ };
100
+ apply(staged);
101
+ if (!supported)
102
+ return null;
103
+ const children = hostedChildUpdates(before, after, policy);
104
+ if (!children)
105
+ return null;
106
+ for (const [id, data] of children)
107
+ updates.set(id, data);
108
+ return [...updates];
109
+ }
110
+ export function withHostedChildren(descriptor, policy) {
111
+ if (descriptor.kind === 'radial-resize')
112
+ return {
113
+ ...descriptor,
114
+ apply(node, value, scene) {
115
+ const patch = descriptor.apply(node, value, scene);
116
+ if (planHostedEdit(scene, (staged) => staged.update(node.id, patch), policy))
117
+ return patch;
118
+ return Object.fromEntries(Object.keys(patch).map((key) => [key, node[key]]));
119
+ },
120
+ };
121
+ if (descriptor.kind !== 'linear-resize')
122
+ return descriptor;
123
+ const plan = (node, patch, sceneApi, modifiers) => planHostedEdit(sceneApi, (staged) => {
124
+ if (descriptor.commit)
125
+ descriptor.commit(node, patch, staged, modifiers);
126
+ else
127
+ staged.update(descriptor.overrideTarget?.(node, staged) ?? node.id, patch);
128
+ }, policy);
129
+ const hasHostedChildren = (scene) => Object.values(scene?.nodes() ?? {}).some((node) => policy.host(node) &&
130
+ (node.children ?? []).some((id) => {
131
+ const child = scene.get(id);
132
+ return child && policy.child(child);
133
+ }));
134
+ return {
135
+ ...descriptor,
136
+ apply(node, value, sceneApi, modifiers) {
137
+ const patch = descriptor.apply(node, value, sceneApi, modifiers);
138
+ if (!hasHostedChildren(sceneApi) || plan(node, patch, sceneApi, modifiers))
139
+ return patch;
140
+ const target = sceneApi.get(descriptor.overrideTarget?.(node, sceneApi) ?? node.id) ?? node;
141
+ return Object.fromEntries(Object.keys(patch).map((key) => [key, target[key]]));
142
+ },
143
+ previewOverrides(node, value, sceneApi, modifiers) {
144
+ if (!hasHostedChildren(sceneApi))
145
+ return descriptor.previewOverrides?.(node, value, sceneApi, modifiers) ?? [];
146
+ const patch = descriptor.apply(node, value, sceneApi, modifiers);
147
+ return plan(node, patch, sceneApi, modifiers) ?? [];
148
+ },
149
+ commit(node, patch, sceneApi, modifiers) {
150
+ if (!hasHostedChildren(sceneApi)) {
151
+ if (descriptor.commit)
152
+ descriptor.commit(node, patch, sceneApi, modifiers);
153
+ else
154
+ sceneApi.update(descriptor.overrideTarget?.(node, sceneApi) ?? node.id, patch);
155
+ return;
156
+ }
157
+ const updates = plan(node, patch, sceneApi, modifiers);
158
+ if (!updates)
159
+ return;
160
+ for (const [id, data] of updates) {
161
+ sceneApi.update(id, data);
162
+ sceneApi.markDirty(id);
163
+ }
164
+ },
165
+ };
166
+ }
@@ -0,0 +1,8 @@
1
+ export declare function shouldFollowOpeningGrid(args: {
2
+ eventTime: number;
3
+ hasActiveHost: boolean;
4
+ lastHostEventTime: number;
5
+ pointerType?: string;
6
+ }): boolean;
7
+ export declare function shouldHandleOpeningHostLeave(nativeEvent: unknown): boolean;
8
+ //# sourceMappingURL=opening-grid-follow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opening-grid-follow.d.ts","sourceRoot":"","sources":["../../src/shared/opening-grid-follow.ts"],"names":[],"mappings":"AAAA,wBAAgB,uBAAuB,CAAC,IAAI,EAAE;IAC5C,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,OAAO,CAAA;IACtB,iBAAiB,EAAE,MAAM,CAAA;IACzB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,GAAG,OAAO,CAGV;AAED,wBAAgB,4BAA4B,CAAC,WAAW,EAAE,OAAO,GAAG,OAAO,CAS1E"}
@@ -0,0 +1,12 @@
1
+ export function shouldFollowOpeningGrid(args) {
2
+ if (args.pointerType === 'xr' && args.hasActiveHost)
3
+ return false;
4
+ return args.eventTime !== args.lastHostEventTime;
5
+ }
6
+ export function shouldHandleOpeningHostLeave(nativeEvent) {
7
+ if (!nativeEvent || typeof nativeEvent !== 'object')
8
+ return true;
9
+ const event = nativeEvent;
10
+ const isSpatialPointer = event.inputSource != null || event.pointerState?.inputSource != null;
11
+ return !isSpatialPointer || event.openingHoverBridge === true;
12
+ }
@@ -0,0 +1,3 @@
1
+ import type { OpeningPropertyPreviewDependencies } from './opening-property-preview';
2
+ export declare const openingPropertyPreviewHost: OpeningPropertyPreviewDependencies;
3
+ //# sourceMappingURL=opening-property-preview-host.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opening-property-preview-host.d.ts","sourceRoot":"","sources":["../../src/shared/opening-property-preview-host.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kCAAkC,EAAE,MAAM,4BAA4B,CAAA;AAEpF,eAAO,MAAM,0BAA0B,EAAE,kCAiBxC,CAAA"}
@@ -0,0 +1,21 @@
1
+ import { useLiveNodeOverrides, useScene } from '@pascal-app/core';
2
+ export const openingPropertyPreviewHost = {
3
+ nodes: () => useScene.getState().nodes,
4
+ override: (id) => useLiveNodeOverrides.getState().get(id),
5
+ setOverride: (id, patch) => useLiveNodeOverrides.getState().set(id, patch),
6
+ clearOverrideFields: (id, fields) => useLiveNodeOverrides.getState().clearFields(id, fields),
7
+ markDirty: (id) => useScene.getState().markDirty(id),
8
+ updateNode: (id, patch) => useScene.getState().updateNode(id, patch),
9
+ scheduleFrame: (callback) => {
10
+ if (typeof requestAnimationFrame === 'function')
11
+ return requestAnimationFrame(callback);
12
+ callback(0);
13
+ return 0;
14
+ },
15
+ cancelFrame: (handle) => {
16
+ if (typeof cancelAnimationFrame === 'function')
17
+ cancelAnimationFrame(handle);
18
+ },
19
+ scheduleDelay: (callback, delay) => setTimeout(callback, delay),
20
+ cancelDelay: (handle) => clearTimeout(handle),
21
+ };
@@ -0,0 +1,19 @@
1
+ import type { AnyNode, AnyNodeId, DoorNode, WindowNode } from '@pascal-app/core';
2
+ export type OpeningPropertyPreviewDependencies = {
3
+ nodes: () => Readonly<Record<AnyNodeId, AnyNode>>;
4
+ override: (id: AnyNodeId) => Partial<AnyNode> | undefined;
5
+ setOverride: (id: AnyNodeId, patch: Partial<AnyNode>) => void;
6
+ clearOverrideFields: (id: AnyNodeId, fields: string[]) => void;
7
+ markDirty: (id: AnyNodeId) => void;
8
+ updateNode: (id: AnyNodeId, patch: Partial<AnyNode>) => void;
9
+ scheduleFrame: (callback: FrameRequestCallback) => number;
10
+ cancelFrame: (handle: number) => void;
11
+ scheduleDelay: (callback: () => void, delay: number) => number;
12
+ cancelDelay: (handle: number) => void;
13
+ };
14
+ export declare function createOpeningPropertyPreview<T extends DoorNode | WindowNode>(id: AnyNodeId, dependencies: OpeningPropertyPreviewDependencies): {
15
+ preview(patch: Partial<T>): void;
16
+ commit(patch?: Partial<T>): void;
17
+ cancel: () => void;
18
+ };
19
+ //# sourceMappingURL=opening-property-preview.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opening-property-preview.d.ts","sourceRoot":"","sources":["../../src/shared/opening-property-preview.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAGhF,MAAM,MAAM,kCAAkC,GAAG;IAC/C,KAAK,EAAE,MAAM,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAA;IACjD,QAAQ,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,SAAS,CAAA;IACzD,WAAW,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,IAAI,CAAA;IAC7D,mBAAmB,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAA;IAC9D,SAAS,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,IAAI,CAAA;IAClC,UAAU,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,IAAI,CAAA;IAC5D,aAAa,EAAE,CAAC,QAAQ,EAAE,oBAAoB,KAAK,MAAM,CAAA;IACzD,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;IACrC,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;IAC9D,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;CACtC,CAAA;AAID,wBAAgB,4BAA4B,CAAC,CAAC,SAAS,QAAQ,GAAG,UAAU,EAC1E,EAAE,EAAE,SAAS,EACb,YAAY,EAAE,kCAAkC;mBAsD/B,OAAO,CAAC,CAAC,CAAC;mBAcV,OAAO,CAAC,CAAC,CAAC;;EAyB5B"}
@@ -0,0 +1,99 @@
1
+ import { constrainCurtainOpening } from './curtain-opening-limits';
2
+ const CURTAIN_PARENT_PREVIEW_INTERVAL_MS = 100;
3
+ export function createOpeningPropertyPreview(id, dependencies) {
4
+ let pending;
5
+ let dirtyFrame;
6
+ let parentDelay;
7
+ const parent = () => {
8
+ const parentId = dependencies.nodes()[id]?.parentId;
9
+ return parentId ? dependencies.nodes()[parentId] : undefined;
10
+ };
11
+ const dirtyOpening = () => {
12
+ dependencies.markDirty(id);
13
+ };
14
+ const dirtyParent = () => {
15
+ const parentId = dependencies.nodes()[id]?.parentId;
16
+ if (parentId)
17
+ dependencies.markDirty(parentId);
18
+ };
19
+ const cancelScheduledDirty = () => {
20
+ if (dirtyFrame === undefined)
21
+ return;
22
+ dependencies.cancelFrame(dirtyFrame);
23
+ dirtyFrame = undefined;
24
+ };
25
+ const scheduleDirty = () => {
26
+ if (dirtyFrame !== undefined)
27
+ return;
28
+ let completedSynchronously = false;
29
+ const handle = dependencies.scheduleFrame(() => {
30
+ completedSynchronously = true;
31
+ dirtyFrame = undefined;
32
+ dirtyOpening();
33
+ const parentNode = parent();
34
+ if (parentNode?.type !== 'wall' || parentNode.wallType !== 'curtain') {
35
+ dirtyParent();
36
+ return;
37
+ }
38
+ if (parentDelay !== undefined)
39
+ return;
40
+ parentDelay = dependencies.scheduleDelay(() => {
41
+ parentDelay = undefined;
42
+ dirtyParent();
43
+ }, CURTAIN_PARENT_PREVIEW_INTERVAL_MS);
44
+ });
45
+ if (!completedSynchronously)
46
+ dirtyFrame = handle;
47
+ };
48
+ const clear = () => {
49
+ if (!pending)
50
+ return;
51
+ cancelScheduledDirty();
52
+ if (parentDelay !== undefined) {
53
+ dependencies.cancelDelay(parentDelay);
54
+ parentDelay = undefined;
55
+ }
56
+ dependencies.clearOverrideFields(id, [...Object.keys(pending), 'metadata']);
57
+ pending = undefined;
58
+ dirtyOpening();
59
+ dirtyParent();
60
+ };
61
+ return {
62
+ preview(patch) {
63
+ const nodes = dependencies.nodes();
64
+ const node = nodes[id];
65
+ if (node?.type !== 'door' && node?.type !== 'window')
66
+ return;
67
+ const live = dependencies.override(id);
68
+ const effective = live ? { ...node, ...live } : node;
69
+ patch = constrainCurtainOpening(effective, patch, nodes);
70
+ pending = { ...pending, ...patch };
71
+ dependencies.setOverride(id, {
72
+ ...patch,
73
+ metadata: { ...node.metadata, ...effective.metadata, deferParentRebuild: true },
74
+ });
75
+ scheduleDirty();
76
+ },
77
+ commit(patch) {
78
+ const live = dependencies.override(id);
79
+ if (pending && !Object.keys(pending).some((key) => live && key in live)) {
80
+ clear();
81
+ return;
82
+ }
83
+ const current = pending && live
84
+ ? Object.fromEntries(Object.keys(pending)
85
+ .filter((key) => key in live)
86
+ .map((key) => [key, live[key]]))
87
+ : undefined;
88
+ const nodes = dependencies.nodes();
89
+ const node = nodes[id];
90
+ const updates = node?.type === 'door' || node?.type === 'window'
91
+ ? constrainCurtainOpening(node, { ...current, ...patch }, nodes)
92
+ : {};
93
+ if (Object.keys(updates).length)
94
+ dependencies.updateNode(id, updates);
95
+ clear();
96
+ },
97
+ cancel: clear,
98
+ };
99
+ }
@@ -1,3 +1,4 @@
1
- import { type AnyNode, type AnyNodeId } from '@pascal-app/core';
1
+ import { type AnyNode, type AnyNodeDefinition, type AnyNodeId } from '@pascal-app/core';
2
+ export declare const restingFloorplanAffectedIds: NonNullable<AnyNodeDefinition['floorplanAffectedIds']>;
2
3
  export declare function restingNodePlanFrame(node: AnyNode, resolve: (id: AnyNodeId) => AnyNode | undefined): import("@pascal-app/core/procedural-items").Frame;
3
4
  //# sourceMappingURL=resting-surface-plan.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"resting-surface-plan.d.ts","sourceRoot":"","sources":["../../src/shared/resting-surface-plan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,SAAS,EAAuC,MAAM,kBAAkB,CAAA;AAGpG,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,OAAO,GAAG,SAAS,qDAwBhD"}
1
+ {"version":3,"file":"resting-surface-plan.d.ts","sourceRoot":"","sources":["../../src/shared/resting-surface-plan.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,iBAAiB,EACtB,KAAK,SAAS,EAIf,MAAM,kBAAkB,CAAA;AAOzB,eAAO,MAAM,2BAA2B,EAAE,WAAW,CACnD,iBAAiB,CAAC,sBAAsB,CAAC,CAa1C,CAAA;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,OAAO,EACb,OAAO,EAAE,CAAC,EAAE,EAAE,SAAS,KAAK,OAAO,GAAG,SAAS,qDAkChD"}
@@ -1,5 +1,21 @@
1
- import { getEffectiveNode, useLiveTransforms } from '@pascal-app/core';
1
+ import { collectSubtree, getEffectiveNode, useLiveTransforms, } from '@pascal-app/core';
2
2
  import { nodeLevelFrame } from '@pascal-app/core/procedural-items';
3
+ // Live transforms do not replace the committed snapshot; topology edits do.
4
+ const affectedIdsBySnapshot = new WeakMap();
5
+ // Hosted footprints read ancestor poses, so a host preview invalidates its descendants too.
6
+ export const restingFloorplanAffectedIds = ({ nodeId, nodes }) => {
7
+ let cached = affectedIdsBySnapshot.get(nodes);
8
+ if (!cached) {
9
+ cached = new Map();
10
+ affectedIdsBySnapshot.set(nodes, cached);
11
+ }
12
+ let ids = cached.get(nodeId);
13
+ if (!ids) {
14
+ ids = collectSubtree(nodes, nodeId)?.descendants.map((node) => node.id) ?? [];
15
+ cached.set(nodeId, ids);
16
+ }
17
+ return ids;
18
+ };
3
19
  export function restingNodePlanFrame(node, resolve) {
4
20
  const nodes = { [node.id]: node };
5
21
  let id = node.parentId;
@@ -12,12 +28,21 @@ export function restingNodePlanFrame(node, resolve) {
12
28
  const effective = getEffectiveNode(parent);
13
29
  const live = useLiveTransforms.getState().get(parent.id);
14
30
  nodes[id] =
15
- live &&
16
- (parent.type === 'shelf' || parent.type === 'cabinet' || parent.type === 'procedural-item')
31
+ live && parent.type !== 'item' && parent.type !== 'level'
17
32
  ? {
18
33
  ...effective,
19
34
  position: live.position,
20
- rotation: parent.type === 'cabinet' ? live.rotation : [0, live.rotation, 0],
35
+ rotation: 'rotation' in effective && typeof effective.rotation === 'number'
36
+ ? live.rotation
37
+ : [
38
+ 'rotation' in effective && Array.isArray(effective.rotation)
39
+ ? effective.rotation[0]
40
+ : 0,
41
+ live.rotation,
42
+ 'rotation' in effective && Array.isArray(effective.rotation)
43
+ ? effective.rotation[2]
44
+ : 0,
45
+ ],
21
46
  }
22
47
  : effective;
23
48
  if (parent.type === 'level')
@@ -0,0 +1,12 @@
1
+ import type { AnyNode, AnyNodeId } from '@pascal-app/core';
2
+ /**
3
+ * The other surface of the same room: a slab's ceiling, a ceiling's slab —
4
+ * on the same level with the same outline. The plan draws them on top of each
5
+ * other (only the slab takes a click), so deselecting one deselects both.
6
+ * Both kinds declare it as their plan `selectionCounterparts`.
7
+ */
8
+ export declare function sameOutlineSurfaceCounterparts({ node, nodes, }: {
9
+ node: AnyNode;
10
+ nodes: Readonly<Record<string, AnyNode | undefined>>;
11
+ }): AnyNodeId[];
12
+ //# sourceMappingURL=surface-counterparts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surface-counterparts.d.ts","sourceRoot":"","sources":["../../src/shared/surface-counterparts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAwB1D;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAAC,EAC7C,IAAI,EACJ,KAAK,GACN,EAAE;IACD,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC,CAAC,CAAA;CACrD,GAAG,SAAS,EAAE,CAYd"}
@@ -0,0 +1,27 @@
1
+ const POINT_EPSILON = 1e-6;
2
+ function isSurface(node) {
3
+ return ((node?.type === 'slab' || node?.type === 'ceiling') &&
4
+ Array.isArray(node.polygon));
5
+ }
6
+ function samePolygon(a, b) {
7
+ return (a.length === b.length &&
8
+ a.every((point, index) => Math.abs(point[0] - b[index][0]) <= POINT_EPSILON &&
9
+ Math.abs(point[1] - b[index][1]) <= POINT_EPSILON));
10
+ }
11
+ /**
12
+ * The other surface of the same room: a slab's ceiling, a ceiling's slab —
13
+ * on the same level with the same outline. The plan draws them on top of each
14
+ * other (only the slab takes a click), so deselecting one deselects both.
15
+ * Both kinds declare it as their plan `selectionCounterparts`.
16
+ */
17
+ export function sameOutlineSurfaceCounterparts({ node, nodes, }) {
18
+ if (!isSurface(node))
19
+ return [];
20
+ const other = node.type === 'slab' ? 'ceiling' : 'slab';
21
+ return Object.values(nodes)
22
+ .filter((candidate) => isSurface(candidate) &&
23
+ candidate.type === other &&
24
+ (candidate.parentId ?? null) === (node.parentId ?? null) &&
25
+ samePolygon(candidate.polygon, node.polygon))
26
+ .map((candidate) => candidate.id);
27
+ }
@@ -54,6 +54,7 @@ export type WallPlanAttachment = Omit<WallHit, 'wall'> & {
54
54
  };
55
55
  /** Resolve a plan point against one wall, including its curved centerline. */
56
56
  export declare function resolveWallAttachmentAtPlanPoint(wall: WallNode, planPoint: readonly [number, number], maxDistance?: number): WallPlanAttachment | null;
57
+ export declare function projectPlanPointToWallLocalX(wall: WallNode, planPoint: readonly [number, number]): number;
57
58
  /**
58
59
  * Return the closest wall attachment target in plan space, including curved
59
60
  * walls. This is deliberately separate from `findClosestWallInPlan`: doors,
@@ -1 +1 @@
1
- {"version":3,"file":"wall-attach-target.d.ts","sourceRoot":"","sources":["../../src/shared/wall-attach-target.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"wall-attach-target.d.ts","sourceRoot":"","sources":["../../src/shared/wall-attach-target.ts"],"names":[],"mappings":"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"}