From 1ac2ebaad2e5072fbff3f8606a3cd9286b8cd849 Mon Sep 17 00:00:00 2001 From: NetterSilver <133535268+Silvertree2010@users.noreply.github.com> Date: Mon, 19 Oct 2026 08:31:44 +0200 Subject: [PATCH] Keep line and arc elevation when lengthening with LENGTHEN (#1313) Found while testing crates/engine/src/cmd/modify2.rs:764 Co-authored-by: Claude Haiku 5.5 --- crates/engine/src/cmd/modify2.rs | 11 +++++++-- crates/engine/src/cmd/modify2_tests.rs | 33 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/crates/engine/src/cmd/modify2.rs b/crates/engine/src/cmd/modify2.rs index 5562f969c..37a48092b 100644 --- a/crates/engine/src/cmd/modify2.rs +++ b/crates/engine/src/cmd/modify2.rs @@ -761,7 +761,13 @@ pub(crate) fn lengthen_kind(k: &EntityKind, pick: Option, mode: LenMode) - return Err(too_short()); } let ne = fixed + dir * nl; - Ok(if at_b { line(a, ne) } else { line(ne, b) }) + let mut out = l.clone(); + if at_b { + out.b = ne.to3(l.b.z); + } else { + out.a = ne.to3(l.a.z); + } + Ok(EntityKind::Line(out)) } EntityKind::Arc(ar) => { let g = Arc::new(ar.center.xy(), ar.radius, ar.start, ar.end); @@ -782,7 +788,8 @@ pub(crate) fn lengthen_kind(k: &EntityKind, pick: Option, mode: LenMode) - if !(ns > 1e-12 && ns < TAU - 1e-9) { return Err(other("The new arc would be zero length or a full circle.")); } - Ok(if at_end { arc(&Arc::new(g.center, g.radius, g.start, g.start + ns)) } else { arc(&Arc::new(g.center, g.radius, g.end - ns, g.end)) }) + let na = if at_end { Arc::new(g.center, g.radius, g.start, g.start + ns) } else { Arc::new(g.center, g.radius, g.end - ns, g.end) }; + Ok(EntityKind::Arc(cadcraft_doc::Arc { radius: na.radius, start: na.start, end: na.end, ..ar.clone() })) } EntityKind::LwPolyline(p) if !p.closed && p.vertices.len() >= 2 => { let total = Polyline { vertices: p.vertices.clone(), closed: false }.len(); diff --git a/crates/engine/src/cmd/modify2_tests.rs b/crates/engine/src/cmd/modify2_tests.rs index 9b76c84fc..836e5c017 100644 --- a/crates/engine/src/cmd/modify2_tests.rs +++ b/crates/engine/src/cmd/modify2_tests.rs @@ -214,6 +214,39 @@ fn lengthen_json() { assert!(near(poly(&kind(&s, &p)).vertices[0].p, -5.0, 10.0)); } +#[test] +fn lengthen_keeps_elevation() { + let mut s = Session::new(); + let l = h(&s.execute("line", &json!({"points": [[0, 0], [10, 0]]})).unwrap()); + let a = h(&s.execute("arc", &json!({"center": [0, 0], "radius": 1, "start": 0, "end": 90})).unwrap()); + let doc = s.doc_mut().unwrap(); + doc.modify_entity(Handle::parse_hex(&l).unwrap(), |e| { + if let EntityKind::Line(x) = &mut e.kind { + x.a.z = 5.0; + x.b.z = 5.0; + } + }) + .unwrap(); + doc.modify_entity(Handle::parse_hex(&a).unwrap(), |e| { + if let EntityKind::Arc(x) = &mut e.kind { + x.center.z = 3.0; + } + }) + .unwrap(); + s.execute("lengthen", &json!({"handle": l, "delta": 2})).unwrap(); + let EntityKind::Line(x) = kind(&s, &l) else { panic!("not a line") }; + assert_eq!((x.a.x, x.a.y, x.a.z), (0.0, 0.0, 5.0)); + assert_eq!((x.b.x, x.b.y, x.b.z), (12.0, 0.0, 5.0)); + s.execute("lengthen", &json!({"handle": l, "delta": 1, "pick": [0, 0]})).unwrap(); + let EntityKind::Line(x) = kind(&s, &l) else { panic!("not a line") }; + assert_eq!((x.a.x, x.a.y, x.a.z), (-1.0, 0.0, 5.0)); + assert_eq!((x.b.x, x.b.y, x.b.z), (12.0, 0.0, 5.0)); + s.execute("lengthen", &json!({"handle": a, "deltaAngle": 10})).unwrap(); + let EntityKind::Arc(x) = kind(&s, &a) else { panic!("not an arc") }; + assert_eq!(x.center.z, 3.0); + assert!((arc_of(&kind(&s, &a)).sweep() - 100f64.to_radians()).abs() < 1e-9); +} + #[test] fn lengthen_command_line() { let mut s = Session::new();