1use std::collections::VecDeque;
2
3use Polygon::{PolyQuad, PolyTri};
4use {Polygon, Quad, Triangle};
5
6pub trait EmitTriangles {
8 type Vertex;
10
11 fn emit_triangles<F>(&self, F)
14 where
15 F: FnMut(Triangle<Self::Vertex>);
16}
17
18impl<T: Clone> EmitTriangles for Quad<T> {
19 type Vertex = T;
20
21 fn emit_triangles<F>(&self, mut emit: F)
22 where
23 F: FnMut(Triangle<T>),
24 {
25 let &Quad {
26 ref x,
27 ref y,
28 ref z,
29 ref w,
30 } = self;
31 emit(Triangle::new(x.clone(), y.clone(), z.clone()));
32 emit(Triangle::new(z.clone(), w.clone(), x.clone()));
33 }
34}
35
36impl<T: Clone> EmitTriangles for Triangle<T> {
37 type Vertex = T;
38
39 fn emit_triangles<F>(&self, mut emit: F)
40 where
41 F: FnMut(Triangle<T>),
42 {
43 emit(self.clone());
44 }
45}
46
47impl<T: Clone> EmitTriangles for Polygon<T> {
48 type Vertex = T;
49
50 fn emit_triangles<F>(&self, emit: F)
51 where
52 F: FnMut(Triangle<T>),
53 {
54 match self {
55 &PolyTri(ref t) => t.emit_triangles(emit),
56 &PolyQuad(ref q) => q.emit_triangles(emit),
57 }
58 }
59}
60
61pub trait Triangulate<T, V> {
65 fn triangulate(self) -> TriangulateIterator<T, V>;
67}
68
69impl<V, P: EmitTriangles<Vertex = V>, T: Iterator<Item = P>> Triangulate<T, V> for T {
70 fn triangulate(self) -> TriangulateIterator<T, V> {
71 TriangulateIterator::new(self)
72 }
73}
74
75pub struct TriangulateIterator<SRC, V> {
77 source: SRC,
78 buffer: VecDeque<Triangle<V>>,
79}
80
81impl<V, U: EmitTriangles<Vertex = V>, SRC: Iterator<Item = U>> TriangulateIterator<SRC, V> {
82 fn new(src: SRC) -> TriangulateIterator<SRC, V> {
83 TriangulateIterator {
84 source: src,
85 buffer: VecDeque::new(),
86 }
87 }
88}
89
90impl<V, U: EmitTriangles<Vertex = V>, SRC: Iterator<Item = U>> Iterator
91 for TriangulateIterator<SRC, V>
92{
93 type Item = Triangle<V>;
94
95 fn size_hint(&self) -> (usize, Option<usize>) {
96 let (n, _) = self.source.size_hint();
97 (n, None)
98 }
99
100 fn next(&mut self) -> Option<Self::Item> {
101 loop {
102 match self.buffer.pop_front() {
103 Some(v) => return Some(v),
104 None => (),
105 }
106
107 match self.source.next() {
108 Some(p) => p.emit_triangles(|v| self.buffer.push_back(v)),
109 None => return None,
110 }
111 }
112 }
113}