@pascal-app/editor 0.9.1 → 1.0.0-beta.1

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 (366) hide show
  1. package/package.json +14 -9
  2. package/src/components/editor/alignment-3d-guide-layer.tsx +10 -2
  3. package/src/components/editor/bake-exporter.tsx +49 -0
  4. package/src/components/editor/bake-thumbnail.tsx +95 -0
  5. package/src/components/editor/camera-dragging-lifecycle.test.ts +49 -0
  6. package/src/components/editor/camera-dragging-lifecycle.ts +41 -0
  7. package/src/components/editor/custom-camera-controls.tsx +332 -199
  8. package/src/components/editor/delete-confirmation-dialog.tsx +54 -0
  9. package/src/components/editor/editor-layout-mobile.tsx +5 -0
  10. package/src/components/editor/editor-layout-v2.tsx +18 -0
  11. package/src/components/editor/elevation-3d-guide-layer.tsx +120 -0
  12. package/src/components/editor/export-manager.tsx +71 -63
  13. package/src/components/editor/fence-tangent-lines-3d.tsx +87 -0
  14. package/src/components/editor/first-person/build-collider-world.test.ts +102 -5
  15. package/src/components/editor/first-person/build-collider-world.ts +52 -5
  16. package/src/components/editor/first-person/terrain-collider.test.ts +132 -0
  17. package/src/components/editor/first-person/terrain-collider.ts +212 -0
  18. package/src/components/editor/first-person-controls.tsx +410 -136
  19. package/src/components/editor/floating-action-menu.tsx +435 -64
  20. package/src/components/editor/floating-building-action-menu.tsx +1 -1
  21. package/src/components/editor/floorplan-background-selection.test.ts +72 -0
  22. package/src/components/editor/floorplan-background-selection.ts +7 -20
  23. package/src/components/editor/floorplan-camera-sync.test.ts +249 -0
  24. package/src/components/editor/floorplan-camera-sync.ts +213 -0
  25. package/src/components/editor/floorplan-mode-coordinator.tsx +82 -0
  26. package/src/components/editor/floorplan-navigation-presentation.test.ts +142 -0
  27. package/src/components/editor/floorplan-navigation-presentation.ts +156 -0
  28. package/src/components/editor/floorplan-panel.tsx +2517 -1492
  29. package/src/components/editor/grid.tsx +166 -39
  30. package/src/components/editor/group-actions.ts +597 -0
  31. package/src/components/editor/group-floating-action-menu.tsx +130 -0
  32. package/src/components/editor/group-move-3d.ts +397 -0
  33. package/src/components/editor/group-rotate-handle.tsx +102 -64
  34. package/src/components/editor/group-selection-box-3d.tsx +173 -0
  35. package/src/components/editor/group-transform-shared.test.ts +192 -1
  36. package/src/components/editor/group-transform-shared.ts +240 -7
  37. package/src/components/editor/handles/handle-arrow.tsx +81 -23
  38. package/src/components/editor/handles/handle-drag-history.test.ts +96 -0
  39. package/src/components/editor/handles/handle-drag-history.ts +14 -0
  40. package/src/components/editor/handles/preview-overrides.test.ts +26 -0
  41. package/src/components/editor/handles/preview-overrides.ts +13 -0
  42. package/src/components/editor/handles/resize-snap.test.ts +52 -0
  43. package/src/components/editor/handles/resize-snap.ts +23 -0
  44. package/src/components/editor/handles/use-handle-drag.ts +49 -6
  45. package/src/components/editor/index.tsx +289 -35
  46. package/src/components/editor/measurement-pill.tsx +68 -23
  47. package/src/components/editor/node-action-menu.tsx +14 -1
  48. package/src/components/editor/node-arrow-handles.tsx +409 -180
  49. package/src/components/editor/opening-guides-3d-layer.tsx +144 -0
  50. package/src/components/editor/quick-measurement-card.tsx +76 -0
  51. package/src/components/editor/quick-measurement-hud.tsx +34 -0
  52. package/src/components/editor/riser-diagram-panel.tsx +137 -0
  53. package/src/components/editor/selection-manager.tsx +814 -466
  54. package/src/components/editor/site-edge-labels.tsx +28 -6
  55. package/src/components/editor/slab-hole-highlights.tsx +13 -5
  56. package/src/components/editor/snapshot-capture-overlay.tsx +258 -115
  57. package/src/components/editor/three-context-bridge.ts +22 -0
  58. package/src/components/editor/thumbnail-generator.tsx +118 -253
  59. package/src/components/editor/use-floorplan-background-placement.ts +113 -45
  60. package/src/components/editor/use-floorplan-hit-testing.test.ts +82 -0
  61. package/src/components/editor/use-floorplan-hit-testing.ts +144 -161
  62. package/src/components/editor/use-floorplan-scene-data.ts +5 -5
  63. package/src/components/editor/use-mesh-settle-epoch.ts +27 -0
  64. package/src/components/editor/wall-measurement-label.tsx +10 -28
  65. package/src/components/editor/wall-move-side-handles.tsx +229 -39
  66. package/src/components/editor/wall-opening-highlights.tsx +63 -32
  67. package/src/components/editor/wall-snap-beacon-layer.tsx +162 -6
  68. package/src/components/editor-2d/floorplan-action-menu-layer.tsx +9 -5
  69. package/src/components/editor-2d/floorplan-alignment-guide-layer.tsx +2 -1
  70. package/src/components/editor-2d/floorplan-cursor-indicator-overlay.tsx +40 -9
  71. package/src/components/editor-2d/floorplan-cursor-indicator-position.test.ts +31 -0
  72. package/src/components/editor-2d/floorplan-cursor-indicator-position.ts +39 -0
  73. package/src/components/editor-2d/floorplan-group-action-menu.tsx +87 -0
  74. package/src/components/editor-2d/floorplan-group-move.tsx +744 -0
  75. package/src/components/editor-2d/floorplan-measurement-tool-layer.test.ts +113 -0
  76. package/src/components/editor-2d/floorplan-measurement-tool-layer.tsx +1672 -0
  77. package/src/components/editor-2d/floorplan-quick-measure-layer.tsx +212 -0
  78. package/src/components/editor-2d/floorplan-registered-tool-layer.tsx +72 -0
  79. package/src/components/editor-2d/floorplan-registry-action-menu.tsx +219 -20
  80. package/src/components/editor-2d/floorplan-registry-move-overlay.tsx +327 -59
  81. package/src/components/editor-2d/floorplan-render-context.test.ts +27 -0
  82. package/src/components/editor-2d/floorplan-render-context.tsx +113 -8
  83. package/src/components/editor-2d/floorplan-snap-beacon-layer.tsx +5 -3
  84. package/src/components/editor-2d/renderers/floorplan-annotation-layout.test.ts +285 -0
  85. package/src/components/editor-2d/renderers/floorplan-annotation-layout.ts +516 -0
  86. package/src/components/editor-2d/renderers/floorplan-dimension-renderer.test.tsx +236 -0
  87. package/src/components/editor-2d/renderers/floorplan-dimension-renderer.tsx +618 -0
  88. package/src/components/editor-2d/renderers/floorplan-geometry-renderer.test.tsx +369 -0
  89. package/src/components/editor-2d/renderers/floorplan-geometry-renderer.tsx +431 -32
  90. package/src/components/editor-2d/renderers/floorplan-label-angle.test.ts +89 -0
  91. package/src/components/editor-2d/renderers/floorplan-label-angle.ts +106 -0
  92. package/src/components/editor-2d/renderers/floorplan-placement-preview-layer.tsx +94 -26
  93. package/src/components/editor-2d/renderers/floorplan-registry-layer.test.ts +587 -0
  94. package/src/components/editor-2d/renderers/floorplan-registry-layer.tsx +2280 -578
  95. package/src/components/editor-2d/renderers/floorplan-stair-layer.tsx +20 -10
  96. package/src/components/editor-2d/renderers/floorplan-voronoi-layer.tsx +128 -0
  97. package/src/components/systems/ceiling/ceiling-selection-affordance-system.tsx +425 -61
  98. package/src/components/systems/ceiling/ceiling-system.tsx +97 -4
  99. package/src/components/systems/roof/roof-edit-system.tsx +1768 -13
  100. package/src/components/systems/selection-affordance-manager.tsx +38 -0
  101. package/src/components/systems/zone/zone-label-editor-system.tsx +14 -1
  102. package/src/components/systems/zone/zone-system.tsx +42 -13
  103. package/src/components/tools/elevator/elevator-tool.tsx +34 -8
  104. package/src/components/tools/elevator/move-elevator-tool.tsx +13 -2
  105. package/src/components/tools/fence/fence-drafting.ts +107 -8
  106. package/src/components/tools/item/move-tool.tsx +17 -13
  107. package/src/components/tools/item/placement-math.test.ts +13 -1
  108. package/src/components/tools/item/placement-math.ts +28 -2
  109. package/src/components/tools/item/placement-strategies.ts +246 -5
  110. package/src/components/tools/item/placement-types.ts +13 -1
  111. package/src/components/tools/item/use-draft-node.ts +146 -57
  112. package/src/components/tools/item/use-placement-coordinator.tsx +813 -125
  113. package/src/components/tools/registry/move-registry-node-tool.tsx +636 -103
  114. package/src/components/tools/roof/roof-tool.tsx +336 -94
  115. package/src/components/tools/select/box-select-state.ts +18 -7
  116. package/src/components/tools/select/box-select-tool.tsx +176 -40
  117. package/src/components/tools/select/marquee-geometry.test.ts +161 -0
  118. package/src/components/tools/select/marquee-geometry.ts +155 -0
  119. package/src/components/tools/select/plane-box-select-tool.tsx +1 -8
  120. package/src/components/tools/select/select-candidates.ts +1 -1
  121. package/src/components/tools/shared/cursor-sphere.tsx +62 -26
  122. package/src/components/tools/shared/drag-bounding-box.tsx +28 -4
  123. package/src/components/tools/shared/facing-indicator.tsx +87 -0
  124. package/src/components/tools/shared/facing-pose-indicator.tsx +54 -0
  125. package/src/components/tools/shared/floor-stack-preview.ts +4 -0
  126. package/src/components/tools/shared/horizontal-construction-plane.ts +123 -0
  127. package/src/components/tools/shared/placement-box.tsx +183 -1
  128. package/src/components/tools/shared/pointer-support-cap.test.ts +98 -0
  129. package/src/components/tools/shared/pointer-support-cap.ts +273 -0
  130. package/src/components/tools/shared/polygon-editor.tsx +276 -35
  131. package/src/components/tools/site/site-boundary-editor.tsx +101 -42
  132. package/src/components/tools/site/stroke-pointer-ownership.test.ts +91 -0
  133. package/src/components/tools/site/stroke-pointer-ownership.ts +57 -0
  134. package/src/components/tools/site/terrain-brush-cursor.tsx +247 -0
  135. package/src/components/tools/site/terrain-sculpt-grid.tsx +192 -0
  136. package/src/components/tools/site/terrain-sculpt-tool.tsx +356 -0
  137. package/src/components/tools/stair/stair-click-guard.test.ts +58 -0
  138. package/src/components/tools/stair/stair-click-guard.ts +72 -0
  139. package/src/components/tools/stair/stair-defaults.ts +1 -0
  140. package/src/components/tools/stair/stair-tool.tsx +164 -42
  141. package/src/components/tools/tool-manager.tsx +149 -30
  142. package/src/components/tools/wall/wall-drafting.test.ts +447 -0
  143. package/src/components/tools/wall/wall-drafting.ts +304 -108
  144. package/src/components/tools/wall/wall-snap-geometry.test.ts +52 -0
  145. package/src/components/tools/wall/wall-snap-geometry.ts +137 -9
  146. package/src/components/tools/zone/zone-boundary-editor.tsx +5 -1
  147. package/src/components/tools/zone/zone-tool.tsx +98 -88
  148. package/src/components/ui/action-menu/camera-actions.tsx +24 -17
  149. package/src/components/ui/action-menu/control-modes.tsx +44 -94
  150. package/src/components/ui/action-menu/furnish-tools.tsx +5 -5
  151. package/src/components/ui/action-menu/index.tsx +2 -4
  152. package/src/components/ui/action-menu/measurement-control.tsx +267 -0
  153. package/src/components/ui/action-menu/structure-tools.tsx +22 -13
  154. package/src/components/ui/action-menu/view-toggles.tsx +42 -90
  155. package/src/components/ui/command-palette/editor-commands.tsx +16 -3
  156. package/src/components/ui/command-palette/index.tsx +4 -3
  157. package/src/components/ui/controls/material-paint-panel.tsx +93 -18
  158. package/src/components/ui/controls/material-picker.tsx +162 -152
  159. package/src/components/ui/controls/material-properties-editor.tsx +108 -0
  160. package/src/components/ui/controls/metric-control.tsx +118 -44
  161. package/src/components/ui/controls/scene-material-list.tsx +247 -0
  162. package/src/components/ui/controls/slider-control.tsx +88 -38
  163. package/src/components/ui/controls/terrain-sculpt-panel.tsx +193 -0
  164. package/src/components/ui/floating-level-selector.tsx +74 -20
  165. package/src/components/ui/helpers/building-helper.tsx +10 -23
  166. package/src/components/ui/helpers/contextual-helper-panel.tsx +428 -0
  167. package/src/components/ui/helpers/helper-manager.tsx +273 -14
  168. package/src/components/ui/helpers/item-helper.tsx +28 -32
  169. package/src/components/ui/helpers/registered-tool-helper.tsx +45 -11
  170. package/src/components/ui/helpers/roof-helper.tsx +10 -12
  171. package/src/components/ui/icon-ref.tsx +47 -0
  172. package/src/components/ui/item-catalog/catalog-items.tsx +39 -1
  173. package/src/components/ui/item-catalog/item-catalog.tsx +13 -36
  174. package/src/components/ui/level-duplicate-dialog.tsx +1 -1
  175. package/src/components/ui/panels/multi-selection-panel.tsx +57 -0
  176. package/src/components/ui/panels/node-display.ts +17 -17
  177. package/src/components/ui/panels/panel-manager.tsx +36 -14
  178. package/src/components/ui/panels/panel-wrapper.tsx +24 -3
  179. package/src/components/ui/panels/parametric-inspector.tsx +19 -4
  180. package/src/components/ui/panels/reference-panel.tsx +54 -19
  181. package/src/components/ui/panels/selection-breakdown.test.ts +24 -0
  182. package/src/components/ui/panels/selection-breakdown.ts +20 -0
  183. package/src/components/ui/primitives/shortcut-token.tsx +39 -3
  184. package/src/components/ui/primitives/sidebar.tsx +1 -0
  185. package/src/components/ui/sidebar/app-sidebar.tsx +5 -1
  186. package/src/components/ui/sidebar/icon-rail.tsx +50 -31
  187. package/src/components/ui/sidebar/panels/plugins-panel.tsx +218 -0
  188. package/src/components/ui/sidebar/panels/settings-panel/index.tsx +82 -41
  189. package/src/components/ui/sidebar/panels/settings-panel/keyboard-shortcuts-dialog.tsx +76 -6
  190. package/src/components/ui/sidebar/panels/settings-panel/load-build-dialog.tsx +12 -4
  191. package/src/components/ui/sidebar/panels/site-panel/building-tree-node.tsx +2 -1
  192. package/src/components/ui/sidebar/panels/site-panel/ceiling-tree-node.tsx +4 -3
  193. package/src/components/ui/sidebar/panels/site-panel/chimney-tree-node.tsx +10 -7
  194. package/src/components/ui/sidebar/panels/site-panel/column-tree-node.tsx +1 -1
  195. package/src/components/ui/sidebar/panels/site-panel/door-tree-node.tsx +7 -2
  196. package/src/components/ui/sidebar/panels/site-panel/dormer-tree-node.tsx +10 -7
  197. package/src/components/ui/sidebar/panels/site-panel/elevator-tree-node.tsx +1 -1
  198. package/src/components/ui/sidebar/panels/site-panel/fence-tree-node.tsx +1 -1
  199. package/src/components/ui/sidebar/panels/site-panel/gutter-tree-node.tsx +10 -7
  200. package/src/components/ui/sidebar/panels/site-panel/index.tsx +42 -17
  201. package/src/components/ui/sidebar/panels/site-panel/item-tree-node.tsx +31 -17
  202. package/src/components/ui/sidebar/panels/site-panel/level-tree-node.tsx +1 -1
  203. package/src/components/ui/sidebar/panels/site-panel/registry-tree-node.tsx +72 -25
  204. package/src/components/ui/sidebar/panels/site-panel/roof-tree-node.tsx +7 -3
  205. package/src/components/ui/sidebar/panels/site-panel/shelf-tree-node.tsx +12 -8
  206. package/src/components/ui/sidebar/panels/site-panel/slab-tree-node.tsx +4 -3
  207. package/src/components/ui/sidebar/panels/site-panel/solar-panel-tree-node.tsx +10 -7
  208. package/src/components/ui/sidebar/panels/site-panel/spawn-tree-node.tsx +1 -1
  209. package/src/components/ui/sidebar/panels/site-panel/stair-tree-node.tsx +2 -2
  210. package/src/components/ui/sidebar/panels/site-panel/tree-node.tsx +44 -3
  211. package/src/components/ui/sidebar/panels/site-panel/tree-structure.ts +36 -0
  212. package/src/components/ui/sidebar/panels/site-panel/wall-tree-node.tsx +1 -1
  213. package/src/components/ui/sidebar/panels/site-panel/window-tree-node.tsx +7 -2
  214. package/src/components/ui/sidebar/panels/site-panel/zone-tree-node.tsx +3 -3
  215. package/src/components/ui/sidebar/tab-bar.tsx +42 -28
  216. package/src/components/ui/sidebar/use-plugin-panels.tsx +132 -0
  217. package/src/components/ui/snap-target-badge.test.tsx +40 -0
  218. package/src/components/ui/snap-target-badge.tsx +88 -0
  219. package/src/components/viewer/viewer-controls-bar.tsx +466 -0
  220. package/src/components/viewer/viewer-scene-header.tsx +235 -0
  221. package/src/components/viewer-overlay.tsx +36 -596
  222. package/src/components/viewer-zone-system.tsx +6 -1
  223. package/src/components/walkthrough-hud.tsx +111 -0
  224. package/src/hooks/use-auto-save.test.ts +14 -0
  225. package/src/hooks/use-auto-save.ts +54 -7
  226. package/src/hooks/use-ceiling-events.ts +3 -2
  227. package/src/hooks/use-drag-action.ts +4 -1
  228. package/src/hooks/use-grid-events.ts +24 -0
  229. package/src/hooks/use-keyboard.ts +438 -70
  230. package/src/index.tsx +355 -9
  231. package/src/lib/active-placement-surface.test.ts +24 -0
  232. package/src/lib/active-placement-surface.ts +42 -0
  233. package/src/lib/camera-pose.test.ts +237 -0
  234. package/src/lib/camera-pose.ts +172 -0
  235. package/src/lib/ceiling-plan-snap.ts +24 -0
  236. package/src/lib/contextual-help.test.ts +112 -0
  237. package/src/lib/contextual-help.ts +144 -0
  238. package/src/lib/continuation.ts +64 -0
  239. package/src/lib/direct-manipulation.test.ts +275 -0
  240. package/src/lib/direct-manipulation.ts +118 -0
  241. package/src/lib/door-interaction.ts +1 -1
  242. package/src/lib/editor-api.ts +23 -35
  243. package/src/lib/elevation-guides.test.ts +107 -0
  244. package/src/lib/elevation-guides.ts +236 -0
  245. package/src/lib/floorplan/annotation-visibility.test.ts +327 -0
  246. package/src/lib/floorplan/annotation-visibility.ts +133 -0
  247. package/src/lib/floorplan/apply-alignment.test.ts +25 -0
  248. package/src/lib/floorplan/apply-alignment.ts +18 -12
  249. package/src/lib/floorplan/drawing-coordination.test.ts +46 -0
  250. package/src/lib/floorplan/drawing-coordination.ts +13 -0
  251. package/src/lib/floorplan/floorplan-export.test.ts +319 -0
  252. package/src/lib/floorplan/floorplan-export.tsx +978 -0
  253. package/src/lib/floorplan/floorplan-extension.test.ts +43 -0
  254. package/src/lib/floorplan/floorplan-extension.ts +181 -0
  255. package/src/lib/floorplan/floorplan-mode.test.ts +120 -0
  256. package/src/lib/floorplan/floorplan-mode.ts +73 -0
  257. package/src/lib/floorplan/floorplan-pdfkit-document.ts +194 -0
  258. package/src/lib/floorplan/floorplan-pdfkit-renderer.test.ts +107 -0
  259. package/src/lib/floorplan/floorplan-pdfkit-renderer.ts +680 -0
  260. package/src/lib/floorplan/geometry.ts +52 -0
  261. package/src/lib/floorplan/index.ts +3 -0
  262. package/src/lib/floorplan/items.ts +5 -2
  263. package/src/lib/floorplan/plan-coords.ts +21 -0
  264. package/src/lib/fresh-planar-placement.test.ts +283 -3
  265. package/src/lib/fresh-planar-placement.ts +85 -1
  266. package/src/lib/glb-export.test.ts +556 -0
  267. package/src/lib/glb-export.ts +1071 -0
  268. package/src/lib/ground-surface.ts +95 -0
  269. package/src/lib/history.test.ts +96 -0
  270. package/src/lib/history.ts +31 -0
  271. package/src/lib/interaction/hot-set.test.ts +133 -0
  272. package/src/lib/interaction/hot-set.ts +67 -0
  273. package/src/lib/interaction/overlay-policy.test.ts +52 -0
  274. package/src/lib/interaction/overlay-policy.ts +59 -0
  275. package/src/lib/interaction/scope.ts +243 -0
  276. package/src/lib/level-duplication.test.ts +2 -1
  277. package/src/lib/level-selection.ts +2 -2
  278. package/src/lib/material-paint.ts +36 -49
  279. package/src/lib/measurement-kind.test.ts +30 -0
  280. package/src/lib/measurement-kind.ts +19 -0
  281. package/src/lib/measurement-label.test.ts +47 -0
  282. package/src/lib/measurement-label.ts +68 -0
  283. package/src/lib/measurement-parser.ts +116 -0
  284. package/src/lib/measurements.test.ts +188 -0
  285. package/src/lib/measurements.ts +210 -0
  286. package/src/lib/paint-scope.test.ts +454 -0
  287. package/src/lib/paint-scope.ts +461 -0
  288. package/src/lib/placement-drag-release.ts +23 -0
  289. package/src/lib/planar-cursor-placement.test.ts +57 -0
  290. package/src/lib/plugin-panels.test.ts +19 -0
  291. package/src/lib/plugin-panels.ts +91 -0
  292. package/src/lib/quick-action-feedback.ts +33 -0
  293. package/src/lib/quick-action-nodes.test.ts +94 -0
  294. package/src/lib/quick-action-nodes.ts +47 -0
  295. package/src/lib/quick-measurement.test.ts +77 -0
  296. package/src/lib/quick-measurement.ts +109 -0
  297. package/src/lib/roof-duplication.ts +6 -6
  298. package/src/lib/roof-hover-outline-proxy.ts +22 -0
  299. package/src/lib/roof-wall-hit.ts +164 -0
  300. package/src/lib/scene-clipboard.test.ts +325 -0
  301. package/src/lib/scene-clipboard.ts +310 -21
  302. package/src/lib/scene.ts +28 -5
  303. package/src/lib/selection-routing.test.ts +313 -0
  304. package/src/lib/selection-routing.ts +180 -0
  305. package/src/lib/sfx/index.ts +1 -0
  306. package/src/lib/sfx/movement-tick.test.ts +65 -0
  307. package/src/lib/sfx/movement-tick.ts +18 -0
  308. package/src/lib/sfx-bus.ts +82 -14
  309. package/src/lib/sfx-player.test.ts +266 -0
  310. package/src/lib/sfx-player.ts +262 -69
  311. package/src/lib/site-boundary.test.ts +53 -0
  312. package/src/lib/site-boundary.ts +27 -0
  313. package/src/lib/slab-plan-snap.test.ts +93 -0
  314. package/src/lib/slab-plan-snap.ts +108 -0
  315. package/src/lib/snapping-mode.test.ts +165 -0
  316. package/src/lib/snapping-mode.ts +191 -0
  317. package/src/lib/stair-duplication.test.ts +103 -0
  318. package/src/lib/stair-duplication.ts +58 -86
  319. package/src/lib/stair-levels.ts +2 -0
  320. package/src/lib/surface-plan-snap.test.ts +71 -0
  321. package/src/lib/surface-plan-snap.ts +256 -0
  322. package/src/lib/terrain-sculpt.test.ts +429 -0
  323. package/src/lib/terrain-sculpt.ts +301 -0
  324. package/src/lib/terrain-verb-color.test.ts +51 -0
  325. package/src/lib/terrain-verb-color.ts +58 -0
  326. package/src/lib/touch-gesture-priority.test.ts +45 -0
  327. package/src/lib/touch-gesture-priority.ts +30 -0
  328. package/src/lib/use-linear-display.ts +40 -0
  329. package/src/lib/window-interaction.ts +1 -1
  330. package/src/lib/world-grid-snap.ts +37 -5
  331. package/src/store/camera-pose-store.test.ts +29 -0
  332. package/src/store/camera-pose-store.ts +27 -0
  333. package/src/store/live-draft-preview-stores.test.ts +136 -0
  334. package/src/store/navigation-sync-pose-store.test.ts +34 -0
  335. package/src/store/navigation-sync-pose-store.ts +27 -0
  336. package/src/store/terrain-sculpt-mode.test.ts +223 -0
  337. package/src/store/use-delete-confirmation.ts +27 -0
  338. package/src/store/use-direct-manipulation-feedback.ts +20 -0
  339. package/src/store/use-drawing-view.test.ts +23 -0
  340. package/src/store/use-drawing-view.ts +84 -0
  341. package/src/store/use-editor.tsx +665 -126
  342. package/src/store/use-elevation-guides.ts +40 -0
  343. package/src/store/use-facing-pose.ts +44 -0
  344. package/src/store/use-fence-curve-draft.ts +51 -0
  345. package/src/store/use-first-person-hud.ts +40 -0
  346. package/src/store/use-floorplan-annotation-visibility.ts +60 -0
  347. package/src/store/use-floorplan-draft-preview.ts +151 -0
  348. package/src/store/use-floorplan-marquee.ts +50 -0
  349. package/src/store/use-floorplan-mode.ts +110 -0
  350. package/src/store/use-interaction-scope.test.ts +206 -0
  351. package/src/store/use-interaction-scope.ts +140 -0
  352. package/src/store/use-measurement-draft.test.ts +559 -0
  353. package/src/store/use-measurement-draft.ts +570 -0
  354. package/src/store/use-opening-guides.ts +41 -0
  355. package/src/store/use-path-draft-preview.ts +90 -0
  356. package/src/store/use-placement-preview.ts +11 -3
  357. package/src/store/use-quick-measurement-hud.test.ts +53 -0
  358. package/src/store/use-quick-measurement-hud.ts +77 -0
  359. package/src/store/use-segment-draft-chain.ts +28 -0
  360. package/src/store/use-stair-build-preview.ts +53 -0
  361. package/src/store/use-wall-snap-indicator.ts +2 -0
  362. package/src/components/editor/first-person/bvh-ecctrl.tsx +0 -860
  363. package/src/components/editor/group-move-handle.tsx +0 -316
  364. package/src/components/ui/panels/paint-panel.tsx +0 -163
  365. package/src/lib/floorplan/selection-tool.ts +0 -271
  366. package/src/lib/level-name.ts +0 -11
package/src/index.tsx CHANGED
@@ -2,7 +2,21 @@
2
2
  // own shells on top of `@pascal-app/editor` (community-app, embedders)
3
3
  // don't have to learn three separate package imports. The canonical
4
4
  // definitions still live in `@pascal-app/core` / `@pascal-app/viewer`.
5
- export { useScene } from '@pascal-app/core'
5
+ export {
6
+ type ApplySceneSnapshotOptions,
7
+ acquireSceneReadOnlyLease,
8
+ applyScenePatch,
9
+ applySceneSnapshot,
10
+ type SceneCommit,
11
+ type SceneCommitListener,
12
+ type SceneCommitOrigin,
13
+ type SceneMaterialPatch,
14
+ type SceneNodePatch,
15
+ type ScenePatch,
16
+ type SceneSnapshot,
17
+ subscribeSceneCommits,
18
+ useScene,
19
+ } from '@pascal-app/core'
6
20
  export { useViewer } from '@pascal-app/viewer'
7
21
  export type { EditorProps } from './components/editor'
8
22
  export { default as Editor } from './components/editor'
@@ -11,12 +25,70 @@ export { default as Editor } from './components/editor'
11
25
  // they're referenced throughout the editor's own internals; the public
12
26
  // surface uses the shorter, shell-friendly names from the unified
13
27
  // preset-system spec.
28
+ export { BakeExporter } from './components/editor/bake-exporter'
29
+ export { BakeThumbnail } from './components/editor/bake-thumbnail'
30
+ export { FirstPersonControls } from './components/editor/first-person-controls'
14
31
  export { FloatingActionMenu as FloatingMenu } from './components/editor/floating-action-menu'
15
- export { formatMeasurement, MeasurementPill } from './components/editor/measurement-pill'
32
+ // Embed surface — the editor's real in-canvas affordances, so a host can mount
33
+ // authentic selection handles, interactive build tools, and the mover on top
34
+ // of a bare `<Viewer>` without the full `<Editor>` shell.
35
+ // - `NodeArrowHandles` renders the selected node's registry resize/rotate/move
36
+ // handles.
37
+ // - `MoveTool` runs the kind-owned mover once a translate handle arms
38
+ // `useEditor.movingNode`.
39
+ // - `ToolManager` mounts the active registry build tool (wall / door / window /
40
+ // …) for interactive placement when `useEditor` is in build mode with a
41
+ // tool, plus the snap/alignment guide layers. Mount it only while a tool is
42
+ // active to avoid its select-mode boundary editors.
43
+ // - `Grid` is the interactive drafting plane: it raycasts the pointer and
44
+ // emits the `grid:move` / `grid:click` events the build tools consume (the
45
+ // wall tool is driven entirely by them; door/window use them for free-follow
46
+ // alongside the viewer's `wall:*` mesh events). Without it the tools mount
47
+ // but their cursor never tracks the pointer. Mount it while a tool is active.
48
+ // All read `useViewer` selection + `useEditor` state, and cooperate with host
49
+ // camera controls via the `useViewer.inputDragging` / `useEditor.movingNode`
50
+ // flags. Tools place onto `useViewer.selection.levelId`, so the host must set a
51
+ // building + level selection first.
52
+ export { Grid } from './components/editor/grid'
53
+ export {
54
+ DimensionPill,
55
+ type DimensionPillPart,
56
+ formatMeasurement,
57
+ MeasurementPill,
58
+ } from './components/editor/measurement-pill'
59
+ // In-world arrow handle primitives (chevron geometry, invisible hit area,
60
+ // shared material, palette + scale constants). Re-exported so kind-owned
61
+ // 3D selection affordances in `@pascal-app/nodes` (duct side-move / height /
62
+ // extend arrows) reuse the same UI family as the wall / fence side handles.
63
+ export {
64
+ ARROW_COLOR,
65
+ ARROW_HOVER_COLOR,
66
+ ARROW_SCALE,
67
+ createArrowHandleGeometry,
68
+ createArrowHitAreaGeometry,
69
+ HandleArrow,
70
+ type HandleArrowInputShape,
71
+ type HandleArrowPlacement,
72
+ type HandleArrowProps,
73
+ InvisibleHandleHitArea,
74
+ NO_RAYCAST,
75
+ NodeArrowHandles,
76
+ swallowNextClick,
77
+ useArrowMaterial,
78
+ useInvisibleHitAreaMaterial,
79
+ } from './components/editor/node-arrow-handles'
80
+ export { QuickMeasurementCard } from './components/editor/quick-measurement-card'
16
81
  export {
17
82
  type SnapshotCameraData,
18
83
  ThumbnailGenerator,
19
84
  } from './components/editor/thumbnail-generator'
85
+ export { useFloorplanRender } from './components/editor-2d/floorplan-render-context'
86
+ export { FloorplanDimensionRenderer } from './components/editor-2d/renderers/floorplan-dimension-renderer'
87
+ export { FloorplanGeometryRenderer } from './components/editor-2d/renderers/floorplan-geometry-renderer'
88
+ export {
89
+ FloorplanNodePreview,
90
+ type FloorplanNodePreviewProps,
91
+ } from './components/editor-2d/renderers/floorplan-placement-preview-layer'
20
92
  // SVG path builders for arc / annular-sector / arrow-head shapes —
21
93
  // inlined into `kind: 'path'` / `kind: 'polygon'` primitives by curved
22
94
  // stair rendering in `nodes/src/stair/floorplan.ts`.
@@ -32,9 +104,11 @@ export {
32
104
  // shared/segment-angle.ts) once every Stage D port is in.
33
105
  export {
34
106
  createFenceOnCurrentLevel,
107
+ createSplineFenceOnCurrentLevel,
35
108
  type FencePlanPoint,
36
109
  snapFenceDraftPoint,
37
110
  } from './components/tools/fence/fence-drafting'
111
+ export { MoveTool } from './components/tools/item/move-tool'
38
112
  // Placement-math helpers — shared by kind-owned placement tools in
39
113
  // `@pascal-app/nodes` (wall curve sagitta snap, door / window placement,
40
114
  // item drop) so kinds don't reach into editor internals.
@@ -62,9 +136,25 @@ export { CursorSphere } from './components/tools/shared/cursor-sphere'
62
136
  export { DragBoundingBox } from './components/tools/shared/drag-bounding-box'
63
137
  export { getFloorStackPreviewPosition } from './components/tools/shared/floor-stack-preview'
64
138
  export { useFreshPlacementVisibility } from './components/tools/shared/fresh-placement-visibility'
139
+ export {
140
+ type HorizontalConstructionPlane,
141
+ publishHorizontalConstructionPlane,
142
+ resampleTerrainConstructionPlane,
143
+ resolveEventConstructionPlane,
144
+ resolveLevelConstructionPlane,
145
+ } from './components/tools/shared/horizontal-construction-plane'
146
+ export { PlacementBox } from './components/tools/shared/placement-box'
147
+ // Pointer-decided support surface (deck top vs floor underneath) — the
148
+ // draw tools (wall / fence) ride their grid plane and commit cap on it.
149
+ export {
150
+ type PointerSupportSurface,
151
+ resolvePointerSupportElevation,
152
+ resolvePointerSupportSurface,
153
+ } from './components/tools/shared/pointer-support-cap'
65
154
  // Phase 5 Stage D — PolygonEditor for slab/ceiling boundary + hole editors.
66
155
  export {
67
156
  PolygonEditor,
157
+ type PolygonEditorPlanPointSnapContext,
68
158
  type PolygonEditorProps,
69
159
  } from './components/tools/shared/polygon-editor'
70
160
  export {
@@ -95,19 +185,24 @@ export {
95
185
  DEFAULT_STAIR_TYPE,
96
186
  DEFAULT_STAIR_WIDTH,
97
187
  } from './components/tools/stair/stair-defaults'
188
+ export { preloadRegistryToolModules, ToolManager } from './components/tools/tool-manager'
98
189
  export {
190
+ chainEndJoinsExistingWall,
99
191
  createWallOnCurrentLevel,
100
192
  getSegmentGridStep,
101
193
  isSegmentLongEnough,
194
+ resolveEndpointWallSplit,
102
195
  snapPointToGrid,
103
196
  snapScalarToGrid,
104
197
  snapWallDraftPoint,
105
198
  snapWallDraftPointDetailed,
106
- WALL_FINE_GRID_STEP,
199
+ WALL_CONNECT_SNAP_RADIUS,
107
200
  WALL_GRID_STEP,
201
+ WALL_JOIN_SNAP_RADIUS,
108
202
  type WallDraftSnapKind,
109
203
  type WallDraftSnapResult,
110
204
  type WallPlanPoint,
205
+ type WallSnapRadii,
111
206
  } from './components/tools/wall/wall-drafting'
112
207
  // `ToolbarLeft` / `ToolbarRight` are the headless-spec aliases for the
113
208
  // existing `ViewerToolbarLeft` / `ViewerToolbarRight` exports — the
@@ -124,12 +219,20 @@ export {
124
219
  } from './components/ui/action-menu/view-toggles'
125
220
  export { useCommandPalette } from './components/ui/command-palette'
126
221
  export { ActionButton, ActionGroup } from './components/ui/controls/action-button'
127
- export { MaterialPaintPanel } from './components/ui/controls/material-paint-panel'
128
- export { MaterialPicker } from './components/ui/controls/material-picker'
222
+ export {
223
+ MaterialPaintPanel,
224
+ type MaterialPaintPanelProps,
225
+ } from './components/ui/controls/material-paint-panel'
226
+ export {
227
+ MaterialPicker,
228
+ type MaterialPickerProps,
229
+ type MaterialSourceFilter,
230
+ } from './components/ui/controls/material-picker'
129
231
  export { MetricControl } from './components/ui/controls/metric-control'
130
232
  export { PanelSection } from './components/ui/controls/panel-section'
131
233
  export { SegmentedControl } from './components/ui/controls/segmented-control'
132
234
  export { SliderControl } from './components/ui/controls/slider-control'
235
+ export { TerrainSculptPanel } from './components/ui/controls/terrain-sculpt-panel'
133
236
  export { ToggleControl } from './components/ui/controls/toggle-control'
134
237
  export { FloatingLevelSelector } from './components/ui/floating-level-selector'
135
238
  export { CATALOG_ITEMS } from './components/ui/item-catalog/catalog-items'
@@ -164,6 +267,26 @@ export {
164
267
  } from './components/ui/sidebar/panels/settings-panel'
165
268
  export type { SitePanelProps } from './components/ui/sidebar/panels/site-panel'
166
269
  export type { SidebarTab } from './components/ui/sidebar/tab-bar'
270
+ export {
271
+ resolveAssetSnapTarget,
272
+ resolveNodeSnapTarget,
273
+ type SnapTarget,
274
+ SnapTargetBadge,
275
+ SnapTargetIcon,
276
+ } from './components/ui/snap-target-badge'
277
+ export {
278
+ ViewerControlsBar,
279
+ type ViewerControlsBarProps,
280
+ } from './components/viewer/viewer-controls-bar'
281
+ export {
282
+ ViewerSceneHeader,
283
+ type ViewerSceneHeaderProps,
284
+ } from './components/viewer/viewer-scene-header'
285
+ export {
286
+ WalkthroughHud,
287
+ type WalkthroughHudProps,
288
+ type WalkthroughInteract,
289
+ } from './components/walkthrough-hud'
167
290
  export type { SaveStatus } from './hooks/use-auto-save'
168
291
  // useDragAction is the React-side glue for the registry's DragAction
169
292
  // primitive. Public so registry-driven kinds (Phase 5+ Stage D ports)
@@ -171,9 +294,41 @@ export type { SaveStatus } from './hooks/use-auto-save'
171
294
  export { type UseDragActionArgs, useDragAction } from './hooks/use-drag-action'
172
295
  // Phase 5 Stage D — extras for kind-owned placement tools (FenceTool etc.).
173
296
  export { markToolCancelConsumed } from './hooks/use-keyboard'
297
+ export { useReducedMotion } from './hooks/use-reduced-motion'
174
298
  export { type Selection, useSelection } from './hooks/use-selection'
299
+ export {
300
+ clearPlacementSurface,
301
+ getPlacementSurface,
302
+ type PlacementSurface,
303
+ publishPlacementSurface,
304
+ } from './lib/active-placement-surface'
305
+ export {
306
+ CEILING_ALIGNMENT_THRESHOLD_M,
307
+ type CeilingPlanSnapInput,
308
+ type CeilingPlanSnapResult,
309
+ clearCeilingSnapFeedback,
310
+ resolveCeilingPlanPointSnap,
311
+ } from './lib/ceiling-plan-snap'
175
312
  export { EDITOR_LAYER } from './lib/constants'
176
313
  // Helper libs used by the kind-owned roof / stair / elevator panels.
314
+ export {
315
+ CONTINUATION_PROFILES,
316
+ type ContinuationContext,
317
+ type ContinuationMode,
318
+ continuationContextOf,
319
+ nextContinuation,
320
+ } from './lib/continuation'
321
+ export {
322
+ clearStructuralElevationGuide,
323
+ collectElevationSnapTargets,
324
+ ELEVATION_ALIGNMENT_THRESHOLD_M,
325
+ type ElevationGuideSource,
326
+ type ElevationSnapMatch,
327
+ type ElevationSnapTarget,
328
+ publishStructuralElevationGuide,
329
+ resolveElevationSnapMatch,
330
+ resolveStructuralElevationSnap,
331
+ } from './lib/elevation-guides'
177
332
  export {
178
333
  resolveCurrentBuildingId,
179
334
  resolveElevatorNodeSupportY,
@@ -200,16 +355,92 @@ export {
200
355
  type FloorplanStairSegmentEntry,
201
356
  getFloorplanWallThickness,
202
357
  } from './lib/floorplan'
358
+ export type {
359
+ FloorplanAnnotationCategory,
360
+ FloorplanAnnotationVisibility,
361
+ } from './lib/floorplan/annotation-visibility'
362
+ export {
363
+ createFloorplanContextExtensions,
364
+ FLOORPLAN_CONTEXT_EXTENSION_KEY,
365
+ FLOORPLAN_GEOMETRY_METADATA_KEY,
366
+ FLOORPLAN_NODE_EXTENSION_KEY,
367
+ type FloorplanAnnotationRole,
368
+ type FloorplanMetricNotation,
369
+ type FloorplanNodeExtension,
370
+ type FloorplanRenderPurpose,
371
+ type FloorplanSchedule,
372
+ type FloorplanToolContext,
373
+ type FloorplanToolMode,
374
+ floorplanGeometryMetadata,
375
+ getFloorplanNodeExtension,
376
+ readFloorplanContext,
377
+ readFloorplanGeometryMetadata,
378
+ readFloorplanMetricNotationOverride,
379
+ withFloorplanGeometryMetadata,
380
+ } from './lib/floorplan/floorplan-extension'
381
+ export {
382
+ DEFAULT_FLOORPLAN_MODE,
383
+ FLOORPLAN_MODES,
384
+ type FloorplanMode,
385
+ isFloorplanToolAvailableInMode,
386
+ } from './lib/floorplan/floorplan-mode'
203
387
  export { commitFreshPlacementSubtree } from './lib/fresh-planar-placement'
388
+ export { exportSceneToGlb } from './lib/glb-export'
389
+ export {
390
+ type HistoryCommandDelegate,
391
+ installHistoryCommandDelegate,
392
+ runRedo,
393
+ runUndo,
394
+ } from './lib/history'
395
+ export {
396
+ boundaryReshapeScope,
397
+ curveReshapeScope,
398
+ endpointReshapeScope,
399
+ holeEditScope,
400
+ movingNodeOf,
401
+ scopeNodeId,
402
+ } from './lib/interaction/scope'
204
403
  export {
205
404
  buildResetSurfaceMaterialUpdates,
206
405
  buildRoofSurfaceMaterialPatch,
207
406
  buildSingleSurfaceMaterialPatch,
208
407
  buildStairSurfaceMaterialPatch,
209
- buildWallSurfaceMaterialPatch,
210
408
  getActivePaintMaterialLabel,
211
409
  hasActivePaintMaterial,
212
410
  } from './lib/material-paint'
411
+ export {
412
+ CREATABLE_MEASUREMENT_KINDS,
413
+ type CreatableMeasurementKind,
414
+ DEFAULT_CREATABLE_MEASUREMENT_KIND,
415
+ isCreatableMeasurementKind,
416
+ normalizeCreatableMeasurementKind,
417
+ } from './lib/measurement-kind'
418
+ export {
419
+ measurementPolygonLabelAnchor,
420
+ triangulateMeasurementPolygon,
421
+ } from './lib/measurement-label'
422
+ export {
423
+ buildMeasurementAngleArcPoints,
424
+ cubicMetersToVolumeUnit,
425
+ formatAreaLabel,
426
+ formatLinearMeasurement,
427
+ formatVolumeLabel,
428
+ getAreaUnitLabel,
429
+ getLinearUnitLabel,
430
+ getVolumeUnitLabel,
431
+ type LinearUnit,
432
+ linearControlValueToMeters,
433
+ linearUnitToMeters,
434
+ MEASUREMENT_ACTIVE_COLOR,
435
+ MEASUREMENT_DANGLING_COLOR,
436
+ MEASUREMENT_FLOORPLAN_COLOR,
437
+ MEASUREMENT_PERSISTENT_COLOR,
438
+ measurementFloorplanPresentationColor,
439
+ measurementPresentationColor,
440
+ metersToLinearUnit,
441
+ squareMetersToAreaUnit,
442
+ } from './lib/measurements'
443
+ export { consumePlacementDragRelease } from './lib/placement-drag-release'
213
444
  export {
214
445
  addFreshPlacementMetadata,
215
446
  getPlacementMetadataRecord,
@@ -221,10 +452,37 @@ export {
221
452
  type PlanarPoint,
222
453
  resolvePlanarCursorPosition,
223
454
  } from './lib/planar-cursor-placement'
455
+ export {
456
+ type EditorHostPanel,
457
+ type EditorHostPanelWorkspace,
458
+ editorHostPanelRegistry,
459
+ registerEditorHostPanel,
460
+ } from './lib/plugin-panels'
461
+ export {
462
+ createQuickMeasurementPointerScheduler,
463
+ quickMeasurementContext,
464
+ resolveQuickMeasurementReport,
465
+ } from './lib/quick-measurement'
224
466
  export { clearRoofDuplicateMetadata, duplicateRoofSubtree } from './lib/roof-duplication'
467
+ // Roof wall-face hit resolution + overlap guard — shared by the
468
+ // kind-owned door / window tools in `@pascal-app/nodes` and the item
469
+ // placement coordinator's roof-wall strategy.
470
+ export { hasRoofFaceChildOverlap, type RoofWallHit, resolveRoofWallHit } from './lib/roof-wall-hit'
225
471
  export type { SceneGraph } from './lib/scene'
226
472
  export { applySceneGraphToEditor } from './lib/scene'
473
+ export { movementSfxStepKey } from './lib/sfx/movement-tick'
227
474
  export { triggerSFX } from './lib/sfx-bus'
475
+ export { playSFX, type SFXName, type SFXPlaybackOptions } from './lib/sfx-player'
476
+ export {
477
+ clearSlabSnapFeedback,
478
+ resolveSlabEdgeBandSnap,
479
+ resolveSlabPlanPointSnap,
480
+ SLAB_ALIGNMENT_THRESHOLD_M,
481
+ type SlabEdgeBandSnapInput,
482
+ type SlabEdgeBandSnapResult,
483
+ type SlabPlanSnapInput,
484
+ type SlabPlanSnapResult,
485
+ } from './lib/slab-plan-snap'
228
486
  export { duplicateStairSubtree } from './lib/stair-duplication'
229
487
  export {
230
488
  getBuildingLevelsForLevel,
@@ -234,36 +492,124 @@ export {
234
492
  resolveStairPlacementLevelId,
235
493
  resolveStairToLevelId,
236
494
  } from './lib/stair-levels'
495
+ export {
496
+ clearSurfacePlanSnapFeedback,
497
+ resolveSurfacePlanPointSnap,
498
+ SURFACE_ALIGNMENT_THRESHOLD_M,
499
+ type SurfacePlanSnapInput,
500
+ type SurfacePlanSnapResult,
501
+ } from './lib/surface-plan-snap'
502
+ export {
503
+ fieldExtentForSite,
504
+ flattenSite,
505
+ resetSiteTerrain,
506
+ resolveFlattenTarget,
507
+ sculptFieldForSite,
508
+ } from './lib/terrain-sculpt'
237
509
  // `cn` (twMerge + clsx) — used by kind-owned panels in `@pascal-app/
238
510
  // nodes` so they don't need their own copy / their own tailwind-merge
239
511
  // dependency.
240
512
  export { cn } from './lib/utils'
241
513
  export {
242
514
  getActiveBuildingPose,
515
+ projectAlignmentGuidesWorldToActiveBuildingLocal,
243
516
  resolveAlignmentForActiveBuilding,
517
+ resolveAlignmentForFloorplanView,
244
518
  snapBuildingLocalToWorldGrid,
245
519
  snapWorldXZForActiveBuilding,
246
520
  } from './lib/world-grid-snap'
247
521
  export { default as useAlignmentGuides } from './store/use-alignment-guides'
248
522
  export { default as useAudio } from './store/use-audio'
249
523
  export { type CommandAction, useCommandRegistry } from './store/use-command-registry'
524
+ export {
525
+ DRAWING_TYPE_OPTIONS,
526
+ default as useDrawingView,
527
+ } from './store/use-drawing-view'
250
528
  export type {
529
+ CaptureMode,
251
530
  FloorplanSelectionTool,
252
- MovingFenceEndpoint,
253
- MovingWallEndpoint,
531
+ SnapshotCropMode,
532
+ SnapshotStandardAspect,
254
533
  SplitOrientation,
255
534
  Tool,
256
535
  ToolDefaults,
257
536
  ViewMode,
258
537
  WorkspaceMode,
259
538
  } from './store/use-editor'
260
- export { default as useEditor } from './store/use-editor'
539
+ export {
540
+ default as useEditor,
541
+ getActiveContinuationContext,
542
+ getContinuation,
543
+ isAlignmentGuideActive,
544
+ isAngleSnapActive,
545
+ isGridSnapActive,
546
+ isMagneticSnapActive,
547
+ } from './store/use-editor'
548
+ export { default as useFacingPose, type FacingPose } from './store/use-facing-pose'
549
+ export { default as useFenceCurveDraft } from './store/use-fence-curve-draft'
550
+ export { type FirstPersonHudState, useFirstPersonHud } from './store/use-first-person-hud'
551
+ export { default as useFloorplanAnnotationVisibility } from './store/use-floorplan-annotation-visibility'
552
+ export { useFloorplanDraftPreview } from './store/use-floorplan-draft-preview'
553
+ export { default as useFloorplanMode } from './store/use-floorplan-mode'
554
+ export {
555
+ default as useInteractionScope,
556
+ getEditingHole,
557
+ getIsCurveReshape,
558
+ getMovingNode,
559
+ useActiveHandleDrag,
560
+ useEditingHole,
561
+ useEndpointReshape,
562
+ useIsCurveReshape,
563
+ useMovingNode,
564
+ useReshapingNode,
565
+ } from './store/use-interaction-scope'
566
+ export {
567
+ commitMeasurementDraft,
568
+ finishMeasurementDraft,
569
+ handleMeasurementDraftEscape,
570
+ type MeasurementAxis,
571
+ type MeasurementAxisGuide,
572
+ type MeasurementDraftOwner,
573
+ type MeasurementDraftPayload,
574
+ type MeasurementDraftStage,
575
+ type MeasurementKind,
576
+ type MeasurementPoint,
577
+ type MeasurementSurfacePoint,
578
+ measurementPolygonMidpoints,
579
+ useMeasurementDraft,
580
+ } from './store/use-measurement-draft'
581
+ export {
582
+ default as useOpeningGuides,
583
+ type OpeningGuide3D,
584
+ type OpeningGuideVec3,
585
+ } from './store/use-opening-guides'
261
586
  export {
262
587
  type PaletteView,
263
588
  type PaletteViewProps,
264
589
  usePaletteViewRegistry,
265
590
  } from './store/use-palette-view-registry'
591
+ export {
592
+ type PathDraftKind,
593
+ type PathDraftParameter,
594
+ type PathDraftParameters,
595
+ type PathDraftPoint,
596
+ usePathDraftPreview,
597
+ } from './store/use-path-draft-preview'
266
598
  export { default as usePlacementPreview } from './store/use-placement-preview'
599
+ export {
600
+ activateQuickMeasurementHudSource,
601
+ clearQuickMeasurementHudSource,
602
+ publishQuickMeasurementHudSource,
603
+ type QuickMeasurementHudEntry,
604
+ type QuickMeasurementHudSource,
605
+ selectQuickMeasurementHudEntry,
606
+ useQuickMeasurementHud,
607
+ } from './store/use-quick-measurement-hud'
608
+ export { default as useSegmentDraftChain } from './store/use-segment-draft-chain'
609
+ export {
610
+ type StairPreviewPoint,
611
+ useStairBuildPreview,
612
+ } from './store/use-stair-build-preview'
267
613
  export { useUploadStore } from './store/use-upload'
268
614
  export { useWallMoveGhosts, type WallMoveGhostBridge } from './store/use-wall-move-ghosts'
269
615
  export {
@@ -0,0 +1,24 @@
1
+ import { afterEach, describe, expect, test } from 'bun:test'
2
+ import { Vector3 } from 'three'
3
+ import {
4
+ clearPlacementSurface,
5
+ getPlacementSurface,
6
+ publishPlacementSurface,
7
+ } from './active-placement-surface'
8
+
9
+ describe('active placement surface', () => {
10
+ afterEach(() => clearPlacementSurface())
11
+
12
+ test('marks a frozen construction plane so terrain raycasting can bypass it', () => {
13
+ publishPlacementSurface(new Vector3(1, 0, 2), new Vector3(0, 1, 0), 'fixed-plane')
14
+
15
+ expect(getPlacementSurface()?.projection).toBe('fixed-plane')
16
+ })
17
+
18
+ test('ordinary surface publishes reset the projection mode', () => {
19
+ publishPlacementSurface(new Vector3(), new Vector3(0, 1, 0), 'fixed-plane')
20
+ publishPlacementSurface(new Vector3(), new Vector3(0, 1, 0))
21
+
22
+ expect(getPlacementSurface()?.projection).toBe('surface')
23
+ })
24
+ })
@@ -0,0 +1,42 @@
1
+ import { Vector3 } from 'three'
2
+
3
+ // The surface the active placement/move ghost is currently snapped to: a contact
4
+ // point (world space) and the surface's outward unit normal. Published each frame
5
+ // by the placement tools (the item coordinator + the drawn-kind tools) and read
6
+ // by the grid so its snap patch sits at the ghost's height AND orients to the
7
+ // surface — horizontal on a floor / shelf top, vertical in a wall plane.
8
+ //
9
+ // A plain module singleton (not a store): both writer and reader run inside
10
+ // `useFrame`, so reactivity would only add overhead. The vectors are reused, so
11
+ // readers must consume them within the same frame.
12
+ export type PlacementSurface = {
13
+ point: Vector3
14
+ normal: Vector3
15
+ projection: 'surface' | 'fixed-plane'
16
+ }
17
+
18
+ const surface: PlacementSurface = {
19
+ point: new Vector3(),
20
+ normal: new Vector3(0, 1, 0),
21
+ projection: 'surface',
22
+ }
23
+ let active = false
24
+
25
+ export function publishPlacementSurface(
26
+ point: Vector3,
27
+ normal: Vector3,
28
+ projection: PlacementSurface['projection'] = 'surface',
29
+ ): void {
30
+ surface.point.copy(point)
31
+ surface.normal.copy(normal)
32
+ surface.projection = projection
33
+ active = true
34
+ }
35
+
36
+ export function clearPlacementSurface(): void {
37
+ active = false
38
+ }
39
+
40
+ export function getPlacementSurface(): PlacementSurface | null {
41
+ return active ? surface : null
42
+ }