forked from 1b-agent/opencadstudio-upstream
An open "C" tube (the € currency symbol's ring) rendered as a full closed donut: truck builds a torus as a full revolution and can't trim it, and the wireframe/silhouette arc estimate was wrong. The arc estimate failed because `collect_face_polygon` reads only the first loop, and the "widest empty gap = tube body" heuristic breaks once the tube carries interior holes (where the two horizontal bars punch through it): a hole splits the body into wide hole-free stretches that masquerade as the opening. `torus_phi_range` now walks every boundary loop and classifies each: a minor circle sitting in a constant-φ plane (spread < ~8.6°) is an end cap; a wider loop is an interference hole. The opening is the gap flanked on both sides by end caps — a hole never bounds it — so the body is the rest of the turn. Torus faces now route to the bespoke sampler (like spheres); `tess_torus_face` clips its φ grid to that arc, so the shaded tube is an open C. `torus_isolines` and `collect_curved_gens` use the same range for the wireframe rim and the silhouette. Removes the now-dead truck torus path (`torus_faces`, `Outward::Torus`, `vadd`). Co-Authored-By: Claude Opus 4.8 <[email protected]>