Commit Graph
128 Commits
Author SHA1 Message Date
HakanandClaude Sonnet 4.6 4b5f4c7ee8 fix(hatch): sync color from entity in synced_hatch_models
Color was read from the stale HatchModel cache instead of the live
entity, so property-panel color changes appeared on boundaries (wire)
but not on the hatch fill pattern.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-12 17:33:16 +03:00
Hakan ca07268c7c cargo fmt 2026-05-12 10:36:15 +03:00
Hakan 468cbde5e1 fix(hatch): improve angle handling for circular arcs in tessellation 2026-05-12 09:41:41 +03:00
Hakan Seven 773a5f74cb fix(hatch): more improvement on arc boundary and pattern 2026-05-10 20:29:39 +03:00
Hakan Seven 461d0c5d86 hatch boundary correction for cw ccw 2026-05-09 23:56:04 +03:00
HakanandClaude Sonnet 4.6 321433ee45 fix(render): cap wire segments to prevent GPU memory exhaustion
Adds two-layer protection against large entities crashing the renderer:
- MAX_SEGS_PER_WIRE (100K): per-entity hard cap, excess segments truncated
- MAX_TOTAL_SEGS (3M): scene-level budget in upload_wires, excess wires skipped

Both limits log a warning to stderr when triggered.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 17:24:28 +03:00
HakanandClaude Sonnet 4.6 4b4c0d31d2 chore: switch acadrust to GitHub source, fix removed is_annotative field
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 09:50:02 +03:00
Hakan Seven 048bb41aef feat(render): solid fill for PolyfaceMesh and PolygonMesh entities
PolyfaceMesh and PolygonMesh were wireframe-only. They now render with
the same flat-color solid fill as Face3D entities.

- Add fill_tris: Vec<[f32;3]> to TruckEntity and WireModel
- PolyfaceMesh: fan-triangulate each face into fill_tris
- PolygonMesh: triangulate each grid quad into fill_tris
- tessellate.rs Lines branch: apply world_offset to fill_tris
- Face3DGpu::from_wires: collect fill_tris from all wires in addition
  to Face3D key_vertices quads
- upload_face3d: pass all_wires so fill_tris are batched into one draw call
2026-05-06 23:24:26 +03:00
Hakan Seven d30f80f963 chore: suppress dead_code warning on compute_and_set_world_offset 2026-05-06 23:07:37 +03:00
Hakan Seven 2da3640b45 perf: build hatch/image/mesh caches off the UI thread
Parsing + DerivedCaches construction now runs entirely in a dedicated
OS thread inside open_path(). FileOpened handler only assigns the
pre-built caches, keeping the UI thread free during file load.

- Add build_derived_caches(): parallel hatch + mesh tessellation via rayon
- Extend Message::FileOpened / open_path return type with DerivedCaches
- Drop populate_*_from_document() calls from FileOpened handler
2026-05-06 23:04:53 +03:00
Hakan Seven 45f9f96c93 perf: implement L–S performance improvements
- L: pre-project wire endpoints to screen before ApparentIntersection pair loops
- O+S: tight per-segment AABB cull + move a0/a1 Vec3 outside inner snap loop
- P: epoch-cached entity→block reverse map replaces O(E×B) scan
- Q: lazy per-point projection in hit tests eliminates per-wire Vec<Point> alloc
- R: HatchModel.boundary Arc<Vec> so clone is pointer bump not heap alloc
2026-05-06 22:42:22 +03:00
Hakan SevenandClaude Sonnet 4.6 b83c982bc2 fix(scene): hatch pattern scale and per-entity annotative check
- Hatch pattern_scale multiplied by annotation_scale in model space so
  pattern density stays consistent when CANNOSCALE changes
- Annotative check now uses AcAnnoPO xdata (R2007+ marker) instead of
  relying solely on group-code-293 flag; falls back to is_annotative
  for files with no xdata (old DXF backward compat)
- acadrust patched to local path for is_annotative field

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 22:19:28 +03:00
HakanandClaude Sonnet 4.6 0e5dec0948 feat: annotation scale system (CANNOSCALE, PSLTSCALE, MultiLeader, Leader)
- Scale popup dropdown replaces cycle behavior; paper-space viewport scale
  editable when a viewport is active/selected
- CANNOSCALE persisted via DXF $USERR1 (read on open, write on save)
- PSLTSCALE: linetype dash lengths scaled by viewport anno_scale so dashes
  appear uniform physical size in paper space
- MultiLeader: arrow size, dogleg length, and text height scale with
  anno_scale; leader line paths (world coords) stay fixed
- Leader: arrow size and hookline length scale with anno_scale; also
  corrects world_offset subtraction that was previously deferred to the
  TruckObject::Lines path

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 17:50:46 +03:00
Hakan 534e4ff26b feat: implement Grippable and PropertyEditable traits for Solid3D, Region, and Body; add snap points and geometry properties 2026-05-06 10:00:37 +03:00
Hakan SevenandClaude Sonnet 4.6 899b3f4796 feat: GPU scissor rect for paper-space viewport wires
Viewport-projected wires now clip at pixel level to their viewport boundary.

- WireModel.vp_scissor: Option<[f32; 4]> — paper-space bbox set on projection
- WireGpu.vp_scissor carries it through to the draw loop
- Pipeline.compute_wire_scissors() converts paper→NDC→pixel each frame
- render() calls set_scissor_rect() per wire, reset after viewport group
- INTEGRATION_GAPS.md: Viewport ⚠️ → ✅, all 51 gaps resolved

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 07:12:05 +03:00
Hakan SevenandClaude Sonnet 4.6 27aca41dd1 feat: plinegen + SAB parsing for Solid3D/Region/Body
LwPolyline PLINEGEN=0 (DXF default): emit SegmentedLines with NaN
separators between vertex-to-vertex segments; wire_gpu resets
arc-length to 0 after each NaN so linetype pattern restarts per vertex.
PLINEGEN=1: existing Contour path unchanged (continuous pattern).
WireModel gains plinegen field propagated through tessellate pipeline.

Solid3D/Region/Body: call SabReader::read() when parse_sat() returns
None due to binary SAB format (DWG files / newer AutoCAD exports).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 06:55:28 +03:00
Hakan SevenandClaude Sonnet 4.6 63b17547f9 fix: warn on missing non-ASCII CXF glyphs; close ellipse snap gap
cxf.rs: missing non-ASCII glyphs now emit eprintln! once per font+char
pair via a global Mutex<HashSet> dedup set. ASCII chars silent (expected).

INTEGRATION_GAPS.md: ellipse partial arc snap marked done — endpoints are
correctly emitted via key_vertices → SnapType::Endpoint in snap engine.
Unicode warning gap closed. plinegen behaviour documented.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-05 20:20:16 +03:00
Hakan Seven 603d07412e refactor: replace angle calculations with radians for consistency 2026-05-03 21:58:38 +03:00
Hakan SevenandClaude Sonnet 4.6 9b29db61d4 feat: apply OCS→WCS transform to Hatch wire outline boundary edges
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 20:24:38 +03:00
Hakan SevenandClaude Sonnet 4.6 4527819b2d chore: remove stale multi-viewport limitation comment from ViewportPaneMode
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 20:18:08 +03:00
Hakan SevenandClaude Sonnet 4.6 5a7ebbbb38 feat: add Node snap points to dimension defpoints
Dimension measurement origin points (first_point, second_point,
definition_point, angle_vertex, etc.) are now emitted as Node snap
hints so OSNAP Node mode can locate them precisely without relying on
the tessellated geometry wire alone.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 17:15:41 +03:00
Hakan SevenandClaude Sonnet 4.6 000f74f951 feat: render CircularArc and EllipticArc hatch boundary edges
Hatch boundaries with arc or ellipse edges were silently dropped from
the wire outline, leaving gaps in the hatch contour. CircularArc and
EllipticArc boundary edges are now tessellated as polyline segments and
their centers are emitted as Center snap hints.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 17:15:02 +03:00
Hakan SevenandClaude Sonnet 4.6 674a94f756 feat: implement OCS→WCS transform for Arc, Circle, and Line
Entities carrying a non-standard extrusion normal (normal ≠ (0,0,1)) were
rendered flat in the XY plane. The DXF arbitrary-axis algorithm is now
implemented in scene::transform::{ocs_axes, ocs_point_to_wcs} and applied
during tessellation of Arc, Circle, and Line so they render correctly on
tilted planes in 3D DXF files.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 17:13:42 +03:00
Hakan SevenandClaude Sonnet 4.6 c7b050fb09 feat: emit Insertion snap point for block references
Block INSERTs are expanded into sub-entity wires for rendering but the
OSNAP Insertion hint at the block reference origin was never generated.
Now a zero-geometry WireModel carrying the Insertion snap hint is appended
so OSNAP Insertion mode can locate the block origin.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 17:08:20 +03:00
Hakan SevenandClaude Sonnet 4.6 2eb19a21bb 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>
2026-05-02 15:15:13 +03:00
Hakan SevenandClaude Sonnet 4.6 b346eb4d6e fix: remove dead code warning and fix sheet viewport double-click in DWG files
Remove unused `screen_delta_to_world` camera method (superseded by the
corrected pan_active_viewport formula).

Fix `is_content_viewport`: the old geometry fallback required the viewport
center to be near the origin, but DWG files never write the viewport id
field (stays 0) and the sheet viewport center is the paper centre
(e.g. 105, 148.5 mm for A4) — not the origin. This caused the sheet
viewport to be classified as a content viewport in DWG files, making it
both tessellated (border visible) and enterable via double-click.

The new heuristic uses only the scale: a sheet viewport has scale ≈ 1:1
(view_height ≈ paper height); true content viewports have deliberate
drawing scales (1:50, 1:100, …) that are far from 1.0.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-02 14:55:12 +03:00
Hakan SevenandClaude Sonnet 4.6 fbb6a20f10 fix: correct MSPACE viewport pan speed to match mouse movement
The old formula (distance × 0.001) was a fixed approximation that ignored
the paper camera's current zoom level and the viewport's paper-space size,
causing panning to feel sluggish.

New formula: model_per_pixel = (2 × paper_half_h / canvas_height) × (view_height / vp_height)
This converts screen pixels → paper-space mm → model units correctly,
making the content follow the cursor regardless of paper zoom or scale.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 21:39:05 +03:00
Hakan SevenandClaude Sonnet 4.6 93614ab554 fix: apply global LTSCALE to linetype pattern rendering
Entity linetype_scale is a per-entity multiplier applied on top of the
document-level $LTSCALE header variable. The previous code used only the
entity scale (defaulting to 1.0), ignoring $LTSCALE entirely. Drawings
with a non-default LTSCALE showed dash patterns at the wrong size.

Effective scale is now: document.header.linetype_scale * entity linetype_scale.
Applied in both render::render_style_for and the complex-linetype path in
tessellate_entity.

Fixes part of #10

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 21:13:56 +03:00
Hakan SevenandClaude Sonnet 4.6 ebef467720 fix: hide sheet viewport border and improve crossing selection
Two layout-related fixes:

1. Sheet viewport (id=1) was rendered as a grey rectangle border in
   paper-space layouts. It is the paper boundary, not a user viewport,
   and should not appear. Now filtered via is_content_viewport() before
   tessellation. The redundant id==1 color branch is removed.

2. Box crossing-selection (right-to-left drag) only detected wires whose
   vertex points fell inside the selection box. Large entities like viewport
   frames could be visually crossed without any corner inside the box and
   would not be selected. Added segment-box edge intersection tests so any
   wire segment that crosses the selection rectangle boundary is included.

Fixes part of #10

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 21:12:14 +03:00
Hakan SevenandClaude Sonnet 4.6 01943c5b8d fix: correct paper-space grip projection and MTEXT attachment point rendering
- Grip points in paper space now use the 2-D linear to_px transform
  (tx/ty/ortho_size) instead of the 3-D view_proj matrix, matching the
  coordinate system used by PaperCanvas
- world_offset is no longer subtracted from paper-space entity grip
  positions — paper-space coordinates are already unoffset (same rule
  as wire tessellation in wires_for_block)
- MTEXT v_offset corrected for all attachment points: CXF glyphs sit
  on the baseline and extend upward, so Top attachment needs v_offset=-h,
  Bottom needs (n_lines-1)*line_h, Middle is the midpoint of the two

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 12:16:46 +03:00
Hakan SevenandClaude Sonnet 4.6 3298ebff91 fix: use PlotSettings paper dimensions for correct paper-space rendering
paper_limits() now reads paper_width/paper_height/plot_rotation from the
Layout object (populated by a patched acadrust from the embedded DWG
PlotSettings). This fixes layouts where min/max_limits do not match the
physical paper size (e.g. A4 portrait content inside A3 landscape limits).

DXF files use codes 44/45/73 from raw_plot_settings_codes; DWG files use
the PlotSettings block embedded in the LAYOUT object. Both fall back to
min/max_limits when paper_width is zero.

Depends on HakanSeven12/acadrust feat/layout-paper-dimensions (PR #21 on
hakanaktt/acadrust); using that fork until the PR is merged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 08:04:35 +03:00
Hakan SevenandClaude Sonnet 4.6 cbb37a0909 fix: persist camera in View table and fix pitch clamp for exact top/bottom views
- Save camera to named View table entries (H7CAD_Camera_Model / H7CAD_Camera_<layout>)
  on every navigation change; restore from these entries on file open and tab switch.
  acadrust's DWG writer overrides *Active VPort view_height/view_center with
  zoom-extents values, but leaves the View table untouched, so this survives save.
- Fix pitch recovery: clamp vd.z to [-1, 1] instead of [-0.999, 0.999] so that
  asin(1.0) = π/2 exactly for plan/top views, preventing the subtle tilt on reload.
- Fix IEEE 754 edge case: atan2(+0, -0) = π for plan view direction (0,0,1);
  special-case yaw = 0 when both vd.x and vd.y are near zero.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 07:43:45 +03:00
Hakan SevenandClaude Sonnet 4.6 35e487934c fix: correct yaw recovery from view_direction vector
view_dir = rotation * Z = (sin(yaw)*cos(pitch), -cos(yaw)*cos(pitch), sin(pitch))
so yaw = atan2(x, -y), not atan2(x, y).
The sign error caused a 180-degree Z rotation on every save/reload cycle.
Applies to apply_active_vport_camera, apply_sheet_viewport_camera, and
camera_for_viewport.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 07:20:55 +03:00
Hakan SevenandClaude Sonnet 4.6 8f90a68930 feat: restore and persist saved camera position per layout
- On file open and layout tab switch, restore the camera from the
  document's saved view (*Active VPort for model space, sheet viewport
  for paper space) instead of fitting to wire bounds.
- After any zoom/pan/rotate, write the new camera position back to the
  document and mark the file dirty so it is saved with the file.
- Uses last_synced_camera_gen to avoid marking the file dirty on the
  initial camera restore.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 07:07:19 +03:00
Hakan SevenandClaude Sonnet 4.6 ed94a5b81f fix: correct viewport projection by converting view_target to wire-space
Model entity wires are tessellated with world_offset subtracted for GPU
precision, but view_target/view_center were raw model coordinates.
Subtracting world_offset from view_target aligns both coordinate systems
so model content projects correctly into viewport rectangles in paper space.

Also fixes scale priority (view_height before custom_scale) and adds
view_center DCS offset to the projection, completing the paper-space
viewport rendering.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 06:42:06 +03:00
Hakan SevenandClaude Sonnet 4.6 6a0b9169d6 fix: identify user viewports by geometry when id is 0 or negative
The acadrust DWG reader never assigns a viewport id (always 0).
Some DXF exporters use id=-1 for all viewports.  In both cases the
previous id > 1 check excluded every viewport from content rendering.

Replace is_user_viewport_id(id) with is_content_viewport(vp) that
uses a geometry heuristic for unknown ids (0 / negative):
  - id=1           → always sheet viewport (excluded)
  - id≥2           → always user viewport  (included)
  - id=0 or id<0   → sheet if center≈(0,0) AND scale≈1.0, else user

This allows DWG files and non-standard DXF files to display model
content inside their paper-space viewports and be entered via
double-click.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 22:06:43 +03:00
Hakan SevenandClaude Sonnet 4.6 66a73b00e1 fix: make viewports from external DXF/DWG files visible and enterable
Two root causes prevented paper-space viewports from loading correctly:

1. acadrust's ViewportStatusFlags::from_bits() maps bit 0 → is_on, but
   the real DXF/DWG spec uses bit 15 (0x8000) for "viewport on". Post-load
   fixup in io/mod.rs now corrects this for both DXF and DWG files: when
   bit 0 is clear but bit 15 is set, is_on is forced true and locked is
   derived from bit 14 (0x4000).

2. Some DXF exporters write id=-1 for all viewport entities instead of the
   standard id=1 (sheet) / id≥2 (user) convention. The is_user_viewport_id()
   helper now treats any id ≠ 0 and ≠ 1 as a user viewport, covering both
   the standard id≥2 and the non-standard id=-1 cases.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 21:57:02 +03:00
Hakan SevenandClaude Sonnet 4.6 00e61a1301 fix: correct entity color adaptation for viewport content in paper space
Model-space entities shown through a viewport were tessellated using
paper_bg_color (light), but the interactive viewport pane renders them
on bg_color (dark), causing white/black entities to appear incorrectly.

- model_wires_for_viewport: tessellate with bg_color so the viewport
  pane (dark background) gets correctly adapted entity colors
- viewport_content_wires: re-adapt projected wire colors using
  paper_bg_color before rendering onto the paper canvas

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 21:39:38 +03:00
HakanandClaude Sonnet 4.6 d06db45950 feat: adapt white/black entity colors to background luminance
White entities on light backgrounds (e.g. paper space) render as black;
black entities on dark backgrounds (e.g. model space) render as white.
All other colors pass through unchanged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 10:00:46 +03:00
Hakan SevenandClaude Sonnet 4.6 7065bfa935 fix: do not apply world_offset to paper-space entities
Paper-space entities (wires, hatches, wipeouts) live in sheet
coordinates (~mm scale) and do not need the model-space centring
shift.  world_offset was incorrectly subtracted from their coordinates,
displacing all paper-space geometry away from the paper sheet.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 21:38:48 +03:00
Hakan SevenandClaude Sonnet 4.6 1a19a841e6 fix: correct polyline arc direction, text precision, Face3D edge color, buffer chunking
- fix: polyline arc center sign was inverted (- → +) causing arcs to render on the
  wrong side in LwPolyline and Polyline2D
- fix: store glyph strokes in local space with f64 origin so world_offset subtraction
  uses f64 precision; prevents blocky text at large UTM coordinates
- fix: Face3D fill darkened to 45% so edge wires are visually distinct from fill
- fix: wire batch vertex buffer chunked to 256 MB GPU limit (was panic on large files)
- fix: gpu_face3d_edges changed from Option<WireGpu> to Vec<WireGpu> to support chunks

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 20:58:44 +03:00
Hakan Seven 02203dba93 Revert "fix: skip degenerate triangle for 3-corner Face3D"
This reverts commit 517af91245.
2026-04-29 20:34:18 +03:00
Hakan SevenandClaude Sonnet 4.6 517af91245 fix: skip degenerate triangle for 3-corner Face3D
acadrust Face3D encodes triangles by setting fourth_corner == third_corner.
The fill builder was emitting a zero-area second triangle for these cases.
Now checks the p2==p3 distance and skips the second triangle.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 21:57:38 +03:00
Hakan SevenandClaude Sonnet 4.6 298098e764 perf: dedicated Face3D shader — N draw calls → 2
3DFACE entities previously created one WireGpu buffer per entity,
resulting in N separate draw calls per frame. For files with large
triangle meshes this was the dominant GPU CPU overhead.

New pipeline:
- face3d.wgsl: simple flat-color vertex + fragment shader (MVP only,
  no quad expansion, no pattern distance computation)
- Face3DGpu: batches ALL Face3D entities into a single TriangleList
  buffer (6 vertices per face, per-vertex color) — 1 draw call
- WireGpu::from_batch: merges N Face3D edge wire models into one
  quad-expanded buffer for edge rendering — 1 draw call
- split_face3d_wires: separates face3d from other wires at Primitive
  build time via document handle lookup (O(N), once per epoch)

Hit-testing via WireModel (CPU) is unaffected — face3d wires remain
in entity_wires_arc() and hit_test_wires() as before.

Before: N 3DFACE → N draw calls, N × 96 B/vertex WireVertex
After:  N 3DFACE → 2 draw calls (fill + edges), 28 B/vertex fill

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 21:53:31 +03:00
Hakan SevenandClaude Sonnet 4.6 5f69d8c3f0 fix: apply world_offset to hatch, solid, and wipeout boundary coordinates
hatch_model_from_dxf(), solid_hatch_model(), and wipeout_boundary_2d()
were converting DXF world-space coordinates directly to f32 without
subtracting world_offset. After the world_offset change moved all wire
geometry to local space, hatches/solids/wipeouts rendered at the wrong
position (displaced by the centroid offset, up to ~4M m for Turkish UTM).

All three functions now accept world_offset and apply it to every
boundary vertex before the f64→f32 cast.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 18:21:40 +03:00
Hakan SevenandClaude Sonnet 4.6 e191315713 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>
2026-04-27 18:04:35 +03:00
Hakan SevenandClaude Sonnet 4.6 a2fb334966 fix: world_offset precision fix for large-coordinate DXF files (e.g. Turkish UTM)
Subtracts the DXF header extents centroid (world_offset) from all coordinates
in f64 BEFORE casting to f32. This eliminates the ~0.5 m ULP error that occurs
at 4,000,000 m UTM coordinates and caused geometry to disappear on zoom-out.

- Scene: adds world_offset field + compute_and_set_world_offset() method
- tessellate.rs: threads world_offset through all f64→f32 conversions
  (legacy_geometry, dimension_geometry, solid_wire_fallback, multileader)
- truck_tess.rs: to_local() helper already in place from prior session
- mod.rs: tessellate_entity() and entity_aabb() apply world_offset
- update.rs: compute_and_set_world_offset() called after doc load
- cmd_result.rs / solid3d_cmds.rs: pass correct offset to truck tessellators

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 07:41:38 +03:00
Hakan SevenandClaude Sonnet 4.6 e38638502e fix: selected wires always visible on top of occluding geometry
Changed selection overlay pipeline from depth_compare=Greater to
depth_compare=Always so selected wires are redrawn at full brightness
after all other passes, making them visible regardless of what is in
front of them.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 03:04:31 +03:00
Hakan SevenandClaude Sonnet 4.6 c27927c2b3 fix: X-ray ghost pass for selected wires occluded by other geometry
Selected wires are now visible through occluding objects. A second
wire_xray pipeline (depth_compare=Greater, depth_write_enabled=false)
renders 25%-alpha ghost copies of selected wires only where they are
behind the depth buffer, leaving fully-visible portions at full glow
brightness unchanged.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 03:01:42 +03:00
Hakan SevenandClaude Sonnet 4.6 392f4503d8 feat: complex linetype text elements and ellipse quadrant snaps
Complex linetypes now render embedded text elements (e.g. GAS_LINE's
"GAS" labels): the LtSegment::Text variant is parsed from LIN files,
scaled along with shape/dash segments, and tessellated via
cxf::tessellate_text_ex aligned to the linetype direction.

Full ellipses gain four Quadrant snap hints at ±major/±minor axis
endpoints in addition to the existing Center snap, matching AutoCAD
snap behaviour.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 02:34:51 +03:00