fix: restore visibility for large-coordinate DXF files after world_offset regression
Three root causes caused all geometry and UCS arrows to disappear: 1. TruckObject::Lines and TruckObject::Text variants returned world-space f32 coordinates without applying world_offset, so fit_all() computed bounds spanning from local space to UTM world space (~4 M m), placing the camera impossibly far from all visible geometry. 2. Ray/XLine entities with unnormalized direction vectors (common in some DXF exporters) produced astronomically large far-point coordinates (up to 1e28) that overwhelmed the camera fit even after the offset fix. Fixed by normalizing the direction vector before multiplying by DISPLAY_EXTENT. 3. Origin-stuck corrupted entities (coordinates ≈ 0 in world space become ≈ -world_offset in local space) pulled the fit_all() bounds far from the actual drawing. Fixed by computing local_extent_max from EXTMIN/EXTMAX (10× safety margin) and skipping points outside that range in fit_all(). Additional hardening: wire_gpu.rs now skips ±inf segments (not just NaN), and snap_pts/key_vertices in all TruckObject variants are offset-corrected. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
a2fb334966
commit
e191315713
4 changed files with 115 additions and 43 deletions
|
|
@ -126,6 +126,10 @@ pub struct Scene {
|
|||
/// Scene centroid subtracted from all coordinates before f32 conversion.
|
||||
/// Eliminates f32 precision loss at large world coordinates (e.g. UTM 4,000,000 m).
|
||||
pub world_offset: [f64; 3],
|
||||
/// Largest local-space coordinate expected from real geometry, derived from
|
||||
/// EXTMIN/EXTMAX (10× safety margin). Used by fit_all() to ignore garbage
|
||||
/// entity coordinates (origin-stuck entities, bad Ray/XLine direction vectors).
|
||||
pub local_extent_max: f32,
|
||||
}
|
||||
|
||||
impl Scene {
|
||||
|
|
@ -157,6 +161,7 @@ impl Scene {
|
|||
bg_color: [0.11, 0.11, 0.11, 1.0],
|
||||
paper_bg_color: [1.0, 1.0, 1.0, 1.0],
|
||||
world_offset: [0.0; 3],
|
||||
local_extent_max: 1e9,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -173,15 +178,22 @@ impl Scene {
|
|||
// Sentinel: DXF files with no geometry have EXTMIN = 1e20, EXTMAX = -1e20.
|
||||
// Fall back to no offset so the scene stays at the origin.
|
||||
let valid = min.x < max.x && min.y < max.y;
|
||||
self.world_offset = if valid {
|
||||
[
|
||||
if valid {
|
||||
self.world_offset = [
|
||||
(min.x + max.x) * 0.5,
|
||||
(min.y + max.y) * 0.5,
|
||||
(min.z + max.z) * 0.5,
|
||||
]
|
||||
];
|
||||
// 10× the EXTMIN→EXTMAX half-diagonal gives fit_all() a threshold to
|
||||
// reject origin-stuck/corrupted entities far outside the drawing area.
|
||||
let hw = ((max.x - min.x) * 0.5) as f32;
|
||||
let hh = ((max.y - min.y) * 0.5) as f32;
|
||||
let hz = ((max.z - min.z) * 0.5).max(1.0) as f32;
|
||||
self.local_extent_max = hw.max(hh).max(hz) * 10.0;
|
||||
} else {
|
||||
[0.0; 3]
|
||||
};
|
||||
self.world_offset = [0.0; 3];
|
||||
self.local_extent_max = 1e9;
|
||||
}
|
||||
}
|
||||
|
||||
/// Public accessor for the block-record handle of the current layout.
|
||||
|
|
@ -2316,12 +2328,26 @@ impl Scene {
|
|||
|
||||
let mut min = glam::Vec3::splat(f32::MAX);
|
||||
let mut max = glam::Vec3::splat(f32::MIN);
|
||||
// Reject points beyond 10× the drawing's EXTMIN→EXTMAX half-size.
|
||||
// These come from origin-stuck entities (y ≈ -world_offset.y after subtraction),
|
||||
// Ray/XLine far-points with bad direction vectors, or corrupt coordinates.
|
||||
let lim = self.local_extent_max;
|
||||
for wire in &wires {
|
||||
for &[x, y, z] in &wire.points {
|
||||
if !x.is_finite() || !y.is_finite() || !z.is_finite() {
|
||||
continue;
|
||||
}
|
||||
if x.abs() > lim || y.abs() > lim || z.abs() > lim {
|
||||
continue;
|
||||
}
|
||||
min = min.min(glam::Vec3::new(x, y, z));
|
||||
max = max.max(glam::Vec3::new(x, y, z));
|
||||
}
|
||||
}
|
||||
// If no usable points found, leave the camera unchanged.
|
||||
if min.x > max.x {
|
||||
return;
|
||||
}
|
||||
if min == max {
|
||||
max += glam::Vec3::splat(1.0);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue