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.
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.
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]>
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]>
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]>
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]>
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
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
- 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]>
- 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]>
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]>
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]>
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]>
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]>
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]>
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]>
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]>