Plexus is a Rust library for generating and manipulating 3D meshes.
Generation and Iterator Expressions
Meshes can be generated from primitives like cubes and spheres using iterator
expressions. Primitives emit topological structures like Triangle
s or
Quad
s, which contain arbitrary geometric data in their vertices. These can be
transformed and decomposed into other topologies and geometric data via
triangulation, tesselation, and conversion into rendering pipeline data.
use Point3;
use MeshBuffer;
use sphere;
use *;
// Example module in the local crate that provides basic rendering.
use ;
// Construct a buffer of index and vertex data from a sphere primitive.
let buffer = with_unit_radius
.polygons_with_position
.map_vertices
.map_vertices
.map_vertices
.;
draw;
Half-Edge Graph Meshes
Generators are flexible and easy to use, but only represent vertex geometry and
are difficult to query and manipulate. A Mesh
, represented as a half-edge
graph, supports
arbitrary geometry for vertices, edges, and faces. The graph can also be
queried and manipulated in ways that generators and iterator expressions
cannot.
use R32;
use Point3;
use sphere;
use Mesh;
use *;
// Construct a mesh from a sphere primitive. The vertex geometry is convertible
// to `Point3` via the `FromGeometry` trait in this example.
let mut mesh = with_unit_radius
.polygons_with_position
.;
// Extrude a face in the mesh.
let key = mesh.faces.nth.unwrap.key;
let face = mesh.face_mut.unwrap.extrude.unwrap;
Geometric Traits
Meshes support arbitrary geometry via optional traits. Implementing these
traits allows more operations to be supported, but only two basic traits are
required: Geometry
and Attribute
.
use ;
use ;
use AsPosition;
Geometric traits are optionally implemented for types in the nalgebra and cgmath crates so that common types can be used right away for vertex geometry.
Hashing Floating-Point Values
When collecting an iterator expression into a graph or buffer, an indexer is
used to transform the geometry into raw buffers. HashIndexer
is fast and
reliable, and is used by collect
(which can be overridden via
collect_with_indexer
). However, geometry often contains floating point
values, which do not implement Hash
. An LruIndexer
can also be used, but
can be slower and requires a sufficient capacity to work correctly.
The decorum crate is used to ease
this problem. Hashable types like NotNan
, Finite
, R32
, etc. can be used
as geometric data. Common geometric types also implement traits that provide
conversions to and from a conjugate type that implements Hash
(via the
into_hash
and from_hash
functions).
The decorum
crate also exposes some hashing functions for floating point
primitives, which can be used to directly implement Hash
. With the
derivative crate, floating point fields
can be hashed using one of these functions while deriving Hash
. The Vertex
type used in the above example could be defined as follows:
use decorum;