use super::*;
use crate::geometry::cuts::StandardGemCuts;
#[test]
fn generate_guide_buffers_is_correctly_sized_and_facet_bounded() {
let planes = StandardGemCuts::standard_round_brilliant();
let camera = Camera::new(0.60, 0.45, 2.4, 42.0);
let guides = generate_guide_buffers(16, 12, &camera, &planes);
assert_eq!(guides.depth.len(), 16 * 12);
assert_eq!(guides.normal.len(), 16 * 12);
assert_eq!(guides.facet_id.len(), 16 * 12);
let centre = 6 * 16 + 8;
assert!(
guides.facet_id[centre] >= 0,
"centre pixel should hit the gem"
);
for &id in &guides.facet_id {
assert!(
id == -1 || usize::try_from(id).is_ok_and(|index| index < planes.len()),
"facet id {id} out of range for {} planes",
planes.len()
);
}
}
#[test]
fn generate_guide_buffers_handles_zero_area_without_panicking() {
let planes = StandardGemCuts::standard_round_brilliant();
let camera = Camera::new(0.0, 0.0, 2.4, 42.0);
let guides = generate_guide_buffers(0, 0, &camera, &planes);
assert_eq!(guides.depth.len(), 0);
assert_eq!(guides.normal.len(), 0);
assert_eq!(guides.facet_id.len(), 0);
}
#[test]
fn a_miss_pixel_gets_the_sentinel_depth_and_facet_id() {
let planes = StandardGemCuts::standard_round_brilliant();
let camera = Camera::new(0.0, 1.5, 50.0, 5.0);
let guides = generate_guide_buffers(4, 4, &camera, &planes);
assert!(
guides.facet_id.contains(&-1),
"expected at least one miss pixel at this camera distance/fov"
);
for (i, &id) in guides.facet_id.iter().enumerate() {
if id == -1 {
assert_eq!(guides.depth[i].to_bits(), 1.0e6_f32.to_bits());
assert_eq!(guides.normal[i], Vec3::ZERO);
}
}
}
#[test]
fn generate_guide_buffers_cancellable_matches_the_non_cancellable_version_when_never_cancelled() {
let planes = StandardGemCuts::standard_round_brilliant();
let camera = Camera::new(0.60, 0.45, 2.4, 42.0);
let cancel = AtomicBool::new(false);
let expected = generate_guide_buffers(16, 12, &camera, &planes);
let actual = generate_guide_buffers_cancellable(16, 12, &camera, &planes, &cancel)
.expect("an AtomicBool that's never set true must never yield a cancelled result");
assert_eq!(actual.depth, expected.depth);
assert_eq!(actual.facet_id, expected.facet_id);
}
#[test]
fn single_thread_and_multi_thread_paths_produce_identical_guides() {
let planes = StandardGemCuts::standard_round_brilliant();
let camera = Camera::new(0.60, 0.45, 2.4, 42.0);
let cancel = AtomicBool::new(false);
let job = GuideJob {
width: 21,
height: 13,
camera: &camera,
planes: &planes,
tools: &[],
n_d: 0.0,
cancel: &cancel,
};
let single = generate_with_threads(job, 1).expect("never cancelled");
assert!(
single.facet_id.iter().any(|&id| id >= 0),
"fixture must hit the gem somewhere"
);
let bits = |g: &GuideBuffers| -> Vec<u32> {
g.depth
.iter()
.copied()
.map(f32::to_bits)
.chain(g.normal.iter().flat_map(|n| n.to_array().map(f32::to_bits)))
.collect()
};
for threads in [2, 3, 7, 64] {
let multi = generate_with_threads(job, threads).expect("never cancelled");
assert_eq!(bits(&multi), bits(&single), "{threads} threads");
assert_eq!(multi.facet_id, single.facet_id, "{threads} threads");
}
}
#[test]
fn generating_into_a_reused_buffer_matches_a_fresh_allocation() {
let planes = StandardGemCuts::standard_round_brilliant();
let cancel = AtomicBool::new(false);
let old_camera = Camera::new(1.10, 0.20, 2.4, 42.0);
let camera = Camera::new(0.60, 0.45, 2.4, 42.0);
let mut reused = generate_guide_buffers(24, 16, &old_camera, &planes);
assert!(generate_guide_buffers_into(
16,
12,
&camera,
&planes,
&cancel,
&mut reused
));
let fresh = generate_guide_buffers(16, 12, &camera, &planes);
assert_eq!(reused.facet_id, fresh.facet_id);
assert_eq!(reused.depth.len(), fresh.depth.len());
for (a, b) in reused.depth.iter().zip(&fresh.depth) {
assert_eq!(a.to_bits(), b.to_bits());
}
assert_eq!(reused.normal, fresh.normal);
}
#[test]
fn generate_guide_buffers_cancellable_returns_none_when_pre_cancelled() {
let planes = StandardGemCuts::standard_round_brilliant();
let camera = Camera::new(0.60, 0.45, 2.4, 42.0);
let cancel = AtomicBool::new(true);
let result = generate_guide_buffers_cancellable(64, 64, &camera, &planes, &cancel);
assert!(
result.is_none(),
"a generation cancelled before it starts must not produce buffers"
);
}
#[test]
fn guide_buffers_with_no_tools_match_the_plane_only_entry_point_bit_for_bit() {
let planes = StandardGemCuts::standard_round_brilliant();
let camera = Camera::new(0.60, 0.45, 2.4, 42.0);
let old = generate_guide_buffers(16, 12, &camera, &planes);
let new = generate_guide_buffers_geom(16, 12, &camera, StoneGeometry::planes_only(&planes));
assert_eq!(old.facet_id, new.facet_id);
let bits = |b: &GuideBuffers| -> Vec<u32> { b.depth.iter().map(|d| d.to_bits()).collect() };
assert_eq!(bits(&old), bits(&new));
}
#[test]
fn without_an_index_the_signature_is_all_zeros_and_other_buffers_are_unchanged() {
let planes = StandardGemCuts::standard_round_brilliant();
let camera = Camera::new(0.60, 0.45, 2.4, 42.0);
let plain = generate_guide_buffers(24, 16, &camera, &planes);
assert_eq!(plain.path_sig, vec![0; 24 * 16]);
let zero = generate_guide_buffers_with_index(24, 16, &camera, &planes, 0.0);
assert_eq!(zero.path_sig, plain.path_sig);
let indexed = generate_guide_buffers_with_index(24, 16, &camera, &planes, 2.417);
assert_eq!(indexed.facet_id, plain.facet_id);
assert_eq!(indexed.normal, plain.normal);
for (a, b) in indexed.depth.iter().zip(&plain.depth) {
assert_eq!(a.to_bits(), b.to_bits());
}
}
#[test]
fn signature_is_zero_exactly_on_misses() {
let planes = StandardGemCuts::standard_round_brilliant();
let camera = Camera::new(0.60, 0.45, 2.4, 42.0);
let guides = generate_guide_buffers_with_index(48, 32, &camera, &planes, 2.417);
assert!(guides.facet_id.contains(&-1), "fixture needs a miss pixel");
assert!(
guides.facet_id.iter().any(|&id| id >= 0),
"fixture needs a hit pixel"
);
for (i, &id) in guides.facet_id.iter().enumerate() {
assert_eq!(guides.path_sig[i] == 0, id < 0, "pixel {i}, facet {id}");
}
}
#[test]
fn signature_is_identical_for_one_two_and_eight_threads() {
let planes = StandardGemCuts::standard_round_brilliant();
let camera = Camera::new(0.60, 0.45, 2.4, 42.0);
let cancel = AtomicBool::new(false);
let job = GuideJob {
width: 61,
height: 37,
camera: &camera,
planes: &planes,
tools: &[],
n_d: 2.417,
cancel: &cancel,
};
let single = generate_with_threads(job, 1).expect("never cancelled");
let distinct: std::collections::HashSet<u32> = single.path_sig.iter().copied().collect();
assert!(
distinct.len() > 4,
"a brilliant seen at this pose must show several interior regions"
);
for threads in [2, 8] {
let multi = generate_with_threads(job, threads).expect("never cancelled");
assert_eq!(multi.path_sig, single.path_sig, "{threads} threads");
}
}
#[test]
fn signature_regions_change_with_the_index() {
let planes = StandardGemCuts::standard_round_brilliant();
let camera = Camera::new(0.60, 0.45, 2.4, 42.0);
let diamond = generate_guide_buffers_with_index(64, 48, &camera, &planes, 2.417);
let glass = generate_guide_buffers_with_index(64, 48, &camera, &planes, 1.52);
assert_ne!(diamond.path_sig, glass.path_sig);
assert_eq!(diamond.facet_id, glass.facet_id);
}
#[test]
fn signature_survives_buffer_reuse() {
let planes = StandardGemCuts::standard_round_brilliant();
let cancel = AtomicBool::new(false);
let old_camera = Camera::new(1.10, 0.20, 2.4, 42.0);
let camera = Camera::new(0.60, 0.45, 2.4, 42.0);
let mut reused = generate_guide_buffers_with_index(24, 16, &old_camera, &planes, 2.417);
assert!(generate_guide_buffers_into_with_index(
16,
12,
&camera,
&planes,
2.417,
&cancel,
&mut reused
));
let fresh = generate_guide_buffers_with_index(16, 12, &camera, &planes, 2.417);
assert_eq!(reused.path_sig, fresh.path_sig);
}
#[test]
fn guide_buffers_encode_tool_facet_ids_above_the_plane_count() {
let planes = StandardGemCuts::standard_round_brilliant();
let tools = [ToolPrimitive::cylinder(
Vec3::new(0.0, 0.44, 0.0),
Vec3::X,
0.3,
2.0,
)];
let camera = Camera::new(0.0, 1.5, 4.0, 20.0);
let guides = generate_guide_buffers_geom(
24,
24,
&camera,
StoneGeometry {
planes: &planes,
tools: &tools,
},
);
let first_tool_id = i32::try_from(planes.len()).expect("the plane count fits i32");
assert!(
guides.facet_id.contains(&first_tool_id),
"the groove floor must appear as tool facet {first_tool_id}"
);
assert!(guides.facet_id.iter().all(|&id| id <= first_tool_id));
}