doc: an iso curve of a solid's face along u or v is the surface's own curve

LinkSource::Iso with `u` or `v` on a solid now takes kernel::iso_curves: the
face's isoparametric curve through the point, exactly, cut by the face's
loops, each piece a wire with its exact curve. An explicit direction (the face
cut by a plane: an intersection curve, waiting for SMLib's exact SSI curves)
and a mesh body still use the triangles' section.

(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 07:22:43 -04:00
parent 95e9a80faf
commit 814475f4f3
+29 -2
View File
@@ -243,8 +243,24 @@ fn resolve_uncached(
}
let name = st.bodies.get(bi).map(|b| b.name.clone()).unwrap_or_else(|| body.clone());
source = LinkSource::Iso { body: name, at: q, dir: dir.clone() };
wires = crate::project3d::iso_curve(&mesh, f, q, dir);
exact = vec![Vec::new(); wires.len()];
let along = match dir.trim().to_ascii_lowercase().as_str() {
"u" => Some(true),
"v" => Some(false),
_ => None,
};
match (st.bodies.get(bi).filter(|b| !b.body.is_mesh()), along) {
// A solid's face along its own parameter: the surface's isoparametric curve.
(Some(target), Some(along_u)) => {
let face = usize::try_from(f).map_err(|_| DocError::Invalid("face index exceeds platform limit".into()))?;
(wires, exact) = exact_wires(crate::kernel::iso_curves(&target.body, face, q, along_u)?)?;
}
// Along an explicit direction (the face cut by a plane), or on a mesh body: its
// triangles' section.
_ => {
wires = crate::project3d::iso_curve(&mesh, f, q, dir);
exact = vec![Vec::new(); wires.len()];
}
}
Vec::new()
}
LinkSource::Spun { body, origin, dir } => {
@@ -377,6 +393,17 @@ fn projected_wires(
Ok((wires, exact))
}
/// Record curves as wires, one each: its points (for display) and the curve itself.
fn exact_wires(curves: Vec<(solidcraft_geom::brep::Curve, [f64; 2])>) -> Result<(Vec<Vec<Vec3>>, Vec<Vec<WireCurve>>)> {
let mut wires = Vec::with_capacity(curves.len());
let mut exact = Vec::with_capacity(curves.len());
for (curve, interval) in curves {
wires.push(crate::kernel::PathPiece::Segs(crate::kernel::curve_path(&curve, interval)?).points());
exact.push(vec![WireCurve { curve, interval }]);
}
Ok((wires, exact))
}
/// Curve `ci` of the solved sketch `ss` as its exact pieces in space, in the order its polyline
/// runs; none where a piece has no record curve.
fn sketch_curves(ss: &crate::eval::SolvedSketch, ci: usize) -> Vec<WireCurve> {