1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
//! Higher order geometric traits.
//!
//! This module defines higher order traits for operations on a graph. It also
//! provides aliases for geometric types to improve readability of type
//! constraints. These traits can be used as contraints to prove to the
//! compiler that certain operations are supported without specifying
//! complicated relationships.
//!
//! The traits in this module have blanket implementations that apply when
//! certain geometric and operational traits are implemented. For example, if a
//! type implements `AsPosition` and the `Output` type of that implementation
//! also implements `Cross` and `Normalize`, then a `Geometry` using that type
//! as its `Vertex` attribute will likely implement the `FaceNormal` trait in
//! this module.
//!
//! # Examples
//!
//! A function that subdivides faces in a graph by splitting edges at their
//! midpoints:
//!
//! ```rust
//! # extern crate plexus;
//! # extern crate smallvec;
//! use plexus::geometry::alias::VertexPosition;
//! use plexus::geometry::compose::EdgeMidpoint;
//! use plexus::geometry::convert::AsPosition;
//! use plexus::geometry::Geometry;
//! use plexus::graph::{FaceView, MeshGraph};
//! use plexus::prelude::*;
//! use smallvec::SmallVec;
//!
//! # fn main() {
//! // Requires `EdgeMidpoint` for `split_at_midpoint`.
//! pub fn circumscribe<G>(face: FaceView<&mut MeshGraph<G>, G>) -> FaceView<&mut MeshGraph<G>, G>
//! where
//! G: EdgeMidpoint<Midpoint = VertexPosition<G>> + Geometry,
//! G::Vertex: AsPosition,
//! {
//! let arity = face.arity();
//! let mut arc = face.into_arc();
//! let mut splits = SmallVec::<[_; 4]>::with_capacity(arity);
//! for _ in 0..arity {
//! let vertex = arc.split_at_midpoint();
//! splits.push(vertex.key());
//! arc = vertex.into_outgoing_arc().into_next_arc();
//! }
//! let mut face = arc.into_face().unwrap();
//! for (a, b) in splits.into_iter().perimeter() {
//! face = face.split(ByKey(a), ByKey(b)).unwrap().into_face().unwrap();
//! }
//! face
//! }
//! # }
//! ```
pub use crate*;