#![allow(
clippy::unwrap_used,
clippy::print_stdout,
clippy::print_stderr,
missing_docs
)]
use brepkit_math::mat::Mat4;
use brepkit_operations::boolean::{BooleanOp, boolean};
use brepkit_operations::measure;
use brepkit_operations::primitives;
use brepkit_operations::transform::transform_solid;
use brepkit_topology::Topology;
fn main() {
let mut topo = Topology::new();
let bx = primitives::make_box(&mut topo, 50.0, 30.0, 10.0).unwrap();
let cyl = primitives::make_cylinder(&mut topo, 5.0, 20.0).unwrap();
let mat = Mat4::translation(25.0, 15.0, -5.0);
transform_solid(&mut topo, cyl, &mat).unwrap();
let box_vol = measure::solid_volume(&topo, bx, 0.1).unwrap();
eprintln!("Box volume: {box_vol}");
let result = boolean(&mut topo, BooleanOp::Cut, bx, cyl).unwrap();
let solid = topo.solid(result).unwrap();
let shell = topo.shell(solid.outer_shell()).unwrap();
eprintln!("Result has {} faces", shell.faces().len());
for (i, &fid) in shell.faces().iter().enumerate() {
let face = topo.face(fid).unwrap();
let surface = face.surface();
let reversed = face.is_reversed();
let inner_count = face.inner_wires().len();
let area = measure::face_area(&topo, fid, 0.1).unwrap_or(0.0);
let surf_type = match surface {
brepkit_topology::face::FaceSurface::Plane { normal, d } => {
format!(
"Plane(n={:.2},{:.2},{:.2} d={:.2})",
normal.x(),
normal.y(),
normal.z(),
d
)
}
brepkit_topology::face::FaceSurface::Nurbs(_) => "Nurbs".to_string(),
brepkit_topology::face::FaceSurface::Cylinder(_) => "Cylinder".to_string(),
brepkit_topology::face::FaceSurface::Cone(_) => "Cone".to_string(),
brepkit_topology::face::FaceSurface::Sphere(_) => "Sphere".to_string(),
brepkit_topology::face::FaceSurface::Torus(_) => "Torus".to_string(),
};
eprintln!(
" Face {i}: {surf_type} reversed={reversed} inner_wires={inner_count} area={area:.2}"
);
}
eprintln!("\nPer-face signed volume (divergence theorem):");
let mut total_sv = 0.0;
for (i, &fid) in shell.faces().iter().enumerate() {
let mesh = brepkit_operations::tessellate::tessellate(&topo, fid, 0.1).unwrap();
let mut face_vol = 0.0;
for tri in mesh.indices.chunks_exact(3) {
let v0 = mesh.positions[tri[0] as usize];
let v1 = mesh.positions[tri[1] as usize];
let v2 = mesh.positions[tri[2] as usize];
let cross = brepkit_math::vec::Vec3::new(
v1.y() * v2.z() - v1.z() * v2.y(),
v1.z() * v2.x() - v1.x() * v2.z(),
v1.x() * v2.y() - v1.y() * v2.x(),
);
let dot = v0.x() * cross.x() + v0.y() * cross.y() + v0.z() * cross.z();
face_vol += dot / 6.0;
}
eprintln!(
" Face {i}: signed_vol = {face_vol:.2} ({} tris)",
mesh.indices.len() / 3
);
total_sv += face_vol;
}
eprintln!("\nTotal signed volume: {total_sv:.2}");
let vol = measure::solid_volume(&topo, result, 0.1).unwrap();
let expected = 50.0 * 30.0 * 10.0 - std::f64::consts::PI * 25.0 * 10.0;
eprintln!("measure volume: {vol:.2}");
eprintln!("Expected volume: {expected:.2}");
eprintln!("Box volume: {box_vol:.2}");
}