use std::marker::PhantomData;
use std::collections::VecDeque;
#[derive(Clone, Debug, PartialEq, Eq, Copy)]
pub struct Quad<T> {
pub x: T,
pub y: T,
pub z: T,
pub w: T,
}
impl<T> Quad<T> {
pub fn new(v0: T, v1: T, v2: T, v3: T) -> Quad<T> {
Quad {
x: v0,
y: v1,
z: v2,
w: v3
}
}
}
#[derive(Clone, Debug, PartialEq, Eq, Copy)]
pub struct Triangle<T> {
pub x: T,
pub y: T,
pub z: T,
}
impl<T> Triangle<T> {
pub fn new(v0: T, v1: T, v2: T) -> Triangle<T> {
Triangle {
x: v0,
y: v1,
z: v2
}
}
}
#[derive(Debug, Clone, PartialEq, Copy)]
pub enum Polygon<T> {
PolyTri(Triangle<T>),
PolyQuad(Quad<T>)
}
pub trait EmitVertices<T> {
fn emit_vertices<F>(self, mut emit: F) where F: FnMut(T);
}
impl<T> EmitVertices<T> for Triangle<T> {
fn emit_vertices<F>(self, mut emit: F) where F: FnMut(T) {
let Triangle{x, y, z} = self;
emit(x);
emit(y);
emit(z);
}
}
impl<T> EmitVertices<T> for Quad<T> {
fn emit_vertices<F>(self, mut emit: F) where F: FnMut(T) {
let Quad{x, y, z, w} = self;
emit(x);
emit(y);
emit(z);
emit(w);
}
}
impl<T> EmitVertices<T> for Polygon<T> {
fn emit_vertices<F>(self, emit: F) where F: FnMut(T) {
use self::Polygon::{ PolyQuad, PolyTri };
match self {
PolyTri(p) => p.emit_vertices(emit),
PolyQuad(p) => p.emit_vertices(emit)
}
}
}
pub trait Vertices<SRC, V> {
fn vertices(self) -> VerticesIterator<SRC, V>;
}
impl<V, P: EmitVertices<V>, T: Iterator<Item=P>> Vertices<T, V> for T {
fn vertices(self) -> VerticesIterator<T, V> {
VerticesIterator {
source: self,
buffer: VecDeque::new()
}
}
}
pub struct VerticesIterator<SRC, V> {
source: SRC,
buffer: VecDeque<V>
}
impl<V, U: EmitVertices<V>, SRC: Iterator<Item=U>> Iterator for VerticesIterator<SRC, V> {
type Item = V;
fn next(&mut self) -> Option<V> {
loop {
match self.buffer.pop_front() {
Some(v) => return Some(v),
None => ()
}
match self.source.next() {
Some(p) => p.emit_vertices(|v| self.buffer.push_back(v)),
None => return None
}
}
}
}
pub trait MapVertex<T, U> {
type Output;
fn map_vertex<F>(self, mut map: F) -> Self::Output where F: FnMut(T) -> U;
}
impl<T: Clone, U> MapVertex<T, U> for Triangle<T> {
type Output = Triangle<U>;
fn map_vertex<F>(self, mut map: F) -> Triangle<U> where F: FnMut(T) -> U {
let Triangle{x, y, z} = self;
Triangle {
x: map(x),
y: map(y),
z: map(z)
}
}
}
impl<T: Clone, U> MapVertex<T, U> for Quad<T> {
type Output = Quad<U>;
fn map_vertex<F>(self, mut map: F) -> Quad<U> where F: FnMut(T) -> U {
let Quad{x, y, z, w} = self;
Quad {
x: map(x),
y: map(y),
z: map(z),
w: map(w)
}
}
}
impl<T: Clone, U> MapVertex<T, U> for Polygon<T> {
type Output = Polygon<U>;
fn map_vertex<F>(self, map: F) -> Polygon<U> where F: FnMut(T) -> U {
use self::Polygon::{ PolyTri, PolyQuad };
match self {
PolyTri(p) => PolyTri(p.map_vertex(map)),
PolyQuad(p) => PolyQuad(p.map_vertex(map))
}
}
}
pub trait MapToVertices<T, U> {
type Output;
fn vertex<F>(self, map: F) -> MapToVerticesIter<Self, T, U, F>
where F: FnMut(T) -> U;
}
impl<VIn, VOut,
P, POut: MapVertex<VIn, VOut, Output=P>,
T: Iterator<Item=POut>>
MapToVertices<VIn, VOut> for T {
type Output = P;
fn vertex<F>(self, map: F) -> MapToVerticesIter<T, VIn, VOut, F>
where F: FnMut(VIn) -> VOut {
MapToVerticesIter {
src: self,
f: map,
phantom_t: PhantomData,
phantom_u: PhantomData
}
}
}
struct MapToVerticesIter<SRC, T, U, F: FnMut(T) -> U> {
src: SRC,
f: F,
phantom_t: PhantomData<T>,
phantom_u: PhantomData<U>
}
impl<'a, P,
POut: MapVertex<T, U, Output=P>,
SRC: Iterator<Item=POut>,
T, U, F: FnMut(T) -> U> Iterator for MapToVerticesIter<SRC, T, U, F> {
type Item = P;
fn size_hint(&self) -> (usize, Option<usize>) {
self.src.size_hint()
}
fn next(&mut self) -> Option<P> {
self.src.next().map(|x| x.map_vertex(|x| (self.f)(x)))
}
}
#[derive(Clone, Debug, PartialEq, Eq, Copy, Hash)]
pub struct Line<T> {
pub x: T,
pub y: T
}
impl<T> Line<T> {
pub fn new(x: T, y: T) -> Line<T> {
Line{x: x, y: y}
}
}
pub trait EmitLines {
type Vertex;
fn emit_lines<E>(self, emit: E)
where E: FnMut(Line<Self::Vertex>);
}
impl<T: Clone> EmitLines for Triangle<T> {
type Vertex = T;
fn emit_lines<E>(self, mut emit: E)
where E: FnMut(Line<T>)
{
emit(Line::new(self.x.clone(), self.y.clone()));
emit(Line::new(self.y , self.z.clone()));
emit(Line::new(self.z , self.x ));
}
}
impl<T: Clone> EmitLines for Quad<T> {
type Vertex = T;
fn emit_lines<E>(self, mut emit: E)
where E: FnMut(Line<T>)
{
emit(Line::new(self.x.clone(), self.y.clone()));
emit(Line::new(self.y , self.z.clone()));
emit(Line::new(self.z , self.w.clone()));
emit(Line::new(self.w , self.x ));
}
}
impl<T: Clone> EmitLines for Polygon<T> {
type Vertex = T;
fn emit_lines<E>(self, emit: E)
where E: FnMut(Line<T>)
{
match self {
Polygon::PolyTri(x) => x.emit_lines(emit),
Polygon::PolyQuad(x) => x.emit_lines(emit)
}
}
}
pub trait Lines {
type Vertex;
fn lines(self) -> LinesIterator<Self, Self::Vertex>;
}
impl<T, P, V> Lines for T
where T: Iterator<Item=P>,
P: EmitLines<Vertex=V>
{
type Vertex = V;
fn lines(self) -> LinesIterator<T, V> {
LinesIterator {
source: self,
buffer: VecDeque::new()
}
}
}
pub struct LinesIterator<I, V> {
source: I,
buffer: VecDeque<Line<V>>,
}
impl<I, P, V> Iterator for LinesIterator<I, V>
where I: Iterator<Item=P>,
P: EmitLines<Vertex=V>
{
type Item = Line<V>;
fn size_hint(&self) -> (usize, Option<usize>) {
let (n, _) = self.source.size_hint();
(n, None)
}
fn next(&mut self) -> Option<Line<V>> {
loop {
match self.buffer.pop_front() {
Some(v) => return Some(v),
None => ()
}
match self.source.next() {
Some(p) => p.emit_lines(|v| self.buffer.push_back(v)),
None => return None
}
}
}
}