From deec2a8fd3dd018d4ae062fd1b39a387e1f856ab Mon Sep 17 00:00:00 2001 From: Hakan Seven Date: Thu, 25 Jun 2026 00:15:58 +0300 Subject: [PATCH] fix(xclip): keep clipped hatch loops in world_origin-relative space MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `clip_hatch_boundary` lifted each loop into the clip polygon's world space (`+world_origin`) to run the Sutherland–Hodgman clip, but returned the result in absolute world coordinates. The renderer adds the per-hatch `world_origin` anchor back in the vertex shader, so clipped hatches with a large origin (e.g. UTM drawings) were drawn double-shifted and lost f32 precision. Subtract the origin again on the way out so the output stays in the same precision-preserving anchor space as the input. Also drop a stale third argument from two xclip tests left over from the world-offset removal, which had broken `cargo test` compilation. Co-Authored-By: Claude Opus 4.8 --- src/scene/pick/xclip.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/scene/pick/xclip.rs b/src/scene/pick/xclip.rs index 4aaebaaff..4d0298e3f 100644 --- a/src/scene/pick/xclip.rs +++ b/src/scene/pick/xclip.rs @@ -241,8 +241,10 @@ pub fn clip_hatch_boundary( if !out.is_empty() { out.push([f32::NAN, f32::NAN]); } + // Lower back into the loop's `world_origin`-relative space so the + // result keeps the same f32-precision anchor the renderer adds back. for p in clipped { - out.push([p[0], p[1]]); + out.push([p[0] - ox, p[1] - oy]); } } } @@ -603,7 +605,7 @@ mod tests { ins.common.xdictionary_handle = Some(h_xdict); let resolved = insert_spatial_filter(&doc, &ins).expect("filter resolves"); - let poly = world_clip_polygon_f64(resolved, &ins, [0.0, 0.0, 0.0]); + let poly = world_clip_polygon_f64(resolved, &ins); assert_eq!(poly.len(), 4); // A polyline half inside, half outside the 0..10 square. @@ -672,7 +674,7 @@ mod tests { ins.set_x_scale(0.1); ins.set_y_scale(0.1); - let poly = world_clip_polygon(&sf, &ins, [0.0, 0.0, 0.0]); + let poly = world_clip_polygon(&sf, &ins); // vert (580,4528) → ×1000 → (580000,4528000) → ×0.1 + insert → // (639668, 4516955). let xs: Vec = poly.iter().map(|p| p[0]).collect();