matterviz 0.3.1 → 0.3.2
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/FilePicker.svelte +37 -20
- package/dist/Icon.svelte +2 -2
- package/dist/app.css +29 -0
- package/dist/brillouin/BrillouinZone.svelte +19 -61
- package/dist/brillouin/BrillouinZone.svelte.d.ts +1 -1
- package/dist/brillouin/BrillouinZoneExportPane.svelte +12 -20
- package/dist/brillouin/BrillouinZoneScene.svelte +2 -2
- package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
- package/dist/chempot-diagram/ChemPotDiagram.svelte +192 -0
- package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +13 -0
- package/dist/chempot-diagram/ChemPotDiagram2D.svelte +677 -0
- package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +16 -0
- package/dist/chempot-diagram/ChemPotDiagram3D.svelte +2688 -0
- package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +16 -0
- package/dist/chempot-diagram/ChemPotScene3D.svelte +8 -0
- package/dist/chempot-diagram/ChemPotScene3D.svelte.d.ts +7 -0
- package/dist/chempot-diagram/color.d.ts +10 -0
- package/dist/chempot-diagram/color.js +33 -0
- package/dist/chempot-diagram/compute.d.ts +38 -0
- package/dist/chempot-diagram/compute.js +650 -0
- package/dist/chempot-diagram/index.d.ts +5 -0
- package/dist/chempot-diagram/index.js +5 -0
- package/dist/chempot-diagram/pointer.d.ts +16 -0
- package/dist/chempot-diagram/pointer.js +40 -0
- package/dist/chempot-diagram/temperature.d.ts +15 -0
- package/dist/chempot-diagram/temperature.js +37 -0
- package/dist/chempot-diagram/types.d.ts +83 -0
- package/dist/chempot-diagram/types.js +27 -0
- package/dist/colors/index.d.ts +3 -1
- package/dist/colors/index.js +4 -0
- package/dist/composition/BarChart.svelte +13 -22
- package/dist/composition/BubbleChart.svelte +5 -3
- package/dist/composition/FormulaFilter.svelte +586 -94
- package/dist/composition/FormulaFilter.svelte.d.ts +35 -1
- package/dist/composition/PieChart.svelte +43 -18
- package/dist/composition/PieChart.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull.svelte +4 -2
- package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull2D.svelte +13 -44
- package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull3D.svelte +16 -7
- package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull4D.svelte +17 -7
- package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHullControls.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHullStats.svelte +701 -226
- package/dist/convex-hull/ConvexHullStats.svelte.d.ts +6 -1
- package/dist/convex-hull/ConvexHullTooltip.svelte +1 -0
- package/dist/convex-hull/demo-temperature.d.ts +6 -0
- package/dist/convex-hull/demo-temperature.js +36 -0
- package/dist/convex-hull/helpers.d.ts +1 -1
- package/dist/convex-hull/helpers.js +2 -4
- package/dist/convex-hull/index.d.ts +1 -0
- package/dist/convex-hull/index.js +1 -0
- package/dist/convex-hull/thermodynamics.d.ts +8 -21
- package/dist/convex-hull/thermodynamics.js +106 -17
- package/dist/convex-hull/types.d.ts +5 -0
- package/dist/convex-hull/types.js +5 -0
- package/dist/coordination/CoordinationBarPlot.svelte +29 -46
- package/dist/element/BohrAtom.svelte +1 -1
- package/dist/element/data.js +2 -14
- package/dist/element/data.json.gz +0 -0
- package/dist/element/types.d.ts +1 -0
- package/dist/fermi-surface/FermiSurface.svelte +20 -64
- package/dist/fermi-surface/FermiSurface.svelte.d.ts +1 -1
- package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
- package/dist/fermi-surface/FermiSurfaceScene.svelte +1 -1
- package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
- package/dist/fermi-surface/parse.js +16 -22
- package/dist/heatmap-matrix/HeatmapMatrix.svelte +1273 -0
- package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +110 -0
- package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +171 -0
- package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +31 -0
- package/dist/heatmap-matrix/index.d.ts +53 -0
- package/dist/heatmap-matrix/index.js +100 -0
- package/dist/heatmap-matrix/shared.d.ts +2 -0
- package/dist/heatmap-matrix/shared.js +4 -0
- package/dist/icons.d.ts +111 -0
- package/dist/icons.js +111 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/io/export.js +15 -3
- package/dist/io/file-drop.d.ts +7 -0
- package/dist/io/file-drop.js +43 -0
- package/dist/io/index.d.ts +2 -2
- package/dist/io/index.js +2 -112
- package/dist/io/types.d.ts +1 -0
- package/dist/io/url-drop.d.ts +2 -0
- package/dist/io/url-drop.js +118 -0
- package/dist/isosurface/Isosurface.svelte +101 -45
- package/dist/isosurface/IsosurfaceControls.svelte +19 -0
- package/dist/isosurface/parse.js +73 -30
- package/dist/isosurface/slice.d.ts +2 -1
- package/dist/isosurface/slice.js +3 -3
- package/dist/isosurface/types.d.ts +13 -1
- package/dist/isosurface/types.js +98 -0
- package/dist/labels.d.ts +2 -1
- package/dist/labels.js +1 -0
- package/dist/layout/InfoTag.svelte +62 -62
- package/dist/layout/SubpageGrid.svelte +74 -0
- package/dist/layout/SubpageGrid.svelte.d.ts +14 -0
- package/dist/layout/index.d.ts +1 -0
- package/dist/layout/index.js +1 -0
- package/dist/layout/json-tree/JsonNode.svelte +83 -85
- package/dist/layout/json-tree/JsonTree.svelte +20 -19
- package/dist/layout/json-tree/JsonTree.svelte.d.ts +1 -1
- package/dist/layout/json-tree/JsonValue.svelte +196 -116
- package/dist/layout/json-tree/types.d.ts +10 -2
- package/dist/layout/json-tree/utils.d.ts +2 -0
- package/dist/layout/json-tree/utils.js +33 -0
- package/dist/math.d.ts +7 -0
- package/dist/math.js +358 -7
- package/dist/overlays/ContextMenu.svelte +3 -2
- package/dist/overlays/DraggablePane.svelte +163 -58
- package/dist/overlays/DraggablePane.svelte.d.ts +2 -0
- package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +232 -77
- package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +6 -2
- package/dist/phase-diagram/PhaseDiagramControls.svelte +32 -11
- package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +3 -2
- package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +103 -0
- package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +15 -0
- package/dist/phase-diagram/PhaseDiagramExportPane.svelte +102 -95
- package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +7 -0
- package/dist/phase-diagram/PhaseDiagramTooltip.svelte +100 -26
- package/dist/phase-diagram/PhaseDiagramTooltip.svelte.d.ts +6 -3
- package/dist/phase-diagram/index.d.ts +2 -0
- package/dist/phase-diagram/index.js +2 -0
- package/dist/phase-diagram/svg-to-diagram.d.ts +2 -0
- package/dist/phase-diagram/svg-to-diagram.js +865 -0
- package/dist/phase-diagram/types.d.ts +10 -0
- package/dist/phase-diagram/utils.d.ts +7 -4
- package/dist/phase-diagram/utils.js +149 -59
- package/dist/plot/AxisLabel.svelte +26 -0
- package/dist/plot/AxisLabel.svelte.d.ts +16 -0
- package/dist/plot/BarPlot.svelte +473 -228
- package/dist/plot/BarPlot.svelte.d.ts +3 -3
- package/dist/plot/BarPlotControls.svelte +3 -2
- package/dist/plot/BarPlotControls.svelte.d.ts +1 -1
- package/dist/plot/ColorBar.svelte +54 -54
- package/dist/plot/ColorBar.svelte.d.ts +1 -1
- package/dist/plot/ColorScaleSelect.svelte +1 -1
- package/dist/plot/ElementScatter.svelte +3 -2
- package/dist/plot/FillArea.svelte +4 -1
- package/dist/plot/Histogram.svelte +320 -230
- package/dist/plot/Histogram.svelte.d.ts +2 -2
- package/dist/plot/HistogramControls.svelte +29 -10
- package/dist/plot/HistogramControls.svelte.d.ts +6 -2
- package/dist/plot/InteractiveAxisLabel.svelte.d.ts +2 -2
- package/dist/plot/PlotControls.svelte +109 -27
- package/dist/plot/PlotControls.svelte.d.ts +1 -1
- package/dist/plot/PlotLegend.svelte +1 -1
- package/dist/plot/PortalSelect.svelte +2 -1
- package/dist/plot/ReferenceLine.svelte +2 -1
- package/dist/plot/ReferenceLine.svelte.d.ts +1 -0
- package/dist/plot/ReferencePlane.svelte +1 -3
- package/dist/plot/ScatterPlot.svelte +343 -209
- package/dist/plot/ScatterPlot.svelte.d.ts +3 -3
- package/dist/plot/ScatterPlot3D.svelte.d.ts +2 -2
- package/dist/plot/ScatterPlot3DControls.svelte +203 -250
- package/dist/plot/ScatterPlot3DScene.svelte +4 -7
- package/dist/plot/ScatterPlot3DScene.svelte.d.ts +2 -2
- package/dist/plot/ScatterPlotControls.svelte +95 -55
- package/dist/plot/ScatterPlotControls.svelte.d.ts +1 -1
- package/dist/plot/ZeroLines.svelte +44 -0
- package/dist/plot/ZeroLines.svelte.d.ts +32 -0
- package/dist/plot/ZoomRect.svelte +21 -0
- package/dist/plot/ZoomRect.svelte.d.ts +8 -0
- package/dist/plot/axis-utils.d.ts +1 -1
- package/dist/plot/index.d.ts +6 -2
- package/dist/plot/index.js +6 -2
- package/dist/plot/interactions.d.ts +8 -10
- package/dist/plot/interactions.js +2 -3
- package/dist/plot/layout.d.ts +7 -1
- package/dist/plot/layout.js +12 -4
- package/dist/plot/reference-line.d.ts +4 -21
- package/dist/plot/reference-line.js +7 -81
- package/dist/plot/types.d.ts +42 -17
- package/dist/plot/types.js +10 -0
- package/dist/plot/utils/label-placement.js +13 -10
- package/dist/plot/utils.d.ts +1 -0
- package/dist/plot/utils.js +14 -0
- package/dist/rdf/RdfPlot.svelte +55 -66
- package/dist/settings.d.ts +3 -0
- package/dist/settings.js +17 -3
- package/dist/spectral/Bands.svelte +515 -143
- package/dist/spectral/Bands.svelte.d.ts +22 -2
- package/dist/spectral/helpers.d.ts +23 -1
- package/dist/spectral/helpers.js +65 -9
- package/dist/spectral/types.d.ts +2 -0
- package/dist/structure/AtomLegend.svelte +29 -8
- package/dist/structure/AtomLegend.svelte.d.ts +1 -1
- package/dist/structure/CellSelect.svelte +92 -22
- package/dist/structure/Structure.svelte +108 -118
- package/dist/structure/Structure.svelte.d.ts +1 -1
- package/dist/structure/StructureControls.svelte +25 -22
- package/dist/structure/StructureControls.svelte.d.ts +1 -1
- package/dist/structure/StructureInfoPane.svelte +7 -1
- package/dist/structure/StructureScene.svelte +104 -66
- package/dist/structure/StructureScene.svelte.d.ts +2 -1
- package/dist/structure/atom-properties.d.ts +6 -2
- package/dist/structure/atom-properties.js +38 -25
- package/dist/structure/export.js +10 -7
- package/dist/structure/ferrox-wasm-types.d.ts +3 -2
- package/dist/structure/ferrox-wasm-types.js +0 -3
- package/dist/structure/ferrox-wasm.d.ts +3 -2
- package/dist/structure/ferrox-wasm.js +1 -2
- package/dist/structure/index.d.ts +6 -0
- package/dist/structure/index.js +22 -0
- package/dist/structure/parse.js +19 -16
- package/dist/structure/partial-occupancy.d.ts +25 -0
- package/dist/structure/partial-occupancy.js +102 -0
- package/dist/structure/validation.js +6 -3
- package/dist/symmetry/SymmetryStats.svelte +18 -4
- package/dist/symmetry/WyckoffTable.svelte +18 -10
- package/dist/symmetry/index.d.ts +7 -4
- package/dist/symmetry/index.js +83 -18
- package/dist/table/HeatmapTable.svelte +425 -65
- package/dist/table/HeatmapTable.svelte.d.ts +12 -1
- package/dist/table/ToggleMenu.svelte +2 -0
- package/dist/table/index.d.ts +2 -0
- package/dist/trajectory/Trajectory.svelte +147 -145
- package/dist/trajectory/TrajectoryExportPane.svelte +13 -9
- package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +1 -1
- package/dist/trajectory/constants.d.ts +6 -0
- package/dist/trajectory/constants.js +7 -0
- package/dist/trajectory/extract.js +3 -5
- package/dist/trajectory/format-detect.d.ts +9 -0
- package/dist/trajectory/format-detect.js +76 -0
- package/dist/trajectory/frame-reader.d.ts +17 -0
- package/dist/trajectory/frame-reader.js +339 -0
- package/dist/trajectory/helpers.d.ts +15 -0
- package/dist/trajectory/helpers.js +187 -0
- package/dist/trajectory/index.d.ts +1 -0
- package/dist/trajectory/index.js +11 -4
- package/dist/trajectory/parse/ase.d.ts +2 -0
- package/dist/trajectory/parse/ase.js +76 -0
- package/dist/trajectory/parse/hdf5.d.ts +2 -0
- package/dist/trajectory/parse/hdf5.js +121 -0
- package/dist/trajectory/parse/index.d.ts +12 -0
- package/dist/trajectory/parse/index.js +304 -0
- package/dist/trajectory/parse/lammps.d.ts +5 -0
- package/dist/trajectory/parse/lammps.js +169 -0
- package/dist/trajectory/parse/vasp.d.ts +2 -0
- package/dist/trajectory/parse/vasp.js +65 -0
- package/dist/trajectory/parse/xyz.d.ts +2 -0
- package/dist/trajectory/parse/xyz.js +109 -0
- package/dist/trajectory/types.d.ts +11 -0
- package/dist/trajectory/types.js +1 -0
- package/dist/utils.d.ts +2 -0
- package/dist/utils.js +4 -0
- package/dist/xrd/XrdPlot.svelte +6 -4
- package/dist/xrd/calc-xrd.js +0 -1
- package/package.json +30 -24
- package/readme.md +4 -4
- package/dist/trajectory/parse.d.ts +0 -42
- package/dist/trajectory/parse.js +0 -1267
- /package/dist/element/{data.json.d.ts → data.json.gz.d.ts} +0 -0
|
@@ -6,9 +6,10 @@ import { format_num } from '../labels';
|
|
|
6
6
|
import * as math from '../math';
|
|
7
7
|
import { DEFAULTS } from '../settings';
|
|
8
8
|
import { colors } from '../state.svelte';
|
|
9
|
-
import { Arrow, atomic_radii, Cylinder, get_center_of_mass, Lattice, } from './';
|
|
9
|
+
import { Arrow, atomic_radii, Cylinder, get_center_of_mass, get_site_vector_info, Lattice, } from './';
|
|
10
10
|
import { get_orig_site_idx, get_property_colors, } from './atom-properties';
|
|
11
11
|
import * as measure from './measure';
|
|
12
|
+
import { compute_slice_geometry, merge_split_partial_sites, PARTIAL_OCCUPANCY_CAP_ARC, } from './partial-occupancy';
|
|
12
13
|
import { T, useThrelte } from '@threlte/core';
|
|
13
14
|
import * as extras from '@threlte/extras';
|
|
14
15
|
import { untrack } from 'svelte';
|
|
@@ -35,7 +36,7 @@ $effect(() => {
|
|
|
35
36
|
frame_id = requestAnimationFrame(animate);
|
|
36
37
|
return () => cancelAnimationFrame(frame_id);
|
|
37
38
|
});
|
|
38
|
-
let { structure = undefined, base_structure = undefined, atom_radius = DEFAULTS.structure.atom_radius, same_size_atoms = false, camera_position = DEFAULTS.structure.camera_position, camera_projection = DEFAULTS.structure.camera_projection, rotation_damping = DEFAULTS.structure.rotation_damping, max_zoom = DEFAULTS.structure.max_zoom, min_zoom = DEFAULTS.structure.min_zoom, rotate_speed = DEFAULTS.structure.rotate_speed, zoom_speed = DEFAULTS.structure.zoom_speed, pan_speed = DEFAULTS.structure.pan_speed, zoom_to_cursor = DEFAULTS.structure.zoom_to_cursor, show_atoms = DEFAULTS.structure.show_atoms, show_bonds = DEFAULTS.structure.show_bonds, show_site_labels = DEFAULTS.structure.show_site_labels, show_site_indices = DEFAULTS.structure.show_site_indices, site_label_size = DEFAULTS.structure.site_label_size, site_label_offset = $bindable(DEFAULTS.structure.site_label_offset), site_label_bg_color = `color-mix(in srgb, #000000 0%, transparent)`, site_label_color = `#ffffff`, site_label_padding = 3, show_force_vectors = DEFAULTS.structure.show_force_vectors, force_scale = DEFAULTS.structure.force_scale, force_color = DEFAULTS.structure.force_color, gizmo = DEFAULTS.structure.show_gizmo, hovered_idx = $bindable(null), hovered_site = $bindable(null), float_fmt = `.3~f`, auto_rotate = DEFAULTS.structure.auto_rotate, bond_thickness = DEFAULTS.structure.bond_thickness, bond_color = DEFAULTS.structure.bond_color, bonding_strategy = DEFAULTS.structure.bonding_strategy, bonding_options = {}, fov = DEFAULTS.structure.fov, initial_zoom = DEFAULTS.structure.initial_zoom, ambient_light = DEFAULTS.structure.ambient_light, directional_light = DEFAULTS.structure.directional_light, sphere_segments = DEFAULTS.structure.sphere_segments, lattice_props = {}, atom_label, camera_is_moving = $bindable(false), width = 0, height = 0, measure_mode = `distance`, selected_sites = $bindable([]), measured_sites = $bindable([]), added_bonds = $bindable([]), removed_bonds = $bindable([]), selection_highlight_color = `#6cf0ff`,
|
|
39
|
+
let { structure = undefined, base_structure = undefined, atom_radius = DEFAULTS.structure.atom_radius, same_size_atoms = false, camera_position = DEFAULTS.structure.camera_position, camera_target = undefined, camera_projection = DEFAULTS.structure.camera_projection, rotation_damping = DEFAULTS.structure.rotation_damping, max_zoom = DEFAULTS.structure.max_zoom, min_zoom = DEFAULTS.structure.min_zoom, rotate_speed = DEFAULTS.structure.rotate_speed, zoom_speed = DEFAULTS.structure.zoom_speed, pan_speed = DEFAULTS.structure.pan_speed, zoom_to_cursor = DEFAULTS.structure.zoom_to_cursor, show_atoms = DEFAULTS.structure.show_atoms, show_bonds = DEFAULTS.structure.show_bonds, show_site_labels = DEFAULTS.structure.show_site_labels, show_site_indices = DEFAULTS.structure.show_site_indices, site_label_size = DEFAULTS.structure.site_label_size, site_label_offset = $bindable(DEFAULTS.structure.site_label_offset), site_label_bg_color = `color-mix(in srgb, #000000 0%, transparent)`, site_label_color = `#ffffff`, site_label_padding = 3, show_force_vectors = DEFAULTS.structure.show_force_vectors, force_scale = DEFAULTS.structure.force_scale, force_color = DEFAULTS.structure.force_color, gizmo = DEFAULTS.structure.show_gizmo, hovered_idx = $bindable(null), hovered_site = $bindable(null), float_fmt = `.3~f`, auto_rotate = DEFAULTS.structure.auto_rotate, bond_thickness = DEFAULTS.structure.bond_thickness, bond_color = DEFAULTS.structure.bond_color, bonding_strategy = DEFAULTS.structure.bonding_strategy, bonding_options = {}, fov = DEFAULTS.structure.fov, initial_zoom = DEFAULTS.structure.initial_zoom, ambient_light = DEFAULTS.structure.ambient_light, directional_light = DEFAULTS.structure.directional_light, sphere_segments = DEFAULTS.structure.sphere_segments, lattice_props = {}, atom_label, camera_is_moving = $bindable(false), width = 0, height = 0, measure_mode = `distance`, selected_sites = $bindable([]), measured_sites = $bindable([]), added_bonds = $bindable([]), removed_bonds = $bindable([]), selection_highlight_color = `#6cf0ff`,
|
|
39
40
|
// Active highlight group with different color
|
|
40
41
|
active_sites = $bindable([]), active_highlight_color = `var(--struct-active-highlight-color, #2563eb)`, rotation = DEFAULTS.structure.rotation, scene = $bindable(), camera = $bindable(), orbit_controls = $bindable(), rotation_target_ref = $bindable(), initial_computed_zoom = $bindable(), hidden_elements = $bindable(new SvelteSet()), hidden_prop_vals = $bindable(new SvelteSet()), element_radius_overrides = $bindable({}), site_radius_overrides = $bindable(new SvelteMap()), atom_color_config = {
|
|
41
42
|
mode: DEFAULTS.structure.atom_color_mode,
|
|
@@ -49,9 +50,7 @@ $effect(() => {
|
|
|
49
50
|
scene = threlte.scene;
|
|
50
51
|
camera = threlte.camera.current;
|
|
51
52
|
if (threlte.renderer) {
|
|
52
|
-
Object.assign(threlte.renderer.domElement, {
|
|
53
|
-
__renderer: threlte.renderer,
|
|
54
|
-
});
|
|
53
|
+
Object.assign(threlte.renderer.domElement, { __renderer: threlte.renderer });
|
|
55
54
|
}
|
|
56
55
|
});
|
|
57
56
|
// Expose rotation target for external reset
|
|
@@ -119,12 +118,10 @@ function toggle_bond(site_1, site_2) {
|
|
|
119
118
|
}
|
|
120
119
|
// bond_pairs may not be sorted, so use get_bond_key for comparison
|
|
121
120
|
const key = `${idx_i}-${idx_j}`;
|
|
122
|
-
if (bond_pairs.some((bond) => get_bond_key(bond.site_idx_1, bond.site_idx_2) === key))
|
|
121
|
+
if (bond_pairs.some((bond) => get_bond_key(bond.site_idx_1, bond.site_idx_2) === key))
|
|
123
122
|
removed_bonds = [...removed_bonds, [idx_i, idx_j]];
|
|
124
|
-
|
|
125
|
-
else {
|
|
123
|
+
else
|
|
126
124
|
added_bonds = [...added_bonds, [idx_i, idx_j]];
|
|
127
|
-
}
|
|
128
125
|
}
|
|
129
126
|
// Deduplicate clicks: when a highlight sphere and the underlying atom both
|
|
130
127
|
// intercept the same native click, only the first intersection should fire.
|
|
@@ -132,11 +129,13 @@ function toggle_bond(site_1, site_2) {
|
|
|
132
129
|
let last_native_event = null;
|
|
133
130
|
function toggle_selection(site_index, evt) {
|
|
134
131
|
evt?.stopPropagation?.();
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
132
|
+
const native_event = evt
|
|
133
|
+
?.nativeEvent;
|
|
134
|
+
if (native_event instanceof Event) {
|
|
135
|
+
if (native_event === last_native_event)
|
|
136
|
+
return;
|
|
137
|
+
last_native_event = native_event;
|
|
138
|
+
}
|
|
140
139
|
if (measure_mode === `edit-bonds`) {
|
|
141
140
|
// In edit-bonds mode, select atoms to add/remove bonds between them
|
|
142
141
|
const new_sites = measured_sites.includes(site_index)
|
|
@@ -232,7 +231,7 @@ $effect(() => {
|
|
|
232
231
|
computed_zoom = new_zoom;
|
|
233
232
|
});
|
|
234
233
|
$effect.pre(() => {
|
|
235
|
-
if (camera_position.every((
|
|
234
|
+
if (camera_position.every((val) => val === 0) && structure) {
|
|
236
235
|
const distance = Math.max(1, structure_size) * (60 / fov);
|
|
237
236
|
camera_position = [distance, distance * 0.3, distance * 0.8];
|
|
238
237
|
}
|
|
@@ -268,7 +267,8 @@ const calc_weighted_radius = (site) => {
|
|
|
268
267
|
let atom_data = $derived.by(() => {
|
|
269
268
|
if (!show_atoms || !structure?.sites)
|
|
270
269
|
return [];
|
|
271
|
-
|
|
270
|
+
const render_sites = merge_split_partial_sites(structure.sites, hidden_elements);
|
|
271
|
+
return render_sites.flatMap(({ site_idx, site, is_image_atom }) => {
|
|
272
272
|
const orig_idx = get_orig_site_idx(site, site_idx);
|
|
273
273
|
// Skip sites with hidden property values
|
|
274
274
|
const prop_val = property_colors?.values[orig_idx];
|
|
@@ -283,23 +283,25 @@ let atom_data = $derived.by(() => {
|
|
|
283
283
|
// Use property color if available (e.g. coordination number, Wyckoff position)
|
|
284
284
|
// Otherwise, each species gets its own element color (important for disordered sites)
|
|
285
285
|
const site_property_color = property_colors?.colors[orig_idx];
|
|
286
|
-
|
|
287
|
-
const
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
286
|
+
const visible_species = site.species.filter(({ element }) => !hidden_elements.has(element));
|
|
287
|
+
const slice_geometry = compute_slice_geometry(visible_species);
|
|
288
|
+
return slice_geometry.map((slice_data) => {
|
|
289
|
+
return {
|
|
290
|
+
site_idx,
|
|
291
|
+
element: slice_data.element,
|
|
292
|
+
occupancy: slice_data.occupancy,
|
|
293
|
+
position: site.xyz,
|
|
294
|
+
radius,
|
|
295
|
+
color: site_property_color ?? colors.element?.[slice_data.element],
|
|
296
|
+
has_partial_occupancy: slice_data.occupancy < 1,
|
|
297
|
+
start_phi: slice_data.start_phi,
|
|
298
|
+
end_phi: slice_data.end_phi,
|
|
299
|
+
phi_length: slice_data.phi_length,
|
|
300
|
+
render_start_cap: slice_data.render_start_cap,
|
|
301
|
+
render_end_cap: slice_data.render_end_cap,
|
|
302
|
+
is_image_atom,
|
|
303
|
+
};
|
|
304
|
+
});
|
|
303
305
|
});
|
|
304
306
|
});
|
|
305
307
|
let filtered_bond_pairs = $derived.by(() => {
|
|
@@ -389,21 +391,47 @@ const get_site_radius = (site, site_idx) => {
|
|
|
389
391
|
const base_radius = same_size_atoms ? 1 : override ?? calc_weighted_radius(site);
|
|
390
392
|
return base_radius * atom_radius;
|
|
391
393
|
};
|
|
392
|
-
|
|
393
|
-
|
|
394
|
+
// Interpolate between spin-down (#3498db blue) and spin-up (#e74c3c red)
|
|
395
|
+
// based on the z-component direction of a magnetic vector
|
|
396
|
+
function spin_direction_color(vec) {
|
|
397
|
+
const mag = Math.hypot(...vec);
|
|
398
|
+
const z_frac = mag > 1e-10 ? (vec[2] / mag + 1) / 2 : 0.5; // 0=down, 1=up
|
|
399
|
+
const red = Math.round(52 + (231 - 52) * z_frac);
|
|
400
|
+
const grn = Math.round(152 + (76 - 152) * z_frac);
|
|
401
|
+
const blu = Math.round(219 + (60 - 219) * z_frac);
|
|
402
|
+
return `#${red.toString(16).padStart(2, `0`)}${grn.toString(16).padStart(2, `0`)}${blu.toString(16).padStart(2, `0`)}`;
|
|
403
|
+
}
|
|
404
|
+
// Extract per-site vectors from force, magmom, or spin properties.
|
|
405
|
+
// For magmom/spin, color interpolates between spin-up (red) and spin-down (blue).
|
|
406
|
+
let force_data = $derived.by(() => {
|
|
407
|
+
if (!show_force_vectors || !structure?.sites)
|
|
408
|
+
return [];
|
|
409
|
+
return structure.sites
|
|
394
410
|
.map((site) => {
|
|
395
|
-
|
|
411
|
+
const info = get_site_vector_info(site);
|
|
412
|
+
if (!info)
|
|
396
413
|
return null;
|
|
397
|
-
|
|
414
|
+
let arrow_color;
|
|
415
|
+
if (info.key !== `force`) {
|
|
416
|
+
arrow_color = spin_direction_color(info.vec);
|
|
417
|
+
}
|
|
418
|
+
else {
|
|
419
|
+
const majority_element = site.species.length > 0
|
|
420
|
+
? site.species.reduce((max, spec) => spec.occu > max.occu ? spec : max)
|
|
421
|
+
.element
|
|
422
|
+
: undefined;
|
|
423
|
+
arrow_color = (majority_element && colors.element?.[majority_element]) ||
|
|
424
|
+
force_color;
|
|
425
|
+
}
|
|
398
426
|
return {
|
|
399
427
|
position: site.xyz,
|
|
400
|
-
vector:
|
|
428
|
+
vector: info.vec,
|
|
401
429
|
scale: force_scale,
|
|
402
|
-
color:
|
|
430
|
+
color: arrow_color,
|
|
403
431
|
};
|
|
404
432
|
})
|
|
405
|
-
.filter((item) => item !== null)
|
|
406
|
-
|
|
433
|
+
.filter((item) => item !== null);
|
|
434
|
+
});
|
|
407
435
|
let instanced_atom_groups = $derived(Object.values(atom_data
|
|
408
436
|
.filter((atom) => !atom.has_partial_occupancy)
|
|
409
437
|
.reduce((groups, atom) => {
|
|
@@ -452,7 +480,7 @@ let orbit_controls_props = $derived({
|
|
|
452
480
|
zoomToCursor: zoom_to_cursor,
|
|
453
481
|
enablePan: pan_speed > 0,
|
|
454
482
|
panSpeed: pan_speed,
|
|
455
|
-
target: rotation_target,
|
|
483
|
+
target: camera_target ?? rotation_target,
|
|
456
484
|
maxZoom: max_zoom,
|
|
457
485
|
minZoom: min_zoom,
|
|
458
486
|
autoRotate: Boolean(auto_rotate),
|
|
@@ -498,27 +526,17 @@ let measure_line_color = $derived.by(() => {
|
|
|
498
526
|
style:padding="{site_label_padding}px"
|
|
499
527
|
style:color={site_label_color}
|
|
500
528
|
>
|
|
501
|
-
{#if show_site_labels
|
|
529
|
+
{#if show_site_labels}
|
|
502
530
|
{#if site.species.length === 1}
|
|
503
|
-
{site.species[0].element}-{site_idx + 1}
|
|
531
|
+
{site.species[0].element}{#if show_site_indices}-{site_idx + 1}{/if}
|
|
504
532
|
{:else}
|
|
505
533
|
{@html site.species.map((spec) =>
|
|
506
534
|
`${spec.element}<sub>${
|
|
507
535
|
format_num(spec.occu, `.3~`).replace(`0.`, `.`)
|
|
508
536
|
}</sub>`
|
|
509
|
-
).join(``)}-{
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
{/if}
|
|
513
|
-
{:else if show_site_labels}
|
|
514
|
-
{#if site.species.length === 1}
|
|
515
|
-
{site.species[0].element}
|
|
516
|
-
{:else}
|
|
517
|
-
{@html site.species.map((spec) =>
|
|
518
|
-
`${spec.element}<sub>${
|
|
519
|
-
format_num(spec.occu, `.3~`).replace(`0.`, `.`)
|
|
520
|
-
}</sub>`
|
|
521
|
-
).join(``)}
|
|
537
|
+
).join(``)}{#if show_site_indices}-{
|
|
538
|
+
site_idx + 1
|
|
539
|
+
}{/if}
|
|
522
540
|
{/if}
|
|
523
541
|
{:else if show_site_indices}
|
|
524
542
|
{site_idx + 1}
|
|
@@ -637,7 +655,7 @@ let measure_line_color = $derived.by(() => {
|
|
|
637
655
|
sphere_segments,
|
|
638
656
|
sphere_segments,
|
|
639
657
|
atom.start_phi,
|
|
640
|
-
|
|
658
|
+
atom.phi_length,
|
|
641
659
|
]}
|
|
642
660
|
/>
|
|
643
661
|
<T.MeshStandardMaterial
|
|
@@ -647,9 +665,16 @@ let measure_line_color = $derived.by(() => {
|
|
|
647
665
|
/>
|
|
648
666
|
</T.Mesh>
|
|
649
667
|
|
|
650
|
-
{#if atom.has_partial_occupancy}
|
|
668
|
+
{#if atom.has_partial_occupancy && atom.render_start_cap}
|
|
651
669
|
<T.Mesh rotation={[0, atom.start_phi, 0]}>
|
|
652
|
-
<T.CircleGeometry
|
|
670
|
+
<T.CircleGeometry
|
|
671
|
+
args={[
|
|
672
|
+
0.5,
|
|
673
|
+
sphere_segments,
|
|
674
|
+
PARTIAL_OCCUPANCY_CAP_ARC.start_cap_arc_start,
|
|
675
|
+
PARTIAL_OCCUPANCY_CAP_ARC.arc_length,
|
|
676
|
+
]}
|
|
677
|
+
/>
|
|
653
678
|
<T.MeshStandardMaterial
|
|
654
679
|
color={partial_color}
|
|
655
680
|
side={2}
|
|
@@ -657,8 +682,17 @@ let measure_line_color = $derived.by(() => {
|
|
|
657
682
|
transparent={partial_edit_image}
|
|
658
683
|
/>
|
|
659
684
|
</T.Mesh>
|
|
685
|
+
{/if}
|
|
686
|
+
{#if atom.has_partial_occupancy && atom.render_end_cap}
|
|
660
687
|
<T.Mesh rotation={[0, atom.end_phi, 0]}>
|
|
661
|
-
<T.CircleGeometry
|
|
688
|
+
<T.CircleGeometry
|
|
689
|
+
args={[
|
|
690
|
+
0.5,
|
|
691
|
+
sphere_segments,
|
|
692
|
+
PARTIAL_OCCUPANCY_CAP_ARC.end_cap_arc_start,
|
|
693
|
+
PARTIAL_OCCUPANCY_CAP_ARC.arc_length,
|
|
694
|
+
]}
|
|
695
|
+
/>
|
|
662
696
|
<T.MeshStandardMaterial
|
|
663
697
|
color={partial_color}
|
|
664
698
|
side={2}
|
|
@@ -806,8 +840,12 @@ let measure_line_color = $derived.by(() => {
|
|
|
806
840
|
|
|
807
841
|
<!-- hovered site tooltip -->
|
|
808
842
|
{#if hovered_site && !camera_is_moving && active_tooltip === `atom`}
|
|
809
|
-
{@const abc = hovered_site.abc.map((
|
|
810
|
-
|
|
843
|
+
{@const abc = hovered_site.abc.map((val) => format_num(val, float_fmt)).join(
|
|
844
|
+
`, `,
|
|
845
|
+
)}
|
|
846
|
+
{@const xyz = hovered_site.xyz.map((val) => format_num(val, float_fmt)).join(
|
|
847
|
+
`, `,
|
|
848
|
+
)}
|
|
811
849
|
{@const bond_neighbors = (() => {
|
|
812
850
|
if (hovered_idx == null || !structure?.sites) return []
|
|
813
851
|
return filtered_bond_pairs
|
|
@@ -874,7 +912,7 @@ let measure_line_color = $derived.by(() => {
|
|
|
874
912
|
structure?.sites}
|
|
875
913
|
{@const selected_atoms = selected_sites
|
|
876
914
|
.map((idx) => structure?.sites?.[idx])
|
|
877
|
-
.filter(
|
|
915
|
+
.filter((site): site is Site => site != null)}
|
|
878
916
|
{#if selected_atoms.length > 0}
|
|
879
917
|
{@const avg = (dim: number) =>
|
|
880
918
|
selected_atoms.reduce((sum, atom) => sum + atom.xyz[dim], 0) /
|
|
@@ -994,12 +1032,12 @@ let measure_line_color = $derived.by(() => {
|
|
|
994
1032
|
{:else if measure_mode === `angle` && measured_sites.length >= 3}
|
|
995
1033
|
{#each measured_sites as idx_center (idx_center)}
|
|
996
1034
|
{@const center = structure.sites[idx_center]}
|
|
997
|
-
{#each measured_sites.filter((
|
|
1035
|
+
{#each measured_sites.filter((idx) => idx !== idx_center) as
|
|
998
1036
|
idx_a,
|
|
999
1037
|
loop_idx
|
|
1000
1038
|
(idx_center + `-` + idx_a)
|
|
1001
1039
|
}
|
|
1002
|
-
{#each measured_sites.filter((
|
|
1040
|
+
{#each measured_sites.filter((idx) => idx !== idx_center).slice(loop_idx + 1) as
|
|
1003
1041
|
idx_b
|
|
1004
1042
|
(idx_center + `-` + idx_a + `-` + idx_b)
|
|
1005
1043
|
}
|
|
@@ -18,6 +18,7 @@ type $$ComponentProps = {
|
|
|
18
18
|
atom_radius?: number;
|
|
19
19
|
same_size_atoms?: boolean;
|
|
20
20
|
camera_position?: [x: number, y: number, z: number];
|
|
21
|
+
camera_target?: Vec3;
|
|
21
22
|
camera_projection?: CameraProjection;
|
|
22
23
|
rotation_damping?: number;
|
|
23
24
|
max_zoom?: number;
|
|
@@ -90,6 +91,6 @@ type $$ComponentProps = {
|
|
|
90
91
|
volumetric_data?: VolumetricData;
|
|
91
92
|
isosurface_settings?: IsosurfaceSettings;
|
|
92
93
|
};
|
|
93
|
-
declare const StructureScene: import("svelte").Component<$$ComponentProps, {}, "cursor" | "site_label_offset" | "
|
|
94
|
+
declare const StructureScene: import("svelte").Component<$$ComponentProps, {}, "cursor" | "site_label_offset" | "scene" | "camera" | "orbit_controls" | "hidden_elements" | "hidden_prop_vals" | "element_radius_overrides" | "site_radius_overrides" | "selected_sites" | "hovered_idx" | "hovered_site" | "camera_is_moving" | "measured_sites" | "added_bonds" | "removed_bonds" | "active_sites" | "rotation_target_ref" | "initial_computed_zoom" | "add_atom_mode" | "add_element" | "dragging_atoms">;
|
|
94
95
|
type StructureScene = ReturnType<typeof StructureScene>;
|
|
95
96
|
export default StructureScene;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { AnyStructure, Site } from './';
|
|
2
1
|
import type { ColorScaleType, D3InterpolateName } from '../colors';
|
|
3
2
|
import type { AtomColorMode } from '../settings';
|
|
3
|
+
import type { AnyStructure, Site } from './';
|
|
4
4
|
import type { BondingStrategy } from './bonding';
|
|
5
5
|
import type { MoyoDataset } from '@spglib/moyo-wasm';
|
|
6
6
|
export interface AtomColorConfig {
|
|
@@ -16,6 +16,9 @@ export interface AtomPropertyColors {
|
|
|
16
16
|
max_value?: number;
|
|
17
17
|
unique_values?: (number | string)[];
|
|
18
18
|
}
|
|
19
|
+
type SymmetryDataWithOrigMap = MoyoDataset & {
|
|
20
|
+
orig_site_indices_by_std_idx?: number[][];
|
|
21
|
+
};
|
|
19
22
|
export declare const get_d3_color_scales: () => string[];
|
|
20
23
|
export declare function apply_color_scale(vals: number[], scale?: string, type?: ColorScaleType): {
|
|
21
24
|
colors: string[];
|
|
@@ -27,7 +30,8 @@ export declare const apply_categorical_color_scale: (vals: string[], scale?: str
|
|
|
27
30
|
};
|
|
28
31
|
export declare const get_orig_site_idx: (site: Site | undefined, site_idx: number) => number;
|
|
29
32
|
export declare function get_coordination_colors(structure: AnyStructure, strategy?: BondingStrategy, scale?: string, type?: ColorScaleType): AtomPropertyColors;
|
|
30
|
-
export declare function get_wyckoff_colors(structure: AnyStructure, sym_data:
|
|
33
|
+
export declare function get_wyckoff_colors(structure: AnyStructure, sym_data: SymmetryDataWithOrigMap | null, scale?: string): AtomPropertyColors;
|
|
31
34
|
export declare function get_custom_colors(structure: AnyStructure, fn: (site: Site, idx: number) => number | string, scale?: string, type?: ColorScaleType): AtomPropertyColors;
|
|
32
35
|
export declare function get_atom_colors(structure: AnyStructure, config: Partial<AtomColorConfig>, bonding_strategy?: BondingStrategy, sym_data?: MoyoDataset | null): AtomPropertyColors;
|
|
33
36
|
export declare function get_property_colors(structure: AnyStructure | undefined, config: Partial<AtomColorConfig>, bonding_strategy: BondingStrategy, sym_data: MoyoDataset | null): AtomPropertyColors | null;
|
|
37
|
+
export {};
|
|
@@ -15,6 +15,25 @@ const get_interpolator = (scale) => {
|
|
|
15
15
|
return interp_fn;
|
|
16
16
|
};
|
|
17
17
|
const to_hex = (interp_fn, t) => rgb(interp_fn(t)).formatHex();
|
|
18
|
+
const build_image_site = (site, lattice_T, offset, orig_idx) => {
|
|
19
|
+
const img_abc = [
|
|
20
|
+
site.abc[0] + offset[0],
|
|
21
|
+
site.abc[1] + offset[1],
|
|
22
|
+
site.abc[2] + offset[2],
|
|
23
|
+
];
|
|
24
|
+
return {
|
|
25
|
+
...site,
|
|
26
|
+
abc: img_abc,
|
|
27
|
+
xyz: math.mat3x3_vec3_multiply(lattice_T, img_abc),
|
|
28
|
+
properties: { ...site.properties, orig_site_idx: orig_idx },
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
const get_all_offsets = (pbc) => [-1, 0, 1]
|
|
32
|
+
.flatMap((dx) => [-1, 0, 1].flatMap((dy) => [-1, 0, 1].map((dz) => [dx, dy, dz])))
|
|
33
|
+
.filter(([dx, dy, dz]) => !(dx === 0 && dy === 0 && dz === 0) &&
|
|
34
|
+
(pbc[0] || dx === 0) &&
|
|
35
|
+
(pbc[1] || dy === 0) &&
|
|
36
|
+
(pbc[2] || dz === 0));
|
|
18
37
|
const make_categorical = (vals, scale, sort_fn) => {
|
|
19
38
|
const interp_fn = get_interpolator(scale);
|
|
20
39
|
const uniq = sort_fn ? [...new Set(vals)].sort(sort_fn) : [...new Set(vals)].sort();
|
|
@@ -68,24 +87,10 @@ function expand_structure_for_pbc(structure) {
|
|
|
68
87
|
const { sites, lattice } = structure;
|
|
69
88
|
const lattice_T = math.transpose_3x3_matrix(lattice.matrix);
|
|
70
89
|
const pbc = lattice.pbc ?? [true, true, true];
|
|
71
|
-
|
|
72
|
-
const all_offsets = [-1, 0, 1]
|
|
73
|
-
.flatMap((dx) => [-1, 0, 1].flatMap((dy) => [-1, 0, 1].map((dz) => [dx, dy, dz])))
|
|
74
|
-
.filter(([dx, dy, dz]) => !(dx === 0 && dy === 0 && dz === 0) &&
|
|
75
|
-
(pbc[0] || dx === 0) &&
|
|
76
|
-
(pbc[1] || dy === 0) &&
|
|
77
|
-
(pbc[2] || dz === 0));
|
|
90
|
+
const all_offsets = get_all_offsets(pbc);
|
|
78
91
|
// Small structures: expand all atoms
|
|
79
92
|
if (sites.length < 20 || !pbc.some((periodic) => periodic)) {
|
|
80
|
-
const image_sites = sites.flatMap((site, orig_idx) => all_offsets.map((
|
|
81
|
-
const img_abc = [site.abc[0] + dx, site.abc[1] + dy, site.abc[2] + dz];
|
|
82
|
-
return {
|
|
83
|
-
...site,
|
|
84
|
-
abc: img_abc,
|
|
85
|
-
xyz: math.mat3x3_vec3_multiply(lattice_T, img_abc),
|
|
86
|
-
properties: { ...site.properties, orig_site_idx: orig_idx },
|
|
87
|
-
};
|
|
88
|
-
}));
|
|
93
|
+
const image_sites = sites.flatMap((site, orig_idx) => all_offsets.map((offset) => build_image_site(site, lattice_T, offset, orig_idx)));
|
|
89
94
|
return { ...structure, sites: [...sites, ...image_sites] };
|
|
90
95
|
}
|
|
91
96
|
// Large structures: only expand atoms near boundaries (within 5Å bond distance)
|
|
@@ -96,15 +101,7 @@ function expand_structure_for_pbc(structure) {
|
|
|
96
101
|
.filter(([dx, dy, dz]) => (dx === 0 || (dx === -1 ? norm[0] <= cutoff[0] : norm[0] >= 1 - cutoff[0])) &&
|
|
97
102
|
(dy === 0 || (dy === -1 ? norm[1] <= cutoff[1] : norm[1] >= 1 - cutoff[1])) &&
|
|
98
103
|
(dz === 0 || (dz === -1 ? norm[2] <= cutoff[2] : norm[2] >= 1 - cutoff[2])))
|
|
99
|
-
.map((
|
|
100
|
-
const img_abc = [site.abc[0] + dx, site.abc[1] + dy, site.abc[2] + dz];
|
|
101
|
-
return {
|
|
102
|
-
...site,
|
|
103
|
-
abc: img_abc,
|
|
104
|
-
xyz: math.mat3x3_vec3_multiply(lattice_T, img_abc),
|
|
105
|
-
properties: { ...site.properties, orig_site_idx: orig_idx },
|
|
106
|
-
};
|
|
107
|
-
});
|
|
104
|
+
.map((offset) => build_image_site(site, lattice_T, offset, orig_idx));
|
|
108
105
|
});
|
|
109
106
|
return { ...structure, sites: [...sites, ...image_sites] };
|
|
110
107
|
}
|
|
@@ -135,9 +132,25 @@ export function get_wyckoff_colors(structure, sym_data, scale = DEFAULT_COLOR_SC
|
|
|
135
132
|
unique_values: [`unknown`],
|
|
136
133
|
};
|
|
137
134
|
}
|
|
135
|
+
const wyckoff_by_orig_idx = new Map();
|
|
136
|
+
const mapping_by_std_idx = sym_data.orig_site_indices_by_std_idx;
|
|
137
|
+
if (mapping_by_std_idx) {
|
|
138
|
+
for (let std_idx = 0; std_idx < sym_data.wyckoffs.length; std_idx += 1) {
|
|
139
|
+
const wyckoff = sym_data.wyckoffs[std_idx];
|
|
140
|
+
for (const orig_idx of mapping_by_std_idx[std_idx] ?? []) {
|
|
141
|
+
if (!wyckoff_by_orig_idx.has(orig_idx))
|
|
142
|
+
wyckoff_by_orig_idx.set(orig_idx, wyckoff);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
138
146
|
// Create unique orbit identifiers: Wyckoff position + element symbol
|
|
139
147
|
const orbit_ids = structure.sites.map((site, idx) => {
|
|
140
148
|
const sym_idx = get_orig_site_idx(site, idx);
|
|
149
|
+
const mapped_wyckoff = wyckoff_by_orig_idx.get(sym_idx);
|
|
150
|
+
if (mapped_wyckoff !== undefined) {
|
|
151
|
+
const element = site.species[0]?.element ?? `?`;
|
|
152
|
+
return mapped_wyckoff ? `${mapped_wyckoff}|${element}` : `unknown`;
|
|
153
|
+
}
|
|
141
154
|
if (sym_idx >= sym_data.wyckoffs.length) {
|
|
142
155
|
console.error(`[get_wyckoff_colors] Site ${idx} (maps to ${sym_idx}) has no Wyckoff data. ` +
|
|
143
156
|
`Structure has ${n} sites but symmetry data only has ${sym_data.wyckoffs.length}.`);
|
package/dist/structure/export.js
CHANGED
|
@@ -10,13 +10,16 @@ export function has_color_property(mat) {
|
|
|
10
10
|
if (!(`color` in mat))
|
|
11
11
|
return false;
|
|
12
12
|
const color = mat.color;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
if (!color || typeof color !== `object`)
|
|
14
|
+
return false;
|
|
15
|
+
// Check for Color-like object with numeric r/g/b channels (duck typing)
|
|
16
|
+
const color_obj = color;
|
|
17
|
+
const red_channel = color_obj.r;
|
|
18
|
+
const green_channel = color_obj.g;
|
|
19
|
+
const blue_channel = color_obj.b;
|
|
20
|
+
return typeof red_channel === `number` &&
|
|
21
|
+
typeof green_channel === `number` &&
|
|
22
|
+
typeof blue_channel === `number`;
|
|
20
23
|
}
|
|
21
24
|
// Extract color from a ShaderMaterial by checking common color uniform patterns
|
|
22
25
|
function extract_shader_color(shader_mat) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Vec3 } from '../math';
|
|
1
2
|
export type WasmResult<T> = {
|
|
2
3
|
ok: T;
|
|
3
4
|
} | {
|
|
@@ -14,7 +15,7 @@ export declare function unwrap_or<T>(result: WasmResult<T>, default_value: T): T
|
|
|
14
15
|
export interface NeighborListResult {
|
|
15
16
|
center_indices: number[];
|
|
16
17
|
neighbor_indices: number[];
|
|
17
|
-
image_offsets: [
|
|
18
|
+
image_offsets: Vec3[];
|
|
18
19
|
distances: number[];
|
|
19
20
|
}
|
|
20
21
|
export interface MatcherOptions {
|
|
@@ -28,7 +29,7 @@ export interface MatcherOptions {
|
|
|
28
29
|
export type StructureFormat = `cif` | `poscar` | `json`;
|
|
29
30
|
export type ReductionAlgorithm = `niggli` | `lll`;
|
|
30
31
|
export interface HklInfo {
|
|
31
|
-
hkl:
|
|
32
|
+
hkl: Vec3;
|
|
32
33
|
multiplicity: number;
|
|
33
34
|
}
|
|
34
35
|
export interface XrdPattern {
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
// Pure type definitions and utility functions for ferrox-wasm results.
|
|
2
|
-
// This module has no WASM side effects, making it safe to import in tests
|
|
3
|
-
// without triggering WASM resolution.
|
|
4
1
|
// Type guard to check if result is successful
|
|
5
2
|
export function is_ok(result) {
|
|
6
3
|
return `ok` in result;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Vec3 } from '../math';
|
|
1
2
|
import type { Crystal } from './';
|
|
2
3
|
import type { MatcherOptions, NeighborListResult, ReductionAlgorithm, StructureFormat, WasmResult, XrdOptions, XrdPattern } from './ferrox-wasm-types';
|
|
3
4
|
export * from './ferrox-wasm-types';
|
|
@@ -81,8 +82,8 @@ export declare function interpolate_structures(start: Crystal, end: Crystal, n_i
|
|
|
81
82
|
}): Promise<WasmResult<Crystal[]>>;
|
|
82
83
|
export declare function copy_structure(structure: Crystal, sanitize?: boolean): Promise<WasmResult<Crystal>>;
|
|
83
84
|
export declare function wrap_to_unit_cell(structure: Crystal): Promise<WasmResult<Crystal>>;
|
|
84
|
-
export declare function create_supercell_matrix(structure: Crystal, matrix: [
|
|
85
|
-
export declare function translate_sites(structure: Crystal, indices: number[], vector:
|
|
85
|
+
export declare function create_supercell_matrix(structure: Crystal, matrix: [Vec3, Vec3, Vec3]): Promise<WasmResult<Crystal>>;
|
|
86
|
+
export declare function translate_sites(structure: Crystal, indices: number[], vector: Vec3, frac_coords?: boolean): Promise<WasmResult<Crystal>>;
|
|
86
87
|
export declare function perturb_structure(structure: Crystal, distance: number, options?: {
|
|
87
88
|
min_distance?: number;
|
|
88
89
|
seed?: number;
|
|
@@ -25,8 +25,7 @@ export function ensure_ferrox_wasm_ready() {
|
|
|
25
25
|
init_promise = (async () => {
|
|
26
26
|
try {
|
|
27
27
|
// Dynamic import to avoid loading WASM until needed
|
|
28
|
-
const { default: init } = (await import(
|
|
29
|
-
/* @vite-ignore */ `matterviz-wasm`));
|
|
28
|
+
const { default: init } = (await import(`matterviz-wasm`));
|
|
30
29
|
// Initialize WASM module (the package handles WASM loading internally)
|
|
31
30
|
wasm_module = await init();
|
|
32
31
|
return wasm_module;
|
|
@@ -67,6 +67,11 @@ export declare function format_formula_by_electronegativity(structure: AnyStruct
|
|
|
67
67
|
export declare const atomic_radii: CompositionType;
|
|
68
68
|
export declare function get_density(structure: Crystal): number;
|
|
69
69
|
export declare function get_center_of_mass(structure: AnyStructure): Vec3;
|
|
70
|
+
export declare function get_site_vector_info(site: Site): {
|
|
71
|
+
vec: Vec3;
|
|
72
|
+
key: string;
|
|
73
|
+
} | null;
|
|
74
|
+
export declare function get_site_vector(site: Site): Vec3 | null;
|
|
70
75
|
export interface StructureHandlerData {
|
|
71
76
|
structure?: AnyStructure;
|
|
72
77
|
filename?: string;
|
|
@@ -75,6 +80,7 @@ export interface StructureHandlerData {
|
|
|
75
80
|
error_msg?: string;
|
|
76
81
|
fullscreen?: boolean;
|
|
77
82
|
camera_position?: Vec3;
|
|
83
|
+
camera_target?: Vec3;
|
|
78
84
|
camera_has_moved?: boolean;
|
|
79
85
|
color_scheme?: string;
|
|
80
86
|
performance_mode?: `quality` | `speed`;
|
package/dist/structure/index.js
CHANGED
|
@@ -84,3 +84,25 @@ export function get_center_of_mass(structure) {
|
|
|
84
84
|
}
|
|
85
85
|
return math.scale(center, 1 / total_weight);
|
|
86
86
|
}
|
|
87
|
+
// Property keys checked for per-site vector data (force, magnetic moment, spin)
|
|
88
|
+
const VECTOR_PROPERTY_KEYS = [`force`, `magmom`, `spin`];
|
|
89
|
+
// Extract a vector and its source key from a site's properties. Checks force, magmom,
|
|
90
|
+
// and spin in priority order. Scalar values are converted to z-directed vectors [0, 0, val].
|
|
91
|
+
export function get_site_vector_info(site) {
|
|
92
|
+
const props = site.properties;
|
|
93
|
+
if (!props)
|
|
94
|
+
return null;
|
|
95
|
+
for (const key of VECTOR_PROPERTY_KEYS) {
|
|
96
|
+
const val = props[key];
|
|
97
|
+
if (Array.isArray(val) && val.length === 3 &&
|
|
98
|
+
val.every((elem) => typeof elem === `number` && isFinite(elem)))
|
|
99
|
+
return { vec: val, key };
|
|
100
|
+
if (typeof val === `number` && isFinite(val))
|
|
101
|
+
return { vec: [0, 0, val], key };
|
|
102
|
+
}
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
// Convenience wrapper returning just the vector (preserves existing API)
|
|
106
|
+
export function get_site_vector(site) {
|
|
107
|
+
return get_site_vector_info(site)?.vec ?? null;
|
|
108
|
+
}
|