halfedge
English | 中文
A half-edge mesh data structure library for Rust, providing comprehensive tools for 3D mesh processing: traversal, topology operations, geometry, subdivision, decimation, parameterization, geodesics, deformation, boolean operations, and more.
Features
- Half-edge data structure with slotmap-based stable handles (
VertexId/HalfEdgeId/FaceId/EdgeId) - Traversal: eager & lazy iterators (zero-allocation), boundary loops, k-ring neighborhoods, undirected edges
- Query DSL: chainable builder (
v.halfedge_to(w).cw_rotated().dst_vert().run(&mesh)) - Topology operations: edge split / flip / collapse / extrude / poke,
add_trianglebuilder - Geometry: edge lengths, face areas/normals, cotan Laplacian, curvatures (Gaussian / mean / principal), dihedral angles, point-triangle distance, AABB, ray-mesh intersection
- Subdivision: Loop, Catmull-Clark, sqrt(3)
- Decimation: QEM (Quadric Error Metric) simplification with robust degenerate detection
- Parameterization: Tutte embedding, harmonic (cotan), LSCM, MVC (Mean Value Coordinates)
- Geodesics: Heat Method (Crane et al. 2013), Dijkstra single/multi-source, shortest path backtracking
- Deformation: Laplacian surface editing (Sorkine 2004), ARAP (Sorkine & Alexa 2007)
- Conformal mapping: harmonic map, Mobius transform, discrete conformal scale factors
- Boolean operations: union / intersection / difference / symmetric difference
- Remeshing: isotropic remeshing
- Triangulation: ear-clipping & fan triangulation (planar / 3D)
- Weld: vertex welding by distance threshold
- Primitives: cube / UV-sphere / cylinder / cone / grid / torus builders
- I/O: OBJ (n-gon), PLY (ASCII + binary), STL (ASCII & binary), OFF, glTF/GLB load/save; unified
load_mesh/save_meshentry points - Property system: OpenMesh-style dynamic properties (
Any + TypeIdtype erasure);Vec<Option<T>>backing for O(1) access - Builtin attributes: newtype wrappers for vertex normal / UV / color / face normal
- MeshCache: lazy caching layer for computed attributes (face normal/area, vertex normal/valence, edge length)
- Validation: full topology self-check (twin / next / manifold / degeneracy)
- Connectivity: connected components (face / vertex BFS), merge / split
- Orientation: consistency detection & repair
- BVH: bounding volume hierarchy (AABB tree) for ray / nearest query
- Sparse linear algebra: symmetric system builder + conjugate gradient with Jacobi preconditioner
- Intrinsic Delaunay: intrinsic edge flips for Delaunay triangulation (Fisher 2007)
- Direction fields: N-RoSy fields via covariant Laplacian eigenvalue (Knoppel 2013)
- SDF & Marching Cubes: signed distance functions + isosurface extraction (Lorensen 1987)
- Mesh repair: hole filling, degenerate face removal, isolated vertex cleanup
- Robust predicates: Shewchuk
orient2d/orient3d/incircle/insphere(adaptive precision) - Serde support: feature-gated
Serialize/DeserializeforMeshStorageand handles - Parallelism: rayon-based parallel iterators across geometry, remeshing, decimation, boolean, geodesics, parameterization, and deformation
Scalartype alias: configurable floating-point type (f64default) for future generic support
Quick start
[]
= "0.1"
use ;
use add_triangle;
let mut mesh = new;
let v0 = mesh.add_vertex;
let v1 = mesh.add_vertex;
let v2 = mesh.add_vertex;
add_triangle.unwrap;
Optional features
serde: EnableSerialize/DeserializeforMeshStorage,Vertex,HalfEdge,Face, andEdgeId. Add toCargo.toml:
[]
= { = "0.1", = ["serde"] }
Module overview
| Module | Description |
|---|---|
ids |
Strong-type handles (VertexId / HalfEdgeId / FaceId / EdgeId) |
storage |
MeshStorage container (slotmap-backed stable handles) |
traversal |
Eager/lazy neighborhood iterators, boundary loops, k-ring, undirected edges |
query |
Chainable query DSL (Builder pattern) |
topology_ops |
split / flip / collapse / extrude / poke, add_triangle builder |
geometry |
Lengths, areas, normals, cotan Laplacian, curvatures, AABB, ray intersection |
subdiv |
Loop / Catmull-Clark / sqrt(3) |
decimate |
QEM (Quadric Error Metric) simplification with robust degenerate detection |
parameterization |
Tutte / Harmonic / LSCM / MVC |
geodesics |
Heat Method / Dijkstra (single & multi-source) / shortest path |
deformation |
Laplacian surface editing / ARAP |
conformal |
Harmonic map, Mobius transform, discrete conformal scale factors |
boolean |
Union / intersection / difference / symmetric difference |
remesh |
Isotropic remeshing |
triangulation |
Ear-clipping & fan triangulation (planar / 3D) |
weld |
Vertex welding by distance threshold |
connectivity |
Connected components (face / vertex BFS), merge / split |
orientation |
Face orientation consistency detection & repair |
bvh |
Bounding volume hierarchy (AABB tree) for ray / nearest query |
primitives |
Cube / sphere / cylinder / cone / grid / torus builders |
io |
OBJ / PLY (ASCII + binary) / STL (ASCII & binary) / OFF / glTF/GLB load/save |
export |
wgpu-compatible vertex / index buffers |
property |
OpenMesh-style dynamic properties (Any + TypeId type erasure) |
builtin_attrs |
Newtype wrappers for vertex normal / UV / color / face normal |
cache |
Lazy caching layer for computed attributes (face normal/area, vertex normal/valence, edge length) |
validate |
Topology self-check (twin / next / manifold / degeneracy) |
linalg |
Sparse linear algebra (symmetric system + conjugate gradient with Jacobi preconditioner) |
intrinsic |
Intrinsic Delaunay triangulation (edge flips) |
direction_field |
N-RoSy direction fields (covariant Laplacian eigenvalue) |
sdf |
SDF primitives, CSG operations, Marching Cubes |
repair |
Hole filling, degenerate face removal, isolated vertex cleanup |
predicates |
Shewchuk robust geometric predicates (orient2d / orient3d / incircle / insphere) |
test_util |
Test fixtures (build_icosphere) |
Examples
The examples/ directory contains 15 standalone runnable examples. 14 produce text output via println!; the 15th is a GPU-accelerated interactive 3D viewer.
| Example | Module | Run |
|---|---|---|
storage_basic |
storage |
cargo run --example storage_basic |
build_mesh |
io |
cargo run --example build_mesh |
obj_io |
io |
cargo run --example obj_io |
traversal |
traversal |
cargo run --example traversal |
topology_ops |
topology_ops |
cargo run --example topology_ops |
extrude_face |
topology_ops |
cargo run --example extrude_face |
geometry_query |
geometry |
cargo run --example geometry_query |
laplacian_smooth |
geometry |
cargo run --example laplacian_smooth |
point_triangle_distance |
geometry |
cargo run --example point_triangle_distance |
loop_subdivision |
subdiv |
cargo run --example loop_subdivision |
property |
property |
cargo run --example property |
validate |
validate |
cargo run --example validate |
export_wgpu |
export |
cargo run --example export_wgpu |
icosphere |
test_util |
cargo run --example icosphere |
engvis_viewer |
visualization | cargo run --example engvis_viewer |
Interactive 3D viewer
engvis_viewer uses engvis-renderer (wgpu 27 / egui 0.33 / winit 0.30) to render halfedge mesh operations in real time. It is declared as a dev-dependency and does not affect the published library.
The right-side UI panel switches between 5 operations and their parameters at runtime; no restart required.
Design
- Strong typing: all handles are slotmap keys with compile-time distinction
- Eager & lazy iterators: pre-collected
Vecversions (allow&mut meshduring iteration) and lazy versions (zero heap allocation, hold&MeshStorageborrow) - Robust degeneracy guards: all panic paths covered (empty collections, zero-length, division by zero, index out of bounds,
unwrap) - Symmetric sparse system builder:
SparseSystem::addwrites both(i,j)and(j,i)for symmetric matrices Scalartype alias: configurable floating-point type (f64default) for future generic support- Lazy caching:
MeshCacheavoids redundant recomputation of normals, areas, and valences - 662 unit tests covering all modules
Benchmarks
Criterion benchmarks are included for performance-critical operations:
| Benchmark | Measures |
|---|---|
traversal |
Vertex/face/edge iteration, boundary loops, k-ring |
topology_ops |
Edge split, flip, collapse, extrude |
subdiv |
Loop, Catmull-Clark, sqrt(3) subdivision |
geometry_algs |
Normals, areas, curvatures, ray intersection |
Run all benchmarks:
Results are written to target/criterion/report/index.html.
Documentation
Each module has a companion LaTeX design document in docs/ (compiled to PDF) with algorithm derivations, TikZ flowcharts, and complexity analysis.
A Chinese tutorial website built with mdbook is in book/. Build it locally:
API documentation: https://docs.rs/halfedge
Known issues
block v0.1.6future-incompat warning: When building with theviewerfeature (which pulls inwgpu/engvis), Cargo prints a future-incompatibility warning for the transitiveblockcrate. This originates in upstream dependencies and does not affect the default build (no features). It will be resolved when those dependencies publish a fix; no action is required here.
Roadmap
halfedge is usable today, but some capabilities that distinguish it from industrial-grade libraries (notably CGAL) are still planned. Items are grouped by priority.
P1 — correctness & API maturity (planned)
- Exact arithmetic kernel: replace plain
f64with adaptive exact predicates (à la CGALEPEC) for construction operations, eliminating numerical risk on near-degenerate geometry. - Non-manifold support: the data structure currently enforces a 2-manifold. Support non-manifold edges/vertices (T-junctions, self-intersections) behind a feature flag.
- API stability markers: annotate public items with stability tiers
(
stable/unstable/experimental) and publish a 1.0 compatibility plan.
P2 — performance & platform reach (planned)
- SOA storage: separate position / connectivity arrays for better cache locality on large meshes.
wasm32-unknown-unknownvalidation: the library builds forwasm32-unknown-unknown(verified;rayonfalls back to serial). Browser runtime integration is not yet exercised by CI.- Dependency stabilization: track
sprstoward a 1.0 release, or vendor a minimal sparse solver to drop the dependency.
P3 — ecosystem & reach (ongoing)
- Grow the maintainer base beyond a single author.
- Translate design docs and the mdbook tutorial to English.
- Publish benchmark comparisons against other mesh libraries.
Contributions to any of these are very welcome — see CONTRIBUTING.md.
License
Dual-licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT License (LICENSE-MIT)
at your option.
Contributing
Contributions are welcome! Please read CONTRIBUTING.md for development setup, code conventions, and the pull request workflow.
This project follows the Contributor Covenant Code of Conduct.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.