feat(viewer2d): render DWG lineweight in screen pixels

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>
This commit is contained in:
minsung
2026-08-04 17:25:11 +09:00
co-authored by Claude Opus 5
parent eec33820a6
commit c67a803e4d
12 changed files with 6922 additions and 34 deletions
+12
View File
@@ -162,6 +162,7 @@ async function loadAndRender(buf: ArrayBuffer, name: string): Promise<CadParseRe
const def = pickDefaultSpace(spaces);
viewer.load(result, { spaceHandle: def?.handleHex ?? null });
viewer.resize();
syncLwtBtn();
return result;
}
@@ -229,6 +230,17 @@ document.getElementById('theme')!.addEventListener('click', () => {
viewer.setTheme(dark);
fillLayers();
});
// 선가중치(LWT): 처음에는 도면의 LWDISPLAY 값을 따르고, 누르면 강제 on/off.
const lwtBtn = document.getElementById('lwt') as HTMLButtonElement;
const syncLwtBtn = () => {
const on = viewer.getLineweightEnabled();
lwtBtn.classList.toggle('primary', on);
lwtBtn.title = `선가중치 표시 ${on ? 'ON' : 'OFF'} (AutoCAD LWDISPLAY)`;
};
lwtBtn.addEventListener('click', () => {
viewer.setLineweightEnabled(!viewer.getLineweightEnabled());
syncLwtBtn();
});
document.getElementById('layersBtn')!.addEventListener('click', () => {
layersPanel.style.display = layersPanel.style.display === 'flex' ? 'none' : 'flex';
});