Trim and Break on ellipses, splines and conics: cut at the exact crossings (alternating projection onto both curves), pieces stay exact (Bézier spans as single-span control splines, conic arcs as conics); geom Seg2::split_at and closest_param

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AS5Tn3xieewUSg3uxrMVdL
This commit is contained in:
bherbruckandClaude Opus 5.5 committed 2026-10-08 03:23:40 +00:00
1 parent 097217a3f3
commit d285cedd73
6 files changed
+371

No files matched your search

+10
View File
@@ -258,6 +258,11 @@ fn trim(s: &mut Session, p: &Value) -> Result<Value> {
let (out, info) = edit(s, p, cmd, false, |sk, doc| {
let ci = curve_arg(sk, p, cmd)?;
let id = sk.curves.get(ci).map(|c| c.id.clone()).unwrap_or_default();
if sk.curves.get(ci).is_some_and(|c| c.kind.is_freeform()) {
let r = super::sketch_freeform::trim_or_break(sk, ci, at, true, cmd)?;
doc.prune_model_params();
return Ok(json!({"trimmed": id, "pieces": r["curves"]}));
}
let sh = sk.shape(ci).ok_or_else(|| bad(cmd, "curve"))?;
let tq = sh.param(sh.project(at));
let (cuts, full) = bracket(sk, ci, tq);
@@ -311,6 +316,11 @@ fn break_cmd(s: &mut Session, p: &Value) -> Result<Value> {
let cmd = "BreakSketchCmd";
let (out, info) = edit(s, p, cmd, false, |sk, _| {
let ci = curve_arg(sk, p, cmd)?;
if sk.curves.get(ci).is_some_and(|c| c.kind.is_freeform()) {
let at = req_vec2(cmd, p, "at")?;
let r = super::sketch_freeform::trim_or_break(sk, ci, at, false, cmd)?;
return Ok(r["curves"].as_array().map(|a| a.iter().filter_map(|x| x.as_str().map(str::to_string)).collect()).unwrap_or_default());
}
let sh = sk.shape(ci).ok_or_else(|| bad(cmd, "curve"))?;
let (ts, cutters): (Vec<f64>, Vec<Option<usize>>) = if let Some(list) = p.get("points").and_then(Value::as_array) {
let mut v: Vec<f64> = list.iter().take(1000).filter_map(vec2).map(|q| sh.param(sh.project(q))).collect();