The px-per-mm mapping was a hard-coded guess twice over, and the right
value depends on the monitor - AutoCAD has the same knob as the Adjust
Display Scale slider. Expose it: a slider plus a number box next to the
lineweight toggle, with a readout of what the drawing's own weights come
out to (0.35mm -> 7px, 0.50mm -> 10px at the 20 px/mm default). The
value persists in localStorage.
Retuning applies to the live materials instead of rebuilding the scene.
The hairline cut-off is a millimetre value, so changing the scale moves
every weight by the same factor without changing which bucket a segment
belongs to - each fat batch now remembers its weight in mm, and only
material.linewidth is rewritten. That keeps a drag on the slider instant
even on the 37 MB road drawing.
Measured headless on its 0.35mm gutter line: 2-3px at scale 8, 7px at
20, 14px at 40 - matching the readout in each case.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Hand test against an AutoCAD capture: the 0.50mm road edge is ~10px
there but only ~4px here. Lineweight is zoom-independent screen pixels,
so the two captures compare directly - the 8 px/mm mapping was 2.5x too
small. AutoCAD's default display scale is one pixel per 0.05mm, so use
20 px/mm (0.35mm = 7px, 0.50mm = 10px, 2.11mm = 42px) and raise the
clamp to 48px.
Add setLineweightScale()/getLineweightScale() so a host can retune it -
AutoCAD exposes the same thing as the Adjust Display Scale slider.
Re-measured headless: the 0.35mm road-gutter line now renders ~7px, so
both weight classes land on the same scale.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Every line was drawn 1px regardless of its CAD lineweight. Two causes:
the dwg-wasm parseResult never carried the field (acadrust reads
EntityCommon::line_weight but it was dropped in serialization), and the
renderer merged all segments into one LineSegments whose
LineBasicMaterial.linewidth WebGL ignores.
Resolve ByLayer/ByBlock/Default per entity and bucket segments by
dash|lineweight. Weighted buckets get their own LineSegments2 +
LineMaterial with worldUnits:false, so width stays constant in pixels
while zooming - AutoCAD LWDISPLAY semantics - at 8 px/mm (0.25mm = 2px).
Anything at or below the 0.25mm default stays in the hairline batch so
drawings that never assigned a weight render exactly as before.
Fat batches are instanced, so layer masking compacts the instance buffer
and lowers instanceCount instead of rewriting an index; slotOf tracks
where each segment moved so the selection highlight still finds its
vertices. Per-entity color spans (meta.spans) let the highlight repaint
across the hairline batch and every bucket it touched. Buckets past
400k segments fall back to hairline to bound GPU/heap cost.
Display follows the drawing's LWDISPLAY and can be forced from the
toolbar; the property panel now shows the entity lineweight.
Verified headless at a fixed camera on the 65k-entity road drawing:
cyan road edge 2px -> 5px, layer hide/restore returns the exact baseline
pixel counts, and a 0.35mm LWPOLYLINE selects and highlights.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>