fix: fillet fit review follow-ups (#404)

* fix: fillet fit review follow-ups

From the review of #388 (merged before these landed):
- The Fillet dialog's Applied Radius showed nothing when editing a fillet
  that was already reduced: the preview found the radius by diffing the
  states before and after. The engine's preview now keeps the command
  replies, and the dialog reads the radius of the feature they name.
- Pattern copies of a reduced fillet try the radius the original was
  reduced to first, instead of each searching again (up to 16 fillets).
- fit: reduce with a chord or variable radius is refused instead of being
  silently ignored.
- One helper appends a note to a feature's warning; too_large is imported
  like unsupported in the loop and curve blends.

Refs #293

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01TWc1smHYwTSVrVc8SNvS44

* Use the solidcraft_doc crate name after the rename

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01HWLPLy7ug7URSK5WybjRNa

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: bherbruck <[email protected]>
This commit is contained in:
authored and GitHub committed 2026-10-12 18:57:09 -04:00
1 parent 11ecb64059
commit deb96318a1
8 files changed
+58 -32

No files matched your search

+15 -15
View File
@@ -274,6 +274,14 @@ fn fillet_fitted(
}
}
/// Add `note` to a feature's warning.
fn append_warning(warning: &mut Option<String>, note: String) {
*warning = Some(match warning.take() {
Some(w) => format!("{w}; {note}"),
None => note,
});
}
/// A length in mm, without trailing zeros.
fn show_mm(v: f64) -> String {
let s = format!("{v:.6}");
@@ -285,11 +293,6 @@ impl ModelState {
pub fn fitted_radius(&self, feature: u64) -> Option<f64> {
self.fitted.get(&feature).copied()
}
/// Every reduced fillet radius (by feature id).
pub fn fitted_radii(&self) -> impl Iterator<Item = (u64, f64)> + '_ {
self.fitted.iter().map(|(k, v)| (*k, *v))
}
}
/// Model after some prefix of the timeline.
@@ -948,10 +951,7 @@ impl Model {
});
if r.is_ok() {
if let Some(note) = boolean_diagnostics.warning() {
warning = Some(match warning {
Some(existing) => format!("{existing}; {note}"),
None => note,
});
append_warning(&mut warning, note);
}
} else {
boolean_diagnostics = Default::default();
@@ -2842,7 +2842,11 @@ fn replay(
let Some(mb) = st.bodies.get(ti).cloned() else { continue };
let nb = match &src.kind {
FeatureKind::Chamfer { distance2, angle, flip, .. } => chamfer_with(vals, &mb.body, &moved, r, distance2, angle, *flip)?,
FeatureKind::Fillet { fit, .. } => fillet_fitted(&mb.body, &moved, r, *fit)?.0,
// A copy is congruent to the original: the radius it was reduced to first.
FeatureKind::Fillet { fit, .. } => match st.fitted.get(&src.id).copied() {
Some(used) => kernel::fillet(&mb.body, &moved, used).or_else(|_| fillet_fitted(&mb.body, &moved, r, *fit).map(|x| x.0))?,
None => fillet_fitted(&mb.body, &moved, r, *fit)?.0,
},
_ => kernel::fillet(&mb.body, &moved, r)?,
};
let nb = Traced::step(nb, &[&mb.traced()]);
@@ -3595,11 +3599,7 @@ fn eval_feature(doc: &Document, vals: &BTreeMap<String, Value>, f: &Feature, st:
let (b, used) = fillet_fitted(&mb.body, &edges, r, *fit)?;
if let Some(used) = used {
st.fitted.insert(f.id, used);
let note = format!("the radius is reduced to {} mm, the largest that fits these edges", show_mm(used));
*warning = Some(match warning.take() {
Some(w) => format!("{w}; {note}"),
None => note,
});
append_warning(warning, format!("the radius is reduced to {} mm, the largest that fits these edges", show_mm(used)));
}
(b, input)
}