solidcraft-smlib: mass properties of any body, by its material regions (fork 311946c)

SMLib's mass properties no longer refuse bodies that are not one manifold
solid: several lumps and lumps touching along edges or points are the sum
over their material regions, and a sheet is its faces' area and centre with
volume 0. Docs of Brep::mass_properties and kernel::measure say so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017itGh5fpMEousnZ91cYcVt
This commit is contained in:
jyviko
2026-10-22 08:14:27 -04:00
parent 78937d1dbc
commit afce22bb60
3 changed files with 9 additions and 7 deletions
+4 -3
View File
@@ -48,9 +48,10 @@ pub struct MassMeasure {
/// dRelativeAccuracy".
const ACCURACY: f64 = 1e-4;
/// Measure a body. A solid body's volume, area and centre are SMLib's, integrated on its exact
/// surfaces, and its box is SMLib's exact box; a body SMLib cannot measure is an error. A mesh
/// body is measured from its triangles, exactly.
/// Measure a body. A B-rep body's volume, area and centre are SMLib's, integrated on its exact
/// surfaces over its material regions (a sheet's: its faces' area and their centre, volume 0),
/// and its box is SMLib's exact box; a body SMLib cannot measure is an error. A mesh body is
/// measured from its triangles, exactly.
pub fn measure(b: &Body) -> Result<BodyMeasure> {
if let Some((pos, tris)) = b.triangle_mesh() {
// Exact for a mesh body; topology counts are facets, sides and vertices.
+1 -1
View File
@@ -1 +1 @@
964474aef3baeaca3a1291182eb912297265b3e9
311946c25118c9443e33c6dfac16ed1b778156e1
+4 -3
View File
@@ -7,7 +7,7 @@ use crate::{Brep, Result, error, ffi};
/// finest SMLib allows. Analytic primitives then come out within 2e-7 of their closed forms.
pub const MEASURE_ACCURACY: f64 = 1e-8;
/// Mass properties of a closed solid at unit density (mm, mm², mm³, mm⁵). For a density ρ the
/// Mass properties of a body at unit density (mm, mm², mm³, mm⁵). For a density ρ the
/// mass is ρ·`volume` and the inertia scales by ρ.
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct MassProperties {
@@ -33,8 +33,9 @@ impl MassProperties {
impl Brep {
/// Mass properties at `relative_accuracy` (clamped to [1e-8, 1e-1]; [`MEASURE_ACCURACY`] is
/// the finest). A body that is not a closed manifold solid is an error; [`Brep::area`]
/// measures those.
/// the finest): the sum over the body's material regions, so several lumps, or lumps
/// touching along edges or at points, measure too. A body with no material (a sheet, an open
/// shell) has volume 0 and no inertia, its faces' area and the centroid of that area.
pub fn mass_properties(&self, relative_accuracy: f64) -> Result<MassProperties> {
let m = ffi::measure::mass_properties(&self.0, relative_accuracy).map_err(error)?;
let [area, volume, cx, cy, cz, ixx, iyy, izz, iyz, izx, ixy] = m;