manifold-rust 0.11.0

Pure Rust port of the Manifold 3D geometry library
Documentation
# manifold-rust


[![crates.io](https://img.shields.io/crates/v/manifold-rust.svg)](https://crates.io/crates/manifold-rust)
[![docs.rs](https://docs.rs/manifold-rust/badge.svg)](https://docs.rs/manifold-rust)
[![license](https://img.shields.io/crates/l/manifold-rust.svg)](https://github.com/larsbrubaker/manifold-rust/blob/main/LICENSE)

[![Demo](README_HERO.png)](https://larsbrubaker.github.io/manifold-rust/)

## Support the Project


<a href="https://buymeacoffee.com/larsbrubaker"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" height="50" width="210"></a>

manifold-rust is open-source and free to use, maintained in spare time as a labor of love. Friends James Smith and Dan Ruskin help out from time to time too.

If you find it useful, here are a few ways to help keep development going:

- **Donations:** [Buy Me a Coffee]https://buymeacoffee.com/larsbrubaker — every coffee helps.
- **Star the repo:** Costs nothing and helps others find the project.
- **Report issues:** [Open an issue]https://github.com/larsbrubaker/manifold-rust/issues for bugs or feature ideas.
- **Contribute:** PRs welcome — open an issue first to discuss larger changes.

Pure Rust port of [Manifold](https://github.com/elalish/manifold) — a geometry library for 3D boolean operations on triangle meshes.

> Part of the [rust-apps]https://github.com/larsbrubaker/rust-apps suite — a collection of Rust graphics and geometry libraries by Lars Brubaker.

> **Status: Port complete.** All 18 phases of the C++ engine (v3.5.0) are implemented and
> every C++ test is ported or covered — 630 tests passing, 0 failing (the handful of
> `#[ignore]`d tests are debug-build-speed only and pass in release). Heavy boolean/CSG
> workloads run at parity with the sequential C++ build, and the optional `parallel`
> feature roughly doubles them. See [PORTING_PLAN.md]PORTING_PLAN.md for the full record.
> Beyond the port, the library now also includes a **robust boolean engine** that accepts
> non-manifold input — see [Robust booleans on non-manifold input]#robust-booleans-on-non-manifold-input.

## What is Manifold?


Manifold is a high-performance C++ library for 3D solid modeling. It supports:

- Boolean operations (union, intersection, difference) on triangle meshes
- Mesh constructors (sphere, cube, cylinder, extrude, revolve)
- Cross-section (2D polygon) operations
- Smooth subdivision and SDF-based mesh generation
- Convex hull
- Minkowski sum/difference

This Rust port targets **exact numerical match** with the C++ implementation — same algorithms, same floating-point results, same triangle topology. Exactness is validated by instrumented, boolean-by-boolean trace comparison against a locally built C++ reference (see `validate-reference.ps1`), down to the tie-breaking order of symbolic-perturbation predicates.

Beyond the port, it adds one capability the C++ library does not have: a second, *robust*
boolean engine that accepts closed non-manifold meshes (shared edges/vertices,
disconnected shells, internal voids) — common in real-world scan and Thingiverse
geometry that the strict pipeline rejects. See
[Robust booleans on non-manifold input](#robust-booleans-on-non-manifold-input).

## Why


[MatterHackers](https://www.matterhackers.com) uses 3D mesh boolean operations extensively in production for 3D printing workflows. A pure Rust implementation avoids FFI overhead and integrates cleanly with Rust tooling including WASM compilation.

## Installation


Available on [crates.io](https://crates.io/crates/manifold-rust):

```bash
cargo add manifold-rust
```

API documentation: <https://docs.rs/manifold-rust>

## Usage


```rust
use manifold_rust::manifold::Manifold;
use manifold_rust::linalg::Vec3;

// Constructors
let cube = Manifold::cube(Vec3::new(1.0, 1.0, 1.0), true);
let sphere = Manifold::sphere(0.6, 32);

// Guaranteed-manifold booleans (also available as + - operators)
let difference = cube.difference(&sphere);
assert_eq!(difference.status(), manifold_rust::types::Error::NoError);

// Measure
println!("volume = {}", difference.volume());
println!("area   = {}", difference.surface_area());
println!("genus  = {}", difference.genus());

// Mesh I/O via MeshGL
let mesh = difference.get_mesh_gl(0);
let round_tripped = Manifold::from_mesh_gl(&mesh);
```

Enable parallel execution (results stay bit-identical to the sequential build —
only determinism-preserving sites are parallelized):

```toml
[dependencies]
manifold-rust = { version = "0.11", features = ["parallel"] }
```

### Robust booleans on non-manifold input


Alongside the default exact (C++-matching) pipeline there is a second,
*robust* boolean engine (Barki, Guennebaud, Foufou 2015) built on exact
rational arithmetic. It requires inputs only to be **closed and orientable**:
shared edges/vertices, disconnected shells, and internal voids are all fine.
On manifold inputs it agrees with the exact engine to near-f64 precision
(triangulation may differ), and vertex properties (colors, UVs) carry
through to the result the same way the exact engine's do.

```rust
use manifold_rust::manifold::Manifold;
use manifold_rust::types::{BooleanConfig, BooleanEngine};

// Import geometry the strict path would reject as NotManifold:
let soup = Manifold::from_mesh_gl_robust(&mesh);          // or from_mesh_gl64_robust

// Per-call engine choice…
let cut = soup.difference_with_engine(&cutter, BooleanEngine::Auto);

// …or a process-global default. Auto = exact for manifold pairs,
// robust whenever a non-manifold operand is involved.
BooleanConfig::set_default_engine(BooleanEngine::Auto);
let cut = soup.difference(&cutter);
```

Geometry that is not even closed imports as empty with
`Error::NotClosed`. The default engine remains `Exact`, so existing code is
byte-identical to previous releases.

## Demo


An interactive WASM demo is live at <https://larsbrubaker.github.io/manifold-rust/> —
booleans, extrude/revolve with twist, convex hull, subdivision, a Menger sponge, and more,
all running the Rust engine compiled to WebAssembly.

The Boolean Gallery includes an engine selector (Exact / Robust / Auto) and can load
random mesh pairs from the [Thingi10K](https://github.com/larsbrubaker/Thingi10K)
dataset — manifold or non-manifold — to exercise the robust engine on real-world
geometry. Every operation's inputs (model IDs, transform, engine) are captured behind a
*Copy Debug Info* button so a failing combination can be pasted straight into a bug
report.

## Building


```bash
cargo build
cargo test
```

Restore the upstream C++ reference before doing exact-match validation:

```bash
git submodule update --init --recursive
```

Build and compare against the C++ reference with:

```powershell
./validate-reference.ps1
```

You can also run a narrower validation slice by phase, for example:

```powershell
./validate-reference.ps1 -Phase phase8
```

This configures and builds `cpp-reference/manifold`, runs the matching C++
reference tests, and then runs the corresponding Rust tests for the selected
phase.

For the WASM demo:
```bash
cd demo
bun run build:wasm
bun run dev
```

## Performance


The port is benchmarked against the C++ reference using Rust ports of the
upstream perf drivers, printing identical output lines so runs diff cleanly:

- `cargo run --release --example perf_test` — a sphere-minus-sphere boolean at
  doubling tessellation levels (`extras/perf_test.cpp`)
- `cargo run --release --example large_scene_test -- <n>` — union of an
  n×n×n grid of unit spheres through the CSG tree (`extras/large_scene_test.cpp`)

Representative timings, best of several runs on the same machine (Windows 10,
i7-7660U 2C/4T, 8 GB RAM; both sides sequential: C++ built Release with
`MANIFOLD_PAR=OFF`, Rust default features, MSVC 19.44 / rustc via fat LTO):

| Benchmark | input tris | C++ | Rust |
|---|---|---|---|
| sphere ∖ sphere | 2 048 | 5.2 ms | 5.5 ms |
| sphere ∖ sphere | 32 768 | 48 ms | 43 ms |
| sphere ∖ sphere | 131 072 | 170 ms | 177 ms |
| sphere ∖ sphere | 524 288 | 659 ms | 621 ms |
| sphere ∖ sphere | 2 097 152 | 2.61 s | 2.57 s |
| sphere grid union, n=10 (999 spheres) || 2.29 s | 2.32 s |
| sphere grid union, n=20 (7 999 spheres) || 13.5 s | 14.5 s |

Both implementations produce identical triangle counts on every benchmark (and
the test suite validates bit-exact geometry). The largest perf_test round
(8.4 M input tris) needs several GB of working set and is dominated by paging
on the 8 GB test machine, so its timings are not comparable there. Peak memory
is within ~10 % of C++ (1.47 GB vs 1.34 GB peak working set on the 2 M-tri
round) after slimming the cached collider to the C++ storage layout and
dropping assembly intermediates at the same points the C++ clears them; use
`cargo run --release --example mem_profile` with `MANIFOLD_TIMING=1` to see
per-stage heap use.

Per-stage timing is available on both sides for gap hunting: set the
`MANIFOLD_TIMING` environment variable for the Rust build (stage boundaries
match the C++ `MANIFOLD_TIMING` build's output) — this is how the cached-face-
collider optimization was found, which brought the intersection stage from
2.7× slower than C++ to faster than C++.

An optional `parallel` cargo feature parallelizes determinism-preserving
sites with rayon (results stay bit-identical to the sequential build); see
`PORTING_PLAN.md` for which stages it covers.

## Architecture


The port follows the C++ module structure:

| Rust module | C++ source | Description |
|-------------|-----------|-------------|
| `vec` / `linalg` | `linalg.h`, `vec.h` | Vector math, linear algebra |
| `polygon` | `polygon.cpp` | 2D polygon triangulation |
| `impl` | `impl.cpp`, `impl.h` | Core mesh data structure |
| `constructors` | `constructors.cpp` | Primitive mesh constructors |
| `boolean3` | `boolean3.cpp` | 3D boolean operations |
| `boolean_result` | `boolean_result.cpp` | Boolean output assembly |
| `csg_tree` | `csg_tree.cpp` | CSG tree evaluation |
| `edge_op` | `edge_op.cpp` | Edge manipulation |
| `face_op` | `face_op.cpp` | Face manipulation |
| `smoothing` | `smoothing.cpp` | Smooth normals and subdivision |
| `subdivision` | `subdivision.cpp` | Mesh subdivision |
| `properties` | `properties.cpp` | Mesh properties |
| `sdf` | `sdf.cpp` | SDF-based mesh generation |
| `quickhull` | `quickhull.cpp` | Convex hull |
| `minkowski` | `minkowski.cpp` | Minkowski operations |
| `cross_section` | `cross_section/` | 2D cross section |
| `robust` | — (Rust-only) | Robust boolean engine for non-manifold input (Barki et al. 2015) |

## License


Apache-2.0 — matching the original Manifold library.

## Credits


- **[Emmett Lalish]https://github.com/elalish** — Author of the original Manifold library.
- **[Lars Brubaker]https://github.com/larsbrubaker** — Port author.
- **[MatterHackers]https://www.matterhackers.com** — Sponsor.