Extend open paths from endpoints with the Freehand tool and skip hidden layers in path edits (#4508)

* Let the Freehand tool continue a selected open path from its endpoint and show endpoint overlays in the Freehand and Spline tools

* Share the closest-point search with the open path endpoint lookup, tally endpoint connections in a single pass, and rename the endpoint overlay function

* Skip hidden layers and use the feeds-aware transform in path point searches, path overlays, and Freehand point placement

* Map the Spline tool's merge goal with the feeds-aware transform so it matches the endpoint candidates

* Highlight the hovered open path endpoint in the Freehand and Spline tools
This commit is contained in:
Keavon Chambers
2026-09-06 20:37:49 -07:00
committed by GitHub
parent 97430120f4
commit 5612b63633
9 changed files with 408 additions and 27 deletions

View File

@@ -366,7 +366,15 @@ impl Vector {
/// Anchor points at the ends of open subpaths. These are points with exactly one connection by a segment to another anchor.
pub fn anchor_endpoints(&self) -> impl Iterator<Item = PointId> + '_ {
self.anchor_points().enumerate().filter(|&(index, _)| self.segment_domain.connected_count(index) == 1).map(|(_, id)| id)
// O(points + segments): tally every point's connections in a single pass
let mut connected_counts = vec![0_usize; self.point_domain.ids().len()];
for &point_index in self.segment_domain.start_point().iter().chain(self.segment_domain.end_point()) {
if let Some(count) = connected_counts.get_mut(point_index) {
*count += 1;
}
}
self.anchor_points().zip(connected_counts).filter(|&(_, count)| count == 1).map(|(id, _)| id)
}
/// Computes if all the connected handles are colinear for an anchor, or if that handle is colinear for a handle.