#![allow(
clippy::unwrap_used,
clippy::missing_docs_in_private_items,
missing_docs
)]
use std::hint::black_box;
use std::time::Duration;
use criterion::{Criterion, criterion_group, criterion_main};
use brepkit_math::mat::Mat4;
use brepkit_operations::boolean::{BooleanOp, boolean};
use brepkit_operations::primitives::{make_box, make_cylinder};
use brepkit_operations::transform::transform_solid;
use brepkit_topology::Topology;
use brepkit_topology::shell::Shell;
use brepkit_topology::solid::{Solid, SolidId};
fn merge_disjoint(topo: &mut Topology, solids: &[SolidId]) -> SolidId {
let mut faces = Vec::new();
for &s in solids {
let outer = topo.solid(s).unwrap().outer_shell();
faces.extend_from_slice(topo.shell(outer).unwrap().faces());
}
let outer = topo.add_shell(Shell::new(faces).unwrap());
topo.add_solid(Solid::new(outer, vec![]))
}
fn two_boxes(topo: &mut Topology) -> (SolidId, SolidId) {
let a = make_box(topo, 1.0, 1.0, 1.0).unwrap();
let b = make_box(topo, 1.0, 1.0, 1.0).unwrap();
transform_solid(topo, b, &Mat4::translation(0.5, 0.5, 0.5)).unwrap();
(a, b)
}
fn bench_booleans(c: &mut Criterion) {
let mut group = c.benchmark_group("boolean");
group
.sample_size(10)
.warm_up_time(Duration::from_millis(500))
.measurement_time(Duration::from_secs(2));
for (name, op) in [
("cut_box_box", BooleanOp::Cut),
("fuse_box_box", BooleanOp::Fuse),
("intersect_box_box", BooleanOp::Intersect),
] {
group.bench_function(name, |bencher| {
bencher.iter(|| {
let mut topo = Topology::new();
let (a, b) = two_boxes(&mut topo);
black_box(boolean(&mut topo, op, a, b).unwrap())
});
});
}
group.bench_function("cut_cylinder_through_box", |bencher| {
bencher.iter(|| {
let mut topo = Topology::new();
let box_id = make_box(&mut topo, 4.0, 4.0, 2.0).unwrap();
let cyl = make_cylinder(&mut topo, 1.0, 6.0).unwrap();
transform_solid(&mut topo, cyl, &Mat4::translation(2.0, 2.0, -2.0)).unwrap();
black_box(boolean(&mut topo, BooleanOp::Cut, box_id, cyl).unwrap())
});
});
group.bench_function("perforated_cut_36", |bencher| {
bencher.iter(|| {
let mut topo = Topology::new();
let pitch = 2.4;
let span = 7.0 * pitch;
let slab = make_box(&mut topo, span, span, 2.0).unwrap();
transform_solid(&mut topo, slab, &Mat4::translation(0.0, 0.0, 1.0)).unwrap();
let mut tools = Vec::new();
for j in 0..6 {
for i in 0..6 {
let h = make_box(&mut topo, 1.0, 1.0, 4.0).unwrap();
let m = Mat4::translation((i + 1) as f64 * pitch, (j + 1) as f64 * pitch, 0.0);
transform_solid(&mut topo, h, &m).unwrap();
tools.push(h);
}
}
let tool = merge_disjoint(&mut topo, &tools);
black_box(boolean(&mut topo, BooleanOp::Cut, slab, tool).unwrap())
});
});
group.finish();
}
criterion_group!(benches, bench_booleans);
criterion_main!(benches);