kernel: a point path's polyline is swept as the lines it is, however smooth

The SMLib point sweep refused a polyline whose points turn gently (a smooth run
of more than two points), a branch on the shape of the input: a polyline is
the path its points make, and SMLib's cornered sweep mitres it at each point.
Curves with an exact form no longer reach the kernel as points (previous
commit); what still does (curves projected onto a face, intersection and iso
curves, sweep_path's point lists) is followed as those points.

(not built: base in progress)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017itGh5fpMEousnZ91cYcVt
This commit is contained in:
jyviko
2026-10-22 01:01:49 -04:00
parent 7952516eb4
commit 43e8b03494
+5 -13
View File
@@ -518,20 +518,12 @@ pub fn sweep_path_with(plane: &Plane, region: &Region2, path: &[Vec3], ctl: &Swe
smlib_sweep_points(plane, region, &crate::PointPath::polyline(path.to_vec()), ctl)
}
/// [`crate::sweep_point_path_with`] through SMLib: each drawn 3D spline exactly (its spans), each
/// polyline as the lines between its points ([`crate::PointPath::segs`]), swept by
/// [`crate::sweep_with`], which mitres the corners. A smooth polyline of more points stands for a
/// curve that reaches the kernel only as points (a projected, linked or included 3D curve), which
/// SMLib has no path for yet.
/// [`crate::sweep_point_path_with`] through SMLib: each curve held exactly as its segments (a
/// drawn 3D spline's spans, a sketch curve's or an edge's curve), each polyline as the lines
/// between its points ([`crate::PointPath::segs`]), swept by [`crate::sweep_with`], which mitres
/// the corners. A polyline is the path its points make, however smooth they run: a curve that
/// reaches the kernel only as points is followed as those points.
pub(crate) fn smlib_sweep_points(plane: &Plane, region: &Region2, path: &crate::PointPath, ctl: &SweepControl) -> Result<Body> {
for piece in &path.pieces {
if let crate::PathPiece::Polyline(pts) = piece {
let pts = clean(pts)?;
if pts.len() > 2 && !pts.windows(3).any(|w| turn(w[1] - w[0], w[2] - w[1]) > CORNER) {
return Err(crate::smlib_sweeps::refuse("sweep along a smooth path of points (a projected or linked 3D curve)"));
}
}
}
let segs = path.segs()?;
if segs.is_empty() || segs.len() > 1000 {
return Err(KernelError::Invalid("the path needs 1…1000 segments".into()));