Crate polyhedral_mass_properties

Source
Expand description

Calculates the mass properties (mass, center of mass and inertia matrix/tensor) of triangle meshes.

The algorithm is based on the paper “Computing the Moment of Inertia of a Solid Defined by a Triangle Mesh” by Michael Kallay (Code).

§How it works

Each triangle in the mesh has its own contribution (TriangleContrib) to the mass properties of the whole mesh. These contributions can be calculated independently and then summed up (O(N) where N is the number of triangles in the mesh).

The sum can then be converted to the actual mass properties (MassProperties) with MassProperties::from_contrib_sum (O(1)).

§Examples

With vertices: &[[f64; 3]] and indices: &[usize]:

let contribution_sum = indices
    .chunks_exact(3)
    .map(|indices| {
        TriangleContrib::new(
            vertices[indices[0]],
            vertices[indices[1]],
            vertices[indices[2]],
        )
    })
    .sum();
let mass_properties = MassProperties::from_contrib_sum(contribution_sum);

§Iterator

If indices is an iterator over usize with a known length (e.g. implements ExactSizeIterator), you can do the following without needing to collect the indices first:

let contribution_sum = (0..indices.len() / 3)
    .map(|_| {
        TriangleContrib::new(
            vertices[indices.next().unwrap()],
            vertices[indices.next().unwrap()],
            vertices[indices.next().unwrap()],
        )
    })
    .sum();
let mass_properties = MassProperties::from_contrib_sum(contribution_sum);

§Multi-threading with Rayon

Calculating the mass properties can be easily multi-threaded by using Rayon.

use rayon::prelude::*;

let contribution_sum = indices
    .par_chunks_exact(3) // par_chunks_exact instead of chunks_exact
    .map(|indices| {
        TriangleContrib::new(
            vertices[indices[0]],
            vertices[indices[1]],
            vertices[indices[2]],
        )
    })
    .sum();
let mass_properties = MassProperties::from_contrib_sum(contribution_sum);
Multi-threading has some overhead and can even be slower for small meshes, especially if you can iterate over the indices instead of collecting them first for Rayon. Benchmark the multi-threaded version for your use case first before using it.

§Feature flags

  • std: Enable the usage of the standard library. Enabled by fma and gltf.
  • fma: Use FMA instructions for better performance. Needs to be compiled with RUSTFLAGS="-C target-cpu=native".
  • serde: Implement the Serialize and Deserialize traits for Inertia and MassProperties.
  • gltf: Enable calculating the mass properties for gltf/glb files using [MassProperties::from_gltf].

Structs§

Inertia
Entries of the inertia matrix/tensor.
MassProperties
The calculated mass properties.
TriangleContrib
The contribution of one triangle in the mesh to the mass properties of the whole mesh.