fix: reject planar joins that displace original faces
This commit is contained in:
1 parent
74fed469dc
commit
fc8b71956c
3 files changed
+94
-3
No files matched your search
@@ -317,6 +317,37 @@ fn planar_booleans_with_coincident_faces() {
|
||||
assert!(rel(measure(&i).unwrap().volume, 250.0) < 1e-9);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stepped_logo_join_never_moves_faces_to_hide_an_edge_pinch() {
|
||||
let mut body = box_solid(Vec3::ZERO, Vec3::new(10.0, 20.0, 10.0)).unwrap();
|
||||
for (i, (lo, hi)) in
|
||||
[(Vec3::new(0.0, 0.0, 10.0), Vec3::new(10.0, 10.0, 20.0)), (Vec3::new(-10.0, 0.0, 10.0), Vec3::new(0.0, 10.0, 20.0))].into_iter().enumerate()
|
||||
{
|
||||
let tool = box_solid(lo, hi).unwrap();
|
||||
body = boolean(&body, &tool, BoolOp::Union).unwrap().unwrap();
|
||||
assert!(body.validity().is_empty());
|
||||
let m = measure(&body).unwrap();
|
||||
assert!((m.volume - (3000.0 + i as f64 * 1000.0)).abs() < 1e-6, "join {i}: {}", m.volume);
|
||||
assert!((m.bbox.max.z - 20.0).abs() < 1e-9, "join {i}: {}", m.bbox.max.z);
|
||||
let tops =
|
||||
body.faces(0.01).unwrap().iter().filter(|f| f.plane_normal.is_some_and(|n| n.z > 0.999999) && (f.centroid.z - 20.0).abs() < 1e-9).count();
|
||||
assert_eq!(tops, 1, "join {i}: the top must be a single selectable face");
|
||||
assert!(m.bbox.min.dist(Vec3::new(if i == 0 { 0.0 } else { -10.0 }, 0.0, 0.0)) < 1e-9);
|
||||
assert!(m.bbox.max.dist(Vec3::new(10.0, 20.0, 20.0)) < 1e-9);
|
||||
}
|
||||
let tool = box_solid(Vec3::new(-10.0, 10.0, 10.0), Vec3::new(0.0, 20.0, 20.0)).unwrap();
|
||||
let error = boolean(&body, &tool, BoolOp::Union).unwrap_err();
|
||||
assert!(error.to_string().contains("zero-thickness edge contact"), "{error}");
|
||||
// An intentional overlap removes the pinch without any automatic displacement.
|
||||
let overlap = box_solid(Vec3::new(-10.0, 10.0, 10.0), Vec3::new(0.1, 20.0, 20.0)).unwrap();
|
||||
let joined = boolean(&body, &overlap, BoolOp::Union).unwrap().unwrap();
|
||||
assert!(joined.validity().is_empty());
|
||||
let m = measure(&joined).unwrap();
|
||||
assert!((m.volume - 5010.0).abs() < 1e-6);
|
||||
assert!(m.bbox.min.dist(Vec3::new(-10.0, 0.0, 0.0)) < 1e-9);
|
||||
assert!(m.bbox.max.dist(Vec3::new(10.0, 20.0, 20.0)) < 1e-9);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn corner_boss_on_stepped_case_has_one_exact_top_face() {
|
||||
let outer = box_solid(Vec3::new(-50.0, -25.0, 0.0), Vec3::new(50.0, 25.0, 25.0)).unwrap();
|
||||
|
||||
Reference in new issue
Block a user