@pascal-app/nodes 1.0.3 → 1.0.4

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 (708) hide show
  1. package/dist/block/definition.d.ts.map +1 -1
  2. package/dist/block/definition.js +18 -3
  3. package/dist/block/floorplan.d.ts +11 -1
  4. package/dist/block/floorplan.d.ts.map +1 -1
  5. package/dist/block/floorplan.js +81 -13
  6. package/dist/block/geometry.d.ts +2 -2
  7. package/dist/block/geometry.d.ts.map +1 -1
  8. package/dist/block/geometry.js +39 -24
  9. package/dist/block/hosted-edit.d.ts.map +1 -1
  10. package/dist/block/hosted-edit.js +25 -0
  11. package/dist/block/material-slots.d.ts +1 -3
  12. package/dist/block/material-slots.d.ts.map +1 -1
  13. package/dist/block/material-slots.js +1 -11
  14. package/dist/block/paint.d.ts.map +1 -1
  15. package/dist/block/paint.js +4 -10
  16. package/dist/block/panel.d.ts.map +1 -1
  17. package/dist/block/panel.js +8 -3
  18. package/dist/block/selection.d.ts.map +1 -1
  19. package/dist/block/selection.js +2 -2
  20. package/dist/box-vent/definition.d.ts.map +1 -1
  21. package/dist/box-vent/definition.js +2 -5
  22. package/dist/box-vent/panel.d.ts.map +1 -1
  23. package/dist/box-vent/panel.js +5 -28
  24. package/dist/cabinet/countertop-layout.d.ts +13 -2
  25. package/dist/cabinet/countertop-layout.d.ts.map +1 -1
  26. package/dist/cabinet/definition.d.ts.map +1 -1
  27. package/dist/cabinet/definition.js +1 -2
  28. package/dist/cabinet/floorplan.d.ts.map +1 -1
  29. package/dist/cabinet/floorplan.js +125 -28
  30. package/dist/cabinet/geometry/shared.d.ts +1 -2
  31. package/dist/cabinet/geometry/shared.d.ts.map +1 -1
  32. package/dist/cabinet/geometry/shared.js +1 -2
  33. package/dist/cabinet/run-layout.d.ts.map +1 -1
  34. package/dist/cabinet/run-layout.js +8 -5
  35. package/dist/cabinet/run-ops.d.ts +13 -2
  36. package/dist/cabinet/run-ops.d.ts.map +1 -1
  37. package/dist/cabinet/tool.d.ts.map +1 -1
  38. package/dist/cabinet/tool.js +22 -24
  39. package/dist/cabinet/wall-snap.d.ts.map +1 -1
  40. package/dist/cabinet/wall-snap.js +8 -8
  41. package/dist/ceiling/boundary-editor.d.ts.map +1 -1
  42. package/dist/ceiling/boundary-editor.js +5 -3
  43. package/dist/ceiling/definition.d.ts +4 -4
  44. package/dist/ceiling/definition.d.ts.map +1 -1
  45. package/dist/ceiling/definition.js +15 -15
  46. package/dist/ceiling/floorplan-affordances.d.ts +84 -4
  47. package/dist/ceiling/floorplan-affordances.d.ts.map +1 -1
  48. package/dist/ceiling/floorplan-affordances.js +0 -1
  49. package/dist/ceiling/floorplan-move.d.ts.map +1 -1
  50. package/dist/ceiling/floorplan-move.js +0 -1
  51. package/dist/ceiling/floorplan.d.ts +1 -1
  52. package/dist/ceiling/floorplan.d.ts.map +1 -1
  53. package/dist/ceiling/floorplan.js +2 -1
  54. package/dist/ceiling/height-bounds.d.ts +19 -0
  55. package/dist/ceiling/height-bounds.d.ts.map +1 -0
  56. package/dist/ceiling/height-bounds.js +24 -0
  57. package/dist/ceiling/hole-editor.d.ts.map +1 -1
  58. package/dist/ceiling/hole-editor.js +3 -4
  59. package/dist/ceiling/materials.d.ts +1 -1
  60. package/dist/ceiling/materials.d.ts.map +1 -1
  61. package/dist/ceiling/materials.js +10 -3
  62. package/dist/ceiling/paint.d.ts +2 -8
  63. package/dist/ceiling/paint.d.ts.map +1 -1
  64. package/dist/ceiling/paint.js +121 -24
  65. package/dist/ceiling/panel.d.ts.map +1 -1
  66. package/dist/ceiling/panel.js +40 -23
  67. package/dist/ceiling/renderer.d.ts.map +1 -1
  68. package/dist/ceiling/renderer.js +41 -5
  69. package/dist/chimney/move-tool.d.ts.map +1 -1
  70. package/dist/chimney/move-tool.js +8 -2
  71. package/dist/chimney/paint.d.ts.map +1 -1
  72. package/dist/chimney/paint.js +3 -10
  73. package/dist/column/definition.d.ts.map +1 -1
  74. package/dist/column/definition.js +24 -2
  75. package/dist/column/floorplan-affordances.d.ts.map +1 -1
  76. package/dist/column/floorplan-affordances.js +5 -0
  77. package/dist/column/floorplan.d.ts +1 -1
  78. package/dist/column/floorplan.d.ts.map +1 -1
  79. package/dist/column/floorplan.js +47 -2
  80. package/dist/column/hosted-resize.d.ts +101 -2
  81. package/dist/column/hosted-resize.d.ts.map +1 -1
  82. package/dist/column/panel.d.ts.map +1 -1
  83. package/dist/column/panel.js +147 -146
  84. package/dist/column/renderer.d.ts.map +1 -1
  85. package/dist/column/renderer.js +6 -4
  86. package/dist/column/surface.d.ts.map +1 -1
  87. package/dist/column/surface.js +7 -0
  88. package/dist/construction-dimension/floorplan.js +7 -3
  89. package/dist/cupola/definition.d.ts.map +1 -1
  90. package/dist/cupola/definition.js +2 -8
  91. package/dist/cupola/panel.d.ts.map +1 -1
  92. package/dist/cupola/panel.js +5 -23
  93. package/dist/door/definition.d.ts.map +1 -1
  94. package/dist/door/definition.js +12 -3
  95. package/dist/door/door-math.d.ts +5 -10
  96. package/dist/door/door-math.d.ts.map +1 -1
  97. package/dist/door/door-math.js +14 -15
  98. package/dist/door/floorplan-move.d.ts.map +1 -1
  99. package/dist/door/floorplan-move.js +3 -1
  100. package/dist/door/floorplan.d.ts.map +1 -1
  101. package/dist/door/floorplan.js +55 -21
  102. package/dist/door/mechanism.d.ts +4 -0
  103. package/dist/door/mechanism.d.ts.map +1 -0
  104. package/dist/door/mechanism.js +24 -0
  105. package/dist/door/move-tool.d.ts.map +1 -1
  106. package/dist/door/move-tool.js +72 -48
  107. package/dist/door/paint.d.ts.map +1 -1
  108. package/dist/door/paint.js +3 -0
  109. package/dist/door/panel.d.ts.map +1 -1
  110. package/dist/door/panel.js +34 -259
  111. package/dist/door/placement.d.ts +45 -0
  112. package/dist/door/placement.d.ts.map +1 -0
  113. package/dist/door/placement.js +51 -0
  114. package/dist/door/preview.d.ts.map +1 -1
  115. package/dist/door/preview.js +2 -0
  116. package/dist/door/renderer.d.ts.map +1 -1
  117. package/dist/door/renderer.js +3 -2
  118. package/dist/door/tool.d.ts.map +1 -1
  119. package/dist/door/tool.js +92 -21
  120. package/dist/dormer/csg-geometry.d.ts.map +1 -1
  121. package/dist/dormer/csg-geometry.js +2 -0
  122. package/dist/dormer/paint.d.ts.map +1 -1
  123. package/dist/dormer/paint.js +2 -5
  124. package/dist/dormer/panel.d.ts.map +1 -1
  125. package/dist/dormer/panel.js +4 -14
  126. package/dist/downspout/definition.d.ts.map +1 -1
  127. package/dist/downspout/definition.js +2 -2
  128. package/dist/duct-fitting/definition.d.ts.map +1 -1
  129. package/dist/duct-fitting/definition.js +2 -1
  130. package/dist/duct-fitting/geometry.d.ts.map +1 -1
  131. package/dist/duct-fitting/geometry.js +1 -1
  132. package/dist/duct-fitting/move-tool.d.ts.map +1 -1
  133. package/dist/duct-fitting/move-tool.js +8 -2
  134. package/dist/duct-segment/definition.d.ts.map +1 -1
  135. package/dist/duct-segment/definition.js +2 -2
  136. package/dist/duct-segment/geometry.d.ts.map +1 -1
  137. package/dist/duct-segment/geometry.js +1 -1
  138. package/dist/duct-segment/move-tool.d.ts.map +1 -1
  139. package/dist/duct-segment/move-tool.js +8 -2
  140. package/dist/elevator/definition.d.ts.map +1 -1
  141. package/dist/elevator/definition.js +1 -2
  142. package/dist/elevator/panel.d.ts.map +1 -1
  143. package/dist/elevator/panel.js +5 -27
  144. package/dist/elevator/parametrics.js +1 -1
  145. package/dist/elevator/renderer.d.ts.map +1 -1
  146. package/dist/elevator/renderer.js +3 -4
  147. package/dist/eyebrow-vent/definition.d.ts.map +1 -1
  148. package/dist/eyebrow-vent/definition.js +2 -5
  149. package/dist/eyebrow-vent/paint.d.ts.map +1 -1
  150. package/dist/eyebrow-vent/paint.js +3 -6
  151. package/dist/eyebrow-vent/panel.d.ts.map +1 -1
  152. package/dist/eyebrow-vent/panel.js +5 -23
  153. package/dist/fence/actions/move-endpoint.d.ts +1 -1
  154. package/dist/fence/actions/move-endpoint.d.ts.map +1 -1
  155. package/dist/fence/actions/move-endpoint.js +2 -1
  156. package/dist/fence/definition.d.ts +2 -1
  157. package/dist/fence/definition.d.ts.map +1 -1
  158. package/dist/fence/definition.js +83 -28
  159. package/dist/fence/drafting.d.ts +36 -0
  160. package/dist/fence/drafting.d.ts.map +1 -0
  161. package/dist/fence/drafting.js +210 -0
  162. package/dist/fence/feature-tool.d.ts +4 -0
  163. package/dist/fence/feature-tool.d.ts.map +1 -0
  164. package/dist/fence/feature-tool.js +140 -0
  165. package/dist/fence/features.d.ts +2 -0
  166. package/dist/fence/features.d.ts.map +1 -0
  167. package/dist/fence/features.js +12 -0
  168. package/dist/fence/floorplan-affordances.d.ts.map +1 -1
  169. package/dist/fence/floorplan-affordances.js +2 -1
  170. package/dist/fence/floorplan.d.ts +2 -3
  171. package/dist/fence/floorplan.d.ts.map +1 -1
  172. package/dist/fence/floorplan.js +131 -71
  173. package/dist/fence/geometry-parts.d.ts +50 -0
  174. package/dist/fence/geometry-parts.d.ts.map +1 -0
  175. package/dist/fence/geometry-parts.js +1144 -0
  176. package/dist/fence/geometry.d.ts +2 -3
  177. package/dist/fence/geometry.d.ts.map +1 -1
  178. package/dist/fence/geometry.js +84 -7
  179. package/dist/fence/index.d.ts +1 -0
  180. package/dist/fence/index.d.ts.map +1 -1
  181. package/dist/fence/index.js +1 -0
  182. package/dist/fence/inspector-editors.d.ts +15 -0
  183. package/dist/fence/inspector-editors.d.ts.map +1 -1
  184. package/dist/fence/inspector-editors.js +128 -3
  185. package/dist/fence/lift.d.ts.map +1 -1
  186. package/dist/fence/lift.js +5 -2
  187. package/dist/fence/move-tool.js +2 -1
  188. package/dist/fence/panel-model.d.ts +4 -0
  189. package/dist/fence/panel-model.d.ts.map +1 -0
  190. package/dist/fence/panel-model.js +12 -0
  191. package/dist/fence/parametrics.d.ts +0 -12
  192. package/dist/fence/parametrics.d.ts.map +1 -1
  193. package/dist/fence/parametrics.js +185 -18
  194. package/dist/fence/system.d.ts.map +1 -1
  195. package/dist/fence/system.js +141 -31
  196. package/dist/fence/tool.d.ts.map +1 -1
  197. package/dist/fence/tool.js +256 -47
  198. package/dist/fence-feature/actions.d.ts +7 -0
  199. package/dist/fence-feature/actions.d.ts.map +1 -0
  200. package/dist/fence-feature/actions.js +26 -0
  201. package/dist/fence-feature/definition.d.ts +4 -0
  202. package/dist/fence-feature/definition.d.ts.map +1 -0
  203. package/dist/fence-feature/definition.js +112 -0
  204. package/dist/fence-feature/floorplan-affordances.d.ts +3 -0
  205. package/dist/fence-feature/floorplan-affordances.d.ts.map +1 -0
  206. package/dist/fence-feature/floorplan-affordances.js +37 -0
  207. package/dist/fence-feature/floorplan.d.ts +4 -0
  208. package/dist/fence-feature/floorplan.d.ts.map +1 -0
  209. package/dist/fence-feature/floorplan.js +120 -0
  210. package/dist/fence-feature/geometry.d.ts +5 -0
  211. package/dist/fence-feature/geometry.d.ts.map +1 -0
  212. package/dist/fence-feature/geometry.js +43 -0
  213. package/dist/fence-feature/handles.d.ts +5 -0
  214. package/dist/fence-feature/handles.d.ts.map +1 -0
  215. package/dist/fence-feature/handles.js +84 -0
  216. package/dist/fence-feature/inspector.d.ts +6 -0
  217. package/dist/fence-feature/inspector.d.ts.map +1 -0
  218. package/dist/fence-feature/inspector.js +214 -0
  219. package/dist/fence-feature/interaction.d.ts +3 -0
  220. package/dist/fence-feature/interaction.d.ts.map +1 -0
  221. package/dist/fence-feature/interaction.js +41 -0
  222. package/dist/fence-feature/move-session.d.ts +9 -0
  223. package/dist/fence-feature/move-session.d.ts.map +1 -0
  224. package/dist/fence-feature/move-session.js +48 -0
  225. package/dist/fence-feature/move-tool.d.ts +5 -0
  226. package/dist/fence-feature/move-tool.d.ts.map +1 -0
  227. package/dist/fence-feature/move-tool.js +58 -0
  228. package/dist/fence-feature/pick-target.d.ts +7 -0
  229. package/dist/fence-feature/pick-target.d.ts.map +1 -0
  230. package/dist/fence-feature/pick-target.js +52 -0
  231. package/dist/floor-opening/definition.d.ts +3 -0
  232. package/dist/floor-opening/definition.d.ts.map +1 -0
  233. package/dist/floor-opening/definition.js +41 -0
  234. package/dist/floor-opening/floorplan.d.ts +156 -0
  235. package/dist/floor-opening/floorplan.d.ts.map +1 -0
  236. package/dist/floor-opening/floorplan.js +63 -0
  237. package/dist/gutter/definition.d.ts.map +1 -1
  238. package/dist/gutter/definition.js +2 -2
  239. package/dist/imported-mesh/definition.d.ts.map +1 -1
  240. package/dist/imported-mesh/definition.js +2 -0
  241. package/dist/imported-mesh/geometry.d.ts +1 -1
  242. package/dist/imported-mesh/geometry.d.ts.map +1 -1
  243. package/dist/imported-mesh/geometry.js +40 -12
  244. package/dist/index.d.ts +13 -2
  245. package/dist/index.d.ts.map +1 -1
  246. package/dist/index.js +20 -2
  247. package/dist/item/authored-face-host.d.ts +10 -0
  248. package/dist/item/authored-face-host.d.ts.map +1 -0
  249. package/dist/item/authored-face-host.js +87 -0
  250. package/dist/item/authored-params.d.ts +15 -0
  251. package/dist/item/authored-params.d.ts.map +1 -0
  252. package/dist/item/authored-params.js +72 -0
  253. package/dist/item/definition.d.ts +2 -2
  254. package/dist/item/definition.d.ts.map +1 -1
  255. package/dist/item/definition.js +33 -4
  256. package/dist/item/floorplan.d.ts +1 -1
  257. package/dist/item/floorplan.d.ts.map +1 -1
  258. package/dist/item/floorplan.js +35 -5
  259. package/dist/item/index.d.ts +1 -0
  260. package/dist/item/index.d.ts.map +1 -1
  261. package/dist/item/index.js +1 -0
  262. package/dist/item/model-loader.d.ts +2 -0
  263. package/dist/item/model-loader.d.ts.map +1 -1
  264. package/dist/item/model-loader.js +55 -23
  265. package/dist/item/move-tool.js +4 -4
  266. package/dist/item/paint.d.ts.map +1 -1
  267. package/dist/item/paint.js +5 -24
  268. package/dist/item/panel.d.ts +1 -3
  269. package/dist/item/panel.d.ts.map +1 -1
  270. package/dist/item/panel.js +20 -24
  271. package/dist/item/placement-notice.d.ts +14 -0
  272. package/dist/item/placement-notice.d.ts.map +1 -0
  273. package/dist/item/placement-notice.js +38 -0
  274. package/dist/item/plan-symbols.d.ts +67 -0
  275. package/dist/item/plan-symbols.d.ts.map +1 -0
  276. package/dist/item/plan-symbols.js +407 -0
  277. package/dist/item/renderer.d.ts +10 -0
  278. package/dist/item/renderer.d.ts.map +1 -1
  279. package/dist/item/renderer.js +64 -38
  280. package/dist/item/script-param-defaults.d.ts +12 -0
  281. package/dist/item/script-param-defaults.d.ts.map +1 -0
  282. package/dist/item/script-param-defaults.js +34 -0
  283. package/dist/lean-to-extension/definition.d.ts.map +1 -1
  284. package/dist/lean-to-extension/definition.js +1 -2
  285. package/dist/lean-to-extension/geometry.d.ts.map +1 -1
  286. package/dist/lean-to-extension/geometry.js +1 -1
  287. package/dist/lean-to-extension/layout.d.ts.map +1 -1
  288. package/dist/lean-to-extension/layout.js +2 -3
  289. package/dist/lean-to-extension/placement-validation.d.ts.map +1 -1
  290. package/dist/lean-to-extension/placement-validation.js +5 -5
  291. package/dist/lean-to-extension/tool.d.ts.map +1 -1
  292. package/dist/lean-to-extension/tool.js +5 -5
  293. package/dist/lineset/move-tool.d.ts.map +1 -1
  294. package/dist/lineset/move-tool.js +8 -2
  295. package/dist/liquid-line/move-tool.d.ts.map +1 -1
  296. package/dist/liquid-line/move-tool.js +8 -2
  297. package/dist/measurement/definition.js +1 -1
  298. package/dist/pipe-fitting/move-tool.d.ts.map +1 -1
  299. package/dist/pipe-fitting/move-tool.js +8 -2
  300. package/dist/pipe-segment/move-tool.d.ts.map +1 -1
  301. package/dist/pipe-segment/move-tool.js +8 -2
  302. package/dist/procedural-item/animation.d.ts +8 -0
  303. package/dist/procedural-item/animation.d.ts.map +1 -0
  304. package/dist/procedural-item/animation.js +116 -0
  305. package/dist/procedural-item/definition.d.ts.map +1 -1
  306. package/dist/procedural-item/definition.js +74 -8
  307. package/dist/procedural-item/geometry.d.ts +5 -1
  308. package/dist/procedural-item/geometry.d.ts.map +1 -1
  309. package/dist/procedural-item/geometry.js +239 -15
  310. package/dist/procedural-item/renderer.d.ts.map +1 -1
  311. package/dist/procedural-item/renderer.js +272 -23
  312. package/dist/ridge-vent/panel.d.ts.map +1 -1
  313. package/dist/ridge-vent/panel.js +5 -23
  314. package/dist/ridge-vent/renderer.d.ts.map +1 -1
  315. package/dist/ridge-vent/renderer.js +9 -8
  316. package/dist/roof/definition.d.ts.map +1 -1
  317. package/dist/roof/definition.js +4 -1
  318. package/dist/roof/floorplan.d.ts +8 -0
  319. package/dist/roof/floorplan.d.ts.map +1 -1
  320. package/dist/roof/floorplan.js +194 -18
  321. package/dist/roof/panel-model.d.ts.map +1 -1
  322. package/dist/roof/panel-model.js +10 -6
  323. package/dist/roof/panel.d.ts.map +1 -1
  324. package/dist/roof/panel.js +3 -10
  325. package/dist/roof/renderer.d.ts.map +1 -1
  326. package/dist/roof/renderer.js +5 -2
  327. package/dist/roof-segment/panel.d.ts.map +1 -1
  328. package/dist/roof-segment/panel.js +5 -24
  329. package/dist/roof-segment/renderer.d.ts.map +1 -1
  330. package/dist/roof-segment/renderer.js +17 -8
  331. package/dist/separator/definition.d.ts +3 -0
  332. package/dist/separator/definition.d.ts.map +1 -0
  333. package/dist/separator/definition.js +39 -0
  334. package/dist/separator/renderer.d.ts +5 -0
  335. package/dist/separator/renderer.d.ts.map +1 -0
  336. package/dist/separator/renderer.js +36 -0
  337. package/dist/shared/duct-body-paint.d.ts +0 -4
  338. package/dist/shared/duct-body-paint.d.ts.map +1 -1
  339. package/dist/shared/duct-body-paint.js +1 -5
  340. package/dist/shared/item-interaction-actions.d.ts +6 -0
  341. package/dist/shared/item-interaction-actions.d.ts.map +1 -0
  342. package/dist/shared/item-interaction-actions.js +27 -0
  343. package/dist/shared/item-interactions.d.ts +9 -0
  344. package/dist/shared/item-interactions.d.ts.map +1 -0
  345. package/dist/shared/item-interactions.js +74 -0
  346. package/dist/shared/item-light-placement.d.ts +2 -0
  347. package/dist/shared/item-light-placement.d.ts.map +1 -0
  348. package/dist/shared/item-light-placement.js +3 -0
  349. package/dist/shared/move-roof-tool.js +2 -1
  350. package/dist/shared/node-batch/batchable.d.ts +12 -0
  351. package/dist/shared/node-batch/batchable.d.ts.map +1 -0
  352. package/dist/shared/node-batch/batchable.js +41 -0
  353. package/dist/shared/node-batch/candidates.d.ts +7 -5
  354. package/dist/shared/node-batch/candidates.d.ts.map +1 -1
  355. package/dist/shared/node-batch/candidates.js +43 -59
  356. package/dist/shared/node-batch/release.d.ts +8 -0
  357. package/dist/shared/node-batch/release.d.ts.map +1 -0
  358. package/dist/shared/node-batch/release.js +16 -0
  359. package/dist/shared/node-batch/system.d.ts.map +1 -1
  360. package/dist/shared/node-batch/system.js +17 -12
  361. package/dist/shared/node-batch/types.d.ts +4 -1
  362. package/dist/shared/node-batch/types.d.ts.map +1 -1
  363. package/dist/shared/opening-documentation.d.ts +13 -1
  364. package/dist/shared/opening-documentation.d.ts.map +1 -1
  365. package/dist/shared/opening-documentation.js +245 -59
  366. package/dist/shared/opening-guides-runtime.d.ts.map +1 -1
  367. package/dist/shared/opening-guides-runtime.js +17 -14
  368. package/dist/shared/opening-placement-dimensions.d.ts.map +1 -1
  369. package/dist/shared/opening-placement-dimensions.js +3 -3
  370. package/dist/shared/opening-plane-offset.d.ts +23 -0
  371. package/dist/shared/opening-plane-offset.d.ts.map +1 -0
  372. package/dist/shared/opening-plane-offset.js +24 -0
  373. package/dist/shared/polygon-centroid-move.d.ts.map +1 -1
  374. package/dist/shared/polygon-centroid-move.js +4 -1
  375. package/dist/shared/polygon-vertex-affordance.d.ts.map +1 -1
  376. package/dist/shared/polygon-vertex-affordance.js +19 -15
  377. package/dist/shared/run-hangers.d.ts.map +1 -1
  378. package/dist/shared/run-hangers.js +5 -4
  379. package/dist/shared/scripted-opening-handles.d.ts +18 -0
  380. package/dist/shared/scripted-opening-handles.d.ts.map +1 -0
  381. package/dist/shared/scripted-opening-handles.js +53 -0
  382. package/dist/shared/scripted-opening.d.ts +25 -0
  383. package/dist/shared/scripted-opening.d.ts.map +1 -0
  384. package/dist/shared/scripted-opening.js +72 -0
  385. package/dist/shared/slot-paint.d.ts +14 -2
  386. package/dist/shared/slot-paint.d.ts.map +1 -1
  387. package/dist/shared/slot-paint.js +29 -29
  388. package/dist/shared/surface-paint.d.ts.map +1 -1
  389. package/dist/shared/surface-paint.js +2 -5
  390. package/dist/shared/swap-preview-material.d.ts +11 -0
  391. package/dist/shared/swap-preview-material.d.ts.map +1 -0
  392. package/dist/shared/swap-preview-material.js +16 -0
  393. package/dist/shared/system-checks.d.ts.map +1 -1
  394. package/dist/shared/system-checks.js +5 -3
  395. package/dist/shared/wall-attach-target.d.ts +3 -10
  396. package/dist/shared/wall-attach-target.d.ts.map +1 -1
  397. package/dist/shared/wall-attach-target.js +3 -63
  398. package/dist/shared/wall-opening-ceiling.d.ts +5 -15
  399. package/dist/shared/wall-opening-ceiling.d.ts.map +1 -1
  400. package/dist/shared/wall-opening-ceiling.js +10 -18
  401. package/dist/shelf/definition.d.ts.map +1 -1
  402. package/dist/shelf/definition.js +1 -1
  403. package/dist/shelf/geometry.d.ts.map +1 -1
  404. package/dist/shelf/geometry.js +1 -2
  405. package/dist/shelf/paint.d.ts.map +1 -1
  406. package/dist/shelf/paint.js +4 -10
  407. package/dist/site/line-ribbon.d.ts +31 -0
  408. package/dist/site/line-ribbon.d.ts.map +1 -0
  409. package/dist/site/line-ribbon.js +117 -0
  410. package/dist/site/lot-mask.d.ts +18 -0
  411. package/dist/site/lot-mask.d.ts.map +1 -0
  412. package/dist/site/lot-mask.js +35 -0
  413. package/dist/site/panel.d.ts +10 -0
  414. package/dist/site/panel.d.ts.map +1 -0
  415. package/dist/site/panel.js +155 -0
  416. package/dist/site/parametrics.d.ts +7 -0
  417. package/dist/site/parametrics.d.ts.map +1 -1
  418. package/dist/site/parametrics.js +8 -0
  419. package/dist/site/recessed-slab-ground-holes.d.ts.map +1 -1
  420. package/dist/site/recessed-slab-ground-holes.js +5 -2
  421. package/dist/site/renderer.d.ts.map +1 -1
  422. package/dist/site/renderer.js +150 -19
  423. package/dist/site/setbacks.d.ts +33 -0
  424. package/dist/site/setbacks.d.ts.map +1 -0
  425. package/dist/site/setbacks.js +204 -0
  426. package/dist/site/terrain-geometry.d.ts +28 -1
  427. package/dist/site/terrain-geometry.d.ts.map +1 -1
  428. package/dist/site/terrain-geometry.js +78 -4
  429. package/dist/site/terrain-holes.d.ts +15 -0
  430. package/dist/site/terrain-holes.d.ts.map +1 -0
  431. package/dist/site/terrain-holes.js +74 -0
  432. package/dist/site/terrain-mesh.d.ts +9 -2
  433. package/dist/site/terrain-mesh.d.ts.map +1 -1
  434. package/dist/site/terrain-mesh.js +36 -9
  435. package/dist/site/terrain-renderer.d.ts +9 -2
  436. package/dist/site/terrain-renderer.d.ts.map +1 -1
  437. package/dist/site/terrain-renderer.js +14 -4
  438. package/dist/slab/boundary-editor.d.ts +1 -1
  439. package/dist/slab/boundary-editor.d.ts.map +1 -1
  440. package/dist/slab/boundary-editor.js +13 -13
  441. package/dist/slab/definition.d.ts.map +1 -1
  442. package/dist/slab/definition.js +19 -3
  443. package/dist/slab/dependency-tracker.d.ts.map +1 -1
  444. package/dist/slab/dependency-tracker.js +67 -7
  445. package/dist/slab/elevation-limit.d.ts.map +1 -1
  446. package/dist/slab/elevation-limit.js +2 -2
  447. package/dist/slab/floorplan-affordances.d.ts +176 -4
  448. package/dist/slab/floorplan-affordances.d.ts.map +1 -1
  449. package/dist/slab/floorplan-affordances.js +0 -1
  450. package/dist/slab/floorplan-move.d.ts.map +1 -1
  451. package/dist/slab/floorplan-move.js +3 -4
  452. package/dist/slab/floorplan.d.ts +7 -0
  453. package/dist/slab/floorplan.d.ts.map +1 -1
  454. package/dist/slab/floorplan.js +22 -5
  455. package/dist/slab/geometry.d.ts.map +1 -1
  456. package/dist/slab/geometry.js +186 -76
  457. package/dist/slab/move-tool.js +7 -6
  458. package/dist/slab/paint.d.ts +18 -5
  459. package/dist/slab/paint.d.ts.map +1 -1
  460. package/dist/slab/paint.js +458 -9
  461. package/dist/slab/panel.d.ts.map +1 -1
  462. package/dist/slab/panel.js +28 -9
  463. package/dist/slab/placement-ownership.d.ts +2 -1
  464. package/dist/slab/placement-ownership.d.ts.map +1 -1
  465. package/dist/slab/placement-ownership.js +2 -2
  466. package/dist/slab/surface-split.d.ts +24 -0
  467. package/dist/slab/surface-split.d.ts.map +1 -0
  468. package/dist/slab/surface-split.js +389 -0
  469. package/dist/slab/tool.d.ts.map +1 -1
  470. package/dist/slab/tool.js +3 -3
  471. package/dist/stair/baluster-geometry.d.ts +21 -0
  472. package/dist/stair/baluster-geometry.d.ts.map +1 -0
  473. package/dist/stair/baluster-geometry.js +74 -0
  474. package/dist/stair/baluster-guard.d.ts +50 -0
  475. package/dist/stair/baluster-guard.d.ts.map +1 -0
  476. package/dist/stair/baluster-guard.js +71 -0
  477. package/dist/stair/boards-guard.d.ts +37 -0
  478. package/dist/stair/boards-guard.d.ts.map +1 -0
  479. package/dist/stair/boards-guard.js +61 -0
  480. package/dist/stair/cable-guard.d.ts +39 -0
  481. package/dist/stair/cable-guard.d.ts.map +1 -0
  482. package/dist/stair/cable-guard.js +105 -0
  483. package/dist/stair/construction-controls.d.ts +15 -0
  484. package/dist/stair/construction-controls.d.ts.map +1 -0
  485. package/dist/stair/construction-controls.js +29 -0
  486. package/dist/stair/continuous-railings.d.ts +10 -0
  487. package/dist/stair/continuous-railings.d.ts.map +1 -0
  488. package/dist/stair/continuous-railings.js +159 -0
  489. package/dist/stair/definition.d.ts.map +1 -1
  490. package/dist/stair/definition.js +16 -37
  491. package/dist/stair/documentation.d.ts +1 -1
  492. package/dist/stair/documentation.d.ts.map +1 -1
  493. package/dist/stair/documentation.js +10 -17
  494. package/dist/stair/floorplan-affordances.d.ts.map +1 -1
  495. package/dist/stair/floorplan-affordances.js +9 -25
  496. package/dist/stair/floorplan.d.ts +1 -23
  497. package/dist/stair/floorplan.d.ts.map +1 -1
  498. package/dist/stair/floorplan.js +102 -86
  499. package/dist/stair/glass-guard.d.ts +72 -0
  500. package/dist/stair/glass-guard.d.ts.map +1 -0
  501. package/dist/stair/glass-guard.js +167 -0
  502. package/dist/stair/guard-path.d.ts +119 -0
  503. package/dist/stair/guard-path.d.ts.map +1 -0
  504. package/dist/stair/guard-path.js +208 -0
  505. package/dist/stair/materials.d.ts +11 -0
  506. package/dist/stair/materials.d.ts.map +1 -0
  507. package/dist/stair/materials.js +51 -0
  508. package/dist/stair/metal-guard.d.ts +38 -0
  509. package/dist/stair/metal-guard.d.ts.map +1 -0
  510. package/dist/stair/metal-guard.js +79 -0
  511. package/dist/stair/paint.d.ts +32 -0
  512. package/dist/stair/paint.d.ts.map +1 -1
  513. package/dist/stair/paint.js +75 -36
  514. package/dist/stair/panel.d.ts.map +1 -1
  515. package/dist/stair/panel.js +154 -17
  516. package/dist/stair/parametrics.d.ts +1 -1
  517. package/dist/stair/parametrics.d.ts.map +1 -1
  518. package/dist/stair/parametrics.js +32 -15
  519. package/dist/stair/plan-entry.d.ts +31 -0
  520. package/dist/stair/plan-entry.d.ts.map +1 -0
  521. package/dist/stair/plan-entry.js +325 -0
  522. package/dist/stair/post-and-rail-guard.d.ts +31 -0
  523. package/dist/stair/post-and-rail-guard.d.ts.map +1 -0
  524. package/dist/stair/post-and-rail-guard.js +63 -0
  525. package/dist/stair/railing-controls.d.ts +9 -0
  526. package/dist/stair/railing-controls.d.ts.map +1 -0
  527. package/dist/stair/railing-controls.js +49 -0
  528. package/dist/stair/renderer.d.ts.map +1 -1
  529. package/dist/stair/renderer.js +259 -259
  530. package/dist/stair/use-stair-render-data.d.ts +317 -0
  531. package/dist/stair/use-stair-render-data.d.ts.map +1 -0
  532. package/dist/stair/use-stair-render-data.js +73 -0
  533. package/dist/stair-segment/definition.d.ts.map +1 -1
  534. package/dist/stair-segment/definition.js +51 -10
  535. package/dist/stair-segment/panel.d.ts.map +1 -1
  536. package/dist/stair-segment/panel.js +36 -42
  537. package/dist/stair-segment/parametrics.d.ts +1 -1
  538. package/dist/stair-segment/parametrics.d.ts.map +1 -1
  539. package/dist/stair-segment/parametrics.js +21 -8
  540. package/dist/stair-segment/renderer.d.ts.map +1 -1
  541. package/dist/stair-segment/renderer.js +16 -28
  542. package/dist/turbine-vent/definition.d.ts.map +1 -1
  543. package/dist/turbine-vent/definition.js +2 -5
  544. package/dist/turbine-vent/paint.d.ts.map +1 -1
  545. package/dist/turbine-vent/paint.js +2 -5
  546. package/dist/turbine-vent/panel.d.ts.map +1 -1
  547. package/dist/turbine-vent/panel.js +5 -23
  548. package/dist/unit/unit-panel.d.ts.map +1 -1
  549. package/dist/unit/unit-panel.js +6 -1
  550. package/dist/wall/actions.d.ts.map +1 -1
  551. package/dist/wall/actions.js +7 -2
  552. package/dist/wall/construction-dimensions.js +8 -5
  553. package/dist/wall/contextual-dimensions.js +4 -4
  554. package/dist/wall/curtain-wall-materials.d.ts +1 -1
  555. package/dist/wall/curtain-wall-materials.d.ts.map +1 -1
  556. package/dist/wall/curtain-wall-materials.js +2 -2
  557. package/dist/wall/curve-tool.d.ts.map +1 -1
  558. package/dist/wall/curve-tool.js +4 -0
  559. package/dist/wall/definition.d.ts.map +1 -1
  560. package/dist/wall/definition.js +41 -17
  561. package/dist/wall/floorplan-move.d.ts +1 -1
  562. package/dist/wall/floorplan-move.d.ts.map +1 -1
  563. package/dist/wall/floorplan-move.js +20 -83
  564. package/dist/wall/floorplan-tool.d.ts.map +1 -1
  565. package/dist/wall/floorplan-tool.js +10 -11
  566. package/dist/wall/floorplan.d.ts +3 -1
  567. package/dist/wall/floorplan.d.ts.map +1 -1
  568. package/dist/wall/floorplan.js +184 -21
  569. package/dist/wall/measurement.d.ts.map +1 -1
  570. package/dist/wall/measurement.js +5 -5
  571. package/dist/wall/move-endpoint-tool.d.ts.map +1 -1
  572. package/dist/wall/move-endpoint-tool.js +20 -7
  573. package/dist/wall/move-shared.d.ts.map +1 -1
  574. package/dist/wall/move-shared.js +11 -7
  575. package/dist/wall/move-tool.d.ts.map +1 -1
  576. package/dist/wall/move-tool.js +118 -148
  577. package/dist/wall/paint.d.ts +26 -15
  578. package/dist/wall/paint.d.ts.map +1 -1
  579. package/dist/wall/paint.js +306 -117
  580. package/dist/wall/panel-model.d.ts +18 -0
  581. package/dist/wall/panel-model.d.ts.map +1 -1
  582. package/dist/wall/panel-model.js +77 -19
  583. package/dist/wall/panel.d.ts.map +1 -1
  584. package/dist/wall/panel.js +217 -41
  585. package/dist/wall/parametrics.d.ts.map +1 -1
  586. package/dist/wall/parametrics.js +3 -0
  587. package/dist/wall/rectangle-command.d.ts +111 -12
  588. package/dist/wall/rectangle-command.d.ts.map +1 -1
  589. package/dist/wall/rectangle-tool.d.ts.map +1 -1
  590. package/dist/wall/rectangle-tool.js +26 -8
  591. package/dist/wall/renderer.d.ts.map +1 -1
  592. package/dist/wall/renderer.js +4 -2
  593. package/dist/wall/split-floorplan-layer.d.ts.map +1 -1
  594. package/dist/wall/split-floorplan-layer.js +7 -7
  595. package/dist/wall/split-session.d.ts.map +1 -1
  596. package/dist/wall/split-session.js +7 -1
  597. package/dist/wall/system.d.ts.map +1 -1
  598. package/dist/wall/system.js +36 -4
  599. package/dist/wall/tool.d.ts.map +1 -1
  600. package/dist/wall/tool.js +105 -49
  601. package/dist/wall/treatment-level-data.d.ts +3 -2
  602. package/dist/wall/treatment-level-data.d.ts.map +1 -1
  603. package/dist/wall/treatment-level-data.js +17 -13
  604. package/dist/wall/treatments.d.ts +10 -10
  605. package/dist/wall/treatments.d.ts.map +1 -1
  606. package/dist/wall/treatments.js +67 -54
  607. package/dist/wall/wall-batch-system.d.ts +7 -0
  608. package/dist/wall/wall-batch-system.d.ts.map +1 -1
  609. package/dist/wall/wall-batch-system.js +35 -3
  610. package/dist/wall/wall-batch.d.ts +6 -0
  611. package/dist/wall/wall-batch.d.ts.map +1 -1
  612. package/dist/wall/wall-batch.js +7 -1
  613. package/dist/window/definition.d.ts.map +1 -1
  614. package/dist/window/definition.js +12 -4
  615. package/dist/window/floorplan-move.d.ts.map +1 -1
  616. package/dist/window/floorplan-move.js +3 -1
  617. package/dist/window/floorplan.d.ts.map +1 -1
  618. package/dist/window/floorplan.js +145 -60
  619. package/dist/window/mechanism.d.ts +4 -0
  620. package/dist/window/mechanism.d.ts.map +1 -0
  621. package/dist/window/mechanism.js +20 -0
  622. package/dist/window/move-tool.d.ts.map +1 -1
  623. package/dist/window/move-tool.js +79 -48
  624. package/dist/window/paint.d.ts.map +1 -1
  625. package/dist/window/paint.js +3 -0
  626. package/dist/window/panel.d.ts.map +1 -1
  627. package/dist/window/panel.js +32 -88
  628. package/dist/window/placement.d.ts +23 -0
  629. package/dist/window/placement.d.ts.map +1 -0
  630. package/dist/window/placement.js +66 -0
  631. package/dist/window/preview.d.ts.map +1 -1
  632. package/dist/window/preview.js +2 -0
  633. package/dist/window/renderer.d.ts.map +1 -1
  634. package/dist/window/renderer.js +3 -2
  635. package/dist/window/tool.d.ts.map +1 -1
  636. package/dist/window/tool.js +96 -24
  637. package/dist/window/window-math.d.ts +6 -14
  638. package/dist/window/window-math.d.ts.map +1 -1
  639. package/dist/window/window-math.js +14 -20
  640. package/dist/zone/contextual-dimensions.d.ts.map +1 -1
  641. package/dist/zone/contextual-dimensions.js +6 -28
  642. package/dist/zone/definition.d.ts.map +1 -1
  643. package/dist/zone/definition.js +3 -3
  644. package/dist/zone/floorplan-affordances.d.ts +200 -0
  645. package/dist/zone/floorplan-affordances.d.ts.map +1 -1
  646. package/dist/zone/floorplan.d.ts +1 -1
  647. package/dist/zone/floorplan.d.ts.map +1 -1
  648. package/dist/zone/floorplan.js +93 -53
  649. package/dist/zone/quantities-panel.d.ts.map +1 -1
  650. package/dist/zone/quantities-panel.js +3 -14
  651. package/dist/zone/quick-measurement.d.ts +2 -2
  652. package/dist/zone/quick-measurement.d.ts.map +1 -1
  653. package/dist/zone/quick-measurement.js +6 -5
  654. package/dist/zone/renderer.d.ts +1 -1
  655. package/dist/zone/renderer.d.ts.map +1 -1
  656. package/dist/zone/renderer.js +58 -146
  657. package/dist/zone/room-clear-dimensions.js +3 -3
  658. package/dist/zone/room-documentation.d.ts.map +1 -1
  659. package/dist/zone/room-documentation.js +2 -6
  660. package/package.json +11 -11
  661. package/dist/block/slots.d.ts +0 -4
  662. package/dist/block/slots.d.ts.map +0 -1
  663. package/dist/block/slots.js +0 -17
  664. package/dist/cabinet/slots.d.ts +0 -4
  665. package/dist/cabinet/slots.d.ts.map +0 -1
  666. package/dist/cabinet/slots.js +0 -24
  667. package/dist/ceiling/slots.d.ts +0 -6
  668. package/dist/ceiling/slots.d.ts.map +0 -1
  669. package/dist/ceiling/slots.js +0 -7
  670. package/dist/column/slots.d.ts +0 -9
  671. package/dist/column/slots.d.ts.map +0 -1
  672. package/dist/column/slots.js +0 -19
  673. package/dist/door/slots.d.ts +0 -9
  674. package/dist/door/slots.d.ts.map +0 -1
  675. package/dist/door/slots.js +0 -20
  676. package/dist/elevator/slots.d.ts +0 -8
  677. package/dist/elevator/slots.d.ts.map +0 -1
  678. package/dist/elevator/slots.js +0 -17
  679. package/dist/fence/slots.d.ts +0 -10
  680. package/dist/fence/slots.d.ts.map +0 -1
  681. package/dist/fence/slots.js +0 -23
  682. package/dist/item/__fixtures__/main-floorplan.d.ts +0 -26
  683. package/dist/item/__fixtures__/main-floorplan.d.ts.map +0 -1
  684. package/dist/item/__fixtures__/main-floorplan.js +0 -297
  685. package/dist/lean-to-extension/slots.d.ts +0 -5
  686. package/dist/lean-to-extension/slots.d.ts.map +0 -1
  687. package/dist/lean-to-extension/slots.js +0 -15
  688. package/dist/shelf/slots.d.ts +0 -9
  689. package/dist/shelf/slots.d.ts.map +0 -1
  690. package/dist/shelf/slots.js +0 -30
  691. package/dist/slab/slots.d.ts +0 -10
  692. package/dist/slab/slots.d.ts.map +0 -1
  693. package/dist/slab/slots.js +0 -20
  694. package/dist/stair/floor-stack.d.ts +0 -10
  695. package/dist/stair/floor-stack.d.ts.map +0 -1
  696. package/dist/stair/floor-stack.js +0 -115
  697. package/dist/stair/slots.d.ts +0 -7
  698. package/dist/stair/slots.d.ts.map +0 -1
  699. package/dist/stair/slots.js +0 -13
  700. package/dist/wall/drawing-mode.d.ts +0 -12
  701. package/dist/wall/drawing-mode.d.ts.map +0 -1
  702. package/dist/wall/drawing-mode.js +0 -38
  703. package/dist/wall/slots.d.ts +0 -10
  704. package/dist/wall/slots.d.ts.map +0 -1
  705. package/dist/wall/slots.js +0 -92
  706. package/dist/window/slots.d.ts +0 -5
  707. package/dist/window/slots.d.ts.map +0 -1
  708. package/dist/window/slots.js +0 -11
@@ -1,17 +1,369 @@
1
- import { createSlotPaintCapability, previewGeometrySlot } from '../shared/slot-paint';
1
+ import { area, containsPoint, distanceToBoundary, FOUNDATION_SLOT_DEFAULT, floorPlatePaintRefusal, floorStepKeysOf, floorStepOverrideFor, floorStepRoleCovers, intersection, parseFloorStepRole, parseMaterialRef, parseRoomFinishRole, roomFinishRole, runAsSingleSceneHistoryStep, SLAB_TOP_SLOT_DEFAULT, slabSlots, slotDefaultPaintMaterial, useScene, withFloorStepOverride, } from '@pascal-app/core';
2
+ import { buildSlotPreviewMaterial, createSlotPaintCapability, declaredSlotLook, previewGeometrySlot, resolveSlotPaintMaterialRef, } from '../shared/slot-paint';
3
+ import { swapPreviewMaterial } from '../shared/swap-preview-material';
4
+ function zoneOf(zoneId) {
5
+ const node = useScene.getState().nodes[zoneId];
6
+ return node?.type === 'zone' ? node : null;
7
+ }
2
8
  /**
3
- * Slab paint on the unified slot model. A slab exposes two faces — `surface`
4
- * (top) and `side` (walls + underside) — each its own mesh tagged with
5
- * `userData.slotId`, so the clicked face resolves to its slot; commit writes
6
- * `node.slots[slotId]` (a shared scene-material or `library:` ref) like the shelf.
9
+ * The footprint whose edge band a room's edge falls back to: the base plate of
10
+ * the level that overlaps `shape` most, as the renderer picks it.
7
11
  */
8
- export const slabPaint = createSlotPaintCapability({
12
+ function edgeBandBase(shape) {
13
+ const overlap = (slab) => area(intersection({ outer: slab.polygon, holes: slab.holes }, { outer: shape.polygon, holes: shape.holes ?? [] }));
14
+ return Object.values(useScene.getState().nodes)
15
+ .filter((node) => node.type === 'slab' && node.plateRole === 'base' && node.parentId === shape.parentId)
16
+ .sort((a, b) => overlap(b) - overlap(a) || a.id.localeCompare(b.id))[0];
17
+ }
18
+ function sideRole(role) {
19
+ const step = parseFloorStepRole(role);
20
+ if (step)
21
+ return { ...step, field: 'floorStepFinish' };
22
+ const edge = /^edge:(.+)$/.exec(role);
23
+ return edge
24
+ ? { zoneId: edge[1], key: null, step: null, field: 'floorEdgeFinish' }
25
+ : null;
26
+ }
27
+ /** The rooms on `zone`'s level — where a doorway's step paint may be stored. */
28
+ function levelZones(zone) {
29
+ return Object.values(useScene.getState().nodes).filter((node) => node.type === 'zone' && node.parentId === zone.parentId);
30
+ }
31
+ /** A doorway's own step paint, wherever it is stored. */
32
+ function stepOverride(zone, key, step) {
33
+ return key ? floorStepOverrideFor(zone, key, step, levelZones(zone)) : undefined;
34
+ }
35
+ function readFinish(role) {
36
+ const side = sideRole(role);
37
+ if (side) {
38
+ const zone = zoneOf(side.zoneId);
39
+ if (side.field === 'floorStepFinish')
40
+ return ((zone && stepOverride(zone, side.key, side.step)?.finish) ??
41
+ zone?.floorStepFinish ??
42
+ zone?.floor?.finish ??
43
+ SLAB_TOP_SLOT_DEFAULT);
44
+ if (zone?.floorEdgeFinish)
45
+ return zone.floorEdgeFinish;
46
+ return zone ? edgeBandBase(zone)?.slots?.edge : undefined;
47
+ }
48
+ const parsed = parseRoomFinishRole(role);
49
+ if (!parsed)
50
+ return undefined;
51
+ const zone = zoneOf(parsed.zoneId);
52
+ if (!zone)
53
+ return undefined;
54
+ if (!parsed.regionId || parsed.regionId === ROOM_WIDE)
55
+ return zone.floor?.finish;
56
+ return zone.floor?.regions?.find((region) => region.id === parsed.regionId)?.finish;
57
+ }
58
+ /**
59
+ * Write a room finish in one history step, minting the shared scene material
60
+ * the same way `commitSlotPaint` does so a one-off colour is stored once.
61
+ */
62
+ /** The region id a room-scope floor role carries: the whole room, every finish source. */
63
+ export const ROOM_WIDE = '*';
64
+ /** The zone a room-scope floor role (`room:<zoneId>/*`) names. */
65
+ export function roomWideZone(role) {
66
+ const parsed = parseRoomFinishRole(role);
67
+ return parsed?.regionId === ROOM_WIDE ? parsed.zoneId : null;
68
+ }
69
+ /** A floor role naming the room's whole floor, not one painted part: `room:<zoneId>`. */
70
+ function plainFloorZone(role) {
71
+ const parsed = parseRoomFinishRole(role);
72
+ return parsed && !parsed.regionId ? parsed.zoneId : null;
73
+ }
74
+ /** What a step shows with no paint of its own, its room's or its floor's. */
75
+ const UNPAINTED_STEP = { materialPreset: SLAB_TOP_SLOT_DEFAULT };
76
+ function lookMaterial(look) {
77
+ return look ? buildSlotPreviewMaterial(look.material, look.materialPreset) : null;
78
+ }
79
+ function swapPreviews(root, shown) {
80
+ const restores = [];
81
+ root.traverse((object) => {
82
+ const mesh = object;
83
+ const { paintRole, __fromGeometry } = mesh.userData;
84
+ if (!(mesh.isMesh && __fromGeometry === true && typeof paintRole === 'string'))
85
+ return;
86
+ const material = shown(paintRole);
87
+ if (material)
88
+ restores.push(swapPreviewMaterial(mesh, material));
89
+ });
90
+ return () => {
91
+ for (let index = restores.length - 1; index >= 0; index -= 1)
92
+ restores[index]?.();
93
+ };
94
+ }
95
+ /**
96
+ * A room floor's preview on one plate: the floor and the steps that follow it
97
+ * (no room step finish, no doorway paint). Painted, they take the paint;
98
+ * erased, the floor shows the plate's own top and its steps the unpainted step.
99
+ * The whole room (`wide`) also covers its painted parts; erased, it clears its
100
+ * edge too, and its steps whatever the room step finish.
101
+ */
102
+ function previewRoomFloor(args, zoneId, wide) {
103
+ const zone = zoneOf(zoneId);
104
+ if (!zone)
105
+ return null;
106
+ const erasing = args.material === undefined && args.materialPreset === undefined;
107
+ const paint = erasing ? null : buildSlotPreviewMaterial(args.material, args.materialPreset);
108
+ const floorRole = roomFinishRole(zoneId);
109
+ const followingStep = (role) => {
110
+ const step = parseFloorStepRole(role);
111
+ return step?.zoneId === zoneId && !stepOverride(zone, step.key, step.step) ? step : null;
112
+ };
113
+ return swapPreviews(args.root, (role) => {
114
+ const step = followingStep(role);
115
+ const floorOrPart = role === floorRole || (wide && role.startsWith(`${floorRole}/`));
116
+ if (!erasing)
117
+ return floorOrPart || (step && !zone.floorStepFinish) ? paint : null;
118
+ if (floorOrPart)
119
+ return lookMaterial(plateSlotLook(args.node, 'surface'));
120
+ if (step && (wide || !zone.floorStepFinish))
121
+ return lookMaterial(UNPAINTED_STEP);
122
+ if (wide && zone.floorEdgeFinish && role === `edge:${zoneId}`)
123
+ return lookMaterial(footprintEdgeLook(args.node));
124
+ return null;
125
+ });
126
+ }
127
+ /**
128
+ * A footprint edge band's preview on one plate: the band itself on the
129
+ * footprint, and on any plate the room edges that carry the band (rooms with no
130
+ * edge finish of their own). Erased, each shows what it draws with no finish.
131
+ */
132
+ function previewEdgeBand(args) {
133
+ const erasing = args.material === undefined && args.materialPreset === undefined;
134
+ const paint = erasing ? null : buildSlotPreviewMaterial(args.material, args.materialPreset);
135
+ return swapPreviews(args.root, (role) => {
136
+ const edge = /^edge:(.+)$/.exec(role);
137
+ if (role !== 'edge' && !(edge && !zoneOf(edge[1])?.floorEdgeFinish))
138
+ return null;
139
+ return paint ?? lookMaterial(bareSideLook(args.node, 'edge'));
140
+ });
141
+ }
142
+ function commitRoomFinish(role, material, materialPreset) {
143
+ const side = sideRole(role);
144
+ const parsed = side ? { zoneId: side.zoneId, regionId: null } : parseRoomFinishRole(role);
145
+ if (!parsed)
146
+ return;
147
+ const state = useScene.getState();
148
+ const resolution = resolveSlotPaintMaterialRef(state.materials, material, materialPreset);
149
+ if (!resolution)
150
+ return;
151
+ const { ref, newSceneMaterial } = resolution;
152
+ if (side?.field === 'floorStepFinish') {
153
+ commitStepFinish(side.zoneId, side.key, side.step, ref ?? undefined, newSceneMaterial);
154
+ return;
155
+ }
156
+ useScene.setState((current) => {
157
+ if (current.readOnly)
158
+ return current;
159
+ const zone = current.nodes[parsed.zoneId];
160
+ if (zone?.type !== 'zone')
161
+ return current;
162
+ const floor = { ...zone.floor };
163
+ if (parsed.regionId === ROOM_WIDE) {
164
+ // The room scope: painting gives the whole floor one finish, its painted
165
+ // parts included; erasing clears everything that makes it look painted —
166
+ // its finish, its painted parts, its steps and its edge.
167
+ if (ref)
168
+ floor.finish = ref;
169
+ else
170
+ delete floor.finish;
171
+ delete floor.regions;
172
+ }
173
+ else if (parsed.regionId) {
174
+ const regions = floor.regions ?? [];
175
+ const index = regions.findIndex((region) => region.id === parsed.regionId);
176
+ if (index < 0)
177
+ return current;
178
+ // A region with no finish would fall through to the room finish, which is
179
+ // what the eraser should do — but the schema requires one, so an erased
180
+ // region drops out of the list instead.
181
+ floor.regions = ref
182
+ ? regions.map((region, at) => (at === index ? { ...region, finish: ref } : region))
183
+ : regions.filter((_, at) => at !== index);
184
+ }
185
+ else if (ref) {
186
+ floor.finish = ref;
187
+ }
188
+ else {
189
+ delete floor.finish;
190
+ }
191
+ const next = (side ? { ...zone, [side.field]: ref ?? undefined } : { ...zone, floor });
192
+ if (parsed.regionId === ROOM_WIDE && !ref) {
193
+ delete next.floorStepFinish;
194
+ delete next.floorEdgeFinish;
195
+ }
196
+ return {
197
+ ...(newSceneMaterial
198
+ ? { materials: { ...current.materials, [newSceneMaterial.id]: newSceneMaterial } }
199
+ : {}),
200
+ nodes: { ...current.nodes, [parsed.zoneId]: next },
201
+ };
202
+ });
203
+ useScene.getState().markDirty(parsed.zoneId);
204
+ }
205
+ /**
206
+ * Paint (`ref`) or erase a room's steps in one history step. A doorway role
207
+ * writes that doorway's override (see `withFloorStepOverride`); the room scope
208
+ * sets the room's step finish and drops the doorway paint of every step the
209
+ * room currently has, so all of them show it. Overrides of steps the room does
210
+ * not have are someone else's and stay.
211
+ */
212
+ function commitStepFinish(zoneId, key, step, ref, newSceneMaterial) {
213
+ const changed = [];
214
+ useScene.setState((current) => {
215
+ if (current.readOnly)
216
+ return current;
217
+ const owner = current.nodes[zoneId];
218
+ if (owner?.type !== 'zone')
219
+ return current;
220
+ const zones = new Map(Object.values(current.nodes)
221
+ .filter((node) => node.type === 'zone' && node.parentId === owner.parentId)
222
+ .map((zone) => [zone.id, zone]));
223
+ const apply = (doorway, finish) => {
224
+ for (const zone of withFloorStepOverride(zones.get(zoneId), doorway, key ? step : null, finish, [...zones.values()]))
225
+ zones.set(zone.id, zone);
226
+ };
227
+ if (key)
228
+ apply(key, ref);
229
+ else {
230
+ for (const doorway of floorStepKeysOf(current.nodes, owner.parentId ?? '', zoneId))
231
+ apply(doorway, undefined);
232
+ const next = { ...zones.get(zoneId) };
233
+ if (ref)
234
+ next.floorStepFinish = ref;
235
+ else
236
+ delete next.floorStepFinish;
237
+ zones.set(zoneId, next);
238
+ }
239
+ const nodes = { ...current.nodes };
240
+ for (const [id, zone] of zones)
241
+ if (zone !== current.nodes[id]) {
242
+ nodes[id] = zone;
243
+ changed.push(id);
244
+ }
245
+ if (!changed.length && !newSceneMaterial)
246
+ return current;
247
+ return {
248
+ ...(newSceneMaterial
249
+ ? { materials: { ...current.materials, [newSceneMaterial.id]: newSceneMaterial } }
250
+ : {}),
251
+ nodes,
252
+ };
253
+ });
254
+ for (const id of changed)
255
+ useScene.getState().markDirty(id);
256
+ }
257
+ function baseSurfaceRoom(node, point) {
258
+ if (node.type !== 'slab' || node.plateRole !== 'base')
259
+ return null;
260
+ const zones = (node.zoneIds ?? [])
261
+ .map(zoneOf)
262
+ .filter((zone) => !!zone && zone.hasFloor !== false);
263
+ if (point)
264
+ zones.sort((a, b) => {
265
+ const distance = (zone) => {
266
+ const polygon = [{ outer: zone.polygon, holes: zone.holes }];
267
+ const p = [point[0], point[2]];
268
+ return containsPoint(polygon, p) ? 0 : distanceToBoundary(polygon, p);
269
+ };
270
+ return distance(a) - distance(b) || a.id.localeCompare(b.id);
271
+ });
272
+ return zones[0] ? `room:${zones[0].id}` : null;
273
+ }
274
+ /** A finish ref or inline legacy material, as a look. */
275
+ function finishLook(finish) {
276
+ if (finish === undefined)
277
+ return null;
278
+ return typeof finish === 'string'
279
+ ? { materialPreset: finish }
280
+ : { material: finish };
281
+ }
282
+ /** A plate slot as drawn: its value, else its legacy finish, else its declared default. */
283
+ function plateSlotLook(node, slot) {
284
+ return (base.getEffectiveMaterial?.({
285
+ node,
286
+ role: slot,
287
+ nodes: useScene.getState().nodes,
288
+ materials: useScene.getState().materials,
289
+ }) ?? slotDefaultPaintMaterial(slabSlots().find((entry) => entry.slotId === slot)?.default));
290
+ }
291
+ /**
292
+ * A plate side face with no finish of its own: the pre-split `side` slot, else
293
+ * the declared default — the renderer's fallback for edge, riser and underside.
294
+ */
295
+ function bareSideLook(node, slot) {
296
+ return (finishLook(node.slots?.side) ??
297
+ slotDefaultPaintMaterial(slabSlots().find((entry) => entry.slotId === slot)?.default));
298
+ }
299
+ /** A room edge with no edge finish: its footprint's band, else the bare face. */
300
+ function footprintEdgeLook(node) {
301
+ const plate = node;
302
+ return finishLook(edgeBandBase(plate)?.slots?.edge) ?? bareSideLook(node, 'edge');
303
+ }
304
+ /**
305
+ * What a floor surface shows once erased: a region falls to its room's floor
306
+ * finish, a room's floor finish to the plate's own top, the room's steps to its
307
+ * floor, its edge to the footprint's edge band, a plate's side faces to their
308
+ * bare look, a slot to its declared default.
309
+ */
310
+ export function erasedSlabLook({ node, role }) {
311
+ if (role === 'foundation')
312
+ return declaredSlotLook(node, role);
313
+ if (node.boundary === 'auto' && (role === 'riser' || role === 'underside'))
314
+ return bareSideLook(node, role);
315
+ const side = sideRole(role);
316
+ if (side) {
317
+ const zone = zoneOf(side.zoneId);
318
+ // A doorway falls back to the room's steps, the room's steps to its floor,
319
+ // then to the unpainted step; a room's edge to its footprint's band.
320
+ return side.field === 'floorStepFinish'
321
+ ? ((side.key ? finishLook(zone?.floorStepFinish) : null) ??
322
+ finishLook(zone?.floor?.finish) ??
323
+ UNPAINTED_STEP)
324
+ : footprintEdgeLook(node);
325
+ }
326
+ const parsed = parseRoomFinishRole(role);
327
+ if (!parsed)
328
+ return declaredSlotLook(node, role);
329
+ const floor = parsed.regionId ? zoneOf(parsed.zoneId)?.floor?.finish : undefined;
330
+ return finishLook(floor) ?? plateSlotLook(node, 'surface');
331
+ }
332
+ const base = createSlotPaintCapability({
9
333
  roomScope: true,
10
- resolveRole: ({ hitObject }) => {
334
+ // A floor, the whole room and a footprint's edge band preview their
335
+ // followers too, erased included, so they build their own erased look.
336
+ erasedLook: (args) => roomWideZone(args.role) ||
337
+ (args.node.boundary === 'auto' &&
338
+ (plainFloorZone(args.role) || args.role === 'edge'))
339
+ ? null
340
+ : erasedSlabLook(args),
341
+ resolveRole: ({ node, hitObject, localPosition }) => {
342
+ const paintRole = hitObject?.userData.paintRole;
343
+ if (typeof paintRole === 'string')
344
+ return paintRole === 'surface'
345
+ ? (baseSurfaceRoom(node, localPosition) ?? paintRole)
346
+ : paintRole;
11
347
  const slotId = hitObject?.userData?.slotId;
12
- return slotId === 'side' ? 'side' : 'surface';
348
+ if (typeof slotId !== 'string')
349
+ return null;
350
+ return slotId === 'surface' ? (baseSurfaceRoom(node, localPosition) ?? slotId) : slotId;
351
+ },
352
+ applyPreview: (args) => {
353
+ const zoneId = roomWideZone(args.role);
354
+ if (zoneId)
355
+ return previewRoomFloor(args, zoneId, true);
356
+ if (args.node.boundary === 'auto') {
357
+ const floor = plainFloorZone(args.role);
358
+ if (floor)
359
+ return previewRoomFloor(args, floor, false);
360
+ if (args.role === 'edge')
361
+ return previewEdgeBand(args);
362
+ }
363
+ return parseFloorStepRole(args.role)
364
+ ? previewGeometrySlot(args, (meshRole) => floorStepRoleCovers(args.role, meshRole))
365
+ : previewGeometrySlot(args);
13
366
  },
14
- applyPreview: previewGeometrySlot,
15
367
  // Legacy inline material applied to the whole slab → maps onto the top only;
16
368
  // the side picker shows its own default.
17
369
  legacyEffective: (node, role) => {
@@ -24,3 +376,100 @@ export const slabPaint = createSlotPaintCapability({
24
376
  return null;
25
377
  },
26
378
  });
379
+ export const slabPaint = {
380
+ ...base,
381
+ // "Steps · Kitchen": the room a floor finish belongs to, by name.
382
+ roleLabel: (_node, role) => {
383
+ if (role === 'foundation')
384
+ return 'Foundation';
385
+ const side = sideRole(role);
386
+ const zoneId = side?.zoneId ?? parseRoomFinishRole(role)?.zoneId;
387
+ if (!zoneId)
388
+ return null;
389
+ const part = side ? (side.field === 'floorStepFinish' ? 'Steps' : 'Floor edge') : 'Floor';
390
+ const room = zoneOf(zoneId)?.name?.trim() || 'Room';
391
+ if (!side?.key)
392
+ return `${part} · ${room}`;
393
+ const through = useScene.getState().nodes[side.key];
394
+ const label = through?.type === 'zone'
395
+ ? through.name?.trim() || 'Room'
396
+ : through?.name?.trim() || 'Doorway';
397
+ return `${part} · ${room} · ${label}`;
398
+ },
399
+ buildPatch: (args) => args.role === 'foundation' || sideRole(args.role) || parseRoomFinishRole(args.role)
400
+ ? {}
401
+ : base.buildPatch(args),
402
+ commit: (args) => {
403
+ if (args.role === 'surface' && args.node.type === 'slab' && args.node.plateRole === 'base') {
404
+ const role = baseSurfaceRoom(args.node);
405
+ if (!role)
406
+ return floorPlatePaintRefusal(useScene.getState().nodes, args.node, args.role) ?? undefined;
407
+ commitRoomFinish(role, args.material, args.materialPreset);
408
+ return;
409
+ }
410
+ if (args.role === 'foundation') {
411
+ const state = useScene.getState();
412
+ const plate = state.nodes[args.node.id];
413
+ if (plate?.type !== 'slab' || plate.plateRole !== 'base' || state.readOnly)
414
+ return;
415
+ const resolution = resolveSlotPaintMaterialRef(state.materials, args.material, args.materialPreset);
416
+ if (!resolution)
417
+ return;
418
+ const { ref, newSceneMaterial } = resolution;
419
+ runAsSingleSceneHistoryStep(useScene, () => {
420
+ if (newSceneMaterial)
421
+ useScene.getState().addSceneMaterial(newSceneMaterial);
422
+ useScene.getState().updateNode(plate.id, {
423
+ foundation: {
424
+ ...plate.foundation,
425
+ type: plate.foundation?.type ?? 'none',
426
+ material: ref ?? undefined,
427
+ },
428
+ });
429
+ });
430
+ return;
431
+ }
432
+ if (sideRole(args.role) || parseRoomFinishRole(args.role)) {
433
+ commitRoomFinish(args.role, args.material, args.materialPreset);
434
+ return;
435
+ }
436
+ base.commit?.(args);
437
+ },
438
+ getEffectiveMaterial: (args) => {
439
+ if (!(args.role === 'foundation' || sideRole(args.role) || parseRoomFinishRole(args.role)))
440
+ return base.getEffectiveMaterial?.(args) ?? null;
441
+ const finish = args.role === 'foundation'
442
+ ? (args.node.foundation?.material ?? FOUNDATION_SLOT_DEFAULT)
443
+ : readFinish(args.role);
444
+ if (finish === undefined) {
445
+ // Unpainted, a room's floor shows the plate's own top and its edge the
446
+ // plate's edge band — each the slot's value, else its declared default.
447
+ const slot = !args.rendered
448
+ ? null
449
+ : parseRoomFinishRole(args.role)
450
+ ? 'surface'
451
+ : sideRole(args.role)?.field === 'floorEdgeFinish'
452
+ ? 'edge'
453
+ : null;
454
+ if (!slot)
455
+ return null;
456
+ const effective = base.getEffectiveMaterial?.({ ...args, role: slot }) ??
457
+ slotDefaultPaintMaterial(slabSlots().find((entry) => entry.slotId === slot)?.default);
458
+ return effective
459
+ ? { material: effective.material, materialPreset: effective.materialPreset }
460
+ : null;
461
+ }
462
+ if (typeof finish !== 'string') {
463
+ return { material: finish, materialPreset: undefined };
464
+ }
465
+ const parsed = parseMaterialRef(finish);
466
+ if (parsed?.kind === 'library')
467
+ return { material: undefined, materialPreset: finish };
468
+ if (parsed?.kind === 'scene') {
469
+ const sceneMaterial = useScene.getState().materials[parsed.id];
470
+ if (sceneMaterial)
471
+ return { material: sceneMaterial.material, materialPreset: undefined };
472
+ }
473
+ return null;
474
+ },
475
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"panel.d.ts","sourceRoot":"","sources":["../../src/slab/panel.tsx"],"names":[],"mappings":"AA+BA;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,uCAgaxB;AAED,eAAe,SAAS,CAAA"}
1
+ {"version":3,"file":"panel.d.ts","sourceRoot":"","sources":["../../src/slab/panel.tsx"],"names":[],"mappings":"AAwCA;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,uCA0cxB;AAED,eAAe,SAAS,CAAA"}
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { MIN_SLAB_THICKNESS, useScene } from '@pascal-app/core';
4
- import { ActionButton, ActionGroup, holeEditScope, PanelSection, PanelWrapper, SegmentedControl, SliderControl, triggerSFX, useEditingHole, useEditor, useInteractionScope, } from '@pascal-app/editor';
3
+ import { isDerivedNode, MIN_SLAB_THICKNESS, useScene, } from '@pascal-app/core';
4
+ import { ActionButton, ActionGroup, FloorFoundationPanel, holeEditScope, PanelSection, PanelWrapper, SegmentedControl, ShapeChoice, SliderControl, startOpeningDraft, triggerSFX, useEditingHole, useEditor, useInteractionScope, } from '@pascal-app/editor';
5
5
  import { useViewer } from '@pascal-app/viewer';
6
6
  import { Edit, Move, Plus, Trash2 } from 'lucide-react';
7
7
  import { useCallback, useEffect, useRef } from 'react';
@@ -24,9 +24,14 @@ export function SlabPanel() {
24
24
  const editingHole = useEditingHole();
25
25
  const setMovingNode = useEditor((s) => s.setMovingNode);
26
26
  const node = useScene((s) => selectedId ? s.nodes[selectedId] : undefined);
27
- // See "Panel slider-drag fix recipe" in plans/editor-node-registry.md.
28
- // Stable handler refs across re-renders so slider drags don't trigger
29
- // a Maximum update depth cascade on the panel's SliderControls.
27
+ useEffect(() => {
28
+ if (!node?.plateRole || node.plateRole === 'base' || !node.parentId || !node.zoneIds?.[0])
29
+ return;
30
+ useViewer.getState().setSelection({ selectedIds: [] });
31
+ useEditor.getState().selectRoom({ levelId: node.parentId, zoneId: node.zoneIds[0] });
32
+ }, [node]);
33
+ // Stable handler refs so slider drags don't trigger a Maximum update depth
34
+ // cascade; see "Custom panels" in wiki/architecture/node-definitions.md.
30
35
  const nodeRef = useRef(node);
31
36
  nodeRef.current = node;
32
37
  const handleUpdate = useCallback((updates) => {
@@ -171,6 +176,11 @@ export function SlabPanel() {
171
176
  }, [node, setMovingNode, setSelection]);
172
177
  if (!(node && node.type === 'slab' && selectedId))
173
178
  return null;
179
+ if (node.plateRole === 'base')
180
+ return _jsx(FloorFoundationPanel, { node: node, onClose: handleClose });
181
+ const derived = isDerivedNode(node);
182
+ const room = useEditor.getState().room;
183
+ const openingZoneId = room && node.zoneIds?.includes(room.zoneId) ? room.zoneId : node.zoneIds?.[0];
174
184
  const calculateArea = (polygon) => {
175
185
  if (polygon.length < 3)
176
186
  return 0;
@@ -210,13 +220,22 @@ export function SlabPanel() {
210
220
  const holeArea = calculateArea(hole);
211
221
  const isEditing = editingHole?.nodeId === selectedId && editingHole?.holeIndex === index;
212
222
  const source = node.holeMetadata?.[index]?.source ?? 'manual';
213
- const isAutoHole = source !== 'manual';
214
- const autoLabel = source === 'elevator' ? 'Auto elevator cutout' : 'Auto stair cutout';
223
+ // A derived plate's holes are owned by its rooms and openings: an
224
+ // opening's hole opens that opening, the rest are read-only.
225
+ const openingId = derived ? node.holeMetadata?.[index]?.openingId : undefined;
226
+ const isAutoHole = source !== 'manual' || derived;
227
+ const autoLabel = source === 'elevator'
228
+ ? 'Auto elevator cutout'
229
+ : source === 'stair'
230
+ ? 'Auto stair cutout'
231
+ : source === 'floor-opening'
232
+ ? 'Opening'
233
+ : 'Room cutout';
215
234
  return (_jsxs("div", { className: `flex items-center justify-between rounded-lg border p-2 transition-colors ${isEditing
216
235
  ? 'border-primary/50 bg-primary/10'
217
236
  : 'border-transparent hover:bg-accent/30'}`, children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("p", { className: `font-medium text-xs ${isEditing ? 'text-primary' : 'text-white'}`, children: ["Hole ", index + 1, " ", isEditing && '(Editing)'] }), _jsxs("p", { className: "text-[10px] text-muted-foreground", children: [holeArea.toFixed(2), " m\u00B2 \u00B7 ", hole.length, " pts \u00B7", ' ', isAutoHole ? autoLabel : 'Manual'] })] }), _jsx("div", { className: "flex items-center gap-1", children: isEditing ? (_jsx(ActionButton, { className: "h-7 bg-primary text-primary-foreground hover:bg-primary/90", label: "Done", onClick: () => useInteractionScope
218
237
  .getState()
219
- .endIf((scope) => scope.kind === 'reshaping' && scope.reshape === 'hole') })) : isAutoHole ? (_jsx("div", { className: "rounded-md bg-[#2C2C2E] px-2 py-1 text-[10px] text-muted-foreground", children: "Auto" })) : (_jsxs(_Fragment, { children: [_jsx("button", { className: "flex h-7 w-7 items-center justify-center rounded-md bg-[#2C2C2E] text-muted-foreground hover:bg-[#3e3e3e] hover:text-foreground", onClick: () => handleEditHole(index), type: "button", children: _jsx(Edit, { className: "h-3.5 w-3.5" }) }), _jsx("button", { className: "flex h-7 w-7 items-center justify-center rounded-md bg-red-500/10 text-red-400 hover:bg-red-500/20 hover:text-red-300", onClick: () => handleDeleteHole(index), type: "button", children: _jsx(Trash2, { className: "h-3.5 w-3.5" }) })] })) })] }, index));
220
- }) })) : (_jsx("div", { className: "px-2 py-3 text-center text-muted-foreground text-xs", children: "No holes" })), _jsx("div", { className: "px-1 pt-1 pb-1", children: _jsx(ActionButton, { className: "w-full", disabled: editingHole?.nodeId === selectedId, icon: _jsx(Plus, { className: "h-3.5 w-3.5" }), label: "Add Hole", onClick: handleAddHole }) })] }), _jsx(ActionGroup, { children: _jsx(ActionButton, { icon: _jsx(Move, { className: "h-3.5 w-3.5" }), label: "Move", onClick: handleMove }) })] }));
238
+ .endIf((scope) => scope.kind === 'reshaping' && scope.reshape === 'hole') })) : openingId ? (_jsx("button", { className: "flex h-7 w-7 items-center justify-center rounded-md bg-[#2C2C2E] text-muted-foreground hover:bg-[#3e3e3e] hover:text-foreground", "data-slab-hole-opening": openingId, onClick: () => setSelection({ selectedIds: [openingId] }), type: "button", children: _jsx(Edit, { className: "h-3.5 w-3.5" }) })) : isAutoHole ? (_jsx("div", { className: "rounded-md bg-[#2C2C2E] px-2 py-1 text-[10px] text-muted-foreground", children: "Auto" })) : (_jsxs(_Fragment, { children: [_jsx("button", { className: "flex h-7 w-7 items-center justify-center rounded-md bg-[#2C2C2E] text-muted-foreground hover:bg-[#3e3e3e] hover:text-foreground", onClick: () => handleEditHole(index), type: "button", children: _jsx(Edit, { className: "h-3.5 w-3.5" }) }), _jsx("button", { className: "flex h-7 w-7 items-center justify-center rounded-md bg-red-500/10 text-red-400 hover:bg-red-500/20 hover:text-red-300", onClick: () => handleDeleteHole(index), type: "button", children: _jsx(Trash2, { className: "h-3.5 w-3.5" }) })] })) })] }, index));
239
+ }) })) : (_jsx("div", { className: "px-2 py-3 text-center text-muted-foreground text-xs", children: "No holes" })), _jsx("div", { className: "px-1 pt-1 pb-1", children: derived ? (_jsx(ShapeChoice, { className: "px-1 text-muted-foreground text-xs", disabled: !openingZoneId, label: node.support === 'open' ? 'Cut hatch' : 'Cut opening', onPick: (shape) => openingZoneId && startOpeningDraft(openingZoneId, 'floor', shape) })) : (_jsx(ActionButton, { className: "w-full", disabled: editingHole?.nodeId === selectedId, icon: _jsx(Plus, { className: "h-3.5 w-3.5" }), label: "Add Hole", onClick: handleAddHole })) })] }), _jsx(ActionGroup, { children: _jsx(ActionButton, { icon: _jsx(Move, { className: "h-3.5 w-3.5" }), label: "Move", onClick: handleMove }) })] }));
221
240
  }
222
241
  export default SlabPanel;
@@ -1,3 +1,4 @@
1
+ import type { VisibleScene } from '@pascal-app/editor';
1
2
  export type SlabCompletionTrigger = 'grid' | 'keyboard';
2
- export declare function shouldRegistryCommitSlab(viewMode: '2d' | '3d' | 'split', trigger: SlabCompletionTrigger): boolean;
3
+ export declare function shouldRegistryCommitSlab(scene: VisibleScene | null, trigger: SlabCompletionTrigger): boolean;
3
4
  //# sourceMappingURL=placement-ownership.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"placement-ownership.d.ts","sourceRoot":"","sources":["../../src/slab/placement-ownership.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,UAAU,CAAA;AAEvD,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,EAC/B,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAET"}
1
+ {"version":3,"file":"placement-ownership.d.ts","sourceRoot":"","sources":["../../src/slab/placement-ownership.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEtD,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,UAAU,CAAA;AAEvD,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,YAAY,GAAG,IAAI,EAC1B,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAET"}
@@ -1,3 +1,3 @@
1
- export function shouldRegistryCommitSlab(viewMode, trigger) {
2
- return trigger === 'keyboard' || viewMode !== '2d';
1
+ export function shouldRegistryCommitSlab(scene, trigger) {
2
+ return trigger === 'keyboard' || scene !== '2d';
3
3
  }
@@ -0,0 +1,24 @@
1
+ import { type PlateSurfacePartition, type SlabNode } from '@pascal-app/core';
2
+ import { BufferGeometry } from 'three';
3
+ export type SplitBucket = {
4
+ role: string;
5
+ geometry: BufferGeometry;
6
+ };
7
+ /**
8
+ * Split a slab buffer by face orientation only — the pre-plate behaviour, kept
9
+ * verbatim for manual slabs so their two meshes and their paint slots never
10
+ * change.
11
+ */
12
+ export declare function splitSlabFacesByFacing(geometry: BufferGeometry): {
13
+ top: BufferGeometry;
14
+ side: BufferGeometry;
15
+ };
16
+ /**
17
+ * Split a plate buffer into one bucket per rendered role: a top bucket per
18
+ * partition cell, `edge` / `riser` per exposure run, and `underside`. Buckets
19
+ * come back in a stable order (cells in partition order, then the sides) so the
20
+ * mesh order of a plate is the same on every rebuild.
21
+ */
22
+ export declare function splitPlateFaces(geometry: BufferGeometry, partition: PlateSurfacePartition, slab: Pick<SlabNode, 'elevation' | 'thickness' | 'polygon' | 'holes'>): SplitBucket[];
23
+ export declare function clipPlateTerrainFill(geometry: BufferGeometry, partition: PlateSurfacePartition): BufferGeometry;
24
+ //# sourceMappingURL=surface-split.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surface-split.d.ts","sourceRoot":"","sources":["../../src/slab/surface-split.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,qBAAqB,EAG1B,KAAK,QAAQ,EAEd,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,cAAc,EAA+C,MAAM,OAAO,CAAA;AAqBnF,MAAM,MAAM,WAAW,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,cAAc,CAAA;CAAE,CAAA;AAgNpE;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,cAAc,GAAG;IAChE,GAAG,EAAE,cAAc,CAAA;IACnB,IAAI,EAAE,cAAc,CAAA;CACrB,CAQA;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,cAAc,EACxB,SAAS,EAAE,qBAAqB,EAChC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,WAAW,GAAG,WAAW,GAAG,SAAS,GAAG,OAAO,CAAC,GACpE,WAAW,EAAE,CAmJf;AA4BD,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,cAAc,EACxB,SAAS,EAAE,qBAAqB,GAC/B,cAAc,CA0BhB"}