use super::{accept_cut, mesh_is_closed_exact, mesh_signed_volume, UnionCand};
use crate::{ClippingProcessor, GeometryRouter, Mesh};
pub(super) fn subtract(
result: &mut Mesh,
cands: &[UnionCand],
members: &[usize],
clipper: &ClippingProcessor,
) -> bool {
let extended: Vec<Mesh> = members
.iter()
.map(|&m| {
GeometryRouter::extend_opening_mesh_through_host(&cands[m].mesh, result, cands[m].dir)
})
.collect();
let refs: Vec<&Mesh> = extended.iter().collect();
let mut union =
ClippingProcessor::consolidate_coplanar(crate::kernel::mesh_bridge::union_many(&refs));
if union.is_empty() || !mesh_is_closed_exact(&union) {
if crate::kernel::budget::tripped() {
return false;
}
union = ClippingProcessor::consolidate_coplanar(
crate::kernel::mesh_bridge::union_many_preserving_coordinates(&refs),
);
if union.is_empty() || !mesh_is_closed_exact(&union) {
return false;
}
}
let tri_before = result.triangle_count();
let vol_before = mesh_signed_volume(result);
let Ok(cut) = clipper.subtract_mesh(result, &union) else {
return false;
};
accept_cut(result, cut, tri_before, vol_before, f64::INFINITY)
}