@pascal-app/nodes 1.0.5 → 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,17 +1,21 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { getActiveRoofHeight, getEffectiveNode, useLiveNodeOverrides, } from '@pascal-app/core';
3
+ import { getActiveRoofHeight, getEffectiveNode, useLiveNodeOverrides, usePascalI18n, } from '@pascal-app/core';
4
4
  import { getLinearUnitLabel, linearControlValueToMeters, metersToLinearUnit, PanelSection, SliderControl, } from '@pascal-app/editor';
5
5
  import { useViewer } from '@pascal-app/viewer';
6
6
  import { useEffect, useMemo } from 'react';
7
7
  import { createRoofGlazingPreview } from './glazing-preview.js';
8
8
  export function BarrelRoofPanel({ node: stored }) {
9
+ const i18n = usePascalI18n();
9
10
  useLiveNodeOverrides((state) => state.overrides.get(stored.id));
10
11
  const node = getEffectiveNode(stored);
11
12
  const unit = useViewer((state) => state.unit);
12
13
  const preview = useMemo(() => createRoofGlazingPreview([stored.id]), [stored.id]);
13
14
  useEffect(() => () => preview.cancel(), [preview]);
14
- return (_jsxs(PanelSection, { title: "Barrel arch", children: [_jsx(SliderControl, { label: "Rise", min: metersToLinearUnit(0.01, unit), max: metersToLinearUnit(node.depth / 2, unit), step: 0.1, precision: 2, unit: getLinearUnitLabel(unit), value: metersToLinearUnit(getActiveRoofHeight(node), unit), onChange: (value) => preview.previewFields({
15
+ return (_jsxs(PanelSection, { title: i18n._({ id: 'node.roof.barrelPanel.barrelArch', message: 'Barrel arch' }), children: [_jsx(SliderControl, { label: i18n._({ id: 'node.roof.barrelPanel.rise', message: 'Rise' }), min: metersToLinearUnit(0.01, unit), max: metersToLinearUnit(node.depth / 2, unit), step: 0.1, precision: 2, unit: getLinearUnitLabel(unit), value: metersToLinearUnit(getActiveRoofHeight(node), unit), onChange: (value) => preview.previewFields({
15
16
  barrelRise: Math.min(node.depth / 2, linearControlValueToMeters(value, unit, { minMeters: 0.01 })),
16
- }), onCommit: preview.finish, onCancel: preview.cancel, restoreOnCommit: false, previewWhileTyping: true }), _jsx(SliderControl, { label: "Arch bays", min: 4, max: 32, step: 1, precision: 0, value: node.barrelSegments ?? 12, onChange: (value) => preview.previewFields({ barrelSegments: Math.round(value) }), onCommit: preview.finish, onCancel: preview.cancel, restoreOnCommit: false, previewWhileTyping: true }), _jsx("p", { className: "px-1 text-xs text-muted-foreground", children: "Flat panes follow a circular arch. Rise is measured from the eaves." })] }));
17
+ }), onCommit: preview.finish, onCancel: preview.cancel, restoreOnCommit: false, previewWhileTyping: true }), _jsx(SliderControl, { label: i18n._({ id: 'node.roof.barrelPanel.archBays', message: 'Arch bays' }), min: 4, max: 32, step: 1, precision: 0, value: node.barrelSegments ?? 12, onChange: (value) => preview.previewFields({ barrelSegments: Math.round(value) }), onCommit: preview.finish, onCancel: preview.cancel, restoreOnCommit: false, previewWhileTyping: true }), _jsx("p", { className: "px-1 text-xs text-muted-foreground", children: i18n._({
18
+ id: 'node.roof.barrelPanel.flatPanesFollowACircularArch',
19
+ message: 'Flat panes follow a circular arch. Rise is measured from the eaves.',
20
+ }) })] }));
17
21
  }
@@ -1 +1 @@
1
- {"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/roof/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,cAAc,EAKpB,MAAM,kBAAkB,CAAA;AAczB,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAsFnC;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,cAAc,CAAC,OAAO,QAAQ,CA6K1D,CAAA"}
1
+ {"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/roof/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,cAAc,EAKpB,MAAM,kBAAkB,CAAA;AAsBzB,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAsFnC;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,cAAc,CAAC,OAAO,QAAQ,CAwM1D,CAAA"}
@@ -1,10 +1,13 @@
1
1
  import { RoofNode as RoofNodeSchema, } from '@pascal-app/core';
2
- import { DRAFTING_SURFACE_EXTENSION_KEY, PANEL_MODEL_EXTENSION, } from '@pascal-app/editor';
2
+ import { DRAFTING_SURFACE_EXTENSION_KEY, FLOORPLAN_NODE_EXTENSION_KEY, PANEL_MODEL_EXTENSION, } from '@pascal-app/editor';
3
3
  import { buildRoofFloorplan } from './floorplan.js';
4
+ import { roofFloorplanAffectedIds, roofFloorplanSiblingOverrides } from './floorplan-overrides.js';
5
+ import { roofPaint } from './paint.js';
4
6
  import { roofPanelModel } from './panel-model.js';
5
7
  import { roofParametrics } from './parametrics.js';
6
- import useRoofFootprintSource from './roof-footprint-source.js';
8
+ import useRoofFootprintSource, { irregularRoomHintVisibility, noRoomHintVisibility, } from './roof-footprint-source.js';
7
9
  import useRoofPlacementMode, { conicalRoofToolHintVisibility, standardRoofToolHintVisibility, } from './roof-placement-mode.js';
10
+ import useRoofRidgeMode from './roof-ridge-mode.js';
8
11
  import { RoofNode } from './schema.js';
9
12
  const MOVE_FRONT_OFFSET = 0.35;
10
13
  const MIN_ROOF_FOOTPRINT = 1;
@@ -95,6 +98,9 @@ export const roofDefinition = {
95
98
  [DRAFTING_SURFACE_EXTENSION_KEY]: {
96
99
  kind: 'roof',
97
100
  },
101
+ [FLOORPLAN_NODE_EXTENSION_KEY]: {
102
+ tool: () => import('./floorplan-tool.js'),
103
+ },
98
104
  },
99
105
  defaults: () => {
100
106
  const stub = RoofNodeSchema.parse({ id: 'roof_default', type: 'roof' });
@@ -103,6 +109,7 @@ export const roofDefinition = {
103
109
  },
104
110
  capabilities: {
105
111
  exterior: true,
112
+ paint: roofPaint,
106
113
  reveal: {
107
114
  phase: 'roof',
108
115
  style: 'assemble',
@@ -201,9 +208,30 @@ export const roofDefinition = {
201
208
  },
202
209
  {
203
210
  key: 'R',
204
- label: 'Rotate roof direction 90°',
211
+ label: 'Ridge direction',
205
212
  visible: standardRoofToolHintVisibility,
213
+ chip: {
214
+ subscribe: (onChange) => useRoofRidgeMode.subscribe(onChange),
215
+ value: () => useRoofRidgeMode.getState().mode,
216
+ cycle: () => useRoofRidgeMode.getState().toggle(),
217
+ labels: {
218
+ long: 'Ridge: Long side',
219
+ short: 'Ridge: Short side',
220
+ },
221
+ icons: {
222
+ long: 'lucide:rectangle-horizontal',
223
+ short: 'lucide:rectangle-vertical',
224
+ },
225
+ tooltip: 'Ridge direction - click or press R to turn it 90°',
226
+ },
227
+ },
228
+ // Room makes nothing where there is no room to roof: say why, where a click would do nothing.
229
+ {
230
+ key: 'Room',
231
+ label: 'Not a rectangle: draw this roof instead',
232
+ visible: irregularRoomHintVisibility,
206
233
  },
234
+ { key: 'Room', label: 'Point inside a room, porch or deck', visible: noRoomHintVisibility },
207
235
  { key: 'Esc', label: 'Cancel' },
208
236
  ],
209
237
  toolOptions: [
@@ -232,6 +260,8 @@ export const roofDefinition = {
232
260
  parametrics: roofParametrics,
233
261
  handles: resolveRoofHandles,
234
262
  floorplan: buildRoofFloorplan,
263
+ floorplanSiblingOverrides: roofFloorplanSiblingOverrides,
264
+ floorplanAffectedIds: roofFloorplanAffectedIds,
235
265
  rendersChildren: false,
236
266
  renderer: {
237
267
  kind: 'parametric',
@@ -0,0 +1,22 @@
1
+ import type { AnyNode, AnyNodeId, LiveTransformLike } from '@pascal-app/core';
2
+ /**
3
+ * A roof's plan is drawn by the roof node from its segments (`ctx.children`) and its level's
4
+ * other roofs (`ctx.siblings`), which a drag moves through live overrides and transforms, not the
5
+ * scene. Projecting those into the builder's snapshot keeps the outline, ridges, hips and valleys
6
+ * on the segment while it is moved, resized or turned, in 2D or 3D.
7
+ */
8
+ export declare function roofFloorplanSiblingOverrides(args: {
9
+ nodeId: AnyNodeId;
10
+ nodes: Record<AnyNodeId, AnyNode>;
11
+ liveTransforms: Map<string, LiveTransformLike>;
12
+ liveOverrides: Map<string, Record<string, unknown>>;
13
+ }): Record<AnyNodeId, AnyNode>;
14
+ /**
15
+ * The roofs whose plan a live roof or segment edit changes: every roof on its level, since a
16
+ * wing's ridge runs on to the main roof's slope and their valleys are drawn by one of the two.
17
+ */
18
+ export declare function roofFloorplanAffectedIds(args: {
19
+ node: AnyNode;
20
+ nodes: Record<AnyNodeId, AnyNode>;
21
+ }): readonly AnyNodeId[];
22
+ //# sourceMappingURL=floorplan-overrides.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"floorplan-overrides.d.ts","sourceRoot":"","sources":["../../src/roof/floorplan-overrides.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAK7E;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAAC,IAAI,EAAE;IAClD,MAAM,EAAE,SAAS,CAAA;IACjB,KAAK,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;IACjC,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAA;IAC9C,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;CACpD,GAAG,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAsB7B;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE;IAC7C,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,EAAE,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;CAClC,GAAG,SAAS,SAAS,EAAE,CASvB"}
@@ -0,0 +1,46 @@
1
+ const isRoofPart = (node) => node?.type === 'roof' || node?.type === 'roof-segment';
2
+ /**
3
+ * A roof's plan is drawn by the roof node from its segments (`ctx.children`) and its level's
4
+ * other roofs (`ctx.siblings`), which a drag moves through live overrides and transforms, not the
5
+ * scene. Projecting those into the builder's snapshot keeps the outline, ridges, hips and valleys
6
+ * on the segment while it is moved, resized or turned, in 2D or 3D.
7
+ */
8
+ export function roofFloorplanSiblingOverrides(args) {
9
+ const { nodes, liveOverrides, liveTransforms } = args;
10
+ if (liveOverrides.size === 0 && liveTransforms.size === 0)
11
+ return nodes;
12
+ let out = null;
13
+ for (const [id, live] of liveTransforms) {
14
+ const existing = nodes[id];
15
+ if (!isRoofPart(existing))
16
+ continue;
17
+ out ??= { ...nodes };
18
+ out[id] = {
19
+ ...existing,
20
+ position: live.position,
21
+ rotation: live.rotation,
22
+ };
23
+ }
24
+ for (const [id, override] of liveOverrides) {
25
+ const existing = out?.[id] ?? nodes[id];
26
+ if (!isRoofPart(existing) || Object.keys(override).length === 0)
27
+ continue;
28
+ out ??= { ...nodes };
29
+ out[id] = { ...existing, ...override };
30
+ }
31
+ return out ?? nodes;
32
+ }
33
+ /**
34
+ * The roofs whose plan a live roof or segment edit changes: every roof on its level, since a
35
+ * wing's ridge runs on to the main roof's slope and their valleys are drawn by one of the two.
36
+ */
37
+ export function roofFloorplanAffectedIds(args) {
38
+ const { node, nodes } = args;
39
+ const roof = node.type === 'roof-segment' && node.parentId ? nodes[node.parentId] : node;
40
+ if (roof?.type !== 'roof')
41
+ return [];
42
+ const level = roof.parentId ? nodes[roof.parentId] : undefined;
43
+ const onLevel = level?.children ?? [];
44
+ const roofs = onLevel.filter((id) => id !== roof.id && nodes[id]?.type === 'roof');
45
+ return [roof.id, ...roofs];
46
+ }
@@ -0,0 +1,9 @@
1
+ import { type FloorplanToolContext } from '@pascal-app/editor';
2
+ /**
3
+ * The roof tool in 2D-only view. The 3D `RoofTool` lives in the canvas, which never renders while
4
+ * its pane is hidden, so in 2D-only view this commits instead, from the plan's own grid events: it
5
+ * snaps the corners, writes them into the plan's draft rectangle (or hovers the room, or for a cone
6
+ * the curved wall) and writes the roof. Split and 3D views keep the 3D tool as the one owner.
7
+ */
8
+ export default function RoofFloorplanTool({ activeLevelId, sceneApi, selectNode, }: FloorplanToolContext): null;
9
+ //# sourceMappingURL=floorplan-tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"floorplan-tool.d.ts","sourceRoot":"","sources":["../../src/roof/floorplan-tool.tsx"],"names":[],"mappings":"AASA,OAAO,EAEL,KAAK,oBAAoB,EAM1B,MAAM,oBAAoB,CAAA;AAoB3B;;;;;GAKG;AACH,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,EACxC,aAAa,EACb,QAAQ,EACR,UAAU,GACX,EAAE,oBAAoB,QAkLtB"}
@@ -0,0 +1,168 @@
1
+ 'use client';
2
+ import { emitter, RoofType as RoofTypeSchema, } from '@pascal-app/core';
3
+ import { clearSurfacePlanSnapFeedback, markToolCancelConsumed, triggerSFX, useEditor, useFloorplanDraftPreview, visibleScene, } from '@pascal-app/editor';
4
+ import { useViewer } from '@pascal-app/viewer';
5
+ import { useEffect } from 'react';
6
+ import { createConicalRoofSectorAboveWall } from './conical-roof.js';
7
+ import { parseRoofFootprintSource, pickConicalRoofWall, pickRoofRoom, roofFootprintPreviewIds, } from './roof-footprint.js';
8
+ import useRoofFootprintSource from './roof-footprint-source.js';
9
+ import useRoofPlacementMode from './roof-placement-mode.js';
10
+ import useRoofRidgeMode, { ridgeQuarterTurn } from './roof-ridge-mode.js';
11
+ import { collectRoofAlignmentAnchors, commitRoofFootprint, commitRoofPlacement, resolveRoofDraftPoint, } from './tool.js';
12
+ /**
13
+ * The roof tool in 2D-only view. The 3D `RoofTool` lives in the canvas, which never renders while
14
+ * its pane is hidden, so in 2D-only view this commits instead, from the plan's own grid events: it
15
+ * snaps the corners, writes them into the plan's draft rectangle (or hovers the room, or for a cone
16
+ * the curved wall) and writes the roof. Split and 3D views keep the 3D tool as the one owner.
17
+ */
18
+ export default function RoofFloorplanTool({ activeLevelId, sceneApi, selectNode, }) {
19
+ const planOwnsInput = useEditor((state) => visibleScene(state) === '2d');
20
+ const levelId = planOwnsInput ? activeLevelId : null;
21
+ const roofType = useEditor((state) => {
22
+ const parsed = RoofTypeSchema.safeParse(state.toolDefaults.roof?.roofType);
23
+ return parsed.success ? parsed.data : 'gable';
24
+ });
25
+ // A new source or roof type starts over, as the 3D tool does: a first corner kept across it
26
+ // would end the next rectangle with no draft on the plan to show it.
27
+ const source = useRoofFootprintSource((state) => parseRoofFootprintSource(state.source, roofType));
28
+ useEffect(() => {
29
+ if (!levelId)
30
+ return;
31
+ let corner1 = null;
32
+ const draft = useFloorplanDraftPreview.getState;
33
+ // A rectangle the 3D tool opened before the view changed has no first corner here: drop it, or
34
+ // the plan's draft and this tool's corner fall out of step (each click starts one, ends the other).
35
+ const clearDraft = () => {
36
+ draft().setRoofDraftStart(null);
37
+ draft().setRoofDraftEnd(null);
38
+ draft().setRoofDraftQuarterTurn(false);
39
+ };
40
+ clearDraft();
41
+ // Snapped as the 3D tool snaps in split view (onto the walls below too), so the same clicks
42
+ // make the same roof in either view.
43
+ let alignmentCandidates = collectRoofAlignmentAnchors(sceneApi.nodes(), levelId, roofType);
44
+ const planPoint = (event) => resolveRoofDraftPoint(event, levelId, sceneApi.nodes(), roofType, alignmentCandidates);
45
+ let previewedId = null;
46
+ const preview = (target) => {
47
+ if ((target?.id ?? null) === previewedId)
48
+ return;
49
+ previewedId = target?.id ?? null;
50
+ useViewer.getState().setPreviewSelectedIds(target?.ids ?? []);
51
+ };
52
+ const conicalWall = (event) => pickConicalRoofWall(levelId, sceneApi.nodes(), [
53
+ event.localPosition[0],
54
+ event.localPosition[2],
55
+ ]);
56
+ const onMove = (event) => {
57
+ if (source === 'walls') {
58
+ const wall = conicalWall(event);
59
+ preview(wall && { id: wall.id, ids: [wall.id] });
60
+ return;
61
+ }
62
+ if (source === 'room') {
63
+ const room = pickRoofRoom(levelId, sceneApi.nodes(), planPoint(event));
64
+ useRoofFootprintSource.getState().setRoomPick(room.pick);
65
+ preview(room.target && { id: room.target.id, ids: roofFootprintPreviewIds(room.target) });
66
+ return;
67
+ }
68
+ const [x, z] = planPoint(event);
69
+ if (!corner1)
70
+ return;
71
+ draft().setRoofDraftEnd([x, z]);
72
+ draft().setRoofDraftQuarterTurn(ridgeQuarterTurn(Math.abs(x - corner1[0]), Math.abs(z - corner1[2]), useRoofRidgeMode.getState().mode));
73
+ };
74
+ const onClick = (event) => {
75
+ if (source === 'walls') {
76
+ const wall = conicalWall(event);
77
+ if (!wall)
78
+ return;
79
+ preview(null);
80
+ const segmentId = createConicalRoofSectorAboveWall(wall, sceneApi.nodes(), sceneApi, levelId);
81
+ if (segmentId)
82
+ selectNode(segmentId);
83
+ return;
84
+ }
85
+ if (source === 'room') {
86
+ const { target, pick } = pickRoofRoom(levelId, sceneApi.nodes(), planPoint(event));
87
+ useRoofFootprintSource.getState().setRoomPick(pick);
88
+ if (!target)
89
+ return;
90
+ const roofId = commitRoofFootprint(sceneApi, levelId, target, useRoofRidgeMode.getState().mode);
91
+ if (roofId)
92
+ selectNode(roofId);
93
+ return;
94
+ }
95
+ const [x, z] = planPoint(event);
96
+ const corner = [x, event.localPosition[1], z];
97
+ if (!corner1) {
98
+ corner1 = corner;
99
+ draft().setRoofDraftStart([x, z]);
100
+ draft().setRoofDraftEnd([x, z]);
101
+ triggerSFX('sfx:structure-build-start');
102
+ return;
103
+ }
104
+ const roofId = commitRoofPlacement(sceneApi, levelId, corner1, corner, useViewer.getState().selection.selectedIds, useRoofRidgeMode.getState().mode, useRoofPlacementMode.getState().mode);
105
+ corner1 = null;
106
+ clearDraft();
107
+ alignmentCandidates = collectRoofAlignmentAnchors(sceneApi.nodes(), levelId, roofType);
108
+ clearSurfacePlanSnapFeedback();
109
+ if (roofId)
110
+ selectNode(roofId);
111
+ };
112
+ const onCancel = () => {
113
+ if (!corner1)
114
+ return;
115
+ markToolCancelConsumed();
116
+ corner1 = null;
117
+ clearDraft();
118
+ };
119
+ const onKeyDown = (event) => {
120
+ const target = event.target;
121
+ if (target instanceof HTMLInputElement ||
122
+ target instanceof HTMLTextAreaElement ||
123
+ (target instanceof HTMLElement && target.isContentEditable))
124
+ return;
125
+ if (event.repeat || event.metaKey || event.ctrlKey || event.altKey)
126
+ return;
127
+ const key = event.key.toLowerCase();
128
+ // As in 3D: P cycles a cone's placement surface, R turns a drawn roof's ridge.
129
+ if (source === 'walls') {
130
+ if (key !== 'p')
131
+ return;
132
+ event.preventDefault();
133
+ useRoofPlacementMode.getState().cycleMode();
134
+ triggerSFX('sfx:grid-snap');
135
+ return;
136
+ }
137
+ if (key !== 'r')
138
+ return;
139
+ event.preventDefault();
140
+ useRoofRidgeMode.getState().toggle();
141
+ triggerSFX('sfx:item-rotate');
142
+ };
143
+ // The HUD chip flips the ridge too; the draft's ridge line follows either way.
144
+ const unsubscribeRidgeMode = useRoofRidgeMode.subscribe(() => {
145
+ const start = draft().roofDraftStart;
146
+ const end = draft().roofDraftEnd;
147
+ if (!(corner1 && start && end))
148
+ return;
149
+ draft().setRoofDraftQuarterTurn(ridgeQuarterTurn(Math.abs(end[0] - start[0]), Math.abs(end[1] - start[1]), useRoofRidgeMode.getState().mode));
150
+ });
151
+ emitter.on('grid:move', onMove);
152
+ emitter.on('grid:click', onClick);
153
+ emitter.on('tool:cancel', onCancel);
154
+ window.addEventListener('keydown', onKeyDown);
155
+ return () => {
156
+ emitter.off('grid:move', onMove);
157
+ emitter.off('grid:click', onClick);
158
+ emitter.off('tool:cancel', onCancel);
159
+ window.removeEventListener('keydown', onKeyDown);
160
+ unsubscribeRidgeMode();
161
+ useRoofFootprintSource.getState().setRoomPick(null);
162
+ preview(null);
163
+ clearDraft();
164
+ clearSurfacePlanSnapFeedback();
165
+ };
166
+ }, [levelId, roofType, sceneApi, selectNode, source]);
167
+ return null;
168
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"floorplan.d.ts","sourceRoot":"","sources":["../../src/roof/floorplan.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iBAAiB,EAEtB,KAAK,eAAe,EAGpB,KAAK,QAAQ,EAKd,MAAM,kBAAkB,CAAA;AA2BzB;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMvD;AA8LD;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,eAAe,GAAG,iBAAiB,GAAG,IAAI,CA0MjG"}
1
+ {"version":3,"file":"floorplan.d.ts","sourceRoot":"","sources":["../../src/roof/floorplan.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,iBAAiB,EAEtB,KAAK,eAAe,EAIpB,KAAK,QAAQ,EAKd,MAAM,kBAAkB,CAAA;AAyCzB;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMvD;AAqPD;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,eAAe,GAAG,iBAAiB,GAAG,IAAI,CAmPjG"}
@@ -1,6 +1,7 @@
1
- import { getGlazedRoofPlanLines, getRoofSegmentVisibleTopBounds, roofPlanOverlapEntryOwns, subtractPolygonsFromPolygon, unionPolygons, } from '@pascal-app/core';
1
+ import { getGlazedRoofPlanLines, getRoofSegmentVisibleTopBounds, getSegmentSlopeFrame, roofPlanOverlapEntryOwns, subtractPolygonsFromPolygon, unionPolygons, } from '@pascal-app/core';
2
2
  import { floorplanGeometryMetadata, readFloorplanContext } from '@pascal-app/editor';
3
3
  import { getConicalRoofPlanFootprint, getRoofSegmentPlanLinework } from '../roof-segment/floorplan.js';
4
+ import { getRoofSurfaceCreases } from './roof-plan-creases.js';
4
5
  /**
5
6
  * `roof-segment.pitch` is stored in DEGREES; a roof plan is annotated as the
6
7
  * rise over a 12 run. 30.256° → tan 0.5833 × 12 → 7.00 → '7:12'. Rounded to
@@ -78,6 +79,34 @@ function overlapEntry(entry, ctx) {
78
79
  depth: entry.segment.depth,
79
80
  };
80
81
  }
82
+ /**
83
+ * A planar form's roof planes in segment-local plan coordinates, each as
84
+ * `[gx, gz, c]` with height `c + gx·lx + gz·lz` above the eave: every slope
85
+ * rises at the pitch from its eave line. `null` for the forms with curved or
86
+ * broken slopes, which keep their own linework.
87
+ */
88
+ function localRoofPlanes(seg) {
89
+ const hw = Math.max(seg.width, 0.01) / 2;
90
+ const hd = Math.max(seg.depth, 0.01) / 2;
91
+ const tan = getSegmentSlopeFrame(seg).tanTheta;
92
+ const towardPlusZ = [0, -tan, tan * hd];
93
+ const towardMinusZ = [0, tan, tan * hd];
94
+ const towardPlusX = [-tan, 0, tan * hw];
95
+ const towardMinusX = [tan, 0, tan * hw];
96
+ switch (seg.roofType) {
97
+ case 'flat':
98
+ return [[0, 0, 0]];
99
+ case 'shed':
100
+ // high eave at lz = −hd, falling to +hd, as the 3D builder slopes it
101
+ return [towardPlusZ];
102
+ case 'gable':
103
+ return [towardPlusZ, towardMinusZ];
104
+ case 'hip':
105
+ return [towardPlusZ, towardMinusZ, towardPlusX, towardMinusX];
106
+ default:
107
+ return null;
108
+ }
109
+ }
81
110
  /** A segment's footprint + ridge/hip/break/slope linework, in world plan coords. */
82
111
  function buildSegPlan(roof, seg, drafting) {
83
112
  const cosRoof = Math.cos(-roof.rotation);
@@ -93,18 +122,48 @@ function buildSegPlan(roof, seg, drafting) {
93
122
  ];
94
123
  const hw = Math.max(seg.width, 0.01) / 2;
95
124
  const hd = Math.max(seg.depth, 0.01) / 2;
125
+ const conical = seg.roofType === 'conical';
126
+ // The drip edge: core's own visible-top bounds, which add the horizontal
127
+ // component of `overhang` (plus half the wall thickness and, on the sloped
128
+ // faces, the shingle projection) to the footprint on each side.
129
+ const edge = getRoofSegmentVisibleTopBounds(seg);
130
+ // In the editor a line that ends on the wall line runs on to the eave or
131
+ // rake, as the 3D's hips, ridges and slope breaks do.
132
+ const toEdge = (v, half, min, max) => Math.abs(v - half) < 1e-6 ? max : Math.abs(v + half) < 1e-6 ? min : v;
133
+ const reach = drafting || conical ? null : edge;
134
+ const mapSeg = (s) => s.map(([lx, lz]) => reach
135
+ ? tp(toEdge(lx, hw, reach.minX, reach.maxX), toEdge(lz, hd, reach.minZ, reach.maxZ))
136
+ : tp(lx, lz));
96
137
  const lw = getRoofSegmentPlanLinework(seg);
97
- const mapSeg = (s) => [
98
- tp(s[0][0], s[0][1]),
99
- tp(s[1][0], s[1][1]),
100
- ];
101
- const footprint = seg.roofType === 'conical'
138
+ const footprint = conical
102
139
  ? getConicalRoofPlanFootprint(seg).map(([x, z]) => tp(x, z))
103
140
  : [tp(-hw, -hd), tp(hw, -hd), tp(hw, hd), tp(-hw, hd)];
141
+ const eave = [
142
+ tp(edge.minX, edge.minZ),
143
+ tp(edge.maxX, edge.minZ),
144
+ tp(edge.maxX, edge.maxZ),
145
+ tp(edge.minX, edge.maxZ),
146
+ ];
147
+ const outline = reach ? eave : footprint;
104
148
  const ridges = lw.ridges.map(mapSeg);
105
149
  const hips = lw.hips.map(mapSeg);
106
150
  const breaks = lw.breaks.map(mapSeg);
107
- const glazing = getGlazedRoofPlanLines(seg).map(mapSeg);
151
+ const glazing = getGlazedRoofPlanLines(seg).map(([a, b]) => [tp(a[0], a[1]), tp(b[0], b[1])]);
152
+ const local = localRoofPlanes(seg);
153
+ // Heights in the roof's level frame, so the planes of two roofs side by side
154
+ // compare. The planes run on past the wall line, as the overhang does.
155
+ const base = roof.position[1] + seg.position[1] + seg.wallHeight;
156
+ const surface = local
157
+ ? {
158
+ roofId: String(roof.id),
159
+ footprint: outline,
160
+ planes: local.map(([gx, gz, c0]) => {
161
+ const a = gx * cos - gz * sin;
162
+ const b = gx * sin + gz * cos;
163
+ return { a, b, c: base + c0 - a * segCx - b * segCz };
164
+ }),
165
+ }
166
+ : null;
108
167
  if (!drafting) {
109
168
  const slopes = lw.slope
110
169
  ? [
@@ -115,25 +174,18 @@ function buildSegPlan(roof, seg, drafting) {
115
174
  },
116
175
  ]
117
176
  : [];
118
- return { footprint, eave: footprint, ridges, hips, breaks, glazing, slopes };
177
+ return { footprint, eave, outline, ridges, hips, breaks, glazing, slopes, surface };
119
178
  }
120
- // The drip edge: core's own visible-top bounds, which add the horizontal
121
- // component of `overhang` (plus half the wall thickness and, on the sloped
122
- // faces, the shingle projection) to the footprint on each side.
123
- const edge = getRoofSegmentVisibleTopBounds(seg);
124
179
  const pitch = seg.roofType === 'barrel' ? '' : roofPitchLabel(seg.pitch);
125
180
  return {
126
181
  footprint,
127
- eave: [
128
- tp(edge.minX, edge.minZ),
129
- tp(edge.maxX, edge.minZ),
130
- tp(edge.maxX, edge.maxZ),
131
- tp(edge.minX, edge.maxZ),
132
- ],
182
+ eave,
183
+ outline,
133
184
  ridges,
134
185
  hips,
135
186
  breaks,
136
187
  glazing,
188
+ surface,
137
189
  slopes: slopeArrows(seg).map((arrow) => ({
138
190
  tail: tp(arrow.tail[0], arrow.tail[1]),
139
191
  head: tp(arrow.head[0], arrow.head[1]),
@@ -234,26 +286,25 @@ export function buildRoofFloorplan(node, ctx) {
234
286
  }
235
287
  }
236
288
  const currentEntries = entries.filter((entry) => entry.roof.id === node.id);
289
+ const owningCandidates = (entry) => entries.filter((candidate) => {
290
+ if (candidate.segment.id === entry.segment.id)
291
+ return false;
292
+ if (candidate.segment.roofType === 'shed')
293
+ return false;
294
+ return roofPlanOverlapEntryOwns(overlapEntry(candidate, ctx), overlapEntry(entry, ctx));
295
+ });
237
296
  const visiblePlans = currentEntries.map((entry) => {
238
- const cutters = entries
239
- .filter((candidate) => {
240
- if (candidate.segment.id === entry.segment.id)
241
- return false;
242
- if (candidate.segment.roofType === 'shed')
243
- return false;
244
- return roofPlanOverlapEntryOwns(overlapEntry(candidate, ctx), overlapEntry(entry, ctx));
245
- })
246
- .map((candidate) => candidate.plan.footprint);
297
+ const cutters = owningCandidates(entry).map((candidate) => candidate.plan.outline);
247
298
  return {
248
299
  plan: entry.plan,
249
300
  cutters,
250
- footprints: subtractPolygonsFromPolygon(entry.plan.footprint, cutters),
301
+ outlines: subtractPolygonsFromPolygon(entry.plan.outline, cutters),
251
302
  eaves: subtractPolygonsFromPolygon(entry.plan.eave, cutters),
252
303
  /** True when the drip edge is far enough outside the wall line to draw. */
253
304
  hasOverhang: drafting && polygonSpread(entry.plan.eave) - polygonSpread(entry.plan.footprint) > 0.04,
254
305
  };
255
306
  });
256
- const rings = unionPolygons(visiblePlans.flatMap(({ footprints }) => footprints));
307
+ const rings = unionPolygons(visiblePlans.flatMap(({ outlines }) => outlines));
257
308
  if (rings.length === 0)
258
309
  return null;
259
310
  const eaveRings = unionPolygons(visiblePlans.flatMap(({ eaves, hasOverhang }) => (hasOverhang ? eaves : [])));
@@ -303,7 +354,7 @@ export function buildRoofFloorplan(node, ctx) {
303
354
  pointerEvents: 'none',
304
355
  });
305
356
  }
306
- // Merged outline (wall line under the roof).
357
+ // Merged outline: the eave and rake in the editor, the wall line on a sheet.
307
358
  for (const ring of rings) {
308
359
  if (ring.length < 3)
309
360
  continue;
@@ -317,24 +368,63 @@ export function buildRoofFloorplan(node, ctx) {
317
368
  pointerEvents: 'none',
318
369
  });
319
370
  }
371
+ // Selected or moved, the wall line each segment stands on: whether the roof sits on the walls'
372
+ // centre lines (a selected segment draws its own).
373
+ if (!drafting && palette && ((view?.moving ?? false) || showSelectedChrome)) {
374
+ for (const { plan } of visiblePlans) {
375
+ children.push({
376
+ kind: 'polygon',
377
+ points: plan.footprint.map(([x, z]) => [x, z]),
378
+ fill: 'none',
379
+ stroke: palette.selectedStroke,
380
+ strokeWidth: 0.035,
381
+ strokeLinejoin: 'miter',
382
+ pointerEvents: 'none',
383
+ });
384
+ }
385
+ }
386
+ // Ridges, hips and valleys of the planar segments, off the surface they make
387
+ // together with this level's other roofs: a wing's ridge runs on until it
388
+ // meets the main roof's slope, and a valley runs where the two slopes meet.
389
+ // The curved and broken forms are not in that surface: where one owns an
390
+ // overlap it cuts these lines as before.
391
+ const planarEntries = entries.filter((entry) => entry.plan.surface);
392
+ const curvedCutters = (entry) => owningCandidates(entry)
393
+ .filter((candidate) => !candidate.plan.surface)
394
+ .map((candidate) => candidate.plan.outline);
395
+ for (const crease of getRoofSurfaceCreases(planarEntries.map((entry) => entry.plan.surface))) {
396
+ if (crease.roofId !== String(node.id))
397
+ continue;
398
+ const [i, k] = crease.between;
399
+ const cutters = [
400
+ ...curvedCutters(planarEntries[i]),
401
+ ...(k === i ? [] : curvedCutters(planarEntries[k])),
402
+ ];
403
+ const width = crease.kind === 'ridge' ? ridgeWidth : hipWidth;
404
+ for (const visible of clipLineByCutters([crease.from, crease.to], cutters))
405
+ pushLine(visible[0], visible[1], width);
406
+ }
320
407
  for (const { plan, cutters } of visiblePlans) {
321
408
  for (const line of plan.glazing) {
322
409
  for (const visible of clipLineByCutters(line, cutters))
323
410
  pushLine(visible[0], visible[1], hipWidth);
324
411
  }
325
- for (const line of plan.breaks) {
326
- for (const visible of clipLineByCutters(line, cutters)) {
327
- pushLine(visible[0], visible[1], hipWidth);
412
+ // A planar segment's ridges and hips were drawn off the shared surface above.
413
+ if (!plan.surface) {
414
+ for (const line of plan.breaks) {
415
+ for (const visible of clipLineByCutters(line, cutters)) {
416
+ pushLine(visible[0], visible[1], hipWidth);
417
+ }
328
418
  }
329
- }
330
- for (const line of plan.hips) {
331
- for (const visible of clipLineByCutters(line, cutters)) {
332
- pushLine(visible[0], visible[1], hipWidth);
419
+ for (const line of plan.hips) {
420
+ for (const visible of clipLineByCutters(line, cutters)) {
421
+ pushLine(visible[0], visible[1], hipWidth);
422
+ }
333
423
  }
334
- }
335
- for (const line of plan.ridges) {
336
- for (const visible of clipLineByCutters(line, cutters)) {
337
- pushLine(visible[0], visible[1], ridgeWidth);
424
+ for (const line of plan.ridges) {
425
+ for (const visible of clipLineByCutters(line, cutters)) {
426
+ pushLine(visible[0], visible[1], ridgeWidth);
427
+ }
338
428
  }
339
429
  }
340
430
  // One down-slope arrow per roof plane, each tagged with the pitch in
@@ -1,4 +1,5 @@
1
1
  import type { CurtainGrid, RoofGlazing } from '@pascal-app/core';
2
+ import { type MessageDescriptor } from '@pascal-app/core';
2
3
  import type { createRoofGlazingPreview } from './glazing-preview.js';
3
4
  type Preview = ReturnType<typeof createRoofGlazingPreview>;
4
5
  type NumberField = 'frameWidth' | 'frameDepth' | 'glassThickness' | 'glassOpacity' | 'glassRoughness';
@@ -27,7 +28,7 @@ export declare function GlazingColor({ field, label, value, mixed, preview, }: {
27
28
  }): import("react").JSX.Element;
28
29
  export declare const GLAZING_INFILL_OPTIONS: {
29
30
  value: RoofGlazing['panelType'];
30
- label: string;
31
+ label: MessageDescriptor;
31
32
  }[];
32
33
  export {};
33
34
  //# sourceMappingURL=glazing-controls.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"glazing-controls.d.ts","sourceRoot":"","sources":["../../src/roof/glazing-controls.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAYhE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAA;AAEjE,KAAK,OAAO,GAAG,UAAU,CAAC,OAAO,wBAAwB,CAAC,CAAA;AAC1D,KAAK,WAAW,GACZ,YAAY,GACZ,YAAY,GACZ,gBAAgB,GAChB,cAAc,GACd,gBAAgB,CAAA;AAEpB,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,KAAK,EACL,KAAK,EACL,OAAO,EACP,QAAgB,EAChB,KAAa,GACd,EAAE;IACD,KAAK,EAAE,WAAW,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB,+BAiCA;AAED,wBAAgB,mBAAmB,CAAC,EAClC,IAAI,EACJ,KAAK,EACL,WAAW,EACX,IAAI,EACJ,KAAK,EACL,OAAO,GACR,EAAE;IACD,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAA;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,WAAW,CAAA;IACjB,KAAK,EAAE,SAAS,WAAW,EAAE,CAAA;IAC7B,OAAO,EAAE,OAAO,CAAA;CACjB,+BA+EA;AAED,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,KAAK,EACL,KAAK,EACL,KAAK,EACL,OAAO,GACR,EAAE;IACD,KAAK,EAAE,YAAY,GAAG,YAAY,CAAA;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,OAAO,CAAA;IACd,OAAO,EAAE,OAAO,CAAA;CACjB,+BAwBA;AAED,eAAO,MAAM,sBAAsB,EAAE;IAAE,KAAK,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAItF,CAAA"}
1
+ {"version":3,"file":"glazing-controls.d.ts","sourceRoot":"","sources":["../../src/roof/glazing-controls.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAChE,OAAO,EAAE,KAAK,iBAAiB,EAAiB,MAAM,kBAAkB,CAAA;AAYxE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAA;AAEjE,KAAK,OAAO,GAAG,UAAU,CAAC,OAAO,wBAAwB,CAAC,CAAA;AAC1D,KAAK,WAAW,GACZ,YAAY,GACZ,YAAY,GACZ,gBAAgB,GAChB,cAAc,GACd,gBAAgB,CAAA;AAEpB,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,KAAK,EACL,KAAK,EACL,OAAO,EACP,QAAgB,EAChB,KAAa,GACd,EAAE;IACD,KAAK,EAAE,WAAW,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB,+BAiCA;AAED,wBAAgB,mBAAmB,CAAC,EAClC,IAAI,EACJ,KAAK,EACL,WAAW,EACX,IAAI,EACJ,KAAK,EACL,OAAO,GACR,EAAE;IACD,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAA;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,WAAW,CAAA;IACjB,KAAK,EAAE,SAAS,WAAW,EAAE,CAAA;IAC7B,OAAO,EAAE,OAAO,CAAA;CACjB,+BA2HA;AAED,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,KAAK,EACL,KAAK,EACL,KAAK,EACL,OAAO,GACR,EAAE;IACD,KAAK,EAAE,YAAY,GAAG,YAAY,CAAA;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,OAAO,CAAA;IACd,OAAO,EAAE,OAAO,CAAA;CACjB,+BA2BA;AAED,eAAO,MAAM,sBAAsB,EAAE;IACnC,KAAK,EAAE,WAAW,CAAC,WAAW,CAAC,CAAA;IAC/B,KAAK,EAAE,iBAAiB,CAAA;CACzB,EAIA,CAAA"}