Files
OneCAD-Simulation/crates/geometry/tests/void_shells.rs
T

70 lines
2.9 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! A solid with a void shell (a box shelled, then capped) opens with every shell and everything
//! joined to them (#364); a feature that fails to rebuild is reported naming the body it changes.
use fieldcraft_geometry::{Design, open_design};
const PI: f64 = std::f64::consts::PI;
/// The outer box, 40 × 30 × 20 mm, and its cavity with 2 mm walls and floor.
const BOX: f64 = 40.0 * 30.0 * 20.0;
const CAVITY: f64 = 36.0 * 26.0 * 18.0;
const LID: f64 = 40.0 * 30.0 * 2.0;
/// A post ⌀6 × 5 mm standing on the floor.
const POST: f64 = PI * 9.0 * 5.0;
fn open(bytes: &[u8]) -> Design {
let design = open_design(bytes).unwrap();
assert!(design.errors.is_empty(), "{:?}", design.errors);
assert_eq!(design.bodies.len(), 1);
design
}
fn check(design: &Design, volume: f64, faces: usize) {
let body = design.body("Case").unwrap();
let m = body.measure().unwrap();
assert!((m.volume - volume).abs() < 1e-5 * volume, "{} vs {volume}", m.volume);
assert_eq!(m.faces, faces);
let mut names: Vec<&str> = body.faces().iter().map(|f| f.name.as_str()).collect();
assert_eq!(names.len(), faces);
names.sort_unstable();
names.dedup();
assert_eq!(names.len(), faces, "every face has its own name");
// The mesh sees the same solid: every face tessellated, the same enclosed volume.
let mesh = body.tessellate(0.01).unwrap();
let mut tags = mesh.tri_face.clone();
tags.sort_unstable();
tags.dedup();
assert_eq!(tags.len(), faces);
assert!((mesh.enclosed_volume() - volume).abs() < 1e-3 * volume, "{} vs {volume}", mesh.enclosed_volume());
}
#[test]
fn a_closed_hollow_box_keeps_its_void_shell() {
// Six outside faces and six cavity faces.
check(&open(include_bytes!("designs/hollow-box.solidcraft")), BOX - CAVITY + LID, 12);
}
#[test]
fn a_post_joined_to_the_void_floor_comes_through() {
// The hollow box's twelve faces, the post's top and its side (two halves).
check(&open(include_bytes!("designs/hollow-box-post.solidcraft")), BOX - CAVITY + LID + POST, 15);
}
#[test]
fn a_post_in_an_open_tray_comes_through() {
// Five outside faces, the rim, five cavity faces and the post's three.
check(&open(include_bytes!("designs/open-tray-post.solidcraft")), BOX - CAVITY + POST, 14);
}
#[test]
fn a_feature_that_fails_names_the_body_it_changes() {
let text = std::str::from_utf8(include_bytes!("designs/hollow-box-post.solidcraft")).unwrap();
assert!(text.contains(r#""height": "5""#));
let broken = text.replace(r#""height": "5""#, r#""height": "0""#);
let design = open_design(broken.as_bytes()).unwrap();
let [error] = design.errors.as_slice() else { panic!("{:?}", design.errors) };
assert_eq!(error.feature, "Cylinder1");
assert_eq!(error.bodies, ["Case"]);
let warning = error.warning();
assert!(warning.starts_with(r#"Cylinder1 failed to build, so body "Case" may differ from the design: "#), "{warning}");
}