Skip to main content

vtk_pure_rs/data/
generic_dataset.rs

1//! Generic dataset enum that wraps any concrete dataset type.
2//!
3//! `AnyDataSet` provides a unified type for working with different dataset
4//! types through the `DataSet` trait interface.
5
6use crate::types::BoundingBox;
7
8use crate::data::{
9    DataSetAttributes, FieldData, ImageData, PolyData, RectilinearGrid, StructuredGrid,
10    UnstructuredGrid,
11};
12use crate::data::traits::{DataObject, DataSet};
13
14/// Enum wrapping all concrete dataset types.
15///
16/// Provides delegated access to `DataSet` trait methods without dynamic dispatch.
17#[derive(Debug, Clone)]
18pub enum AnyDataSet {
19    /// Polygonal mesh.
20    Poly(PolyData),
21    /// Regular image grid.
22    Image(ImageData),
23    /// Unstructured mixed-cell mesh.
24    Unstructured(UnstructuredGrid),
25    /// Axis-aligned grid with non-uniform spacing.
26    Rectilinear(RectilinearGrid),
27    /// Curvilinear structured grid.
28    Structured(StructuredGrid),
29}
30
31impl AnyDataSet {
32    /// Number of points in the dataset.
33    pub fn num_points(&self) -> usize {
34        match self {
35            Self::Poly(d) => d.num_points(),
36            Self::Image(d) => d.num_points(),
37            Self::Unstructured(d) => d.num_points(),
38            Self::Rectilinear(d) => d.num_points(),
39            Self::Structured(d) => d.num_points(),
40        }
41    }
42
43    /// Number of cells in the dataset.
44    pub fn num_cells(&self) -> usize {
45        match self {
46            Self::Poly(d) => d.num_cells(),
47            Self::Image(d) => d.num_cells(),
48            Self::Unstructured(d) => d.num_cells(),
49            Self::Rectilinear(d) => d.num_cells(),
50            Self::Structured(d) => d.num_cells(),
51        }
52    }
53
54    /// Get coordinates of a point by index.
55    pub fn point(&self, idx: usize) -> [f64; 3] {
56        match self {
57            Self::Poly(d) => d.point(idx),
58            Self::Image(d) => d.point(idx),
59            Self::Unstructured(d) => d.point(idx),
60            Self::Rectilinear(d) => d.point(idx),
61            Self::Structured(d) => d.point(idx),
62        }
63    }
64
65    /// Bounding box of the dataset.
66    pub fn bounds(&self) -> BoundingBox {
67        match self {
68            Self::Poly(d) => d.bounds(),
69            Self::Image(d) => d.bounds(),
70            Self::Unstructured(d) => d.bounds(),
71            Self::Rectilinear(d) => d.bounds(),
72            Self::Structured(d) => d.bounds(),
73        }
74    }
75
76    /// Point data attributes.
77    pub fn point_data(&self) -> &DataSetAttributes {
78        match self {
79            Self::Poly(d) => d.point_data(),
80            Self::Image(d) => d.point_data(),
81            Self::Unstructured(d) => d.point_data(),
82            Self::Rectilinear(d) => d.point_data(),
83            Self::Structured(d) => d.point_data(),
84        }
85    }
86
87    /// Cell data attributes.
88    pub fn cell_data(&self) -> &DataSetAttributes {
89        match self {
90            Self::Poly(d) => d.cell_data(),
91            Self::Image(d) => d.cell_data(),
92            Self::Unstructured(d) => d.cell_data(),
93            Self::Rectilinear(d) => d.cell_data(),
94            Self::Structured(d) => d.cell_data(),
95        }
96    }
97}
98
99impl DataObject for AnyDataSet {
100    fn field_data(&self) -> &FieldData {
101        match self {
102            Self::Poly(d) => d.field_data(),
103            Self::Image(d) => d.field_data(),
104            Self::Unstructured(d) => d.field_data(),
105            Self::Rectilinear(d) => d.field_data(),
106            Self::Structured(d) => d.field_data(),
107        }
108    }
109
110    fn field_data_mut(&mut self) -> &mut FieldData {
111        match self {
112            Self::Poly(d) => d.field_data_mut(),
113            Self::Image(d) => d.field_data_mut(),
114            Self::Unstructured(d) => d.field_data_mut(),
115            Self::Rectilinear(d) => d.field_data_mut(),
116            Self::Structured(d) => d.field_data_mut(),
117        }
118    }
119}
120
121impl DataSet for AnyDataSet {
122    fn num_points(&self) -> usize {
123        self.num_points()
124    }
125
126    fn num_cells(&self) -> usize {
127        self.num_cells()
128    }
129
130    fn point(&self, idx: usize) -> [f64; 3] {
131        self.point(idx)
132    }
133
134    fn bounds(&self) -> BoundingBox {
135        self.bounds()
136    }
137
138    fn point_data(&self) -> &DataSetAttributes {
139        self.point_data()
140    }
141
142    fn point_data_mut(&mut self) -> &mut DataSetAttributes {
143        match self {
144            Self::Poly(d) => d.point_data_mut(),
145            Self::Image(d) => d.point_data_mut(),
146            Self::Unstructured(d) => d.point_data_mut(),
147            Self::Rectilinear(d) => d.point_data_mut(),
148            Self::Structured(d) => d.point_data_mut(),
149        }
150    }
151
152    fn cell_data(&self) -> &DataSetAttributes {
153        self.cell_data()
154    }
155
156    fn cell_data_mut(&mut self) -> &mut DataSetAttributes {
157        match self {
158            Self::Poly(d) => d.cell_data_mut(),
159            Self::Image(d) => d.cell_data_mut(),
160            Self::Unstructured(d) => d.cell_data_mut(),
161            Self::Rectilinear(d) => d.cell_data_mut(),
162            Self::Structured(d) => d.cell_data_mut(),
163        }
164    }
165}
166
167impl From<PolyData> for AnyDataSet {
168    fn from(d: PolyData) -> Self {
169        Self::Poly(d)
170    }
171}
172
173impl From<ImageData> for AnyDataSet {
174    fn from(d: ImageData) -> Self {
175        Self::Image(d)
176    }
177}
178
179impl From<UnstructuredGrid> for AnyDataSet {
180    fn from(d: UnstructuredGrid) -> Self {
181        Self::Unstructured(d)
182    }
183}
184
185impl From<RectilinearGrid> for AnyDataSet {
186    fn from(d: RectilinearGrid) -> Self {
187        Self::Rectilinear(d)
188    }
189}
190
191impl From<StructuredGrid> for AnyDataSet {
192    fn from(d: StructuredGrid) -> Self {
193        Self::Structured(d)
194    }
195}
196
197#[cfg(test)]
198mod tests {
199    use super::*;
200
201    #[test]
202    fn any_dataset_from_poly_data() {
203        let pd = PolyData::from_triangles(
204            vec![[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]],
205            vec![[0, 1, 2]],
206        );
207        let any = AnyDataSet::from(pd);
208        assert_eq!(any.num_points(), 3);
209        assert_eq!(any.num_cells(), 1);
210        let p = any.point(1);
211        assert!((p[0] - 1.0).abs() < 1e-10);
212    }
213
214    #[test]
215    fn any_dataset_from_image_data() {
216        let img = ImageData::with_dimensions(3, 3, 3);
217        let any = AnyDataSet::from(img);
218        assert_eq!(any.num_points(), 27);
219        let b = any.bounds();
220        assert!(b.diagonal_length() > 0.0);
221    }
222}