use indicatrix_formats::asc::parse_asc;
use crate::geometry::{
cuts::StandardGemCuts,
meet_solver::{Block, classify_blocks, meet_tier_inputs_from_asc},
plane::GpuFacetPlane,
};
const HDR: &str = "GemCad 5.0\ng 96 0.0\ny 1 n\nI 1.54\n";
fn flat_plane(planes: &[GpuFacetPlane]) -> GpuFacetPlane {
let flats: Vec<GpuFacetPlane> = planes
.iter()
.copied()
.filter(|p| p.normal[0].abs() < 1e-6 && p.normal[2].abs() < 1e-6)
.collect();
assert_eq!(flats.len(), 1, "{planes:?}");
flats[0]
}
fn assert_flat_side(tiers: &str, flat_tier: usize, crown: bool, depth: f64) {
let schedule = parse_asc(&format!("{HDR}{tiers}")).expect("fixture must parse");
let plane = flat_plane(&StandardGemCuts::from_asc_schedule(&schedule));
let expected_y = if crown { 1.0 } else { -1.0 };
assert!(
(plane.normal[1] - expected_y).abs() < 1e-6,
"{tiers:?}: flat facet normal {:?}",
plane.normal
);
assert!(
(f64::from(plane.d) + depth).abs() < 1e-6,
"{tiers:?}: d = {}",
plane.d
);
let blocks = classify_blocks(&meet_tier_inputs_from_asc(&schedule));
let expected_block = if crown { Block::Crown } else { Block::Pavilion };
assert_eq!(blocks[flat_tier], expected_block, "{tiers:?}");
}
#[test]
fn a_zero_angle_negative_distance_culet_after_a_crown_tier_is_pavilion() {
assert_flat_side("a 41 0.5 0 48\na 0.00 -0.28924 0\n", 1, false, 0.28924);
}
#[test]
fn a_culet_as_the_first_tier_is_pavilion() {
assert_flat_side("a 0.00 -0.368 0\na -41 0.6 0 48\n", 0, false, 0.368);
}
#[test]
fn a_negative_zero_token_culet_after_a_crown_tier_is_pavilion() {
assert_flat_side(
"a 41 0.5 0 48\na -0.000000 -0.76837424 96 n F G SMALL CULET FACET\n",
1,
false,
0.768_374_24,
);
}
#[test]
fn a_positive_distance_table_after_a_pavilion_tier_is_crown() {
assert_flat_side(
"a -41 0.6 0 48\na 0.000000 0.57655827 96 n T\n",
1,
true,
0.576_558_27,
);
}