@reekon-tools/boldr-cad 0.1.0 → 1.1.0

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 (555) hide show
  1. package/README.md +99 -16
  2. package/dist/app/edit.d.ts +12 -1
  3. package/dist/app/edit.js +96 -11
  4. package/dist/app/edit.js.map +1 -1
  5. package/dist/app/state.d.ts +31 -4
  6. package/dist/app/state.js +31 -2
  7. package/dist/app/state.js.map +1 -1
  8. package/dist/data/memory.d.ts +9 -1
  9. package/dist/data/memory.js +13 -8
  10. package/dist/data/memory.js.map +1 -1
  11. package/dist/data/provider.d.ts +30 -10
  12. package/dist/data/sync.d.ts +14 -3
  13. package/dist/data/sync.js +133 -66
  14. package/dist/data/sync.js.map +1 -1
  15. package/dist/editor/actions.d.ts +1 -2
  16. package/dist/editor/actions.js +391 -113
  17. package/dist/editor/actions.js.map +1 -1
  18. package/dist/editor/confirm.d.ts +23 -0
  19. package/dist/editor/confirm.js +35 -0
  20. package/dist/editor/confirm.js.map +1 -0
  21. package/dist/editor/elevation.d.ts +191 -90
  22. package/dist/editor/elevation.js +812 -616
  23. package/dist/editor/elevation.js.map +1 -1
  24. package/dist/editor/face.d.ts +73 -0
  25. package/dist/editor/face.js +269 -0
  26. package/dist/editor/face.js.map +1 -0
  27. package/dist/editor/files.d.ts +6 -0
  28. package/dist/editor/files.js +50 -4
  29. package/dist/editor/files.js.map +1 -1
  30. package/dist/editor/gestures.d.ts +18 -3
  31. package/dist/editor/gestures.js +145 -30
  32. package/dist/editor/gestures.js.map +1 -1
  33. package/dist/editor/keypad.d.ts +20 -5
  34. package/dist/editor/keypad.js +62 -15
  35. package/dist/editor/keypad.js.map +1 -1
  36. package/dist/editor/keys.js +36 -4
  37. package/dist/editor/keys.js.map +1 -1
  38. package/dist/editor/laser.d.ts +20 -4
  39. package/dist/editor/laser.js +104 -21
  40. package/dist/editor/laser.js.map +1 -1
  41. package/dist/editor/linkActions.d.ts +49 -0
  42. package/dist/editor/linkActions.js +210 -0
  43. package/dist/editor/linkActions.js.map +1 -0
  44. package/dist/editor/linkFollow.d.ts +2 -0
  45. package/dist/editor/linkFollow.js +53 -0
  46. package/dist/editor/linkFollow.js.map +1 -0
  47. package/dist/editor/linkWrite.d.ts +13 -0
  48. package/dist/editor/linkWrite.js +84 -0
  49. package/dist/editor/linkWrite.js.map +1 -0
  50. package/dist/editor/links.d.ts +84 -0
  51. package/dist/editor/links.js +130 -0
  52. package/dist/editor/links.js.map +1 -0
  53. package/dist/editor/markup.d.ts +29 -3
  54. package/dist/editor/markup.js +95 -10
  55. package/dist/editor/markup.js.map +1 -1
  56. package/dist/editor/mode.d.ts +40 -2
  57. package/dist/editor/mode.js +71 -4
  58. package/dist/editor/mode.js.map +1 -1
  59. package/dist/editor/ports.d.ts +38 -6
  60. package/dist/editor/ports.js +10 -1
  61. package/dist/editor/ports.js.map +1 -1
  62. package/dist/editor/project.d.ts +38 -6
  63. package/dist/editor/project.js +170 -27
  64. package/dist/editor/project.js.map +1 -1
  65. package/dist/editor/selection.d.ts +10 -0
  66. package/dist/editor/selection.js +62 -8
  67. package/dist/editor/selection.js.map +1 -1
  68. package/dist/editor/status.js +3 -0
  69. package/dist/editor/status.js.map +1 -1
  70. package/dist/editor/tooltips.d.ts +5 -0
  71. package/dist/editor/tooltips.js +48 -0
  72. package/dist/editor/tooltips.js.map +1 -0
  73. package/dist/editor/view3d.d.ts +17 -0
  74. package/dist/editor/view3d.js +135 -0
  75. package/dist/editor/view3d.js.map +1 -0
  76. package/dist/editor/view3dState.d.ts +39 -0
  77. package/dist/editor/view3dState.js +44 -0
  78. package/dist/editor/view3dState.js.map +1 -0
  79. package/dist/export/dxf.js +1 -1
  80. package/dist/export/dxf.js.map +1 -1
  81. package/dist/export/pdf.js +17 -12
  82. package/dist/export/pdf.js.map +1 -1
  83. package/dist/export/plan.d.ts +23 -6
  84. package/dist/export/plan.js +127 -44
  85. package/dist/export/plan.js.map +1 -1
  86. package/dist/index.d.ts +7 -1
  87. package/dist/index.js +2 -0
  88. package/dist/index.js.map +1 -1
  89. package/dist/model/constraints.js +15 -4
  90. package/dist/model/constraints.js.map +1 -1
  91. package/dist/model/demo.js +3 -3
  92. package/dist/model/demo.js.map +1 -1
  93. package/dist/model/elevation.d.ts +6 -9
  94. package/dist/model/elevation.js +5 -13
  95. package/dist/model/elevation.js.map +1 -1
  96. package/dist/model/faces.d.ts +58 -0
  97. package/dist/model/faces.js +197 -0
  98. package/dist/model/faces.js.map +1 -0
  99. package/dist/model/facesolve.d.ts +72 -0
  100. package/dist/model/facesolve.js +369 -0
  101. package/dist/model/facesolve.js.map +1 -0
  102. package/dist/model/history.d.ts +3 -2
  103. package/dist/model/history.js +17 -11
  104. package/dist/model/history.js.map +1 -1
  105. package/dist/model/images.d.ts +18 -0
  106. package/dist/model/images.js +26 -0
  107. package/dist/model/images.js.map +1 -0
  108. package/dist/model/links.d.ts +46 -0
  109. package/dist/model/links.js +73 -0
  110. package/dist/model/links.js.map +1 -0
  111. package/dist/model/markup.d.ts +46 -0
  112. package/dist/model/markup.js +71 -0
  113. package/dist/model/markup.js.map +1 -0
  114. package/dist/model/measurement.d.ts +11 -0
  115. package/dist/model/measurement.js +24 -0
  116. package/dist/model/measurement.js.map +1 -0
  117. package/dist/model/openings.d.ts +4 -0
  118. package/dist/model/openings.js +4 -0
  119. package/dist/model/openings.js.map +1 -1
  120. package/dist/model/planGeom.d.ts +72 -2
  121. package/dist/model/planGeom.js +184 -10
  122. package/dist/model/planGeom.js.map +1 -1
  123. package/dist/model/project.js +3 -2
  124. package/dist/model/project.js.map +1 -1
  125. package/dist/model/projectfile.js +2 -1
  126. package/dist/model/projectfile.js.map +1 -1
  127. package/dist/model/rooms.js +2 -2
  128. package/dist/model/rooms.js.map +1 -1
  129. package/dist/model/settings.d.ts +6 -0
  130. package/dist/model/settings.js +2 -2
  131. package/dist/model/settings.js.map +1 -1
  132. package/dist/model/sketch.d.ts +14 -0
  133. package/dist/model/sketch.js +143 -24
  134. package/dist/model/sketch.js.map +1 -1
  135. package/dist/model/smooth.d.ts +6 -0
  136. package/dist/model/smooth.js +52 -0
  137. package/dist/model/smooth.js.map +1 -0
  138. package/dist/model/store.d.ts +12 -0
  139. package/dist/model/store.js +35 -3
  140. package/dist/model/store.js.map +1 -1
  141. package/dist/model/types.d.ts +173 -8
  142. package/dist/model/wallfaces.d.ts +32 -0
  143. package/dist/model/wallfaces.js +133 -20
  144. package/dist/model/wallfaces.js.map +1 -1
  145. package/dist/model/wallshape.d.ts +15 -0
  146. package/dist/model/wallshape.js +89 -0
  147. package/dist/model/wallshape.js.map +1 -0
  148. package/dist/react/BottomBar.d.ts +9 -5
  149. package/dist/react/BottomBar.js +213 -24
  150. package/dist/react/BottomBar.js.map +1 -1
  151. package/dist/react/Buttons.d.ts +13 -2
  152. package/dist/react/Buttons.js +37 -5
  153. package/dist/react/Buttons.js.map +1 -1
  154. package/dist/react/CadEditor.d.ts +54 -4
  155. package/dist/react/CadEditor.js +79 -21
  156. package/dist/react/CadEditor.js.map +1 -1
  157. package/dist/react/ConfirmSheet.d.ts +4 -0
  158. package/dist/react/ConfirmSheet.js +31 -0
  159. package/dist/react/ConfirmSheet.js.map +1 -0
  160. package/dist/react/ConflictSheet.d.ts +2 -1
  161. package/dist/react/ConflictSheet.js +16 -8
  162. package/dist/react/ConflictSheet.js.map +1 -1
  163. package/dist/react/Drawer.d.ts +8 -2
  164. package/dist/react/Drawer.js +167 -38
  165. package/dist/react/Drawer.js.map +1 -1
  166. package/dist/react/Duck.d.ts +13 -0
  167. package/dist/react/Duck.js +45 -0
  168. package/dist/react/Duck.js.map +1 -0
  169. package/dist/react/Empty3D.d.ts +2 -0
  170. package/dist/react/Empty3D.js +39 -0
  171. package/dist/react/Empty3D.js.map +1 -0
  172. package/dist/react/FitScroll.d.ts +6 -0
  173. package/dist/react/FitScroll.js +14 -0
  174. package/dist/react/FitScroll.js.map +1 -0
  175. package/dist/react/Icon.native.d.ts +6 -0
  176. package/dist/react/Icon.native.js +4 -0
  177. package/dist/react/Icon.native.js.map +1 -1
  178. package/dist/react/Icon.web.d.ts +6 -0
  179. package/dist/react/Icon.web.js +4 -0
  180. package/dist/react/Icon.web.js.map +1 -1
  181. package/dist/react/KeypadSheet.d.ts +9 -2
  182. package/dist/react/KeypadSheet.js +174 -42
  183. package/dist/react/KeypadSheet.js.map +1 -1
  184. package/dist/react/LaserTray.js +8 -5
  185. package/dist/react/LaserTray.js.map +1 -1
  186. package/dist/react/MarkupPanel.d.ts +8 -0
  187. package/dist/react/MarkupPanel.js +67 -0
  188. package/dist/react/MarkupPanel.js.map +1 -0
  189. package/dist/react/PageThumb.native.d.ts +7 -2
  190. package/dist/react/PageThumb.native.js +19 -7
  191. package/dist/react/PageThumb.native.js.map +1 -1
  192. package/dist/react/PageThumb.web.d.ts +3 -2
  193. package/dist/react/PageThumb.web.js +4 -4
  194. package/dist/react/PageThumb.web.js.map +1 -1
  195. package/dist/react/PlanCanvas.native.d.ts +1 -1
  196. package/dist/react/PlanCanvas.native.js +134 -36
  197. package/dist/react/PlanCanvas.native.js.map +1 -1
  198. package/dist/react/PlanCanvas.web.js +16 -5
  199. package/dist/react/PlanCanvas.web.js.map +1 -1
  200. package/dist/react/Popovers.d.ts +12 -6
  201. package/dist/react/Popovers.js +53 -26
  202. package/dist/react/Popovers.js.map +1 -1
  203. package/dist/react/Rail.d.ts +24 -0
  204. package/dist/react/Rail.js +324 -34
  205. package/dist/react/Rail.js.map +1 -1
  206. package/dist/react/ShapeMenu.d.ts +7 -0
  207. package/dist/react/ShapeMenu.js +58 -0
  208. package/dist/react/ShapeMenu.js.map +1 -0
  209. package/dist/react/Sheet.d.ts +14 -4
  210. package/dist/react/Sheet.js +54 -9
  211. package/dist/react/Sheet.js.map +1 -1
  212. package/dist/react/Slider.d.ts +18 -0
  213. package/dist/react/Slider.js +27 -0
  214. package/dist/react/Slider.js.map +1 -0
  215. package/dist/react/Toast.js +14 -6
  216. package/dist/react/Toast.js.map +1 -1
  217. package/dist/react/ToolTip.d.ts +7 -0
  218. package/dist/react/ToolTip.js +43 -0
  219. package/dist/react/ToolTip.js.map +1 -0
  220. package/dist/react/TopBar.d.ts +6 -3
  221. package/dist/react/TopBar.js +48 -17
  222. package/dist/react/TopBar.js.map +1 -1
  223. package/dist/react/Tween.d.ts +7 -0
  224. package/dist/react/Tween.js +26 -0
  225. package/dist/react/Tween.js.map +1 -0
  226. package/dist/react/Tween.native.d.ts +6 -0
  227. package/dist/react/Tween.native.js +43 -0
  228. package/dist/react/Tween.native.js.map +1 -0
  229. package/dist/react/View3D.native.d.ts +4 -0
  230. package/dist/react/View3D.native.js +103 -0
  231. package/dist/react/View3D.native.js.map +1 -0
  232. package/dist/react/View3D.web.d.ts +4 -0
  233. package/dist/react/View3D.web.js +151 -0
  234. package/dist/react/View3D.web.js.map +1 -0
  235. package/dist/react/View3DHost.d.ts +143 -0
  236. package/dist/react/View3DHost.js +377 -0
  237. package/dist/react/View3DHost.js.map +1 -0
  238. package/dist/react/corners.d.ts +7 -0
  239. package/dist/react/corners.js +51 -0
  240. package/dist/react/corners.js.map +1 -0
  241. package/dist/react/easing.d.ts +15 -0
  242. package/dist/react/easing.js +10 -0
  243. package/dist/react/easing.js.map +1 -0
  244. package/dist/react/host.d.ts +7 -2
  245. package/dist/react/host.js +8 -3
  246. package/dist/react/host.js.map +1 -1
  247. package/dist/react/hostKeypad.d.ts +56 -0
  248. package/dist/react/hostKeypad.js +5 -0
  249. package/dist/react/hostKeypad.js.map +1 -0
  250. package/dist/react/motion.d.ts +77 -0
  251. package/dist/react/motion.js +173 -0
  252. package/dist/react/motion.js.map +1 -0
  253. package/dist/react/ports.js +90 -8
  254. package/dist/react/ports.js.map +1 -1
  255. package/dist/react/saving.d.ts +15 -0
  256. package/dist/react/saving.js +76 -0
  257. package/dist/react/saving.js.map +1 -0
  258. package/dist/react/store.d.ts +38 -1
  259. package/dist/react/store.js +31 -1
  260. package/dist/react/store.js.map +1 -1
  261. package/dist/react/theme.d.ts +10 -0
  262. package/dist/react/theme.js +8 -0
  263. package/dist/react/theme.js.map +1 -1
  264. package/dist/react/topRow.d.ts +22 -0
  265. package/dist/react/topRow.js +61 -0
  266. package/dist/react/topRow.js.map +1 -0
  267. package/dist/react/touch.d.ts +6 -0
  268. package/dist/react/touch.js +9 -0
  269. package/dist/react/touch.js.map +1 -0
  270. package/dist/render/ctx.d.ts +8 -0
  271. package/dist/render/draw.d.ts +33 -1
  272. package/dist/render/draw.js +593 -215
  273. package/dist/render/draw.js.map +1 -1
  274. package/dist/render/elevation.d.ts +65 -43
  275. package/dist/render/elevation.js +414 -140
  276. package/dist/render/elevation.js.map +1 -1
  277. package/dist/render/figmaIcons.d.ts +12 -0
  278. package/dist/render/figmaIcons.js +21 -0
  279. package/dist/render/figmaIcons.js.map +1 -0
  280. package/dist/render/hit.d.ts +22 -2
  281. package/dist/render/hit.js +168 -25
  282. package/dist/render/hit.js.map +1 -1
  283. package/dist/render/icons.js +69 -10
  284. package/dist/render/icons.js.map +1 -1
  285. package/dist/render/linkTile.d.ts +15 -0
  286. package/dist/render/linkTile.js +369 -0
  287. package/dist/render/linkTile.js.map +1 -0
  288. package/dist/render/markup.d.ts +11 -0
  289. package/dist/render/markup.js +112 -0
  290. package/dist/render/markup.js.map +1 -0
  291. package/dist/render/navigate.d.ts +88 -0
  292. package/dist/render/navigate.js +100 -0
  293. package/dist/render/navigate.js.map +1 -0
  294. package/dist/render/snap.d.ts +20 -1
  295. package/dist/render/snap.js +118 -25
  296. package/dist/render/snap.js.map +1 -1
  297. package/dist/render/squircle.d.ts +8 -0
  298. package/dist/render/squircle.js +71 -0
  299. package/dist/render/squircle.js.map +1 -0
  300. package/dist/render/view.d.ts +115 -2
  301. package/dist/render/view.js +244 -19
  302. package/dist/render/view.js.map +1 -1
  303. package/dist/skia/SkiaDrawCtx.d.ts +30 -2
  304. package/dist/skia/SkiaDrawCtx.js +198 -43
  305. package/dist/skia/SkiaDrawCtx.js.map +1 -1
  306. package/dist/skia/host.d.ts +18 -2
  307. package/dist/skia/host.js +46 -1
  308. package/dist/skia/host.js.map +1 -1
  309. package/dist/solver/equations.js +37 -2
  310. package/dist/solver/equations.js.map +1 -1
  311. package/dist/solver/gauss-newton.d.ts +17 -0
  312. package/dist/solver/gauss-newton.js +144 -36
  313. package/dist/solver/gauss-newton.js.map +1 -1
  314. package/dist/solver/linalg.d.ts +45 -2
  315. package/dist/solver/linalg.js +164 -10
  316. package/dist/solver/linalg.js.map +1 -1
  317. package/dist/solver/types.d.ts +5 -0
  318. package/dist/tools/annotate.d.ts +57 -1
  319. package/dist/tools/annotate.js +64 -43
  320. package/dist/tools/annotate.js.map +1 -1
  321. package/dist/tools/chamfer.d.ts +12 -0
  322. package/dist/tools/chamfer.js +114 -0
  323. package/dist/tools/chamfer.js.map +1 -0
  324. package/dist/tools/corner.d.ts +38 -0
  325. package/dist/tools/corner.js +99 -0
  326. package/dist/tools/corner.js.map +1 -0
  327. package/dist/tools/dim.d.ts +86 -9
  328. package/dist/tools/dim.js +582 -97
  329. package/dist/tools/dim.js.map +1 -1
  330. package/dist/tools/elevation.js +5 -5
  331. package/dist/tools/elevation.js.map +1 -1
  332. package/dist/tools/fillet.d.ts +9 -0
  333. package/dist/tools/fillet.js +86 -0
  334. package/dist/tools/fillet.js.map +1 -0
  335. package/dist/tools/freehand.d.ts +3 -2
  336. package/dist/tools/freehand.js +19 -12
  337. package/dist/tools/freehand.js.map +1 -1
  338. package/dist/tools/index.js +14 -4
  339. package/dist/tools/index.js.map +1 -1
  340. package/dist/tools/line.d.ts +8 -3
  341. package/dist/tools/line.js +66 -30
  342. package/dist/tools/line.js.map +1 -1
  343. package/dist/tools/modify.d.ts +13 -0
  344. package/dist/tools/modify.js +105 -25
  345. package/dist/tools/modify.js.map +1 -1
  346. package/dist/tools/openings.js +25 -18
  347. package/dist/tools/openings.js.map +1 -1
  348. package/dist/tools/registry.d.ts +8 -0
  349. package/dist/tools/registry.js +42 -2
  350. package/dist/tools/registry.js.map +1 -1
  351. package/dist/tools/select.d.ts +77 -3
  352. package/dist/tools/select.js +560 -74
  353. package/dist/tools/select.js.map +1 -1
  354. package/dist/tools/shapes.d.ts +14 -0
  355. package/dist/tools/shapes.js +154 -75
  356. package/dist/tools/shapes.js.map +1 -1
  357. package/dist/units/format.d.ts +11 -3
  358. package/dist/units/format.js +27 -6
  359. package/dist/units/format.js.map +1 -1
  360. package/dist/units/parse.d.ts +2 -1
  361. package/dist/units/parse.js +5 -4
  362. package/dist/units/parse.js.map +1 -1
  363. package/dist/units/prefs.d.ts +9 -1
  364. package/dist/units/prefs.js +6 -0
  365. package/dist/units/prefs.js.map +1 -1
  366. package/dist/view3d/build.d.ts +35 -0
  367. package/dist/view3d/build.js +630 -0
  368. package/dist/view3d/build.js.map +1 -0
  369. package/dist/view3d/camera.d.ts +60 -0
  370. package/dist/view3d/camera.js +84 -0
  371. package/dist/view3d/camera.js.map +1 -0
  372. package/dist/view3d/fatLines.d.ts +11 -0
  373. package/dist/view3d/fatLines.js +83 -0
  374. package/dist/view3d/fatLines.js.map +1 -0
  375. package/dist/view3d/lines.d.ts +17 -0
  376. package/dist/view3d/lines.js +271 -0
  377. package/dist/view3d/lines.js.map +1 -0
  378. package/dist/view3d/mesh.d.ts +51 -0
  379. package/dist/view3d/mesh.js +101 -0
  380. package/dist/view3d/mesh.js.map +1 -0
  381. package/dist/view3d/poly.d.ts +16 -0
  382. package/dist/view3d/poly.js +109 -0
  383. package/dist/view3d/poly.js.map +1 -0
  384. package/dist/view3d/viewer.d.ts +86 -0
  385. package/dist/view3d/viewer.js +350 -0
  386. package/dist/view3d/viewer.js.map +1 -0
  387. package/package.json +15 -2
  388. package/src/app/edit.ts +83 -12
  389. package/src/app/main.ts +11 -5
  390. package/src/app/state.ts +38 -5
  391. package/src/data/memory.ts +15 -10
  392. package/src/data/provider.ts +25 -10
  393. package/src/data/sync.ts +107 -53
  394. package/src/editor/actions.ts +292 -83
  395. package/src/editor/confirm.ts +58 -0
  396. package/src/editor/elevation.ts +698 -478
  397. package/src/editor/face.ts +227 -0
  398. package/src/editor/files.ts +40 -4
  399. package/src/editor/gestures.ts +147 -31
  400. package/src/editor/keypad.ts +67 -18
  401. package/src/editor/keys.ts +25 -5
  402. package/src/editor/laser.ts +98 -20
  403. package/src/editor/linkActions.ts +194 -0
  404. package/src/editor/linkFollow.ts +43 -0
  405. package/src/editor/linkWrite.ts +77 -0
  406. package/src/editor/links.ts +181 -0
  407. package/src/editor/markup.ts +92 -8
  408. package/src/editor/mode.ts +83 -7
  409. package/src/editor/ports.ts +39 -6
  410. package/src/editor/project.ts +157 -26
  411. package/src/editor/selection.ts +54 -8
  412. package/src/editor/status.ts +2 -0
  413. package/src/editor/tooltips.ts +47 -0
  414. package/src/editor/view3d.ts +119 -0
  415. package/src/editor/view3dState.ts +61 -0
  416. package/src/export/dxf.ts +1 -1
  417. package/src/export/pdf.ts +15 -7
  418. package/src/export/plan.ts +119 -35
  419. package/src/index.ts +7 -1
  420. package/src/input/keyboard.ts +2 -4
  421. package/src/model/constraints.ts +13 -4
  422. package/src/model/demo.ts +3 -3
  423. package/src/model/elevation.ts +6 -16
  424. package/src/model/faces.ts +153 -0
  425. package/src/model/facesolve.ts +322 -0
  426. package/src/model/history.ts +19 -11
  427. package/src/model/images.ts +35 -0
  428. package/src/model/links.ts +77 -0
  429. package/src/model/markup.ts +80 -0
  430. package/src/model/measurement.ts +26 -0
  431. package/src/model/openings.ts +6 -0
  432. package/src/model/planGeom.ts +174 -8
  433. package/src/model/project.ts +3 -2
  434. package/src/model/projectfile.ts +2 -1
  435. package/src/model/rooms.ts +1 -1
  436. package/src/model/settings.ts +8 -2
  437. package/src/model/sketch.ts +101 -14
  438. package/src/model/smooth.ts +51 -0
  439. package/src/model/store.ts +35 -4
  440. package/src/model/types.ts +170 -8
  441. package/src/model/wallfaces.ts +126 -17
  442. package/src/model/wallshape.ts +97 -0
  443. package/src/react/BottomBar.tsx +263 -46
  444. package/src/react/Buttons.tsx +50 -9
  445. package/src/react/CadEditor.tsx +142 -34
  446. package/src/react/ConfirmSheet.tsx +38 -0
  447. package/src/react/ConflictSheet.tsx +19 -12
  448. package/src/react/Drawer.tsx +213 -110
  449. package/src/react/Duck.tsx +50 -0
  450. package/src/react/Empty3D.tsx +32 -0
  451. package/src/react/FitScroll.tsx +19 -0
  452. package/src/react/Icon.native.tsx +5 -0
  453. package/src/react/Icon.web.tsx +5 -0
  454. package/src/react/KeypadSheet.tsx +253 -60
  455. package/src/react/LaserTray.tsx +12 -8
  456. package/src/react/MarkupPanel.tsx +150 -0
  457. package/src/react/PageThumb.native.tsx +18 -7
  458. package/src/react/PageThumb.web.tsx +4 -4
  459. package/src/react/PlanCanvas.native.tsx +151 -34
  460. package/src/react/PlanCanvas.web.tsx +15 -5
  461. package/src/react/Popovers.tsx +116 -51
  462. package/src/react/Rail.tsx +360 -27
  463. package/src/react/ShapeMenu.tsx +66 -0
  464. package/src/react/Sheet.tsx +56 -11
  465. package/src/react/Slider.tsx +48 -0
  466. package/src/react/Toast.tsx +16 -9
  467. package/src/react/ToolTip.tsx +49 -0
  468. package/src/react/TopBar.tsx +97 -39
  469. package/src/react/Tween.native.tsx +36 -0
  470. package/src/react/Tween.tsx +24 -0
  471. package/src/react/View3D.native.tsx +131 -0
  472. package/src/react/View3D.web.tsx +131 -0
  473. package/src/react/View3DHost.ts +367 -0
  474. package/src/react/corners.ts +52 -0
  475. package/src/react/easing.ts +14 -0
  476. package/src/react/host.ts +8 -3
  477. package/src/react/hostKeypad.ts +66 -0
  478. package/src/react/motion.tsx +239 -0
  479. package/src/react/ports.ts +78 -9
  480. package/src/react/saving.ts +80 -0
  481. package/src/react/store.ts +35 -3
  482. package/src/react/theme.ts +8 -0
  483. package/src/react/topRow.ts +71 -0
  484. package/src/react/touch.ts +10 -0
  485. package/src/render/ctx.ts +8 -0
  486. package/src/render/draw.ts +437 -175
  487. package/src/render/elevation.ts +349 -143
  488. package/src/render/figmaIcons.ts +22 -0
  489. package/src/render/hit.ts +140 -21
  490. package/src/render/icons.ts +69 -10
  491. package/src/render/linkTile.ts +297 -0
  492. package/src/render/markup.ts +91 -0
  493. package/src/render/navigate.ts +114 -0
  494. package/src/render/snap.ts +105 -22
  495. package/src/render/squircle.ts +73 -0
  496. package/src/render/view.ts +255 -19
  497. package/src/skia/SkiaDrawCtx.ts +163 -41
  498. package/src/skia/host.ts +46 -1
  499. package/src/solver/equations.ts +37 -2
  500. package/src/solver/gauss-newton.ts +125 -28
  501. package/src/solver/linalg.ts +141 -5
  502. package/src/solver/types.ts +5 -0
  503. package/src/styles.css +91 -42
  504. package/src/tools/annotate.ts +58 -29
  505. package/src/tools/chamfer.ts +103 -0
  506. package/src/tools/corner.ts +99 -0
  507. package/src/tools/dim.ts +525 -93
  508. package/src/tools/elevation.ts +5 -5
  509. package/src/tools/fillet.ts +82 -0
  510. package/src/tools/freehand.ts +20 -16
  511. package/src/tools/index.ts +17 -4
  512. package/src/tools/line.ts +59 -23
  513. package/src/tools/modify.ts +86 -24
  514. package/src/tools/openings.ts +11 -16
  515. package/src/tools/registry.ts +27 -2
  516. package/src/tools/select.ts +424 -75
  517. package/src/tools/shapes.ts +119 -58
  518. package/src/ui/ctx.ts +2 -1
  519. package/src/ui/domPorts.ts +23 -4
  520. package/src/ui/drawer.ts +6 -26
  521. package/src/ui/elevation.ts +10 -101
  522. package/src/ui/keypad.ts +8 -14
  523. package/src/ui/laser.ts +2 -2
  524. package/src/ui/menu.ts +63 -17
  525. package/src/ui/noteinput.ts +3 -3
  526. package/src/ui/opacity.ts +108 -0
  527. package/src/ui/palette.ts +67 -12
  528. package/src/ui/rail.ts +21 -7
  529. package/src/ui/topbar.ts +4 -14
  530. package/src/units/format.ts +24 -6
  531. package/src/units/parse.ts +4 -3
  532. package/src/units/prefs.ts +13 -1
  533. package/src/view3d/build.ts +607 -0
  534. package/src/view3d/camera.ts +113 -0
  535. package/src/view3d/fatLines.ts +83 -0
  536. package/src/view3d/lines.ts +258 -0
  537. package/src/view3d/mesh.ts +111 -0
  538. package/src/view3d/poly.ts +104 -0
  539. package/src/view3d/viewer.ts +348 -0
  540. package/dist/react/ElevCanvas.native.d.ts +0 -3
  541. package/dist/react/ElevCanvas.native.js +0 -58
  542. package/dist/react/ElevCanvas.native.js.map +0 -1
  543. package/dist/react/ElevCanvas.web.d.ts +0 -4
  544. package/dist/react/ElevCanvas.web.js +0 -44
  545. package/dist/react/ElevCanvas.web.js.map +0 -1
  546. package/dist/react/ElevationSheet.d.ts +0 -2
  547. package/dist/react/ElevationSheet.js +0 -38
  548. package/dist/react/ElevationSheet.js.map +0 -1
  549. package/dist/render/elevationView.d.ts +0 -3
  550. package/dist/render/elevationView.js +0 -100
  551. package/dist/render/elevationView.js.map +0 -1
  552. package/src/react/ElevCanvas.native.tsx +0 -68
  553. package/src/react/ElevCanvas.web.tsx +0 -42
  554. package/src/react/ElevationSheet.tsx +0 -88
  555. package/src/render/elevationView.ts +0 -73
@@ -0,0 +1,348 @@
1
+ import {
2
+ BufferAttribute, BufferGeometry, Color, DirectionalLight, DoubleSide, Fog, Group, HemisphereLight, Mesh, MeshBasicMaterial,
3
+ MeshLambertMaterial, PerspectiveCamera, PlaneGeometry, Raycaster, Scene, Vector2, Vector3, WebGLRenderer, type Material,
4
+ } from 'three';
5
+ import type { Scene3 } from './build';
6
+ import { lineMaterial, linesMesh, setLineColor, setLineView } from './fatLines';
7
+ import { axes, eye, FOV, type Orbit } from './camera';
8
+ import { MATS, type Mat3, type Part3, type PartKind, type V3 } from './mesh';
9
+
10
+ /*
11
+ The 3D view drawn with three.js, the same in a browser (a <canvas>) and on a device (expo-gl): whoever hosts it hands
12
+ over a renderer and says when to draw. The plan's x and y lie flat and its z stands up — three.js has y up, so a
13
+ plan point x, y, z is drawn at x, z, −y (a turn, not a mirror: faces keep their front).
14
+ */
15
+
16
+ export type Theme3 = 'light' | 'dark';
17
+
18
+ /**
19
+ * Each surface's colour, the outlines', and the page's, in either theme (walls white with dark cut tops, as a drawing
20
+ * shows a cut; outlines dark, so walls and what's on them stand apart; a door's frame dark round it, its leaf wood).
21
+ */
22
+ const PALETTE: Record<Theme3, Record<Exclude<Mat3, 'pick'> | 'bg' | 'ground' | 'line', string>> = {
23
+ dark: { bg: '#181A1C', ground: '#202326', wall: '#E8EAED', top: '#626364', floor: '#9C978E', cab: '#C9A57A', counter: '#EEECE7', glass: '#89C3FF', door: '#A9784D', frame: '#5E6166', line: '#26282B' },
24
+ light: { bg: '#FFFFFF', ground: '#EEF0F2', wall: '#FFFFFF', top: '#626364', floor: '#BDB6AA', cab: '#C9A57A', counter: '#F4F2EE', glass: '#89C3FF', door: '#A9784D', frame: '#5E6166', line: '#303235' },
25
+ };
26
+ /** How wide the outlines are, in points, however near or far. */
27
+ const LINE_W = 1.5;
28
+ /**
29
+ * What's tapped turns the selection's yellow: tinted toward it, and glowing with it a little, so a face turned away
30
+ * from the light still reads as picked (tinted only, a wall in shade came out the brown of the door's wood).
31
+ */
32
+ const PICKED = '#FFAD00', PICK_TINT = 0.8, PICK_GLOW = 0.35;
33
+
34
+ /** What a tap landed on: the part, and the face's normal there (plan x, y, z). */
35
+ export interface Hit3 { kind: PartKind; id: string; n: V3 }
36
+
37
+ const toThree = (x: number, y: number, z: number) => new Vector3(x, z, -y);
38
+
39
+ /**
40
+ * How far in the near plane can come, as a share of the distance to the nearest thing in view: what's nearest can sit
41
+ * off the middle of the view (as far as its corners, 45° out on a wide one), where it's nearer the camera's plane than
42
+ * to the camera.
43
+ */
44
+ const NEAR_SHARE = 0.6;
45
+
46
+ /**
47
+ * A renderer for a GL context made elsewhere (expo-gl's, on a device). three.js gets the context from a stand-in canvas
48
+ * (its size, and no-ops for the events three.js listens for), as react-three-fiber does — never as `context`: three.js
49
+ * refuses a context that's an instance of WebGLRenderingContext, taking it for WebGL 1, and expo-gl's WebGL 2 context is
50
+ * one (its WebGL2RenderingContext extends WebGLRenderingContext). Asked for through a canvas, it isn't checked.
51
+ */
52
+ export function rendererOn(gl: WebGL2RenderingContext): WebGLRenderer {
53
+ const w = gl.drawingBufferWidth, h = gl.drawingBufferHeight;
54
+ const canvas = {
55
+ width: w, height: h, clientWidth: w, clientHeight: h,
56
+ style: {}, addEventListener() {}, removeEventListener() {}, dispatchEvent: () => true, getContext: () => gl,
57
+ };
58
+ return new WebGLRenderer({ canvas: canvas as unknown as HTMLCanvasElement, antialias: false });
59
+ }
60
+
61
+ /**
62
+ * The model drawn as one geometry, its triangles by material — a dozen draws however big the plan, where a part each
63
+ * was over 600 on a 36-room one, and on a device every draw is many calls across to the GL thread — and each part's
64
+ * place in it, so what's tapped is drawn yellow by regrouping alone (nothing sent to the GPU again).
65
+ */
66
+ interface Merged {
67
+ mesh: Mesh;
68
+ /** each material's run of the index: where it starts, how long */
69
+ runs: [number, number][];
70
+ /** per part, its run within each material's: where it starts, how long */
71
+ parts: { key: string; runs: [number, number][] }[];
72
+ }
73
+
74
+ /**
75
+ * Size a renderer made with rendererOn to a view `w` × `h` points at the screen's `pixelRatio`, after the GL view's
76
+ * own resize: on iOS that makes its framebuffers again and binds framebuffers behind three.js's back, so the default
77
+ * one is bound afresh here — three.js has it down as bound already. Not three.js's resetState(): that reads
78
+ * gl.canvas, which expo-gl's context hasn't got (it threw as the 3D tab opened on a device).
79
+ */
80
+ export function sizeOn(renderer: WebGLRenderer, gl: WebGL2RenderingContext, w: number, h: number, pixelRatio: number): void {
81
+ renderer.setPixelRatio(pixelRatio);
82
+ renderer.setSize(w, h, false);
83
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
84
+ }
85
+
86
+ export class Viewer3D {
87
+ readonly scene = new Scene();
88
+ readonly camera = new PerspectiveCamera((FOV * 180) / Math.PI, 1, 1, 1e5);
89
+ private readonly root = new Group();
90
+ /** (pushed further back than the surfaces are for their outlines, or it would cover the floors just above it) */
91
+ private readonly ground = new Mesh(new PlaneGeometry(1, 1), new MeshBasicMaterial({ polygonOffset: true, polygonOffsetFactor: 4, polygonOffsetUnits: 8 }));
92
+ private readonly ray = new Raycaster();
93
+ /** the ground fades into the page past the model (no horizon line where it ends) */
94
+ private readonly fog = new Fog(0x000000, 1e5, 2e5);
95
+ private readonly lineMat = lineMaterial(LINE_W);
96
+ private lines: Mesh | null = null;
97
+ private mats: Material[] = [];
98
+ private hiMats: Material[] = [];
99
+ /** what's drawn */
100
+ private merged: Merged | null = null;
101
+ /** a mesh a part, for taps only: never drawn (so never sent to the GPU) */
102
+ private meshes: Mesh[] = [];
103
+ /** each part's box (three.js's axes: x0, y0, z0, x1, y1, z1), for how near the near plane can come */
104
+ private boxes = new Float64Array(0);
105
+ /** the box everything is in, three.js's axes */
106
+ private readonly lo = new Vector3();
107
+ private readonly hi = new Vector3();
108
+ private picked: string | null = null;
109
+ private size = 1;
110
+ private w = 1;
111
+ private h = 1;
112
+
113
+ constructor(private readonly renderer: WebGLRenderer, private theme: Theme3) {
114
+ // light from all round (brighter from above), and a sun from the north-west so walls facing different ways differ
115
+ const sun = new DirectionalLight(0xffffff, 2);
116
+ sun.position.set(-0.8, 1, -0.35);
117
+ this.scene.add(new HemisphereLight(0xffffff, 0x6e7177, 3), sun, this.root);
118
+ this.ground.rotation.x = -Math.PI / 2;
119
+ this.ground.position.y = -0.25;
120
+ this.scene.add(this.ground);
121
+ this.scene.fog = this.fog;
122
+ this.makeMaterials();
123
+ }
124
+
125
+ private makeMaterials(): void {
126
+ for (const m of [...this.mats, ...this.hiMats]) m.dispose();
127
+ const p = PALETTE[this.theme];
128
+ const make = (m: Mat3, hi: boolean): Material => {
129
+ if (m === 'pick') return new MeshBasicMaterial({ visible: false, side: DoubleSide });
130
+ const color = new Color(p[m]), glow = hi ? { emissive: new Color(PICKED), emissiveIntensity: PICK_GLOW } : {};
131
+ if (hi) color.lerp(new Color(PICKED), m === 'top' ? 1 : PICK_TINT);
132
+ // (every surface a touch further away than it is, so an outline on it is drawn over it)
133
+ const back = { polygonOffset: true, polygonOffsetFactor: 1, polygonOffsetUnits: 1 };
134
+ return m === 'glass'
135
+ ? new MeshLambertMaterial({ color, transparent: true, opacity: hi ? 0.6 : 0.32, side: DoubleSide, depthWrite: false, ...back, ...glow })
136
+ : new MeshLambertMaterial({ color, ...back, ...glow });
137
+ };
138
+ this.mats = MATS.map(m => make(m, false));
139
+ this.hiMats = MATS.map(m => make(m, true));
140
+ (this.ground.material as MeshBasicMaterial).color.set(p.ground);
141
+ this.renderer.setClearColor(p.bg);
142
+ this.fog.color.set(p.bg);
143
+ setLineColor(this.lineMat, p.line);
144
+ // (the merged mesh's groups pick from both: a part's own, then its yellow ones)
145
+ if (this.merged) this.merged.mesh.material = [...this.mats, ...this.hiMats];
146
+ for (const m of this.meshes) m.material = this.mats;
147
+ }
148
+
149
+ setTheme(theme: Theme3): void {
150
+ if (theme === this.theme) return;
151
+ this.theme = theme;
152
+ this.makeMaterials();
153
+ }
154
+
155
+ /** Show `s`, in place of what was shown. */
156
+ setModel(s: Scene3): void {
157
+ for (const m of this.meshes) m.geometry.dispose();
158
+ this.meshes = s.parts.map(p => this.meshOf(p));
159
+ if (this.merged) { this.root.remove(this.merged.mesh); this.merged.mesh.geometry.dispose(); }
160
+ this.merged = this.merge(s);
161
+ this.root.add(this.merged.mesh);
162
+ this.regroup();
163
+ this.boxes = new Float64Array(s.parts.length * 6);
164
+ s.parts.forEach((p, k) => {
165
+ const b = p.pos.length ? [Infinity, Infinity, Infinity, -Infinity, -Infinity, -Infinity] : [0, 0, 0, 0, 0, 0];
166
+ for (let i = 0; i < p.pos.length; i += 3) {
167
+ const v = [p.pos[i], p.pos[i + 2], -p.pos[i + 1]];
168
+ for (let a = 0; a < 3; a++) { b[a] = Math.min(b[a], v[a]); b[a + 3] = Math.max(b[a + 3], v[a]); }
169
+ }
170
+ this.boxes.set(b, k * 6);
171
+ });
172
+ this.lo.set(s.min[0], s.min[2], -s.max[1]);
173
+ this.hi.set(s.max[0], s.max[2], -s.min[1]);
174
+ // the outlines, drawn the same width however far away
175
+ if (this.lines) { this.root.remove(this.lines); this.lines.geometry.dispose(); this.lines = null; }
176
+ if (s.lines.length) {
177
+ const n = s.lines.length / 3, pts = new Float32Array(s.lines.length);
178
+ for (let i = 0; i < n; i++) { pts[3 * i] = s.lines[3 * i]; pts[3 * i + 1] = s.lines[3 * i + 2]; pts[3 * i + 2] = -s.lines[3 * i + 1]; }
179
+ this.lines = linesMesh(pts, this.lineMat);
180
+ this.root.add(this.lines);
181
+ }
182
+ // the ground: under it all, well past it
183
+ const cx = (s.min[0] + s.max[0]) / 2, cy = (s.min[1] + s.max[1]) / 2;
184
+ this.size = Math.max(120, s.max[0] - s.min[0], s.max[1] - s.min[1], s.max[2] - s.min[2]);
185
+ this.ground.scale.set(this.size * 12, this.size * 12, 1);
186
+ this.ground.position.set(cx, -0.25, -cy);
187
+ }
188
+
189
+ /** Part `p` on its own, to tap (its faces' sides as they're drawn: a tap goes through a face turned away). */
190
+ private meshOf(p: Part3): Mesh {
191
+ const n = p.pos.length / 3, pos = new Float32Array(n * 3);
192
+ for (let i = 0; i < n; i++) { pos[3 * i] = p.pos[3 * i]; pos[3 * i + 1] = p.pos[3 * i + 2]; pos[3 * i + 2] = -p.pos[3 * i + 1]; }
193
+ const g = new BufferGeometry(), idx: number[] = [];
194
+ g.setAttribute('position', new BufferAttribute(pos, 3));
195
+ MATS.forEach((m, k) => {
196
+ const t = p.tris[m];
197
+ if (!t || !t.length) return;
198
+ g.addGroup(idx.length, t.length, k);
199
+ for (const i of t) idx.push(i);
200
+ });
201
+ g.setIndex(new BufferAttribute(n > 65535 ? new Uint32Array(idx) : new Uint16Array(idx), 1));
202
+ g.computeBoundingSphere();
203
+ const mesh = new Mesh(g, this.mats);
204
+ mesh.userData = { kind: p.kind, id: p.id };
205
+ mesh.matrixAutoUpdate = false;
206
+ return mesh;
207
+ }
208
+
209
+ /** Every part as one geometry: each material's triangles together, a part's together within them. */
210
+ private merge(s: Scene3): Merged {
211
+ let n = 0, total = 0;
212
+ for (const p of s.parts) { n += p.pos.length / 3; for (const m of MATS) total += p.tris[m]?.length ?? 0; }
213
+ const pos = new Float32Array(n * 3), nrm = new Float32Array(n * 3), idx = n > 65535 ? new Uint32Array(total) : new Uint16Array(total);
214
+ const base: number[] = [];
215
+ let v = 0;
216
+ for (const p of s.parts) {
217
+ base.push(v);
218
+ for (let i = 0; i < p.pos.length; i += 3, v++) {
219
+ pos[3 * v] = p.pos[i]; pos[3 * v + 1] = p.pos[i + 2]; pos[3 * v + 2] = -p.pos[i + 1];
220
+ nrm[3 * v] = p.nrm[i]; nrm[3 * v + 1] = p.nrm[i + 2]; nrm[3 * v + 2] = -p.nrm[i + 1];
221
+ }
222
+ }
223
+ const runs: [number, number][] = [], parts = s.parts.map(p => ({ key: p.kind + ':' + p.id, runs: [] as [number, number][] }));
224
+ let at = 0;
225
+ MATS.forEach(m => {
226
+ const start = at;
227
+ s.parts.forEach((p, k) => {
228
+ const t = p.tris[m] ?? [], from = at;
229
+ for (const i of t) idx[at++] = base[k] + i;
230
+ parts[k].runs.push([from, at - from]);
231
+ });
232
+ runs.push([start, at - start]);
233
+ });
234
+ const g = new BufferGeometry();
235
+ g.setAttribute('position', new BufferAttribute(pos, 3));
236
+ g.setAttribute('normal', new BufferAttribute(nrm, 3));
237
+ g.setIndex(new BufferAttribute(idx, 1));
238
+ g.computeBoundingSphere();
239
+ const mesh = new Mesh(g, [...this.mats, ...this.hiMats]);
240
+ mesh.matrixAutoUpdate = false;
241
+ return { mesh, runs, parts };
242
+ }
243
+
244
+ /** The merged mesh's draws: each material's run, with what's tapped drawn yellow (a door is two parts: its doorway, its frame and leaf). */
245
+ private regroup(): void {
246
+ const mg = this.merged;
247
+ if (!mg) return;
248
+ const g = mg.mesh.geometry, hi = mg.parts.filter(p => p.key === this.picked);
249
+ g.clearGroups();
250
+ mg.runs.forEach(([start, len], m) => {
251
+ if (!len) return;
252
+ // (a part's runs lie in order within its material's: what's around them stays as it is)
253
+ const lit = hi.map(p => p.runs[m]).filter(r => r[1] > 0).sort((p, q) => p[0] - q[0]);
254
+ let from = start;
255
+ for (const [s, l] of lit) {
256
+ if (s > from) g.addGroup(from, s - from, m);
257
+ g.addGroup(s, l, MATS.length + m);
258
+ from = s + l;
259
+ }
260
+ if (start + len > from) g.addGroup(from, start + len - from, m);
261
+ });
262
+ }
263
+
264
+ /** What's tapped ("kind:id"), drawn yellow; null for nothing. */
265
+ setPicked(key: string | null): void {
266
+ if (key === this.picked) return;
267
+ this.picked = key;
268
+ this.regroup();
269
+ }
270
+
271
+ /** The view's size on the screen (points): the camera's shape, and where taps land. */
272
+ setSize(w: number, h: number): void {
273
+ this.w = Math.max(1, w);
274
+ this.h = Math.max(1, h);
275
+ this.camera.aspect = this.w / this.h;
276
+ this.camera.updateProjectionMatrix();
277
+ setLineView(this.lineMat, this.w, this.h);
278
+ }
279
+
280
+ /**
281
+ * Put the camera where `o` says. Its near and far planes close in on what's in view: depth is told apart in steps
282
+ * set by how far apart they are, and a device's depth buffer can be 16 bits (Android's expo-gl asks for no more), so
283
+ * with the near plane a few inches out a door's casing — ⅝" off the wall — came and went in the wall behind it.
284
+ */
285
+ setOrbit(o: Orbit): void {
286
+ const e = eye(o), { up } = axes(o), E = toThree(e[0], e[1], e[2]);
287
+ this.camera.position.copy(E);
288
+ this.camera.up.copy(toThree(up[0], up[1], up[2]));
289
+ this.camera.lookAt(toThree(o.x, o.y, o.z));
290
+ this.fog.near = o.dist + this.size;
291
+ this.fog.far = o.dist + this.size * 4;
292
+ // the nearest thing: a part (by its box), or the ground under the camera
293
+ let nearest = E.y - this.ground.position.y;
294
+ const b = this.boxes;
295
+ for (let i = 0; i < b.length; i += 6) {
296
+ const dx = Math.max(b[i] - E.x, 0, E.x - b[i + 3]), dy = Math.max(b[i + 1] - E.y, 0, E.y - b[i + 4]), dz = Math.max(b[i + 2] - E.z, 0, E.z - b[i + 5]);
297
+ nearest = Math.min(nearest, Math.sqrt(dx * dx + dy * dy + dz * dz));
298
+ }
299
+ // the furthest: the model's far corner, or where the ground has faded into the page (past it nothing shows)
300
+ let furthest = this.fog.far;
301
+ for (const x of [this.lo.x, this.hi.x]) for (const y of [this.lo.y, this.hi.y]) for (const z of [this.lo.z, this.hi.z]) {
302
+ furthest = Math.max(furthest, Math.hypot(x - E.x, y - E.y, z - E.z));
303
+ }
304
+ this.camera.near = Math.max(0.5, NEAR_SHARE * nearest);
305
+ this.camera.far = Math.max(this.camera.near * 2, furthest * 1.02 + 1);
306
+ this.camera.updateProjectionMatrix();
307
+ }
308
+
309
+ /** What the last frame took: draws, and triangles. */
310
+ stats(): { calls: number; triangles: number } {
311
+ const r = this.renderer.info.render;
312
+ return { calls: r.calls, triangles: r.triangles };
313
+ }
314
+
315
+ render(): void {
316
+ this.renderer.render(this.scene, this.camera);
317
+ }
318
+
319
+ /** What's under screen point x, y (points from the view's top left), nearest first; null for nothing. */
320
+ pick(x: number, y: number): Hit3 | null {
321
+ this.ray.setFromCamera(new Vector2((x / this.w) * 2 - 1, 1 - (y / this.h) * 2), this.camera);
322
+ for (const h of this.ray.intersectObjects(this.meshes, false)) {
323
+ const ud = h.object.userData as { kind?: PartKind; id?: string };
324
+ if (!ud.kind || !ud.id) continue;
325
+ const n = h.face?.normal;
326
+ return { kind: ud.kind, id: ud.id, n: n ? [n.x, -n.z, n.y] : [0, 0, 1] };
327
+ }
328
+ return null;
329
+ }
330
+
331
+ /** Where plan point x, y, z is on the screen (points), as the camera sees it now. */
332
+ project(x: number, y: number, z: number): [number, number] {
333
+ const v = toThree(x, y, z).project(this.camera);
334
+ return [((v.x + 1) / 2) * this.w, ((1 - v.y) / 2) * this.h];
335
+ }
336
+
337
+ dispose(): void {
338
+ for (const m of this.meshes) m.geometry.dispose();
339
+ this.merged?.mesh.geometry.dispose();
340
+ this.merged = null;
341
+ for (const m of [...this.mats, ...this.hiMats]) m.dispose();
342
+ this.lines?.geometry.dispose();
343
+ this.lineMat.dispose();
344
+ this.ground.geometry.dispose();
345
+ (this.ground.material as Material).dispose();
346
+ this.meshes = [];
347
+ }
348
+ }
@@ -1,3 +0,0 @@
1
- export declare function ElevCanvas({ version }: {
2
- version: number;
3
- }): import("react").JSX.Element;
@@ -1,58 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { Canvas, Picture } from '@shopify/react-native-skia';
3
- import { useLayoutEffect, useMemo, useState } from 'react';
4
- import { View } from 'react-native';
5
- import { Gesture, GestureDetector, PointerType } from 'react-native-gesture-handler';
6
- import { elev, elevAfterRender, elevPointerCancel, elevPointerDown, elevPointerLeave, elevPointerMove, elevPointerUp, elevSyncFrame, fitElevation, } from '../editor/elevation';
7
- import { drawElevationView } from '../render/elevationView';
8
- import { recordPicture } from '../skia/host';
9
- /** The open wall elevation on a device: recorded with Skia on each change, touches routed by editor/elevation.ts. */
10
- const kindOf = (t) => (t === PointerType.STYLUS ? 'pen' : t === PointerType.MOUSE ? 'mouse' : 'touch');
11
- const pin = (t, kind) => ({ id: t.id, kind, x: t.x, y: t.y, t: Date.now(), cx: t.absoluteX, cy: t.absoluteY });
12
- export function ElevCanvas({ version }) {
13
- const [picture, setPicture] = useState(null);
14
- const [size, setSize] = useState({ w: 0, h: 0 });
15
- const onLayout = (e) => {
16
- const { width, height } = e.nativeEvent.layout;
17
- setSize({ w: width, h: height });
18
- fitElevation();
19
- };
20
- useLayoutEffect(() => {
21
- if (!size.w || !size.h || !elevSyncFrame())
22
- return;
23
- elev.W = size.w;
24
- elev.H = size.h;
25
- const { picture: p, result } = recordPicture(size.w, size.h, ctx => drawElevationView(ctx));
26
- elevAfterRender(result);
27
- setPicture(p);
28
- }, [version, size]);
29
- const gesture = useMemo(() => {
30
- const touches = Gesture.Manual()
31
- .runOnJS(true)
32
- .onTouchesDown((e, manager) => {
33
- manager.activate();
34
- for (const t of e.changedTouches)
35
- elevPointerDown(pin(t, kindOf(e.pointerType)));
36
- })
37
- .onTouchesMove((e) => { for (const t of e.changedTouches)
38
- elevPointerMove(pin(t, kindOf(e.pointerType))); })
39
- .onTouchesUp((e, manager) => {
40
- for (const t of e.changedTouches)
41
- elevPointerUp(pin(t, kindOf(e.pointerType)));
42
- if (e.numberOfTouches === 0)
43
- manager.end();
44
- })
45
- .onTouchesCancelled((e, manager) => {
46
- for (const t of e.changedTouches)
47
- elevPointerCancel(pin(t, kindOf(e.pointerType)));
48
- manager.fail();
49
- });
50
- const hover = Gesture.Hover()
51
- .runOnJS(true)
52
- .onUpdate(e => elevPointerMove({ id: -1, kind: kindOf(e.pointerType), x: e.x, y: e.y, t: Date.now(), cx: e.absoluteX, cy: e.absoluteY }))
53
- .onEnd(() => elevPointerLeave('mouse'));
54
- return Gesture.Simultaneous(touches, hover);
55
- }, []);
56
- return (_jsx(GestureDetector, { gesture: gesture, children: _jsx(View, { style: { position: 'absolute', top: 0, left: 0, right: 0, bottom: 0 }, onLayout: onLayout, testID: "elevCv", children: _jsx(Canvas, { style: { flex: 1 }, children: picture && _jsx(Picture, { picture: picture }) }) }) }));
57
- }
58
- //# sourceMappingURL=ElevCanvas.native.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ElevCanvas.native.js","sourceRoot":"","sources":["../../src/react/ElevCanvas.native.tsx"],"names":[],"mappings":"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"}
@@ -1,4 +0,0 @@
1
- /** The open wall elevation in the browser: drawn on each change, pointer and wheel routed by editor/elevation.ts. */
2
- export declare function ElevCanvas({ version }: {
3
- version: number;
4
- }): import("react").JSX.Element;
@@ -1,44 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useEffect, useLayoutEffect, useRef } from 'react';
3
- import { elev, elevAfterRender, elevPointerCancel, elevPointerDown, elevPointerLeave, elevPointerMove, elevPointerUp, elevSyncFrame, elevWheel, fitElevation, } from '../editor/elevation';
4
- import { drawElevationView } from '../render/elevationView';
5
- import { setCursorTarget } from './ports';
6
- /** The open wall elevation in the browser: drawn on each change, pointer and wheel routed by editor/elevation.ts. */
7
- export function ElevCanvas({ version }) {
8
- const ref = useRef(null);
9
- useEffect(() => {
10
- const cv = ref.current, ac = new AbortController(), on = { signal: ac.signal };
11
- setCursorTarget('elevation', c => { cv.style.cursor = c; });
12
- const pin = (e) => {
13
- const r = cv.getBoundingClientRect();
14
- return { id: e.pointerId, kind: e.pointerType, x: e.clientX - r.left, y: e.clientY - r.top, t: performance.now(), button: e.button, shift: e.shiftKey, mod: e.metaKey || e.ctrlKey, cx: e.clientX, cy: e.clientY };
15
- };
16
- cv.addEventListener('pointerdown', e => { cv.setPointerCapture(e.pointerId); elevPointerDown(pin(e)); }, on);
17
- cv.addEventListener('pointermove', e => elevPointerMove(pin(e)), on);
18
- cv.addEventListener('pointerup', e => elevPointerUp(pin(e)), on);
19
- cv.addEventListener('pointercancel', e => elevPointerCancel(pin(e)), on);
20
- cv.addEventListener('pointerleave', e => elevPointerLeave(e.pointerType), on);
21
- cv.addEventListener('wheel', e => { e.preventDefault(); const r = cv.getBoundingClientRect(); elevWheel(e.clientX - r.left, e.clientY - r.top, e.deltaY); }, { passive: false, signal: ac.signal });
22
- const ro = new ResizeObserver(() => fitElevation());
23
- ro.observe(cv.parentElement);
24
- return () => { ac.abort(); ro.disconnect(); setCursorTarget('elevation', null); };
25
- }, []);
26
- useLayoutEffect(() => {
27
- const cv = ref.current;
28
- if (!cv || !elevSyncFrame())
29
- return;
30
- const box = cv.parentElement.getBoundingClientRect(), dpr = window.devicePixelRatio || 1;
31
- elev.W = box.width;
32
- elev.H = box.height;
33
- if (cv.width !== Math.round(elev.W * dpr) || cv.height !== Math.round(elev.H * dpr)) {
34
- cv.width = Math.round(elev.W * dpr);
35
- cv.height = Math.round(elev.H * dpr);
36
- }
37
- cv.style.cursor = elev.tool === 'select' ? '' : 'crosshair';
38
- const c = cv.getContext('2d');
39
- c.setTransform(dpr, 0, 0, dpr, 0, 0);
40
- elevAfterRender(drawElevationView(c));
41
- });
42
- return _jsx("canvas", { ref: ref, id: "elevCv", style: { position: 'absolute', inset: 0, width: '100%', height: '100%', touchAction: 'none', display: 'block' }, "data-v": version });
43
- }
44
- //# sourceMappingURL=ElevCanvas.web.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ElevCanvas.web.js","sourceRoot":"","sources":["../../src/react/ElevCanvas.web.tsx"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- /** The full-screen wall elevation: header, the wall drawn straight on, its toolbar, and its bar with the yellow +. */
2
- export declare function ElevationSheet(): import("react").JSX.Element | null;
@@ -1,38 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Pressable, StyleSheet, Text, View } from 'react-native';
3
- import { redo, undo } from '../app/edit';
4
- import { closeElevation, deleteSelectedElevDim, editSelected, elev, elevBar, ELEV_RAIL, elevOpen, elevTitle, elevTrashEnabled, fitElevation, flipElevation, setElevTool, } from '../editor/elevation';
5
- import { CircleButton, Pill } from './Buttons';
6
- import { ElevCanvas } from './ElevCanvas';
7
- import { Icon } from './Icon';
8
- import { useEditorVersion } from './store';
9
- import { C, FONT, shadow } from './theme';
10
- /** The full-screen wall elevation: header, the wall drawn straight on, its toolbar, and its bar with the yellow +. */
11
- export function ElevationSheet() {
12
- const version = useEditorVersion();
13
- if (!elevOpen() || !elev.frame)
14
- return null;
15
- // the selected dimension, as the last drawing kept it
16
- const act = elev.active ? JSON.parse(elev.active) : null, on = act ? { act } : undefined;
17
- const t = elevTitle(), bar = elevBar(act);
18
- return (_jsxs(View, { style: s.sheet, accessibilityRole: "none", accessibilityLabel: "Wall elevation", testID: "elev", children: [_jsxs(View, { style: s.top, children: [_jsx(CircleButton, { icon: "back", label: "Back to the plan", onPress: closeElevation, testID: "elevClose" }), _jsxs(View, { style: s.title, children: [_jsx(Text, { style: s.titleText, testID: "elevTitle", children: t.title }), _jsx(Text, { style: s.sub, testID: "elevSub", children: t.sub })] }), _jsxs(Pill, { kind: "grey", accessibilityLabel: "Flip: look from the other side", onPress: flipElevation, style: { minWidth: 0 }, children: [_jsx(Icon, { name: "flip" }), _jsx(Text, { style: s.flip, children: "Flip" })] }), _jsx(CircleButton, { icon: "fit", label: "Fit to screen", onPress: fitElevation, testID: "elevFit" })] }), _jsxs(View, { style: s.body, children: [_jsx(ElevCanvas, { version: version }), _jsxs(View, { style: s.rail, children: [ELEV_RAIL.map((it, i) => it === '|' ? _jsx(View, { style: s.div }, 'd' + i) : (_jsx(Pressable, { accessibilityRole: "button", accessibilityLabel: it[1], accessibilityState: { selected: elev.tool === it[0] }, onPress: () => setElevTool(it[0]), style: [s.btn, elev.tool === it[0] && { backgroundColor: '#fff' }], children: _jsx(Icon, { name: it[3], color: elev.tool === it[0] ? C.dark : '#fff' }) }, it[0]))), _jsx(Pressable, { accessibilityRole: "button", accessibilityLabel: "Undo", onPress: () => undo(), style: s.btn, children: _jsx(Icon, { name: "undo" }) }), _jsx(Pressable, { accessibilityRole: "button", accessibilityLabel: "Redo", onPress: () => redo(), style: s.btn, children: _jsx(Icon, { name: "redo" }) })] }), bar && (_jsxs(View, { style: s.bar, testID: "elevBar", children: [_jsx(Text, { style: s.barText, testID: "elevSel", children: bar.label }), bar.actions.map(a => (_jsxs(Pressable, { accessibilityRole: "button", accessibilityLabel: a.label, onPress: a.run, style: s.cb, children: [_jsx(Icon, { name: a.icon }), _jsx(Text, { style: s.cbText, children: a.label })] }, a.label))), bar.plus && (_jsx(Pressable, { accessibilityRole: "button", accessibilityLabel: "Change this measurement", testID: "elevAdd", onPress: editSelected, style: s.add, children: _jsx(Icon, { name: "plus", color: C.dark }) }))] })), elevTrashEnabled(on) && (_jsx(Pressable, { accessibilityRole: "button", accessibilityLabel: "Delete the selected dimension", testID: "elevTrash", onPress: deleteSelectedElevDim, style: s.trash, children: _jsx(Icon, { name: "trash" }) }))] })] }));
19
- }
20
- const s = StyleSheet.create({
21
- sheet: { position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, backgroundColor: C.dark, zIndex: 52 },
22
- top: { flexDirection: 'row', alignItems: 'center', gap: 10, paddingTop: 12, paddingHorizontal: 12, paddingBottom: 10 },
23
- title: { flex: 1, minWidth: 0 },
24
- titleText: { fontFamily: FONT, fontSize: 16, fontWeight: '700', color: '#fff' },
25
- sub: { fontFamily: FONT, fontSize: 12.5, color: C.lg1 },
26
- flip: { fontFamily: FONT, fontSize: 14, fontWeight: '600', color: '#fff' },
27
- body: { flex: 1, position: 'relative', overflow: 'hidden' },
28
- rail: { position: 'absolute', left: 12, top: 12, backgroundColor: C.g2, borderRadius: 30, paddingVertical: 8, paddingHorizontal: 6, alignItems: 'center', ...shadow },
29
- btn: { width: 40, height: 40, borderRadius: 20, alignItems: 'center', justifyContent: 'center' },
30
- div: { width: 28, height: 1, backgroundColor: C.g3, marginVertical: 5 },
31
- bar: { position: 'absolute', bottom: 14, alignSelf: 'center', flexDirection: 'row', alignItems: 'center', gap: 6, backgroundColor: C.g2, borderRadius: 34, paddingVertical: 6, paddingLeft: 16, paddingRight: 6, ...shadow },
32
- barText: { fontFamily: FONT, fontSize: 13, fontWeight: '600', color: '#fff', marginRight: 6 },
33
- cb: { minWidth: 58, height: 54, borderRadius: 27, alignItems: 'center', justifyContent: 'center', gap: 3, paddingHorizontal: 8 },
34
- cbText: { fontFamily: FONT, fontSize: 10.5, fontWeight: '500', color: '#fff' },
35
- add: { width: 48, height: 48, borderRadius: 24, backgroundColor: C.yellow, alignItems: 'center', justifyContent: 'center' },
36
- trash: { position: 'absolute', right: 16, bottom: 16, width: 56, height: 56, borderRadius: 28, backgroundColor: C.red, alignItems: 'center', justifyContent: 'center', ...shadow },
37
- });
38
- //# sourceMappingURL=ElevationSheet.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ElevationSheet.js","sourceRoot":"","sources":["../../src/react/ElevationSheet.tsx"],"names":[],"mappings":"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"}
@@ -1,3 +0,0 @@
1
- import { type ElevHit } from './elevation';
2
- import type { DrawCtx } from './ctx';
3
- export declare function drawElevationView(c: DrawCtx): ElevHit[];
@@ -1,100 +0,0 @@
1
- import { DOOR_H, elevLines, elevLineUZ, toU, WINDOW_H } from '../model/elevation';
2
- import { SK } from '../model/store';
3
- import { elev, NEW_W, openingAt } from '../editor/elevation';
4
- import { fmtLen } from '../units';
5
- import { drawElevation, drawKeyPlan, elevFit, elevT, extraRowsPx, previewChip } from './elevation';
6
- import { TH } from './theme';
7
- import { S } from './view';
8
- /* The open wall elevation as a whole: the wall (render/elevation.ts), what's selected, the drawing tools' previews,
9
- and the key plan. Fits the view the first time. Returns the tappable chips. */
10
- /** Size of the key plan in the top-right corner. */
11
- const keyPlanSize = (W) => Math.min(150, Math.max(96, W * 0.16));
12
- export function drawElevationView(c) {
13
- const sk = SK(), f = elev.frame, W = elev.W, H = elev.H;
14
- // the key plan sits top-right: keep the wall clear of it (beside it on wide screens, below it on tall ones)
15
- const k = keyPlanSize(W), wide = W >= H;
16
- if (!elev.view)
17
- elev.view = elevFit(f, W, H, { left: 56, bottom: extraRowsPx(sk, f), ...(wide ? { right: k + 28 } : { top: k + 28 }) });
18
- const hits = drawElevation(c, W, H, elev.view, sk, f, elev.active);
19
- // yellow: the opening being dragged, selected openings, selected corners (a bold edge line)
20
- c.save();
21
- c.strokeStyle = TH.yellow;
22
- for (const h of hits) {
23
- if (h.act.k === 'body' && (h.act.op === elev.dragOp || elev.objs.some(o => o.k === 'op' && o.id === h.act.op))) {
24
- c.lineWidth = 3;
25
- c.strokeRect(h.x - 2, h.y - 2, h.w + 4, h.h + 4);
26
- }
27
- else if (h.act.k === 'corner' && elev.objs.some(o => o.k === 'corner' && o.end === h.act.end)) {
28
- c.lineWidth = 5;
29
- c.beginPath();
30
- c.moveTo(h.x + h.w / 2, h.y);
31
- c.lineTo(h.x + h.w / 2, h.y + h.h);
32
- c.stroke();
33
- }
34
- }
35
- const T = elevT(elev.view, W, H);
36
- c.lineCap = 'round';
37
- c.lineWidth = 4;
38
- for (const ln of elevLines(sk, f)) {
39
- if (!elev.objs.some(o => o.k === 'line' && o.id === ln.id))
40
- continue;
41
- const [a, b] = elevLineUZ(f, ln), p = S(T, a[0], a[1]), q = S(T, b[0], b[1]);
42
- c.beginPath();
43
- c.moveTo(p[0], p[1]);
44
- c.lineTo(q[0], q[1]);
45
- c.stroke();
46
- }
47
- c.restore();
48
- drawPreview(c, T, f);
49
- drawKeyPlan(c, W - k - 14, 14, k, sk, f);
50
- return hits;
51
- }
52
- /** Previews for the drawing tools: the line being drawn (with its length), a ghost door/window, the snap marker. */
53
- function drawPreview(c, T, f) {
54
- const cur = elev.cursor;
55
- if (elev.tool === 'select' || !cur)
56
- return;
57
- c.save();
58
- if ((elev.tool === 'door' || elev.tool === 'window') && (cur.p[1] >= -1 && cur.p[1] <= f.H + 1)) {
59
- const spot = openingAt(elev.tool, cur.p[0], cur.p[1]);
60
- if (spot) {
61
- const h = elev.tool === 'door' ? DOOR_H : WINDOW_H, u0 = toU(f, spot.at - NEW_W / 2), u1 = toU(f, spot.at + NEW_W / 2);
62
- const [x0, y0] = S(T, Math.min(u0, u1), spot.sill + h), [x1, y1] = S(T, Math.max(u0, u1), spot.sill);
63
- c.fillStyle = 'rgba(0,102,255,.08)';
64
- c.fillRect(x0, y0, x1 - x0, y1 - y0);
65
- c.strokeStyle = TH.blue;
66
- c.lineWidth = 1.5;
67
- c.setLineDash([6, 4]);
68
- c.strokeRect(x0, y0, x1 - x0, y1 - y0);
69
- }
70
- }
71
- else if (elev.tool === 'line' || elev.tool === 'guide') {
72
- const [mx, my] = S(T, cur.p[0], cur.p[1]);
73
- if (elev.lineStart) {
74
- const [sx, sy] = S(T, elev.lineStart[0], elev.lineStart[1]);
75
- c.strokeStyle = elev.tool === 'guide' ? TH.constr : TH.ink;
76
- c.lineWidth = 2;
77
- c.setLineDash(elev.tool === 'guide' ? [6, 5] : []);
78
- c.beginPath();
79
- c.moveTo(sx, sy);
80
- c.lineTo(mx, my);
81
- c.stroke();
82
- c.setLineDash([]);
83
- const len = Math.hypot(cur.p[0] - elev.lineStart[0], cur.p[1] - elev.lineStart[1]);
84
- if (len > 0.5)
85
- previewChip(c, fmtLen(len), (sx + mx) / 2, (sy + my) / 2 - 16);
86
- c.fillStyle = TH.ink;
87
- c.beginPath();
88
- c.arc(sx, sy, 3.5, 0, Math.PI * 2);
89
- c.fill();
90
- }
91
- c.setLineDash([]);
92
- c.strokeStyle = cur.kind ? TH.purple : TH.ink2;
93
- c.lineWidth = 2;
94
- c.beginPath();
95
- c.arc(mx, my, cur.kind === 'pt' ? 7 : 5, 0, Math.PI * 2);
96
- c.stroke();
97
- }
98
- c.restore();
99
- }
100
- //# sourceMappingURL=elevationView.js.map