fix: identify DWG sheet viewport by center=(0,0) instead of scale heuristic

Debug output revealed the sheet viewport has id=0 (DWG reader never sets
the field), scale=0.8965 (not ≈1.0, so the 0.02 tolerance missed it),
and center=(0.0, 0.0) — exactly at the paper-space origin.

In DWG format the overall/sheet viewport always has its center at the
origin. Content viewports are placed at their actual paper positions and
always have a non-zero center. Switching from the scale heuristic to the
center-position check makes the detection reliable regardless of what
scale value the sheet viewport happens to carry.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Hakan Seven 2026-05-02 15:15:13 +03:00
commit 2eb19a21bb

View file

@ -209,20 +209,15 @@ impl Scene {
if vp.id == 1 { return false; } if vp.id == 1 { return false; }
if vp.id > 1 { return true; } if vp.id > 1 { return true; }
// id ≤ 0: DWG files never write group-code 69 (viewport id), so all // id ≤ 0: DWG files never write group-code 69 (viewport id), so all
// viewports arrive with id=0. Distinguish the sheet viewport by scale: // viewports arrive with id=0.
// the sheet ("overall") viewport has view_height ≈ vp.height → scale ≈ 1. //
// True content viewports have deliberate drawing scales (1:50, 1:100 …) // In DWG format the sheet ("overall") viewport always has its center at
// whose scale value is far from 1.0. The old check also required the // the paper-space origin (0, 0). Content viewports are placed at their
// center to be at the origin, but the sheet viewport center is the // actual position on the paper and therefore have a non-zero center.
// paper centre (e.g. 105, 148.5 for A4), so that condition failed for // Using center position is more reliable than a scale heuristic because
// DWG files and incorrectly classified the sheet viewport as a content // the sheet viewport's scale is not always exactly 1:1 (observed: 0.8965
// viewport — making it tessellated and enterable via double-click. // in real-world files, which the old 0.02 tolerance missed entirely).
let scale = if vp.view_height.abs() > 1e-9 { vp.center.x.abs() >= 0.5 || vp.center.y.abs() >= 0.5
vp.height / vp.view_height
} else {
1.0
};
(scale - 1.0).abs() >= 0.02
} }