matterviz 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (326) hide show
  1. package/dist/brillouin/BrillouinZone.svelte +68 -145
  2. package/dist/brillouin/BrillouinZone.svelte.d.ts +5 -14
  3. package/dist/brillouin/BrillouinZoneExportPane.svelte +43 -96
  4. package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +1 -1
  5. package/dist/brillouin/BrillouinZoneInfoPane.svelte +9 -32
  6. package/dist/brillouin/BrillouinZoneInfoPane.svelte.d.ts +2 -3
  7. package/dist/brillouin/BrillouinZoneScene.svelte +49 -203
  8. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +3 -23
  9. package/dist/brillouin/ReciprocalVectors.svelte +39 -0
  10. package/dist/brillouin/ReciprocalVectors.svelte.d.ts +9 -0
  11. package/dist/brillouin/compute.d.ts +2 -0
  12. package/dist/brillouin/compute.js +80 -77
  13. package/dist/brillouin/geometry.d.ts +8 -0
  14. package/dist/brillouin/geometry.js +57 -0
  15. package/dist/brillouin/index.d.ts +2 -0
  16. package/dist/brillouin/index.js +2 -0
  17. package/dist/brillouin/types.d.ts +2 -2
  18. package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +1 -1
  19. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +100 -191
  20. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +4 -1
  21. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +176 -464
  22. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +7 -1
  23. package/dist/chempot-diagram/color.d.ts +3 -6
  24. package/dist/chempot-diagram/color.js +5 -5
  25. package/dist/chempot-diagram/compute.d.ts +3 -3
  26. package/dist/chempot-diagram/compute.js +3 -1
  27. package/dist/chempot-diagram/controls-state.svelte.d.ts +10 -0
  28. package/dist/chempot-diagram/controls-state.svelte.js +42 -0
  29. package/dist/chempot-diagram/export.d.ts +47 -0
  30. package/dist/chempot-diagram/export.js +133 -0
  31. package/dist/chempot-diagram/index.d.ts +1 -0
  32. package/dist/chempot-diagram/index.js +1 -0
  33. package/dist/chempot-diagram/pointer.d.ts +0 -10
  34. package/dist/chempot-diagram/pointer.js +4 -4
  35. package/dist/chempot-diagram/types.d.ts +3 -3
  36. package/dist/colors/index.js +2 -2
  37. package/dist/composition/FormulaFilter.svelte +6 -5
  38. package/dist/composition/PieChart.svelte +5 -5
  39. package/dist/composition/chem-sys.js +3 -2
  40. package/dist/composition/format.js +3 -2
  41. package/dist/composition/parse.d.ts +0 -1
  42. package/dist/composition/parse.js +17 -19
  43. package/dist/controls.d.ts +1 -0
  44. package/dist/controls.js +0 -1
  45. package/dist/convex-hull/ConvexHull.svelte +8 -10
  46. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -4
  47. package/dist/convex-hull/ConvexHull2D.svelte +94 -175
  48. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  49. package/dist/convex-hull/ConvexHull3D.svelte +176 -680
  50. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  51. package/dist/convex-hull/ConvexHull4D.svelte +180 -680
  52. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  53. package/dist/convex-hull/ConvexHullChrome.svelte +268 -0
  54. package/dist/convex-hull/ConvexHullChrome.svelte.d.ts +30 -0
  55. package/dist/convex-hull/ConvexHullControls.svelte +88 -7
  56. package/dist/convex-hull/ConvexHullControls.svelte.d.ts +7 -6
  57. package/dist/convex-hull/ConvexHullInfoPane.svelte +18 -5
  58. package/dist/convex-hull/ConvexHullInfoPane.svelte.d.ts +6 -5
  59. package/dist/convex-hull/ConvexHullStats.svelte +29 -168
  60. package/dist/convex-hull/ConvexHullStats.svelte.d.ts +3 -1
  61. package/dist/convex-hull/ConvexHullTooltip.svelte +11 -2
  62. package/dist/convex-hull/ConvexHullTooltip.svelte.d.ts +2 -1
  63. package/dist/convex-hull/barycentric-coords.d.ts +2 -4
  64. package/dist/convex-hull/barycentric-coords.js +6 -33
  65. package/dist/convex-hull/canvas-interactions.svelte.d.ts +79 -0
  66. package/dist/convex-hull/canvas-interactions.svelte.js +278 -0
  67. package/dist/convex-hull/helpers.d.ts +39 -7
  68. package/dist/convex-hull/helpers.js +154 -69
  69. package/dist/convex-hull/hull-state.svelte.d.ts +44 -0
  70. package/dist/convex-hull/hull-state.svelte.js +124 -0
  71. package/dist/convex-hull/index.d.ts +9 -7
  72. package/dist/convex-hull/index.js +7 -2
  73. package/dist/convex-hull/thermodynamics.js +91 -920
  74. package/dist/convex-hull/types.d.ts +12 -4
  75. package/dist/convex-hull/types.js +12 -0
  76. package/dist/coordination/CoordinationBarPlot.svelte +4 -11
  77. package/dist/element/BohrAtom.svelte +2 -1
  78. package/dist/element/ElementTile.svelte.d.ts +1 -1
  79. package/dist/element/index.d.ts +4 -0
  80. package/dist/element/index.js +18 -0
  81. package/dist/feedback/DragOverlay.svelte +3 -1
  82. package/dist/feedback/DragOverlay.svelte.d.ts +1 -0
  83. package/dist/feedback/StatusMessage.svelte +13 -3
  84. package/dist/fermi-surface/FermiSurface.svelte +67 -146
  85. package/dist/fermi-surface/FermiSurface.svelte.d.ts +5 -14
  86. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
  87. package/dist/fermi-surface/FermiSurfaceScene.svelte +72 -224
  88. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +3 -23
  89. package/dist/fermi-surface/compute.js +11 -10
  90. package/dist/fermi-surface/export.js +4 -15
  91. package/dist/fermi-surface/index.d.ts +0 -1
  92. package/dist/fermi-surface/index.js +0 -1
  93. package/dist/fermi-surface/parse.d.ts +1 -1
  94. package/dist/fermi-surface/parse.js +64 -75
  95. package/dist/fermi-surface/types.d.ts +2 -2
  96. package/dist/heatmap-matrix/HeatmapMatrix.svelte +55 -40
  97. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +4 -3
  98. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +3 -2
  99. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +5 -5
  100. package/dist/heatmap-matrix/index.d.ts +3 -2
  101. package/dist/index.d.ts +1 -0
  102. package/dist/index.js +1 -0
  103. package/dist/io/ExportPane.svelte +166 -0
  104. package/dist/io/ExportPane.svelte.d.ts +17 -0
  105. package/dist/io/decompress.js +1 -2
  106. package/dist/io/export.d.ts +5 -1
  107. package/dist/io/export.js +32 -28
  108. package/dist/io/fetch.d.ts +2 -1
  109. package/dist/io/file-drop.d.ts +7 -0
  110. package/dist/io/file-drop.js +13 -0
  111. package/dist/io/index.d.ts +2 -0
  112. package/dist/io/index.js +10 -0
  113. package/dist/io/types.d.ts +13 -0
  114. package/dist/isosurface/parse.js +46 -44
  115. package/dist/labels.js +1 -1
  116. package/dist/layout/FullscreenButton.svelte +33 -0
  117. package/dist/layout/FullscreenButton.svelte.d.ts +10 -0
  118. package/dist/layout/FullscreenToggle.svelte +8 -14
  119. package/dist/layout/ViewerChrome.svelte +116 -0
  120. package/dist/layout/ViewerChrome.svelte.d.ts +17 -0
  121. package/dist/layout/fullscreen.d.ts +4 -0
  122. package/dist/layout/fullscreen.svelte.d.ts +8 -0
  123. package/dist/layout/fullscreen.svelte.js +37 -0
  124. package/dist/layout/index.d.ts +3 -0
  125. package/dist/layout/index.js +3 -0
  126. package/dist/math.d.ts +7 -3
  127. package/dist/math.js +18 -21
  128. package/dist/overlays/index.d.ts +4 -0
  129. package/dist/periodic-table/PeriodicTable.svelte +9 -8
  130. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +1 -1
  131. package/dist/phase-diagram/PhaseDiagramControls.svelte +3 -2
  132. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +4 -3
  133. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +2 -1
  134. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +2 -3
  135. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +47 -132
  136. package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +3 -4
  137. package/dist/phase-diagram/colors.js +1 -1
  138. package/dist/phase-diagram/parse.d.ts +2 -1
  139. package/dist/plot/bar/BarPlot.svelte +79 -316
  140. package/dist/plot/bar/BarPlot.svelte.d.ts +7 -15
  141. package/dist/plot/bar/BarPlotControls.svelte.d.ts +1 -1
  142. package/dist/plot/bar/SpacegroupBarPlot.svelte +2 -1
  143. package/dist/plot/box/BoxPlot.svelte +76 -246
  144. package/dist/plot/box/BoxPlot.svelte.d.ts +4 -3
  145. package/dist/plot/box/BoxPlotControls.svelte.d.ts +1 -1
  146. package/dist/plot/box/Violin.svelte.d.ts +1 -1
  147. package/dist/plot/box/box-plot.d.ts +3 -2
  148. package/dist/plot/box/box-plot.js +5 -2
  149. package/dist/plot/box/kde.d.ts +2 -1
  150. package/dist/plot/box/kde.js +4 -4
  151. package/dist/plot/core/auto-place.d.ts +1 -1
  152. package/dist/plot/core/auto-place.js +4 -1
  153. package/dist/plot/core/components/ColorBar.svelte +5 -5
  154. package/dist/plot/core/components/ColorBar.svelte.d.ts +5 -4
  155. package/dist/plot/core/components/Line.svelte +3 -2
  156. package/dist/plot/core/components/Line.svelte.d.ts +3 -2
  157. package/dist/plot/core/components/PlotAxis.svelte +2 -1
  158. package/dist/plot/core/components/PlotAxis.svelte.d.ts +2 -1
  159. package/dist/plot/core/components/PlotControls.svelte.d.ts +1 -1
  160. package/dist/plot/core/components/ReferenceLine3D.svelte +2 -2
  161. package/dist/plot/core/components/ReferenceLine3D.svelte.d.ts +4 -4
  162. package/dist/plot/core/components/ReferencePlane.svelte +2 -2
  163. package/dist/plot/core/components/ReferencePlane.svelte.d.ts +4 -4
  164. package/dist/plot/core/data-cleaning.js +18 -18
  165. package/dist/plot/core/fill-utils.d.ts +4 -3
  166. package/dist/plot/core/fill-utils.js +6 -3
  167. package/dist/plot/core/interactions.d.ts +5 -1
  168. package/dist/plot/core/interactions.js +14 -0
  169. package/dist/plot/core/pan-zoom.svelte.d.ts +35 -0
  170. package/dist/plot/core/pan-zoom.svelte.js +221 -0
  171. package/dist/plot/core/placed-tween.svelte.d.ts +21 -0
  172. package/dist/plot/core/placed-tween.svelte.js +68 -0
  173. package/dist/plot/core/reference-line.d.ts +10 -10
  174. package/dist/plot/core/reference-line.js +6 -6
  175. package/dist/plot/core/scales.d.ts +17 -25
  176. package/dist/plot/core/scales.js +10 -8
  177. package/dist/plot/core/svg.d.ts +2 -1
  178. package/dist/plot/core/types.d.ts +18 -7
  179. package/dist/plot/core/utils/label-placement.d.ts +1 -1
  180. package/dist/plot/core/utils/label-placement.js +3 -3
  181. package/dist/plot/core/utils.d.ts +2 -1
  182. package/dist/plot/histogram/Histogram.svelte +77 -314
  183. package/dist/plot/histogram/HistogramControls.svelte.d.ts +1 -1
  184. package/dist/plot/sankey/Sankey.svelte +2 -5
  185. package/dist/plot/sankey/Sankey.svelte.d.ts +1 -1
  186. package/dist/plot/sankey/sankey.js +3 -1
  187. package/dist/plot/scatter/BinnedScatterPlot.svelte +3 -5
  188. package/dist/plot/scatter/BinnedScatterPlot.svelte.d.ts +4 -4
  189. package/dist/plot/scatter/ScatterPlot.svelte +160 -450
  190. package/dist/plot/scatter/ScatterPlot.svelte.d.ts +7 -15
  191. package/dist/plot/scatter/ScatterPlotControls.svelte.d.ts +1 -1
  192. package/dist/plot/scatter/binned-scatter-types.d.ts +4 -11
  193. package/dist/plot/scatter/index.d.ts +1 -1
  194. package/dist/plot/scatter-3d/ScatterPlot3D.svelte +15 -26
  195. package/dist/plot/scatter-3d/ScatterPlot3D.svelte.d.ts +6 -14
  196. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte +9 -10
  197. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte.d.ts +5 -5
  198. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte +122 -121
  199. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte.d.ts +5 -14
  200. package/dist/plot/scatter-3d/Surface3D.svelte +6 -5
  201. package/dist/plot/scatter-3d/Surface3D.svelte.d.ts +4 -3
  202. package/dist/plot/sunburst/Sunburst.svelte +16 -20
  203. package/dist/plot/sunburst/Sunburst.svelte.d.ts +4 -3
  204. package/dist/plot/sunburst/SunburstControls.svelte.d.ts +1 -1
  205. package/dist/plot/sunburst/sunburst.js +4 -1
  206. package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
  207. package/dist/sanitize.js +13 -2
  208. package/dist/scene/SceneCamera.svelte +62 -0
  209. package/dist/scene/SceneCamera.svelte.d.ts +19 -0
  210. package/dist/scene/bind-renderer.svelte.d.ts +2 -0
  211. package/dist/scene/bind-renderer.svelte.js +14 -0
  212. package/dist/scene/index.d.ts +4 -0
  213. package/dist/scene/index.js +5 -0
  214. package/dist/scene/props.js +52 -0
  215. package/dist/scene/types.d.ts +26 -0
  216. package/dist/scene/types.js +1 -0
  217. package/dist/settings.d.ts +14 -2
  218. package/dist/settings.js +59 -1
  219. package/dist/spectral/Bands.svelte +8 -7
  220. package/dist/spectral/Bands.svelte.d.ts +3 -2
  221. package/dist/spectral/BandsAndDos.svelte +22 -24
  222. package/dist/spectral/BrillouinBandsDos.svelte +3 -3
  223. package/dist/spectral/Dos.svelte +5 -4
  224. package/dist/spectral/Dos.svelte.d.ts +2 -1
  225. package/dist/spectral/helpers.d.ts +6 -6
  226. package/dist/spectral/helpers.js +43 -37
  227. package/dist/state.svelte.d.ts +0 -7
  228. package/dist/state.svelte.js +0 -6
  229. package/dist/structure/Arrow.svelte +2 -4
  230. package/dist/structure/AtomLegend.svelte.d.ts +1 -1
  231. package/dist/structure/CanvasTooltip.svelte +1 -0
  232. package/dist/structure/CellSelect.svelte +11 -3
  233. package/dist/structure/CellSelect.svelte.d.ts +2 -1
  234. package/dist/structure/Lattice.svelte +2 -2
  235. package/dist/structure/Structure.svelte +291 -355
  236. package/dist/structure/Structure.svelte.d.ts +5 -15
  237. package/dist/structure/StructureControls.svelte +217 -2
  238. package/dist/structure/StructureControls.svelte.d.ts +5 -3
  239. package/dist/structure/StructureExportPane.svelte +54 -156
  240. package/dist/structure/StructureExportPane.svelte.d.ts +4 -5
  241. package/dist/structure/StructureInfoPane.svelte +5 -3
  242. package/dist/structure/StructureInfoPane.svelte.d.ts +5 -5
  243. package/dist/structure/StructureScene.svelte +365 -198
  244. package/dist/structure/StructureScene.svelte.d.ts +22 -20
  245. package/dist/structure/{label-placement.d.ts → atom-label-placement.d.ts} +3 -3
  246. package/dist/structure/{label-placement.js → atom-label-placement.js} +12 -2
  247. package/dist/structure/atom-properties.d.ts +1 -1
  248. package/dist/structure/atom-properties.js +11 -16
  249. package/dist/structure/bond-order-perception.js +2 -4
  250. package/dist/structure/bonding.d.ts +3 -0
  251. package/dist/structure/bonding.js +91 -48
  252. package/dist/structure/export.d.ts +24 -4
  253. package/dist/structure/export.js +64 -122
  254. package/dist/structure/index.d.ts +2 -0
  255. package/dist/structure/index.js +2 -0
  256. package/dist/structure/parse.d.ts +3 -2
  257. package/dist/structure/parse.js +333 -370
  258. package/dist/structure/partial-occupancy.d.ts +0 -1
  259. package/dist/structure/partial-occupancy.js +1 -1
  260. package/dist/structure/pbc.d.ts +1 -1
  261. package/dist/structure/pbc.js +186 -13
  262. package/dist/structure/polyhedra.d.ts +41 -0
  263. package/dist/structure/polyhedra.js +602 -0
  264. package/dist/structure/site.d.ts +4 -0
  265. package/dist/structure/site.js +1 -0
  266. package/dist/structure/supercell.js +3 -2
  267. package/dist/structure/validation.js +5 -6
  268. package/dist/symmetry/SymmetryElementControls.svelte +69 -0
  269. package/dist/symmetry/SymmetryElementControls.svelte.d.ts +9 -0
  270. package/dist/symmetry/SymmetryElements.svelte +354 -0
  271. package/dist/symmetry/SymmetryElements.svelte.d.ts +24 -0
  272. package/dist/symmetry/SymmetryStats.svelte +111 -6
  273. package/dist/symmetry/WyckoffTable.svelte +68 -7
  274. package/dist/symmetry/WyckoffTable.svelte.d.ts +3 -0
  275. package/dist/symmetry/cell-transform.js +7 -14
  276. package/dist/symmetry/index.d.ts +14 -4
  277. package/dist/symmetry/index.js +301 -80
  278. package/dist/symmetry/spacegroups.d.ts +5 -1
  279. package/dist/symmetry/spacegroups.js +15 -1
  280. package/dist/symmetry/symmetry-elements.d.ts +33 -0
  281. package/dist/symmetry/symmetry-elements.js +521 -0
  282. package/dist/symmetry/wyckoff-db.d.ts +9 -0
  283. package/dist/symmetry/wyckoff-db.js +87 -0
  284. package/dist/table/HeatmapTable.svelte +4 -15
  285. package/dist/table/HeatmapTable.svelte.d.ts +1 -1
  286. package/dist/trajectory/Trajectory.svelte +58 -61
  287. package/dist/trajectory/Trajectory.svelte.d.ts +10 -22
  288. package/dist/trajectory/TrajectoryExportPane.svelte +15 -24
  289. package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +4 -5
  290. package/dist/trajectory/TrajectoryInfoPane.svelte +3 -2
  291. package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +3 -2
  292. package/dist/trajectory/constants.js +6 -2
  293. package/dist/trajectory/extract.js +17 -37
  294. package/dist/trajectory/format-detect.d.ts +0 -1
  295. package/dist/trajectory/format-detect.js +3 -9
  296. package/dist/trajectory/frame-reader.d.ts +0 -1
  297. package/dist/trajectory/frame-reader.js +62 -128
  298. package/dist/trajectory/helpers.d.ts +10 -2
  299. package/dist/trajectory/helpers.js +56 -36
  300. package/dist/trajectory/parse/ase.d.ts +9 -1
  301. package/dist/trajectory/parse/ase.js +47 -32
  302. package/dist/trajectory/parse/diagnostics.d.ts +3 -0
  303. package/dist/trajectory/parse/diagnostics.js +14 -0
  304. package/dist/trajectory/parse/index.d.ts +1 -1
  305. package/dist/trajectory/parse/index.js +54 -102
  306. package/dist/trajectory/parse/lammps.d.ts +0 -2
  307. package/dist/trajectory/parse/lammps.js +8 -6
  308. package/dist/trajectory/parse/pymatgen.d.ts +2 -0
  309. package/dist/trajectory/parse/pymatgen.js +74 -0
  310. package/dist/trajectory/parse/vasp.js +4 -3
  311. package/dist/trajectory/parse/xyz.d.ts +9 -21
  312. package/dist/trajectory/parse/xyz.js +28 -33
  313. package/dist/trajectory/plotting.d.ts +0 -1
  314. package/dist/trajectory/plotting.js +3 -100
  315. package/dist/utils.d.ts +1 -0
  316. package/dist/utils.js +1 -1
  317. package/dist/xrd/XrdPlot.svelte +14 -29
  318. package/dist/xrd/broadening.d.ts +2 -1
  319. package/dist/xrd/calc-xrd.js +6 -11
  320. package/dist/xrd/index.d.ts +2 -2
  321. package/package.json +29 -16
  322. package/dist/element/data.json +0 -11864
  323. package/dist/fermi-surface/marching-cubes.d.ts +0 -2
  324. package/dist/fermi-surface/marching-cubes.js +0 -2
  325. package/dist/plot/core/hover-lock.svelte.d.ts +0 -14
  326. package/dist/plot/core/hover-lock.svelte.js +0 -45
@@ -1,5 +1,4 @@
1
1
  import type { Site } from './';
2
- export declare const PARTIAL_OCCUPANCY_SLICE_GAP_RAD = 0.001;
3
2
  export type RenderSite = {
4
3
  site_idx: number;
5
4
  site: Site;
@@ -1,4 +1,4 @@
1
- export const PARTIAL_OCCUPANCY_SLICE_GAP_RAD = 1e-3;
1
+ const PARTIAL_OCCUPANCY_SLICE_GAP_RAD = 1e-3;
2
2
  const OCCUPANCY_EPS = 1e-6;
3
3
  const MIN_PHI_LENGTH = 1e-4;
4
4
  const MERGE_DISTANCE_TOLERANCE = 1e-8;
@@ -5,5 +5,5 @@ export declare const wrap_frac_coord: (coord: number) => number;
5
5
  export declare const wrap_to_unit_cell: (frac: Vec3) => Vec3;
6
6
  export declare function find_image_atoms(structure: ParsedStructure, { tolerance }?: {
7
7
  tolerance?: number;
8
- }): [number, Vec3, Vec3][];
8
+ }): [number, Vec3, Vec3, boolean?][];
9
9
  export declare function get_pbc_image_sites(...args: Parameters<typeof find_image_atoms>): ParsedStructure;
@@ -1,6 +1,21 @@
1
1
  import * as math from '../math';
2
+ import { element_lookup, get_majority_element } from './bonding';
3
+ // Distance slack added to the covalent-radii sum when deciding whether a
4
+ // candidate image atom bonds to a base atom (VESTA-like bond search criterion)
5
+ const BOND_SLACK = 0.4; // Å
6
+ // Below this separation two sites are overlapping copies, not a bond (matches
7
+ // the min_bond_dist default in bonding.ts)
8
+ const MIN_BOND_DIST = 0.4; // Å
2
9
  // Wrap a single fractional coordinate to [0, 1), clamping near-1 values to 0
3
10
  // and rounding to 15 digits to suppress floating-point noise.
11
+ // NOTE on epsilon: this is the tightest of three intentionally different wrap
12
+ // helpers. Coordinates here come almost straight from file parsing, so float
13
+ // error is tiny and a 1e-10 snap + toFixed(15) preserves maximal precision.
14
+ // Compare wrap_frac @1e-9 [[src/lib/symmetry/index.ts:80]] (post moyo
15
+ // standardization + matrix transforms) and wrap_point @1e-8
16
+ // [[src/lib/symmetry/symmetry-elements.ts:214]] (feeds symmetry-element dedup
17
+ // keys). Do not unify: loosening this epsilon changes snapping near cell
18
+ // boundaries for parsed structures.
4
19
  export const wrap_frac_coord = (coord) => {
5
20
  const wrapped = coord - Math.floor(coord);
6
21
  if (wrapped >= 1 - 1e-10)
@@ -13,17 +28,23 @@ export const wrap_to_unit_cell = (frac) => [
13
28
  wrap_frac_coord(frac[1]),
14
29
  wrap_frac_coord(frac[2]),
15
30
  ];
31
+ // Trajectory-like data: >10% of atoms far outside the unit cell. Image-atom
32
+ // generation is skipped for such structures.
33
+ const is_scattered_trajectory = (sites) => {
34
+ const atoms_outside_cell = sites.filter(({ abc }) => abc.some((coord) => coord < -0.1 || coord > 1.1));
35
+ return atoms_outside_cell.length > sites.length * 0.1;
36
+ };
37
+ // Cartesian position of fractional coords abc in the given lattice (rows = lattice vectors)
38
+ const frac_to_cart_pos = (abc, lattice_vecs) => math.add(math.scale(lattice_vecs[0], abc[0]), math.scale(lattice_vecs[1], abc[1]), math.scale(lattice_vecs[2], abc[2]));
16
39
  export function find_image_atoms(structure, { tolerance } = {}) {
17
- // Find image atoms for PBC. Returns [atom_idx, image_xyz, image_abc] tuples.
40
+ // Find image atoms for PBC. Returns [atom_idx, image_xyz, image_abc, is_completion?]
41
+ // tuples; is_completion marks phase-2 images that exist only to complete bonds /
42
+ // coordination polyhedra at cell faces (renderers may hide them when neither shows).
18
43
  // Skips image generation for trajectory data with scattered atoms.
19
44
  if (!structure.lattice || !structure.sites || structure.sites.length === 0)
20
45
  return [];
21
- // Skip trajectory data (>10% atoms outside cell)
22
- const atoms_outside_cell = structure.sites.filter(({ abc }) => abc.some((coord) => coord < -0.1 || coord > 1.1));
23
- // Skip image generation for trajectory data (>10% atoms outside cell)
24
- if (atoms_outside_cell.length > structure.sites.length * 0.1) {
46
+ if (is_scattered_trajectory(structure.sites))
25
47
  return [];
26
- }
27
48
  // Check if this is a supercell to correctly identify external boundaries correctly
28
49
  const image_sites = [];
29
50
  const lattice_vecs = structure.lattice.matrix;
@@ -87,7 +108,7 @@ export function find_image_atoms(structure, { tolerance } = {}) {
87
108
  img_abc[2] === site.abc[2])
88
109
  continue;
89
110
  // Compute xyz from img_abc to ensure consistency
90
- const img_xyz = math.add(math.scale(lattice_vecs[0], img_abc[0]), math.scale(lattice_vecs[1], img_abc[1]), math.scale(lattice_vecs[2], img_abc[2]));
111
+ const img_xyz = frac_to_cart_pos(img_abc, lattice_vecs);
91
112
  // Skip zero-displacement images (should not happen, guards against FP edge cases)
92
113
  const displacement = math.subtract(img_xyz, site.xyz);
93
114
  const displacement_len_sq = displacement.reduce((sum, val) => sum + val * val, 0);
@@ -96,6 +117,156 @@ export function find_image_atoms(structure, { tolerance } = {}) {
96
117
  image_sites.push([idx, img_xyz, img_abc]);
97
118
  }
98
119
  }
120
+ // Phase 2: polyhedra-completing images (VESTA boundary-mode-like). The face
121
+ // tolerance above only catches atoms within ~0.5 Å of a boundary, but bonds
122
+ // reach a covalent-radii sum further: an anion just beyond a cell face may be
123
+ // needed to complete the coordination shell of a cation near that face, so
124
+ // bonds and coordination polyhedra at cell edges come out truncated without it.
125
+ // Phase 2 adds ONLY such anion images: a candidate must qualify as a polyhedron
126
+ // vertex (a non-metal/metalloid - same condition as is_anion_vertex in
127
+ // polyhedra.ts) and be strictly more electronegative than the anchor atom it
128
+ // bonds to. Everything else - elemental metals, intermetallics (incl. multi
129
+ // metal ones like Al-Fe-Ni where EN differs but no polyhedra exist), equal-EN
130
+ // covalent networks, cation copies - gets no phase-2 images, so the default
131
+ // render stays minimal and grows uniformly from all cell surfaces (the phase-1
132
+ // boundary copies above are the only non-anion atoms outside the cell).
133
+ const site_radii = [];
134
+ const site_en = [];
135
+ const site_is_metal = [];
136
+ let max_radius = 0;
137
+ // Minimum electronegativity among potential anchors: a candidate can only ever
138
+ // complete some cation's shell if it's strictly more electronegative than this
139
+ let min_anchor_en = Infinity;
140
+ for (const site of structure.sites) {
141
+ const elem = get_majority_element(site);
142
+ const data = elem === null ? undefined : element_lookup.get(elem);
143
+ const radius = data?.covalent_radius ?? null;
144
+ const en = data?.electronegativity ?? null;
145
+ site_radii.push(radius);
146
+ site_en.push(en);
147
+ site_is_metal.push(data?.metal === true);
148
+ if (radius !== null && radius > max_radius)
149
+ max_radius = radius;
150
+ if (radius !== null && en !== null && en < min_anchor_en)
151
+ min_anchor_en = en;
152
+ }
153
+ const max_bond_dist = 2 * max_radius + BOND_SLACK;
154
+ if (max_bond_dist > BOND_SLACK && min_anchor_en < Infinity) {
155
+ // Perpendicular cell heights: |frac| * height lower-bounds the Cartesian
156
+ // distance along each axis (valid for oblique cells)
157
+ const volume = Math.abs(math.dot(lattice_vecs[0], math.cross_3d(lattice_vecs[1], lattice_vecs[2])));
158
+ // height = volume / opposite-face area. A zero-volume (degenerate) cell has two
159
+ // parallel lattice vectors and ill-defined heights; treat every axis as
160
+ // infinitely tall so the pad logic below adds no images (pad -> 0) instead of
161
+ // dividing by zero. When volume > 0 the vectors are linearly independent, so no
162
+ // pairwise cross product can be zero.
163
+ const heights = volume === 0
164
+ ? [Infinity, Infinity, Infinity]
165
+ : [
166
+ volume / Math.hypot(...math.cross_3d(lattice_vecs[1], lattice_vecs[2])),
167
+ volume / Math.hypot(...math.cross_3d(lattice_vecs[0], lattice_vecs[2])),
168
+ volume / Math.hypot(...math.cross_3d(lattice_vecs[0], lattice_vecs[1])),
169
+ ];
170
+ // Anchor set for the bond test: base atoms plus the phase-1 boundary images
171
+ // (corner/edge/face copies). Anchoring on those too matches VESTA - every
172
+ // displayed boundary cation gets its shell completed (e.g. all 8 corner
173
+ // octahedra in rutile, not just the one at the origin).
174
+ const anchor_positions = structure.sites.map((site) => site.xyz);
175
+ const anchor_radii = [...site_radii];
176
+ const anchor_en = [...site_en];
177
+ for (const [src_idx, img_xyz] of image_sites) {
178
+ anchor_positions.push(img_xyz);
179
+ anchor_radii.push(site_radii[src_idx]);
180
+ anchor_en.push(site_en[src_idx]);
181
+ }
182
+ // Spatial grid over anchors for the bond check
183
+ const grid = new Map();
184
+ const grid_key = (pos) => pos.map((coord) => Math.floor(coord / max_bond_dist)).join(`,`);
185
+ for (const [idx, pos] of anchor_positions.entries()) {
186
+ const key = grid_key(pos);
187
+ const cell = grid.get(key);
188
+ if (cell)
189
+ cell.push(idx);
190
+ else
191
+ grid.set(key, [idx]);
192
+ }
193
+ // True when the candidate (an anion image) bonds a strictly less
194
+ // electronegative anchor, i.e. completes some cation's coordination shell
195
+ const completes_cation_shell = (pos, radius, en) => {
196
+ const [cx, cy, cz] = pos.map((coord) => Math.floor(coord / max_bond_dist));
197
+ for (let dx = -1; dx <= 1; dx++) {
198
+ for (let dy = -1; dy <= 1; dy++) {
199
+ for (let dz = -1; dz <= 1; dz++) {
200
+ for (const anchor_idx of grid.get(`${cx + dx},${cy + dy},${cz + dz}`) ?? []) {
201
+ const anchor_radius = anchor_radii[anchor_idx];
202
+ const anchor_electroneg = anchor_en[anchor_idx];
203
+ if (anchor_radius === null)
204
+ continue;
205
+ if (anchor_electroneg === null || en <= anchor_electroneg)
206
+ continue;
207
+ const dist = math.euclidean_dist(pos, anchor_positions[anchor_idx]);
208
+ if (dist > MIN_BOND_DIST && dist <= radius + anchor_radius + BOND_SLACK) {
209
+ return true;
210
+ }
211
+ }
212
+ }
213
+ }
214
+ }
215
+ return false;
216
+ };
217
+ // Dedupe against phase-1 images via (site, integer shift) keys
218
+ const seen_images = new Set(image_sites.map(([idx, _xyz, img_abc]) => `${idx}|${img_abc
219
+ .map((coord, axis) => Math.round(coord - structure.sites[idx].abc[axis]))
220
+ .join(`,`)}`));
221
+ for (const [idx, site] of structure.sites.entries()) {
222
+ const radius = site_radii[idx];
223
+ const en = site_en[idx];
224
+ // Skip candidates that could never be a polyhedron vertex: metals (e.g.
225
+ // Fe/Ni in Al-Fe-Ni intermetallics, despite their higher EN) and anything
226
+ // not strictly more electronegative than at least one anchor (covers all
227
+ // sites of elemental/equal-EN structures and all cations)
228
+ if (radius === null || en === null || en <= min_anchor_en)
229
+ continue;
230
+ if (site_is_metal[idx])
231
+ continue;
232
+ // Per-axis shifts that could land a copy of this atom within bonding reach
233
+ // of the cell: {0} plus +1/-1 when the atom is within max_bond_dist of the
234
+ // respective boundary
235
+ const axis_shifts = [0, 1, 2].map((axis) => {
236
+ if (!pbc[axis])
237
+ return [0];
238
+ // + face tolerance: anchors (phase-1 images) can sit slightly outside the cell
239
+ const pad = (max_bond_dist + PHYSICAL_TOLERANCE) / heights[axis];
240
+ const shifts = [0];
241
+ if (site.abc[axis] < pad)
242
+ shifts.push(1);
243
+ if (site.abc[axis] > 1 - pad)
244
+ shifts.push(-1);
245
+ return shifts;
246
+ });
247
+ for (const shift_a of axis_shifts[0]) {
248
+ for (const shift_b of axis_shifts[1]) {
249
+ for (const shift_c of axis_shifts[2]) {
250
+ if (shift_a === 0 && shift_b === 0 && shift_c === 0)
251
+ continue;
252
+ const key = `${idx}|${shift_a},${shift_b},${shift_c}`;
253
+ if (seen_images.has(key))
254
+ continue;
255
+ const img_abc = [
256
+ site.abc[0] + shift_a,
257
+ site.abc[1] + shift_b,
258
+ site.abc[2] + shift_c,
259
+ ];
260
+ const img_xyz = frac_to_cart_pos(img_abc, lattice_vecs);
261
+ if (!completes_cation_shell(img_xyz, radius, en))
262
+ continue;
263
+ seen_images.add(key);
264
+ image_sites.push([idx, img_xyz, img_abc, true]);
265
+ }
266
+ }
267
+ }
268
+ }
269
+ }
99
270
  return image_sites;
100
271
  }
101
272
  // Return structure with image atoms added
@@ -104,23 +275,25 @@ export function get_pbc_image_sites(...args) {
104
275
  if (!structure || !structure.sites || structure.sites.length === 0) {
105
276
  return structure;
106
277
  }
107
- // Check for trajectory data
108
- const atoms_outside_cell = structure.sites.filter((site) => site.abc.some((coord) => coord < -0.1 || coord > 1.1));
109
278
  // Return trajectory data unchanged
110
- if (atoms_outside_cell.length > structure.sites.length * 0.1) {
279
+ if (is_scattered_trajectory(structure.sites))
111
280
  return structure;
112
- }
113
281
  // Add image atoms to regular crystal structures
114
282
  const image_sites = find_image_atoms(...args);
115
283
  const imaged_struct = { ...structure, sites: [...structure.sites] };
116
284
  // Add image atoms as new sites using provided (xyz, abc) from find_image_atoms
117
- for (const [site_idx, img_xyz, img_abc] of image_sites) {
285
+ for (const [site_idx, img_xyz, img_abc, is_completion] of image_sites) {
118
286
  const orig_site = structure.sites[site_idx];
119
287
  imaged_struct.sites.push({
120
288
  ...orig_site,
121
289
  abc: img_abc,
122
290
  xyz: img_xyz,
123
- properties: { ...orig_site.properties, orig_site_idx: site_idx },
291
+ properties: {
292
+ ...orig_site.properties,
293
+ orig_site_idx: site_idx,
294
+ // phase-2 images only complete bonds/polyhedra - hidden when neither renders
295
+ ...(is_completion ? { completion_image: true } : {}),
296
+ },
124
297
  });
125
298
  }
126
299
  return imaged_struct;
@@ -0,0 +1,41 @@
1
+ import type { ElementSymbol } from '../element';
2
+ import type { Vec3 } from '../math';
3
+ import type { AnyStructure, BondPair } from './';
4
+ export type PolyhedraColorMode = `vertex` | `center` | `uniform`;
5
+ export interface PolyhedraOptions {
6
+ min_neighbors?: number;
7
+ max_neighbors?: number;
8
+ excluded_center_elements?: readonly string[];
9
+ included_center_elements?: readonly string[];
10
+ electronegativity_margin?: number;
11
+ distance_factor?: number;
12
+ weak_bond_norm?: number;
13
+ volume_eps?: number;
14
+ }
15
+ export interface ConvexHullResult {
16
+ vertices: Vec3[];
17
+ input_idxs: number[];
18
+ faces: [number, number, number][];
19
+ volume: number;
20
+ }
21
+ export interface Polyhedron {
22
+ center_site_idx: number;
23
+ center_orig_idx: number;
24
+ center_element: ElementSymbol;
25
+ vertices: Vec3[];
26
+ vertex_site_idxs: number[];
27
+ faces: [number, number, number][];
28
+ volume: number;
29
+ }
30
+ export interface MergedPolyhedraBuffers {
31
+ positions: Float32Array;
32
+ colors: Float32Array;
33
+ edge_positions: Float32Array;
34
+ triangle_count: number;
35
+ edge_count: number;
36
+ }
37
+ export declare function convex_hull_3d(points: readonly Vec3[], eps_scale?: number): ConvexHullResult;
38
+ export declare function build_adjacency(bonds: readonly BondPair[]): Map<number, Set<number>>;
39
+ export declare const is_spectator_center: (element: string) => boolean;
40
+ export declare function compute_polyhedra(structure: AnyStructure, bonds: readonly BondPair[], options?: PolyhedraOptions): Polyhedron[];
41
+ export declare function merge_polyhedra_buffers(polyhedra: readonly Polyhedron[], get_vertex_color: (poly: Polyhedron, vertex_idx: number) => string, coplanar_tol?: number): MergedPolyhedraBuffers;