BREP_kernel 0.2.0

A boundary representation (BREP) geometry kernel for building CAD applications.
Documentation
use brep_kernel::{
    boolean_operation, make_box, make_box_brep, make_cylinder, make_cylinder_brep,
    mesh_to_faceted_brep, tessellate_brep_watertight, BooleanOperation, BooleanOptions, Vec3,
};
use criterion::{black_box, criterion_group, criterion_main, Criterion};

fn benchmark(c: &mut Criterion) {
    c.bench_function("rust/box-mesh", |b| {
        b.iter(|| black_box(make_box(10.0, 8.0, 6.0)))
    });
    c.bench_function("rust/cylinder-mesh-128", |b| {
        b.iter(|| black_box(make_cylinder(5.0, 10.0, 128)))
    });

    // Boolean fragment/assemble hot path: two overlapping boxes through all
    // three ops, plus a curved block - cylinder subtract. Exercises
    // fragment_solid / fragment_face, boolean assemble, and sew.
    let box_a = make_box_brep(Vec3::new(0.0, 0.0, 0.0), 4.0, 4.0, 4.0).unwrap();
    let box_b = make_box_brep(Vec3::new(2.0, 1.0, 1.0), 4.0, 4.0, 4.0).unwrap();
    let block = make_box_brep(Vec3::new(-5.0, -5.0, -5.0), 10.0, 10.0, 10.0).unwrap();
    let drill = make_cylinder_brep(
        Vec3::new(0.0, 0.0, -6.0),
        Vec3::new(0.0, 0.0, 1.0),
        3.0,
        12.0,
    )
    .unwrap();
    let opts = BooleanOptions::default();
    c.bench_function("bench_boolean_phases", |b| {
        b.iter(|| {
            let u = boolean_operation(&box_a, &box_b, BooleanOperation::Union, &opts).unwrap();
            let i = boolean_operation(&box_a, &box_b, BooleanOperation::Intersect, &opts).unwrap();
            let s = boolean_operation(&box_a, &box_b, BooleanOperation::Subtract, &opts).unwrap();
            let d = boolean_operation(&block, &drill, BooleanOperation::Subtract, &opts).unwrap();
            black_box((u.edges.len(), i.edges.len(), s.edges.len(), d.edges.len()))
        })
    });

    // Watertight tessellation O(E*V) stress: a faceted BREP with many
    // topology edges/vertices, re-tessellated as if on every display refresh.
    // This is the site that ran vertices.iter().find(id==) ~2x per edge.
    let cyl_mesh = make_cylinder(5.0, 10.0, 96);
    let faceted = mesh_to_faceted_brep(&cyl_mesh.positions, Some(&cyl_mesh.indices), 1e-6).unwrap();
    c.bench_function("watertight_tess_manyedge", |b| {
        b.iter(|| black_box(tessellate_brep_watertight(&faceted, 0.05).unwrap()))
    });
}

criterion_group!(benches, benchmark);
criterion_main!(benches);