use crate::draw;
use crate::geom;
use crate::geom::graph::node;
use crate::math::BaseFloat;
use std::cell::RefCell;
use std::ops;
pub mod color;
pub mod primitive;
pub mod spatial;
use self::spatial::dimension;
pub use self::color::{IntoRgba, SetColor};
pub use self::primitive::{Ellipse, Line, Primitive, Quad, Rect, Tri};
pub use self::spatial::dimension::SetDimensions;
pub use self::spatial::orientation::SetOrientation;
pub use self::spatial::position::SetPosition;
pub type ColorScalar = color::DefaultScalar;
pub type Rgba = color::DefaultRgba;
pub type Drawn<S, V, I> = (spatial::Properties<S>, V, I);
#[derive(Debug)]
pub struct Draw<'a, S = geom::scalar::Default>
where
S: 'a + BaseFloat,
{
state: RefCell<&'a mut draw::State<S>>,
}
#[derive(Debug)]
pub struct VerticesFromRanges {
pub ranges: draw::IntermediaryVertexDataRanges,
pub fill_color: Option<draw::mesh::vertex::Color>,
}
#[derive(Debug)]
pub struct IndicesFromRange {
pub range: ops::Range<usize>,
}
impl<'a, S> Draw<'a, S>
where
S: BaseFloat,
{
pub fn new(state: &'a mut draw::State<S>) -> Self {
Draw {
state: RefCell::new(state),
}
}
pub fn untransformed_dimension_of<F>(&self, n: &node::Index, point_axis: &F) -> Option<S>
where
F: Fn(&draw::mesh::vertex::Point<S>) -> S,
{
self.state
.borrow_mut()
.untransformed_dimension_of(n, point_axis)
}
pub fn untransformed_x_dimension_of(&self, n: &node::Index) -> Option<S> {
self.state.borrow_mut().untransformed_x_dimension_of(n)
}
pub fn untransformed_y_dimension_of(&self, n: &node::Index) -> Option<S> {
self.state.borrow_mut().untransformed_y_dimension_of(n)
}
pub fn untransformed_z_dimension_of(&self, n: &node::Index) -> Option<S> {
self.state.borrow_mut().untransformed_z_dimension_of(n)
}
pub fn dimension_of<F>(&mut self, n: &node::Index, point_axis: &F) -> Option<S>
where
F: Fn(&draw::mesh::vertex::Point<S>) -> S,
{
self.state.borrow_mut().dimension_of(n, point_axis)
}
pub fn x_dimension_of(&self, n: &node::Index) -> Option<S> {
self.state.borrow_mut().x_dimension_of(n)
}
pub fn y_dimension_of(&self, n: &node::Index) -> Option<S> {
self.state.borrow_mut().y_dimension_of(n)
}
pub fn z_dimension_of(&self, n: &node::Index) -> Option<S> {
self.state.borrow_mut().z_dimension_of(n)
}
pub fn theme<F, T>(&self, get: F) -> T
where
F: FnOnce(&draw::Theme) -> T,
{
let state = self.state.borrow();
get(&state.theme)
}
}
pub trait Vertices<S>: Sized {
fn next(&mut self, data: &draw::IntermediaryMesh<S>) -> Option<draw::mesh::Vertex<S>>;
fn into_iter(self, data: &draw::IntermediaryMesh<S>) -> IterVertices<Self, S> {
IterVertices {
vertices: self,
data,
}
}
}
pub trait Indices: Sized {
fn next(&mut self, intermediary_indices: &[usize]) -> Option<usize>;
fn into_iter(self, intermediary_indices: &[usize]) -> IterIndices<Self> {
IterIndices {
indices: self,
intermediary_indices,
}
}
}
pub trait IntoDrawn<S>
where
S: BaseFloat,
{
type Vertices: Vertices<S>;
type Indices: Indices;
fn into_drawn(self, _: Draw<S>) -> Drawn<S, Self::Vertices, Self::Indices>;
}
pub struct IterVertices<'a, V, S: 'a> {
vertices: V,
data: &'a draw::IntermediaryMesh<S>,
}
pub struct IterIndices<'a, I> {
indices: I,
intermediary_indices: &'a [usize],
}
impl<S> dimension::Properties<S>
where
S: BaseFloat,
{
pub fn to_scalars(&self, draw: &Draw<S>) -> (Option<S>, Option<S>, Option<S>) {
const EXPECT_DIMENSION: &'static str = "no raw dimension for node";
let x = self.x.as_ref().map(|x| {
x.to_scalar(|n| {
draw.untransformed_x_dimension_of(n)
.expect(EXPECT_DIMENSION)
})
});
let y = self.y.as_ref().map(|y| {
y.to_scalar(|n| {
draw.untransformed_y_dimension_of(n)
.expect(EXPECT_DIMENSION)
})
});
let z = self.z.as_ref().map(|z| {
z.to_scalar(|n| {
draw.untransformed_z_dimension_of(n)
.expect(EXPECT_DIMENSION)
})
});
(x, y, z)
}
}
impl<S, I> Vertices<S> for I
where
I: Iterator<Item = draw::mesh::Vertex<S>>,
{
fn next(&mut self, _data: &draw::IntermediaryMesh<S>) -> Option<draw::mesh::Vertex<S>> {
self.next()
}
}
impl<I> Indices for I
where
I: Iterator<Item = usize>,
{
fn next(&mut self, _intermediary_indices: &[usize]) -> Option<usize> {
self.next()
}
}
impl<'a, V, S> Iterator for IterVertices<'a, V, S>
where
V: Vertices<S>,
{
type Item = draw::mesh::Vertex<S>;
fn next(&mut self) -> Option<Self::Item> {
let IterVertices {
ref mut vertices,
data,
} = *self;
Vertices::next(vertices, data)
}
}
impl<'a, I> Iterator for IterIndices<'a, I>
where
I: Indices,
{
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
let IterIndices {
ref mut indices,
intermediary_indices,
} = *self;
Indices::next(indices, intermediary_indices)
}
}
impl<S> Vertices<S> for VerticesFromRanges
where
S: BaseFloat,
{
fn next(&mut self, mesh: &draw::IntermediaryMesh<S>) -> Option<draw::mesh::Vertex<S>> {
let VerticesFromRanges {
ref mut ranges,
fill_color,
} = *self;
let point = Iterator::next(&mut ranges.points);
let color = Iterator::next(&mut ranges.colors);
let tex_coords = Iterator::next(&mut ranges.tex_coords);
let point = match point {
None => return None,
Some(point_ix) => *mesh
.vertex_data
.points
.get(point_ix)
.expect("no point for point index in IntermediaryMesh"),
};
let color = color
.map(|color_ix| {
*mesh
.vertex_data
.colors
.get(color_ix)
.expect("no color for color index in IntermediaryMesh")
})
.or(fill_color)
.expect("no color for vertex");
let tex_coords = tex_coords
.map(|tex_coords_ix| {
*mesh
.vertex_data
.tex_coords
.get(tex_coords_ix)
.expect("no tex_coords for tex_coords index in IntermediaryMesh")
})
.unwrap_or_else(draw::mesh::vertex::default_tex_coords);
Some(draw::mesh::vertex::new(point, color, tex_coords))
}
}
impl Indices for IndicesFromRange {
fn next(&mut self, intermediary_indices: &[usize]) -> Option<usize> {
Iterator::next(&mut self.range).map(|ix| {
*intermediary_indices
.get(ix)
.expect("index into `intermediary_indices` is out of range")
})
}
}