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 <midasdf@users.noreply.github.com>
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

+29
View File
@@ -2,6 +2,7 @@
//! type, whether the command starts from a shortcut, the toolbar or a menu.
use serde_json::json;
use solidcraft_engine::doc::expr::Kind as ValueKind;
use solidcraft_engine::geom::Vec3;
use solidcraft_engine::{Sel, Session};
@@ -561,6 +562,34 @@ fn a_hole_is_mirrored_as_a_feature() {
assert_eq!(cmds[0].1["features"], json!(["Hole1"]));
}
/// The canvas names the G2 size correctly and edits the same value when the feature is reopened.
#[test]
fn curvature_canvas_value_uses_equivalent_radius_when_created_and_reopened() {
for style in ["curvature", "g2"] {
let mut app = boxed();
let e = edge(&app, Vec3::new(20.0, 0.0, 20.0));
let mut d = start(&mut app, vec![e], "solid.fillet");
d.extra.insert("type".into(), json!(style));
let (label, kind, value) = d.primary().unwrap();
assert_eq!((label, kind), ("Equivalent Radius", ValueKind::Length));
*value = "3 mm".into();
let (command, params) = apply_commands(&app, &d).unwrap().remove(0);
assert_eq!(params["radius"], json!("3 mm"), "the canvas edits the actual command value");
app.session.execute(&command, &params).unwrap();
let feature = app.session.doc.features.last().unwrap().id;
let mut reopened = crate::dialogs::for_feature(&app, feature, None).unwrap();
let (label, kind, value) = reopened.primary().unwrap();
assert_eq!((label, kind), ("Equivalent Radius", ValueKind::Length));
assert_eq!(value.as_str(), "3 mm");
}
for (command, label) in [("solid.fillet", "Radius"), ("solid.chamfer", "Distance")] {
let mut app = boxed();
let e = edge(&app, Vec3::new(20.0, 0.0, 20.0));
let mut d = start(&mut app, vec![e], command);
assert_eq!(d.primary().unwrap().0, label);
}
}
/// The radius arrow points into the body: dragging toward the material grows the round.
#[test]
fn fillet_and_chamfer_arrows_point_into_the_body() {