kernel: an operand SMLib's check refuses goes through SMLib's healer

Truck's bodies are trusted into SMLib as given, but some miss SMLib's rules by a little (an
edge's vertex 4.4e-5 mm off it against a tolerance of 3.3e-5 after a truck operation), and
every boolean on them was refused by the check of its result. An operand whose trusted import
fails SMLib's check is imported again through SMLib's healer, and the healed body is used only
where SMLib then finds it valid; its numbering is checked against the record as before, so a
heal that renumbers leaves the result without history rather than with a wrong one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QWhMwdqJYQKQq8RCLSL1LT
This commit is contained in:
jyviko
2026-10-21 06:05:55 -04:00
parent e35b4d744e
commit 00e43aacce
+19 -4
View File
@@ -174,13 +174,28 @@ pub(crate) fn body_from_smlib_ordered(brep: &solidcraft_smlib::Brep) -> Result<(
})
}
/// `body` in SMLib ([`smlib_body`]), with where each of SMLib's faces and edges is in the body's
/// face and edge order: SMLib's export of the imported body, checked to number every face,
/// edge and vertex as the body's record does. `None` where it does not.
/// `body` in SMLib ([`smlib_body`], healed where SMLib's check refuses it as given), with where
/// each of SMLib's faces and edges is in the body's face and edge order: SMLib's export of the
/// imported body, checked to number every face, edge and vertex as the body's record does.
/// `None` where it does not.
#[cfg(feature = "smlib")]
pub(crate) fn smlib_body_ordered(body: &Body) -> Result<(solidcraft_smlib::Brep, Option<solidcraft_smlib::history::Order>)> {
use solidcraft_smlib::{Brep, CheckLevel};
let record = brep_record(body)?;
let brep = solidcraft_smlib::Brep::from_record(&record, true).map_err(|e| KernelError::Failed(format!("SMLib: {e}")))?;
let import = |trusted: bool| Brep::from_record(&record, trusted).map_err(|e| KernelError::Failed(format!("SMLib: {e}")));
let valid = |b: &Brep| b.check(CheckLevel::All).is_ok_and(|c| c.is_valid());
// A record SMLib's check refuses as given (a gap a little over the record's tolerance, a
// hole listed before its face's outer loop) goes through SMLib's healer; healed, it is kept
// only where SMLib then finds it valid.
let trusted = import(true)?;
let brep = if valid(&trusted) {
trusted
} else {
match import(false) {
Ok(healed) if valid(&healed) => healed,
_ => trusted,
}
};
let order = match brep.to_native_ordered() {
Ok((back, order)) => same_numbering(&record, &back).then_some(order),
Err(e) => {