@pascal-app/nodes 1.0.0 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (439) hide show
  1. package/dist/block/definition.d.ts.map +1 -1
  2. package/dist/block/definition.js +4 -1
  3. package/dist/block/face-host.d.ts.map +1 -1
  4. package/dist/block/face-host.js +19 -2
  5. package/dist/block/hosted-edit.d.ts +13 -0
  6. package/dist/block/hosted-edit.d.ts.map +1 -0
  7. package/dist/block/hosted-edit.js +205 -0
  8. package/dist/block/last-operation.d.ts +1 -1
  9. package/dist/block/last-operation.d.ts.map +1 -1
  10. package/dist/block/last-operation.js +6 -4
  11. package/dist/block/modal-session.d.ts +2 -1
  12. package/dist/block/modal-session.d.ts.map +1 -1
  13. package/dist/block/modal-session.js +2 -2
  14. package/dist/block/selection.d.ts.map +1 -1
  15. package/dist/block/selection.js +82 -24
  16. package/dist/block/surface.d.ts +4 -0
  17. package/dist/block/surface.d.ts.map +1 -0
  18. package/dist/block/surface.js +54 -0
  19. package/dist/block/use-block-face-operation.d.ts +2 -2
  20. package/dist/block/use-block-face-operation.d.ts.map +1 -1
  21. package/dist/block/use-block-face-operation.js +25 -11
  22. package/dist/box-vent/definition.d.ts.map +1 -1
  23. package/dist/box-vent/definition.js +1 -0
  24. package/dist/box-vent/panel.js +4 -4
  25. package/dist/building/renderer.d.ts.map +1 -1
  26. package/dist/building/renderer.js +1 -1
  27. package/dist/cabinet/appliance-layout.d.ts +26 -0
  28. package/dist/cabinet/appliance-layout.d.ts.map +1 -0
  29. package/dist/cabinet/appliance-layout.js +52 -0
  30. package/dist/cabinet/countertop-layout.d.ts +173 -0
  31. package/dist/cabinet/countertop-layout.d.ts.map +1 -0
  32. package/dist/cabinet/countertop-layout.js +80 -0
  33. package/dist/cabinet/definition.d.ts.map +1 -1
  34. package/dist/cabinet/definition.js +17 -8
  35. package/dist/cabinet/geometry/cooktop.d.ts.map +1 -1
  36. package/dist/cabinet/geometry/cooktop.js +2 -2
  37. package/dist/cabinet/geometry/run.d.ts.map +1 -1
  38. package/dist/cabinet/geometry/run.js +10 -71
  39. package/dist/cabinet/geometry/sink.d.ts +2 -12
  40. package/dist/cabinet/geometry/sink.d.ts.map +1 -1
  41. package/dist/cabinet/geometry/sink.js +8 -39
  42. package/dist/cabinet/hosted-resize.d.ts +5 -0
  43. package/dist/cabinet/hosted-resize.d.ts.map +1 -0
  44. package/dist/cabinet/hosted-resize.js +14 -0
  45. package/dist/cabinet/placement-snap.d.ts.map +1 -1
  46. package/dist/cabinet/placement-snap.js +4 -2
  47. package/dist/cabinet/run-layout.d.ts +8 -1
  48. package/dist/cabinet/run-layout.d.ts.map +1 -1
  49. package/dist/cabinet/run-layout.js +22 -14
  50. package/dist/cabinet/run-ops.d.ts +3 -3
  51. package/dist/cabinet/run-ops.js +3 -3
  52. package/dist/cabinet/run-panel.d.ts +1 -1
  53. package/dist/cabinet/run-panel.d.ts.map +1 -1
  54. package/dist/cabinet/run-panel.js +16 -7
  55. package/dist/cabinet/surfaces.d.ts +5 -0
  56. package/dist/cabinet/surfaces.d.ts.map +1 -0
  57. package/dist/cabinet/surfaces.js +113 -0
  58. package/dist/cabinet/tool.d.ts.map +1 -1
  59. package/dist/cabinet/tool.js +8 -4
  60. package/dist/cabinet/tree-structure.d.ts.map +1 -1
  61. package/dist/cabinet/tree-structure.js +10 -9
  62. package/dist/ceiling/definition.d.ts.map +1 -1
  63. package/dist/ceiling/definition.js +6 -1
  64. package/dist/ceiling/floorplan-affordances.d.ts +4 -4
  65. package/dist/ceiling/panel.js +1 -1
  66. package/dist/ceiling/renderer.d.ts.map +1 -1
  67. package/dist/ceiling/renderer.js +3 -2
  68. package/dist/chimney/definition.d.ts.map +1 -1
  69. package/dist/chimney/definition.js +1 -0
  70. package/dist/chimney/panel.js +9 -9
  71. package/dist/column/definition.d.ts.map +1 -1
  72. package/dist/column/definition.js +10 -3
  73. package/dist/column/floorplan-affordances.d.ts.map +1 -1
  74. package/dist/column/floorplan-affordances.js +6 -1
  75. package/dist/column/floorplan.d.ts.map +1 -1
  76. package/dist/column/floorplan.js +23 -11
  77. package/dist/column/hosted-resize.d.ts +116 -0
  78. package/dist/column/hosted-resize.d.ts.map +1 -0
  79. package/dist/column/hosted-resize.js +9 -0
  80. package/dist/column/panel.d.ts.map +1 -1
  81. package/dist/column/panel.js +6 -3
  82. package/dist/column/renderer.d.ts.map +1 -1
  83. package/dist/column/renderer.js +25 -103
  84. package/dist/column/shape.d.ts +22 -0
  85. package/dist/column/shape.d.ts.map +1 -0
  86. package/dist/column/shape.js +120 -0
  87. package/dist/column/surface.d.ts +4 -0
  88. package/dist/column/surface.d.ts.map +1 -0
  89. package/dist/column/surface.js +66 -0
  90. package/dist/cupola/definition.d.ts.map +1 -1
  91. package/dist/cupola/definition.js +1 -0
  92. package/dist/cupola/panel.js +1 -1
  93. package/dist/door/definition.d.ts.map +1 -1
  94. package/dist/door/definition.js +40 -1
  95. package/dist/door/door-math.d.ts +1 -1
  96. package/dist/door/door-math.d.ts.map +1 -1
  97. package/dist/door/door-math.js +7 -10
  98. package/dist/door/floorplan-affordances.d.ts.map +1 -1
  99. package/dist/door/floorplan-affordances.js +8 -12
  100. package/dist/door/move-tool.d.ts.map +1 -1
  101. package/dist/door/move-tool.js +3 -4
  102. package/dist/door/panel.d.ts.map +1 -1
  103. package/dist/door/panel.js +28 -57
  104. package/dist/door/tool.d.ts.map +1 -1
  105. package/dist/door/tool.js +20 -2
  106. package/dist/dormer/definition.d.ts.map +1 -1
  107. package/dist/dormer/definition.js +1 -0
  108. package/dist/dormer/panel-position-section.js +2 -2
  109. package/dist/dormer/panel.js +1 -1
  110. package/dist/downspout/definition.d.ts.map +1 -1
  111. package/dist/downspout/definition.js +1 -0
  112. package/dist/duct-segment/parametrics.d.ts.map +1 -1
  113. package/dist/duct-segment/parametrics.js +5 -1
  114. package/dist/duct-segment/tool.d.ts +1 -0
  115. package/dist/duct-segment/tool.d.ts.map +1 -1
  116. package/dist/duct-segment/tool.js +21 -8
  117. package/dist/duct-terminal/tool.d.ts.map +1 -1
  118. package/dist/duct-terminal/tool.js +77 -8
  119. package/dist/elevator/definition.d.ts.map +1 -1
  120. package/dist/elevator/definition.js +2 -0
  121. package/dist/elevator/parametrics.d.ts.map +1 -1
  122. package/dist/elevator/parametrics.js +98 -1
  123. package/dist/eyebrow-vent/definition.d.ts.map +1 -1
  124. package/dist/eyebrow-vent/definition.js +1 -0
  125. package/dist/eyebrow-vent/panel.js +1 -1
  126. package/dist/fence/definition.d.ts.map +1 -1
  127. package/dist/fence/definition.js +1 -0
  128. package/dist/fence/inspector-editors.js +1 -1
  129. package/dist/fence/tool.js +2 -2
  130. package/dist/guide/definition.d.ts.map +1 -1
  131. package/dist/guide/definition.js +1 -0
  132. package/dist/gutter/definition.d.ts.map +1 -1
  133. package/dist/gutter/definition.js +1 -0
  134. package/dist/hvac-equipment/tool.d.ts.map +1 -1
  135. package/dist/hvac-equipment/tool.js +8 -2
  136. package/dist/imported-mesh/definition.d.ts +5 -0
  137. package/dist/imported-mesh/definition.d.ts.map +1 -0
  138. package/dist/imported-mesh/definition.js +38 -0
  139. package/dist/imported-mesh/floorplan.d.ts +4 -0
  140. package/dist/imported-mesh/floorplan.d.ts.map +1 -0
  141. package/dist/imported-mesh/floorplan.js +34 -0
  142. package/dist/imported-mesh/geometry.d.ts +5 -0
  143. package/dist/imported-mesh/geometry.d.ts.map +1 -0
  144. package/dist/imported-mesh/geometry.js +34 -0
  145. package/dist/imported-mesh/index.d.ts +4 -0
  146. package/dist/imported-mesh/index.d.ts.map +1 -0
  147. package/dist/imported-mesh/index.js +3 -0
  148. package/dist/imported-mesh/schema.d.ts +2 -0
  149. package/dist/imported-mesh/schema.d.ts.map +1 -0
  150. package/dist/imported-mesh/schema.js +1 -0
  151. package/dist/index.d.ts +2 -0
  152. package/dist/index.d.ts.map +1 -1
  153. package/dist/index.js +8 -0
  154. package/dist/item/__fixtures__/main-floorplan.d.ts +26 -0
  155. package/dist/item/__fixtures__/main-floorplan.d.ts.map +1 -0
  156. package/dist/item/__fixtures__/main-floorplan.js +297 -0
  157. package/dist/item/definition.d.ts.map +1 -1
  158. package/dist/item/definition.js +3 -1
  159. package/dist/item/floorplan-move.d.ts +9 -1
  160. package/dist/item/floorplan-move.d.ts.map +1 -1
  161. package/dist/item/floorplan-move.js +231 -99
  162. package/dist/item/floorplan.d.ts +22 -0
  163. package/dist/item/floorplan.d.ts.map +1 -1
  164. package/dist/item/floorplan.js +72 -2
  165. package/dist/item/move-tool.d.ts +1 -1
  166. package/dist/item/move-tool.d.ts.map +1 -1
  167. package/dist/item/move-tool.js +15 -7
  168. package/dist/item/panel.js +1 -1
  169. package/dist/item/renderer.d.ts.map +1 -1
  170. package/dist/item/renderer.js +8 -2
  171. package/dist/level/renderer.js +1 -1
  172. package/dist/lineset/tool.d.ts.map +1 -1
  173. package/dist/lineset/tool.js +1 -0
  174. package/dist/liquid-line/tool.d.ts.map +1 -1
  175. package/dist/liquid-line/tool.js +5 -1
  176. package/dist/measurement/definition.d.ts.map +1 -1
  177. package/dist/measurement/definition.js +1 -0
  178. package/dist/pipe-segment/parametrics.d.ts.map +1 -1
  179. package/dist/pipe-segment/parametrics.js +5 -1
  180. package/dist/pipe-segment/tool.d.ts.map +1 -1
  181. package/dist/pipe-segment/tool.js +14 -3
  182. package/dist/pipe-trap/tool.d.ts.map +1 -1
  183. package/dist/pipe-trap/tool.js +7 -8
  184. package/dist/procedural-item/definition.d.ts +4 -0
  185. package/dist/procedural-item/definition.d.ts.map +1 -0
  186. package/dist/procedural-item/definition.js +257 -0
  187. package/dist/procedural-item/geometry.d.ts +31 -0
  188. package/dist/procedural-item/geometry.d.ts.map +1 -0
  189. package/dist/procedural-item/geometry.js +88 -0
  190. package/dist/procedural-item/index.d.ts +3 -0
  191. package/dist/procedural-item/index.d.ts.map +1 -0
  192. package/dist/procedural-item/index.js +2 -0
  193. package/dist/procedural-item/move-session.d.ts +15 -0
  194. package/dist/procedural-item/move-session.d.ts.map +1 -0
  195. package/dist/procedural-item/move-session.js +197 -0
  196. package/dist/procedural-item/move-tool.d.ts +5 -0
  197. package/dist/procedural-item/move-tool.d.ts.map +1 -0
  198. package/dist/procedural-item/move-tool.js +193 -0
  199. package/dist/procedural-item/renderer.d.ts +5 -0
  200. package/dist/procedural-item/renderer.d.ts.map +1 -0
  201. package/dist/procedural-item/renderer.js +66 -0
  202. package/dist/ridge-vent/definition.d.ts.map +1 -1
  203. package/dist/ridge-vent/definition.js +1 -0
  204. package/dist/ridge-vent/panel.js +4 -4
  205. package/dist/roof/definition.d.ts.map +1 -1
  206. package/dist/roof/definition.js +4 -1
  207. package/dist/roof/panel-model.d.ts +4 -0
  208. package/dist/roof/panel-model.d.ts.map +1 -0
  209. package/dist/roof/panel-model.js +151 -0
  210. package/dist/roof/panel.d.ts.map +1 -1
  211. package/dist/roof/panel.js +9 -8
  212. package/dist/roof/parametrics.d.ts.map +1 -1
  213. package/dist/roof/parametrics.js +16 -1
  214. package/dist/roof-segment/definition.d.ts.map +1 -1
  215. package/dist/roof-segment/definition.js +1 -0
  216. package/dist/roof-segment/panel.d.ts.map +1 -1
  217. package/dist/roof-segment/panel.js +5 -5
  218. package/dist/roof-segment/parametrics.d.ts.map +1 -1
  219. package/dist/roof-segment/parametrics.js +176 -1
  220. package/dist/scan/definition.d.ts.map +1 -1
  221. package/dist/scan/definition.js +1 -0
  222. package/dist/shared/automatic-run-end-cap.d.ts +1 -0
  223. package/dist/shared/automatic-run-end-cap.d.ts.map +1 -1
  224. package/dist/shared/automatic-run-end-cap.js +10 -0
  225. package/dist/shared/commit-opening-move.d.ts +4 -0
  226. package/dist/shared/commit-opening-move.d.ts.map +1 -0
  227. package/dist/shared/commit-opening-move.js +9 -0
  228. package/dist/shared/curtain-opening-limits.d.ts +14 -0
  229. package/dist/shared/curtain-opening-limits.d.ts.map +1 -0
  230. package/dist/shared/curtain-opening-limits.js +53 -0
  231. package/dist/shared/distribution-run-tool.d.ts +10 -0
  232. package/dist/shared/distribution-run-tool.d.ts.map +1 -1
  233. package/dist/shared/distribution-run-tool.js +56 -11
  234. package/dist/shared/draft-axis-guides.d.ts +0 -6
  235. package/dist/shared/draft-axis-guides.d.ts.map +1 -1
  236. package/dist/shared/draft-axis-guides.js +1 -8
  237. package/dist/shared/hosted-resize.d.ts +12 -0
  238. package/dist/shared/hosted-resize.d.ts.map +1 -0
  239. package/dist/shared/hosted-resize.js +166 -0
  240. package/dist/shared/opening-grid-follow.d.ts +8 -0
  241. package/dist/shared/opening-grid-follow.d.ts.map +1 -0
  242. package/dist/shared/opening-grid-follow.js +12 -0
  243. package/dist/shared/opening-property-preview-host.d.ts +3 -0
  244. package/dist/shared/opening-property-preview-host.d.ts.map +1 -0
  245. package/dist/shared/opening-property-preview-host.js +21 -0
  246. package/dist/shared/opening-property-preview.d.ts +19 -0
  247. package/dist/shared/opening-property-preview.d.ts.map +1 -0
  248. package/dist/shared/opening-property-preview.js +99 -0
  249. package/dist/shared/panel-fields.d.ts +15 -0
  250. package/dist/shared/panel-fields.d.ts.map +1 -0
  251. package/dist/shared/panel-fields.js +31 -0
  252. package/dist/shared/resting-surface-plan.d.ts +4 -0
  253. package/dist/shared/resting-surface-plan.d.ts.map +1 -0
  254. package/dist/shared/resting-surface-plan.js +53 -0
  255. package/dist/shared/surface-counterparts.d.ts +12 -0
  256. package/dist/shared/surface-counterparts.d.ts.map +1 -0
  257. package/dist/shared/surface-counterparts.js +27 -0
  258. package/dist/shared/wall-attach-target.d.ts +1 -0
  259. package/dist/shared/wall-attach-target.d.ts.map +1 -1
  260. package/dist/shared/wall-attach-target.js +4 -1
  261. package/dist/shared/wall-event-from-grid.d.ts +5 -0
  262. package/dist/shared/wall-event-from-grid.d.ts.map +1 -0
  263. package/dist/shared/wall-event-from-grid.js +36 -0
  264. package/dist/shelf/definition.d.ts.map +1 -1
  265. package/dist/shelf/definition.js +5 -2
  266. package/dist/shelf/floorplan-affordances.d.ts.map +1 -1
  267. package/dist/shelf/floorplan-affordances.js +5 -3
  268. package/dist/shelf/floorplan-move.d.ts.map +1 -1
  269. package/dist/shelf/floorplan-move.js +3 -2
  270. package/dist/shelf/floorplan.d.ts.map +1 -1
  271. package/dist/shelf/floorplan.js +9 -2
  272. package/dist/shelf/geometry.d.ts.map +1 -1
  273. package/dist/shelf/geometry.js +2 -10
  274. package/dist/site/renderer.d.ts.map +1 -1
  275. package/dist/site/renderer.js +9 -2
  276. package/dist/skylight/definition.d.ts.map +1 -1
  277. package/dist/skylight/definition.js +1 -0
  278. package/dist/skylight/panel.js +6 -6
  279. package/dist/slab/definition.d.ts.map +1 -1
  280. package/dist/slab/definition.js +4 -0
  281. package/dist/slab/panel.js +1 -1
  282. package/dist/solar-panel/definition.d.ts.map +1 -1
  283. package/dist/solar-panel/definition.js +1 -0
  284. package/dist/solar-panel/panel.js +2 -2
  285. package/dist/spawn/definition.d.ts.map +1 -1
  286. package/dist/spawn/definition.js +1 -0
  287. package/dist/spawn/panel.js +1 -1
  288. package/dist/stair/definition.d.ts.map +1 -1
  289. package/dist/stair/definition.js +2 -0
  290. package/dist/stair/panel.d.ts.map +1 -1
  291. package/dist/stair/panel.js +9 -7
  292. package/dist/stair/parametrics.d.ts.map +1 -1
  293. package/dist/stair/parametrics.js +164 -1
  294. package/dist/stair-segment/definition.d.ts.map +1 -1
  295. package/dist/stair-segment/definition.js +1 -0
  296. package/dist/stair-segment/panel.js +4 -4
  297. package/dist/stair-segment/parametrics.d.ts.map +1 -1
  298. package/dist/stair-segment/parametrics.js +81 -1
  299. package/dist/turbine-vent/definition.d.ts.map +1 -1
  300. package/dist/turbine-vent/definition.js +1 -0
  301. package/dist/turbine-vent/panel.js +1 -1
  302. package/dist/unit/definition.d.ts +10 -0
  303. package/dist/unit/definition.d.ts.map +1 -0
  304. package/dist/unit/definition.js +38 -0
  305. package/dist/unit/index.d.ts +2 -0
  306. package/dist/unit/index.d.ts.map +1 -0
  307. package/dist/unit/index.js +1 -0
  308. package/dist/unit/parametrics.d.ts +3 -0
  309. package/dist/unit/parametrics.d.ts.map +1 -0
  310. package/dist/unit/parametrics.js +4 -0
  311. package/dist/unit/schema.d.ts +2 -0
  312. package/dist/unit/schema.d.ts.map +1 -0
  313. package/dist/unit/schema.js +1 -0
  314. package/dist/unit/unit-panel.d.ts +5 -0
  315. package/dist/unit/unit-panel.d.ts.map +1 -0
  316. package/dist/unit/unit-panel.js +61 -0
  317. package/dist/wall/actions.d.ts +3 -0
  318. package/dist/wall/actions.d.ts.map +1 -0
  319. package/dist/wall/actions.js +56 -0
  320. package/dist/wall/curtain-opening-frame.d.ts +14 -0
  321. package/dist/wall/curtain-opening-frame.d.ts.map +1 -0
  322. package/dist/wall/curtain-opening-frame.js +111 -0
  323. package/dist/wall/curtain-panel-highlight.d.ts +3 -0
  324. package/dist/wall/curtain-panel-highlight.d.ts.map +1 -0
  325. package/dist/wall/curtain-panel-highlight.js +113 -0
  326. package/dist/wall/curtain-wall-adapter.d.ts +3 -0
  327. package/dist/wall/curtain-wall-adapter.d.ts.map +1 -0
  328. package/dist/wall/curtain-wall-adapter.js +55 -0
  329. package/dist/wall/curtain-wall-floorplan.d.ts +3 -0
  330. package/dist/wall/curtain-wall-floorplan.d.ts.map +1 -0
  331. package/dist/wall/curtain-wall-floorplan.js +91 -0
  332. package/dist/wall/curtain-wall-geometry.d.ts +4 -0
  333. package/dist/wall/curtain-wall-geometry.d.ts.map +1 -0
  334. package/dist/wall/curtain-wall-geometry.js +226 -0
  335. package/dist/wall/curtain-wall-layout.d.ts +16 -0
  336. package/dist/wall/curtain-wall-layout.d.ts.map +1 -0
  337. package/dist/wall/curtain-wall-layout.js +176 -0
  338. package/dist/wall/curtain-wall-materials.d.ts +5 -0
  339. package/dist/wall/curtain-wall-materials.d.ts.map +1 -0
  340. package/dist/wall/curtain-wall-materials.js +55 -0
  341. package/dist/wall/curtain-wall-panel.d.ts +14 -0
  342. package/dist/wall/curtain-wall-panel.d.ts.map +1 -0
  343. package/dist/wall/curtain-wall-panel.js +167 -0
  344. package/dist/wall/curtain-wall-piece-geometry.d.ts +5 -0
  345. package/dist/wall/curtain-wall-piece-geometry.d.ts.map +1 -0
  346. package/dist/wall/curtain-wall-piece-geometry.js +220 -0
  347. package/dist/wall/curtain-wall-shadow.d.ts +4 -0
  348. package/dist/wall/curtain-wall-shadow.d.ts.map +1 -0
  349. package/dist/wall/curtain-wall-shadow.js +15 -0
  350. package/dist/wall/definition.d.ts +0 -15
  351. package/dist/wall/definition.d.ts.map +1 -1
  352. package/dist/wall/definition.js +65 -4
  353. package/dist/wall/drawing-mode.d.ts +12 -0
  354. package/dist/wall/drawing-mode.d.ts.map +1 -0
  355. package/dist/wall/drawing-mode.js +38 -0
  356. package/dist/wall/floorplan-tool.d.ts +4 -0
  357. package/dist/wall/floorplan-tool.d.ts.map +1 -0
  358. package/dist/wall/floorplan-tool.js +107 -0
  359. package/dist/wall/floorplan.d.ts.map +1 -1
  360. package/dist/wall/floorplan.js +6 -2
  361. package/dist/wall/length-patch.d.ts +3 -0
  362. package/dist/wall/length-patch.d.ts.map +1 -0
  363. package/dist/wall/length-patch.js +14 -0
  364. package/dist/wall/move-tool.d.ts.map +1 -1
  365. package/dist/wall/move-tool.js +23 -1
  366. package/dist/wall/paint.d.ts.map +1 -1
  367. package/dist/wall/paint.js +39 -4
  368. package/dist/wall/panel-model.d.ts +4 -0
  369. package/dist/wall/panel-model.d.ts.map +1 -0
  370. package/dist/wall/panel-model.js +117 -0
  371. package/dist/wall/panel.d.ts.map +1 -1
  372. package/dist/wall/panel.js +20 -24
  373. package/dist/wall/property-preview.d.ts +7 -0
  374. package/dist/wall/property-preview.d.ts.map +1 -0
  375. package/dist/wall/property-preview.js +31 -0
  376. package/dist/wall/rectangle-command.d.ts +149 -0
  377. package/dist/wall/rectangle-command.d.ts.map +1 -0
  378. package/dist/wall/rectangle-command.js +22 -0
  379. package/dist/wall/rectangle-tool.d.ts +2 -0
  380. package/dist/wall/rectangle-tool.d.ts.map +1 -0
  381. package/dist/wall/rectangle-tool.js +147 -0
  382. package/dist/wall/renderer.d.ts.map +1 -1
  383. package/dist/wall/renderer.js +7 -4
  384. package/dist/wall/slots.d.ts +2 -2
  385. package/dist/wall/slots.d.ts.map +1 -1
  386. package/dist/wall/slots.js +10 -2
  387. package/dist/wall/split-floorplan-layer.d.ts +4 -0
  388. package/dist/wall/split-floorplan-layer.d.ts.map +1 -0
  389. package/dist/wall/split-floorplan-layer.js +71 -0
  390. package/dist/wall/split-pointer.d.ts +3 -0
  391. package/dist/wall/split-pointer.d.ts.map +1 -0
  392. package/dist/wall/split-pointer.js +95 -0
  393. package/dist/wall/split-preview.d.ts +55 -0
  394. package/dist/wall/split-preview.d.ts.map +1 -0
  395. package/dist/wall/split-preview.js +106 -0
  396. package/dist/wall/split-session.d.ts +16 -0
  397. package/dist/wall/split-session.d.ts.map +1 -0
  398. package/dist/wall/split-session.js +138 -0
  399. package/dist/wall/split-store.d.ts +16 -0
  400. package/dist/wall/split-store.d.ts.map +1 -0
  401. package/dist/wall/split-store.js +6 -0
  402. package/dist/wall/split-tool.d.ts +10 -0
  403. package/dist/wall/split-tool.d.ts.map +1 -0
  404. package/dist/wall/split-tool.js +95 -0
  405. package/dist/wall/system.d.ts.map +1 -1
  406. package/dist/wall/system.js +3 -1
  407. package/dist/wall/tool.d.ts.map +1 -1
  408. package/dist/wall/tool.js +14 -6
  409. package/dist/wall/wall-batch-system.d.ts.map +1 -1
  410. package/dist/wall/wall-batch-system.js +3 -0
  411. package/dist/window/definition.d.ts.map +1 -1
  412. package/dist/window/definition.js +48 -1
  413. package/dist/window/floorplan-affordances.d.ts.map +1 -1
  414. package/dist/window/floorplan-affordances.js +8 -10
  415. package/dist/window/move-tool.d.ts.map +1 -1
  416. package/dist/window/move-tool.js +4 -6
  417. package/dist/window/panel.d.ts.map +1 -1
  418. package/dist/window/panel.js +22 -60
  419. package/dist/window/tool.d.ts.map +1 -1
  420. package/dist/window/tool.js +34 -2
  421. package/dist/window/window-math.d.ts +1 -1
  422. package/dist/window/window-math.d.ts.map +1 -1
  423. package/dist/window/window-math.js +8 -11
  424. package/dist/zone/definition.d.ts.map +1 -1
  425. package/dist/zone/definition.js +8 -1
  426. package/dist/zone/floorplan.d.ts +1 -3
  427. package/dist/zone/floorplan.d.ts.map +1 -1
  428. package/dist/zone/floorplan.js +43 -28
  429. package/dist/zone/quantities-panel.d.ts.map +1 -1
  430. package/dist/zone/quantities-panel.js +32 -44
  431. package/dist/zone/renderer.d.ts.map +1 -1
  432. package/dist/zone/renderer.js +21 -7
  433. package/dist/zone/unit-membership.d.ts +12 -0
  434. package/dist/zone/unit-membership.d.ts.map +1 -0
  435. package/dist/zone/unit-membership.js +22 -0
  436. package/package.json +15 -9
  437. package/dist/shared/opening-documentation-fields.d.ts +0 -16
  438. package/dist/shared/opening-documentation-fields.d.ts.map +0 -1
  439. package/dist/shared/opening-documentation-fields.js +0 -54
@@ -1,9 +1,10 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- import { useLiveNodeOverrides, useLiveTransforms, useRegistry, useScene, } from '@pascal-app/core';
4
- import { baseMaterial, createColumnBoxGeometry, createColumnCylinderGeometry, createColumnSphereGeometry, createColumnTorusGeometry, createMaterial, createMaterialFromPresetRef, createSurfaceRoleMaterial, resolveMaterialRef, resolveSlotDefaultMaterial, useNodeEvents, useViewer, } from '@pascal-app/viewer';
3
+ import { collectDescendants, createSceneApi, useLiveNodeOverrides, useLiveTransforms, useRegistry, useScene, } from '@pascal-app/core';
4
+ import { baseMaterial, createColumnBoxGeometry, createColumnCylinderGeometry, createColumnSphereGeometry, createColumnTorusGeometry, createMaterial, createMaterialFromPresetRef, createSurfaceRoleMaterial, NodeRenderer, resolveMaterialRef, resolveSlotDefaultMaterial, useNodeEvents, useViewer, } from '@pascal-app/viewer';
5
5
  import { createContext, useContext, useEffect, useMemo, useRef } from 'react';
6
6
  import { BufferGeometry, Float32BufferAttribute } from 'three';
7
+ import { columnCapitalBlocks, columnShaftLayout, getSegments, getShaftScaleAt, getShaftSegmentCount, getShaftTwistRadians, } from './shape';
7
8
  import { COLUMN_BASE_DEFAULT, COLUMN_CAPITAL_DEFAULT, COLUMN_FRAME_DEFAULT, COLUMN_SHAFT_DEFAULT, } from './slots';
8
9
  const DEFAULT_COLUMN_MATERIAL = baseMaterial();
9
10
  const DEFAULT_COLUMN_SLOT_MATERIALS = createSingleColumnMaterialMap(DEFAULT_COLUMN_MATERIAL);
@@ -99,51 +100,6 @@ function createColumnSlotMaterials({ colorPreset, material, materialPreset, node
99
100
  }),
100
101
  };
101
102
  }
102
- function getSegments(node) {
103
- if (node.crossSection === 'octagonal')
104
- return 8;
105
- if (node.crossSection === 'sixteen-sided')
106
- return 16;
107
- return 32;
108
- }
109
- function getShaftProfile(node) {
110
- return node.shaftProfile ?? (node.shaftTaper > 0 ? 'tapered' : 'straight');
111
- }
112
- function getShaftSegmentCount(node) {
113
- const shaftProfile = getShaftProfile(node);
114
- const shaftTaper = node.shaftTaper ?? 0;
115
- const hasTwist = Math.abs(node.shaftTwistStep ?? 0) > 0.001;
116
- return Math.max(hasTwist ? 4 : 1, shaftProfile === 'straight' && shaftTaper <= 0 && !hasTwist
117
- ? 1
118
- : (node.shaftSegmentCount ?? (hasTwist ? 12 : 24)));
119
- }
120
- function getShaftTwistRadians(node, index) {
121
- return ((node.shaftTwistStep ?? 0) * Math.PI * index) / 180;
122
- }
123
- function getShaftScaleAt(node, t) {
124
- const shaftProfile = getShaftProfile(node);
125
- const shaftTaper = Math.min(node.shaftTaper ?? 0, 0.85);
126
- const startScale = node.shaftStartScale ?? 0.72;
127
- const endScale = node.shaftEndScale ?? startScale;
128
- const shaftBulge = node.shaftBulge ??
129
- (shaftProfile === 'bulged'
130
- ? 0.16
131
- : shaftProfile === 'baluster'
132
- ? 0.2
133
- : shaftProfile === 'hourglass'
134
- ? 0.18
135
- : 0);
136
- const taperedScale = 1 - shaftTaper * t;
137
- const linearScale = (startScale + (endScale - startScale) * t) * taperedScale;
138
- const bulgeCurve = Math.sin(Math.PI * t);
139
- const hourglassCurve = Math.abs(t - 0.5) * 2;
140
- const profileScale = shaftProfile === 'bulged' || shaftProfile === 'baluster'
141
- ? linearScale + shaftBulge * bulgeCurve
142
- : shaftProfile === 'hourglass'
143
- ? linearScale - shaftBulge * (1 - hourglassCurve)
144
- : linearScale;
145
- return Math.max(0.1, profileScale);
146
- }
147
103
  function clamp(value, min, max) {
148
104
  return Math.min(max, Math.max(min, value));
149
105
  }
@@ -868,58 +824,15 @@ function LeafCarvings({ node, capitalY, capitalHeight, }) {
868
824
  })) }));
869
825
  }
870
826
  function Capital({ node, y, height }) {
871
- if (height <= 0)
827
+ const blocks = columnCapitalBlocks(node, y, height);
828
+ if (!blocks.length)
872
829
  return null;
873
- const capitalStyle = node.capitalStyle ?? 'simple';
874
- if (capitalStyle === 'none')
875
- return null;
876
- if (capitalStyle === 'south-indian-bracket' || capitalStyle === 'wood-bracket') {
877
- const tierCount = Math.max(1, node.bracketTierCount ?? 3);
878
- const tierHeight = height / tierCount;
879
- const bracketDepth = node.bracketDepth ?? 0.35;
880
- return (_jsxs("group", { children: [Array.from({ length: tierCount }, (_, index) => {
881
- const t = index / Math.max(1, tierCount - 1);
882
- const scale = (node.capitalWidthScale ?? 1.6) + t * 0.32;
883
- return (_jsx(SquareBlock, { depth: node.depth * scale + bracketDepth * t, height: tierHeight, width: node.width * scale + bracketDepth * t, y: y + index * tierHeight }, index));
884
- }), Array.from({ length: node.pendantCount ?? 0 }, (_, index) => {
885
- const count = Math.max(1, node.pendantCount ?? 0);
886
- const angle = (index / count) * Math.PI * 2;
830
+ return (_jsxs("group", { children: [blocks.map((block, index) => block.kind === 'box' ? (_jsx(SquareBlock, { y: block.y, height: block.height, width: block.width, depth: block.depth }, index)) : block.kind === 'oval' ? (_jsx(OvalBlock, { y: block.y, height: block.height, width: block.width, depth: block.depth }, index)) : block.kind === 'round' ? (_jsx(RoundBlock, { y: block.y, height: block.height, radius: block.radius, segments: getSegments(node) }, index)) : (_jsx(ColumnBlock, { node: node, y: block.y, height: block.height, scale: block.scale }, index))), (node.capitalStyle === 'south-indian-bracket' || node.capitalStyle === 'wood-bracket') &&
831
+ Array.from({ length: node.pendantCount ?? 0 }, (_, index) => {
832
+ const angle = (index / Math.max(1, node.pendantCount ?? 0)) * Math.PI * 2;
887
833
  const distance = Math.max(node.width, node.depth) * 0.56;
888
834
  return (_jsx(MappedCone, { height: height * 0.28, position: [Math.cos(angle) * distance, y - height * 0.1, Math.sin(angle) * distance], radiusX: 0.035, rotation: [0, 0, 0], segments: 6 }, index));
889
- })] }));
890
- }
891
- if (capitalStyle === 'rounded' || capitalStyle === 'doric') {
892
- const topWidth = node.width * (node.capitalWidthScale ?? 1.34);
893
- const topDepth = node.depth * (node.capitalDepthScale ?? node.capitalWidthScale ?? 1.34);
894
- return (_jsxs("group", { children: [_jsx(OvalBlock, { depth: topDepth * 0.72, height: height * 0.24, segments: 32, width: topWidth * 0.72, y: y }), _jsx(OvalBlock, { depth: topDepth * 0.92, height: height * 0.32, segments: 32, width: topWidth * 0.92, y: y + height * 0.24 }), _jsx(SquareBlock, { depth: topDepth, height: height * 0.44, width: topWidth, y: y + height * 0.56 })] }));
895
- }
896
- if (capitalStyle === 'stepped') {
897
- const widthScale = node.capitalWidthScale ?? 1.46;
898
- const depthScale = node.capitalDepthScale ?? widthScale;
899
- const tierCount = Math.max(3, node.capitalTierCount ?? 3);
900
- const tierHeight = height / tierCount;
901
- const stepSpread = node.capitalStepSpread ?? 0.42;
902
- return (_jsx("group", { children: Array.from({ length: tierCount }, (_, index) => {
903
- const t = index / Math.max(1, tierCount - 1);
904
- const widthScaleAt = Math.max(0.5, widthScale - (1 - t) * stepSpread);
905
- const depthScaleAt = Math.max(0.5, depthScale - (1 - t) * stepSpread);
906
- return (_jsx(SquareBlock, { depth: node.depth * depthScaleAt, height: tierHeight * 1.01, width: node.width * widthScaleAt, y: y + index * tierHeight }, index));
907
- }) }));
908
- }
909
- if (capitalStyle === 'volute' ||
910
- capitalStyle === 'ionic-volute' ||
911
- capitalStyle === 'leaf-carved' ||
912
- capitalStyle === 'corinthian-leaf') {
913
- const topWidth = node.width * (node.capitalWidthScale ?? 1.46);
914
- const topDepth = node.depth * (node.capitalDepthScale ?? node.capitalWidthScale ?? 1.46);
915
- return (_jsxs("group", { children: [_jsx(ColumnBlock, { height: height * 0.24, node: node, scale: 0.9, y: y }), _jsx(ColumnBlock, { height: height * 0.2, node: node, scale: 1.08, y: y + height * 0.24 }), _jsx(SquareBlock, { depth: topDepth, height: height * 0.28, width: topWidth, y: y + height * 0.44 }), _jsx(Volutes, { capitalHeight: height, capitalY: y, node: node }), _jsx(LeafCarvings, { capitalHeight: height, capitalY: y, node: node })] }));
916
- }
917
- const widthScale = node.capitalWidthScale ?? (capitalStyle === 'simple-slab' ? 1.28 : 1.18);
918
- const depthScale = node.capitalDepthScale ?? widthScale;
919
- if (node.crossSection === 'square' || node.crossSection === 'rectangular') {
920
- return (_jsx(SquareBlock, { depth: node.depth * depthScale, height: height, width: node.width * widthScale, y: y }));
921
- }
922
- return (_jsx(RoundBlock, { height: height, radius: Math.max(node.radius * widthScale, node.width * widthScale * 0.5), segments: getSegments(node), y: y }));
835
+ }), _jsx(Volutes, { capitalHeight: height, capitalY: y, node: node }), _jsx(LeafCarvings, { capitalHeight: height, capitalY: y, node: node })] }));
923
836
  }
924
837
  /**
925
838
  * The column's geometry tree — either a fabricated support frame or the
@@ -931,12 +844,7 @@ function Capital({ node, y, height }) {
931
844
  * wrapping this in its own providers.
932
845
  */
933
846
  function ColumnBody({ node }) {
934
- const shaftLayout = useMemo(() => {
935
- const baseHeight = node.baseStyle === 'none' ? 0 : Math.min(node.baseHeight, node.height * 0.4);
936
- const capitalHeight = node.capitalStyle === 'none' ? 0 : Math.min(node.capitalHeight, node.height * 0.4);
937
- const shaftHeight = Math.max(0.1, node.height - baseHeight - capitalHeight);
938
- return { baseHeight, capitalHeight, shaftY: baseHeight, shaftHeight };
939
- }, [node.baseHeight, node.baseStyle, node.capitalHeight, node.capitalStyle, node.height]);
847
+ const shaftLayout = columnShaftLayout(node);
940
848
  if (node.supportStyle !== 'vertical') {
941
849
  const support = node.supportStyle === 'a-frame' ? (_jsx(AFrameSupport, { node: node })) : node.supportStyle === 'y-frame' ? (_jsx(YFrameSupport, { node: node })) : node.supportStyle === 'v-frame' ? (_jsx(VFrameSupport, { node: node })) : node.supportStyle === 'x-brace' ? (_jsx(XBraceSupport, { node: node })) : node.supportStyle === 'k-brace' ? (_jsx(KBraceSupport, { node: node })) : node.supportStyle === 'single-strut' ? (_jsx(SingleStrutSupport, { node: node })) : node.supportStyle === 'tripod' ? (_jsx(TripodSupport, { node: node })) : node.supportStyle === 'trestle' ? (_jsx(TrestleSupport, { node: node })) : node.supportStyle === 'portal-frame' ? (_jsx(PortalFrameSupport, { node: node })) : (_jsx(BoxFrameSupport, { node: node }));
942
850
  return _jsx(ColumnSlot, { slotId: "frame", children: support });
@@ -1011,6 +919,20 @@ export const ColumnRenderer = ({ node: rawNode }) => {
1011
919
  colorPreset,
1012
920
  }), [shading, textures, colorPreset, node, sceneMaterials]);
1013
921
  useRegistry(node.id, node.type, ref);
1014
- return (_jsx(ColumnMaterialContext.Provider, { value: materials, children: _jsx(ColumnEdgeSoftnessContext.Provider, { value: node.edgeSoftness ?? 0.025, children: _jsx("group", { position: liveTransform?.position ?? node.position, ref: ref, rotation: [0, liveTransform?.rotation ?? node.rotation, 0], visible: node.visible, ...handlers, children: _jsx(ColumnBody, { node: node }) }) }) }));
922
+ // This renderer bypasses GeometrySystem, which normally invalidates hosted descendants.
923
+ useEffect(() => {
924
+ const dirtySubtree = () => {
925
+ const scene = createSceneApi(useScene);
926
+ for (const id of collectDescendants(node.id, { scene })) {
927
+ scene.markDirty(id);
928
+ }
929
+ };
930
+ dirtySubtree();
931
+ return useLiveTransforms.subscribe((state, previous) => {
932
+ if (state.transforms.get(node.id) !== previous.transforms.get(node.id))
933
+ dirtySubtree();
934
+ });
935
+ }, [node]);
936
+ return (_jsx(ColumnMaterialContext.Provider, { value: materials, children: _jsx(ColumnEdgeSoftnessContext.Provider, { value: node.edgeSoftness ?? 0.025, children: _jsxs("group", { position: liveTransform?.position ?? node.position, ref: ref, rotation: [0, liveTransform?.rotation ?? node.rotation, 0], visible: node.visible, ...handlers, children: [_jsx(ColumnBody, { node: node }), node.children.map((id) => (_jsx(NodeRenderer, { nodeId: id }, id)))] }) }) }));
1015
937
  };
1016
938
  export default ColumnRenderer;
@@ -0,0 +1,22 @@
1
+ import type { ColumnNode } from '@pascal-app/core';
2
+ export declare function getSegments(node: ColumnNode): 8 | 16 | 32;
3
+ export declare function getShaftSegmentCount(node: ColumnNode): number;
4
+ export declare function getShaftTwistRadians(node: ColumnNode, index: number): number;
5
+ export declare function getShaftScaleAt(node: ColumnNode, t: number): number;
6
+ export declare function columnShaftLayout(node: ColumnNode): {
7
+ baseHeight: number;
8
+ capitalHeight: number;
9
+ shaftY: number;
10
+ shaftHeight: number;
11
+ };
12
+ export type CapitalBlock = {
13
+ kind: 'box' | 'round' | 'oval' | 'column';
14
+ y: number;
15
+ height: number;
16
+ width?: number;
17
+ depth?: number;
18
+ radius?: number;
19
+ scale?: number;
20
+ };
21
+ export declare function columnCapitalBlocks(node: ColumnNode, y: number, height: number): CapitalBlock[];
22
+ //# sourceMappingURL=shape.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shape.d.ts","sourceRoot":"","sources":["../../src/column/shape.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAClD,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,eAI3C;AAMD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,UAAU,UAUpD;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,UAEnE;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,UA0B1D;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU;;;;;EAMjD;AACD,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAA;IACzC,CAAC,EAAE,MAAM,CAAA;IACT,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AACD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,YAAY,EAAE,CAyE/F"}
@@ -0,0 +1,120 @@
1
+ export function getSegments(node) {
2
+ if (node.crossSection === 'octagonal')
3
+ return 8;
4
+ if (node.crossSection === 'sixteen-sided')
5
+ return 16;
6
+ return 32;
7
+ }
8
+ function getShaftProfile(node) {
9
+ return node.shaftProfile ?? (node.shaftTaper > 0 ? 'tapered' : 'straight');
10
+ }
11
+ export function getShaftSegmentCount(node) {
12
+ const shaftProfile = getShaftProfile(node);
13
+ const shaftTaper = node.shaftTaper ?? 0;
14
+ const hasTwist = Math.abs(node.shaftTwistStep ?? 0) > 0.001;
15
+ return Math.max(hasTwist ? 4 : 1, shaftProfile === 'straight' && shaftTaper <= 0 && !hasTwist
16
+ ? 1
17
+ : (node.shaftSegmentCount ?? (hasTwist ? 12 : 24)));
18
+ }
19
+ export function getShaftTwistRadians(node, index) {
20
+ return ((node.shaftTwistStep ?? 0) * Math.PI * index) / 180;
21
+ }
22
+ export function getShaftScaleAt(node, t) {
23
+ const shaftProfile = getShaftProfile(node);
24
+ const shaftTaper = Math.min(node.shaftTaper ?? 0, 0.85);
25
+ const startScale = node.shaftStartScale ?? 0.72;
26
+ const endScale = node.shaftEndScale ?? startScale;
27
+ const shaftBulge = node.shaftBulge ??
28
+ (shaftProfile === 'bulged'
29
+ ? 0.16
30
+ : shaftProfile === 'baluster'
31
+ ? 0.2
32
+ : shaftProfile === 'hourglass'
33
+ ? 0.18
34
+ : 0);
35
+ const taperedScale = 1 - shaftTaper * t;
36
+ const linearScale = (startScale + (endScale - startScale) * t) * taperedScale;
37
+ const bulgeCurve = Math.sin(Math.PI * t);
38
+ const hourglassCurve = Math.abs(t - 0.5) * 2;
39
+ const profileScale = shaftProfile === 'bulged' || shaftProfile === 'baluster'
40
+ ? linearScale + shaftBulge * bulgeCurve
41
+ : shaftProfile === 'hourglass'
42
+ ? linearScale - shaftBulge * (1 - hourglassCurve)
43
+ : linearScale;
44
+ return Math.max(0.1, profileScale);
45
+ }
46
+ export function columnShaftLayout(node) {
47
+ const baseHeight = node.baseStyle === 'none' ? 0 : Math.min(node.baseHeight, node.height * 0.4);
48
+ const capitalHeight = node.capitalStyle === 'none' ? 0 : Math.min(node.capitalHeight, node.height * 0.4);
49
+ const shaftHeight = Math.max(0.1, node.height - baseHeight - capitalHeight);
50
+ return { baseHeight, capitalHeight, shaftY: baseHeight, shaftHeight };
51
+ }
52
+ export function columnCapitalBlocks(node, y, height) {
53
+ const style = node.capitalStyle ?? 'simple';
54
+ if (height <= 0 || style === 'none')
55
+ return [];
56
+ if (style === 'south-indian-bracket' || style === 'wood-bracket') {
57
+ const count = Math.max(1, node.bracketTierCount ?? 3);
58
+ return Array.from({ length: count }, (_, index) => {
59
+ const t = index / Math.max(1, count - 1), scale = (node.capitalWidthScale ?? 1.6) + t * 0.32;
60
+ return {
61
+ kind: 'box',
62
+ y: y + (index * height) / count,
63
+ height: height / count,
64
+ width: node.width * scale + (node.bracketDepth ?? 0.35) * t,
65
+ depth: node.depth * scale + (node.bracketDepth ?? 0.35) * t,
66
+ };
67
+ });
68
+ }
69
+ if (style === 'rounded' || style === 'doric') {
70
+ const width = node.width * (node.capitalWidthScale ?? 1.34), depth = node.depth * (node.capitalDepthScale ?? node.capitalWidthScale ?? 1.34);
71
+ return [
72
+ { kind: 'oval', y, height: height * 0.24, width: width * 0.72, depth: depth * 0.72 },
73
+ {
74
+ kind: 'oval',
75
+ y: y + height * 0.24,
76
+ height: height * 0.32,
77
+ width: width * 0.92,
78
+ depth: depth * 0.92,
79
+ },
80
+ { kind: 'box', y: y + height * 0.56, height: height * 0.44, width, depth },
81
+ ];
82
+ }
83
+ if (style === 'stepped') {
84
+ const widthScale = node.capitalWidthScale ?? 1.46, depthScale = node.capitalDepthScale ?? widthScale, count = Math.max(3, node.capitalTierCount ?? 3);
85
+ return Array.from({ length: count }, (_, index) => {
86
+ const t = index / Math.max(1, count - 1), spread = (1 - t) * (node.capitalStepSpread ?? 0.42);
87
+ return {
88
+ kind: 'box',
89
+ y: y + (index * height) / count,
90
+ height: (height / count) * 1.01,
91
+ width: node.width * Math.max(0.5, widthScale - spread),
92
+ depth: node.depth * Math.max(0.5, depthScale - spread),
93
+ };
94
+ });
95
+ }
96
+ if (['volute', 'ionic-volute', 'leaf-carved', 'corinthian-leaf'].includes(style)) {
97
+ return [
98
+ { kind: 'column', y, height: height * 0.24, scale: 0.9 },
99
+ { kind: 'column', y: y + height * 0.24, height: height * 0.2, scale: 1.08 },
100
+ {
101
+ kind: 'box',
102
+ y: y + height * 0.44,
103
+ height: height * 0.28,
104
+ width: node.width * (node.capitalWidthScale ?? 1.46),
105
+ depth: node.depth * (node.capitalDepthScale ?? node.capitalWidthScale ?? 1.46),
106
+ },
107
+ ];
108
+ }
109
+ const widthScale = node.capitalWidthScale ?? (style === 'simple-slab' ? 1.28 : 1.18), depthScale = node.capitalDepthScale ?? widthScale;
110
+ return node.crossSection === 'square' || node.crossSection === 'rectangular'
111
+ ? [{ kind: 'box', y, height, width: node.width * widthScale, depth: node.depth * depthScale }]
112
+ : [
113
+ {
114
+ kind: 'round',
115
+ y,
116
+ height,
117
+ radius: Math.max(node.radius * widthScale, node.width * widthScale * 0.5),
118
+ },
119
+ ];
120
+ }
@@ -0,0 +1,4 @@
1
+ import { type ColumnNode, type DeclaredHostSurface, type SurfaceProvider } from '@pascal-app/core';
2
+ export declare function columnTopSurfaces(node: ColumnNode): DeclaredHostSurface[];
3
+ export declare const columnSurfaceProvider: SurfaceProvider;
4
+ //# sourceMappingURL=surface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surface.d.ts","sourceRoot":"","sources":["../../src/column/surface.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,UAAU,EACf,KAAK,mBAAmB,EAExB,KAAK,eAAe,EAErB,MAAM,kBAAkB,CAAA;AAoBzB,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,GAAG,mBAAmB,EAAE,CAgDzE;AAED,eAAO,MAAM,qBAAqB,EAAE,eAUnC,CAAA"}
@@ -0,0 +1,66 @@
1
+ import { hitDerivedSurfaceProvider, } from '@pascal-app/core';
2
+ import { columnCapitalBlocks, columnShaftLayout, getSegments, getShaftScaleAt, getShaftSegmentCount, getShaftTwistRadians, } from './shape';
3
+ function roundRegion(radius, segments, yaw = 0) {
4
+ return {
5
+ kind: 'polygon',
6
+ points: Array.from({ length: segments }, (_, i) => {
7
+ const angle = (i * Math.PI * 2) / segments + yaw;
8
+ return [Math.sin(angle) * radius, Math.cos(angle) * radius];
9
+ }),
10
+ };
11
+ }
12
+ export function columnTopSurfaces(node) {
13
+ if (node.supportStyle !== 'vertical' || node.style === 'cluster')
14
+ return [];
15
+ const layout = columnShaftLayout(node);
16
+ const cap = columnCapitalBlocks(node, layout.shaftY + layout.shaftHeight, layout.capitalHeight).at(-1);
17
+ let y;
18
+ let region;
19
+ if (cap) {
20
+ y = cap.y + cap.height;
21
+ if (cap.kind === 'round')
22
+ region = roundRegion(cap.radius, getSegments(node));
23
+ else {
24
+ const bevel = Math.min(Math.max(0, node.edgeSoftness ?? 0.025), Math.min(cap.width, cap.depth, cap.height) * 0.35);
25
+ region = { kind: 'rect', size: [cap.width / 2 - bevel, cap.depth / 2 - bevel] };
26
+ }
27
+ }
28
+ else {
29
+ const segments = getShaftSegmentCount(node);
30
+ const scale = getShaftScaleAt(node, (segments - 0.5) / segments);
31
+ const yaw = getShaftTwistRadians(node, segments - 1);
32
+ y = layout.shaftY + layout.shaftHeight + (layout.shaftHeight / segments) * 0.015;
33
+ if (node.crossSection === 'square' || node.crossSection === 'rectangular') {
34
+ const corner = Math.min(Math.max(0, node.shaftCornerRadius ?? 0.035), Math.min(node.width, node.depth) * 0.45) * scale;
35
+ const x = (node.width * scale) / 2 - corner;
36
+ const z = (node.depth * scale) / 2 - corner;
37
+ region = {
38
+ kind: 'polygon',
39
+ points: [
40
+ [-x, -z],
41
+ [x, -z],
42
+ [x, z],
43
+ [-x, z],
44
+ ].map(([px, pz]) => [
45
+ px * Math.cos(yaw) + pz * Math.sin(yaw),
46
+ -px * Math.sin(yaw) + pz * Math.cos(yaw),
47
+ ]),
48
+ };
49
+ }
50
+ else
51
+ region = roundRegion(node.radius * scale, getSegments(node), yaw);
52
+ }
53
+ return [{ id: 'top', position: [0, y, 0], normal: [0, 1, 0], region }];
54
+ }
55
+ export const columnSurfaceProvider = {
56
+ ...hitDerivedSurfaceProvider,
57
+ surfaces: (host) => columnTopSurfaces(host),
58
+ resolveHit(host, hit, ctx) {
59
+ const derived = hitDerivedSurfaceProvider.resolveHit(host, hit, ctx);
60
+ if (!derived)
61
+ return null;
62
+ const top = columnTopSurfaces(host)[0];
63
+ // Lower ornaments remain hit-derived; only the principal top has a durable resize identity.
64
+ return top && Math.abs(hit.point[1] - top.position[1]) < 1e-4 ? top : derived;
65
+ },
66
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/cupola/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAA;AAIzB,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AA6FrC;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,EAAE,cAAc,CAAC,OAAO,UAAU,CAgE9D,CAAA"}
1
+ {"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/cupola/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAA;AAIzB,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AA6FrC;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,EAAE,cAAc,CAAC,OAAO,UAAU,CAiE9D,CAAA"}
@@ -126,6 +126,7 @@ export const cupolaDefinition = {
126
126
  parametrics: cupolaParametrics,
127
127
  handles: cupolaHandles,
128
128
  floorplan: buildCupolaFloorplan,
129
+ rendersChildren: false,
129
130
  renderer: {
130
131
  kind: 'parametric',
131
132
  module: () => import('./renderer'),
@@ -102,5 +102,5 @@ export default function CupolaPanel() {
102
102
  ], value: node.roofStyle ?? 'dome' }), _jsx(SegmentedControl, { onChange: (v) => handleUpdate({ finial: v === 'on' }), options: [
103
103
  { label: 'Finial', value: 'on' },
104
104
  { label: 'No Finial', value: 'off' },
105
- ], value: (node.finial ?? true) ? 'on' : 'off' })] }), _jsxs(PanelSection, { title: "Dimensions", children: [_jsx(SliderControl, { label: "Width", max: 1000, min: 0.3, onChange: (v) => previewProp({ width: v }), onCommit: (v) => handleUpdate({ width: v }), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: Math.round(node.width * 100) / 100 }), _jsx(SliderControl, { label: "Depth", max: 1000, min: 0.3, onChange: (v) => previewProp({ depth: v }), onCommit: (v) => handleUpdate({ depth: v }), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: Math.round(node.depth * 100) / 100 }), _jsx(SliderControl, { label: "Height", max: 1000, min: 0.4, onChange: (v) => previewProp({ height: v }), onCommit: (v) => handleUpdate({ height: v }), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: Math.round(node.height * 100) / 100 })] }), _jsxs(PanelSection, { title: "Position", children: [_jsx(SliderControl, { label: "X", max: Math.round(((segment?.width ?? 10) / 2) * 100) / 100, min: -Math.round(((segment?.width ?? 10) / 2) * 100) / 100, onChange: (v) => previewProp({ position: [v, node.position[1] ?? 0, node.position[2] ?? 0] }), onCommit: (v) => handleUpdate({ position: [v, node.position[1] ?? 0, node.position[2] ?? 0] }), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: Math.round((node.position[0] ?? 0) * 100) / 100 }), _jsx(SliderControl, { label: "Y", max: Math.max((segment?.wallHeight ?? 3) + (segment ? getActiveRoofHeight(segment) : 3) + 2, (node.position[1] ?? 0) + 0.1), min: Math.min(0, (node.position[1] ?? 0) - 0.5), onChange: (v) => previewProp({ position: [node.position[0] ?? 0, v, node.position[2] ?? 0] }), onCommit: (v) => handleUpdate({ position: [node.position[0] ?? 0, v, node.position[2] ?? 0] }), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: Math.round((node.position[1] ?? 0) * 100) / 100 }), _jsx(SliderControl, { label: "Z", max: Math.round(((segment?.depth ?? 10) / 2) * 100) / 100, min: -Math.round(((segment?.depth ?? 10) / 2) * 100) / 100, onChange: (v) => previewProp({ position: [node.position[0] ?? 0, node.position[1] ?? 0, v] }), onCommit: (v) => handleUpdate({ position: [node.position[0] ?? 0, node.position[1] ?? 0, v] }), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: Math.round((node.position[2] ?? 0) * 100) / 100 }), _jsx(SliderControl, { label: "Rotation", max: 180, min: -180, onChange: (deg) => previewProp({ rotation: (deg * Math.PI) / 180 }), onCommit: (deg) => handleUpdate({ rotation: (deg * Math.PI) / 180 }), precision: 0, restoreOnCommit: false, step: 1, unit: "\u00B0", value: Math.round(((node.rotation ?? 0) * 180) / Math.PI) })] }), _jsx(PanelSection, { title: "Actions", children: _jsxs(ActionGroup, { children: [_jsx(ActionButton, { icon: _jsx(Move, { className: "h-3.5 w-3.5" }), label: "Move", onClick: handleMove }), _jsx(ActionButton, { icon: _jsx(Copy, { className: "h-3.5 w-3.5" }), label: "Duplicate", onClick: handleDuplicate }), _jsx(ActionButton, { className: "hover:bg-red-500/20", icon: _jsx(Trash2, { className: "h-3.5 w-3.5 text-red-400" }), label: "Delete", onClick: handleDelete })] }) })] }));
105
+ ], value: (node.finial ?? true) ? 'on' : 'off' })] }), _jsxs(PanelSection, { title: "Dimensions", children: [_jsx(SliderControl, { label: "Width", max: 1000, min: 0.3, onChange: (v) => previewProp({ width: v }), onCommit: (v) => handleUpdate({ width: v }), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: node.width }), _jsx(SliderControl, { label: "Depth", max: 1000, min: 0.3, onChange: (v) => previewProp({ depth: v }), onCommit: (v) => handleUpdate({ depth: v }), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: node.depth }), _jsx(SliderControl, { label: "Height", max: 1000, min: 0.4, onChange: (v) => previewProp({ height: v }), onCommit: (v) => handleUpdate({ height: v }), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: node.height })] }), _jsxs(PanelSection, { title: "Position", children: [_jsx(SliderControl, { label: "X", max: Math.round(((segment?.width ?? 10) / 2) * 100) / 100, min: -Math.round(((segment?.width ?? 10) / 2) * 100) / 100, onChange: (v) => previewProp({ position: [v, node.position[1] ?? 0, node.position[2] ?? 0] }), onCommit: (v) => handleUpdate({ position: [v, node.position[1] ?? 0, node.position[2] ?? 0] }), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: node.position[0] ?? 0 }), _jsx(SliderControl, { label: "Y", max: Math.max((segment?.wallHeight ?? 3) + (segment ? getActiveRoofHeight(segment) : 3) + 2, (node.position[1] ?? 0) + 0.1), min: Math.min(0, (node.position[1] ?? 0) - 0.5), onChange: (v) => previewProp({ position: [node.position[0] ?? 0, v, node.position[2] ?? 0] }), onCommit: (v) => handleUpdate({ position: [node.position[0] ?? 0, v, node.position[2] ?? 0] }), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: node.position[1] ?? 0 }), _jsx(SliderControl, { label: "Z", max: Math.round(((segment?.depth ?? 10) / 2) * 100) / 100, min: -Math.round(((segment?.depth ?? 10) / 2) * 100) / 100, onChange: (v) => previewProp({ position: [node.position[0] ?? 0, node.position[1] ?? 0, v] }), onCommit: (v) => handleUpdate({ position: [node.position[0] ?? 0, node.position[1] ?? 0, v] }), precision: 2, restoreOnCommit: false, step: 0.05, unit: "m", value: node.position[2] ?? 0 }), _jsx(SliderControl, { label: "Rotation", max: 180, min: -180, onChange: (deg) => previewProp({ rotation: (deg * Math.PI) / 180 }), onCommit: (deg) => handleUpdate({ rotation: (deg * Math.PI) / 180 }), precision: 0, restoreOnCommit: false, step: 1, unit: "\u00B0", value: Math.round(((node.rotation ?? 0) * 180) / Math.PI) })] }), _jsx(PanelSection, { title: "Actions", children: _jsxs(ActionGroup, { children: [_jsx(ActionButton, { icon: _jsx(Move, { className: "h-3.5 w-3.5" }), label: "Move", onClick: handleMove }), _jsx(ActionButton, { icon: _jsx(Copy, { className: "h-3.5 w-3.5" }), label: "Duplicate", onClick: handleDuplicate }), _jsx(ActionButton, { className: "hover:bg-red-500/20", icon: _jsx(Trash2, { className: "h-3.5 w-3.5 text-red-400" }), label: "Delete", onClick: handleDelete })] }) })] }));
106
106
  }
@@ -1 +1 @@
1
- {"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/door/definition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAIV,cAAc,EAGf,MAAM,kBAAkB,CAAA;AAkBzB,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AA4HnC;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,cAAc,EAAE,cAAc,CAAC,OAAO,QAAQ,CAqH1D,CAAA"}
1
+ {"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/door/definition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAIV,cAAc,EAGf,MAAM,kBAAkB,CAAA;AAqBzB,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAkKnC;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,cAAc,EAAE,cAAc,CAAC,OAAO,QAAQ,CAsH1D,CAAA"}
@@ -1,5 +1,8 @@
1
+ import { curtainOpeningResizeMax } from '../shared/curtain-opening-limits';
1
2
  import { buildDoorFloorplanSchedule, computeDoorFloorplanLevelData, } from '../shared/opening-documentation';
2
3
  import { publishOpeningResizeGuides } from '../shared/opening-guides-runtime';
4
+ import { createOpeningPropertyPreview } from '../shared/opening-property-preview';
5
+ import { openingPropertyPreviewHost } from '../shared/opening-property-preview-host';
3
6
  import { readRoofFaceHeightMax, readRoofFaceWidthMax } from '../shared/roof-opening-host';
4
7
  import { buildRoofWallOpeningCut } from '../shared/roof-wall-opening-cut';
5
8
  import { readHostWallCeiling } from '../shared/wall-opening-ceiling';
@@ -46,7 +49,7 @@ function doorWidthHandle(side) {
46
49
  const roofMax = readRoofFaceWidthMax(n, scene, sign);
47
50
  if (roofMax !== null)
48
51
  return Math.max(MIN_DOOR_WIDTH, roofMax);
49
- return readWallLength(n, scene);
52
+ return curtainOpeningResizeMax(n, scene.nodes(), 'x', sign) ?? readWallLength(n, scene);
50
53
  },
51
54
  currentValue: (n) => n.width,
52
55
  onDrag: (node) => publishOpeningResizeGuides(node, false),
@@ -88,6 +91,9 @@ function doorHeightHandle() {
88
91
  const roofMax = readRoofFaceHeightMax(n, scene, 1);
89
92
  if (roofMax !== null)
90
93
  return Math.max(MIN_DOOR_HEIGHT, roofMax);
94
+ const curtainMax = curtainOpeningResizeMax(n, scene.nodes(), 'y', 1);
95
+ if (curtainMax !== undefined)
96
+ return curtainMax;
91
97
  const bottom = n.position[1] - n.height / 2;
92
98
  return Math.max(MIN_DOOR_HEIGHT, readHostWallCeiling(n.wallId, scene) - bottom);
93
99
  },
@@ -126,11 +132,43 @@ function doorMoveHandle() {
126
132
  },
127
133
  };
128
134
  }
135
+ function doorRadiusHandle(index) {
136
+ const sign = index === 0 ? -1 : 1;
137
+ return {
138
+ kind: 'corner-radius',
139
+ corner: [sign, 1],
140
+ width: (node) => node.width,
141
+ height: (node) => node.height,
142
+ currentValue: (node) => node.openingRadiusMode === 'individual'
143
+ ? (node.openingTopRadii[index] ?? 0)
144
+ : node.cornerRadius,
145
+ max: (node) => Math.min(node.width / 2, node.height),
146
+ apply: (node, radius, _scene, modifiers) => {
147
+ if (!modifiers.shiftKey) {
148
+ return { openingShape: 'rounded', openingRadiusMode: 'all', cornerRadius: radius };
149
+ }
150
+ const radii = node.openingRadiusMode === 'individual'
151
+ ? [...node.openingTopRadii]
152
+ : [node.cornerRadius, node.cornerRadius];
153
+ radii[index] = radius;
154
+ return {
155
+ openingShape: 'rounded',
156
+ openingRadiusMode: 'individual',
157
+ openingTopRadii: radii,
158
+ };
159
+ },
160
+ createPreview: (node) => createOpeningPropertyPreview(node.id, openingPropertyPreviewHost),
161
+ visible: (node) => node.openingShape !== 'arch',
162
+ portal: 'grandparent',
163
+ };
164
+ }
129
165
  const doorHandles = [
130
166
  doorMoveHandle(),
131
167
  doorWidthHandle('left'),
132
168
  doorWidthHandle('right'),
133
169
  doorHeightHandle(),
170
+ doorRadiusHandle(0),
171
+ doorRadiusHandle(1),
134
172
  ];
135
173
  /**
136
174
  * Door — Phase 5 batch kind. Hosted on walls, cuts holes in them,
@@ -200,6 +238,7 @@ export const doorDefinition = {
200
238
  },
201
239
  parametrics: doorParametrics,
202
240
  handles: doorHandles,
241
+ rendersChildren: false,
203
242
  renderer: {
204
243
  kind: 'parametric',
205
244
  module: () => import('./renderer'),
@@ -1,4 +1,4 @@
1
- import type { WallNode } from '@pascal-app/core';
1
+ import { type WallNode } from '@pascal-app/core';
2
2
  /**
3
3
  * Keep the door handle at the same relative height when the door is resized:
4
4
  * scale it by the height ratio, then clamp to the panel's slider bounds
@@ -1 +1 @@
1
- {"version":3,"file":"door-math.d.ts","sourceRoot":"","sources":["../../src/door/door-math.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAEhD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,MAAM,CAGR;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,YAAY,SAAI,EAChB,aAAa,SAAI,GAChB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAU1B;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAQxC;AAKD,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAA"}
1
+ {"version":3,"file":"door-math.d.ts","sourceRoot":"","sources":["../../src/door/door-math.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,QAAQ,EACd,MAAM,kBAAkB,CAAA;AAEzB;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,MAAM,CAGR;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,YAAY,SAAI,EAChB,aAAa,SAAI,GAChB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAI1B;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAOxC;AAKD,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAA"}
@@ -1,3 +1,4 @@
1
+ import { getCurtainWallConfig, getWallCurveFrameAt, getWallCurveLength, } from '@pascal-app/core';
1
2
  /**
2
3
  * Keep the door handle at the same relative height when the door is resized:
3
4
  * scale it by the height ratio, then clamp to the panel's slider bounds
@@ -13,22 +14,18 @@ export function scaleHandleHeight(handleHeight, oldHeight, newHeight) {
13
14
  * Converts wall-local (X along wall, Y = height above wall base) to world XYZ.
14
15
  */
15
16
  export function wallLocalToWorld(wallNode, localX, localY, levelYOffset = 0, slabElevation = 0) {
16
- const wallAngle = Math.atan2(wallNode.end[1] - wallNode.start[1], wallNode.end[0] - wallNode.start[0]);
17
- return [
18
- wallNode.start[0] + localX * Math.cos(wallAngle),
19
- slabElevation + localY + levelYOffset,
20
- wallNode.start[1] + localX * Math.sin(wallAngle),
21
- ];
17
+ const wallLength = getWallCurveLength(wallNode);
18
+ const frame = getWallCurveFrameAt(wallNode, wallLength > 1e-6 ? localX / wallLength : 0);
19
+ return [frame.point.x, slabElevation + localY + levelYOffset, frame.point.y];
22
20
  }
23
21
  /**
24
22
  * Clamps door center X so it stays fully within wall bounds.
25
23
  * Y is always height/2 — doors sit at floor level.
26
24
  */
27
25
  export function clampToWall(wallNode, localX, width, height) {
28
- const dx = wallNode.end[0] - wallNode.start[0];
29
- const dz = wallNode.end[1] - wallNode.start[1];
30
- const wallLength = Math.sqrt(dx * dx + dz * dz);
31
- const clampedX = Math.max(width / 2, Math.min(wallLength - width / 2, localX));
26
+ const wallLength = getWallCurveLength(wallNode);
27
+ const margin = wallNode.wallType === 'curtain' ? getCurtainWallConfig(wallNode).perimeterWidth : 0;
28
+ const clampedX = Math.max(margin + width / 2, Math.min(wallLength - margin - width / 2, localX));
32
29
  const clampedY = height / 2; // Doors always sit at floor level
33
30
  return { clampedX, clampedY };
34
31
  }
@@ -1 +1 @@
1
- {"version":3,"file":"floorplan-affordances.d.ts","sourceRoot":"","sources":["../../src/door/floorplan-affordances.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,mBAAmB,EAKzB,MAAM,kBAAkB,CAAA;AAMzB;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,mBAAmB,EAAE,mBAAmB,CAAC,QAAQ,CAuF7D,CAAA"}
1
+ {"version":3,"file":"floorplan-affordances.d.ts","sourceRoot":"","sources":["../../src/door/floorplan-affordances.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,mBAAmB,EAMzB,MAAM,kBAAkB,CAAA;AAQzB;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,mBAAmB,EAAE,mBAAmB,CAAC,QAAQ,CAkF7D,CAAA"}
@@ -1,4 +1,6 @@
1
- import { useLiveNodeOverrides, useScene, } from '@pascal-app/core';
1
+ import { getWallCurveLength, useLiveNodeOverrides, useScene, } from '@pascal-app/core';
2
+ import { curtainOpeningLimits } from '../shared/curtain-opening-limits';
3
+ import { projectPlanPointToWallLocalX } from '../shared/wall-attach-target';
2
4
  const MIN_DOOR_WIDTH = 0.3;
3
5
  /**
4
6
  * 2D drag affordance for the door's width side-arrows. Sister to the 3D
@@ -29,21 +31,15 @@ export const doorWidthAffordance = {
29
31
  // toward wall.end), -1 for 'start' (drag outward toward wall.start).
30
32
  const growDir = side === 'end' ? 1 : -1;
31
33
  const anchorX = side === 'end' ? initialDoorX - initialWidth / 2 : initialDoorX + initialWidth / 2;
32
- // Wall axis (level-local) for projecting pointer movement to a
33
- // wall-local X delta.
34
- const wallStart = wall ? wall.start : [0, 0];
35
- const wallEnd = wall ? wall.end : [1, 0];
36
- const dx = wallEnd[0] - wallStart[0];
37
- const dz = wallEnd[1] - wallStart[1];
38
- const wallLength = Math.hypot(dx, dz) || 1;
39
- const dirX = dx / wallLength;
40
- const dirZ = dz / wallLength;
34
+ const wallLength = wall ? getWallCurveLength(wall) : 1;
41
35
  // Max width keeps the dragged edge inside the wall span. With the
42
36
  // anchor fixed, the moving edge is `anchorX ± width`, so the largest
43
37
  // legal width is the headroom on the grow side.
44
- const maxWidth = growDir > 0 ? wallLength - anchorX : anchorX;
38
+ const limits = curtainOpeningLimits(node, nodes);
39
+ const margin = limits?.margin ?? 0;
40
+ const maxWidth = growDir > 0 ? (limits?.length ?? wallLength) - margin - anchorX : anchorX - margin;
45
41
  const projectToWallLocalX = (planPoint) => {
46
- return (planPoint[0] - wallStart[0]) * dirX + (planPoint[1] - wallStart[1]) * dirZ;
42
+ return wall ? projectPlanPointToWallLocalX(wall, planPoint) : planPoint[0];
47
43
  };
48
44
  // Initial pointer in wall-local X — anchored to where the user
49
45
  // actually pressed, so any subtle offset between the arrow's visual
@@ -1 +1 @@
1
- {"version":3,"file":"move-tool.d.ts","sourceRoot":"","sources":["../../src/door/move-tool.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,QAAQ,EAYT,MAAM,kBAAkB,CAAA;AAkDzB,QAAA,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CA0hC9C,CAAA;AAED,eAAe,YAAY,CAAA"}
1
+ {"version":3,"file":"move-tool.d.ts","sourceRoot":"","sources":["../../src/door/move-tool.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,QAAQ,EAYT,MAAM,kBAAkB,CAAA;AAmDzB,QAAA,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAwhC9C,CAAA;AAED,eAAe,YAAY,CAAA"}