diff --git a/src/entities/lwpolyline.rs b/src/entities/lwpolyline.rs index 910f8f329..538288f22 100644 --- a/src/entities/lwpolyline.rs +++ b/src/entities/lwpolyline.rs @@ -601,13 +601,19 @@ impl crate::entities::traits::Transformable for LwPolyline { } } -pub(crate) fn wide_fills(pl: &acadrust::entities::LwPolyline) -> Vec> { +/// Solid-fill bands for a wide LwPolyline, plus the `world_origin` they are +/// relative to. The band vertices are small f32 offsets from `origin` (the +/// first vertex), so the relative-to-eye hatch fill keeps sub-unit precision at +/// UTM-scale coordinates — building them in absolute f32 collapsed the band into +/// a string of squares far from the origin. +pub(crate) fn wide_fills(pl: &acadrust::entities::LwPolyline) -> ([f64; 2], Vec>) { let hw_const = (pl.constant_width / 2.0) as f32; let verts = &pl.vertices; let n = verts.len(); if n < 2 { - return vec![]; + return ([0.0; 2], vec![]); } + let origin = [verts[0].location.x, verts[0].location.y]; let seg_count = if pl.is_closed { n } else { n - 1 }; let mut out = Vec::new(); for i in 0..seg_count { @@ -626,15 +632,21 @@ pub(crate) fn wide_fills(pl: &acadrust::entities::LwPolyline) -> Vec Vec> { +/// Solid-fill bands for a wide Polyline2D, plus the `world_origin` they are +/// relative to (the first vertex). See `lwpolyline::wide_fills` — offsets are +/// f32 from `origin` so the band stays precise at UTM-scale coordinates. +pub(crate) fn wide_fills(pl: &acadrust::entities::Polyline2D) -> ([f64; 2], Vec>) { let hw_default = (pl.start_width.max(pl.end_width) / 2.0) as f32; let verts = &pl.vertices; let n = verts.len(); if n < 2 { - return vec![]; + return ([0.0; 2], vec![]); } + let origin = [verts[0].location.x, verts[0].location.y]; let seg_count = if pl.is_closed() { n } else { n - 1 }; let mut out = Vec::new(); for i in 0..seg_count { @@ -707,13 +711,19 @@ pub(crate) fn wide_fills(pl: &acadrust::entities::Polyline2D) -> Vec (&pl.common, crate::entities::lwpolyline::wide_fills(pl)), - EntityType::Polyline2D(pl) => (&pl.common, crate::entities::polyline::wide_fills(pl)), + let (common, fill_origin, fills) = match entity { + EntityType::LwPolyline(pl) => { + let (o, f) = crate::entities::lwpolyline::wide_fills(pl); + (&pl.common, o, f) + } + EntityType::Polyline2D(pl) => { + let (o, f) = crate::entities::polyline::wide_fills(pl); + (&pl.common, o, f) + } _ => continue, }; if fills.is_empty() { @@ -4792,7 +4798,7 @@ impl Scene { color, angle_offset: 0.0, scale: 1.0, - world_origin: [0.0; 2], + world_origin: fill_origin, vp_scissor: None, draw_depth: depth_map.get(&common.handle.value()).copied().unwrap_or(0.0), });