matterviz 0.3.7 → 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.
- package/dist/Icon.svelte +7 -4
- package/dist/MillerIndexInput.svelte +1 -1
- package/dist/api/optimade.js +32 -26
- package/dist/app.css +0 -3
- package/dist/brillouin/BrillouinZone.svelte +76 -148
- package/dist/brillouin/BrillouinZone.svelte.d.ts +6 -14
- package/dist/brillouin/BrillouinZoneExportPane.svelte +43 -96
- package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +1 -1
- package/dist/brillouin/BrillouinZoneInfoPane.svelte +9 -32
- package/dist/brillouin/BrillouinZoneInfoPane.svelte.d.ts +2 -3
- package/dist/brillouin/BrillouinZoneScene.svelte +97 -205
- package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +4 -23
- package/dist/brillouin/BrillouinZoneTooltip.svelte +16 -25
- package/dist/brillouin/ReciprocalVectors.svelte +39 -0
- package/dist/brillouin/ReciprocalVectors.svelte.d.ts +9 -0
- package/dist/brillouin/compute.d.ts +2 -0
- package/dist/brillouin/compute.js +89 -90
- package/dist/brillouin/geometry.d.ts +8 -0
- package/dist/brillouin/geometry.js +57 -0
- package/dist/brillouin/index.d.ts +2 -0
- package/dist/brillouin/index.js +2 -0
- package/dist/brillouin/types.d.ts +2 -2
- package/dist/chempot-diagram/ChemPotDiagram.svelte +14 -13
- package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +1 -1
- package/dist/chempot-diagram/ChemPotDiagram2D.svelte +109 -203
- package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +4 -1
- package/dist/chempot-diagram/ChemPotDiagram3D.svelte +180 -470
- package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +7 -1
- package/dist/chempot-diagram/async-compute.svelte.js +3 -1
- package/dist/chempot-diagram/chempot-worker.js +2 -1
- package/dist/chempot-diagram/color.d.ts +3 -6
- package/dist/chempot-diagram/color.js +5 -5
- package/dist/chempot-diagram/compute.d.ts +4 -4
- package/dist/chempot-diagram/compute.js +20 -20
- package/dist/chempot-diagram/controls-state.svelte.d.ts +10 -0
- package/dist/chempot-diagram/controls-state.svelte.js +42 -0
- package/dist/chempot-diagram/export.d.ts +47 -0
- package/dist/chempot-diagram/export.js +133 -0
- package/dist/chempot-diagram/index.d.ts +1 -0
- package/dist/chempot-diagram/index.js +1 -0
- package/dist/chempot-diagram/pointer.d.ts +0 -10
- package/dist/chempot-diagram/pointer.js +4 -4
- package/dist/chempot-diagram/types.d.ts +3 -3
- package/dist/colors/index.js +8 -7
- package/dist/composition/FormulaFilter.svelte +18 -11
- package/dist/composition/PieChart.svelte +11 -10
- package/dist/composition/chem-sys.d.ts +8 -0
- package/dist/composition/chem-sys.js +86 -0
- package/dist/composition/format.js +7 -4
- package/dist/composition/index.d.ts +1 -0
- package/dist/composition/index.js +1 -0
- package/dist/composition/parse.d.ts +0 -1
- package/dist/composition/parse.js +41 -31
- package/dist/controls.d.ts +1 -0
- package/dist/controls.js +0 -1
- package/dist/convex-hull/ConvexHull.svelte +8 -10
- package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -4
- package/dist/convex-hull/ConvexHull2D.svelte +106 -185
- package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull3D.svelte +179 -683
- package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull4D.svelte +183 -687
- package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHullChrome.svelte +268 -0
- package/dist/convex-hull/ConvexHullChrome.svelte.d.ts +30 -0
- package/dist/convex-hull/ConvexHullControls.svelte +88 -7
- package/dist/convex-hull/ConvexHullControls.svelte.d.ts +7 -6
- package/dist/convex-hull/ConvexHullInfoPane.svelte +18 -5
- package/dist/convex-hull/ConvexHullInfoPane.svelte.d.ts +6 -5
- package/dist/convex-hull/ConvexHullStats.svelte +36 -175
- package/dist/convex-hull/ConvexHullStats.svelte.d.ts +3 -1
- package/dist/convex-hull/ConvexHullTooltip.svelte +11 -2
- package/dist/convex-hull/ConvexHullTooltip.svelte.d.ts +2 -1
- package/dist/convex-hull/GasPressureControls.svelte +4 -4
- package/dist/convex-hull/TemperatureSlider.svelte +2 -2
- package/dist/convex-hull/barycentric-coords.d.ts +2 -4
- package/dist/convex-hull/barycentric-coords.js +6 -33
- package/dist/convex-hull/canvas-interactions.svelte.d.ts +79 -0
- package/dist/convex-hull/canvas-interactions.svelte.js +278 -0
- package/dist/convex-hull/demo-temperature.d.ts +1 -1
- package/dist/convex-hull/demo-temperature.js +20 -22
- package/dist/convex-hull/gas-thermodynamics.d.ts +2 -2
- package/dist/convex-hull/gas-thermodynamics.js +22 -30
- package/dist/convex-hull/helpers.d.ts +42 -7
- package/dist/convex-hull/helpers.js +171 -78
- package/dist/convex-hull/hull-state.svelte.d.ts +44 -0
- package/dist/convex-hull/hull-state.svelte.js +124 -0
- package/dist/convex-hull/index.d.ts +10 -8
- package/dist/convex-hull/index.js +7 -2
- package/dist/convex-hull/thermodynamics.js +136 -960
- package/dist/convex-hull/types.d.ts +13 -5
- package/dist/convex-hull/types.js +12 -0
- package/dist/coordination/CoordinationBarPlot.svelte +27 -34
- package/dist/coordination/CoordinationBarPlot.svelte.d.ts +1 -1
- package/dist/element/BohrAtom.svelte +2 -1
- package/dist/element/index.d.ts +4 -0
- package/dist/element/index.js +18 -0
- package/dist/feedback/DragOverlay.svelte +3 -1
- package/dist/feedback/DragOverlay.svelte.d.ts +1 -0
- package/dist/feedback/StatusMessage.svelte +13 -3
- package/dist/fermi-surface/FermiSlice.svelte +13 -5
- package/dist/fermi-surface/FermiSurface.svelte +78 -151
- package/dist/fermi-surface/FermiSurface.svelte.d.ts +5 -14
- package/dist/fermi-surface/FermiSurfaceControls.svelte +1 -1
- package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
- package/dist/fermi-surface/FermiSurfaceScene.svelte +72 -221
- package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +3 -23
- package/dist/fermi-surface/FermiSurfaceTooltip.svelte +8 -34
- package/dist/fermi-surface/compute.js +67 -66
- package/dist/fermi-surface/export.js +6 -16
- package/dist/fermi-surface/index.d.ts +0 -1
- package/dist/fermi-surface/index.js +0 -1
- package/dist/fermi-surface/parse.d.ts +1 -1
- package/dist/fermi-surface/parse.js +71 -79
- package/dist/fermi-surface/types.d.ts +3 -2
- package/dist/heatmap-matrix/HeatmapMatrix.svelte +69 -52
- package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +4 -3
- package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +3 -2
- package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +5 -5
- package/dist/heatmap-matrix/index.d.ts +3 -2
- package/dist/heatmap-matrix/index.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/io/ExportPane.svelte +166 -0
- package/dist/io/ExportPane.svelte.d.ts +17 -0
- package/dist/io/decompress.js +5 -4
- package/dist/io/export.d.ts +9 -5
- package/dist/io/export.js +77 -51
- package/dist/io/fetch.d.ts +2 -1
- package/dist/io/fetch.js +5 -1
- package/dist/io/file-drop.d.ts +8 -1
- package/dist/io/file-drop.js +48 -36
- package/dist/io/index.d.ts +2 -0
- package/dist/io/index.js +10 -0
- package/dist/io/types.d.ts +13 -0
- package/dist/io/url-drop.js +64 -33
- package/dist/isosurface/parse.js +52 -51
- package/dist/isosurface/slice.js +5 -4
- package/dist/isosurface/types.js +1 -1
- package/dist/keyboard.d.ts +3 -0
- package/dist/keyboard.js +23 -0
- package/dist/labels.d.ts +1 -1
- package/dist/labels.js +9 -8
- package/dist/layout/FullscreenButton.svelte +33 -0
- package/dist/layout/FullscreenButton.svelte.d.ts +10 -0
- package/dist/layout/FullscreenToggle.svelte +8 -14
- package/dist/layout/PropertyFilter.svelte +3 -2
- package/dist/layout/SettingsSection.svelte +1 -1
- package/dist/layout/ViewerChrome.svelte +116 -0
- package/dist/layout/ViewerChrome.svelte.d.ts +17 -0
- package/dist/layout/fullscreen.d.ts +4 -0
- package/dist/layout/fullscreen.svelte.d.ts +8 -0
- package/dist/layout/fullscreen.svelte.js +37 -0
- package/dist/layout/index.d.ts +3 -0
- package/dist/layout/index.js +3 -0
- package/dist/layout/json-tree/JsonNode.svelte +1 -1
- package/dist/layout/json-tree/JsonTree.svelte +2 -2
- package/dist/layout/json-tree/utils.js +5 -4
- package/dist/marching-cubes.js +8 -13
- package/dist/math.d.ts +12 -4
- package/dist/math.js +42 -30
- package/dist/overlays/DraggablePane.svelte +4 -4
- package/dist/overlays/index.d.ts +4 -0
- package/dist/periodic-table/PeriodicTable.svelte +27 -15
- package/dist/periodic-table/PropertySelect.svelte +1 -0
- package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +9 -3
- package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +1 -1
- package/dist/phase-diagram/PhaseDiagramControls.svelte +3 -2
- package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +4 -3
- package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +4 -2
- package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +2 -3
- package/dist/phase-diagram/PhaseDiagramExportPane.svelte +47 -132
- package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +3 -4
- package/dist/phase-diagram/PhaseDiagramTooltip.svelte +1 -1
- package/dist/phase-diagram/build-diagram.js +2 -2
- package/dist/phase-diagram/colors.js +1 -1
- package/dist/phase-diagram/parse.d.ts +2 -1
- package/dist/phase-diagram/parse.js +6 -5
- package/dist/phase-diagram/types.d.ts +1 -1
- package/dist/phase-diagram/utils.d.ts +3 -3
- package/dist/phase-diagram/utils.js +8 -12
- package/dist/plot/{BarPlot.svelte → bar/BarPlot.svelte} +246 -841
- package/dist/plot/{BarPlot.svelte.d.ts → bar/BarPlot.svelte.d.ts} +8 -16
- package/dist/plot/{BarPlotControls.svelte → bar/BarPlotControls.svelte} +6 -5
- package/dist/plot/{BarPlotControls.svelte.d.ts → bar/BarPlotControls.svelte.d.ts} +3 -3
- package/dist/plot/{SpacegroupBarPlot.svelte → bar/SpacegroupBarPlot.svelte} +8 -7
- package/dist/plot/{SpacegroupBarPlot.svelte.d.ts → bar/SpacegroupBarPlot.svelte.d.ts} +1 -1
- package/dist/plot/bar/data.d.ts +40 -0
- package/dist/plot/bar/data.js +154 -0
- package/dist/plot/bar/geometry.d.ts +39 -0
- package/dist/plot/bar/geometry.js +60 -0
- package/dist/plot/bar/index.d.ts +3 -0
- package/dist/plot/bar/index.js +3 -0
- package/dist/plot/box/BoxPlot.svelte +1292 -0
- package/dist/plot/box/BoxPlot.svelte.d.ts +95 -0
- package/dist/plot/box/BoxPlotControls.svelte +109 -0
- package/dist/plot/box/BoxPlotControls.svelte.d.ts +19 -0
- package/dist/plot/box/Violin.svelte +14 -0
- package/dist/plot/box/Violin.svelte.d.ts +70 -0
- package/dist/plot/box/box-plot.d.ts +56 -0
- package/dist/plot/box/box-plot.js +129 -0
- package/dist/plot/box/index.d.ts +5 -0
- package/dist/plot/box/index.js +5 -0
- package/dist/plot/box/kde.d.ts +17 -0
- package/dist/plot/box/kde.js +160 -0
- package/dist/plot/box/quantile.d.ts +3 -0
- package/dist/plot/box/quantile.js +53 -0
- package/dist/plot/{auto-place.d.ts → core/auto-place.d.ts} +1 -1
- package/dist/plot/{auto-place.js → core/auto-place.js} +6 -3
- package/dist/plot/core/axis-utils.d.ts +46 -0
- package/dist/plot/core/axis-utils.js +110 -0
- package/dist/plot/{AxisLabel.svelte → core/components/AxisLabel.svelte} +2 -2
- package/dist/plot/{AxisLabel.svelte.d.ts → core/components/AxisLabel.svelte.d.ts} +1 -1
- package/dist/plot/{ColorBar.svelte → core/components/ColorBar.svelte} +41 -38
- package/dist/plot/{ColorBar.svelte.d.ts → core/components/ColorBar.svelte.d.ts} +7 -6
- package/dist/plot/{ColorScaleSelect.svelte → core/components/ColorScaleSelect.svelte} +4 -3
- package/dist/plot/{ColorScaleSelect.svelte.d.ts → core/components/ColorScaleSelect.svelte.d.ts} +2 -2
- package/dist/plot/core/components/ControlPane.svelte +46 -0
- package/dist/plot/core/components/ControlPane.svelte.d.ts +13 -0
- package/dist/plot/{FillArea.svelte → core/components/FillArea.svelte} +17 -6
- package/dist/plot/{FillArea.svelte.d.ts → core/components/FillArea.svelte.d.ts} +1 -1
- package/dist/plot/{InteractiveAxisLabel.svelte → core/components/InteractiveAxisLabel.svelte} +3 -3
- package/dist/plot/{InteractiveAxisLabel.svelte.d.ts → core/components/InteractiveAxisLabel.svelte.d.ts} +2 -2
- package/dist/plot/{Line.svelte → core/components/Line.svelte} +33 -15
- package/dist/plot/{Line.svelte.d.ts → core/components/Line.svelte.d.ts} +3 -2
- package/dist/plot/{PlotAxis.svelte → core/components/PlotAxis.svelte} +9 -6
- package/dist/plot/{PlotAxis.svelte.d.ts → core/components/PlotAxis.svelte.d.ts} +5 -3
- package/dist/plot/{PlotControls.svelte → core/components/PlotControls.svelte} +17 -29
- package/dist/plot/core/components/PlotControls.svelte.d.ts +4 -0
- package/dist/plot/{PlotLegend.svelte → core/components/PlotLegend.svelte} +21 -10
- package/dist/plot/{PlotLegend.svelte.d.ts → core/components/PlotLegend.svelte.d.ts} +3 -2
- package/dist/plot/{PlotTooltip.svelte → core/components/PlotTooltip.svelte} +17 -1
- package/dist/plot/{PlotTooltip.svelte.d.ts → core/components/PlotTooltip.svelte.d.ts} +8 -0
- package/dist/plot/{PortalSelect.svelte → core/components/PortalSelect.svelte} +11 -7
- package/dist/plot/{ReferenceLine.svelte → core/components/ReferenceLine.svelte} +3 -3
- package/dist/plot/{ReferenceLine.svelte.d.ts → core/components/ReferenceLine.svelte.d.ts} +1 -1
- package/dist/plot/{ReferenceLine3D.svelte → core/components/ReferenceLine3D.svelte} +5 -5
- package/dist/plot/{ReferenceLine3D.svelte.d.ts → core/components/ReferenceLine3D.svelte.d.ts} +5 -5
- package/dist/plot/{ReferencePlane.svelte → core/components/ReferencePlane.svelte} +8 -8
- package/dist/plot/{ReferencePlane.svelte.d.ts → core/components/ReferencePlane.svelte.d.ts} +5 -5
- package/dist/plot/{ZeroLines.svelte → core/components/ZeroLines.svelte} +3 -3
- package/dist/plot/{ZeroLines.svelte.d.ts → core/components/ZeroLines.svelte.d.ts} +3 -3
- package/dist/plot/{ZoomRect.svelte → core/components/ZoomRect.svelte} +1 -1
- package/dist/plot/{ZoomRect.svelte.d.ts → core/components/ZoomRect.svelte.d.ts} +1 -1
- package/dist/plot/core/components/index.d.ts +17 -0
- package/dist/plot/core/components/index.js +17 -0
- package/dist/plot/{data-cleaning.d.ts → core/data-cleaning.d.ts} +71 -1
- package/dist/plot/{data-cleaning.js → core/data-cleaning.js} +21 -23
- package/dist/plot/{data-transform.d.ts → core/data-transform.d.ts} +2 -2
- package/dist/plot/{data-transform.js → core/data-transform.js} +3 -3
- package/dist/plot/core/fill-utils.d.ts +34 -0
- package/dist/plot/core/fill-utils.js +391 -0
- package/dist/plot/core/index.d.ts +10 -0
- package/dist/plot/core/index.js +11 -0
- package/dist/plot/core/interactions.d.ts +39 -0
- package/dist/plot/core/interactions.js +209 -0
- package/dist/plot/{layout.d.ts → core/layout.d.ts} +1 -0
- package/dist/plot/{layout.js → core/layout.js} +16 -8
- package/dist/plot/core/pan-zoom.svelte.d.ts +35 -0
- package/dist/plot/core/pan-zoom.svelte.js +221 -0
- package/dist/plot/core/placed-tween.svelte.d.ts +21 -0
- package/dist/plot/core/placed-tween.svelte.js +68 -0
- package/dist/plot/{reference-line.d.ts → core/reference-line.d.ts} +11 -11
- package/dist/plot/{reference-line.js → core/reference-line.js} +29 -42
- package/dist/plot/core/scales.d.ts +40 -0
- package/dist/plot/{scales.js → core/scales.js} +94 -93
- package/dist/plot/core/svg.d.ts +3 -0
- package/dist/plot/core/svg.js +41 -0
- package/dist/plot/{types.d.ts → core/types.d.ts} +36 -85
- package/dist/plot/{types.js → core/types.js} +1 -1
- package/dist/plot/{utils → core/utils}/label-placement.d.ts +3 -3
- package/dist/plot/{utils → core/utils}/label-placement.js +3 -3
- package/dist/plot/core/utils/series-visibility.d.ts +26 -0
- package/dist/plot/{utils → core/utils}/series-visibility.js +29 -2
- package/dist/plot/core/utils.d.ts +12 -0
- package/dist/plot/core/utils.js +27 -0
- package/dist/plot/{Histogram.svelte → histogram/Histogram.svelte} +174 -551
- package/dist/plot/{Histogram.svelte.d.ts → histogram/Histogram.svelte.d.ts} +2 -2
- package/dist/plot/{HistogramControls.svelte → histogram/HistogramControls.svelte} +6 -6
- package/dist/plot/{HistogramControls.svelte.d.ts → histogram/HistogramControls.svelte.d.ts} +4 -4
- package/dist/plot/histogram/index.d.ts +2 -0
- package/dist/plot/histogram/index.js +2 -0
- package/dist/plot/index.d.ts +8 -41
- package/dist/plot/index.js +10 -39
- package/dist/plot/sankey/Sankey.svelte +697 -0
- package/dist/plot/sankey/Sankey.svelte.d.ts +74 -0
- package/dist/plot/sankey/SankeyControls.svelte +98 -0
- package/dist/plot/sankey/SankeyControls.svelte.d.ts +19 -0
- package/dist/plot/sankey/index.d.ts +4 -0
- package/dist/plot/sankey/index.js +3 -0
- package/dist/plot/sankey/sankey-types.d.ts +42 -0
- package/dist/plot/sankey/sankey-types.js +4 -0
- package/dist/plot/sankey/sankey.d.ts +52 -0
- package/dist/plot/sankey/sankey.js +189 -0
- package/dist/plot/{BinnedScatterPlot.svelte → scatter/BinnedScatterPlot.svelte} +64 -64
- package/dist/plot/{BinnedScatterPlot.svelte.d.ts → scatter/BinnedScatterPlot.svelte.d.ts} +6 -6
- package/dist/plot/{ElementScatter.svelte → scatter/ElementScatter.svelte} +6 -6
- package/dist/plot/{ElementScatter.svelte.d.ts → scatter/ElementScatter.svelte.d.ts} +2 -2
- package/dist/plot/{ScatterPlot.svelte → scatter/ScatterPlot.svelte} +297 -1008
- package/dist/plot/{ScatterPlot.svelte.d.ts → scatter/ScatterPlot.svelte.d.ts} +10 -18
- package/dist/plot/{ScatterPlotControls.svelte → scatter/ScatterPlotControls.svelte} +6 -5
- package/dist/plot/{ScatterPlotControls.svelte.d.ts → scatter/ScatterPlotControls.svelte.d.ts} +2 -2
- package/dist/plot/{ScatterPoint.svelte → scatter/ScatterPoint.svelte} +7 -7
- package/dist/plot/{ScatterPoint.svelte.d.ts → scatter/ScatterPoint.svelte.d.ts} +3 -3
- package/dist/plot/{adaptive-density.d.ts → scatter/adaptive-density.d.ts} +14 -4
- package/dist/plot/{adaptive-density.js → scatter/adaptive-density.js} +46 -20
- package/dist/plot/{binned-scatter-types.d.ts → scatter/binned-scatter-types.d.ts} +5 -12
- package/dist/plot/scatter/index.d.ts +7 -0
- package/dist/plot/scatter/index.js +5 -0
- package/dist/plot/scatter/scatter-data.d.ts +19 -0
- package/dist/plot/scatter/scatter-data.js +212 -0
- package/dist/plot/{ScatterPlot3D.svelte → scatter-3d/ScatterPlot3D.svelte} +25 -34
- package/dist/plot/{ScatterPlot3D.svelte.d.ts → scatter-3d/ScatterPlot3D.svelte.d.ts} +9 -17
- package/dist/plot/{ScatterPlot3DControls.svelte → scatter-3d/ScatterPlot3DControls.svelte} +14 -14
- package/dist/plot/{ScatterPlot3DControls.svelte.d.ts → scatter-3d/ScatterPlot3DControls.svelte.d.ts} +6 -6
- package/dist/plot/{ScatterPlot3DScene.svelte → scatter-3d/ScatterPlot3DScene.svelte} +129 -128
- package/dist/plot/{ScatterPlot3DScene.svelte.d.ts → scatter-3d/ScatterPlot3DScene.svelte.d.ts} +6 -15
- package/dist/plot/{Surface3D.svelte → scatter-3d/Surface3D.svelte} +7 -6
- package/dist/plot/{Surface3D.svelte.d.ts → scatter-3d/Surface3D.svelte.d.ts} +5 -4
- package/dist/plot/scatter-3d/index.d.ts +4 -0
- package/dist/plot/scatter-3d/index.js +4 -0
- package/dist/plot/sunburst/Sunburst.svelte +1041 -0
- package/dist/plot/sunburst/Sunburst.svelte.d.ts +97 -0
- package/dist/plot/sunburst/SunburstControls.svelte +200 -0
- package/dist/plot/sunburst/SunburstControls.svelte.d.ts +26 -0
- package/dist/plot/sunburst/index.d.ts +4 -0
- package/dist/plot/sunburst/index.js +4 -0
- package/dist/plot/sunburst/render.d.ts +34 -0
- package/dist/plot/sunburst/render.js +122 -0
- package/dist/plot/sunburst/sunburst.d.ts +62 -0
- package/dist/plot/sunburst/sunburst.js +269 -0
- package/dist/rdf/RdfPlot.svelte +2 -1
- package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
- package/dist/rdf/calc-rdf.js +11 -24
- package/dist/sanitize.js +14 -3
- package/dist/scene/SceneCamera.svelte +62 -0
- package/dist/scene/SceneCamera.svelte.d.ts +19 -0
- package/dist/scene/bind-renderer.svelte.d.ts +2 -0
- package/dist/scene/bind-renderer.svelte.js +14 -0
- package/dist/scene/index.d.ts +4 -0
- package/dist/scene/index.js +5 -0
- package/dist/scene/props.js +52 -0
- package/dist/scene/types.d.ts +26 -0
- package/dist/scene/types.js +1 -0
- package/dist/settings.d.ts +79 -3
- package/dist/settings.js +321 -1
- package/dist/spectral/Bands.svelte +47 -36
- package/dist/spectral/Bands.svelte.d.ts +6 -6
- package/dist/spectral/BandsAndDos.svelte +23 -25
- package/dist/spectral/BrillouinBandsDos.svelte +42 -30
- package/dist/spectral/Dos.svelte +15 -23
- package/dist/spectral/Dos.svelte.d.ts +4 -3
- package/dist/spectral/helpers.d.ts +8 -6
- package/dist/spectral/helpers.js +137 -65
- package/dist/state.svelte.d.ts +0 -7
- package/dist/state.svelte.js +0 -6
- package/dist/structure/Arrow.svelte +2 -4
- package/dist/structure/AtomLegend.svelte +8 -9
- package/dist/structure/AtomLegend.svelte.d.ts +1 -1
- package/dist/structure/CanvasTooltip.svelte +1 -0
- package/dist/structure/CellSelect.svelte +12 -5
- package/dist/structure/CellSelect.svelte.d.ts +2 -1
- package/dist/structure/Cylinder.svelte +12 -8
- package/dist/structure/Cylinder.svelte.d.ts +4 -1
- package/dist/structure/Lattice.svelte +2 -2
- package/dist/structure/Structure.svelte +365 -423
- package/dist/structure/Structure.svelte.d.ts +5 -15
- package/dist/structure/StructureControls.svelte +217 -2
- package/dist/structure/StructureControls.svelte.d.ts +5 -3
- package/dist/structure/StructureExportPane.svelte +54 -156
- package/dist/structure/StructureExportPane.svelte.d.ts +4 -5
- package/dist/structure/StructureInfoPane.svelte +10 -9
- package/dist/structure/StructureInfoPane.svelte.d.ts +5 -5
- package/dist/structure/StructureScene.svelte +376 -208
- package/dist/structure/StructureScene.svelte.d.ts +22 -20
- package/dist/structure/{label-placement.d.ts → atom-label-placement.d.ts} +3 -3
- package/dist/structure/{label-placement.js → atom-label-placement.js} +15 -5
- package/dist/structure/atom-properties.d.ts +1 -1
- package/dist/structure/atom-properties.js +17 -22
- package/dist/structure/bond-order-perception.js +3 -5
- package/dist/structure/bonding.d.ts +4 -0
- package/dist/structure/bonding.js +134 -63
- package/dist/structure/export.d.ts +24 -4
- package/dist/structure/export.js +89 -143
- package/dist/structure/index.d.ts +4 -4
- package/dist/structure/index.js +3 -3
- package/dist/structure/measure.d.ts +3 -2
- package/dist/structure/measure.js +6 -5
- package/dist/structure/parse.d.ts +3 -2
- package/dist/structure/parse.js +419 -438
- package/dist/structure/partial-occupancy.d.ts +0 -1
- package/dist/structure/partial-occupancy.js +1 -1
- package/dist/structure/pbc.d.ts +1 -1
- package/dist/structure/pbc.js +190 -13
- package/dist/structure/polyhedra.d.ts +41 -0
- package/dist/structure/polyhedra.js +602 -0
- package/dist/structure/site.d.ts +4 -0
- package/dist/structure/site.js +1 -0
- package/dist/structure/supercell.js +3 -2
- package/dist/structure/validation.js +5 -6
- package/dist/symmetry/SymmetryElementControls.svelte +69 -0
- package/dist/symmetry/SymmetryElementControls.svelte.d.ts +9 -0
- package/dist/symmetry/SymmetryElements.svelte +354 -0
- package/dist/symmetry/SymmetryElements.svelte.d.ts +24 -0
- package/dist/symmetry/SymmetryStats.svelte +113 -8
- package/dist/symmetry/WyckoffTable.svelte +68 -7
- package/dist/symmetry/WyckoffTable.svelte.d.ts +3 -0
- package/dist/symmetry/cell-transform.js +7 -14
- package/dist/symmetry/index.d.ts +14 -4
- package/dist/symmetry/index.js +291 -72
- package/dist/symmetry/spacegroups.d.ts +12 -1
- package/dist/symmetry/spacegroups.js +63 -14
- package/dist/symmetry/symmetry-elements.d.ts +33 -0
- package/dist/symmetry/symmetry-elements.js +521 -0
- package/dist/symmetry/wyckoff-db.d.ts +9 -0
- package/dist/symmetry/wyckoff-db.js +87 -0
- package/dist/table/HeatmapTable.svelte +66 -25
- package/dist/table/HeatmapTable.svelte.d.ts +1 -1
- package/dist/table/index.d.ts +1 -3
- package/dist/table/index.js +1 -1
- package/dist/theme/index.js +8 -8
- package/dist/tooltip/KCoords.svelte +45 -0
- package/dist/tooltip/KCoords.svelte.d.ts +8 -0
- package/dist/tooltip/index.d.ts +1 -0
- package/dist/tooltip/index.js +1 -0
- package/dist/trajectory/Trajectory.svelte +123 -100
- package/dist/trajectory/Trajectory.svelte.d.ts +11 -22
- package/dist/trajectory/TrajectoryExportPane.svelte +17 -25
- package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +4 -5
- package/dist/trajectory/TrajectoryInfoPane.svelte +5 -3
- package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +3 -2
- package/dist/trajectory/constants.js +6 -2
- package/dist/trajectory/extract.js +17 -37
- package/dist/trajectory/format-detect.d.ts +1 -1
- package/dist/trajectory/format-detect.js +27 -19
- package/dist/trajectory/frame-reader.d.ts +0 -1
- package/dist/trajectory/frame-reader.js +63 -162
- package/dist/trajectory/helpers.d.ts +10 -2
- package/dist/trajectory/helpers.js +56 -36
- package/dist/trajectory/index.js +1 -1
- package/dist/trajectory/parse/ase.d.ts +9 -1
- package/dist/trajectory/parse/ase.js +47 -32
- package/dist/trajectory/parse/diagnostics.d.ts +3 -0
- package/dist/trajectory/parse/diagnostics.js +14 -0
- package/dist/trajectory/parse/hdf5.js +1 -1
- package/dist/trajectory/parse/index.d.ts +1 -1
- package/dist/trajectory/parse/index.js +65 -105
- package/dist/trajectory/parse/lammps.d.ts +0 -2
- package/dist/trajectory/parse/lammps.js +8 -6
- package/dist/trajectory/parse/pymatgen.d.ts +2 -0
- package/dist/trajectory/parse/pymatgen.js +74 -0
- package/dist/trajectory/parse/vasp.js +38 -18
- package/dist/trajectory/parse/xyz.d.ts +13 -1
- package/dist/trajectory/parse/xyz.js +102 -94
- package/dist/trajectory/plotting.d.ts +1 -2
- package/dist/trajectory/plotting.js +16 -113
- package/dist/utils.d.ts +2 -0
- package/dist/utils.js +7 -5
- package/dist/xrd/XrdPlot.svelte +16 -30
- package/dist/xrd/broadening.d.ts +2 -1
- package/dist/xrd/calc-xrd.js +18 -20
- package/dist/xrd/index.d.ts +2 -2
- package/dist/xrd/parse.js +2 -2
- package/package.json +43 -26
- package/dist/element/data.json +0 -11864
- package/dist/fermi-surface/marching-cubes.d.ts +0 -2
- package/dist/fermi-surface/marching-cubes.js +0 -2
- package/dist/plot/PlotControls.svelte.d.ts +0 -4
- package/dist/plot/axis-utils.d.ts +0 -19
- package/dist/plot/axis-utils.js +0 -78
- package/dist/plot/defaults.d.ts +0 -19
- package/dist/plot/defaults.js +0 -9
- package/dist/plot/fill-utils.d.ts +0 -46
- package/dist/plot/fill-utils.js +0 -322
- package/dist/plot/hover-lock.svelte.d.ts +0 -14
- package/dist/plot/hover-lock.svelte.js +0 -46
- package/dist/plot/interactions.d.ts +0 -12
- package/dist/plot/interactions.js +0 -101
- package/dist/plot/scales.d.ts +0 -48
- package/dist/plot/svg.d.ts +0 -1
- package/dist/plot/svg.js +0 -11
- package/dist/plot/utils/series-visibility.d.ts +0 -15
- package/dist/plot/utils.d.ts +0 -1
- package/dist/plot/utils.js +0 -14
- /package/dist/plot/{PortalSelect.svelte.d.ts → core/components/PortalSelect.svelte.d.ts} +0 -0
- /package/dist/plot/{binned-scatter-types.js → scatter/binned-scatter-types.js} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { D3InterpolateName } from '../colors'
|
|
3
|
-
import {
|
|
3
|
+
import { get_d3_interpolator } from '../colors'
|
|
4
4
|
import type { ElementSymbol } from '../element'
|
|
5
5
|
import { element_data } from '../element'
|
|
6
6
|
import Isosurface from '../isosurface/Isosurface.svelte'
|
|
@@ -9,12 +9,9 @@
|
|
|
9
9
|
import { format_num } from '../labels'
|
|
10
10
|
import type { Vec3 } from '../math'
|
|
11
11
|
import * as math from '../math'
|
|
12
|
-
import
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
VectorColorMode,
|
|
16
|
-
VectorLayerConfig,
|
|
17
|
-
} from '../settings'
|
|
12
|
+
import { bind_renderer, build_orbit_props, SceneCamera } from '../scene'
|
|
13
|
+
import type { SceneControlProps } from '../scene'
|
|
14
|
+
import type { ShowBonds, VectorColorMode, VectorLayerConfig } from '../settings'
|
|
18
15
|
import { DEFAULTS } from '../settings'
|
|
19
16
|
import { create_pulse_animation } from '../effects.svelte'
|
|
20
17
|
import { colors } from '../state.svelte'
|
|
@@ -42,6 +39,9 @@
|
|
|
42
39
|
get_orig_site_idx,
|
|
43
40
|
get_property_colors,
|
|
44
41
|
} from './atom-properties'
|
|
42
|
+
import type { SymmetryElement } from '../symmetry'
|
|
43
|
+
import { has_visible_symmetry_overlay } from '../symmetry/symmetry-elements'
|
|
44
|
+
import SymmetryElements from '../symmetry/SymmetryElements.svelte'
|
|
45
45
|
import * as measure from './measure'
|
|
46
46
|
import {
|
|
47
47
|
compute_slice_geometry,
|
|
@@ -49,11 +49,12 @@
|
|
|
49
49
|
PARTIAL_OCCUPANCY_CAP_ARC,
|
|
50
50
|
} from './partial-occupancy'
|
|
51
51
|
import type { MoyoDataset } from '@spglib/moyo-wasm'
|
|
52
|
-
import { T
|
|
52
|
+
import { T } from '@threlte/core'
|
|
53
53
|
import * as extras from '@threlte/extras'
|
|
54
54
|
import { type ComponentProps, type Snippet, untrack } from 'svelte'
|
|
55
55
|
import { SvelteMap, SvelteSet } from 'svelte/reactivity'
|
|
56
|
-
import {
|
|
56
|
+
import { BufferAttribute, BufferGeometry, Color, DoubleSide, Vector3 } from 'three'
|
|
57
|
+
import type { Mesh, Object3D } from 'three'
|
|
57
58
|
import Bond from './Bond.svelte'
|
|
58
59
|
import type { BondEditResult, BondingStrategy, BondKeyTarget } from './bonding'
|
|
59
60
|
import {
|
|
@@ -65,6 +66,7 @@
|
|
|
65
66
|
get_bond_key,
|
|
66
67
|
get_bond_render_matrices,
|
|
67
68
|
get_explicit_bond_metadata,
|
|
69
|
+
get_majority_element,
|
|
68
70
|
set_bond_order as apply_set_bond_order,
|
|
69
71
|
structure_bond_to_bond_pair,
|
|
70
72
|
} from './bonding'
|
|
@@ -77,7 +79,9 @@
|
|
|
77
79
|
choose_site_label_offset,
|
|
78
80
|
LABEL_OFFSET_EPS,
|
|
79
81
|
make_label_position_calculator,
|
|
80
|
-
} from './label-placement'
|
|
82
|
+
} from './atom-label-placement'
|
|
83
|
+
import type { PolyhedraColorMode, Polyhedron } from './polyhedra'
|
|
84
|
+
import { compute_polyhedra, merge_polyhedra_buffers } from './polyhedra'
|
|
81
85
|
|
|
82
86
|
type InstancedAtomGroup = {
|
|
83
87
|
element: string
|
|
@@ -168,12 +172,27 @@
|
|
|
168
172
|
auto_bond_order = DEFAULTS.structure.auto_bond_order,
|
|
169
173
|
aromatic_display = DEFAULTS.structure.aromatic_display,
|
|
170
174
|
bonding_options = {},
|
|
175
|
+
show_polyhedra = DEFAULTS.structure.show_polyhedra,
|
|
176
|
+
polyhedra_opacity = DEFAULTS.structure.polyhedra_opacity,
|
|
177
|
+
polyhedra_show_edges = DEFAULTS.structure.polyhedra_show_edges,
|
|
178
|
+
polyhedra_edge_color = DEFAULTS.structure.polyhedra_edge_color,
|
|
179
|
+
polyhedra_color_mode = DEFAULTS.structure.polyhedra_color_mode,
|
|
180
|
+
polyhedra_color = DEFAULTS.structure.polyhedra_color,
|
|
181
|
+
polyhedra_hide_center_atoms = DEFAULTS.structure.polyhedra_hide_center_atoms,
|
|
182
|
+
polyhedra_min_neighbors = DEFAULTS.structure.polyhedra_min_neighbors,
|
|
183
|
+
polyhedra_max_neighbors = DEFAULTS.structure.polyhedra_max_neighbors,
|
|
184
|
+
polyhedra_excluded_elements = DEFAULTS.structure.polyhedra_excluded_elements,
|
|
185
|
+
polyhedra_included_elements = DEFAULTS.structure.polyhedra_included_elements,
|
|
186
|
+
polyhedra_rendered_elements = $bindable<string[]>([]),
|
|
171
187
|
fov = DEFAULTS.structure.fov,
|
|
172
188
|
initial_zoom = DEFAULTS.structure.initial_zoom,
|
|
173
189
|
ambient_light = DEFAULTS.structure.ambient_light,
|
|
174
190
|
directional_light = DEFAULTS.structure.directional_light,
|
|
175
191
|
sphere_segments = DEFAULTS.structure.sphere_segments,
|
|
176
192
|
lattice_props = {},
|
|
193
|
+
symmetry_elements = [],
|
|
194
|
+
symmetry_elements_props = {},
|
|
195
|
+
symmetry_declutter = true,
|
|
177
196
|
atom_label,
|
|
178
197
|
camera_is_moving = $bindable(false),
|
|
179
198
|
width = 0,
|
|
@@ -218,7 +237,7 @@
|
|
|
218
237
|
dragging_atoms = $bindable(false),
|
|
219
238
|
volumetric_data = undefined,
|
|
220
239
|
isosurface_settings = DEFAULT_ISOSURFACE_SETTINGS,
|
|
221
|
-
}: {
|
|
240
|
+
}: SceneControlProps & {
|
|
222
241
|
structure?: AnyStructure
|
|
223
242
|
base_structure?: AnyStructure // The original structure without image atoms, used for property color calculation
|
|
224
243
|
atom_radius?: number // scale factor for atomic radii
|
|
@@ -226,15 +245,6 @@
|
|
|
226
245
|
// determined by the atomic radius of the element
|
|
227
246
|
camera_position?: [x: number, y: number, z: number] // initial camera position from which to render the scene
|
|
228
247
|
camera_target?: Vec3 // external orbit-controls target for pan synchronization
|
|
229
|
-
camera_projection?: CameraProjection // camera projection type
|
|
230
|
-
rotation_damping?: number // rotation damping factor (how quickly the rotation comes to rest after mouse release)
|
|
231
|
-
// zoom level of the camera
|
|
232
|
-
max_zoom?: number
|
|
233
|
-
min_zoom?: number
|
|
234
|
-
rotate_speed?: number // rotation speed. set to 0 to disable rotation.
|
|
235
|
-
zoom_speed?: number // zoom speed. set to 0 to disable zooming.
|
|
236
|
-
pan_speed?: number // pan speed. set to 0 to disable panning.
|
|
237
|
-
zoom_to_cursor?: boolean // zoom toward cursor position instead of scene center
|
|
238
248
|
show_atoms?: boolean
|
|
239
249
|
show_bonds?: ShowBonds
|
|
240
250
|
show_site_labels?: boolean
|
|
@@ -250,30 +260,46 @@
|
|
|
250
260
|
vector_shaft_radius?: number
|
|
251
261
|
vector_arrow_head_radius?: number
|
|
252
262
|
vector_arrow_head_length?: number
|
|
253
|
-
gizmo?: boolean | ComponentProps<typeof extras.Gizmo>
|
|
254
263
|
hovered_idx?: number | null
|
|
255
264
|
hovered_site?: Site | null
|
|
256
265
|
float_fmt?: string
|
|
257
|
-
auto_rotate?: number
|
|
258
|
-
initial_zoom?: number
|
|
259
266
|
bond_thickness?: number
|
|
260
267
|
bond_color?: string
|
|
261
268
|
bonding_strategy?: BondingStrategy
|
|
262
269
|
auto_bond_order?: boolean
|
|
263
270
|
aromatic_display?: `aromatic` | `kekule`
|
|
264
271
|
bonding_options?: Record<string, unknown>
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
272
|
+
show_polyhedra?: ShowBonds // when to render coordination polyhedra
|
|
273
|
+
polyhedra_opacity?: number
|
|
274
|
+
polyhedra_show_edges?: boolean
|
|
275
|
+
polyhedra_edge_color?: string
|
|
276
|
+
polyhedra_color_mode?: PolyhedraColorMode
|
|
277
|
+
polyhedra_color?: string // custom color used when polyhedra_color_mode is 'uniform'
|
|
278
|
+
polyhedra_hide_center_atoms?: boolean
|
|
279
|
+
polyhedra_min_neighbors?: number // min coordination number to form a polyhedron
|
|
280
|
+
polyhedra_max_neighbors?: number // max CN - skips e.g. CN-12 cuboctahedra
|
|
281
|
+
polyhedra_excluded_elements?: readonly string[] // elements never used as polyhedra centers
|
|
282
|
+
polyhedra_included_elements?: readonly string[] // force-include (bypasses spectator hiding)
|
|
283
|
+
polyhedra_rendered_elements?: string[] // (output) elements that currently have polyhedra
|
|
268
284
|
sphere_segments?: number
|
|
269
285
|
lattice_props?: ComponentProps<typeof Lattice>
|
|
286
|
+
// Symmetry elements (from symmetry_elements_from_ops) to overlay on the structure.
|
|
287
|
+
// Fractional coords must refer to the SAME cell as the rendered lattice (moyo
|
|
288
|
+
// operations are in the input-cell frame, i.e. the original untransformed cell).
|
|
289
|
+
symmetry_elements?: SymmetryElement[]
|
|
290
|
+
symmetry_elements_props?: Omit<ComponentProps<typeof SymmetryElements>, `elements` | `lattice`>
|
|
291
|
+
// Auto-reduce visual clutter while a symmetry-element overlay is visible: hides
|
|
292
|
+
// coordination polyhedra and calculated bonds, and shrinks atoms so axes/planes/
|
|
293
|
+
// centers stay readable. Purely derived — toggling the overlay off restores the
|
|
294
|
+
// configured appearance.
|
|
295
|
+
symmetry_declutter?: boolean
|
|
270
296
|
atom_label?: Snippet<[{ site: Site; site_idx: number }]>
|
|
271
297
|
site_label_size?: number
|
|
272
298
|
site_label_offset?: Vec3
|
|
273
299
|
site_label_bg_color?: string
|
|
274
300
|
site_label_color?: string
|
|
275
301
|
site_label_padding?: number
|
|
276
|
-
camera_is_moving?: boolean //
|
|
302
|
+
camera_is_moving?: boolean // bindable: true while orbit controls are active
|
|
277
303
|
width?: number // Viewer dimensions for responsive zoom
|
|
278
304
|
height?: number
|
|
279
305
|
// measurement props
|
|
@@ -291,9 +317,6 @@
|
|
|
291
317
|
active_sites?: number[]
|
|
292
318
|
active_highlight_color?: string
|
|
293
319
|
rotation?: Vec3 // rotation control prop
|
|
294
|
-
// Expose scene and camera for external use (e.g. export pane)
|
|
295
|
-
scene?: Scene
|
|
296
|
-
camera?: Camera
|
|
297
320
|
orbit_controls?: ComponentProps<typeof extras.OrbitControls>[`ref`] // OrbitControls instance
|
|
298
321
|
rotation_target_ref?: Vec3 // Expose rotation target for reset
|
|
299
322
|
initial_computed_zoom?: number // Expose initial zoom for reset
|
|
@@ -322,13 +345,9 @@
|
|
|
322
345
|
)
|
|
323
346
|
let pulse_opacity = $derived(0.15 + 0.25 * pulse.unit)
|
|
324
347
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
camera = threlte.camera.current
|
|
329
|
-
if (threlte.renderer) {
|
|
330
|
-
Object.assign(threlte.renderer.domElement, { __renderer: threlte.renderer })
|
|
331
|
-
}
|
|
348
|
+
bind_renderer((threlte_scene, threlte_camera) => {
|
|
349
|
+
scene = threlte_scene
|
|
350
|
+
camera = threlte_camera
|
|
332
351
|
})
|
|
333
352
|
|
|
334
353
|
// Expose rotation target for external reset
|
|
@@ -409,9 +428,8 @@
|
|
|
409
428
|
|
|
410
429
|
// Desaturate a color by blending it toward gray (for ghosting image atoms in edit mode)
|
|
411
430
|
const gray = new Color(0x999999)
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
}
|
|
431
|
+
const desaturate = (hex: string | undefined, amount = 0.4): string =>
|
|
432
|
+
`#${new Color(hex ?? 0x999999).lerp(gray, amount).getHexString()}`
|
|
415
433
|
|
|
416
434
|
// === Edit-atoms mode state ===
|
|
417
435
|
let transform_object = $state<Mesh | undefined>(undefined)
|
|
@@ -738,6 +756,27 @@
|
|
|
738
756
|
return true
|
|
739
757
|
}
|
|
740
758
|
|
|
759
|
+
// Pointer props (hover + select) shared by instanced atoms and partial-occupancy
|
|
760
|
+
// hit targets. is_edit_image disables interaction for ghosted PBC image atoms.
|
|
761
|
+
const atom_pointer_props = (site_idx: number, is_edit_image: boolean) => ({
|
|
762
|
+
...atom_hover_props(site_idx, is_edit_image),
|
|
763
|
+
onpointerdown(event: PointerEvent) {
|
|
764
|
+
if (is_edit_image || measure_mode !== `edit-bonds` || bond_edit_mode !== `add`) return
|
|
765
|
+
select_edit_bonds_site(site_idx, event)
|
|
766
|
+
},
|
|
767
|
+
onclick(event: MouseEvent) {
|
|
768
|
+
if (is_edit_image) return
|
|
769
|
+
if (measure_mode === `edit-bonds`) {
|
|
770
|
+
if (bond_edit_mode !== `add`) return
|
|
771
|
+
if (skip_duplicate_edit_bonds_click(site_idx)) {
|
|
772
|
+
event.stopPropagation()
|
|
773
|
+
return
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
toggle_selection(site_idx, event)
|
|
777
|
+
},
|
|
778
|
+
})
|
|
779
|
+
|
|
741
780
|
function toggle_selection(site_index: number, evt?: Event) {
|
|
742
781
|
evt?.stopPropagation?.()
|
|
743
782
|
const event_with_native = evt as Event & { nativeEvent?: unknown } | undefined
|
|
@@ -853,7 +892,7 @@
|
|
|
853
892
|
|
|
854
893
|
let rotation_target = $derived(
|
|
855
894
|
lattice
|
|
856
|
-
?
|
|
895
|
+
? math.scale(math.add(...lattice.matrix), 0.5)
|
|
857
896
|
: structure
|
|
858
897
|
? get_center_of_mass(structure)
|
|
859
898
|
: [0, 0, 0] as Vec3,
|
|
@@ -924,16 +963,43 @@
|
|
|
924
963
|
camera_position = [distance, distance * 0.3, distance * 0.8]
|
|
925
964
|
}
|
|
926
965
|
})
|
|
966
|
+
// Whether a never|always|crystals|molecules setting applies to the current structure
|
|
967
|
+
const applies_to_structure = (when: ShowBonds): boolean =>
|
|
968
|
+
when === `always` ||
|
|
969
|
+
(when === `crystals` && Boolean(lattice)) ||
|
|
970
|
+
(when === `molecules` && !lattice)
|
|
971
|
+
|
|
972
|
+
// Declutter while a symmetry-element overlay actually draws something (elements present
|
|
973
|
+
// AND an enabled kind among them): hide coordination polyhedra/bonds and shrink atoms so
|
|
974
|
+
// axes/planes/centers stay readable. Gating on visibility (not just `symmetry_elements`)
|
|
975
|
+
// avoids hiding everything when nothing renders in its place — e.g. an inversion-only
|
|
976
|
+
// cell under the rotation-only default. Pure derived overrides: the configured
|
|
977
|
+
// appearance returns untouched the moment the overlay goes away.
|
|
978
|
+
const declutter_active = $derived(
|
|
979
|
+
symmetry_declutter &&
|
|
980
|
+
has_visible_symmetry_overlay(symmetry_elements, symmetry_elements_props.show_kinds),
|
|
981
|
+
)
|
|
982
|
+
const effective_show_polyhedra: ShowBonds = $derived(
|
|
983
|
+
declutter_active ? `never` : show_polyhedra,
|
|
984
|
+
)
|
|
985
|
+
// Calculated bonds are hidden in declutter mode (only their cylinders — bond_pairs
|
|
986
|
+
// stay computed so tooltips and manually added bonds keep working)
|
|
987
|
+
const effective_show_bonds: ShowBonds = $derived(
|
|
988
|
+
declutter_active ? `never` : show_bonds,
|
|
989
|
+
)
|
|
990
|
+
const effective_atom_radius = $derived(declutter_active ? atom_radius * 0.6 : atom_radius)
|
|
991
|
+
|
|
927
992
|
$effect(() => {
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
993
|
+
// Bonds are computed when either bond rendering or polyhedra need them. The
|
|
994
|
+
// raw/effective mix is deliberate: RAW show_bonds keeps bond_pairs available
|
|
995
|
+
// during symmetry declutter (cylinders hide via effective_show_bonds in
|
|
996
|
+
// bonds_to_render, but tooltips + manually added bonds still need the data),
|
|
997
|
+
// while EFFECTIVE show_polyhedra skips computing bonds whose only consumer —
|
|
998
|
+
// the polyhedra $derived below, gated on the same effective value — won't run.
|
|
999
|
+
const want_bonds = applies_to_structure(show_bonds)
|
|
1000
|
+
const want_polyhedra = applies_to_structure(effective_show_polyhedra)
|
|
1001
|
+
if (structure && (want_bonds || want_polyhedra)) {
|
|
1002
|
+
bond_pairs = BONDING_STRATEGIES[bonding_strategy](structure, bonding_options)
|
|
937
1003
|
} else bond_pairs = []
|
|
938
1004
|
})
|
|
939
1005
|
|
|
@@ -958,9 +1024,16 @@
|
|
|
958
1024
|
return total_occu > 0 ? weighted_sum / total_occu : 1
|
|
959
1025
|
}
|
|
960
1026
|
|
|
1027
|
+
// Disordered sites are often stored as separate split sites (one species each)
|
|
1028
|
+
// at the same position; merge_split_partial_sites groups them into one render
|
|
1029
|
+
// site whose `species` holds every element. Shared by atom rendering and the
|
|
1030
|
+
// hover tooltip so it lists all elements, not just the majority one.
|
|
1031
|
+
let render_sites = $derived(
|
|
1032
|
+
structure?.sites ? merge_split_partial_sites(structure.sites, hidden_elements) : [],
|
|
1033
|
+
)
|
|
1034
|
+
|
|
961
1035
|
let atom_data = $derived.by(() => {
|
|
962
|
-
if (!show_atoms
|
|
963
|
-
const render_sites = merge_split_partial_sites(structure.sites, hidden_elements)
|
|
1036
|
+
if (!show_atoms) return []
|
|
964
1037
|
return render_sites.flatMap(({ site_idx, site, is_image_atom }) => {
|
|
965
1038
|
const orig_idx = get_orig_site_idx(site, site_idx)
|
|
966
1039
|
|
|
@@ -968,12 +1041,26 @@
|
|
|
968
1041
|
const prop_val = property_colors?.values[orig_idx]
|
|
969
1042
|
if (prop_val !== undefined && hidden_prop_vals.has(prop_val)) return []
|
|
970
1043
|
|
|
1044
|
+
// Optionally hide atoms at the center of a rendered polyhedron
|
|
1045
|
+
if (polyhedra_hide_center_atoms && polyhedra_center_site_idxs.has(site_idx)) {
|
|
1046
|
+
return []
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
// Phase-2 PBC images exist only to complete bonds/coordination polyhedra at
|
|
1050
|
+
// cell faces. When neither renders (polyhedra toggled off, symmetry declutter,
|
|
1051
|
+
// …) they'd float disconnected outside the cell — hide them.
|
|
1052
|
+
if (
|
|
1053
|
+
site.properties?.completion_image &&
|
|
1054
|
+
!applies_to_structure(effective_show_bonds) &&
|
|
1055
|
+
!applies_to_structure(effective_show_polyhedra)
|
|
1056
|
+
) return []
|
|
1057
|
+
|
|
971
1058
|
// Calculate radius: same_size > site override > element override > default
|
|
972
1059
|
// All radii scale uniformly with atom_radius for consistent slider behavior
|
|
973
1060
|
const base_radius = same_size_atoms
|
|
974
1061
|
? 1
|
|
975
1062
|
: site_radius_overrides?.get(site_idx) ?? calc_weighted_radius(site)
|
|
976
|
-
const radius = base_radius *
|
|
1063
|
+
const radius = base_radius * effective_atom_radius
|
|
977
1064
|
|
|
978
1065
|
// Use property color if available (e.g. coordination number, Wyckoff position)
|
|
979
1066
|
// Otherwise, each species gets its own element color (important for disordered sites)
|
|
@@ -1080,17 +1167,110 @@
|
|
|
1080
1167
|
return [...calculated, ...added]
|
|
1081
1168
|
})
|
|
1082
1169
|
|
|
1170
|
+
// Bonds drawn as cylinders. When show_bonds doesn't apply, calculated bonds are
|
|
1171
|
+
// hidden but manually added bonds stay visible (bond_pairs may still be computed
|
|
1172
|
+
// for polyhedra, so this can't rely on bond_pairs being empty).
|
|
1173
|
+
let bonds_to_render = $derived.by(() => {
|
|
1174
|
+
if (applies_to_structure(effective_show_bonds)) return filtered_bond_pairs
|
|
1175
|
+
const added_keys = new Set(added_bonds.map(bond_key_for))
|
|
1176
|
+
return filtered_bond_pairs.filter((bond) => added_keys.has(bond_key_for(bond)))
|
|
1177
|
+
})
|
|
1178
|
+
|
|
1083
1179
|
let editable_bond_pairs = $derived(
|
|
1084
|
-
bond_edits_enabled ?
|
|
1180
|
+
bond_edits_enabled ? bonds_to_render.filter(can_edit_bond) : [],
|
|
1181
|
+
)
|
|
1182
|
+
|
|
1183
|
+
// Coordination polyhedra around cation-like centers, derived from the same
|
|
1184
|
+
// (edited, filtered) bond graph as rendered bonds so the two never disagree.
|
|
1185
|
+
// Colors are resolved in polyhedra_buffers below, so color-scheme/mode changes
|
|
1186
|
+
// never recompute the hull geometry.
|
|
1187
|
+
let polyhedra: Polyhedron[] = $derived.by(() => {
|
|
1188
|
+
if (
|
|
1189
|
+
!structure?.sites || dragging_atoms ||
|
|
1190
|
+
!applies_to_structure(effective_show_polyhedra) ||
|
|
1191
|
+
filtered_bond_pairs.length === 0
|
|
1192
|
+
) return []
|
|
1193
|
+
return compute_polyhedra(structure, filtered_bond_pairs, {
|
|
1194
|
+
min_neighbors: polyhedra_min_neighbors,
|
|
1195
|
+
max_neighbors: polyhedra_max_neighbors,
|
|
1196
|
+
excluded_center_elements: polyhedra_excluded_elements,
|
|
1197
|
+
included_center_elements: polyhedra_included_elements,
|
|
1198
|
+
})
|
|
1199
|
+
})
|
|
1200
|
+
|
|
1201
|
+
// Color of a site: property color (coordination/Wyckoff modes) or element color
|
|
1202
|
+
const polyhedra_site_color = (site_idx: number): string => {
|
|
1203
|
+
const site = structure?.sites[site_idx]
|
|
1204
|
+
const orig_idx = get_orig_site_idx(site, site_idx)
|
|
1205
|
+
const element = get_majority_element(site)
|
|
1206
|
+
return property_colors?.colors[orig_idx] ??
|
|
1207
|
+
(element && colors.element?.[element]) ?? `#808080`
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1210
|
+
// Separate derived so material-only changes (opacity, edge color) don't rebuild
|
|
1211
|
+
// buffers and color changes don't rebuild hulls
|
|
1212
|
+
let polyhedra_buffers = $derived.by(() => {
|
|
1213
|
+
if (polyhedra.length === 0) return null
|
|
1214
|
+
const get_vertex_color = (poly: Polyhedron, vertex_idx: number): string => {
|
|
1215
|
+
if (polyhedra_color_mode === `uniform`) return polyhedra_color
|
|
1216
|
+
if (polyhedra_color_mode === `center`) {
|
|
1217
|
+
return polyhedra_site_color(poly.center_site_idx)
|
|
1218
|
+
}
|
|
1219
|
+
// 'vertex' (default): each corner takes the color of the atom that forms it
|
|
1220
|
+
return polyhedra_site_color(poly.vertex_site_idxs[vertex_idx])
|
|
1221
|
+
}
|
|
1222
|
+
return merge_polyhedra_buffers(polyhedra, get_vertex_color)
|
|
1223
|
+
})
|
|
1224
|
+
|
|
1225
|
+
let polyhedra_center_site_idxs = $derived(
|
|
1226
|
+
new Set(polyhedra.map((poly) => poly.center_site_idx)),
|
|
1085
1227
|
)
|
|
1086
1228
|
|
|
1229
|
+
// Publish which elements currently anchor polyhedra (consumed by controls so
|
|
1230
|
+
// per-element toggles reflect the actual render state incl. spectator hiding)
|
|
1231
|
+
$effect(() => {
|
|
1232
|
+
const elems = [...new Set(polyhedra.map((poly) => poly.center_element))].sort()
|
|
1233
|
+
if (elems.join(`,`) !== polyhedra_rendered_elements.join(`,`)) {
|
|
1234
|
+
polyhedra_rendered_elements = elems
|
|
1235
|
+
}
|
|
1236
|
+
})
|
|
1237
|
+
|
|
1238
|
+
// Geometries with proper disposal on dependency change (same pattern as ReferencePlane)
|
|
1239
|
+
const buffer_geometry = (attrs: Record<string, Float32Array>): BufferGeometry => {
|
|
1240
|
+
const geo = new BufferGeometry()
|
|
1241
|
+
for (const [name, array] of Object.entries(attrs)) {
|
|
1242
|
+
geo.setAttribute(name, new BufferAttribute(array, 3))
|
|
1243
|
+
}
|
|
1244
|
+
return geo
|
|
1245
|
+
}
|
|
1246
|
+
let polyhedra_geometry: BufferGeometry | null = $state(null)
|
|
1247
|
+
$effect(() => {
|
|
1248
|
+
let geo: BufferGeometry | null = null
|
|
1249
|
+
if (polyhedra_buffers && polyhedra_buffers.triangle_count > 0) {
|
|
1250
|
+
const { positions: position, colors: color } = polyhedra_buffers
|
|
1251
|
+
geo = buffer_geometry({ position, color })
|
|
1252
|
+
geo.computeVertexNormals() // non-indexed -> per-face normals (flat shading)
|
|
1253
|
+
}
|
|
1254
|
+
polyhedra_geometry = geo
|
|
1255
|
+
return () => geo?.dispose()
|
|
1256
|
+
})
|
|
1257
|
+
|
|
1258
|
+
let polyhedra_edge_geometry: BufferGeometry | null = $state(null)
|
|
1259
|
+
$effect(() => {
|
|
1260
|
+
const geo = polyhedra_show_edges && polyhedra_buffers && polyhedra_buffers.edge_count > 0
|
|
1261
|
+
? buffer_geometry({ position: polyhedra_buffers.edge_positions })
|
|
1262
|
+
: null
|
|
1263
|
+
polyhedra_edge_geometry = geo
|
|
1264
|
+
return () => geo?.dispose()
|
|
1265
|
+
})
|
|
1266
|
+
|
|
1087
1267
|
let smart_site_label_offsets = $derived.by(() => {
|
|
1088
1268
|
const offsets = new SvelteMap<number, Vec3>()
|
|
1089
|
-
if (
|
|
1269
|
+
if (bonds_to_render.length === 0) return offsets
|
|
1090
1270
|
|
|
1091
1271
|
const bond_directions_by_site = new SvelteMap<number, Vec3[]>()
|
|
1092
1272
|
const add_bond_direction = (site_idx: number, pos_1: Vec3, pos_2: Vec3) => {
|
|
1093
|
-
const direction = math.
|
|
1273
|
+
const direction = math.normalize_vec(
|
|
1094
1274
|
math.subtract(pos_2, pos_1),
|
|
1095
1275
|
[0, 0, 0],
|
|
1096
1276
|
)
|
|
@@ -1101,7 +1281,7 @@
|
|
|
1101
1281
|
])
|
|
1102
1282
|
}
|
|
1103
1283
|
|
|
1104
|
-
for (const { site_idx_1, site_idx_2, pos_1, pos_2 } of
|
|
1284
|
+
for (const { site_idx_1, site_idx_2, pos_1, pos_2 } of bonds_to_render) {
|
|
1105
1285
|
add_bond_direction(site_idx_1, pos_1, pos_2)
|
|
1106
1286
|
add_bond_direction(site_idx_2, pos_2, pos_1)
|
|
1107
1287
|
}
|
|
@@ -1112,7 +1292,7 @@
|
|
|
1112
1292
|
})
|
|
1113
1293
|
|
|
1114
1294
|
let instanced_bond_groups = $derived.by(() => {
|
|
1115
|
-
if (!structure?.sites ||
|
|
1295
|
+
if (!structure?.sites || bonds_to_render.length === 0) return []
|
|
1116
1296
|
|
|
1117
1297
|
const group = {
|
|
1118
1298
|
thickness: bond_thickness,
|
|
@@ -1125,7 +1305,7 @@
|
|
|
1125
1305
|
}[],
|
|
1126
1306
|
}
|
|
1127
1307
|
|
|
1128
|
-
for (const bond_data of
|
|
1308
|
+
for (const bond_data of bonds_to_render) {
|
|
1129
1309
|
const site_a = structure.sites[bond_data.site_idx_1]
|
|
1130
1310
|
const site_b = structure.sites[bond_data.site_idx_2]
|
|
1131
1311
|
|
|
@@ -1155,6 +1335,24 @@
|
|
|
1155
1335
|
return map
|
|
1156
1336
|
})
|
|
1157
1337
|
|
|
1338
|
+
// Partial-occupancy atoms render as separate wedge (lune) meshes that converge
|
|
1339
|
+
// to a point at the sphere's poles, leaving the ball hard to hover from some
|
|
1340
|
+
// angles. Give each such site one invisible full-sphere hit target so it's as
|
|
1341
|
+
// reliably hoverable as an ordered atom (single solid sphere). One per site.
|
|
1342
|
+
let partial_hit_targets = $derived.by(() => {
|
|
1343
|
+
const targets = new SvelteMap<number, EditableAtomHitTarget & { is_image_atom: boolean }>()
|
|
1344
|
+
for (const atom of atom_data) {
|
|
1345
|
+
if (!atom.has_partial_occupancy || targets.has(atom.site_idx)) continue
|
|
1346
|
+
targets.set(atom.site_idx, {
|
|
1347
|
+
site_idx: atom.site_idx,
|
|
1348
|
+
position: atom.position,
|
|
1349
|
+
radius: atom.radius,
|
|
1350
|
+
is_image_atom: atom.is_image_atom,
|
|
1351
|
+
})
|
|
1352
|
+
}
|
|
1353
|
+
return [...targets.values()]
|
|
1354
|
+
})
|
|
1355
|
+
|
|
1158
1356
|
let editable_atom_hit_targets = $derived.by(() => {
|
|
1159
1357
|
if (
|
|
1160
1358
|
measure_mode !== `edit-bonds` ||
|
|
@@ -1184,7 +1382,7 @@
|
|
|
1184
1382
|
? site_radius_overrides?.get(site_idx)
|
|
1185
1383
|
: undefined
|
|
1186
1384
|
const base_radius = same_size_atoms ? 1 : override ?? calc_weighted_radius(site)
|
|
1187
|
-
return base_radius *
|
|
1385
|
+
return base_radius * effective_atom_radius
|
|
1188
1386
|
}
|
|
1189
1387
|
|
|
1190
1388
|
// Interpolate between spin-down (#3498db blue) and spin-up (#e74c3c red)
|
|
@@ -1253,16 +1451,16 @@
|
|
|
1253
1451
|
let mean: Vec3 = [0, 0, 0]
|
|
1254
1452
|
for (const key of site_keys) {
|
|
1255
1453
|
const vec = vec_map.get(key)
|
|
1256
|
-
if (vec) mean = math.add(mean, math.
|
|
1454
|
+
if (vec) mean = math.add(mean, math.normalize_vec(vec)) as Vec3
|
|
1257
1455
|
}
|
|
1258
|
-
const mean_dir = math.
|
|
1456
|
+
const mean_dir = math.normalize_vec(mean, [0, 1, 0] as Vec3)
|
|
1259
1457
|
const [u_vec, v_vec] = math.compute_in_plane_basis(mean_dir)
|
|
1260
1458
|
const offsets = new SvelteMap<string, Vec3>()
|
|
1261
1459
|
for (const [idx, key] of site_keys.entries()) {
|
|
1262
1460
|
const angle = (2 * Math.PI * idx) / n_keys
|
|
1263
|
-
const dx = math.scale(u_vec, gap_abs * Math.cos(angle))
|
|
1264
|
-
const dy = math.scale(v_vec, gap_abs * Math.sin(angle))
|
|
1265
|
-
offsets.set(key, math.add(dx, dy)
|
|
1461
|
+
const dx = math.scale(u_vec, gap_abs * Math.cos(angle))
|
|
1462
|
+
const dy = math.scale(v_vec, gap_abs * Math.sin(angle))
|
|
1463
|
+
offsets.set(key, math.add(dx, dy))
|
|
1266
1464
|
}
|
|
1267
1465
|
return offsets
|
|
1268
1466
|
})
|
|
@@ -1316,8 +1514,8 @@
|
|
|
1316
1514
|
}
|
|
1317
1515
|
|
|
1318
1516
|
const offset = site_offsets?.[site_idx]?.get(key)
|
|
1319
|
-
const position = offset ? math.add(site.xyz, offset)
|
|
1320
|
-
const arrow_vec = vector_normalize ? math.
|
|
1517
|
+
const position = offset ? math.add(site.xyz, offset) : site.xyz
|
|
1518
|
+
const arrow_vec = vector_normalize ? math.normalize_vec(vec) : vec
|
|
1321
1519
|
|
|
1322
1520
|
return {
|
|
1323
1521
|
site_idx,
|
|
@@ -1365,57 +1563,29 @@
|
|
|
1365
1563
|
),
|
|
1366
1564
|
)
|
|
1367
1565
|
|
|
1368
|
-
let
|
|
1369
|
-
|
|
1370
|
-
[...AXIS_COLORS, ...NEG_AXIS_COLORS].map(([axis, color, hover_color]) => [
|
|
1371
|
-
axis,
|
|
1372
|
-
{
|
|
1373
|
-
color,
|
|
1374
|
-
labelColor: `#111`,
|
|
1375
|
-
opacity: axis.startsWith(`n`) ? 0.9 : 0.8,
|
|
1376
|
-
hover: {
|
|
1377
|
-
color: hover_color,
|
|
1378
|
-
labelColor: `#222222`,
|
|
1379
|
-
opacity: axis.startsWith(`n`) ? 1 : 0.9,
|
|
1380
|
-
},
|
|
1381
|
-
},
|
|
1382
|
-
]),
|
|
1383
|
-
)
|
|
1384
|
-
return {
|
|
1385
|
-
background: { enabled: false },
|
|
1386
|
-
className: `responsive-gizmo`,
|
|
1387
|
-
...axis_options,
|
|
1388
|
-
...(typeof gizmo === `boolean` ? {} : gizmo),
|
|
1389
|
-
offset: { left: 5, bottom: 5 },
|
|
1390
|
-
}
|
|
1391
|
-
})
|
|
1392
|
-
|
|
1393
|
-
let orbit_controls_props = $derived({
|
|
1394
|
-
position: [0, 0, 0],
|
|
1395
|
-
enableRotate: rotate_speed > 0,
|
|
1396
|
-
rotateSpeed: rotate_speed,
|
|
1397
|
-
enableZoom: zoom_speed > 0,
|
|
1398
|
-
zoomSpeed: camera_projection === `orthographic` ? zoom_speed * 2 : zoom_speed,
|
|
1399
|
-
zoomToCursor: zoom_to_cursor,
|
|
1400
|
-
enablePan: pan_speed > 0,
|
|
1401
|
-
panSpeed: pan_speed,
|
|
1566
|
+
let orbit_controls_props = $derived(build_orbit_props({
|
|
1567
|
+
camera_projection,
|
|
1402
1568
|
target: camera_target ?? rotation_target,
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1569
|
+
rotate_speed,
|
|
1570
|
+
zoom_speed,
|
|
1571
|
+
zoom_to_cursor,
|
|
1572
|
+
pan_speed,
|
|
1573
|
+
max_zoom,
|
|
1574
|
+
min_zoom,
|
|
1575
|
+
auto_rotate,
|
|
1576
|
+
rotation_damping,
|
|
1577
|
+
set_camera_is_moving: (moving) => (camera_is_moving = moving),
|
|
1578
|
+
// Close hover tooltips + bond context menu while the camera moves. Only hide the
|
|
1579
|
+
// VISIBLE menu (not bond_context_target): clicking a menu button fires this
|
|
1580
|
+
// orbit-controls start handler before the button's own handler runs, which still
|
|
1581
|
+
// needs the target bond to apply the edit (see bond_context_target comment).
|
|
1582
|
+
onstart_extra: () => {
|
|
1411
1583
|
cancel_atom_hover_clear()
|
|
1412
1584
|
hovered_idx = null
|
|
1585
|
+
hovered_bond_key = null
|
|
1413
1586
|
bond_context_menu = null
|
|
1414
1587
|
},
|
|
1415
|
-
|
|
1416
|
-
camera_is_moving = false
|
|
1417
|
-
},
|
|
1418
|
-
})
|
|
1588
|
+
}))
|
|
1419
1589
|
|
|
1420
1590
|
let measure_line_color = $derived.by(() => {
|
|
1421
1591
|
if (typeof window === `undefined`) return
|
|
@@ -1492,31 +1662,17 @@
|
|
|
1492
1662
|
</extras.HTML>
|
|
1493
1663
|
{/snippet}
|
|
1494
1664
|
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
</T.PerspectiveCamera>
|
|
1507
|
-
{:else}
|
|
1508
|
-
<T.OrthographicCamera
|
|
1509
|
-
makeDefault
|
|
1510
|
-
position={camera_position}
|
|
1511
|
-
zoom={computed_zoom}
|
|
1512
|
-
near={-100}
|
|
1513
|
-
far={camera_far}
|
|
1514
|
-
>
|
|
1515
|
-
<extras.OrbitControls bind:ref={orbit_controls} {...orbit_controls_props}>
|
|
1516
|
-
{#if gizmo}<extras.Gizmo {...gizmo_props} />{/if}
|
|
1517
|
-
</extras.OrbitControls>
|
|
1518
|
-
</T.OrthographicCamera>
|
|
1519
|
-
{/if}
|
|
1665
|
+
<SceneCamera
|
|
1666
|
+
{camera_projection}
|
|
1667
|
+
position={camera_position}
|
|
1668
|
+
{fov}
|
|
1669
|
+
zoom={computed_zoom}
|
|
1670
|
+
near={camera_near}
|
|
1671
|
+
far={camera_far}
|
|
1672
|
+
orbit_props={orbit_controls_props}
|
|
1673
|
+
{gizmo}
|
|
1674
|
+
bind:orbit_controls
|
|
1675
|
+
/>
|
|
1520
1676
|
|
|
1521
1677
|
<T.DirectionalLight position={[3, 10, 10]} intensity={directional_light} />
|
|
1522
1678
|
<T.AmbientLight intensity={ambient_light} />
|
|
@@ -1546,28 +1702,7 @@
|
|
|
1546
1702
|
<extras.Instance
|
|
1547
1703
|
position={atom.position}
|
|
1548
1704
|
scale={atom.radius}
|
|
1549
|
-
{...
|
|
1550
|
-
onpointerdown={(event: PointerEvent) => {
|
|
1551
|
-
if (
|
|
1552
|
-
edit_mode_image ||
|
|
1553
|
-
measure_mode !== `edit-bonds` ||
|
|
1554
|
-
bond_edit_mode !== `add`
|
|
1555
|
-
) {
|
|
1556
|
-
return
|
|
1557
|
-
}
|
|
1558
|
-
select_edit_bonds_site(atom.site_idx, event)
|
|
1559
|
-
}}
|
|
1560
|
-
onclick={(event: MouseEvent) => {
|
|
1561
|
-
if (edit_mode_image) return
|
|
1562
|
-
if (measure_mode === `edit-bonds`) {
|
|
1563
|
-
if (bond_edit_mode !== `add`) return
|
|
1564
|
-
if (skip_duplicate_edit_bonds_click(atom.site_idx)) {
|
|
1565
|
-
event.stopPropagation()
|
|
1566
|
-
return
|
|
1567
|
-
}
|
|
1568
|
-
}
|
|
1569
|
-
toggle_selection(atom.site_idx, event)
|
|
1570
|
-
}}
|
|
1705
|
+
{...atom_pointer_props(atom.site_idx, edit_mode_image)}
|
|
1571
1706
|
/>
|
|
1572
1707
|
{/each}
|
|
1573
1708
|
</extras.InstancedMesh>
|
|
@@ -1580,32 +1715,9 @@
|
|
|
1580
1715
|
}
|
|
1581
1716
|
{@const partial_edit_image = measure_mode === `edit-atoms` && atom.is_image_atom}
|
|
1582
1717
|
{@const ghost_opacity = partial_edit_image ? 0.5 : 1}
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
{...atom_hover_props(atom.site_idx, partial_edit_image)}
|
|
1587
|
-
onpointerdown={(event: PointerEvent) => {
|
|
1588
|
-
if (
|
|
1589
|
-
partial_edit_image ||
|
|
1590
|
-
measure_mode !== `edit-bonds` ||
|
|
1591
|
-
bond_edit_mode !== `add`
|
|
1592
|
-
) {
|
|
1593
|
-
return
|
|
1594
|
-
}
|
|
1595
|
-
select_edit_bonds_site(atom.site_idx, event)
|
|
1596
|
-
}}
|
|
1597
|
-
onclick={(event: MouseEvent) => {
|
|
1598
|
-
if (partial_edit_image) return
|
|
1599
|
-
if (measure_mode === `edit-bonds`) {
|
|
1600
|
-
if (bond_edit_mode !== `add`) return
|
|
1601
|
-
if (skip_duplicate_edit_bonds_click(atom.site_idx)) {
|
|
1602
|
-
event.stopPropagation()
|
|
1603
|
-
return
|
|
1604
|
-
}
|
|
1605
|
-
}
|
|
1606
|
-
toggle_selection(atom.site_idx, event)
|
|
1607
|
-
}}
|
|
1608
|
-
>
|
|
1718
|
+
<!-- Visual only: pointer interaction handled by the invisible full-sphere
|
|
1719
|
+
hit targets below (wedge meshes leave gaps at the poles). -->
|
|
1720
|
+
<T.Group position={atom.position} scale={atom.radius}>
|
|
1609
1721
|
{@const partial_color = partial_edit_image
|
|
1610
1722
|
? desaturate(atom.color)
|
|
1611
1723
|
: atom.color}
|
|
@@ -1626,7 +1738,7 @@
|
|
|
1626
1738
|
/>
|
|
1627
1739
|
</T.Mesh>
|
|
1628
1740
|
|
|
1629
|
-
{#if atom.
|
|
1741
|
+
{#if atom.render_start_cap}
|
|
1630
1742
|
<T.Mesh rotation={[0, atom.start_phi, 0]}>
|
|
1631
1743
|
<T.CircleGeometry
|
|
1632
1744
|
args={[
|
|
@@ -1644,7 +1756,7 @@
|
|
|
1644
1756
|
/>
|
|
1645
1757
|
</T.Mesh>
|
|
1646
1758
|
{/if}
|
|
1647
|
-
{#if atom.
|
|
1759
|
+
{#if atom.render_end_cap}
|
|
1648
1760
|
<T.Mesh rotation={[0, atom.end_phi, 0]}>
|
|
1649
1761
|
<T.CircleGeometry
|
|
1650
1762
|
args={[
|
|
@@ -1671,6 +1783,20 @@
|
|
|
1671
1783
|
{/if}
|
|
1672
1784
|
{/each}
|
|
1673
1785
|
|
|
1786
|
+
<!-- Invisible full-sphere hit targets for partial-occupancy sites so the
|
|
1787
|
+
whole ball is hoverable/clickable (wedge meshes leave gaps at the poles). -->
|
|
1788
|
+
{#each partial_hit_targets as hit (hit.site_idx)}
|
|
1789
|
+
{@const hit_edit_image = measure_mode === `edit-atoms` && hit.is_image_atom}
|
|
1790
|
+
<T.Mesh
|
|
1791
|
+
position={hit.position}
|
|
1792
|
+
scale={hit.radius}
|
|
1793
|
+
{...atom_pointer_props(hit.site_idx, hit_edit_image)}
|
|
1794
|
+
>
|
|
1795
|
+
<T.SphereGeometry args={[0.5, sphere_segments, sphere_segments]} />
|
|
1796
|
+
<T.MeshBasicMaterial transparent opacity={0} depthWrite={false} />
|
|
1797
|
+
</T.Mesh>
|
|
1798
|
+
{/each}
|
|
1799
|
+
|
|
1674
1800
|
<!-- Site labels/indices for instanced atoms -->
|
|
1675
1801
|
{#if show_site_labels || show_site_indices}
|
|
1676
1802
|
{#each unique_instanced_atoms as atom (atom.site_idx)}
|
|
@@ -1697,6 +1823,32 @@
|
|
|
1697
1823
|
{/each}
|
|
1698
1824
|
{/if}
|
|
1699
1825
|
|
|
1826
|
+
<!-- Coordination polyhedra: all faces in one merged mesh, edges in one
|
|
1827
|
+
LineSegments (1-2 draw calls regardless of supercell size) -->
|
|
1828
|
+
{#if polyhedra_geometry}
|
|
1829
|
+
<T.Mesh geometry={polyhedra_geometry} frustumCulled={false} raycast={() => null}>
|
|
1830
|
+
<!-- depthWrite when mostly opaque: VESTA-like occlusion between polyhedra;
|
|
1831
|
+
fully translucent settings fall back to see-through blending -->
|
|
1832
|
+
<T.MeshStandardMaterial
|
|
1833
|
+
vertexColors
|
|
1834
|
+
transparent={polyhedra_opacity < 1}
|
|
1835
|
+
opacity={polyhedra_opacity}
|
|
1836
|
+
side={DoubleSide}
|
|
1837
|
+
depthWrite={polyhedra_opacity >= 0.65}
|
|
1838
|
+
flatShading
|
|
1839
|
+
/>
|
|
1840
|
+
</T.Mesh>
|
|
1841
|
+
{#if polyhedra_edge_geometry}
|
|
1842
|
+
<T.LineSegments
|
|
1843
|
+
geometry={polyhedra_edge_geometry}
|
|
1844
|
+
frustumCulled={false}
|
|
1845
|
+
raycast={() => null}
|
|
1846
|
+
>
|
|
1847
|
+
<T.LineBasicMaterial color={polyhedra_edge_color} />
|
|
1848
|
+
</T.LineSegments>
|
|
1849
|
+
{/if}
|
|
1850
|
+
{/if}
|
|
1851
|
+
|
|
1700
1852
|
<!-- Clickable bond hit-test cylinders in edit-bonds mode -->
|
|
1701
1853
|
{#if measure_mode === `edit-bonds` && editable_bond_pairs.length > 0}
|
|
1702
1854
|
{#each editable_bond_pairs as
|
|
@@ -1911,8 +2063,8 @@
|
|
|
1911
2063
|
{@const site = structure.sites[site_index]}
|
|
1912
2064
|
{#if site}
|
|
1913
2065
|
<!-- shift selected site labels down to avoid overlapping regular site labels-->
|
|
1914
|
-
{@const selection_offset = math.add(site_label_offset, [0, -0.5, 0])}
|
|
1915
|
-
{@const pos = math.add(site.xyz, selection_offset)
|
|
2066
|
+
{@const selection_offset = math.add<Vec3>(site_label_offset, [0, -0.5, 0])}
|
|
2067
|
+
{@const pos = math.add(site.xyz, selection_offset)}
|
|
1916
2068
|
<extras.HTML center position={pos}>
|
|
1917
2069
|
<span class="selection-label">{loop_idx + 1}</span>
|
|
1918
2070
|
</extras.HTML>
|
|
@@ -1953,10 +2105,13 @@
|
|
|
1953
2105
|
.map(([elem, count]) => `${elem}: ${count}`)
|
|
1954
2106
|
return ` (${parts.join(`, `)})`
|
|
1955
2107
|
})()}
|
|
2108
|
+
{@const tooltip_species =
|
|
2109
|
+
render_sites.find((rs) => rs.site_idx === hovered_idx)?.site.species ??
|
|
2110
|
+
hovered_site.species ?? []}
|
|
1956
2111
|
<CanvasTooltip position={hovered_site.xyz}>
|
|
1957
2112
|
<!-- Element symbols with occupancies for disordered sites -->
|
|
1958
2113
|
<div class="elements">
|
|
1959
|
-
{#each
|
|
2114
|
+
{#each tooltip_species as
|
|
1960
2115
|
{ element, occu, oxidation_state: oxi_state },
|
|
1961
2116
|
idx
|
|
1962
2117
|
(`${element ?? ``}-${occu ?? ``}-${oxi_state ?? ``}-${idx}`)
|
|
@@ -1965,16 +2120,17 @@
|
|
|
1965
2120
|
elem.symbol === element
|
|
1966
2121
|
)?.name ??
|
|
1967
2122
|
``}
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
2123
|
+
<span class="species">
|
|
2124
|
+
{#if occu !== 1}<span class="occupancy">{
|
|
2125
|
+
format_num(occu, `.3~f`)
|
|
2126
|
+
}</span>{/if}
|
|
2127
|
+
<strong>
|
|
2128
|
+
{element}{#if oxi_state != null && oxi_state !== 0}<sup>{Math.abs(
|
|
2129
|
+
oxi_state,
|
|
2130
|
+
)}{oxi_state > 0 ? `+` : `−`}</sup>{/if}
|
|
2131
|
+
</strong>
|
|
2132
|
+
{#if element_name}<span class="elem-name">{element_name}</span>{/if}
|
|
2133
|
+
</span>
|
|
1978
2134
|
{/each}
|
|
1979
2135
|
</div>
|
|
1980
2136
|
<div class="coordinates fractional">abc: ({abc})</div>
|
|
@@ -1987,6 +2143,13 @@
|
|
|
1987
2143
|
|
|
1988
2144
|
{#if visual_lattice}
|
|
1989
2145
|
<Lattice matrix={visual_lattice.matrix} {...lattice_props} />
|
|
2146
|
+
{#if symmetry_elements.length > 0}
|
|
2147
|
+
<SymmetryElements
|
|
2148
|
+
elements={symmetry_elements}
|
|
2149
|
+
lattice={visual_lattice.matrix}
|
|
2150
|
+
{...symmetry_elements_props}
|
|
2151
|
+
/>
|
|
2152
|
+
{/if}
|
|
1990
2153
|
{/if}
|
|
1991
2154
|
|
|
1992
2155
|
<!-- TransformControls for editing atoms in edit-atoms mode -->
|
|
@@ -2096,7 +2259,7 @@
|
|
|
2096
2259
|
] as Vec3}
|
|
2097
2260
|
{@const direct = math.euclidean_dist(pos_i, pos_j)}
|
|
2098
2261
|
{@const pbc = lattice
|
|
2099
|
-
? measure.distance_pbc(pos_i, pos_j, lattice.matrix)
|
|
2262
|
+
? measure.distance_pbc(pos_i, pos_j, lattice.matrix, undefined, lattice.pbc)
|
|
2100
2263
|
: direct}
|
|
2101
2264
|
{@const differ = lattice ? Math.abs(pbc - direct) > 1e-6 : false}
|
|
2102
2265
|
<extras.HTML center position={midpoint}>
|
|
@@ -2125,8 +2288,10 @@
|
|
|
2125
2288
|
}
|
|
2126
2289
|
{@const site_a = structure.sites[idx_a]}
|
|
2127
2290
|
{@const site_b = structure.sites[idx_b]}
|
|
2128
|
-
{@const
|
|
2129
|
-
|
|
2291
|
+
{@const disp = (to: Vec3) =>
|
|
2292
|
+
measure.displacement_pbc(center.xyz, to, lattice?.matrix, undefined, lattice?.pbc)}
|
|
2293
|
+
{@const v1 = disp(site_a.xyz)}
|
|
2294
|
+
{@const v2 = disp(site_b.xyz)}
|
|
2130
2295
|
{@const n1 = Math.hypot(v1[0], v1[1], v1[2])}
|
|
2131
2296
|
{@const n2 = Math.hypot(v2[0], v2[1], v2[2])}
|
|
2132
2297
|
{@const angle_deg = measure.angle_between_vectors(v1, v2, `degrees`)}
|
|
@@ -2162,10 +2327,6 @@
|
|
|
2162
2327
|
</T.Group>
|
|
2163
2328
|
|
|
2164
2329
|
<style>
|
|
2165
|
-
:global(.structure .responsive-gizmo) {
|
|
2166
|
-
width: clamp(70px, 18cqmin, 100px) !important;
|
|
2167
|
-
height: clamp(70px, 18cqmin, 100px) !important;
|
|
2168
|
-
}
|
|
2169
2330
|
.atom-label {
|
|
2170
2331
|
background: var(--struct-atom-label-bg, rgba(0, 0, 0, 0.1));
|
|
2171
2332
|
border: 0;
|
|
@@ -2179,6 +2340,13 @@
|
|
|
2179
2340
|
.elements {
|
|
2180
2341
|
margin-bottom: var(--canvas-tooltip-elements-margin);
|
|
2181
2342
|
}
|
|
2343
|
+
.species {
|
|
2344
|
+
display: inline-block;
|
|
2345
|
+
white-space: nowrap;
|
|
2346
|
+
&:not(:first-child) {
|
|
2347
|
+
margin-left: var(--canvas-tooltip-species-gap, 0.5em);
|
|
2348
|
+
}
|
|
2349
|
+
}
|
|
2182
2350
|
.occupancy {
|
|
2183
2351
|
font-size: var(--canvas-tooltip-occu-font-size);
|
|
2184
2352
|
opacity: var(--canvas-tooltip-occu-opacity);
|