Fillets and chamfers ending on a boss's pieced wall or beside it, on a face that runs along its seam twice, and loops the loop blend refuses (#926)

Fillets and chamfers ending on a boss's pieced wall or beside it, on a face that runs along its seam twice, and loops the loop blend refuses

- A straight edge whose end meets one curved surface in several faces (a cylinder a join left
  in pieces) ends on that surface: the section is cut where it crosses each seam, which is
  shortened there; where no seam is crossed (the wall missing inside the other body) the
  section lies on the bared surface and the rest of the side edge becomes a seam.
- Two end faces that aren't both planes meeting in lines: each face takes the section's points
  on it, cut where it crosses the edge between them. Not where an end face runs on smoothly
  from a side (an earlier round): the corner build takes those.
- Face boundaries close over several connector edges.
- A face on a periodic surface running along its seam twice (as a STEP file gives it) is
  rebuilt the same way (#691).
- A curved chain ending square on a face that runs on past its side extends that face's seam.
- A smooth chain stops before an edge between faces that meet smoothly.
- A loop the loop blend refuses for its shape is blended edge by edge; refusals about its size
  stand.
- Action matrix: ACTION_MATRIX_ACTIONS and ACTION_MATRIX_VALIDITY for quick local runs; the
  fillets and chamfers that pass now recorded.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
bherbruck authored and GitHub committed 2026-10-14 00:28:09 -04:00
1 parent 63095fedb3
commit ce902be66c
5 files changed
+537 -133

No files matched your search

@@ -639,7 +639,14 @@ fn action_matrix_worker() {
}
let list = actions(&s);
let edit = driving_parameter(&s);
// Local runs only: `ACTION_MATRIX_ACTIONS=edge.fillet,edge.chamfer` tries just those actions
// (don't bless such a run), `ACTION_MATRIX_VALIDITY=1` adds each passing action's body check.
let only: Option<Vec<String>> = std::env::var("ACTION_MATRIX_ACTIONS").ok().map(|v| v.split(',').map(str::to_string).collect());
let validity = std::env::var_os("ACTION_MATRIX_VALIDITY").is_some();
for (i, a) in list.iter().enumerate().skip(from) {
if only.as_ref().is_some_and(|o| !o.iter().any(|x| x == a.action)) {
continue;
}
// Whole families of pieces are sampled together (see [`family`]).
let k = key(&design, &family(&a.entity), a.action);
if !stable_hash(&k).is_multiple_of(sample) {
@@ -650,6 +657,11 @@ fn action_matrix_worker() {
let mut scratch = s.scratch();
let r = perform(&mut scratch, &a.act, &before);
let mut line = outcome(&design, &a.entity, a.action, &r, t.elapsed().as_millis());
if validity && r.is_ok() {
let st = scratch.model.state();
let bad: Vec<String> = st.bodies.iter().flat_map(|b| b.body.validity().into_iter().map(|v| format!("{}: {v}", b.name))).collect();
line["validity"] = json!(bad);
}
// What was sent, for reproducing a failure (kept in the results, not the baseline).
line["command"] = match &a.act {
Act::Run(id, p) => json!({"command": id, "params": p}),