From aa3c214bf714affe17dc1269ba62d01634074a9d Mon Sep 17 00:00:00 2001 From: Ezbaze <68749104+Ezbaze@users.noreply.github.com> Date: Sat, 14 Jun 2025 22:22:43 +0100 Subject: [PATCH] Fix Sample Points node to avoid duplicating endpoints instead of closing its sampled paths (#2714) * Skip duplicate endpoint and close sampled paths in Sample Points node Closes #2713 * Comment --------- Co-authored-by: Keavon Chambers --- .../src/vector/algorithms/bezpath_algorithms.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/node-graph/gcore/src/vector/algorithms/bezpath_algorithms.rs b/node-graph/gcore/src/vector/algorithms/bezpath_algorithms.rs index 50c42a88..8a30d2c2 100644 --- a/node-graph/gcore/src/vector/algorithms/bezpath_algorithms.rs +++ b/node-graph/gcore/src/vector/algorithms/bezpath_algorithms.rs @@ -1,7 +1,7 @@ use super::poisson_disk::poisson_disk_sample; use crate::vector::misc::dvec2_to_point; use glam::DVec2; -use kurbo::{BezPath, DEFAULT_ACCURACY, Line, ParamCurve, ParamCurveDeriv, PathSeg, Point, Rect, Shape}; +use kurbo::{BezPath, DEFAULT_ACCURACY, Line, ParamCurve, ParamCurveDeriv, PathEl, PathSeg, Point, Rect, Shape}; pub fn position_on_bezpath(bezpath: &BezPath, t: f64, euclidian: bool, segments_length: Option<&[f64]>) -> Point { let (segment_index, t) = t_value_to_parametric(bezpath, t, euclidian, segments_length); @@ -21,6 +21,8 @@ pub fn tangent_on_bezpath(bezpath: &BezPath, t: f64, euclidian: bool, segments_l pub fn sample_points_on_bezpath(bezpath: BezPath, spacing: f64, start_offset: f64, stop_offset: f64, adaptive_spacing: bool, segments_length: &[f64]) -> Option { let mut sample_bezpath = BezPath::new(); + let was_closed = matches!(bezpath.elements().last(), Some(PathEl::ClosePath)); + // Calculate the total length of the collected segments. let total_length: f64 = segments_length.iter().sum(); @@ -50,11 +52,15 @@ pub fn sample_points_on_bezpath(bezpath: BezPath, spacing: f64, start_offset: f6 return None; } + // Decide how many loop-iterations: if closed, skip the last duplicate point + let sample_count_usize = sample_count as usize; + let max_i = if was_closed { sample_count_usize } else { sample_count_usize + 1 }; + // Generate points along the path based on calculated intervals. let mut length_up_to_previous_segment = 0.; let mut next_segment_index = 0; - for count in 0..=sample_count as usize { + for count in 0..max_i { let fraction = count as f64 / sample_count; let length_up_to_next_sample_point = fraction * used_length + start_offset; let mut next_length = length_up_to_next_sample_point - length_up_to_previous_segment; @@ -84,6 +90,10 @@ pub fn sample_points_on_bezpath(bezpath: BezPath, spacing: f64, start_offset: f6 } } + if was_closed { + sample_bezpath.close_path(); + } + Some(sample_bezpath) }