| Crates.io | mcubes |
| lib.rs | mcubes |
| version | 0.1.5 |
| created_at | 2025-06-05 01:48:21.362+00 |
| updated_at | 2025-09-01 20:04:35.197403+00 |
| description | The Marching Cubes algorithm for creating isosurfaces |
| homepage | |
| repository | https://github.com/David-OConnor/mcubes |
| max_upload_size | |
| id | 1701012 |
| size | 4,409,495 |
Uses the Marching Cubes algorithm to create isosurfaces in Rust or Python, from volume data. Designed to be easy to integrate in applications.

Based loosely on PyMarchingCubes.
Outputs a native Mesh, which contains native Vertexs. In practice, you will convert these to whatever
mesh struct your application uses. For example, graphics::Mesh.
Uses lin-alg for its Vec3 type; this is the library's only dependency.

Used by the Daedalus molecule viewer to view experimentally-derived electron density from protein crystals.
The grid must be regularly spaced, along 3 orthogonal axes. Values are either a Vec<f32>, or points which impl
mcubes::GridPoint. This trait contains a single method: To get the value at that point.
Example creating a solvent-accessible-surface mesh by setting the ISO level to 0, and
rendering only the vertices.

Example use:
use mcubes::{GridPoint, MarchingCubes, MeshSide};
/// An example data struct from your application. If you use something like this
/// to represent a point, you may with to use the `from_gridpoints` constructor.
pub struct ElectronDensity {
pub coords: Vec3,
pub density: f64,
}
impl GridPoint for ElectronDensity {
fn value(&self) -> f64 { self.density }
}
fn create_mesh(hdr: &MapHeader, density: &[ElectronDensity], iso_level: f32) {
let mc = MarchingCubes::from_gridpoints(
// Number of grid points along each axis
(hdr.nx as usize, hdr.ny as usize, hdr.nz as usize),
// Grid dimensions per unit cell along each axis
(hdr.cell[0], hdr.cell[1], hdr.cell[2]),
// Sampling interval along each axis. (Usually the same as grid point number of grid points.)
(hdr.mx as f32, hdr.my as f32, hdr.mz as f32),
density,
// The value to draw the isosurface at.
iso_level,
);
// If you are using a `Vec<f32` for data instead if `GridPoint`, use this constructor:
let mc = MarchingCubes::new(
(hdr.nx as usize, hdr.ny as usize, hdr.nz as usize),
(hdr.cell[0], hdr.cell[1], hdr.cell[2]),
(hdr.mx as f32, hdr.my as f32, hdr.mz as f32),
values, // Vec<f32>
iso_level,
);
// Use MeshSide::Inside or MeshSide::Outside as required.
let mesh = mc.generate(MeshSide::Both);
// Example of converting the generic output mesh to a graphic engine's:
let vertices = mesh
.vertices
.iter()
.map(|v| graphics::Vertex::new(v.posit.to_arr(), v.normal))
.collect();
scene.meshes[MESH_DENSITY_SURFACE] = graphics::Mesh {
vertices,
indices: mesh.indices,
material: 0,
};
}
Why another Marching Cubes library? I couldn't figure out how to use the existing ones.