solidcraft-smlib: Brep::edge_face_distance, SMLib's own edge/face gap

Binds smlib_brep_edge_face_distance: how far an edge lies from a face's
surface over the surface's own domain, the gap SMLib sizes an edge's
tolerance by.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
jyviko
2026-10-27 22:02:31 -04:00
committed by Irakli Kourtis
parent 9d2abb2ebc
commit 0bee8c2ed2
2 changed files with 29 additions and 2 deletions
+17 -1
View File
@@ -1,4 +1,5 @@
//! `smlib_brep_mass_properties`, `smlib_brep_area` and `smlib_brep_bounds` (the fork's `capi/src/smlib_measure.cpp`), declared by
//! `smlib_brep_mass_properties`, `smlib_brep_area`, `smlib_brep_bounds` and
//! `smlib_brep_edge_face_distance` (the fork's `capi/src/smlib_measure.cpp`), declared by
//! hand. Part of the FFI boundary, like its parent: called only through [`crate::measure`].
#![allow(unsafe_code)]
@@ -14,6 +15,7 @@ unsafe extern "C" {
pub fn smlib_brep_mass_properties(brep: *const RawBrep, relative_accuracy: f64, out: *mut f64) -> i32;
pub fn smlib_brep_area(brep: *const RawBrep, relative_accuracy: f64, out: *mut f64) -> i32;
pub fn smlib_brep_bounds(brep: *const RawBrep, lo: *mut f64, hi: *mut f64) -> i32;
pub fn smlib_brep_edge_face_distance(brep: *const RawBrep, edge: i64, face: i64, out: *mut f64) -> i32;
}
#[cfg(feature = "native")]
@@ -43,6 +45,20 @@ pub fn bounds(b: &Handle) -> Result<([f64; 3], [f64; 3]), i32> {
}
}
#[cfg(feature = "native")]
pub fn edge_face_distance(b: &Handle, edge: i64, face: i64) -> Result<f64, i32> {
let mut d = 0.0;
match unsafe { smlib_brep_edge_face_distance(b.raw(), edge, face, &mut d) } {
OK => Ok(d),
s => Err(s),
}
}
#[cfg(not(feature = "native"))]
pub fn edge_face_distance(_: &Handle, _: i64, _: i64) -> Result<f64, i32> {
Err(NOT_BUILT)
}
#[cfg(not(feature = "native"))]
pub fn bounds(_: &Handle) -> Result<([f64; 3], [f64; 3]), i32> {
Err(NOT_BUILT)
+12 -1
View File
@@ -1,5 +1,5 @@
//! Exact mass properties from SMLib: area, volume, centroid and inertia, integrated on the exact
//! surfaces rather than a tessellation, and the exact box.
//! surfaces rather than a tessellation; the exact box; how far an edge lies from a face's surface.
use crate::{Brep, Result, error, ffi};
@@ -48,6 +48,17 @@ impl Brep {
ffi::measure::bounds(&self.0).map_err(error)
}
/// How far edge `edge` (its curve over its interval) lies from the surface of face `face`,
/// over that surface's own domain and not beyond it, in mm: SMLib's own edge/face gap, the
/// one it sizes an edge's tolerance by. Indices are in the body's edge and face order (as
/// it was imported and is exported). An edge run past its face's patch measures how far it
/// goes; SMLib keeps such an edge whole when making its UV trim only when its zone tolerance
/// (half the flat arrays' `EDGE_TOLERANCE`) covers this.
pub fn edge_face_distance(&self, edge: usize, face: usize) -> Result<f64> {
let (Ok(e), Ok(f)) = (i64::try_from(edge), i64::try_from(face)) else { return Err(error(ffi::ERR_ARG)) };
ffi::measure::edge_face_distance(&self.0, e, f).map_err(error)
}
/// Total area of every face, each counted once, so sheets and open shells too.
pub fn area(&self, relative_accuracy: f64) -> Result<f64> {
ffi::measure::area(&self.0, relative_accuracy).map_err(error)