Found while working on #243. Lowering I-shape profiles with non-dyadic dimensions (e.g. IPE 300 sizes) at `Tolerance::ZERO` fails before any boolean runs: "contour segments leave a gap of 2.6e-18". The contour's segments are computed independently in f64, so consecutive segment ends differ by rounding. At a positive tolerance they weld; at ZERO they don't.
Proposal
Build profile contours so that consecutive segments share one endpoint value (compute each corner once and reuse it), rather than accepting a gap at ZERO. Keep the existing refusal for genuinely open contours.
Done when
IPE-sized I profiles, with and without root fillets, and other non-dyadic parametric profiles lower at `Tolerance::ZERO` with exactly closed contours. A test covers a set of decimal dimensions.
Found while working on #243. Lowering I-shape profiles with non-dyadic dimensions (e.g. IPE 300 sizes) at `Tolerance::ZERO` fails before any boolean runs: "contour segments leave a gap of 2.6e-18". The contour's segments are computed independently in f64, so consecutive segment ends differ by rounding. At a positive tolerance they weld; at ZERO they don't.
Proposal
Build profile contours so that consecutive segments share one endpoint value (compute each corner once and reuse it), rather than accepting a gap at ZERO. Keep the existing refusal for genuinely open contours.
Done when
IPE-sized I profiles, with and without root fillets, and other non-dyadic parametric profiles lower at `Tolerance::ZERO` with exactly closed contours. A test covers a set of decimal dimensions.