4 Commits
Author SHA1 Message Date
Hakan SevenandClaude Opus 4.7 de37ee04bf fix(scene): viewport auto-fit fallback + f64-precision projection
Three changes to make paper-space viewports render correctly on
UTM-scale drawings whose viewports were saved with default
view_target=(0, 0, 0) and a view_center pointing at empty WCS:

1. **Auto-fit fallback.** When the saved view's WCS rect doesn't
   overlap the IQR-bounded content cluster (`world_offset ±
   local_extent_max`), override `view_center` with `world_offset` and
   recompute `view_height` to fit the cluster into the paper viewport.
   Matches AutoCAD's silent auto-fit-on-open for stale / uninitialized
   viewports; without it those viewports rendered blank.

2. **f64 projection inner loop.** The previous f32 path computed
   `(wire_offset_rel - target_offset_rel).dot(view_right) -
   view_center` by subtracting values at ~5e6 magnitude (f32 ULP
   ~0.5 m) to land on a small paper offset. The cancellation produced
   centimetre-scale jitter on paper output even when the model was
   clean. Reconstruct the wire WCS coord, subtract the display center,
   and dot-project in f64; cast to f32 only at the final paper
   position where magnitudes are bounded by the viewport rect.

3. **examples/inspect_viewports.rs** — diagnostic that dumps every
   viewport's saved view fields (view_target, view_center, view_height
   vs paper height, custom_scale, status flags) plus drawing-level
   insertion_units and model-space extents. Used to verify that
   acadrust's DWG reader reads view_height correctly; the
   `view_height == vp.height` patterns observed on real files turn out
   to be genuine "default 1:1" file content rather than a reader bug
   (a round-trip test through DwgWriter / DwgReader survives all
   per-viewport values).

Also: switch the `acadrust` patch from `HakanSeven12/acadrust@feat/
expose-blockrecord-is-loaded` (a stale branch with the abandoned
is_loaded experiment) to `hakanaktt/acadrust@main`. Upstream main
now carries the layout paper-dimensions and mirrored-arc fixes that
this branch used to add — plus PR #20's DXF reading fixes that the
old branch was missing.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-05-16 19:32:36 +03:00
HakanandClaude Opus 4.7 78cbb5570e perf(scene): frustum-cull wires using camera view AABB
Block defns and top-level entities now know their world-space XY
AABB, and `tessellate_entity` / `expand_insert` early-out for anything
that doesn't intersect the camera's view rect. Tested commit-only on
time_open (correct subset emitted with default camera); GUI run
pending user verification.

Cache plumbing:
  - `LocalWire` / `BlockDefn` carry `aabb_local` (post-build recursive
    union over nested defns).
  - `Scene::view_world_aabb()` derives a 25%-margined world rect from
    the active camera + last-seen render aspect.
  - `wire_cache` / `paper_sheet_cache` keys widen to
    `(geometry_epoch, camera_generation)` so pan/zoom invalidates the
    cached wire list — and pipeline `cached_epoch` widens to match
    so the GPU re-uploads on view change.
  - `XrefStatus::Unloaded` ack already shipped — orthogonal to this.

Also adds `examples/xref_states.rs` to dump per-block_record xref
metadata for diagnosing the is_loaded / unloaded distinction.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-05-14 13:52:04 +03:00
Hakan SevenandClaude Opus 4.7 03555ce8bd chore: expose lib target + open-path profiling examples
Examples can't import from a bin-only crate, so add a thin lib.rs that
re-exports the existing modules. Used by the new examples that helped
diagnose the freeze fixed in the previous commit.

- examples/time_open: times parse / purge / cache / first-wires phases
- examples/inspect_insert: lists Insert blocks with sub-entity counts
- examples/find_raster: dumps RasterImage path + dimensions

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-05-13 23:02:54 +03:00
HakanandClaude Opus 4.7 b2588e1790 feat(io): drop parser-garbage entities at load time
acadrust's DWG reader occasionally desynchronises on certain files
(observed on render.dwg: 1519 of 1763 LwPolylines arrived with non-unit
normals in the 1e200+ range and 100k phantom vertices). Tessellating
those entities allocates gigabytes and produces NaN-laden wires,
freezing the UI.

Add a pre-tessellation guard that scans freshly loaded documents and
drops any entity failing a cheap sanity check: non-unit normal,
non-finite or absurd coordinate, or vertex count above 100k. Count of
dropped entities is threaded through DerivedCaches and surfaced as a
warning in the command line so the user knows the file was patched up
on the way in.

Same file in DXF form parses cleanly (0 corrupt), so this is strictly
a DWG-path workaround until the upstream parser bug is fixed.

The new examples/inspect_polyline.rs is a one-off diagnostic that dumps
LwPolyline/Polyline2D/Polyline3D fields plus a corrupt-entity count;
useful for narrowing down the acadrust bug.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-05-13 10:00:16 +03:00