Curvature-continuous (G2) fillets for straight planar edges (#862)

Fillet gets a Curvature (G2) radius type (type: "curvature", alias "g2"): a quintic blend whose size is the equivalent circular setback, for convex and concave straight edges between planar faces with a perpendicular planar end face at each end. Unsupported cases are refused rather than falling back to a circular fillet, and a blend that would cross a loop in its end face is refused. Persisted as a fillet style under format 19; labels in en/de/ja/ko/zh.

Co-authored-by: midasdf <[email protected]>
This commit is contained in:
midasdfandmidasdf authored and GitHub committed 2026-10-14 04:26:53 -04:00
1 parent 3669d4b3d0
commit 6e84c03946
18 files changed
+323 -13

No files matched your search

+4 -1
View File
@@ -1059,6 +1059,9 @@ pub enum FilletStyle {
Constant,
/// `radius` is the chord: the width across the blend.
Chord,
/// G2 quintic blend of planar faces along a straight edge. `radius` sets the
/// equivalent circular setback, not a constant curvature radius.
Curvature,
/// `radius` at the end of each edge nearest `start`, `radius2` at the other; `mid` radii at
/// positions between (0 to 1 from the start end); straight between them, or `smooth`.
Variable {
@@ -1653,7 +1656,7 @@ impl FeatureKind {
v.extend(mid.iter().map(|(_, r)| r.as_str()));
}
FilletStyle::Spline { radii, .. } => v.extend(radii.iter().map(String::as_str)),
FilletStyle::Constant | FilletStyle::Chord => {}
FilletStyle::Constant | FilletStyle::Chord | FilletStyle::Curvature => {}
}
}
FeatureKind::Chamfer { distance, distance2, angle, .. } => {
+1
View File
@@ -4144,6 +4144,7 @@ fn eval_feature(doc: &Document, vals: &BTreeMap<String, Value>, f: &Feature, st:
let input = mb.traced();
// The blended body, and the lineage of what the last blend started from.
let (nb, from) = match &f.kind {
FeatureKind::Fillet { style: crate::FilletStyle::Curvature, .. } => (kernel::fillet_g2(&mb.body, &edges, r)?, input),
FeatureKind::Fillet { style: crate::FilletStyle::Chord, .. } => (kernel::fillet_chord(&mb.body, &edges, r)?, input),
FeatureKind::Fillet { style: crate::FilletStyle::Variable { radius2, start, mid, smooth }, .. } => {
let r2 = val(vals, radius2, Kind::Length)?;
+3
View File
@@ -135,6 +135,9 @@
//! - 19: editable associative offset-distance dimensions. Older offsets retain their saved
//! fixed distances; migration does not invent dimensions or change geometry.
//! Under the same version, a fillet's style can be `curvature` (a G2 quintic blend; `radius`
//! is the equivalent circular setback). Fillets of the other styles save as before; 0.9.0
//! would refuse the unknown style.
use serde_json::Value;
+1
View File
@@ -77,6 +77,7 @@ impl FeatureKind {
}
FeatureKind::Fillet { radius, style, .. } => match style {
crate::FilletStyle::Constant => v.push(("Radius", radius, L)),
crate::FilletStyle::Curvature => v.push(("Equivalent radius", radius, L)),
crate::FilletStyle::Chord => v.push(("Chord length", radius, L)),
crate::FilletStyle::Variable { radius2, mid, .. } => {
v.push(("Start radius", radius, L));