@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
@@ -0,0 +1,10 @@
1
+ import { type FaceHostCapability, type ItemNode } from '@pascal-app/core';
2
+ /**
3
+ * Authored objects host ceiling items (pendants, fans, recessed cans) on
4
+ * their real undersides — a vault plane, a soffit, a beam — found from the
5
+ * pointer's hit, so placement follows the geometry the script built. A
6
+ * pendant hangs plumb, a recessed fixture tilts with the slope; either
7
+ * becomes the object's child.
8
+ */
9
+ export declare const authoredItemFaceHost: FaceHostCapability<ItemNode>;
10
+ //# sourceMappingURL=authored-face-host.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authored-face-host.d.ts","sourceRoot":"","sources":["../../src/item/authored-face-host.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EAGvB,KAAK,QAAQ,EAGd,MAAM,kBAAkB,CAAA;AA4CzB;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,EAAE,kBAAkB,CAAC,QAAQ,CAsC7D,CAAA"}
@@ -0,0 +1,87 @@
1
+ import { flushMountRotation, mountsFlush, sceneRegistry, } from '@pascal-app/core';
2
+ import { Quaternion, Triangle, Vector3 } from 'three';
3
+ /** Faces pointing at least this far down take ceiling items (a vault plane at up to ~70°). */
4
+ const UNDERSIDE_MAX_NORMAL_Y = -0.35;
5
+ const UNDERSIDE_FACE = 'underside';
6
+ function hitNormal(object, faceIndex) {
7
+ const geometry = object.geometry;
8
+ const position = geometry?.getAttribute('position');
9
+ if (!(geometry && position) || faceIndex === undefined)
10
+ return null;
11
+ const index = geometry.getIndex();
12
+ const vertex = (k) => (index ? index.getX(faceIndex * 3 + k) : faceIndex * 3 + k);
13
+ const triangle = new Triangle(new Vector3().fromBufferAttribute(position, vertex(0)), new Vector3().fromBufferAttribute(position, vertex(1)), new Vector3().fromBufferAttribute(position, vertex(2)));
14
+ return triangle.getNormal(new Vector3());
15
+ }
16
+ /**
17
+ * Where a ceiling item hangs under an authored object: the hit point and the
18
+ * face normal, both in the host item's frame, when the face points down.
19
+ */
20
+ function resolveUnderside(args) {
21
+ if (!args.host.source || args.asset.attachTo !== 'ceiling')
22
+ return null;
23
+ const hostObject = sceneRegistry.nodes.get(args.host.id);
24
+ const object = args.object;
25
+ const localNormal = hitNormal(object, args.faceIndex);
26
+ if (!(hostObject && localNormal))
27
+ return null;
28
+ object.updateWorldMatrix(true, false);
29
+ hostObject.updateWorldMatrix(true, false);
30
+ const world = object.localToWorld(new Vector3(...args.localPosition));
31
+ const point = hostObject.worldToLocal(world.clone());
32
+ const toHost = hostObject.getWorldQuaternion(new Quaternion()).invert();
33
+ const normal = localNormal
34
+ .applyQuaternion(object.getWorldQuaternion(new Quaternion()))
35
+ .applyQuaternion(toHost)
36
+ .normalize();
37
+ if (normal.y > UNDERSIDE_MAX_NORMAL_Y)
38
+ return null;
39
+ return { world, point, normal };
40
+ }
41
+ /**
42
+ * Authored objects host ceiling items (pendants, fans, recessed cans) on
43
+ * their real undersides — a vault plane, a soffit, a beam — found from the
44
+ * pointer's hit, so placement follows the geometry the script built. A
45
+ * pendant hangs plumb, a recessed fixture tilts with the slope; either
46
+ * becomes the object's child.
47
+ */
48
+ export const authoredItemFaceHost = {
49
+ currentFaceId: (item) => (item?.asset.attachTo === 'ceiling' ? UNDERSIDE_FACE : null),
50
+ clearItemFields: [],
51
+ resolvePlacement: (args) => {
52
+ const hit = resolveUnderside(args);
53
+ if (!hit)
54
+ return null;
55
+ const yaw = args.draftItem?.rotation[1] ?? 0;
56
+ // A recessed fixture seats flush along the face, tilted with a slope; a
57
+ // pendant or fan hangs plumb from the point.
58
+ const flush = mountsFlush({ ...args.asset, dimensions: args.rawDimensions });
59
+ const offset = flush
60
+ ? hit.normal.clone().multiplyScalar(0.02)
61
+ : new Vector3(0, -args.rawDimensions[1], 0);
62
+ const at = hit.point.clone().add(offset);
63
+ const position = [at.x, at.y, at.z];
64
+ const rotation = flush
65
+ ? flushMountRotation([hit.normal.x, hit.normal.y, hit.normal.z], yaw)
66
+ : [0, yaw, 0];
67
+ const cursor = hit.world.clone().add(offset);
68
+ return {
69
+ faceId: UNDERSIDE_FACE,
70
+ nodeUpdate: {
71
+ position,
72
+ rotation,
73
+ parentId: args.host.id,
74
+ wallId: undefined,
75
+ blockFaceId: undefined,
76
+ roofSegmentId: undefined,
77
+ roofFace: undefined,
78
+ },
79
+ position,
80
+ rotation,
81
+ cursorPosition: cursor.toArray(),
82
+ cursorRotation: rotation,
83
+ };
84
+ },
85
+ storedPlacementPatch: () => null,
86
+ isStoredPlacementValid: ({ host, asset }) => Boolean(host.source) && asset.attachTo === 'ceiling',
87
+ };
@@ -0,0 +1,15 @@
1
+ import type { ScriptedNode } from '@pascal-app/core';
2
+ /**
3
+ * The params an authored object's script declares, as controls. Sliders
4
+ * preview their value while dragging and rebuild on release (a rebuild runs
5
+ * the script again: tens to hundreds of milliseconds in three.js, seconds in
6
+ * Blender). A param changed from
7
+ * the script's default can be put back, alone or with all the others.
8
+ */
9
+ export declare function AuthoredParams({ node, }: {
10
+ node: {
11
+ id: string;
12
+ source?: ScriptedNode['source'];
13
+ };
14
+ }): import("react").JSX.Element | null;
15
+ //# sourceMappingURL=authored-params.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authored-params.d.ts","sourceRoot":"","sources":["../../src/item/authored-params.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAGV,YAAY,EACb,MAAM,kBAAkB,CAAA;AAezB;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,EAC7B,IAAI,GACL,EAAE;IACD,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAA;KAAE,CAAA;CACtD,sCAsHA"}
@@ -0,0 +1,72 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { PanelSection, rebuildAuthoredObject, SegmentedControl, SliderControl, ToggleControl, Tooltip, TooltipContent, TooltipTrigger, } from '@pascal-app/editor';
4
+ import { RotateCcw } from 'lucide-react';
5
+ import { useRef, useState } from 'react';
6
+ import { isScriptDefault, scriptDefault, scriptDefaultsPatch } from './script-param-defaults';
7
+ /**
8
+ * The params an authored object's script declares, as controls. Sliders
9
+ * preview their value while dragging and rebuild on release (a rebuild runs
10
+ * the script again: tens to hundreds of milliseconds in three.js, seconds in
11
+ * Blender). A param changed from
12
+ * the script's default can be put back, alone or with all the others.
13
+ */
14
+ export function AuthoredParams({ node, }) {
15
+ const source = node.source;
16
+ const [drafts, setDrafts] = useState({});
17
+ const [busy, setBusy] = useState(false);
18
+ const rebuilding = useRef(false);
19
+ const [error, setError] = useState(null);
20
+ if (!source || source.manifest.params.length === 0)
21
+ return null;
22
+ const rebuild = (patch) => {
23
+ if (rebuilding.current)
24
+ return;
25
+ rebuilding.current = true;
26
+ setBusy(true);
27
+ setError(null);
28
+ rebuildAuthoredObject(node.id, patch)
29
+ .catch((reason) => {
30
+ console.error('[authored object] rebuild failed', reason);
31
+ setError("Couldn't rebuild with these values.");
32
+ })
33
+ .finally(() => {
34
+ rebuilding.current = false;
35
+ setBusy(false);
36
+ setDrafts((current) => {
37
+ const rest = { ...current };
38
+ for (const id of Object.keys(patch))
39
+ delete rest[id];
40
+ return rest;
41
+ });
42
+ });
43
+ };
44
+ const control = (spec) => {
45
+ const value = source.params[spec.id] ?? scriptDefault(spec);
46
+ const label = spec.label ?? spec.id;
47
+ if (spec.kind === 'boolean') {
48
+ return (_jsx(ToggleControl, { checked: Boolean(value), label: label, onChange: (checked) => rebuild({ [spec.id]: checked }) }));
49
+ }
50
+ if (spec.kind === 'string') {
51
+ if (!spec.options?.length) {
52
+ return (_jsxs("div", { className: "flex h-7 items-center justify-between gap-2 px-2 text-xs", children: [_jsx("span", { className: "text-muted-foreground", children: label }), _jsx("span", { className: "truncate", children: String(value) })] }));
53
+ }
54
+ return (_jsx(SegmentedControl, { onChange: (next) => rebuild({ [spec.id]: next }), options: spec.options.map((option) => ({ label: option, value: option })), value: String(value) }));
55
+ }
56
+ const current = drafts[spec.id] ?? Number(value);
57
+ const span = Math.max(Math.abs(Number(spec.default)), 1);
58
+ return (_jsx(SliderControl, { label: label, max: spec.max ?? Number(spec.default) + span, min: spec.min ?? Number(spec.default) - span, onChange: (next) => {
59
+ if (!rebuilding.current)
60
+ setDrafts((d) => ({ ...d, [spec.id]: next }));
61
+ }, onCommit: (next) => rebuild({ [spec.id]: next }), precision: spec.step !== undefined && spec.step < 1 ? 2 : 0, restoreOnCommit: false, step: spec.step ?? 0.01, unit: spec.unit, value: current }));
62
+ };
63
+ const row = (spec) => {
64
+ const input = control(spec);
65
+ return (_jsxs("div", { className: "flex items-center gap-1", inert: busy, children: [_jsx("div", { className: "min-w-0 flex-1", children: input }), isScriptDefault(spec, source.params[spec.id]) ? null : (_jsx(ResetButton, { label: `Reset ${spec.label ?? spec.id}`, onClick: () => rebuild({ [spec.id]: scriptDefault(spec) }) }))] }, spec.id));
66
+ };
67
+ const resetAll = scriptDefaultsPatch(source.manifest.params, source.params);
68
+ return (_jsxs(PanelSection, { title: "Parameters", children: [source.manifest.params.map(row), Object.keys(resetAll).length > 0 ? (_jsxs("button", { className: "mt-1 flex h-8 items-center justify-center gap-1.5 rounded-full border border-border/50 px-3 font-medium text-foreground text-xs transition-colors hover:bg-accent/50", "data-authored-params-reset": true, disabled: busy, onClick: () => rebuild(resetAll), type: "button", children: [_jsx(RotateCcw, { className: "h-3.5 w-3.5" }), "Reset parameters"] })) : null, busy ? (_jsx("div", { className: "px-2 py-1 text-muted-foreground text-xs", children: source.language === 'bpy' ? 'Rebuilding in Blender…' : 'Rebuilding…' })) : null, error ? _jsx("div", { className: "px-2 py-1 text-red-400 text-xs", children: error }) : null] }));
69
+ }
70
+ function ResetButton({ label, onClick }) {
71
+ return (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { "aria-label": label, className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-full text-muted-foreground transition-colors hover:bg-accent hover:text-foreground", "data-authored-param-reset": true, onClick: onClick, type: "button", children: _jsx(RotateCcw, { className: "h-3.5 w-3.5" }) }) }), _jsx(TooltipContent, { side: "top", children: "Reset to default" })] }));
72
+ }
@@ -3,8 +3,8 @@ import { ItemNode } from './schema';
3
3
  /**
4
4
  * Item — Phase 5 batch kind. Catalog-backed, GLB-rendered, multi-host.
5
5
  *
6
- * Demonstrates the **custom `def.renderer` escape hatch** (see
7
- * plans/editor-node-registry.md): items use `useGLTF` from drei to
6
+ * Demonstrates the **custom `def.renderer` escape hatch** ("Opting out of a
7
+ * generic path" in wiki/architecture/node-definitions.md): items use `useGLTF` from drei to
8
8
  * load CDN assets, plus a non-trivial interactive-widget layer inside
9
9
  * the rendered scene. Not expressible as a pure `def.geometry`. The
10
10
  * registry mounts the custom React renderer as-is.
@@ -1 +1 @@
1
- {"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/item/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAA;AAOzB,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AA+HnC;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,cAAc,EAAE,cAAc,CAAC,OAAO,QAAQ,CAyL1D,CAAA"}
1
+ {"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/item/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,cAAc,EAGpB,MAAM,kBAAkB,CAAA;AAWzB,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AA+HnC;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,eAAO,MAAM,cAAc,EAAE,cAAc,CAAC,OAAO,QAAQ,CAqN1D,CAAA"}
@@ -1,9 +1,13 @@
1
- import { getScaledDimensions, } from '@pascal-app/core';
1
+ import { getEffectiveCutterNode, getScaledDimensions, resolveCutterHost, toggleMechanism, } from '@pascal-app/core';
2
+ import { itemHasLights, itemMechanism, toggleItemLights } from '../shared/item-interactions';
3
+ import { itemBatchable } from '../shared/node-batch/batchable';
2
4
  import { restingFloorplanAffectedIds } from '../shared/resting-surface-plan';
5
+ import { authoredItemFaceHost } from './authored-face-host';
3
6
  import { buildItemContextualDimensions, buildItemFloorplan } from './floorplan';
4
7
  import { itemFloorplanMoveTarget } from './floorplan-move';
5
8
  import { itemPaint } from './paint';
6
9
  import { itemParametrics } from './parametrics';
10
+ import { itemPlacementNotice } from './placement-notice';
7
11
  import { ItemNode } from './schema';
8
12
  // The two floor gizmos flank the item at mid-height so they never overlap,
9
13
  // even on small items: move sits past the left edge, rotate past the right
@@ -126,8 +130,8 @@ function itemWallMoveHandle() {
126
130
  /**
127
131
  * Item — Phase 5 batch kind. Catalog-backed, GLB-rendered, multi-host.
128
132
  *
129
- * Demonstrates the **custom `def.renderer` escape hatch** (see
130
- * plans/editor-node-registry.md): items use `useGLTF` from drei to
133
+ * Demonstrates the **custom `def.renderer` escape hatch** ("Opting out of a
134
+ * generic path" in wiki/architecture/node-definitions.md): items use `useGLTF` from drei to
131
135
  * load CDN assets, plus a non-trivial interactive-widget layer inside
132
136
  * the rendered scene. Not expressible as a pure `def.geometry`. The
133
137
  * registry mounts the custom React renderer as-is.
@@ -162,6 +166,7 @@ export const itemDefinition = {
162
166
  extensions: {
163
167
  'pascal:editor/floorplan': {
164
168
  contextualDimensions: buildItemContextualDimensions,
169
+ actionMenu: { actions: () => import('../shared/item-interaction-actions') },
165
170
  },
166
171
  },
167
172
  // Defaults shape is cast: the schema requires a fully-typed `asset`
@@ -188,7 +193,10 @@ export const itemDefinition = {
188
193
  },
189
194
  }),
190
195
  capabilities: {
196
+ batchable: itemBatchable,
191
197
  selectable: { hitVolume: 'bbox' },
198
+ // Authored objects host ceiling items on their undersides; catalog items do not.
199
+ faceHost: authoredItemFaceHost,
192
200
  surfaces: {
193
201
  top: {
194
202
  height: (node) => {
@@ -200,6 +208,7 @@ export const itemDefinition = {
200
208
  duplicable: { subtree: 'with-children' },
201
209
  deletable: true,
202
210
  paint: itemPaint,
211
+ mechanism: itemMechanism,
203
212
  // Items participate in compositions — e.g. "table-with-plants",
204
213
  // "shelf-with-books-on-top" — so they're presettable in their own
205
214
  // right (and as descendants of presettable parents). The GLB-kind
@@ -298,13 +307,33 @@ export const itemDefinition = {
298
307
  // Stage C: floor-plan polygon. ctx.resolve walks the parent chain
299
308
  // (wall / nested item / level) to compute the world-space transform.
300
309
  floorplan: buildItemFloorplan,
301
- floorplanAffectedIds: restingFloorplanAffectedIds,
310
+ floorplanAffectedIds: (args) => {
311
+ const ids = [...restingFloorplanAffectedIds(args)];
312
+ for (const node of [args.node, getEffectiveCutterNode(args.node)]) {
313
+ if (node.type !== 'item')
314
+ continue;
315
+ for (const cutter of node.source?.manifest.cutters ?? []) {
316
+ const host = resolveCutterHost(node, cutter.host === 'mounted' ? 'cutout' : `cut:${cutter.host}`, args.nodes);
317
+ if (host)
318
+ ids.push(host.id);
319
+ }
320
+ }
321
+ return ids;
322
+ },
302
323
  // 2D move-on-floorplan handler. Branches on `asset.attachTo`:
303
324
  // wall items snap to walls (like door / window), ceiling items
304
325
  // snap to ceiling polygons, floor items snap to slabs. attachTo
305
326
  // *transitions* (drop a wall item on a ceiling) remain canonical
306
327
  // in the 3D path; 2D only re-anchors within the same family.
307
328
  floorplanMoveTarget: itemFloorplanMoveTarget,
329
+ placementNotice: itemPlacementNotice,
330
+ keyboardActions: {
331
+ e: {
332
+ appliesTo: (node) => itemMechanism.has(node) || itemHasLights(node),
333
+ // Same as the action bar: mechanisms when the item has them, otherwise its light.
334
+ run: (node) => itemMechanism.has(node) ? toggleMechanism(itemMechanism, node) : toggleItemLights(node),
335
+ },
336
+ },
308
337
  toolHints: [
309
338
  { key: 'Left click', label: 'Place item' },
310
339
  { key: 'R / T', label: 'Rotate' },
@@ -19,7 +19,7 @@ type Transform = {
19
19
  y: number;
20
20
  rotation: number;
21
21
  };
22
- export declare function resolveItemTransform(item: ItemNode, ctx: GeometryContext, cache?: Map<`roof_${string}` | `rseg_${string}` | `site_${string}` | `building_${string}` | `level_${string}` | `elevator_${string}` | `unit_${string}` | `zone_${string}` | `block_${string}` | `ceiling_${string}` | `item_${string}` | `procedural-item_${string}` | `column_${string}` | `construction-dimension_${string}` | `wall_${string}` | `slab_${string}` | `fence_${string}` | `structural-grid_${string}` | `imesh_${string}` | `stair_${string}` | `scan_${string}` | `guide_${string}` | `measurement_${string}` | `spawn_${string}` | `shelf_${string}` | `duct-segment_${string}` | `duct-fitting_${string}` | `duct-terminal_${string}` | `hvac-equipment_${string}` | `lineset_${string}` | `liquid-line_${string}` | `pipe-segment_${string}` | `pipe-fitting_${string}` | `pipe-trap_${string}` | `leanto_${string}` | `door_${string}` | `window_${string}` | `cabinet_${string}` | `cabinet-module_${string}` | `sseg_${string}` | `bvent_${string}` | `rvent_${string}` | `tvent_${string}` | `cupola_${string}` | `eyebrow-vent_${string}` | `gutter_${string}` | `chimney_${string}` | `solarpanel_${string}` | `skylight_${string}` | `dormer_${string}` | `downspout_${string}`, Transform | null>): Transform | null;
22
+ export declare function resolveItemTransform(item: ItemNode, ctx: GeometryContext, cache?: Map<`roof_${string}` | `rseg_${string}` | `site_${string}` | `building_${string}` | `level_${string}` | `elevator_${string}` | `unit_${string}` | `zone_${string}` | `block_${string}` | `ceiling_${string}` | `item_${string}` | `procedural-item_${string}` | `column_${string}` | `construction-dimension_${string}` | `wall_${string}` | `slab_${string}` | `separator_${string}` | `floor-opening_${string}` | `fence_${string}` | `structural-grid_${string}` | `imesh_${string}` | `stair_${string}` | `scan_${string}` | `guide_${string}` | `measurement_${string}` | `spawn_${string}` | `shelf_${string}` | `duct-segment_${string}` | `duct-fitting_${string}` | `duct-terminal_${string}` | `hvac-equipment_${string}` | `lineset_${string}` | `liquid-line_${string}` | `pipe-segment_${string}` | `pipe-fitting_${string}` | `pipe-trap_${string}` | `leanto_${string}` | `door_${string}` | `window_${string}` | `fence-gate_${string}` | `fence-opening_${string}` | `cabinet_${string}` | `cabinet-module_${string}` | `sseg_${string}` | `bvent_${string}` | `rvent_${string}` | `tvent_${string}` | `cupola_${string}` | `eyebrow-vent_${string}` | `gutter_${string}` | `chimney_${string}` | `solarpanel_${string}` | `skylight_${string}` | `dormer_${string}` | `downspout_${string}`, Transform | null>): Transform | null;
23
23
  export declare function buildItemContextualDimensions(node: ItemNode, ctx: GeometryContext): FloorplanGeometry | null;
24
24
  export declare function buildItemFloorplan(node: ItemNode, ctx: GeometryContext): FloorplanGeometry | null;
25
25
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"floorplan.d.ts","sourceRoot":"","sources":["../../src/item/floorplan.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,iBAAiB,EAEtB,KAAK,eAAe,EAKpB,KAAK,QAAQ,EAId,MAAM,kBAAkB,CAAA;AAIzB;;;;;;;;;;;;;;GAcG;AACH,KAAK,SAAS,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAA;AA2D3D,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,QAAQ,EACd,GAAG,EAAE,eAAe,EACpB,KAAK,0pCAAyC,GAC7C,SAAS,GAAG,IAAI,CAwKlB;AAED,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,QAAQ,EACd,GAAG,EAAE,eAAe,GACnB,iBAAiB,GAAG,IAAI,CA+C1B;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,eAAe,GAAG,iBAAiB,GAAG,IAAI,CAmGjG"}
1
+ {"version":3,"file":"floorplan.d.ts","sourceRoot":"","sources":["../../src/item/floorplan.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,iBAAiB,EAEtB,KAAK,eAAe,EAOpB,KAAK,QAAQ,EAKd,MAAM,kBAAkB,CAAA;AASzB;;;;;;;;;;;;;;GAcG;AACH,KAAK,SAAS,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAA;AA2D3D,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,QAAQ,EACd,GAAG,EAAE,eAAe,EACpB,KAAK,mwCAAyC,GAC7C,SAAS,GAAG,IAAI,CAyKlB;AAED,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,QAAQ,EACd,GAAG,EAAE,eAAe,GACnB,iBAAiB,GAAG,IAAI,CA+C1B;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,eAAe,GAAG,iBAAiB,GAAG,IAAI,CA+HjG"}
@@ -1,6 +1,7 @@
1
- import { getBlockFaceFrame, getEffectiveNode, getRoofWallFaceFrame, getScaledDimensions, roofFacePointToSegment, useLiveTransforms, } from '@pascal-app/core';
2
- import { formatLinearMeasurement, readFloorplanMetricNotationOverride } from '@pascal-app/editor';
1
+ import { getBlockFaceFrame, getEffectiveNode, getRoofWallFaceFrame, getScaledDimensions, getWallBodyCenterOffset, getWallLocalFaceZ, roofFacePointToSegment, scriptImages, useLiveTransforms, } from '@pascal-app/core';
2
+ import { formatLinearMeasurement, readFloorplanContext, readFloorplanMetricNotationOverride, } from '@pascal-app/editor';
3
3
  import { restingNodePlanFrame } from '../shared/resting-surface-plan';
4
+ import { buildPlanItemSymbol, classifyPlanItem, PLAN_SYMBOL_METADATA_KEY } from './plan-symbols';
4
5
  // Plan-space rotation convention used by the legacy `rotatePlanVector`
5
6
  // in `editor/src/lib/floorplan/geometry.ts`. This is a CLOCKWISE rotation
6
7
  // — the registry-side equivalent of the canonical floor-plan transform
@@ -74,8 +75,9 @@ export function resolveItemTransform(item, ctx, cache = new Map()) {
74
75
  const wall = parentNode;
75
76
  const wallRotation = -Math.atan2(wall.end[1] - wall.start[1], wall.end[0] - wall.start[0]);
76
77
  const wallLocalZ = item.asset.attachTo === 'wall-side'
77
- ? ((wall.thickness ?? 0.1) / 2) * (item.side === 'front' ? 1 : -1)
78
- : item.position[2];
78
+ ? getWallLocalFaceZ(parentNode, item.side === 'front' ? 'a' : 'b')
79
+ : item.position[2] +
80
+ (item.asset.attachTo === 'wall' ? getWallBodyCenterOffset(parentNode) : 0);
79
81
  const [offsetX, offsetY] = rotateVec(item.position[0], wallLocalZ, wallRotation);
80
82
  result = {
81
83
  x: wall.start[0] + offsetX,
@@ -273,13 +275,41 @@ export function buildItemFloorplan(node, ctx) {
273
275
  const [rx, ry] = rotateVec(x, y, transform.rotation);
274
276
  return [cx + rx, cy + ry];
275
277
  });
278
+ // A sheet (drafting) draws the permit-set symbol — fixtures as labelled
279
+ // linework, furniture as a light outline — never the sprite or the
280
+ // editor's amber footprint. Ceiling items and decor draw nothing.
281
+ if (readFloorplanContext(ctx).drafting) {
282
+ const planClass = classifyPlanItem(node.asset);
283
+ const symbol = buildPlanItemSymbol(planClass, {
284
+ map: (x, y) => {
285
+ const [rx, ry] = rotateVec(x, y, transform.rotation);
286
+ return [cx + rx, cy + ry];
287
+ },
288
+ width,
289
+ depth,
290
+ });
291
+ // the sheet lays its tags out around fixtures and (more loosely)
292
+ // furniture; the mark rides on the outline itself, which the sheet's
293
+ // model / annotation split passes through untouched (it rebuilds groups)
294
+ const [outline, ...rest] = symbol;
295
+ if (!outline)
296
+ return null;
297
+ const marked = {
298
+ ...outline,
299
+ metadata: {
300
+ ...outline.metadata,
301
+ [PLAN_SYMBOL_METADATA_KEY]: planClass.kind,
302
+ },
303
+ };
304
+ return { kind: 'group', children: [marked, ...rest] };
305
+ }
276
306
  const isSelected = ctx.viewState?.selected ?? false;
277
307
  // Marquee preview — the about-to-be-selected tint every other kind shows.
278
308
  const isHighlighted = ctx.viewState?.highlighted ?? false;
279
309
  const showSelection = isSelected || isHighlighted;
280
310
  const isMoving = ctx.viewState?.moving ?? false;
281
311
  const selectedStroke = ctx.viewState?.palette?.selectedStroke ?? '#3b82f6';
282
- const floorPlanUrl = node.asset.floorPlanUrl;
312
+ const floorPlanUrl = scriptImages(node)?.floorPlan ?? node.asset.floorPlanUrl;
283
313
  const children = [
284
314
  {
285
315
  kind: 'polygon',
@@ -1,3 +1,4 @@
1
1
  export { itemDefinition } from './definition';
2
+ export { getPendingItemModelLoadCount } from './model-loader';
2
3
  export { ItemNode } from './schema';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/item/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/item/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,4BAA4B,EAAE,MAAM,gBAAgB,CAAA;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA"}
@@ -1,2 +1,3 @@
1
1
  export { itemDefinition } from './definition';
2
+ export { getPendingItemModelLoadCount } from './model-loader';
2
3
  export { ItemNode } from './schema';
@@ -1,5 +1,7 @@
1
1
  import { LoadingManager } from 'three';
2
2
  import { type GLTF, GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
3
+ /** Active item transactions on this host manager, including their retry waits. */
4
+ export declare function getPendingItemModelLoadCount(manager?: LoadingManager): number;
3
5
  export type ItemAssetUnavailable = {
4
6
  message: string;
5
7
  url: string;
@@ -1 +1 @@
1
- {"version":3,"file":"model-loader.d.ts","sourceRoot":"","sources":["../../src/item/model-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgC,cAAc,EAAE,MAAM,OAAO,CAAA;AACpE,OAAO,EAAE,KAAK,IAAI,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAA;AAUhF,MAAM,MAAM,oBAAoB,GAAG;IACjC,OAAO,EAAE,MAAM,CAAA;IACf,GAAG,EAAE,MAAM,CAAA;CACZ,CAAA;AAED,MAAM,MAAM,wBAAwB,GAAG,WAAW,GAAG,aAAa,GAAG,YAAY,CAAA;AAEjF,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,wBAAwB,CAgBrF;AAED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAiB3E;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,IAAI,GAAG,oBAAoB,GAAG,IAAI,CAO/E;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,QAE9C;AAED,qBAAa,cAAe,SAAQ,UAAU;IAC5C,QAAQ,CAAC,WAAW,EAAE,cAAc,CAAA;IACpC,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAA;gBAE7B,OAAO,CAAC,EAAE,cAAc,EAAE,aAAa,wBAA0B;IAMpE,IAAI,CACX,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,EAC5B,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,EAC3C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GACjC,IAAI;CAwER"}
1
+ {"version":3,"file":"model-loader.d.ts","sourceRoot":"","sources":["../../src/item/model-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgC,cAAc,EAAE,MAAM,OAAO,CAAA;AAEpE,OAAO,EAAE,KAAK,IAAI,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAA;AAOhF,kFAAkF;AAClF,wBAAgB,4BAA4B,CAAC,OAAO,iBAAwB,GAAG,MAAM,CAEpF;AAMD,MAAM,MAAM,oBAAoB,GAAG;IACjC,OAAO,EAAE,MAAM,CAAA;IACf,GAAG,EAAE,MAAM,CAAA;CACZ,CAAA;AAED,MAAM,MAAM,wBAAwB,GAAG,WAAW,GAAG,aAAa,GAAG,YAAY,CAAA;AAEjF,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,wBAAwB,CAgBrF;AAED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAiB3E;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,IAAI,GAAG,oBAAoB,GAAG,IAAI,CAO/E;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,QAE9C;AAED,qBAAa,cAAe,SAAQ,UAAU;IAC5C,QAAQ,CAAC,WAAW,EAAE,cAAc,CAAA;IACpC,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAA;gBAE7B,OAAO,CAAC,EAAE,cAAc,EAAE,aAAa,wBAA0B;IAOpE,IAAI,CACX,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,EAC5B,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,EAC3C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GACjC,IAAI;CA+FR"}
@@ -1,8 +1,14 @@
1
1
  import { DefaultLoadingManager, Group, LoadingManager } from 'three';
2
+ import { MeshoptDecoder } from 'three/examples/jsm/libs/meshopt_decoder.module.js';
2
3
  import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
3
4
  const ITEM_ASSET_UNAVAILABLE_KEY = 'pascalItemAssetUnavailable';
4
5
  const DEFAULT_RETRY_DELAYS_MS = [1_000, 3_000];
5
6
  const itemLoadGenerations = new Map();
7
+ const pendingItemModelLoads = new WeakMap();
8
+ /** Active item transactions on this host manager, including their retry waits. */
9
+ export function getPendingItemModelLoadCount(manager = DefaultLoadingManager) {
10
+ return pendingItemModelLoads.get(manager) ?? 0;
11
+ }
6
12
  export function classifyItemModelLoadFailure(error) {
7
13
  if (!(error instanceof Error))
8
14
  return 'unexpected';
@@ -53,6 +59,7 @@ export class ItemGLTFLoader extends GLTFLoader {
53
59
  retryDelaysMs;
54
60
  constructor(manager, retryDelaysMs = DEFAULT_RETRY_DELAYS_MS) {
55
61
  super(new LoadingManager());
62
+ this.setMeshoptDecoder(MeshoptDecoder);
56
63
  this.hostManager = manager ?? DefaultLoadingManager;
57
64
  this.retryDelaysMs = retryDelaysMs;
58
65
  }
@@ -61,11 +68,15 @@ export class ItemGLTFLoader extends GLTFLoader {
61
68
  let retryCount = 0;
62
69
  let finished = false;
63
70
  const wasCancelled = () => (itemLoadGenerations.get(url) ?? 0) !== generation;
71
+ const end = () => {
72
+ pendingItemModelLoads.set(this.hostManager, getPendingItemModelLoadCount(this.hostManager) - 1);
73
+ this.hostManager.itemEnd(url);
74
+ };
64
75
  const cancel = () => {
65
76
  if (finished)
66
77
  return;
67
78
  finished = true;
68
- this.hostManager.itemEnd(url);
79
+ end();
69
80
  };
70
81
  const complete = (gltf) => {
71
82
  if (finished)
@@ -79,7 +90,7 @@ export class ItemGLTFLoader extends GLTFLoader {
79
90
  onLoad(gltf);
80
91
  }
81
92
  finally {
82
- this.hostManager.itemEnd(url);
93
+ end();
83
94
  }
84
95
  };
85
96
  const fail = (error) => {
@@ -97,8 +108,12 @@ export class ItemGLTFLoader extends GLTFLoader {
97
108
  console.error(error);
98
109
  }
99
110
  finally {
100
- this.hostManager.itemError(url);
101
- this.hostManager.itemEnd(url);
111
+ try {
112
+ this.hostManager.itemError(url);
113
+ }
114
+ finally {
115
+ end();
116
+ }
102
117
  }
103
118
  };
104
119
  const attempt = () => {
@@ -106,26 +121,43 @@ export class ItemGLTFLoader extends GLTFLoader {
106
121
  cancel();
107
122
  return;
108
123
  }
109
- super.load(url, complete, onProgress, (error) => {
110
- if (wasCancelled()) {
111
- cancel();
112
- return;
113
- }
114
- const kind = classifyItemModelLoadFailure(error);
115
- if (kind === 'unexpected') {
116
- fail(error);
117
- return;
118
- }
119
- if (kind === 'unavailable' || retryCount >= this.retryDelaysMs.length) {
120
- complete(createUnavailableItemGltf(url, error));
121
- return;
122
- }
123
- const delay = this.retryDelaysMs[retryCount] ?? 0;
124
- retryCount += 1;
125
- setTimeout(attempt, delay);
126
- });
124
+ try {
125
+ super.load(url, complete, onProgress, (error) => {
126
+ if (finished)
127
+ return;
128
+ if (wasCancelled()) {
129
+ cancel();
130
+ return;
131
+ }
132
+ const kind = classifyItemModelLoadFailure(error);
133
+ if (kind === 'unexpected') {
134
+ fail(error);
135
+ return;
136
+ }
137
+ if (kind === 'unavailable' || retryCount >= this.retryDelaysMs.length) {
138
+ complete(createUnavailableItemGltf(url, error));
139
+ return;
140
+ }
141
+ const delay = this.retryDelaysMs[retryCount] ?? 0;
142
+ retryCount += 1;
143
+ setTimeout(attempt, delay);
144
+ });
145
+ }
146
+ catch (error) {
147
+ if (finished)
148
+ throw error;
149
+ fail(error);
150
+ }
127
151
  };
128
- this.hostManager.itemStart(url);
152
+ pendingItemModelLoads.set(this.hostManager, getPendingItemModelLoadCount(this.hostManager) + 1);
153
+ try {
154
+ this.hostManager.itemStart(url);
155
+ }
156
+ catch (error) {
157
+ finished = true;
158
+ end();
159
+ throw error;
160
+ }
129
161
  attempt();
130
162
  }
131
163
  }
@@ -124,9 +124,9 @@ export function MoveItemTool({ node: source }) {
124
124
  const cursor = usePlacementCoordinator({
125
125
  asset: node.asset,
126
126
  draftNode,
127
- // Carry painted slot overrides onto the duplicate's draft (wall/ceiling
128
- // items create their draft lazily inside the coordinator).
129
- slots: node.slots,
127
+ // The duplicate's draft keeps the item's painted slots and collections
128
+ // (wall/ceiling items create their draft lazily inside the coordinator).
129
+ copied: node,
130
130
  // Duplicates start fresh in floor mode; wall/ceiling draft is created lazily by ensureDraft.
131
131
  initialState: isNew && !isSceneDraft
132
132
  ? {
@@ -147,7 +147,7 @@ export function MoveItemTool({ node: source }) {
147
147
  // items are created lazily on surface entry.
148
148
  gridPosition.copy(new Vector3(...node.position));
149
149
  if (!node.asset.attachTo) {
150
- draftNode.create(gridPosition, node.asset, node.rotation, node.scale, node.slots);
150
+ draftNode.create(gridPosition, node.asset, node.rotation, node.scale, node);
151
151
  }
152
152
  }
153
153
  else {
@@ -1 +1 @@
1
- {"version":3,"file":"paint.d.ts","sourceRoot":"","sources":["../../src/item/paint.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,eAAe,EAMrB,MAAM,kBAAkB,CAAA;AA+NzB,eAAO,MAAM,SAAS,EAAE,eAoBvB,CAAA"}
1
+ {"version":3,"file":"paint.d.ts","sourceRoot":"","sources":["../../src/item/paint.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,eAAe,EAOrB,MAAM,kBAAkB,CAAA;AAwNzB,eAAO,MAAM,SAAS,EAAE,eAWvB,CAAA"}
@@ -1,5 +1,6 @@
1
- import { generateSceneMaterialId, parseMaterialRef, toSceneMaterialRef, useScene, } from '@pascal-app/core';
1
+ import { generateSceneMaterialId, parseMaterialRef, slotPaintMaterial, toSceneMaterialRef, useScene, } from '@pascal-app/core';
2
2
  import { createMaterial, createMaterialFromPresetRef, useViewer } from '@pascal-app/viewer';
3
+ import { swapPreviewMaterial } from '../shared/swap-preview-material';
3
4
  function deepEqual(a, b) {
4
5
  if (Object.is(a, b))
5
6
  return true;
@@ -159,7 +160,6 @@ function applyItemPreview(role, root, material, materialPreset) {
159
160
  if (Array.isArray(tag)) {
160
161
  const current = mesh.material;
161
162
  if (Array.isArray(current)) {
162
- const previousArray = [...current];
163
163
  const nextArray = [...current];
164
164
  let changed = false;
165
165
  for (let index = 0; index < tag.length; index += 1) {
@@ -170,20 +170,13 @@ function applyItemPreview(role, root, material, materialPreset) {
170
170
  }
171
171
  if (!changed)
172
172
  return;
173
- mesh.material = nextArray;
174
- restores.push(() => {
175
- mesh.material = previousArray;
176
- });
173
+ restores.push(swapPreviewMaterial(mesh, nextArray));
177
174
  return;
178
175
  }
179
176
  if (tag[0] !== role)
180
177
  return;
181
178
  }
182
- const previous = mesh.material;
183
- mesh.material = previewMaterial;
184
- restores.push(() => {
185
- mesh.material = previous;
186
- });
179
+ restores.push(swapPreviewMaterial(mesh, previewMaterial));
187
180
  });
188
181
  if (restores.length === 0)
189
182
  return null;
@@ -198,17 +191,5 @@ export const itemPaint = {
198
191
  buildPatch: ({ node, role, material, materialPreset }) => buildItemSlotsPatch(node, role, material, materialPreset),
199
192
  commit: ({ node, role, material, materialPreset }) => commitItemPaint(node, role, material, materialPreset),
200
193
  applyPreview: ({ role, root, material, materialPreset }) => applyItemPreview(role, root, material, materialPreset),
201
- getEffectiveMaterial: ({ node, role }) => {
202
- const ref = node.slots?.[role];
203
- const parsed = parseMaterialRef(ref);
204
- if (!parsed)
205
- return null;
206
- if (parsed.kind === 'library') {
207
- return { material: undefined, materialPreset: ref };
208
- }
209
- const sceneMaterial = useScene.getState().materials[parsed.id];
210
- if (!sceneMaterial)
211
- return null;
212
- return { material: sceneMaterial.material, materialPreset: undefined };
213
- },
194
+ getEffectiveMaterial: ({ node, role }) => slotPaintMaterial(node.slots?.[role], useScene.getState().materials),
214
195
  };