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
use std::collections::VecDeque;
use Polygon::{PolyQuad, PolyTri};
use {Polygon, Quad, Triangle};
pub trait EmitTriangles {
type Vertex;
fn emit_triangles<F>(&self, F)
where
F: FnMut(Triangle<Self::Vertex>);
}
impl<T: Clone> EmitTriangles for Quad<T> {
type Vertex = T;
fn emit_triangles<F>(&self, mut emit: F)
where
F: FnMut(Triangle<T>),
{
let &Quad {
ref x,
ref y,
ref z,
ref w,
} = self;
emit(Triangle::new(x.clone(), y.clone(), z.clone()));
emit(Triangle::new(z.clone(), w.clone(), x.clone()));
}
}
impl<T: Clone> EmitTriangles for Triangle<T> {
type Vertex = T;
fn emit_triangles<F>(&self, mut emit: F)
where
F: FnMut(Triangle<T>),
{
emit(self.clone());
}
}
impl<T: Clone> EmitTriangles for Polygon<T> {
type Vertex = T;
fn emit_triangles<F>(&self, emit: F)
where
F: FnMut(Triangle<T>),
{
match self {
&PolyTri(ref t) => t.emit_triangles(emit),
&PolyQuad(ref q) => q.emit_triangles(emit),
}
}
}
pub trait Triangulate<T, V> {
fn triangulate(self) -> TriangulateIterator<T, V>;
}
impl<V, P: EmitTriangles<Vertex = V>, T: Iterator<Item = P>> Triangulate<T, V> for T {
fn triangulate(self) -> TriangulateIterator<T, V> {
TriangulateIterator::new(self)
}
}
pub struct TriangulateIterator<SRC, V> {
source: SRC,
buffer: VecDeque<Triangle<V>>,
}
impl<V, U: EmitTriangles<Vertex = V>, SRC: Iterator<Item = U>> TriangulateIterator<SRC, V> {
fn new(src: SRC) -> TriangulateIterator<SRC, V> {
TriangulateIterator {
source: src,
buffer: VecDeque::new(),
}
}
}
impl<V, U: EmitTriangles<Vertex = V>, SRC: Iterator<Item = U>> Iterator
for TriangulateIterator<SRC, V>
{
type Item = Triangle<V>;
fn size_hint(&self) -> (usize, Option<usize>) {
let (n, _) = self.source.size_hint();
(n, None)
}
fn next(&mut self) -> Option<Self::Item> {
loop {
match self.buffer.pop_front() {
Some(v) => return Some(v),
None => (),
}
match self.source.next() {
Some(p) => p.emit_triangles(|v| self.buffer.push_back(v)),
None => return None,
}
}
}
}