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 {
Quad,
Triangle,
Polygon,
};
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
}
}
}
}