feat(lwpolyline): render the wide-polyline band via the wire shader

A wide polyline's flat band was drawn by the hatch pipeline: a solid fill
with only draw-order depth. It ignored the entity linetype (the width
"crushed" the dash pattern) and showed through 3-D geometry in a tilted view.

Draw the band from the polyline's own centre-line wire instead. A new
`WireModel.world_width` (drawing units) makes the wire vertex shader expand
the quad by `world_half_width / world_per_pixel` (clamped to a hairline), so
the band is sized in world units and tracks zoom. Because it is now a wire:

- the GPU dash shader dashes the band by arc-length — the linetype applies;
- it is depth-tested at the polyline elevation — no draw-order see-through;
- no CPU band triangles or per-dash geometry are generated.

`world_half_width` rides in `WireConst` (native, replacing a pad) and the web
`WireInstance` (loc 14); both wire shaders branch on it. The tessellator sets
`world_width` from the LwPolyline width on the Contour / SegmentedLines arms,
and the model-space fill loop no longer emits a hatch band for any LwPolyline.
Pick still uses the band polygon (`pick_tris`).

Blocks keep the hatch band: `LocalWire` carries no `world_width` (finalize
zeroes it), so a scaled insert still scales its band correctly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Hakan SevenandClaude Opus 4.8 committed 2026-07-20 14:50:27 +03:00
1 parent 3d37e1f8d8
commit bd1a5affd7
44 files changed
+158 -17

No files matched your search

+8 -9
View File
@@ -691,15 +691,14 @@ impl Scene {
// Wide LWPolyline and Polyline2D fills
for entity in self.document.entities() {
let (common, fill_origin, fills) = match entity {
// A thickened wide LwPolyline becomes a 3-D tube: its bottom cap
// is drawn as a real depth-tested surface by the tessellator, not
// as this flat 2-D band (which, having only draw-order depth,
// would show through the tube walls in a 3-D view).
EntityType::LwPolyline(pl) if pl.thickness.abs() > 1e-10 => continue,
EntityType::LwPolyline(pl) => {
let (o, f) = crate::entities::lwpolyline::wide_fills(pl);
(&pl.common, o, f)
}
// A wide LwPolyline no longer draws its band here: the shader
// expands the centre-line wire to `world_width` (a real
// depth-tested band that also carries the linetype dash), so a
// second flat 2-D band with only draw-order depth would double
// it and show through 3-D geometry. A thickened one is likewise
// a 3-D tube built by the tessellator. Its band still backs pick
// (`pick_tris`), just not this fill.
EntityType::LwPolyline(_) => continue,
EntityType::Polyline2D(pl) => {
let (o, f) = crate::entities::polyline::wide_fills(pl);
(&pl.common, o, f)