Skip to main content

ak_vis/viewer/session/
snapshot.rs

1use super::{ImageSelectionFrames, SelectedImageAtom, SelectionFrames};
2
3#[derive(Clone, Copy, Debug, PartialEq, Eq)]
4pub struct SupercellSettings {
5    pub repeats: [u32; 3],
6    pub ghost_repeated_images: bool,
7}
8
9#[derive(Clone, Debug, PartialEq, Eq)]
10pub struct ViewerSnapshot {
11    pub current_frame: usize,
12    pub selection: SelectionFrames,
13    pub image_selection: ImageSelectionFrames,
14    pub supercell: SupercellSettings,
15}
16
17#[derive(Clone, Debug, PartialEq)]
18pub struct DisplayAtom {
19    pub identity: SelectedImageAtom,
20    pub position: [f64; 3],
21    pub is_main_cell: bool,
22}
23
24#[derive(Debug, Clone, Copy)]
25pub struct ViewerSessionClosed;
26
27impl std::fmt::Display for ViewerSessionClosed {
28    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29        write!(f, "viewer session is no longer available")
30    }
31}
32
33impl std::error::Error for ViewerSessionClosed {}
34
35impl Default for ViewerSnapshot {
36    fn default() -> Self {
37        Self {
38            current_frame: 0,
39            selection: SelectionFrames {
40                frames: Vec::new(),
41                ordered: Vec::new(),
42            },
43            image_selection: ImageSelectionFrames { frames: Vec::new() },
44            supercell: SupercellSettings::default(),
45        }
46    }
47}
48
49impl Default for SupercellSettings {
50    fn default() -> Self {
51        Self {
52            repeats: [0, 0, 0],
53            ghost_repeated_images: true,
54        }
55    }
56}
57
58pub(super) fn clamp_frame(index: usize, len: usize) -> usize {
59    if len == 0 { 0 } else { index.min(len - 1) }
60}
61
62fn axis_offsets(repeat_extent: u32) -> Vec<i32> {
63    let repeat_extent = repeat_extent as i32;
64    (-repeat_extent..=repeat_extent).collect()
65}
66
67pub(super) fn supercell_offsets(repeats: [u32; 3]) -> Vec<[i32; 3]> {
68    let mut offsets = Vec::new();
69    for ia in axis_offsets(repeats[0]) {
70        for ib in axis_offsets(repeats[1]) {
71            for ic in axis_offsets(repeats[2]) {
72                offsets.push([ia, ib, ic]);
73            }
74        }
75    }
76    offsets.sort_by_key(|offset| {
77        (
78            offset.iter().map(|value| value.abs()).sum::<i32>(),
79            offset[0].abs(),
80            offset[1].abs(),
81            offset[2].abs(),
82            offset[0],
83            offset[1],
84            offset[2],
85        )
86    });
87    offsets
88}
89
90pub(super) fn scaled_cell_translation(cell: ak_core::geometry::Cell, offset: [i32; 3]) -> [f64; 3] {
91    let a = cell.a();
92    let b = cell.b();
93    let c = cell.c();
94    let shift = a * offset[0] as f64 + b * offset[1] as f64 + c * offset[2] as f64;
95    [shift[0], shift[1], shift[2]]
96}