mirror of
https://github.com/bherbruck/solidcraft.git
synced 2026-11-03 18:45:55 +00:00
Tests: a round flange stays an exact circle through unfold, refold and DXF, with a cut near its rim
The test it replaces probed for a polyline by placing a 0.2 um square in the gap between the rim and a 1 um polyline: a micro feature in a millimetre part. This one asserts the property itself, in millimetres: every rim segment of the flat pattern is an arc of radius 10, the DXF draws one circle of radius 10, and a 1 mm cut 0.5 mm inside the rim stays one hole. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -2324,36 +2324,38 @@ fn cut_across_a_concave_notch_uses_crossings_not_just_contained_corners() {
|
||||
assert!((volume(&mut s) - 10500.0).abs() < 1e-6);
|
||||
}
|
||||
|
||||
/// A round flange stays an exact circle through unfold, refold and DXF (never a polyline), and a
|
||||
/// cut close to its rim stays a hole in the flat pattern.
|
||||
#[test]
|
||||
fn tiny_cut_inside_exact_circle_survives_unfold_refold_and_dxf() {
|
||||
fn a_round_flange_stays_a_circle_and_keeps_a_cut_near_its_rim_through_unfold_refold_and_dxf() {
|
||||
for initially_flat in [false, true] {
|
||||
let mut s = Session::default();
|
||||
run(&mut s, "sketch.create", json!({"plane": "XY", "name": "Disc"}));
|
||||
run(&mut s, "sketch.circle.center", json!({"center": [0,0], "radius": 10}));
|
||||
run(&mut s, "sketch.finish", json!({}));
|
||||
run(&mut s, "sheet.flange", json!({"sketch": "Disc"}));
|
||||
let circle = s.model.state().sheets[0].base.outer.clone();
|
||||
let displayed = circle.polyline(1e-3);
|
||||
// A square 0.2 µm across, centred 0.4 µm inside the circle on the bisector of the
|
||||
// display polyline's first chord (its middle 0.98 µm inside): outside the polyline, inside
|
||||
// the exact circle, each of its walls and its gap to the rim wider than SMLib's 0.1 µm
|
||||
// modelling tolerance.
|
||||
let (half, at) = (0.0001, (displayed[0] + displayed[1]).normalized().unwrap() * 9.9996);
|
||||
assert!(!circle.contains(at));
|
||||
if initially_flat {
|
||||
run(&mut s, "sheet.unfold", json!({}));
|
||||
}
|
||||
run(&mut s, "sketch.create", json!({"plane": "XY", "name": "TinyCut"}));
|
||||
run(&mut s, "sketch.rectangle.two_point", json!({"p0": [at.x-half,at.y-half], "p1": [at.x+half,at.y+half]}));
|
||||
// A 1 mm square whose outer side is 0.5 mm inside the rim.
|
||||
run(&mut s, "sketch.create", json!({"plane": "XY", "name": "Cut"}));
|
||||
run(&mut s, "sketch.rectangle.two_point", json!({"p0": [8.5,-0.5], "p1": [9.5,0.5]}));
|
||||
run(&mut s, "sketch.finish", json!({}));
|
||||
run(&mut s, "solid.extrude", json!({"sketch": "TinyCut", "through_all": true, "operation": "cut", "direction": "symmetric"}));
|
||||
run(&mut s, "solid.extrude", json!({"sketch": "Cut", "through_all": true, "operation": "cut", "direction": "symmetric"}));
|
||||
for stage in ["sheet.unfold", "sheet.refold"] {
|
||||
let regions = s.model.state().sheets[0].flat_regions().unwrap();
|
||||
let rim = ®ions[0].outer.segs;
|
||||
assert!(
|
||||
!rim.is_empty() && rim.iter().all(|seg| matches!(seg, solidcraft_geom::Seg2::Arc { radius, .. } if (*radius - 10.0).abs() < 1e-12)),
|
||||
"{rim:?}"
|
||||
);
|
||||
assert_eq!(regions[0].holes.len(), 1);
|
||||
assert!((regions[0].holes[0].signed_area().abs() - 4e-8).abs() < 1e-13);
|
||||
assert!((regions[0].holes[0].signed_area().abs() - 1.0).abs() < 1e-12);
|
||||
assert_eq!(s.model.state().bodies.len(), 1);
|
||||
let dxf = run(&mut s, "sheet.export_dxf", json!({}))["dxf"].as_str().unwrap().to_string();
|
||||
assert_eq!(solidcraft_io::read_dxf(&dxf).unwrap().len(), 5);
|
||||
let drawn = solidcraft_io::read_dxf(&dxf).unwrap();
|
||||
assert!(drawn.iter().any(|g| matches!(g, solidcraft_io::Geom2::Circle(_, r) if (*r - 10.0).abs() < 1e-12)), "{drawn:?}");
|
||||
assert_eq!(drawn.len(), 5, "the circle and the square's four sides: {drawn:?}");
|
||||
if stage == "sheet.unfold" && initially_flat {
|
||||
run(&mut s, "sheet.refold", json!({}));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user