use chijin::Shape;
use glam::DVec3;
fn dvec3(x: f64, y: f64, z: f64) -> DVec3 {
DVec3::new(x, y, z)
}
fn test_box() -> Shape {
Shape::box_from_corners(dvec3(0.0, 0.0, 0.0), dvec3(10.0, 10.0, 10.0))
}
fn test_box_2() -> Shape {
Shape::box_from_corners(dvec3(5.0, 5.0, 5.0), dvec3(15.0, 15.0, 15.0))
}
fn test_box_3() -> Shape {
Shape::box_from_corners(dvec3(3.0, 3.0, 3.0), dvec3(8.0, 8.0, 8.0))
}
fn shape_to_brep_bytes(shape: &Shape) -> Vec<u8> {
let mut buf = Vec::new();
shape.write_brep_bin(&mut buf).unwrap();
buf
}
#[test]
fn test_t01_union_drop_result_first() {
let a = test_box();
let b = test_box_2();
let result = a.union(&b).unwrap();
drop(result);
drop(a);
drop(b);
}
#[test]
fn test_t01_union_drop_result_last() {
let a = test_box();
let b = test_box_2();
let result = a.union(&b).unwrap();
drop(a);
drop(b);
drop(result);
}
#[test]
fn test_t01_subtract_drop_order() {
let a = test_box();
let b = test_box_2();
let result = a.subtract(&b).unwrap();
drop(a);
drop(b);
drop(result);
}
#[test]
fn test_t01_intersect_drop_order() {
let a = test_box();
let b = test_box_2();
let result = a.intersect(&b).unwrap();
drop(a);
drop(b);
drop(result);
}
#[test]
fn test_t01_chained_boolean_drops() {
let a = test_box();
let b = test_box_2();
let c = test_box_3();
let r1 = a.union(&b).unwrap();
let r2 = r1.shape.subtract(&c).unwrap();
drop(r1);
drop(r2);
drop(a);
drop(b);
drop(c);
}
#[test]
fn test_t02_multiple_reads_no_crash() {
let original = test_box();
let brep_data = shape_to_brep_bytes(&original);
for _ in 0..5 {
let _shape = Shape::read_brep_bin(&mut brep_data.as_slice()).unwrap();
}
}
#[test]
fn test_t03_mesh_normals_count() {
let shape = test_box();
let mesh = shape.mesh_with_tolerance(0.1).unwrap();
assert_eq!(mesh.normals.len(), mesh.vertices.len());
}
#[test]
fn test_t04_approximation_tolerance() {
let cyl = Shape::cylinder(dvec3(0.0, 0.0, 0.0), 10.0, dvec3(0.0, 0.0, 1.0), 20.0);
let mut has_difference = false;
for edge in cyl.edges() {
let coarse = edge.approximation_segments(1.0).count();
let fine = edge.approximation_segments(0.01).count();
if fine > coarse {
has_difference = true;
}
}
assert!(
has_difference,
"Fine tolerance should produce more points than coarse"
);
}
#[test]
fn test_t05_translated_compound() {
let a = test_box();
let b = test_box_2();
let compound: Shape = a.union(&b).unwrap().into();
let v = dvec3(100.0, 0.0, 0.0);
let shifted = compound.translated(v);
let orig_mesh = compound.mesh_with_tolerance(0.1).unwrap();
let shifted_mesh = shifted.mesh_with_tolerance(0.1).unwrap();
assert_eq!(orig_mesh.vertices.len(), shifted_mesh.vertices.len());
for (o, s) in orig_mesh.vertices.iter().zip(shifted_mesh.vertices.iter()) {
assert!((s.x - o.x - v.x).abs() < 1e-6);
assert!((s.y - o.y - v.y).abs() < 1e-6);
assert!((s.z - o.z - v.z).abs() < 1e-6);
}
}
#[test]
fn test_t06_brep_roundtrip() {
let original = test_box();
let orig_mesh = original.mesh_with_tolerance(0.1).unwrap();
let brep_data = shape_to_brep_bytes(&original);
let restored = Shape::read_brep_bin(&mut brep_data.as_slice()).unwrap();
let rest_mesh = restored.mesh_with_tolerance(0.1).unwrap();
assert_eq!(orig_mesh.vertices.len(), rest_mesh.vertices.len());
for (o, r) in orig_mesh.vertices.iter().zip(rest_mesh.vertices.iter()) {
assert!((o.x - r.x).abs() < 1e-10);
assert!((o.y - r.y).abs() < 1e-10);
assert!((o.z - r.z).abs() < 1e-10);
}
}
#[test]
fn test_t07_stream_api_only() {
let shape = test_box();
let data = shape_to_brep_bytes(&shape);
assert!(!data.is_empty());
let _restored = Shape::read_brep_bin(&mut data.as_slice()).unwrap();
}
#[test]
fn test_t08_boolean_returns_shape() {
let a = test_box();
let b = test_box_2();
let _union: Shape = a.union(&b).unwrap().into();
let _sub: Shape = a.subtract(&b).unwrap().into();
let _inter: Shape = a.intersect(&b).unwrap().into();
}
#[test]
fn test_hollow_cube_write_step() {
let outer = Shape::box_from_corners(dvec3(-10.0, -10.0, -10.0), dvec3(10.0, 10.0, 10.0));
let inner = Shape::box_from_corners(dvec3(-5.0, -5.0, -5.0), dvec3(5.0, 5.0, 5.0));
let hollow_cube: Shape = outer.subtract(&inner).unwrap().into();
std::fs::create_dir_all("out").unwrap();
let mut file = std::fs::File::create("out/hollow_cube.step").unwrap();
hollow_cube.write_step(&mut file).unwrap();
}
#[test]
fn test_empty_shape() {
let empty = Shape::empty();
assert!(!empty.is_null());
}
#[test]
fn test_deep_copy() {
let original = test_box();
let copy = original.deep_copy();
drop(original);
assert!((copy.volume() - 1000.0).abs() < 1e-6);
}
#[test]
fn test_edge_iteration() {
let shape = test_box();
assert!((shape.volume() - 1000.0).abs() < 1e-6);
}
#[test]
fn test_half_space_intersect() {
let shape = test_box();
let half = Shape::half_space(dvec3(5.0, 0.0, 0.0), dvec3(1.0, 0.0, 0.0));
let result = shape.intersect(&half).unwrap();
assert!(!result.shape.is_null());
}
#[test]
fn test_cylinder() {
let cyl = Shape::cylinder(dvec3(0.0, 0.0, 0.0), 5.0, dvec3(0.0, 0.0, 1.0), 10.0);
let expected = std::f64::consts::PI * 5.0f64.powi(2) * 10.0;
assert!((cyl.volume() - expected).abs() < 1e-6);
}
#[test]
fn test_brep_text_roundtrip() {
let original = test_box();
let mut text_data = Vec::new();
original.write_brep_text(&mut text_data).unwrap();
assert!(!text_data.is_empty());
let restored = Shape::read_brep_text(&mut text_data.as_slice()).unwrap();
let orig_mesh = original.mesh_with_tolerance(0.1).unwrap();
let rest_mesh = restored.mesh_with_tolerance(0.1).unwrap();
assert_eq!(orig_mesh.vertices.len(), rest_mesh.vertices.len());
}