diff --git a/crates/smlib/src/ffi/trim.rs b/crates/smlib/src/ffi/trim.rs index f72439d9d6..a4fca195a0 100644 --- a/crates/smlib/src/ffi/trim.rs +++ b/crates/smlib/src/ffi/trim.rs @@ -1,6 +1,6 @@ //! The untrim and extend blocks of `capi/include/smlib.h` (`smlib_untrim_face`, -//! `smlib_extend_sheet`; the fork's `capi/src/smlib_untrim.cpp` and `smlib_extend.cpp`), declared -//! by hand. Part of the FFI boundary, like its parent: called only through [`crate::trim`]. +//! `smlib_extend_sheet`; the fork's `capi/src/smlib_untrim.cpp` and `smlib_extend.cpp`) and +//! `smlib_face_points` (`smlib_imprint.cpp`, the pieces a trim chooses from), declared by hand. Part of the FFI boundary, like its parent: called only through [`crate::trim`]. #![allow(unsafe_code)] @@ -29,6 +29,7 @@ unsafe extern "C" { in_place: i32, out: *mut *mut RawBrep, ) -> i32; + fn smlib_face_points(body: *const RawBrep, out: *mut f64, n_faces: i64) -> i32; fn smlib_extend_sheet(sheet: *const RawBrep, point: *const f64, tol: f64, distance: f64, mode: i32, out: *mut *mut RawBrep) -> i32; } @@ -56,3 +57,16 @@ pub fn untrim_face(body: &Handle, point: &[f64; 3], tol: f64, holes: Option<&[[f pub fn untrim_face(_: &Handle, _: &[f64; 3], _: f64, _: Option<&[[f64; 3]]>, _: bool, _: bool) -> Result { Err(NOT_BUILT) } + +#[cfg(feature = "native")] +pub fn face_points(body: &Handle, n_faces: usize) -> Result, i32> { + let n = i64::try_from(n_faces).map_err(|_| super::ERR_ARG)?; + let mut out = vec![[0.0f64; 3]; n_faces]; + let s = unsafe { smlib_face_points(body.raw(), out.as_mut_ptr().cast::(), n) }; + if s == super::OK { Ok(out) } else { Err(s) } +} + +#[cfg(not(feature = "native"))] +pub fn face_points(_: &Handle, _: usize) -> Result, i32> { + Err(NOT_BUILT) +} diff --git a/crates/smlib/src/trim.rs b/crates/smlib/src/trim.rs index 4ca3571c39..4c9948d967 100644 --- a/crates/smlib/src/trim.rs +++ b/crates/smlib/src/trim.rs @@ -56,4 +56,12 @@ impl Brep { s => error(s), }) } + + /// A point inside each face, in SMLib's face order: on the face's surface, inside its trims + /// (`SmFace::CalculateAnInternalPoint`). + pub fn face_points(&self) -> Result> { + init()?; + let [faces, _, _] = self.counts()?; + ffi::trim::face_points(&self.0, faces).map_err(error) + } }