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:
+41
-1
@@ -14,6 +14,45 @@
|
||||
* { box-sizing: border-box; }
|
||||
html, body { margin: 0; height: 100%; background: var(--bg); color: var(--ink); font-family: var(--sans); }
|
||||
#app { position: fixed; inset: 0; }
|
||||
|
||||
/* ── 상단 로딩 프로그레스 바 (src/topProgress.ts 가 구동) ───────────────
|
||||
.bar : 실제 진행률. width 트랜지션 = 메인 스레드 의존.
|
||||
.sweep : WASM 파싱 / Viewer2D.load() 같은 동기 블로킹 구간용. transform
|
||||
키프레임은 컴포지터 스레드에서 돌기 때문에 메인 스레드가 멈춰
|
||||
있어도 계속 흐른다 — 그 구간에 줄 수 있는 유일한 피드백. */
|
||||
#progress {
|
||||
position: fixed; top: 0; left: 0; right: 0; height: 3px; z-index: 100;
|
||||
pointer-events: none; overflow: hidden;
|
||||
opacity: 0; transition: opacity .3s ease .15s;
|
||||
}
|
||||
#progress.on { opacity: 1; transition-delay: 0s; }
|
||||
#progress .bar {
|
||||
position: absolute; top: 0; bottom: 0; left: 0; width: 0;
|
||||
background: linear-gradient(90deg, var(--accent), #58a6ff 55%, var(--wasm));
|
||||
box-shadow: 0 0 10px rgba(63,185,80,.65), 0 0 4px rgba(88,166,255,.5);
|
||||
transition: width .28s cubic-bezier(.25,.8,.25,1);
|
||||
}
|
||||
#progress.err .bar {
|
||||
background: var(--danger);
|
||||
box-shadow: 0 0 10px rgba(248,81,73,.7);
|
||||
}
|
||||
#progress .sweep {
|
||||
position: absolute; top: 0; bottom: 0; left: 0; width: 34%;
|
||||
background: linear-gradient(90deg, transparent, rgba(230,237,243,.9), transparent);
|
||||
transform: translateX(-105%); will-change: transform; opacity: 0;
|
||||
}
|
||||
#progress.busy .sweep {
|
||||
opacity: 1;
|
||||
animation: pr-sweep 1.15s cubic-bezier(.4,0,.2,1) infinite;
|
||||
}
|
||||
@keyframes pr-sweep {
|
||||
from { transform: translateX(-105%); }
|
||||
to { transform: translateX(400%); }
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
#progress .sweep { animation: none; }
|
||||
#progress .bar { transition: none; }
|
||||
}
|
||||
#toolbar {
|
||||
position: fixed; top: 12px; left: 12px; right: 12px; z-index: 10;
|
||||
display: flex; flex-wrap: wrap; gap: 8px; align-items: center; pointer-events: none;
|
||||
@@ -159,7 +198,7 @@
|
||||
}
|
||||
.layer-sub-btn:hover { color: var(--ink); border-color: var(--accent); background: rgba(63,185,80,.1); }
|
||||
</style>
|
||||
<script type="module" crossorigin src="/assets/index-KG0HO38y.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-D3FqDGwP.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
@@ -175,6 +214,7 @@
|
||||
<div id="spaces" title="Model Space / Paper Space (Layout)"></div>
|
||||
<button id="fit" type="button">Fit (F)</button>
|
||||
<button id="theme" type="button">Theme</button>
|
||||
<button id="lwt" type="button" title="선가중치 표시 (AutoCAD LWDISPLAY)">선가중치</button>
|
||||
<button id="layersBtn" type="button">Layers</button>
|
||||
<button id="propsBtn" type="button">Props (속성)</button>
|
||||
<div id="status">ready</div>
|
||||
|
||||
Reference in New Issue
Block a user