conspire/geometry/mesh/tessellation/read/
mod.rs1#[cfg(test)]
2mod test;
3
4use crate::{
5 geometry::{
6 Coordinate, Coordinates,
7 mesh::{
8 Connectivity,
9 tessellation::{D, Tessellation},
10 },
11 },
12 math::TensorVec,
13};
14use std::{
15 cell::OnceCell,
16 collections::HashMap,
17 fs::File,
18 io::{BufReader, Error as ErrorIO, Read},
19 path::Path,
20};
21
22impl TryFrom<&Path> for Tessellation {
23 type Error = ErrorIO;
24 fn try_from(path: &Path) -> Result<Self, Self::Error> {
25 let mut reader = BufReader::new(File::open(path)?);
26 let mut header = [0u8; 80];
27 reader.read_exact(&mut header)?;
28 let mut count_bytes = [0u8; 4];
29 reader.read_exact(&mut count_bytes)?;
30 let triangle_count = u32::from_le_bytes(count_bytes) as usize;
31 let mut connectivity = Vec::with_capacity(triangle_count);
32 let mut normals = Coordinates::with_capacity(triangle_count);
33 let mut vertex_map = HashMap::with_capacity(D * triangle_count);
34 let mut unique_vertices_f32 = Vec::with_capacity(D * triangle_count);
35 (0..triangle_count).try_for_each(|_| {
36 let normal_f32 = read_vec3_f32(&mut reader)?;
37 let v0 = read_vec3_f32(&mut reader)?;
38 let v1 = read_vec3_f32(&mut reader)?;
39 let v2 = read_vec3_f32(&mut reader)?;
40 let mut attr = [0u8; 2];
41 reader.read_exact(&mut attr)?;
42 let _attribute_byte_count = u16::from_le_bytes(attr);
43 let i0 = dedup_vertex(&mut vertex_map, &mut unique_vertices_f32, v0);
44 let i1 = dedup_vertex(&mut vertex_map, &mut unique_vertices_f32, v1);
45 let i2 = dedup_vertex(&mut vertex_map, &mut unique_vertices_f32, v2);
46 connectivity.push([i0, i1, i2]);
47 normals.push(Coordinate::const_from([
48 normal_f32[0] as f64,
49 normal_f32[1] as f64,
50 normal_f32[2] as f64,
51 ]));
52 Ok::<(), ErrorIO>(())
53 })?;
54 let coordinates: Coordinates<D> = unique_vertices_f32
55 .into_iter()
56 .map(|v| Coordinate::const_from([v[0] as f64, v[1] as f64, v[2] as f64]))
57 .collect();
58 let connectivity = vec![Connectivity::Triangular(connectivity.into())];
59 let mesh = (connectivity, coordinates).into();
60 let normals = vec![normals].into();
61 Ok(Tessellation {
62 mesh,
63 normals,
64 bvh: OnceCell::new(),
65 })
66 }
67}
68
69fn read_vec3_f32<R: Read>(reader: &mut R) -> Result<[f32; D], ErrorIO> {
70 Ok([read_f32(reader)?, read_f32(reader)?, read_f32(reader)?])
71}
72
73fn read_f32<R: Read>(reader: &mut R) -> Result<f32, ErrorIO> {
74 let mut bytes = [0u8; 4];
75 reader.read_exact(&mut bytes)?;
76 Ok(f32::from_le_bytes(bytes))
77}
78
79fn dedup_vertex(
80 vertex_map: &mut HashMap<[u32; D], usize>,
81 unique_vertices: &mut Vec<[f32; D]>,
82 vertex: [f32; D],
83) -> usize {
84 let key = [
85 vertex[0].to_bits(),
86 vertex[1].to_bits(),
87 vertex[2].to_bits(),
88 ];
89 if let Some(&index) = vertex_map.get(&key) {
90 index
91 } else {
92 let index = unique_vertices.len();
93 unique_vertices.push(vertex);
94 vertex_map.insert(key, index);
95 index
96 }
97}