feat: fit reduce lowers the radius only where it doesn't fit (#496)
Fillet fit: reduce lowers the radius only where it doesn't fit: picked edges are grouped where they can limit each other (sharing a face or vertex), and each group gets the requested radius where it fits, otherwise the largest that does. Refs #293. Co-authored-by: Iraklis Kourtis <jyviko@gmail.com>
This commit is contained in:
1 parent
6d5df4b9b3
commit
0f0bb09858
9 files changed
+252
-35
No files matched your search
@@ -1604,10 +1604,16 @@ pub fn show(app: &mut SolveApp, ctx: &egui::Context) {
|
||||
let fit = extra_choice(ui, &mut d.extra, "fi_fit", "fit", &[("Exact", "exact"), ("Reduce to Fit", "reduce")]);
|
||||
ui.end_row();
|
||||
if fit == 1
|
||||
&& let Some(r) = app.preview.applied
|
||||
&& let Some((lo, hi)) = app.preview.applied
|
||||
{
|
||||
// A range where edges apart from each other fit different radii.
|
||||
row_label(ui, "Applied Radius");
|
||||
ui.label(RichText::new(crate::prefs::show_mm(app, r, 1)).color(t.warning));
|
||||
let shown = if hi > lo {
|
||||
format!("{} – {}", crate::prefs::show_mm_bare(app, lo), crate::prefs::show_mm(app, hi, 1))
|
||||
} else {
|
||||
crate::prefs::show_mm(app, lo, 1)
|
||||
};
|
||||
ui.label(RichText::new(shown).color(t.warning));
|
||||
ui.end_row();
|
||||
}
|
||||
} else if !*chamfer {
|
||||
|
||||
@@ -537,7 +537,7 @@ fn fillet_radius_fit_reduces_and_shows_the_applied_radius() {
|
||||
assert_eq!(p["fit"], json!("reduce"));
|
||||
let job = crate::preview::compute(&app.session, &[(id.clone(), p.clone())], crate::preview::Colors::from_tokens(&crate::theme::Tokens::dark()))
|
||||
.unwrap();
|
||||
assert_eq!(job.applied, Some(3.0));
|
||||
assert_eq!(job.applied, Some((3.0, 3.0)));
|
||||
// Applied and edited again, the fillet keeps its fit.
|
||||
app.session.execute(&id, &p).unwrap();
|
||||
let fillet = app.session.doc.features.last().unwrap().id;
|
||||
@@ -546,7 +546,7 @@ fn fillet_radius_fit_reduces_and_shows_the_applied_radius() {
|
||||
// Its edit preview shows the radius it uses too.
|
||||
let cmds = apply_commands(&app, &e).unwrap();
|
||||
let job = crate::preview::compute(&app.session, &cmds, crate::preview::Colors::from_tokens(&crate::theme::Tokens::dark())).unwrap();
|
||||
assert_eq!(job.applied, Some(3.0));
|
||||
assert_eq!(job.applied, Some((3.0, 3.0)));
|
||||
}
|
||||
|
||||
/// Apply a dialog's commands to the session; the new feature's id.
|
||||
|
||||
@@ -41,8 +41,9 @@ pub struct Built {
|
||||
pub error: Option<String>,
|
||||
/// Extent of what the preview shows (the view's depth range must cover it).
|
||||
pub bounds: Aabb3,
|
||||
/// The radius a fillet used when it reduced one too large for its edges (`fit: reduce`).
|
||||
pub applied: Option<f64>,
|
||||
/// The smallest and largest radius a fillet used when it reduced one too large for its edges
|
||||
/// (`fit: reduce`).
|
||||
pub applied: Option<(f64, f64)>,
|
||||
}
|
||||
|
||||
type Job = Result<Built, String>;
|
||||
@@ -68,8 +69,8 @@ pub struct PreviewState {
|
||||
/// Time the last preview took (ms), for `ui.inspect`.
|
||||
pub ms: f64,
|
||||
started: f64,
|
||||
/// The radius the previewed fillet used when it reduced the one asked for.
|
||||
pub applied: Option<f64>,
|
||||
/// The smallest and largest radius the previewed fillet used when it reduced the one asked for.
|
||||
pub applied: Option<(f64, f64)>,
|
||||
}
|
||||
|
||||
impl PreviewState {
|
||||
@@ -231,7 +232,7 @@ pub fn compute(s: &Session, cmds: &[(String, Value)], colors: Colors) -> Job {
|
||||
b.bounds = state_bounds(&p.after);
|
||||
// The radius a previewed fillet used when it reduced the one asked for (a new
|
||||
// fillet or an edited one: the feature the replies name).
|
||||
b.applied = p.replies.iter().filter_map(|r| r.get("feature").and_then(Value::as_u64)).find_map(|id| p.after.fitted_radius(id));
|
||||
b.applied = p.replies.iter().filter_map(|r| r.get("feature").and_then(Value::as_u64)).find_map(|id| p.after.fitted_range(id));
|
||||
Ok(b)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user