Skip to main content

vtk_pure_rs/data/
selection.rs

1/// Type of content in a selection node.
2#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3pub enum SelectionContentType {
4    /// Selection by global IDs.
5    GlobalIds,
6    /// Selection by pedigree IDs.
7    PedigreeIds,
8    /// Selection by indices (point or cell indices).
9    Indices,
10    /// Selection by frustum (6 planes).
11    Frustum,
12    /// Selection by value range on a named array.
13    Thresholds,
14    /// Selection by block index (for MultiBlock).
15    Blocks,
16}
17
18/// Whether the selection applies to points or cells.
19#[derive(Debug, Clone, Copy, PartialEq, Eq)]
20pub enum SelectionFieldType {
21    Point,
22    Cell,
23}
24
25/// A single node in a selection, specifying what to select and how.
26#[derive(Debug, Clone)]
27pub struct SelectionNode {
28    pub content_type: SelectionContentType,
29    pub field_type: SelectionFieldType,
30    /// The selection data — interpretation depends on content_type.
31    /// For Indices: list of i64 indices.
32    /// For Thresholds: [min, max] pairs.
33    pub selection_list: Vec<f64>,
34    /// Optional array name for Thresholds content type.
35    pub array_name: Option<String>,
36}
37
38impl SelectionNode {
39    /// Create a selection by point indices.
40    pub fn from_point_indices(indices: Vec<i64>) -> Self {
41        Self {
42            content_type: SelectionContentType::Indices,
43            field_type: SelectionFieldType::Point,
44            selection_list: indices.into_iter().map(|i| i as f64).collect(),
45            array_name: None,
46        }
47    }
48
49    /// Create a selection by cell indices.
50    pub fn from_cell_indices(indices: Vec<i64>) -> Self {
51        Self {
52            content_type: SelectionContentType::Indices,
53            field_type: SelectionFieldType::Cell,
54            selection_list: indices.into_iter().map(|i| i as f64).collect(),
55            array_name: None,
56        }
57    }
58
59    /// Create a threshold selection on a named array.
60    pub fn from_threshold(array_name: &str, min: f64, max: f64, field_type: SelectionFieldType) -> Self {
61        Self {
62            content_type: SelectionContentType::Thresholds,
63            field_type,
64            selection_list: vec![min, max],
65            array_name: Some(array_name.to_string()),
66        }
67    }
68}
69
70/// A selection consisting of one or more selection nodes.
71#[derive(Debug, Clone, Default)]
72pub struct Selection {
73    nodes: Vec<SelectionNode>,
74}
75
76impl Selection {
77    pub fn new() -> Self {
78        Self::default()
79    }
80
81    pub fn add_node(&mut self, node: SelectionNode) {
82        self.nodes.push(node);
83    }
84
85    pub fn num_nodes(&self) -> usize {
86        self.nodes.len()
87    }
88
89    pub fn node(&self, idx: usize) -> Option<&SelectionNode> {
90        self.nodes.get(idx)
91    }
92
93    pub fn nodes(&self) -> &[SelectionNode] {
94        &self.nodes
95    }
96}
97
98#[cfg(test)]
99mod tests {
100    use super::*;
101
102    #[test]
103    fn point_index_selection() {
104        let mut sel = Selection::new();
105        sel.add_node(SelectionNode::from_point_indices(vec![0, 5, 10]));
106        assert_eq!(sel.num_nodes(), 1);
107        let node = sel.node(0).unwrap();
108        assert_eq!(node.content_type, SelectionContentType::Indices);
109        assert_eq!(node.field_type, SelectionFieldType::Point);
110        assert_eq!(node.selection_list.len(), 3);
111    }
112
113    #[test]
114    fn threshold_selection() {
115        let node = SelectionNode::from_threshold("temperature", 100.0, 200.0, SelectionFieldType::Cell);
116        assert_eq!(node.content_type, SelectionContentType::Thresholds);
117        assert_eq!(node.array_name.as_deref(), Some("temperature"));
118        assert_eq!(node.selection_list, vec![100.0, 200.0]);
119    }
120}