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