https://github.com/olson-sean-k/plexus
Polygonal mesh processing.
https://github.com/olson-sean-k/plexus
geometry graphics half-edge mesh polygon rust topology
Last synced: 5 months ago
JSON representation
Polygonal mesh processing.
- Host: GitHub
- URL: https://github.com/olson-sean-k/plexus
- Owner: olson-sean-k
- License: mit
- Created: 2017-07-27T00:48:30.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2025-05-01T18:35:03.000Z (5 months ago)
- Last Synced: 2025-05-13T14:17:17.447Z (5 months ago)
- Topics: geometry, graphics, half-edge, mesh, polygon, rust, topology
- Language: Rust
- Homepage: https://plexus.rs
- Size: 2.07 MB
- Stars: 178
- Watchers: 11
- Forks: 15
- Open Issues: 16
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
![]()
**Plexus** is a highly composable Rust library for polygonal mesh processing.
See [the website][website] for the most recent [API documentation][rustdoc] and
the [user guide][guide].[](https://github.com/olson-sean-k/plexus)
[](https://docs.rs/plexus)
[](https://crates.io/crates/plexus)
[](https://gitter.im/plexus-rs/community)## Primitives
Plexus provides primitive topological structures that can be composed using
generators and iterator expressions. Iterator expressions operate over a
sequence of polygons with arbitrary vertex data. These polygons can be
decomposed, tessellated, indexed, and collected into mesh data structures.```rust
use decorum::R64; // See "Integrations".
use nalgebra::Point3;
use plexus::buffer::MeshBuffer;
use plexus::index::Flat3;
use plexus::prelude::*;
use plexus::primitive::generate::Position;
use plexus::primitive::sphere::UvSphere;use crate::render::pipeline::{Color4, Vertex};
type E3 = Point3;
// Create a buffer of index and vertex data from a uv-sphere.
let buffer: MeshBuffer = UvSphere::new(16, 8)
.polygons::>()
.map_vertices(|position| Vertex::new(position, Color4::white()))
.triangulate()
.collect();
```The above example uses a generator and iterator expression to transform the
positional data of a sphere into a linear buffer for indexed drawing. See [the
sphere example][example-sphere] for a rendered demonstration.## Half-Edge Graphs
The `MeshGraph` type represents polygonal meshes as an ergonomic [half-edge
graph][dcel] that supports arbitrary data in vertices, arcs (half-edges), edges,
and faces. Graphs can be traversed and manipulated in many ways that iterator
expressions and linear buffers cannot.```rust
use plexus::graph::MeshGraph;
use plexus::prelude::*;
use plexus::primitive::Tetragon;
use ultraviolet::vec::Vec3;type E3 = Vec3;
// Create a graph of a tetragon.
let mut graph = MeshGraph::::from(Tetragon::from([
(1.0, 1.0, 0.0),
(-1.0, 1.0, 0.0),
(-1.0, -1.0, 0.0),
(1.0, -1.0, 0.0),
]));
// Extrude the face of the tetragon.
let key = graph.faces().next().unwrap().key();
let face = graph.face_mut(key).unwrap().extrude_with_offset(1.0).unwrap();
```Plexus avoids exposing very basic topological operations like inserting
individual vertices into a graph, because they can easily be done incorrectly.
Instead, graphs are typically manipulated with more abstract operations like
merging and splitting.See [the user guide][guide-graphs] for more details about graphs.
## Geometric Traits
Plexus provides optional traits to support spatial operations by exposing
positional data in vertices. If the data exposed by the `AsPosition` trait
supports these geometric traits, then geometric operations become available in
primitive and mesh data structure APIs.```rust
use glam::Vec3A;
use plexus::geometry::{AsPosition, Vector};
use plexus::graph::GraphData;
use plexus::prelude::*;type E3 = Vec3A;
#[derive(Clone, Copy, PartialEq)]
pub struct Vertex {
pub position: E3,
pub normal: Vector,
}impl GraphData for Vertex {
type Vertex = Self;
type Arc = ();
type Edge = ();
type Face = ();
}impl AsPosition for Vertex {
type Position = E3;fn as_position(&self) -> &Self::Position {
&self.position
}
}
```Data structures like `MeshGraph` also provide functions that allow user code to
compute geometry without requiring any of these traits; the data in these
structures may be arbitrary, including no data at all.## Integrations
Plexus integrates with the [`theon`] crate to provide geometric traits and
support various mathematics crates in the Rust ecosystem. Any mathematics crate
can be used and, if it is supported by Theon, Plexus provides geometric APIs by
enabling Cargo features.| Feature | Default | Crate |
|------------------------|---------|-----------------|
| `geometry-cgmath` | No | [`cgmath`] |
| `geometry-glam` | No | [`glam`] |
| `geometry-mint` | No | [`mint`] |
| `geometry-nalgebra` | No | [`nalgebra`] |
| `geometry-ultraviolet` | No | [`ultraviolet`] |Enabling the corresponding feature is recommended if using one of these
supported crates.Plexus also integrates with the [`decorum`] crate for floating-point
representations that can be hashed for fast indexing. The `R64` type is a
(totally ordered) real number with an `f64` representation that cannot be `NaN`
nor infinity, for example. Geometric conversion traits are implemented for
supported types to allow for implicit conversions of scalar types.## Encodings
Plexus provides support for polygonal mesh encodings. This allows mesh data
structures like `MeshGraph` and `MeshBuffer` to be serialized and deserialized
to and from various formats.```rust
use nalgebra::Point3;
use plexus::encoding::ply::{FromPly, PositionEncoding};
use plexus::graph::MeshGraph;
use plexus::prelude::*;
use std::fs::File;type E3 = Point3;
let ply = File::open("cube.ply").unwrap();
let encoding = PositionEncoding::::default();
let (graph, _) = MeshGraph::::from_ply(encoding, ply).unwrap();
```Encoding support is optional and enabled via Cargo features.
| Feature | Default | Encoding | Read | Write |
|----------------|---------|----------|------|-------|
| `encoding-ply` | No | PLY | Yes | No |See [the teapot example][example-teapot] for a rendered demonstration of reading
a mesh from the file system.[dcel]: https://en.wikipedia.org/wiki/doubly_connected_edge_list
[guide]: https://plexus.rs/user-guide/getting-started
[guide-graphs]: https://plexus.rs/user-guide/graphs
[rustdoc]: https://plexus.rs/rustdoc/plexus
[website]: https://plexus.rs[example-sphere]: https://github.com/olson-sean-k/plexus/tree/master/examples/sphere/src/main.rs
[example-teapot]: https://github.com/olson-sean-k/plexus/tree/master/examples/teapot/src/main.rs[`cgmath`]: https://crates.io/crates/cgmath
[`decorum`]: https://crates.io/crates/decorum
[`glam`]: https://crates.io/crates/glam
[`mint`]: https://crates.io/crates/mint
[`nalgebra`]: https://crates.io/crates/nalgebra
[`theon`]: https://crates.io/crates/theon
[`ultraviolet`]: https://crates.io/crates/ultraviolet