plexus/
lib.rs

1//! **Plexus** is a library for 2D and 3D mesh processing.
2//!
3//! Please note that versions in the `0.0.*` series are experimental and
4//! unstable! Use exact version constraints when specifying a dependency to
5//! avoid spurious breakage.
6#![allow(unknown_lints)] // Allow clippy lints.
7
8extern crate arrayvec;
9#[cfg(feature = "geometry-cgmath")]
10extern crate cgmath;
11extern crate decorum;
12#[macro_use]
13extern crate derivative;
14extern crate either;
15#[macro_use]
16extern crate failure;
17extern crate fnv;
18extern crate fool;
19#[macro_use]
20extern crate itertools;
21#[cfg(feature = "geometry-mint")]
22extern crate mint;
23#[cfg(feature = "geometry-nalgebra")]
24extern crate nalgebra;
25extern crate num;
26extern crate smallvec;
27extern crate typenum;
28
29use decorum::Real;
30use num::{One, Zero};
31use std::fmt::Debug;
32use std::ops::Div;
33
34pub mod buffer;
35pub mod geometry;
36pub mod graph;
37pub mod primitive;
38
39// TODO: Documentation comments include static image content from the GitHub
40//       repository. This is fragile and difficult to maintain. Use a mechanism
41//       provided by rustdoc or doxidize for this instead.
42
43pub mod prelude {
44    //! Re-exports commonly used types and traits.
45    //!
46    //! Importing the contents of this module is recommended when working with
47    //! generators and iterator expressions, as those operations are expressed
48    //! mostly through traits.
49    //!
50    //! # Traits
51    //!
52    //! This module re-exports numerous traits. Traits from the `primitive`
53    //! module for generating, decomposing, and indexing iterators over
54    //! topological data (e.g., `Triangle`, `Quad`, etc.) are re-exported so
55    //! that functions in iterator expressions can be used without lengthy
56    //! imports.
57    //!
58    //! Basic traits for (de)constructing `MeshBuffer`s and `MeshGraph`s are
59    //! also re-exported. These traits allow mesh types to be constructed from
60    //! raw buffers and buffers to be re-indexed.
61    //!
62    //! # Types
63    //!
64    //! The `Selector` enum and its variants are re-exported for convenience.
65    //! `Selector` is often used when mutating `MeshGraph`s.
66    //!
67    //! The geometric `Duplet` and `Triplet` types are also re-exported. These
68    //! types are emitted by generators and support various conversions.
69
70    pub use crate::buffer::{IntoFlatIndex as _, IntoStructuredIndex as _};
71    pub use crate::geometry::{Duplet, Triplet};
72    pub use crate::graph::Selector;
73    pub use crate::primitive::decompose::{
74        Edges as _, IntoEdges as _, IntoSubdivisions as _, IntoTetrahedrons as _,
75        IntoTriangles as _, IntoVertices as _, Subdivide as _, Tetrahedrons as _, Triangulate as _,
76        Vertices as _,
77    };
78    pub use crate::primitive::generate::{
79        IndicesForNormal as _, IndicesForPosition as _, PolygonGenerator as _,
80        PolygonsWithNormal as _, PolygonsWithPosition as _, PolygonsWithUvMap as _,
81        VerticesWithNormal as _, VerticesWithPosition as _,
82    };
83    pub use crate::primitive::index::{
84        CollectWithIndexer as _, FlatIndexVertices as _, IndexVertices as _,
85    };
86    pub use crate::primitive::{Converged as _, Map as _, MapVertices as _, Zip as _};
87    pub use crate::IteratorExt as _;
88    pub use crate::{FromRawBuffers as _, FromRawBuffersWithArity as _};
89
90    pub use Selector::ByIndex;
91    pub use Selector::ByKey;
92}
93
94pub trait FromRawBuffers<N, G>: Sized {
95    type Error: Debug;
96
97    fn from_raw_buffers<I, J>(indices: I, vertices: J) -> Result<Self, Self::Error>
98    where
99        I: IntoIterator<Item = N>,
100        J: IntoIterator<Item = G>;
101}
102
103pub trait FromRawBuffersWithArity<N, G>: Sized {
104    type Error: Debug;
105
106    fn from_raw_buffers_with_arity<I, J>(
107        indices: I,
108        vertices: J,
109        arity: usize,
110    ) -> Result<Self, Self::Error>
111    where
112        I: IntoIterator<Item = N>,
113        J: IntoIterator<Item = G>;
114}
115
116/// Extension methods for types implementing `Iterator`.
117pub trait IteratorExt: Iterator + Sized {
118    /// Provides an iterator over a window of duplets that includes the first
119    /// value in the sequence at the beginning and end of the iteration.
120    ///
121    /// Given a collection with ordered elements `a`, `b`, and `c`, this
122    /// iterator yeilds the ordered items `(a, b)`, `(b, c)`, `(c, a)`.
123    fn perimeter(self) -> Perimeter<Self>
124    where
125        Self::Item: Clone;
126}
127
128impl<I> IteratorExt for I
129where
130    I: Iterator,
131{
132    fn perimeter(self) -> Perimeter<I>
133    where
134        I::Item: Clone,
135    {
136        Perimeter::new(self)
137    }
138}
139
140pub struct Perimeter<I>
141where
142    I: Iterator,
143    I::Item: Clone,
144{
145    input: I,
146    first: Option<I::Item>,
147    previous: Option<I::Item>,
148}
149
150impl<I> Perimeter<I>
151where
152    I: Iterator,
153    I::Item: Clone,
154{
155    fn new(mut input: I) -> Self {
156        let first = input.next();
157        let previous = first.clone();
158        Perimeter {
159            input,
160            first,
161            previous,
162        }
163    }
164}
165
166impl<I> Iterator for Perimeter<I>
167where
168    I: Iterator,
169    I::Item: Clone,
170{
171    type Item = (I::Item, I::Item);
172
173    fn next(&mut self) -> Option<Self::Item> {
174        let next = self.input.next();
175        match (self.previous.clone(), next.or_else(|| self.first.take())) {
176            (Some(a), Some(b)) => {
177                self.previous = Some(b.clone());
178                Some((a, b))
179            }
180            _ => None,
181        }
182    }
183
184    fn size_hint(&self) -> (usize, Option<usize>) {
185        self.input.size_hint()
186    }
187}
188
189trait Half {
190    fn half() -> Self;
191}
192
193impl<T> Half for T
194where
195    T: Div<T, Output = T> + One + Real + Zero,
196{
197    fn half() -> Self {
198        let one = T::one();
199        one / (one + one)
200    }
201}