feat(pline): snap onto the start point closes the polyline

A PLINE point landing back on the first vertex (endpoint snap) now
closes the polyline instead of stacking a duplicate vertex there —
including an arc closing segment, whose bulge is already computed for
the last-to-first span (#421). Line mode requires two real segments
first so a doubled-back line isn't treated as closed. Setting
Closed: Yes in the properties panel on a polyline whose last vertex
already sits on the first drops the duplicate control point for the
same reason.

Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
Hakan SevenandClaude Fable 5 committed 2026-07-21 11:25:33 +03:00
1 parent 33864bace6
commit 411f5396bc
2 files changed
+26

No files matched your search

+12
View File
@@ -504,6 +504,18 @@ fn apply_geom_prop(pline: &mut LwPolyline, field: &str, value: &str) {
} else {
value == "true"
};
// Closing a polyline whose last vertex already sits on the first
// would stack two control points there (a polyline drawn back to
// its start point and then closed) — drop the duplicate so the
// closing segment replaces it (#421).
if pline.is_closed && pline.vertices.len() > 2 {
let (first, last) = (&pline.vertices[0], pline.vertices.last().unwrap());
let d2 = (first.location.x - last.location.x).powi(2)
+ (first.location.y - last.location.y).powi(2);
if d2 < 1e-12 {
pline.vertices.pop();
}
}
return;
}
"plinegen" => {
+14
View File
@@ -270,6 +270,20 @@ impl CadCommand for PlineCommand {
self.bulges[last_idx] = bulge;
}
// A point landing back on the FIRST vertex (endpoint snap) closes the
// polyline instead of stacking a duplicate vertex there — the segment
// bulge just computed above already describes the closing segment
// (#421). Line mode needs two real segments first so a doubled-back
// line isn't "closed"; an arc segment closes from two vertices.
if let Some(first) = self.vertices.first() {
let enough = self.vertices.len() >= 3
|| (self.vertices.len() == 2 && matches!(self.mode, SegMode::Arc));
let d2 = (pt.x - first.x).powi(2) + (pt.y - first.y).powi(2);
if enough && d2 < 1e-12 {
return self.sync_live(true, true);
}
}
self.vertices.push(pt);
self.bulges.push(0.0);
// Publish to the document as soon as the polyline has a segment so it