@reekon-tools/boldr-cad 0.1.0 → 1.0.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 (547) hide show
  1. package/README.md +81 -9
  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 +5 -0
  9. package/dist/data/memory.js +2 -2
  10. package/dist/data/memory.js.map +1 -1
  11. package/dist/data/provider.d.ts +19 -7
  12. package/dist/data/sync.d.ts +7 -2
  13. package/dist/data/sync.js +115 -64
  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 +19 -4
  34. package/dist/editor/keypad.js +39 -9
  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 +36 -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 +167 -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 +5 -0
  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 +46 -3
  155. package/dist/react/CadEditor.js +77 -20
  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 +581 -96
  329. package/dist/tools/dim.js.map +1 -1
  330. package/dist/tools/elevation.js +1 -1
  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 +22 -15
  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 +10 -2
  358. package/dist/units/format.js +18 -3
  359. package/dist/units/format.js.map +1 -1
  360. package/dist/view3d/build.d.ts +35 -0
  361. package/dist/view3d/build.js +630 -0
  362. package/dist/view3d/build.js.map +1 -0
  363. package/dist/view3d/camera.d.ts +60 -0
  364. package/dist/view3d/camera.js +84 -0
  365. package/dist/view3d/camera.js.map +1 -0
  366. package/dist/view3d/fatLines.d.ts +11 -0
  367. package/dist/view3d/fatLines.js +83 -0
  368. package/dist/view3d/fatLines.js.map +1 -0
  369. package/dist/view3d/lines.d.ts +17 -0
  370. package/dist/view3d/lines.js +271 -0
  371. package/dist/view3d/lines.js.map +1 -0
  372. package/dist/view3d/mesh.d.ts +51 -0
  373. package/dist/view3d/mesh.js +101 -0
  374. package/dist/view3d/mesh.js.map +1 -0
  375. package/dist/view3d/poly.d.ts +16 -0
  376. package/dist/view3d/poly.js +109 -0
  377. package/dist/view3d/poly.js.map +1 -0
  378. package/dist/view3d/viewer.d.ts +86 -0
  379. package/dist/view3d/viewer.js +350 -0
  380. package/dist/view3d/viewer.js.map +1 -0
  381. package/package.json +15 -2
  382. package/src/app/edit.ts +83 -12
  383. package/src/app/main.ts +11 -5
  384. package/src/app/state.ts +38 -5
  385. package/src/data/memory.ts +2 -2
  386. package/src/data/provider.ts +15 -7
  387. package/src/data/sync.ts +87 -50
  388. package/src/editor/actions.ts +292 -83
  389. package/src/editor/confirm.ts +58 -0
  390. package/src/editor/elevation.ts +698 -478
  391. package/src/editor/face.ts +227 -0
  392. package/src/editor/files.ts +40 -4
  393. package/src/editor/gestures.ts +147 -31
  394. package/src/editor/keypad.ts +43 -11
  395. package/src/editor/keys.ts +25 -5
  396. package/src/editor/laser.ts +98 -20
  397. package/src/editor/linkActions.ts +194 -0
  398. package/src/editor/linkFollow.ts +43 -0
  399. package/src/editor/linkWrite.ts +77 -0
  400. package/src/editor/links.ts +181 -0
  401. package/src/editor/markup.ts +92 -8
  402. package/src/editor/mode.ts +83 -7
  403. package/src/editor/ports.ts +37 -6
  404. package/src/editor/project.ts +155 -26
  405. package/src/editor/selection.ts +54 -8
  406. package/src/editor/status.ts +2 -0
  407. package/src/editor/tooltips.ts +47 -0
  408. package/src/editor/view3d.ts +119 -0
  409. package/src/editor/view3dState.ts +61 -0
  410. package/src/export/dxf.ts +1 -1
  411. package/src/export/pdf.ts +15 -7
  412. package/src/export/plan.ts +119 -35
  413. package/src/index.ts +5 -0
  414. package/src/input/keyboard.ts +2 -4
  415. package/src/model/constraints.ts +13 -4
  416. package/src/model/demo.ts +3 -3
  417. package/src/model/elevation.ts +6 -16
  418. package/src/model/faces.ts +153 -0
  419. package/src/model/facesolve.ts +322 -0
  420. package/src/model/history.ts +19 -11
  421. package/src/model/images.ts +35 -0
  422. package/src/model/links.ts +77 -0
  423. package/src/model/markup.ts +80 -0
  424. package/src/model/measurement.ts +26 -0
  425. package/src/model/openings.ts +6 -0
  426. package/src/model/planGeom.ts +174 -8
  427. package/src/model/project.ts +3 -2
  428. package/src/model/projectfile.ts +2 -1
  429. package/src/model/rooms.ts +1 -1
  430. package/src/model/settings.ts +8 -2
  431. package/src/model/sketch.ts +101 -14
  432. package/src/model/smooth.ts +51 -0
  433. package/src/model/store.ts +35 -4
  434. package/src/model/types.ts +170 -8
  435. package/src/model/wallfaces.ts +126 -17
  436. package/src/model/wallshape.ts +97 -0
  437. package/src/react/BottomBar.tsx +263 -46
  438. package/src/react/Buttons.tsx +50 -9
  439. package/src/react/CadEditor.tsx +133 -30
  440. package/src/react/ConfirmSheet.tsx +38 -0
  441. package/src/react/ConflictSheet.tsx +19 -12
  442. package/src/react/Drawer.tsx +213 -110
  443. package/src/react/Duck.tsx +50 -0
  444. package/src/react/Empty3D.tsx +32 -0
  445. package/src/react/FitScroll.tsx +19 -0
  446. package/src/react/Icon.native.tsx +5 -0
  447. package/src/react/Icon.web.tsx +5 -0
  448. package/src/react/KeypadSheet.tsx +253 -60
  449. package/src/react/LaserTray.tsx +12 -8
  450. package/src/react/MarkupPanel.tsx +150 -0
  451. package/src/react/PageThumb.native.tsx +18 -7
  452. package/src/react/PageThumb.web.tsx +4 -4
  453. package/src/react/PlanCanvas.native.tsx +151 -34
  454. package/src/react/PlanCanvas.web.tsx +15 -5
  455. package/src/react/Popovers.tsx +116 -51
  456. package/src/react/Rail.tsx +360 -27
  457. package/src/react/ShapeMenu.tsx +66 -0
  458. package/src/react/Sheet.tsx +56 -11
  459. package/src/react/Slider.tsx +48 -0
  460. package/src/react/Toast.tsx +16 -9
  461. package/src/react/ToolTip.tsx +49 -0
  462. package/src/react/TopBar.tsx +97 -39
  463. package/src/react/Tween.native.tsx +36 -0
  464. package/src/react/Tween.tsx +24 -0
  465. package/src/react/View3D.native.tsx +131 -0
  466. package/src/react/View3D.web.tsx +131 -0
  467. package/src/react/View3DHost.ts +367 -0
  468. package/src/react/corners.ts +52 -0
  469. package/src/react/easing.ts +14 -0
  470. package/src/react/host.ts +8 -3
  471. package/src/react/hostKeypad.ts +66 -0
  472. package/src/react/motion.tsx +239 -0
  473. package/src/react/ports.ts +78 -9
  474. package/src/react/saving.ts +80 -0
  475. package/src/react/store.ts +35 -3
  476. package/src/react/theme.ts +8 -0
  477. package/src/react/topRow.ts +71 -0
  478. package/src/react/touch.ts +10 -0
  479. package/src/render/ctx.ts +8 -0
  480. package/src/render/draw.ts +437 -175
  481. package/src/render/elevation.ts +349 -143
  482. package/src/render/figmaIcons.ts +22 -0
  483. package/src/render/hit.ts +140 -21
  484. package/src/render/icons.ts +69 -10
  485. package/src/render/linkTile.ts +297 -0
  486. package/src/render/markup.ts +91 -0
  487. package/src/render/navigate.ts +114 -0
  488. package/src/render/snap.ts +105 -22
  489. package/src/render/squircle.ts +73 -0
  490. package/src/render/view.ts +255 -19
  491. package/src/skia/SkiaDrawCtx.ts +163 -41
  492. package/src/skia/host.ts +46 -1
  493. package/src/solver/equations.ts +37 -2
  494. package/src/solver/gauss-newton.ts +125 -28
  495. package/src/solver/linalg.ts +141 -5
  496. package/src/solver/types.ts +5 -0
  497. package/src/styles.css +91 -42
  498. package/src/tools/annotate.ts +58 -29
  499. package/src/tools/chamfer.ts +103 -0
  500. package/src/tools/corner.ts +99 -0
  501. package/src/tools/dim.ts +524 -92
  502. package/src/tools/elevation.ts +1 -1
  503. package/src/tools/fillet.ts +82 -0
  504. package/src/tools/freehand.ts +20 -16
  505. package/src/tools/index.ts +17 -4
  506. package/src/tools/line.ts +59 -23
  507. package/src/tools/modify.ts +86 -24
  508. package/src/tools/openings.ts +8 -13
  509. package/src/tools/registry.ts +27 -2
  510. package/src/tools/select.ts +424 -75
  511. package/src/tools/shapes.ts +119 -58
  512. package/src/ui/ctx.ts +2 -1
  513. package/src/ui/domPorts.ts +23 -4
  514. package/src/ui/drawer.ts +6 -26
  515. package/src/ui/elevation.ts +10 -101
  516. package/src/ui/keypad.ts +8 -14
  517. package/src/ui/laser.ts +2 -2
  518. package/src/ui/menu.ts +63 -17
  519. package/src/ui/noteinput.ts +3 -3
  520. package/src/ui/opacity.ts +108 -0
  521. package/src/ui/palette.ts +67 -12
  522. package/src/ui/rail.ts +21 -7
  523. package/src/ui/topbar.ts +4 -14
  524. package/src/units/format.ts +18 -3
  525. package/src/view3d/build.ts +607 -0
  526. package/src/view3d/camera.ts +113 -0
  527. package/src/view3d/fatLines.ts +83 -0
  528. package/src/view3d/lines.ts +258 -0
  529. package/src/view3d/mesh.ts +111 -0
  530. package/src/view3d/poly.ts +104 -0
  531. package/src/view3d/viewer.ts +348 -0
  532. package/dist/react/ElevCanvas.native.d.ts +0 -3
  533. package/dist/react/ElevCanvas.native.js +0 -58
  534. package/dist/react/ElevCanvas.native.js.map +0 -1
  535. package/dist/react/ElevCanvas.web.d.ts +0 -4
  536. package/dist/react/ElevCanvas.web.js +0 -44
  537. package/dist/react/ElevCanvas.web.js.map +0 -1
  538. package/dist/react/ElevationSheet.d.ts +0 -2
  539. package/dist/react/ElevationSheet.js +0 -38
  540. package/dist/react/ElevationSheet.js.map +0 -1
  541. package/dist/render/elevationView.d.ts +0 -3
  542. package/dist/render/elevationView.js +0 -100
  543. package/dist/render/elevationView.js.map +0 -1
  544. package/src/react/ElevCanvas.native.tsx +0 -68
  545. package/src/react/ElevCanvas.web.tsx +0 -42
  546. package/src/react/ElevationSheet.tsx +0 -88
  547. package/src/render/elevationView.ts +0 -73
@@ -6,6 +6,8 @@ export interface Pt extends XY {
6
6
  fixed?: boolean;
7
7
  origin?: boolean;
8
8
  datum?: boolean;
9
+ /** on a wall face: a point the plan sets (a corner of the wall, of a door or window) — fixed, kept in step with the plan */
10
+ anchor?: boolean;
9
11
  }
10
12
  export type LineKind = 'line' | 'wall';
11
13
  export interface Line {
@@ -16,6 +18,10 @@ export interface Line {
16
18
  thick: number;
17
19
  /** wall height, inches; unset = the default wall height in Settings */
18
20
  height?: number;
21
+ /** on a wall face: an edge the plan sets (the floor, the ceiling, the wall's ends, a door's or window's sides) */
22
+ anchor?: boolean;
23
+ /** on a wall face: an edge of this cabinet */
24
+ cab?: string;
19
25
  }
20
26
  /** Curves can be walls too (kind 'wall', with a thickness), like straight lines. */
21
27
  export interface Circle {
@@ -53,6 +59,17 @@ export interface Constraint {
53
59
  line?: string | null;
54
60
  /** dist: aligned, horizontal or vertical */
55
61
  kind?: 'al' | 'h' | 'v';
62
+ /**
63
+ * dist, a wall's length: measured along this face of it — +1 the face to the left of its line's A → B, −1 the right
64
+ * — corner to corner, as a tape measure along it reads. diam, a curved wall's: across its outer face (+1) or its
65
+ * inner face (−1). Unset, its centreline.
66
+ */
67
+ face?: 1 | -1;
68
+ /**
69
+ * pldist between two walls (`l`, and `l2`, the wall `p` is on): which face of each it's measured from — +1 the face
70
+ * toward the other, −1 the far one, 0 the centreline; unset, both centrelines.
71
+ */
72
+ faces?: [number, number];
56
73
  value?: number;
57
74
  /** false = reference dimension (shown in parentheses, never drives geometry) */
58
75
  driving?: boolean;
@@ -60,10 +77,32 @@ export interface Constraint {
60
77
  off?: number;
61
78
  /** diameters: direction of the diameter line, radians (default 60°) */
62
79
  ang?: number;
80
+ /** diameters: shown, entered and measured as a radius (a fillet's) — `value` is still the diameter */
81
+ rad?: boolean;
63
82
  sign?: number;
64
83
  layer?: 'print';
65
- /** the BOLDR measurement this driving dimension's value is kept in (set by the host's measurement link) */
84
+ /**
85
+ * the drawing's own BOLDR measurement this driving dimension's value is kept in — made automatically by drawings
86
+ * from before Save to group, and still kept in step for them; no new ones are made
87
+ */
66
88
  measurementId?: string;
89
+ /**
90
+ * a job measurement this driving dimension shows (picked to drive a line, or saved to the group): the job's, never the
91
+ * drawing's — its value comes from the job, and a new one is written back only once the person says so. Never set
92
+ * together with measurementId.
93
+ */
94
+ measurementRef?: LinkTarget;
95
+ /**
96
+ * the host's own record of the laser reading that set this dimension's value (opaque, kept as JSON), handed back when
97
+ * it's saved to the group so the measurement is recorded as the tool's; dropped when the value changes any other way
98
+ */
99
+ capture?: unknown;
100
+ /** a default nobody measured (a new cabinet's size): it drives the drawing but isn't kept as a measurement until it's entered */
101
+ auto?: boolean;
102
+ /** on a wall face: drawn by the wall view (a cabinet's shape and size, the dimensions along the floor and beside things), not as a plan dimension or badge */
103
+ elev?: boolean;
104
+ /** on a wall face: kept by the plan (a door's or window's shape there, and where the plan locks it), never edited */
105
+ anchor?: boolean;
67
106
  }
68
107
  /** A room: its corner points, and (for loops with curves) the line or arc id after each corner. */
69
108
  export interface Room {
@@ -107,6 +146,11 @@ export interface Opening {
107
146
  /** centre, inches along the line from its start point */
108
147
  at: number;
109
148
  w: number;
149
+ /**
150
+ * the width was entered (typed or lasered); until then it's the standard size, shown grey. Unset on drawings from
151
+ * before this was kept: a width other than the standard one was entered.
152
+ */
153
+ wSet?: boolean;
110
154
  type: 'door' | 'window';
111
155
  flip: boolean;
112
156
  dims?: OpeningDim[];
@@ -119,7 +163,61 @@ export interface Opening {
119
163
  /** the sill height was entered (keypad / laser): it's locked — the window can't be dragged up or down until it's freed */
120
164
  sillLocked?: boolean;
121
165
  }
122
- export type NoteType = 'pen' | 'arrow' | 'cloud' | 'text';
166
+ /**
167
+ * line … ellipse: markup shapes drawn by a drag, kept as two corners like a cloud (a line: its two ends, like an arrow).
168
+ * link: a tile for one of the job's files (see LinkTarget), at x, y, with an optional leader. (A measurement comes into a
169
+ * drawing only as the dimension it drives; a measurement tile from before that rule still draws, its value live.)
170
+ */
171
+ export type NoteType = 'pen' | 'arrow' | 'cloud' | 'text' | 'line' | 'rect' | 'triangle' | 'ellipse' | 'link';
172
+ /**
173
+ * One of the job's files or measurements, as a drawing points at it. The host finds it by its group and id within the
174
+ * job it's open in — never by `path` — so a copied or moved job's drawings still find theirs.
175
+ */
176
+ export interface LinkTarget {
177
+ kind: 'file' | 'measurement';
178
+ id: string;
179
+ /** the group it's in (any group of the job) */
180
+ groupId: string;
181
+ /** a form group's column (the host finds the measurement in it) */
182
+ columnId?: string;
183
+ /** the host's own reference, handed back as it was */
184
+ path?: string;
185
+ /**
186
+ * What it was when it was linked: shown until the host says what it is now, offline, in exports, and once it's been
187
+ * removed. Never refreshed by itself (a drawing opened would count as edited).
188
+ */
189
+ name?: string;
190
+ groupName?: string;
191
+ /** the host's tag for the kind of file (its icon) */
192
+ fileType?: string;
193
+ /** a measurement's kind: 'length', 'angle', or the host's own */
194
+ mkind?: string;
195
+ /** a measurement's value: µm for a length, degrees for an angle */
196
+ value?: number;
197
+ /** that value as the host writes it */
198
+ text?: string;
199
+ }
200
+ /**
201
+ * What a link is now, as the host says (LinkTarget has what it was when it was linked). A file's kind, for its icon:
202
+ * 'photo', 'pdf', 'document', 'note', 'calculator', 'label', 'drawing' or anything else (a plain page).
203
+ */
204
+ export interface LinkInfo {
205
+ /** false once the host has looked and it's gone — never while it's still loading */
206
+ exists: boolean;
207
+ name?: string;
208
+ groupName?: string;
209
+ fileType?: string;
210
+ /** a small picture of it: a URL or a data URL */
211
+ thumbUrl?: string;
212
+ mkind?: string;
213
+ /** µm for a length, degrees for an angle */
214
+ value?: number;
215
+ /** the value as the host writes it */
216
+ text?: string;
217
+ /** whether it can be opened from the drawing, and its measurement changed from it (unset: yes) */
218
+ canOpen?: boolean;
219
+ canEdit?: boolean;
220
+ }
123
221
  export interface Note {
124
222
  id: string;
125
223
  type: NoteType;
@@ -128,10 +226,33 @@ export interface Note {
128
226
  y?: number;
129
227
  text?: string;
130
228
  color: string;
229
+ /**
230
+ * text: how tall its letters are on the drawing, in inches (unset: 5") — fixed to the drawing, so it zooms with it as
231
+ * the lines do; the box, padding and corners grow with it. Set by the note's corner handles or the markup panel.
232
+ * link: the tile's side on the drawing, inches (set as it's placed: a tile's size on the screen at that zoom).
233
+ */
234
+ ts?: number;
235
+ /** text, from before `ts`: a size in screen pixels (14 px read as 5", as the PDF has always printed it) */
236
+ size?: number;
237
+ /** stroke width in screen pixels (unset: 3, a cloud 2.5); not for text */
238
+ width?: number;
239
+ /** dashed or dotted (unset: solid); a note's box takes it too */
240
+ style?: 'dash' | 'dot';
241
+ /** pen strokes and arrows: how each end finishes (unset: round, an arrow's end an arrowhead) */
242
+ startCap?: NoteCap;
243
+ cap?: NoteCap;
244
+ /** link: what it's a tile for (x, y is the tile's centre, `ts` its side on the drawing, inches) */
245
+ link?: LinkTarget;
246
+ /**
247
+ * link: where its leader points, plan inches — the leader runs from the tile's edge to here, so `cap` is the end at
248
+ * what it points to. Unset: no leader. Its look is the note's color, width, style and caps.
249
+ */
250
+ leader?: [number, number];
131
251
  }
252
+ export type NoteCap = 'butt' | 'round' | 'arrow';
132
253
  /**
133
- * A line drawn on a wall elevation (layout marks, guides). a / b are [s, z]: s inches along the wall from its
134
- * start point A (so it survives flipping the view), z inches up from the floor.
254
+ * A line drawn on a wall elevation by earlier versions (layout marks, guides). a / b are [s, z]: s inches along the
255
+ * wall from its start point A, z inches up from the floor. Read only to move it into the wall's face (WallFace).
135
256
  */
136
257
  export interface ElevLine {
137
258
  id: string;
@@ -139,6 +260,40 @@ export interface ElevLine {
139
260
  b: [number, number];
140
261
  guide?: boolean;
141
262
  }
263
+ /**
264
+ * A cabinet on a wall face: a rectangle of four face points — bottom-left, bottom-right, top-right and top-left as
265
+ * seen — kept square by constraints. w, h: its width and height constraints.
266
+ */
267
+ export interface Cabinet {
268
+ bl: string;
269
+ br: string;
270
+ tr: string;
271
+ tl: string;
272
+ w?: string;
273
+ h?: string;
274
+ /** inches from the wall face out into the room */
275
+ depth: number;
276
+ /** the depth was entered (not the standard one) */
277
+ depthSet?: boolean;
278
+ label?: string;
279
+ }
280
+ /**
281
+ * What's drawn on one face of a wall (one side of it, as its elevation shows it): a sketch of its own, edited and
282
+ * solved like the plan. x runs across the wall as seen from that side, y up from the floor. The plan's corners,
283
+ * floor, ceiling and doors and windows are in it as anchors (fixed points and edges, ids starting "@"), kept in step
284
+ * with the plan, so what's drawn can be snapped, constrained and dimensioned to them.
285
+ */
286
+ export interface WallFace extends Sketch {
287
+ cabs: Record<string, Cabinet>;
288
+ /**
289
+ * Where the face's corners were when what's drawn on it was last placed: across as seen, and each in the plan. When
290
+ * one end of the wall moves, what's drawn keeps its place from the end that moved less (it stays where it is).
291
+ */
292
+ wall?: {
293
+ u: [number, number];
294
+ ends: [[number, number], [number, number]];
295
+ };
296
+ }
142
297
  export interface Sketch {
143
298
  points: Record<string, Pt>;
144
299
  lines: Record<string, Line>;
@@ -151,11 +306,15 @@ export interface Sketch {
151
306
  seq: {
152
307
  room: number;
153
308
  };
154
- /** lines drawn on wall elevations, per wall face: key "<wall line id>|<side>" (side 1: left of A → B, -1: right) */
309
+ /** what's drawn on wall elevations, per wall face: key "<wall line id>|<side>" (side 1: left of A → B, -1: right) */
310
+ faces?: Record<string, WallFace>;
311
+ /** earlier versions' lines on wall elevations (same keys): moved into `faces` when the drawing loads */
155
312
  elev?: Record<string, ElevLine[]>;
156
313
  }
157
314
  /** Photo or plan traced under the drawing. (x, y) is its top-left corner in world inches. */
158
315
  export interface Underlay {
316
+ /** which of the page's images (unique on its page) */
317
+ id: string;
159
318
  src: string;
160
319
  x: number;
161
320
  y: number;
@@ -163,7 +322,9 @@ export interface Underlay {
163
322
  /** height in inches; when missing, it follows the image's own aspect ratio */
164
323
  h?: number;
165
324
  opacity?: number;
166
- /** locked images can't be moved or resized (they still show, and can be unlocked) */
325
+ /** turned about its middle, degrees clockwise as it's seen (unset: upright) — x, y, w, h are the box before it's turned */
326
+ rot?: number;
327
+ /** locked images can't be moved, resized or turned (they still show, and can be unlocked) */
167
328
  locked?: boolean;
168
329
  }
169
330
  export interface View {
@@ -171,11 +332,12 @@ export interface View {
171
332
  cy: number;
172
333
  s: number;
173
334
  }
335
+ /** underlays: the page's photos and plans, drawn in order (the last on top) */
174
336
  export interface Page {
175
337
  id: string;
176
338
  name: string;
177
339
  sk: Sketch;
178
- underlay: Underlay | null;
340
+ underlays: Underlay[];
179
341
  view: View | null;
180
342
  _fit?: boolean;
181
343
  }
@@ -195,7 +357,10 @@ export interface Analysis {
195
357
  ok: boolean;
196
358
  }
197
359
  /** 'odim': a door/window position dimension, id "<opening id>|<part>" (part 'a' / 'b' = distance to a wall end, 'd:<id>' = a placed one). */
198
- export type SelType = 'point' | 'line' | 'circle' | 'arc' | 'cons' | 'dim' | 'room' | 'opening' | 'odim' | 'note' | 'underlay';
360
+ /** On a wall face, also 'cab' (a cabinet) and 'elev' (one of the wall view's dimension chips; id: what it measures, as JSON). */
361
+ /** 'oanchor': one end of a door or window in the plan, id "<opening>|s0" or "<opening>|s1" */
362
+ /** 'wface': one edge (face) of a wall, id '<line id>|1' (the face to the left of its A → B) or '<line id>|-1' (the right) */
363
+ export type SelType = 'point' | 'line' | 'circle' | 'arc' | 'cons' | 'dim' | 'room' | 'opening' | 'odim' | 'oanchor' | 'note' | 'underlay' | 'cab' | 'elev' | 'wface';
199
364
  export interface SelItem {
200
365
  type: SelType;
201
366
  id: string;
@@ -6,7 +6,39 @@ export interface WallFace {
6
6
  /** neighbouring walls on this side, cut where they meet the face: their extent in s */
7
7
  strips: [number, number][];
8
8
  }
9
+ /**
10
+ * A wall meeting one end of another (not a guide), and its thickness: a straight one, by the point it runs out to
11
+ * (`far`); a curved one, by its centre and which way it leaves the corner (`ccw`: counter-clockwise, from its start).
12
+ */
13
+ export interface FaceEnd {
14
+ thick: number;
15
+ far?: string;
16
+ arc?: {
17
+ c: string;
18
+ ccw: boolean;
19
+ };
20
+ }
21
+ /** The walls meeting each end of a wall. */
22
+ export interface FaceEnds {
23
+ a: FaceEnd[];
24
+ b: FaceEnd[];
25
+ }
26
+ /**
27
+ * The walls meeting each end of a wall: those it shares the point with, and those its end sits on partway along (a T —
28
+ * a wall run up to the middle of another). One partway along runs out both ways from the end, as if it were split
29
+ * there, so the faces either side of the end stop at its near face. (A curved wall's end on its centreline, as snapping
30
+ * puts it: its radius is taken from there.)
31
+ */
32
+ export declare function faceEnds(sk: Sketch, lid: string): FaceEnds;
33
+ /**
34
+ * One face of a straight wall from A to B, `t` thick: `side` +1 the face to the left of A → B, −1 the right. The
35
+ * walls at its ends (`ends`) and every point are looked up by `pt` — the sketch's own, or a solve's trial positions
36
+ * (a face dimension is solved through this). Null if A and B are one point.
37
+ */
38
+ export declare function faceSpan(pt: (id: string) => XY, A: XY, B: XY, t: number, side: 1 | -1, ends: FaceEnds): WallFace | null;
9
39
  /** One face of straight wall `lid`: `side` +1 is the face to the left of A → B, −1 the right. Null if it isn't a usable line. */
10
40
  export declare function wallFace(sk: Sketch, lid: string, side: 1 | -1): WallFace | null;
41
+ /** How long one face of a wall is, corner to corner (what a tape measure along it reads); its centreline if it's not a wall. */
42
+ export declare function faceLength(sk: Sketch, lid: string, side: 1 | -1): number;
11
43
  /** A face corner as a point: on the face (half the wall's thickness off the centerline) at the corner. */
12
44
  export declare function faceCorner(sk: Sketch, lid: string, side: 1 | -1, end: 'a' | 'b'): XY | null;
@@ -1,17 +1,83 @@
1
1
  import { hyp } from './geom';
2
- /** One face of straight wall `lid`: `side` +1 is the face to the left of A → B, −1 the right. Null if it isn't a usable line. */
3
- export function wallFace(sk, lid, side) {
4
- const l = sk.lines[lid];
5
- if (!l)
6
- return null;
7
- const A = sk.points[l.a], B = sk.points[l.b];
2
+ /** How close (inches) counts as the same place, for a wall's end on another wall. */
3
+ const ON = 1e-3;
4
+ /**
5
+ * The walls meeting each end of a wall: those it shares the point with, and those its end sits on partway along (a T —
6
+ * a wall run up to the middle of another). One partway along runs out both ways from the end, as if it were split
7
+ * there, so the faces either side of the end stop at its near face. (A curved wall's end on its centreline, as snapping
8
+ * puts it: its radius is taken from there.)
9
+ */
10
+ export function faceEnds(sk, lid) {
11
+ const l = sk.lines[lid], out = { a: [], b: [] };
12
+ for (const end of ['a', 'b']) {
13
+ const pid = l[end], P = sk.points[pid], list = out[end];
14
+ for (const id in sk.lines) {
15
+ const n = sk.lines[id];
16
+ if (id === lid || n.kind !== 'wall' || n.constr)
17
+ continue;
18
+ if (n.a === pid || n.b === pid)
19
+ list.push({ far: n.a === pid ? n.b : n.a, thick: n.thick });
20
+ else if (P && alongWall(sk, n, P))
21
+ list.push({ far: n.a, thick: n.thick }, { far: n.b, thick: n.thick });
22
+ }
23
+ // (an arc runs counter-clockwise from its start, a, to its end, b; one drawn as a wall without a thickness is 4½")
24
+ for (const id in sk.arcs) {
25
+ const n = sk.arcs[id], t = n.thick || 4.5;
26
+ if (n.kind !== 'wall' || n.constr)
27
+ continue;
28
+ if (n.a === pid || n.b === pid) {
29
+ list.push({ arc: { c: n.c, ccw: n.a === pid }, thick: t });
30
+ continue;
31
+ }
32
+ const C = sk.points[n.c], S = sk.points[n.a];
33
+ if (P && C && S && alongCurve(sk, n.c, hyp(S.x - C.x, S.y - C.y), t, P, n))
34
+ list.push({ arc: { c: n.c, ccw: true }, thick: t }, { arc: { c: n.c, ccw: false }, thick: t });
35
+ }
36
+ for (const id in sk.circles) {
37
+ const n = sk.circles[id], t = n.thick || 4.5;
38
+ if (n.kind !== 'wall' || n.constr)
39
+ continue;
40
+ if (P && alongCurve(sk, n.c, n.r, t, P))
41
+ list.push({ arc: { c: n.c, ccw: true }, thick: t }, { arc: { c: n.c, ccw: false }, thick: t });
42
+ }
43
+ }
44
+ return out;
45
+ }
46
+ /** Whether point P is on straight wall `n` partway along it (within its thickness, short of its ends). */
47
+ function alongWall(sk, n, P) {
48
+ const A = sk.points[n.a], B = sk.points[n.b];
8
49
  if (!A || !B)
9
- return null;
50
+ return false;
51
+ const L = hyp(B.x - A.x, B.y - A.y);
52
+ if (L < ON)
53
+ return false;
54
+ const s = ((P.x - A.x) * (B.x - A.x) + (P.y - A.y) * (B.y - A.y)) / L, off = Math.abs((B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)) / L;
55
+ return s > ON && s < L - ON && off <= n.thick / 2 + ON;
56
+ }
57
+ /** Whether point P is on a curved wall (centre `c`, radius `r`, `t` thick) partway along it — for an arc, short of its ends. */
58
+ function alongCurve(sk, c, r, t, P, arc) {
59
+ const C = sk.points[c];
60
+ if (!C || r < ON || Math.abs(hyp(P.x - C.x, P.y - C.y) - r) > t / 2 + ON)
61
+ return false;
62
+ if (!arc)
63
+ return true;
64
+ const A = sk.points[arc.a], B = sk.points[arc.b];
65
+ if (!A || !B)
66
+ return false;
67
+ const turn = (v) => ((v % (2 * Math.PI)) + 2 * Math.PI) % (2 * Math.PI);
68
+ const t0 = Math.atan2(A.y - C.y, A.x - C.x), sweep = turn(Math.atan2(B.y - C.y, B.x - C.x) - t0), at = turn(Math.atan2(P.y - C.y, P.x - C.x) - t0);
69
+ return at * r > ON && at < sweep && (sweep - at) * r > ON;
70
+ }
71
+ /**
72
+ * One face of a straight wall from A to B, `t` thick: `side` +1 the face to the left of A → B, −1 the right. The
73
+ * walls at its ends (`ends`) and every point are looked up by `pt` — the sketch's own, or a solve's trial positions
74
+ * (a face dimension is solved through this). Null if A and B are one point.
75
+ */
76
+ export function faceSpan(pt, A, B, t, side, ends) {
10
77
  const L = hyp(B.x - A.x, B.y - A.y);
11
78
  if (L < 1e-6)
12
79
  return null;
13
80
  const ux = (B.x - A.x) / L, uy = (B.y - A.y) / L, nx = -uy * side, ny = ux * side;
14
- const t = l.kind === 'wall' ? l.thick : 0;
15
81
  const F = { x: A.x + nx * (t / 2), y: A.y + ny * (t / 2) };
16
82
  /** Where the face line (F + û s) crosses each face of a neighbouring wall leaving `P` in direction d. */
17
83
  const crossings = (P, d, tn) => {
@@ -25,20 +91,52 @@ export function wallFace(sk, lid, side) {
25
91
  const s1 = at(tn / 2), s2 = at(-tn / 2);
26
92
  return [Math.min(s1, s2), Math.max(s1, s2)];
27
93
  };
94
+ /**
95
+ * Where the face line crosses each face of a curved wall leaving `P` in direction d (its tangent there) around centre
96
+ * `C`: the circles half its thickness either side of it, each where it crosses nearest the corner (`sP`, s at P). A
97
+ * face the line misses is taken along the tangent, as a straight wall's would be.
98
+ */
99
+ const arcCrossings = (P, C, d, tn, sP, ccw) => {
100
+ const den = ux * d[1] - uy * d[0];
101
+ if (Math.abs(den) < 0.05)
102
+ return null; // (it carries on in line with the face, as a fillet does: no corner)
103
+ const R = hyp(P.x - C.x, P.y - C.y), fx = F.x - C.x, fy = F.y - C.y, b = ux * fx + uy * fy;
104
+ /** Along the tangent: where the face line crosses the line k to its left (a straight wall's face). */
105
+ const along = (k) => { const Q = { x: P.x - d[1] * k, y: P.y + d[0] * k }; return ((Q.x - F.x) * d[1] - (Q.y - F.y) * d[0]) / den; };
106
+ /** Where the face line crosses the circle of radius rho (k: the same face along the tangent, if it misses it). */
107
+ const at = (rho, k) => {
108
+ const disc = b * b - (fx * fx + fy * fy - rho * rho);
109
+ if (rho <= 0 || disc < 0)
110
+ return along(k);
111
+ const r1 = -b - Math.sqrt(disc), r2 = -b + Math.sqrt(disc);
112
+ return Math.abs(r1 - sP) <= Math.abs(r2 - sP) ? r1 : r2;
113
+ };
114
+ // (left of the tangent is toward the centre for an arc leaving counter-clockwise: its inner face)
115
+ const s1 = at(R + tn / 2, ccw ? -tn / 2 : tn / 2), s2 = at(R - tn / 2, ccw ? tn / 2 : -tn / 2);
116
+ return [Math.min(s1, s2), Math.max(s1, s2)];
117
+ };
28
118
  const strips = [];
29
119
  /** One end of the face: s of the corner, collecting the neighbouring walls cut on this side. */
30
- const end = (pid, atStart) => {
120
+ const end = (P, walls, atStart) => {
31
121
  let toward = null, away = null;
32
- const P = sk.points[pid];
33
- for (const id in sk.lines) {
34
- const n = sk.lines[id];
35
- if (id === lid || n.kind !== 'wall' || n.constr || (n.a !== pid && n.b !== pid))
36
- continue;
37
- const Q = sk.points[n.a === pid ? n.b : n.a], Ln = hyp(Q.x - P.x, Q.y - P.y);
38
- if (Ln < 1e-6)
39
- continue;
40
- const d = [(Q.x - P.x) / Ln, (Q.y - P.y) / Ln];
41
- const c = crossings(P, d, n.thick);
122
+ for (const n of walls) {
123
+ let d, c;
124
+ if (n.arc) {
125
+ // a curved wall: it leaves the corner along its tangent there
126
+ const C = pt(n.arc.c), R = hyp(P.x - C.x, P.y - C.y);
127
+ if (R < 1e-6)
128
+ continue;
129
+ const k = n.arc.ccw ? 1 : -1;
130
+ d = [(-(P.y - C.y) / R) * k, ((P.x - C.x) / R) * k];
131
+ c = arcCrossings(P, C, d, n.thick, atStart ? 0 : L, n.arc.ccw);
132
+ }
133
+ else {
134
+ const Q = pt(n.far), Ln = hyp(Q.x - P.x, Q.y - P.y);
135
+ if (Ln < 1e-6)
136
+ continue;
137
+ d = [(Q.x - P.x) / Ln, (Q.y - P.y) / Ln];
138
+ c = crossings(P, d, n.thick);
139
+ }
42
140
  if (!c)
43
141
  continue;
44
142
  if (d[0] * nx + d[1] * ny > 0) {
@@ -55,7 +153,22 @@ export function wallFace(sk, lid, side) {
55
153
  }
56
154
  return toward ?? away ?? (atStart ? 0 : L);
57
155
  };
58
- return { s0: end(l.a, true), s1: end(l.b, false), strips };
156
+ return { s0: end(A, ends.a, true), s1: end(B, ends.b, false), strips };
157
+ }
158
+ /** One face of straight wall `lid`: `side` +1 is the face to the left of A → B, −1 the right. Null if it isn't a usable line. */
159
+ export function wallFace(sk, lid, side) {
160
+ const l = sk.lines[lid];
161
+ if (!l)
162
+ return null;
163
+ const A = sk.points[l.a], B = sk.points[l.b];
164
+ if (!A || !B)
165
+ return null;
166
+ return faceSpan(id => sk.points[id], A, B, l.kind === 'wall' ? l.thick : 0, side, faceEnds(sk, lid));
167
+ }
168
+ /** How long one face of a wall is, corner to corner (what a tape measure along it reads); its centreline if it's not a wall. */
169
+ export function faceLength(sk, lid, side) {
170
+ const f = wallFace(sk, lid, side);
171
+ return f ? f.s1 - f.s0 : 0;
59
172
  }
60
173
  /** A face corner as a point: on the face (half the wall's thickness off the centerline) at the corner. */
61
174
  export function faceCorner(sk, lid, side, end) {
@@ -1 +1 @@
1
- {"version":3,"file":"wallfaces.js","sourceRoot":"","sources":["../../src/model/wallfaces.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"wallfaces.js","sourceRoot":"","sources":["../../src/model/wallfaces.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { Sketch, XY } from './types';
2
+ /** A piece of wall to fill: a straight wall (`id`), or a bevel at a sharp joint (`of`: a wall it belongs to). */
3
+ export interface WallPiece {
4
+ id: string | null;
5
+ of: string;
6
+ pts: XY[];
7
+ }
8
+ /**
9
+ * The pieces to fill for the sketch's straight walls (`show`: which to include, e.g. not hidden construction walls).
10
+ * Each wall's outline runs: its start's right corner, its end's right corner, (its end point, at a joint), its end's
11
+ * left corner, its start's left corner, (its start point, at a joint) — right and left as seen going from start to end.
12
+ */
13
+ export declare function wallPieces(sk: Sketch, show?: (w: {
14
+ constr?: boolean;
15
+ }) => boolean): WallPiece[];
@@ -0,0 +1,89 @@
1
+ import { hyp } from './geom';
2
+ const left = (u) => ({ x: -u.y, y: u.x });
3
+ const right = (u) => ({ x: u.y, y: -u.x });
4
+ const at = (p, n, k) => ({ x: p.x + n.x * k, y: p.y + n.y * k });
5
+ /** Where two lines (a point and a direction each) cross; for parallel ones, the middle of the two points if they're the same line, else null. */
6
+ function cross(p1, d1, p2, d2) {
7
+ const c = d1.x * d2.y - d1.y * d2.x;
8
+ if (Math.abs(c) < 1e-9) {
9
+ const off = Math.abs((p2.x - p1.x) * d1.y - (p2.y - p1.y) * d1.x);
10
+ return off < 1e-6 ? { x: (p1.x + p2.x) / 2, y: (p1.y + p2.y) / 2 } : null;
11
+ }
12
+ const l = ((p2.x - p1.x) * d2.y - (p2.y - p1.y) * d2.x) / c;
13
+ return { x: p1.x + d1.x * l, y: p1.y + d1.y * l };
14
+ }
15
+ /**
16
+ * The pieces to fill for the sketch's straight walls (`show`: which to include, e.g. not hidden construction walls).
17
+ * Each wall's outline runs: its start's right corner, its end's right corner, (its end point, at a joint), its end's
18
+ * left corner, its start's left corner, (its start point, at a joint) — right and left as seen going from start to end.
19
+ */
20
+ export function wallPieces(sk, show = () => true) {
21
+ const walls = Object.entries(sk.lines).filter(([, l]) => l.kind === 'wall' && show(l));
22
+ // what meets at each point: straight walls (their direction away from it) and whether a curved wall does
23
+ /** at each point a curved wall ends: the centres of those curves */
24
+ const ends = new Map(), curved = new Map();
25
+ for (const [id, l] of walls) {
26
+ const A = sk.points[l.a], B = sk.points[l.b], L = hyp(B.x - A.x, B.y - A.y);
27
+ if (L < 1e-9)
28
+ continue;
29
+ const u = { x: (B.x - A.x) / L, y: (B.y - A.y) / L };
30
+ (ends.get(l.a) ?? ends.set(l.a, []).get(l.a)).push({ id, u, t: l.thick });
31
+ (ends.get(l.b) ?? ends.set(l.b, []).get(l.b)).push({ id, u: { x: -u.x, y: -u.y }, t: l.thick });
32
+ }
33
+ for (const a of Object.values(sk.arcs)) {
34
+ if (a.kind !== 'wall' || !show(a))
35
+ continue;
36
+ for (const p of [a.a, a.b])
37
+ (curved.get(p) ?? curved.set(p, []).get(p)).push(sk.points[a.c]);
38
+ }
39
+ /** whether a straight wall leaving P along u runs on into a curve there (tangent to it: a fillet) */
40
+ const tangent = (pid, u) => {
41
+ const P = sk.points[pid];
42
+ return (curved.get(pid) ?? []).every(o => Math.abs(u.x * (P.x - o.x) + u.y * (P.y - o.y)) < 0.02 * (hyp(P.x - o.x, P.y - o.y) || 1));
43
+ };
44
+ /** each wall end's two corners: [left, right] as seen going away from the point; joint: whether the point itself is part of its outline */
45
+ const corners = new Map();
46
+ const bevels = [];
47
+ for (const [pid, list] of ends) {
48
+ const P = sk.points[pid];
49
+ if (list.length === 1 || curved.has(pid)) {
50
+ // a free end is square, and so is one running on into a curve (a fillet: the curve's end is square to it too);
51
+ // next to a curve at an angle, run on half the thickness so the two overlap
52
+ for (const e of list) {
53
+ const Q = curved.has(pid) && !tangent(pid, e.u) ? at(P, e.u, -e.t / 2) : P;
54
+ corners.set(e.id + '|' + pid, { l: at(Q, left(e.u), e.t / 2), r: at(Q, right(e.u), e.t / 2), joint: false });
55
+ }
56
+ continue;
57
+ }
58
+ // walls around the point, counter-clockwise; between each and the next, the corner where their sides cross
59
+ const sorted = [...list].sort((p, q) => Math.atan2(p.u.y, p.u.x) - Math.atan2(q.u.y, q.u.x));
60
+ const ccw = new Map(), cw = new Map();
61
+ for (let i = 0; i < sorted.length; i++) {
62
+ const a = sorted[i], b = sorted[(i + 1) % sorted.length];
63
+ const ea = at(P, left(a.u), a.t / 2), eb = at(P, right(b.u), b.t / 2);
64
+ const c = cross(ea, a.u, eb, b.u), limit = 2 * Math.max(a.t, b.t);
65
+ if (c && hyp(c.x - P.x, c.y - P.y) <= limit) {
66
+ ccw.set(i, c);
67
+ cw.set((i + 1) % sorted.length, c);
68
+ continue;
69
+ }
70
+ // too sharp (or parallel sides that don't meet): each side stops square, and a bevel closes the corner
71
+ ccw.set(i, ea);
72
+ cw.set((i + 1) % sorted.length, eb);
73
+ if (hyp(ea.x - eb.x, ea.y - eb.y) > 1e-6)
74
+ bevels.push({ id: null, of: a.id, pts: [P, ea, eb] });
75
+ }
76
+ sorted.forEach((e, i) => corners.set(e.id + '|' + pid, { l: ccw.get(i), r: cw.get(i), joint: true }));
77
+ }
78
+ const out = [];
79
+ for (const [id, l] of walls) {
80
+ const a = corners.get(id + '|' + l.a), b = corners.get(id + '|' + l.b);
81
+ if (!a || !b)
82
+ continue;
83
+ // at the start, away from it is along the wall; at the end, back along it — so its left is the wall's right
84
+ const pts = [a.r, b.l, ...(b.joint ? [sk.points[l.b]] : []), b.r, a.l, ...(a.joint ? [sk.points[l.a]] : [])];
85
+ out.push({ id, of: id, pts: pts.map(p => ({ x: p.x, y: p.y })) });
86
+ }
87
+ return [...out, ...bevels];
88
+ }
89
+ //# sourceMappingURL=wallshape.js.map