From a3e9b05130a958e2b9a51a50b013f6132418031a Mon Sep 17 00:00:00 2001 From: Hakan Seven Date: Tue, 26 May 2026 18:16:40 +0300 Subject: [PATCH] fix(hatch): stop drawing ghost line between boundary polylines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The polyline arm of the hatch wire outline guarded its NaN separator with `if count > 0 && pts.len() != start_idx`. `start_idx` was assigned to `pts.len()` two lines earlier with nothing in between to grow `pts`, so the inequality was structurally always false — the separator was never emitted. When a hatch carried more than one boundary path (multi-region hatch), the renderer drew a straight segment from the last vertex of path A to the first vertex of path B because the two polylines lived in `pts` back-to-back with no NaN break. The result was a visible stray line between hatch regions. Switch the polyline arm to the same `if !pts.is_empty()` guard the Line / CircularArc / EllipticArc arms use, and capture `start_idx` *after* the separator so the closed-loop close-back logic still points at this polyline's first real vertex. Co-Authored-By: Claude Opus 4.7 --- src/entities/hatch.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/entities/hatch.rs b/src/entities/hatch.rs index 0a68fc40c..826d157b9 100644 --- a/src/entities/hatch.rs +++ b/src/entities/hatch.rs @@ -352,17 +352,26 @@ impl FallbackTess for Hatch { // `Vector3.z`; straight segments emit just the // start vertex, bulged segments tessellate the arc // between v0 → v1. - let start_idx = pts.len(); let verts = &poly.vertices; let count = verts.len(); + if count == 0 { + continue; + } + // Break the wire between this polyline and whatever + // preceded it — without the separator the renderer + // draws a ghost segment from the previous edge / path + // straight to this polyline's first vertex, which + // shows up as a stray boundary line between hatch + // regions. + if !pts.is_empty() { + pts.push([f32::NAN; 3]); + } + let start_idx = pts.len(); let seg_count = if poly.is_closed { count } else { count.saturating_sub(1) }; - if count > 0 && pts.len() != start_idx { - pts.push([f32::NAN; 3]); - } for i in 0..seg_count { let v0 = &verts[i]; let v1 = &verts[(i + 1) % count];