@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,8 +1,12 @@
1
- import { getActiveRoofHeight, getPitchFromActiveRoofHeight, getRoofSegmentResizePatch, RoofSegmentNode as RoofSegmentNodeSchema, } from '@pascal-app/core';
1
+ import { getActiveRoofHeight, getPitchFromActiveRoofHeight, getRoofSegmentResizePatch, RoofSegmentNode as RoofSegmentNodeSchema, snapScalar, } from '@pascal-app/core';
2
+ import { getSegmentGridStep, isGridSnapActive, isMagneticSnapActive, PANEL_MODEL_EXTENSION, } from '@pascal-app/editor';
3
+ import { roofFloorplanAffectedIds } from '../roof/floorplan-overrides.js';
4
+ import { bearingWallThickness, catchRoofSideOnWalls, roofCatchWalls, segmentWallLine, } from '../roof/wall-catch.js';
2
5
  import { buildRoofSegmentFloorplan } from './floorplan.js';
3
6
  import { roofSegmentMoveTarget, roofSegmentResizeAffordance, roofSegmentRotateAffordance, } from './floorplan-affordances.js';
4
7
  import { matchRoofSegmentMeasurementFeature, roofSegmentMeasurementFeatures } from './measurement.js';
5
8
  import { roofSegmentPaint, roofSegmentSlots } from './paint.js';
9
+ import { roofSegmentPanelModel } from './panel-model.js';
6
10
  import { roofSegmentParametrics } from './parametrics.js';
7
11
  import { RoofSegmentNode } from './schema.js';
8
12
  const SIDE_HANDLE_OFFSET = 0.3;
@@ -33,6 +37,42 @@ function getSideResizeHandleY(n, localZ) {
33
37
  const roofY = n.wallHeight + roofHeight * (1 - Math.max(0, Math.min(1, t)));
34
38
  return Math.max(roofY, MIN_WALL_DISPLAY) + ROOF_HANDLE_CLEARANCE;
35
39
  }
40
+ function roofOf(n, sceneApi) {
41
+ const roof = n.parentId ? sceneApi?.get(n.parentId) : undefined;
42
+ return roof?.type === 'roof' ? roof : undefined;
43
+ }
44
+ // A dragged side lands on a wall under it in grid and lines, ahead of the grid, as a move does.
45
+ // The arrows leave `gridSnap` off so the catch sees the raw size, and grid it here when nothing
46
+ // catches; Alt skips this hook, so the side follows the cursor.
47
+ function snapSideOntoWalls(axis, side) {
48
+ return (n, value, sceneApi) => {
49
+ const grid = isGridSnapActive();
50
+ if (!grid && !isMagneticSnapActive())
51
+ return value;
52
+ const roof = roofOf(n, sceneApi);
53
+ if (roof) {
54
+ const caught = catchRoofSideOnWalls({
55
+ line: segmentWallLine(roof, n),
56
+ axis,
57
+ side,
58
+ value,
59
+ walls: roofCatchWalls(sceneApi.nodes(), roof.parentId),
60
+ });
61
+ if (caught !== null)
62
+ return caught;
63
+ }
64
+ return grid ? snapScalar(value, getSegmentGridStep()) : value;
65
+ };
66
+ }
67
+ // Sized onto the walls under it, a segment's gable and heel walls take their thickness; off them,
68
+ // its own (written either way, so a drag back off the walls drops the thickness it previewed).
69
+ function onBearingWalls(n, patch, sceneApi) {
70
+ const roof = roofOf(n, sceneApi);
71
+ if (!(roof && sceneApi))
72
+ return patch;
73
+ const thickness = bearingWallThickness(segmentWallLine(roof, { ...n, ...patch }), roofCatchWalls(sceneApi.nodes(), roof.parentId));
74
+ return { ...patch, wallThickness: thickness ?? n.wallThickness };
75
+ }
36
76
  // Width arrow on the +X (right) or -X (left) side. Asymmetric resize:
37
77
  // dragging one arrow grows the segment outward from its own edge while
38
78
  // the opposite edge stays world-fixed — the same pattern doors use
@@ -54,9 +94,9 @@ function roofSegmentWidthHandle(side) {
54
94
  // 'max' = +X edge anchored (left arrow grows the -X edge outward).
55
95
  anchor: side === 'right' ? 'min' : 'max',
56
96
  min: MIN_ROOF_DIM,
57
- gridSnap: true,
97
+ connectionSnap: snapSideOntoWalls('x', sign),
58
98
  currentValue: (n) => n.width,
59
- apply: (initial, newWidth) => getRoofSegmentResizePatch(initial, 'x', sign, newWidth),
99
+ apply: (initial, newWidth, sceneApi) => onBearingWalls(initial, getRoofSegmentResizePatch(initial, 'x', sign, newWidth), sceneApi),
60
100
  placement: {
61
101
  position: (n) => [sign * (n.width / 2 + SIDE_HANDLE_OFFSET), getSideResizeHandleY(n, 0), 0],
62
102
  // Flip the left chevron so it points outward toward -X. The
@@ -82,9 +122,9 @@ function roofSegmentDepthHandle(side) {
82
122
  axis: 'z',
83
123
  anchor: side === 'front' ? 'min' : 'max',
84
124
  min: MIN_ROOF_DIM,
85
- gridSnap: true,
125
+ connectionSnap: snapSideOntoWalls('z', sign),
86
126
  currentValue: (n) => n.depth,
87
- apply: (initial, newDepth) => getRoofSegmentResizePatch(initial, 'z', sign, newDepth),
127
+ apply: (initial, newDepth, sceneApi) => onBearingWalls(initial, getRoofSegmentResizePatch(initial, 'z', sign, newDepth), sceneApi),
88
128
  placement: {
89
129
  position: (n) => [
90
130
  0,
@@ -247,6 +287,9 @@ export const roofSegmentDefinition = {
247
287
  // snapping chip and honours the active mode like every other structural
248
288
  // move. Resize / rotate run through their own reshaping scope.
249
289
  snapProfile: 'structural',
290
+ extensions: {
291
+ [PANEL_MODEL_EXTENSION]: roofSegmentPanelModel,
292
+ },
250
293
  defaults: () => {
251
294
  const stub = RoofSegmentNodeSchema.parse({
252
295
  id: 'roof-segment_default',
@@ -291,6 +334,8 @@ export const roofSegmentDefinition = {
291
334
  module: () => import('./renderer.js'),
292
335
  },
293
336
  floorplan: buildRoofSegmentFloorplan,
337
+ // Its roof draws the outline and creases from it: a live edit rebuilds that roof's plan.
338
+ floorplanAffectedIds: roofFloorplanAffectedIds,
294
339
  measurement: {
295
340
  features: (node, ctx) => roofSegmentMeasurementFeatures(node, ctx.parent?.type === 'roof' ? ctx.parent : null),
296
341
  match: (node, ctx, point, maxDistance) => matchRoofSegmentMeasurementFeature(node, ctx.parent?.type === 'roof' ? ctx.parent : null, point, maxDistance),
@@ -1 +1 @@
1
- {"version":3,"file":"floorplan-affordances.d.ts","sourceRoot":"","sources":["../../src/roof-segment/floorplan-affordances.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EAGxB,KAAK,eAAe,EAIrB,MAAM,kBAAkB,CAAA;AA6CzB;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,EAAE,mBAAmB,CAAC,eAAe,CAmF5E,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,EAAE,mBAAmB,CAAC,eAAe,CA8B5E,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,EAAE,mBAAmB,CAAC,eAAe,CA4CtE,CAAA"}
1
+ {"version":3,"file":"floorplan-affordances.d.ts","sourceRoot":"","sources":["../../src/roof-segment/floorplan-affordances.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EAGxB,KAAK,eAAe,EAIrB,MAAM,kBAAkB,CAAA;AA0DzB;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,EAAE,mBAAmB,CAAC,eAAe,CAyG5E,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,EAAE,mBAAmB,CAAC,eAAe,CA8B5E,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,EAAE,mBAAmB,CAAC,eAAe,CAyEtE,CAAA"}
@@ -1,6 +1,7 @@
1
1
  import { getRoofSegmentResizePatch, snapScalar, useLiveNodeOverrides, useScene, } from '@pascal-app/core';
2
- import { getSegmentGridStep, isAngleSnapActive, isGridSnapActive } from '@pascal-app/editor';
2
+ import { getSegmentGridStep, isAngleSnapActive, isGridSnapActive, isMagneticSnapActive, } from '@pascal-app/editor';
3
3
  import { commitSeatedRoofEdit } from '../roof/roof-level-target.js';
4
+ import { bearingWallThickness, catchRoofOnWalls, catchRoofSideOnWalls, placeRoofOnWalls, roofCatchWalls, segmentWallLine, } from '../roof/wall-catch.js';
4
5
  import { createFloorplanCursorResolver } from '../shared/floorplan-cursor.js';
5
6
  import { rotateAffordanceDelta } from '../shared/rotate-affordance.js';
6
7
  const MIN_ROOF_DIM = 1;
@@ -68,6 +69,16 @@ export const roofSegmentResizeAffordance = {
68
69
  const { axis, side } = resize;
69
70
  const initialValue = axis === 'x' ? node.width : node.depth;
70
71
  const { effRot } = resolveSegmentFrame(node, nodes);
72
+ const roofId = node.parentId;
73
+ const roof = roofId ? nodes[roofId] : undefined;
74
+ const walls = roofCatchWalls(nodes, roof?.parentId);
75
+ const line = {
76
+ center: [cx, cz],
77
+ angle: effRot,
78
+ hw: node.width / 2,
79
+ hd: node.depth / 2,
80
+ wallThickness: node.wallThickness,
81
+ };
71
82
  const cosEff = Math.cos(effRot);
72
83
  const sinEff = Math.sin(effRot);
73
84
  // Project (planPoint - center) onto the segment's local X or Z axis
@@ -80,22 +91,34 @@ export const roofSegmentResizeAffordance = {
80
91
  };
81
92
  const initialLocal = projectLocalAxis(initialPlanPoint[0], initialPlanPoint[1]);
82
93
  let lastValue = initialValue;
94
+ // Sized onto the walls under it, its gable and heel walls take their thickness; off them, it
95
+ // keeps its own (the live override merges, so it is always written).
96
+ const resized = (value) => {
97
+ const patch = getRoofSegmentResizePatch(node, axis, side, value);
98
+ const thickness = bearingWallThickness(segmentWallLine(roof ?? { position: [0, 0, 0], rotation: 0 }, { ...node, ...patch }), walls);
99
+ return { ...patch, wallThickness: thickness ?? node.wallThickness };
100
+ };
83
101
  return {
84
102
  affectedIds: [segmentId],
85
- apply({ planPoint }) {
103
+ apply({ planPoint, modifiers }) {
86
104
  const currentLocal = projectLocalAxis(planPoint[0], planPoint[1]);
87
105
  const delta = (currentLocal - initialLocal) * side;
88
106
  const rawValue = initialValue + delta;
89
107
  // Mode-aware grid step (0 outside grid mode, so `lines` / `off` resize
90
108
  // freely — the "smooth" behaviour that used to need a held Shift). The
91
109
  // reshaping scope opened by the dispatcher resolves the `polygon` set.
92
- const step = isGridSnapActive() ? getSegmentGridStep() : 0;
93
- const snappedValue = step > 0 ? snapScalar(rawValue, step) : rawValue;
110
+ // Alt holds the raw cursor, as in 3D.
111
+ const free = modifiers.altKey;
112
+ const step = !free && isGridSnapActive() ? getSegmentGridStep() : 0;
113
+ let snappedValue = step > 0 ? snapScalar(rawValue, step) : rawValue;
114
+ // The dragged side lands on a wall under it in grid and lines, as a move does.
115
+ if (!free && (isGridSnapActive() || isMagneticSnapActive())) {
116
+ snappedValue =
117
+ catchRoofSideOnWalls({ line, axis, side, value: rawValue, walls }) ?? snappedValue;
118
+ }
94
119
  const newValue = Math.max(MIN_ROOF_DIM, snappedValue);
95
120
  lastValue = newValue;
96
- useLiveNodeOverrides
97
- .getState()
98
- .set(segmentId, getRoofSegmentResizePatch(node, axis, side, newValue));
121
+ useLiveNodeOverrides.getState().set(segmentId, resized(newValue));
99
122
  useScene.getState().markDirty(segmentId);
100
123
  },
101
124
  canCommit() {
@@ -103,7 +126,7 @@ export const roofSegmentResizeAffordance = {
103
126
  },
104
127
  commit() {
105
128
  useLiveNodeOverrides.getState().clear(segmentId);
106
- commitSeatedRoofEdit([{ id: segmentId, data: getRoofSegmentResizePatch(node, axis, side, lastValue) }], segmentId);
129
+ commitSeatedRoofEdit([{ id: segmentId, data: resized(lastValue) }], segmentId);
107
130
  },
108
131
  };
109
132
  },
@@ -158,7 +181,7 @@ export const roofSegmentRotateAffordance = {
158
181
  export const roofSegmentMoveTarget = ({ node, nodes }) => {
159
182
  const segmentId = node.id;
160
183
  const initialY = node.position[1];
161
- const { cx, cz, roofRot, cosRoof, sinRoof } = resolveSegmentFrame(node, nodes);
184
+ const { cx, cz, effRot, cosRoof, sinRoof } = resolveSegmentFrame(node, nodes);
162
185
  const roofId = node.parentId;
163
186
  const roof = roofId ? nodes[roofId] : undefined;
164
187
  const roofPosX = roof?.position[0] ?? 0;
@@ -167,26 +190,52 @@ export const roofSegmentMoveTarget = ({ node, nodes }) => {
167
190
  original: [cx, cz],
168
191
  metadata: node.metadata,
169
192
  });
170
- // Inverse of the forward transform `[cosRoof, -sinRoof; sinRoof, cosRoof]`
171
- // is `[cosRoof, sinRoof; -sinRoof, cosRoof]`. Used to project world cursor
172
- // back into roof-local coords.
173
- void roofRot;
193
+ const walls = roofCatchWalls(nodes, roof?.parentId);
174
194
  let lastLocal = [node.position[0], node.position[1], node.position[2]];
195
+ // Off them again, it keeps its own (the live override merges, so it is always written).
196
+ let lastThickness = node.wallThickness;
197
+ const moved = () => ({
198
+ position: lastLocal,
199
+ wallThickness: lastThickness,
200
+ });
175
201
  return {
176
202
  affectedIds: [segmentId],
177
- apply({ planPoint }) {
203
+ apply({ planPoint, modifiers }) {
178
204
  // Mode-aware: `getSegmentGridStep()` is 0 outside grid mode (so `lines` /
179
205
  // `off` move freely), and the `moving` scope resolves the `polygon` set
180
- // via the kind's `snapProfile` — no held-Shift bypass.
181
- const step = isGridSnapActive() ? getSegmentGridStep() : 0;
206
+ // via the kind's `snapProfile` — no held-Shift bypass. Alt holds the raw cursor, as in 3D.
207
+ const free = modifiers.altKey;
208
+ const step = !free && isGridSnapActive() ? getSegmentGridStep() : 0;
182
209
  const snap = (value) => snapScalar(value, step);
183
- const worldPoint = resolveCursor(planPoint, { snap });
210
+ const raw = resolveCursor(planPoint);
211
+ let worldPoint = resolveCursor(planPoint, { snap });
212
+ // Its wall line lands on the walls under it in grid and lines, its outer face on a porch's
213
+ // invisible walls or a deck's railings.
214
+ if (!free && (isGridSnapActive() || isMagneticSnapActive())) {
215
+ const caught = catchRoofOnWalls({
216
+ lines: [
217
+ {
218
+ center: raw,
219
+ angle: effRot,
220
+ hw: node.width / 2,
221
+ hd: node.depth / 2,
222
+ wallThickness: node.wallThickness,
223
+ },
224
+ ],
225
+ walls,
226
+ angle: effRot,
227
+ });
228
+ worldPoint = placeRoofOnWalls(raw, worldPoint, caught, effRot);
229
+ }
184
230
  const dx = worldPoint[0] - roofPosX;
185
231
  const dz = worldPoint[1] - roofPosZ;
186
232
  let localX = dx * cosRoof + dz * sinRoof;
187
233
  let localZ = -dx * sinRoof + dz * cosRoof;
188
234
  lastLocal = [localX, initialY, localZ];
189
- useLiveNodeOverrides.getState().set(segmentId, { position: lastLocal });
235
+ // Moved onto the walls under it, its gable and heel walls take their thickness.
236
+ lastThickness =
237
+ bearingWallThickness({ center: worldPoint, angle: effRot, hw: node.width / 2, hd: node.depth / 2 }, walls) ?? node.wallThickness;
238
+ useLiveNodeOverrides.getState().set(segmentId, moved());
190
239
  useScene.getState().markDirty(segmentId);
191
240
  },
192
241
  canCommit() {
@@ -195,7 +244,7 @@ export const roofSegmentMoveTarget = ({ node, nodes }) => {
195
244
  commit() {
196
245
  useLiveNodeOverrides.getState().clear(segmentId);
197
246
  // Dragged onto the walls that carry it, its roof goes to the level above them.
198
- commitSeatedRoofEdit([{ id: segmentId, data: { position: lastLocal } }], segmentId);
247
+ commitSeatedRoofEdit([{ id: segmentId, data: moved() }], segmentId);
199
248
  },
200
249
  };
201
250
  };
@@ -1 +1 @@
1
- {"version":3,"file":"floorplan.d.ts","sourceRoot":"","sources":["../../src/roof-segment/floorplan.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iBAAiB,EAEtB,KAAK,eAAe,EAIpB,KAAK,eAAe,EACrB,MAAM,kBAAkB,CAAA;AAEzB;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,eAAe,EACrB,GAAG,EAAE,eAAe,GACnB,iBAAiB,GAAG,IAAI,CAiM1B;AAED,MAAM,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AAC9C,MAAM,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AAE/C,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,EAAE,CAY3E;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,eAAe,GAAG;IACjE,MAAM,EAAE,OAAO,EAAE,CAAA;IACjB,IAAI,EAAE,OAAO,EAAE,CAAA;IACf,MAAM,EAAE,OAAO,EAAE,CAAA;IACjB,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;CAC7C,CA0GA"}
1
+ {"version":3,"file":"floorplan.d.ts","sourceRoot":"","sources":["../../src/roof-segment/floorplan.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iBAAiB,EAEtB,KAAK,eAAe,EAKpB,KAAK,eAAe,EACrB,MAAM,kBAAkB,CAAA;AAEzB;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,eAAe,EACrB,GAAG,EAAE,eAAe,GACnB,iBAAiB,GAAG,IAAI,CAwM1B;AAED,MAAM,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AAC9C,MAAM,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AAE/C,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,EAAE,CAY3E;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,eAAe,GAAG;IACjE,MAAM,EAAE,OAAO,EAAE,CAAA;IACjB,IAAI,EAAE,OAAO,EAAE,CAAA;IACf,MAAM,EAAE,OAAO,EAAE,CAAA;IACjB,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;CAC7C,CA0GA"}
@@ -1,4 +1,4 @@
1
- import { getConicalRoofCoverage, getDutchRoofMetrics, } from '@pascal-app/core';
1
+ import { getConicalRoofCoverage, getDutchRoofMetrics, getRoofSegmentVisibleTopBounds, } from '@pascal-app/core';
2
2
  /**
3
3
  * Stage C floor-plan builder for roof segment. Renders the segment as a
4
4
  * proper architectural roof plan: the footprint outline plus the
@@ -52,7 +52,8 @@ export function buildRoofSegmentFloorplan(node, ctx) {
52
52
  const palette = view?.palette;
53
53
  const isSelected = view?.selected ?? false;
54
54
  const isHighlighted = view?.highlighted ?? false;
55
- const showSelectedChrome = isSelected || isHighlighted;
55
+ // Moved too: the wall line shows whether it lands on the walls' centre lines.
56
+ const showSelectedChrome = isSelected || isHighlighted || (view?.moving ?? false);
56
57
  // Black architectural outline by default; palette accent on select.
57
58
  // Mirrors the elevator / column style so all structural elements read
58
59
  // the same in the floor plan.
@@ -129,9 +130,8 @@ export function buildRoofSegmentFloorplan(node, ctx) {
129
130
  point: [cx, cz],
130
131
  });
131
132
  const sideArrowOffset = 0.12;
132
- const rotateCornerOffset = 0.22;
133
+ const rotateCornerOffset = 0.3;
133
134
  const halfW = node.width / 2;
134
- const halfD = node.depth / 2;
135
135
  // Effective rotation = parent roof rotation + segment-local rotation.
136
136
  // Reuse `cos` / `sin` from the corner computation above (they were
137
137
  // computed for the same `rotation` value).
@@ -151,11 +151,13 @@ export function buildRoofSegmentFloorplan(node, ctx) {
151
151
  });
152
152
  }
153
153
  else {
154
+ // Past the eaves and rakes the plan outlines, so the arrows sit clear of the roof's edge.
155
+ const eave = getRoofSegmentVisibleTopBounds(node);
154
156
  const sides = [
155
- { local: [halfW + sideArrowOffset, 0], localAngle: 0, axis: 'x', side: 1 },
156
- { local: [-(halfW + sideArrowOffset), 0], localAngle: Math.PI, axis: 'x', side: -1 },
157
- { local: [0, halfD + sideArrowOffset], localAngle: Math.PI / 2, axis: 'z', side: 1 },
158
- { local: [0, -(halfD + sideArrowOffset)], localAngle: -Math.PI / 2, axis: 'z', side: -1 },
157
+ { local: [eave.maxX + sideArrowOffset, 0], localAngle: 0, axis: 'x', side: 1 },
158
+ { local: [eave.minX - sideArrowOffset, 0], localAngle: Math.PI, axis: 'x', side: -1 },
159
+ { local: [0, eave.maxZ + sideArrowOffset], localAngle: Math.PI / 2, axis: 'z', side: 1 },
160
+ { local: [0, eave.minZ - sideArrowOffset], localAngle: -Math.PI / 2, axis: 'z', side: -1 },
159
161
  ];
160
162
  for (const side of sides) {
161
163
  const [ox, oz] = rotateLocal(side.local[0], side.local[1]);
@@ -169,11 +171,12 @@ export function buildRoofSegmentFloorplan(node, ctx) {
169
171
  });
170
172
  }
171
173
  }
172
- // Rotate-arrow at the +X / +Z corner. Local angle π/4 puts the
173
- // curved arrow's bow at the diagonal corner so it reads as a
174
- // rotation gizmo around the segment centre.
174
+ // Rotate-arrow off the +X / +Z corner of the eaves, clear of the plan's
175
+ // outline, sized to a roof. Local angle π/4 puts the curved arrow's bow
176
+ // on the diagonal so it reads as a rotation gizmo around the centre.
175
177
  if (node.roofType !== 'conical') {
176
- const [cornerX, cornerZ] = rotateLocal(halfW + rotateCornerOffset, halfD + rotateCornerOffset);
178
+ const eave = getRoofSegmentVisibleTopBounds(node);
179
+ const [cornerX, cornerZ] = rotateLocal(eave.maxX + rotateCornerOffset, eave.maxZ + rotateCornerOffset);
177
180
  const [radialX, radialZ] = rotateLocal(1, 1);
178
181
  children.push({
179
182
  kind: 'rotate-arrow',
@@ -181,6 +184,7 @@ export function buildRoofSegmentFloorplan(node, ctx) {
181
184
  angle: Math.atan2(radialZ, radialX),
182
185
  affordance: 'roof-segment-rotate',
183
186
  pivot: [cx, cz],
187
+ scale: 2,
184
188
  });
185
189
  }
186
190
  }
@@ -1,4 +1,6 @@
1
- import { type PaintCapability } from '@pascal-app/core';
1
+ import { type PaintCapability, type RoofSegmentNode, type RoofWallBand } from '@pascal-app/core';
2
+ /** A heel or gable paints on its own: its own finish, cleared back to its fallback by the eraser. */
3
+ export declare function wallBandPatch(band: RoofWallBand, material: RoofSegmentNode['material'], materialPreset: string | undefined): Partial<RoofSegmentNode>;
2
4
  export declare const roofSegmentPaint: PaintCapability;
3
5
  export { roofSegmentSlots } from '@pascal-app/core';
4
6
  //# sourceMappingURL=paint.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"paint.d.ts","sourceRoot":"","sources":["../../src/roof-segment/paint.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,eAAe,EAIrB,MAAM,kBAAkB,CAAA;AAgDzB,eAAO,MAAM,gBAAgB,EAAE,eA8C9B,CAAA;AAED,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA"}
1
+ {"version":3,"file":"paint.d.ts","sourceRoot":"","sources":["../../src/roof-segment/paint.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,YAAY,EAIlB,MAAM,kBAAkB,CAAA;AAiEzB,qGAAqG;AACrG,wBAAgB,aAAa,CAC3B,IAAI,EAAE,YAAY,EAClB,QAAQ,EAAE,eAAe,CAAC,UAAU,CAAC,EACrC,cAAc,EAAE,MAAM,GAAG,SAAS,GACjC,OAAO,CAAC,eAAe,CAAC,CAG1B;AAED,eAAO,MAAM,gBAAgB,EAAE,eAoE9B,CAAA;AAED,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA"}
@@ -1,4 +1,4 @@
1
- import { getEffectiveRoofSurfaceMaterial, getEffectiveSegmentSurfaceMaterial, getRoofGlazing, isGlazedRoofSegment, sceneRegistry, useScene, } from '@pascal-app/core';
1
+ import { getEffectiveRoofSurfaceMaterial, getEffectiveSegmentSurfaceMaterial, getRoofGlazing, getRoofWallBandMaterial, isGlazedRoofSegment, roofWallBandFields, sceneRegistry, useScene, } from '@pascal-app/core';
2
2
  import { buildRoofSegmentSurfaceMaterialPatch } from '@pascal-app/editor';
3
3
  import { GLAZED_ROOF_SLOTS } from '../roof/glazed-materials.js';
4
4
  import { buildSlotPreviewMaterial, createSlotPaintCapability } from '../shared/slot-paint.js';
@@ -41,9 +41,30 @@ const glazingPaint = createSlotPaintCapability({
41
41
  return swapPreviewMaterial(mesh, next);
42
42
  },
43
43
  });
44
+ // Slots 4–6 are the wall bands split off the wall/trim slot (the viewer's `ROOF_HEEL_MATERIAL_INDEX`…).
45
+ const WALL_BAND_BY_INDEX = {
46
+ 4: 'heel',
47
+ 5: 'gable-left',
48
+ 6: 'gable-right',
49
+ };
50
+ const WALL_BAND_LABELS = {
51
+ heel: 'Heel band',
52
+ 'gable-left': 'Left gable',
53
+ 'gable-right': 'Right gable',
54
+ };
44
55
  function standardRole(index) {
56
+ if (index !== null && WALL_BAND_BY_INDEX[index])
57
+ return WALL_BAND_BY_INDEX[index];
45
58
  return index === 3 ? 'top' : index === 0 ? 'edge' : index === 1 || index === 2 ? 'wall' : null;
46
59
  }
60
+ function isWallBand(role) {
61
+ return role === 'heel' || role === 'gable-left' || role === 'gable-right';
62
+ }
63
+ /** A heel or gable paints on its own: its own finish, cleared back to its fallback by the eraser. */
64
+ export function wallBandPatch(band, material, materialPreset) {
65
+ const fields = roofWallBandFields(band);
66
+ return { [fields.material]: material, [fields.materialPreset]: materialPreset };
67
+ }
47
68
  export const roofSegmentPaint = {
48
69
  materialTarget: 'roof',
49
70
  resolveRole(args) {
@@ -51,10 +72,17 @@ export const roofSegmentPaint = {
51
72
  ? glazingPaint.resolveRole(args)
52
73
  : standardRole(args.materialIndex);
53
74
  },
75
+ roleLabel(node, role) {
76
+ return isWallBand(role) && !isGlazedRoofSegment(node)
77
+ ? WALL_BAND_LABELS[role]
78
+ : null;
79
+ },
54
80
  buildPatch(args) {
55
81
  if (isGlazedRoofSegment(args.node))
56
82
  return glazingPaint.buildPatch(args);
57
83
  const role = args.role;
84
+ if (isWallBand(role))
85
+ return wallBandPatch(role, args.material, args.materialPreset);
58
86
  if (role !== 'top' && role !== 'edge' && role !== 'wall')
59
87
  return {};
60
88
  return buildRoofSegmentSurfaceMaterialPatch(args.node, role, args.material, args.materialPreset);
@@ -82,9 +110,22 @@ export const roofSegmentPaint = {
82
110
  if (isGlazedRoofSegment(node))
83
111
  return glazingPaint.getEffectiveMaterial?.(args) ?? null;
84
112
  const role = args.role;
113
+ const parent = node.parentId ? args.nodes?.[node.parentId] : undefined;
114
+ if (isWallBand(role)) {
115
+ // Unpainted, a gable shows the edge role and the heel band the roof's (else the walls').
116
+ const own = getRoofWallBandMaterial(node, role) ??
117
+ (role === 'heel' && parent?.type === 'roof'
118
+ ? getRoofWallBandMaterial(parent, 'heel')
119
+ : null);
120
+ if (own)
121
+ return { material: own.material, materialPreset: own.materialPreset };
122
+ if (role === 'heel')
123
+ return null;
124
+ const edge = getEffectiveSegmentSurfaceMaterial(node, 'edge', parent?.type === 'roof' ? getEffectiveRoofSurfaceMaterial(parent, 'edge') : undefined);
125
+ return { material: edge.material, materialPreset: edge.materialPreset };
126
+ }
85
127
  if (role !== 'top' && role !== 'edge' && role !== 'wall')
86
128
  return null;
87
- const parent = node.parentId ? args.nodes?.[node.parentId] : undefined;
88
129
  const spec = getEffectiveSegmentSurfaceMaterial(node, role, parent?.type === 'roof' ? getEffectiveRoofSurfaceMaterial(parent, role) : undefined);
89
130
  return { material: spec.material, materialPreset: spec.materialPreset };
90
131
  },
@@ -0,0 +1,23 @@
1
+ import { type RoofBuildUp, type RoofSegmentNode } from '@pascal-app/core';
2
+ import type { NodePanelModel } from '@pascal-app/editor';
3
+ /** The Preset choices for the `current` value: none, the presets, and Custom while it is. */
4
+ export declare function roofBuildUpPresetOptions(current: string | null): {
5
+ label: string;
6
+ value: string;
7
+ }[];
8
+ export declare function roofBuildUpPresetValue(buildUp: RoofBuildUp | undefined): string;
9
+ /** The patch a Preset choice writes; `null` for Custom, which is no choice. */
10
+ export declare function roofBuildUpPresetPatch(id: string): Partial<RoofSegmentNode> | null;
11
+ export { roofBuildUpOfDeck } from '@pascal-app/core';
12
+ /** A layer with `name`, trimmed; empty takes the name off, the kind's own name standing for it. */
13
+ export declare function namedLayer<T extends {
14
+ name?: string;
15
+ }>(layer: T, name: string): T;
16
+ /** `next` keeps `previous`'s name while it is the same kind of material (a new thickness, say). */
17
+ export declare function keptName<T extends {
18
+ kind: string;
19
+ name?: string;
20
+ }>(previous: T | undefined, next: T | undefined): T | undefined;
21
+ /** Multi-selected planes take one layers preset together, in one undo step. */
22
+ export declare const roofSegmentPanelModel: NodePanelModel<RoofSegmentNode>;
23
+ //# sourceMappingURL=panel-model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"panel-model.d.ts","sourceRoot":"","sources":["../../src/roof-segment/panel-model.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,eAAe,EAIrB,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAKxD,6FAA6F;AAC7F,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;;;IAM9D;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,WAAW,GAAG,SAAS,GAAG,MAAM,CAE/E;AAED,+EAA+E;AAC/E,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI,CAIlF;AAGD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAEpD,mGAAmG;AACnG,wBAAgB,UAAU,CAAC,CAAC,SAAS;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,CAIjF;AAED,mGAAmG;AACnG,wBAAgB,QAAQ,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,EAChE,QAAQ,EAAE,CAAC,GAAG,SAAS,EACvB,IAAI,EAAE,CAAC,GAAG,SAAS,GAClB,CAAC,GAAG,SAAS,CAGf;AAED,+EAA+E;AAC/E,eAAO,MAAM,qBAAqB,EAAE,cAAc,CAAC,eAAe,CA2BjE,CAAA"}
@@ -0,0 +1,64 @@
1
+ import { isGlazedRoofSegment, ROOF_BUILD_UP_PRESETS, roofBuildUpPatch, runAsSingleSceneHistoryStep, useScene, } from '@pascal-app/core';
2
+ const NONE = 'none';
3
+ const CUSTOM = 'custom';
4
+ /** The Preset choices for the `current` value: none, the presets, and Custom while it is. */
5
+ export function roofBuildUpPresetOptions(current) {
6
+ return [
7
+ { label: 'None (deck and shingle)', value: NONE },
8
+ ...(current === CUSTOM ? [{ label: 'Custom', value: CUSTOM }] : []),
9
+ ...ROOF_BUILD_UP_PRESETS.map((preset) => ({ label: preset.label, value: preset.id })),
10
+ ];
11
+ }
12
+ export function roofBuildUpPresetValue(buildUp) {
13
+ return buildUp ? (buildUp.presetId ?? CUSTOM) : NONE;
14
+ }
15
+ /** The patch a Preset choice writes; `null` for Custom, which is no choice. */
16
+ export function roofBuildUpPresetPatch(id) {
17
+ if (id === NONE)
18
+ return { buildUp: undefined };
19
+ const preset = ROOF_BUILD_UP_PRESETS.find((entry) => entry.id === id);
20
+ return preset ? roofBuildUpPatch(preset.buildUp) : null;
21
+ }
22
+ // The layers a plane without any is drawn as live in core, where Bones frames such a plane by them.
23
+ export { roofBuildUpOfDeck } from '@pascal-app/core';
24
+ /** A layer with `name`, trimmed; empty takes the name off, the kind's own name standing for it. */
25
+ export function namedLayer(layer, name) {
26
+ const { name: _name, ...rest } = layer;
27
+ const trimmed = name.trim().slice(0, 60);
28
+ return (trimmed ? { ...rest, name: trimmed } : rest);
29
+ }
30
+ /** `next` keeps `previous`'s name while it is the same kind of material (a new thickness, say). */
31
+ export function keptName(previous, next) {
32
+ if (!next || next.name !== undefined || previous?.name === undefined)
33
+ return next;
34
+ return next.kind === previous.kind ? { ...next, name: previous.name } : next;
35
+ }
36
+ /** Multi-selected planes take one layers preset together, in one undo step. */
37
+ export const roofSegmentPanelModel = {
38
+ rows: () => [],
39
+ multiControls: ({ selection }) => {
40
+ const planes = selection.filter((plane) => !isGlazedRoofSegment(plane));
41
+ if (planes.length === 0)
42
+ return [];
43
+ const values = planes.map((plane) => roofBuildUpPresetValue(plane.buildUp));
44
+ const value = values.every((entry) => entry === values[0]) ? values[0] : null;
45
+ return [
46
+ {
47
+ id: 'roof-segment-layers-preset',
48
+ kind: 'select',
49
+ section: 'Layers',
50
+ label: 'Preset',
51
+ options: roofBuildUpPresetOptions(value),
52
+ value,
53
+ onChange: (id) => {
54
+ const patch = roofBuildUpPresetPatch(id);
55
+ if (!patch)
56
+ return;
57
+ runAsSingleSceneHistoryStep(useScene, () => useScene
58
+ .getState()
59
+ .updateNodes(planes.map((plane) => ({ id: plane.id, data: patch }))));
60
+ },
61
+ },
62
+ ];
63
+ },
64
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"panel.d.ts","sourceRoot":"","sources":["../../src/roof-segment/panel.tsx"],"names":[],"mappings":"AA0GA,MAAM,CAAC,OAAO,UAAU,gBAAgB,uCA6qBvC"}
1
+ {"version":3,"file":"panel.d.ts","sourceRoot":"","sources":["../../src/roof-segment/panel.tsx"],"names":[],"mappings":"AAiJA,MAAM,CAAC,OAAO,UAAU,gBAAgB,uCAgxBvC"}