Commit Graph
350 Commits
Author SHA1 Message Date
HakanandClaude Opus 4.7 2f751c08f4 fix(scene): drop Z gate in fit_all so high-elevation entities show
Civil 3D files can legitimately carry profile geometry at huge Z
(10^6+ units) inside an otherwise small XY footprint — long-section
polylines on a road, for example. fit_all's outlier gate previously
filtered any point whose |x|, |y|, or |z| exceeded 10× the header
extent half-size, which dropped those polylines and made ZOOM
EXTENTS center on the main drawing only, leaving the profile
geometry permanently invisible.

The gate exists to reject origin-stuck entities and Ray/XLine far
points, both of which manifest as large XY excursions after
world_offset subtraction. Z-axis outliers are not a known garbage
pattern, so the gate now only checks XY.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-05-13 10:05:38 +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
HakanandClaude Opus 4.7 586df77b2c feat(io): show loading overlay while opening CAD files
Big DWG/DXF files block the UI for seconds during parse + cache build,
leaving the user wondering whether the app froze. Split the file-open
flow into pick → load and show a modal overlay during the load: file
name, size, phase label (Reading / Parsing / Building caches /
Finalizing), animated indeterminate bar, and Cancel button.

Phase is tracked via a shared AtomicU8 written by the loader thread
and read by the overlay each frame. Cancel hides the overlay and
discards the result; the parser thread runs to completion in the
background since acadrust has no interrupt hook.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-05-13 09:59:07 +03:00
Hakan Seven 288ccff95a fix(render): preserve f64 precision until world_offset subtraction
Entity converters were casting WCS coordinates to f32 before the renderer
subtracted world_offset, which destroyed sub-unit precision on drawings
sitting at large coordinates (typical UTM-style CAD files). The multileader
case made it visible — glyphs warped under rotation — but every entity
that emits TruckObject::Lines/SegmentedLines/key_vertices/fill_tris was
affected.

Type changes (in src/scene/acad_to_truck.rs):
- TruckObject::Lines / SegmentedLines: Vec<[f32; 3]> → Vec<[f64; 3]>
- TruckEntity::key_vertices / fill_tris: f32 → f64

All ~17 producer files updated to keep WCS coordinates in f64 right up to
the TruckEntity boundary. The consumer in scene/tessellate.rs now performs
`(x - ox) as f32` (f64 subtract, then cast) for points, key_vertices, and
fill_tris — preserving precision near the camera origin even when the
drawing sits at million-unit coordinates.

catmull_rom_pts (multileader spline) is now f64; the scene path widens its
offset-relative f32 ctrl points to f64 around the call and narrows back at
the output.

Notes:
- Table layout still uses glam::Vec3 (f32) internally; widened to f64 only
  at the TruckEntity boundary for type compatibility. Separate cleanup to
  switch its internal math to f64 is tracked.
- snap_pts and tangent_geoms remain f32 — they are UI feedback (snap
  candidates, tangent hints) and the precision is sufficient there.
2026-05-12 23:47:40 +03:00
Hakan Seven 8bfa5088c4 fix(multileader): render text properly — strip MText codes, honor full layout
Multileader text was emitted as a single literal stroke pass with no MText
code handling, no rotation, no attachment, no line breaks, no per-piece
color and bad f32 precision under world_offset. Two separate render paths
both had the same bug, and one was masking the fix in the other.

This rewrite, applied to both paths:

- Strips MText format codes (`{\fArial Black|b0|i0|c162|p34;...}`) so the
  rendered text is the actual content, not the markup.
- Honors text_rotation (preferring text_direction so transforms survive),
  text_attachment_point (Left/Center/Right horizontal anchor), and
  text_left_attachment for vertical alignment via a shared
  v_offset_for_attachment helper.
- Splits on \P/\n/\N and word-wraps to text_width.
- Applies line_spacing_factor with the same 5/3 × height convention as
  MText.
- Resolves the text style via text_style_handle (fallback STANDARD).
- Applies ml.scale_factor everywhere (arrow size, dogleg length, text
  height, text width). anno_scale is now only applied when
  enable_annotation_scale is set.
- Splits the scene-level output into separate WireModels so leader,
  text, frame and background fill each carry their own colour
  (ctx.text_color, ml.text_frame, ctx.background_fill_color).
- Mirrors text_direction, base_direction and root.direction in
  apply_transform so a mirrored multileader's text follows the geometry
  instead of staying at its original rotation.
- Computes the text origin and frame corners in offset-relative f32
  space — drawings sit at large absolute coordinates and casting to f32
  before subtracting world_offset was wrecking the rotated sub-glyph
  precision.
2026-05-12 23:27:53 +03:00
Hakan Seven 2600ae1815 chore: release v0.2.5 v0.2.5 2026-05-12 22:29:22 +03:00
Hakan Seven ef57a629c0 Update image in README.md 2026-05-12 22:26:34 +03:00
Hakan Seven 406e04f2f0 chore: repin acadrust to 622729f on clean HakanSeven12 fork
Old fork was deleted and re-forked from upstream; the mirror-handedness fix
is now isolated on fix/mirrored-arc-handedness with no other diverging work.
2026-05-12 22:18:23 +03:00
Hakan Seven 200f10fd25 fix(explode): correct arc/ellipse direction in mirrored INSERT blocks
Mirrored INSERTs reverse OCS handedness, but acadrust's explode used to
keep the original normal — making CCW-around-normal arcs and ellipses
sweep the wrong way. The fix lives in acadrust 7c711e9, which flips the
new normal when det < 0 and reprojects center/major_axis/angles into the
new OCS. H7CAD's fix_mirrored_arc workaround is no longer needed.
2026-05-12 22:04:12 +03:00
Hakan Seven 04b898106c chore: release v0.2.4 v0.2.4 2026-05-12 20:54:03 +03:00
HakanandClaude Sonnet 4.6 a3efad9caf fix(hatch): align EllipticArc angle logic with CircularArc
Use reflection (TAU - sa, TAU - ea) for CW arcs and span.abs() for
segment count, consistent with the CircularArc pattern in both
hatch boundary (mod.rs) and tessellate (tessellate.rs).

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-05-12 17:47:54 +03:00
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 <[email protected]>
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
Hakan Seven fba207a40a fix(arc): simplify angle calculation for clockwise and counterclockwise arcs 2026-05-07 21:44:22 +03:00
HakanandClaude Sonnet 4.6 5e85698dee docs: document temporary wire segment caps in rendering optimization notes
Explains the stop-gap MAX_SEGS_PER_WIRE / MAX_TOTAL_SEGS limits added in
321433e, why they must be reverted, and the condition under which they
should be removed (Phase 1.3 CPU cull landed and verified).

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-05-07 17:26:15 +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 <[email protected]>
2026-05-07 17:24:28 +03:00
HakanandClaude Sonnet 4.6 8e154e2e9e docs: add rendering optimization roadmap for LOD and frustum culling
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-05-07 16:05:31 +03:00
Hakan 034671f4b3 chore: remove ROADMAP.md as it is no longer needed 2026-05-07 11:38:48 +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 <[email protected]>
2026-05-07 09:50:02 +03:00
Hakan e66c7d44da chore: remove PERFORMANCE.md as it is no longer needed 2026-05-07 09:23:28 +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 ca9ec8f47d fix(scene): bump geometry epoch after cache assignment on file open
populate_*_from_document() each called bump_geometry(); direct cache
assignment skipped it, leaving the wire cache stale on first open.
2026-05-06 23:10:35 +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 <[email protected]>
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 <[email protected]>
2026-05-06 17:50:46 +03:00
HakanandClaude Sonnet 4.6 543c626feb chore: release v0.2.3
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
v0.2.3
2026-05-06 11:50:13 +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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
2026-05-05 20:20:16 +03:00
Hakan SevenandClaude Sonnet 4.6 f000a8acfb feat: add OLE2Frame interactivity + fix Shape rotation from DXF
OLE2Frame: full TruckConvertible/Grippable/PropertyEditable/Transformable
impls in src/entities/ole2frame.rs — grips on corners + center, properties
panel, translate/scale transforms.

Shape: rotation (DXF code 50) now converted degrees→radians on load in
fix_dxf_dimension_rotations(), matching Dimension and Attribute behaviour.

All ❌ gaps resolved. Remaining: Viewport GPU scissor, LWPolyline plinegen.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-05-05 20:12:44 +03:00
Hakan SevenandClaude Sonnet 4.6 de520199ac docs: mark 5 more gaps resolved — thickness, Hatch OCS, RasterImage clip, complex lt, MLine OCS
thickness: ✅ Arc/Circle/Line/LwPolyline/Polyline2D all extrude along WCS normal
Hatch OCS→WCS: ✅ all boundary edge types transformed
RasterImage clip_boundary: ✅ polygonal + rectangular implemented
Complex linetype text: ✅ already done in complex_lt.rs (gap was wrong)
MLine/Leader OCS: ✅ N/A — vertices already in WCS per DXF spec

Remaining: Viewport GPU scissor, LWPolyline plinegen, OLE2Frame, Shape rotation

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-05-05 20:06:35 +03:00
Hakan SevenandClaude Sonnet 4.6 fe954fa3ff feat: extrude LwPolyline and Polyline2D thickness along WCS normal
Tessellates bottom + top paths with NaN-separated walls at each vertex.
Arc segments (bulge != 0) use 16-step parametric tessellation.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-05-05 20:06:35 +03:00
Hakan Seven 18cc51f498 Merge pull request #15 from HakanSeven12/arc
refactor: replace angle calculations with radians for consistency
2026-05-03 22:04:38 +03:00
Hakan Seven 603d07412e refactor: replace angle calculations with radians for consistency 2026-05-03 21:58:38 +03:00
Hakan Seven 3fd346729a Replace old screenshot with new one
Updated the screenshot in the README file.
2026-05-03 21:45:46 +03:00
Hakan Seven 8be415213a chore: release v0.2.2 v0.2.2 2026-05-03 21:40:24 +03:00
Hakan Seven d7422b9396 fix: store arc angles in radians 2026-05-03 20:14:28 +03:00
Hakan Seven 1b4c5e13e5 fix: keep open drawing when creating new file 2026-05-03 19:55:38 +03:00
Hakan SevenandClaude Sonnet 4.6 c51eeb4ad0 feat: extrude Arc and Circle thickness along WCS normal
Arc: tessellates bottom + top arcs (32 segs each) with 2 endpoint walls.
Circle: tessellates bottom + top circles (64 segs each) with 4 quadrant walls.
Both use TruckObject::Lines with NaN-separated segments.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-05-02 20:30:30 +03:00
Hakan SevenandClaude Sonnet 4.6 ce17e8abdf feat: extrude Line thickness along WCS normal
When line.thickness != 0, renders 4 NaN-separated wire segments
(bottom, top, left wall, right wall) using TruckObject::Lines.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-05-02 20:27:15 +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 <[email protected]>
2026-05-02 20:24:38 +03:00
Hakan SevenandClaude Sonnet 4.6 3ca038bec8 docs: remove Iced 0.14 batch reference from viewport gap description
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-05-02 20:18:28 +03:00
Hakan SevenandClaude Sonnet 4.6 4527819b2d chore: remove stale multi-viewport limitation comment from ViewportPaneMode
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-05-02 20:18:08 +03:00
Hakan SevenandClaude Sonnet 4.6 654b8d579b docs: correct viewport status — compositing largely works, GPU scissor and multi-viewport 3D missing
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
2026-05-02 20:16:16 +03:00