genmesh/
poly.rs

1use std::collections::VecDeque;
2use std::marker::PhantomData;
3
4/// A polygon with 4 points. Maps to `GL_QUADS`
5#[derive(Clone, Debug, PartialEq, Eq, Copy)]
6pub struct Quad<T> {
7    /// the first point of a quad
8    pub x: T,
9    /// the second point of a quad
10    pub y: T,
11    /// the third point of a quad
12    pub z: T,
13    /// the fourth point of a quad
14    pub w: T,
15}
16
17impl<T> Quad<T> {
18    /// create a new `Quad` with supplied vertices
19    pub fn new(v0: T, v1: T, v2: T, v3: T) -> Self {
20        Quad {
21            x: v0,
22            y: v1,
23            z: v2,
24            w: v3,
25        }
26    }
27}
28
29/// A polygon with 3 points. Maps to `GL_TRIANGLE`
30#[derive(Clone, Debug, PartialEq, Eq, Copy)]
31pub struct Triangle<T> {
32    /// the first point of a triangle
33    pub x: T,
34    /// the second point of a triangle
35    pub y: T,
36    /// the third point of a triangle
37    pub z: T,
38}
39
40impl<T> Triangle<T> {
41    /// create a new `Triangle` with supplied vertcies
42    pub fn new(v0: T, v1: T, v2: T) -> Self {
43        Triangle {
44            x: v0,
45            y: v1,
46            z: v2,
47        }
48    }
49}
50
51/// This is All-the-types container. This exists since some generators
52/// produce both `Triangles` and `Quads`.
53#[derive(Debug, Clone, PartialEq, Copy)]
54pub enum Polygon<T> {
55    /// A wraped triangle
56    PolyTri(Triangle<T>),
57    /// A wraped quad
58    PolyQuad(Quad<T>),
59}
60
61/// The core mechanism of `Vertices` trait. This is a mechanism for unwraping
62/// a polygon extracting all of the vertices that it bound together.
63pub trait EmitVertices<T> {
64    /// Consume a polygon, each
65    /// vertex is emitted to the parent function by calling the supplied
66    /// lambda function
67    fn emit_vertices<F>(self, F)
68    where
69        F: FnMut(T);
70}
71
72impl<T> EmitVertices<T> for Line<T> {
73    fn emit_vertices<F>(self, mut emit: F)
74    where
75        F: FnMut(T),
76    {
77        let Line { x, y } = self;
78        emit(x);
79        emit(y);
80    }
81}
82
83impl<T> EmitVertices<T> for Triangle<T> {
84    fn emit_vertices<F>(self, mut emit: F)
85    where
86        F: FnMut(T),
87    {
88        let Triangle { x, y, z } = self;
89        emit(x);
90        emit(y);
91        emit(z);
92    }
93}
94
95impl<T> EmitVertices<T> for Quad<T> {
96    fn emit_vertices<F>(self, mut emit: F)
97    where
98        F: FnMut(T),
99    {
100        let Quad { x, y, z, w } = self;
101        emit(x);
102        emit(y);
103        emit(z);
104        emit(w);
105    }
106}
107
108impl<T> EmitVertices<T> for Polygon<T> {
109    fn emit_vertices<F>(self, emit: F)
110    where
111        F: FnMut(T),
112    {
113        use self::Polygon::{PolyQuad, PolyTri};
114
115        match self {
116            PolyTri(p) => p.emit_vertices(emit),
117            PolyQuad(p) => p.emit_vertices(emit),
118        }
119    }
120}
121
122/// Supplies a way to convert an iterator of polygons to an iterator
123/// of vertices. Useful for when you need to write the vertices into
124/// a graphics pipeline.
125pub trait Vertices<SRC, V> {
126    /// Convert a polygon iterator to a vertices iterator.
127    fn vertices(self) -> VerticesIterator<SRC, V>;
128}
129
130impl<V, P: EmitVertices<V>, T: Iterator<Item = P>> Vertices<T, V> for T {
131    fn vertices(self) -> VerticesIterator<T, V> {
132        VerticesIterator {
133            source: self,
134            buffer: VecDeque::new(),
135        }
136    }
137}
138
139/// an iterator that breaks a polygon down into its individual
140/// verticies.
141pub struct VerticesIterator<SRC, V> {
142    source: SRC,
143    buffer: VecDeque<V>,
144}
145
146impl<V, U: EmitVertices<V>, SRC: Iterator<Item = U>> Iterator for VerticesIterator<SRC, V> {
147    type Item = V;
148
149    fn next(&mut self) -> Option<V> {
150        loop {
151            match self.buffer.pop_front() {
152                Some(v) => return Some(v),
153                None => (),
154            }
155
156            match self.source.next() {
157                Some(p) => p.emit_vertices(|v| self.buffer.push_back(v)),
158                None => return None,
159            }
160        }
161    }
162}
163
164/// equivalent of `map` but per-vertex
165pub trait MapVertex<T, U> {
166    /// `Output` should be a a container of the same shape of the type
167    /// It's internal values should reflect any transformation the map did.
168    type Output;
169    /// map a function to each vertex in polygon creating a new polygon
170    fn map_vertex<F>(self, F) -> Self::Output
171    where
172        F: FnMut(T) -> U;
173}
174
175impl<T: Clone, U> MapVertex<T, U> for Line<T> {
176    type Output = Line<U>;
177
178    fn map_vertex<F>(self, mut map: F) -> Line<U>
179    where
180        F: FnMut(T) -> U,
181    {
182        let Line { x, y } = self;
183        Line {
184            x: map(x),
185            y: map(y),
186        }
187    }
188}
189
190impl<T: Clone, U> MapVertex<T, U> for Triangle<T> {
191    type Output = Triangle<U>;
192
193    fn map_vertex<F>(self, mut map: F) -> Triangle<U>
194    where
195        F: FnMut(T) -> U,
196    {
197        let Triangle { x, y, z } = self;
198        Triangle {
199            x: map(x),
200            y: map(y),
201            z: map(z),
202        }
203    }
204}
205
206impl<T: Clone, U> MapVertex<T, U> for Quad<T> {
207    type Output = Quad<U>;
208
209    fn map_vertex<F>(self, mut map: F) -> Quad<U>
210    where
211        F: FnMut(T) -> U,
212    {
213        let Quad { x, y, z, w } = self;
214        Quad {
215            x: map(x),
216            y: map(y),
217            z: map(z),
218            w: map(w),
219        }
220    }
221}
222
223impl<T: Clone, U> MapVertex<T, U> for Polygon<T> {
224    type Output = Polygon<U>;
225
226    fn map_vertex<F>(self, map: F) -> Polygon<U>
227    where
228        F: FnMut(T) -> U,
229    {
230        use self::Polygon::{PolyQuad, PolyTri};
231
232        match self {
233            PolyTri(p) => PolyTri(p.map_vertex(map)),
234            PolyQuad(p) => PolyQuad(p.map_vertex(map)),
235        }
236    }
237}
238
239/// This acts very similar to a vertex shader. It gives a way to manipulate
240/// and modify the vertices in a polygon. This is useful if you need to scale
241/// the mesh using a matrix multiply, or just for modifying the type of each
242/// vertex.
243pub trait MapToVertices<T, U>: Sized {
244    /// `Output` should be a a container of the same shape of the type
245    /// It's internal values should reflect any transformation the map did.
246    type Output;
247
248    /// from a iterator of polygons, produces a iterator of polygons. Each
249    /// vertex in the process is modified with the suppled function.
250    fn vertex<F>(self, map: F) -> MapToVerticesIter<Self, T, U, F>
251    where
252        F: FnMut(T) -> U;
253}
254
255impl<VIn, VOut, P, POut: MapVertex<VIn, VOut, Output = P>, T: Iterator<Item = POut>>
256    MapToVertices<VIn, VOut> for T
257{
258    type Output = P;
259
260    fn vertex<F>(self, map: F) -> MapToVerticesIter<T, VIn, VOut, F>
261    where
262        F: FnMut(VIn) -> VOut,
263    {
264        MapToVerticesIter {
265            src: self,
266            f: map,
267            phantom: PhantomData,
268        }
269    }
270}
271
272pub struct MapToVerticesIter<SRC, T, U, F: FnMut(T) -> U> {
273    src: SRC,
274    f: F,
275    phantom: PhantomData<(T, U)>,
276}
277
278impl<
279        'a,
280        P,
281        POut: MapVertex<T, U, Output = P>,
282        SRC: Iterator<Item = POut>,
283        T,
284        U,
285        F: FnMut(T) -> U,
286    > Iterator for MapToVerticesIter<SRC, T, U, F>
287{
288    type Item = P;
289
290    fn size_hint(&self) -> (usize, Option<usize>) {
291        self.src.size_hint()
292    }
293
294    fn next(&mut self) -> Option<P> {
295        self.src.next().map(|x| x.map_vertex(|x| (self.f)(x)))
296    }
297}
298
299/// Represents a line
300#[derive(Clone, Debug, PartialEq, Eq, Copy, Hash)]
301pub struct Line<T> {
302    /// the first point
303    pub x: T,
304    /// The second point
305    pub y: T,
306}
307
308impl<T> Line<T> {
309    /// Create a new line using point x and y
310    pub fn new(x: T, y: T) -> Self {
311        Line { x: x, y: y }
312    }
313}
314
315/// Convert a Polygon into it's fragments
316pub trait EmitLines {
317    /// The Vertex defines the corners of a Polygon
318    type Vertex;
319
320    /// convert a polygon into lines, each line is emitted via
321    /// calling of the callback of `emit` This allow for
322    /// a variable amount of lines to be returned
323    fn emit_lines<E>(self, emit: E)
324    where
325        E: FnMut(Line<Self::Vertex>);
326}
327
328impl<T: Clone> EmitLines for Triangle<T> {
329    type Vertex = T;
330
331    fn emit_lines<E>(self, mut emit: E)
332    where
333        E: FnMut(Line<T>),
334    {
335        emit(Line::new(self.x.clone(), self.y.clone()));
336        emit(Line::new(self.y, self.z.clone()));
337        emit(Line::new(self.z, self.x));
338    }
339}
340
341impl<T: Clone> EmitLines for Quad<T> {
342    type Vertex = T;
343
344    fn emit_lines<E>(self, mut emit: E)
345    where
346        E: FnMut(Line<T>),
347    {
348        emit(Line::new(self.x.clone(), self.y.clone()));
349        emit(Line::new(self.y, self.z.clone()));
350        emit(Line::new(self.z, self.w.clone()));
351        emit(Line::new(self.w, self.x));
352    }
353}
354
355impl<T: Clone> EmitLines for Polygon<T> {
356    type Vertex = T;
357
358    fn emit_lines<E>(self, emit: E)
359    where
360        E: FnMut(Line<T>),
361    {
362        match self {
363            Polygon::PolyTri(x) => x.emit_lines(emit),
364            Polygon::PolyQuad(x) => x.emit_lines(emit),
365        }
366    }
367}
368
369/// Creates an LinesIterator from another Iterator
370pub trait Lines: Sized {
371    /// The type of each point in the lines
372    type Vertex;
373
374    /// Convert the iterator into a LinesIterator
375    fn lines(self) -> LinesIterator<Self, Self::Vertex>;
376}
377
378impl<T, P, V> Lines for T
379where
380    T: Iterator<Item = P>,
381    P: EmitLines<Vertex = V>,
382{
383    type Vertex = V;
384
385    fn lines(self) -> LinesIterator<T, V> {
386        LinesIterator {
387            source: self,
388            buffer: VecDeque::new(),
389        }
390    }
391}
392
393/// An iterator that turns Polygons into an Iterator of Lines
394pub struct LinesIterator<I, V> {
395    source: I,
396    buffer: VecDeque<Line<V>>,
397}
398
399impl<I, P, V> Iterator for LinesIterator<I, V>
400where
401    I: Iterator<Item = P>,
402    P: EmitLines<Vertex = V>,
403{
404    type Item = Line<V>;
405
406    fn size_hint(&self) -> (usize, Option<usize>) {
407        let (n, _) = self.source.size_hint();
408        (n, None)
409    }
410
411    fn next(&mut self) -> Option<Line<V>> {
412        loop {
413            match self.buffer.pop_front() {
414                Some(v) => return Some(v),
415                None => (),
416            }
417
418            match self.source.next() {
419                Some(p) => p.emit_lines(|v| self.buffer.push_back(v)),
420                None => return None,
421            }
422        }
423    }
424}