Sheet convert: a wall cut off at its strip keeps each corner with its own edge

end_at_wall takes the plate's end strip off a wall that stands on part of
an edge of the fixed face: the strip's two corners and its two edges go.
They were filtered at their places in the face's lists, counted from the
bend's edge, which pairs corner j with edge j only while the places do
not run across the lists' start. SMLib merges the plate's end strip and
both walls at x = 100 into one L-shaped face whose loop starts on the
strip, so the corners left were each followed by the next one's edge:
the bend's edge took the wall end's face and the wall end took the
plate's. The bend then ran the wall's full width and no relief cut it.
Both lists are now kept counted from the bend's edge.

a_wall_on_part_of_an_edge_meets_a_wall_at_a_relieved_corner_and_is_relieved_at_its_end
passes: bends [22, 92] (was [26, 96]). From the geometry: T 2, R 2, the
setback R + T = 4 on the plate from y = 0 and from x = 100; the round
corner relief 8 across is centred on the setbacks' corner (96, 4), so it
takes 4 off the end of each bend there: the long bend from x = 0 to
96 - 4 = 92, the short one from y = 4 + 4 = 8 to 30, 22 long.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
jyviko
2026-10-30 00:35:26 -04:00
committed by Irakli Kourtis
parent 74001e5325
commit a84369fe71
+14 -4
View File
@@ -597,10 +597,11 @@ fn end_at_wall(base: &mut Face, wall: &mut Face, ids: (usize, usize), by: f64, b
if let Some(x) = wall.pts.get_mut((k + 1) % m) {
*x = q1;
}
let kept = |j: usize, out: &[usize]| !out.contains(&((j + m - k) % m));
wall.pts = wall.pts.iter().enumerate().filter(|(j, _)| kept(*j, &corners_out)).map(|(_, x)| *x).collect();
wall.across = wall.across.iter().enumerate().filter(|(j, _)| kept(*j, &edges_out)).map(|(_, x)| *x).collect();
wall.round = wall.round.iter().enumerate().filter(|(j, _)| kept(*j, &edges_out)).map(|(_, x)| *x).collect();
// Counted from the bend's edge, so each kept corner is still followed by its own edge
// wherever the face's loop starts.
wall.pts = kept_from(&wall.pts, k, &corners_out);
wall.across = kept_from(&wall.across, k, &edges_out);
wall.round = kept_from(&wall.round, k, &edges_out);
// The fixed face's edge: the bend from `p1` to `q1` (it runs the other way along it), no bend
// beside it.
let (Some(&a), Some(&b)) = (base.pts.get(i), base.pts.get((i + 1) % n)) else { return };
@@ -620,6 +621,15 @@ fn end_at_wall(base: &mut Face, wall: &mut Face, ids: (usize, usize), by: f64, b
base.round.splice(i..=i, std::iter::repeat_n(None, count));
}
/// The items of a loop's per-corner or per-edge list `of`, counted from item `k` on, less those
/// at the places `out` (counted from `k`). Corners and edges taken out at the same places counted
/// from one start stay paired (edge `j` from corner `j`); taken out at their places in the list
/// they would not where the places run across the list's start.
fn kept_from<T: Copy>(of: &[T], k: usize, out: &[usize]) -> Vec<T> {
let m = of.len();
(0..m).filter(|j| !out.contains(j)).filter_map(|j| of.get((k + j) % m).copied()).collect()
}
/// Give flange `i` its panel: `outline` in flat coordinates, counter-clockwise, its edge at the
/// bend first trimmed to the end of the bend zone.
fn set_panel(sh: &mut SheetBody, i: usize, outline: &[Vec2]) {