fix(viewer2d): show lineweight at AutoCAD's display scale (20 px/mm)

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>
This commit is contained in:
minsung
2026-08-04 20:34:27 +09:00
co-authored by Claude Opus 5
parent ce3859c487
commit cf1298749b
5 changed files with 6051 additions and 11 deletions
+48 -5
View File
@@ -96,10 +96,18 @@ lineweight 는 **화면 픽셀 폭**이다. 줌해도 굵기가 변하지 않는
따라서 월드 단위가 아니라 스크린 스페이스로 그려야 한다.
```
px = mm × 8 (LW_PX_PER_MM, 최대 24px)
0.25mm ≈ 2px · 0.50mm ≈ 4px · 2.11mm ≈ 17px ← AutoCAD 기본 표시 배율과 동일 눈금
px = mm × 20 (LW_PX_PER_MM, 최대 48px)
0.35mm = 7px · 0.50mm = 10px · 2.11mm = 42px ← AutoCAD 기본 표시 배율(0.05mm당 1px)
```
배율은 `setLineweightScale(pxPerMm)` 로 조정 가능하다(AutoCAD "표시 배율" 슬라이더 대응,
`null` 이면 기본값 복귀).
> **처음에는 8px/mm 로 넣었다가 손테스트에서 "얇다"고 반려됐다.** 정답지(AutoCAD
> 캡처)의 `도로 가장자리`(0.50mm) 선이 약 10px 인데 8px/mm 면 4px 밖에 안 된다.
> lineweight 는 줌 무관 화면 픽셀이므로 두 캡처의 픽셀 두께를 직접 비교하면 되고,
> 그 결과가 20px/mm 다. 자세한 대조는 5-5 절.
### 3-2. 0.25mm 이하는 헤어라인 유지 — **회귀 방지 장치**
`-3`(Default)·`-1`(ByLayer → 레이어도 Default)이 도면 대부분을 차지한다.
@@ -231,7 +239,40 @@ LWPOLYLINE · #151257
cyan 픽셀 수가 감소(11502→11486) → fat 배치의 정점이 강조색으로 재도색됨을 확인.
### 5-4. 회귀 없음
### 5-4. 도면이 실제로 들고 있는 수치
굵기는 **레이어가 아니라 엔티티**에 들어 있다. 23개 레이어 lineweight 는 **전부 `-3`
(Default)** 이라 ByLayer 로는 아무 정보도 나오지 않는다.
| 레이어 | ACI | lineweight | 개수 |
|---|---|---|---|
| 도로 가장자리 | 1 (빨강) | **50 = 0.50mm** | 18 |
| 도로마킹 | 255 / 7 / 2 / 4 | 50 = 0.50mm | 799 |
| 부체도로 가장자리 | 20 | 50 = 0.50mm | 32 |
| 비탈면방향 | 140 / 150 | 35 = 0.35mm | 34,758 |
| 노면측구 | 4 (시안) | 35 = 0.35mm | 303 |
| 시작·끝라인 / Drawing확폭 | 4 / 6 / 2 / 3 | 40 = 0.40mm | 105 |
| SubContour · MainContour | 3 / 6 | 13 = 0.13mm | 8,794 |
| **도로면 (MESH 삼각망)** | 7 | **-3 Default** | 1 (185,444 faces) |
| Station (중심선·라벨) | 1 (빨강) | -1 → 레이어 -3 → Default | 1,082 |
주의: 화면의 **빨간 선이 두 종류**다. 굵은 쪽이 `도로 가장자리`(0.50mm), 도로 한가운데를
지나는 얇은 쪽이 `Station` 중심선(Default → 헤어라인). 정답지에서 굵게 나오는 것은 전자다.
### 5-5. 정답지 대조 (배율 확정 근거)
lineweight 는 줌과 무관한 화면 픽셀이므로, 두 캡처의 **절대 픽셀 두께**를 그대로 비교한다.
| | `도로 가장자리` 0.50mm | 헤어라인(MESH, Default) |
|--|--|--|
| AutoCAD 정답지 | **≈10 px** | 1 px |
| 뷰어 (8px/mm, 반려) | ≈4 px | 1 px |
| 뷰어 (20px/mm, 현재) | **10 px** | 1 px |
헤드리스 재측정으로 교차 확인: 시안색 `노면측구`(0.35mm)가 화면에서 **≈7 px**
(= 0.35 × 20). 두 클래스가 같은 배율로 맞는다.
### 5-6. 회귀 없음
- `npx tsc --noEmit` 통과
- `npm run build` 통과
@@ -241,8 +282,10 @@ cyan 픽셀 수가 감소(11502→11486) → fat 배치의 정점이 강조색
## 6. 남은 과제
1. **표시 배율 고정**`LW_PX_PER_MM = 8` 이 상수다. AutoCAD 는 "선가중치 설정 → 표시 배율"
슬라이더로 조절 가능하므로, 필요하면 `setLineweightScale()` 로 노출할 것.
1. **표시 배율 UI 부재**값은 `setLineweightScale(pxPerMm)` 로 조절되지만 툴바에는
on/off 버튼만 있다. 슬라이더가 필요하면 이 API 에 붙이면 된다.
0.35mm 가 7px 라 `비탈면방향`(34,758개)이 있는 구간은 화면이 상당히 무거워 보인다 —
도면이 지정한 수치대로이긴 하나, 배율을 낮추고 싶으면 이 API 를 쓴다.
2. **ByBlock 근사** — 블록 자식의 `-2` 는 INSERT 굵기를 상속하지만, 중첩 블록에서
중간 INSERT 가 `-2` 인 경우까지는 추적하지 않는다(점선 처리와 동일한 기존 정책).
3. **DXF 레이어 굵기 없음**`dxf-parser` 의 LAYER 핸들러가 코드 370 을 무시한다.