use super::super::interner::{Interner, Vid};
use super::super::retriangulate::{edge_exists, Canonical, Mesh2d, SubTri};
use super::super::retriangulate_recover::{enforce_constraint, recover_via_traversal};
use super::super::{DropAxis, ImplicitPoint, Sign};
use super::{audit_and_recover, pocket_rebuild_valid};
use std::collections::BTreeMap;
fn e2(x: f64, y: f64) -> ImplicitPoint {
ImplicitPoint::Explicit([x, y, 0.0])
}
fn vids4() -> [Vid; 4] {
let mut it = Interner::new();
[
it.intern(e2(0.0, 0.0)),
it.intern(e2(1.0, 0.0)),
it.intern(e2(1.0, 1.0)),
it.intern(e2(0.0, 1.0)),
]
}
#[test]
fn accepts_a_valid_two_pocket_cover() {
let [a, b, c, d] = vids4();
assert!(pocket_rebuild_valid(&[[a, b, c], [a, c, d]]));
assert!(pocket_rebuild_valid(&[]));
}
#[test]
fn accepts_a_zero_area_sliver_with_distinct_vids() {
let mut it = Interner::new();
let a = it.intern(e2(0.0, 0.0));
let m = it.intern(e2(1.0, 0.0));
let b = it.intern(e2(2.0, 0.0));
assert!(pocket_rebuild_valid(&[[a, m, b]]));
}
#[test]
fn rejects_vid_degenerate_triangles_in_every_position() {
let [a, b, _, _] = vids4();
assert!(!pocket_rebuild_valid(&[[a, b, a]]));
assert!(!pocket_rebuild_valid(&[[a, a, b]]));
assert!(!pocket_rebuild_valid(&[[b, a, a]]));
assert!(!pocket_rebuild_valid(&[[a, a, a]]));
}
#[test]
fn rejects_a_duplicated_directed_edge() {
let [a, b, c, d] = vids4();
assert!(!pocket_rebuild_valid(&[[a, b, c], [a, b, c]]));
assert!(!pocket_rebuild_valid(&[[a, b, c], [a, c, b], [a, b, d]]));
}
fn boundary_exit_mesh(it: &mut Interner) -> (Mesh2d, Vid, Vid) {
let a = it.intern(e2(0.0, 0.0));
let u = it.intern(e2(2.0, 1.0));
let v = it.intern(e2(1.0, 2.0));
let b = it.intern(e2(3.0, 3.0));
let mesh = Mesh2d {
tris: vec![[a, u, v]],
axis: DropAxis::Z,
w0: Sign::Positive,
unrecovered: 0,
audit_needed: false,
coords: BTreeMap::new(),
};
(mesh, a, b)
}
#[test]
fn bailed_traversal_leaves_mesh_unchanged_and_audit_counts_unrecovered() {
let mut it = Interner::new();
let (mut mesh, a, b) = boundary_exit_mesh(&mut it);
let before: Vec<SubTri> = mesh.tris.clone();
recover_via_traversal(&mut mesh, &it, a, b);
assert_eq!(
mesh.tris, before,
"a bailing traversal must not touch the mesh"
);
assert!(!edge_exists(&mesh, a, b));
let canon = Canonical {
corners: [a, mesh.tris[0][1], mesh.tris[0][2]],
segments: vec![(a, b)],
points: vec![],
};
let axis = mesh.axis;
audit_and_recover(&mut mesh, &it, &canon, axis);
assert_eq!(
mesh.tris, before,
"audit recovery must also leave the mesh unchanged"
);
assert_eq!(
mesh.unrecovered, 1,
"the unforced constraint must be counted"
);
}
#[test]
fn enforce_constraint_reports_audit_needed_when_recovery_fails() {
let mut it = Interner::new();
let (mut mesh, a, b) = boundary_exit_mesh(&mut it);
enforce_constraint(&mut mesh, &it, a, b);
assert!(!edge_exists(&mesh, a, b));
assert!(
mesh.audit_needed,
"failed recovery must request the conformity audit"
);
}