Sweeps: a path through a drawn 3D arc follows the arc, not a spline through its three points

path_points took any wire with three or more fit points as a fitted spline, and a 3D arc keeps
its start, through and end points as its fit: the pipe along a quarter arc of radius 20 ran
along the cubic through those three points and came out 388.06 mm³, not π·2²·10π = 394.78.
A wire with its exact arc (Wire::arc) now goes to the kernel as that circle, from its start
counter-clockwise about its normal through its sweep (kernel::curve_path of the record circle).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
jyviko
2026-10-29 00:34:55 -04:00
committed by Irakli Kourtis
parent de5c338e78
commit ac70662d63
+9
View File
@@ -5118,6 +5118,15 @@ fn path_points(ps: &SolvedSketch, ids: &[String], start: Vec3) -> Result<Option<
for id in ids {
if let Some(wi) = ps.sketch.wire_index(id) {
pieces.push(match ps.sketch.wires.get(wi) {
// A drawn 3D arc is its circle, from its start counter-clockwise about its normal
// (its three fit points define it; a spline through them is not the arc).
Some(solidcraft_sketch::Wire { arc: Some(arc), .. }) => {
let x = (arc.start - arc.center).normalized().ok_or_else(|| DocError::Invalid("a 3D arc of no radius".into()))?;
let y = arc.normal.cross(x);
let frame = solidcraft_geom::brep::Frame { origin: arc.center.into(), x_axis: x.into(), y_axis: y.into() };
let circle = solidcraft_geom::brep::Curve::Circle { frame, radius: arc.radius };
kernel::PathPiece::Segs(kernel::curve_path(&circle, [0.0, solidcraft_sketch::arc_sweep(arc)])?)
}
Some(w) if w.fit.len() >= 3 => kernel::PathPiece::Spline { fit: w.fit.clone(), reversed: false },
Some(w) if !w.exact.is_empty() => {
let mut segs = Vec::new();