Fillets and chamfers where edges meet at corners on a curved wall or a knife-edge tip (#851) (#935)

Rolling-ball blends now handle knife edges, where the two faces have opposite normals; an edge that runs out along an end face tangent to one side; and rounds that end in an earlier round on curved faces, picked together or one after another. The three edges at a vertex of smooth faces, rounded to one radius, end in a piece of sphere. When the given order of up to four edges is refused, or leaves a face boundary off its surface, other orders are tried.

Closes #851.

Co-authored-by: lasselian <22126420+lasselian@users.noreply.github.com>
This commit is contained in:
Lasse Lianandlasselian authored and GitHub committed 2026-10-13 23:21:47 -04:00
1 parent 45f92277cb
commit a2c7396160
10 files changed
+1364 -54

No files matched your search

+27
View File
@@ -152,6 +152,33 @@ pub(crate) fn plan(solid: &Solid, tol: f64, turn: Option<size::Turn>) -> Result<
Ok((plan, stats))
}
/// Whether every curved face's boundary lies on the face's surface, within `accept`: a point
/// off the surface's own parameter range is off it. The planner needs this of every face; a
/// blend that runs on past the end of a neighbouring round's surface does not have it.
pub(crate) fn boundaries_on_surfaces(solid: &Solid, accept: f64) -> bool {
use mt::{BoundedCurve, ParametricCurve};
for face in solid.face_iter() {
let Some(eval) = surface::eval_surface(&face.surface()) else { continue };
if matches!(eval, EvalSurface::Plane { .. }) {
continue;
}
let dom = uv::domain(&eval);
let mut prev: Option<[f64; 2]> = None;
for e in face.edge_iter() {
let c = e.oriented_curve();
let (lo, hi) = c.range_tuple();
for k in 0..=32 {
let p = crate::body::from_p3(c.subs(lo + (hi - lo) * f64::from(k) / 32.0));
match uv::project(&eval, &dom, p, prev, accept) {
Some(uv) => prev = Some(uv),
None => return false,
}
}
}
}
true
}
/// Bounded work for the facet angle, as the reference mesher bounds it: a face whose boundary
/// would get more than `MAX_ANGLE_BOUNDARY` segments has its curved edges sampled again at twice
/// the angle, as often as it takes, down to the tolerance alone (a plate with a thousand small