mirror of
https://github.com/bherbruck/solidcraft.git
synced 2026-11-03 10:35:58 +00:00
kernel: IGES trim pieces that miss their meeting point are closed onto it
The pieces of an IGES trim curve run on from one another, and the sewer made each meeting point one vertex, but left a piece that missed it where it was, the gap on the vertex's tolerance: an edge 0.01 mm short of its corner, 2000 times the file's resolution, which SMLib refuses (SmTrimmingTools #0, SmBrep line or clamped B-spline piece that misses it is made to end there exactly; any other piece that misses keeps its ends, and the gap is reported. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0113gDVmStT5tCGKW9Fxgc5K
This commit is contained in:
@@ -361,6 +361,54 @@ fn surfaces_in_separate_groups_remain_separate_parts() {
|
||||
}
|
||||
}
|
||||
|
||||
/// The box of [`trimmed_surfaces_sew_into_a_solid`] with its edge (0, 0, 0)–(0, 20, 0) stopping
|
||||
/// 0.01 mm short of its corner in both faces that use it, its next pieces starting at the
|
||||
/// corner. The pieces of a trim curve run on from one another, so the edge ends at the corner the
|
||||
/// other three edges there agree on, exactly: a closed box SMLib finds valid. The edge was left
|
||||
/// short with the gap on the vertex's tolerance, 2000 times the file's resolution (#3845).
|
||||
#[test]
|
||||
fn trim_pieces_that_miss_their_corner_are_closed_onto_it() {
|
||||
let c =
|
||||
|i: usize| -> [f64; 3] { [if i & 1 != 0 { 10.0 } else { 0.0 }, if i & 2 != 0 { 20.0 } else { 0.0 }, if i & 4 != 0 { 30.0 } else { 0.0 }] };
|
||||
let short = [0.0, 19.99, 0.0];
|
||||
let quads = [[0, 2, 3, 1], [4, 5, 7, 6], [0, 1, 5, 4], [2, 6, 7, 3], [0, 4, 6, 2], [1, 3, 7, 5]];
|
||||
let mut ents: Vec<(i64, i64, String)> = Vec::new();
|
||||
let fmt = |p: [f64; 3]| format!("{:?},{:?},{:?}", p[0], p[1], p[2]);
|
||||
for q in quads {
|
||||
let (a, b, cc, d) = (c(q[0]), c(q[1]), c(q[2]), c(q[3]));
|
||||
let surf = format!("1,1,1,1,0,0,1,0,0,0.,0.,1.,1.,0.,0.,1.,1.,1.,1.,1.,1.,{},{},{},{},0.,1.,0.,1.", fmt(a), fmt(b), fmt(d), fmt(cc));
|
||||
ents.push((128, 0, surf));
|
||||
let s_de = 2 * ents.len() - 1;
|
||||
let mut lines = Vec::new();
|
||||
for (p0, p1) in [(a, b), (b, cc), (cc, d), (d, a)] {
|
||||
// The short edge: its end at (0, 20, 0) is 0.01 short.
|
||||
let (p0, p1) = match (p0, p1) {
|
||||
([0.0, 0.0, 0.0], [0.0, 20.0, 0.0]) => (p0, short),
|
||||
([0.0, 20.0, 0.0], [0.0, 0.0, 0.0]) => (short, p1),
|
||||
x => x,
|
||||
};
|
||||
ents.push((110, 0, format!("{},{}", fmt(p0), fmt(p1))));
|
||||
lines.push(2 * ents.len() - 1);
|
||||
}
|
||||
ents.push((102, 0, format!("4,{}", lines.iter().map(|x| x.to_string()).collect::<Vec<_>>().join(","))));
|
||||
let comp = 2 * ents.len() - 1;
|
||||
ents.push((142, 0, format!("0,{s_de},0,{comp},2")));
|
||||
let cos = 2 * ents.len() - 1;
|
||||
ents.push((144, 0, format!("{s_de},1,0,{cos}")));
|
||||
}
|
||||
let imp = iges_import(&iges_file(&ents)).unwrap();
|
||||
assert!(imp.warnings.is_empty(), "{:?}", imp.warnings);
|
||||
assert!(imp.bodies[0].closed);
|
||||
let body = &imp.bodies[0].body;
|
||||
let check = body.smlib().unwrap().check(solidcraft_smlib::CheckLevel::All).unwrap();
|
||||
assert!(check.is_valid(), "{check}");
|
||||
for v in &body.record().vertices {
|
||||
assert!(v.tolerance <= body.record().tolerance, "a vertex {:?} kept a gap in its tolerance {}", v.point, v.tolerance);
|
||||
}
|
||||
let m = measure(body).unwrap();
|
||||
assert!(rel(m.volume, 6000.0) < 1e-6 && rel(m.area, 2200.0) < 1e-6, "{} {}", m.volume, m.area);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_drill_point_round_trips_through_iges() {
|
||||
// A blind hole with a cone tip: the tip's face closes at its apex (its seam runs out to the
|
||||
|
||||
Reference in New Issue
Block a user