Programmatic SPLINE limits the degree to 1..10 (fixes #268) (#269)

spline {control, degree} took any degree up to the control-point count
minus one; tessellation and extents grow with its square, so a few
thousand control points with a high degree hung the app on every redraw.
The Degree prompt, spline.cv and DXF input already limit it to 1..10.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Valentin Klein
2026-10-10 15:33:31 -04:00
committed by GitHub
co-authored by Claude Opus 5.5
parent 160b0fd644
commit 5eb7fd452a
2 changed files with 23 additions and 1 deletions
+3 -1
View File
@@ -245,7 +245,9 @@ fn run_spline(s: &mut Session, p: &Value) -> Result<Value> {
if c.len() < 2 {
return Err(bad("spline", "need 2+ control points"));
}
Spline::from_control(c, p.get("degree").and_then(Value::as_u64).unwrap_or(3) as usize)
// Degree 1..=10 as at the Degree prompt, `spline.cv` and DXF input (tessellation grows
// with its square).
Spline::from_control(c, p.get("degree").and_then(Value::as_u64).unwrap_or(3).clamp(1, 10) as usize)
} else {
return Err(bad("spline", "`fit` or `control` points are required"));
};
+20
View File
@@ -0,0 +1,20 @@
//! Programmatic SPLINE keeps the degree within 1..=10 like the Degree prompt (issue #268): a high
//! degree on many control points made tessellation and extents take minutes.
use cadcraft_engine::Session;
use cadcraft_engine::doc::EntityKind;
use serde_json::json;
#[test]
fn programmatic_spline_degree_is_limited() {
let control: Vec<[f64; 2]> = (0..3000).map(|i| [f64::from(i), f64::from(i % 7)]).collect();
for (degree, want) in [(json!(2_147_483_647), 10), (json!(2999), 10), (json!(11), 10), (json!(0), 1), (json!(4), 4)] {
let mut s = Session::new();
s.execute("spline", &json!({ "control": control, "degree": degree })).unwrap();
let d = s.doc().unwrap();
let Some(EntityKind::Spline(sp)) = d.model.iter().last().map(|e| &e.kind) else { panic!("no spline") };
assert_eq!(sp.degree, want);
let ext = d.extents(&s.space());
assert!(ext.min.x <= 0.0 && ext.max.x >= 2999.0, "{ext:?}");
}
}