Fix: false "projected face changed shape" warnings after a rollback

Re-reading an unchanged projected face could walk its loops in another order or
direction, or (from some meshes) return the same half of a split circle twice.
The link was then rebuilt, warning and dropping constraints on it. Projected
geometry now compares by position regardless of order and direction, and a
duplicated half arc is turned into the missing half.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
This commit is contained in:
bherbruckandClaude Opus 5.5 committed 2026-10-07 23:47:39 +00:00
1 parent 08cf223ced
commit 0271919d52
3 files changed
+110 -1

No files matched your search

+15
View File
@@ -841,3 +841,18 @@ fn feature_inputs_are_parameters() {
let back = solvecraft_doc::Document::from_json(&s.doc.to_json()).unwrap();
assert_eq!(back.features[0].param_names, s.doc.features[0].param_names);
}
#[test]
fn rolling_back_and_forward_leaves_no_projection_warnings() {
let mut s = Session::default();
s.run_script(&crate::sample::script()).unwrap();
let warnings = |s: &Session| -> Vec<String> {
s.doc.features.iter().filter_map(|f| s.model.result(f.id).and_then(|r| r.warning.clone()).map(|w| format!("{}: {w}", f.name))).collect()
};
assert!(warnings(&s).is_empty(), "{:?}", warnings(&s));
for pos in 0..s.doc.features.len() {
run(&mut s, "timeline.rollTo", json!({ "position": pos }));
run(&mut s, "timeline.rollTo", json!({}));
assert!(warnings(&s).is_empty(), "after rolling to {pos}: {:?}", warnings(&s));
}
}