fix(kernel): revolving adjacent profiles on the axis makes no zero-area faces (#490)
Profiles revolved together merge into one region that keeps a vertex where each shared edge met the axis. With the axis edge in several pieces the loop skipped the builders for a profile with an edge on the axis, and the generic sweep turned each piece into a degenerate face that booleans failed on. Runs of collinear axis lines are merged into one first. Fixes #487 Co-authored-by: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
219816d282
commit
91de39d3fe
3 files changed
+64
-2
No files matched your search
@@ -125,6 +125,32 @@ fn revolve_washer_and_sphere() {
|
||||
assert!(rel(ms.volume, 4.0 / 3.0 * PI * 1000.0) < 1e-3, "{}", ms.volume);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn revolve_adjacent_profiles_on_the_axis() {
|
||||
// Two rectangles on the axis, revolved together: their merged outline keeps a vertex
|
||||
// where the shared edge met the axis. The swept axis pieces used to be zero-area faces,
|
||||
// and cutting the body's flat end out of another failed.
|
||||
let r = Region2 {
|
||||
outer: Loop2::polygon(&[
|
||||
Vec2::new(0.0, 0.0),
|
||||
Vec2::new(30.0, 0.0),
|
||||
Vec2::new(60.0, 0.0),
|
||||
Vec2::new(60.0, 20.0),
|
||||
Vec2::new(30.0, 20.0),
|
||||
Vec2::new(0.0, 20.0),
|
||||
]),
|
||||
holes: vec![],
|
||||
};
|
||||
let b = revolve(&Plane::XZ, &[r], Vec2::ZERO, Vec2::X, 2.0 * PI).unwrap().pop().unwrap();
|
||||
assert!(rel(measure(&b).unwrap().volume, PI * 400.0 * 60.0) < 5e-4);
|
||||
let faces = b.faces(1e-3).unwrap();
|
||||
assert!(faces.iter().all(|f| f.area > 1e-6), "{:?}", faces.iter().map(|f| f.area).collect::<Vec<_>>());
|
||||
let disc = cylinder(Vec3::new(-1.0, 0.0, 0.0), Vec3::X, 40.0, 3.0).unwrap();
|
||||
let cut = boolean(&disc, &b, BoolOp::Cut).unwrap().unwrap();
|
||||
let want = PI * 1600.0 * 3.0 - PI * 400.0 * 2.0;
|
||||
assert!(rel(measure(&cut).unwrap().volume, want) < 1e-3, "{} vs {want}", measure(&cut).unwrap().volume);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn chamfer_and_step() {
|
||||
let b = box_solid(Vec3::ZERO, Vec3::new(20.0, 20.0, 20.0)).unwrap();
|
||||
|
||||
Reference in new issue
Block a user