@pascal-app/nodes 1.0.6 → 1.0.7

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 (566) hide show
  1. package/README.md +1 -0
  2. package/dist/beam/actions/move-endpoint.d.ts +24 -0
  3. package/dist/beam/actions/move-endpoint.d.ts.map +1 -0
  4. package/dist/beam/actions/move-endpoint.js +54 -0
  5. package/dist/beam/definition.d.ts +14 -0
  6. package/dist/beam/definition.d.ts.map +1 -0
  7. package/dist/beam/definition.js +173 -0
  8. package/dist/beam/draft-settings.d.ts +17 -0
  9. package/dist/beam/draft-settings.d.ts.map +1 -0
  10. package/dist/beam/draft-settings.js +81 -0
  11. package/dist/beam/drafting.d.ts +35 -0
  12. package/dist/beam/drafting.d.ts.map +1 -0
  13. package/dist/beam/drafting.js +103 -0
  14. package/dist/beam/floorplan-affordances.d.ts +8 -0
  15. package/dist/beam/floorplan-affordances.d.ts.map +1 -0
  16. package/dist/beam/floorplan-affordances.js +40 -0
  17. package/dist/beam/floorplan-move.d.ts +11 -0
  18. package/dist/beam/floorplan-move.d.ts.map +1 -0
  19. package/dist/beam/floorplan-move.js +54 -0
  20. package/dist/beam/floorplan.d.ts +11 -0
  21. package/dist/beam/floorplan.d.ts.map +1 -0
  22. package/dist/beam/floorplan.js +91 -0
  23. package/dist/beam/geometry.d.ts +19 -0
  24. package/dist/beam/geometry.d.ts.map +1 -0
  25. package/dist/beam/geometry.js +63 -0
  26. package/dist/beam/index.d.ts +3 -0
  27. package/dist/beam/index.d.ts.map +1 -0
  28. package/dist/beam/index.js +2 -0
  29. package/dist/beam/move-endpoint-tool.d.ts +21 -0
  30. package/dist/beam/move-endpoint-tool.d.ts.map +1 -0
  31. package/dist/beam/move-endpoint-tool.js +49 -0
  32. package/dist/beam/move-tool.d.ts +12 -0
  33. package/dist/beam/move-tool.d.ts.map +1 -0
  34. package/dist/beam/move-tool.js +114 -0
  35. package/dist/beam/panel-model.d.ts +28 -0
  36. package/dist/beam/panel-model.d.ts.map +1 -0
  37. package/dist/beam/panel-model.js +123 -0
  38. package/dist/beam/panel.d.ts +13 -0
  39. package/dist/beam/panel.d.ts.map +1 -0
  40. package/dist/beam/panel.js +107 -0
  41. package/dist/beam/parametrics.d.ts +3 -0
  42. package/dist/beam/parametrics.d.ts.map +1 -0
  43. package/dist/beam/parametrics.js +4 -0
  44. package/dist/beam/renderer.d.ts +13 -0
  45. package/dist/beam/renderer.d.ts.map +1 -0
  46. package/dist/beam/renderer.js +36 -0
  47. package/dist/beam/schema.d.ts +2 -0
  48. package/dist/beam/schema.d.ts.map +1 -0
  49. package/dist/beam/schema.js +1 -0
  50. package/dist/beam/tool.d.ts +13 -0
  51. package/dist/beam/tool.d.ts.map +1 -0
  52. package/dist/beam/tool.js +152 -0
  53. package/dist/box-vent/panel.d.ts.map +1 -1
  54. package/dist/box-vent/panel.js +8 -7
  55. package/dist/cabinet/batchable.d.ts +10 -0
  56. package/dist/cabinet/batchable.d.ts.map +1 -0
  57. package/dist/cabinet/batchable.js +12 -0
  58. package/dist/cabinet/compartment-card.d.ts.map +1 -1
  59. package/dist/cabinet/compartment-card.js +142 -46
  60. package/dist/cabinet/countertop-layout.d.ts +5 -0
  61. package/dist/cabinet/countertop-layout.d.ts.map +1 -1
  62. package/dist/cabinet/definition.d.ts.map +1 -1
  63. package/dist/cabinet/definition.js +3 -0
  64. package/dist/cabinet/dimension-input.d.ts +6 -0
  65. package/dist/cabinet/dimension-input.d.ts.map +1 -0
  66. package/dist/cabinet/dimension-input.js +8 -0
  67. package/dist/cabinet/essential-controls.d.ts.map +1 -1
  68. package/dist/cabinet/essential-controls.js +82 -17
  69. package/dist/cabinet/index.d.ts +1 -1
  70. package/dist/cabinet/index.d.ts.map +1 -1
  71. package/dist/cabinet/index.js +1 -1
  72. package/dist/cabinet/kitchen-catalog.d.ts +17 -4
  73. package/dist/cabinet/kitchen-catalog.d.ts.map +1 -1
  74. package/dist/cabinet/kitchen-catalog.js +45 -7
  75. package/dist/cabinet/kitchen-collection.d.ts.map +1 -1
  76. package/dist/cabinet/kitchen-collection.js +21 -5
  77. package/dist/cabinet/kitchen-module-actions.d.ts.map +1 -1
  78. package/dist/cabinet/kitchen-module-actions.js +107 -14
  79. package/dist/cabinet/neighbor-placement.d.ts +10 -0
  80. package/dist/cabinet/neighbor-placement.d.ts.map +1 -1
  81. package/dist/cabinet/panel.d.ts.map +1 -1
  82. package/dist/cabinet/panel.js +127 -50
  83. package/dist/cabinet/run-finishing.d.ts +5 -0
  84. package/dist/cabinet/run-finishing.d.ts.map +1 -1
  85. package/dist/cabinet/run-ops.d.ts +5 -0
  86. package/dist/cabinet/run-ops.d.ts.map +1 -1
  87. package/dist/cabinet/run-panel.d.ts.map +1 -1
  88. package/dist/cabinet/run-panel.js +203 -52
  89. package/dist/cabinet/tool.d.ts.map +1 -1
  90. package/dist/cabinet/tool.js +8 -5
  91. package/dist/ceiling/build-up-section.d.ts +7 -0
  92. package/dist/ceiling/build-up-section.d.ts.map +1 -0
  93. package/dist/ceiling/build-up-section.js +57 -0
  94. package/dist/ceiling/definition.d.ts.map +1 -1
  95. package/dist/ceiling/definition.js +3 -1
  96. package/dist/ceiling/floorplan-affordances.d.ts +112 -0
  97. package/dist/ceiling/floorplan-affordances.d.ts.map +1 -1
  98. package/dist/ceiling/materials.d.ts +5 -0
  99. package/dist/ceiling/materials.d.ts.map +1 -1
  100. package/dist/ceiling/materials.js +17 -0
  101. package/dist/ceiling/panel-model.d.ts +13 -0
  102. package/dist/ceiling/panel-model.d.ts.map +1 -0
  103. package/dist/ceiling/panel-model.js +49 -0
  104. package/dist/ceiling/panel.d.ts.map +1 -1
  105. package/dist/ceiling/panel.js +82 -18
  106. package/dist/ceiling/renderer.d.ts.map +1 -1
  107. package/dist/ceiling/renderer.js +10 -4
  108. package/dist/ceiling/tool.d.ts.map +1 -1
  109. package/dist/ceiling/tool.js +24 -4
  110. package/dist/chimney/panel.d.ts.map +1 -1
  111. package/dist/chimney/panel.js +113 -41
  112. package/dist/column/definition.d.ts.map +1 -1
  113. package/dist/column/definition.js +3 -0
  114. package/dist/column/floorplan.d.ts.map +1 -1
  115. package/dist/column/floorplan.js +17 -0
  116. package/dist/column/hosted-resize.d.ts +28 -1
  117. package/dist/column/hosted-resize.d.ts.map +1 -1
  118. package/dist/column/panel.d.ts.map +1 -1
  119. package/dist/column/panel.js +125 -37
  120. package/dist/column/post-options.d.ts +10 -0
  121. package/dist/column/post-options.d.ts.map +1 -0
  122. package/dist/column/post-options.js +71 -0
  123. package/dist/column/post-placement.d.ts +78 -0
  124. package/dist/column/post-placement.d.ts.map +1 -0
  125. package/dist/column/post-placement.js +157 -0
  126. package/dist/column/post-section.d.ts +17 -0
  127. package/dist/column/post-section.d.ts.map +1 -0
  128. package/dist/column/post-section.js +95 -0
  129. package/dist/column/post-tool.d.ts +11 -0
  130. package/dist/column/post-tool.d.ts.map +1 -0
  131. package/dist/column/post-tool.js +94 -0
  132. package/dist/column/tool.d.ts +3 -10
  133. package/dist/column/tool.d.ts.map +1 -1
  134. package/dist/column/tool.js +13 -1
  135. package/dist/cupola/panel.d.ts.map +1 -1
  136. package/dist/cupola/panel.js +14 -7
  137. package/dist/door/actions.d.ts +7 -0
  138. package/dist/door/actions.d.ts.map +1 -0
  139. package/dist/door/actions.js +32 -0
  140. package/dist/door/contextual-dimensions.d.ts.map +1 -1
  141. package/dist/door/contextual-dimensions.js +11 -1
  142. package/dist/door/definition.d.ts.map +1 -1
  143. package/dist/door/definition.js +34 -7
  144. package/dist/door/floorplan-affordances.d.ts.map +1 -1
  145. package/dist/door/floorplan-affordances.js +5 -2
  146. package/dist/door/floorplan-move.d.ts.map +1 -1
  147. package/dist/door/floorplan-move.js +28 -6
  148. package/dist/door/floorplan.d.ts +2 -0
  149. package/dist/door/floorplan.d.ts.map +1 -1
  150. package/dist/door/floorplan.js +89 -16
  151. package/dist/door/move-tool.d.ts.map +1 -1
  152. package/dist/door/move-tool.js +60 -16
  153. package/dist/door/paint.d.ts +2 -7
  154. package/dist/door/paint.d.ts.map +1 -1
  155. package/dist/door/paint.js +26 -2
  156. package/dist/door/panel.d.ts.map +1 -1
  157. package/dist/door/panel.js +242 -90
  158. package/dist/door/parametrics.js +1 -1
  159. package/dist/door/placement.d.ts.map +1 -1
  160. package/dist/door/placement.js +9 -2
  161. package/dist/door/swing.d.ts +22 -0
  162. package/dist/door/swing.d.ts.map +1 -0
  163. package/dist/door/swing.js +36 -0
  164. package/dist/door/tool.d.ts.map +1 -1
  165. package/dist/door/tool.js +76 -29
  166. package/dist/dormer/panel-actions-section.d.ts.map +1 -1
  167. package/dist/dormer/panel-actions-section.js +3 -1
  168. package/dist/dormer/panel-position-section.d.ts.map +1 -1
  169. package/dist/dormer/panel-position-section.js +4 -3
  170. package/dist/dormer/panel-windows-section.d.ts.map +1 -1
  171. package/dist/dormer/panel-windows-section.js +38 -1
  172. package/dist/dormer/panel.d.ts.map +1 -1
  173. package/dist/dormer/panel.js +24 -18
  174. package/dist/downspout/inspector-editors.d.ts.map +1 -1
  175. package/dist/downspout/inspector-editors.js +3 -2
  176. package/dist/duct-fitting/inspector-editors.d.ts.map +1 -1
  177. package/dist/duct-fitting/inspector-editors.js +6 -1
  178. package/dist/duct-fitting/tool.d.ts.map +1 -1
  179. package/dist/duct-fitting/tool.js +11 -2
  180. package/dist/duct-terminal/tool.d.ts.map +1 -1
  181. package/dist/duct-terminal/tool.js +11 -2
  182. package/dist/elevator/panel.d.ts.map +1 -1
  183. package/dist/elevator/panel.js +41 -18
  184. package/dist/eyebrow-vent/panel.d.ts.map +1 -1
  185. package/dist/eyebrow-vent/panel.js +16 -6
  186. package/dist/fence/drafting.d.ts +2 -3
  187. package/dist/fence/drafting.d.ts.map +1 -1
  188. package/dist/fence/drafting.js +2 -3
  189. package/dist/fence/inspector-editors.d.ts.map +1 -1
  190. package/dist/fence/inspector-editors.js +64 -21
  191. package/dist/fence/move-endpoint-tool.d.ts.map +1 -1
  192. package/dist/fence/move-endpoint-tool.js +11 -2
  193. package/dist/fence/system.d.ts.map +1 -1
  194. package/dist/fence/system.js +13 -0
  195. package/dist/fence-feature/actions.d.ts.map +1 -1
  196. package/dist/fence-feature/actions.js +5 -2
  197. package/dist/fence-feature/inspector.d.ts.map +1 -1
  198. package/dist/fence-feature/inspector.js +150 -34
  199. package/dist/fence-feature/move-session.d.ts +1 -1
  200. package/dist/floor-opening/floorplan.d.ts +29 -6
  201. package/dist/floor-opening/floorplan.d.ts.map +1 -1
  202. package/dist/floor-opening/floorplan.js +172 -14
  203. package/dist/gutter/downspouts-panel.d.ts.map +1 -1
  204. package/dist/gutter/downspouts-panel.js +14 -2
  205. package/dist/hvac-equipment/tool.d.ts.map +1 -1
  206. package/dist/hvac-equipment/tool.js +3 -2
  207. package/dist/i18n/definition-messages.d.ts +5 -0
  208. package/dist/i18n/definition-messages.d.ts.map +1 -0
  209. package/dist/i18n/definition-messages.js +771 -0
  210. package/dist/index.d.ts +4 -1
  211. package/dist/index.d.ts.map +1 -1
  212. package/dist/index.js +6 -1
  213. package/dist/item/authored-params.d.ts.map +1 -1
  214. package/dist/item/authored-params.js +19 -4
  215. package/dist/item/floorplan.d.ts +1 -1
  216. package/dist/item/floorplan.d.ts.map +1 -1
  217. package/dist/item/panel.d.ts.map +1 -1
  218. package/dist/item/panel.js +9 -7
  219. package/dist/liquid-line/tool.d.ts.map +1 -1
  220. package/dist/liquid-line/tool.js +10 -3
  221. package/dist/measurement/tool.d.ts +1 -1
  222. package/dist/measurement/tool.d.ts.map +1 -1
  223. package/dist/measurement/tool.js +8 -8
  224. package/dist/pipe-fitting/tool.d.ts.map +1 -1
  225. package/dist/pipe-fitting/tool.js +3 -2
  226. package/dist/pipe-trap/tool.d.ts.map +1 -1
  227. package/dist/pipe-trap/tool.js +7 -2
  228. package/dist/procedural-item/renderer.d.ts.map +1 -1
  229. package/dist/procedural-item/renderer.js +8 -1
  230. package/dist/ridge-vent/panel.d.ts.map +1 -1
  231. package/dist/ridge-vent/panel.js +22 -9
  232. package/dist/roof/barrel-panel.d.ts.map +1 -1
  233. package/dist/roof/barrel-panel.js +7 -3
  234. package/dist/roof/definition.d.ts.map +1 -1
  235. package/dist/roof/definition.js +33 -3
  236. package/dist/roof/floorplan-overrides.d.ts +22 -0
  237. package/dist/roof/floorplan-overrides.d.ts.map +1 -0
  238. package/dist/roof/floorplan-overrides.js +46 -0
  239. package/dist/roof/floorplan-tool.d.ts +9 -0
  240. package/dist/roof/floorplan-tool.d.ts.map +1 -0
  241. package/dist/roof/floorplan-tool.js +168 -0
  242. package/dist/roof/floorplan.d.ts.map +1 -1
  243. package/dist/roof/floorplan.js +131 -41
  244. package/dist/roof/glazing-controls.d.ts +2 -1
  245. package/dist/roof/glazing-controls.d.ts.map +1 -1
  246. package/dist/roof/glazing-controls.js +51 -13
  247. package/dist/roof/glazing-panel-editor.d.ts.map +1 -1
  248. package/dist/roof/glazing-panel-editor.js +40 -13
  249. package/dist/roof/glazing-panel.d.ts.map +1 -1
  250. package/dist/roof/glazing-panel.js +73 -9
  251. package/dist/roof/paint.d.ts +19 -0
  252. package/dist/roof/paint.d.ts.map +1 -0
  253. package/dist/roof/paint.js +158 -0
  254. package/dist/roof/panel.d.ts.map +1 -1
  255. package/dist/roof/panel.js +90 -22
  256. package/dist/roof/renderer.d.ts.map +1 -1
  257. package/dist/roof/renderer.js +13 -2
  258. package/dist/roof/roof-footprint-source.d.ts +17 -0
  259. package/dist/roof/roof-footprint-source.d.ts.map +1 -1
  260. package/dist/roof/roof-footprint-source.js +14 -0
  261. package/dist/roof/roof-footprint.d.ts +36 -2
  262. package/dist/roof/roof-footprint.d.ts.map +1 -1
  263. package/dist/roof/roof-footprint.js +124 -2
  264. package/dist/roof/roof-materials.d.ts.map +1 -1
  265. package/dist/roof/roof-materials.js +10 -1
  266. package/dist/roof/roof-placement-mode.d.ts +0 -2
  267. package/dist/roof/roof-placement-mode.d.ts.map +1 -1
  268. package/dist/roof/roof-placement-mode.js +8 -6
  269. package/dist/roof/roof-plan-creases.d.ts +50 -0
  270. package/dist/roof/roof-plan-creases.d.ts.map +1 -0
  271. package/dist/roof/roof-plan-creases.js +194 -0
  272. package/dist/roof/roof-ridge-mode.d.ts +20 -0
  273. package/dist/roof/roof-ridge-mode.d.ts.map +1 -0
  274. package/dist/roof/roof-ridge-mode.js +16 -0
  275. package/dist/roof/tool.d.ts +17 -4
  276. package/dist/roof/tool.d.ts.map +1 -1
  277. package/dist/roof/tool.js +211 -113
  278. package/dist/roof/wall-catch.d.ts +106 -0
  279. package/dist/roof/wall-catch.d.ts.map +1 -0
  280. package/dist/roof/wall-catch.js +267 -0
  281. package/dist/roof-segment/build-up-section.d.ts +9 -0
  282. package/dist/roof-segment/build-up-section.d.ts.map +1 -0
  283. package/dist/roof-segment/build-up-section.js +191 -0
  284. package/dist/roof-segment/definition.d.ts.map +1 -1
  285. package/dist/roof-segment/definition.js +50 -5
  286. package/dist/roof-segment/floorplan-affordances.d.ts.map +1 -1
  287. package/dist/roof-segment/floorplan-affordances.js +68 -19
  288. package/dist/roof-segment/floorplan.d.ts.map +1 -1
  289. package/dist/roof-segment/floorplan.js +16 -12
  290. package/dist/roof-segment/paint.d.ts +3 -1
  291. package/dist/roof-segment/paint.d.ts.map +1 -1
  292. package/dist/roof-segment/paint.js +43 -2
  293. package/dist/roof-segment/panel-model.d.ts +23 -0
  294. package/dist/roof-segment/panel-model.d.ts.map +1 -0
  295. package/dist/roof-segment/panel-model.js +64 -0
  296. package/dist/roof-segment/panel.d.ts.map +1 -1
  297. package/dist/roof-segment/panel.js +96 -14
  298. package/dist/roof-segment/parametrics.d.ts.map +1 -1
  299. package/dist/roof-segment/parametrics.js +4 -0
  300. package/dist/roof-segment/renderer.d.ts.map +1 -1
  301. package/dist/roof-segment/renderer.js +26 -5
  302. package/dist/separator/definition.d.ts.map +1 -1
  303. package/dist/separator/definition.js +10 -12
  304. package/dist/separator/floorplan-affordances.d.ts +9 -0
  305. package/dist/separator/floorplan-affordances.d.ts.map +1 -0
  306. package/dist/separator/floorplan-affordances.js +23 -0
  307. package/dist/separator/floorplan.d.ts +9 -0
  308. package/dist/separator/floorplan.d.ts.map +1 -0
  309. package/dist/separator/floorplan.js +54 -0
  310. package/dist/separator/renderer.d.ts +4 -0
  311. package/dist/separator/renderer.d.ts.map +1 -1
  312. package/dist/separator/renderer.js +21 -6
  313. package/dist/separator/selection.d.ts +10 -0
  314. package/dist/separator/selection.d.ts.map +1 -0
  315. package/dist/separator/selection.js +35 -0
  316. package/dist/shared/build-up-controls.d.ts +88 -0
  317. package/dist/shared/build-up-controls.d.ts.map +1 -0
  318. package/dist/shared/build-up-controls.js +139 -0
  319. package/dist/shared/curtain-opening-limits.d.ts.map +1 -1
  320. package/dist/shared/curtain-opening-limits.js +44 -14
  321. package/dist/shared/item-interaction-actions.d.ts.map +1 -1
  322. package/dist/shared/item-interaction-actions.js +11 -2
  323. package/dist/shared/layer-thickness.d.ts +2 -0
  324. package/dist/shared/layer-thickness.d.ts.map +1 -0
  325. package/dist/shared/layer-thickness.js +3 -0
  326. package/dist/shared/move-roof-tool.d.ts.map +1 -1
  327. package/dist/shared/move-roof-tool.js +100 -5
  328. package/dist/shared/node-batch/batchable.d.ts +2 -0
  329. package/dist/shared/node-batch/batchable.d.ts.map +1 -1
  330. package/dist/shared/node-batch/batchable.js +4 -0
  331. package/dist/shared/node-batch/candidates.d.ts +21 -5
  332. package/dist/shared/node-batch/candidates.d.ts.map +1 -1
  333. package/dist/shared/node-batch/candidates.js +85 -50
  334. package/dist/shared/node-batch/system.d.ts.map +1 -1
  335. package/dist/shared/node-batch/system.js +24 -15
  336. package/dist/shared/opening-casing-move.d.ts +16 -0
  337. package/dist/shared/opening-casing-move.d.ts.map +1 -0
  338. package/dist/shared/opening-casing-move.js +33 -0
  339. package/dist/shared/opening-casing-section.d.ts +15 -0
  340. package/dist/shared/opening-casing-section.d.ts.map +1 -0
  341. package/dist/shared/opening-casing-section.js +38 -0
  342. package/dist/shared/opening-casing.d.ts +26 -0
  343. package/dist/shared/opening-casing.d.ts.map +1 -0
  344. package/dist/shared/opening-casing.js +80 -0
  345. package/dist/shared/opening-depth-position.d.ts +13 -0
  346. package/dist/shared/opening-depth-position.d.ts.map +1 -0
  347. package/dist/shared/opening-depth-position.js +34 -0
  348. package/dist/shared/opening-documentation.d.ts.map +1 -1
  349. package/dist/shared/opening-documentation.js +17 -8
  350. package/dist/shared/opening-guides-runtime.d.ts +2 -1
  351. package/dist/shared/opening-guides-runtime.d.ts.map +1 -1
  352. package/dist/shared/opening-guides-runtime.js +11 -7
  353. package/dist/shared/opening-labels.d.ts +11 -0
  354. package/dist/shared/opening-labels.d.ts.map +1 -0
  355. package/dist/shared/opening-labels.js +46 -0
  356. package/dist/shared/opening-placement-dimensions.d.ts.map +1 -1
  357. package/dist/shared/opening-placement-dimensions.js +11 -9
  358. package/dist/shared/opening-plane-offset.d.ts +4 -3
  359. package/dist/shared/opening-plane-offset.d.ts.map +1 -1
  360. package/dist/shared/opening-plane-offset.js +7 -4
  361. package/dist/shared/opening-swap.d.ts +8 -0
  362. package/dist/shared/opening-swap.d.ts.map +1 -0
  363. package/dist/shared/opening-swap.js +18 -0
  364. package/dist/shared/polygon-vertex-affordance.d.ts +19 -0
  365. package/dist/shared/polygon-vertex-affordance.d.ts.map +1 -1
  366. package/dist/shared/polygon-vertex-affordance.js +65 -6
  367. package/dist/shared/roof-opening-host.d.ts +2 -1
  368. package/dist/shared/roof-opening-host.d.ts.map +1 -1
  369. package/dist/shared/roof-opening-host.js +14 -5
  370. package/dist/shared/roof-wall-opening-cut.d.ts.map +1 -1
  371. package/dist/shared/roof-wall-opening-cut.js +14 -6
  372. package/dist/shared/roof-wall-opening-placement.d.ts +2 -1
  373. package/dist/shared/roof-wall-opening-placement.d.ts.map +1 -1
  374. package/dist/shared/roof-wall-opening-placement.js +6 -4
  375. package/dist/shared/run-hanger-inspector.d.ts.map +1 -1
  376. package/dist/shared/run-hanger-inspector.js +39 -5
  377. package/dist/shared/system-check-panel.d.ts.map +1 -1
  378. package/dist/shared/system-check-panel.js +94 -15
  379. package/dist/shared/wall-attach-target.d.ts.map +1 -1
  380. package/dist/shared/wall-attach-target.js +6 -3
  381. package/dist/shelf/definition.d.ts.map +1 -1
  382. package/dist/shelf/definition.js +2 -0
  383. package/dist/site/ground-hole.d.ts +3 -3
  384. package/dist/site/ground-hole.js +3 -3
  385. package/dist/site/ground-veil.d.ts +5 -12
  386. package/dist/site/ground-veil.d.ts.map +1 -1
  387. package/dist/site/ground-veil.js +9 -33
  388. package/dist/site/panel.d.ts.map +1 -1
  389. package/dist/site/panel.js +52 -12
  390. package/dist/site/renderer.d.ts.map +1 -1
  391. package/dist/site/renderer.js +52 -23
  392. package/dist/skylight/panel.d.ts.map +1 -1
  393. package/dist/skylight/panel.js +49 -19
  394. package/dist/slab/deck-geometry.d.ts +28 -0
  395. package/dist/slab/deck-geometry.d.ts.map +1 -0
  396. package/dist/slab/deck-geometry.js +320 -0
  397. package/dist/slab/definition.d.ts +2 -1
  398. package/dist/slab/definition.d.ts.map +1 -1
  399. package/dist/slab/definition.js +6 -1
  400. package/dist/slab/dependency-tracker.d.ts.map +1 -1
  401. package/dist/slab/dependency-tracker.js +3 -0
  402. package/dist/slab/floorplan-affordances.d.ts +500 -0
  403. package/dist/slab/floorplan-affordances.d.ts.map +1 -1
  404. package/dist/slab/geometry.d.ts.map +1 -1
  405. package/dist/slab/geometry.js +46 -9
  406. package/dist/slab/panel.d.ts.map +1 -1
  407. package/dist/slab/panel.js +97 -21
  408. package/dist/slab/renderer.d.ts +11 -0
  409. package/dist/slab/renderer.d.ts.map +1 -0
  410. package/dist/slab/renderer.js +19 -0
  411. package/dist/slab/system.d.ts.map +1 -1
  412. package/dist/slab/system.js +12 -1
  413. package/dist/solar-panel/panel.d.ts.map +1 -1
  414. package/dist/solar-panel/panel.js +49 -14
  415. package/dist/stair/construction-controls.d.ts +3 -1
  416. package/dist/stair/construction-controls.d.ts.map +1 -1
  417. package/dist/stair/construction-controls.js +75 -12
  418. package/dist/stair/paint.d.ts +6 -0
  419. package/dist/stair/paint.d.ts.map +1 -1
  420. package/dist/stair/panel.d.ts.map +1 -1
  421. package/dist/stair/panel.js +243 -51
  422. package/dist/stair/parametrics.d.ts.map +1 -1
  423. package/dist/stair/parametrics.js +7 -0
  424. package/dist/stair/placement-defaults.d.ts +18 -0
  425. package/dist/stair/placement-defaults.d.ts.map +1 -0
  426. package/dist/stair/placement-defaults.js +27 -0
  427. package/dist/stair/railing-controls.d.ts.map +1 -1
  428. package/dist/stair/railing-controls.js +78 -18
  429. package/dist/stair/renderer.d.ts.map +1 -1
  430. package/dist/stair/renderer.js +16 -10
  431. package/dist/stair/structure-controls.d.ts +18 -0
  432. package/dist/stair/structure-controls.d.ts.map +1 -0
  433. package/dist/stair/structure-controls.js +275 -0
  434. package/dist/stair/tool.d.ts.map +1 -1
  435. package/dist/stair/tool.js +13 -9
  436. package/dist/stair/use-stair-render-data.d.ts +41 -0
  437. package/dist/stair/use-stair-render-data.d.ts.map +1 -1
  438. package/dist/stair-segment/panel.d.ts.map +1 -1
  439. package/dist/stair-segment/panel.js +65 -18
  440. package/dist/turbine-vent/panel.d.ts.map +1 -1
  441. package/dist/turbine-vent/panel.js +14 -5
  442. package/dist/unit/unit-panel.d.ts.map +1 -1
  443. package/dist/unit/unit-panel.js +28 -12
  444. package/dist/wall/actions.d.ts +1 -1
  445. package/dist/wall/actions.d.ts.map +1 -1
  446. package/dist/wall/actions.js +17 -13
  447. package/dist/wall/construction-dimensions.d.ts +6 -0
  448. package/dist/wall/construction-dimensions.d.ts.map +1 -1
  449. package/dist/wall/construction-dimensions.js +8 -0
  450. package/dist/wall/contextual-dimensions.d.ts +6 -0
  451. package/dist/wall/contextual-dimensions.d.ts.map +1 -1
  452. package/dist/wall/contextual-dimensions.js +104 -17
  453. package/dist/wall/curtain-opening-frame.d.ts.map +1 -1
  454. package/dist/wall/curtain-opening-frame.js +6 -4
  455. package/dist/wall/curtain-wall-layout.d.ts +1 -1
  456. package/dist/wall/curtain-wall-layout.d.ts.map +1 -1
  457. package/dist/wall/curtain-wall-layout.js +6 -4
  458. package/dist/wall/curtain-wall-materials.d.ts.map +1 -1
  459. package/dist/wall/curtain-wall-materials.js +8 -3
  460. package/dist/wall/curtain-wall-panel.d.ts.map +1 -1
  461. package/dist/wall/curtain-wall-panel.js +241 -37
  462. package/dist/wall/curve-tool.d.ts.map +1 -1
  463. package/dist/wall/curve-tool.js +2 -3
  464. package/dist/wall/definition.d.ts.map +1 -1
  465. package/dist/wall/definition.js +20 -5
  466. package/dist/wall/floorplan-affordances.d.ts.map +1 -1
  467. package/dist/wall/floorplan-affordances.js +9 -6
  468. package/dist/wall/floorplan-move.d.ts.map +1 -1
  469. package/dist/wall/floorplan-move.js +66 -16
  470. package/dist/wall/floorplan.d.ts +4 -5
  471. package/dist/wall/floorplan.d.ts.map +1 -1
  472. package/dist/wall/floorplan.js +62 -46
  473. package/dist/wall/move-endpoint-tool.d.ts.map +1 -1
  474. package/dist/wall/move-endpoint-tool.js +1 -0
  475. package/dist/wall/move-tool.d.ts.map +1 -1
  476. package/dist/wall/move-tool.js +77 -12
  477. package/dist/wall/paint.d.ts +2 -2
  478. package/dist/wall/paint.d.ts.map +1 -1
  479. package/dist/wall/paint.js +11 -4
  480. package/dist/wall/panel-model.d.ts +17 -2
  481. package/dist/wall/panel-model.d.ts.map +1 -1
  482. package/dist/wall/panel-model.js +158 -18
  483. package/dist/wall/panel.d.ts +8 -0
  484. package/dist/wall/panel.d.ts.map +1 -1
  485. package/dist/wall/panel.js +228 -156
  486. package/dist/wall/parametrics.d.ts +1 -1
  487. package/dist/wall/parametrics.d.ts.map +1 -1
  488. package/dist/wall/parametrics.js +14 -1
  489. package/dist/wall/railing-wall-adapter.d.ts +7 -0
  490. package/dist/wall/railing-wall-adapter.d.ts.map +1 -0
  491. package/dist/wall/railing-wall-adapter.js +38 -0
  492. package/dist/wall/railing-wall-floorplan.d.ts +8 -0
  493. package/dist/wall/railing-wall-floorplan.d.ts.map +1 -0
  494. package/dist/wall/railing-wall-floorplan.js +27 -0
  495. package/dist/wall/railing-wall-geometry.d.ts +12 -0
  496. package/dist/wall/railing-wall-geometry.d.ts.map +1 -0
  497. package/dist/wall/railing-wall-geometry.js +51 -0
  498. package/dist/wall/railing-wall-guard.d.ts +81 -0
  499. package/dist/wall/railing-wall-guard.d.ts.map +1 -0
  500. package/dist/wall/railing-wall-guard.js +435 -0
  501. package/dist/wall/railing-wall-materials.d.ts +11 -0
  502. package/dist/wall/railing-wall-materials.d.ts.map +1 -0
  503. package/dist/wall/railing-wall-materials.js +31 -0
  504. package/dist/wall/railing-wall-panel-model.d.ts +30 -0
  505. package/dist/wall/railing-wall-panel-model.d.ts.map +1 -0
  506. package/dist/wall/railing-wall-panel-model.js +117 -0
  507. package/dist/wall/railing-wall-panel.d.ts +17 -0
  508. package/dist/wall/railing-wall-panel.d.ts.map +1 -0
  509. package/dist/wall/railing-wall-panel.js +42 -0
  510. package/dist/wall/rectangle-command.d.ts +79 -1
  511. package/dist/wall/rectangle-command.d.ts.map +1 -1
  512. package/dist/wall/rectangle-tool.d.ts.map +1 -1
  513. package/dist/wall/rectangle-tool.js +2 -0
  514. package/dist/wall/renderer.d.ts.map +1 -1
  515. package/dist/wall/renderer.js +3 -1
  516. package/dist/wall/skirting-floor-gaps.d.ts +8 -0
  517. package/dist/wall/skirting-floor-gaps.d.ts.map +1 -0
  518. package/dist/wall/skirting-floor-gaps.js +36 -0
  519. package/dist/wall/system.d.ts +0 -14
  520. package/dist/wall/system.d.ts.map +1 -1
  521. package/dist/wall/system.js +6 -1
  522. package/dist/wall/tool.d.ts +16 -0
  523. package/dist/wall/tool.d.ts.map +1 -1
  524. package/dist/wall/tool.js +160 -47
  525. package/dist/wall/treatments.d.ts +3 -0
  526. package/dist/wall/treatments.d.ts.map +1 -1
  527. package/dist/wall/treatments.js +30 -7
  528. package/dist/window/actions.d.ts +7 -0
  529. package/dist/window/actions.d.ts.map +1 -0
  530. package/dist/window/actions.js +29 -0
  531. package/dist/window/definition.d.ts.map +1 -1
  532. package/dist/window/definition.js +11 -2
  533. package/dist/window/floorplan-move.d.ts.map +1 -1
  534. package/dist/window/floorplan-move.js +5 -0
  535. package/dist/window/floorplan.d.ts +2 -0
  536. package/dist/window/floorplan.d.ts.map +1 -1
  537. package/dist/window/floorplan.js +58 -1
  538. package/dist/window/mechanism.d.ts.map +1 -1
  539. package/dist/window/mechanism.js +21 -1
  540. package/dist/window/move-tool.d.ts.map +1 -1
  541. package/dist/window/move-tool.js +10 -3
  542. package/dist/window/paint.d.ts +2 -7
  543. package/dist/window/paint.d.ts.map +1 -1
  544. package/dist/window/paint.js +31 -3
  545. package/dist/window/panel.d.ts.map +1 -1
  546. package/dist/window/panel.js +311 -69
  547. package/dist/window/placement.d.ts.map +1 -1
  548. package/dist/window/placement.js +5 -1
  549. package/dist/window/swing.d.ts +13 -0
  550. package/dist/window/swing.d.ts.map +1 -0
  551. package/dist/window/swing.js +16 -0
  552. package/dist/window/tool.d.ts.map +1 -1
  553. package/dist/window/tool.js +19 -14
  554. package/dist/zone/floorplan-affordances.d.ts +136 -0
  555. package/dist/zone/floorplan-affordances.d.ts.map +1 -1
  556. package/dist/zone/quantities-panel.d.ts.map +1 -1
  557. package/dist/zone/quantities-panel.js +34 -9
  558. package/dist/zone/renderer.d.ts.map +1 -1
  559. package/dist/zone/renderer.js +9 -5
  560. package/package.json +14 -14
  561. package/dist/site/generic-foundation-geometry.d.ts +0 -16
  562. package/dist/site/generic-foundation-geometry.d.ts.map +0 -1
  563. package/dist/site/generic-foundation-geometry.js +0 -75
  564. package/dist/site/generic-foundation.d.ts +0 -4
  565. package/dist/site/generic-foundation.d.ts.map +0 -1
  566. package/dist/site/generic-foundation.js +0 -91
@@ -1,4 +1,5 @@
1
- import { doorSlots } from '@pascal-app/core';
1
+ import { doorSlots, getDoorOpeningSize } from '@pascal-app/core';
2
+ import { NEW_DOOR_FRAME_THICKNESS } from '@pascal-app/core/building';
2
3
  import { curtainOpeningResizeMax } from '../shared/curtain-opening-limits.js';
3
4
  import { doorBatchable } from '../shared/node-batch/batchable.js';
4
5
  import { buildDoorFloorplanSchedule, computeDoorFloorplanLevelData, } from '../shared/opening-documentation.js';
@@ -54,7 +55,8 @@ function doorWidthHandle(side) {
54
55
  const roofMax = readRoofFaceWidthMax(n, scene, sign);
55
56
  if (roofMax !== null)
56
57
  return Math.max(MIN_DOOR_WIDTH, roofMax);
57
- return curtainOpeningResizeMax(n, scene.nodes(), 'x', sign) ?? readWallLength(n, scene);
58
+ return (curtainOpeningResizeMax(n, scene.nodes(), 'x', sign) ??
59
+ readWallLength(n, scene) - (getDoorOpeningSize(n).width - n.width));
58
60
  },
59
61
  currentValue: (n) => n.width,
60
62
  onDrag: (node) => publishOpeningResizeGuides(node, false),
@@ -80,7 +82,12 @@ function doorWidthHandle(side) {
80
82
  placement: {
81
83
  // door-local: +X axis lives along door's own X. Inner ride group
82
84
  // applies door.rotation, so we sit purely on door-local +X / -X.
83
- position: (n) => [sign * (n.width / 2 + SIDE_HANDLE_OFFSET), 0, 0],
85
+ position: (n) => [
86
+ -getDoorOpeningSize(n).leafOffsetX +
87
+ sign * (getDoorOpeningSize(n).width / 2 + SIDE_HANDLE_OFFSET),
88
+ 0,
89
+ 0,
90
+ ],
84
91
  rotationY: () => (side === 'right' ? 0 : Math.PI),
85
92
  },
86
93
  portal: 'grandparent',
@@ -100,7 +107,9 @@ function doorHeightHandle() {
100
107
  if (curtainMax !== undefined)
101
108
  return curtainMax;
102
109
  const bottom = n.position[1] - n.height / 2;
103
- return Math.max(MIN_DOOR_HEIGHT, readHostWallCeiling(n.wallId, scene, n) - bottom);
110
+ return Math.max(MIN_DOOR_HEIGHT, readHostWallCeiling(n.wallId, scene, n) -
111
+ bottom -
112
+ (getDoorOpeningSize(n).height - n.height));
104
113
  },
105
114
  currentValue: (n) => n.height,
106
115
  onDrag: (node) => publishOpeningResizeGuides(node, false),
@@ -115,7 +124,7 @@ function doorHeightHandle() {
115
124
  };
116
125
  },
117
126
  placement: {
118
- position: (n) => [0, n.height / 2 + HEIGHT_HANDLE_OFFSET, 0],
127
+ position: (n) => [0, getDoorOpeningSize(n).height - n.height / 2 + HEIGHT_HANDLE_OFFSET, 0],
119
128
  },
120
129
  portal: 'grandparent',
121
130
  };
@@ -205,6 +214,8 @@ export const doorDefinition = {
205
214
  'pascal:editor/floorplan': {
206
215
  contextualDimensions: buildDoorContextualDimensions,
207
216
  schedule: buildDoorFloorplanSchedule,
217
+ // Swap hinge / swing side from the action bar, in 2D and 3D.
218
+ actionMenu: { actions: () => import('./actions.js') },
208
219
  },
209
220
  },
210
221
  surfaceRole: 'joinery',
@@ -212,14 +223,30 @@ export const doorDefinition = {
212
223
  // full default shape — door has 40+ fields, listing them inline would
213
224
  // duplicate the schema. Parse a minimal stub, drop id/type, return rest.
214
225
  defaults: () => {
215
- const stub = DoorNode.parse({ id: 'door_default', type: 'door' });
226
+ const stub = DoorNode.parse({
227
+ id: 'door_default',
228
+ type: 'door',
229
+ frameThickness: NEW_DOOR_FRAME_THICKNESS,
230
+ casingFaceA: true,
231
+ casingFaceB: true,
232
+ });
216
233
  const { id: _id, type: _type, ...rest } = stub;
217
234
  return rest;
218
235
  },
219
236
  capabilities: {
220
237
  reveal: { phase: 'openings', style: 'cut' },
221
238
  exterior: openingSeenFromOutside,
222
- revealOnEdit: ['position', 'width', 'height', 'openingShape', 'openingKind', 'doorType'],
239
+ revealOnEdit: [
240
+ 'position',
241
+ 'width',
242
+ 'height',
243
+ 'sidelightLeft',
244
+ 'sidelightRight',
245
+ 'transomHeight',
246
+ 'openingShape',
247
+ 'openingKind',
248
+ 'doorType',
249
+ ],
223
250
  batchable: doorBatchable,
224
251
  selectable: { hitVolume: 'bbox' },
225
252
  duplicable: true,
@@ -1 +1 @@
1
- {"version":3,"file":"floorplan-affordances.d.ts","sourceRoot":"","sources":["../../src/door/floorplan-affordances.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,mBAAmB,EAMzB,MAAM,kBAAkB,CAAA;AAQzB;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,mBAAmB,EAAE,mBAAmB,CAAC,QAAQ,CAkF7D,CAAA"}
1
+ {"version":3,"file":"floorplan-affordances.d.ts","sourceRoot":"","sources":["../../src/door/floorplan-affordances.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,mBAAmB,EAQzB,MAAM,kBAAkB,CAAA;AAQzB;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,mBAAmB,EAAE,mBAAmB,CAAC,QAAQ,CAsF7D,CAAA"}
@@ -1,4 +1,4 @@
1
- import { getWallCurveLength, useLiveNodeOverrides, useScene, } from '@pascal-app/core';
1
+ import { getDoorOpeningSize, getWallCurveLength, openingHostFacing, useLiveNodeOverrides, useScene, } from '@pascal-app/core';
2
2
  import { curtainOpeningLimits } from '../shared/curtain-opening-limits.js';
3
3
  import { projectPlanPointToWallLocalX } from '../shared/wall-attach-target.js';
4
4
  const MIN_DOOR_WIDTH = 0.3;
@@ -37,7 +37,10 @@ export const doorWidthAffordance = {
37
37
  // legal width is the headroom on the grow side.
38
38
  const limits = curtainOpeningLimits(node, nodes);
39
39
  const margin = limits?.margin ?? 0;
40
- const maxWidth = growDir > 0 ? (limits?.length ?? wallLength) - margin - anchorX : anchorX - margin;
40
+ const size = getDoorOpeningSize(node);
41
+ const sidelight = (size.width - node.width) / 2 - growDir * size.leafOffsetX * openingHostFacing(node);
42
+ const maxWidth = (growDir > 0 ? (limits?.length ?? wallLength) - margin - anchorX : anchorX - margin) -
43
+ sidelight;
41
44
  const projectToWallLocalX = (planPoint) => {
42
45
  return wall ? projectPlanPointToWallLocalX(wall, planPoint) : planPoint[0];
43
46
  };
@@ -1 +1 @@
1
- {"version":3,"file":"floorplan-move.d.ts","sourceRoot":"","sources":["../../src/door/floorplan-move.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,mBAAmB,EAOzB,MAAM,kBAAkB,CAAA;AAoBzB;;;;;;;;;;;;;;GAcG;AAEH,eAAO,MAAM,uBAAuB,EAAE,mBAAmB,CAAC,QAAQ,CAsPjE,CAAA"}
1
+ {"version":3,"file":"floorplan-move.d.ts","sourceRoot":"","sources":["../../src/door/floorplan-move.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,QAAQ,EAEb,KAAK,mBAAmB,EASzB,MAAM,kBAAkB,CAAA;AAqBzB;;;;;;;;;;;;;;GAcG;AAEH,eAAO,MAAM,uBAAuB,EAAE,mBAAmB,CAAC,QAAQ,CA2RjE,CAAA"}
@@ -1,6 +1,7 @@
1
- import { useLiveNodeOverrides, useLiveTransforms, useScene, WallNode as WallNodeSchema, } from '@pascal-app/core';
1
+ import { doorPositionForFacing, getDoorOpeningSize, openingHostFacing, useLiveNodeOverrides, useLiveTransforms, useScene, WallNode as WallNodeSchema, } from '@pascal-app/core';
2
2
  import { isGridSnapActive, isMagneticSnapActive, snapToHalf, triggerSFX, useEditor, usePlacementPreview, } from '@pascal-app/editor';
3
3
  import { createFloorplanCursorResolver } from '../shared/floorplan-cursor.js';
4
+ import { movedOpeningCasingFaces } from '../shared/opening-casing-move.js';
4
5
  import { openingPlaneOffsetOnWall } from '../shared/opening-plane-offset.js';
5
6
  import { getOpeningHostLevelId, getRoofHostedOpeningPlanPoint } from '../shared/roof-opening-host.js';
6
7
  import { findClosestWallInPlan, projectWallLocalPointToPlan, resolveOpeningPlacement, snapLocalXToNeighbors, } from '../shared/wall-attach-target.js';
@@ -158,23 +159,37 @@ export const doorFloorplanMoveTarget = ({ node }) => {
158
159
  // openings / wall ends); it competes with — and wins over — the grid
159
160
  // snap. Follows the magnetic ("lines") mode; the grid component lives in
160
161
  // `snapToHalf` (mode-aware → raw when grid is off).
162
+ const facingX = doorPositionForFacing({ ...node, position: [hit.localX, node.position[1], node.position[2]] }, [0, hit.itemRotation + (flipped ? Math.PI : 0), 0])[0];
161
163
  const neighborX = !isMagneticSnapActive()
162
164
  ? null
163
165
  : snapLocalXToNeighbors({
164
166
  wall: hit.wall,
165
- localX: hit.localX,
166
- width: node.width,
167
+ localX: facingX -
168
+ getDoorOpeningSize(node).leafOffsetX *
169
+ openingHostFacing({ rotation: [0, hit.itemRotation + (flipped ? Math.PI : 0), 0] }),
170
+ width: getDoorOpeningSize(node).width,
167
171
  selfId: nodeId,
168
172
  nodes,
169
173
  });
170
- const snappedLocalX = neighborX ?? snapToHalf(hit.localX);
171
- const { clampedX, clampedY } = clampToWall(hit.wall, snappedLocalX, node.width, node.height);
174
+ const offset = getDoorOpeningSize(node).leafOffsetX *
175
+ openingHostFacing({ rotation: [0, hit.itemRotation + (flipped ? Math.PI : 0), 0] });
176
+ const snappedLocalX = neighborX === null
177
+ ? snapToHalf(facingX - offset) + offset
178
+ : neighborX +
179
+ getDoorOpeningSize(node).leafOffsetX *
180
+ openingHostFacing({ rotation: [0, hit.itemRotation + (flipped ? Math.PI : 0), 0] });
181
+ const { clampedX, clampedY, transomHeight } = clampToWall(hit.wall, snappedLocalX, node.width, node.height, {
182
+ ...node,
183
+ rotation: [0, hit.itemRotation + (flipped ? Math.PI : 0), 0],
184
+ }, nodes);
172
185
  // One click per real position step, keyed on the SNAPPED along-wall value
173
186
  // so it ticks only when the door actually moves to a new cell.
174
187
  tickGridStep(clampedX);
175
188
  // Apply the R-flip on top of the wall-derived side.
176
189
  const side = flipped ? (hit.side === 'front' ? 'back' : 'front') : hit.side;
177
190
  const itemRotation = hit.itemRotation + (flipped ? Math.PI : 0);
191
+ // Another wall may be drawn the other way round: the casing keeps to its side.
192
+ const casing = movedOpeningCasingFaces(node, hit.wall.id, [0, itemRotation, 0], nodes);
178
193
  lastValid = {
179
194
  // Same-wall moves keep the wall-local plane offset; another host resets it.
180
195
  position: [clampedX, clampedY, openingPlaneOffsetOnWall(node, hit.wall.id)],
@@ -187,6 +202,8 @@ export const doorFloorplanMoveTarget = ({ node }) => {
187
202
  roofSegmentId: undefined,
188
203
  roofFace: undefined,
189
204
  visible: true,
205
+ ...casing,
206
+ ...(transomHeight === undefined ? {} : { transomHeight }),
190
207
  };
191
208
  setLiveOverride(`wall:${hit.wall.id}:${side}`, {
192
209
  parentId: hit.wall.id,
@@ -195,6 +212,8 @@ export const doorFloorplanMoveTarget = ({ node }) => {
195
212
  roofSegmentId: undefined,
196
213
  roofFace: undefined,
197
214
  visible: true,
215
+ ...casing,
216
+ ...(transomHeight === undefined ? {} : { transomHeight }),
198
217
  });
199
218
  useLiveTransforms.getState().set(nodeId, {
200
219
  position: lastValid.position,
@@ -215,7 +234,10 @@ export const doorFloorplanMoveTarget = ({ node }) => {
215
234
  // Block commit if the door overlaps another wall child — UNLESS Alt
216
235
  // force-places (same `placeable` rule as the 3D move + the shared
217
236
  // `resolveOpeningPlacement`).
218
- const collides = hasWallChildOverlap(lastValid.parentId, useScene.getState().nodes, lastValid.position[0], lastValid.position[1], live.width, live.height, live.id);
237
+ const collides = hasWallChildOverlap(lastValid.parentId, useScene.getState().nodes, lastValid.position[0] -
238
+ getDoorOpeningSize({ ...live, ...lastValid }).leafOffsetX *
239
+ openingHostFacing({ rotation: lastValid.rotation }), lastValid.position[1] +
240
+ (getDoorOpeningSize({ ...live, ...lastValid }).height - live.height) / 2, getDoorOpeningSize({ ...live, ...lastValid }).width, getDoorOpeningSize({ ...live, ...lastValid }).height, live.id);
219
241
  return resolveOpeningPlacement({ collides, forcePlace }).placeable;
220
242
  },
221
243
  commit() {
@@ -23,6 +23,8 @@ import type { DoorNode, FloorplanGeometry, GeometryContext } from '@pascal-app/c
23
23
  * with no swing arc.
24
24
  * 4. Center line through the cutout (matches the legacy's
25
25
  * `getOpeningCenterLine` segment for visual continuity).
26
+ * 5. Casing legs standing proud of each cased wall face beside the
27
+ * cutout (`buildOpeningCasingPlan`).
26
28
  *
27
29
  * Requires `ctx.parent` to be a wall (door.parentId is the wall it's
28
30
  * mounted on). Returns null when the parent isn't a wall (orphaned
@@ -1 +1 @@
1
- {"version":3,"file":"floorplan.d.ts","sourceRoot":"","sources":["../../src/door/floorplan.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EACR,iBAAiB,EAEjB,eAAe,EAEhB,MAAM,kBAAkB,CAAA;AAczB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,eAAe,GAAG,iBAAiB,GAAG,IAAI,CAuxBjG"}
1
+ {"version":3,"file":"floorplan.d.ts","sourceRoot":"","sources":["../../src/door/floorplan.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EACR,iBAAiB,EAEjB,eAAe,EAEhB,MAAM,kBAAkB,CAAA;AAezB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,eAAe,GAAG,iBAAiB,GAAG,IAAI,CA+1BjG"}
@@ -1,5 +1,6 @@
1
- import { getWallBodyCenterOffset } from '@pascal-app/core';
1
+ import { getDoorOpeningSize, getWallBodyCenterOffset, openingHostFacing } from '@pascal-app/core';
2
2
  import { readFloorplanContext, readFloorplanGeometryMetadata, withFloorplanGeometryMetadata, } from '@pascal-app/editor';
3
+ import { buildOpeningCasingPlan } from '../shared/opening-casing.js';
3
4
  import { buildOpeningMarkAnnotation, } from '../shared/opening-documentation.js';
4
5
  import { buildOpeningPlacementDimensions } from '../shared/opening-placement-dimensions.js';
5
6
  import { resolveOpeningPlanPlane } from '../shared/opening-plane-offset.js';
@@ -27,6 +28,8 @@ import { resolveOpeningPlanPlane } from '../shared/opening-plane-offset.js';
27
28
  * with no swing arc.
28
29
  * 4. Center line through the cutout (matches the legacy's
29
30
  * `getOpeningCenterLine` segment for visual continuity).
31
+ * 5. Casing legs standing proud of each cased wall face beside the
32
+ * cutout (`buildOpeningCasingPlan`).
30
33
  *
31
34
  * Requires `ctx.parent` to be a wall (door.parentId is the wall it's
32
35
  * mounted on). Returns null when the parent isn't a wall (orphaned
@@ -54,6 +57,8 @@ export function buildDoorFloorplan(node, ctx) {
54
57
  const perpZ = dirX;
55
58
  const distance = node.position[0];
56
59
  const width = node.width;
60
+ const opening = getDoorOpeningSize(node);
61
+ const openingOffset = -opening.leafOffsetX * openingHostFacing(node);
57
62
  const wallDepth = wall.thickness ?? 0.1;
58
63
  const plane = resolveOpeningPlanPlane(node, wallDepth);
59
64
  const depth = plane.depth;
@@ -82,17 +87,41 @@ export function buildDoorFloorplan(node, ctx) {
82
87
  const swingAngle = Math.PI / 2;
83
88
  // Footprint rectangle in the cutout.
84
89
  const points = [
85
- [cx - dirX * halfWidth + perpX * halfDepth, cz - dirZ * halfWidth + perpZ * halfDepth],
86
- [cx + dirX * halfWidth + perpX * halfDepth, cz + dirZ * halfWidth + perpZ * halfDepth],
87
- [cx + dirX * halfWidth - perpX * halfDepth, cz + dirZ * halfWidth - perpZ * halfDepth],
88
- [cx - dirX * halfWidth - perpX * halfDepth, cz - dirZ * halfWidth - perpZ * halfDepth],
90
+ [
91
+ cx + dirX * openingOffset - dirX * (opening.width / 2) + perpX * halfDepth,
92
+ cz + dirZ * openingOffset - dirZ * (opening.width / 2) + perpZ * halfDepth,
93
+ ],
94
+ [
95
+ cx + dirX * openingOffset + dirX * (opening.width / 2) + perpX * halfDepth,
96
+ cz + dirZ * openingOffset + dirZ * (opening.width / 2) + perpZ * halfDepth,
97
+ ],
98
+ [
99
+ cx + dirX * openingOffset + dirX * (opening.width / 2) - perpX * halfDepth,
100
+ cz + dirZ * openingOffset + dirZ * (opening.width / 2) - perpZ * halfDepth,
101
+ ],
102
+ [
103
+ cx + dirX * openingOffset - dirX * (opening.width / 2) - perpX * halfDepth,
104
+ cz + dirZ * openingOffset - dirZ * (opening.width / 2) - perpZ * halfDepth,
105
+ ],
89
106
  ];
90
107
  const halfWallDepth = wallDepth / 2;
91
108
  const openingCutoutPoints = (ox, oz) => [
92
- [ox - dirX * halfWidth + perpX * halfWallDepth, oz - dirZ * halfWidth + perpZ * halfWallDepth],
93
- [ox + dirX * halfWidth + perpX * halfWallDepth, oz + dirZ * halfWidth + perpZ * halfWallDepth],
94
- [ox + dirX * halfWidth - perpX * halfWallDepth, oz + dirZ * halfWidth - perpZ * halfWallDepth],
95
- [ox - dirX * halfWidth - perpX * halfWallDepth, oz - dirZ * halfWidth - perpZ * halfWallDepth],
109
+ [
110
+ ox + dirX * openingOffset - dirX * (opening.width / 2) + perpX * halfWallDepth,
111
+ oz + dirZ * openingOffset - dirZ * (opening.width / 2) + perpZ * halfWallDepth,
112
+ ],
113
+ [
114
+ ox + dirX * openingOffset + dirX * (opening.width / 2) + perpX * halfWallDepth,
115
+ oz + dirZ * openingOffset + dirZ * (opening.width / 2) + perpZ * halfWallDepth,
116
+ ],
117
+ [
118
+ ox + dirX * openingOffset + dirX * (opening.width / 2) - perpX * halfWallDepth,
119
+ oz + dirZ * openingOffset + dirZ * (opening.width / 2) - perpZ * halfWallDepth,
120
+ ],
121
+ [
122
+ ox + dirX * openingOffset - dirX * (opening.width / 2) - perpX * halfWallDepth,
123
+ oz + dirZ * openingOffset - dirZ * (opening.width / 2) - perpZ * halfWallDepth,
124
+ ],
96
125
  ];
97
126
  const view = ctx.viewState;
98
127
  const palette = view?.palette;
@@ -134,6 +163,36 @@ export function buildDoorFloorplan(node, ctx) {
134
163
  strokeLinejoin: 'round',
135
164
  },
136
165
  ];
166
+ for (const [side, extra] of [
167
+ [-1, node.sidelightLeft ?? 0],
168
+ [1, node.sidelightRight ?? 0],
169
+ ]) {
170
+ if (!extra || opening.width === width)
171
+ continue;
172
+ const sign = side * openingHostFacing(node);
173
+ const a = (sign * width) / 2;
174
+ const b = sign * (width / 2 + extra);
175
+ children.push({
176
+ kind: 'polyline',
177
+ points: [
178
+ [cx + dirX * a, cz + dirZ * a],
179
+ [cx + dirX * b, cz + dirZ * b],
180
+ ],
181
+ fill: 'none',
182
+ stroke: accentColor,
183
+ strokeWidth: 2,
184
+ vectorEffect: 'non-scaling-stroke',
185
+ });
186
+ }
187
+ // Casing legs on the wall faces beside the cutout, as the 3D door has them.
188
+ const casing = buildOpeningCasingPlan(node, wall, {
189
+ fill: fillColor,
190
+ stroke: accentMuted,
191
+ strokeWidth: showSelectedChrome ? 1.4 : 1,
192
+ vectorEffect: 'non-scaling-stroke',
193
+ });
194
+ if (casing)
195
+ children.push(casing);
137
196
  if (node.openingShape !== 'rectangle') {
138
197
  const overheadRise = Math.min(width, node.openingShape === 'arch' ? node.archHeight : node.cornerRadius) * 0.2;
139
198
  const overheadSide = swingDirection === 'inward' ? 1 : -1;
@@ -263,8 +322,9 @@ export function buildDoorFloorplan(node, ctx) {
263
322
  // fall through to just the opening footprint (the earlier behaviour).
264
323
  const isSwingDoor = node.doorType === 'hinged' || isDoubleLeaf;
265
324
  // A frameless wall opening — drawn as a bare gap, no leaf / arc / panel
266
- // (mirrors the 3D system, which renders only the cutout for openings).
267
- const isOpening = node.openingKind === 'opening';
325
+ // (mirrors the 3D system, which renders only the cutout for openings). A
326
+ // door on a railing is always one: a gap in the guard.
327
+ const isOpening = node.openingKind === 'opening' || wall.wallType === 'railing';
268
328
  if (isOpening) {
269
329
  // Open doorway — a frameless gap in the wall. No leaf, arc, or panel;
270
330
  // the cleared footprint above is the whole symbol.
@@ -278,7 +338,7 @@ export function buildDoorFloorplan(node, ctx) {
278
338
  // The fold span / depth are fixed so the plan symbol stays static
279
339
  // regardless of the live open state.
280
340
  const FOLD_SPAN_RATIO = 0.8;
281
- const panelCount = node.leafCount === 2 ? 2 : 4;
341
+ const panelCount = node.leafCount >= 6 ? node.leafCount : node.leafCount === 2 ? 2 : 4;
282
342
  const panelLen = (width * FOLD_SPAN_RATIO) / panelCount;
283
343
  const peakDepth = panelLen * 0.7;
284
344
  // Anchor the accordion's base line on the room-facing wall face (the
@@ -287,7 +347,11 @@ export function buildDoorFloorplan(node, ctx) {
287
347
  const baseOffX = perpX * halfDepth * swingSign;
288
348
  const baseOffZ = perpZ * halfDepth * swingSign;
289
349
  // Start at the hinge edge and step toward the opposite jamb.
290
- const hingeTangentSign = hingesSide === 'left' ? 1 : -1;
350
+ const hingeTangentSign = panelCount > 4
351
+ ? (node.slideDirection === 'right' ? -1 : 1) * openingHostFacing(node)
352
+ : hingesSide === 'left'
353
+ ? 1
354
+ : -1;
291
355
  const startX = cx - dirX * halfWidth * hingeTangentSign + baseOffX;
292
356
  const startZ = cz - dirZ * halfWidth * hingeTangentSign + baseOffZ;
293
357
  const stepX = dirX * panelLen * hingeTangentSign;
@@ -322,7 +386,8 @@ export function buildDoorFloorplan(node, ctx) {
322
386
  // regardless of the live open state.
323
387
  const slideSign = node.slideDirection === 'right' ? 1 : -1;
324
388
  const panelHalfThick = Math.min(depth * 0.22, 0.03);
325
- const panelHalfLen = width * 0.275;
389
+ const panelCount = Math.max(2, Math.min(4, node.leafCount));
390
+ const panelHalfLen = panelCount === 2 ? width * 0.275 : width / panelCount / 2 + 0.01;
326
391
  const panelRect = (centerAlong, perpSign) => {
327
392
  const rcx = cx + dirX * centerAlong + perpX * panelHalfThick * perpSign;
328
393
  const rcz = cz + dirZ * centerAlong + perpZ * panelHalfThick * perpSign;
@@ -348,8 +413,16 @@ export function buildDoorFloorplan(node, ctx) {
348
413
  });
349
414
  // Left panel toward one face, right panel toward the other; they
350
415
  // overlap across the centre.
351
- pushPanel(panelRect(-halfWidth + panelHalfLen, 1));
352
- pushPanel(panelRect(halfWidth - panelHalfLen, -1));
416
+ for (let index = 0; index < panelCount; index++) {
417
+ const front = node.slidingStyle === 'bypass'
418
+ ? index % 2 === (panelCount === 3 || slideSign < 0 ? 1 : 0)
419
+ : panelCount === 4
420
+ ? index === 1 || index === 2
421
+ : panelCount === 3
422
+ ? index === 1
423
+ : index === (slideSign < 0 ? 1 : 0);
424
+ pushPanel(panelRect(-halfWidth + (width * (index + 0.5)) / panelCount, front ? 1 : -1));
425
+ }
353
426
  // Slide-direction arrow, centred and pushed clear of the wall face
354
427
  // so it doesn't overlap the wall or panels.
355
428
  const arrowPerp = -(halfDepth + Math.max(panelHalfThick * 4, halfWidth * 0.22));
@@ -1 +1 @@
1
- {"version":3,"file":"move-tool.d.ts","sourceRoot":"","sources":["../../src/door/move-tool.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,QAAQ,EAcT,MAAM,kBAAkB,CAAA;AAoDzB,QAAA,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAyjC9C,CAAA;eAEc,YAAY"}
1
+ {"version":3,"file":"move-tool.d.ts","sourceRoot":"","sources":["../../src/door/move-tool.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,QAAQ,EAqBT,MAAM,kBAAkB,CAAA;AAqDzB,QAAA,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CA8mC9C,CAAA;eAEc,YAAY"}
@@ -1,11 +1,12 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { beginSceneHistoryDraft, collectionIdsOf, DoorNode, emitter, getOpeningWallPlacement, holdHiddenWallPointerEvents, isCurvedWall, runSceneHistoryDraftWrite, sceneRegistry, spatialGridManager, useLiveTransforms, useScene, } from '@pascal-app/core';
2
+ import { beginSceneHistoryDraft, collectionIdsOf, DoorNode, doorPositionForFacing, emitter, getDoorOpeningSize, getOpeningWallPlacement, getWallThickness, holdHiddenWallPointerEvents, isCurvedWall, openingHostFacing, resolveHostedOpeningFrameDepth, resolveOpeningFrameDepth, runSceneHistoryDraftWrite, sceneRegistry, spatialGridManager, useLiveNodeOverrides, useLiveTransforms, useScene, } from '@pascal-app/core';
3
3
  import { calculateItemRotation, clearPlacementSurface, consumePlacementDragRelease, EDITOR_LAYER, getSideFromNormal, isGridSnapActive, isMagneticSnapActive, isValidWallSideFace, publishPlacementSurface, stripPlacementMetadataFlags, triggerSFX, useAlignmentGuides, useEditor, useFacingPose, } from '@pascal-app/editor';
4
4
  import { useViewer } from '@pascal-app/viewer';
5
5
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
6
6
  import { BoxGeometry, EdgesGeometry, Vector3 } from 'three';
7
7
  import { LineBasicNodeMaterial } from 'three/webgpu';
8
8
  import { commitOpeningMove } from '../shared/commit-opening-move.js';
9
+ import { movedOpeningCasingFaces } from '../shared/opening-casing-move.js';
9
10
  import { clearOpeningGuides3D, publishOpeningGuidesForWallEvent, } from '../shared/opening-guides-runtime.js';
10
11
  import { beginOpeningMoveHistorySession } from '../shared/opening-move-history.js';
11
12
  import { isWallMeshHidden, shouldIgnoreWallEventForOpeningMove, } from '../shared/opening-move-wall-gate.js';
@@ -40,9 +41,10 @@ const MoveDoorTool = ({ node: movingDoorNode }) => {
40
41
  const ghostNode = useMemo(() => ({
41
42
  ...movingDoorNode,
42
43
  side: ghostSide,
44
+ transomHeight: ghostPose?.transomHeight ?? movingDoorNode.transomHeight,
43
45
  position: [0, 0, 0],
44
46
  rotation: [0, 0, 0],
45
- }), [movingDoorNode, ghostSide]);
47
+ }), [movingDoorNode, ghostSide, ghostPose?.transomHeight]);
46
48
  const exitMoveMode = useCallback(() => {
47
49
  useEditor.getState().setMovingNode(null);
48
50
  }, []);
@@ -90,6 +92,8 @@ const MoveDoorTool = ({ node: movingDoorNode }) => {
90
92
  }
91
93
  // Same-wall moves keep the wall-local plane offset; another host resets it.
92
94
  const planeOffsetOn = (wallId) => openingPlaneOffsetOnWall(movingDoorNode, wallId);
95
+ // Another host may name its faces the other way round: the casing keeps to its side of it.
96
+ const casingOn = (hostId, rotation) => movedOpeningCasingFaces(movingDoorNode, hostId, rotation, useScene.getState().nodes);
93
97
  let currentHostId = movingDoorNode.parentId;
94
98
  let dragAnchor = null;
95
99
  // The wall the door was grabbed from. Nulled the first time the anchor
@@ -177,6 +181,7 @@ const MoveDoorTool = ({ node: movingDoorNode }) => {
177
181
  };
178
182
  const getSlabElevation = (wallEvent) => spatialGridManager.getSlabElevationForWall(wallEvent.node.parentId ?? '', wallEvent.node.start, wallEvent.node.end, wallEvent.node.curveOffset ?? 0, wallEvent.node.thickness, wallEvent.node.supportSlabId, wallEvent.node.justification);
179
183
  const hideCursor = () => {
184
+ useLiveNodeOverrides.getState().clearFields(movingDoorNode.id, ['transomHeight']);
180
185
  if (cursorGroupRef.current)
181
186
  cursorGroupRef.current.visible = false;
182
187
  useAlignmentGuides.getState().clear();
@@ -243,19 +248,36 @@ const MoveDoorTool = ({ node: movingDoorNode }) => {
243
248
  startX: preserveGrab ? original.position[0] : rawLocalX,
244
249
  };
245
250
  }
246
- const targetLocalX = dragAnchor.startX + (rawLocalX - dragAnchor.rawX);
251
+ const targetLocalX = doorPositionForFacing({
252
+ ...movingDoorNode,
253
+ position: [
254
+ dragAnchor.startX + (rawLocalX - dragAnchor.rawX),
255
+ movingDoorNode.position[1],
256
+ movingDoorNode.position[2],
257
+ ],
258
+ }, [0, itemRotation, 0])[0];
247
259
  const localX = resolveWallSlideAlignment({
248
260
  wallNode: event.node,
249
- rawLocalX: targetLocalX,
250
- width: movingDoorNode.width,
261
+ rawLocalX: targetLocalX -
262
+ getDoorOpeningSize(movingDoorNode).leafOffsetX *
263
+ openingHostFacing({ rotation: [0, itemRotation, 0] }),
264
+ width: getDoorOpeningSize(movingDoorNode).width,
251
265
  candidates: alignmentCandidates,
252
266
  // Along-wall alignment guides display in every snapping mode; the
253
267
  // magnetic pull onto them lands only in "lines" mode. The grid
254
268
  // component lives in `snapToHalf` (itself mode-aware).
255
269
  applySnap: isMagneticSnapActive(),
256
270
  });
257
- const { clampedX, clampedY } = clampToWall(event.node, localX, movingDoorNode.width, movingDoorNode.height);
258
- const valid = !hasWallChildOverlap(event.node.id, useScene.getState().nodes, clampedX, clampedY, movingDoorNode.width, movingDoorNode.height, movingDoorNode.id);
271
+ const { clampedX, clampedY, transomHeight } = clampToWall(event.node, localX +
272
+ getDoorOpeningSize(movingDoorNode).leafOffsetX *
273
+ openingHostFacing({ rotation: [0, itemRotation, 0] }), movingDoorNode.width, movingDoorNode.height, { ...movingDoorNode, rotation: [0, itemRotation, 0] }, useScene.getState().nodes);
274
+ const fittedSize = getDoorOpeningSize({
275
+ ...movingDoorNode,
276
+ transomHeight: transomHeight ?? movingDoorNode.transomHeight,
277
+ });
278
+ const valid = !hasWallChildOverlap(event.node.id, useScene.getState().nodes, clampedX -
279
+ getDoorOpeningSize(movingDoorNode).leafOffsetX *
280
+ openingHostFacing({ rotation: [0, itemRotation, 0] }), clampedY + (fittedSize.height - movingDoorNode.height) / 2, fittedSize.width, fittedSize.height, movingDoorNode.id);
259
281
  return {
260
282
  wallNode: event.node,
261
283
  wallId: event.node.id,
@@ -264,10 +286,15 @@ const MoveDoorTool = ({ node: movingDoorNode }) => {
264
286
  clampedX,
265
287
  clampedY,
266
288
  valid,
289
+ transomHeight,
267
290
  event,
268
291
  };
269
292
  };
270
293
  const applyPreview = (target) => {
294
+ if (target.transomHeight !== undefined)
295
+ useLiveNodeOverrides
296
+ .getState()
297
+ .set(movingDoorNode.id, { transomHeight: target.transomHeight });
271
298
  // One grid-snap tick per real position step, keyed on the SNAPPED
272
299
  // along-wall position so it ticks only when the door actually moves to a
273
300
  // new cell (not on every micro mouse-move). Per-frame guard collapses any
@@ -336,29 +363,36 @@ const MoveDoorTool = ({ node: movingDoorNode }) => {
336
363
  rotationY: ghostYaw,
337
364
  tint: placement.tint,
338
365
  side: target.side,
366
+ transomHeight: target.transomHeight,
339
367
  });
340
368
  // Forward-facing triangle (editor-side overlay), in the same building-local
341
369
  // frame the ghost renders in. The door's front is its local +Z. Drop it to
342
- // the floor under the wall (the ghost Y is the opening centre, ~1m up).
370
+ // the door's sill (the ghost Y is the opening centre, ~1m up).
343
371
  useFacingPose.getState().set({
344
372
  position: [
345
373
  ghostWorldPos[0],
346
- getLevelYOffset() + getSlabElevation(target.event),
374
+ ghostWorldPos[1] - movingDoorNode.height / 2,
347
375
  ghostWorldPos[2],
348
376
  ],
349
377
  rotationY: ghostYaw,
350
- depth: movingDoorNode.frameDepth ?? 0.07,
378
+ depth: resolveOpeningFrameDepth(movingDoorNode, getWallThickness(target.wallNode)),
351
379
  });
352
380
  // Publish the wall surface so the snap grid tilts into the wall plane at
353
381
  // the opening (its outward normal is the door's facing, +Z by `ghostYaw`).
354
382
  publishPlacementSurface(new Vector3(...ghostWorldPos), new Vector3(Math.sin(ghostYaw), 0, Math.cos(ghostYaw)));
383
+ const fittedSize = getDoorOpeningSize({
384
+ ...movingDoorNode,
385
+ transomHeight: target.transomHeight ?? movingDoorNode.transomHeight,
386
+ });
355
387
  publishOpeningGuidesForWallEvent({
356
388
  wall: target.wallNode,
357
389
  movingId: movingDoorNode.id,
358
- centerS: target.clampedX,
359
- centerY: target.clampedY,
360
- width: movingDoorNode.width,
361
- height: movingDoorNode.height,
390
+ centerS: target.clampedX -
391
+ getDoorOpeningSize(movingDoorNode).leafOffsetX *
392
+ openingHostFacing({ rotation: [0, target.itemRotation, 0] }),
393
+ centerY: target.clampedY + (fittedSize.height - movingDoorNode.height) / 2,
394
+ width: getDoorOpeningSize(movingDoorNode).width,
395
+ height: fittedSize.height,
362
396
  // Doors sit on the floor — no sill/head or vertical alignment guides.
363
397
  includeVertical: false,
364
398
  levelYOffset: getLevelYOffset(),
@@ -437,8 +471,10 @@ const MoveDoorTool = ({ node: movingDoorNode }) => {
437
471
  position: [target.clampedX, target.clampedY, planeOffsetOn(target.wallId)],
438
472
  rotation: [0, target.itemRotation, 0],
439
473
  side: target.side,
474
+ ...(target.transomHeight === undefined ? {} : { transomHeight: target.transomHeight }),
440
475
  wallId: target.wallId,
441
476
  parentId: target.wallId,
477
+ ...casingOn(target.wallId, [0, target.itemRotation, 0]),
442
478
  roofSegmentId: undefined,
443
479
  roofFace: undefined,
444
480
  // The moving node is hidden during free-follow; the committed door
@@ -472,8 +508,10 @@ const MoveDoorTool = ({ node: movingDoorNode }) => {
472
508
  position: [target.clampedX, target.clampedY, planeOffsetOn(target.wallId)],
473
509
  rotation: [0, target.itemRotation, 0],
474
510
  side: target.side,
511
+ ...(target.transomHeight === undefined ? {} : { transomHeight: target.transomHeight }),
475
512
  parentId: target.wallId,
476
513
  wallId: target.wallId,
514
+ ...casingOn(target.wallId, [0, target.itemRotation, 0]),
477
515
  roofSegmentId: undefined,
478
516
  visible: true,
479
517
  });
@@ -625,6 +663,7 @@ const MoveDoorTool = ({ node: movingDoorNode }) => {
625
663
  width: movingDoorNode.width,
626
664
  height: movingDoorNode.height,
627
665
  ignoreId: movingDoorNode.id,
666
+ opening: movingDoorNode,
628
667
  vertical: { kind: 'bottom-locked' },
629
668
  });
630
669
  const updateRoofCursor = (target, roof) => {
@@ -709,6 +748,7 @@ const MoveDoorTool = ({ node: movingDoorNode }) => {
709
748
  roofSegmentId: segmentId,
710
749
  roofFace: target.face.id,
711
750
  parentId: segmentId,
751
+ ...casingOn(segmentId, [0, 0, 0]),
712
752
  visible: true,
713
753
  });
714
754
  history.commitStep(() => {
@@ -741,6 +781,7 @@ const MoveDoorTool = ({ node: movingDoorNode }) => {
741
781
  wallId: undefined,
742
782
  roofSegmentId: segmentId,
743
783
  roofFace: target.face.id,
784
+ ...casingOn(segmentId, [0, 0, 0]),
744
785
  visible: true,
745
786
  });
746
787
  });
@@ -852,9 +893,11 @@ const MoveDoorTool = ({ node: movingDoorNode }) => {
852
893
  // No preview yet (R pressed before the first pointermove at initial
853
894
  // placement): flip the hidden node so the FIRST preview/commit already
854
895
  // reflects the chosen side.
896
+ const rotation = [0, sideOverride === 'back' ? Math.PI : 0, 0];
855
897
  updateDraft({
856
898
  side: sideOverride,
857
- rotation: [0, sideOverride === 'back' ? Math.PI : 0, 0],
899
+ rotation,
900
+ position: doorPositionForFacing(movingDoorNode, rotation),
858
901
  });
859
902
  }
860
903
  };
@@ -940,6 +983,7 @@ const MoveDoorTool = ({ node: movingDoorNode }) => {
940
983
  updateDraft({ visible: true });
941
984
  }
942
985
  useLiveTransforms.getState().clear(movingDoorNode.id);
986
+ useLiveNodeOverrides.getState().clearFields(movingDoorNode.id, ['transomHeight']);
943
987
  useAlignmentGuides.getState().clear();
944
988
  clearOpeningGuides3D();
945
989
  useFacingPose.getState().clear();
@@ -964,7 +1008,7 @@ const MoveDoorTool = ({ node: movingDoorNode }) => {
964
1008
  };
965
1009
  }, [movingDoorNode, exitMoveMode]);
966
1010
  const edgesGeo = useMemo(() => {
967
- const boxGeo = new BoxGeometry(movingDoorNode.width, movingDoorNode.height, movingDoorNode.frameDepth ?? 0.07);
1011
+ const boxGeo = new BoxGeometry(movingDoorNode.width, movingDoorNode.height, resolveHostedOpeningFrameDepth(movingDoorNode, useScene.getState().nodes));
968
1012
  const geo = new EdgesGeometry(boxGeo);
969
1013
  boxGeo.dispose();
970
1014
  return geo;
@@ -1,8 +1,3 @@
1
- /**
2
- * Door paint on the unified slot model. The door's opening proxy (a proud,
3
- * invisible cutout) wins the shared scene raycast over the wall in front of the
4
- * recessed door body, so `resolveSlotByReRaycast` re-raycasts the door's own
5
- * subtree to find the part (panel / frame / glass / hardware) under the cursor.
6
- */
7
- export declare const doorPaint: import("@pascal-app/core").PaintCapability;
1
+ import { type PaintCapability } from '@pascal-app/core';
2
+ export declare const doorPaint: PaintCapability;
8
3
  //# sourceMappingURL=paint.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"paint.d.ts","sourceRoot":"","sources":["../../src/door/paint.ts"],"names":[],"mappings":"AAMA;;;;;GAKG;AACH,eAAO,MAAM,SAAS,4CAOpB,CAAA"}
1
+ {"version":3,"file":"paint.d.ts","sourceRoot":"","sources":["../../src/door/paint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,eAAe,EAA+C,MAAM,kBAAkB,CAAA;AAiCpG,eAAO,MAAM,SAAS,EAAE,eAQvB,CAAA"}