forked from 1b-agent/opencadstudio-upstream
Guard constraint solving and DWG export against degenerate geometry
Retaining a line's length added a P2PDistance constraint, whose gradient divides by the current distance. For a zero-length line the solver got a NaN Jacobian and its SVD fallback never returned, freezing the editor (e.g. ECONSTRAINT on a line drawn by clicking one point twice). Hold coincident endpoints together with per-axis differences instead. Control-point splines read without knots are given a degree their control points can carry (at most n - 1) and a clamped knot vector when a drawing loads. Generating knots for fewer points than the degree underflowed during DWG write: a panic in debug builds, an unbounded allocation in release, and reachable from autosave. A lone control point with no knots or fit points is purged as corrupt. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
1 parent
a3d65e2fc8
commit
1ac9309f85
3 files changed
+110
-6
No files matched your search
@@ -2346,3 +2346,22 @@ mod region_tests {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod degenerate_constraint_tests {
|
||||
use crate::app::OpenCADStudio;
|
||||
|
||||
/// Retaining a zero-length line's size used to hand the solver a NaN
|
||||
/// Jacobian, and its SVD fallback never returned.
|
||||
#[test]
|
||||
fn equal_constraint_with_a_zero_length_line_returns() {
|
||||
let mut app = OpenCADStudio::new_for_test();
|
||||
app.automation_op(r#"{"op":"new"}"#);
|
||||
app.automation_op(r#"{"op":"run","cmd":"LINE 0,0 0,0 "}"#);
|
||||
app.automation_op(r#"{"op":"run","cmd":"LINE 5,5 20,7 "}"#);
|
||||
app.automation_op(r#"{"op":"select","type":"Line"}"#);
|
||||
app.automation_op(r#"{"op":"run","cmd":"ECONSTRAINT"}"#);
|
||||
let lines = app.automation_op(r#"{"op":"query","type":"Line","detail":"geometry"}"#);
|
||||
assert_eq!(lines["ok"], true, "{lines}");
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user