Commit Graph
65 Commits
Author SHA1 Message Date
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 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 81db3c37d0 perf: cache hatch/wipeout/image/mesh models per geometry epoch (F+G+H)
Add Arc<Vec<...>>-backed epoch caches for hatches, wipeouts, images, and
meshes — the same pattern used for wires. build_primitive() now returns
an O(1) Arc refcount bump on navigation frames instead of rebuilding
every collection from scratch.

Also wrap ImageModel.pixels in Arc<Vec<u8>> so cloning an ImageModel is
O(1) regardless of image resolution.

Navigation frames no longer copy pixel data, tessellated hatch boundaries,
or mesh geometry — all per-frame CPU work on unchanged geometry is now
eliminated.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 11:34:52 +03:00
Hakan SevenandClaude Sonnet 4.6 d1ecaf4695 perf: eliminate per-frame re-tessellation and GPU re-upload in large files
Add two complementary render caches that make mouse navigation essentially
free regardless of file size:

Option A – Wire tessellation cache: entity_wires_arc() caches the
tessellated Vec<WireModel> keyed by geometry_epoch and returns an Arc,
so navigation frames (no preview wires) incur zero Vec clones and zero
tessellation work. Primitive::wires changed to Arc<Vec<WireModel>>.

Option B – GPU buffer cache: Pipeline stores cached_epoch; prepare()
skips all upload_wires/hatches/images/meshes calls when the epoch is
unchanged, writing only the 192-byte camera uniform instead.

geometry_epoch is a process-wide AtomicU64 incremented by every Scene
mutation (add/erase entity, selection, layer visibility, layout switch,
populate_*, grip, transform, copy, clear, preview wires). Using a global
counter rather than a per-scene counter prevents two tabs that happen to
have the same local bump count from sharing a cached_epoch value, which
was causing the first file's geometry to remain on screen after opening a
second file.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-26 02:13:31 +03:00
Hakan SevenandClaude Sonnet 4.6 a6592cc9bc fix: ViewCube hover, glow, centroids, corner geometry and snap angles
- Hide OS crosshair and drawn crosshair when cursor is over ViewCube area
- Enhanced hover glow in WGSL shader (blue tint + brightness boost)
- Fixed region_centroids() Y-axis sign for all FRONT/BACK-related regions
- Swapped corner geometry assignments (TPF↔TBK, BTF↔BBK) to match
  intended FRONT/BACK semantics (sy=-1 = FRONT, sy=+1 = BACK)
- Corrected all snap_angles: yaw_pitch_to_quat(0,0) places eye at -Y
  (FRONT view), so FRONT=0 and BACK=PI — cascaded through edges/corners

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 19:11:19 +03:00
Hakan SevenandClaude Sonnet 4.6 42048362e2 fix: MSAA resolve no longer overwrites widget backgrounds
MSAA and depth textures are now sized to the shader widget's clip
bounds instead of the full surface. The resolve writes to a matching
clip-sized intermediate texture; a blit pass (blit.wgsl, viewport
trick) then copies the result to the exact clip region of the surface
target, leaving all other widgets untouched.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 12:20:47 +03:00
Hakan SevenandClaude Sonnet 4.6 c12b30ad3d feat: 4× MSAA anti-aliasing for main drawing pipelines
All main render pipelines (wire, hatch, image, mesh) now use 4×
multisampling. Drawing passes render to a dedicated MSAA color buffer;
a final empty resolve pass transfers the anti-aliased result to the
iced surface target. The ViewCube renders post-resolve at 1× to avoid
pipeline incompatibility. Depth buffer also upgraded to 4× MSAA.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 00:52:38 +03:00
Hakan SevenandClaude Sonnet 4.6 c184535d5e fix: render wipeout fills after wire pass so they correctly mask wires
Previously wipeout solid fills were part of the hatch pass (pass 1),
drawn before wires (pass 5), so all wires appeared on top of the
wipeout. This fix moves wipeout fills into a dedicated pass 6 that
runs after wires, so the background-colored polygon correctly covers
the lines/text beneath it — matching AutoCAD behaviour.

- Scene.wipeout_models() separated from synced_hatch_models()
- Primitive.wipeout_hatches populated via wipeout_models()
- Pipeline.gpu_wipeouts + upload_wipeouts() + pass 6 after wires

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 23:44:36 +03:00
Hakan SevenandClaude Sonnet 4.6 c2f1c9078f fix: use file_path as GPU texture debug label to eliminate dead_code warning
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 23:35:13 +03:00
Hakan SevenandClaude Sonnet 4.6 4312b6c3a5 feat: raster image render pipeline (IMAGE command + GPU textured quad)
- Add IMAGE / IMAGEATTACH / IM command with async file-picker (rfd)
- src/scene/image_model.rs: ImageModel with RGBA pixel data + quad corners
- src/scene/pipeline/image_gpu.rs: ImageGpu with wgpu texture, sampler, opacity uniform
- src/scene/pipeline/mod.rs: image render pipeline (pass 2, between hatches and meshes)
- src/scene/render.rs: include images in Primitive, call upload_images in prepare
- src/scene/mod.rs: images HashMap, populate_images_from_document, cache on add_entity
- src/modules/home/draw/raster_image.rs: ImageCommand (two-click: origin + width, aspect-correct preview)
- src/io/mod.rs: pick_image_file() async helper (file dialog + dimension decode)
- app: ImagePick / ImagePickResult messages, populate on file open and undo/redo

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 23:19:08 +03:00
Hakan Seven d2fdac7f1e first commit 2026-03-22 14:56:27 +03:00