vtk_pure_rs/data/
unstructured_grid.rs1use crate::types::{BoundingBox, CellType};
2
3use crate::data::{CellArray, DataSetAttributes, FieldData, Points};
4use crate::data::traits::{DataObject, DataSet};
5
6#[derive(Debug, Clone, Default)]
12pub struct UnstructuredGrid {
13 pub points: Points<f64>,
14 cells: CellArray,
15 cell_types: Vec<CellType>,
16 point_data: DataSetAttributes,
17 cell_data: DataSetAttributes,
18 field_data: FieldData,
19}
20
21impl UnstructuredGrid {
22 pub fn new() -> Self {
23 Self::default()
24 }
25
26 pub fn push_cell(&mut self, cell_type: CellType, point_ids: &[i64]) {
28 self.cells.push_cell(point_ids);
29 self.cell_types.push(cell_type);
30 }
31
32 pub fn cell_type(&self, idx: usize) -> CellType {
34 self.cell_types[idx]
35 }
36
37 pub fn cell_points(&self, idx: usize) -> &[i64] {
39 self.cells.cell(idx)
40 }
41
42 pub fn cell_types(&self) -> &[CellType] {
44 &self.cell_types
45 }
46
47 pub fn cells(&self) -> &CellArray {
49 &self.cells
50 }
51
52 pub fn point_data(&self) -> &DataSetAttributes {
53 &self.point_data
54 }
55
56 pub fn point_data_mut(&mut self) -> &mut DataSetAttributes {
57 &mut self.point_data
58 }
59
60 pub fn cell_data(&self) -> &DataSetAttributes {
61 &self.cell_data
62 }
63
64 pub fn cell_data_mut(&mut self) -> &mut DataSetAttributes {
65 &mut self.cell_data
66 }
67
68 pub fn from_tetrahedra(points: Vec<[f64; 3]>, tets: Vec<[i64; 4]>) -> Self {
70 let mut ug = Self::new();
71 ug.points = Points::from_vec(points);
72 for tet in &tets {
73 ug.push_cell(CellType::Tetra, tet);
74 }
75 ug
76 }
77
78 pub fn from_hexahedra(points: Vec<[f64; 3]>, hexes: Vec<[i64; 8]>) -> Self {
80 let mut ug = Self::new();
81 ug.points = Points::from_vec(points);
82 for hex in &hexes {
83 ug.push_cell(CellType::Hexahedron, hex);
84 }
85 ug
86 }
87
88 pub fn with_point_array(mut self, array: crate::data::AnyDataArray) -> Self {
90 let name = array.name().to_string();
91 self.point_data.add_array(array);
92 if self.point_data.scalars().is_none() {
93 self.point_data.set_active_scalars(&name);
94 }
95 self
96 }
97
98 pub fn with_cell_array(mut self, array: crate::data::AnyDataArray) -> Self {
100 self.cell_data.add_array(array);
101 self
102 }
103}
104
105impl DataObject for UnstructuredGrid {
106 fn field_data(&self) -> &FieldData {
107 &self.field_data
108 }
109
110 fn field_data_mut(&mut self) -> &mut FieldData {
111 &mut self.field_data
112 }
113}
114
115impl DataSet for UnstructuredGrid {
116 fn num_points(&self) -> usize {
117 self.points.len()
118 }
119
120 fn num_cells(&self) -> usize {
121 self.cells.num_cells()
122 }
123
124 fn point(&self, idx: usize) -> [f64; 3] {
125 self.points.get(idx)
126 }
127
128 fn bounds(&self) -> BoundingBox {
129 self.points.bounds()
130 }
131
132 fn point_data(&self) -> &DataSetAttributes {
133 &self.point_data
134 }
135
136 fn point_data_mut(&mut self) -> &mut DataSetAttributes {
137 &mut self.point_data
138 }
139
140 fn cell_data(&self) -> &DataSetAttributes {
141 &self.cell_data
142 }
143
144 fn cell_data_mut(&mut self) -> &mut DataSetAttributes {
145 &mut self.cell_data
146 }
147}
148
149impl std::fmt::Display for UnstructuredGrid {
150 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
151 write!(f, "UnstructuredGrid: {} points, {} cells, {} point arrays",
152 self.points.len(), self.cells.num_cells(), self.point_data.num_arrays())
153 }
154}
155
156#[cfg(test)]
157mod tests {
158 use super::*;
159
160 #[test]
161 fn single_tetrahedron() {
162 let mut grid = UnstructuredGrid::new();
163 grid.points.push([0.0, 0.0, 0.0]);
164 grid.points.push([1.0, 0.0, 0.0]);
165 grid.points.push([0.5, 1.0, 0.0]);
166 grid.points.push([0.5, 0.5, 1.0]);
167
168 grid.push_cell(CellType::Tetra, &[0, 1, 2, 3]);
169
170 assert_eq!(grid.num_points(), 4);
171 assert_eq!(grid.num_cells(), 1);
172 assert_eq!(grid.cell_type(0), CellType::Tetra);
173 assert_eq!(grid.cell_points(0), &[0, 1, 2, 3]);
174 }
175
176 #[test]
177 fn mixed_cells() {
178 let mut grid = UnstructuredGrid::new();
179 for i in 0..8 {
180 let x = (i % 2) as f64;
181 let y = ((i / 2) % 2) as f64;
182 let z = (i / 4) as f64;
183 grid.points.push([x, y, z]);
184 }
185
186 grid.push_cell(CellType::Hexahedron, &[0, 1, 3, 2, 4, 5, 7, 6]);
188 grid.push_cell(CellType::Triangle, &[4, 5, 7]);
190
191 assert_eq!(grid.num_cells(), 2);
192 assert_eq!(grid.cell_type(0), CellType::Hexahedron);
193 assert_eq!(grid.cell_type(1), CellType::Triangle);
194 }
195}