1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
use {Vertex, Index, Triangle, Error};
use std::iter::FromIterator;
pub struct Model<V: Vertex, I: Index> {
pub mesh: TriangularMesh<V, I>,
}
pub trait BuildModel {
type Vertex;
fn build_model<V,I>(self) -> Result<Model<V,I>, Error>
where V: Vertex, I: Index, V: From<Self::Vertex>;
}
pub struct TriangularMesh<V: Vertex, I: Index> {
pub vertices: Vec<V>,
pub indices: Vec<I>,
}
pub struct Triangles<'a, V: Vertex+'a, I: Index+'a>
{
mesh: &'a TriangularMesh<V,I>,
indices: ::std::slice::Iter<'a, I>,
}
impl<V: Vertex, I: Index> Model<V,I> {
pub fn empty() -> Self {
Model { mesh: TriangularMesh::empty() }
}
pub fn new<F>(builder: F) -> Result<Self, Error>
where F: BuildModel, V: From<F::Vertex> {
builder.build_model()
}
}
impl<V: Vertex, I: Index> TriangularMesh<V,I> {
pub fn empty() -> Self {
TriangularMesh { vertices: Vec::new(), indices: Vec::new() }
}
pub fn triangles(&self) -> Triangles<V,I> {
Triangles { mesh: self, indices: self.indices.iter() }
}
}
impl<V,I> FromIterator<Triangle<V>> for TriangularMesh<V,I>
where V: Vertex, I: Index
{
fn from_iter<T>(iter: T) -> Self
where T: IntoIterator<Item=Triangle<V>> {
let triangles: Vec<_> = iter.into_iter().collect();
let mut vertices: Vec<_> = triangles.iter().flat_map(|tri| tri.vertices.iter().cloned()).collect();
vertices.sort_by(|a, b| a.partial_cmp(b).unwrap());
vertices.dedup();
let indices = triangles.iter().flat_map(|tri| {
tri.vertices.iter().map(|vert| {
let index: u64 = vertices.binary_search_by(|a| a.partial_cmp(vert).unwrap()).unwrap() as u64;
I::from_u64(index).expect("index type too small for mesh")
})
}).collect();
TriangularMesh { vertices: vertices, indices: indices }
}
}
impl<'a, V: Vertex+'a, I: Index+'a> Iterator for Triangles<'a, V, I> {
type Item = Triangle<V>;
fn next(&mut self) -> Option<Triangle<V>> {
if let Some(i1) = self.indices.next() {
let i2 = self.indices.next().expect("expected at least two more indices");
let i3 = self.indices.next().expect("expected at least one more index");
let vertices: Vec<_> = [i1,i2,i3].into_iter().map(|&&idx| {
let idx: u64 = idx.into();
self.mesh.vertices[idx as usize].clone()
}).collect();
Some(Triangle {
vertices: [vertices[0].clone(), vertices[1].clone(), vertices[2].clone()],
})
} else {
None
}
}
}
#[cfg(test)]
mod test {
use {TriangularMesh, Vector, Triangle};
use build;
#[test]
fn can_enumerate_triangles() {
let cube: TriangularMesh<Vector,u64> = build::unit_cube();
assert_eq!(cube.triangles().count(), 12);
}
#[test]
fn can_build_out_of_triangles() {
let triangles = vec![
Triangle { vertices: [Vector(1.0, 1.0, 1.0), Vector(2.0, 2.0, 2.0), Vector(3.0,3.0,3.0)] },
Triangle { vertices: [Vector(5.0, 5.0, 5.0), Vector(6.0, 6.0, 6.0), Vector(7.0,7.0,7.0)] },
];
let mesh: TriangularMesh<_, u16> = triangles.into_iter().collect();
let processed_triangles: Vec<_> = mesh.triangles().collect();
assert_eq!(processed_triangles, vec![
Triangle { vertices: [Vector(1.0, 1.0, 1.0), Vector(2.0, 2.0, 2.0), Vector(3.0,3.0,3.0)] },
Triangle { vertices: [Vector(5.0, 5.0, 5.0), Vector(6.0, 6.0, 6.0), Vector(7.0,7.0,7.0)] },
]);
}
}