Booleans build the same body every time: face order no longer follows heap addresses (#748)
truck's face and edge IDs are their addresses, so walking maps keyed by them followed heap layout, and the ribbed lid's side-wall hole passed or failed by chance. The planar boolean's rebuild and glue now take truck's connected components in the shell's order, and the planar boolean's own maps are ordered. Healing's union-find keeps the lesser root and takes a run's ends in order of use. The face classification after an intersection orders each component's faces by the shell first. The lid now builds the same body on every run, with a test that builds it six times in one process. Its 0.5 mm side-wall holes, and one sensor enclosure hole of the same kind, now fail every time and are marked failing in the baseline. Fixes #707. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
58af8accfa
commit
a3dfbaa0b0
6 files changed
+95
-32
No files matched your search
@@ -1246,3 +1246,30 @@ fn a_plane_on_a_patterned_counterbore_after_a_thickness_change() {
|
||||
]);
|
||||
reproduces(None, Value::Array(c));
|
||||
}
|
||||
|
||||
/// #707: the same design builds the same body every time, in one process too. Faces were put in
|
||||
/// the hash order of their addresses in a few places (truck's connected components, the planar
|
||||
/// boolean's rebuild, healing's merges), so a later boolean on the ribbed lid passed or failed
|
||||
/// from run to run.
|
||||
#[test]
|
||||
fn the_ribbed_lid_builds_the_same_body_every_time() {
|
||||
let path = root().join("examples/regressions/lid_ribs_flush_with_window.json");
|
||||
let fingerprint = || {
|
||||
let s = load(&path).unwrap();
|
||||
let st = s.model.state();
|
||||
st.bodies
|
||||
.iter()
|
||||
.map(|b| {
|
||||
let mesh = b.body.tessellate(0.1).unwrap();
|
||||
let bits = mesh.positions.iter().fold(0u64, |acc, p| {
|
||||
acc.rotate_left(7).wrapping_add(p.x.to_bits() ^ p.y.to_bits().rotate_left(21) ^ p.z.to_bits().rotate_left(42))
|
||||
});
|
||||
format!("{} {} {bits:x}", b.name, b.body.face_count())
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
};
|
||||
let first = fingerprint();
|
||||
for _ in 0..5 {
|
||||
assert_eq!(fingerprint(), first);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user