Fix boss-bottom blends and merged arc-corner surfaces (#1294)

A fillet or chamfer on a cylindrical boss's bottom arc now builds with a closed display mesh: the seam-extension containment ray counts a shared curved-boundary endpoint once. Merging the split faces of a three-edge arc corner rebuilds the face on the original input face's full surface instead of a piece's restricted patch, and runs under the kernel's panic guard. Fixes #1262 and #1263.

Co-authored-by: Karl-VonRichter <20079846+Karl-VonRichter@users.noreply.github.com>
This commit is contained in:
Karl Von RichterandKarl-VonRichter authored and GitHub committed 2026-10-15 02:03:31 -04:00
1 parent af2f09fac2
commit d6f167a88a
4 files changed
+42 -12

No files matched your search

+14 -1
View File
@@ -231,6 +231,11 @@ pub(crate) fn extension_fits(face: &mt::Face, p: Vec3, q: Vec3, tol: f64) -> boo
{
return false;
}
// Curve endpoints may round to opposite sides of a ray that follows a
// straight boundary into the face. Treat points within its clearance as
// on the ray, so a shared endpoint contributes one crossing.
let ay = if ay.abs() <= tol { 0.0 } else { ay };
let by = if by.abs() <= tol { 0.0 } else { by };
if (ay > 0.0) != (by > 0.0) {
let hit = ax - ay * (bx - ax) / (by - ay);
if hit > tol && hit <= len + tol {
@@ -2663,12 +2668,20 @@ mod tests {
),
(Shape::Flat, 0.32, 0.8 / 3.0),
] {
let out = blend(&body, &[Vec3::new(52.0, 20.0, 0.0)], 0.8, shape, "blend").unwrap();
let picks = [Vec3::new(52.0, 20.0, 0.0)];
let out = match shape {
Shape::Round => fillet(&body, &picks, 0.8),
_ => chamfer(&body, &picks, 0.8),
}
.unwrap();
assert!(out.validity().is_empty(), "{:?}", out.validity());
// Pappus: the section turned half round the axis at its centroid's radius.
let want = area * std::f64::consts::PI * (12.0 - c);
let removed = v0 - vol(&out);
assert!((removed - want).abs() < want * 2e-3, "{removed} vs {want}");
// The app's planned mesh must also close, with the same analytic removal.
let planned = crate::issue_851_tests::planned_volume(&body) - crate::issue_851_tests::planned_volume(&out);
assert!((planned - want).abs() < want * 2e-3, "display mesh: {planned} vs {want}");
}
}